<template> <ComboBox v-if="!areShowsLoading" v-model="selectedShow" :label="t('showSelector.selectShow')" :no-data-label="hasShows ? t('showSelector.noDataMatch') : t('showSelector.noData')" :keyboard-shortcut="keys.ctrl_b" :keyboard-shortcut-label="t('showSelector.keyboardShortcut')" :choices="filteredShows" data-testid="show-selector" @search="showSearchQuery = $event" @close="filterActive = null" > <template #default="{ choice: show, index, activeIndex, ...attrs }"> <li v-bind="attrs"> <p class="tw-m-0 tw-font-bold tw-flex tw-items-baseline tw-justify-between"> <span>{{ show.name }}</span> <span class="tw-text-xs tw-opacity-75 tw-flex-none tw-font-normal"> ID: {{ show.id }} </span> </p> <span v-if="!show.is_active" class="tw-text-sm tw-rounded-full tw-bg-black/10 tw-text-black/75 tw-px-2 tw-inline-block tw-float-right tw-m-0 tw-ml-1 tw-mb-1" > {{ t('showSelector.showState.inactive') }} </span> <p v-show="activeIndex === index" class="tw-my-1 tw-text-sm tw-opacity-90"> {{ show.short_description }} </p> <span class="tw-clear-both" /> </li> </template> <template #filter> <div v-if="hasShows"> <p class="mb-2 tw-text-sm tw-font-bold">{{ t('showSelector.showState.label') }}</p> <div class="tw-flex tw-text-sm"> <SwitchButton :model-value="filterActive === true" class="tw-whitespace-nowrap" :label="t('showSelector.showState.active')" @update:model-value="toggleFilterActive(true)" /> <SwitchButton :model-value="filterActive === false" class="tw-whitespace-nowrap" :label="t('showSelector.showState.inactive')" @update:model-value="toggleFilterActive(false)" /> </div> </div> <AddShowButton class="tw-block" :class="{ 'tw-mt-auto': hasShows }" :modal="addShowModal" /> </template> <template #pre> <AddShowModal ref="addShowModal" /> </template> </ComboBox> </template> <script lang="ts" setup> import { sort } from 'fast-sort' import { computed, ref } from 'vue' import { useStore } from 'vuex' import { useMagicKeys } from '@vueuse/core' import { useI18n } from '@/i18n' import { useSelectedShow } from '@/utilities' import SwitchButton from '@/components/SwitchButton.vue' import ComboBox from '@/components/ComboBox.vue' import AddShowButton from '@/components/shows/AddShowButton.vue' import AddShowModal from '@/components/shows/AddShowModal.vue' type Show = { id: number is_active: boolean name: string short_description: string } const keys = useMagicKeys() const store = useStore() const { t } = useI18n() const selectedShow = useSelectedShow() const showSearchQuery = ref('') const filterActive = ref<null | boolean>(null) const addShowModal = ref() const shows = computed<Show[]>(() => store.state.shows.shows) const areShowsLoading = computed(() => !store.state.shows.loaded.shows) const hasShows = computed(() => shows.value.length > 0) const sortedShows = computed(() => { return sort(shows.value).by([ { desc: (show) => show.is_active }, { asc: (show) => show.name.toLowerCase() }, ]) }) const filteredShows = computed(() => { return sortedShows.value .filter((show) => (filterActive.value !== null ? show.is_active === filterActive.value : true)) .filter( (show) => show.name.includes(showSearchQuery.value) || show.id.toString() === showSearchQuery.value, ) }) function toggleFilterActive(toggleState: boolean) { if (filterActive.value === toggleState) { filterActive.value = null return } filterActive.value = toggleState } </script> <script lang="ts"> export default { compatConfig: { MODE: 3, }, } </script>