implement tag filtering
This commit is contained in:
parent
c6f8032918
commit
431112dea9
2 changed files with 87 additions and 7 deletions
src/views/gallery
|
@ -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">
|
||||
|
|
13
src/views/gallery/gallery.d.ts
vendored
13
src/views/gallery/gallery.d.ts
vendored
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue