Newer
Older
:model-value="selectedShow"
:label="t('showSelector.selectShow')"
:no-data-label="hasShows ? t('showSelector.noDataMatch') : t('showSelector.noData')"
:keyboard-shortcut="!isMac ? keys.alt_k : undefined"
:keyboard-shortcut-label="t('showSelector.keyboardShortcut')"
:choices="filteredShows"
data-testid="show-selector"
@update:model-value="showStore.selectedShowId = $event.id"
@search="showSearchQuery = $event"
@close="filterActive = null"
>
<template #default="{ choice, index, activeIndex, ...attrs }">
<li v-bind="attrs">
<p class="tw-m-0 tw-font-bold tw-flex tw-items-baseline tw-justify-between">
<SafeHTML :html="(choice as Show).name" sanitize-preset="strip" />
<span class="tw-text-xs tw-opacity-75 tw-flex-none tw-font-normal">
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>
<SafeHTML
v-show="activeIndex === index"
as="p"
class="tw-my-1 tw-text-sm tw-opacity-90"
:html="(choice as Show).shortDescription"
<span class="tw-clear-both" />
</li>
</template>
<template #selected="{ isOpen }">
<span
v-if="!isOpen && selectedShow"
class="tw-absolute tw-pointer-events-none tw-top-8 tw-left-3 tw-truncate"
style="max-width: calc(100% - 5.5rem)"
>
<SafeHTML :html="selectedShow.name" sanitize-preset="strip" />
</span>
<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>
<div class="tw-block" :class="{ 'tw-mt-auto': hasShows }">
<AddShowButton test-id="show-selector:add-show" />
</div>
</template>
</ComboBox>
</template>
<script lang="ts" setup>
import { sort } from 'fast-sort'
import { computed, ref } from 'vue'
import { useMagicKeys } from '@vueuse/core'
import { useI18n } from '@/i18n'
import { sanitizeHTML } from '@/util'
import { useShowStore } from '@/stores'
import SwitchButton from '@/components/SwitchButton.vue'
import ComboBox from '@/components/ComboBox.vue'
import AddShowButton from '@/components/shows/AddShowButton.vue'
import SafeHTML from '@/components/generic/SafeHTML'
import { Show } from '@/types'
defineOptions({ compatConfig: { MODE: 3 } })
const keys = useMagicKeys()
const { t } = useI18n()
const showStore = useShowStore()
const selectedShow = computed<Show | null>(() => showStore.selectedShow)
const showSearchQuery = ref('')
const filterActive = ref<null | boolean>(null)
const isMac = navigator.platform.toLowerCase().includes('mac')
const hasShows = computed(() => showStore.items.length > 0)
return sort(showStore.items).by([
{ desc: (show) => show.isActive },
{ asc: (show) => sanitizeHTML(show.name).toLowerCase() },
])
})
const filteredShows = computed(() => {
return sortedShows.value
.filter((show) => (filterActive.value !== null ? show.isActive === filterActive.value : true))
sanitizeHTML(show.name).toLocaleLowerCase().includes(showSearchQuery.value) ||
show.id.toString() === showSearchQuery.value,