@svadmin/ui 0.72.0 → 0.74.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 +62 -22
- package/THIRD_PARTY_NOTICES.md +52 -0
- package/dist/app.css +8488 -6297
- package/dist/app.theme.css +8514 -6374
- package/dist/class-properties.generated.d.ts +1 -0
- package/dist/class-properties.generated.js +2 -0
- package/dist/classnames.d.ts +8 -0
- package/dist/classnames.js +26 -0
- package/dist/component-registry.d.ts +14977 -0
- package/dist/component-registry.js +216 -0
- package/dist/components/AboutSettings.svelte +7 -1
- package/dist/components/AboutSettings.svelte.d.ts +4 -1
- package/dist/components/ActivityFeed.svelte +9 -3
- package/dist/components/ActivityFeed.svelte.d.ts +3 -0
- package/dist/components/AdminApp.svelte +19 -10
- package/dist/components/AdminApp.svelte.d.ts +6 -0
- package/dist/components/ApiSettings.svelte +41 -5
- package/dist/components/ApprovalCenter.svelte +283 -0
- package/dist/components/ApprovalCenter.svelte.d.ts +10 -0
- package/dist/components/AuditLogViewer.svelte +3 -1
- package/dist/components/AutoForm.svelte +53 -9
- package/dist/components/AutoForm.svelte.d.ts +3 -0
- package/dist/components/AutoTable.svelte +846 -43
- package/dist/components/AutoTable.svelte.d.ts +22 -1
- package/dist/components/BoundRecordDetailDrawer.svelte +17 -2
- package/dist/components/BoundRecordDetailDrawer.svelte.d.ts +4 -0
- package/dist/components/Breadcrumbs.svelte +11 -1
- package/dist/components/CancelTaskButton.svelte +12 -42
- package/dist/components/ColorPicker.svelte +73 -0
- package/dist/components/ColorPicker.svelte.d.ts +15 -0
- package/dist/components/ComboboxField.svelte +143 -34
- package/dist/components/ComboboxField.svelte.d.ts +4 -2
- package/dist/components/CreatePage.svelte +4 -0
- package/dist/components/CreatePage.svelte.d.ts +2 -0
- package/dist/components/DashboardView.svelte +99 -0
- package/dist/components/DashboardView.svelte.d.ts +14 -0
- package/dist/components/DatePicker.svelte +10 -0
- package/dist/components/DatePicker.svelte.d.ts +6 -0
- package/dist/components/DateRangeInput.svelte +155 -0
- package/dist/components/DateRangeInput.svelte.d.ts +35 -0
- package/dist/components/DateRangePicker.svelte +10 -0
- package/dist/components/DateRangePicker.svelte.d.ts +6 -0
- package/dist/components/DateTimeInput.svelte +134 -0
- package/dist/components/DateTimeInput.svelte.d.ts +27 -0
- package/dist/components/DateTimePicker.svelte +10 -0
- package/dist/components/DateTimePicker.svelte.d.ts +6 -0
- package/dist/components/DevTools.svelte +36 -28
- package/dist/components/DevframePanel.svelte +123 -0
- package/dist/components/DevframePanel.svelte.d.ts +3 -0
- package/dist/components/EditPage.svelte +4 -0
- package/dist/components/EditPage.svelte.d.ts +2 -0
- package/dist/components/ErrorSummary.svelte +52 -0
- package/dist/components/ErrorSummary.svelte.d.ts +14 -0
- package/dist/components/FieldRenderer.svelte +172 -99
- package/dist/components/FileUpload.svelte +412 -0
- package/dist/components/FileUpload.svelte.d.ts +43 -0
- package/dist/components/FilterBuilder.svelte +244 -265
- package/dist/components/FilterBuilder.svelte.d.ts +3 -0
- package/dist/components/FilterCollectionInput.svelte +80 -0
- package/dist/components/FilterCollectionInput.svelte.d.ts +10 -0
- package/dist/components/GanttChart.svelte +66 -14
- package/dist/components/GanttChart.svelte.d.ts +6 -0
- package/dist/components/Header.svelte +18 -2
- package/dist/components/ImportWizard.svelte +509 -100
- package/dist/components/ImportWizard.svelte.d.ts +11 -0
- package/dist/components/JsonSchemaForm.svelte +322 -98
- package/dist/components/JsonSchemaForm.svelte.d.ts +18 -1
- package/dist/components/KanbanBoard.svelte +195 -40
- package/dist/components/KanbanBoard.svelte.d.ts +9 -2
- package/dist/components/Layout.svelte +4 -3
- package/dist/components/LazyAutoForm.svelte +28 -0
- package/dist/components/LazyAutoForm.svelte.d.ts +8 -0
- package/dist/components/LazyAutoTable.svelte +28 -0
- package/dist/components/LazyAutoTable.svelte.d.ts +8 -0
- package/dist/components/LazySettingsPage.svelte +28 -0
- package/dist/components/LazySettingsPage.svelte.d.ts +8 -0
- package/dist/components/LazyShowPage.svelte +28 -0
- package/dist/components/LazyShowPage.svelte.d.ts +8 -0
- package/dist/components/LazyTaskQueueDrawer.svelte.d.ts +1 -1
- package/dist/components/ListPage.svelte +9 -1
- package/dist/components/ListPage.svelte.d.ts +5 -0
- package/dist/components/LoginPage.svelte +2 -2
- package/dist/components/MoneyInput.svelte +25 -0
- package/dist/components/MoneyInput.svelte.d.ts +20 -0
- package/dist/components/MultiTabKeepAlive.svelte +11 -6
- package/dist/components/NotificationsSettings.svelte +69 -2
- package/dist/components/NotificationsSettings.svelte.d.ts +25 -1
- package/dist/components/NumberInput.svelte +25 -0
- package/dist/components/NumberInput.svelte.d.ts +19 -0
- package/dist/components/NumericInput.svelte +110 -0
- package/dist/components/NumericInput.svelte.d.ts +23 -0
- package/dist/components/PercentInput.svelte +25 -0
- package/dist/components/PercentInput.svelte.d.ts +20 -0
- package/dist/components/PermissionMatrix.svelte +20 -1
- package/dist/components/PivotExportButton.svelte +157 -0
- package/dist/components/PivotExportButton.svelte.d.ts +16 -0
- package/dist/components/PivotTable.svelte +229 -74
- package/dist/components/PivotTable.svelte.d.ts +19 -2
- package/dist/components/QuickEditDrawer.svelte +4 -1
- package/dist/components/QuickEditDrawer.svelte.d.ts +2 -0
- package/dist/components/RadioGroup.svelte +121 -0
- package/dist/components/RadioGroup.svelte.d.ts +43 -0
- package/dist/components/RangeSlider.svelte +127 -0
- package/dist/components/RangeSlider.svelte.d.ts +22 -0
- package/dist/components/Rate.svelte +121 -0
- package/dist/components/Rate.svelte.d.ts +16 -0
- package/dist/components/RecordDetailDrawer.svelte +6 -2
- package/dist/components/RecordDetailDrawer.svelte.d.ts +4 -0
- package/dist/components/RelationPicker.svelte +341 -0
- package/dist/components/RelationPicker.svelte.d.ts +26 -0
- package/dist/components/ResourceOperationsPage.svelte +25 -19
- package/dist/components/ResourceOperationsPage.svelte.d.ts +5 -1
- package/dist/components/RetryTaskButton.svelte +12 -42
- package/dist/components/SecuritySettings.svelte +29 -5
- package/dist/components/SegmentedControl.svelte +145 -0
- package/dist/components/SegmentedControl.svelte.d.ts +38 -0
- package/dist/components/SettingsPage.svelte +3 -1
- package/dist/components/SettingsPage.svelte.d.ts +1 -0
- package/dist/components/ShowInferencer.svelte +4 -2
- package/dist/components/ShowInferencer.svelte.d.ts +2 -0
- package/dist/components/ShowPage.svelte +25 -6
- package/dist/components/ShowPage.svelte.d.ts +5 -0
- package/dist/components/Sidebar.svelte +5 -5
- package/dist/components/Slider.svelte +100 -0
- package/dist/components/Slider.svelte.d.ts +19 -0
- package/dist/components/SpreadsheetView.svelte +1037 -124
- package/dist/components/SpreadsheetView.svelte.d.ts +19 -0
- package/dist/components/StepsForm.svelte +5 -5
- package/dist/components/SvarAutoTable.svelte +39 -0
- package/dist/components/SvarAutoTable.svelte.d.ts +13 -0
- package/dist/components/SvarDataGrid.svelte +362 -0
- package/dist/components/SvarDataGrid.svelte.d.ts +57 -0
- package/dist/components/SvarGridCell.svelte +10 -0
- package/dist/components/SvarGridCell.svelte.d.ts +7 -0
- package/dist/components/SvarResourceRead.svelte +50 -0
- package/dist/components/SvarResourceRead.svelte.d.ts +23 -0
- package/dist/components/SvarResourceTable.svelte +63 -0
- package/dist/components/SvarResourceTable.svelte.d.ts +42 -0
- package/dist/components/SvarResourceTableView.svelte +364 -0
- package/dist/components/SvarResourceTableView.svelte.d.ts +4 -0
- package/dist/components/TagsInput.svelte +178 -0
- package/dist/components/TagsInput.svelte.d.ts +17 -0
- package/dist/components/TaskQueueDrawer.svelte +72 -16
- package/dist/components/TimePicker.svelte +10 -0
- package/dist/components/TimePicker.svelte.d.ts +6 -0
- package/dist/components/TreeSelect.svelte +440 -46
- package/dist/components/TreeSelect.svelte.d.ts +6 -1
- package/dist/components/TreeTable.svelte +484 -82
- package/dist/components/TreeTable.svelte.d.ts +24 -1
- package/dist/components/TwoFactorAuthPage.svelte +85 -48
- package/dist/components/TwoFactorAuthPage.svelte.d.ts +12 -1
- package/dist/components/VirtualTable.svelte +116 -20
- package/dist/components/VirtualTable.svelte.d.ts +5 -0
- package/dist/components/account/CompanyProfilePage.svelte +74 -38
- package/dist/components/account/GetStartedPage.svelte +2 -1
- package/dist/components/account/ImportMembersPage.svelte +22 -167
- package/dist/components/account/ImportMembersPage.svelte.d.ts +4 -1
- package/dist/components/account/MemberDirectory.svelte +156 -0
- package/dist/components/account/MemberDirectory.svelte.d.ts +19 -0
- package/dist/components/account/MembersStarterPage.svelte +9 -55
- package/dist/components/account/MembersStarterPage.svelte.d.ts +5 -1
- package/dist/components/account/SecurityLogPage.svelte +4 -1
- package/dist/components/account/SettingsPlainPage.svelte +7 -38
- package/dist/components/account/SettingsPlainPage.svelte.d.ts +4 -1
- package/dist/components/account/SettingsSidebarPage.svelte +7 -20
- package/dist/components/account/TeamMembersPage.svelte +4 -20
- package/dist/components/account/TeamMembersPage.svelte.d.ts +5 -1
- package/dist/components/account/UserProfilePage.svelte +3 -25
- package/dist/components/account/UserProfilePage.svelte.d.ts +17 -2
- package/dist/components/auto-table-grid.d.ts +26 -0
- package/dist/components/auto-table-grid.js +1 -0
- package/dist/components/buttons/ExportButton.svelte +56 -12
- package/dist/components/buttons/ExportButton.svelte.d.ts +11 -0
- package/dist/components/content/ContentPageHeader.svelte +12 -9
- package/dist/components/content/ContentPageShell.svelte +6 -9
- package/dist/components/content/FileBrowser.svelte +35 -0
- package/dist/components/content/FileBrowser.svelte.d.ts +14 -0
- package/dist/components/content/MetricBlock.svelte +10 -13
- package/dist/components/content/NetworkTable.svelte +3 -3
- package/dist/components/content/NetworkTable.svelte.d.ts +1 -0
- package/dist/components/content/PageToolbar.svelte +6 -10
- package/dist/components/content/ReferenceNotice.svelte +5 -0
- package/dist/components/content/ReferenceNotice.svelte.d.ts +18 -0
- package/dist/components/content/SectionHeader.svelte +8 -13
- package/dist/components/content/SettingsFieldRow.svelte +9 -23
- package/dist/components/content/SettingsGroup.svelte +11 -27
- package/dist/components/content/StatusBadge.svelte +3 -8
- package/dist/components/content/WorkspaceLayout.svelte +8 -12
- package/dist/components/enterprise/filter-tree.d.ts +48 -0
- package/dist/components/enterprise/filter-tree.js +224 -0
- package/dist/components/enterprise/json-schema-form.d.ts +39 -0
- package/dist/components/enterprise/json-schema-form.js +195 -0
- package/dist/components/enterprise/recursive-schema-form.d.ts +30 -0
- package/dist/components/enterprise/recursive-schema-form.js +196 -0
- package/dist/components/enterprise/spreadsheet-formula.d.ts +12 -0
- package/dist/components/enterprise/spreadsheet-formula.js +245 -0
- package/dist/components/export-reference.d.ts +2 -0
- package/dist/components/export-reference.js +9 -0
- package/dist/components/fieldComponentMap.js +2 -0
- package/dist/components/fields/DateField.svelte +12 -12
- package/dist/components/fields/date-display.d.ts +6 -0
- package/dist/components/fields/date-display.js +24 -0
- package/dist/components/fields/date-field-value.d.ts +2 -0
- package/dist/components/fields/date-field-value.js +13 -0
- package/dist/components/json-schema-form-state.d.ts +37 -0
- package/dist/components/json-schema-form-state.js +168 -0
- package/dist/components/network/TeamCrewTablePage.svelte +6 -1
- package/dist/components/network/UserCardsNFTPage.svelte +2 -0
- package/dist/components/profile/PublicProfilePage.svelte +2 -0
- package/dist/components/record-detail.svelte.d.ts +3 -0
- package/dist/components/record-detail.svelte.js +10 -4
- package/dist/components/saved-list-views.d.ts +74 -1
- package/dist/components/saved-list-views.js +191 -3
- package/dist/components/svar-grid-cells.d.ts +14 -0
- package/dist/components/svar-grid-cells.js +2 -0
- package/dist/components/svar-grid-contract.d.ts +80 -0
- package/dist/components/svar-grid-contract.js +159 -0
- package/dist/components/svar-grid-interactions.d.ts +54 -0
- package/dist/components/svar-grid-interactions.js +174 -0
- package/dist/components/svar-grid-loading.d.ts +40 -0
- package/dist/components/svar-grid-loading.js +180 -0
- package/dist/components/svar-grid-operations.d.ts +37 -0
- package/dist/components/svar-grid-operations.js +186 -0
- package/dist/components/svar-grid-panes.d.ts +34 -0
- package/dist/components/svar-grid-panes.js +66 -0
- package/dist/components/svar-grid-resource-loading.d.ts +18 -0
- package/dist/components/svar-grid-resource-loading.js +68 -0
- package/dist/components/svar-grid-resource-session.svelte.d.ts +29 -0
- package/dist/components/svar-grid-resource-session.svelte.js +61 -0
- package/dist/components/table-contract.d.ts +12 -1
- package/dist/components/task-action.svelte.d.ts +13 -0
- package/dist/components/task-action.svelte.js +73 -0
- package/dist/components/ui/DesignSystemShowcase.svelte +164 -0
- package/dist/components/ui/DesignSystemShowcase.svelte.d.ts +3 -0
- package/dist/components/ui/badge/badge-variants.d.ts +3 -2
- package/dist/components/ui/badge/badge-variants.js +2 -1
- package/dist/components/ui/badge/badge.svelte +3 -0
- package/dist/components/ui/badge/badge.svelte.d.ts +1 -0
- package/dist/components/ui/button/button-variants.d.ts +5 -4
- package/dist/components/ui/button/button-variants.js +7 -2
- package/dist/components/ui/checkbox/checkbox.svelte +5 -1
- package/dist/components/ui/checkbox/checkbox.svelte.d.ts +5 -1
- package/dist/components/ui/input/input.svelte +8 -6
- package/dist/components/ui/input/input.svelte.d.ts +4 -1
- package/dist/components/ui/select/select.svelte +4 -1
- package/dist/components/ui/select/select.svelte.d.ts +2 -1
- package/dist/components/ui/textarea/textarea.svelte +2 -1
- package/dist/components.css +3110 -0
- package/dist/date-input-policy.d.ts +4 -0
- package/dist/date-input-policy.js +35 -0
- package/dist/design-contract.d.ts +13 -0
- package/dist/design-contract.js +11 -0
- package/dist/design-system-components.d.ts +100 -0
- package/dist/design-system-components.js +101 -0
- package/dist/design-system.d.ts +15 -0
- package/dist/design-system.js +7 -0
- package/dist/devtools-bridge.d.ts +80 -0
- package/dist/devtools-bridge.js +92 -0
- package/dist/index.d.ts +50 -1
- package/dist/index.js +32 -2
- package/dist/page-chrome.css +12 -49
- package/dist/recipes.d.ts +960 -0
- package/dist/recipes.js +264 -0
- package/dist/rendering/index.d.ts +87 -0
- package/dist/rendering/index.js +117 -0
- package/dist/styles/aliases.css +49 -0
- package/dist/styles/compatibility.epilogue.css +384 -0
- package/dist/styles/compatibility.prelude.css +5513 -0
- package/dist/styles/conditional-states.css +28 -0
- package/dist/styles/conditional-utilities.css +22 -0
- package/dist/tree-table-model.d.ts +24 -0
- package/dist/tree-table-model.js +111 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/package.json +40 -10
- package/styles-compatibility.json +12 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { ResourceRendering } from '../rendering/index.js';
|
|
1
2
|
import type { Snippet } from 'svelte';
|
|
2
3
|
interface Props {
|
|
3
4
|
resourceName: string;
|
|
5
|
+
rendering?: ResourceRendering | undefined;
|
|
4
6
|
title?: string;
|
|
5
7
|
density?: 'compact' | 'comfortable';
|
|
6
8
|
columns?: 1 | 2 | 3 | 4;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Loader2, RefreshCw } from '@lucide/svelte';
|
|
3
|
+
import {
|
|
4
|
+
DashboardContractError, captureAdminContext, captureAuthSession, createEnterpriseRequestContext,
|
|
5
|
+
decodeDashboardQuery, decodeDashboardSnapshot,
|
|
6
|
+
} from '@svadmin/core';
|
|
7
|
+
import type { DashboardProvider, DashboardSnapshot, EnterpriseProviderRequestContext } from '@svadmin/core';
|
|
8
|
+
import { useTranslation } from '@svadmin/core/i18n';
|
|
9
|
+
import { onDestroy, untrack } from 'svelte';
|
|
10
|
+
import MetricStrip, { type MetricStripItem } from './MetricStrip.svelte';
|
|
11
|
+
import { Button } from './ui/button/index.js';
|
|
12
|
+
|
|
13
|
+
interface Props {
|
|
14
|
+
provider: DashboardProvider;
|
|
15
|
+
dashboardId: string;
|
|
16
|
+
requestContext?: EnterpriseProviderRequestContext;
|
|
17
|
+
filters?: readonly { field: string; value: string | number | boolean | null }[];
|
|
18
|
+
title?: string;
|
|
19
|
+
}
|
|
20
|
+
let { provider, dashboardId, requestContext, filters = [], title }: Props = $props();
|
|
21
|
+
const context = captureAdminContext();
|
|
22
|
+
const i18n = useTranslation();
|
|
23
|
+
let snapshot = $state<DashboardSnapshot>();
|
|
24
|
+
let loading = $state(false);
|
|
25
|
+
let error = $state<'load' | 'invalid'>();
|
|
26
|
+
let epoch = 0;
|
|
27
|
+
let mounted = true;
|
|
28
|
+
let generatedContext: EnterpriseProviderRequestContext | undefined;
|
|
29
|
+
onDestroy(() => { mounted = false; });
|
|
30
|
+
|
|
31
|
+
function resolveContext(): EnterpriseProviderRequestContext {
|
|
32
|
+
if (requestContext) return requestContext;
|
|
33
|
+
const tenant = context.tenantCacheKey?.__svadminTenant;
|
|
34
|
+
if (typeof tenant !== 'string' && typeof tenant !== 'number') throw new Error('Missing tenant context');
|
|
35
|
+
if (generatedContext?.tenantId === tenant) return generatedContext;
|
|
36
|
+
generatedContext = createEnterpriseRequestContext({ tenantId: tenant });
|
|
37
|
+
return generatedContext;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function load(): Promise<void> {
|
|
41
|
+
const currentEpoch = ++epoch;
|
|
42
|
+
loading = true;
|
|
43
|
+
error = undefined;
|
|
44
|
+
try {
|
|
45
|
+
const request = decodeDashboardQuery({
|
|
46
|
+
dashboardId: dashboardId.trim(),
|
|
47
|
+
...(filters.length ? { filters: filters.map(filter => ({ ...filter })) } : {}),
|
|
48
|
+
});
|
|
49
|
+
const result = decodeDashboardSnapshot(await provider.get(resolveContext(), request));
|
|
50
|
+
if (!mounted || currentEpoch !== epoch) return;
|
|
51
|
+
snapshot = result;
|
|
52
|
+
} catch (cause) {
|
|
53
|
+
if (!mounted || currentEpoch !== epoch) return;
|
|
54
|
+
snapshot = undefined;
|
|
55
|
+
error = cause instanceof DashboardContractError ? 'invalid' : 'load';
|
|
56
|
+
} finally {
|
|
57
|
+
if (mounted && currentEpoch === epoch) loading = false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const metricItems = $derived<MetricStripItem[]>(snapshot?.widgets.flatMap(widget =>
|
|
62
|
+
widget.kind === 'metric' ? widget.metrics.map(metric => ({
|
|
63
|
+
id: `${widget.id}:${metric.id}`, label: metric.label,
|
|
64
|
+
value: typeof metric.value === 'boolean' ? String(metric.value) : metric.value ?? '—',
|
|
65
|
+
...(metric.tone ? { tone: metric.tone } : {}),
|
|
66
|
+
...(metric.href ? { href: metric.href } : {}),
|
|
67
|
+
})) : [],
|
|
68
|
+
) ?? []);
|
|
69
|
+
|
|
70
|
+
$effect(() => {
|
|
71
|
+
void provider; void dashboardId; void requestContext; void filters;
|
|
72
|
+
void captureAuthSession(context.authProvider).cacheKey;
|
|
73
|
+
untrack(() => { snapshot = undefined; void load(); });
|
|
74
|
+
});
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<section class="svadmin-dashboard-view" aria-label={title ?? i18n.t('dashboard.title')}>
|
|
78
|
+
<header class="svadmin-dashboard-view__header">
|
|
79
|
+
<h2>{title ?? i18n.t('dashboard.title')}</h2>
|
|
80
|
+
<Button type="button" variant="outline" size="sm" aria-label={i18n.t('common.refresh')} onclick={() => void load()}>
|
|
81
|
+
<RefreshCw aria-hidden="true" class={loading ? 'svadmin-dashboard-view__spin' : undefined} />
|
|
82
|
+
</Button>
|
|
83
|
+
</header>
|
|
84
|
+
{#if loading}<div role="status"><Loader2 aria-hidden="true" /> {i18n.t('common.loading')}</div>
|
|
85
|
+
{:else if error}<div role="alert">{i18n.t(`dashboard.${error}`)}</div>
|
|
86
|
+
{:else if snapshot}
|
|
87
|
+
{#each snapshot.widgets.filter(widget => widget.kind === 'text') as widget (widget.id)}
|
|
88
|
+
<section aria-labelledby={`dashboard-widget-${widget.id}`}><h3 id={`dashboard-widget-${widget.id}`}>{widget.title}</h3><p>{widget.text}</p></section>
|
|
89
|
+
{/each}
|
|
90
|
+
<MetricStrip items={metricItems} ariaLabel={title ?? i18n.t('dashboard.metrics')} />
|
|
91
|
+
{:else}<div role="status">{i18n.t('dashboard.empty')}</div>{/if}
|
|
92
|
+
</section>
|
|
93
|
+
|
|
94
|
+
<style>
|
|
95
|
+
.svadmin-dashboard-view { display: grid; gap: 1rem; min-width: 0; }
|
|
96
|
+
.svadmin-dashboard-view__header { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
|
|
97
|
+
:global(.svadmin-dashboard-view__spin) { animation: svadmin-dashboard-spin 1s linear infinite; }
|
|
98
|
+
@keyframes svadmin-dashboard-spin { to { transform: rotate(360deg); } }
|
|
99
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DashboardProvider, EnterpriseProviderRequestContext } from '@svadmin/core';
|
|
2
|
+
interface Props {
|
|
3
|
+
provider: DashboardProvider;
|
|
4
|
+
dashboardId: string;
|
|
5
|
+
requestContext?: EnterpriseProviderRequestContext;
|
|
6
|
+
filters?: readonly {
|
|
7
|
+
field: string;
|
|
8
|
+
value: string | number | boolean | null;
|
|
9
|
+
}[];
|
|
10
|
+
title?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const DashboardView: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type DashboardView = ReturnType<typeof DashboardView>;
|
|
14
|
+
export default DashboardView;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ComponentProps } from 'svelte';
|
|
3
|
+
import DateTimeInput from './DateTimeInput.svelte';
|
|
4
|
+
|
|
5
|
+
export type DatePickerProps = Omit<ComponentProps<typeof DateTimeInput>, 'mode'>;
|
|
6
|
+
|
|
7
|
+
let props: DatePickerProps = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<DateTimeInput {...props} mode="date" />
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ComponentProps } from 'svelte';
|
|
2
|
+
import DateTimeInput from './DateTimeInput.svelte';
|
|
3
|
+
export type DatePickerProps = Omit<ComponentProps<typeof DateTimeInput>, 'mode'>;
|
|
4
|
+
declare const DatePicker: import("svelte").Component<DatePickerProps, {}, "">;
|
|
5
|
+
type DatePicker = ReturnType<typeof DatePicker>;
|
|
6
|
+
export default DatePicker;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { definedOptions } from '@svadmin/core/options';
|
|
3
|
+
import DateTimeInput, { type DateTimeInputMode } from './DateTimeInput.svelte';
|
|
4
|
+
import { cn } from '../utils.js';
|
|
5
|
+
import { useTranslation } from '@svadmin/core/i18n';
|
|
6
|
+
import { dateInputAllowed, dateInputNumber } from '../date-input-policy.js';
|
|
7
|
+
import { Select } from './ui/select/index.js';
|
|
8
|
+
import type { DateInputOptions } from '@svadmin/core';
|
|
9
|
+
import { formatCivilDateTime, parseDateTimeInstant, type DateTimeValueMode, type DateTimeDisambiguation } from '@svadmin/core/date-time';
|
|
10
|
+
|
|
11
|
+
export interface DateRangeInputValue {
|
|
12
|
+
start: string | null;
|
|
13
|
+
end: string | null;
|
|
14
|
+
}
|
|
15
|
+
export type DateRangePreset = NonNullable<DateInputOptions['presets']>[number];
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
value?: DateRangeInputValue | null;
|
|
19
|
+
mode?: DateTimeInputMode;
|
|
20
|
+
valueMode?: DateTimeValueMode;
|
|
21
|
+
timeZone?: string;
|
|
22
|
+
disambiguation?: DateTimeDisambiguation;
|
|
23
|
+
min?: string;
|
|
24
|
+
max?: string;
|
|
25
|
+
step?: number;
|
|
26
|
+
disabledDate?: (date: string) => boolean;
|
|
27
|
+
presets?: DateRangePreset[];
|
|
28
|
+
startId?: string;
|
|
29
|
+
endId?: string;
|
|
30
|
+
startName?: string;
|
|
31
|
+
endName?: string;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
required?: boolean;
|
|
34
|
+
invalid?: boolean;
|
|
35
|
+
describedby?: string;
|
|
36
|
+
startAriaLabel?: string;
|
|
37
|
+
endAriaLabel?: string;
|
|
38
|
+
class?: string;
|
|
39
|
+
onchange?: (value: DateRangeInputValue) => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let {
|
|
43
|
+
value = $bindable({ start: null, end: null }),
|
|
44
|
+
mode = 'date',
|
|
45
|
+
valueMode = 'civil',
|
|
46
|
+
timeZone,
|
|
47
|
+
disambiguation = 'reject',
|
|
48
|
+
min,
|
|
49
|
+
max,
|
|
50
|
+
step,
|
|
51
|
+
disabledDate,
|
|
52
|
+
presets = [],
|
|
53
|
+
startId,
|
|
54
|
+
endId,
|
|
55
|
+
startName,
|
|
56
|
+
endName,
|
|
57
|
+
disabled = false,
|
|
58
|
+
required = false,
|
|
59
|
+
invalid = false,
|
|
60
|
+
describedby,
|
|
61
|
+
startAriaLabel,
|
|
62
|
+
endAriaLabel,
|
|
63
|
+
class: className = '',
|
|
64
|
+
onchange,
|
|
65
|
+
}: Props = $props();
|
|
66
|
+
|
|
67
|
+
const i18n = useTranslation();
|
|
68
|
+
const instantMode = $derived(valueMode === 'instant');
|
|
69
|
+
const startMax = $derived(!instantMode && value?.end && (!max || value.end < max) ? value.end : max);
|
|
70
|
+
const endMin = $derived(!instantMode && value?.start && (!min || value.start > min) ? value.start : min);
|
|
71
|
+
function validInstant(value: string | null | undefined): string | undefined {
|
|
72
|
+
return value && parseDateTimeInstant(value) !== undefined ? value : undefined;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function presetAllowed(preset: DateRangePreset): boolean {
|
|
76
|
+
const { start, end } = preset.value;
|
|
77
|
+
if (instantMode) {
|
|
78
|
+
if (mode !== 'datetime' || !timeZone) return false;
|
|
79
|
+
const first = parseDateTimeInstant(start);
|
|
80
|
+
const last = parseDateTimeInstant(end);
|
|
81
|
+
if (first === undefined || last === undefined || first > last) return false;
|
|
82
|
+
const firstDraft = formatCivilDateTime(first, timeZone);
|
|
83
|
+
const lastDraft = formatCivilDateTime(last, timeZone);
|
|
84
|
+
return firstDraft !== undefined && lastDraft !== undefined
|
|
85
|
+
&& dateInputAllowed(firstDraft, mode, min, max, disabledDate)
|
|
86
|
+
&& dateInputAllowed(lastDraft, mode, min, max, disabledDate);
|
|
87
|
+
}
|
|
88
|
+
const first = dateInputNumber(start, mode);
|
|
89
|
+
const last = dateInputNumber(end, mode);
|
|
90
|
+
return first !== undefined && last !== undefined && first <= last
|
|
91
|
+
&& dateInputAllowed(start, mode, min, max, disabledDate)
|
|
92
|
+
&& dateInputAllowed(end, mode, min, max, disabledDate);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function choosePreset(event: Event): void {
|
|
96
|
+
const select = event.currentTarget;
|
|
97
|
+
if (!(select instanceof HTMLSelectElement)) return;
|
|
98
|
+
const preset = select.value === '' ? undefined : presets[Number(select.value)];
|
|
99
|
+
select.value = '';
|
|
100
|
+
if (disabled || !preset || !presetAllowed(preset)) return;
|
|
101
|
+
const result = { ...preset.value };
|
|
102
|
+
value = result;
|
|
103
|
+
onchange?.(result);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function update(part: 'start' | 'end', next: string | null): void {
|
|
107
|
+
const result: DateRangeInputValue = { start: value?.start ?? null, end: value?.end ?? null, [part]: next };
|
|
108
|
+
value = result;
|
|
109
|
+
onchange?.(result);
|
|
110
|
+
}
|
|
111
|
+
</script>
|
|
112
|
+
|
|
113
|
+
<div class={cn('svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-421ac2be5045', className)} data-date-range-input>
|
|
114
|
+
{#if presets.length > 0}
|
|
115
|
+
<Select value="" {disabled} aria-label={i18n.t('dateInput.presets')} onchange={choosePreset}>
|
|
116
|
+
<option value="">{i18n.t('dateInput.presets')}</option>
|
|
117
|
+
{#each presets as preset, index (index)}
|
|
118
|
+
<option value={String(index)} disabled={!presetAllowed(preset)}>{preset.label}</option>
|
|
119
|
+
{/each}
|
|
120
|
+
</Select>
|
|
121
|
+
{/if}
|
|
122
|
+
<DateTimeInput
|
|
123
|
+
value={value?.start ?? null}
|
|
124
|
+
{mode}
|
|
125
|
+
{valueMode}
|
|
126
|
+
{disambiguation}
|
|
127
|
+
{...definedOptions({
|
|
128
|
+
timeZone, min, max: startMax, step, disabledDate,
|
|
129
|
+
id: startId, name: startName, describedby,
|
|
130
|
+
maxInstant: instantMode ? validInstant(value?.end) : undefined,
|
|
131
|
+
})}
|
|
132
|
+
{disabled}
|
|
133
|
+
{required}
|
|
134
|
+
{invalid}
|
|
135
|
+
ariaLabel={startAriaLabel ?? i18n.t('common.startDate')}
|
|
136
|
+
onchange={(next) => update('start', next)}
|
|
137
|
+
/>
|
|
138
|
+
<span aria-hidden="true">{i18n.t('dateInput.to')}</span>
|
|
139
|
+
<DateTimeInput
|
|
140
|
+
value={value?.end ?? null}
|
|
141
|
+
{mode}
|
|
142
|
+
{valueMode}
|
|
143
|
+
{disambiguation}
|
|
144
|
+
{...definedOptions({
|
|
145
|
+
timeZone, min: endMin, max, step, disabledDate,
|
|
146
|
+
id: endId, name: endName, describedby,
|
|
147
|
+
minInstant: instantMode ? validInstant(value?.start) : undefined,
|
|
148
|
+
})}
|
|
149
|
+
{disabled}
|
|
150
|
+
{required}
|
|
151
|
+
{invalid}
|
|
152
|
+
ariaLabel={endAriaLabel ?? i18n.t('common.endDate')}
|
|
153
|
+
onchange={(next) => update('end', next)}
|
|
154
|
+
/>
|
|
155
|
+
</div>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type DateTimeInputMode } from './DateTimeInput.svelte';
|
|
2
|
+
import type { DateInputOptions } from '@svadmin/core';
|
|
3
|
+
import { type DateTimeValueMode, type DateTimeDisambiguation } from '@svadmin/core/date-time';
|
|
4
|
+
export interface DateRangeInputValue {
|
|
5
|
+
start: string | null;
|
|
6
|
+
end: string | null;
|
|
7
|
+
}
|
|
8
|
+
export type DateRangePreset = NonNullable<DateInputOptions['presets']>[number];
|
|
9
|
+
interface Props {
|
|
10
|
+
value?: DateRangeInputValue | null;
|
|
11
|
+
mode?: DateTimeInputMode;
|
|
12
|
+
valueMode?: DateTimeValueMode;
|
|
13
|
+
timeZone?: string;
|
|
14
|
+
disambiguation?: DateTimeDisambiguation;
|
|
15
|
+
min?: string;
|
|
16
|
+
max?: string;
|
|
17
|
+
step?: number;
|
|
18
|
+
disabledDate?: (date: string) => boolean;
|
|
19
|
+
presets?: DateRangePreset[];
|
|
20
|
+
startId?: string;
|
|
21
|
+
endId?: string;
|
|
22
|
+
startName?: string;
|
|
23
|
+
endName?: string;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
required?: boolean;
|
|
26
|
+
invalid?: boolean;
|
|
27
|
+
describedby?: string;
|
|
28
|
+
startAriaLabel?: string;
|
|
29
|
+
endAriaLabel?: string;
|
|
30
|
+
class?: string;
|
|
31
|
+
onchange?: (value: DateRangeInputValue) => void;
|
|
32
|
+
}
|
|
33
|
+
declare const DateRangeInput: import("svelte").Component<Props, {}, "value">;
|
|
34
|
+
type DateRangeInput = ReturnType<typeof DateRangeInput>;
|
|
35
|
+
export default DateRangeInput;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ComponentProps } from 'svelte';
|
|
3
|
+
import DateRangeInput from './DateRangeInput.svelte';
|
|
4
|
+
|
|
5
|
+
export type DateRangePickerProps = Omit<ComponentProps<typeof DateRangeInput>, 'mode'>;
|
|
6
|
+
|
|
7
|
+
let props: DateRangePickerProps = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<DateRangeInput {...props} mode="date" />
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ComponentProps } from 'svelte';
|
|
2
|
+
import DateRangeInput from './DateRangeInput.svelte';
|
|
3
|
+
export type DateRangePickerProps = Omit<ComponentProps<typeof DateRangeInput>, 'mode'>;
|
|
4
|
+
declare const DateRangePicker: import("svelte").Component<DateRangePickerProps, {}, "">;
|
|
5
|
+
type DateRangePicker = ReturnType<typeof DateRangePicker>;
|
|
6
|
+
export default DateRangePicker;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Input } from './ui/input/index.js';
|
|
3
|
+
import { cn } from '../utils.js';
|
|
4
|
+
import { useTranslation } from '@svadmin/core/i18n';
|
|
5
|
+
import { civilDateTimeToInstant, parseDateTimeInstant, formatCivilDateTime, type DateTimeValueMode, type DateTimeDisambiguation } from '@svadmin/core/date-time';
|
|
6
|
+
import { untrack } from 'svelte';
|
|
7
|
+
import { dateInputAllowed } from '../date-input-policy.js';
|
|
8
|
+
|
|
9
|
+
export type DateTimeInputMode = 'date' | 'time' | 'datetime';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
value?: string | null;
|
|
13
|
+
mode?: DateTimeInputMode;
|
|
14
|
+
min?: string;
|
|
15
|
+
max?: string;
|
|
16
|
+
minInstant?: string;
|
|
17
|
+
maxInstant?: string;
|
|
18
|
+
step?: number;
|
|
19
|
+
disabledDate?: (date: string) => boolean;
|
|
20
|
+
id?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
required?: boolean;
|
|
24
|
+
invalid?: boolean;
|
|
25
|
+
describedby?: string;
|
|
26
|
+
ariaLabel?: string;
|
|
27
|
+
class?: string;
|
|
28
|
+
onchange?: (value: string | null) => void;
|
|
29
|
+
timeZone?: string;
|
|
30
|
+
valueMode?: DateTimeValueMode;
|
|
31
|
+
disambiguation?: DateTimeDisambiguation;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let {
|
|
35
|
+
value = $bindable(null),
|
|
36
|
+
mode = 'date',
|
|
37
|
+
min,
|
|
38
|
+
max,
|
|
39
|
+
minInstant,
|
|
40
|
+
maxInstant,
|
|
41
|
+
step,
|
|
42
|
+
disabledDate,
|
|
43
|
+
id,
|
|
44
|
+
name,
|
|
45
|
+
disabled = false,
|
|
46
|
+
required = false,
|
|
47
|
+
invalid = false,
|
|
48
|
+
describedby,
|
|
49
|
+
ariaLabel,
|
|
50
|
+
class: className = '',
|
|
51
|
+
onchange,
|
|
52
|
+
timeZone,
|
|
53
|
+
valueMode = 'civil',
|
|
54
|
+
disambiguation = 'reject',
|
|
55
|
+
}: Props = $props();
|
|
56
|
+
|
|
57
|
+
const inputType = $derived(mode === 'datetime' ? 'datetime-local' : mode);
|
|
58
|
+
const i18n = useTranslation();
|
|
59
|
+
function toDraft(next: string | null | undefined): string {
|
|
60
|
+
if (!next) return '';
|
|
61
|
+
if (mode !== 'datetime' || valueMode === 'civil') return next;
|
|
62
|
+
const instant = parseDateTimeInstant(next);
|
|
63
|
+
return instant !== undefined && timeZone ? formatCivilDateTime(instant, timeZone) ?? '' : '';
|
|
64
|
+
}
|
|
65
|
+
function toValue(next: string): string | null {
|
|
66
|
+
if (next === '') return null;
|
|
67
|
+
if (mode !== 'datetime' || valueMode === 'civil') return next;
|
|
68
|
+
if (!timeZone) return null;
|
|
69
|
+
// 已带偏移的绑定值已确定重复小时中的具体时间点,不重新猜测。
|
|
70
|
+
if (value && next === toDraft(value) && parseDateTimeInstant(value) !== undefined) return value;
|
|
71
|
+
const instant = civilDateTimeToInstant(next, timeZone, disambiguation);
|
|
72
|
+
return instant === undefined ? null : new Date(instant).toISOString();
|
|
73
|
+
}
|
|
74
|
+
let draft = $state(untrack(() => toDraft(value)));
|
|
75
|
+
let inputRef = $state<HTMLInputElement | null>(null);
|
|
76
|
+
const instantMode = $derived(valueMode === 'instant');
|
|
77
|
+
function instantAllowed(next: string | null): boolean {
|
|
78
|
+
if (!instantMode || next === null) return true;
|
|
79
|
+
const instant = parseDateTimeInstant(next);
|
|
80
|
+
const lower = minInstant === undefined ? undefined : parseDateTimeInstant(minInstant);
|
|
81
|
+
const upper = maxInstant === undefined ? undefined : parseDateTimeInstant(maxInstant);
|
|
82
|
+
return instant !== undefined && (lower === undefined || instant >= lower) && (upper === undefined || instant <= upper);
|
|
83
|
+
}
|
|
84
|
+
const configurationInvalid = $derived(instantMode && (mode !== 'datetime'
|
|
85
|
+
|| !timeZone || formatCivilDateTime(0, timeZone) === undefined
|
|
86
|
+
|| minInstant !== undefined && parseDateTimeInstant(minInstant) === undefined
|
|
87
|
+
|| maxInstant !== undefined && parseDateTimeInstant(maxInstant) === undefined));
|
|
88
|
+
const boundValueInvalid = $derived(instantMode && !!value && toDraft(value) === '');
|
|
89
|
+
const policyInvalid = $derived(configurationInvalid || boundValueInvalid || draft !== '' && (
|
|
90
|
+
!dateInputAllowed(draft, mode, min, max, disabledDate)
|
|
91
|
+
|| instantMode && (toValue(draft) === null || !instantAllowed(toValue(draft)))
|
|
92
|
+
));
|
|
93
|
+
$effect.pre(() => {
|
|
94
|
+
void mode;
|
|
95
|
+
draft = toDraft(value);
|
|
96
|
+
});
|
|
97
|
+
$effect(() => {
|
|
98
|
+
inputRef?.setCustomValidity(policyInvalid ? i18n.t('dateInput.unavailable') : '');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
function handleInput(event: Event): void {
|
|
102
|
+
const input = event.currentTarget;
|
|
103
|
+
if (!(input instanceof HTMLInputElement) || disabled || configurationInvalid) return;
|
|
104
|
+
draft = input.value;
|
|
105
|
+
if (draft && !dateInputAllowed(draft, mode, min, max, disabledDate)) return;
|
|
106
|
+
const next = toValue(input.value);
|
|
107
|
+
if (input.value !== '' && next === null) return;
|
|
108
|
+
if (!instantAllowed(next)) return;
|
|
109
|
+
value = next;
|
|
110
|
+
onchange?.(next);
|
|
111
|
+
}
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<div class={cn('svadmin-u-6da6a3c3f741', className)} data-date-time-input={mode}>
|
|
115
|
+
{#if instantMode && name}
|
|
116
|
+
<input type="hidden" {name} value={value ?? ''} {disabled} />
|
|
117
|
+
{/if}
|
|
118
|
+
<Input
|
|
119
|
+
{id}
|
|
120
|
+
name={instantMode ? undefined : name}
|
|
121
|
+
type={inputType}
|
|
122
|
+
bind:ref={inputRef}
|
|
123
|
+
value={draft}
|
|
124
|
+
{min}
|
|
125
|
+
{max}
|
|
126
|
+
{step}
|
|
127
|
+
{disabled}
|
|
128
|
+
{required}
|
|
129
|
+
aria-invalid={invalid || policyInvalid || undefined}
|
|
130
|
+
aria-describedby={describedby}
|
|
131
|
+
aria-label={ariaLabel}
|
|
132
|
+
oninput={handleInput}
|
|
133
|
+
/>
|
|
134
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type DateTimeValueMode, type DateTimeDisambiguation } from '@svadmin/core/date-time';
|
|
2
|
+
export type DateTimeInputMode = 'date' | 'time' | 'datetime';
|
|
3
|
+
interface Props {
|
|
4
|
+
value?: string | null;
|
|
5
|
+
mode?: DateTimeInputMode;
|
|
6
|
+
min?: string;
|
|
7
|
+
max?: string;
|
|
8
|
+
minInstant?: string;
|
|
9
|
+
maxInstant?: string;
|
|
10
|
+
step?: number;
|
|
11
|
+
disabledDate?: (date: string) => boolean;
|
|
12
|
+
id?: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
required?: boolean;
|
|
16
|
+
invalid?: boolean;
|
|
17
|
+
describedby?: string;
|
|
18
|
+
ariaLabel?: string;
|
|
19
|
+
class?: string;
|
|
20
|
+
onchange?: (value: string | null) => void;
|
|
21
|
+
timeZone?: string;
|
|
22
|
+
valueMode?: DateTimeValueMode;
|
|
23
|
+
disambiguation?: DateTimeDisambiguation;
|
|
24
|
+
}
|
|
25
|
+
declare const DateTimeInput: import("svelte").Component<Props, {}, "value">;
|
|
26
|
+
type DateTimeInput = ReturnType<typeof DateTimeInput>;
|
|
27
|
+
export default DateTimeInput;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ComponentProps } from 'svelte';
|
|
3
|
+
import DateTimeInput from './DateTimeInput.svelte';
|
|
4
|
+
|
|
5
|
+
export type DateTimePickerProps = Omit<ComponentProps<typeof DateTimeInput>, 'mode'>;
|
|
6
|
+
|
|
7
|
+
let props: DateTimePickerProps = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<DateTimeInput {...props} mode="datetime" />
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ComponentProps } from 'svelte';
|
|
2
|
+
import DateTimeInput from './DateTimeInput.svelte';
|
|
3
|
+
export type DateTimePickerProps = Omit<ComponentProps<typeof DateTimeInput>, 'mode'>;
|
|
4
|
+
declare const DateTimePicker: import("svelte").Component<DateTimePickerProps, {}, "">;
|
|
5
|
+
type DateTimePicker = ReturnType<typeof DateTimePicker>;
|
|
6
|
+
export default DateTimePicker;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { onMount } from 'svelte';
|
|
3
|
+
import { DEV } from 'esm-env';
|
|
3
4
|
import { SvelteMap } from 'svelte/reactivity';
|
|
4
5
|
import { fly } from 'svelte/transition';
|
|
5
6
|
import { useQueryClient } from '@tanstack/svelte-query';
|
|
@@ -10,6 +11,11 @@
|
|
|
10
11
|
parseQueryKey,
|
|
11
12
|
} from '@svadmin/core';
|
|
12
13
|
import { useTranslation } from '@svadmin/core/i18n';
|
|
14
|
+
import {
|
|
15
|
+
attachSvadminDevtoolsQueryClient,
|
|
16
|
+
installSvadminDevtoolsBridge,
|
|
17
|
+
publishSvadminDevtoolsSnapshot,
|
|
18
|
+
} from '../devtools-bridge.js';
|
|
13
19
|
|
|
14
20
|
import TooltipButton from './TooltipButton.svelte';
|
|
15
21
|
import * as Tabs from './ui/tabs/index.js';
|
|
@@ -19,34 +25,18 @@
|
|
|
19
25
|
import { X, Bug, ChevronDown, ChevronUp, Wand2 } from '@lucide/svelte';
|
|
20
26
|
import InferencerPanel from './InferencerPanel.svelte';
|
|
21
27
|
|
|
22
|
-
type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
type ProviderDiagnostic = {
|
|
28
|
-
name: string;
|
|
29
|
-
configured: boolean;
|
|
30
|
-
capabilities: string;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
type SafeQueryDiagnostic = {
|
|
34
|
-
provider: string;
|
|
35
|
-
resource: string;
|
|
36
|
-
operation: string;
|
|
37
|
-
status: string;
|
|
38
|
-
retries: number;
|
|
39
|
-
duration: string;
|
|
40
|
-
cacheAge: string;
|
|
41
|
-
invalidation: string;
|
|
42
|
-
};
|
|
28
|
+
import type {
|
|
29
|
+
DevtoolsCacheDiagnostics,
|
|
30
|
+
DevtoolsProviderDiagnostic,
|
|
31
|
+
DevtoolsQueryDiagnostic,
|
|
32
|
+
} from '../devtools-bridge.js';
|
|
43
33
|
|
|
44
|
-
const EMPTY_CACHE_DIAGNOSTICS:
|
|
34
|
+
const EMPTY_CACHE_DIAGNOSTICS: DevtoolsCacheDiagnostics = {
|
|
45
35
|
queries: { total: 0, fetching: 0, stale: 0, errors: 0 },
|
|
46
36
|
mutations: { total: 0, pending: 0, paused: 0, errors: 0 },
|
|
47
37
|
};
|
|
48
38
|
|
|
49
|
-
const isDev =
|
|
39
|
+
const isDev = DEV;
|
|
50
40
|
const i18n = useTranslation();
|
|
51
41
|
const queryClient = useQueryClient();
|
|
52
42
|
const adminContext = captureAdminContext();
|
|
@@ -54,8 +44,8 @@
|
|
|
54
44
|
let { docked = false }: { docked?: boolean } = $props();
|
|
55
45
|
let visible = $state(false);
|
|
56
46
|
let collapsed = $state(false);
|
|
57
|
-
let cacheDiagnostics = $state.raw<
|
|
58
|
-
let safeQueryDiagnostics = $state.raw<
|
|
47
|
+
let cacheDiagnostics = $state.raw<DevtoolsCacheDiagnostics>(EMPTY_CACHE_DIAGNOSTICS);
|
|
48
|
+
let safeQueryDiagnostics = $state.raw<DevtoolsQueryDiagnostic[]>([]);
|
|
59
49
|
const queryTimings = new SvelteMap<string, { startedAt?: number; duration?: number }>();
|
|
60
50
|
|
|
61
51
|
function toggle() {
|
|
@@ -109,6 +99,8 @@
|
|
|
109
99
|
|
|
110
100
|
onMount(() => {
|
|
111
101
|
if (!isDev) return;
|
|
102
|
+
attachSvadminDevtoolsQueryClient(queryClient);
|
|
103
|
+
installSvadminDevtoolsBridge();
|
|
112
104
|
refreshCacheDiagnostics();
|
|
113
105
|
const unsubscribeQueries = queryClient.getQueryCache().subscribe((event) => {
|
|
114
106
|
// Observer events arrive in pairs during component rerenders. Refreshing diagnostics triggers another render,
|
|
@@ -163,7 +155,7 @@
|
|
|
163
155
|
}
|
|
164
156
|
});
|
|
165
157
|
|
|
166
|
-
const frameworkProviders = $derived.by(():
|
|
158
|
+
const frameworkProviders = $derived.by((): DevtoolsProviderDiagnostic[] => {
|
|
167
159
|
const access = adminContext.accessControlProvider;
|
|
168
160
|
const audit = adminContext.auditLogProvider;
|
|
169
161
|
const notification = adminContext.notificationProvider;
|
|
@@ -233,6 +225,22 @@
|
|
|
233
225
|
},
|
|
234
226
|
];
|
|
235
227
|
});
|
|
228
|
+
|
|
229
|
+
$effect(() => {
|
|
230
|
+
if (!isDev) return;
|
|
231
|
+
publishSvadminDevtoolsSnapshot({
|
|
232
|
+
version: 1,
|
|
233
|
+
environment: 'development',
|
|
234
|
+
route: path,
|
|
235
|
+
locale,
|
|
236
|
+
theme,
|
|
237
|
+
colorTheme,
|
|
238
|
+
resourceCount: resources.length,
|
|
239
|
+
providers: frameworkProviders,
|
|
240
|
+
cache: cacheDiagnostics,
|
|
241
|
+
queries: safeQueryDiagnostics,
|
|
242
|
+
});
|
|
243
|
+
});
|
|
236
244
|
</script>
|
|
237
245
|
|
|
238
246
|
<svelte:window onkeydown={isDev ? handleKeydown : undefined} />
|
|
@@ -241,8 +249,8 @@
|
|
|
241
249
|
{#if visible}
|
|
242
250
|
<div
|
|
243
251
|
class="svadmin-u-7bc555991dba svadmin-u-189f036c335c svadmin-u-5a438c30beec svadmin-u-f50571addf44 svadmin-u-11863ecc32e7 svadmin-u-c69e21ff5804 svadmin-u-1301e5c1ce71 svadmin-u-ca6bcd4b6f3f svadmin-u-d5e98261a758 svadmin-u-cd0ad9a56558 svadmin-u-14e46609fd68 svadmin-u-1d5904e7e755 svadmin-u-2cd02d11d1af"
|
|
244
|
-
class:
|
|
245
|
-
class:min-
|
|
252
|
+
class:svadmin-devtools--collapsed-width={collapsed}
|
|
253
|
+
class:svadmin-devtools--collapsed-min-width={collapsed}
|
|
246
254
|
transition:fly={{ y: 400, duration: 300 }}
|
|
247
255
|
>
|
|
248
256
|
<div class="svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-8ef2268efbbc svadmin-u-0e17f2bd9074 svadmin-u-03b4dd7f172b svadmin-u-2ef11f1cb219 svadmin-u-65fdbade2025">
|