1
0
Fork 0

implement tag filtering

This commit is contained in:
lightling 2024-03-21 20:16:02 -04:00
parent c6f8032918
commit 431112dea9
2 changed files with 87 additions and 7 deletions

View file

@ -2,7 +2,7 @@
import { onMounted, ref } from 'vue'
import { type RouteRecordRaw, useRouter } from 'vue-router'
import type { GalleryEntries, GalleryList } from './gallery'
import type { GalleryDisplayedEntries, GalleryList } from './gallery'
import { type GalleryListDefinition } from 'content/routes.js'
import { amendVariantsWithDefaults } from './gallery-utilities'
import { fetchAndParseYaml, storage } from 'src/utilities/fetch'
@ -26,13 +26,30 @@ const globalConfig = routeStore._globals
const storageId = `${globalConfig.id}`
const router = useRouter()
let config: GalleryList = null!
const tagsToggled: string[] = []
const ready = ref(false)
const galleryReady = ref(false)
const entries = ref({} as GalleryEntries)
const entries = ref({} as GalleryDisplayedEntries)
const variants = ref(validateVariants(props.variants))
const hasWarnings = ref(false)
const hideWarnings = defineModel('showWarnings', { type: Boolean })
const tagsByCategory = ref({} as { [category: string]: Record<string, string> })
const onLoadTags = () => {
tagsByCategory.value = { 'NoCategory': {}}
Object.keys(config.tags).forEach(id => {
const tag = config.tags[id]
if (!!tag.category) {
if (!tagsByCategory.value[tag.category]) {
tagsByCategory.value[tag.category] = {}
}
tagsByCategory.value[tag.category][id] = tag.displayName || id
} else {
tagsByCategory.value['NoCategory'][id] = tag.displayName || id
}
})
}
const onDisplayEntries = () => {
galleryReady.value = false
@ -83,10 +100,33 @@ const onHideWarningsToggled = (event: Event) => {
storage.write(`${storageId}::hideWarnings`, (event.target as HTMLInputElement).checked)
}
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)
}
}
if (tagsToggled.length < 1) {
Object.keys(entries.value).forEach(entryId => {
entries.value[entryId].hidden = false
})
} else {
Object.keys(entries.value).forEach(entryId => {
entries.value[entryId].hidden = !entries.value[entryId].tags.some(own => tagsToggled.includes(own))
})
}
}
onMounted(async () => {
ready.value = false
config = await fetchAndParseYaml<GalleryList>(routeConfig.config)
document.title = routeConfig.title
hideWarnings.value = storage.read(`${storageId}::hideWarnings`) || false
onLoadTags()
onDisplayEntries()
ready.value = true
})
@ -115,17 +155,44 @@ onMounted(async () => {
v-model='hideWarnings'
@input='onHideWarningsToggled($event)'
)
Transition
.filters(
v-if='galleryReady'
)
.category(
v-for='(tags, category) in tagsByCategory'
:id='category'
)
h2(
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'
)
GalleryTile(
Transition(
v-for='(entry, id) in entries'
:entry='entry'
:id='id'
:hideWarnings='hideWarnings'
@click='onTileClicked($event)'
)
GalleryTile(
v-if='!entry.hidden'
:entry='entry'
:id='id'
:hideWarnings='hideWarnings'
@click='onTileClicked($event)'
)
</template>
<style scoped lang="sass">

View file

@ -1,6 +1,7 @@
export type GalleryEntryInheritedProperties = {
description?: string
fields?: Record<string, string>
tags: string[]
title: string | null | undefined
warning?: string
}
@ -14,6 +15,18 @@ export type GalleryEntry = GalleryEntryInheritedProperties & {
export type GalleryEntries = { [idOrTitle: string]: GalleryEntry }
export type GalleryDisplayedEntries = { [idOrTitle: string]: GalleryEntry & {
hidden?: boolean
}}
export type GalleryTag = {
category?: string
displayName?: string
}
export type GalleryTags = { [id: string]: GalleryTag }
export type GalleryList = {
entries: GalleryEntries
tags: GalleryTags
}