implement tag filtering
This commit is contained in:
parent
c6f8032918
commit
431112dea9
2 changed files with 87 additions and 7 deletions
|
@ -2,7 +2,7 @@
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import { type RouteRecordRaw, useRouter } from 'vue-router'
|
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 { type GalleryListDefinition } from 'content/routes.js'
|
||||||
import { amendVariantsWithDefaults } from './gallery-utilities'
|
import { amendVariantsWithDefaults } from './gallery-utilities'
|
||||||
import { fetchAndParseYaml, storage } from 'src/utilities/fetch'
|
import { fetchAndParseYaml, storage } from 'src/utilities/fetch'
|
||||||
|
@ -26,13 +26,30 @@ const globalConfig = routeStore._globals
|
||||||
const storageId = `${globalConfig.id}`
|
const storageId = `${globalConfig.id}`
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
let config: GalleryList = null!
|
let config: GalleryList = null!
|
||||||
|
const tagsToggled: string[] = []
|
||||||
|
|
||||||
const ready = ref(false)
|
const ready = ref(false)
|
||||||
const galleryReady = ref(false)
|
const galleryReady = ref(false)
|
||||||
const entries = ref({} as GalleryEntries)
|
const entries = ref({} as GalleryDisplayedEntries)
|
||||||
const variants = ref(validateVariants(props.variants))
|
const variants = ref(validateVariants(props.variants))
|
||||||
const hasWarnings = ref(false)
|
const hasWarnings = ref(false)
|
||||||
const hideWarnings = defineModel('showWarnings', { type: Boolean })
|
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 = () => {
|
const onDisplayEntries = () => {
|
||||||
galleryReady.value = false
|
galleryReady.value = false
|
||||||
|
@ -83,10 +100,33 @@ const onHideWarningsToggled = (event: Event) => {
|
||||||
storage.write(`${storageId}::hideWarnings`, (event.target as HTMLInputElement).checked)
|
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 () => {
|
onMounted(async () => {
|
||||||
|
ready.value = false
|
||||||
config = await fetchAndParseYaml<GalleryList>(routeConfig.config)
|
config = await fetchAndParseYaml<GalleryList>(routeConfig.config)
|
||||||
document.title = routeConfig.title
|
document.title = routeConfig.title
|
||||||
hideWarnings.value = storage.read(`${storageId}::hideWarnings`) || false
|
hideWarnings.value = storage.read(`${storageId}::hideWarnings`) || false
|
||||||
|
onLoadTags()
|
||||||
onDisplayEntries()
|
onDisplayEntries()
|
||||||
ready.value = true
|
ready.value = true
|
||||||
})
|
})
|
||||||
|
@ -115,17 +155,44 @@ onMounted(async () => {
|
||||||
v-model='hideWarnings'
|
v-model='hideWarnings'
|
||||||
@input='onHideWarningsToggled($event)'
|
@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
|
Transition
|
||||||
.gallery(
|
.gallery(
|
||||||
v-if='galleryReady'
|
v-if='galleryReady'
|
||||||
)
|
)
|
||||||
GalleryTile(
|
Transition(
|
||||||
v-for='(entry, id) in entries'
|
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>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="sass">
|
<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 = {
|
export type GalleryEntryInheritedProperties = {
|
||||||
description?: string
|
description?: string
|
||||||
fields?: Record<string, string>
|
fields?: Record<string, string>
|
||||||
|
tags: string[]
|
||||||
title: string | null | undefined
|
title: string | null | undefined
|
||||||
warning?: string
|
warning?: string
|
||||||
}
|
}
|
||||||
|
@ -14,6 +15,18 @@ export type GalleryEntry = GalleryEntryInheritedProperties & {
|
||||||
|
|
||||||
export type GalleryEntries = { [idOrTitle: string]: GalleryEntry }
|
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 = {
|
export type GalleryList = {
|
||||||
entries: GalleryEntries
|
entries: GalleryEntries
|
||||||
|
tags: GalleryTags
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue