SpeciesFileGroup/taxonworks

View on GitHub
app/javascript/vue/components/Filter/Facets/BiologicalAssociation/FacetBiologicalProperty.vue

Summary

Maintainability
Test Coverage
<template>
  <FacetContainer>
    <h3>Biological property</h3>
    <div class="field">
      <VAutocomplete
        url="/controlled_vocabulary_terms/autocomplete"
        param="term"
        :add-params="{ type: ['BiologicalProperty'] }"
        label="label_html"
        clear-after
        @getItem="({ id }) => addBiologicalProperty(id)"
      />
      <table
        v-if="biologicalProperties.length"
        class="vue-table"
      >
        <thead>
          <tr>
            <th>Property</th>
            <th />
            <th />
          </tr>
        </thead>
        <transition-group
          name="list-complete"
          tag="tbody"
        >
          <template
            v-for="item in biologicalProperties"
            :key="item.id"
          >
            <RowItem
              class="list-complete-item"
              :item="item"
              label="object_tag"
              :options="{
                subject: true,
                object: false
              }"
              v-model="item.isSubject"
              @remove="removeBiologicalProperty"
            />
          </template>
        </transition-group>
      </table>
    </div>
  </FacetContainer>
</template>

<script setup>
import RowItem from '@/components/Filter/Facets/shared/RowItem.vue'
import FacetContainer from '@/components/Filter/Facets/FacetContainer.vue'
import VAutocomplete from '@/components/ui/Autocomplete.vue'
import { URLParamsToJSON } from '@/helpers/url/parse.js'
import { ControlledVocabularyTerm } from '@/routes/endpoints'
import { ref, computed, watch } from 'vue'
import { removeFromArray } from '@/helpers/arrays'

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

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

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

watch(
  [
    () => params.value.object_biological_property_id,
    () => params.value.subject_biological_property_id
  ],
  () => {
    if (
      !params.value.object_biological_property_id?.length &&
      !params.value.subject_biological_property_id?.length &&
      biologicalProperties.value.length
    ) {
      biologicalProperties.value = []
    }
  }
)

watch(
  biologicalProperties,
  (newVal) => {
    params.value.object_biological_property_id = newVal
      .filter((item) => !item.isSubject)
      .map((item) => item.id)
    params.value.subject_biological_property_id = newVal
      .filter((item) => item.isSubject)
      .map((item) => item.id)
  },
  { deep: true }
)

function addBiologicalProperty(id, isSubject = false) {
  ControlledVocabularyTerm.find(id).then(({ body }) => {
    biologicalProperties.value.push({
      ...body,
      isSubject
    })
  })
}

function removeBiologicalProperty(biologicalRelationship) {
  removeFromArray(biologicalProperties.value, biologicalRelationship)
}

const {
  subject_biological_property_id: subjectIds = [],
  object_biological_property_id: objectIds = []
} = URLParamsToJSON(location.href)

subjectIds.forEach((id) => {
  addBiologicalProperty(id, true)
})

objectIds.forEach((id) => {
  addBiologicalProperty(id, false)
})
</script>