@svadmin/ui 0.29.3 → 0.30.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/dist/README.md +18 -0
- package/dist/actions.d.ts +35 -0
- package/dist/actions.js +84 -0
- package/dist/app.css +673 -0
- package/dist/component-registry.svelte.d.ts +36 -0
- package/dist/component-registry.svelte.js +20 -0
- package/dist/components/AICommandBar.svelte +180 -0
- package/dist/components/AICommandBar.svelte.d.ts +6 -0
- package/dist/components/AboutSettings.svelte +106 -0
- package/dist/components/AboutSettings.svelte.d.ts +18 -0
- package/dist/components/AdminApp.svelte +205 -0
- package/dist/components/AdminApp.svelte.d.ts +28 -0
- package/dist/components/AnimatedCounter.svelte +46 -0
- package/dist/components/AnimatedCounter.svelte.d.ts +11 -0
- package/dist/components/AnomalyBadge.svelte +65 -0
- package/dist/components/AnomalyBadge.svelte.d.ts +16 -0
- package/dist/components/AppearanceSettings.svelte +183 -0
- package/dist/components/AppearanceSettings.svelte.d.ts +3 -0
- package/dist/components/AuditLogDrawer.svelte +93 -0
- package/dist/components/AuditLogDrawer.svelte.d.ts +8 -0
- package/dist/components/AuditLogViewer.svelte +226 -0
- package/dist/components/AuditLogViewer.svelte.d.ts +3 -0
- package/dist/components/Authenticated.svelte +51 -0
- package/dist/components/Authenticated.svelte.d.ts +11 -0
- package/dist/components/AutoForm.svelte +244 -0
- package/dist/components/AutoForm.svelte.d.ts +20 -0
- package/dist/components/AutoSaveIndicator.svelte +35 -0
- package/dist/components/AutoSaveIndicator.svelte.d.ts +9 -0
- package/dist/components/AutoTable.svelte +839 -0
- package/dist/components/AutoTable.svelte.d.ts +44 -0
- package/dist/components/Breadcrumbs.svelte +58 -0
- package/dist/components/Breadcrumbs.svelte.d.ts +3 -0
- package/dist/components/CanAccess.svelte +23 -0
- package/dist/components/CanAccess.svelte.d.ts +12 -0
- package/dist/components/CatchAllNavigate.svelte +21 -0
- package/dist/components/CatchAllNavigate.svelte.d.ts +3 -0
- package/dist/components/ChatDialog.svelte +535 -0
- package/dist/components/ChatDialog.svelte.d.ts +14 -0
- package/dist/components/ComboboxField.svelte +129 -0
- package/dist/components/ComboboxField.svelte.d.ts +17 -0
- package/dist/components/CommandPalette.svelte +135 -0
- package/dist/components/CommandPalette.svelte.d.ts +8 -0
- package/dist/components/ConfigErrorScreen.svelte +126 -0
- package/dist/components/ConfigErrorScreen.svelte.d.ts +11 -0
- package/dist/components/ConfirmDialog.svelte +53 -0
- package/dist/components/ConfirmDialog.svelte.d.ts +13 -0
- package/dist/components/CopilotPanel.svelte +163 -0
- package/dist/components/CopilotPanel.svelte.d.ts +6 -0
- package/dist/components/CreatePage.svelte +39 -0
- package/dist/components/CreatePage.svelte.d.ts +10 -0
- package/dist/components/DevTools.svelte +149 -0
- package/dist/components/DevTools.svelte.d.ts +3 -0
- package/dist/components/DraggableGrid.svelte +86 -0
- package/dist/components/DraggableGrid.svelte.d.ts +17 -0
- package/dist/components/DraggableHeader.svelte +112 -0
- package/dist/components/DraggableHeader.svelte.d.ts +25 -0
- package/dist/components/DrawerForm.svelte +35 -0
- package/dist/components/DrawerForm.svelte.d.ts +11 -0
- package/dist/components/EditPage.svelte +52 -0
- package/dist/components/EditPage.svelte.d.ts +12 -0
- package/dist/components/EmptyState.svelte +31 -0
- package/dist/components/EmptyState.svelte.d.ts +8 -0
- package/dist/components/ErrorBoundary.svelte +49 -0
- package/dist/components/ErrorBoundary.svelte.d.ts +12 -0
- package/dist/components/ErrorComponent.svelte +36 -0
- package/dist/components/ErrorComponent.svelte.d.ts +9 -0
- package/dist/components/FieldRenderer.svelte +357 -0
- package/dist/components/FieldRenderer.svelte.d.ts +13 -0
- package/dist/components/ForgotPasswordPage.svelte +112 -0
- package/dist/components/ForgotPasswordPage.svelte.d.ts +6 -0
- package/dist/components/Header.svelte +94 -0
- package/dist/components/Header.svelte.d.ts +12 -0
- package/dist/components/InferencerPanel.svelte +192 -0
- package/dist/components/InferencerPanel.svelte.d.ts +3 -0
- package/dist/components/InfiniteList.svelte +93 -0
- package/dist/components/InfiniteList.svelte.d.ts +20 -0
- package/dist/components/InlineEdit.svelte +88 -0
- package/dist/components/InlineEdit.svelte.d.ts +12 -0
- package/dist/components/InsightCard.svelte +98 -0
- package/dist/components/InsightCard.svelte.d.ts +11 -0
- package/dist/components/KeyboardShortcuts.svelte +61 -0
- package/dist/components/KeyboardShortcuts.svelte.d.ts +6 -0
- package/dist/components/Layout.svelte +167 -0
- package/dist/components/Layout.svelte.d.ts +12 -0
- package/dist/components/ListPage.svelte +71 -0
- package/dist/components/ListPage.svelte.d.ts +32 -0
- package/dist/components/LiveIndicator.svelte +58 -0
- package/dist/components/LiveIndicator.svelte.d.ts +12 -0
- package/dist/components/LoginPage.svelte +163 -0
- package/dist/components/LoginPage.svelte.d.ts +28 -0
- package/dist/components/MarkdownRenderer.svelte +127 -0
- package/dist/components/MarkdownRenderer.svelte.d.ts +11 -0
- package/dist/components/ModalForm.svelte +38 -0
- package/dist/components/ModalForm.svelte.d.ts +10 -0
- package/dist/components/NavigateToResource.svelte +20 -0
- package/dist/components/NavigateToResource.svelte.d.ts +3 -0
- package/dist/components/PageHeader.svelte +39 -0
- package/dist/components/PageHeader.svelte.d.ts +11 -0
- package/dist/components/PageSkeleton.svelte +71 -0
- package/dist/components/PageSkeleton.svelte.d.ts +7 -0
- package/dist/components/PasswordInput.svelte +96 -0
- package/dist/components/PasswordInput.svelte.d.ts +12 -0
- package/dist/components/PermissionMatrix.svelte +185 -0
- package/dist/components/PermissionMatrix.svelte.d.ts +19 -0
- package/dist/components/ProfilePage.svelte +284 -0
- package/dist/components/ProfilePage.svelte.d.ts +3 -0
- package/dist/components/RegisterPage.svelte +112 -0
- package/dist/components/RegisterPage.svelte.d.ts +7 -0
- package/dist/components/RolesSettings.svelte +146 -0
- package/dist/components/RolesSettings.svelte.d.ts +3 -0
- package/dist/components/SettingsPage.svelte +113 -0
- package/dist/components/SettingsPage.svelte.d.ts +3 -0
- package/dist/components/ShowPage.svelte +73 -0
- package/dist/components/ShowPage.svelte.d.ts +7 -0
- package/dist/components/Sidebar.svelte +417 -0
- package/dist/components/Sidebar.svelte.d.ts +14 -0
- package/dist/components/SidebarItem.svelte +129 -0
- package/dist/components/SidebarItem.svelte.d.ts +11 -0
- package/dist/components/SmartSuggest.svelte +158 -0
- package/dist/components/SmartSuggest.svelte.d.ts +19 -0
- package/dist/components/StatsCard.svelte +79 -0
- package/dist/components/StatsCard.svelte.d.ts +23 -0
- package/dist/components/StepsForm.svelte +194 -0
- package/dist/components/StepsForm.svelte.d.ts +13 -0
- package/dist/components/TaskQueueDrawer.svelte +158 -0
- package/dist/components/TaskQueueDrawer.svelte.d.ts +11 -0
- package/dist/components/TenantSwitcher.svelte +84 -0
- package/dist/components/TenantSwitcher.svelte.d.ts +12 -0
- package/dist/components/ThemedTitle.svelte +32 -0
- package/dist/components/ThemedTitle.svelte.d.ts +9 -0
- package/dist/components/Toast.svelte +46 -0
- package/dist/components/Toast.svelte.d.ts +3 -0
- package/dist/components/TooltipButton.svelte +42 -0
- package/dist/components/TooltipButton.svelte.d.ts +14 -0
- package/dist/components/UndoableNotification.svelte +69 -0
- package/dist/components/UndoableNotification.svelte.d.ts +9 -0
- package/dist/components/UpdatePasswordPage.svelte +89 -0
- package/dist/components/UpdatePasswordPage.svelte.d.ts +6 -0
- package/dist/components/VirtualTable.svelte +76 -0
- package/dist/components/VirtualTable.svelte.d.ts +27 -0
- package/dist/components/VoiceInput.svelte +120 -0
- package/dist/components/VoiceInput.svelte.d.ts +15 -0
- package/dist/components/buttons/CloneButton.svelte +30 -0
- package/dist/components/buttons/CloneButton.svelte.d.ts +13 -0
- package/dist/components/buttons/CreateButton.svelte +29 -0
- package/dist/components/buttons/CreateButton.svelte.d.ts +12 -0
- package/dist/components/buttons/DeleteButton.svelte +59 -0
- package/dist/components/buttons/DeleteButton.svelte.d.ts +15 -0
- package/dist/components/buttons/EditButton.svelte +30 -0
- package/dist/components/buttons/EditButton.svelte.d.ts +13 -0
- package/dist/components/buttons/ExportButton.svelte +30 -0
- package/dist/components/buttons/ExportButton.svelte.d.ts +12 -0
- package/dist/components/buttons/ImportButton.svelte +56 -0
- package/dist/components/buttons/ImportButton.svelte.d.ts +19 -0
- package/dist/components/buttons/ListButton.svelte +23 -0
- package/dist/components/buttons/ListButton.svelte.d.ts +8 -0
- package/dist/components/buttons/RefreshButton.svelte +36 -0
- package/dist/components/buttons/RefreshButton.svelte.d.ts +8 -0
- package/dist/components/buttons/SaveButton.svelte +27 -0
- package/dist/components/buttons/SaveButton.svelte.d.ts +9 -0
- package/dist/components/buttons/ShowButton.svelte +31 -0
- package/dist/components/buttons/ShowButton.svelte.d.ts +13 -0
- package/dist/components/buttons/index.d.ts +10 -0
- package/dist/components/buttons/index.js +10 -0
- package/dist/components/charts/BarChart.svelte +69 -0
- package/dist/components/charts/BarChart.svelte.d.ts +15 -0
- package/dist/components/charts/LineChart.svelte +115 -0
- package/dist/components/charts/LineChart.svelte.d.ts +17 -0
- package/dist/components/charts/PieChart.svelte +95 -0
- package/dist/components/charts/PieChart.svelte.d.ts +15 -0
- package/dist/components/charts/index.d.ts +3 -0
- package/dist/components/charts/index.js +3 -0
- package/dist/components/fieldComponentMap.d.ts +24 -0
- package/dist/components/fieldComponentMap.js +65 -0
- package/dist/components/fields/ArrayField.svelte +86 -0
- package/dist/components/fields/ArrayField.svelte.d.ts +9 -0
- package/dist/components/fields/BooleanField.svelte +13 -0
- package/dist/components/fields/BooleanField.svelte.d.ts +8 -0
- package/dist/components/fields/DateField.svelte +6 -0
- package/dist/components/fields/DateField.svelte.d.ts +8 -0
- package/dist/components/fields/EmailField.svelte +9 -0
- package/dist/components/fields/EmailField.svelte.d.ts +6 -0
- package/dist/components/fields/FileField.svelte +14 -0
- package/dist/components/fields/FileField.svelte.d.ts +7 -0
- package/dist/components/fields/ImageField.svelte +9 -0
- package/dist/components/fields/ImageField.svelte.d.ts +9 -0
- package/dist/components/fields/JsonField.svelte +72 -0
- package/dist/components/fields/JsonField.svelte.d.ts +6 -0
- package/dist/components/fields/MarkdownField.svelte +9 -0
- package/dist/components/fields/MarkdownField.svelte.d.ts +6 -0
- package/dist/components/fields/MultiSelectField.svelte +21 -0
- package/dist/components/fields/MultiSelectField.svelte.d.ts +10 -0
- package/dist/components/fields/NumberField.svelte +6 -0
- package/dist/components/fields/NumberField.svelte.d.ts +8 -0
- package/dist/components/fields/RelationField.svelte +24 -0
- package/dist/components/fields/RelationField.svelte.d.ts +8 -0
- package/dist/components/fields/RichTextField.svelte +35 -0
- package/dist/components/fields/RichTextField.svelte.d.ts +7 -0
- package/dist/components/fields/SelectField.svelte +14 -0
- package/dist/components/fields/SelectField.svelte.d.ts +10 -0
- package/dist/components/fields/TagField.svelte +12 -0
- package/dist/components/fields/TagField.svelte.d.ts +6 -0
- package/dist/components/fields/TextField.svelte +11 -0
- package/dist/components/fields/TextField.svelte.d.ts +7 -0
- package/dist/components/fields/UrlField.svelte +14 -0
- package/dist/components/fields/UrlField.svelte.d.ts +7 -0
- package/dist/components/ui/alert/alert-description.svelte +17 -0
- package/dist/components/ui/alert/alert-description.svelte.d.ts +6 -0
- package/dist/components/ui/alert/alert-title.svelte +17 -0
- package/dist/components/ui/alert/alert-title.svelte.d.ts +6 -0
- package/dist/components/ui/alert/alert.svelte +44 -0
- package/dist/components/ui/alert/alert.svelte.d.ts +32 -0
- package/dist/components/ui/alert/index.d.ts +4 -0
- package/dist/components/ui/alert/index.js +5 -0
- package/dist/components/ui/alert-dialog/alert-dialog-content.svelte +29 -0
- package/dist/components/ui/alert-dialog/alert-dialog-content.svelte.d.ts +10 -0
- package/dist/components/ui/alert-dialog/alert-dialog-description.svelte +16 -0
- package/dist/components/ui/alert-dialog/alert-dialog-description.svelte.d.ts +7 -0
- package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte +11 -0
- package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte.d.ts +8 -0
- package/dist/components/ui/alert-dialog/alert-dialog-header.svelte +11 -0
- package/dist/components/ui/alert-dialog/alert-dialog-header.svelte.d.ts +8 -0
- package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte +16 -0
- package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte.d.ts +7 -0
- package/dist/components/ui/alert-dialog/alert-dialog-portal.svelte +6 -0
- package/dist/components/ui/alert-dialog/alert-dialog-portal.svelte.d.ts +3 -0
- package/dist/components/ui/alert-dialog/alert-dialog-title.svelte +16 -0
- package/dist/components/ui/alert-dialog/alert-dialog-title.svelte.d.ts +7 -0
- package/dist/components/ui/alert-dialog/index.d.ts +13 -0
- package/dist/components/ui/alert-dialog/index.js +13 -0
- package/dist/components/ui/avatar/avatar.svelte +63 -0
- package/dist/components/ui/avatar/avatar.svelte.d.ts +32 -0
- package/dist/components/ui/avatar/index.d.ts +2 -0
- package/dist/components/ui/avatar/index.js +2 -0
- package/dist/components/ui/badge/badge.svelte +49 -0
- package/dist/components/ui/badge/badge.svelte.d.ts +38 -0
- package/dist/components/ui/badge/index.d.ts +2 -0
- package/dist/components/ui/badge/index.js +3 -0
- package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +18 -0
- package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte.d.ts +4 -0
- package/dist/components/ui/breadcrumb/breadcrumb-item.svelte +15 -0
- package/dist/components/ui/breadcrumb/breadcrumb-item.svelte.d.ts +8 -0
- package/dist/components/ui/breadcrumb/breadcrumb-link.svelte +15 -0
- package/dist/components/ui/breadcrumb/breadcrumb-link.svelte.d.ts +8 -0
- package/dist/components/ui/breadcrumb/breadcrumb-list.svelte +15 -0
- package/dist/components/ui/breadcrumb/breadcrumb-list.svelte.d.ts +8 -0
- package/dist/components/ui/breadcrumb/breadcrumb-page.svelte +18 -0
- package/dist/components/ui/breadcrumb/breadcrumb-page.svelte.d.ts +8 -0
- package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte +22 -0
- package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte.d.ts +8 -0
- package/dist/components/ui/breadcrumb/breadcrumb.svelte +11 -0
- package/dist/components/ui/breadcrumb/breadcrumb.svelte.d.ts +8 -0
- package/dist/components/ui/breadcrumb/index.d.ts +7 -0
- package/dist/components/ui/breadcrumb/index.js +7 -0
- package/dist/components/ui/button/button.svelte +90 -0
- package/dist/components/ui/button/button.svelte.d.ts +70 -0
- package/dist/components/ui/button/index.d.ts +2 -0
- package/dist/components/ui/button/index.js +5 -0
- package/dist/components/ui/card/card-action.svelte +23 -0
- package/dist/components/ui/card/card-action.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-content.svelte +20 -0
- package/dist/components/ui/card/card-content.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-description.svelte +20 -0
- package/dist/components/ui/card/card-description.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-footer.svelte +20 -0
- package/dist/components/ui/card/card-footer.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-header.svelte +23 -0
- package/dist/components/ui/card/card-header.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-title.svelte +15 -0
- package/dist/components/ui/card/card-title.svelte.d.ts +5 -0
- package/dist/components/ui/card/card.svelte +22 -0
- package/dist/components/ui/card/card.svelte.d.ts +8 -0
- package/dist/components/ui/card/index.d.ts +8 -0
- package/dist/components/ui/card/index.js +10 -0
- package/dist/components/ui/checkbox/checkbox.svelte +39 -0
- package/dist/components/ui/checkbox/checkbox.svelte.d.ts +4 -0
- package/dist/components/ui/checkbox/index.d.ts +2 -0
- package/dist/components/ui/checkbox/index.js +4 -0
- package/dist/components/ui/collapsible/index.d.ts +5 -0
- package/dist/components/ui/collapsible/index.js +5 -0
- package/dist/components/ui/command/command-dialog.svelte +31 -0
- package/dist/components/ui/command/command-dialog.svelte.d.ts +10 -0
- package/dist/components/ui/command/index.d.ts +2 -0
- package/dist/components/ui/command/index.js +2 -0
- package/dist/components/ui/context-menu/index.d.ts +9 -0
- package/dist/components/ui/context-menu/index.js +9 -0
- package/dist/components/ui/dialog/dialog-close.svelte +11 -0
- package/dist/components/ui/dialog/dialog-close.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-content.svelte +48 -0
- package/dist/components/ui/dialog/dialog-content.svelte.d.ts +13 -0
- package/dist/components/ui/dialog/dialog-description.svelte +17 -0
- package/dist/components/ui/dialog/dialog-description.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-footer.svelte +32 -0
- package/dist/components/ui/dialog/dialog-footer.svelte.d.ts +8 -0
- package/dist/components/ui/dialog/dialog-header.svelte +20 -0
- package/dist/components/ui/dialog/dialog-header.svelte.d.ts +5 -0
- package/dist/components/ui/dialog/dialog-overlay.svelte +17 -0
- package/dist/components/ui/dialog/dialog-overlay.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-portal.svelte +7 -0
- package/dist/components/ui/dialog/dialog-portal.svelte.d.ts +3 -0
- package/dist/components/ui/dialog/dialog-title.svelte +17 -0
- package/dist/components/ui/dialog/dialog-title.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-trigger.svelte +11 -0
- package/dist/components/ui/dialog/dialog-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog.svelte +7 -0
- package/dist/components/ui/dialog/dialog.svelte.d.ts +3 -0
- package/dist/components/ui/dialog/index.d.ts +11 -0
- package/dist/components/ui/dialog/index.js +13 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +35 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +36 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +9 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +10 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte.d.ts +6 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +27 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +11 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +45 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte.d.ts +9 -0
- package/dist/components/ui/dropdown-menu/index.d.ts +7 -0
- package/dist/components/ui/dropdown-menu/index.js +7 -0
- package/dist/components/ui/input/index.d.ts +2 -0
- package/dist/components/ui/input/index.js +4 -0
- package/dist/components/ui/input/input.svelte +48 -0
- package/dist/components/ui/input/input.svelte.d.ts +13 -0
- package/dist/components/ui/label/index.d.ts +1 -0
- package/dist/components/ui/label/index.js +1 -0
- package/dist/components/ui/label/label.svelte +18 -0
- package/dist/components/ui/label/label.svelte.d.ts +5 -0
- package/dist/components/ui/pagination/index.d.ts +7 -0
- package/dist/components/ui/pagination/index.js +7 -0
- package/dist/components/ui/pagination/pagination-content.svelte +11 -0
- package/dist/components/ui/pagination/pagination-content.svelte.d.ts +8 -0
- package/dist/components/ui/pagination/pagination-ellipsis.svelte +12 -0
- package/dist/components/ui/pagination/pagination-ellipsis.svelte.d.ts +4 -0
- package/dist/components/ui/pagination/pagination-item.svelte +11 -0
- package/dist/components/ui/pagination/pagination-item.svelte.d.ts +8 -0
- package/dist/components/ui/pagination/pagination-link.svelte +26 -0
- package/dist/components/ui/pagination/pagination-link.svelte.d.ts +9 -0
- package/dist/components/ui/pagination/pagination-next.svelte +22 -0
- package/dist/components/ui/pagination/pagination-next.svelte.d.ts +8 -0
- package/dist/components/ui/pagination/pagination-previous.svelte +22 -0
- package/dist/components/ui/pagination/pagination-previous.svelte.d.ts +8 -0
- package/dist/components/ui/pagination/pagination.svelte +11 -0
- package/dist/components/ui/pagination/pagination.svelte.d.ts +8 -0
- package/dist/components/ui/popover/index.d.ts +6 -0
- package/dist/components/ui/popover/index.js +6 -0
- package/dist/components/ui/popover/popover-content.svelte +25 -0
- package/dist/components/ui/popover/popover-content.svelte.d.ts +7 -0
- package/dist/components/ui/progress/index.d.ts +1 -0
- package/dist/components/ui/progress/index.js +1 -0
- package/dist/components/ui/progress/progress.svelte +22 -0
- package/dist/components/ui/progress/progress.svelte.d.ts +8 -0
- package/dist/components/ui/scroll-area/index.d.ts +1 -0
- package/dist/components/ui/scroll-area/index.js +1 -0
- package/dist/components/ui/scroll-area/scroll-area.svelte +20 -0
- package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +9 -0
- package/dist/components/ui/select/index.d.ts +2 -0
- package/dist/components/ui/select/index.js +2 -0
- package/dist/components/ui/select/select.svelte +36 -0
- package/dist/components/ui/select/select.svelte.d.ts +8 -0
- package/dist/components/ui/separator/index.d.ts +2 -0
- package/dist/components/ui/separator/index.js +4 -0
- package/dist/components/ui/separator/separator.svelte +23 -0
- package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/index.d.ts +7 -0
- package/dist/components/ui/sheet/index.js +7 -0
- package/dist/components/ui/sheet/sheet-content.svelte +28 -0
- package/dist/components/ui/sheet/sheet-content.svelte.d.ts +8 -0
- package/dist/components/ui/sheet/sheet-description.svelte +22 -0
- package/dist/components/ui/sheet/sheet-description.svelte.d.ts +6 -0
- package/dist/components/ui/sheet/sheet-footer.svelte +22 -0
- package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +6 -0
- package/dist/components/ui/sheet/sheet-header.svelte +22 -0
- package/dist/components/ui/sheet/sheet-header.svelte.d.ts +6 -0
- package/dist/components/ui/sheet/sheet-title.svelte +22 -0
- package/dist/components/ui/sheet/sheet-title.svelte.d.ts +6 -0
- package/dist/components/ui/sheet/sheet.svelte +78 -0
- package/dist/components/ui/sheet/sheet.svelte.d.ts +10 -0
- package/dist/components/ui/skeleton/index.d.ts +2 -0
- package/dist/components/ui/skeleton/index.js +2 -0
- package/dist/components/ui/skeleton/skeleton.svelte +21 -0
- package/dist/components/ui/skeleton/skeleton.svelte.d.ts +8 -0
- package/dist/components/ui/switch/index.d.ts +2 -0
- package/dist/components/ui/switch/index.js +2 -0
- package/dist/components/ui/switch/switch.svelte +49 -0
- package/dist/components/ui/switch/switch.svelte.d.ts +10 -0
- package/dist/components/ui/table/index.d.ts +9 -0
- package/dist/components/ui/table/index.js +11 -0
- package/dist/components/ui/table/table-body.svelte +15 -0
- package/dist/components/ui/table/table-body.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-caption.svelte +20 -0
- package/dist/components/ui/table/table-caption.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-cell.svelte +15 -0
- package/dist/components/ui/table/table-cell.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-footer.svelte +20 -0
- package/dist/components/ui/table/table-footer.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-head.svelte +15 -0
- package/dist/components/ui/table/table-head.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-header.svelte +20 -0
- package/dist/components/ui/table/table-header.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-row.svelte +15 -0
- package/dist/components/ui/table/table-row.svelte.d.ts +5 -0
- package/dist/components/ui/table/table.svelte +17 -0
- package/dist/components/ui/table/table.svelte.d.ts +5 -0
- package/dist/components/ui/tabs/index.d.ts +5 -0
- package/dist/components/ui/tabs/index.js +5 -0
- package/dist/components/ui/tabs/tabs-content.svelte +30 -0
- package/dist/components/ui/tabs/tabs-content.svelte.d.ts +9 -0
- package/dist/components/ui/tabs/tabs-list.svelte +26 -0
- package/dist/components/ui/tabs/tabs-list.svelte.d.ts +6 -0
- package/dist/components/ui/tabs/tabs-trigger.svelte +37 -0
- package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +9 -0
- package/dist/components/ui/tabs/tabs.svelte +27 -0
- package/dist/components/ui/tabs/tabs.svelte.d.ts +9 -0
- package/dist/components/ui/textarea/index.d.ts +2 -0
- package/dist/components/ui/textarea/index.js +2 -0
- package/dist/components/ui/textarea/textarea.svelte +24 -0
- package/dist/components/ui/textarea/textarea.svelte.d.ts +6 -0
- package/dist/components/ui/tooltip/index.d.ts +6 -0
- package/dist/components/ui/tooltip/index.js +8 -0
- package/dist/components/ui/tooltip/tooltip-content.svelte +52 -0
- package/dist/components/ui/tooltip/tooltip-content.svelte.d.ts +11 -0
- package/dist/components/ui/tooltip/tooltip-portal.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-portal.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip-provider.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-provider.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip-trigger.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip.svelte +10 -0
- package/dist/components/ui/tooltip/tooltip.svelte.d.ts +4 -0
- package/dist/editor-config.svelte.d.ts +15 -0
- package/dist/editor-config.svelte.js +19 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.js +127 -0
- package/dist/markdown-deps.d.ts +21 -0
- package/dist/router-state.svelte.d.ts +5 -0
- package/dist/router-state.svelte.js +58 -0
- package/dist/types.d.ts +42 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.js +5 -0
- package/package.json +2 -2
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { fade, fly } from 'svelte/transition';
|
|
4
|
+
import Sidebar from './Sidebar.svelte';
|
|
5
|
+
import Toast from './Toast.svelte';
|
|
6
|
+
import Header from './Header.svelte';
|
|
7
|
+
import CommandPalette from './CommandPalette.svelte';
|
|
8
|
+
import KeyboardShortcuts from './KeyboardShortcuts.svelte';
|
|
9
|
+
import ChatDialog from './ChatDialog.svelte';
|
|
10
|
+
import TooltipButton from './TooltipButton.svelte';
|
|
11
|
+
import { t } from '@svadmin/core/i18n';
|
|
12
|
+
import { getAuthProvider } from '@svadmin/core';
|
|
13
|
+
import type { Identity, MenuItem } from '@svadmin/core';
|
|
14
|
+
import { navigate } from '@svadmin/core/router';
|
|
15
|
+
import { currentPath } from '@svadmin/core/router';
|
|
16
|
+
import { Skeleton } from './ui/skeleton/index.js';
|
|
17
|
+
import { Button } from './ui/button/index.js';
|
|
18
|
+
import * as Sheet from './ui/sheet/index.js';
|
|
19
|
+
import { Menu } from '@lucide/svelte';
|
|
20
|
+
|
|
21
|
+
let commandOpen = $state(false);
|
|
22
|
+
let shortcutsOpen = $state(false);
|
|
23
|
+
let mobileMenuOpen = $state(false);
|
|
24
|
+
|
|
25
|
+
let { children, title = 'Admin', menu, siteUrl, routeMode = 'auto' }: { children: Snippet; title?: string; menu?: MenuItem[]; siteUrl?: string; routeMode?: 'hash' | 'path' | 'auto' } = $props();
|
|
26
|
+
|
|
27
|
+
let hasAuth = true;
|
|
28
|
+
let auth: ReturnType<typeof getAuthProvider> | null = null;
|
|
29
|
+
try {
|
|
30
|
+
auth = getAuthProvider();
|
|
31
|
+
} catch {
|
|
32
|
+
hasAuth = false;
|
|
33
|
+
}
|
|
34
|
+
let loading = $state(true);
|
|
35
|
+
let identity = $state<Identity | null>(null);
|
|
36
|
+
|
|
37
|
+
$effect(() => {
|
|
38
|
+
if (!auth) {
|
|
39
|
+
loading = false;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
(async () => {
|
|
43
|
+
try {
|
|
44
|
+
const { authenticated, redirectTo } = await auth.check();
|
|
45
|
+
if (!authenticated) {
|
|
46
|
+
navigate(redirectTo ?? '/login');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
identity = await auth.getIdentity();
|
|
50
|
+
} finally {
|
|
51
|
+
loading = false;
|
|
52
|
+
}
|
|
53
|
+
})();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
async function handleLogout() {
|
|
57
|
+
if (!auth) return;
|
|
58
|
+
const result = await auth.logout();
|
|
59
|
+
if (result.success) {
|
|
60
|
+
navigate(result.redirectTo ?? '/login');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let collapsed = $state(false);
|
|
65
|
+
|
|
66
|
+
// Swipe gesture for mobile menu
|
|
67
|
+
let touchStartX = $state(0);
|
|
68
|
+
let touchEndX = $state(0);
|
|
69
|
+
|
|
70
|
+
function handleTouchStart(e: TouchEvent) {
|
|
71
|
+
if (e.touches.length === 1) {
|
|
72
|
+
touchStartX = e.touches[0].clientX;
|
|
73
|
+
touchEndX = e.touches[0].clientX;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function handleTouchMove(e: TouchEvent) {
|
|
78
|
+
if (e.touches.length === 1) {
|
|
79
|
+
touchEndX = e.touches[0].clientX;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function handleTouchEnd() {
|
|
84
|
+
// Only trigger swipe-to-open if starting near the left edge (e.g., within 30px)
|
|
85
|
+
// and swiping right by at least 50px
|
|
86
|
+
if (touchStartX < 30 && touchEndX - touchStartX > 50) {
|
|
87
|
+
mobileMenuOpen = true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<svelte:window
|
|
93
|
+
onkeydown={(e) => {
|
|
94
|
+
if ((e.ctrlKey || e.metaKey) && e.key === 'k') { e.preventDefault(); commandOpen = true; }
|
|
95
|
+
if (e.key === '?' && !['INPUT', 'TEXTAREA', 'SELECT'].includes((e.target as HTMLElement)?.tagName)) { e.preventDefault(); shortcutsOpen = true; }
|
|
96
|
+
}}
|
|
97
|
+
ontouchstart={handleTouchStart}
|
|
98
|
+
ontouchmove={handleTouchMove}
|
|
99
|
+
ontouchend={handleTouchEnd}
|
|
100
|
+
/>
|
|
101
|
+
{#if loading}
|
|
102
|
+
<div class="flex h-screen" in:fade={{ duration: 150 }}>
|
|
103
|
+
<div class="hidden md:block w-64 bg-sidebar/80 p-4 space-y-4">
|
|
104
|
+
<Skeleton class="h-8 w-32" />
|
|
105
|
+
<div class="space-y-2 mt-6">
|
|
106
|
+
{#each Array(5) as _}
|
|
107
|
+
<Skeleton class="h-9 w-full rounded-lg" />
|
|
108
|
+
{/each}
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
<div class="flex-1 p-8 space-y-6">
|
|
112
|
+
<Skeleton class="h-8 w-48" />
|
|
113
|
+
<div class="space-y-3">
|
|
114
|
+
{#each Array(4) as _}
|
|
115
|
+
<Skeleton class="h-12 w-full" />
|
|
116
|
+
{/each}
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
{:else}
|
|
121
|
+
<div class="flex h-screen bg-background" in:fade={{ duration: 200, delay: 50 }}>
|
|
122
|
+
<!-- Desktop sidebar -->
|
|
123
|
+
<div class="hidden md:block">
|
|
124
|
+
<Sidebar {collapsed} {identity} {title} {menu} {routeMode} onToggle={() => collapsed = !collapsed} onLogout={handleLogout} />
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<!-- Mobile sidebar via Sheet -->
|
|
128
|
+
<Sheet.Root bind:open={mobileMenuOpen} side="left">
|
|
129
|
+
<div class="md:hidden">
|
|
130
|
+
<Sidebar collapsed={false} {identity} {title} {menu} {routeMode} onToggle={() => { mobileMenuOpen = false; }} onLogout={handleLogout} />
|
|
131
|
+
</div>
|
|
132
|
+
</Sheet.Root>
|
|
133
|
+
|
|
134
|
+
<div
|
|
135
|
+
class="flex-1 flex flex-col overflow-hidden transition-all duration-300"
|
|
136
|
+
class:md:ml-64={!collapsed}
|
|
137
|
+
class:md:ml-16={collapsed}
|
|
138
|
+
>
|
|
139
|
+
<!-- Header with mobile hamburger -->
|
|
140
|
+
<Header
|
|
141
|
+
{siteUrl}
|
|
142
|
+
showSearch={true}
|
|
143
|
+
onSearchClick={() => { commandOpen = true; }}
|
|
144
|
+
>
|
|
145
|
+
{#snippet children()}
|
|
146
|
+
<!-- Mobile hamburger -->
|
|
147
|
+
<TooltipButton tooltip={t('common.menu')} class="md:hidden" onclick={() => { mobileMenuOpen = true; }}>
|
|
148
|
+
<Menu class="h-5 w-5" />
|
|
149
|
+
</TooltipButton>
|
|
150
|
+
{/snippet}
|
|
151
|
+
</Header>
|
|
152
|
+
|
|
153
|
+
<!-- Content area -->
|
|
154
|
+
<main class="flex-1 overflow-y-auto p-6 md:p-8">
|
|
155
|
+
{#key currentPath()}
|
|
156
|
+
<div in:fly={{ x: 20, duration: 150 }} out:fade={{ duration: 80 }}>
|
|
157
|
+
{@render children()}
|
|
158
|
+
</div>
|
|
159
|
+
{/key}
|
|
160
|
+
</main>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
<CommandPalette bind:open={commandOpen} />
|
|
164
|
+
<KeyboardShortcuts bind:open={shortcutsOpen} />
|
|
165
|
+
<ChatDialog />
|
|
166
|
+
<Toast />
|
|
167
|
+
{/if}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { MenuItem } from '@svadmin/core';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
children: Snippet;
|
|
5
|
+
title?: string;
|
|
6
|
+
menu?: MenuItem[];
|
|
7
|
+
siteUrl?: string;
|
|
8
|
+
routeMode?: 'hash' | 'path' | 'auto';
|
|
9
|
+
};
|
|
10
|
+
declare const Layout: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type Layout = ReturnType<typeof Layout>;
|
|
12
|
+
export default Layout;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getResource } from '@svadmin/core';
|
|
3
|
+
import { navigate } from '@svadmin/core/router';
|
|
4
|
+
import { t } from '@svadmin/core/i18n';
|
|
5
|
+
import type { Snippet } from 'svelte';
|
|
6
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
7
|
+
import PageHeader from './PageHeader.svelte';
|
|
8
|
+
import AutoTable from './AutoTable.svelte';
|
|
9
|
+
import { Button } from './ui/button/index.js';
|
|
10
|
+
import { Plus } from '@lucide/svelte';
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
resourceName: string;
|
|
14
|
+
title?: string;
|
|
15
|
+
canCreate?: boolean;
|
|
16
|
+
/** Passthrough: enable row selection checkboxes */
|
|
17
|
+
selectable?: boolean;
|
|
18
|
+
/** Passthrough: custom header actions */
|
|
19
|
+
headerActions?: Snippet;
|
|
20
|
+
/** Passthrough: custom cell renderer per field */
|
|
21
|
+
cellRenderer?: Snippet<[{ field: FieldDefinition; value: unknown; record: Record<string, unknown> }]>;
|
|
22
|
+
/** Passthrough: custom row actions */
|
|
23
|
+
rowActions?: Snippet<[{ record: Record<string, unknown>; id: string | number }]>;
|
|
24
|
+
/** Passthrough: custom empty state */
|
|
25
|
+
emptyState?: Snippet;
|
|
26
|
+
/** Passthrough: expandable row content */
|
|
27
|
+
expandedRowRender?: Snippet<[{ record: Record<string, unknown> }]>;
|
|
28
|
+
class?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let {
|
|
32
|
+
resourceName,
|
|
33
|
+
title,
|
|
34
|
+
canCreate,
|
|
35
|
+
selectable,
|
|
36
|
+
headerActions,
|
|
37
|
+
cellRenderer,
|
|
38
|
+
rowActions,
|
|
39
|
+
emptyState,
|
|
40
|
+
expandedRowRender,
|
|
41
|
+
class: className = '',
|
|
42
|
+
}: Props = $props();
|
|
43
|
+
|
|
44
|
+
const resource = $derived(getResource(resourceName));
|
|
45
|
+
const pageTitle = $derived(title ?? resource.label);
|
|
46
|
+
const showCreate = $derived(canCreate ?? resource.canCreate !== false);
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<div class="space-y-6 {className}">
|
|
50
|
+
<PageHeader title={pageTitle}>
|
|
51
|
+
{#snippet actions()}
|
|
52
|
+
{#if showCreate}
|
|
53
|
+
<Button onclick={() => navigate(`/${resourceName}/create`)}>
|
|
54
|
+
<Plus class="h-4 w-4" data-icon="inline-start" /> {t('common.create')}
|
|
55
|
+
</Button>
|
|
56
|
+
{/if}
|
|
57
|
+
{#if headerActions}
|
|
58
|
+
{@render headerActions()}
|
|
59
|
+
{/if}
|
|
60
|
+
{/snippet}
|
|
61
|
+
</PageHeader>
|
|
62
|
+
|
|
63
|
+
<AutoTable
|
|
64
|
+
{resourceName}
|
|
65
|
+
{selectable}
|
|
66
|
+
defaultCellRenderer={cellRenderer}
|
|
67
|
+
{rowActions}
|
|
68
|
+
{emptyState}
|
|
69
|
+
{expandedRowRender}
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
3
|
+
interface Props {
|
|
4
|
+
resourceName: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
canCreate?: boolean;
|
|
7
|
+
/** Passthrough: enable row selection checkboxes */
|
|
8
|
+
selectable?: boolean;
|
|
9
|
+
/** Passthrough: custom header actions */
|
|
10
|
+
headerActions?: Snippet;
|
|
11
|
+
/** Passthrough: custom cell renderer per field */
|
|
12
|
+
cellRenderer?: Snippet<[{
|
|
13
|
+
field: FieldDefinition;
|
|
14
|
+
value: unknown;
|
|
15
|
+
record: Record<string, unknown>;
|
|
16
|
+
}]>;
|
|
17
|
+
/** Passthrough: custom row actions */
|
|
18
|
+
rowActions?: Snippet<[{
|
|
19
|
+
record: Record<string, unknown>;
|
|
20
|
+
id: string | number;
|
|
21
|
+
}]>;
|
|
22
|
+
/** Passthrough: custom empty state */
|
|
23
|
+
emptyState?: Snippet;
|
|
24
|
+
/** Passthrough: expandable row content */
|
|
25
|
+
expandedRowRender?: Snippet<[{
|
|
26
|
+
record: Record<string, unknown>;
|
|
27
|
+
}]>;
|
|
28
|
+
class?: string;
|
|
29
|
+
}
|
|
30
|
+
declare const ListPage: import("svelte").Component<Props, {}, "">;
|
|
31
|
+
type ListPage = ReturnType<typeof ListPage>;
|
|
32
|
+
export default ListPage;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { fade } from 'svelte/transition';
|
|
3
|
+
import { Wifi, WifiOff, Loader2 } from '@lucide/svelte';
|
|
4
|
+
import { Badge } from './ui/badge/index.js';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
status = 'disconnected',
|
|
8
|
+
resource = '',
|
|
9
|
+
lastEvent = null,
|
|
10
|
+
showDetails = false,
|
|
11
|
+
} = $props<{
|
|
12
|
+
status: 'connecting' | 'connected' | 'disconnected';
|
|
13
|
+
resource?: string;
|
|
14
|
+
lastEvent?: { type: string; timestamp?: number } | null;
|
|
15
|
+
showDetails?: boolean;
|
|
16
|
+
}>();
|
|
17
|
+
|
|
18
|
+
const statusConfigs = {
|
|
19
|
+
connected: { variant: 'default' as const, dotClass: 'bg-success', label: 'Live', icon: Wifi },
|
|
20
|
+
connecting: { variant: 'secondary' as const, dotClass: 'bg-warning', label: 'Connecting...', icon: Loader2 as typeof Wifi },
|
|
21
|
+
disconnected: { variant: 'destructive' as const, dotClass: 'bg-destructive', label: 'Offline', icon: WifiOff },
|
|
22
|
+
} as const;
|
|
23
|
+
type StatusKey = 'connected' | 'connecting' | 'disconnected';
|
|
24
|
+
const cfg = $derived(statusConfigs[status as StatusKey]);
|
|
25
|
+
|
|
26
|
+
const timeSinceEvent = $derived(
|
|
27
|
+
lastEvent?.timestamp
|
|
28
|
+
? Math.floor((Date.now() - lastEvent.timestamp) / 1000)
|
|
29
|
+
: null
|
|
30
|
+
);
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
{#key status}
|
|
34
|
+
<div transition:fade={{ duration: 200 }}>
|
|
35
|
+
<Badge variant={cfg.variant} class="gap-1.5 select-none" title={cfg.label}>
|
|
36
|
+
<span class="relative flex h-2 w-2">
|
|
37
|
+
<span class="{cfg.dotClass} rounded-full h-2 w-2"></span>
|
|
38
|
+
{#if status === 'connected'}
|
|
39
|
+
<span class="absolute inset-0 rounded-full {cfg.dotClass} opacity-40 animate-ping"></span>
|
|
40
|
+
{/if}
|
|
41
|
+
</span>
|
|
42
|
+
<span class="text-[0.6875rem] font-semibold uppercase tracking-wide">{cfg.label}</span>
|
|
43
|
+
|
|
44
|
+
{#if showDetails && resource}
|
|
45
|
+
<span class="text-[0.625rem] font-mono opacity-70">{resource}</span>
|
|
46
|
+
{/if}
|
|
47
|
+
|
|
48
|
+
{#if showDetails && lastEvent}
|
|
49
|
+
<span class="text-[0.625rem] opacity-70">
|
|
50
|
+
{lastEvent.type}
|
|
51
|
+
{#if timeSinceEvent !== null && timeSinceEvent < 60}
|
|
52
|
+
<span class="opacity-60">{timeSinceEvent}s ago</span>
|
|
53
|
+
{/if}
|
|
54
|
+
</span>
|
|
55
|
+
{/if}
|
|
56
|
+
</Badge>
|
|
57
|
+
</div>
|
|
58
|
+
{/key}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
status: 'connecting' | 'connected' | 'disconnected';
|
|
3
|
+
resource?: string;
|
|
4
|
+
lastEvent?: {
|
|
5
|
+
type: string;
|
|
6
|
+
timestamp?: number;
|
|
7
|
+
} | null;
|
|
8
|
+
showDetails?: boolean;
|
|
9
|
+
};
|
|
10
|
+
declare const LiveIndicator: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type LiveIndicator = ReturnType<typeof LiveIndicator>;
|
|
12
|
+
export default LiveIndicator;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useLogin, getAuthProvider } from '@svadmin/core';
|
|
3
|
+
import { t } from '@svadmin/core/i18n';
|
|
4
|
+
import { navigate } from '@svadmin/core/router';
|
|
5
|
+
import { Button } from './ui/button/index.js';
|
|
6
|
+
import { Input } from './ui/input/index.js';
|
|
7
|
+
import { Label } from './ui/label/index.js';
|
|
8
|
+
import * as Card from './ui/card/index.js';
|
|
9
|
+
import * as Alert from './ui/alert/index.js';
|
|
10
|
+
import PasswordInput from './PasswordInput.svelte';
|
|
11
|
+
import { Separator } from './ui/separator/index.js';
|
|
12
|
+
import { LogIn, User, Loader2, AlertCircle } from '@lucide/svelte';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Social provider config for the login page.
|
|
16
|
+
* Each entry renders a button that calls `onClick()` when clicked.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const socialProviders = [
|
|
21
|
+
* { name: 'Google', icon: '🔵', onClick: () => googleAuth.login({}) },
|
|
22
|
+
* { name: 'GitHub', icon: '🐙', onClick: () => githubAuth.login({}) },
|
|
23
|
+
* ];
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
interface SocialProvider {
|
|
27
|
+
/** Display name (e.g., 'Google') */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Icon character, emoji, or SVG string */
|
|
30
|
+
icon?: string;
|
|
31
|
+
/** Handler to initiate social login */
|
|
32
|
+
onClick: () => void | Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let { title = 'Admin', onSuccess, socialProviders = [] } = $props<{
|
|
36
|
+
title?: string;
|
|
37
|
+
onSuccess?: () => void;
|
|
38
|
+
socialProviders?: SocialProvider[];
|
|
39
|
+
}>();
|
|
40
|
+
|
|
41
|
+
const login = useLogin();
|
|
42
|
+
const authProvider = getAuthProvider();
|
|
43
|
+
|
|
44
|
+
let identifier = $state('');
|
|
45
|
+
let password = $state('');
|
|
46
|
+
let error = $state('');
|
|
47
|
+
|
|
48
|
+
async function handleSubmit(e: Event) {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
error = '';
|
|
51
|
+
|
|
52
|
+
if (!identifier) { error = t('auth.usernameOrEmailRequired'); return; }
|
|
53
|
+
if (!password) { error = t('auth.passwordRequired'); return; }
|
|
54
|
+
|
|
55
|
+
const result = await login.mutate({ email: identifier, username: identifier, password });
|
|
56
|
+
if (result.success) {
|
|
57
|
+
onSuccess?.();
|
|
58
|
+
} else {
|
|
59
|
+
error = result.error?.message ?? t('common.loginFailed');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-slate-100 via-blue-50/30 to-indigo-50/40 dark:from-slate-950 dark:via-slate-900 dark:to-indigo-950/20 p-4">
|
|
65
|
+
<div class="w-full max-w-[380px]">
|
|
66
|
+
<Card.Card>
|
|
67
|
+
<Card.CardHeader class="text-center pb-2">
|
|
68
|
+
<div class="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10 text-primary mx-auto mb-3">
|
|
69
|
+
<LogIn class="h-5 w-5" />
|
|
70
|
+
</div>
|
|
71
|
+
<Card.CardTitle class="text-xl">{t('auth.welcomeBack')}</Card.CardTitle>
|
|
72
|
+
<p class="text-sm text-muted-foreground">{t('auth.welcomeMessage')}</p>
|
|
73
|
+
</Card.CardHeader>
|
|
74
|
+
<Card.CardContent>
|
|
75
|
+
<form onsubmit={handleSubmit} class="space-y-4">
|
|
76
|
+
{#if error}
|
|
77
|
+
<Alert.Root variant="destructive">
|
|
78
|
+
<AlertCircle class="h-4 w-4" />
|
|
79
|
+
<Alert.Description>{error}</Alert.Description>
|
|
80
|
+
</Alert.Root>
|
|
81
|
+
{/if}
|
|
82
|
+
|
|
83
|
+
<div class="space-y-2">
|
|
84
|
+
<Label for="login-identifier">{t('auth.usernameOrEmail')}</Label>
|
|
85
|
+
<div class="relative">
|
|
86
|
+
<User class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none z-[1]" />
|
|
87
|
+
<Input
|
|
88
|
+
id="login-identifier"
|
|
89
|
+
type="text"
|
|
90
|
+
placeholder={t('auth.identifierPlaceholder')}
|
|
91
|
+
bind:value={identifier}
|
|
92
|
+
class="pl-9"
|
|
93
|
+
autocomplete="username"
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div>
|
|
99
|
+
<div class="flex items-center justify-between mb-2">
|
|
100
|
+
<Label for="login-password">{t('auth.password')}</Label>
|
|
101
|
+
{#if authProvider.forgotPassword}
|
|
102
|
+
<Button variant="link" class="text-xs h-auto p-0" onclick={() => navigate('/forgot-password')}>
|
|
103
|
+
{t('auth.forgotPasswordLink')}
|
|
104
|
+
</Button>
|
|
105
|
+
{/if}
|
|
106
|
+
</div>
|
|
107
|
+
<PasswordInput
|
|
108
|
+
id="login-password"
|
|
109
|
+
label=""
|
|
110
|
+
bind:value={password}
|
|
111
|
+
autocomplete="current-password"
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<Button type="submit" class="w-full" disabled={login.isLoading}>
|
|
116
|
+
{#if login.isLoading}
|
|
117
|
+
<Loader2 class="h-4 w-4 animate-spin mr-2" />
|
|
118
|
+
{/if}
|
|
119
|
+
{t('auth.loginButton')}
|
|
120
|
+
</Button>
|
|
121
|
+
</form>
|
|
122
|
+
|
|
123
|
+
{#if socialProviders.length > 0}
|
|
124
|
+
<div class="relative my-5">
|
|
125
|
+
<Separator />
|
|
126
|
+
<span class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-card px-3 text-xs text-muted-foreground">
|
|
127
|
+
{t('auth.orContinueWith')}
|
|
128
|
+
</span>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div class="grid gap-2" class:grid-cols-2={socialProviders.length >= 2}>
|
|
132
|
+
{#each socialProviders as provider (provider.name)}
|
|
133
|
+
<Button
|
|
134
|
+
variant="outline"
|
|
135
|
+
class="w-full"
|
|
136
|
+
onclick={provider.onClick}
|
|
137
|
+
>
|
|
138
|
+
{#if provider.icon}
|
|
139
|
+
<span class="mr-2">{provider.icon}</span>
|
|
140
|
+
{/if}
|
|
141
|
+
{provider.name}
|
|
142
|
+
</Button>
|
|
143
|
+
{/each}
|
|
144
|
+
</div>
|
|
145
|
+
{/if}
|
|
146
|
+
|
|
147
|
+
{#if authProvider.register}
|
|
148
|
+
<div class="flex items-center justify-center gap-1 mt-5 pt-5 border-t">
|
|
149
|
+
<span class="text-sm text-muted-foreground">{t('auth.noAccount')}</span>
|
|
150
|
+
<Button variant="link" class="text-sm h-auto p-0 font-medium" onclick={() => navigate('/register')}>
|
|
151
|
+
{t('auth.register')}
|
|
152
|
+
</Button>
|
|
153
|
+
</div>
|
|
154
|
+
{/if}
|
|
155
|
+
</Card.CardContent>
|
|
156
|
+
</Card.Card>
|
|
157
|
+
|
|
158
|
+
<p class="text-xs text-muted-foreground mt-4 text-center">
|
|
159
|
+
Powered by {title}
|
|
160
|
+
</p>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Social provider config for the login page.
|
|
3
|
+
* Each entry renders a button that calls `onClick()` when clicked.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* const socialProviders = [
|
|
8
|
+
* { name: 'Google', icon: '🔵', onClick: () => googleAuth.login({}) },
|
|
9
|
+
* { name: 'GitHub', icon: '🐙', onClick: () => githubAuth.login({}) },
|
|
10
|
+
* ];
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
interface SocialProvider {
|
|
14
|
+
/** Display name (e.g., 'Google') */
|
|
15
|
+
name: string;
|
|
16
|
+
/** Icon character, emoji, or SVG string */
|
|
17
|
+
icon?: string;
|
|
18
|
+
/** Handler to initiate social login */
|
|
19
|
+
onClick: () => void | Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
type $$ComponentProps = {
|
|
22
|
+
title?: string;
|
|
23
|
+
onSuccess?: () => void;
|
|
24
|
+
socialProviders?: SocialProvider[];
|
|
25
|
+
};
|
|
26
|
+
declare const LoginPage: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
27
|
+
type LoginPage = ReturnType<typeof LoginPage>;
|
|
28
|
+
export default LoginPage;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import * as markedPkg from "marked";
|
|
3
|
+
import * as markedHighlightPkg from "marked-highlight";
|
|
4
|
+
import * as hljsPkg from "highlight.js";
|
|
5
|
+
import * as DOMPurifyPkg from "isomorphic-dompurify";
|
|
6
|
+
import { Check, Copy } from '@lucide/svelte';
|
|
7
|
+
import { Button } from "./ui/button/index.js";
|
|
8
|
+
|
|
9
|
+
const Marked = markedPkg.Marked;
|
|
10
|
+
const markedHighlight = markedHighlightPkg.markedHighlight;
|
|
11
|
+
const hljsModule = hljsPkg.default || hljsPkg;
|
|
12
|
+
const DOMPurify = 'default' in DOMPurifyPkg ? DOMPurifyPkg.default : DOMPurifyPkg;
|
|
13
|
+
|
|
14
|
+
// Only safely import css if hljs exists
|
|
15
|
+
if (hljsModule && Object.keys(hljsModule).length > 0) {
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
import("highlight.js/styles/github-dark.css").catch(() => {});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface Props {
|
|
21
|
+
/** The raw markdown string to render */
|
|
22
|
+
content: string;
|
|
23
|
+
/** Whether to enable streaming/typing effect styling */
|
|
24
|
+
streaming?: boolean;
|
|
25
|
+
/** Custom class for the container */
|
|
26
|
+
class?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let { content, streaming = false, class: className = "" }: Props = $props();
|
|
30
|
+
|
|
31
|
+
const hasMarkdownDeps = !!(Marked && Object.keys(DOMPurify || {}).length > 0);
|
|
32
|
+
|
|
33
|
+
// Configure marked with syntax highlighting if available
|
|
34
|
+
const markedObj = hasMarkdownDeps ? new Marked(
|
|
35
|
+
markedHighlight({
|
|
36
|
+
langPrefix: "hljs language-",
|
|
37
|
+
highlight(code: string, lang: string) {
|
|
38
|
+
const language = hljsModule.getLanguage && hljsModule.getLanguage(lang) ? lang : "plaintext";
|
|
39
|
+
return hljsModule.highlight ? hljsModule.highlight(code, { language }).value : code;
|
|
40
|
+
},
|
|
41
|
+
}),
|
|
42
|
+
) : null;
|
|
43
|
+
|
|
44
|
+
// Render HTML safely
|
|
45
|
+
const html = $derived(
|
|
46
|
+
hasMarkdownDeps
|
|
47
|
+
? DOMPurify.sanitize(markedObj!.parse(content || "") as string)
|
|
48
|
+
: `<div style="white-space: pre-wrap">${String(content || "").replace(/</g, "<").replace(/>/g, ">")}</div>`
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Handle copy code blocks
|
|
52
|
+
let copiedBlock = $state<string | null>(null);
|
|
53
|
+
|
|
54
|
+
function handleCopy(event: MouseEvent) {
|
|
55
|
+
const target = event.target as HTMLElement;
|
|
56
|
+
const button = target.closest(".copy-btn");
|
|
57
|
+
if (!button) return;
|
|
58
|
+
|
|
59
|
+
const pre = button.closest(".code-block-wrapper")?.querySelector("pre");
|
|
60
|
+
if (!pre) return;
|
|
61
|
+
|
|
62
|
+
const code = pre.textContent || "";
|
|
63
|
+
navigator.clipboard.writeText(code);
|
|
64
|
+
|
|
65
|
+
const id = Math.random().toString(36);
|
|
66
|
+
copiedBlock = id;
|
|
67
|
+
button.setAttribute("data-copied-id", id);
|
|
68
|
+
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
if (copiedBlock === id) copiedBlock = null;
|
|
71
|
+
}, 2000);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Inject copy buttons into the HTML after rendering
|
|
75
|
+
// We do this via action instead of raw string manipulation for safety
|
|
76
|
+
function enhanceCodeBlocks(node: HTMLElement, _: string) {
|
|
77
|
+
return {
|
|
78
|
+
update(newHtml: string) {
|
|
79
|
+
// Find all pre > code blocks that don't have wrappers yet
|
|
80
|
+
const pres = node.querySelectorAll("pre:not(.enhanced)");
|
|
81
|
+
pres.forEach((pre) => {
|
|
82
|
+
pre.classList.add("enhanced");
|
|
83
|
+
const wrapper = document.createElement("div");
|
|
84
|
+
wrapper.className =
|
|
85
|
+
"code-block-wrapper group relative my-4 rounded-md bg-foreground/95";
|
|
86
|
+
|
|
87
|
+
const header = document.createElement("div");
|
|
88
|
+
header.className =
|
|
89
|
+
"flex items-center justify-between px-4 py-2 text-xs text-zinc-400 border-b border-zinc-800";
|
|
90
|
+
|
|
91
|
+
const lang =
|
|
92
|
+
Array.from(pre.querySelector("code")?.classList || [])
|
|
93
|
+
.find((c) => c.startsWith("language-"))
|
|
94
|
+
?.replace("language-", "") || "Code";
|
|
95
|
+
header.innerHTML = `
|
|
96
|
+
<span>${lang}</span>
|
|
97
|
+
<button class="copy-btn hover:text-white transition-colors flex items-center gap-1">
|
|
98
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
|
|
99
|
+
</button>
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
pre.replaceWith(wrapper);
|
|
103
|
+
wrapper.appendChild(header);
|
|
104
|
+
|
|
105
|
+
const scrollContainer = document.createElement("div");
|
|
106
|
+
scrollContainer.className = "overflow-x-auto p-4";
|
|
107
|
+
scrollContainer.appendChild(pre);
|
|
108
|
+
wrapper.appendChild(scrollContainer);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Add event listener for copy buttons
|
|
112
|
+
node.addEventListener("click", handleCopy);
|
|
113
|
+
},
|
|
114
|
+
destroy() {
|
|
115
|
+
node.removeEventListener("click", handleCopy);
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
</script>
|
|
120
|
+
|
|
121
|
+
<div
|
|
122
|
+
class="prose prose-sm dark:prose-invert max-w-none wrap-break-word {className}"
|
|
123
|
+
class:streaming={streaming}
|
|
124
|
+
use:enhanceCodeBlocks={html}
|
|
125
|
+
>
|
|
126
|
+
{@html html}
|
|
127
|
+
</div>
|