@vertebr/react 0.8.1 → 0.10.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.
Files changed (109) hide show
  1. package/dist/components/admin/AddonEditor.d.ts +13 -0
  2. package/dist/components/admin/AddonEditor.d.ts.map +1 -0
  3. package/dist/components/admin/AddonEditor.js +27 -0
  4. package/dist/components/admin/AddonOverview.d.ts +8 -0
  5. package/dist/components/admin/AddonOverview.d.ts.map +1 -0
  6. package/dist/components/admin/AddonOverview.js +125 -0
  7. package/dist/components/admin/AddonPreviewThumb.d.ts +11 -0
  8. package/dist/components/admin/AddonPreviewThumb.d.ts.map +1 -0
  9. package/dist/components/admin/AddonPreviewThumb.js +52 -0
  10. package/dist/components/admin/AdminCommandPalette.d.ts +9 -0
  11. package/dist/components/admin/AdminCommandPalette.d.ts.map +1 -0
  12. package/dist/components/admin/AdminCommandPalette.js +68 -0
  13. package/dist/components/admin/AdminContent.d.ts +4 -1
  14. package/dist/components/admin/AdminContent.d.ts.map +1 -1
  15. package/dist/components/admin/AdminContent.js +32 -10
  16. package/dist/components/admin/AdminHeader.d.ts +2 -3
  17. package/dist/components/admin/AdminHeader.d.ts.map +1 -1
  18. package/dist/components/admin/AdminHeader.js +10 -3
  19. package/dist/components/admin/AdminPoweredBy.d.ts +5 -0
  20. package/dist/components/admin/AdminPoweredBy.d.ts.map +1 -0
  21. package/dist/components/admin/AdminPoweredBy.js +8 -0
  22. package/dist/components/admin/AdminSidebar.d.ts.map +1 -1
  23. package/dist/components/admin/AdminSidebar.js +9 -7
  24. package/dist/components/admin/AdminSyncPage.d.ts +7 -0
  25. package/dist/components/admin/AdminSyncPage.d.ts.map +1 -0
  26. package/dist/components/admin/AdminSyncPage.js +169 -0
  27. package/dist/components/admin/AdminTopBar.d.ts +11 -3
  28. package/dist/components/admin/AdminTopBar.d.ts.map +1 -1
  29. package/dist/components/admin/AdminTopBar.js +27 -4
  30. package/dist/components/admin/AuditBoard.d.ts +7 -0
  31. package/dist/components/admin/AuditBoard.d.ts.map +1 -0
  32. package/dist/components/admin/AuditBoard.js +43 -0
  33. package/dist/components/admin/HealthModal.d.ts +9 -0
  34. package/dist/components/admin/HealthModal.d.ts.map +1 -0
  35. package/dist/components/admin/HealthModal.js +59 -0
  36. package/dist/components/admin/PagePreviewPane.d.ts +3 -1
  37. package/dist/components/admin/PagePreviewPane.d.ts.map +1 -1
  38. package/dist/components/admin/PagePreviewPane.js +2 -2
  39. package/dist/components/admin/VertebrAdmin.d.ts.map +1 -1
  40. package/dist/components/admin/VertebrAdmin.js +146 -17
  41. package/dist/components/admin/addonLabels.d.ts +6 -0
  42. package/dist/components/admin/addonLabels.d.ts.map +1 -0
  43. package/dist/components/admin/addonLabels.js +20 -0
  44. package/dist/components/admin/adminSearch.d.ts +12 -0
  45. package/dist/components/admin/adminSearch.d.ts.map +1 -0
  46. package/dist/components/admin/adminSearch.js +120 -0
  47. package/dist/components/admin/breadcrumbs.d.ts.map +1 -1
  48. package/dist/components/admin/breadcrumbs.js +14 -0
  49. package/dist/components/admin/routes.d.ts.map +1 -1
  50. package/dist/components/admin/routes.js +43 -1
  51. package/dist/components/admin/types.d.ts +9 -0
  52. package/dist/components/admin/types.d.ts.map +1 -1
  53. package/dist/components/config/ReferenceInput.d.ts +11 -0
  54. package/dist/components/config/ReferenceInput.d.ts.map +1 -0
  55. package/dist/components/config/ReferenceInput.js +99 -0
  56. package/dist/components/config/RevisionHistory.d.ts +8 -0
  57. package/dist/components/config/RevisionHistory.d.ts.map +1 -0
  58. package/dist/components/config/RevisionHistory.js +84 -0
  59. package/dist/components/config/form/ConfigField.d.ts +3 -2
  60. package/dist/components/config/form/ConfigField.d.ts.map +1 -1
  61. package/dist/components/config/form/ConfigField.js +3 -2
  62. package/dist/components/config/form/ConfigForm.d.ts +1 -1
  63. package/dist/components/config/form/ConfigForm.d.ts.map +1 -1
  64. package/dist/components/config/form/ConfigForm.js +13 -6
  65. package/dist/components/config/form/RecordConfigForm.d.ts +3 -2
  66. package/dist/components/config/form/RecordConfigForm.d.ts.map +1 -1
  67. package/dist/components/config/form/RecordConfigForm.js +2 -1
  68. package/dist/components/config/form/SettingsConfigForm.d.ts +3 -2
  69. package/dist/components/config/form/SettingsConfigForm.d.ts.map +1 -1
  70. package/dist/components/config/form/SettingsConfigForm.js +2 -2
  71. package/dist/components/config/form/types.d.ts +5 -1
  72. package/dist/components/config/form/types.d.ts.map +1 -1
  73. package/dist/components/env/EnvMultiSelect.d.ts +20 -0
  74. package/dist/components/env/EnvMultiSelect.d.ts.map +1 -0
  75. package/dist/components/env/EnvMultiSelect.js +38 -0
  76. package/dist/components/resources/ResourceTable.d.ts +7 -1
  77. package/dist/components/resources/ResourceTable.d.ts.map +1 -1
  78. package/dist/components/resources/ResourceTable.js +56 -6
  79. package/dist/components/theme/ThemeToggle.d.ts +3 -1
  80. package/dist/components/theme/ThemeToggle.d.ts.map +1 -1
  81. package/dist/components/theme/ThemeToggle.js +2 -2
  82. package/dist/components/ui/icons.d.ts +3 -0
  83. package/dist/components/ui/icons.d.ts.map +1 -1
  84. package/dist/components/ui/icons.js +17 -0
  85. package/dist/index.d.ts +2 -1
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +1 -0
  88. package/dist/lib/capabilities.d.ts +4 -0
  89. package/dist/lib/capabilities.d.ts.map +1 -0
  90. package/dist/lib/capabilities.js +9 -0
  91. package/dist/styles/addon.css +540 -0
  92. package/dist/styles/audit.css +34 -0
  93. package/dist/styles/base.css +1 -0
  94. package/dist/styles/font-library.css +2 -0
  95. package/dist/styles/form.css +143 -0
  96. package/dist/styles/index.css +3 -0
  97. package/dist/styles/main.css +0 -38
  98. package/dist/styles/modal.css +113 -0
  99. package/dist/styles/motion.css +55 -0
  100. package/dist/styles/nav.css +39 -4
  101. package/dist/styles/select.css +6 -0
  102. package/dist/styles/shell.css +417 -14
  103. package/dist/styles/sidebar.css +63 -3
  104. package/dist/styles/sync.css +540 -0
  105. package/dist/styles/table.css +15 -5
  106. package/dist/themes/dark.css +11 -11
  107. package/dist/themes/index.css +1 -0
  108. package/dist/themes/light.css +19 -19
  109. package/package.json +1 -1
