@vertebr/react 0.3.0 → 0.5.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/components/admin/AdminContent.d.ts +36 -0
- package/dist/components/admin/AdminContent.d.ts.map +1 -0
- package/dist/components/admin/AdminContent.js +107 -0
- package/dist/components/admin/AdminHeader.d.ts +13 -0
- package/dist/components/admin/AdminHeader.d.ts.map +1 -0
- package/dist/components/admin/AdminHeader.js +32 -0
- package/dist/components/admin/AdminSidebar.d.ts +25 -0
- package/dist/components/admin/AdminSidebar.d.ts.map +1 -0
- package/dist/components/admin/AdminSidebar.js +31 -0
- package/dist/components/admin/VertebrAdmin.d.ts +3 -18
- package/dist/components/admin/VertebrAdmin.d.ts.map +1 -1
- package/dist/components/admin/VertebrAdmin.js +130 -120
- package/dist/components/admin/sidebar.d.ts +3 -0
- package/dist/components/admin/sidebar.d.ts.map +1 -0
- package/dist/components/admin/sidebar.js +13 -0
- package/dist/components/admin/storage.d.ts +4 -0
- package/dist/components/admin/storage.d.ts.map +1 -0
- package/dist/components/admin/storage.js +24 -0
- package/dist/components/admin/types.d.ts +53 -0
- package/dist/components/admin/types.d.ts.map +1 -0
- package/dist/components/admin/types.js +1 -0
- package/dist/components/config/EnumInput.d.ts +10 -0
- package/dist/components/config/EnumInput.d.ts.map +1 -0
- package/dist/components/config/EnumInput.js +19 -0
- package/dist/components/config/EnumListInput.d.ts +10 -0
- package/dist/components/config/EnumListInput.d.ts.map +1 -0
- package/dist/components/config/EnumListInput.js +46 -0
- package/dist/components/config/VisibilityEye.d.ts +8 -0
- package/dist/components/config/VisibilityEye.d.ts.map +1 -0
- package/dist/components/config/VisibilityEye.js +18 -0
- package/dist/components/config/form/ConfigField.d.ts +2 -1
- package/dist/components/config/form/ConfigField.d.ts.map +1 -1
- package/dist/components/config/form/ConfigField.js +9 -4
- package/dist/components/config/form/ConfigForm.d.ts +1 -1
- package/dist/components/config/form/ConfigForm.d.ts.map +1 -1
- package/dist/components/config/form/ConfigForm.js +18 -9
- package/dist/components/config/form/ConfigFormActions.d.ts +2 -1
- package/dist/components/config/form/ConfigFormActions.d.ts.map +1 -1
- package/dist/components/config/form/ConfigFormActions.js +2 -2
- package/dist/components/config/form/RecordConfigForm.d.ts +3 -1
- package/dist/components/config/form/RecordConfigForm.d.ts.map +1 -1
- package/dist/components/config/form/RecordConfigForm.js +16 -8
- package/dist/components/config/form/SettingsConfigForm.d.ts +3 -1
- package/dist/components/config/form/SettingsConfigForm.d.ts.map +1 -1
- package/dist/components/config/form/SettingsConfigForm.js +2 -2
- package/dist/components/config/form/helpers/fields.d.ts +7 -0
- package/dist/components/config/form/helpers/fields.d.ts.map +1 -0
- package/dist/components/config/form/helpers/fields.js +31 -0
- package/dist/components/config/form/helpers/groups.d.ts +4 -0
- package/dist/components/config/form/helpers/groups.d.ts.map +1 -0
- package/dist/components/config/form/helpers/groups.js +107 -0
- package/dist/components/config/form/helpers/images.d.ts +4 -0
- package/dist/components/config/form/helpers/images.d.ts.map +1 -0
- package/dist/components/config/form/helpers/images.js +27 -0
- package/dist/components/config/form/helpers/index.d.ts +7 -0
- package/dist/components/config/form/helpers/index.d.ts.map +1 -0
- package/dist/components/config/form/helpers/index.js +6 -0
- package/dist/components/config/form/helpers/labels.d.ts +5 -0
- package/dist/components/config/form/helpers/labels.d.ts.map +1 -0
- package/dist/components/config/form/helpers/labels.js +28 -0
- package/dist/components/config/form/helpers/schema.d.ts +8 -0
- package/dist/components/config/form/helpers/schema.d.ts.map +1 -0
- package/dist/components/config/form/helpers/schema.js +30 -0
- package/dist/components/config/form/helpers/visibility.d.ts +13 -0
- package/dist/components/config/form/helpers/visibility.d.ts.map +1 -0
- package/dist/components/config/form/helpers/visibility.js +86 -0
- package/dist/components/config/form/types.d.ts +6 -0
- package/dist/components/config/form/types.d.ts.map +1 -1
- package/dist/components/emails/EmailRecipientSelect.d.ts +16 -0
- package/dist/components/emails/EmailRecipientSelect.d.ts.map +1 -0
- package/dist/components/emails/EmailRecipientSelect.js +10 -0
- package/dist/components/emails/EmailsActivityPanel.d.ts +11 -0
- package/dist/components/emails/EmailsActivityPanel.d.ts.map +1 -0
- package/dist/components/emails/EmailsActivityPanel.js +139 -0
- package/dist/components/emails/EmailsBoard.d.ts +47 -0
- package/dist/components/emails/EmailsBoard.d.ts.map +1 -0
- package/dist/components/emails/EmailsBoard.js +594 -0
- package/dist/components/emails/EmailsLibraryPanel.d.ts +25 -0
- package/dist/components/emails/EmailsLibraryPanel.d.ts.map +1 -0
- package/dist/components/emails/EmailsLibraryPanel.js +379 -0
- package/dist/components/emails/EmailsNavSelect.d.ts +18 -0
- package/dist/components/emails/EmailsNavSelect.d.ts.map +1 -0
- package/dist/components/emails/EmailsNavSelect.js +37 -0
- package/dist/components/emails/MultiCheckSelect.d.ts +18 -0
- package/dist/components/emails/MultiCheckSelect.d.ts.map +1 -0
- package/dist/components/emails/MultiCheckSelect.js +74 -0
- package/dist/components/metrics/MetricsBoard.d.ts +8 -2
- package/dist/components/metrics/MetricsBoard.d.ts.map +1 -1
- package/dist/components/metrics/MetricsBoard.js +55 -2
- package/dist/components/metrics/charts.d.ts +14 -0
- package/dist/components/metrics/charts.d.ts.map +1 -0
- package/dist/components/metrics/charts.js +212 -0
- package/dist/components/resources/ResourceActionModal.d.ts +14 -0
- package/dist/components/resources/ResourceActionModal.d.ts.map +1 -0
- package/dist/components/resources/ResourceActionModal.js +64 -0
- package/dist/components/resources/ResourceCell.d.ts.map +1 -1
- package/dist/components/resources/ResourceCell.js +25 -9
- package/dist/components/resources/ResourceCreateModal.d.ts +18 -0
- package/dist/components/resources/ResourceCreateModal.d.ts.map +1 -0
- package/dist/components/resources/ResourceCreateModal.js +22 -0
- package/dist/components/resources/ResourceMailModal.d.ts +12 -0
- package/dist/components/resources/ResourceMailModal.d.ts.map +1 -0
- package/dist/components/resources/ResourceMailModal.js +196 -0
- package/dist/components/resources/ResourceTable.d.ts +9 -3
- package/dist/components/resources/ResourceTable.d.ts.map +1 -1
- package/dist/components/resources/ResourceTable.js +241 -35
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/lib/metricsRanges.d.ts +20 -0
- package/dist/lib/metricsRanges.d.ts.map +1 -0
- package/dist/lib/metricsRanges.js +14 -0
- package/dist/styles/cells.css +42 -0
- package/dist/styles/emails.css +632 -0
- package/dist/styles/form.css +145 -0
- package/dist/styles/index.css +3 -0
- package/dist/styles/mail.css +240 -0
- package/dist/styles/metrics.css +633 -0
- package/dist/styles/modal.css +18 -0
- package/dist/styles/nav.css +103 -1
- package/dist/styles/panel.css +8 -68
- package/dist/styles/table.css +26 -3
- package/package.json +2 -2
- package/dist/components/config/form/helpers.d.ts +0 -16
- package/dist/components/config/form/helpers.d.ts.map +0 -1
- package/dist/components/config/form/helpers.js +0 -186
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CatalogResponse, ConfigResponse, EmailsBoardResponse, GalleryResponse, MetricsResponse, ResourceListResponse, VertebrClient } from "@vertebr/client";
|
|
2
|
+
import type { MetricsRangeId } from "../../lib/metricsRanges";
|
|
3
|
+
import type { Selection } from "./types";
|
|
4
|
+
export type AdminContentProps = {
|
|
5
|
+
client: VertebrClient;
|
|
6
|
+
catalog: CatalogResponse | null;
|
|
7
|
+
selection: Selection;
|
|
8
|
+
authRequired: boolean;
|
|
9
|
+
loading: boolean;
|
|
10
|
+
isPageSelection: boolean;
|
|
11
|
+
metricsData: MetricsResponse | null;
|
|
12
|
+
metricsLoading: boolean;
|
|
13
|
+
metricsRange: MetricsRangeId;
|
|
14
|
+
onMetricsRangeChange: (next: MetricsRangeId) => void;
|
|
15
|
+
onRefreshMetrics: () => Promise<void>;
|
|
16
|
+
galleryData: GalleryResponse | null;
|
|
17
|
+
galleryLoading: boolean;
|
|
18
|
+
onRefreshGallery: () => Promise<void>;
|
|
19
|
+
emailsData: EmailsBoardResponse | null;
|
|
20
|
+
emailsLoading: boolean;
|
|
21
|
+
onRefreshEmails: () => Promise<void>;
|
|
22
|
+
resourceData: ResourceListResponse | null;
|
|
23
|
+
onRefreshResource: () => Promise<void>;
|
|
24
|
+
configData: ConfigResponse | null;
|
|
25
|
+
onConfigSaved: (next: ConfigResponse) => void;
|
|
26
|
+
galleryPicker: {
|
|
27
|
+
galleryUpload?: {
|
|
28
|
+
accept: string[];
|
|
29
|
+
maxBytes: number;
|
|
30
|
+
};
|
|
31
|
+
onListGallery?: () => Promise<GalleryResponse["items"]>;
|
|
32
|
+
onUploadGallery?: (files: File[]) => Promise<GalleryResponse["items"]>;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export declare function AdminContent({ client, catalog, selection, authRequired, loading, isPageSelection, metricsData, metricsLoading, metricsRange, onMetricsRangeChange, onRefreshMetrics, galleryData, galleryLoading, onRefreshGallery, emailsData, emailsLoading, onRefreshEmails, resourceData, onRefreshResource, configData, onConfigSaved, galleryPicker, }: AdminContentProps): import("react").JSX.Element;
|
|
36
|
+
//# sourceMappingURL=AdminContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminContent.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AdminContent.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,aAAa,EACd,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,cAAc,CAAC;IAC7B,oBAAoB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACrD,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACvC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,YAAY,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1C,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,UAAU,EAAE,cAAc,GAAG,IAAI,CAAC;IAClC,aAAa,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,aAAa,EAAE;QACb,aAAa,CAAC,EAAE;YACd,MAAM,EAAE,MAAM,EAAE,CAAC;YACjB,QAAQ,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QACxD,eAAe,CAAC,EAAE,CAChB,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;KACxC,CAAC;CACH,CAAC;AAEF,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,OAAO,EACP,SAAS,EACT,YAAY,EACZ,OAAO,EACP,eAAe,EACf,WAAW,EACX,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,GACd,EAAE,iBAAiB,+BAgPnB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { ConfigForm } from "../config/ConfigForm";
|
|
3
|
+
import { EmailsBoard } from "../emails/EmailsBoard";
|
|
4
|
+
import { GalleryBoard } from "../gallery/GalleryBoard";
|
|
5
|
+
import { MetricsBoard } from "../metrics/MetricsBoard";
|
|
6
|
+
import { ResourcePanel } from "../resources/ResourceTable";
|
|
7
|
+
export function AdminContent({ client, catalog, selection, authRequired, loading, isPageSelection, metricsData, metricsLoading, metricsRange, onMetricsRangeChange, onRefreshMetrics, galleryData, galleryLoading, onRefreshGallery, emailsData, emailsLoading, onRefreshEmails, resourceData, onRefreshResource, configData, onConfigSaved, galleryPicker, }) {
|
|
8
|
+
if (!catalog) {
|
|
9
|
+
return (_jsx("div", { className: "vertebr-content", children: _jsx("section", { className: "vertebr-panel", children: _jsx("div", { className: "vertebr-empty", children: authRequired
|
|
10
|
+
? "Authenticated access required for this environment."
|
|
11
|
+
: loading
|
|
12
|
+
? "Loading…"
|
|
13
|
+
: "Unable to load catalog." }) }) }));
|
|
14
|
+
}
|
|
15
|
+
return (_jsx("div", { className: "vertebr-content", children: _jsxs("section", { className: "vertebr-panel", children: [selection?.kind === "overview" ? (_jsx(MetricsBoard, { label: metricsData?.label ?? catalog.metrics?.label, windowLabel: metricsData?.windowLabel, compareLabel: metricsData?.compareLabel, metrics: metricsData?.metrics ?? [], charts: metricsData?.charts ?? [], range: metricsRange, onRangeChange: onMetricsRangeChange, loading: metricsLoading, onRefresh: () => void onRefreshMetrics() })) : null, selection?.kind === "gallery" && galleryData ? (_jsx(GalleryBoard, { label: galleryData.label, items: galleryData.items, accept: galleryData.accept, maxBytes: galleryData.maxBytes, canDelete: galleryData.canDelete, loading: galleryLoading, onRefresh: () => void onRefreshGallery(), onUpload: async (files) => {
|
|
16
|
+
if (files.length === 1 && files[0]) {
|
|
17
|
+
await client.uploadGalleryFile(files[0]);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
await client.uploadGalleryFiles(files);
|
|
21
|
+
}
|
|
22
|
+
await onRefreshGallery();
|
|
23
|
+
}, onDelete: galleryData.canDelete
|
|
24
|
+
? async (id) => {
|
|
25
|
+
await client.deleteGalleryItem(id);
|
|
26
|
+
await onRefreshGallery();
|
|
27
|
+
}
|
|
28
|
+
: undefined })) : null, selection?.kind === "emails" && emailsData ? (_jsx(EmailsBoard, { data: emailsData, loading: emailsLoading, tab: selection.tab ?? "compose", onRefresh: () => void onRefreshEmails(), onLoadRecipients: async (resourceId) => {
|
|
29
|
+
const listed = await client.listResource(resourceId, {
|
|
30
|
+
fresh: true,
|
|
31
|
+
});
|
|
32
|
+
const seen = new Set();
|
|
33
|
+
const options = [];
|
|
34
|
+
for (const item of listed.items) {
|
|
35
|
+
const email = String(item.email ?? "")
|
|
36
|
+
.trim()
|
|
37
|
+
.toLowerCase();
|
|
38
|
+
if (!email.includes("@") || seen.has(email))
|
|
39
|
+
continue;
|
|
40
|
+
seen.add(email);
|
|
41
|
+
const id = String(item.id ?? item.uid ?? item.slug ?? email);
|
|
42
|
+
const label = String(item.displayName ?? item.name ?? "").trim();
|
|
43
|
+
options.push({
|
|
44
|
+
email,
|
|
45
|
+
id,
|
|
46
|
+
...(label ? { label } : {}),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
options.sort((a, b) => a.email.localeCompare(b.email));
|
|
50
|
+
return options;
|
|
51
|
+
}, onPreview: (payload) => client.previewEmails(payload), onSend: async (payload) => {
|
|
52
|
+
const result = await client.sendEmails(payload);
|
|
53
|
+
return { sent: result.sent, failed: result.failed };
|
|
54
|
+
}, onSchedule: emailsData.canSchedule
|
|
55
|
+
? async (payload) => {
|
|
56
|
+
await client.scheduleEmails(payload);
|
|
57
|
+
}
|
|
58
|
+
: undefined, onCancel: emailsData.canSchedule
|
|
59
|
+
? async (id) => {
|
|
60
|
+
await client.cancelEmailCampaign(id);
|
|
61
|
+
}
|
|
62
|
+
: undefined, onSaveLibrary: emailsData.canLibrary
|
|
63
|
+
? async (template) => {
|
|
64
|
+
await client.saveEmailLibraryTemplate(template);
|
|
65
|
+
}
|
|
66
|
+
: undefined, onDeleteLibrary: emailsData.canLibrary
|
|
67
|
+
? async (id) => {
|
|
68
|
+
await client.deleteEmailLibraryTemplate(id);
|
|
69
|
+
}
|
|
70
|
+
: undefined })) : null, selection?.kind === "resource" && resourceData ? (_jsx(ResourcePanel, { schema: resourceData.schema, items: resourceData.items, label: resourceData.label, permissions: resourceData.permissions, actions: resourceData.actions, collectionActions: resourceData.collectionActions, uploads: resourceData.uploads, storageKey: resourceData.id, onUpdate: resourceData.permissions.update
|
|
71
|
+
? async (rowId, value) => {
|
|
72
|
+
await client.updateResource(resourceData.id, rowId, value);
|
|
73
|
+
await onRefreshResource();
|
|
74
|
+
}
|
|
75
|
+
: undefined, onCreate: resourceData.permissions.create
|
|
76
|
+
? async (value) => {
|
|
77
|
+
await client.createResource(resourceData.id, value);
|
|
78
|
+
await onRefreshResource();
|
|
79
|
+
}
|
|
80
|
+
: undefined, onDelete: resourceData.permissions.delete
|
|
81
|
+
? async (rowId) => {
|
|
82
|
+
await client.deleteResource(resourceData.id, rowId);
|
|
83
|
+
await onRefreshResource();
|
|
84
|
+
}
|
|
85
|
+
: undefined, onAction: async (rowId, actionId, input) => {
|
|
86
|
+
await client.runResourceAction(resourceData.id, rowId, actionId, input);
|
|
87
|
+
}, onActionDone: onRefreshResource, onPreviewMail: async (rowId, actionId, input) => {
|
|
88
|
+
return client.previewResourceMail(resourceData.id, rowId, actionId, input);
|
|
89
|
+
}, onCollectionAction: async (actionId, input) => {
|
|
90
|
+
await client.runCollectionAction(resourceData.id, actionId, input);
|
|
91
|
+
}, onUpload: resourceData.uploads
|
|
92
|
+
? async (field, files) => {
|
|
93
|
+
if (files.length === 1 && files[0]) {
|
|
94
|
+
const result = await client.uploadResourceFile(resourceData.id, field, files[0]);
|
|
95
|
+
return [{ url: result.url, name: result.name }];
|
|
96
|
+
}
|
|
97
|
+
const result = await client.uploadResourceFiles(resourceData.id, field, files);
|
|
98
|
+
return result.files;
|
|
99
|
+
}
|
|
100
|
+
: undefined, ...galleryPicker })) : null, selection?.kind === "config" && configData ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "vertebr-panel-head", children: [_jsx("h2", { children: isPageSelection ? "Page content" : "Settings" }), _jsxs("span", { className: "vertebr-count", children: [Object.keys(configData.schema).length, " fields"] })] }), _jsx(ConfigForm, { schema: configData.schema, value: configData.value, onSave: async (next) => {
|
|
101
|
+
const saved = await client.setConfig(configData.id, next);
|
|
102
|
+
onConfigSaved({
|
|
103
|
+
...configData,
|
|
104
|
+
value: saved.value,
|
|
105
|
+
});
|
|
106
|
+
}, ...galleryPicker })] })) : null] }) }));
|
|
107
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AdminEnvironment } from "@vertebr/client";
|
|
2
|
+
import type { Selection } from "./types";
|
|
3
|
+
export type AdminHeaderProps = {
|
|
4
|
+
activeLabel: string;
|
|
5
|
+
activeEnv?: AdminEnvironment;
|
|
6
|
+
catalogLoaded: boolean;
|
|
7
|
+
authRequired: boolean;
|
|
8
|
+
selection: Selection;
|
|
9
|
+
isPageSelection: boolean;
|
|
10
|
+
error: string | null;
|
|
11
|
+
};
|
|
12
|
+
export declare function AdminHeader({ activeLabel, activeEnv, catalogLoaded, authRequired, selection, isPageSelection, error, }: AdminHeaderProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=AdminHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminHeader.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AdminHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAkCF,wBAAgB,WAAW,CAAC,EAC1B,WAAW,EACX,SAAS,EACT,aAAa,EACb,YAAY,EACZ,SAAS,EACT,eAAe,EACf,KAAK,GACN,EAAE,gBAAgB,+BA+BlB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
function subtitle({ catalogLoaded, authRequired, selection, isPageSelection, }) {
|
|
3
|
+
if (!catalogLoaded && authRequired) {
|
|
4
|
+
return "Provide an access token to load this environment.";
|
|
5
|
+
}
|
|
6
|
+
if (selection?.kind === "overview") {
|
|
7
|
+
return "Commerce, growth, and catalog for the selected environment.";
|
|
8
|
+
}
|
|
9
|
+
if (selection?.kind === "gallery") {
|
|
10
|
+
return "Browse and upload shared media assets.";
|
|
11
|
+
}
|
|
12
|
+
if (selection?.kind === "emails") {
|
|
13
|
+
return "Send or schedule branded email to a list or specific people.";
|
|
14
|
+
}
|
|
15
|
+
if (selection?.kind === "resource") {
|
|
16
|
+
return "Manage records scoped to the selected environment.";
|
|
17
|
+
}
|
|
18
|
+
if (selection?.kind === "config") {
|
|
19
|
+
return isPageSelection
|
|
20
|
+
? "Edit content for this page."
|
|
21
|
+
: "Owner-managed config for this environment.";
|
|
22
|
+
}
|
|
23
|
+
return "Select a panel.";
|
|
24
|
+
}
|
|
25
|
+
export function AdminHeader({ activeLabel, activeEnv, catalogLoaded, authRequired, selection, isPageSelection, error, }) {
|
|
26
|
+
return (_jsxs("header", { className: "vertebr-header", children: [_jsxs("div", { children: [_jsxs("div", { className: "vertebr-heading-row", children: [_jsx("h1", { children: activeLabel }), activeEnv ? (_jsx("span", { className: "vertebr-env-badge", "data-tone": activeEnv.tone ?? "neutral", children: activeEnv.label })) : null] }), _jsx("p", { children: subtitle({
|
|
27
|
+
catalogLoaded,
|
|
28
|
+
authRequired,
|
|
29
|
+
selection,
|
|
30
|
+
isPageSelection,
|
|
31
|
+
}) })] }), error ? (_jsx("span", { className: "vertebr-status", "data-tone": "danger", children: error })) : null] }));
|
|
32
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AdminEnvironment } from "@vertebr/client";
|
|
2
|
+
import type { VbTheme } from "../../hooks/useVertebrTheme";
|
|
3
|
+
import type { SidebarNavGroup } from "./types";
|
|
4
|
+
export type AdminSidebarProps = {
|
|
5
|
+
brand: string;
|
|
6
|
+
title: string;
|
|
7
|
+
envList: AdminEnvironment[];
|
|
8
|
+
environment: string;
|
|
9
|
+
onEnvironmentChange: (nextEnv: string) => void;
|
|
10
|
+
navGroups: SidebarNavGroup[];
|
|
11
|
+
getAccessToken?: () => string | null | undefined | Promise<string | null | undefined>;
|
|
12
|
+
authUserLabel?: string;
|
|
13
|
+
onSignOut?: () => void | Promise<void>;
|
|
14
|
+
authRequired: boolean;
|
|
15
|
+
activeEnv?: AdminEnvironment;
|
|
16
|
+
token: string;
|
|
17
|
+
tokenDraft: string;
|
|
18
|
+
onTokenDraftChange: (value: string) => void;
|
|
19
|
+
onSaveToken: () => void;
|
|
20
|
+
onClearToken: () => void;
|
|
21
|
+
theme: VbTheme;
|
|
22
|
+
onThemeChange: (theme: VbTheme) => void;
|
|
23
|
+
};
|
|
24
|
+
export declare function AdminSidebar({ brand, title, envList, environment, onEnvironmentChange, navGroups, getAccessToken, authUserLabel, onSignOut, authRequired, activeEnv, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, }: AdminSidebarProps): import("react").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=AdminSidebar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminSidebar.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AdminSidebar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,SAAS,CAAC;AAE7D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,MACb,MAAM,GACN,IAAI,GACJ,SAAS,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC,CAAC;AA2EF,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,SAAS,EACT,cAAc,EACd,aAAa,EACb,SAAS,EACT,YAAY,EACZ,SAAS,EACT,KAAK,EACL,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,KAAK,EACL,aAAa,GACd,EAAE,iBAAiB,+BA8FnB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { EnvSelect } from "../env/EnvSelect";
|
|
4
|
+
import { ThemeToggle } from "../theme/ThemeToggle";
|
|
5
|
+
function SidebarNavItem({ item }) {
|
|
6
|
+
const hasChildren = Boolean(item.children?.length);
|
|
7
|
+
const childActive = item.children?.some((child) => child.active) ?? false;
|
|
8
|
+
const sectionActive = item.active || childActive;
|
|
9
|
+
const [open, setOpen] = useState(sectionActive);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (sectionActive)
|
|
12
|
+
setOpen(true);
|
|
13
|
+
}, [sectionActive]);
|
|
14
|
+
if (!hasChildren) {
|
|
15
|
+
return (_jsx("button", { type: "button", "data-active": item.active, onClick: item.onSelect, children: item.label }));
|
|
16
|
+
}
|
|
17
|
+
return (_jsxs("div", { className: "vertebr-nav-item", "data-has-children": "true", "data-open": open || undefined, children: [_jsxs("div", { className: "vertebr-nav-parent", children: [_jsx("button", { type: "button", className: "vertebr-nav-parent-label", "data-active": sectionActive && !childActive, "data-section": sectionActive || undefined, onClick: () => {
|
|
18
|
+
setOpen(true);
|
|
19
|
+
item.onSelect();
|
|
20
|
+
}, children: item.label }), _jsx("button", { type: "button", className: "vertebr-nav-parent-toggle", "aria-label": open ? `Collapse ${item.label}` : `Expand ${item.label}`, "aria-expanded": open, onClick: () => setOpen((prev) => !prev), children: _jsx("span", { "aria-hidden": "true", children: open ? "▾" : "▸" }) })] }), open ? (_jsx("div", { className: "vertebr-nav-sub", role: "group", children: item.children.map((child) => (_jsx("button", { type: "button", className: "vertebr-nav-subitem", "data-active": child.active, onClick: () => {
|
|
21
|
+
setOpen(true);
|
|
22
|
+
child.onSelect();
|
|
23
|
+
}, children: child.label }, child.key))) })) : null] }));
|
|
24
|
+
}
|
|
25
|
+
export function AdminSidebar({ brand, title, envList, environment, onEnvironmentChange, navGroups, getAccessToken, authUserLabel, onSignOut, authRequired, activeEnv, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, }) {
|
|
26
|
+
return (_jsxs("aside", { className: "vertebr-sidebar", children: [_jsxs("div", { className: "vertebr-sidebar-top", children: [_jsxs("div", { className: "vertebr-brand", children: [_jsx("strong", { children: brand }), _jsx("span", { children: title })] }), envList.length > 0 ? (_jsxs("div", { className: "vertebr-env", children: [_jsx("div", { className: "vertebr-nav-label", children: "Environment" }), _jsx(EnvSelect, { environments: envList, value: environment, onChange: onEnvironmentChange })] })) : null, _jsx("nav", { className: "vertebr-nav", children: navGroups.map((group) => (_jsxs("div", { className: "vertebr-nav-group", children: [_jsx("div", { className: "vertebr-nav-label", children: group.label }), group.items.map((item) => (_jsx(SidebarNavItem, { item: item }, item.key)))] }, group.label))) })] }), _jsxs("div", { className: "vertebr-sidebar-bottom", children: [getAccessToken && authUserLabel ? (_jsxs("div", { className: "vertebr-auth", children: [_jsx("div", { className: "vertebr-nav-label", children: "Signed in" }), _jsx("p", { className: "vertebr-auth-hint", children: authUserLabel }), onSignOut ? (_jsx("button", { type: "button", className: "vertebr-btn", onClick: () => void onSignOut(), children: "Sign out" })) : null] })) : null, !getAccessToken && (authRequired || token) ? (_jsxs("div", { className: "vertebr-auth", children: [_jsx("div", { className: "vertebr-nav-label", children: "Access" }), _jsx("p", { className: "vertebr-auth-hint", children: authRequired
|
|
27
|
+
? `This environment requires auth${activeEnv?.auth?.claimKey
|
|
28
|
+
? ` (${activeEnv.auth.claimKey})`
|
|
29
|
+
: ""}.`
|
|
30
|
+
: "Optional access token for protected environments." }), _jsx("input", { className: "vertebr-auth-input", type: "password", placeholder: "Bearer token", value: tokenDraft, onChange: (event) => onTokenDraftChange(event.target.value), autoComplete: "off" }), _jsxs("div", { className: "vertebr-auth-actions", children: [_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-primary", onClick: onSaveToken, children: "Use token" }), token ? (_jsx("button", { type: "button", className: "vertebr-btn", onClick: onClearToken, children: "Clear" })) : null] })] })) : null, _jsx(ThemeToggle, { theme: theme, onChange: onThemeChange })] })] }));
|
|
31
|
+
}
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
title?: string;
|
|
5
|
-
/** localStorage key for remembering the selected environment */
|
|
6
|
-
envStorageKey?: string;
|
|
7
|
-
/** localStorage key for the access token */
|
|
8
|
-
tokenStorageKey?: string;
|
|
9
|
-
/** localStorage key for light/dark theme preference */
|
|
10
|
-
themeStorageKey?: string;
|
|
11
|
-
/** Optional host-provided token getter (Firebase ID token, etc.) */
|
|
12
|
-
getAccessToken?: () => string | null | undefined | Promise<string | null | undefined>;
|
|
13
|
-
/** Signed-in identity shown in the dashboard. */
|
|
14
|
-
authUserLabel?: string;
|
|
15
|
-
/** Host-provided sign-out action. */
|
|
16
|
-
onSignOut?: () => void | Promise<void>;
|
|
17
|
-
};
|
|
18
|
-
export declare function VertebrAdmin({ apiBase, title, envStorageKey, tokenStorageKey, themeStorageKey, getAccessToken, authUserLabel, onSignOut, }: VertebrAdminProps): import("react").JSX.Element;
|
|
1
|
+
import type { VertebrAdminProps } from "./types";
|
|
2
|
+
export type { VertebrAdminProps } from "./types";
|
|
3
|
+
export declare function VertebrAdmin({ apiBase, title, envStorageKey, tokenStorageKey, themeStorageKey, metricsRangeStorageKey, getAccessToken, authUserLabel, onSignOut, }: VertebrAdminProps): import("react").JSX.Element;
|
|
19
4
|
//# sourceMappingURL=VertebrAdmin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VertebrAdmin.d.ts","sourceRoot":"","sources":["../../../src/components/admin/VertebrAdmin.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VertebrAdmin.d.ts","sourceRoot":"","sources":["../../../src/components/admin/VertebrAdmin.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAGV,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAgB,YAAY,CAAC,EAC3B,OAAsB,EACtB,KAAuB,EACvB,aAA6B,EAC7B,eAAiC,EACjC,eAAiC,EACjC,sBAAgD,EAChD,cAAc,EACd,aAAa,EACb,SAAS,GACV,EAAE,iBAAiB,+BA6bnB"}
|