@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.
- package/dist/app.css +187 -1
- package/dist/app.theme.css +187 -1
- package/dist/components/AutoTable.svelte +183 -962
- package/dist/components/content/AuditContent.svelte +33 -0
- package/dist/components/content/AuditContent.svelte.d.ts +11 -0
- package/dist/components/content/AuditSection.svelte +46 -0
- package/dist/components/content/AuditSection.svelte.d.ts +18 -0
- package/dist/components/content/ChartContainer.svelte +32 -0
- package/dist/components/content/ChartContainer.svelte.d.ts +15 -0
- package/dist/components/content/CoverageMatrix.svelte +49 -0
- package/dist/components/content/CoverageMatrix.svelte.d.ts +25 -0
- package/dist/components/content/EvidenceCard.svelte +35 -0
- package/dist/components/content/EvidenceCard.svelte.d.ts +14 -0
- package/dist/components/content/FilterToolbar.svelte +24 -4
- package/dist/components/content/FilterToolbar.svelte.d.ts +1 -1
- package/dist/components/content/StatusPill.svelte +16 -0
- package/dist/components/content/StatusPill.svelte.d.ts +9 -0
- package/dist/components/content/audit-state.d.ts +1 -0
- package/dist/components/content/audit-state.js +1 -0
- package/dist/components/content/index.d.ts +9 -0
- package/dist/components/content/index.js +5 -0
- package/dist/components/list-column-preferences.svelte.d.ts +29 -0
- package/dist/components/list-column-preferences.svelte.js +92 -0
- package/dist/components/list-deletion.svelte.d.ts +38 -0
- package/dist/components/list-deletion.svelte.js +111 -0
- package/dist/components/list-selection.svelte.d.ts +31 -0
- package/dist/components/list-selection.svelte.js +100 -0
- package/dist/components/list-state.svelte.d.ts +49 -0
- package/dist/components/list-state.svelte.js +225 -0
- package/dist/components/saved-list-views.svelte.d.ts +42 -0
- package/dist/components/saved-list-views.svelte.js +405 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { untrack } from 'svelte';
|
|
2
|
+
import { SvelteMap } from 'svelte/reactivity';
|
|
3
|
+
import { activeSavedListViewStorageKey, cloneSavedListViewState, decodeRemoteSavedListViews, decodeSavedListViewAccess, decodeSavedListViewMutationResult, decodeSavedListViewRemoveResult, decodeSavedListViewSubjects, legacyActiveSavedListViewStorageKey, legacySavedListViewsStorageKey, listPreferenceScopeId, readSavedListViews, savedListViewsStorageKey, serializeSavedListViews, } from './saved-list-views.js';
|
|
4
|
+
export function createSavedListViews(options) {
|
|
5
|
+
const listPreferenceScope = $derived(options.scope());
|
|
6
|
+
const savedViewColumnIds = $derived(options.columns());
|
|
7
|
+
const savedViewProvider = $derived(options.provider());
|
|
8
|
+
const preferenceScopeIsLoaded = options.isScopeLoaded;
|
|
9
|
+
const hasExplicitURLState = options.hasExplicitURLState;
|
|
10
|
+
function readPreferences(scope) {
|
|
11
|
+
const savedViews = readSavedListViews(options.readPreference(scope, savedListViewsStorageKey(scope), legacySavedListViewsStorageKey(scope.resourceName)), savedViewColumnIds);
|
|
12
|
+
const candidate = options.readPreference(scope, activeSavedListViewStorageKey(scope), legacyActiveSavedListViewStorageKey(scope.resourceName));
|
|
13
|
+
const activeSavedView = savedViews.find(view => view.id === candidate);
|
|
14
|
+
return { savedViews, activeSavedView };
|
|
15
|
+
}
|
|
16
|
+
const initial = untrack(() => readPreferences(listPreferenceScope));
|
|
17
|
+
const initialSavedView = hasExplicitURLState ? undefined : initial.activeSavedView;
|
|
18
|
+
let savedViews = $state(initial.savedViews);
|
|
19
|
+
let activeSavedViewId = $state(initialSavedView?.id);
|
|
20
|
+
let savedViewName = $state('');
|
|
21
|
+
let savedViewsOpen = $state(false);
|
|
22
|
+
let savedViewSource = $state('local');
|
|
23
|
+
let remoteSavedViews = $state([]);
|
|
24
|
+
let remoteViewsLoading = $state(false);
|
|
25
|
+
let remoteViewsFailed = $state(false);
|
|
26
|
+
let remoteViewsReload = $state(0);
|
|
27
|
+
let remoteDefaultEligible = true;
|
|
28
|
+
let savedViewMutationPending = $state(false);
|
|
29
|
+
let savedViewMutationError = $state();
|
|
30
|
+
let savedViewMutationEpoch = 0;
|
|
31
|
+
let remoteViewEpoch = 0;
|
|
32
|
+
const accessDrafts = new SvelteMap();
|
|
33
|
+
const accessSubjects = new SvelteMap();
|
|
34
|
+
const accessSubjectsLoading = new SvelteMap();
|
|
35
|
+
const accessSubjectsFailed = new SvelteMap();
|
|
36
|
+
const accessSubjectQueries = new SvelteMap();
|
|
37
|
+
const accessSubjectRequests = new Map();
|
|
38
|
+
const availableSavedViews = $derived.by(() => {
|
|
39
|
+
const ids = new Set();
|
|
40
|
+
return [...remoteSavedViews, ...savedViews].filter(view => {
|
|
41
|
+
if (ids.has(view.id))
|
|
42
|
+
return false;
|
|
43
|
+
ids.add(view.id);
|
|
44
|
+
return true;
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
const activeSavedViewName = $derived(availableSavedViews.find(view => view.id === activeSavedViewId)?.name);
|
|
48
|
+
function persistSavedViews() {
|
|
49
|
+
if (typeof window === 'undefined' || !preferenceScopeIsLoaded())
|
|
50
|
+
return;
|
|
51
|
+
try {
|
|
52
|
+
localStorage.setItem(savedListViewsStorageKey(listPreferenceScope), serializeSavedListViews(savedViews));
|
|
53
|
+
}
|
|
54
|
+
catch { /* ignore quota errors */ }
|
|
55
|
+
}
|
|
56
|
+
function persistActiveSavedView() {
|
|
57
|
+
if (typeof window === 'undefined' || !preferenceScopeIsLoaded())
|
|
58
|
+
return;
|
|
59
|
+
try {
|
|
60
|
+
const key = activeSavedListViewStorageKey(listPreferenceScope);
|
|
61
|
+
if (activeSavedViewId)
|
|
62
|
+
localStorage.setItem(key, activeSavedViewId);
|
|
63
|
+
else
|
|
64
|
+
localStorage.removeItem(key);
|
|
65
|
+
}
|
|
66
|
+
catch { /* ignore quota errors */ }
|
|
67
|
+
}
|
|
68
|
+
function markSavedViewDirty() {
|
|
69
|
+
remoteDefaultEligible = false;
|
|
70
|
+
if (!activeSavedViewId)
|
|
71
|
+
return;
|
|
72
|
+
clearActiveSavedView();
|
|
73
|
+
}
|
|
74
|
+
function clearActiveSavedView() {
|
|
75
|
+
remoteDefaultEligible = false;
|
|
76
|
+
activeSavedViewId = undefined;
|
|
77
|
+
persistActiveSavedView();
|
|
78
|
+
}
|
|
79
|
+
function applySavedView(view) {
|
|
80
|
+
remoteDefaultEligible = false;
|
|
81
|
+
const state = cloneSavedListViewState(view.state);
|
|
82
|
+
activeSavedViewId = view.id;
|
|
83
|
+
persistActiveSavedView();
|
|
84
|
+
options.applyState(state);
|
|
85
|
+
}
|
|
86
|
+
// 表格完成列偏好和查询恢复后才打开持久化门,避免把旧租户状态写入新作用域。
|
|
87
|
+
function restoreScope(scope) {
|
|
88
|
+
remoteDefaultEligible = true;
|
|
89
|
+
const preferences = readPreferences(scope);
|
|
90
|
+
savedViewName = '';
|
|
91
|
+
savedViewsOpen = false;
|
|
92
|
+
savedViews = preferences.savedViews;
|
|
93
|
+
remoteSavedViews = [];
|
|
94
|
+
activeSavedViewId = preferences.activeSavedView?.id;
|
|
95
|
+
return preferences.activeSavedView;
|
|
96
|
+
}
|
|
97
|
+
$effect(() => {
|
|
98
|
+
const provider = savedViewProvider;
|
|
99
|
+
const scope = listPreferenceScope;
|
|
100
|
+
const columns = savedViewColumnIds;
|
|
101
|
+
void remoteViewsReload;
|
|
102
|
+
remoteSavedViews = [];
|
|
103
|
+
remoteViewsLoading = false;
|
|
104
|
+
remoteViewsFailed = false;
|
|
105
|
+
accessDrafts.clear();
|
|
106
|
+
accessSubjects.clear();
|
|
107
|
+
accessSubjectsLoading.clear();
|
|
108
|
+
accessSubjectsFailed.clear();
|
|
109
|
+
accessSubjectQueries.clear();
|
|
110
|
+
accessSubjectRequests.clear();
|
|
111
|
+
savedViewMutationEpoch += 1;
|
|
112
|
+
savedViewMutationPending = false;
|
|
113
|
+
savedViewMutationError = undefined;
|
|
114
|
+
savedViewSource = 'local';
|
|
115
|
+
if (!provider || !preferenceScopeIsLoaded())
|
|
116
|
+
return;
|
|
117
|
+
const epoch = ++remoteViewEpoch;
|
|
118
|
+
remoteViewsLoading = true;
|
|
119
|
+
void Promise.resolve().then(() => provider.list({ ...scope })).then(value => {
|
|
120
|
+
if (epoch !== remoteViewEpoch || !preferenceScopeIsLoaded())
|
|
121
|
+
return;
|
|
122
|
+
remoteSavedViews = decodeRemoteSavedListViews(value, columns, !!(provider.save || provider.remove || provider.setDefault || provider.updateAccess));
|
|
123
|
+
if (options.canApplyRemoteDefault() && remoteDefaultEligible) {
|
|
124
|
+
const defaults = remoteSavedViews.filter(view => view.default === true);
|
|
125
|
+
if (!hasExplicitURLState && !activeSavedViewId && defaults.length === 1 && defaults[0]) {
|
|
126
|
+
applySavedView(defaults[0]);
|
|
127
|
+
remoteDefaultEligible = false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}).catch(() => {
|
|
131
|
+
if (epoch === remoteViewEpoch) {
|
|
132
|
+
remoteSavedViews = [];
|
|
133
|
+
remoteViewsFailed = true;
|
|
134
|
+
}
|
|
135
|
+
}).finally(() => {
|
|
136
|
+
if (epoch === remoteViewEpoch)
|
|
137
|
+
remoteViewsLoading = false;
|
|
138
|
+
});
|
|
139
|
+
return () => {
|
|
140
|
+
remoteViewEpoch += 1;
|
|
141
|
+
savedViewMutationEpoch += 1;
|
|
142
|
+
accessSubjectRequests.clear();
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
function saveCurrentView() {
|
|
146
|
+
if (!preferenceScopeIsLoaded() || savedViewMutationPending)
|
|
147
|
+
return;
|
|
148
|
+
remoteDefaultEligible = false;
|
|
149
|
+
const name = savedViewName.trim().slice(0, 60);
|
|
150
|
+
if (!name)
|
|
151
|
+
return;
|
|
152
|
+
const state = options.captureState();
|
|
153
|
+
if (savedViewSource !== 'local') {
|
|
154
|
+
const existing = remoteSavedViews.find(view => view.source === savedViewSource
|
|
155
|
+
&& view.name.toLocaleLowerCase() === name.toLocaleLowerCase());
|
|
156
|
+
if (!savedViewProvider?.save || (existing && (existing.readOnly || !existing.version)))
|
|
157
|
+
return;
|
|
158
|
+
void mutateRemoteView({
|
|
159
|
+
id: existing?.id ?? crypto.randomUUID(), name, state,
|
|
160
|
+
source: savedViewSource, expectedVersion: existing?.version ?? null,
|
|
161
|
+
});
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const existing = savedViews.find(view => view.name.toLocaleLowerCase() === name.toLocaleLowerCase());
|
|
165
|
+
const view = {
|
|
166
|
+
id: existing?.id ?? `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
167
|
+
name, state,
|
|
168
|
+
};
|
|
169
|
+
savedViews = existing
|
|
170
|
+
? savedViews.map(candidate => candidate.id === existing.id ? view : candidate)
|
|
171
|
+
: [view, ...savedViews].slice(0, 25);
|
|
172
|
+
activeSavedViewId = view.id;
|
|
173
|
+
savedViewName = '';
|
|
174
|
+
persistSavedViews();
|
|
175
|
+
persistActiveSavedView();
|
|
176
|
+
}
|
|
177
|
+
function deleteSavedView(id) {
|
|
178
|
+
if (!preferenceScopeIsLoaded() || savedViewMutationPending)
|
|
179
|
+
return;
|
|
180
|
+
const remote = remoteSavedViews.find(view => view.id === id);
|
|
181
|
+
if (remote) {
|
|
182
|
+
if (!savedViewProvider?.remove || remote.readOnly || !remote.version)
|
|
183
|
+
return;
|
|
184
|
+
void mutateRemoteView({
|
|
185
|
+
id, expectedVersion: remote.version, source: remote.source === 'system' ? 'system' : 'team',
|
|
186
|
+
name: remote.name, state: remote.state,
|
|
187
|
+
}, true);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
savedViews = savedViews.filter(view => view.id !== id);
|
|
191
|
+
if (activeSavedViewId === id)
|
|
192
|
+
activeSavedViewId = undefined;
|
|
193
|
+
persistSavedViews();
|
|
194
|
+
persistActiveSavedView();
|
|
195
|
+
}
|
|
196
|
+
async function mutateRemoteView(mutation, remove = false) {
|
|
197
|
+
const provider = savedViewProvider;
|
|
198
|
+
if (!provider || savedViewMutationPending || !preferenceScopeIsLoaded()
|
|
199
|
+
|| (remove && (mutation.expectedVersion === null || !provider.remove))
|
|
200
|
+
|| (!remove && !provider.save))
|
|
201
|
+
return;
|
|
202
|
+
const scope = { ...listPreferenceScope };
|
|
203
|
+
const scopeId = listPreferenceScopeId(scope);
|
|
204
|
+
const columns = savedViewColumnIds;
|
|
205
|
+
const epoch = ++savedViewMutationEpoch;
|
|
206
|
+
const current = () => epoch === savedViewMutationEpoch && provider === savedViewProvider
|
|
207
|
+
&& scopeId === listPreferenceScopeId(listPreferenceScope) && preferenceScopeIsLoaded();
|
|
208
|
+
savedViewMutationPending = true;
|
|
209
|
+
savedViewMutationError = undefined;
|
|
210
|
+
try {
|
|
211
|
+
const result = remove
|
|
212
|
+
? await provider.remove?.(scope, { id: mutation.id, expectedVersion: mutation.expectedVersion ?? 0 })
|
|
213
|
+
: await provider.save?.(scope, { ...mutation, state: cloneSavedListViewState(mutation.state) });
|
|
214
|
+
if (!current())
|
|
215
|
+
return;
|
|
216
|
+
if (remove && mutation.expectedVersion !== null && decodeSavedListViewRemoveResult(result, {
|
|
217
|
+
id: mutation.id, expectedVersion: mutation.expectedVersion,
|
|
218
|
+
})) {
|
|
219
|
+
remoteSavedViews = remoteSavedViews.filter(view => view.id !== mutation.id);
|
|
220
|
+
if (activeSavedViewId === mutation.id)
|
|
221
|
+
activeSavedViewId = undefined;
|
|
222
|
+
persistActiveSavedView();
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const decoded = decodeSavedListViewMutationResult(result, columns, mutation);
|
|
226
|
+
if (!decoded || (remove && decoded.ok)) {
|
|
227
|
+
savedViewMutationError = 'failure';
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (!decoded.ok) {
|
|
231
|
+
savedViewMutationError = 'conflict';
|
|
232
|
+
// 保留本地查询;用户必须重新读取后再决定如何修改。
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const view = { ...decoded.view, readOnly: decoded.view.readOnly !== false };
|
|
236
|
+
remoteSavedViews = [view, ...remoteSavedViews.filter(candidate => candidate.id !== view.id)];
|
|
237
|
+
savedViewName = '';
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
if (current())
|
|
241
|
+
savedViewMutationError = 'failure';
|
|
242
|
+
}
|
|
243
|
+
finally {
|
|
244
|
+
if (current())
|
|
245
|
+
savedViewMutationPending = false;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function setRemoteDefault(view) {
|
|
249
|
+
const provider = savedViewProvider;
|
|
250
|
+
if (!provider?.setDefault || savedViewMutationPending || view.readOnly || !view.version
|
|
251
|
+
|| savedViewMutationError === 'conflict' || !preferenceScopeIsLoaded()
|
|
252
|
+
|| (view.source !== 'team' && view.source !== 'system'))
|
|
253
|
+
return;
|
|
254
|
+
const source = view.source;
|
|
255
|
+
const expectedVersion = view.version;
|
|
256
|
+
const defaultValue = view.default !== true;
|
|
257
|
+
remoteDefaultEligible = false;
|
|
258
|
+
const scope = { ...listPreferenceScope };
|
|
259
|
+
const scopeId = listPreferenceScopeId(scope);
|
|
260
|
+
const epoch = ++savedViewMutationEpoch;
|
|
261
|
+
const current = () => epoch === savedViewMutationEpoch && provider === savedViewProvider
|
|
262
|
+
&& scopeId === listPreferenceScopeId(listPreferenceScope) && preferenceScopeIsLoaded();
|
|
263
|
+
savedViewMutationPending = true;
|
|
264
|
+
savedViewMutationError = undefined;
|
|
265
|
+
void Promise.resolve().then(() => provider.setDefault?.(scope, {
|
|
266
|
+
id: view.id, source, expectedVersion, default: defaultValue,
|
|
267
|
+
})).then(result => {
|
|
268
|
+
if (!current())
|
|
269
|
+
return;
|
|
270
|
+
const decoded = decodeSavedListViewMutationResult(result, savedViewColumnIds, {
|
|
271
|
+
id: view.id, source, expectedVersion,
|
|
272
|
+
});
|
|
273
|
+
if (!decoded) {
|
|
274
|
+
savedViewMutationError = 'failure';
|
|
275
|
+
}
|
|
276
|
+
else if (!decoded.ok) {
|
|
277
|
+
savedViewMutationError = 'conflict';
|
|
278
|
+
}
|
|
279
|
+
else if (decoded.view.default !== defaultValue) {
|
|
280
|
+
savedViewMutationError = 'failure';
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
// 默认标记会同时改变同一作用域的其他视图,成功后重新读取完整集合。
|
|
284
|
+
remoteViewsReload += 1;
|
|
285
|
+
}
|
|
286
|
+
}).catch(() => {
|
|
287
|
+
if (current())
|
|
288
|
+
savedViewMutationError = 'failure';
|
|
289
|
+
}).finally(() => {
|
|
290
|
+
if (current())
|
|
291
|
+
savedViewMutationPending = false;
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
function saveRemoteAccess(view) {
|
|
295
|
+
const provider = savedViewProvider;
|
|
296
|
+
const draft = accessDrafts.get(view.id);
|
|
297
|
+
if (!provider?.updateAccess || !draft || view.readOnly !== false || !view.version
|
|
298
|
+
|| savedViewMutationPending || savedViewMutationError === 'conflict' || !preferenceScopeIsLoaded()
|
|
299
|
+
|| (view.source !== 'team' && view.source !== 'system'))
|
|
300
|
+
return;
|
|
301
|
+
const access = decodeSavedListViewAccess({
|
|
302
|
+
mode: draft.mode,
|
|
303
|
+
subjectIds: draft.mode === 'restricted' ? draft.subjectIds : [],
|
|
304
|
+
});
|
|
305
|
+
if (!access) {
|
|
306
|
+
savedViewMutationError = 'failure';
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const source = view.source;
|
|
310
|
+
const expectedVersion = view.version;
|
|
311
|
+
const scope = { ...listPreferenceScope };
|
|
312
|
+
const scopeId = listPreferenceScopeId(scope);
|
|
313
|
+
const epoch = ++savedViewMutationEpoch;
|
|
314
|
+
const current = () => epoch === savedViewMutationEpoch && provider === savedViewProvider
|
|
315
|
+
&& scopeId === listPreferenceScopeId(listPreferenceScope) && preferenceScopeIsLoaded();
|
|
316
|
+
remoteDefaultEligible = false;
|
|
317
|
+
savedViewMutationPending = true;
|
|
318
|
+
savedViewMutationError = undefined;
|
|
319
|
+
void Promise.resolve().then(() => {
|
|
320
|
+
if (!current())
|
|
321
|
+
return;
|
|
322
|
+
return provider.updateAccess?.(scope, {
|
|
323
|
+
id: view.id, source, expectedVersion, access: { ...access, subjectIds: [...access.subjectIds] },
|
|
324
|
+
});
|
|
325
|
+
}).then(result => {
|
|
326
|
+
if (!current())
|
|
327
|
+
return;
|
|
328
|
+
const decoded = decodeSavedListViewMutationResult(result, savedViewColumnIds, {
|
|
329
|
+
id: view.id, source, expectedVersion,
|
|
330
|
+
});
|
|
331
|
+
if (!decoded)
|
|
332
|
+
savedViewMutationError = 'failure';
|
|
333
|
+
else if (!decoded.ok)
|
|
334
|
+
savedViewMutationError = 'conflict';
|
|
335
|
+
else if (decoded.view.access?.mode !== access.mode
|
|
336
|
+
|| decoded.view.access.subjectIds.length !== access.subjectIds.length
|
|
337
|
+
|| !decoded.view.access.subjectIds.every(id => access.subjectIds.includes(id))) {
|
|
338
|
+
savedViewMutationError = 'failure';
|
|
339
|
+
}
|
|
340
|
+
else
|
|
341
|
+
remoteViewsReload += 1;
|
|
342
|
+
}).catch(() => {
|
|
343
|
+
if (current())
|
|
344
|
+
savedViewMutationError = 'failure';
|
|
345
|
+
}).finally(() => {
|
|
346
|
+
if (current())
|
|
347
|
+
savedViewMutationPending = false;
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
function loadAccessSubjects(view, query = '') {
|
|
351
|
+
const provider = savedViewProvider;
|
|
352
|
+
if (!provider?.listAccessSubjects || view.readOnly !== false
|
|
353
|
+
|| view.source === 'local' || !preferenceScopeIsLoaded())
|
|
354
|
+
return;
|
|
355
|
+
const scope = { ...listPreferenceScope };
|
|
356
|
+
const scopeId = listPreferenceScopeId(scope);
|
|
357
|
+
const request = {};
|
|
358
|
+
accessSubjectRequests.set(view.id, request);
|
|
359
|
+
const current = () => accessSubjectRequests.get(view.id) === request
|
|
360
|
+
&& scopeId === listPreferenceScopeId(listPreferenceScope)
|
|
361
|
+
&& provider === savedViewProvider && preferenceScopeIsLoaded();
|
|
362
|
+
accessSubjectsLoading.set(view.id, true);
|
|
363
|
+
accessSubjectsFailed.delete(view.id);
|
|
364
|
+
accessSubjects.delete(view.id);
|
|
365
|
+
void Promise.resolve().then(() => {
|
|
366
|
+
if (current())
|
|
367
|
+
return provider.listAccessSubjects?.(scope, { query: query.trim(), limit: 50 });
|
|
368
|
+
})
|
|
369
|
+
.then(result => {
|
|
370
|
+
if (!current())
|
|
371
|
+
return;
|
|
372
|
+
const subjects = decodeSavedListViewSubjects(result);
|
|
373
|
+
if (!subjects)
|
|
374
|
+
accessSubjectsFailed.set(view.id, true);
|
|
375
|
+
else
|
|
376
|
+
accessSubjects.set(view.id, subjects);
|
|
377
|
+
})
|
|
378
|
+
.catch(() => {
|
|
379
|
+
if (current())
|
|
380
|
+
accessSubjectsFailed.set(view.id, true);
|
|
381
|
+
})
|
|
382
|
+
.finally(() => { if (current())
|
|
383
|
+
accessSubjectsLoading.delete(view.id); });
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
initialSavedView,
|
|
387
|
+
get availableSavedViews() { return availableSavedViews; },
|
|
388
|
+
get activeSavedViewId() { return activeSavedViewId; },
|
|
389
|
+
get activeSavedViewName() { return activeSavedViewName; },
|
|
390
|
+
get savedViewName() { return savedViewName; },
|
|
391
|
+
set savedViewName(value) { savedViewName = value; },
|
|
392
|
+
get savedViewsOpen() { return savedViewsOpen; },
|
|
393
|
+
set savedViewsOpen(value) { savedViewsOpen = value; },
|
|
394
|
+
get savedViewSource() { return savedViewSource; },
|
|
395
|
+
set savedViewSource(value) { savedViewSource = value; },
|
|
396
|
+
get remoteViewsLoading() { return remoteViewsLoading; },
|
|
397
|
+
get remoteViewsFailed() { return remoteViewsFailed; },
|
|
398
|
+
get savedViewMutationPending() { return savedViewMutationPending; },
|
|
399
|
+
get savedViewMutationError() { return savedViewMutationError; },
|
|
400
|
+
accessDrafts, accessSubjects, accessSubjectsLoading, accessSubjectsFailed, accessSubjectQueries,
|
|
401
|
+
restoreScope, markSavedViewDirty, clearActiveSavedView, applySavedView, saveCurrentView, deleteSavedView,
|
|
402
|
+
setRemoteDefault, saveRemoteAccess, loadAccessSubjects,
|
|
403
|
+
reload() { remoteViewsReload += 1; },
|
|
404
|
+
};
|
|
405
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -330,6 +330,15 @@ export type { RowActionItem } from './components/RowActions.svelte';
|
|
|
330
330
|
export { default as DetailDrawer } from './components/DetailDrawer.svelte';
|
|
331
331
|
export { default as AuditTimeline } from './components/content/AuditTimeline.svelte';
|
|
332
332
|
export type { TimelineItem } from './components/content/AuditTimeline.svelte';
|
|
333
|
+
export { default as AuditSection } from './components/content/AuditSection.svelte';
|
|
334
|
+
export type { AuditAccent } from './components/content/AuditSection.svelte';
|
|
335
|
+
export type { AuditDataState } from './components/content/audit-state.js';
|
|
336
|
+
export { default as ChartContainer } from './components/content/ChartContainer.svelte';
|
|
337
|
+
export { default as CoverageMatrix } from './components/content/CoverageMatrix.svelte';
|
|
338
|
+
export type { CoverageMatrixColumn, CoverageMatrixRow } from './components/content/CoverageMatrix.svelte';
|
|
339
|
+
export { default as EvidenceCard } from './components/content/EvidenceCard.svelte';
|
|
340
|
+
export { default as StatusPill } from './components/content/StatusPill.svelte';
|
|
341
|
+
export type { StatusPillTone } from './components/content/StatusPill.svelte';
|
|
333
342
|
export type { TagTone } from './components/fields/TagField.svelte';
|
|
334
343
|
export type { BooleanTone } from './components/fields/BooleanField.svelte';
|
|
335
344
|
export type { DateFieldFormat } from './components/fields/DateField.svelte';
|
package/dist/index.js
CHANGED
|
@@ -279,6 +279,11 @@ export { referenceDemoData } from './reference-data.js';
|
|
|
279
279
|
export { default as RowActions } from './components/RowActions.svelte';
|
|
280
280
|
export { default as DetailDrawer } from './components/DetailDrawer.svelte';
|
|
281
281
|
export { default as AuditTimeline } from './components/content/AuditTimeline.svelte';
|
|
282
|
+
export { default as AuditSection } from './components/content/AuditSection.svelte';
|
|
283
|
+
export { default as ChartContainer } from './components/content/ChartContainer.svelte';
|
|
284
|
+
export { default as CoverageMatrix } from './components/content/CoverageMatrix.svelte';
|
|
285
|
+
export { default as EvidenceCard } from './components/content/EvidenceCard.svelte';
|
|
286
|
+
export { default as StatusPill } from './components/content/StatusPill.svelte';
|
|
282
287
|
export { default as FilterDropdown } from './components/FilterDropdown.svelte';
|
|
283
288
|
export { default as BatchActionBar } from './components/BatchActionBar.svelte';
|
|
284
289
|
export { default as MediaThumbnail } from './components/content/MediaThumbnail.svelte';
|