app/javascript/vue/tasks/controlled_vocabularies/manage/app.vue
<template>
<div>
<spinner-component
v-if="isSaving"
full-screen
legend="Saving..."
/>
<div class="flex-separate middle">
<h1>Manage controlled vocabulary</h1>
<ul class="context-menu">
<li>
<a :href="RouteNames.ManageBiocurationTask"
>Manage biocuration classes and groups</a
>
</li>
</ul>
</div>
<VSwitch
v-model="type"
:options="Object.keys(CVT_TYPES)"
/>
<div class="flex-separate middle">
<h3>
{{ CVT_TYPES[type] }}
<a
v-if="linkFor.includes(type)"
href="/tasks/controlled_vocabularies/biocuration/build_collection"
>Manage biocuration classes and groups
</a>
</h3>
<CloneControlledVocabularyTerms
:type="type"
@clone="
() => {
loadCVTList(type)
}
"
/>
</div>
<div class="flex-separate margin-medium-top">
<NavBar
class="one_quarter_width"
navbar-class=""
>
<div class="panel content margin-medium-bottom">
<FormKeyword
v-model="cvt"
@submit="createCTV"
/>
</div>
<div
v-if="globalId"
class="panel content"
>
<h3>Preview use</h3>
<span
class="link"
@click="copyToClipboard"
>{{ globalId }}</span
>
</div>
</NavBar>
<ListComponent
:list="list"
@edit="setCTV"
@remove="removeCTV"
@sort="
(data) => {
list = data
}
"
/>
</div>
</div>
</template>
<script setup>
import { computed, ref, watch, onBeforeMount } from 'vue'
import { ControlledVocabularyTerm } from '@/routes/endpoints'
import { addToArray, removeFromArray } from '@/helpers'
import { RouteNames } from '@/routes/routes'
import CVT_TYPES from './constants/controlled_vocabulary_term_types'
import makeControlledVocabularyTerm from '@/factory/controlledVocabularyTerm'
import VSwitch from '@/components/ui/VSwitch.vue'
import ListComponent from './components/List.vue'
import SpinnerComponent from '@/components/ui/VSpinner'
import FormKeyword from '@/components/Form/FormKeyword.vue'
import CloneFromObject from '@/helpers/cloneFromObject'
import CloneControlledVocabularyTerms from './components/CloneControlledVocabularyTerms.vue'
import NavBar from '@/components/layout/NavBar.vue'
const globalId = computed(() => cvt.value?.global_id)
const cvt = ref(makeControlledVocabularyTerm())
const isSaving = ref(false)
const isLoading = ref(false)
const type = ref('Keyword')
const linkFor = ref(['BiocurationClass', 'BiocurationGroup'])
const list = ref([])
watch(
type,
(newVal) => {
isLoading.value = true
loadCVTList(newVal)
},
{
immediate: true
}
)
onBeforeMount(() => {
const urlParams = new URLSearchParams(window.location.search)
const ctvId = urlParams.get('controlled_vocabulary_term_id')
if (/^\d+$/.test(ctvId)) {
ControlledVocabularyTerm.find(ctvId).then(({ body }) => {
type.value = body.type
setCTV(body)
})
}
})
function loadCVTList(type) {
ControlledVocabularyTerm.where({ type: [type] }).then(({ body }) => {
list.value = body
isLoading.value = false
})
}
function createCTV() {
const payload = {
controlled_vocabulary_term: {
...cvt.value,
type: type.value
}
}
const request = cvt.value.id
? ControlledVocabularyTerm.update(cvt.value.id, payload)
: ControlledVocabularyTerm.create(payload)
isSaving.value = true
request
.then(({ body }) => {
TW.workbench.alert.create(
`${body.type} was successfully ${
cvt.value.id ? 'updated' : 'created'
}.`,
'notice'
)
addToArray(list.value, body, { prepend: true })
cvt.value = makeControlledVocabularyTerm()
})
.finally(() => {
isSaving.value = false
})
}
function setCTV(ctv) {
cvt.value = CloneFromObject(makeControlledVocabularyTerm(), ctv)
}
function copyToClipboard() {
navigator.clipboard.writeText(cvt.value.global_id).then(() => {
TW.workbench.alert.create('Copied to clipboard', 'notice')
})
}
function removeCTV(cvt) {
if (
window.confirm(
"You're trying to delete this record. Are you sure want to proceed?"
)
) {
isLoading.value = true
ControlledVocabularyTerm.destroy(cvt.id)
.then((_) => {
removeFromArray(list.value, cvt)
})
.catch(() => {})
.finally((_) => {
isLoading.value = false
})
}
}
</script>