33d3429060
Move the filtersStore → filterManager.setGroups $effect.root out of manager.svelte.ts into bindings.svelte.ts so all cross-store reactive wiring for the feature lives in one place. manager.svelte.ts now only constructs and exports the singleton.
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
/**
|
|
* Bridges feature-level UI state (filterManager + sortStore) to the
|
|
* entity-level fontStore query params.
|
|
*
|
|
* Centralizing this here means consumers (Search, FontSearch,
|
|
* FilterControls, etc.) bind to the manager/store directly without
|
|
* each repeating the same mapping effect. The bridge is a singleton
|
|
* concern — it tracks singleton state and writes to a singleton query
|
|
* observer, so it lives at module scope, not in any individual widget.
|
|
*/
|
|
|
|
import { fontStore } from '$entities/Font';
|
|
import { untrack } from 'svelte';
|
|
import { mapManagerToParams } from '../../lib/mapper/mapManagerToParams';
|
|
import { sortStore } from '../store/sortStore.svelte';
|
|
import { filtersStore } from './filters.svelte';
|
|
import { filterManager } from './manager.svelte';
|
|
|
|
$effect.root(() => {
|
|
/**
|
|
* Populate filterManager groups when backend filter metadata resolves.
|
|
* filtersStore is async; until it loads, filterManager has empty groups
|
|
* and the UI renders nothing for them.
|
|
*/
|
|
$effect(() => {
|
|
const dynamicFilters = filtersStore.filters;
|
|
|
|
if (dynamicFilters.length > 0) {
|
|
filterManager.setGroups(
|
|
dynamicFilters.map(filter => ({
|
|
id: filter.id,
|
|
label: filter.name,
|
|
properties: filter.options.sort((a, b) => b.count - a.count).map(opt => ({
|
|
id: opt.id,
|
|
name: opt.name,
|
|
value: opt.value,
|
|
selected: false,
|
|
})),
|
|
})),
|
|
);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Mirror filter selections + debounced search query into fontStore params.
|
|
* untrack the write so fontStore's internal $state reads don't feed back
|
|
* into this effect's dependency graph.
|
|
*/
|
|
$effect(() => {
|
|
const params = mapManagerToParams(filterManager);
|
|
untrack(() => fontStore.setParams(params));
|
|
});
|
|
|
|
/**
|
|
* Mirror sort selection into fontStore.
|
|
*/
|
|
$effect(() => {
|
|
const apiSort = sortStore.apiValue;
|
|
untrack(() => fontStore.setSort(apiSort));
|
|
});
|
|
});
|