From 64fb80235e312040e6d2793e862b042cb31982f8 Mon Sep 17 00:00:00 2001 From: Lightling <contact@lightling.xyz> Date: Fri, 3 May 2024 18:09:36 -0400 Subject: [PATCH] create filter panel shared component --- .../src/components/shared/filter-panel.vue | 66 +++++++++++++++++++ .../src/views/gallery/gallery-list.vue | 47 ++++--------- 2 files changed, 77 insertions(+), 36 deletions(-) create mode 100644 projects/frontend/src/components/shared/filter-panel.vue diff --git a/projects/frontend/src/components/shared/filter-panel.vue b/projects/frontend/src/components/shared/filter-panel.vue new file mode 100644 index 0000000..aedd9e4 --- /dev/null +++ b/projects/frontend/src/components/shared/filter-panel.vue @@ -0,0 +1,66 @@ +<script setup lang="ts"> + +defineProps<{ + tagsByCategory: { [category: string]: Record<string, string> } +}>() + +const emits = defineEmits<{ + (e: 'toggledTagsChanged', value: string[]): void +}>() + +let tagsToggled: string[] = [] + +/** + * Handler for a tag being selected; + * updates the visibility state of the current entries + * @param event the event context which invoked this handler + * @param tagId: the id of the tag + */ +const onToggleTag = (event: Event, tagId: string) => { + if ((event.target as HTMLInputElement).checked) { + tagsToggled.push(tagId) + } else { + const index = tagsToggled.indexOf(tagId) + if (index > -1) { + tagsToggled.splice(index, 1) + } + } + emits('toggledTagsChanged', tagsToggled) +} + +/** + * Resets the `tagsToggled` array + */ +const resetTags = () => { + tagsToggled = [] +} +</script> + +<template lang="pug"> +.filters + h2 Filters + .category( + v-for='(tags, category) in tagsByCategory' + :id='category' + ) + h3( + v-if='category !== "NoCategory"' + ) {{ category }} + .input.labeled-checkbox( + v-for='(tagDisplayName, tagId) in tags' + :id='tagId' + ) + label( + :for='`${tagId}-toggle`' + ) {{ tagDisplayName }} + input( + type='checkbox' + :name='`${tagId}-toggle`' + :id='`${tagId}-toggle`' + @input='onToggleTag($event, tagId)' + ) +</template> + +<style scoped lang="sass"> + +</style> diff --git a/projects/frontend/src/views/gallery/gallery-list.vue b/projects/frontend/src/views/gallery/gallery-list.vue index 53f150b..729e4dd 100644 --- a/projects/frontend/src/views/gallery/gallery-list.vue +++ b/projects/frontend/src/views/gallery/gallery-list.vue @@ -12,6 +12,7 @@ import { fetchAndParseYaml, storage } from 'src/utilities/fetch' import { getCurrentRoute } from 'src/utilities/vuetils' import { useRouteStore } from 'src/routes' +import FilterPanel from 'src/components/shared/filter-panel.vue' import GalleryTile from './gallery-tile.vue' /** @@ -44,10 +45,10 @@ const globalConfig = routeStore._globals const storageId = `${globalConfig.id}` const router = useRouter() let config: GalleryList = null! -let tagsToggled: string[] = [] const ready = ref(false) const galleryReady = ref(false) +const filterPanelRef = ref(null as typeof FilterPanel | null) const entries = ref({} as GalleryDisplayedEntries) const variants = ref(validateVariantPath(props.variants)) const hasWarnings = ref(false) @@ -148,19 +149,9 @@ const onHideWarningsToggled = (event: Event) => { /** * Handler for a tag being selected; * updates the visibility state of the current entries - * @param event the event context which invoked this handler - * @param tagId: the id of the tag + * @param tagsToggled: the tags currently toggled in the filter panel */ -const onToggleTag = (event: Event, tagId: string) => { - if ((event.target as HTMLInputElement).checked) { - tagsToggled.push(tagId) - } else { - const index = tagsToggled.indexOf(tagId) - if (index > -1) { - tagsToggled.splice(index, 1) - } - } - + const onToggledTagsChanged = (tagsToggled: string[]) => { if (tagsToggled.length < 1) { Object.keys(entries.value).forEach(entryId => { entries.value[entryId].hidden = false @@ -177,10 +168,12 @@ const onToggleTag = (event: Event, tagId: string) => { * and the `tagsToggled` array */ const resetTags = () => { + if (!!filterPanelRef.value) { + filterPanelRef.value.resetTags() + } Object.keys(entries.value).forEach(entryId => { entries.value[entryId].hidden = false }) - tagsToggled = [] } onMounted(async () => { @@ -218,30 +211,12 @@ onMounted(async () => { @input='onHideWarningsToggled($event)' ) Transition - .filters( + FilterPanel( v-if='galleryReady && !!tagsByCategory' + :ref='filterPanelRef' + :tagsByCategory='tagsByCategory' + @toggledTagsChanged='onToggledTagsChanged($event)' ) - h2 Filters - .category( - v-for='(tags, category) in tagsByCategory' - :id='category' - ) - h3( - v-if='category !== "NoCategory"' - ) {{ category }} - .input.labeled-checkbox( - v-for='(tagDisplayName, tagId) in tags' - :id='tagId' - ) - label( - :for='`${tagId}-toggle`' - ) {{ tagDisplayName }} - input( - type='checkbox' - :name='`${tagId}-toggle`' - :id='`${tagId}-toggle`' - @input='onToggleTag($event, tagId)' - ) Transition .gallery( v-if='galleryReady'