Skip to content
Snippets Groups Projects
ExperimentalEvidence.vue 13.06 KiB
<template>
  <div>
    <base-toaster
      :open="toasterIsOpen"
      @close="hideDialog"
    >
      <div class="flex justify-between items-center">
        <font-awesome-icon
          class="ml-3"
          icon="fa-solid fa-thumbs-up "
          size="lg"
        />

        <h4>Request submitted successfully!</h4>
        <button
          class="btn btn-outline"
          @click="hideDialog"
        >
          <font-awesome-icon
            icon="fa-regular fa-circle-xmark"
            size="2x"
          />
        </button>
      </div>
    </base-toaster>

    <div>
      <form
        class="form-horizontal"
        autocomplete="off"
        @submit.prevent="proteinExperimentalHandler"
      >
        <div v-if="isLoading">
          <base-spinner />
        </div>
        <div class="form-group">
          <div class="flex flex-col px-8 space-y-4">
            <div
              v-if="mode === 'Add'"
              class="w-full"
              :class="{ invalid: !experimentalEvidance.isValid }"
            >
              <h1
                class="
                  text-left
                  font-bold
                  mb-2
                  text-xl
                  sm:text-2xl
                  font-montserrat
                "
              >
                Add Experimental Evidence
              </h1>
              <!-- <div v-for="options in proteinExpEvidenceData" :key="options.id">
                <input
                  :id="options.id"
                  v-model="experimentalEvidance.value"
                  type="checkbox"
                  class="h-6 w-6"
                  :name="options"
                  :value="options.type"
                  @blur="clearValidity('experimentalEvidance')"
                />
                <label class="mx-3" :for="options.id">{{ options.type }}</label>
              </div> -->

              <select
                id="expTyp"
                v-model.trim="experimentalEvidance.value"
                class="form-control"
                @blur="clearValidity('experimentalEvidance')"
              >
                <option
                  v-for="options in proteinExpEvidenceData"
                  :key="options.id"
                  :value="options.type"
                >
                  {{ options.type==='frap' ? 'FRAP' :formatValue(options.type) }}
                </option>
              </select>

              <p
                v-if="!experimentalEvidance.isValid"
                class="text-red-500 mt-2"
              >
                {{ experimentalEvidanceMsg }}
              </p>
            </div>
            <div
              v-if="mode === 'Remove'"
              class="w-full"
              :class="{ invalid: !deleteExperimentalEvidance.isValid }"
            >
              <div v-if="!data">
                <h1
                  class="
                    text-left
                    font-bold
                    mb-2
                    text-xl
                    sm:text-2xl
                    font-montserrat
                  "
                >
                  This protein do not have any Experimental Evidance data to
                  remove.
                </h1>
              </div>
              <div v-else>
                <h1
                  class="
                    text-left
                    font-bold
                    mb-2
                    text-xl
                    sm:text-2xl
                    font-montserrat
                  "
                >
                  Remove Experimental Evidence.
                </h1>
                <div
                  v-for="(item, index) in data"
                  :key="index"
                  class="flex space-x-4"
                >
                  <input
                    :id="index"
                    v-model.trim="deleteExperimentalEvidance.value"
                    type="radio"
                    :value="item"
                    @blur="clearValidity('deleteExperimentalEvidance')"
                  >

                  <div class="flex items-center">
                    <label :for="index">
                      {{ item === 'frap' ? 'FRAP' : formatValue(item) }}
                    </label>
                  </div>
                </div>
              </div>

              <p
                v-if="!deleteExperimentalEvidance.isValid"
                class="text-red-500 mt-2"
              >
                {{ experimentalEvidanceMsg }}
              </p>
            </div>
            <div
              class="w-full"
              :class="{ invalid: !comment.isValid }"
            >
              <textarea
                v-if="(!data && mode === 'Add') || data"
                v-model.trim="comment.value"
                class="
                  form-control
                  block
                  px-3
                  py-1.5
                  text-base
                  font-normal
                  text-gray-700
                  bg-white bg-clip-padding
                  rounded
                  transition
                  ease-in-out
                  m-0
                  focus:text-gray-700
                  focus:bg-white
                  focus:border-blue-600
                  focus:outline-none
                "
                rows="5"
                :placeholder="
                  role === 'Maintainer' ? 'Reason (Optional)' : 'Reason'
                "
                @blur="clearValidity('comment')"
              />

              <p
                v-if="!comment.isValid"
                class="text-red-500"
              >
                Reason must not be empty or less than 50 characters.
              </p>
              <p
                v-if="serverError"
                class="text-danger font-bold"
              >
                {{ errMessage }}
              </p>
            </div>
            <div class="space-x-4 w-2/3">
              <button
                v-if="(!data && mode === 'Add') || data"
                class="
                  text-white
                  bg-blue-600
                  hover:bg-blue-700
                  focus:ring-2 focus:ring-blue-300
                  rounded-lg
                  inline-flex
                  items-center
                  px-5
                  py-2.5
                  text-center
                  font-bold
                "
                type="submit"
              >
                {{ mode === "Add" ? "Add" : "Remove" }}
              </button>
              <button
                class="
                  bg-white
                  hover:bg-gray-200
                  focus:ring-2 focus:ring-gray-300
                  rounded-lg
                  border border-gray-300
                  px-5
                  py-2.5
                  hover:text-gray-900
                  font-bold
                "
                type="button"
                @click="close"
              >
                Cancel
              </button>
            </div>
          </div>
        </div>
      </form>
    </div>
  </div>
</template>

<script>

