feat: replace all select dropdowns with IconGridSelect, fix EN template seed
Shared grid-items.ts with reusable item definitions for: sort by/order, album mode, asset type, memory source, locale, response mode, event type filter, chat action, preview target type, provider type. Replaced selects on: - Dashboard: event type, provider, sort (compact mode — auto-width) - Tracking configs: sort by/order, album modes, asset types, memory source - Command configs: locale, response mode, provider type - Targets: chat action - Template configs: preview target type, provider type - Command template configs: provider type - Providers: type selector (read-only during edit) IconGridSelect: added compact prop for inline filter bars (auto-width, smaller padding, shows icon + label text). Backend: template seed now re-creates deleted system templates on startup using raw SQL to handle legacy NOT NULL columns. Added i18n: trackingConfig.providerType, trackingConfig.sortRandom Added provider_type badge to tracking config cards.
This commit is contained in:
@@ -8,9 +8,16 @@
|
||||
import Loading from '$lib/components/Loading.svelte';
|
||||
import MdiIcon from '$lib/components/MdiIcon.svelte';
|
||||
import EventChart from '$lib/components/EventChart.svelte';
|
||||
import IconGridSelect from '$lib/components/IconGridSelect.svelte';
|
||||
import EntitySelect from '$lib/components/EntitySelect.svelte';
|
||||
import { eventTypeFilterItems, sortFilterItems } from '$lib/grid-items';
|
||||
|
||||
let status = $state<any>(null);
|
||||
let providers = $derived(providersCache.items);
|
||||
const providerFilterItems = $derived([
|
||||
{ value: '', label: t('dashboard.allProviders'), icon: 'mdiFilterOff' },
|
||||
...providers.map(p => ({ value: p.id, label: p.name, icon: p.icon || 'mdiServer', desc: p.type })),
|
||||
]);
|
||||
let chartDays = $state<any[]>([]);
|
||||
let loaded = $state(false);
|
||||
let error = $state('');
|
||||
@@ -88,6 +95,16 @@
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// Auto-apply when filter values change (via IconGridSelect bind:value)
|
||||
let _prevFilterKey = '';
|
||||
$effect(() => {
|
||||
const key = `${filterEventType}|${filterProviderId}|${filterSort}`;
|
||||
if (loaded && key !== _prevFilterKey && _prevFilterKey !== '') {
|
||||
applyFilters();
|
||||
}
|
||||
_prevFilterKey = key;
|
||||
});
|
||||
|
||||
function applyFilters() {
|
||||
eventsOffset = 0;
|
||||
loadEvents();
|
||||
@@ -190,14 +207,6 @@
|
||||
collection_renamed: '#6366f1', collection_deleted: '#dc2626', sharing_changed: '#f59e0b',
|
||||
};
|
||||
|
||||
const eventTypeOptions = $derived([
|
||||
{ value: '', label: t('dashboard.allEvents') },
|
||||
{ value: 'assets_added', label: t('dashboard.filterAssetsAdded') },
|
||||
{ value: 'assets_removed', label: t('dashboard.filterAssetsRemoved') },
|
||||
{ value: 'collection_renamed', label: t('dashboard.filterRenamed') },
|
||||
{ value: 'collection_deleted', label: t('dashboard.filterDeleted') },
|
||||
{ value: 'sharing_changed', label: t('dashboard.filterSharingChanged') },
|
||||
]);
|
||||
</script>
|
||||
|
||||
<PageHeader title={t('dashboard.title')} description={t('dashboard.description')} />
|
||||
@@ -248,24 +257,9 @@
|
||||
placeholder={t('dashboard.searchEvents')}
|
||||
class="w-full px-3 py-1.5 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
|
||||
</div>
|
||||
<select bind:value={filterEventType} onchange={applyFilters}
|
||||
class="px-2 py-1.5 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]">
|
||||
{#each eventTypeOptions as opt}
|
||||
<option value={opt.value}>{opt.label}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<select bind:value={filterProviderId} onchange={applyFilters}
|
||||
class="px-2 py-1.5 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]">
|
||||
<option value="">{t('dashboard.allProviders')}</option>
|
||||
{#each providers as p}
|
||||
<option value={p.id}>{p.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<select bind:value={filterSort} onchange={applyFilters}
|
||||
class="px-2 py-1.5 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]">
|
||||
<option value="newest">{t('dashboard.newestFirst')}</option>
|
||||
<option value="oldest">{t('dashboard.oldestFirst')}</option>
|
||||
</select>
|
||||
<IconGridSelect items={eventTypeFilterItems()} bind:value={filterEventType} columns={3} compact />
|
||||
<IconGridSelect items={providerFilterItems} bind:value={filterProviderId} columns={2} compact />
|
||||
<IconGridSelect items={sortFilterItems()} bind:value={filterSort} columns={2} compact />
|
||||
</div>
|
||||
|
||||
<!-- Chart (now inside Events section, affected by filters) -->
|
||||
|
||||
Reference in New Issue
Block a user