@svadmin/ui 0.78.1 → 0.79.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/app.css +187 -1
  2. package/dist/app.theme.css +187 -1
  3. package/dist/components/AutoTable.svelte +183 -962
  4. package/dist/components/content/AuditContent.svelte +33 -0
  5. package/dist/components/content/AuditContent.svelte.d.ts +11 -0
  6. package/dist/components/content/AuditSection.svelte +46 -0
  7. package/dist/components/content/AuditSection.svelte.d.ts +18 -0
  8. package/dist/components/content/ChartContainer.svelte +32 -0
  9. package/dist/components/content/ChartContainer.svelte.d.ts +15 -0
  10. package/dist/components/content/CoverageMatrix.svelte +49 -0
  11. package/dist/components/content/CoverageMatrix.svelte.d.ts +25 -0
  12. package/dist/components/content/EvidenceCard.svelte +35 -0
  13. package/dist/components/content/EvidenceCard.svelte.d.ts +14 -0
  14. package/dist/components/content/FilterToolbar.svelte +24 -4
  15. package/dist/components/content/FilterToolbar.svelte.d.ts +1 -1
  16. package/dist/components/content/StatusPill.svelte +16 -0
  17. package/dist/components/content/StatusPill.svelte.d.ts +9 -0
  18. package/dist/components/content/audit-state.d.ts +1 -0
  19. package/dist/components/content/audit-state.js +1 -0
  20. package/dist/components/content/index.d.ts +9 -0
  21. package/dist/components/content/index.js +5 -0
  22. package/dist/components/list-column-preferences.svelte.d.ts +29 -0
  23. package/dist/components/list-column-preferences.svelte.js +92 -0
  24. package/dist/components/list-deletion.svelte.d.ts +38 -0
  25. package/dist/components/list-deletion.svelte.js +111 -0
  26. package/dist/components/list-selection.svelte.d.ts +31 -0
  27. package/dist/components/list-selection.svelte.js +100 -0
  28. package/dist/components/list-state.svelte.d.ts +49 -0
  29. package/dist/components/list-state.svelte.js +225 -0
  30. package/dist/components/saved-list-views.svelte.d.ts +42 -0
  31. package/dist/components/saved-list-views.svelte.js +405 -0
  32. package/dist/index.d.ts +9 -0
  33. package/dist/index.js +5 -0
  34. package/package.json +1 -1