let host = require('../js/const').apiHost;
import BaseSpinner from '../UI/BaseSpinner.vue';
import BaseToaster from '../UI/BaseToaster.vue';
import _ from 'lodash'
export default {
  components: { BaseSpinner, BaseToaster },
  props: ['data', 'uniprotId', 'canonicalId', 'mode'],
  data() {
    return {
      isLoading: false,
      toasterIsOpen: false,
      formIsValid: true,
      experimentalEvidance: {
        value: 'Select',
        isValid: true,
      },
      deleteExperimentalEvidance: {
        value: '',
        isValid: true,
      },
      comment: {
        value: '',
        isValid: true,
      },
      proteinExpEvidenceData: [
        { id: '1', type: 'Select', displayData:'Select' },
        { id: '2', type: 'in_vitro', displayData:'In Vitro' },
        { id: '3', type: 'in_vivo', displayData:'In Vivo' },
        { id: '4', type: 'in_cellulo', displayData:'In Cellulo' },
        { id: '5', type: 'mass_spectrometry', displayData:'Mass Spectrometry' },
        { id: '6', type: 'colocalization', displayData:'Colocalization' },
        { id: '7', type: 'frap', displayData:'FRAP' },
        { id: '8', type: 'others', displayData:'Others' },
      ],
      experimentalEvidanceMsg: '',
      serverError: false,
      errMessage: '',
    };
  },
  computed: {
    jwt: function () {
      return this.$store.getters['User/jwt'];
    },
    role: function () {
      return this.$store.getters['User/userRole'];
    },
    
  },
  
  methods: {
   formatValue(input){
      let val = _.startCase(input);
      return val;
    },
    showDialog() {
      this.toasterIsOpen = true;
    },
    hideDialog() {
      this.toasterIsOpen = false;
    },
    close() {
      this.$emit('closeProteinExpEvidence');
    },
    clearValidity(input) {
      this[input].isValid = true;
    },
    validateForm() {
      this.formIsValid = true;
      if (this.mode === 'Add') {
        if (
          this.experimentalEvidance.value === '' ||
          this.experimentalEvidance.value === 'Select'
        ) {
          this.experimentalEvidanceMsg =
            'Please select an Experimental evidence value!';
          this.experimentalEvidance.isValid = false;
          this.formIsValid = false;
        }

        let findExpData;
        if (this.data) {
          for (let presentExp of this.data) {
            if (this.experimentalEvidance.value === presentExp) {
              findExpData = presentExp;
            }
          }
        }

        if (findExpData) {
          this.experimentalEvidanceMsg = `Selected experimental evidence ${findExpData.toUpperCase()} is already in this protein. Please select another value to add.`;
          this.experimentalEvidance.isValid = false;
          this.formIsValid = false;
        }
      } else {
        if (this.deleteExperimentalEvidance.value === '') {
         
          this.experimentalEvidanceMsg =
            'Please select an Experimental evidence value to remove!';
          this.deleteExperimentalEvidance.isValid = false;
          this.formIsValid = false;
        }
      }

      if (
        (this.comment.value === '' || this.comment.value.length < 50) &&
        this.role !== 'Maintainer'
      ) {
        this.comment.isValid = false;
        this.formIsValid = false;
      }
    },
    async proteinExperimentalHandler() {
      this.validateForm();
      if (!this.formIsValid) {
        return;
      }

      if (this.isDev) {
        host = require('../js/const').devApiHost;
      }

      let url = `${host}/api/update-items`;
      let data;
      let entityId = `${this.canonicalId}==${this.uniprotId}`;
      if (this.mode === 'Add') {
        if (this.role === 'Maintainer') {
          data = {
            Entity: 'condensate_protein',
            EntityId: entityId,
            ChangeOperation: 'add',
            Attribute: 'exp_evidence',
            SubmissionComments:
              'Maintainer do not need to provide a reason for such change at the moment!',
            Value: this.experimentalEvidance.value,
            Status: 'accepted',
          };
        } else {
          data = {
            Entity: 'condensate_protein',
            EntityId: entityId,
            ChangeOperation: 'add',
            Attribute: 'exp_evidence',
            SubmissionComments: this.comment.value,
            Value: this.experimentalEvidance.value,
            Status: 'requested',
          };
        }
      } else {
        if (this.role === 'Maintainer') {
          data = {
            Entity: 'condensate_protein',
            EntityId: entityId,
            ChangeOperation: 'remove',
            Attribute: 'exp_evidence',
            SubmissionComments:
              'Maintainer do not need to provide a reason for such change at the moment!',
            Value: this.deleteExperimentalEvidance.value,
            Status: 'accepted',
          };
        } else {
          data = {
            Entity: 'condensate_protein',
            EntityId: entityId,
            ChangeOperation: 'remove',
            Attribute: 'exp_evidence',
            SubmissionComments: this.comment.value,
            Value: this.deleteExperimentalEvidance.value,
            Status: 'requested',
          };
        }
      }

      this.isLoading = true;
      try {
        await this.axios.post(
          url,
          { data: data },
          {
            headers: {
              Authorization: `Bearer ${this.jwt}`,
            },
          }
        );
        this.isLoading = false;
        this.toasterIsOpen = true;
        this.experimentalEvidance.value = 'Select';
        this.deleteExperimentalEvidance.value = '';
        this.comment.value = '';
        this.serverError = false;
        this.errMessage = '';
        this.$emit('update-key');
        setTimeout(() => {
          this.toasterIsOpen = false;
        }, 2000);
      } catch (e) {
        console.error(e);
        this.isLoading = false;
        this.serverError = true;
        this.errMessage =
          e.message || 'Something went wrong, please try again later!';
      }
    },
  },
};
</script>

<style scoped>
.invalid h1,
.invalid label {
  color: red;
}
.invalid input,
.invalid textarea,
.invalid select {
  border: 1px solid red;
}
</style>