diff --git a/src/components/chip/GroupChip.svelte b/src/components/chip/GroupChip.svelte new file mode 100644 index 00000000..0405aa25 --- /dev/null +++ b/src/components/chip/GroupChip.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/components/chip/index.ts b/src/components/chip/index.ts index 61617736..ba456fbd 100644 --- a/src/components/chip/index.ts +++ b/src/components/chip/index.ts @@ -1,3 +1,4 @@ export { default as Chip } from './Chip.svelte'; export { default as ItemChipList } from './ItemChipList.svelte'; export { default as ItemChip } from './ItemChip.svelte'; +export { default as GroupChip } from './GroupChip.svelte'; diff --git a/src/routes/[group]/+page.svelte b/src/routes/[group]/+page.svelte index 4f710cc7..2a382a3e 100644 --- a/src/routes/[group]/+page.svelte +++ b/src/routes/[group]/+page.svelte @@ -4,7 +4,7 @@ import { ItemCardGrid } from '$components/card'; import Background from '$components/Background.svelte'; import api from '$endpoints'; - import { ItemChipList } from '$components/chip'; + import { ItemChipList, GroupChip } from '$components/chip'; import { createItemFilter, applyFiltersToGroupItems, type FilterOptions } from '$lib/itemFilter'; import consts from '$lib/consts'; import { generateKeywords } from '$lib/seo'; @@ -15,6 +15,9 @@ let groupData = data.globals.groups[data.groupId]; let filterSelections = createItemFilter(data.globals, data.groupId); + // Items in group + // ================================================== + const listHiddenItems = (groupId: string) => Object.keys(data.globals.items[groupId]) .filter(g => !groupData.info.listedItems.includes(g)); @@ -27,11 +30,24 @@ /** By default list all items until a filter is applied */ let mainItemsList = shownItems; + // Filter groups for this group + // ================================================== + + let filterGroups: [string, boolean][] = []; + function beginEditing() { editing = true; filterSelections = createItemFilter(data.globals, data.groupId); // Make mainItemsList a reference so that updates are shown to the user mainItemsList = shownItems; + // Set up filter groups + filterGroups = groupData.info.filterGroups.map(g => [g, true]); + // Including filter groups not shown + Object.keys(data.globals.groups).forEach(g => { + if (g !== data.groupId && !groupData.info.filterGroups.includes(g)) { + filterGroups.push([g, false]); + } + }); } /** Callback for when editing is finished */ @@ -41,6 +57,9 @@ groupData.readme = readme; await api().group.withId(data.groupId).readme.set(readme); groupData.info.listedItems = [...shownItems]; + groupData.info.filterGroups = filterGroups + .filter(([, selected]) => selected) + .map(([g]) => g); await api().group.withId(data.groupId).info.set(groupData.info); } // Load changes from scratch @@ -72,7 +91,7 @@ $: updateMainItemsList(filterSelections, shownItems); - + {groupData.info.name} - {data.globals.config.siteShortName} @@ -113,6 +132,25 @@ on:filter={e => { filterSelections = e.detail; }} /> + {:else} +
+

Groups used for filtering

+ {#each filterGroups as [filterGroup, selected]} + { + // Toggle filtering for this group + const g = filterGroups.find(([g]) => g === filterGroup); + if (g) { + g[1] = !selected; + } + filterGroups = [...filterGroups]; + }} + /> + {/each} +
{/if} @@ -168,6 +206,12 @@ #filters { width: 100%; } + .filter-group-selection { + display: flex; + align-items: center; + gap: 10px; + width: 98%; + } .item-list { width: 100%; }