@@ -0,0 +1,7 @@
1
+ import type { CatalogResponse, VertebrClient } from "@vertebr/client";
2
+ export type AdminSyncPageProps = {
3
+ client: VertebrClient;
4
+ catalog: CatalogResponse;
5
+ };
6
+ export declare function AdminSyncPage({ client, catalog }: AdminSyncPageProps): import("react").JSX.Element;
7
+ //# sourceMappingURL=AdminSyncPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminSyncPage.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AdminSyncPage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,eAAe,EAGf,aAAa,EACd,MAAM,iBAAiB,CAAC;AAOzB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,eAAe,CAAC;CAC1B,CAAC;AAiDF,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,kBAAkB,+BA2VpE"}
@@ -0,0 +1,169 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useState } from "react";
3
+ import { EnvMultiSelect, EnvFlowBadge } from "../env/EnvMultiSelect";
4
+ import { EnvSelect } from "../env/EnvSelect";
5
+ import { useToast } from "../../hooks/useToast";
6
+ import { Badge, Card } from "../ui/primitives";
7
+ import { IconSync } from "../ui/icons";
8
+ function envById(environments, id) {
9
+ return environments.find((env) => env.id === id);
10
+ }
11
+ function groupTargets(catalog) {
12
+ const targets = catalog.sync?.targets ?? [];
13
+ const groups = new Map();
14
+ for (const target of targets) {
15
+ const group = target.group ?? "Content";
16
+ const list = groups.get(group) ?? [];
17
+ list.push(target);
18
+ groups.set(group, list);
19
+ }
20
+ return groups;
21
+ }
22
+ function statusTone(status) {
23
+ if (status === "error")
24
+ return "danger";
25
+ if (status === "changed" || status === "new")
26
+ return "warn";
27
+ if (status === "unchanged")
28
+ return "ok";
29
+ return "neutral";
30
+ }
31
+ function statusLabel(status) {
32
+ switch (status) {
33
+ case "changed":
34
+ return "Changes";
35
+ case "new":
36
+ return "New";
37
+ case "unchanged":
38
+ return "Match";
39
+ case "missing":
40
+ return "Missing";
41
+ case "skipped":
42
+ return "Skipped";
43
+ case "error":
44
+ return "Error";
45
+ default:
46
+ return status;
47
+ }
48
+ }
49
+ export function AdminSyncPage({ client, catalog }) {
50
+ const sync = catalog.sync;
51
+ const { push } = useToast();
52
+ const environments = catalog.environments;
53
+ const [fromEnv, setFromEnv] = useState(() => sync?.defaultFrom ?? catalog.defaultEnvironment);
54
+ const [toEnv, setToEnv] = useState(() => {
55
+ const defaults = sync?.defaultTo ?? [];
56
+ const from = sync?.defaultFrom ?? catalog.defaultEnvironment;
57
+ return defaults.filter((id) => id !== from);
58
+ });
59
+ const [selectedTargets, setSelectedTargets] = useState(() => (sync?.targets ?? [])
60
+ .filter((target) => target.defaultSelected)
61
+ .map((target) => target.id));
62
+ const [plan, setPlan] = useState(null);
63
+ const [planLoading, setPlanLoading] = useState(false);
64
+ const [running, setRunning] = useState(false);
65
+ const [error, setError] = useState(null);
66
+ const fromEnvironment = envById(environments, fromEnv);
67
+ const toEnvironments = useMemo(() => toEnv
68
+ .map((id) => envById(environments, id))
69
+ .filter((env) => Boolean(env)), [environments, toEnv]);
70
+ const targetGroups = useMemo(() => groupTargets(catalog), [catalog]);
71
+ const hasTargets = (sync?.targets.length ?? 0) > 0;
72
+ const refreshPlan = useCallback(async () => {
73
+ if (!hasTargets || toEnv.length === 0) {
74
+ setPlan(null);
75
+ return;
76
+ }
77
+ setPlanLoading(true);
78
+ setError(null);
79
+ try {
80
+ const next = await client.getSyncPlan({
81
+ from: fromEnv,
82
+ to: toEnv,
83
+ targets: selectedTargets,
84
+ });
85
+ setPlan(next);
86
+ }
87
+ catch (err) {
88
+ setPlan(null);
89
+ setError(err instanceof Error ? err.message : "Could not load sync preview");
90
+ }
91
+ finally {
92
+ setPlanLoading(false);
93
+ }
94
+ }, [client, fromEnv, toEnv, selectedTargets, hasTargets]);
95
+ useEffect(() => {
96
+ void refreshPlan();
97
+ }, [refreshPlan]);
98
+ const toggleTarget = (targetId) => {
99
+ setSelectedTargets((current) => current.includes(targetId)
100
+ ? current.filter((id) => id !== targetId)
101
+ : [...current, targetId]);
102
+ };
103
+ const runSync = async () => {
104
+ if (!hasTargets || toEnv.length === 0 || selectedTargets.length === 0)
105
+ return;
106
+ const fromLabel = fromEnvironment?.label ?? fromEnv;
107
+ const toLabels = toEnvironments.map((env) => env.label).join(", ");
108
+ const targetLabels = (sync?.targets ?? [])
109
+ .filter((target) => selectedTargets.includes(target.id))
110
+ .map((target) => target.label)
111
+ .join(", ");
112
+ const dangerTargets = toEnvironments.some((env) => env.tone === "danger");
113
+ const confirmLines = [
114
+ `Copy from ${fromLabel} to ${toLabels}.`,
115
+ "",
116
+ `Targets: ${targetLabels}`,
117
+ "",
118
+ "This may overwrite content in the destination environment(s).",
119
+ ];
120
+ if (dangerTargets) {
121
+ confirmLines.push("", "You are writing to a production environment.");
122
+ }
123
+ if (!window.confirm(confirmLines.join("\n")))
124
+ return;
125
+ setRunning(true);
126
+ setError(null);
127
+ try {
128
+ const result = await client.runSync({
129
+ from: fromEnv,
130
+ to: toEnv,
131
+ targets: selectedTargets,
132
+ });
133
+ push(result.message ?? (result.ok ? "Sync complete" : "Sync finished with errors"), result.ok ? "ok" : "danger");
134
+ await refreshPlan();
135
+ }
136
+ catch (err) {
137
+ setError(err instanceof Error ? err.message : "Sync failed");
138
+ push(err instanceof Error ? err.message : "Sync failed", "danger");
139
+ }
140
+ finally {
141
+ setRunning(false);
142
+ }
143
+ };
144
+ const planForTarget = (destinationId, targetId) => plan?.destinations
145
+ .find((item) => item.to === destinationId)
146
+ ?.targets.find((item) => item.id === targetId);
147
+ const syncSummary = toEnvironments.length > 0 && selectedTargets.length > 0
148
+ ? `Sync ${selectedTargets.length} item${selectedTargets.length === 1 ? "" : "s"} to ${toEnvironments.map((env) => env.label).join(", ")}`
149
+ : "Select destinations and content to sync";
150
+ if (!hasTargets) {
151
+ return (_jsx("div", { className: "vertebr-sync-page", children: _jsx("div", { className: "vertebr-sync-scroll", children: _jsxs("div", { className: "vertebr-empty-state vertebr-sync-empty", children: [_jsx("h3", { children: "Sync not configured" }), _jsxs("p", { children: ["This admin has multiple environments but no sync targets yet. Hosts register targets with ", _jsx("code", { children: "admin.sync()" }), "."] })] }) }) }));
152
+ }
153
+ return (_jsxs("div", { className: "vertebr-sync-page", children: [_jsxs("div", { className: "vertebr-sync-scroll", children: [_jsx(Card, { title: "Direction", children: _jsxs("div", { className: "vertebr-sync-direction", children: [_jsxs("div", { className: "vertebr-sync-direction-grid", children: [_jsxs("label", { className: "vertebr-sync-field", children: [_jsx("span", { className: "vertebr-sync-field-label", children: "From" }), _jsx(EnvSelect, { environments: environments, value: fromEnv, onChange: (next) => {
154
+ setFromEnv(next);
155
+ setToEnv((current) => current.filter((id) => id !== next));
156
+ } })] }), _jsx("div", { className: "vertebr-sync-connector", "aria-hidden": "true", children: toEnvironments.length > 0 ? (toEnvironments.map((destination) => (_jsx("span", { className: "vertebr-sync-connector-arrow", children: "\u2192" }, destination.id)))) : (_jsx("span", { className: "vertebr-sync-connector-arrow", children: "\u2192" })) }), _jsxs("label", { className: "vertebr-sync-field", children: [_jsx("span", { className: "vertebr-sync-field-label", children: "To" }), _jsx(EnvMultiSelect, { environments: environments, value: toEnv, excludeId: fromEnv, onChange: setToEnv, placeholder: "Select one or more destinations" })] })] }), fromEnvironment && toEnvironments.length > 0 ? (_jsx("div", { className: "vertebr-sync-preview", "aria-label": "Sync direction", children: _jsxs("div", { className: "vertebr-sync-preview-flow", "data-dest-count": toEnvironments.length, children: [_jsxs("div", { className: "vertebr-sync-preview-col vertebr-sync-preview-col-from", children: [_jsx("span", { className: "vertebr-sync-preview-caption", children: "From" }), _jsx(EnvFlowBadge, { environment: fromEnvironment })] }), _jsx("div", { className: "vertebr-sync-preview-col vertebr-sync-preview-col-routes", children: toEnvironments.map((destination, index) => (_jsxs("div", { className: "vertebr-sync-preview-route", children: [_jsx("span", { className: "vertebr-sync-preview-arrow", "aria-hidden": "true", children: "\u2192" }), _jsxs("div", { className: "vertebr-sync-preview-col vertebr-sync-preview-col-to", children: [index === 0 ? (_jsx("span", { className: "vertebr-sync-preview-caption", children: "To" })) : (_jsx("span", { className: "vertebr-sync-preview-caption", "aria-hidden": "true", children: "\u00A0" })), _jsx(EnvFlowBadge, { environment: destination })] })] }, destination.id))) })] }) })) : (_jsx("p", { className: "vertebr-sync-direction-hint", children: "Pick a source environment and one or more destinations to preview changes." }))] }) }), _jsxs(Card, { title: "What to sync", children: [_jsxs("div", { className: "vertebr-sync-targets-head", children: [_jsx("p", { className: "vertebr-sync-targets-copy", children: "Review what will change in each destination before syncing." }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet vertebr-sync-refresh", disabled: planLoading || toEnv.length === 0, onClick: () => void refreshPlan(), children: planLoading ? "Refreshing…" : "Refresh preview" })] }), [...targetGroups.entries()].map(([group, targets]) => (_jsxs("div", { className: "vertebr-sync-target-group", children: [_jsx("div", { className: "vertebr-sync-target-group-label", children: group }), _jsx("ul", { className: "vertebr-sync-target-list", children: targets.map((target) => {
157
+ const selected = selectedTargets.includes(target.id);
158
+ return (_jsx("li", { children: _jsxs("button", { type: "button", className: "vertebr-sync-target-row", "data-selected": selected || undefined, onClick: () => toggleTarget(target.id), children: [_jsx("span", { className: "vertebr-sync-target-check", "aria-hidden": "true", children: selected ? "✓" : "" }), _jsxs("span", { className: "vertebr-sync-target-main", children: [_jsx("span", { className: "vertebr-sync-target-title", children: target.label }), target.description ? (_jsx("span", { className: "vertebr-sync-target-desc", children: target.description })) : null] }), _jsx("span", { className: "vertebr-sync-target-badges", children: toEnvironments.length === 0 ? (_jsx(Badge, { children: "Choose destination" })) : planLoading ? (_jsx(Badge, { children: "Previewing\u2026" })) : (toEnvironments.map((destination) => {
159
+ const item = planForTarget(destination.id, target.id);
160
+ if (!item) {
161
+ return (_jsx(Badge, { children: destination.label }, destination.id));
162
+ }
163
+ return (_jsxs("span", { className: "vertebr-sync-target-dest", title: item.summary, children: [_jsxs(Badge, { tone: statusTone(item.status), children: [destination.label, ": ", statusLabel(item.status)] }), _jsx("span", { className: "vertebr-sync-target-summary", children: item.summary })] }, destination.id));
164
+ })) })] }) }, target.id));
165
+ }) })] }, group)))] }), sync?.excluded.length ? (_jsx(Card, { title: "Never synced", subdued: true, children: _jsx("ul", { className: "vertebr-sync-excluded-list", children: sync.excluded.map((item) => (_jsxs("li", { children: [_jsx("span", { className: "vertebr-sync-excluded-name", children: item.label }), _jsx("span", { className: "vertebr-sync-excluded-reason", children: item.reason })] }, item.label))) }) })) : null, error ? _jsx("div", { className: "vertebr-banner", "data-tone": "danger", children: error }) : null] }), _jsxs("div", { className: "vertebr-savebar vertebr-sync-footer", children: [_jsx("div", { className: "vertebr-savebar-message", children: syncSummary }), _jsx("div", { className: "vertebr-savebar-actions", children: _jsxs("button", { type: "button", className: "vertebr-btn vertebr-btn-primary vertebr-sync-run-btn", disabled: running ||
166
+ planLoading ||
167
+ toEnv.length === 0 ||
168
+ selectedTargets.length === 0, onClick: () => void runSync(), children: [_jsx(IconSync, {}), _jsx("span", { children: running ? "Syncing…" : "Sync selected" })] }) })] })] }));
169
+ }
@@ -1,14 +1,17 @@
1
- import type { AdminEnvironment } from "@vertebr/client";
1
+ import type { AdminEnvironment, HealthCheck } from "@vertebr/client";
2
2
  import type { VbTheme } from "../../hooks/useVertebrTheme";
