SpeciesFileGroup/taxonworks

View on GitHub
app/javascript/vue/components/radials/object/components/common_names/main.vue

Summary

Maintainability
Test Coverage
<template>
  <div class="common_name_annotator separate-bottom">
    <div class="separate-bottom">
      <label>Name</label>
      <input
        type="text"
        placeholder="Name"
        v-model="commonName.name"
      />
    </div>

    <fieldset>
      <legend>Geographic area</legend>
      <SmartSelector
        model="geographic_areas"
        klass="CollectingEvent"
        target="CollectingEvent"
        pin-section="GeographicAreas"
        label="name"
        :add-tabs="['map']"
        pin-type="GeographicArea"
        @selected="(item) => (geographicArea = item)"
      >
        <template #map>
          <GeographicAreaMapPicker
            @select="(item) => (geographicArea = item)"
          />
        </template>
      </SmartSelector>
      <div>
        <SmartSelectorItem
          :item="geographicArea"
          label="name"
          @unset="() => (geographicArea = null)"
        />
      </div>
    </fieldset>

    <fieldset>
      <legend>Language</legend>
      <SmartSelector
        model="languages"
        klass="AlternateValue"
        pin-section="Languages"
        pin-type="Language"
        label="english_name"
        @selected="(item) => (language = item)"
      />
      <SmartSelectorItem
        :item="language"
        label="english_name"
        @unset="() => (language = null)"
      />
    </fieldset>

    <div class="field margin-medium-top">
      <label>Start year</label>
      <input
        class="date-input"
        type="number"
        placeholder="Start year"
        v-model="commonName.start_year"
        min="1600"
        max="3000"
      />
    </div>

    <div class="field">
      <label>End year</label>
      <input
        class="date-input"
        type="number"
        placeholder="End year"
        v-model="commonName.end_year"
        min="1600"
        max="3000"
      />
    </div>

    <div class="margin-medium-bottom">
      <VBtn
        color="create"
        medium
        :disabled="!validate"
        @click="saveCommonName"
      >
        {{ commonName.id ? 'Update' : 'Create' }}
      </VBtn>
      <VBtn
        class="margin-small-left"
        medium
        color="primary"
        @click="reset"
        type="button"
      >
        New
      </VBtn>
    </div>

    <TableList
      class="list"
      label="object_tag"
      :header="['Name', 'Geographic area', 'Language', 'Start', 'End', '']"
      :attributes="[
        'name',
        ['geographic_area', 'object_tag'],
        'language_tag',
        'start_year',
        'end_year'
      ]"
      :list="list"
      edit
      @edit="setCommonName"
      @delete="removeItem"
    />
  </div>
</template>

<script setup>
import TableList from '@/components/table_list.vue'
import SmartSelector from '@/components/ui/SmartSelector.vue'
import SmartSelectorItem from '@/components/ui/SmartSelectorItem.vue'
import makeCommonName from '@/factory/CommonName.js'
import GeographicAreaMapPicker from '@/components/ui/SmartSelector/GeographicAreaMapPicker.vue'
import VBtn from '@/components/ui/VBtn/index.vue'
import { CommonName } from '@/routes/endpoints'
import { computed, ref } from 'vue'
import { useSlice } from '@/components/radials/composables'

const props = defineProps({
  objectId: {
    type: Number,
    required: true
  },

  objectType: {
    type: String,
    required: true
  },

  radialEmit: {
    type: Object,
    required: true
  }
})

const { list, addToList, removeFromList } = useSlice({
  radialEmit: props.radialEmit
})

const validate = computed(
  () => commonName.value.name.length > 2 && commonName.value.otu_id
)

const commonName = ref(makeCommonName(props.objectId))
const geographicArea = ref(null)
const language = ref(null)

function reset() {
  commonName.value = makeCommonName(props.objectId)
  geographicArea.value = null
  language.value = null
}

function saveCommonName() {
  const payload = {
    common_name: {
      ...commonName.value,
      geographic_area_id: geographicArea.value?.id || null,
      language_id: language.value?.id || null
    }
  }

  const saveRequest = commonName.value.id
    ? CommonName.update(commonName.value.id, payload)
    : CommonName.create(payload)

  saveRequest.then(({ body }) => {
    addToList(body)
    reset()
  })
}

function setCommonName(item) {
  commonName.value = { ...item }

  geographicArea.value = item.geographic_area_id
    ? {
        id: item.geographic_area_id,
        name: item.geographic_area?.object_tag
      }
    : null

  language.value = item.language_id
    ? {
        id: item.language_id,
        english_name: item.language_tag
      }
    : null
}

function removeItem(item) {
  CommonName.destroy(item.id).then(() => {
    removeFromList(item)
  })
}

CommonName.where({ otu_id: props.objectId }).then(({ body }) => {
  list.value = body
})
</script>

<style lang="scss">
.radial-annotator {
  .common_name_annotator {
    label {
      display: block;
    }
    .date-input {
      min-width: 150px;
    }
    .vue-autocomplete-input {
      width: 374px;
    }
  }
}
</style>