@@ -0,0 +1,111 @@
1
+ import { tick } from 'svelte';
2
+ import { DeleteManyPartialError, getAdminOptions } from '@svadmin/core';
3
+ export function createListDeletion(options) {
4
+ let request = $state(null);
5
+ let open = $state(false);
6
+ let message = $state('');
7
+ let pending = $state(false);
8
+ let activeDelete;
9
+ $effect(() => {
10
+ if (request && !options.permission().isLoading && !options.permission().allowed) {
11
+ open = false;
12
+ request = null;
13
+ options.reportError(options.messages.failure());
14
+ }
15
+ });
16
+ $effect(() => () => { activeDelete = undefined; });
17
+ function requestDelete(id) {
18
+ if (!options.canRequestSingle() || pending)
19
+ return;
20
+ message = options.messages.single();
21
+ request = { ids: [id], batch: false };
22
+ options.reportError(null);
23
+ open = true;
24
+ }
25
+ function requestBatchDelete() {
26
+ const ids = [...options.selection().selectedIds];
27
+ if (!options.canRequestBatch() || ids.length === 0 || pending)
28
+ return;
29
+ message = options.messages.batch(ids.length);
30
+ request = { ids, batch: true };
31
+ options.reportError(null);
32
+ open = true;
33
+ }
34
+ function cancel() {
35
+ if (pending)
36
+ return;
37
+ open = false;
38
+ request = null;
39
+ }
40
+ function cancelBatchOnCriteriaChange() {
41
+ if (request?.batch && !pending)
42
+ cancel();
43
+ }
44
+ function reset() {
45
+ activeDelete = undefined;
46
+ open = false;
47
+ pending = false;
48
+ request = null;
49
+ options.reportError(null);
50
+ }
51
+ async function confirm() {
52
+ if (!open || !options.canConfirm() || pending || !request)
53
+ return;
54
+ const confirmedRequest = request;
55
+ const selection = options.selection();
56
+ if (confirmedRequest.batch && JSON.stringify(confirmedRequest.ids) !== JSON.stringify(selection.selectedIds)) {
57
+ cancel();
58
+ return;
59
+ }
60
+ const scopeIsCurrent = options.captureScope();
61
+ const token = {};
62
+ activeDelete = token;
63
+ pending = true;
64
+ open = false;
65
+ const clearBeforeMutation = confirmedRequest.batch && getAdminOptions().mutationMode === 'undoable';
66
+ const selectionBeforeDelete = clearBeforeMutation ? selection.captureExplicit() : undefined;
67
+ if (clearBeforeMutation)
68
+ options.clearSelection();
69
+ const current = () => activeDelete === token && scopeIsCurrent();
70
+ try {
71
+ await options.mutate([...confirmedRequest.ids]);
72
+ if (!current())
73
+ return;
74
+ options.clearSelection();
75
+ await tick();
76
+ if (!current())
77
+ return;
78
+ open = false;
79
+ }
80
+ catch (error) {
81
+ if (!current())
82
+ return;
83
+ if (error instanceof DeleteManyPartialError) {
84
+ selection.retainFailedIds(error.failedIds);
85
+ options.reportError(options.messages.partial(error.failedIds.length, confirmedRequest.ids.length));
86
+ }
87
+ else {
88
+ if (selectionBeforeDelete)
89
+ selection.restoreExplicit(selectionBeforeDelete);
90
+ options.reportError(options.messages.failure());
91
+ }
92
+ open = false;
93
+ }
94
+ finally {
95
+ if (activeDelete === token) {
96
+ activeDelete = undefined;
97
+ pending = false;
98
+ request = null;
99
+ }
100
+ await tick();
101
+ await tick();
102
+ }
103
+ }
104
+ return {
105
+ get request() { return request; },
106
+ get open() { return open; },
107
+ get pending() { return pending; },
108
+ get message() { return message; },
109
+ requestDelete, requestBatchDelete, confirm, cancel, cancelBatchOnCriteriaChange, reset,
110
+ };
111
+ }
@@ -0,0 +1,31 @@
1
+ import type { Filter, Sort } from '@svadmin/core';
2
+ import type { RowSelectionState } from '@tanstack/svelte-table';
3
+ import { type BatchSelection } from './table-contract.js';
4
+ interface ListSelectionOptions {
5
+ filters: () => Filter[];
6
+ sorters: () => Sort[];
7
+ total: () => number;
8
+ selectable: () => boolean;
9
+ allowAllMatching: () => boolean;
10
+ onCriteriaChange: () => void;
11
+ }
12
+ export declare function createListSelection(options: ListSelectionOptions): {
13
+ rowSelection: RowSelectionState;
14
+ readonly allMatchingSelected: boolean;
15
+ readonly selectedIds: (string | number)[];
16
+ readonly selectedCount: number;
17
+ rowIsSelected: (key: string) => boolean;
18
+ trackRow: (key: string, id: string | number, selected: boolean) => void;
19
+ toggleExcluded: (key: string, id: string | number) => void;
20
+ selectAllMatching: () => void;
21
+ snapshot: (page: ReadonlyArray<{
22
+ key: string;
23
+ id: string | number;
24
+ }>) => BatchSelection;
25
+ reset: () => void;
26
+ clearExplicit: () => void;
27
+ captureExplicit: () => Map<string, string | number>;
28
+ restoreExplicit: (ids: ReadonlyMap<string, string | number>) => void;
29
+ retainFailedIds: (ids: (string | number)[]) => void;
30
+ };
31
+ export {};
@@ -0,0 +1,100 @@
1
+ import { untrack } from 'svelte';
2
+ import { SvelteMap } from 'svelte/reactivity';
3
+ import { tableRowKey } from './table-contract.js';
4
+ import { cloneListFilter } from './list-state.svelte.js';
5
+ export function createListSelection(options) {
6
+ let rowSelection = $state({});
7
+ let allMatchingSelected = $state(false);
8
+ const selectedIdValueByKey = new SvelteMap();
9
+ const excludedMatchingIds = new SvelteMap();
10
+ const selectedIds = $derived(Object.keys(rowSelection).filter(key => rowSelection[key] === true).flatMap(key => {
11
+ const id = selectedIdValueByKey.get(key);
12
+ return id === undefined ? [] : [id];
13
+ }));
14
+ const selectedCount = $derived(allMatchingSelected
15
+ ? Math.max(0, options.total() - excludedMatchingIds.size) : selectedIds.length);
16
+ const criteria = $derived(JSON.stringify(options.filters()));
17
+ let previousCriteria = untrack(() => criteria);
18
+ $effect.pre(() => {
19
+ const nextCriteria = criteria;
20
+ if (nextCriteria !== previousCriteria) {
21
+ reset();
22
+ options.onCriteriaChange();
23
+ }
24
+ previousCriteria = nextCriteria;
25
+ });
26
+ $effect.pre(() => {
27
+ if (!options.selectable() || !options.allowAllMatching())
28
+ clearMatching();
29
+ if (!options.selectable())
30
+ clearExplicit();
31
+ });
32
+ function clearMatching() {
33
+ allMatchingSelected = false;
34
+ excludedMatchingIds.clear();
35
+ }
36
+ function clearExplicit() {
37
+ selectedIdValueByKey.clear();
38
+ rowSelection = {};
39
+ }
40
+ function reset() {
41
+ clearMatching();
42
+ clearExplicit();
43
+ }
44
+ function rowIsSelected(key) {
45
+ return allMatchingSelected ? !excludedMatchingIds.has(key) : rowSelection[key] === true;
46
+ }
47
+ function trackRow(key, id, selected) {
48
+ if (selected)
49
+ selectedIdValueByKey.set(key, id);
50
+ else
51
+ selectedIdValueByKey.delete(key);
52
+ }
53
+ function toggleExcluded(key, id) {
54
+ if (excludedMatchingIds.has(key))
55
+ excludedMatchingIds.delete(key);
56
+ else
57
+ excludedMatchingIds.set(key, id);
58
+ }
59
+ function selectAllMatching() {
60
+ clearExplicit();
61
+ excludedMatchingIds.clear();
62
+ allMatchingSelected = true;
63
+ }
64
+ function snapshot(page) {
65
+ if (allMatchingSelected)
66
+ return {
67
+ scope: 'all',
68
+ filters: options.filters().map(cloneListFilter),
69
+ sorters: options.sorters().map(sorter => ({ ...sorter })),
70
+ total: options.total(),
71
+ excludedIds: [...excludedMatchingIds.values()],
72
+ };
73
+ return {
74
+ scope: 'selected',
75
+ ids: [...selectedIds],
76
+ currentPageIds: page.filter(row => rowSelection[row.key] === true).map(row => row.id),
77
+ };
78
+ }
79
+ function captureExplicit() {
80
+ return new Map(selectedIdValueByKey);
81
+ }
82
+ function restoreExplicit(ids) {
83
+ selectedIdValueByKey.clear();
84
+ for (const [key, id] of ids)
85
+ selectedIdValueByKey.set(key, id);
86
+ rowSelection = Object.fromEntries([...ids.keys()].map(key => [key, true]));
87
+ }
88
+ function retainFailedIds(ids) {
89
+ restoreExplicit(new Map(ids.map(id => [tableRowKey(id), id])));
90
+ }
91
+ return {
92
+ get rowSelection() { return rowSelection; },
93
+ set rowSelection(value) { rowSelection = value; },
94
+ get allMatchingSelected() { return allMatchingSelected; },
95
+ get selectedIds() { return selectedIds; },
96
+ get selectedCount() { return selectedCount; },
97
+ rowIsSelected, trackRow, toggleExcluded, selectAllMatching, snapshot,
98
+ reset, clearExplicit, captureExplicit, restoreExplicit, retainFailedIds,
99
+ };
100
+ }
@@ -0,0 +1,49 @@
1
+ import type { FieldDefinition, Filter, Pagination, Sort, readURLState, writeURLState } from '@svadmin/core';
2
+ import type { SavedListViewState } from './saved-list-views.js';
3
+ type URLState = ReturnType<typeof readURLState>;
4
+ type ListStateSnapshot = Pick<SavedListViewState, 'search' | 'filters' | 'sorters' | 'pagination'>;
5
+ interface ListStateOptions {
6
+ fields: () => FieldDefinition[];
7
+ defaultPageSize: () => number;
8
+ defaultSort: () => Sort | undefined;
9
+ externalPagination: () => Pagination | undefined;
10
+ externalSorters: () => Sort[] | undefined;
11
+ initialURLState: URLState;
12
+ initialViewState: SavedListViewState | undefined;
13
+ syncWithLocation: () => boolean;
14
+ writeURLState: (state: Parameters<typeof writeURLState>[0]) => void;
15
+ onDirty: () => void;
16
+ }
17
+ export declare function cloneListFilter(filter: Filter): Filter;
18
+ export declare function createListState(options: ListStateOptions): {
19
+ pagination: Pagination;
20
+ sorters: Sort[];
21
+ readonly searchText: string;
22
+ readonly appliedSearchText: string;
23
+ readonly filterValues: Record<string, string>;
24
+ readonly searchableFields: FieldDefinition[];
25
+ readonly filterableFields: FieldDefinition[];
26
+ readonly activeFilterCount: number;
27
+ readonly activeFilterItems: {
28
+ index: number;
29
+ label: string;
30
+ }[];
31
+ readonly activeFilters: Filter[];
32
+ readonly queryPagination: Pagination;
33
+ readonly querySorters: {
34
+ field: string;
35
+ order: "desc" | "asc";
36
+ }[];
37
+ readonly queryFilters: Filter[];
38
+ scheduleSearch: (value: string) => void;
39
+ flushSearch: () => void;
40
+ cancelSearch: () => void;
41
+ clearSearch: () => void;
42
+ clearFilters: () => void;
43
+ setFilterValue: (field: string, value: string) => void;
44
+ removeActiveFilter: (index: number) => void;
45
+ captureState: () => ListStateSnapshot;
46
+ applyState: (state: ListStateSnapshot) => void;
47
+ resetToDefaults: () => void;
48
+ };
49
+ export {};
@@ -0,0 +1,225 @@
1
+ import { untrack } from 'svelte';
2
+ import { definedOptions } from '@svadmin/core/options';
3
+ import { snapshotPlainData } from '@svadmin/core/schema';
4
+ export function cloneListFilter(filter) {
5
+ if ('field' in filter) {
6
+ return {
7
+ field: filter.field,
8
+ operator: filter.operator,
9
+ value: filter.value === undefined ? undefined : snapshotPlainData(filter.value),
10
+ };
11
+ }
12
+ return { operator: filter.operator, value: filter.value.map(cloneListFilter) };
13
+ }
14
+ function editableValues(filters, fields) {
15
+ const keys = new Set(fields.filter(field => field.filterable).map(field => field.key));
16
+ const counts = new Map();
17
+ const values = {};
18
+ for (const filter of filters) {
19
+ if ('field' in filter && filter.operator === 'contains' && typeof filter.value === 'string' && keys.has(filter.field)) {
20
+ counts.set(filter.field, (counts.get(filter.field) ?? 0) + 1);
21
+ }
22
+ }
23
+ for (const filter of filters) {
24
+ if ('field' in filter && filter.operator === 'contains' && typeof filter.value === 'string' && counts.get(filter.field) === 1) {
25
+ values[filter.field] = filter.value;
26
+ }
27
+ }
28
+ return values;
29
+ }
30
+ export function createListState(options) {
31
+ const url = options.initialURLState;
32
+ const initialView = options.initialViewState;
33
+ let pagination = $state(untrack(() => options.externalPagination() ?? {
34
+ current: url.page ?? initialView?.pagination.current ?? 1,
35
+ pageSize: url.pageSize ?? initialView?.pagination.pageSize ?? options.defaultPageSize(),
36
+ }));
37
+ let sorters = $state(untrack(() => {
38
+ const defaultSort = options.defaultSort();
39
+ return options.externalSorters() ?? (url.sortField
40
+ ? [{ field: url.sortField, order: url.sortOrder ?? 'asc' }]
41
+ : initialView?.sorters ?? (defaultSort ? [defaultSort] : []));
42
+ }));
43
+ let filters = $state(url.filters ?? initialView?.filters ?? []);
44
+ let filterValues = $state(untrack(() => editableValues(filters, options.fields())));
45
+ let searchText = $state(url.search ?? initialView?.search ?? '');
46
+ let appliedSearchText = $state(untrack(() => searchText));
47
+ let searchTimer;
48
+ const searchableFields = $derived(options.fields().filter(field => field.searchable));
49
+ const filterableFields = $derived(options.fields().filter(field => field.filterable));
50
+ const activeFilterItems = $derived.by(() => {
51
+ const labels = new Map(options.fields().map(field => [field.key, field.label]));
52
+ return filters.map((filter, index) => ({
53
+ index,
54
+ label: 'field' in filter
55
+ ? `${labels.get(filter.field) ?? filter.field}: ${String(filter.value)}`
56
+ : filter.operator,
57
+ }));
58
+ });
59
+ const activeFilters = $derived.by(() => {
60
+ const result = [...filters];
61
+ if (appliedSearchText.trim() && searchableFields.length > 0) {
62
+ const first = searchableFields[0];
63
+ if (searchableFields.length === 1 && first) {
64
+ result.push({ field: first.key, operator: 'contains', value: appliedSearchText });
65
+ }
66
+ else {
67
+ result.push({
68
+ operator: 'or',
69
+ value: searchableFields.map(field => ({
70
+ field: field.key, operator: 'contains', value: appliedSearchText,
71
+ })),
72
+ });
73
+ }
74
+ }
75
+ return result;
76
+ });
77
+ const queryPagination = $derived(definedOptions({
78
+ current: pagination.current, pageSize: pagination.pageSize, mode: pagination.mode,
79
+ }));
80
+ const querySorters = $derived(sorters.map(sorter => ({ field: sorter.field, order: sorter.order })));
81
+ const queryFilters = $derived(activeFilters.map(cloneListFilter));
82
+ $effect(() => {
83
+ const external = options.externalPagination();
84
+ if (external)
85
+ pagination = external;
86
+ });
87
+ $effect(() => {
88
+ const external = options.externalSorters();
89
+ if (external)
90
+ sorters = external;
91
+ });
92
+ $effect(() => {
93
+ if (!options.syncWithLocation())
94
+ return;
95
+ options.writeURLState({
96
+ page: pagination.current,
97
+ pageSize: pagination.pageSize,
98
+ sortField: sorters[0]?.field,
99
+ sortOrder: sorters[0]?.order,
100
+ search: appliedSearchText || undefined,
101
+ filters,
102
+ });
103
+ });
104
+ $effect(() => cancelSearch);
105
+ function cancelSearch() {
106
+ if (searchTimer !== undefined)
107
+ clearTimeout(searchTimer);
108
+ searchTimer = undefined;
109
+ }
110
+ function scheduleSearch(value) {
111
+ options.onDirty();
112
+ searchText = value;
113
+ cancelSearch();
114
+ searchTimer = setTimeout(() => {
115
+ appliedSearchText = searchText;
116
+ options.onDirty();
117
+ pagination = { ...pagination, current: 1 };
118
+ searchTimer = undefined;
119
+ }, 300);
120
+ }
121
+ function flushSearch() {
122
+ if (searchTimer === undefined)
123
+ return;
124
+ cancelSearch();
125
+ appliedSearchText = searchText;
126
+ }
127
+ function clearSearch() {
128
+ searchText = '';
129
+ appliedSearchText = '';
130
+ pagination = { ...pagination, current: 1 };
131
+ }
132
+ function clearFilters() {
133
+ options.onDirty();
134
+ cancelSearch();
135
+ clearSearch();
136
+ filters = [];
137
+ filterValues = {};
138
+ }
139
+ function setFilterValue(field, value) {
140
+ options.onDirty();
141
+ const trimmedValue = value.trim();
142
+ const nextFilter = { field, operator: 'contains', value: trimmedValue };
143
+ let replaced = false;
144
+ filters = filters.flatMap(filter => {
145
+ if (!('field' in filter) || filter.field !== field || filter.operator !== 'contains')
146
+ return [filter];
147
+ if (!trimmedValue || replaced)
148
+ return [];
149
+ replaced = true;
150
+ return [nextFilter];
151
+ });
152
+ if (trimmedValue && !replaced)
153
+ filters = [...filters, nextFilter];
154
+ filterValues[field] = value;
155
+ pagination = { ...pagination, current: 1 };
156
+ }
157
+ function removeActiveFilter(index) {
158
+ options.onDirty();
159
+ const filter = filters[index];
160
+ if (!filter)
161
+ return;
162
+ const nextFilters = filters.filter((_, filterIndex) => filterIndex !== index);
163
+ filters = nextFilters;
164
+ if ('field' in filter && filter.operator === 'contains') {
165
+ const remaining = nextFilters.filter(candidate => ('field' in candidate && candidate.field === filter.field
166
+ && candidate.operator === 'contains' && typeof candidate.value === 'string'));
167
+ const first = remaining[0];
168
+ filterValues[filter.field] = remaining.length === 1 && first && 'field' in first
169
+ ? String(first.value) : '';
170
+ }
171
+ pagination = { ...pagination, current: 1 };
172
+ }
173
+ function captureState() {
174
+ return {
175
+ search: appliedSearchText,
176
+ filters: filters.map(cloneListFilter),
177
+ sorters: sorters.map(sorter => ({ ...sorter })),
178
+ pagination: {
179
+ current: pagination.current ?? 1,
180
+ pageSize: pagination.pageSize ?? options.defaultPageSize(),
181
+ },
182
+ };
183
+ }
184
+ function applyState(state) {
185
+ cancelSearch();
186
+ searchText = state.search;
187
+ appliedSearchText = state.search;
188
+ filters = state.filters;
189
+ filterValues = editableValues(state.filters, options.fields());
190
+ pagination = { ...pagination, ...state.pagination };
191
+ sorters = state.sorters;
192
+ }
193
+ function resetToDefaults() {
194
+ cancelSearch();
195
+ searchText = '';
196
+ appliedSearchText = '';
197
+ filters = [];
198
+ filterValues = {};
199
+ if (!options.externalPagination())
200
+ pagination = { current: 1, pageSize: options.defaultPageSize() };
201
+ if (!options.externalSorters()) {
202
+ const defaultSort = options.defaultSort();
203
+ sorters = defaultSort ? [{ ...defaultSort }] : [];
204
+ }
205
+ }
206
+ return {
207
+ get pagination() { return pagination; },
208
+ set pagination(value) { pagination = value; },
209
+ get sorters() { return sorters; },
210
+ set sorters(value) { sorters = value; },
211
+ get searchText() { return searchText; },
212
+ get appliedSearchText() { return appliedSearchText; },
213
+ get filterValues() { return filterValues; },
214
+ get searchableFields() { return searchableFields; },
215
+ get filterableFields() { return filterableFields; },
216
+ get activeFilterCount() { return filters.length; },
217
+ get activeFilterItems() { return activeFilterItems; },
218
+ get activeFilters() { return activeFilters; },
219
+ get queryPagination() { return queryPagination; },
220
+ get querySorters() { return querySorters; },
221
+ get queryFilters() { return queryFilters; },
222
+ scheduleSearch, flushSearch, cancelSearch, clearSearch, clearFilters, setFilterValue, removeActiveFilter,
223
+ captureState, applyState, resetToDefaults,
224
+ };
225
+ }
@@ -0,0 +1,42 @@
1
+ import { SvelteMap } from 'svelte/reactivity';
2
+ import { type ListPreferenceScope, type SavedListView, type SavedListViewAccess, type SavedListViewProvider, type SavedListViewState, type SavedListViewSubject } from './saved-list-views.js';
3
+ interface SavedListViewsOptions {
4
+ scope: () => ListPreferenceScope;
5
+ columns: () => Set<string>;
6
+ provider: () => SavedListViewProvider | undefined;
7
+ isScopeLoaded: () => boolean;
8
+ readPreference: (scope: ListPreferenceScope, key: string, legacyKey: string) => string | null;
9
+ hasExplicitURLState: boolean;
10
+ canApplyRemoteDefault: () => boolean;
11
+ captureState: () => SavedListViewState;
12
+ applyState: (state: SavedListViewState) => void;
13
+ }
14
+ export declare function createSavedListViews(options: SavedListViewsOptions): {
15
+ initialSavedView: SavedListView | undefined;
16
+ readonly availableSavedViews: SavedListView[];
17
+ readonly activeSavedViewId: string | undefined;
18
+ readonly activeSavedViewName: string | undefined;
19
+ savedViewName: string;
20
+ savedViewsOpen: boolean;
21
+ savedViewSource: "local" | "team" | "system";
22
+ readonly remoteViewsLoading: boolean;
23
+ readonly remoteViewsFailed: boolean;
24
+ readonly savedViewMutationPending: boolean;
25
+ readonly savedViewMutationError: "failure" | "conflict" | undefined;
26
+ accessDrafts: SvelteMap<string, SavedListViewAccess>;
27
+ accessSubjects: SvelteMap<string, SavedListViewSubject[]>;
28
+ accessSubjectsLoading: SvelteMap<string, boolean>;
29
+ accessSubjectsFailed: SvelteMap<string, boolean>;
30
+ accessSubjectQueries: SvelteMap<string, string>;
31
+ restoreScope: (scope: ListPreferenceScope) => SavedListView | undefined;
32
+ markSavedViewDirty: () => void;
33
+ clearActiveSavedView: () => void;
34
+ applySavedView: (view: SavedListView) => void;
35
+ saveCurrentView: () => void;
36
+ deleteSavedView: (id: string) => void;
37
+ setRemoteDefault: (view: SavedListView) => void;
38
+ saveRemoteAccess: (view: SavedListView) => void;
39
+ loadAccessSubjects: (view: SavedListView, query?: string) => void;
40
+ reload(): void;
41
+ };
42
+ export {};