@happyvertical/smrt-svelte 0.55.18 → 0.55.20
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/agents/cookbook-shell.md +26 -2
- package/agents/overview-surfaces.md +13 -3
- package/agents/workspace.md +46 -0
- package/dist/components/app/AppShell.svelte +29 -7
- package/dist/components/app/AppShell.svelte.d.ts +13 -5
- package/dist/components/app/AppShell.svelte.d.ts.map +1 -1
- package/dist/components/app/DockToggles.svelte +89 -47
- package/dist/components/app/DockToggles.svelte.d.ts +1 -1
- package/dist/components/app/DockToggles.svelte.d.ts.map +1 -1
- package/dist/components/app/PhoneTabBar.svelte +37 -12
- package/dist/components/app/PhoneTabBar.svelte.d.ts +1 -1
- package/dist/components/app/PhoneTabBar.svelte.d.ts.map +1 -1
- package/dist/components/app/ShellSettingsPage.svelte +2 -2
- package/dist/components/app/ShellSettingsPage.svelte.d.ts +2 -2
- package/dist/components/app/ShellSettingsPage.svelte.d.ts.map +1 -1
- package/dist/components/app/dock-toggle.d.ts +45 -0
- package/dist/components/app/dock-toggle.d.ts.map +1 -1
- package/dist/components/app/dock-toggle.js +26 -1
- package/dist/components/app/index.d.ts +1 -0
- package/dist/components/app/index.d.ts.map +1 -1
- package/dist/components/app/shell-user.d.ts +14 -0
- package/dist/components/app/shell-user.d.ts.map +1 -0
- package/dist/components/app/shell-user.js +1 -0
- package/dist/components/cookbook/CookbookSectionOverview.svelte +22 -3
- package/dist/components/cookbook/CookbookSectionOverview.svelte.d.ts +11 -2
- package/dist/components/cookbook/CookbookSectionOverview.svelte.d.ts.map +1 -1
- package/dist/components/cookbook/CookbookSectionPage.svelte +27 -9
- package/dist/components/cookbook/CookbookSectionPage.svelte.d.ts.map +1 -1
- package/dist/components/cookbook/index.d.ts +3 -1
- package/dist/components/cookbook/index.d.ts.map +1 -1
- package/dist/components/cookbook/index.js +2 -1
- package/dist/components/cookbook/registry.d.ts +18 -4
- package/dist/components/cookbook/registry.d.ts.map +1 -1
- package/dist/components/cookbook/registry.js +40 -2
- package/dist/components/cookbook/types.d.ts +39 -4
- package/dist/components/cookbook/types.d.ts.map +1 -1
- package/dist/components/overview/OverviewGrid.svelte +1 -0
- package/dist/components/overview/index.d.ts +1 -1
- package/dist/components/overview/index.d.ts.map +1 -1
- package/dist/components/overview/types.d.ts +6 -0
- package/dist/components/overview/types.d.ts.map +1 -1
- package/dist/components/overview/widgets/ChartWidget.svelte +158 -18
- package/dist/components/overview/widgets/ChartWidget.svelte.d.ts.map +1 -1
- package/dist/components/overview/widgets/ShortcutsWidget.svelte +32 -3
- package/dist/components/overview/widgets/ShortcutsWidget.svelte.d.ts.map +1 -1
- package/dist/components/overview/widgets/core.d.ts +9 -1
- package/dist/components/overview/widgets/core.d.ts.map +1 -1
- package/dist/components/overview/widgets/core.js +20 -1
- package/dist/components/overview/widgets/data.d.ts +16 -6
- package/dist/components/overview/widgets/data.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/AdminShell.svelte +13 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte +52 -7
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte.d.ts +6 -2
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte +54 -5
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte.d.ts +7 -2
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/mobile-shell.d.ts +1 -1
- package/dist/components/workspace/admin-shell/mobile-shell.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/state.svelte.d.ts +9 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/state.svelte.js +14 -0
- package/dist/i18n/strings.overview.d.ts +5 -0
- package/dist/i18n/strings.overview.d.ts.map +1 -1
- package/dist/i18n/strings.overview.js +5 -0
- package/dist/i18n/strings.workspace.d.ts +2 -0
- package/dist/i18n/strings.workspace.d.ts.map +1 -1
- package/dist/i18n/strings.workspace.js +3 -0
- package/package.json +16 -16
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/**
|
|
3
|
-
* Chart widget (#3727): bars
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Chart widget (#3727, #3888): bars, a line, a plain table, a donut or a single
|
|
4
|
+
* headline value over labelled values, drawn from the loaded data. Every chart
|
|
5
|
+
* carries its numbers as text (bar values inline, a visible table for `table`,
|
|
6
|
+
* a visually hidden table for the line and the donut, the value itself for
|
|
7
|
+
* `stat`) so it is readable without sight.
|
|
6
8
|
*/
|
|
7
9
|
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
8
10
|
import { M } from '../../../i18n/strings.overview.js';
|
|
@@ -32,7 +34,10 @@ const points = $derived.by(() => {
|
|
|
32
34
|
}
|
|
33
35
|
return out;
|
|
34
36
|
});
|
|
35
|
-
const
|
|
37
|
+
const STYLES = ['bar', 'line', 'table', 'pie', 'stat'] as const;
|
|
38
|
+
const style = $derived(
|
|
39
|
+
STYLES.find((candidate) => candidate === options.style) ?? 'bar',
|
|
40
|
+
);
|
|
36
41
|
const fmt = (value: number): string =>
|
|
37
42
|
formatWidgetValue(value, {
|
|
38
43
|
format: chart?.format ?? 'integer',
|
|
@@ -51,13 +56,132 @@ const polyline = $derived(
|
|
|
51
56
|
})
|
|
52
57
|
.join(' '),
|
|
53
58
|
);
|
|
59
|
+
|
|
60
|
+
// Donut: slices are percentages of the positive total on a circle whose
|
|
61
|
+
// path length is 100, so a segment's dash length is its share.
|
|
62
|
+
const total = $derived(
|
|
63
|
+
points.reduce((sum, point) => sum + Math.max(0, point.value), 0),
|
|
64
|
+
);
|
|
65
|
+
const slices = $derived.by(() => {
|
|
66
|
+
let offset = 0;
|
|
67
|
+
return points.map((point, index) => {
|
|
68
|
+
const share = total > 0 ? (Math.max(0, point.value) / total) * 100 : 0;
|
|
69
|
+
const slice = { ...point, index, share, offset };
|
|
70
|
+
offset += share;
|
|
71
|
+
return slice;
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
const percent = (share: number): string =>
|
|
75
|
+
formatWidgetValue(share / 100, { format: 'percent', locale });
|
|
76
|
+
|
|
77
|
+
// Stat: the latest value, and its change against the one before.
|
|
78
|
+
const latest = $derived(points.at(-1));
|
|
79
|
+
const delta = $derived.by((): number | null => {
|
|
80
|
+
if (
|
|
81
|
+
chart &&
|
|
82
|
+
typeof chart.delta === 'number' &&
|
|
83
|
+
Number.isFinite(chart.delta)
|
|
84
|
+
) {
|
|
85
|
+
return chart.delta;
|
|
86
|
+
}
|
|
87
|
+
const previous = points.at(-2);
|
|
88
|
+
if (!latest || !previous || previous.value === 0) return null;
|
|
89
|
+
return ((latest.value - previous.value) / Math.abs(previous.value)) * 100;
|
|
90
|
+
});
|
|
91
|
+
const deltaText = $derived(
|
|
92
|
+
delta === null || delta === 0
|
|
93
|
+
? ''
|
|
94
|
+
: t(
|
|
95
|
+
M[
|
|
96
|
+
delta > 0
|
|
97
|
+
? 'ui.overview.metric.change_up'
|
|
98
|
+
: 'ui.overview.metric.change_down'
|
|
99
|
+
],
|
|
100
|
+
{
|
|
101
|
+
value: formatWidgetValue(Math.abs(delta) / 100, {
|
|
102
|
+
format: 'percent',
|
|
103
|
+
locale,
|
|
104
|
+
}),
|
|
105
|
+
},
|
|
106
|
+
),
|
|
107
|
+
);
|
|
54
108
|
const summary = $derived(
|
|
55
109
|
`${title}. ${t(M['ui.overview.chart.summary'], { count: points.length })}`,
|
|
56
110
|
);
|
|
57
111
|
</script>
|
|
58
112
|
|
|
113
|
+
{#snippet dataTable(hidden: boolean)}
|
|
114
|
+
<table class={hidden ? 'smrt-chart__table' : 'smrt-chart__data'}>
|
|
115
|
+
<caption>{t(M['ui.overview.chart.table'])}</caption>
|
|
116
|
+
<thead>
|
|
117
|
+
<tr>
|
|
118
|
+
<th scope="col">{t(M['ui.overview.chart.label_column'])}</th>
|
|
119
|
+
<th scope="col">{t(M['ui.overview.chart.value_column'])}</th>
|
|
120
|
+
</tr>
|
|
121
|
+
</thead>
|
|
122
|
+
<tbody>
|
|
123
|
+
{#each points as point, index (index)}
|
|
124
|
+
<tr><th scope="row">{point.label}</th><td>{fmt(point.value)}</td></tr>
|
|
125
|
+
{/each}
|
|
126
|
+
</tbody>
|
|
127
|
+
</table>
|
|
128
|
+
{/snippet}
|
|
129
|
+
|
|
59
130
|
{#if points.length === 0}
|
|
60
131
|
<p class="smrt-chart__empty" data-smrt-component="ChartWidget">{t(M['ui.overview.no_data'])}</p>
|
|
132
|
+
{:else if style === 'table'}
|
|
133
|
+
<div class="smrt-chart smrt-chart--table" data-smrt-component="ChartWidget">
|
|
134
|
+
{@render dataTable(false)}
|
|
135
|
+
</div>
|
|
136
|
+
{:else if style === 'stat'}
|
|
137
|
+
{#if latest}
|
|
138
|
+
<div class="smrt-chart smrt-chart--stat" data-smrt-component="ChartWidget">
|
|
139
|
+
<p class="smrt-chart__headline">{fmt(latest.value)}</p>
|
|
140
|
+
<p class="smrt-chart__caption">{latest.label}</p>
|
|
141
|
+
{#if deltaText}
|
|
142
|
+
<p class="smrt-chart__delta" data-direction={(delta ?? 0) > 0 ? 'up' : 'down'}>
|
|
143
|
+
<span aria-hidden="true">{(delta ?? 0) > 0 ? '▲' : '▼'}</span>
|
|
144
|
+
{deltaText}
|
|
145
|
+
</p>
|
|
146
|
+
{/if}
|
|
147
|
+
</div>
|
|
148
|
+
{/if}
|
|
149
|
+
{:else if style === 'pie'}
|
|
150
|
+
{#if total > 0}
|
|
151
|
+
<div class="smrt-chart smrt-chart--pie" data-smrt-component="ChartWidget">
|
|
152
|
+
<svg class="smrt-chart__donut" viewBox="0 0 42 42" role="img" aria-label={summary}>
|
|
153
|
+
{#each slices as slice (slice.index)}
|
|
154
|
+
{#if slice.share > 0}
|
|
155
|
+
<circle
|
|
156
|
+
class="smrt-chart__slice"
|
|
157
|
+
data-slot={slice.index % 8}
|
|
158
|
+
cx="21"
|
|
159
|
+
cy="21"
|
|
160
|
+
r="15.9155"
|
|
161
|
+
fill="none"
|
|
162
|
+
stroke-width="6"
|
|
163
|
+
pathLength="100"
|
|
164
|
+
stroke-dasharray="{slice.share} {100 - slice.share}"
|
|
165
|
+
stroke-dashoffset={-slice.offset}
|
|
166
|
+
transform="rotate(-90 21 21)"
|
|
167
|
+
/>
|
|
168
|
+
{/if}
|
|
169
|
+
{/each}
|
|
170
|
+
</svg>
|
|
171
|
+
<ul class="smrt-chart__legend" aria-hidden="true">
|
|
172
|
+
{#each slices as slice (slice.index)}
|
|
173
|
+
<li class="smrt-chart__legend-item">
|
|
174
|
+
<span class="smrt-chart__swatch" data-slot={slice.index % 8}></span>
|
|
175
|
+
<span class="smrt-chart__label">{slice.label}</span>
|
|
176
|
+
<span class="smrt-chart__value">{fmt(slice.value)} · {percent(slice.share)}</span>
|
|
177
|
+
</li>
|
|
178
|
+
{/each}
|
|
179
|
+
</ul>
|
|
180
|
+
{@render dataTable(true)}
|
|
181
|
+
</div>
|
|
182
|
+
{:else}
|
|
183
|
+
<p class="smrt-chart__empty" data-smrt-component="ChartWidget">{t(M['ui.overview.no_data'])}</p>
|
|
184
|
+
{/if}
|
|
61
185
|
{:else if style === 'line'}
|
|
62
186
|
<div class="smrt-chart" data-smrt-component="ChartWidget">
|
|
63
187
|
<svg class="smrt-chart__line" viewBox="0 0 100 40" preserveAspectRatio="none" role="img" aria-label={summary}>
|
|
@@ -67,20 +191,7 @@ const summary = $derived(
|
|
|
67
191
|
<span>{points[0].label}</span>
|
|
68
192
|
<span>{points[points.length - 1].label}</span>
|
|
69
193
|
</p>
|
|
70
|
-
|
|
71
|
-
<caption>{t(M['ui.overview.chart.table'])}</caption>
|
|
72
|
-
<thead>
|
|
73
|
-
<tr>
|
|
74
|
-
<th scope="col">{t(M['ui.overview.chart.label_column'])}</th>
|
|
75
|
-
<th scope="col">{t(M['ui.overview.chart.value_column'])}</th>
|
|
76
|
-
</tr>
|
|
77
|
-
</thead>
|
|
78
|
-
<tbody>
|
|
79
|
-
{#each points as point, index (index)}
|
|
80
|
-
<tr><th scope="row">{point.label}</th><td>{fmt(point.value)}</td></tr>
|
|
81
|
-
{/each}
|
|
82
|
-
</tbody>
|
|
83
|
-
</table>
|
|
194
|
+
{@render dataTable(true)}
|
|
84
195
|
</div>
|
|
85
196
|
{:else}
|
|
86
197
|
<ul class="smrt-chart__bars" aria-label={summary} data-smrt-component="ChartWidget">
|
|
@@ -109,6 +220,35 @@ const summary = $derived(
|
|
|
109
220
|
.smrt-chart__bar { display: block; block-size: 100%; border-radius: inherit; background: var(--smrt-color-primary); }
|
|
110
221
|
.smrt-chart__value { font-variant-numeric: tabular-nums; color: var(--smrt-color-on-surface-variant); }
|
|
111
222
|
.smrt-chart__empty { margin: 0; color: var(--smrt-color-on-surface-variant); }
|
|
223
|
+
.smrt-chart--table { color: var(--smrt-color-on-surface); }
|
|
224
|
+
.smrt-chart__data { inline-size: 100%; border-collapse: collapse; font-size: var(--smrt-typography-body-medium-size, 0.875rem); }
|
|
225
|
+
.smrt-chart__data caption { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
|
|
226
|
+
.smrt-chart__data th, .smrt-chart__data td { padding: var(--smrt-spacing-1) var(--smrt-spacing-2); border-block-end: var(--smrt-hairline); text-align: start; }
|
|
227
|
+
.smrt-chart__data thead th { background: var(--smrt-surface-sunken); color: var(--smrt-color-on-surface-variant); font-weight: var(--smrt-typography-weight-medium, 500); }
|
|
228
|
+
.smrt-chart__data tbody th { font-weight: inherit; overflow-wrap: anywhere; }
|
|
229
|
+
.smrt-chart__data td, .smrt-chart__data thead th:last-child { text-align: end; font-variant-numeric: tabular-nums; }
|
|
230
|
+
.smrt-chart--stat { gap: var(--smrt-spacing-1); color: var(--smrt-color-on-surface); }
|
|
231
|
+
.smrt-chart__headline { margin: 0; font-size: var(--smrt-typography-display-small-size, 2rem); font-weight: var(--smrt-typography-weight-medium, 500); line-height: 1.1; font-variant-numeric: tabular-nums; }
|
|
232
|
+
.smrt-chart__caption { margin: 0; color: var(--smrt-color-on-surface-variant); font-size: var(--smrt-typography-body-medium-size, 0.875rem); }
|
|
233
|
+
.smrt-chart__delta { margin: 0; color: var(--smrt-color-on-surface-variant); font-size: var(--smrt-typography-label-large-size, 0.875rem); }
|
|
234
|
+
.smrt-chart--pie { grid-template-columns: minmax(6rem, 10rem) minmax(0, 1fr); align-items: center; gap: var(--smrt-spacing-4); }
|
|
235
|
+
.smrt-chart__donut { inline-size: 100%; block-size: auto; }
|
|
236
|
+
.smrt-chart__slice[data-slot='0'], .smrt-chart__swatch[data-slot='0'] { stroke: var(--smrt-color-primary); background: var(--smrt-color-primary); }
|
|
237
|
+
.smrt-chart__slice[data-slot='1'], .smrt-chart__swatch[data-slot='1'] { stroke: var(--smrt-color-secondary); background: var(--smrt-color-secondary); }
|
|
238
|
+
.smrt-chart__slice[data-slot='2'], .smrt-chart__swatch[data-slot='2'] { stroke: var(--smrt-color-tertiary); background: var(--smrt-color-tertiary); }
|
|
239
|
+
.smrt-chart__slice[data-slot='3'], .smrt-chart__swatch[data-slot='3'] { stroke: var(--smrt-color-info); background: var(--smrt-color-info); }
|
|
240
|
+
.smrt-chart__slice[data-slot='4'], .smrt-chart__swatch[data-slot='4'] { stroke: var(--smrt-color-primary-container); background: var(--smrt-color-primary-container); }
|
|
241
|
+
.smrt-chart__slice[data-slot='5'], .smrt-chart__swatch[data-slot='5'] { stroke: var(--smrt-color-secondary-container); background: var(--smrt-color-secondary-container); }
|
|
242
|
+
.smrt-chart__slice[data-slot='6'], .smrt-chart__swatch[data-slot='6'] { stroke: var(--smrt-color-tertiary-container); background: var(--smrt-color-tertiary-container); }
|
|
243
|
+
.smrt-chart__slice[data-slot='7'], .smrt-chart__swatch[data-slot='7'] { stroke: var(--smrt-color-info-container); background: var(--smrt-color-info-container); }
|
|
244
|
+
.smrt-chart__legend { display: grid; gap: var(--smrt-spacing-1); margin: 0; padding: 0; list-style: none; color: var(--smrt-color-on-surface); font-size: var(--smrt-typography-body-medium-size, 0.875rem); }
|
|
245
|
+
.smrt-chart__legend-item { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--smrt-spacing-2); }
|
|
246
|
+
.smrt-chart__swatch { inline-size: 0.75rem; block-size: 0.75rem; border-radius: var(--smrt-radius-small); }
|
|
247
|
+
.smrt-chart__legend .smrt-chart__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
248
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
249
|
+
.smrt-chart__slice { transition: stroke-dasharray var(--smrt-duration-normal) var(--smrt-easing-standard), stroke-dashoffset var(--smrt-duration-normal) var(--smrt-easing-standard); }
|
|
250
|
+
.smrt-chart__bar { transition: inline-size var(--smrt-duration-normal) var(--smrt-easing-standard); }
|
|
251
|
+
}
|
|
112
252
|
.smrt-chart__table { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
|
|
113
253
|
}
|
|
114
254
|
</style>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartWidget.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/ChartWidget.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChartWidget.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/ChartWidget.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,KAAK,eAAe,EAAY,MAAM,WAAW,CAAC;AAqM3D,QAAA,MAAM,WAAW,2EAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -13,8 +13,12 @@ import { safeHref } from '../markdown.js';
|
|
|
13
13
|
import type { WidgetComponentProps } from '../types.js';
|
|
14
14
|
import { isRecord, type ShortcutsWidgetData } from './data.js';
|
|
15
15
|
|
|
16
|
-
let {
|
|
17
|
-
|
|
16
|
+
let {
|
|
17
|
+
data,
|
|
18
|
+
iconComponent,
|
|
19
|
+
locale,
|
|
20
|
+
presentation = 'card',
|
|
21
|
+
}: WidgetComponentProps<ShortcutsWidgetData> = $props();
|
|
18
22
|
|
|
19
23
|
const { t } = useI18n();
|
|
20
24
|
const MAX_ITEMS = 48;
|
|
@@ -25,8 +29,21 @@ interface Card {
|
|
|
25
29
|
href: string;
|
|
26
30
|
icon: string;
|
|
27
31
|
description?: string;
|
|
32
|
+
count?: number;
|
|
28
33
|
}
|
|
29
34
|
|
|
35
|
+
const numberFormat = $derived(new Intl.NumberFormat(locale));
|
|
36
|
+
const plural = $derived(new Intl.PluralRules(locale));
|
|
37
|
+
const countLabel = (count: number): string =>
|
|
38
|
+
t(
|
|
39
|
+
M[
|
|
40
|
+
plural.select(count) === 'one'
|
|
41
|
+
? 'ui.overview.shortcuts.records_one'
|
|
42
|
+
: 'ui.overview.shortcuts.records_other'
|
|
43
|
+
],
|
|
44
|
+
{ count: numberFormat.format(count) },
|
|
45
|
+
);
|
|
46
|
+
|
|
30
47
|
const cards = $derived.by((): Card[] => {
|
|
31
48
|
if (!isRecord(data) || !Array.isArray(data.items)) return [];
|
|
32
49
|
const out: Card[] = [];
|
|
@@ -42,6 +59,12 @@ const cards = $derived.by((): Card[] => {
|
|
|
42
59
|
typeof item.icon === 'string' ? item.icon : SHELL_DEFAULT_SECTION_ICON,
|
|
43
60
|
description:
|
|
44
61
|
typeof item.description === 'string' ? item.description : undefined,
|
|
62
|
+
count:
|
|
63
|
+
typeof item.count === 'number' &&
|
|
64
|
+
Number.isFinite(item.count) &&
|
|
65
|
+
item.count >= 0
|
|
66
|
+
? item.count
|
|
67
|
+
: undefined,
|
|
45
68
|
});
|
|
46
69
|
}
|
|
47
70
|
return out;
|
|
@@ -51,7 +74,7 @@ const cards = $derived.by((): Card[] => {
|
|
|
51
74
|
{#if cards.length === 0}
|
|
52
75
|
<p class="smrt-shortcuts__empty" data-smrt-component="ShortcutsWidget">{t(M['ui.overview.shortcuts.empty'])}</p>
|
|
53
76
|
{:else}
|
|
54
|
-
<ul class="smrt-shortcuts" data-smrt-component="ShortcutsWidget">
|
|
77
|
+
<ul class="smrt-shortcuts" data-presentation={presentation} data-smrt-component="ShortcutsWidget">
|
|
55
78
|
{#each cards as card (card.id)}
|
|
56
79
|
<li class="smrt-shortcuts__card">
|
|
57
80
|
<a class="smrt-shortcuts__link" href={card.href}>
|
|
@@ -60,6 +83,7 @@ const cards = $derived.by((): Card[] => {
|
|
|
60
83
|
<ShellSectionIcon name={card.icon} size={28} {iconComponent} />
|
|
61
84
|
</span>
|
|
62
85
|
<span class="smrt-shortcuts__title">{card.label}</span>
|
|
86
|
+
{#if card.count !== undefined}<span class="smrt-shortcuts__count">{countLabel(card.count)}</span>{/if}
|
|
63
87
|
</span>
|
|
64
88
|
{#if card.description}<span class="smrt-shortcuts__desc">{card.description}</span>{/if}
|
|
65
89
|
</a>
|
|
@@ -81,6 +105,11 @@ const cards = $derived.by((): Card[] => {
|
|
|
81
105
|
.smrt-shortcuts__icon :global(.smrt-shell-section-icon) { inline-size: 28px; block-size: 28px; }
|
|
82
106
|
.smrt-shortcuts__title { font-weight: var(--smrt-typography-weight-medium, 500); overflow-wrap: anywhere; }
|
|
83
107
|
.smrt-shortcuts__desc { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; color: var(--smrt-color-on-surface-variant); font-size: var(--smrt-typography-body-medium-size, 0.875rem); }
|
|
108
|
+
.smrt-shortcuts__count { margin-inline-start: auto; flex: 0 0 auto; color: var(--smrt-color-on-surface-variant); font-size: var(--smrt-typography-label-large-size, 0.75rem); font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
109
|
+
/* Plain: entries sit directly on the panel, no frame per entry. */
|
|
110
|
+
.smrt-shortcuts[data-presentation='plain'] { gap: var(--smrt-spacing-1); }
|
|
111
|
+
.smrt-shortcuts[data-presentation='plain'] .smrt-shortcuts__card { border: 0; border-radius: var(--smrt-radius-medium); background: transparent; }
|
|
112
|
+
.smrt-shortcuts[data-presentation='plain'] .smrt-shortcuts__card:hover { background: color-mix(in srgb, var(--smrt-color-on-surface) calc(var(--smrt-state-hover) * 100%), transparent); }
|
|
84
113
|
.smrt-shortcuts__empty { margin: 0; color: var(--smrt-color-on-surface-variant); }
|
|
85
114
|
}
|
|
86
115
|
</style>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShortcutsWidget.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/ShortcutsWidget.svelte.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAY,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"ShortcutsWidget.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/ShortcutsWidget.svelte.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAY,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AA+F/D,QAAA,MAAM,eAAe,+EAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -16,7 +16,15 @@ import type { WidgetDefinition, WidgetLoad } from '../types.js';
|
|
|
16
16
|
import type { ChartWidgetData, MetricWidgetData, RecordListWidgetData, ShortcutsWidgetData } from './data.js';
|
|
17
17
|
/** Metric: one number from a model. Options: model, measure, field, filter. */
|
|
18
18
|
export declare function createMetricWidget(load: WidgetLoad<MetricWidgetData>): WidgetDefinition<MetricWidgetData>;
|
|
19
|
-
/** Chart:
|
|
19
|
+
/** Chart option-schema version: 2 added the `table`, `pie` and `stat` styles. */
|
|
20
|
+
export declare const CHART_OPTIONS_VERSION = 2;
|
|
21
|
+
/** Chart options written at v1 (`style` bar or line) are valid at v2 unchanged. */
|
|
22
|
+
export declare function migrateChartOptions(options: Record<string, unknown>, fromVersion: number): Record<string, unknown> | null;
|
|
23
|
+
/**
|
|
24
|
+
* Chart: values grouped by a field over a period, drawn as `bar`, `line`,
|
|
25
|
+
* `table`, `pie` (donut) or `stat` (headline value with its change). This is
|
|
26
|
+
* the renderer half of the runtime-report chart hints (#3878).
|
|
27
|
+
*/
|
|
20
28
|
export declare function createChartWidget(load: WidgetLoad<ChartWidgetData>): WidgetDefinition<ChartWidgetData>;
|
|
21
29
|
/** Record list: the latest or top records of a model. */
|
|
22
30
|
export declare function createRecordListWidget(load: WidgetLoad<RecordListWidgetData>): WidgetDefinition<RecordListWidgetData>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EAEX,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,WAAW,CAAC;AA2CnB,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,GACjC,gBAAgB,CAAC,gBAAgB,CAAC,CAgBpC;AAED,
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EAEX,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,WAAW,CAAC;AA2CnB,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,GACjC,gBAAgB,CAAC,gBAAgB,CAAC,CAgBpC;AAED,iFAAiF;AACjF,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,mFAAmF;AACnF,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,WAAW,EAAE,MAAM,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAIhC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,UAAU,CAAC,eAAe,CAAC,GAChC,gBAAgB,CAAC,eAAe,CAAC,CAiDnC;AAED,yDAAyD;AACzD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,CAAC,oBAAoB,CAAC,GACrC,gBAAgB,CAAC,oBAAoB,CAAC,CAkCxC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,UAAU,CAAC,mBAAmB,CAAC,GACpC,gBAAgB,CAAC,mBAAmB,CAAC,CAmBvC;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,IAAI,gBAAgB,CAoBnD;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,UAAU,CAAC,mBAAmB,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,GAAE,cAAsC,EAChD,OAAO,GAAE,iBAAsB,EAC/B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,MAAM,IAAI,CAyBZ"}
|
|
@@ -71,7 +71,19 @@ export function createMetricWidget(load) {
|
|
|
71
71
|
load,
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
-
/** Chart:
|
|
74
|
+
/** Chart option-schema version: 2 added the `table`, `pie` and `stat` styles. */
|
|
75
|
+
export const CHART_OPTIONS_VERSION = 2;
|
|
76
|
+
/** Chart options written at v1 (`style` bar or line) are valid at v2 unchanged. */
|
|
77
|
+
export function migrateChartOptions(options, fromVersion) {
|
|
78
|
+
return fromVersion >= 1 && fromVersion < CHART_OPTIONS_VERSION
|
|
79
|
+
? { ...options }
|
|
80
|
+
: null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Chart: values grouped by a field over a period, drawn as `bar`, `line`,
|
|
84
|
+
* `table`, `pie` (donut) or `stat` (headline value with its change). This is
|
|
85
|
+
* the renderer half of the runtime-report chart hints (#3878).
|
|
86
|
+
*/
|
|
75
87
|
export function createChartWidget(load) {
|
|
76
88
|
return {
|
|
77
89
|
type: 'chart',
|
|
@@ -106,12 +118,19 @@ export function createChartWidget(load) {
|
|
|
106
118
|
choices: [
|
|
107
119
|
{ value: 'bar', label: 'ui.overview.opt.style_bar' },
|
|
108
120
|
{ value: 'line', label: 'ui.overview.opt.style_line' },
|
|
121
|
+
{ value: 'table', label: 'ui.overview.opt.style_table' },
|
|
122
|
+
{ value: 'pie', label: 'ui.overview.opt.style_pie' },
|
|
123
|
+
{ value: 'stat', label: 'ui.overview.opt.style_stat' },
|
|
109
124
|
],
|
|
110
125
|
},
|
|
111
126
|
filterField,
|
|
112
127
|
],
|
|
113
128
|
component: ChartWidget,
|
|
114
129
|
load,
|
|
130
|
+
// v2 widens `style` from bar | line to bar | line | table | pie | stat
|
|
131
|
+
// (#3888). Every v1 option set is still valid, so migration is identity.
|
|
132
|
+
version: CHART_OPTIONS_VERSION,
|
|
133
|
+
migrate: migrateChartOptions,
|
|
115
134
|
defaultSpan: 2,
|
|
116
135
|
};
|
|
117
136
|
}
|
|
@@ -26,6 +26,12 @@ export interface ChartWidgetData {
|
|
|
26
26
|
format?: WidgetValueFormat;
|
|
27
27
|
currency?: string;
|
|
28
28
|
href?: string;
|
|
29
|
+
/**
|
|
30
|
+
* `stat` style: percent change of the headline (the last point) against the
|
|
31
|
+
* period before (12.5 means +12.5%). Absent, it is derived from the last two
|
|
32
|
+
* points.
|
|
33
|
+
*/
|
|
34
|
+
delta?: number | null;
|
|
29
35
|
}
|
|
30
36
|
/** `records`: the rows to list. The loader chooses the title field. */
|
|
31
37
|
export interface RecordListWidgetData {
|
|
@@ -41,15 +47,19 @@ export interface RecordListWidgetData {
|
|
|
41
47
|
/** Link to the full list. */
|
|
42
48
|
href?: string;
|
|
43
49
|
}
|
|
50
|
+
/** One page a shortcut links to (#3888). `count` is the record count, when known. */
|
|
51
|
+
export interface ShortcutEntry {
|
|
52
|
+
href: string;
|
|
53
|
+
label: string;
|
|
54
|
+
icon?: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
count?: number;
|
|
57
|
+
}
|
|
44
58
|
/** `shortcuts`: cards that link to pages. */
|
|
45
59
|
export interface ShortcutsWidgetData {
|
|
46
|
-
items: {
|
|
60
|
+
items: (ShortcutEntry & {
|
|
47
61
|
id: string;
|
|
48
|
-
|
|
49
|
-
href: string;
|
|
50
|
-
icon?: string;
|
|
51
|
-
description?: string;
|
|
52
|
-
}[];
|
|
62
|
+
})[];
|
|
53
63
|
}
|
|
54
64
|
/** The part of a shell nav model section `shortcutsFromNav` reads. */
|
|
55
65
|
export interface ShortcutNavSection {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/data.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../../src/components/overview/widgets/data.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;IACJ,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,CAAC,aAAa,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;CAC3C;AAED,sEAAsE;AACtE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS;QACd,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7D,EAAE,CAAC;CACL;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,kBAAkB,EAAE,EACvC,SAAS,CAAC,EAAE,MAAM,GACjB,mBAAmB,CAoBrB;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE"}
|
|
@@ -1006,6 +1006,19 @@ function buildLayoutStyle(shell: ModuleShellState): string {
|
|
|
1006
1006
|
return toggleOn(edge) || showToggle(edge);
|
|
1007
1007
|
}
|
|
1008
1008
|
|
|
1009
|
+
$effect(() => {
|
|
1010
|
+
const next = {
|
|
1011
|
+
top: topRendered,
|
|
1012
|
+
left: shell.isEdgeShown('left'),
|
|
1013
|
+
right: rightRendered,
|
|
1014
|
+
bottom: bottomRendered,
|
|
1015
|
+
};
|
|
1016
|
+
const prev = untrack(() => shell.regionsRendered);
|
|
1017
|
+
if ((Object.keys(next) as PanelEdge[]).some((e) => next[e] !== prev[e])) {
|
|
1018
|
+
shell.regionsRendered = next;
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1009
1022
|
$effect(() => {
|
|
1010
1023
|
shell.hotkeysAvailable = (['top', 'left', 'right', 'bottom'] as const).some(
|
|
1011
1024
|
hotkeyActive,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminShell.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/AdminShell.svelte.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAUtC,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,mBAAmB,CAAC;AActE,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAGH,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AACtB,OAAO,KAAK,EACR,sBAAsB,EACtB,eAAe,EAEf,sBAAsB,EACtB,cAAc,EACd,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,UAAU,KAAM,SAAQ,eAAe;IACrC,sEAAsE;IACtE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C;;;OAGG;IACH,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,6EAA6E;IAC7E,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;OAIG;IACH,eAAe,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC,CAAC;IACxD;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uCAAuC;IACvC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wCAAwC;IACxC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,QAAQ,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC,CAAC;IAChD;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;IAC7C;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,QAAQ,EAAE,aAAa,CAAC;QAAC,SAAS,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC,CAAC;IAC5E,qFAAqF;IACrF,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"AdminShell.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/AdminShell.svelte.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAUtC,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,mBAAmB,CAAC;AActE,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAGH,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AACtB,OAAO,KAAK,EACR,sBAAsB,EACtB,eAAe,EAEf,sBAAsB,EACtB,cAAc,EACd,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,UAAU,KAAM,SAAQ,eAAe;IACrC,sEAAsE;IACtE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C;;;OAGG;IACH,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,6EAA6E;IAC7E,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;OAIG;IACH,eAAe,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC,CAAC;IACxD;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uCAAuC;IACvC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wCAAwC;IACxC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,QAAQ,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC,CAAC;IAChD;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;IAC7C;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,QAAQ,EAAE,aAAa,CAAC;QAAC,SAAS,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC,CAAC;IAC5E,qFAAqF;IACrF,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAqzCH,QAAA,MAAM,UAAU,sDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -22,8 +22,12 @@ interface Props {
|
|
|
22
22
|
account?: boolean;
|
|
23
23
|
/** Where the sign-out control goes; the control is hidden when neither this nor `onSignOut` is given. */
|
|
24
24
|
signOutHref?: string;
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Called by the sign-out control instead of following `signOutHref`. May
|
|
27
|
+
* return a promise: the control is busy and disabled while it is pending;
|
|
28
|
+
* a rejection shows an inline error and leaves the section as it was.
|
|
29
|
+
*/
|
|
30
|
+
onSignOut?: () => unknown;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
const {
|
|
@@ -52,18 +56,49 @@ const REGION_OF_EDGE: Record<PanelEdge, ShellRegion> = {
|
|
|
52
56
|
const regionLabel = (edge: PanelEdge) =>
|
|
53
57
|
t(SHELL_REGION_MESSAGES[REGION_OF_EDGE[edge]]);
|
|
54
58
|
|
|
55
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* The areas this shell offers. A region the user hid stays listed so Show can
|
|
61
|
+
* restore it; a region that is shown but not rendered (nothing to put in it, or
|
|
62
|
+
* not presented at this width) is left out because its row would do nothing.
|
|
63
|
+
*/
|
|
56
64
|
const rows = $derived(
|
|
57
65
|
layout
|
|
58
66
|
? layout.panels
|
|
59
|
-
.filter(
|
|
67
|
+
.filter(
|
|
68
|
+
(panel) =>
|
|
69
|
+
panel.available &&
|
|
70
|
+
(!panel.visible || shell.regionsRendered[panel.edge]),
|
|
71
|
+
)
|
|
60
72
|
.map((panel) => ({ edge: panel.edge, visible: panel.visible }))
|
|
61
73
|
: edges
|
|
62
|
-
.filter(
|
|
74
|
+
.filter(
|
|
75
|
+
(edge) =>
|
|
76
|
+
shell.panels[edge] !== 'hidden' && shell.regionsRendered[edge],
|
|
77
|
+
)
|
|
63
78
|
.map((edge) => ({ edge, visible: true })),
|
|
64
79
|
);
|
|
65
|
-
|
|
80
|
+
/** Counts every shown region, rendered or not, so the last real one can't be hidden. */
|
|
81
|
+
const visibleCount = $derived(
|
|
82
|
+
layout
|
|
83
|
+
? layout.panels.filter((panel) => panel.available && panel.visible).length
|
|
84
|
+
: rows.length,
|
|
85
|
+
);
|
|
66
86
|
const shortcutRows = $derived(rows.filter((row) => row.visible));
|
|
87
|
+
let signingOut = $state(false);
|
|
88
|
+
let signOutFailed = $state(false);
|
|
89
|
+
|
|
90
|
+
async function runSignOut() {
|
|
91
|
+
if (signingOut || !onSignOut) return;
|
|
92
|
+
signingOut = true;
|
|
93
|
+
signOutFailed = false;
|
|
94
|
+
try {
|
|
95
|
+
await onSignOut();
|
|
96
|
+
} catch {
|
|
97
|
+
signOutFailed = true;
|
|
98
|
+
} finally {
|
|
99
|
+
signingOut = false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
67
102
|
const canSignOut = $derived(Boolean(signOutHref || onSignOut));
|
|
68
103
|
const hotkeysEnabled = $derived(shell.settings.hotkeysEnabled !== false);
|
|
69
104
|
|
|
@@ -118,9 +153,19 @@ function conflictFor(edge: PanelEdge): string | null {
|
|
|
118
153
|
{/if}
|
|
119
154
|
{#if canSignOut}
|
|
120
155
|
{#if onSignOut}
|
|
121
|
-
<Button
|
|
156
|
+
<Button
|
|
157
|
+
variant="secondary"
|
|
158
|
+
size="sm"
|
|
159
|
+
loading={signingOut}
|
|
160
|
+
onclick={runSignOut}
|
|
161
|
+
>
|
|
122
162
|
{t(M['ui.shell_settings.sign_out'])}
|
|
123
163
|
</Button>
|
|
164
|
+
{#if signOutFailed}
|
|
165
|
+
<p role="alert" data-smrt-part="error">
|
|
166
|
+
{t(M['ui.shell_settings.sign_out_failed'])}
|
|
167
|
+
</p>
|
|
168
|
+
{/if}
|
|
124
169
|
{:else}
|
|
125
170
|
<Button variant="secondary" size="sm" href={signOutHref}>
|
|
126
171
|
{t(M['ui.shell_settings.sign_out'])}
|
|
@@ -5,8 +5,12 @@ interface Props {
|
|
|
5
5
|
account?: boolean;
|
|
6
6
|
/** Where the sign-out control goes; the control is hidden when neither this nor `onSignOut` is given. */
|
|
7
7
|
signOutHref?: string;
|
|
8
|
-
/**
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Called by the sign-out control instead of following `signOutHref`. May
|
|
10
|
+
* return a promise: the control is busy and disabled while it is pending;
|
|
11
|
+
* a rejection shows an inline error and leaves the section as it was.
|
|
12
|
+
*/
|
|
13
|
+
onSignOut?: () => unknown;
|
|
10
14
|
}
|
|
11
15
|
declare const ShellSettingsPanel: import("svelte").Component<Props, {}, "">;
|
|
12
16
|
type ShellSettingsPanel = ReturnType<typeof ShellSettingsPanel>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShellSettingsPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/ShellSettingsPanel.svelte.ts"],"names":[],"mappings":"AAoBA,UAAU,KAAK;IACb,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yGAAyG;IACzG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB
|
|
1
|
+
{"version":3,"file":"ShellSettingsPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/ShellSettingsPanel.svelte.ts"],"names":[],"mappings":"AAoBA,UAAU,KAAK;IACb,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yGAAyG;IACzG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;CAC3B;AAmPD,QAAA,MAAM,kBAAkB,2CAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
|