Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<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>