@riducms/admin 0.1.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/LICENSE +21 -0
- package/README.md +31 -0
- package/THIRD_PARTY_NOTICES.md +217 -0
- package/package.json +62 -0
- package/src/app/admin-core-view-route.svelte +89 -0
- package/src/app/admin-layout.svelte +457 -0
- package/src/app/admin-navigation-progress.svelte +204 -0
- package/src/app/admin-page-title.svelte +94 -0
- package/src/app/admin-provider-layer.svelte +26 -0
- package/src/app/admin-router-root.svelte +9 -0
- package/src/app/admin-routes.svelte +116 -0
- package/src/app/deferred-redirect.svelte +23 -0
- package/src/app/loading-boundary.svelte +70 -0
- package/src/app/not-found-route.svelte +29 -0
- package/src/app-meta.ts +2 -0
- package/src/app.css +467 -0
- package/src/app.svelte +88 -0
- package/src/assets/ridu-logo-arch.svg +3 -0
- package/src/assets/ridu-word-logo.svg +7 -0
- package/src/components/brand/ridu-logo.svelte +24 -0
- package/src/components/code-block/code-block.svelte +107 -0
- package/src/components/json-tree/json-tree-node.svelte +77 -0
- package/src/components/json-tree/json-viewer.svelte +113 -0
- package/src/components/ui/banner/banner.svelte +41 -0
- package/src/components/ui/banner/index.ts +5 -0
- package/src/components/ui/bulk-action-bar/bulk-action-bar.svelte +50 -0
- package/src/components/ui/bulk-action-bar/index.ts +1 -0
- package/src/components/ui/button/index.ts +8 -0
- package/src/components/ui/calendar/calendar-caption.svelte +72 -0
- package/src/components/ui/calendar/calendar-cell.svelte +20 -0
- package/src/components/ui/calendar/calendar-day.svelte +27 -0
- package/src/components/ui/calendar/calendar-grid-row.svelte +13 -0
- package/src/components/ui/calendar/calendar-grid.svelte +17 -0
- package/src/components/ui/calendar/calendar-head-cell.svelte +20 -0
- package/src/components/ui/calendar/calendar-header.svelte +20 -0
- package/src/components/ui/calendar/calendar-heading.svelte +17 -0
- package/src/components/ui/calendar/calendar-month-select.svelte +45 -0
- package/src/components/ui/calendar/calendar-month.svelte +16 -0
- package/src/components/ui/calendar/calendar-months.svelte +20 -0
- package/src/components/ui/calendar/calendar-nav.svelte +20 -0
- package/src/components/ui/calendar/calendar-next-button.svelte +30 -0
- package/src/components/ui/calendar/calendar-prev-button.svelte +30 -0
- package/src/components/ui/calendar/calendar-year-select.svelte +44 -0
- package/src/components/ui/calendar/calendar.svelte +118 -0
- package/src/components/ui/calendar/index.ts +1 -0
- package/src/components/ui/checkbox/checkbox.svelte +35 -0
- package/src/components/ui/checkbox/index.ts +1 -0
- package/src/components/ui/confirmation-dialog/confirmation-dialog.svelte +37 -0
- package/src/components/ui/confirmation-dialog/index.ts +1 -0
- package/src/components/ui/date-value-control/date-value-calendar.svelte +37 -0
- package/src/components/ui/date-value-control/date-value-control-loader.svelte +36 -0
- package/src/components/ui/date-value-control/date-value-control.svelte +177 -0
- package/src/components/ui/date-value-control/index.ts +3 -0
- package/src/components/ui/dialog/dialog-close.svelte +11 -0
- package/src/components/ui/dialog/dialog-content.svelte +52 -0
- package/src/components/ui/dialog/dialog-description.svelte +20 -0
- package/src/components/ui/dialog/dialog-footer.svelte +20 -0
- package/src/components/ui/dialog/dialog-header.svelte +20 -0
- package/src/components/ui/dialog/dialog-overlay.svelte +20 -0
- package/src/components/ui/dialog/dialog-title.svelte +17 -0
- package/src/components/ui/dialog/dialog-trigger.svelte +11 -0
- package/src/components/ui/dialog/dialog.svelte +7 -0
- package/src/components/ui/dialog/index.ts +8 -0
- package/src/components/ui/dropdown-menu/dropdown-menu-content.svelte +27 -0
- package/src/components/ui/dropdown-menu/dropdown-menu-item.svelte +20 -0
- package/src/components/ui/dropdown-menu/dropdown-menu-separator.svelte +17 -0
- package/src/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +16 -0
- package/src/components/ui/dropdown-menu/dropdown-menu.svelte +7 -0
- package/src/components/ui/dropdown-menu/index.ts +5 -0
- package/src/components/ui/empty-state/empty-state.svelte +34 -0
- package/src/components/ui/empty-state/index.ts +1 -0
- package/src/components/ui/input/index.ts +1 -0
- package/src/components/ui/kbd/index.ts +1 -0
- package/src/components/ui/kbd/kbd.svelte +24 -0
- package/src/components/ui/pagination/index.ts +1 -0
- package/src/components/ui/pagination/pagination.svelte +88 -0
- package/src/components/ui/popover/index.ts +3 -0
- package/src/components/ui/popover/popover-content.svelte +29 -0
- package/src/components/ui/popover/popover-trigger.svelte +11 -0
- package/src/components/ui/popover/popover.svelte +7 -0
- package/src/components/ui/radio-group/index.ts +3 -0
- package/src/components/ui/radio-group/radio-card-item.svelte +38 -0
- package/src/components/ui/radio-group/radio-group-item.svelte +17 -0
- package/src/components/ui/radio-group/radio-group.svelte +19 -0
- package/src/components/ui/select/index.ts +4 -0
- package/src/components/ui/select/select-content.svelte +38 -0
- package/src/components/ui/select/select-item.svelte +40 -0
- package/src/components/ui/select/select-scroll-down-button.svelte +23 -0
- package/src/components/ui/select/select-scroll-up-button.svelte +23 -0
- package/src/components/ui/select/select-trigger.svelte +29 -0
- package/src/components/ui/select/select.svelte +11 -0
- package/src/components/ui/sheet/index.ts +6 -0
- package/src/components/ui/sheet/sheet-close.svelte +7 -0
- package/src/components/ui/sheet/sheet-content.svelte +77 -0
- package/src/components/ui/sheet/sheet-description.svelte +17 -0
- package/src/components/ui/sheet/sheet-overlay.svelte +36 -0
- package/src/components/ui/sheet/sheet-title.svelte +17 -0
- package/src/components/ui/sheet/sheet-trigger.svelte +7 -0
- package/src/components/ui/sheet/sheet.svelte +7 -0
- package/src/components/ui/skeleton/index.ts +1 -0
- package/src/components/ui/skeleton/skeleton.svelte +31 -0
- package/src/components/ui/slider/index.ts +3 -0
- package/src/components/ui/slider/slider-content.svelte +59 -0
- package/src/components/ui/slider/slider.svelte +35 -0
- package/src/components/ui/sonner/index.ts +1 -0
- package/src/components/ui/sonner/sonner.svelte +55 -0
- package/src/components/ui/status-indicator/index.ts +5 -0
- package/src/components/ui/status-indicator/status-indicator.svelte +54 -0
- package/src/components/ui/table/index.ts +6 -0
- package/src/components/ui/table/table-body.svelte +20 -0
- package/src/components/ui/table/table-cell.svelte +23 -0
- package/src/components/ui/table/table-head.svelte +23 -0
- package/src/components/ui/table/table-header.svelte +20 -0
- package/src/components/ui/table/table-row.svelte +23 -0
- package/src/components/ui/table/table.svelte +22 -0
- package/src/components/ui/tabs/index.ts +8 -0
- package/src/components/ui/tabs/tabs-content.svelte +17 -0
- package/src/components/ui/tabs/tabs-list.svelte +40 -0
- package/src/components/ui/tabs/tabs-trigger.svelte +23 -0
- package/src/components/ui/tabs/tabs.svelte +19 -0
- package/src/components/ui/textarea/index.ts +1 -0
- package/src/components/ui/tooltip/index.ts +4 -0
- package/src/components/ui/tooltip/tooltip-content.svelte +50 -0
- package/src/components/ui/tooltip/tooltip-provider.svelte +7 -0
- package/src/components/ui/tooltip/tooltip-trigger.svelte +7 -0
- package/src/components/ui/tooltip/tooltip.svelte +7 -0
- package/src/core/api/admin-client.ts +45 -0
- package/src/core/forms/field-condition.ts +63 -0
- package/src/core/forms/form-controller.svelte.ts +369 -0
- package/src/core/forms/form-draft-recovery.ts +80 -0
- package/src/core/forms/form-schema.ts +609 -0
- package/src/core/forms/form-validation.ts +750 -0
- package/src/core/i18n/admin-i18n.svelte.ts +364 -0
- package/src/core/i18n/localized-schema.ts +111 -0
- package/src/core/notifications/notification-center.svelte.ts +69 -0
- package/src/core/notifications/validation-toast.svelte +18 -0
- package/src/core/plugins/field-registry.ts +60 -0
- package/src/core/plugins/row-label-registry.ts +62 -0
- package/src/core/preferences/preference-write-queue.ts +107 -0
- package/src/core/routing/admin-paths.ts +137 -0
- package/src/core/runtime/admin-runtime.svelte.ts +625 -0
- package/src/features/auth/account-menu.svelte +159 -0
- package/src/features/auth/account-navigation.svelte +44 -0
- package/src/features/auth/account-route.svelte +395 -0
- package/src/features/auth/account-security-controller.svelte.ts +119 -0
- package/src/features/auth/account-security-route.svelte +460 -0
- package/src/features/auth/auth-brand.svelte +17 -0
- package/src/features/auth/auth-frame.svelte +18 -0
- package/src/features/auth/create-first-user-controller.svelte.ts +220 -0
- package/src/features/auth/create-first-user-route.svelte +174 -0
- package/src/features/auth/forgot-password-route.svelte +78 -0
- package/src/features/auth/login-route.svelte +221 -0
- package/src/features/auth/request-verification-route.svelte +73 -0
- package/src/features/auth/reset-password-route.svelte +107 -0
- package/src/features/auth/verify-email-route.svelte +60 -0
- package/src/features/collections/collection-list-bulk-actions.svelte +143 -0
- package/src/features/collections/collection-list-bulk-editor.svelte +157 -0
- package/src/features/collections/collection-list-controller.svelte.ts +717 -0
- package/src/features/collections/collection-list-filter-popover.svelte +238 -0
- package/src/features/collections/collection-list-preferences-controller.svelte.ts +393 -0
- package/src/features/collections/collection-list-results.svelte +410 -0
- package/src/features/collections/collection-list-route.svelte +951 -0
- package/src/features/collections/collection-list-workspace-toolbar.svelte +409 -0
- package/src/features/collections/collection-table-skeleton.svelte +44 -0
- package/src/features/collections/list-workspace.ts +265 -0
- package/src/features/dashboard/dashboard-route.svelte +141 -0
- package/src/features/development/development-tools.svelte +217 -0
- package/src/features/documents/document-api-view-loader.svelte +31 -0
- package/src/features/documents/document-api-view.svelte +547 -0
- package/src/features/documents/document-controller.svelte.ts +1252 -0
- package/src/features/documents/document-field-partition.ts +18 -0
- package/src/features/documents/document-field-sections.svelte +46 -0
- package/src/features/documents/document-heading.ts +20 -0
- package/src/features/documents/document-route-dirty.ts +43 -0
- package/src/features/documents/document-route-loader.svelte +22 -0
- package/src/features/documents/document-route.svelte +1124 -0
- package/src/features/documents/live-preview-panel.svelte +390 -0
- package/src/features/documents/live-preview.ts +61 -0
- package/src/features/documents/upload-document-preview-loader.svelte +40 -0
- package/src/features/documents/upload-document-preview.svelte +525 -0
- package/src/features/localization/content-locale-switcher.svelte +93 -0
- package/src/features/navigation/admin-breadcrumbs.svelte +124 -0
- package/src/features/navigation/admin-command-menu.svelte +245 -0
- package/src/features/navigation/admin-resource-groups.ts +72 -0
- package/src/features/reference-browser/reference-browser-loader.svelte +15 -0
- package/src/features/reference-browser/reference-browser-workflow.svelte.ts +691 -0
- package/src/features/reference-browser/reference-browser.svelte +844 -0
- package/src/features/uploads/bulk-upload-route.svelte +624 -0
- package/src/features/uploads/bulk-upload.ts +39 -0
- package/src/features/uploads/upload-metadata-fields.svelte +112 -0
- package/src/features/versions/version-diff.ts +72 -0
- package/src/features/versions/version-history-route.svelte +581 -0
- package/src/fields/field-clipboard.ts +132 -0
- package/src/fields/field-layout.svelte +60 -0
- package/src/fields/field-layout.ts +57 -0
- package/src/fields/field-messages.svelte +29 -0
- package/src/fields/field-renderer.svelte +152 -0
- package/src/fields/field-shell.svelte +30 -0
- package/src/fields/field-tab-layout.svelte +99 -0
- package/src/fields/join/join-field.svelte +358 -0
- package/src/fields/localized-field-presentation.ts +17 -0
- package/src/fields/nested/nested-field.svelte +602 -0
- package/src/fields/nested/scoped-field.ts +78 -0
- package/src/fields/nested/sortable-row.svelte +32 -0
- package/src/fields/point/point-field.svelte +52 -0
- package/src/fields/radio/radio-field.svelte +34 -0
- package/src/fields/relationship/relationship-field-controller.svelte.ts +245 -0
- package/src/fields/relationship/relationship-field.svelte +258 -0
- package/src/fields/relationship/relationship-lookup-controller.svelte.ts +129 -0
- package/src/fields/relationship/relationship-query.ts +88 -0
- package/src/fields/relationship/relationship-quick-picker-controller.svelte.ts +198 -0
- package/src/fields/relationship/relationship-quick-picker.svelte +327 -0
- package/src/fields/relationship/relationship-value.ts +47 -0
- package/src/fields/scalar/date-control-value.ts +60 -0
- package/src/fields/scalar/date-value.ts +26 -0
- package/src/fields/scalar/scalar-field.svelte +137 -0
- package/src/fields/select/select-field.svelte +132 -0
- package/src/fields/select/select-value.ts +14 -0
- package/src/fields/text/slug-field.svelte +87 -0
- package/src/fields/text/slug.ts +38 -0
- package/src/fields/text/text-field.svelte +41 -0
- package/src/fields/ui/ui-field.svelte +12 -0
- package/src/fields/virtual/virtual-field.svelte +28 -0
- package/src/index.ts +49 -0
- package/src/main.ts +12 -0
- package/src/vite-env.d.ts +9 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useLocation } from "@hvniel/svelte-router";
|
|
3
|
+
|
|
4
|
+
import { ADMIN_NAME } from "@admin/app-meta";
|
|
5
|
+
import { getAdminRuntime } from "@admin/core/runtime/admin-runtime.svelte";
|
|
6
|
+
|
|
7
|
+
const runtime = getAdminRuntime();
|
|
8
|
+
const location = $derived(useLocation());
|
|
9
|
+
const pageTitle = $derived.by(resolvePageTitle);
|
|
10
|
+
|
|
11
|
+
function resolvePageTitle() {
|
|
12
|
+
const segments = location.pathname.split("/").filter(Boolean);
|
|
13
|
+
if (segments.length === 0) return titled(runtime.i18n.t("dashboard:heading"));
|
|
14
|
+
if (segments[0] === "create-first-user") return titled(runtime.i18n.t("auth:createFirstUser"));
|
|
15
|
+
if (segments[0] === "login") return titled(runtime.i18n.t("auth:login"));
|
|
16
|
+
if (segments[0] === "forgot-password") return titled(runtime.i18n.t("auth:forgotPassword"));
|
|
17
|
+
if (segments[0] === "reset-password") return titled(runtime.i18n.t("auth:resetPassword"));
|
|
18
|
+
if (segments[0] === "request-verification")
|
|
19
|
+
return titled(runtime.i18n.t("auth:requestVerification"));
|
|
20
|
+
if (segments[0] === "verify-email") return titled(runtime.i18n.t("auth:verifyEmail"));
|
|
21
|
+
if (segments[0] === "account") {
|
|
22
|
+
return titled(
|
|
23
|
+
segments[1] === "security"
|
|
24
|
+
? runtime.i18n.t("account:accountSecurity")
|
|
25
|
+
: runtime.i18n.t("account:account")
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
if (segments[0] === "collections" && segments[1] !== undefined) {
|
|
29
|
+
const collection = runtime.manifest?.collections.find(
|
|
30
|
+
(candidate) => candidate.slug === segments[1]
|
|
31
|
+
);
|
|
32
|
+
const singular =
|
|
33
|
+
collection === undefined
|
|
34
|
+
? humanize(segments[1])
|
|
35
|
+
: runtime.i18n.text(collection.labels.singular, collection.labels.singularTranslations);
|
|
36
|
+
const plural =
|
|
37
|
+
collection === undefined
|
|
38
|
+
? singular
|
|
39
|
+
: runtime.i18n.text(collection.labels.plural, collection.labels.pluralTranslations);
|
|
40
|
+
if (segments[2] === undefined) return titled(plural);
|
|
41
|
+
if (segments[2] === "create") {
|
|
42
|
+
return titled(
|
|
43
|
+
segments[3] === "api"
|
|
44
|
+
? runtime.i18n.t("documents:apiFor", { label: singular })
|
|
45
|
+
: runtime.i18n.t("collections:createNew", { label: singular })
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
if (segments[2] === "trash")
|
|
49
|
+
return titled(
|
|
50
|
+
runtime.i18n.t("collections:trashFor", {
|
|
51
|
+
label: plural,
|
|
52
|
+
})
|
|
53
|
+
);
|
|
54
|
+
if (segments[3] === "api")
|
|
55
|
+
return titled(runtime.i18n.t("documents:apiFor", { label: singular }));
|
|
56
|
+
if (segments[3] === "versions")
|
|
57
|
+
return titled(runtime.i18n.t("documents:versionsFor", { label: singular }));
|
|
58
|
+
return titled(runtime.i18n.t("documents:editing", { label: singular }));
|
|
59
|
+
}
|
|
60
|
+
if (segments[0] === "globals" && segments[1] !== undefined) {
|
|
61
|
+
const global = runtime.manifest?.globals?.find((candidate) => candidate.slug === segments[1]);
|
|
62
|
+
const label =
|
|
63
|
+
global === undefined
|
|
64
|
+
? humanize(segments[1])
|
|
65
|
+
: runtime.i18n.text(global.labels.singular, global.labels.singularTranslations);
|
|
66
|
+
if (segments[2] === "api") return titled(runtime.i18n.t("documents:apiFor", { label }));
|
|
67
|
+
if (segments[2] === "versions")
|
|
68
|
+
return titled(runtime.i18n.t("documents:versionsFor", { label }));
|
|
69
|
+
return titled(label);
|
|
70
|
+
}
|
|
71
|
+
const pluginPath = segments.join("/");
|
|
72
|
+
const pluginRoute = runtime.pluginRoutes.find((route) => route.path === pluginPath);
|
|
73
|
+
if (pluginRoute?.navigation?.labelKey !== undefined)
|
|
74
|
+
return titled(runtime.i18n.t(pluginRoute.navigation.labelKey));
|
|
75
|
+
if (pluginRoute?.navigation?.label !== undefined) return titled(pluginRoute.navigation.label);
|
|
76
|
+
return titled(humanize(segments.at(-1) ?? runtime.i18n.t("navigation:page")));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function titled(value: string) {
|
|
80
|
+
const application = runtime.manifest?.application;
|
|
81
|
+
const name =
|
|
82
|
+
application === undefined
|
|
83
|
+
? ADMIN_NAME
|
|
84
|
+
: runtime.i18n.text(application.name, application.nameTranslations);
|
|
85
|
+
return `${value} - ${name}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function humanize(value: string) {
|
|
89
|
+
const decoded = decodeURIComponent(value).replaceAll("-", " ");
|
|
90
|
+
return decoded.charAt(0).toLocaleUpperCase(runtime.i18n.language) + decoded.slice(1);
|
|
91
|
+
}
|
|
92
|
+
</script>
|
|
93
|
+
|
|
94
|
+
<svelte:head><title>{pageTitle}</title></svelte:head>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { AdminI18n, AdminProvider } from "@riducms/plugin";
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
4
|
+
|
|
5
|
+
import AdminProviderLayer from "@admin/app/admin-provider-layer.svelte";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
providers: readonly AdminProvider[];
|
|
9
|
+
children: Snippet;
|
|
10
|
+
i18n: AdminI18n;
|
|
11
|
+
index?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let { providers, children, i18n, index = 0 }: Props = $props();
|
|
15
|
+
const provider = $derived(providers[index]);
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
{#snippet remainingView()}
|
|
19
|
+
<AdminProviderLayer {providers} {children} {i18n} index={index + 1} />
|
|
20
|
+
{/snippet}
|
|
21
|
+
|
|
22
|
+
{#if provider === undefined}
|
|
23
|
+
{@render children()}
|
|
24
|
+
{:else}
|
|
25
|
+
<provider.component defaultView={remainingView} {i18n} />
|
|
26
|
+
{/if}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import AdminNavigationProgress from "@admin/app/admin-navigation-progress.svelte";
|
|
3
|
+
import AdminPageTitle from "@admin/app/admin-page-title.svelte";
|
|
4
|
+
import AdminRoutes from "@admin/app/admin-routes.svelte";
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<AdminNavigationProgress />
|
|
8
|
+
<AdminPageTitle />
|
|
9
|
+
<AdminRoutes />
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Route, Routes, useLocation } from "@hvniel/svelte-router";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
adminCreateFirstUserPath,
|
|
6
|
+
adminLoginPath,
|
|
7
|
+
adminRedirectFromSearch,
|
|
8
|
+
adminRoutePatterns,
|
|
9
|
+
} from "@admin/core/routing/admin-paths";
|
|
10
|
+
import { getAdminRuntime } from "@admin/core/runtime/admin-runtime.svelte";
|
|
11
|
+
import CollectionListRoute from "@admin/features/collections/collection-list-route.svelte";
|
|
12
|
+
import BulkUploadRoute from "@admin/features/uploads/bulk-upload-route.svelte";
|
|
13
|
+
import LoginRoute from "@admin/features/auth/login-route.svelte";
|
|
14
|
+
import CreateFirstUserRoute from "@admin/features/auth/create-first-user-route.svelte";
|
|
15
|
+
import ForgotPasswordRoute from "@admin/features/auth/forgot-password-route.svelte";
|
|
16
|
+
import ResetPasswordRoute from "@admin/features/auth/reset-password-route.svelte";
|
|
17
|
+
import RequestVerificationRoute from "@admin/features/auth/request-verification-route.svelte";
|
|
18
|
+
import VerifyEmailRoute from "@admin/features/auth/verify-email-route.svelte";
|
|
19
|
+
import AccountSecurityRoute from "@admin/features/auth/account-security-route.svelte";
|
|
20
|
+
import AccountRoute from "@admin/features/auth/account-route.svelte";
|
|
21
|
+
import DashboardRoute from "@admin/features/dashboard/dashboard-route.svelte";
|
|
22
|
+
import DocumentRoute from "@admin/features/documents/document-route-loader.svelte";
|
|
23
|
+
import VersionHistoryRoute from "@admin/features/versions/version-history-route.svelte";
|
|
24
|
+
|
|
25
|
+
import AdminLayout from "@admin/app/admin-layout.svelte";
|
|
26
|
+
import AdminCoreViewRoute from "@admin/app/admin-core-view-route.svelte";
|
|
27
|
+
import DeferredRedirect from "@admin/app/deferred-redirect.svelte";
|
|
28
|
+
import NotFoundRoute from "@admin/app/not-found-route.svelte";
|
|
29
|
+
|
|
30
|
+
const runtime = getAdminRuntime();
|
|
31
|
+
const location = $derived(useLocation());
|
|
32
|
+
const requestedPath = $derived(`${location.pathname}${location.search}${location.hash}`);
|
|
33
|
+
const postLoginPath = $derived(adminRedirectFromSearch(location.search));
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
{#if runtime.authenticated}
|
|
37
|
+
<Routes>
|
|
38
|
+
<Route path="login">
|
|
39
|
+
{#snippet element()}
|
|
40
|
+
<DeferredRedirect to={postLoginPath} replace />
|
|
41
|
+
{/snippet}
|
|
42
|
+
</Route>
|
|
43
|
+
<Route path="create-first-user">
|
|
44
|
+
{#snippet element()}
|
|
45
|
+
<DeferredRedirect to={adminRoutePatterns.home} replace />
|
|
46
|
+
{/snippet}
|
|
47
|
+
</Route>
|
|
48
|
+
<Route Component={AdminLayout}>
|
|
49
|
+
<Route path="account" Component={AccountRoute} />
|
|
50
|
+
<Route path="account/security" Component={AccountSecurityRoute} />
|
|
51
|
+
<Route index Component={DashboardRoute} />
|
|
52
|
+
<Route path="collections/:collection">
|
|
53
|
+
{#snippet element()}
|
|
54
|
+
<AdminCoreViewRoute surface="collectionList" DefaultView={CollectionListRoute} />
|
|
55
|
+
{/snippet}
|
|
56
|
+
</Route>
|
|
57
|
+
<Route path="collections/:collection/trash" Component={CollectionListRoute} />
|
|
58
|
+
<Route path="collections/:collection/upload" Component={BulkUploadRoute} />
|
|
59
|
+
<Route path="collections/:collection/create/:view?">
|
|
60
|
+
{#snippet element()}
|
|
61
|
+
<AdminCoreViewRoute surface="collectionCreate" DefaultView={DocumentRoute} />
|
|
62
|
+
{/snippet}
|
|
63
|
+
</Route>
|
|
64
|
+
<Route
|
|
65
|
+
path="collections/:collection/:document/versions/:revision?"
|
|
66
|
+
Component={VersionHistoryRoute}
|
|
67
|
+
/>
|
|
68
|
+
<Route path="collections/:collection/:document/:view?">
|
|
69
|
+
{#snippet element()}
|
|
70
|
+
<AdminCoreViewRoute surface="collectionEdit" DefaultView={DocumentRoute} />
|
|
71
|
+
{/snippet}
|
|
72
|
+
</Route>
|
|
73
|
+
<Route path="globals/:global/versions/:revision?" Component={VersionHistoryRoute} />
|
|
74
|
+
<Route path="globals/:global/:view?">
|
|
75
|
+
{#snippet element()}
|
|
76
|
+
<AdminCoreViewRoute surface="global" DefaultView={DocumentRoute} />
|
|
77
|
+
{/snippet}
|
|
78
|
+
</Route>
|
|
79
|
+
{#each runtime.pluginRoutes as pluginRoute (pluginRoute.path)}
|
|
80
|
+
<Route path={pluginRoute.path} Component={pluginRoute.component} />
|
|
81
|
+
{/each}
|
|
82
|
+
<Route path="*">
|
|
83
|
+
{#snippet element()}
|
|
84
|
+
<AdminCoreViewRoute surface="notFound" DefaultView={NotFoundRoute} />
|
|
85
|
+
{/snippet}
|
|
86
|
+
</Route>
|
|
87
|
+
</Route>
|
|
88
|
+
</Routes>
|
|
89
|
+
{:else if runtime.authBootstrapAvailable}
|
|
90
|
+
<Routes>
|
|
91
|
+
<Route path="create-first-user" Component={CreateFirstUserRoute} />
|
|
92
|
+
<Route path="*">
|
|
93
|
+
{#snippet element()}
|
|
94
|
+
<DeferredRedirect to={adminCreateFirstUserPath()} replace />
|
|
95
|
+
{/snippet}
|
|
96
|
+
</Route>
|
|
97
|
+
</Routes>
|
|
98
|
+
{:else}
|
|
99
|
+
<Routes>
|
|
100
|
+
<Route path="create-first-user">
|
|
101
|
+
{#snippet element()}
|
|
102
|
+
<DeferredRedirect to={adminRoutePatterns.login} replace />
|
|
103
|
+
{/snippet}
|
|
104
|
+
</Route>
|
|
105
|
+
<Route path="login" Component={LoginRoute} />
|
|
106
|
+
<Route path="forgot-password" Component={ForgotPasswordRoute} />
|
|
107
|
+
<Route path="reset-password" Component={ResetPasswordRoute} />
|
|
108
|
+
<Route path="request-verification" Component={RequestVerificationRoute} />
|
|
109
|
+
<Route path="verify-email" Component={VerifyEmailRoute} />
|
|
110
|
+
<Route path="*">
|
|
111
|
+
{#snippet element()}
|
|
112
|
+
<DeferredRedirect to={adminLoginPath(requestedPath)} replace />
|
|
113
|
+
{/snippet}
|
|
114
|
+
</Route>
|
|
115
|
+
</Routes>
|
|
116
|
+
{/if}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useNavigate } from "@hvniel/svelte-router";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
to: string;
|
|
6
|
+
replace?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let { to, replace = false }: Props = $props();
|
|
10
|
+
const navigate = useNavigate();
|
|
11
|
+
|
|
12
|
+
$effect(() => {
|
|
13
|
+
let active = true;
|
|
14
|
+
// The router activates useNavigate in a parent effect. Deferring one
|
|
15
|
+
// microtask prevents a mounted redirect from racing that activation.
|
|
16
|
+
queueMicrotask(() => {
|
|
17
|
+
if (active) navigate(to, { replace });
|
|
18
|
+
});
|
|
19
|
+
return () => {
|
|
20
|
+
active = false;
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
</script>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
|
|
4
|
+
import RiduLogo from "@admin/components/brand/ridu-logo.svelte";
|
|
5
|
+
import { Banner } from "@admin/components/ui/banner";
|
|
6
|
+
import { Button } from "@admin/components/ui/button";
|
|
7
|
+
import { getAdminRuntime } from "@admin/core/runtime/admin-runtime.svelte";
|
|
8
|
+
|
|
9
|
+
let { children }: { children: Snippet } = $props();
|
|
10
|
+
const runtime = getAdminRuntime();
|
|
11
|
+
const development = import.meta.hot !== undefined;
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
{#if runtime.loading}
|
|
15
|
+
<main
|
|
16
|
+
class="ridu-surface-grid grid min-h-screen place-items-center"
|
|
17
|
+
aria-label={runtime.i18n.t("general:loadingSchema")}
|
|
18
|
+
>
|
|
19
|
+
<div class="grid justify-items-center gap-4 text-[13px] text-foreground-muted">
|
|
20
|
+
<RiduLogo class="h-7 text-foreground" />
|
|
21
|
+
<span
|
|
22
|
+
class="size-4 animate-spin rounded-full border border-control-border-hover border-r-primary"
|
|
23
|
+
aria-hidden="true"
|
|
24
|
+
></span>
|
|
25
|
+
{runtime.i18n.t("general:loadingSchema")}
|
|
26
|
+
</div>
|
|
27
|
+
</main>
|
|
28
|
+
{:else if runtime.error !== undefined}
|
|
29
|
+
<main class="ridu-surface-grid grid min-h-screen place-items-center p-6">
|
|
30
|
+
<section
|
|
31
|
+
class="grid max-w-[480px] gap-5 rounded-[4px] border border-control-border bg-background-surface p-7"
|
|
32
|
+
role="alert"
|
|
33
|
+
>
|
|
34
|
+
<p class="font-mono text-[10px] tracking-[0.14em] text-destructive uppercase">
|
|
35
|
+
{runtime.i18n.t("errors:adminBootstrapFailed")}
|
|
36
|
+
</p>
|
|
37
|
+
<h1 class="font-serif text-[31px] leading-tight tracking-[-0.015em]">
|
|
38
|
+
{runtime.i18n.t("errors:couldNotLoadApplication")}
|
|
39
|
+
</h1>
|
|
40
|
+
<p class="text-[14px] leading-6 text-foreground-muted">{runtime.error}</p>
|
|
41
|
+
<Button class="w-fit" onclick={() => runtime.bootstrap()}>
|
|
42
|
+
{runtime.i18n.t("general:retry")}
|
|
43
|
+
</Button>
|
|
44
|
+
</section>
|
|
45
|
+
</main>
|
|
46
|
+
{:else}
|
|
47
|
+
{@render children()}
|
|
48
|
+
{#if !development && runtime.refreshingManifest}
|
|
49
|
+
<div class="pointer-events-none fixed top-4 left-1/2 z-50 w-[min(92vw,420px)] -translate-x-1/2">
|
|
50
|
+
<Banner class="shadow-[var(--shadow-popover)]" role="status">
|
|
51
|
+
<span
|
|
52
|
+
class="size-3.5 shrink-0 animate-spin rounded-full border border-control-border-hover border-r-primary"
|
|
53
|
+
aria-hidden="true"
|
|
54
|
+
></span>
|
|
55
|
+
{runtime.i18n.t("navigation:applyingSchemaUpdate")}
|
|
56
|
+
</Banner>
|
|
57
|
+
</div>
|
|
58
|
+
{:else if !development && runtime.manifestRefreshError !== undefined}
|
|
59
|
+
<div class="fixed top-4 left-1/2 z-50 w-[min(92vw,520px)] -translate-x-1/2">
|
|
60
|
+
<Banner class="shadow-[var(--shadow-popover)]" tone="destructive" role="alert">
|
|
61
|
+
<span class="size-2 shrink-0 rounded-full bg-destructive" aria-hidden="true"></span>
|
|
62
|
+
<span class="min-w-0">
|
|
63
|
+
{runtime.i18n.t("navigation:schemaUpdateFailed", {
|
|
64
|
+
message: runtime.manifestRefreshError,
|
|
65
|
+
})}
|
|
66
|
+
</span>
|
|
67
|
+
</Banner>
|
|
68
|
+
</div>
|
|
69
|
+
{/if}
|
|
70
|
+
{/if}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Link } from "@hvniel/svelte-router";
|
|
3
|
+
import ArrowLeftIcon from "~icons/lucide/arrow-left";
|
|
4
|
+
|
|
5
|
+
import { getAdminRuntime } from "@admin/core/runtime/admin-runtime.svelte";
|
|
6
|
+
|
|
7
|
+
const runtime = getAdminRuntime();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<section class="grid min-h-[72vh] place-items-center px-5 py-12 text-center">
|
|
11
|
+
<div class="max-w-md">
|
|
12
|
+
<p class="font-mono text-[10px] tracking-[0.16em] text-primary uppercase">
|
|
13
|
+
{runtime.i18n.t("errors:notFoundCode")}
|
|
14
|
+
</p>
|
|
15
|
+
<h1 class="font-serif mt-3 text-[38px] leading-tight tracking-[-0.02em]">
|
|
16
|
+
{runtime.i18n.t("errors:notFoundHeading")}
|
|
17
|
+
</h1>
|
|
18
|
+
<p class="mt-3 text-[13.5px] leading-6 text-foreground-muted">
|
|
19
|
+
{runtime.i18n.t("errors:notFoundDescription")}
|
|
20
|
+
</p>
|
|
21
|
+
<Link
|
|
22
|
+
class="mt-6 inline-flex items-center gap-2 text-[13px] font-medium text-primary hover:text-primary-hover"
|
|
23
|
+
to="/"
|
|
24
|
+
>
|
|
25
|
+
<ArrowLeftIcon class="size-3.5 rtl:rotate-180" />
|
|
26
|
+
{runtime.i18n.t("errors:returnDashboard")}
|
|
27
|
+
</Link>
|
|
28
|
+
</div>
|
|
29
|
+
</section>
|
package/src/app-meta.ts
ADDED