3
3
  export type AdminTopBarProps = {
4
4
  brand: string;
5
+ hostName?: string;
6
+ hostLogoUrl?: string;
5
7
  envList: AdminEnvironment[];
6
8
  environment: string;
7
9
  onEnvironmentChange: (nextEnv: string) => void;
8
- activeEnv?: AdminEnvironment;
9
10
  authUserLabel?: string;
10
11
  onSignOut?: () => void | Promise<void>;
11
12
  getAccessToken?: () => string | null | undefined | Promise<string | null | undefined>;
13
+ /** When true, skip built-in token field (host supplies token via getAccessToken). */
14
+ authViaTokenOnly?: boolean;
12
15
  authRequired: boolean;
13
16
  token: string;
14
17
  tokenDraft: string;
@@ -19,6 +22,11 @@ export type AdminTopBarProps = {
19
22
  onThemeChange: (theme: VbTheme) => void;
20
23
  sidebarCollapsed: boolean;
21
24
  onToggleSidebar: () => void;
25
+ syncEnabled?: boolean;
26
+ onOpenSync?: () => void;
27
+ onOpenSearch?: () => void;
28
+ healthChecks?: HealthCheck[] | null;
29
+ onRefreshHealth?: () => Promise<void>;
22
30
  };
23
- export declare function AdminTopBar({ brand, envList, environment, onEnvironmentChange, activeEnv, authUserLabel, onSignOut, getAccessToken, authRequired, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, sidebarCollapsed, onToggleSidebar, }: AdminTopBarProps): import("react").JSX.Element;
31
+ export declare function AdminTopBar({ brand, hostName, hostLogoUrl, envList, environment, onEnvironmentChange, authUserLabel, onSignOut, getAccessToken, authViaTokenOnly, authRequired, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, sidebarCollapsed, onToggleSidebar, syncEnabled, onOpenSync, onOpenSearch, healthChecks, onRefreshHealth, }: AdminTopBarProps): import("react").JSX.Element;
24
32
  //# sourceMappingURL=AdminTopBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminTopBar.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AdminTopBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAG3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,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,CAAC,EAAE,gBAAgB,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE,MACb,MAAM,GACN,IAAI,GACJ,SAAS,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC;IACtB,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;IACxC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,SAAS,EACT,cAAc,EACd,YAAY,EACZ,KAAK,EACL,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,KAAK,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,GAChB,EAAE,gBAAgB,+BAsFlB"}
1
+ {"version":3,"file":"AdminTopBar.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AdminTopBar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAI3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE,MACb,MAAM,GACN,IAAI,GACJ,SAAS,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACvC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,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;IACxC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,CAAC;AAiBF,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,WAAW,EACX,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,KAAK,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,EAAE,gBAAgB,+BA0JlB"}
@@ -1,7 +1,30 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
2
3
  import { EnvSelect } from "../env/EnvSelect";
3
4
  import { ThemeToggle } from "../theme/ThemeToggle";
4
- import { IconSearch } from "../ui/icons";
5
- export function AdminTopBar({ brand, envList, environment, onEnvironmentChange, activeEnv, authUserLabel, onSignOut, getAccessToken, authRequired, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, sidebarCollapsed, onToggleSidebar, }) {
6
- return (_jsxs("header", { className: "vertebr-topbar", children: [_jsxs("div", { className: "vertebr-topbar-start", children: [_jsx("button", { type: "button", className: "vertebr-topbar-toggle", "aria-label": sidebarCollapsed ? "Expand sidebar" : "Collapse sidebar", onClick: onToggleSidebar, children: "\u2630" }), _jsx("strong", { className: "vertebr-topbar-brand", children: brand }), envList.length > 0 ? (_jsxs("div", { className: "vertebr-topbar-env", children: [_jsx(EnvSelect, { environments: envList, value: environment, onChange: onEnvironmentChange }), activeEnv ? (_jsx("span", { className: "vertebr-env-badge", "data-tone": activeEnv.tone ?? "neutral", children: activeEnv.label })) : null] })) : null] }), _jsxs("div", { className: "vertebr-topbar-search", "aria-hidden": "true", children: [_jsx(IconSearch, {}), _jsx("span", { children: "Search admin" }), _jsx("kbd", { children: "\u2318K" })] }), _jsxs("div", { className: "vertebr-topbar-end", children: [!getAccessToken && (authRequired || token) ? (_jsxs("div", { className: "vertebr-topbar-token", children: [_jsx("input", { className: "vertebr-auth-input", type: "password", placeholder: "Access token", value: tokenDraft, onChange: (event) => onTokenDraftChange(event.target.value), autoComplete: "off" }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: onSaveToken, children: "Use" }), token ? (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: onClearToken, children: "Clear" })) : null] })) : null, getAccessToken && authUserLabel ? (_jsx("span", { className: "vertebr-topbar-user", children: authUserLabel })) : null, onSignOut ? (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: () => void onSignOut(), children: "Sign out" })) : null, _jsx(ThemeToggle, { theme: theme, onChange: onThemeChange })] })] }));
5
+ import { IconMenu, IconSearch, IconSync } from "../ui/icons";
6
+ import { HealthModal } from "./HealthModal";
7
+ function healthOverall(checks) {
8
+ if (!checks?.length)
9
+ return null;
10
+ if (checks.some((c) => c.status === "error"))
11
+ return "error";
12
+ if (checks.some((c) => c.status === "warn"))
13
+ return "warn";
14
+ return "ok";
15
+ }
16
+ function healthLabel(tone) {
17
+ if (tone === "ok")
18
+ return "Healthy";
19
+ if (tone === "warn")
20
+ return "Attention";
21
+ return "Degraded";
22
+ }
23
+ export function AdminTopBar({ brand, hostName, hostLogoUrl, envList, environment, onEnvironmentChange, authUserLabel, onSignOut, getAccessToken, authViaTokenOnly, authRequired, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, sidebarCollapsed, onToggleSidebar, syncEnabled, onOpenSync, onOpenSearch, healthChecks, onRefreshHealth, }) {
24
+ const [healthOpen, setHealthOpen] = useState(false);
25
+ const healthTone = healthOverall(healthChecks);
26
+ const showTokenField = !getAccessToken &&
27
+ !authViaTokenOnly &&
28
+ (authRequired || Boolean(token));
29
+ return (_jsxs(_Fragment, { children: [_jsxs("header", { className: "vertebr-topbar", children: [_jsxs("div", { className: "vertebr-topbar-start", children: [_jsx("button", { type: "button", className: "vertebr-topbar-toggle", "aria-label": sidebarCollapsed ? "Expand sidebar" : "Collapse sidebar", onClick: onToggleSidebar, children: _jsx(IconMenu, {}) }), _jsx("div", { className: "vertebr-topbar-brand-wrap", children: hostName ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "vertebr-topbar-host", "data-primary": "true", children: [hostLogoUrl ? (_jsx("img", { className: "vertebr-topbar-host-logo", src: hostLogoUrl, alt: "" })) : null, _jsx("strong", { className: "vertebr-topbar-host-label", children: hostName })] }), _jsx("span", { className: "vertebr-topbar-product", children: brand })] })) : (_jsx("strong", { className: "vertebr-topbar-brand", children: brand })) }), envList.length > 1 ? (_jsx("div", { className: "vertebr-topbar-env", children: _jsx(EnvSelect, { environments: envList, value: environment, onChange: onEnvironmentChange }) })) : null] }), _jsx("div", { className: "vertebr-topbar-center", children: _jsxs("button", { type: "button", className: "vertebr-topbar-search", onClick: onOpenSearch, children: [_jsx(IconSearch, {}), _jsx("span", { children: "Search admin" }), _jsx("kbd", { children: "\u2318K" })] }) }), _jsxs("div", { className: "vertebr-topbar-end", children: [_jsxs("div", { className: "vertebr-topbar-cluster", "aria-label": "Operations", children: [healthTone && healthChecks?.length ? (_jsxs("button", { type: "button", className: "vertebr-topbar-health", "data-tone": healthTone, "aria-haspopup": "dialog", "aria-expanded": healthOpen, onClick: () => setHealthOpen(true), children: [_jsx("span", { className: "vertebr-topbar-health-dot", "aria-hidden": true }), _jsx("span", { className: "vertebr-topbar-health-text", children: healthLabel(healthTone) })] })) : null, syncEnabled && onOpenSync ? (_jsxs("button", { type: "button", className: "vertebr-topbar-action", onClick: onOpenSync, children: [_jsx(IconSync, {}), _jsx("span", { children: "Sync" })] })) : null] }), showTokenField ? (_jsxs("div", { className: "vertebr-topbar-token", children: [_jsx("input", { className: "vertebr-auth-input", type: "password", placeholder: "Access token", value: tokenDraft, onChange: (event) => onTokenDraftChange(event.target.value), autoComplete: "off" }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: onSaveToken, children: "Use" }), token ? (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: onClearToken, children: "Clear" })) : null] })) : null, getAccessToken || onSignOut ? (_jsxs("div", { className: "vertebr-topbar-account", children: [getAccessToken && authUserLabel ? (_jsx("span", { className: "vertebr-topbar-user", title: authUserLabel, children: authUserLabel })) : null, onSignOut ? (_jsx("button", { type: "button", className: "vertebr-topbar-signout", onClick: () => void onSignOut(), children: "Sign out" })) : null] })) : null, _jsx(ThemeToggle, { theme: theme, onChange: onThemeChange, compact: true })] })] }), healthOpen && healthChecks?.length ? (_jsx(HealthModal, { checks: healthChecks, environment: environment, onClose: () => setHealthOpen(false), onRefresh: onRefreshHealth })) : null] }));
7
30
  }
