@svadmin/ui 0.85.0 → 0.86.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/README.md +29 -0
- package/dist/app-shell.css +216 -0
- package/dist/app.css +483 -172
- package/dist/app.theme.css +483 -172
- package/dist/component-registry.d.ts +7292 -529
- package/dist/component-registry.js +32 -3
- package/dist/components/AppShellPage.svelte +172 -0
- package/dist/components/AppShellPage.svelte.d.ts +30 -0
- package/dist/components/AutoForm.svelte +7 -12
- package/dist/components/AutoForm.svelte.d.ts +0 -1
- package/dist/components/AutoTable.svelte +2 -0
- package/dist/components/AutoTable.svelte.d.ts +2 -0
- package/dist/components/ConfigurationPage.svelte +0 -3
- package/dist/components/ConfigurationPage.svelte.d.ts +0 -1
- package/dist/components/CreatePage.svelte +1 -5
- package/dist/components/CreatePage.svelte.d.ts +0 -1
- package/dist/components/EditPage.svelte +1 -5
- package/dist/components/EditPage.svelte.d.ts +0 -1
- package/dist/components/FieldRenderer.svelte +2 -10
- package/dist/components/FieldRenderer.svelte.d.ts +0 -1
- package/dist/components/ListPage.svelte +2 -5
- package/dist/components/ListPage.svelte.d.ts +0 -1
- package/dist/components/PageHeader.svelte +1 -3
- package/dist/components/PageHeader.svelte.d.ts +0 -1
- package/dist/components/PagePattern.svelte +36 -13
- package/dist/components/PagePattern.svelte.d.ts +7 -0
- package/dist/components/QuickEditDrawer.svelte +0 -1
- package/dist/components/ShowPage.svelte +5 -9
- package/dist/components/ShowPage.svelte.d.ts +0 -1
- package/dist/components/SvarAutoTable.svelte +2 -1
- package/dist/components/SvarDataGrid.svelte +8 -4
- package/dist/components/SvarDataGrid.svelte.d.ts +3 -0
- package/dist/components/SvarResourceTable.svelte +0 -1
- package/dist/components/SvarResourceTable.svelte.d.ts +0 -1
- package/dist/components/SvarResourceTableView.svelte +2 -2
- package/dist/components/auto-table-grid.d.ts +1 -0
- package/dist/components/content/ContentPageHeader.svelte +2 -1
- package/dist/components/content/ContentPageHeader.svelte.d.ts +1 -0
- package/dist/components/content/ContentPageShell.svelte +1 -1
- package/dist/components/content/ContentPageShell.svelte.d.ts +1 -0
- package/dist/components/content/DataPanel.svelte +58 -0
- package/dist/components/content/DataPanel.svelte.d.ts +16 -0
- package/dist/components/content/DescriptionList.svelte +5 -8
- package/dist/components/content/DescriptionList.svelte.d.ts +0 -1
- package/dist/components/content/FilterToolbar.svelte +2 -5
- package/dist/components/content/FilterToolbar.svelte.d.ts +0 -1
- package/dist/components/content/NetworkTable.svelte +3 -3
- package/dist/components/content/NetworkTable.svelte.d.ts +0 -1
- package/dist/components/content/PageSection.svelte +1 -1
- package/dist/components/content/StatusTabs.svelte +2 -7
- package/dist/components/content/StatusTabs.svelte.d.ts +0 -1
- package/dist/components/content/index.d.ts +1 -0
- package/dist/components/content/index.js +1 -0
- package/dist/components/ui/table/index.d.ts +0 -1
- package/dist/components/ui/table/table.svelte +1 -0
- package/dist/components/ui/table/table.svelte.d.ts +1 -0
- package/dist/components.css +1 -11
- package/dist/data-panel.css +88 -0
- package/dist/design-contract.d.ts +11 -0
- package/dist/design-contract.js +8 -0
- package/dist/design-system.d.ts +3 -2
- package/dist/design-system.js +3 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -0
- package/dist/page-chrome.css +40 -62
- package/dist/recipes.d.ts +67 -154
- package/dist/recipes.js +32 -68
- package/dist/styles/recipes.css +15 -48
- package/package.json +4 -4
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
import { definedOptions } from '@svadmin/core/options';
|
|
4
4
|
import ContentPageShell from './content/ContentPageShell.svelte';
|
|
5
5
|
import WorkspaceLayout from './content/WorkspaceLayout.svelte';
|
|
6
|
+
import DataState from './content/DataState.svelte';
|
|
6
7
|
|
|
7
8
|
export type PagePatternKind = 'list' | 'form' | 'detail' | 'workspace' | 'dashboard';
|
|
9
|
+
export type PagePatternState = 'ready' | 'loading' | 'empty' | 'error' | 'forbidden';
|
|
8
10
|
|
|
9
11
|
interface Props {
|
|
10
12
|
kind: PagePatternKind;
|
|
@@ -18,8 +20,14 @@
|
|
|
18
20
|
children: Snippet;
|
|
19
21
|
footer?: Snippet;
|
|
20
22
|
width?: 'narrow' | 'default' | 'wide';
|
|
23
|
+
/** @deprecated Accepted for compatibility; the product baseline is shared. */
|
|
21
24
|
density?: 'compact' | 'comfortable';
|
|
22
25
|
pageId?: string;
|
|
26
|
+
state?: PagePatternState;
|
|
27
|
+
stateTitle?: string;
|
|
28
|
+
stateDescription?: string;
|
|
29
|
+
retry?: () => void;
|
|
30
|
+
stateAction?: Snippet;
|
|
23
31
|
class?: string;
|
|
24
32
|
}
|
|
25
33
|
|
|
@@ -35,24 +43,41 @@
|
|
|
35
43
|
children,
|
|
36
44
|
footer,
|
|
37
45
|
width,
|
|
38
|
-
density,
|
|
46
|
+
density = 'comfortable',
|
|
39
47
|
pageId,
|
|
48
|
+
state = 'ready',
|
|
49
|
+
stateTitle,
|
|
50
|
+
stateDescription,
|
|
51
|
+
retry,
|
|
52
|
+
stateAction,
|
|
40
53
|
class: className = '',
|
|
41
54
|
}: Props = $props();
|
|
42
55
|
|
|
43
56
|
const resolvedPageId = $derived(pageId ?? `pattern-${kind}`);
|
|
44
57
|
const resolvedWidth = $derived(width ?? (kind === 'form' ? 'narrow' : kind === 'detail' ? 'default' : 'wide'));
|
|
45
|
-
const
|
|
58
|
+
const showState = $derived(state !== 'ready');
|
|
46
59
|
</script>
|
|
47
60
|
|
|
48
61
|
<ContentPageShell
|
|
49
62
|
{title}
|
|
50
63
|
{...definedOptions({ description, eyebrow, actions })}
|
|
51
|
-
density={resolvedDensity}
|
|
52
64
|
width={resolvedWidth}
|
|
65
|
+
{density}
|
|
53
66
|
pageId={resolvedPageId}
|
|
54
67
|
class={className}
|
|
55
68
|
>
|
|
69
|
+
<div data-page-pattern-kind={kind} data-page-pattern-state={state}>
|
|
70
|
+
{#if showState}
|
|
71
|
+
{#if state === 'loading' || state === 'empty' || state === 'error' || state === 'forbidden'}
|
|
72
|
+
<DataState
|
|
73
|
+
{state}
|
|
74
|
+
{...definedOptions({ title: stateTitle })}
|
|
75
|
+
{...definedOptions({ description: stateDescription })}
|
|
76
|
+
{...definedOptions({ retry: state === 'error' ? retry : undefined })}
|
|
77
|
+
{...definedOptions({ action: stateAction })}
|
|
78
|
+
/>
|
|
79
|
+
{/if}
|
|
80
|
+
{:else}
|
|
56
81
|
{#if metrics}
|
|
57
82
|
<div class="page-pattern__metrics" data-page-pattern-metrics>
|
|
58
83
|
{@render metrics()}
|
|
@@ -68,7 +93,7 @@
|
|
|
68
93
|
{#if secondary}
|
|
69
94
|
<WorkspaceLayout primary={children} {...definedOptions({ secondary })} />
|
|
70
95
|
{:else}
|
|
71
|
-
<div class="page-pattern__content" data-page-pattern-content={kind}
|
|
96
|
+
<div class="page-pattern__content" data-page-pattern-content={kind}>
|
|
72
97
|
{@render children()}
|
|
73
98
|
</div>
|
|
74
99
|
{/if}
|
|
@@ -78,13 +103,15 @@
|
|
|
78
103
|
{@render footer()}
|
|
79
104
|
</footer>
|
|
80
105
|
{/if}
|
|
106
|
+
{/if}
|
|
107
|
+
</div>
|
|
81
108
|
</ContentPageShell>
|
|
82
109
|
|
|
83
110
|
<style>
|
|
84
111
|
.page-pattern__metrics {
|
|
85
112
|
display: grid;
|
|
86
113
|
grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
|
|
87
|
-
gap:
|
|
114
|
+
gap: var(--svadmin-space-4);
|
|
88
115
|
}
|
|
89
116
|
|
|
90
117
|
.page-pattern__toolbar,
|
|
@@ -94,11 +121,7 @@
|
|
|
94
121
|
|
|
95
122
|
.page-pattern__content {
|
|
96
123
|
display: grid;
|
|
97
|
-
gap:
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.page-pattern__content[data-density='compact'] {
|
|
101
|
-
gap: 16px;
|
|
124
|
+
gap: var(--svadmin-space-5);
|
|
102
125
|
}
|
|
103
126
|
|
|
104
127
|
.page-pattern__footer {
|
|
@@ -106,9 +129,9 @@
|
|
|
106
129
|
flex-wrap: wrap;
|
|
107
130
|
align-items: center;
|
|
108
131
|
justify-content: flex-end;
|
|
109
|
-
gap:
|
|
110
|
-
margin-top:
|
|
111
|
-
padding-top:
|
|
132
|
+
gap: var(--svadmin-space-2);
|
|
133
|
+
margin-top: var(--svadmin-space-5);
|
|
134
|
+
padding-top: var(--svadmin-space-3);
|
|
112
135
|
border-top: 1px solid var(--border);
|
|
113
136
|
}
|
|
114
137
|
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
export type PagePatternKind = 'list' | 'form' | 'detail' | 'workspace' | 'dashboard';
|
|
3
|
+
export type PagePatternState = 'ready' | 'loading' | 'empty' | 'error' | 'forbidden';
|
|
3
4
|
interface Props {
|
|
4
5
|
kind: PagePatternKind;
|
|
5
6
|
title: string;
|
|
@@ -12,8 +13,14 @@ interface Props {
|
|
|
12
13
|
children: Snippet;
|
|
13
14
|
footer?: Snippet;
|
|
14
15
|
width?: 'narrow' | 'default' | 'wide';
|
|
16
|
+
/** @deprecated Accepted for compatibility; the product baseline is shared. */
|
|
15
17
|
density?: 'compact' | 'comfortable';
|
|
16
18
|
pageId?: string;
|
|
19
|
+
state?: PagePatternState;
|
|
20
|
+
stateTitle?: string;
|
|
21
|
+
stateDescription?: string;
|
|
22
|
+
retry?: () => void;
|
|
23
|
+
stateAction?: Snippet;
|
|
17
24
|
class?: string;
|
|
18
25
|
}
|
|
19
26
|
declare const PagePattern: import("svelte").Component<Props, {}, "">;
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
resourceName: string;
|
|
21
21
|
rendering?: ResourceRendering | undefined;
|
|
22
22
|
id: string | number;
|
|
23
|
-
density?: 'compact' | 'comfortable';
|
|
24
23
|
layout?: 'list' | 'grid';
|
|
25
24
|
columns?: 1 | 2 | 3 | 4;
|
|
26
25
|
bordered?: boolean;
|
|
@@ -36,7 +35,6 @@
|
|
|
36
35
|
resourceName,
|
|
37
36
|
rendering,
|
|
38
37
|
id,
|
|
39
|
-
density = 'comfortable',
|
|
40
38
|
layout = 'list',
|
|
41
39
|
columns = 2,
|
|
42
40
|
bordered = false,
|
|
@@ -58,7 +56,6 @@
|
|
|
58
56
|
}
|
|
59
57
|
navigation.list(resourceName);
|
|
60
58
|
}
|
|
61
|
-
const isCompact = $derived(density === 'compact');
|
|
62
59
|
|
|
63
60
|
const detail = useRecordDetail(() => ({ resourceName, id, rendering }));
|
|
64
61
|
const activeRendering = $derived(detail.rendering);
|
|
@@ -76,10 +73,9 @@
|
|
|
76
73
|
});
|
|
77
74
|
</script>
|
|
78
75
|
|
|
79
|
-
<div data-svadmin-rendering-resource={activeRendering?.resource.name} data-svadmin-rendering-kind={activeRendering ? 'show' : undefined} class="
|
|
76
|
+
<div data-svadmin-rendering-resource={activeRendering?.resource.name} data-svadmin-rendering-kind={activeRendering ? 'show' : undefined} class="svadmin-u-3e7ce58d64fa {className}">
|
|
80
77
|
<PageHeader
|
|
81
78
|
title="{resource.label} {i18n.t('common.detail')} #{id}"
|
|
82
|
-
{density}
|
|
83
79
|
onBack={goBack}
|
|
84
80
|
backLabel={i18n.t('common.back')}
|
|
85
81
|
>
|
|
@@ -108,7 +104,7 @@
|
|
|
108
104
|
<Card.Root class="svadmin-u-2cd02d11d1af svadmin-u-6ee2d41e2d2d svadmin-u-438b2237b8d6">
|
|
109
105
|
<Card.Content class="svadmin-u-8a539c7fe216">
|
|
110
106
|
{#each showFields.slice(0, 6) as _, i (i)}
|
|
111
|
-
<div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed svadmin-u-020ba687fa12
|
|
107
|
+
<div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed svadmin-u-020ba687fa12 svadmin-u-f0faeb26d656 svadmin-u-7a9aabfcd059 svadmin-u-1b2d54a3fd12 svadmin-u-b7daff9b9ddd {i % 2 === 1 ? 'svadmin-u-967d113a1451' : ''}">
|
|
112
108
|
<Skeleton class="svadmin-u-11e59c6d5f6b svadmin-u-b7ce0d2f6c04 svadmin-u-5a14cc9f9ed4" />
|
|
113
109
|
<Skeleton class="svadmin-u-11e59c6d5f6b svadmin-u-1d9f2d98d149 svadmin-u-d2ffb24f3e1d svadmin-u-b6b02c0ebef6 svadmin-u-dfe9bd9e7001 svadmin-u-77533d414653" />
|
|
114
110
|
</div>
|
|
@@ -153,9 +149,9 @@
|
|
|
153
149
|
<Card.Content class="svadmin-u-8a539c7fe216 svadmin-u-fa6acbf81d74 svadmin-u-3533cbce9e93">
|
|
154
150
|
{#each showFields as field, i (i)}
|
|
155
151
|
{@const value = record[field.key]}
|
|
156
|
-
<div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed svadmin-u-020ba687fa12
|
|
157
|
-
<div class="svadmin-u-b03f3c253900
|
|
158
|
-
<div class="svadmin-u-6b3526212209
|
|
152
|
+
<div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed svadmin-u-020ba687fa12 svadmin-u-f0faeb26d656 svadmin-u-7a9aabfcd059 svadmin-u-1b2d54a3fd12 svadmin-u-4701b613ff95 {i % 2 === 1 ? 'svadmin-u-8a25a995eb8e' : ''}">
|
|
153
|
+
<div class="svadmin-u-b03f3c253900 svadmin-u-359090c2d529 svadmin-u-e2327d142859 svadmin-u-2689f3958069 svadmin-u-bfa603190748 svadmin-u-65281709dacf svadmin-u-84bdd56b0e81">{field.label}</div>
|
|
154
|
+
<div class="svadmin-u-6b3526212209 svadmin-u-fc7473ca09eb svadmin-u-d4108abe6359">
|
|
159
155
|
<FieldDisplay
|
|
160
156
|
type={field.type}
|
|
161
157
|
{value}
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
{#snippet gridBody(state)}
|
|
27
27
|
<details><summary>{state.locale.startsWith('zh') ? '表格选择与列顺序' : 'Selection and column order'}</summary>{@render state.controls()}</details>
|
|
28
28
|
<SvarDataGrid {Grid} {Theme} items={state.records} columns={state.columns} primaryKey={state.primaryKey}
|
|
29
|
+
density={state.density}
|
|
29
30
|
{height} freezeLeft={Math.min(freezeLeft, state.columns.length - Math.min(freezeRight, state.columns.length - 1))}
|
|
30
|
-
freezeRight={Math.min(freezeRight, state.columns.length - 1)}
|
|
31
|
+
freezeRight={Math.min(freezeRight, state.columns.length - 1)}
|
|
31
32
|
queryMode="server" sorters={state.sorters} onSortChange={state.onSortChange}
|
|
32
33
|
disabled={state.disabled} scopeKey={state.scopeKey} locale={state.locale} label={state.label}>
|
|
33
34
|
{#snippet cellContent({ id, field })}{@render state.cell({ id, field })}{/snippet}
|
|
@@ -18,7 +18,10 @@
|
|
|
18
18
|
primaryKey?: string;
|
|
19
19
|
childrenKey?: string;
|
|
20
20
|
height?: number;
|
|
21
|
+
/** @deprecated Retained for compatibility; comfortable is the shared default. */
|
|
21
22
|
density?: 'compact' | 'comfortable';
|
|
23
|
+
rowHeight?: number;
|
|
24
|
+
headerHeight?: number;
|
|
22
25
|
freezeLeft?: number;
|
|
23
26
|
/** 独立右侧面板,不使用上游 split.right。 */
|
|
24
27
|
freezeRight?: number;
|
|
@@ -52,14 +55,15 @@
|
|
|
52
55
|
disabledLabel?: string;
|
|
53
56
|
fallbackLabel?: string;
|
|
54
57
|
}
|
|
55
|
-
let { Grid, Theme, items = [], columns, primaryKey = 'id', childrenKey, height = 420, density = 'comfortable', freezeLeft = 0, freezeRight = 0, queryMode = 'local',
|
|
58
|
+
let { Grid, Theme, items = [], columns, primaryKey = 'id', childrenKey, height = 420, density = 'comfortable', rowHeight: rowHeightProp, headerHeight: headerHeightProp, freezeLeft = 0, freezeRight = 0, queryMode = 'local',
|
|
56
59
|
sorters = [], filters = [], onSortChange, onFilterChange, onCellEdit, selectable = false, selectedIds = [], onSelectionChange, onRecordsChange, cellContent,
|
|
57
60
|
windowSource, loadChildren, hasChildrenKey = 'hasChildren', onLoadMore, hasMore = false, scopeKey = 0,
|
|
58
61
|
loading = false, error, disabled = false, locale = 'en-US', label = 'Data grid', emptyLabel = 'No records', loadingLabel = 'Loading',
|
|
59
62
|
disabledLabel = 'Grid is disabled', fallbackLabel = 'Static preview (up to 20 rows)',
|
|
60
63
|
}: SvarDataGridProps = $props();
|
|
61
64
|
const treeKey = $derived(loadChildren ? childrenKey ?? 'children' : childrenKey);
|
|
62
|
-
const rowHeight = $derived(density === 'compact' ? 32 : 44);
|
|
65
|
+
const rowHeight = $derived(rowHeightProp ?? (density === 'compact' ? 32 : 44));
|
|
66
|
+
const headerHeight = $derived(headerHeightProp ?? (density === 'compact' ? 32 : 36));
|
|
63
67
|
// 普通追加不重建引擎,否则无限加载会把滚动位置重置。懒树根替换必须清理分支缓存。
|
|
64
68
|
const dataOwner = $derived({ scopeKey, items: loadChildren ? items : undefined, source: windowSource,
|
|
65
69
|
loadChildren, onLoadMore, primaryKey, treeKey, hasChildrenKey, freezeRight, Grid });
|
|
@@ -304,12 +308,12 @@
|
|
|
304
308
|
{#key dataOwner}<div class="grid-panes" inert={disabled}>
|
|
305
309
|
<div class="grid-viewport center-pane" data-svar-pane="center" style:height="{height}px" role="region" aria-label="Scrollable columns" onkeydowncapture={event => navigatePane(event, 0)}>
|
|
306
310
|
<Grid columns={model.center} data={activeError || isLoading ? [] : records.rows} tree={treeKey !== undefined}
|
|
307
|
-
split={{ left: freezeLeft }} sizes={{ rowHeight, headerHeight
|
|
311
|
+
split={{ left: freezeLeft }} sizes={{ rowHeight, headerHeight, columnWidth: 160 }} select={selectable} multiselect={selectable} {selectedRows}
|
|
308
312
|
reorder={false} draggableRows={false} undo={false} {...queryProps} {...dynamicProps} init={api => init(api, 0)} />
|
|
309
313
|
</div>
|
|
310
314
|
{#if freezeRight > 0}<div class="grid-viewport right-pane" data-svar-pane="right" style:height="{height}px" style:width="{model.rightWidth}px" role="region" aria-label="Frozen right columns" onkeydowncapture={event => navigatePane(event, 1)}>
|
|
311
315
|
<Grid columns={model.right} data={activeError || isLoading ? [] : rightRows} tree={treeKey !== undefined}
|
|
312
|
-
split={{ left: 0 }} sizes={{ rowHeight, headerHeight
|
|
316
|
+
split={{ left: 0 }} sizes={{ rowHeight, headerHeight, columnWidth: 160 }} select={selectable} multiselect={selectable} {selectedRows}
|
|
313
317
|
reorder={false} draggableRows={false} undo={false} {...queryProps} {...dynamicProps} init={api => init(api, 1)} />
|
|
314
318
|
</div>{/if}
|
|
315
319
|
</div>{/key}
|
|
@@ -16,7 +16,10 @@ export interface SvarDataGridProps {
|
|
|
16
16
|
primaryKey?: string;
|
|
17
17
|
childrenKey?: string;
|
|
18
18
|
height?: number;
|
|
19
|
+
/** @deprecated Retained for compatibility; comfortable is the shared default. */
|
|
19
20
|
density?: 'compact' | 'comfortable';
|
|
21
|
+
rowHeight?: number;
|
|
22
|
+
headerHeight?: number;
|
|
20
23
|
freezeLeft?: number;
|
|
21
24
|
/** 独立右侧面板,不使用上游 split.right。 */
|
|
22
25
|
freezeRight?: number;
|
|
@@ -16,7 +16,6 @@ export interface SvarResourceTableProps {
|
|
|
16
16
|
/** 高级读取仍使用资源契约、Provider 和核心查询缓存。 */
|
|
17
17
|
loadingMode?: 'page' | 'window' | 'infinite';
|
|
18
18
|
lazyTree?: SvarLazyTree;
|
|
19
|
-
density?: 'compact' | 'comfortable';
|
|
20
19
|
childrenKey?: string;
|
|
21
20
|
dataScopeKey?: string | number;
|
|
22
21
|
disabled?: boolean;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import type { SvarResourceTableProps } from './SvarResourceTable.svelte';
|
|
16
16
|
|
|
17
17
|
let { Grid, Theme, resourceName, pageSize = 25, filters = [], initialSorters = [], height = 420,
|
|
18
|
-
freezeLeft = 0, freezeRight = 0, loadingMode = 'page', lazyTree,
|
|
18
|
+
freezeLeft = 0, freezeRight = 0, loadingMode = 'page', lazyTree, childrenKey: providedChildrenKey, dataScopeKey = 0, disabled = false,
|
|
19
19
|
editable = false, selectable = false, batchUpdate = false, batchDelete = false, exportable = false,
|
|
20
20
|
savedViews = false, preferenceScopeKey, migrateAutoTableViews = false, deleteVariables, formats = {},
|
|
21
21
|
}: SvarResourceTableProps = $props();
|
|
@@ -333,7 +333,7 @@
|
|
|
333
333
|
</div>{/if}
|
|
334
334
|
{#if feedback}<p role="alert">{feedback}</p>{/if}
|
|
335
335
|
{#if result}<p role="status">{zh ? '成功 / 失败 / 未执行' : 'Succeeded / failed / skipped'}: {result.succeeded.length} / {result.failed.length} / {result.skipped.length}</p>{/if}
|
|
336
|
-
<SvarDataGrid {Grid} {Theme} items={gridItems} {columns} {primaryKey} {height} freezeRight={Math.min(freezeRight, Math.max(0, columns.length - 1))} freezeLeft={Math.min(freezeLeft, columns.length - Math.min(freezeRight, Math.max(0, columns.length - 1)))}
|
|
336
|
+
<SvarDataGrid {Grid} {Theme} items={gridItems} {columns} {primaryKey} {height} freezeRight={Math.min(freezeRight, Math.max(0, columns.length - 1))} freezeLeft={Math.min(freezeLeft, columns.length - Math.min(freezeRight, Math.max(0, columns.length - 1)))}
|
|
337
337
|
queryMode="server" {sorters} filters={textFilters} onSortChange={changeSort} onFilterChange={changeFilter}
|
|
338
338
|
selectable={selectable || batchUpdate || batchDelete} {selectedIds} onSelectionChange={selection} {...advanced ? { onRecordsChange: loaded } : {}} scopeKey={gridScope}
|
|
339
339
|
{...windowSource ? { windowSource } : {}}
|
|
@@ -11,6 +11,7 @@ export interface AutoTableGridState {
|
|
|
11
11
|
}[];
|
|
12
12
|
readonly primaryKey: string;
|
|
13
13
|
readonly sorters: readonly Sort[];
|
|
14
|
+
/** @deprecated Retained for custom grid renderers during the baseline transition. */
|
|
14
15
|
readonly density: 'compact' | 'comfortable';
|
|
15
16
|
readonly locale: string;
|
|
16
17
|
readonly label: string;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
description?: string;
|
|
9
9
|
breadcrumbs?: string[];
|
|
10
10
|
actions?: Snippet;
|
|
11
|
+
/** @deprecated Accepted for compatibility; the product baseline is shared. */
|
|
11
12
|
density?: 'compact' | 'comfortable';
|
|
12
13
|
headingLevel?: 'h1' | 'h2';
|
|
13
14
|
class?: string;
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
headingLevel = 'h1',
|
|
23
24
|
class: className = '',
|
|
24
25
|
}: Props = $props();
|
|
25
|
-
const styles = $derived(contentHeader(
|
|
26
|
+
const styles = $derived(contentHeader());
|
|
26
27
|
</script>
|
|
27
28
|
|
|
28
29
|
<header
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
children: Snippet;
|
|
13
13
|
pageId?: string;
|
|
14
14
|
width?: 'narrow' | 'default' | 'wide';
|
|
15
|
+
/** @deprecated Accepted for compatibility; the product baseline is shared. */
|
|
15
16
|
density?: 'compact' | 'comfortable';
|
|
16
17
|
class?: string;
|
|
17
18
|
}
|
|
@@ -32,7 +33,6 @@
|
|
|
32
33
|
const resolvedWidth = $derived(width === 'narrow' || width === 'wide' ? width : 'default');
|
|
33
34
|
const styles = $derived(contentPage({
|
|
34
35
|
width: resolvedWidth,
|
|
35
|
-
density,
|
|
36
36
|
}));
|
|
37
37
|
</script>
|
|
38
38
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { cn } from '../../utils.js';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
/** Panel heading. Omit it for an untitled surface. */
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
actions?: Snippet;
|
|
10
|
+
children: Snippet;
|
|
11
|
+
footer?: Snippet;
|
|
12
|
+
/** `none` removes body padding so a table or list can meet the panel edge. */
|
|
13
|
+
padding?: 'default' | 'compact' | 'none';
|
|
14
|
+
headingLevel?: 'h2' | 'h3';
|
|
15
|
+
class?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
title,
|
|
20
|
+
description,
|
|
21
|
+
actions,
|
|
22
|
+
children,
|
|
23
|
+
footer,
|
|
24
|
+
padding = 'default',
|
|
25
|
+
headingLevel = 'h2',
|
|
26
|
+
class: className = '',
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
|
|
29
|
+
const uid = $props.id();
|
|
30
|
+
const headingId = `svadmin-data-panel-${uid}`;
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<section
|
|
34
|
+
class={cn('svadmin-data-panel', className)}
|
|
35
|
+
data-svadmin-data-panel
|
|
36
|
+
data-padding={padding}
|
|
37
|
+
aria-labelledby={title ? headingId : undefined}
|
|
38
|
+
>
|
|
39
|
+
{#if title}
|
|
40
|
+
<header class="svadmin-data-panel__header" data-slot="data-panel-header">
|
|
41
|
+
<div class="svadmin-data-panel__heading">
|
|
42
|
+
<svelte:element this={headingLevel} id={headingId} class="svadmin-data-panel__title">
|
|
43
|
+
{title}
|
|
44
|
+
</svelte:element>
|
|
45
|
+
{#if description}
|
|
46
|
+
<p class="svadmin-data-panel__description">{description}</p>
|
|
47
|
+
{/if}
|
|
48
|
+
</div>
|
|
49
|
+
{#if actions}
|
|
50
|
+
<div class="svadmin-data-panel__actions">{@render actions()}</div>
|
|
51
|
+
{/if}
|
|
52
|
+
</header>
|
|
53
|
+
{/if}
|
|
54
|
+
<div class="svadmin-data-panel__body" data-slot="data-panel-body">{@render children()}</div>
|
|
55
|
+
{#if footer}
|
|
56
|
+
<footer class="svadmin-data-panel__footer" data-slot="data-panel-footer">{@render footer()}</footer>
|
|
57
|
+
{/if}
|
|
58
|
+
</section>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Panel heading. Omit it for an untitled surface. */
|
|
4
|
+
title?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
actions?: Snippet;
|
|
7
|
+
children: Snippet;
|
|
8
|
+
footer?: Snippet;
|
|
9
|
+
/** `none` removes body padding so a table or list can meet the panel edge. */
|
|
10
|
+
padding?: 'default' | 'compact' | 'none';
|
|
11
|
+
headingLevel?: 'h2' | 'h3';
|
|
12
|
+
class?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const DataPanel: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type DataPanel = ReturnType<typeof DataPanel>;
|
|
16
|
+
export default DataPanel;
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
columns?: 1 | 2 | 3 | 4;
|
|
15
15
|
layout?: 'vertical' | 'horizontal';
|
|
16
16
|
bordered?: boolean;
|
|
17
|
-
density?: 'compact' | 'comfortable';
|
|
18
17
|
class?: string;
|
|
19
18
|
}
|
|
20
19
|
|
|
@@ -23,11 +22,9 @@
|
|
|
23
22
|
columns = 1,
|
|
24
23
|
layout = 'vertical',
|
|
25
24
|
bordered = false,
|
|
26
|
-
density = 'comfortable',
|
|
27
25
|
class: className = '',
|
|
28
26
|
}: Props = $props();
|
|
29
27
|
|
|
30
|
-
const isCompact = $derived(density === 'compact');
|
|
31
28
|
const isHorizontal = $derived(layout === 'horizontal');
|
|
32
29
|
|
|
33
30
|
function spanClass(span: number | undefined): string {
|
|
@@ -65,7 +62,7 @@
|
|
|
65
62
|
<dt
|
|
66
63
|
class={cn(
|
|
67
64
|
'svadmin-u-2859c861d7de svadmin-u-2689f3958069 svadmin-u-bfa603190748 svadmin-u-012fbd121f37 svadmin-u-65fdbade2025 svadmin-u-a968a4123359 svadmin-u-27165ed73e86 svadmin-u-cdf6e054e5e0',
|
|
68
|
-
|
|
65
|
+
'svadmin-u-f0faeb26d656 svadmin-u-e7ee55ac7ffe svadmin-u-359090c2d529 svadmin-u-e2327d142859',
|
|
69
66
|
isHorizontal ? 'svadmin-u-b03f3c253900' : '',
|
|
70
67
|
)}
|
|
71
68
|
>
|
|
@@ -74,7 +71,7 @@
|
|
|
74
71
|
<dd
|
|
75
72
|
class={cn(
|
|
76
73
|
'svadmin-u-170cee3ff4e4 svadmin-u-2689f3958069 svadmin-u-d4108abe6359 svadmin-u-cd0ad9a56558 svadmin-u-36e579c0b41c svadmin-u-7e0b7cdf1a94',
|
|
77
|
-
|
|
74
|
+
'svadmin-u-f0faeb26d656 svadmin-u-e7ee55ac7ffe svadmin-u-359090c2d529 svadmin-u-e2327d142859',
|
|
78
75
|
)}
|
|
79
76
|
>
|
|
80
77
|
{#if item.href}
|
|
@@ -95,7 +92,7 @@
|
|
|
95
92
|
class={cn(
|
|
96
93
|
'svadmin-u-f3c543ad5fe9',
|
|
97
94
|
columnClass,
|
|
98
|
-
|
|
95
|
+
'svadmin-u-706c16d853e6 svadmin-u-375f36f67650',
|
|
99
96
|
className,
|
|
100
97
|
)}
|
|
101
98
|
>
|
|
@@ -110,7 +107,7 @@
|
|
|
110
107
|
<dt
|
|
111
108
|
class={cn(
|
|
112
109
|
'svadmin-u-2689f3958069 svadmin-u-bfa603190748',
|
|
113
|
-
|
|
110
|
+
'svadmin-u-359090c2d529',
|
|
114
111
|
isHorizontal ? 'svadmin-u-012fbd121f37 svadmin-u-2e7a6d18a20d' : '',
|
|
115
112
|
)}
|
|
116
113
|
>
|
|
@@ -119,7 +116,7 @@
|
|
|
119
116
|
<dd
|
|
120
117
|
class={cn(
|
|
121
118
|
'svadmin-u-170cee3ff4e4 svadmin-u-2689f3958069 svadmin-u-d4108abe6359 svadmin-u-7e0b7cdf1a94 svadmin-u-36e579c0b41c',
|
|
122
|
-
isHorizontal ? 'svadmin-u-359090c2d529 svadmin-u-e2327d142859' :
|
|
119
|
+
isHorizontal ? 'svadmin-u-359090c2d529 svadmin-u-e2327d142859' : 'svadmin-u-b6b02c0ebef6 svadmin-u-fc7473ca09eb',
|
|
123
120
|
)}
|
|
124
121
|
>
|
|
125
122
|
{#if item.href}
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
clearLabel?: string;
|
|
17
17
|
advancedLabel?: string;
|
|
18
18
|
showSearch?: boolean;
|
|
19
|
-
density?: 'compact' | 'comfortable';
|
|
20
19
|
activeFilterCount?: number;
|
|
21
20
|
advancedOpen?: boolean;
|
|
22
21
|
filters?: Snippet;
|
|
@@ -31,7 +30,6 @@
|
|
|
31
30
|
clearLabel = 'Clear search',
|
|
32
31
|
advancedLabel = 'Filters',
|
|
33
32
|
showSearch = true,
|
|
34
|
-
density = 'compact',
|
|
35
33
|
activeFilterCount = 0,
|
|
36
34
|
advancedOpen = $bindable(false),
|
|
37
35
|
filters,
|
|
@@ -40,7 +38,6 @@
|
|
|
40
38
|
class: className = '',
|
|
41
39
|
}: Props = $props();
|
|
42
40
|
|
|
43
|
-
const isCompact = $derived(density === 'compact');
|
|
44
41
|
const advancedPanelId = `svadmin-filter-toolbar-advanced-${uid}`;
|
|
45
42
|
const i18n = useTranslation();
|
|
46
43
|
let mobile = $state(false);
|
|
@@ -53,7 +50,7 @@
|
|
|
53
50
|
});
|
|
54
51
|
</script>
|
|
55
52
|
|
|
56
|
-
<div class={cn('svadmin-filter-toolbar', className)} data-
|
|
53
|
+
<div class={cn('svadmin-filter-toolbar', className)} data-svadmin-filter-toolbar data-advanced-open={advanced && advancedOpen ? 'true' : 'false'}>
|
|
57
54
|
<div class="svadmin-filter-toolbar__row">
|
|
58
55
|
{#if showSearch}
|
|
59
56
|
<div class="svadmin-filter-toolbar__search">
|
|
@@ -86,7 +83,7 @@
|
|
|
86
83
|
{#if advanced || (mobile && filters)}
|
|
87
84
|
<Button
|
|
88
85
|
variant={advancedOpen ? 'secondary' : 'outline'}
|
|
89
|
-
size=
|
|
86
|
+
size="default"
|
|
90
87
|
class="svadmin-filter-toolbar__toggle"
|
|
91
88
|
onclick={() => advancedOpen = !advancedOpen}
|
|
92
89
|
aria-expanded={advancedOpen}
|
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
import DataState from './DataState.svelte';
|
|
7
7
|
import type { DataStateKind } from './DataState.svelte';
|
|
8
8
|
import type { NetworkColumn } from './NetworkTable.types.js';
|
|
9
|
-
interface Props { rows?: T[]; columns: NetworkColumn<T>[]; row?: Snippet<[T]>; state?: DataStateKind; stateTitle?: string; stateDescription?: string; emptyTitle?: string; emptyDescription?: string; retry?: () => void; retryLabel?: string; loadingLabel?: string; class?: string;
|
|
10
|
-
let { rows = [], columns, row, state, stateTitle, stateDescription, emptyTitle, emptyDescription, retry, retryLabel, loadingLabel, class: className = ''
|
|
9
|
+
interface Props { rows?: T[]; columns: NetworkColumn<T>[]; row?: Snippet<[T]>; state?: DataStateKind; stateTitle?: string; stateDescription?: string; emptyTitle?: string; emptyDescription?: string; retry?: () => void; retryLabel?: string; loadingLabel?: string; class?: string; }
|
|
10
|
+
let { rows = [], columns, row, state, stateTitle, stateDescription, emptyTitle, emptyDescription, retry, retryLabel, loadingLabel, class: className = '' }: Props = $props();
|
|
11
11
|
const resolvedState = $derived(state ?? (rows.length === 0 ? 'empty' : undefined));
|
|
12
12
|
</script>
|
|
13
13
|
{#if resolvedState}
|
|
14
14
|
<DataState state={resolvedState} {...definedOptions({ title: stateTitle ?? emptyTitle, description: stateDescription ?? emptyDescription, retry, retryLabel, loadingLabel })} class={className} />
|
|
15
15
|
{:else}
|
|
16
16
|
<div class={'svadmin-u-1384f66f41d0 svadmin-u-5f22e64f2282 svadmin-u-ca6bcd4b6f3f svadmin-u-18049387f0af svadmin-u-cd0ad9a56558 ' + className}>
|
|
17
|
-
<Table.Root
|
|
17
|
+
<Table.Root data-svadmin-datatable>
|
|
18
18
|
<Table.Header data-svadmin-table-head><Table.Row>{#each columns as column (String(column.key))}<Table.Head>{column.label}</Table.Head>{/each}</Table.Row></Table.Header>
|
|
19
19
|
<Table.Body>
|
|
20
20
|
{#each rows as item, index (String('id' in item ? item.id : index))}
|