1adc47f59c
Add a 'Refine ▾' toggle to the gallery filter bar that expands a full-width GalleryFacetPanel below it, inside the same sticky hazey chrome. The panel offers platform chips (with live counts + a 'No platform' unsourced bucket), two count-badged curation-flag toggles (Untagged / No artist), and a from/to date range bounded by the facet min/max. Store gains the platform/untagged/no_artist/date_from/date_to filter params (URL-mirrored, AND-composed) and a panel-gated, single-flighted loadFacets() that fetches /api/gallery/facets scoped to the active filter. Shared cloneFilter/filterToQuery helpers keep the bar and panel writing one URL format. The panel auto-opens on deep-link when refine filters are present and refetches counts (debounced) on every filter change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54 lines
1.7 KiB
JavaScript
54 lines
1.7 KiB
JavaScript
// @vitest-environment happy-dom
|
||
import { describe, it, expect, vi, afterEach } from 'vitest'
|
||
|
||
import GalleryFacetPanel from '../../src/components/gallery/GalleryFacetPanel.vue'
|
||
import { useGalleryStore } from '../../src/stores/gallery.js'
|
||
import { freshPinia, mountComponent } from '../support/mountComponent.js'
|
||
|
||
const FACETS = {
|
||
total: 5,
|
||
platforms: [
|
||
{ value: 'patreon', count: 3 },
|
||
{ value: null, count: 2 }, // unsourced → "No platform" bucket
|
||
],
|
||
untagged: 4,
|
||
no_artist: 1,
|
||
date_min: '2020-01-01T00:00:00+00:00',
|
||
date_max: '2026-06-01T00:00:00+00:00',
|
||
}
|
||
|
||
function stubFetchOk(body) {
|
||
globalThis.fetch = vi.fn(async () => ({
|
||
ok: true, status: 200, statusText: 'OK',
|
||
text: async () => JSON.stringify(body),
|
||
}))
|
||
}
|
||
|
||
describe('GalleryFacetPanel', () => {
|
||
afterEach(() => vi.restoreAllMocks())
|
||
|
||
it('renders platform options with counts and the curation flags', () => {
|
||
const pinia = freshPinia()
|
||
stubFetchOk(FACETS) // covers the onMounted loadFacets() call
|
||
const s = useGalleryStore()
|
||
s.facets = FACETS // seed so counts render synchronously
|
||
const w = mountComponent(GalleryFacetPanel, { pinia })
|
||
const t = w.text()
|
||
expect(t).toContain('patreon')
|
||
expect(t).toContain('3')
|
||
expect(t).toContain('No platform')
|
||
expect(t).toContain('Untagged')
|
||
expect(t).toContain('4')
|
||
expect(t).toContain('No artist')
|
||
})
|
||
|
||
it('shows an en-dash placeholder for a flag count before facets load', () => {
|
||
const pinia = freshPinia()
|
||
stubFetchOk(FACETS)
|
||
useGalleryStore().facets = null // not loaded yet
|
||
const w = mountComponent(GalleryFacetPanel, { pinia })
|
||
expect(w.text()).toContain('Untagged')
|
||
expect(w.text()).toContain('–')
|
||
})
|
||
})
|