@@ -0,0 +1,7 @@
1
+ import type { VertebrClient } from "@vertebr/client";
2
+ export type AuditBoardProps = {
3
+ client: VertebrClient;
4
+ label?: string;
5
+ };
6
+ export declare function AuditBoard({ client, label }: AuditBoardProps): import("react").JSX.Element;
7
+ //# sourceMappingURL=AuditBoard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditBoard.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AuditBoard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEjE,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAaF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,KAAe,EAAE,EAAE,eAAe,+BA4EtE"}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ function formatWhen(at) {
4
+ const date = new Date(at);
5
+ if (Number.isNaN(date.getTime()))
6
+ return at;
7
+ return date.toLocaleString(undefined, {
8
+ month: "short",
9
+ day: "numeric",
10
+ hour: "numeric",
11
+ minute: "2-digit",
12
+ });
13
+ }
14
+ export function AuditBoard({ client, label = "Audit" }) {
15
+ const [items, setItems] = useState([]);
16
+ const [loading, setLoading] = useState(true);
17
+ const [error, setError] = useState(null);
18
+ useEffect(() => {
19
+ let cancelled = false;
20
+ (async () => {
21
+ try {
22
+ setLoading(true);
23
+ setError(null);
24
+ const data = await client.listAudit({ limit: 100, fresh: true });
25
+ if (!cancelled)
26
+ setItems(data.items);
27
+ }
28
+ catch (err) {
29
+ if (!cancelled) {
30
+ setError(err instanceof Error ? err.message : "Failed to load audit");
31
+ }
32
+ }
33
+ finally {
34
+ if (!cancelled)
35
+ setLoading(false);
36
+ }
37
+ })();
38
+ return () => {
39
+ cancelled = true;
40
+ };
41
+ }, [client]);
42
+ return (_jsxs("div", { className: "vertebr-audit", children: [_jsxs("div", { className: "vertebr-panel-head", children: [_jsx("h2", { children: label }), _jsx("span", { className: "vertebr-count", children: loading ? "…" : `${items.length} events` })] }), error ? _jsx("div", { className: "vertebr-error", children: error }) : null, loading && items.length === 0 ? (_jsx("div", { className: "vertebr-empty", children: "Loading audit log\u2026" })) : items.length === 0 ? (_jsx("div", { className: "vertebr-empty", children: "No audit events yet." })) : (_jsx("div", { className: "vertebr-table-wrap", children: _jsxs("table", { className: "vertebr-table vertebr-audit-table", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "When" }), _jsx("th", { children: "Actor" }), _jsx("th", { children: "Action" }), _jsx("th", { children: "Target" }), _jsx("th", { children: "Summary" })] }) }), _jsx("tbody", { children: items.map((entry) => (_jsxs("tr", { children: [_jsx("td", { className: "vertebr-audit-when", children: formatWhen(entry.at) }), _jsx("td", { children: entry.actor ?? "—" }), _jsx("td", { children: _jsx("code", { className: "vertebr-audit-action", children: entry.action }) }), _jsx("td", { children: _jsxs("span", { className: "vertebr-audit-target", children: [entry.targetType, entry.targetId ? ` · ${entry.targetId}` : ""] }) }), _jsx("td", { children: entry.summary })] }, entry.id))) })] }) }))] }));
43
+ }
@@ -0,0 +1,9 @@
1
+ import type { HealthCheck } from "@vertebr/client";
2
+ export type HealthModalProps = {
3
+ checks: HealthCheck[];
4
+ environment?: string;
5
+ onClose: () => void;
6
+ onRefresh?: () => Promise<void>;
7
+ };
8
+ export declare function HealthModal({ checks, environment, onClose, onRefresh, }: HealthModalProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=HealthModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HealthModal.d.ts","sourceRoot":"","sources":["../../../src/components/admin/HealthModal.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,iBAAiB,CAAC;AAEjE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AAkBF,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,WAAW,EACX,OAAO,EACP,SAAS,GACV,EAAE,gBAAgB,+BAuHlB"}
@@ -0,0 +1,59 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ function statusLabel(status) {
4
+ if (status === "ok")
5
+ return "OK";
6
+ if (status === "warn")
7
+ return "Warn";
8
+ return "Error";
9
+ }
10
+ function formatCheckedAt(value) {
11
+ if (!value)
12
+ return null;
13
+ const date = new Date(value);
14
+ if (Number.isNaN(date.getTime()))
15
+ return value;
16
+ return date.toLocaleString(undefined, {
17
+ dateStyle: "medium",
18
+ timeStyle: "short",
19
+ });
20
+ }
21
+ export function HealthModal({ checks, environment, onClose, onRefresh, }) {
22
+ const [refreshing, setRefreshing] = useState(false);
23
+ const [refreshError, setRefreshError] = useState(null);
24
+ useEffect(() => {
25
+ const onKeyDown = (event) => {
26
+ if (event.key === "Escape")
27
+ onClose();
28
+ };
29
+ window.addEventListener("keydown", onKeyDown);
30
+ const previous = document.body.style.overflow;
31
+ document.body.style.overflow = "hidden";
32
+ return () => {
33
+ window.removeEventListener("keydown", onKeyDown);
34
+ document.body.style.overflow = previous;
35
+ };
36
+ }, [onClose]);
37
+ const handleRefresh = async () => {
38
+ if (!onRefresh || refreshing)
39
+ return;
40
+ setRefreshing(true);
41
+ setRefreshError(null);
42
+ try {
43
+ await onRefresh();
44
+ }
45
+ catch (error) {
46
+ setRefreshError(error instanceof Error ? error.message : "Failed to refresh health");
47
+ }
48
+ finally {
49
+ setRefreshing(false);
50
+ }
51
+ };
52
+ const latestCheckedAt = formatCheckedAt(checks.map((c) => c.checkedAt).find(Boolean));
53
+ return (_jsx("div", { className: "vertebr-modal-backdrop", role: "presentation", onClick: onClose, children: _jsxs("div", { className: "vertebr-modal vertebr-modal-sm vertebr-health-modal", role: "dialog", "aria-modal": "true", "aria-label": "System health", onClick: (event) => event.stopPropagation(), children: [_jsxs("header", { className: "vertebr-modal-head", children: [_jsxs("div", { className: "vertebr-modal-heading", children: [_jsx("p", { className: "vertebr-modal-eyebrow", children: "Operations" }), _jsx("h2", { children: "System health" }), environment || latestCheckedAt ? (_jsx("p", { className: "vertebr-health-modal-meta", children: [
54
+ environment ? `Env: ${environment}` : null,
55
+ latestCheckedAt ? `Checked ${latestCheckedAt}` : null,
56
+ ]
57
+ .filter(Boolean)
58
+ .join(" · ") })) : null] }), _jsxs("div", { className: "vertebr-modal-actions", children: [onRefresh ? (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: refreshing, onClick: () => void handleRefresh(), children: refreshing ? "Refreshing…" : "Refresh" })) : null, _jsx("button", { type: "button", className: "vertebr-btn", onClick: onClose, children: "Close" })] })] }), _jsxs("div", { className: "vertebr-modal-body", children: [refreshError ? (_jsx("p", { className: "vertebr-health-modal-error", children: refreshError })) : null, checks.length === 0 ? (_jsx("p", { className: "vertebr-health-modal-empty", children: "No health checks reported." })) : (_jsx("ul", { className: "vertebr-health-list", children: checks.map((check) => (_jsxs("li", { className: "vertebr-health-item", "data-status": check.status, children: [_jsxs("div", { className: "vertebr-health-item-top", children: [_jsxs("span", { className: "vertebr-health-badge", "data-status": check.status, children: [_jsx("span", { className: "vertebr-health-badge-dot", "aria-hidden": true }), statusLabel(check.status)] }), _jsx("strong", { className: "vertebr-health-item-label", children: check.label })] }), check.detail ? (_jsx("p", { className: "vertebr-health-item-detail", children: check.detail })) : null] }, check.id))) }))] })] }) }));
59
+ }
@@ -6,9 +6,11 @@ export type PagePreviewPaneProps = {
6
6
  controlId: string;
7
7
  /** Latest unsaved form values. */
8
8
  draft: Record<string, unknown> | null;
9
+ /** Label for the preview chrome. */
10
+ previewKind?: "page" | "addon";
9
11
  };
