@svadmin/ui 0.73.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 +53 -28
- package/dist/app.css +3733 -4119
- package/dist/app.theme.css +3733 -4119
- 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 +33 -3
- package/dist/components/AutoForm.svelte.d.ts +1 -0
- package/dist/components/AutoTable.svelte +610 -47
- package/dist/components/AutoTable.svelte.d.ts +17 -1
- package/dist/components/BoundRecordDetailDrawer.svelte +9 -0
- package/dist/components/BoundRecordDetailDrawer.svelte.d.ts +2 -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 +114 -27
- package/dist/components/ComboboxField.svelte.d.ts +1 -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 +85 -5
- package/dist/components/DateRangeInput.svelte.d.ts +10 -0
- package/dist/components/DateRangePicker.svelte +10 -0
- package/dist/components/DateRangePicker.svelte.d.ts +6 -0
- package/dist/components/DateTimeInput.svelte +74 -5
- package/dist/components/DateTimeInput.svelte.d.ts +8 -0
- package/dist/components/DateTimePicker.svelte +10 -0
- package/dist/components/DateTimePicker.svelte.d.ts +6 -0
- package/dist/components/DevTools.svelte +34 -26
- package/dist/components/DevframePanel.svelte +123 -0
- package/dist/components/DevframePanel.svelte.d.ts +3 -0
- package/dist/components/ErrorSummary.svelte +52 -0
- package/dist/components/ErrorSummary.svelte.d.ts +14 -0
- package/dist/components/FieldRenderer.svelte +82 -81
- package/dist/components/FileUpload.svelte +214 -52
- package/dist/components/FileUpload.svelte.d.ts +11 -0
- package/dist/components/FilterBuilder.svelte +88 -66
- 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 +339 -17
- package/dist/components/ImportWizard.svelte.d.ts +11 -0
- package/dist/components/JsonSchemaForm.svelte +120 -52
- package/dist/components/JsonSchemaForm.svelte.d.ts +7 -1
- package/dist/components/KanbanBoard.svelte +195 -40
- package/dist/components/KanbanBoard.svelte.d.ts +9 -2
- package/dist/components/Layout.svelte +4 -2
- 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/ListPage.svelte +5 -1
- package/dist/components/ListPage.svelte.d.ts +3 -0
- package/dist/components/LoginPage.svelte +1 -1
- 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/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/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 +4 -2
- package/dist/components/RecordDetailDrawer.svelte.d.ts +2 -0
- package/dist/components/RelationPicker.svelte +341 -0
- package/dist/components/RelationPicker.svelte.d.ts +26 -0
- package/dist/components/ResourceOperationsPage.svelte +18 -18
- package/dist/components/ResourceOperationsPage.svelte.d.ts +2 -2
- 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/ShowPage.svelte +18 -3
- package/dist/components/ShowPage.svelte.d.ts +3 -0
- package/dist/components/Sidebar.svelte +2 -2
- package/dist/components/Slider.svelte +100 -0
- package/dist/components/Slider.svelte.d.ts +19 -0
- package/dist/components/SpreadsheetView.svelte +1213 -95
- package/dist/components/SpreadsheetView.svelte.d.ts +19 -0
- package/dist/components/TagsInput.svelte +178 -0
- package/dist/components/TagsInput.svelte.d.ts +17 -0
- package/dist/components/TimePicker.svelte +10 -0
- package/dist/components/TimePicker.svelte.d.ts +6 -0
- package/dist/components/TreeSelect.svelte +267 -53
- package/dist/components/TreeSelect.svelte.d.ts +3 -0
- 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/buttons/ExportButton.svelte +56 -12
- package/dist/components/buttons/ExportButton.svelte.d.ts +11 -0
- package/dist/components/content/ContentPageHeader.svelte +1 -1
- package/dist/components/content/ContentPageShell.svelte +1 -1
- package/dist/components/content/MetricBlock.svelte +1 -1
- package/dist/components/content/PageToolbar.svelte +1 -1
- package/dist/components/content/ReferenceNotice.svelte +5 -0
- package/dist/components/content/ReferenceNotice.svelte.d.ts +18 -0
- package/dist/components/content/SectionHeader.svelte +1 -1
- package/dist/components/content/SettingsFieldRow.svelte +1 -1
- package/dist/components/content/SettingsGroup.svelte +1 -1
- package/dist/components/content/StatusBadge.svelte +1 -1
- package/dist/components/content/WorkspaceLayout.svelte +1 -1
- package/dist/components/export-reference.d.ts +2 -0
- package/dist/components/export-reference.js +9 -0
- package/dist/components/fieldComponentMap.js +2 -5
- package/dist/components/fields/DateField.svelte +12 -13
- package/dist/components/fields/date-display.d.ts +6 -0
- package/dist/components/fields/date-display.js +24 -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/saved-list-views.d.ts +74 -1
- package/dist/components/saved-list-views.js +191 -3
- 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 -3
- 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 -5
- 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 +7 -2
- 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 -2
- package/dist/components.css +33 -2
- package/dist/date-input-policy.d.ts +4 -0
- package/dist/date-input-policy.js +35 -0
- package/dist/design-system-components.d.ts +100 -0
- package/dist/design-system-components.js +101 -0
- package/dist/design-system.js +1 -1
- package/dist/devtools-bridge.d.ts +80 -0
- package/dist/devtools-bridge.js +92 -0
- package/dist/index.d.ts +37 -2
- package/dist/index.js +23 -2
- package/dist/recipes.d.ts +960 -4
- package/dist/recipes.js +264 -4
- package/dist/tree-table-model.d.ts +24 -0
- package/dist/tree-table-model.js +111 -0
- package/package.json +22 -10
- package/dist/styled-system/css/conditions.js +0 -36
- package/dist/styled-system/css/css.d.ts +0 -22
- package/dist/styled-system/css/css.js +0 -45
- package/dist/styled-system/css/cva.d.ts +0 -6
- package/dist/styled-system/css/cva.js +0 -87
- package/dist/styled-system/css/cx.d.ts +0 -5
- package/dist/styled-system/css/cx.js +0 -15
- package/dist/styled-system/css/index.d.ts +0 -5
- package/dist/styled-system/css/index.js +0 -4
- package/dist/styled-system/css/sva.d.ts +0 -4
- package/dist/styled-system/css/sva.js +0 -46
- package/dist/styled-system/helpers.js +0 -316
- package/dist/styled-system/patterns/aspect-ratio.d.ts +0 -20
- package/dist/styled-system/patterns/aspect-ratio.js +0 -38
- package/dist/styled-system/patterns/bleed.d.ts +0 -21
- package/dist/styled-system/patterns/bleed.js +0 -24
- package/dist/styled-system/patterns/box.d.ts +0 -20
- package/dist/styled-system/patterns/box.js +0 -15
- package/dist/styled-system/patterns/center.d.ts +0 -20
- package/dist/styled-system/patterns/center.js +0 -21
- package/dist/styled-system/patterns/circle.d.ts +0 -20
- package/dist/styled-system/patterns/circle.js +0 -25
- package/dist/styled-system/patterns/container.d.ts +0 -20
- package/dist/styled-system/patterns/container.js +0 -21
- package/dist/styled-system/patterns/cq.d.ts +0 -21
- package/dist/styled-system/patterns/cq.js +0 -21
- package/dist/styled-system/patterns/divider.d.ts +0 -22
- package/dist/styled-system/patterns/divider.js +0 -25
- package/dist/styled-system/patterns/flex.d.ts +0 -26
- package/dist/styled-system/patterns/flex.js +0 -26
- package/dist/styled-system/patterns/float.d.ts +0 -23
- package/dist/styled-system/patterns/float.js +0 -52
- package/dist/styled-system/patterns/grid-item.d.ts +0 -25
- package/dist/styled-system/patterns/grid-item.js +0 -25
- package/dist/styled-system/patterns/grid.d.ts +0 -24
- package/dist/styled-system/patterns/grid.js +0 -27
- package/dist/styled-system/patterns/hstack.d.ts +0 -21
- package/dist/styled-system/patterns/hstack.js +0 -24
- package/dist/styled-system/patterns/index.d.ts +0 -21
- package/dist/styled-system/patterns/index.js +0 -20
- package/dist/styled-system/patterns/link-overlay.d.ts +0 -20
- package/dist/styled-system/patterns/link-overlay.js +0 -24
- package/dist/styled-system/patterns/spacer.d.ts +0 -20
- package/dist/styled-system/patterns/spacer.js +0 -25
- package/dist/styled-system/patterns/square.d.ts +0 -20
- package/dist/styled-system/patterns/square.js +0 -24
- package/dist/styled-system/patterns/stack.d.ts +0 -23
- package/dist/styled-system/patterns/stack.js +0 -24
- package/dist/styled-system/patterns/visually-hidden.d.ts +0 -20
- package/dist/styled-system/patterns/visually-hidden.js +0 -18
- package/dist/styled-system/patterns/vstack.d.ts +0 -21
- package/dist/styled-system/patterns/vstack.js +0 -24
- package/dist/styled-system/patterns/wrap.d.ts +0 -24
- package/dist/styled-system/patterns/wrap.js +0 -25
- package/dist/styled-system/recipes/content-header.d.ts +0 -31
- package/dist/styled-system/recipes/content-header.js +0 -65
- package/dist/styled-system/recipes/content-page.d.ts +0 -34
- package/dist/styled-system/recipes/content-page.js +0 -43
- package/dist/styled-system/recipes/create-recipe.js +0 -82
- package/dist/styled-system/recipes/index.d.ts +0 -17
- package/dist/styled-system/recipes/index.js +0 -16
- package/dist/styled-system/recipes/metric-block.d.ts +0 -34
- package/dist/styled-system/recipes/metric-block.js +0 -76
- package/dist/styled-system/recipes/product-list.d.ts +0 -31
- package/dist/styled-system/recipes/product-list.js +0 -73
- package/dist/styled-system/recipes/product-section.d.ts +0 -31
- package/dist/styled-system/recipes/product-section.js +0 -49
- package/dist/styled-system/recipes/product-settings-row.d.ts +0 -34
- package/dist/styled-system/recipes/product-settings-row.js +0 -58
- package/dist/styled-system/recipes/product-settings.d.ts +0 -31
- package/dist/styled-system/recipes/product-settings.js +0 -57
- package/dist/styled-system/recipes/product-status.d.ts +0 -34
- package/dist/styled-system/recipes/product-status.js +0 -45
- package/dist/styled-system/recipes/product-toolbar.d.ts +0 -31
- package/dist/styled-system/recipes/product-toolbar.js +0 -41
- package/dist/styled-system/recipes/product-workspace.d.ts +0 -34
- package/dist/styled-system/recipes/product-workspace.js +0 -58
- package/dist/styled-system/recipes/surface-metric.d.ts +0 -38
- package/dist/styled-system/recipes/surface-metric.js +0 -63
- package/dist/styled-system/recipes/surface-table.d.ts +0 -34
- package/dist/styled-system/recipes/surface-table.js +0 -62
- package/dist/styled-system/recipes/ui-badge.d.ts +0 -31
- package/dist/styled-system/recipes/ui-badge.js +0 -38
- package/dist/styled-system/recipes/ui-button.d.ts +0 -32
- package/dist/styled-system/recipes/ui-button.js +0 -43
- package/dist/styled-system/recipes/ui-input.d.ts +0 -31
- package/dist/styled-system/recipes/ui-input.js +0 -49
- package/dist/styled-system/recipes/ui-textarea.d.ts +0 -31
- package/dist/styled-system/recipes/ui-textarea.js +0 -24
- package/dist/styled-system/styles.css +0 -1257
- package/dist/styled-system/tokens/index.d.ts +0 -9
- package/dist/styled-system/tokens/index.js +0 -268
- package/dist/styled-system/tokens/tokens.d.ts +0 -36
- package/dist/styled-system/types/composition.d.ts +0 -227
- package/dist/styled-system/types/conditions.d.ts +0 -236
- package/dist/styled-system/types/csstype.d.ts +0 -22570
- package/dist/styled-system/types/index.d.ts +0 -6
- package/dist/styled-system/types/parts.d.ts +0 -8
- package/dist/styled-system/types/pattern.d.ts +0 -78
- package/dist/styled-system/types/prop-type.d.ts +0 -223
- package/dist/styled-system/types/recipe.d.ts +0 -181
- package/dist/styled-system/types/selectors.d.ts +0 -59
- package/dist/styled-system/types/static-css.d.ts +0 -56
- package/dist/styled-system/types/style-props.d.ts +0 -8088
- package/dist/styled-system/types/system-types.d.ts +0 -151
- package/dist/styles/recipes.css +0 -1262
|
@@ -78,12 +78,13 @@
|
|
|
78
78
|
|
|
79
79
|
<div class={cn('svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-8ef2268efbbc svadmin-u-65fdbade2025 svadmin-u-c9ed8c5f79ae svadmin-u-2859c861d7de svadmin-u-d5eab218aa34 svadmin-u-359090c2d529 svadmin-u-7f6912283f11', className)}>
|
|
80
80
|
<!-- Tabs list -->
|
|
81
|
-
<div class="svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-44ee8ba0a421 svadmin-u-1384f66f41d0 svadmin-u-660d2effb880 scrollbar-none">
|
|
81
|
+
<div role="tablist" aria-label="Workspace tabs" class="svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-44ee8ba0a421 svadmin-u-1384f66f41d0 svadmin-u-660d2effb880 scrollbar-none">
|
|
82
82
|
{#each tabs as tab (tab.id)}
|
|
83
83
|
{@const isActive = tab.id === activeTabId}
|
|
84
84
|
<div
|
|
85
|
-
role="
|
|
85
|
+
role="tab"
|
|
86
86
|
tabindex="0"
|
|
87
|
+
aria-selected={isActive}
|
|
87
88
|
class={cn(
|
|
88
89
|
'group svadmin-u-d89972fe17d6 svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-58284b4ea568 svadmin-u-0e17f2bd9074 svadmin-u-ec0091ee009b svadmin-u-421ac2be5045 svadmin-u-359090c2d529 svadmin-u-2689f3958069 svadmin-u-0fe7d7d814d0 svadmin-u-34516836730d svadmin-u-ca6bcd4b6f3f',
|
|
89
90
|
isActive
|
|
@@ -91,11 +92,11 @@
|
|
|
91
92
|
: 'svadmin-u-7f19cdf4c5bb svadmin-u-bfa603190748 svadmin-u-521fa0c7c407 svadmin-u-68646cdcc246 svadmin-u-ea7b2e9e070e'
|
|
92
93
|
)}
|
|
93
94
|
onclick={() => handleSelect(tab)}
|
|
94
|
-
onkeydown={(e) => { if (e.key === 'Enter') handleSelect(tab); }}
|
|
95
|
+
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleSelect(tab); } }}
|
|
95
96
|
oncontextmenu={(e) => handleContextMenu(e, tab.id)}
|
|
96
97
|
>
|
|
97
98
|
{#if tab.pinned}
|
|
98
|
-
<Pin class="svadmin-u-6a60c09e6aaa svadmin-u-9cea05671a29 svadmin-u-20aaf08a7ed1 svadmin-u-012fbd121f37 svadmin-u-c74901da6f6c" />
|
|
99
|
+
<Pin aria-hidden="true" class="svadmin-u-6a60c09e6aaa svadmin-u-9cea05671a29 svadmin-u-20aaf08a7ed1 svadmin-u-012fbd121f37 svadmin-u-c74901da6f6c" />
|
|
99
100
|
{/if}
|
|
100
101
|
|
|
101
102
|
<span class="svadmin-u-f283ea9bea0e svadmin-u-1d274d2422d8">{tab.title}</span>
|
|
@@ -105,6 +106,8 @@
|
|
|
105
106
|
type="button"
|
|
106
107
|
class="svadmin-u-60fbb7713999 svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227 svadmin-u-ac204c108886 svadmin-u-7be4d67a6256 svadmin-u-8db899b4e072 svadmin-u-51e95020d6f2 svadmin-u-ceb69a6b0e5f svadmin-u-8a539c7fe216 svadmin-u-119b2aa0b8f6 svadmin-u-34516836730d"
|
|
107
108
|
onclick={(e) => handleClose(e, tab.id)}
|
|
109
|
+
aria-label={`Close ${tab.title}`}
|
|
110
|
+
title={`Close ${tab.title}`}
|
|
108
111
|
>
|
|
109
112
|
<X class="svadmin-u-9b3d0721b628 svadmin-u-650758f4572a" />
|
|
110
113
|
</button>
|
|
@@ -123,8 +126,10 @@
|
|
|
123
126
|
size="sm"
|
|
124
127
|
class="svadmin-u-d0a52b312f7d svadmin-u-cbbf90f9a828 svadmin-u-8a539c7fe216 svadmin-u-bfa603190748 svadmin-u-ea7b2e9e070e"
|
|
125
128
|
onclick={() => onrefresh(curTab)}
|
|
129
|
+
aria-label={`Refresh ${curTab.title}`}
|
|
130
|
+
title={`Refresh ${curTab.title}`}
|
|
126
131
|
>
|
|
127
|
-
<RefreshCw class="svadmin-u-6a60c09e6aaa svadmin-u-9cea05671a29" />
|
|
132
|
+
<RefreshCw aria-hidden="true" class="svadmin-u-6a60c09e6aaa svadmin-u-9cea05671a29" />
|
|
128
133
|
</Button>
|
|
129
134
|
{/if}
|
|
130
135
|
{/if}
|
|
@@ -136,7 +141,7 @@
|
|
|
136
141
|
class="svadmin-u-d0a52b312f7d svadmin-u-cbbf90f9a828 svadmin-u-8a539c7fe216 svadmin-u-bfa603190748 svadmin-u-51e95020d6f2"
|
|
137
142
|
onclick={handleCloseAll}
|
|
138
143
|
>
|
|
139
|
-
<XCircle class="svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c" />
|
|
144
|
+
<XCircle aria-hidden="true" class="svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c" />
|
|
140
145
|
</Button>
|
|
141
146
|
{/if}
|
|
142
147
|
</div>
|
|
@@ -1,20 +1,86 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export interface NotificationPreferences {
|
|
3
|
+
email: { security: boolean; activity: boolean; reports: boolean };
|
|
4
|
+
push: { security: boolean; activity: boolean; reports: boolean };
|
|
5
|
+
sms: { security: boolean };
|
|
6
|
+
}
|
|
7
|
+
export interface NotificationPreferencesProvider {
|
|
8
|
+
/** 宿主提供的存储范围或服务边界说明。 */
|
|
9
|
+
description?: string;
|
|
10
|
+
load: () => Promise<NotificationPreferences>;
|
|
11
|
+
save: (preferences: NotificationPreferences) => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
</script>
|
|
1
14
|
<script lang="ts">
|
|
2
|
-
import { useNotification } from '@svadmin/core';
|
|
15
|
+
import { captureAdminContext, useNotification } from '@svadmin/core';
|
|
3
16
|
import { useTranslation } from '@svadmin/core/i18n';
|
|
4
17
|
import { Button } from './ui/button/index.js';
|
|
5
18
|
import { Switch } from './ui/switch/index.js';
|
|
6
19
|
import SettingsGroup from './content/SettingsGroup.svelte';
|
|
7
20
|
import SettingsFieldRow from './content/SettingsFieldRow.svelte';
|
|
21
|
+
import DataState from './content/DataState.svelte';
|
|
22
|
+
import FeedbackNotice from './content/FeedbackNotice.svelte';
|
|
8
23
|
|
|
24
|
+
let { preferencesProvider }: { preferencesProvider?: NotificationPreferencesProvider } = $props();
|
|
9
25
|
const i18n = useTranslation();
|
|
26
|
+
const context = captureAdminContext();
|
|
10
27
|
const notification = useNotification();
|
|
11
28
|
let emailAlerts = $state({ security: true, activity: false, reports: true });
|
|
12
29
|
let pushAlerts = $state({ security: true, activity: true, reports: false });
|
|
13
30
|
let smsAlerts = $state({ security: true });
|
|
14
|
-
|
|
31
|
+
let loading = $state(false);
|
|
32
|
+
let saving = $state(false);
|
|
33
|
+
let loaded = $state(false);
|
|
34
|
+
let error = $state('');
|
|
35
|
+
let epoch = 0;
|
|
36
|
+
async function load() {
|
|
37
|
+
const provider = preferencesProvider;
|
|
38
|
+
const request = ++epoch;
|
|
39
|
+
error = ''; loaded = false; saving = false;
|
|
40
|
+
loading = Boolean(provider);
|
|
41
|
+
if (!provider) return;
|
|
42
|
+
try {
|
|
43
|
+
const result = await provider.load();
|
|
44
|
+
if (request !== epoch) return;
|
|
45
|
+
emailAlerts = { ...result.email }; pushAlerts = { ...result.push }; smsAlerts = { ...result.sms };
|
|
46
|
+
loaded = true;
|
|
47
|
+
} catch (caught) {
|
|
48
|
+
if (request === epoch) error = caught instanceof Error ? caught.message : String(caught);
|
|
49
|
+
} finally {
|
|
50
|
+
if (request === epoch) loading = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
$effect(() => {
|
|
54
|
+
void preferencesProvider; void context.authProvider; void context.tenantCacheKey?.__svadminTenant;
|
|
55
|
+
void load();
|
|
56
|
+
return () => { epoch += 1; };
|
|
57
|
+
});
|
|
58
|
+
async function saveSettings() {
|
|
59
|
+
const provider = preferencesProvider;
|
|
60
|
+
if (!provider || !loaded || saving) return;
|
|
61
|
+
const request = epoch;
|
|
62
|
+
saving = true; error = '';
|
|
63
|
+
try {
|
|
64
|
+
await provider.save({ email: { ...emailAlerts }, push: { ...pushAlerts }, sms: { ...smsAlerts } });
|
|
65
|
+
if (request === epoch) notification.success(i18n.t('common.updateSuccess'), 3000);
|
|
66
|
+
} catch (caught) {
|
|
67
|
+
if (request === epoch) error = caught instanceof Error ? caught.message : String(caught);
|
|
68
|
+
} finally {
|
|
69
|
+
if (request === epoch) saving = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
15
72
|
</script>
|
|
16
73
|
|
|
17
74
|
<div class="svadmin-u-b3542e058833">
|
|
75
|
+
{#if preferencesProvider?.description}
|
|
76
|
+
<p role="note">{preferencesProvider.description}</p>
|
|
77
|
+
{/if}
|
|
78
|
+
{#if !preferencesProvider}
|
|
79
|
+
<FeedbackNotice tone="warning" message={i18n.locale === 'zh-CN' ? '未配置通知偏好存储服务,设置不可保存。' : 'Notification preference storage is not configured. Settings cannot be saved.'} />
|
|
80
|
+
{/if}
|
|
81
|
+
{#if loading}<DataState state="loading" />{/if}
|
|
82
|
+
{#if error}<p role="alert">{error}</p>{#if !loaded}<Button onclick={load}>{i18n.t('common.retry')}</Button>{/if}{/if}
|
|
83
|
+
<fieldset disabled={!loaded || loading || saving} class="svadmin-u-b3542e058833">
|
|
18
84
|
<div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed svadmin-u-8ef2268efbbc svadmin-u-1004c0c3954c svadmin-u-020ba687fa12 svadmin-u-64cac80d2e9a"><div><h2 class="svadmin-u-d5c9b0001e7e svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">{i18n.t('settings.notifications')}</h2><p class="svadmin-u-b6b02c0ebef6 svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">{i18n.t('settings.notificationsDescription')}</p></div><Button onclick={saveSettings}>{i18n.t('common.save')}</Button></div>
|
|
19
85
|
<SettingsGroup title={i18n.t('notifications.emailTitle')} description={i18n.t('notifications.emailDescription')}>
|
|
20
86
|
<div class="svadmin-u-fa6acbf81d74 svadmin-u-e783642739e3">
|
|
@@ -33,4 +99,5 @@
|
|
|
33
99
|
<SettingsGroup title={i18n.t('notifications.smsTitle')} description={i18n.t('notifications.smsDescription')}>
|
|
34
100
|
<SettingsFieldRow label={i18n.t('notifications.criticalSecurity')} description={i18n.t('notifications.criticalSecurityDesc')}>{#snippet control()}<Switch id="sms-security" bind:checked={smsAlerts.security} />{/snippet}</SettingsFieldRow>
|
|
35
101
|
</SettingsGroup>
|
|
102
|
+
</fieldset>
|
|
36
103
|
</div>
|
|
@@ -1,3 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
export interface NotificationPreferences {
|
|
2
|
+
email: {
|
|
3
|
+
security: boolean;
|
|
4
|
+
activity: boolean;
|
|
5
|
+
reports: boolean;
|
|
6
|
+
};
|
|
7
|
+
push: {
|
|
8
|
+
security: boolean;
|
|
9
|
+
activity: boolean;
|
|
10
|
+
reports: boolean;
|
|
11
|
+
};
|
|
12
|
+
sms: {
|
|
13
|
+
security: boolean;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface NotificationPreferencesProvider {
|
|
17
|
+
/** 宿主提供的存储范围或服务边界说明。 */
|
|
18
|
+
description?: string;
|
|
19
|
+
load: () => Promise<NotificationPreferences>;
|
|
20
|
+
save: (preferences: NotificationPreferences) => Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
type $$ComponentProps = {
|
|
23
|
+
preferencesProvider?: NotificationPreferencesProvider;
|
|
24
|
+
};
|
|
25
|
+
declare const NotificationsSettings: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
2
26
|
type NotificationsSettings = ReturnType<typeof NotificationsSettings>;
|
|
3
27
|
export default NotificationsSettings;
|
|
@@ -4,7 +4,26 @@
|
|
|
4
4
|
import type { RoleInfo, ResourceInfo, ActionInfo } from '../types.js';
|
|
5
5
|
import { useTranslation } from '@svadmin/core/i18n';
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const translation = useTranslation();
|
|
8
|
+
const fallback: Record<string, [string, string]> = {
|
|
9
|
+
title: ['Permission Matrix', '权限矩阵'],
|
|
10
|
+
description: ['Configure authorization rules for system modules and roles.', '配置系统模块与角色的授权规则。'],
|
|
11
|
+
roles: ['Roles', '角色'],
|
|
12
|
+
noRoles: ['No roles available', '暂无角色'],
|
|
13
|
+
currentRole: ['Current role', '当前角色'],
|
|
14
|
+
noneSelected: ['None selected', '未选择'],
|
|
15
|
+
toggleHint: ['Toggle checkboxes to grant or revoke permissions', '勾选或取消勾选以授予或撤销权限'],
|
|
16
|
+
conflicts: ['conflicting rules', '条冲突规则'],
|
|
17
|
+
resources: ['Resources', '资源'],
|
|
18
|
+
noResources: ['No resources available', '暂无资源'],
|
|
19
|
+
};
|
|
20
|
+
const i18n = {
|
|
21
|
+
t(key: string) {
|
|
22
|
+
const value = translation.t(key);
|
|
23
|
+
const labels = fallback[key.replace(/^permissions\./, '')];
|
|
24
|
+
return value === key && labels ? labels[translation.locale === 'zh-CN' ? 1 : 0] : value;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
8
27
|
|
|
9
28
|
|
|
10
29
|
let {
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onDestroy, untrack } from 'svelte';
|
|
3
|
+
import { Download } from '@lucide/svelte';
|
|
4
|
+
import {
|
|
5
|
+
captureAdminContext, captureAuthSession, useCan, useSubmitTask, useTask,
|
|
6
|
+
downloadExportArtifact, safeArtifactUrl, useTranslation,
|
|
7
|
+
type TaskProvider, type ExportFormat,
|
|
8
|
+
} from '@svadmin/core';
|
|
9
|
+
import { buildPivotExportRequest, snapshotPivotExportTaskResult, type PivotQuery } from '@svadmin/core/pivot';
|
|
10
|
+
import { definedOptions, definedReactiveOptions } from '@svadmin/core/options';
|
|
11
|
+
import { normalizeTaskStatus } from './task-utils';
|
|
12
|
+
import { Button } from './ui/button/index.js';
|
|
13
|
+
|
|
14
|
+
let { query, scopeKey, taskName, taskProvider, idempotencyKey, initialTaskId,
|
|
15
|
+
format = 'csv', disabled = false, onTaskSubmitted }: {
|
|
16
|
+
query: PivotQuery;
|
|
17
|
+
scopeKey: string;
|
|
18
|
+
taskName: string;
|
|
19
|
+
taskProvider?: TaskProvider;
|
|
20
|
+
idempotencyKey?: string;
|
|
21
|
+
initialTaskId?: string;
|
|
22
|
+
format?: ExportFormat;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
onTaskSubmitted?: (id: string) => void | Promise<void>;
|
|
25
|
+
} = $props();
|
|
26
|
+
|
|
27
|
+
const context = captureAdminContext();
|
|
28
|
+
const i18n = useTranslation();
|
|
29
|
+
const request = $derived(buildPivotExportRequest(query, scopeKey, format));
|
|
30
|
+
const permission = useCan(() => ({
|
|
31
|
+
resource: query.resource, action: 'export',
|
|
32
|
+
queryOptions: { enabled: !disabled && !!request },
|
|
33
|
+
}));
|
|
34
|
+
const scope = $derived({
|
|
35
|
+
signature: JSON.stringify(request), provider: taskProvider ?? context.taskProvider,
|
|
36
|
+
taskName, idempotencyKey, tenant: context.tenantCacheKey?.__svadminTenant,
|
|
37
|
+
auth: context.authProvider, session: captureAuthSession(context.authProvider),
|
|
38
|
+
access: context.accessControlProvider, router: context.routerProvider,
|
|
39
|
+
});
|
|
40
|
+
const allowed = $derived(!disabled && !!request && permission.allowed && scope.session.available);
|
|
41
|
+
let mounted = true;
|
|
42
|
+
function current(origin: typeof scope) {
|
|
43
|
+
return mounted && origin.signature === scope.signature && origin.provider === scope.provider
|
|
44
|
+
&& origin.taskName === scope.taskName && origin.idempotencyKey === scope.idempotencyKey
|
|
45
|
+
&& origin.tenant === scope.tenant && origin.auth === scope.auth
|
|
46
|
+
&& origin.access === scope.access && origin.router === scope.router && origin.session.isCurrent();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let owner = $state.raw<typeof scope | undefined>(untrack(() => initialTaskId ? scope : undefined));
|
|
50
|
+
let taskId = $state<string | undefined>(untrack(() => initialTaskId));
|
|
51
|
+
let attempt = $state.raw<{ origin: typeof scope }>();
|
|
52
|
+
let error = $state(false);
|
|
53
|
+
let completedId = $state<string>();
|
|
54
|
+
let wasAllowed = false;
|
|
55
|
+
const ownedId = $derived(owner && current(owner) && allowed ? taskId : undefined);
|
|
56
|
+
const submit = useSubmitTask();
|
|
57
|
+
const task = useTask(definedReactiveOptions({
|
|
58
|
+
get taskId() { return ownedId; },
|
|
59
|
+
get taskProvider() { return scope.provider; },
|
|
60
|
+
errorNotification: false,
|
|
61
|
+
successNotification: false,
|
|
62
|
+
get queryOptions() {
|
|
63
|
+
return { enabled: !!ownedId && !!scope.provider,
|
|
64
|
+
refetchInterval: ownedId && ownedId !== completedId ? 2000 : false as const };
|
|
65
|
+
},
|
|
66
|
+
}));
|
|
67
|
+
const status = $derived(ownedId ? normalizeTaskStatus(task.data?.status) : 'unknown');
|
|
68
|
+
const terminal = $derived(['completed', 'failed', 'cancelled'].includes(status));
|
|
69
|
+
$effect(() => { if (ownedId && terminal) completedId = ownedId; });
|
|
70
|
+
const artifact = $derived.by(() => {
|
|
71
|
+
if (!ownedId || status !== 'completed' || !request || !idempotencyKey) return;
|
|
72
|
+
const result = snapshotPivotExportTaskResult(task.data?.result ?? task.data?.result_data, { taskName, idempotencyKey, request });
|
|
73
|
+
if (!result || !safeArtifactUrl(result.downloadUrl)) return;
|
|
74
|
+
return {
|
|
75
|
+
format: result.format, downloadUrl: result.downloadUrl,
|
|
76
|
+
...(result.fileName ? { fileName: result.fileName } : {}),
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
const failed = $derived(error || (!!ownedId && (task.isError || status === 'failed'
|
|
80
|
+
|| (status === 'completed' && !artifact))));
|
|
81
|
+
const busy = $derived(!!attempt && current(attempt.origin));
|
|
82
|
+
const pending = $derived(!!ownedId && !terminal && !task.isError);
|
|
83
|
+
|
|
84
|
+
onDestroy(() => { mounted = false; attempt = undefined; });
|
|
85
|
+
$effect.pre(() => {
|
|
86
|
+
const revoked = wasAllowed && !allowed;
|
|
87
|
+
wasAllowed = allowed;
|
|
88
|
+
if (owner && (!current(owner) || revoked)) {
|
|
89
|
+
owner = undefined; taskId = undefined; completedId = undefined; error = false;
|
|
90
|
+
}
|
|
91
|
+
if (attempt && (!current(attempt.origin) || !allowed)) { attempt = undefined; error = false; }
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
async function run() {
|
|
95
|
+
if (!allowed || busy || !request || !scope.provider) return;
|
|
96
|
+
const origin = scope;
|
|
97
|
+
const source = scope.provider;
|
|
98
|
+
if (ownedId) {
|
|
99
|
+
if (artifact && owner && current(owner)) {
|
|
100
|
+
const token = { origin };
|
|
101
|
+
const receipt = artifact;
|
|
102
|
+
const resource = request.query.resource;
|
|
103
|
+
attempt = token;
|
|
104
|
+
error = false;
|
|
105
|
+
try {
|
|
106
|
+
const checked = origin.access ? await origin.access.can(definedOptions({
|
|
107
|
+
resource, action: 'export', meta: request.query.meta,
|
|
108
|
+
})) : { can: true };
|
|
109
|
+
if (attempt !== token || !current(origin) || !allowed) return;
|
|
110
|
+
if (!checked.can) {
|
|
111
|
+
owner = undefined; taskId = undefined; error = true;
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
downloadExportArtifact(receipt, resource);
|
|
115
|
+
} catch {
|
|
116
|
+
if (attempt === token && current(origin) && allowed) error = true;
|
|
117
|
+
} finally {
|
|
118
|
+
if (attempt === token) attempt = undefined;
|
|
119
|
+
}
|
|
120
|
+
} else if (task.isError) {
|
|
121
|
+
try { await task.refetch(); } catch { /* 查询状态提供脱敏错误。 */ }
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!taskName.trim() || !idempotencyKey?.trim()) { error = true; return; }
|
|
126
|
+
const token = { origin };
|
|
127
|
+
const notify = onTaskSubmitted;
|
|
128
|
+
attempt = token;
|
|
129
|
+
error = false;
|
|
130
|
+
try {
|
|
131
|
+
const handle = await submit.mutation.mutateAsync({
|
|
132
|
+
taskName, taskProvider: source,
|
|
133
|
+
options: { idempotencyKey, body: { ...request } },
|
|
134
|
+
successNotification: false, errorNotification: false,
|
|
135
|
+
});
|
|
136
|
+
if (attempt !== token || !current(origin) || !allowed) return;
|
|
137
|
+
owner = origin;
|
|
138
|
+
taskId = handle.id;
|
|
139
|
+
try { void Promise.resolve(notify?.(handle.id)).catch(() => {}); } catch { /* 不重发已提交任务。 */ }
|
|
140
|
+
} catch {
|
|
141
|
+
if (attempt === token && current(origin) && allowed) error = true;
|
|
142
|
+
} finally {
|
|
143
|
+
if (attempt === token) attempt = undefined;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const label = $derived(artifact ? i18n.t('common.download') : task.isError && ownedId
|
|
148
|
+
? i18n.t('common.retry') : busy || pending ? i18n.t('common.processing')
|
|
149
|
+
: ownedId && terminal ? i18n.t(status === 'cancelled' ? 'task.status.cancelled' : 'common.error')
|
|
150
|
+
: i18n.t('common.export'));
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<Button variant="outline" size="sm" onclick={run} aria-busy={busy || pending}
|
|
154
|
+
disabled={!allowed || !scope.provider || busy || (!!ownedId && !artifact && !task.isError)}>
|
|
155
|
+
<Download aria-hidden="true" />{label}
|
|
156
|
+
</Button>
|
|
157
|
+
{#if allowed && failed}<p role="alert">{i18n.t('common.error')}</p>{/if}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type TaskProvider, type ExportFormat } from '@svadmin/core';
|
|
2
|
+
import { type PivotQuery } from '@svadmin/core/pivot';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
query: PivotQuery;
|
|
5
|
+
scopeKey: string;
|
|
6
|
+
taskName: string;
|
|
7
|
+
taskProvider?: TaskProvider;
|
|
8
|
+
idempotencyKey?: string;
|
|
9
|
+
initialTaskId?: string;
|
|
10
|
+
format?: ExportFormat;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
onTaskSubmitted?: (id: string) => void | Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
declare const PivotExportButton: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
15
|
+
type PivotExportButton = ReturnType<typeof PivotExportButton>;
|
|
16
|
+
export default PivotExportButton;
|