SpeciesFileGroup/taxonworks

View on GitHub
app/javascript/vue/components/Filter/Facets/Source/FacetCitationTopics.vue

Summary

Maintainability
Test Coverage
<template>
  <FacetContainer>
    <h3>Citation topics</h3>
    <fieldset>
      <legend>Topics</legend>
      <smart-selector
        :autocomplete-params="{ 'type[]': 'Topic' }"
        model="topics"
        target="Citation"
        klass="Topic"
        autocomplete-url="/controlled_vocabulary_terms/autocomplete"
        get-url="/controlled_vocabulary_terms/"
        :custom-list="topicList"
        @selected="addTopic"
      />
    </fieldset>
    <display-list
      :list="topics"
      label="object_tag"
      :delete-warning="false"
      @delete-index="removeTopic"
    />
  </FacetContainer>
</template>

<script setup>
import FacetContainer from '@/components/Filter/Facets/FacetContainer.vue'
import SmartSelector from '@/components/ui/SmartSelector'
import DisplayList from '@/components/displayList'
import { URLParamsToJSON } from '@/helpers/url/parse.js'
import { ControlledVocabularyTerm } from '@/routes/endpoints'
import { ref, computed, watch, onBeforeMount } from 'vue'

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits(['update:modelValue'])

const params = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const topics = ref([])
const topicList = ref([])

watch(
  () => props.modelValue.topic_id,
  (newVal, oldVal) => {
    if (!newVal?.length && oldVal?.length) {
      topics.value = []
    }
  }
)

watch(
  topics,
  () => {
    params.value.topic_id = topics.value.map((topic) => topic.id)
  },
  { deep: true }
)

onBeforeMount(() => {
  const urlParams = URLParamsToJSON(location.href)

  ControlledVocabularyTerm.where({ type: ['Topic'] }).then((response) => {
    topicList.value = { all: response.body }
  })

  if (urlParams.topic_id) {
    urlParams.topic_id.forEach((id) => {
      ControlledVocabularyTerm.find(id).then((response) => {
        addTopic(response.body)
      })
    })
  }
})

const addTopic = (topic) => {
  if (!params.value?.topic_id?.includes(topic.id)) {
    topics.value.push(topic)
  }
}

const removeTopic = (index) => {
  topics.value.splice(index, 1)
}
</script>
<style scoped>
:deep(.vue-autocomplete-input) {
  width: 100%;
}
</style>