Filter Add ButtonCommunity Asset

Open in new window
Open in new window
View RTL
<script lang="ts" setup>
import FilterDropdown from '@/components/FilterDropdown.vue'

// Additional Filters
type AdditionalFilter = {
  id: string
  label: string
  value: Ref<string | Array<string>>
  options: Array<{ label: string; value: string }>
}

const additionalFilters: AdditionalFilter[] = [
  {
    id: 'client',
    label: 'Client',
    value: ref([]),
    options: [
      { label: 'Donald Johnson', value: '17' },
      { label: 'Claudia Olson', value: '32' },
      { label: 'Jesse Wheeler', value: '123' },
    ],
  },
  {
    id: 'patient',
    label: 'Patient',
    value: ref([]),
    options: [
      { label: 'Pixie', value: '3' },
      { label: 'Nimba', value: '33' },
      { label: 'Bink', value: '77' },
      { label: 'Luna', value: '99' },
    ],
  },
  {
    id: 'veterinarian',
    label: 'Veterinarian',
    value: ref([]),
    options: [
      { label: 'Dr. John Doe', value: '23' },
      { label: 'Dr. Jane Smith', value: '34' },
      { label: 'Dr. Jim Beam', value: '45' },
    ],
  },
]

// -- LOGIC FOR ADDING/REMOVING FILTERS
function getLabelForAddedFilter(filterId: string) {
  return additionalFilters.find((filter) => filter.id === filterId)?.label ?? ''
}

function getOptionsForAddedFilter(filterId: string) {
  return (
    additionalFilters.find((filter) => filter.id === filterId)?.options ?? []
  )
}

function getValueForAddedFilter(filterId: string) {
  return additionalFilters.find((filter) => filter.id === filterId)?.value
}

function updateValueForAddedFilter(filterId: string, value: string | string[]) {
  const filter = additionalFilters.find((filter) => filter.id === filterId)

  if (filter) {
    filter.value.value = value
  }
}

const addedFilterIds = ref<string[]>([])

const availableFiltersToAdd = computed(() =>
  additionalFilters.filter((filter) => {
    return !addedFilterIds.value.some(
      (addedFilterId) => addedFilterId === filter.id,
    )
  }),
)

async function addFilter(filterId: string) {
  addedFilterIds.value.push(filterId)

  await nextTick()

  if (addedFilterDropdownRefs.value.length) {
    addedFilterDropdownRefs.value[
      addedFilterDropdownRefs.value.length - 1
    ].open()
  }
}

function removeFilter(filterId: string) {
  addedFilterIds.value = addedFilterIds.value.filter(
    (addedFilterId) => addedFilterId !== filterId,
  )
}

const addedFilterDropdownRefs = ref<InstanceType<typeof FilterDropdown>[]>([])
</script>

<template>
  <nord-stack direction="horizontal" gap="s" wrap>
    <template v-for="filterId in addedFilterIds" :key="filterId">
      <FilterDropdown
        ref="addedFilterDropdownRefs"
        name="add-filter"
        :model-value="getValueForAddedFilter(filterId)?.value"
        :label="getLabelForAddedFilter(filterId)"
        :options="getOptionsForAddedFilter(filterId)"
        multiple
        removable
        @remove="removeFilter(filterId)"
        @update:model-value="updateValueForAddedFilter(filterId, $event || '')"
      />
    </template>

    <FilterAddButton
      v-if="availableFiltersToAdd?.length"
      :options="availableFiltersToAdd"
      @select="addFilter"
    />
  </nord-stack>
</template>

Integration

This community asset is currently only available to use in the New Frontend for Provet Cloud.


Troubleshooting

If you experience any issues while using this community asset, please ask for support in the #vet-frontend Slack channel.


Was this page helpful?

YesNo
Send feedback

We use this feedback to improve our documentation.

 
Edit page
Choose therapy brandChoose veterinary brandAbout Nord Design SystemGet support