@svadmin/ui 0.34.7 → 0.34.9
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/components/AutoTable.svelte +117 -40
- package/package.json +2 -2
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
type ColumnVisibilityState,
|
|
11
11
|
type ExpandedState,
|
|
12
12
|
} from '@tanstack/svelte-table';
|
|
13
|
+
import type { Updater } from '@tanstack/table-core';
|
|
13
14
|
import {
|
|
14
15
|
column_getCanSort,
|
|
15
16
|
column_getIsSorted,
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
row_getIsExpanded,
|
|
29
30
|
row_toggleExpanded,
|
|
30
31
|
cell_getValue,
|
|
31
|
-
} from '@tanstack/
|
|
32
|
+
} from '@tanstack/table-core/static-functions';
|
|
32
33
|
|
|
33
34
|
import { useList, useDelete, useDeleteMany, getResource, notify } from '@svadmin/core';
|
|
34
35
|
import type { Pagination as PaginationState, Sort, Filter, FieldDefinition } from '@svadmin/core';
|
|
@@ -107,7 +108,7 @@
|
|
|
107
108
|
const initPageSize = untrack(() => resource.pageSize ?? (isNaN(storedPageSize) ? 10 : storedPageSize));
|
|
108
109
|
const initDefaultSort = untrack(() => resource.defaultSort);
|
|
109
110
|
|
|
110
|
-
let pagination = $state<
|
|
111
|
+
let pagination = $state<PaginationState>(untrack(() => externalPagination ?? {
|
|
111
112
|
current: urlState.page ?? 1,
|
|
112
113
|
pageSize: urlState.pageSize ?? initPageSize,
|
|
113
114
|
}));
|
|
@@ -173,6 +174,41 @@
|
|
|
173
174
|
return result;
|
|
174
175
|
});
|
|
175
176
|
|
|
177
|
+
function clonePlainValue(value: unknown): unknown {
|
|
178
|
+
if (Array.isArray(value)) return value.map(clonePlainValue);
|
|
179
|
+
if (value && typeof value === 'object') {
|
|
180
|
+
return Object.fromEntries(
|
|
181
|
+
Object.entries(value as Record<string, unknown>).map(([key, entry]) => [key, clonePlainValue(entry)])
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return value;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function cloneFilter(filter: Filter): Filter {
|
|
188
|
+
if ('field' in filter) {
|
|
189
|
+
return {
|
|
190
|
+
field: filter.field,
|
|
191
|
+
operator: filter.operator,
|
|
192
|
+
value: clonePlainValue(filter.value),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
operator: filter.operator,
|
|
197
|
+
value: filter.value.map(cloneFilter),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const queryPagination = $derived<PaginationState>({
|
|
202
|
+
current: pagination.current,
|
|
203
|
+
pageSize: pagination.pageSize,
|
|
204
|
+
mode: pagination.mode,
|
|
205
|
+
});
|
|
206
|
+
const querySorters = $derived<Sort[]>(sorters.map(sorter => ({
|
|
207
|
+
field: sorter.field,
|
|
208
|
+
order: sorter.order,
|
|
209
|
+
})));
|
|
210
|
+
const queryFilters = $derived<Filter[]>(activeFilters.map(cloneFilter));
|
|
211
|
+
|
|
176
212
|
$effect(() => {
|
|
177
213
|
if (Object.values(filterValues).some(v => v.trim())) {
|
|
178
214
|
pagination = { ...pagination, current: 1 };
|
|
@@ -182,9 +218,9 @@
|
|
|
182
218
|
// ─── Data fetching ────────────────────────────────────────────
|
|
183
219
|
const listResult = useList({
|
|
184
220
|
get resource() { return resourceName; },
|
|
185
|
-
get pagination() { return
|
|
186
|
-
get sorters() { return
|
|
187
|
-
get filters() { return
|
|
221
|
+
get pagination() { return queryPagination; },
|
|
222
|
+
get sorters() { return querySorters; },
|
|
223
|
+
get filters() { return queryFilters; },
|
|
188
224
|
});
|
|
189
225
|
const query = listResult;
|
|
190
226
|
const deleteResult = useDelete({ get resource() { return resourceName; } });
|
|
@@ -227,6 +263,68 @@
|
|
|
227
263
|
let expanded = $state.raw<ExpandedState>({});
|
|
228
264
|
let columnOrder = $state<string[]>([]);
|
|
229
265
|
|
|
266
|
+
function applyTableUpdater<T>(current: T, updater: Updater<T>): T {
|
|
267
|
+
return typeof updater === 'function' ? (updater as (old: T) => T)(current) : updater;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const tableSorting = $derived<SortingState>(sorting.map(sorter => ({
|
|
271
|
+
id: sorter.id,
|
|
272
|
+
desc: sorter.desc,
|
|
273
|
+
})));
|
|
274
|
+
const tableColumnVisibility = $derived<ColumnVisibilityState>({ ...columnVisibility });
|
|
275
|
+
const tableRowSelection = $derived<RowSelectionState>({ ...rowSelection });
|
|
276
|
+
const tableExpanded = $derived<ExpandedState>(expanded === true ? true : { ...expanded });
|
|
277
|
+
const tableColumnOrder = $derived<string[]>([...columnOrder]);
|
|
278
|
+
|
|
279
|
+
const sortingAtom = {
|
|
280
|
+
get: () => tableSorting,
|
|
281
|
+
set: (updater: Updater<SortingState>) => {
|
|
282
|
+
const nextSorting = applyTableUpdater(tableSorting, updater);
|
|
283
|
+
sorting = nextSorting;
|
|
284
|
+
|
|
285
|
+
const nextSorters: Sort[] = nextSorting.map((s) => ({
|
|
286
|
+
field: s.id,
|
|
287
|
+
order: s.desc ? 'desc' as const : 'asc' as const,
|
|
288
|
+
}));
|
|
289
|
+
|
|
290
|
+
if (JSON.stringify(nextSorters) !== JSON.stringify(sorters)) {
|
|
291
|
+
sorters = nextSorters;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if ((pagination.current ?? 1) !== 1) {
|
|
295
|
+
pagination = { ...pagination, current: 1 };
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const columnVisibilityAtom = {
|
|
301
|
+
get: () => tableColumnVisibility,
|
|
302
|
+
set: (updater: Updater<ColumnVisibilityState>) => {
|
|
303
|
+
columnVisibility = applyTableUpdater(tableColumnVisibility, updater);
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const rowSelectionAtom = {
|
|
308
|
+
get: () => tableRowSelection,
|
|
309
|
+
set: (updater: Updater<RowSelectionState>) => {
|
|
310
|
+
rowSelection = applyTableUpdater(tableRowSelection, updater);
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const expandedAtom = {
|
|
315
|
+
get: () => tableExpanded,
|
|
316
|
+
set: (updater: Updater<ExpandedState>) => {
|
|
317
|
+
expanded = applyTableUpdater(tableExpanded, updater);
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const columnOrderAtom = {
|
|
322
|
+
get: () => tableColumnOrder,
|
|
323
|
+
set: (updater: Updater<string[]>) => {
|
|
324
|
+
columnOrder = applyTableUpdater(tableColumnOrder, updater);
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
|
|
230
328
|
// Persist column visibility to localStorage
|
|
231
329
|
$effect(() => {
|
|
232
330
|
const storageKey = `svadmin-columns-${resourceName}`;
|
|
@@ -237,25 +335,19 @@
|
|
|
237
335
|
}
|
|
238
336
|
});
|
|
239
337
|
|
|
240
|
-
// Sync
|
|
338
|
+
// Sync external sorters ? local sorting state (controlled mode only)
|
|
241
339
|
$effect(() => {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}));
|
|
246
|
-
if (JSON.stringify(newSorters) !== JSON.stringify(sorters)) {
|
|
247
|
-
sorters = newSorters;
|
|
340
|
+
if (!externalSorters) return;
|
|
341
|
+
if (JSON.stringify(externalSorters) !== JSON.stringify(sorters)) {
|
|
342
|
+
sorters = externalSorters;
|
|
248
343
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
$effect(() => {
|
|
253
|
-
const newSorting = sorters.map(s => ({ id: s.field, desc: s.order === 'desc' }));
|
|
254
|
-
if (JSON.stringify(newSorting) !== JSON.stringify(sorting)) {
|
|
255
|
-
sorting = newSorting;
|
|
344
|
+
const nextSorting = externalSorters.map(s => ({ id: s.field, desc: s.order === 'desc' }));
|
|
345
|
+
if (JSON.stringify(nextSorting) !== JSON.stringify(sorting)) {
|
|
346
|
+
sorting = nextSorting;
|
|
256
347
|
}
|
|
257
348
|
});
|
|
258
349
|
|
|
350
|
+
|
|
259
351
|
// ─── Auto-generate columns from resource fields ──────────────
|
|
260
352
|
const visibleFields = $derived(
|
|
261
353
|
resource.fields.filter(f => f.showInList !== false)
|
|
@@ -303,27 +395,12 @@
|
|
|
303
395
|
manualPagination: true,
|
|
304
396
|
manualSorting: true,
|
|
305
397
|
getRowId: (row: any) => String(row[primaryKey]),
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
},
|
|
313
|
-
onSortingChange: (updater: any) => {
|
|
314
|
-
sorting = typeof updater === 'function' ? updater(sorting) : updater;
|
|
315
|
-
},
|
|
316
|
-
onColumnVisibilityChange: (updater: any) => {
|
|
317
|
-
columnVisibility = typeof updater === 'function' ? updater(columnVisibility) : updater;
|
|
318
|
-
},
|
|
319
|
-
onRowSelectionChange: (updater: any) => {
|
|
320
|
-
rowSelection = typeof updater === 'function' ? updater(rowSelection) : updater;
|
|
321
|
-
},
|
|
322
|
-
onExpandedChange: (updater: any) => {
|
|
323
|
-
expanded = typeof updater === 'function' ? updater(expanded) : updater;
|
|
324
|
-
},
|
|
325
|
-
onColumnOrderChange: (updater: any) => {
|
|
326
|
-
columnOrder = typeof updater === 'function' ? updater(columnOrder) : updater;
|
|
398
|
+
atoms: {
|
|
399
|
+
sorting: sortingAtom,
|
|
400
|
+
columnVisibility: columnVisibilityAtom,
|
|
401
|
+
rowSelection: rowSelectionAtom,
|
|
402
|
+
expanded: expandedAtom,
|
|
403
|
+
columnOrder: columnOrderAtom,
|
|
327
404
|
},
|
|
328
405
|
get enableRowSelection() { return selectable && (canDelete || batchActions); },
|
|
329
406
|
get enableExpanding() { return !!expandedRowRender; },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svadmin/ui",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.9",
|
|
4
4
|
"description": "Pre-built admin UI components — AdminApp, AutoTable, AutoForm, Sidebar, Layout",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"./components/*": "./dist/components/*"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@svadmin/core": "^0.25.
|
|
36
|
+
"@svadmin/core": "^0.25.5",
|
|
37
37
|
"@tanstack/svelte-query": "^6.1.29",
|
|
38
38
|
"highlight.js": "^11.11.1",
|
|
39
39
|
"isomorphic-dompurify": "^3.7.1",
|