10
12
  /**
11
13
  * Live host iframe for Pages. Vertebr posts drafts; the host renders.
12
14
  */
13
- export declare function PagePreviewPane({ previewPath, controlId, draft, }: PagePreviewPaneProps): import("react").JSX.Element;
15
+ export declare function PagePreviewPane({ previewPath, controlId, draft, previewKind, }: PagePreviewPaneProps): import("react").JSX.Element;
14
16
  //# sourceMappingURL=PagePreviewPane.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PagePreviewPane.d.ts","sourceRoot":"","sources":["../../../src/components/admin/PagePreviewPane.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEvD,MAAM,MAAM,oBAAoB,GAAG;IACjC,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACvC,CAAC;AAWF;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,SAAS,EACT,KAAK,GACN,EAAE,oBAAoB,+BAmMtB"}
1
+ {"version":3,"file":"PagePreviewPane.d.ts","sourceRoot":"","sources":["../../../src/components/admin/PagePreviewPane.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEvD,MAAM,MAAM,oBAAoB,GAAG;IACjC,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC,CAAC;AAWF;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,SAAS,EACT,KAAK,EACL,WAAoB,GACrB,EAAE,oBAAoB,+BAmMtB"}
@@ -11,7 +11,7 @@ const MOBILE_HEIGHT = 844;
11
11
  /**
12
12
  * Live host iframe for Pages. Vertebr posts drafts; the host renders.
13
13
  */
14
- export function PagePreviewPane({ previewPath, controlId, draft, }) {
14
+ export function PagePreviewPane({ previewPath, controlId, draft, previewKind = "page", }) {
15
15
  const iframeRef = useRef(null);
16
16
  const stageRef = useRef(null);
17
17
  const draftRef = useRef(draft);
@@ -93,7 +93,7 @@ export function PagePreviewPane({ previewPath, controlId, draft, }) {
93
93
  const timer = window.setTimeout(notifyHostResize, 50);
94
94
  return () => window.clearTimeout(timer);
95
95
  }, [viewport, mobileScale, frameReady, notifyHostResize]);
96
- return (_jsxs("div", { className: "vertebr-page-preview", children: [_jsxs("div", { className: "vertebr-page-preview-meta", children: [_jsxs("p", { children: [_jsx("span", { children: "Preview" }), _jsx("strong", { children: previewPath })] }), _jsxs("p", { children: [_jsx("span", { children: "Status" }), _jsx("strong", { children: frameError
96
+ return (_jsxs("div", { className: "vertebr-page-preview", "data-preview-kind": previewKind, children: [_jsxs("div", { className: "vertebr-page-preview-meta", children: [_jsxs("p", { children: [_jsx("span", { children: previewKind === "addon" ? "Storefront" : "Preview" }), _jsx("strong", { children: previewPath })] }), _jsxs("p", { children: [_jsx("span", { children: "Status" }), _jsx("strong", { children: frameError
97
97
  ? "Unavailable"
98
98
  : frameReady
99
99
  ? "Live"
@@ -1 +1 @@
1
- {"version":3,"file":"VertebrAdmin.d.ts","sourceRoot":"","sources":["../../../src/components/admin/VertebrAdmin.tsx"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAGV,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAgB,YAAY,CAAC,EAC3B,OAAsB,EACtB,QAAQ,EAAE,YAAY,EACtB,KAAuB,EACvB,aAA6B,EAC7B,eAAiC,EACjC,eAAiC,EACjC,sBAAgD,EAChD,cAAc,EACd,aAAa,EACb,SAAS,GACV,EAAE,iBAAiB,+BAskBnB"}
1
+ {"version":3,"file":"VertebrAdmin.d.ts","sourceRoot":"","sources":["../../../src/components/admin/VertebrAdmin.tsx"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAGV,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAgB,YAAY,CAAC,EAC3B,OAAsB,EACtB,QAAQ,EAAE,YAAY,EACtB,KAAuB,EACvB,aAA6B,EAC7B,eAAiC,EACjC,eAAiC,EACjC,sBAAgD,EAChD,cAAc,EACd,aAAa,EACb,SAAS,GACV,EAAE,iBAAiB,+BAguBnB"}