From f74e1a17d8137939ef7da31c9751e607f4ec8498 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 17 Dec 2025 10:17:26 -0800 Subject: [PATCH] add filters and improve database grid styling --- .../database/DatabaseGridWithProvider.svelte | 229 ++++++++++++------ 1 file changed, 153 insertions(+), 76 deletions(-) diff --git a/src/lib/components/database/DatabaseGridWithProvider.svelte b/src/lib/components/database/DatabaseGridWithProvider.svelte index 3ed68056..fe216cbb 100644 --- a/src/lib/components/database/DatabaseGridWithProvider.svelte +++ b/src/lib/components/database/DatabaseGridWithProvider.svelte @@ -8,6 +8,8 @@ import { Grid } from 'wx-svelte-grid' import type { IColumn, IRow } from 'wx-svelte-grid' import { DatabaseProvider } from '$lib/providers/DatabaseProvider' + import CollectionFilters from '$lib/components/collection/CollectionFilters.svelte' + import type { CollectionFilterState } from '$lib/components/collection/CollectionFilters.svelte' import { onMount, onDestroy } from 'svelte' import { goto } from '$app/navigation' @@ -33,6 +35,37 @@ let pageSize = $state(initialPageSize) let searchTimeout: ReturnType | undefined + // Sort state - tracks which column is sorted and in which direction + let sortMarks = $state>({}) + + // Filter state + let elementFilters = $state([]) + let rarityFilters = $state([]) + let seriesFilters = $state<(number | string)[]>([]) + let proficiencyFilters = $state([]) + let seasonFilters = $state([]) + + // Handle filter changes from CollectionFilters component + function handleFiltersChange(filters: CollectionFilterState) { + // Convert series to string[] (weapon series are UUIDs, character series are numbers that need conversion) + const seriesAsStrings = + filters.series.length > 0 ? filters.series.map((s) => String(s)) : undefined + + provider.setFilters({ + element: filters.element.length > 0 ? filters.element : undefined, + rarity: filters.rarity.length > 0 ? filters.rarity : undefined, + series: seriesAsStrings, + proficiency1: filters.proficiency.length > 0 ? filters.proficiency : undefined, + season: filters.season.length > 0 ? filters.season : undefined, + // For characters, also pass series as characterSeries (they use number enum values) + characterSeries: + resource === 'characters' && filters.series.length > 0 + ? filters.series.filter((s): s is number => typeof s === 'number') + : undefined + }) + loadData(1) // Reset to first page when filters change + } + // Create provider const provider = new DatabaseProvider({ resource, pageSize: initialPageSize }) @@ -70,15 +103,42 @@ // Connect provider to grid api.setNext(provider) + // Intercept sort-rows to prevent client-side sorting and do server-side instead + api.intercept('sort-rows', (ev: { key: string; add: boolean }) => { + const { key } = ev + const currentOrder = sortMarks[key]?.order + + // Toggle: asc -> desc -> clear + let newSortKey: string | null = null + let newSortOrder: 'asc' | 'desc' = 'asc' + + if (currentOrder === 'asc') { + sortMarks = { [key]: { order: 'desc' } } + newSortKey = key + newSortOrder = 'desc' + } else if (currentOrder === 'desc') { + sortMarks = {} // Clear sort + newSortKey = null + } else { + sortMarks = { [key]: { order: 'asc' } } + newSortKey = key + newSortOrder = 'asc' + } + + // Update provider and reload from server + provider.setSort(newSortKey, newSortOrder) + loadData(1) // Reset to first page when sorting + + return false // Prevent default client-side sorting + }) + // Add row click handler api.on('select-row', (ev: any) => { - console.log('Row selected:', ev) const rowId = ev.id if (rowId) { // Find the row data to get the granblueId const rowData = data.find((item: any) => item.id === rowId) if (rowData && rowData.granblueId) { - console.log(`Navigating to: /database/${resource}/${rowData.granblueId}`) goto(`/database/${resource}/${rowData.granblueId}`) } } @@ -158,62 +218,67 @@ }) + + + +
- +
{#if headerActions} {@render headerActions()} {/if} -
- - -
+
-
- {#if loading} -
-
Loading...
-
- {/if} - - -
- -