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>