@vertebr/react 0.9.0 → 0.11.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 (89) hide show
  1. package/dist/components/admin/AddonEditor.d.ts +3 -2
  2. package/dist/components/admin/AddonEditor.d.ts.map +1 -1
  3. package/dist/components/admin/AddonEditor.js +14 -10
  4. package/dist/components/admin/AdminContent.d.ts +4 -1
  5. package/dist/components/admin/AdminContent.d.ts.map +1 -1
  6. package/dist/components/admin/AdminContent.js +74 -12
  7. package/dist/components/admin/AdminSaveBar.d.ts.map +1 -1
  8. package/dist/components/admin/AdminSaveBar.js +6 -1
  9. package/dist/components/admin/AdminSyncPage.d.ts.map +1 -1
  10. package/dist/components/admin/AdminSyncPage.js +50 -6
  11. package/dist/components/admin/AdminTopBar.d.ts +6 -2
  12. package/dist/components/admin/AdminTopBar.d.ts.map +1 -1
  13. package/dist/components/admin/AdminTopBar.js +27 -4
  14. package/dist/components/admin/AuditBoard.d.ts +7 -0
  15. package/dist/components/admin/AuditBoard.d.ts.map +1 -0
  16. package/dist/components/admin/AuditBoard.js +43 -0
  17. package/dist/components/admin/HealthModal.d.ts +9 -0
  18. package/dist/components/admin/HealthModal.d.ts.map +1 -0
  19. package/dist/components/admin/HealthModal.js +59 -0
  20. package/dist/components/admin/PagePreviewPane.d.ts +3 -1
  21. package/dist/components/admin/PagePreviewPane.d.ts.map +1 -1
  22. package/dist/components/admin/PagePreviewPane.js +41 -9
  23. package/dist/components/admin/SyncPreviewFrame.d.ts +22 -0
  24. package/dist/components/admin/SyncPreviewFrame.d.ts.map +1 -0
  25. package/dist/components/admin/SyncPreviewFrame.js +135 -0
  26. package/dist/components/admin/VertebrAdmin.d.ts.map +1 -1
  27. package/dist/components/admin/VertebrAdmin.js +88 -22
  28. package/dist/components/admin/adminSearch.d.ts.map +1 -1
  29. package/dist/components/admin/adminSearch.js +9 -0
  30. package/dist/components/admin/breadcrumbs.d.ts.map +1 -1
  31. package/dist/components/admin/breadcrumbs.js +2 -0
  32. package/dist/components/admin/routes.d.ts.map +1 -1
  33. package/dist/components/admin/routes.js +13 -1
  34. package/dist/components/admin/types.d.ts +2 -0
  35. package/dist/components/admin/types.d.ts.map +1 -1
  36. package/dist/components/config/DatetimeInput.d.ts +15 -0
  37. package/dist/components/config/DatetimeInput.d.ts.map +1 -0
  38. package/dist/components/config/DatetimeInput.js +287 -0
  39. package/dist/components/config/EnumInput.d.ts.map +1 -1
  40. package/dist/components/config/EnumInput.js +4 -4
  41. package/dist/components/config/EnumListInput.d.ts.map +1 -1
  42. package/dist/components/config/EnumListInput.js +13 -3
  43. package/dist/components/config/ReferenceInput.d.ts +11 -0
  44. package/dist/components/config/ReferenceInput.d.ts.map +1 -0
  45. package/dist/components/config/ReferenceInput.js +99 -0
  46. package/dist/components/config/RevisionHistory.d.ts +12 -0
  47. package/dist/components/config/RevisionHistory.d.ts.map +1 -0
  48. package/dist/components/config/RevisionHistory.js +139 -0
  49. package/dist/components/config/form/ConfigField.d.ts +3 -2
  50. package/dist/components/config/form/ConfigField.d.ts.map +1 -1
  51. package/dist/components/config/form/ConfigField.js +4 -2
  52. package/dist/components/config/form/ConfigForm.d.ts +1 -1
  53. package/dist/components/config/form/ConfigForm.d.ts.map +1 -1
  54. package/dist/components/config/form/ConfigForm.js +66 -14
  55. package/dist/components/config/form/RecordConfigForm.d.ts +3 -2
  56. package/dist/components/config/form/RecordConfigForm.d.ts.map +1 -1
  57. package/dist/components/config/form/RecordConfigForm.js +2 -1
  58. package/dist/components/config/form/SettingsConfigForm.d.ts +3 -2
  59. package/dist/components/config/form/SettingsConfigForm.d.ts.map +1 -1
  60. package/dist/components/config/form/SettingsConfigForm.js +2 -2
  61. package/dist/components/config/form/types.d.ts +14 -1
  62. package/dist/components/config/form/types.d.ts.map +1 -1
  63. package/dist/components/resources/ResourceTable.d.ts +7 -1
  64. package/dist/components/resources/ResourceTable.d.ts.map +1 -1
  65. package/dist/components/resources/ResourceTable.js +56 -6
  66. package/dist/components/theme/ThemeToggle.d.ts +3 -1
  67. package/dist/components/theme/ThemeToggle.d.ts.map +1 -1
  68. package/dist/components/theme/ThemeToggle.js +2 -2
  69. package/dist/components/ui/icons.d.ts +1 -0
  70. package/dist/components/ui/icons.d.ts.map +1 -1
  71. package/dist/components/ui/icons.js +6 -1
  72. package/dist/hooks/useSaveBar.d.ts +6 -0
  73. package/dist/hooks/useSaveBar.d.ts.map +1 -1
  74. package/dist/index.d.ts +2 -1
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1 -0
  77. package/dist/lib/capabilities.d.ts +4 -0
  78. package/dist/lib/capabilities.d.ts.map +1 -0
  79. package/dist/lib/capabilities.js +9 -0
  80. package/dist/styles/audit.css +34 -0
  81. package/dist/styles/form.css +587 -9
  82. package/dist/styles/index.css +1 -0
  83. package/dist/styles/modal.css +111 -0
  84. package/dist/styles/page-preview.css +84 -0
  85. package/dist/styles/select.css +23 -0
  86. package/dist/styles/shell.css +234 -18
  87. package/dist/styles/sync.css +388 -4
  88. package/dist/themes/light.css +27 -0
  89. package/package.json +3 -1
@@ -0,0 +1,139 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from "react";
3
+ import { useToast } from "../../hooks/useToast";
4
+ function formatWhen(at) {
5
+ const date = new Date(at);
6
+ if (Number.isNaN(date.getTime()))
7
+ return at;
8
+ return date.toLocaleString(undefined, {
9
+ month: "short",
10
+ day: "numeric",
11
+ hour: "numeric",
12
+ minute: "2-digit",
13
+ });
14
+ }
15
+ function formatActor(value) {
16
+ if (!value)
17
+ return null;
18
+ if (value.includes("@"))
19
+ return value;
20
+ if (value.length <= 12)
21
+ return value;
22
+ return `${value.slice(0, 6)}…${value.slice(-4)}`;
23
+ }
24
+ /**
25
+ * Compact History control — opens revision list in a modal so the
26
+ * editor form stays the primary surface.
27
+ */
28
+ export function RevisionHistory({ client, configId, onPublished, }) {
29
+ const { push } = useToast();
30
+ const [open, setOpen] = useState(false);
31
+ const [items, setItems] = useState([]);
32
+ const [count, setCount] = useState(null);
33
+ const [loading, setLoading] = useState(false);
34
+ const [busyId, setBusyId] = useState(null);
35
+ const refresh = useCallback(async () => {
36
+ setLoading(true);
37
+ try {
38
+ const data = await client.listRevisions(configId, { fresh: true });
39
+ setItems(data.items);
40
+ setCount(data.items.length);
41
+ }
42
+ finally {
43
+ setLoading(false);
44
+ }
45
+ }, [client, configId]);
46
+ useEffect(() => {
47
+ let cancelled = false;
48
+ void (async () => {
49
+ try {
50
+ const data = await client.listRevisions(configId, { fresh: true });
51
+ if (!cancelled)
52
+ setCount(data.items.length);
53
+ }
54
+ catch {
55
+ /* badge is optional */
56
+ }
57
+ })();
58
+ return () => {
59
+ cancelled = true;
60
+ };
61
+ }, [client, configId]);
62
+ useEffect(() => {
63
+ if (!open)
64
+ return;
65
+ let cancelled = false;
66
+ void (async () => {
67
+ try {
68
+ setLoading(true);
69
+ const data = await client.listRevisions(configId, { fresh: true });
70
+ if (!cancelled) {
71
+ setItems(data.items);
72
+ setCount(data.items.length);
73
+ }
74
+ }
75
+ catch (err) {
76
+ if (!cancelled) {
77
+ push(err instanceof Error ? err.message : "Failed to load revisions", "danger");
78
+ }
79
+ }
80
+ finally {
81
+ if (!cancelled)
82
+ setLoading(false);
83
+ }
84
+ })();
85
+ return () => {
86
+ cancelled = true;
87
+ };
88
+ }, [open, client, configId, push]);
89
+ useEffect(() => {
90
+ if (!open)
91
+ return;
92
+ const onKeyDown = (event) => {
93
+ if (event.key === "Escape")
94
+ setOpen(false);
95
+ };
96
+ window.addEventListener("keydown", onKeyDown);
97
+ const previous = document.body.style.overflow;
98
+ document.body.style.overflow = "hidden";
99
+ return () => {
100
+ window.removeEventListener("keydown", onKeyDown);
101
+ document.body.style.overflow = previous;
102
+ };
103
+ }, [open]);
104
+ const publish = async (revId) => {
105
+ setBusyId(revId);
106
+ try {
107
+ await client.publishRevision(configId, revId);
108
+ push("Revision published", "ok");
109
+ await refresh();
110
+ await onPublished?.();
111
+ }
112
+ catch (err) {
113
+ push(err instanceof Error ? err.message : "Publish failed", "danger");
114
+ }
115
+ finally {
116
+ setBusyId(null);
117
+ }
118
+ };
119
+ const useRevision = async (revId) => {
120
+ setBusyId(revId);
121
+ try {
122
+ await client.restoreRevision(configId, revId);
123
+ push("Now editing this revision", "ok");
124
+ await refresh();
125
+ await onPublished?.();
126
+ }
127
+ catch (err) {
128
+ push(err instanceof Error ? err.message : "Could not switch revision", "danger");
129
+ }
130
+ finally {
131
+ setBusyId(null);
132
+ }
133
+ };
134
+ return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: "vertebr-revisions-trigger", "aria-haspopup": "dialog", "aria-expanded": open, onClick: () => setOpen(true), children: ["History", count != null ? (_jsx("span", { className: "vertebr-revisions-trigger-count", children: count })) : null] }), open ? (_jsx("div", { className: "vertebr-modal-backdrop", role: "presentation", onClick: () => setOpen(false), children: _jsxs("div", { className: "vertebr-modal vertebr-modal-sm vertebr-revisions-modal", role: "dialog", "aria-modal": "true", "aria-label": "Revision history", 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: "Change safety" }), _jsx("h2", { children: "Revisions" })] }), _jsxs("div", { className: "vertebr-modal-actions", children: [_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: loading || busyId != null, onClick: () => void refresh(), children: loading ? "…" : "Refresh" }), _jsx("button", { type: "button", className: "vertebr-btn", onClick: () => setOpen(false), children: "Close" })] })] }), _jsx("div", { className: "vertebr-modal-body", children: items.length === 0 && !loading ? (_jsx("p", { className: "vertebr-revisions-empty", children: "No revisions yet. Save to create a draft." })) : (_jsx("ul", { className: "vertebr-revisions-list", children: items.map((rev) => {
135
+ const actor = formatActor(rev.createdBy);
136
+ const isCurrent = Boolean(rev.active);
137
+ return (_jsxs("li", { className: "vertebr-revisions-item", "data-active": isCurrent ? "true" : undefined, children: [_jsxs("div", { className: "vertebr-revisions-meta", children: [_jsx("strong", { children: rev.label?.trim() || rev.id }), _jsx("span", { "data-status": rev.status, children: rev.status }), isCurrent ? (_jsx("span", { "data-status": "current", children: "Current" })) : null, _jsxs("span", { className: "vertebr-revisions-when", children: [formatWhen(rev.createdAt), actor ? ` · ${actor}` : ""] })] }), _jsxs("div", { className: "vertebr-revisions-actions", children: [rev.status !== "published" ? (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: busyId != null, onClick: () => void publish(rev.id), children: busyId === rev.id ? "…" : "Publish" })) : null, isCurrent ? null : (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", disabled: busyId != null, onClick: () => void useRevision(rev.id), children: "Use" }))] })] }, rev.id));
138
+ }) })) })] }) })) : null] }));
139
+ }
@@ -1,5 +1,5 @@
1
1
  import { type UseFormReturn } from "react-hook-form";
2
- import type { FieldSchema, ResourceUploadMeta } from "@vertebr/client";
2
+ import type { FieldSchema, ResourceUploadMeta, VertebrClient } from "@vertebr/client";
3
3
  import type { ConfigFormVariant, FontLibraryHandlers, GalleryHandlers } from "./types";
4
4
  export type ConfigFieldProps = GalleryHandlers & FontLibraryHandlers & {
5
5
  fieldKey: string;
@@ -19,6 +19,7 @@ export type ConfigFieldProps = GalleryHandlers & FontLibraryHandlers & {
19
19
  visibilityGroup?: string;
20
20
  /** Render boolean fields as rows in a settings list (config forms). */
21
21
  settingsRow?: boolean;
22
+ client?: VertebrClient;
22
23
  };
23
- export declare function ConfigField({ fieldKey, field, groupLabel, variant, schema, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, hideImagePreview, hideUpload, visibilityGroup, settingsRow, }: ConfigFieldProps): import("react").JSX.Element;
24
+ export declare function ConfigField({ fieldKey, field, groupLabel, variant, schema, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, hideImagePreview, hideUpload, visibilityGroup, settingsRow, client, }: ConfigFieldProps): import("react").JSX.Element;
24
25
  //# sourceMappingURL=ConfigField.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigField.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/ConfigField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIjE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAqBvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvF,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAC5C,mBAAmB,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACpD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,KAAK,EACL,UAAU,EACV,OAAO,EACP,MAAM,EACN,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,KAAK,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,WAAW,GACZ,EAAE,gBAAgB,+BAmSlB"}
1
+ {"version":3,"file":"ConfigField.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/ConfigField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIjE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAuBtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvF,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAC5C,mBAAmB,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACpD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,KAAK,EACL,UAAU,EACV,OAAO,EACP,MAAM,EACN,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,KAAK,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,WAAW,EACX,MAAM,GACP,EAAE,gBAAgB,+BAkUlB"}
@@ -9,11 +9,13 @@ import { isCentsField, isPriceField } from "../../../lib/price";
9
9
  import { FontPickerField } from "../../fonts/FontPickerField";
10
10
  import { ImageUploadControl } from "../../resources/ImageUploadControl";
11
11
  import { DescriptionInput } from "../DescriptionInput";
12
+ import { DatetimeInput } from "../DatetimeInput";
12
13
  import { EnumInput } from "../EnumInput";
13
14
  import { EnumListInput } from "../EnumListInput";
14
15
  import { PriceInput } from "../PriceInput";
16
+ import { ReferenceInput } from "../ReferenceInput";
15
17
  import { displayLabel, firstImageUrl, isMultilineField, fieldVisibilityKey, spanFor, } from "./helpers";
16
- export function ConfigField({ fieldKey, field, groupLabel, variant, schema, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, hideImagePreview, hideUpload, visibilityGroup, settingsRow, }) {
18
+ export function ConfigField({ fieldKey, field, groupLabel, variant, schema, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, hideImagePreview, hideUpload, visibilityGroup, settingsRow, client, }) {
17
19
  const label = displayLabel(fieldKey, field, groupLabel);
18
20
  const visibilityKey = fieldVisibilityKey(fieldKey, schema, visibilityGroup ?? groupLabel);
19
21
  const visibilityOn = !visibilityKey || watched?.[visibilityKey] !== false;
@@ -38,7 +40,7 @@ export function ConfigField({ fieldKey, field, groupLabel, variant, schema, watc
38
40
  : "", onBlur: controllerField.onBlur, onChange: (event) => {
39
41
  const next = event.target.value;
40
42
  controllerField.onChange(next === "" ? undefined : Number(next));
41
- }, name: controllerField.name, ref: controllerField.ref })) })) : field.type === "enum" ? (_jsx(Controller, { control: form.control, name: fieldKey, render: ({ field: controllerField }) => (_jsx(EnumInput, { id: fieldKey, value: controllerField.value, field: field, readOnly: field.readOnly, onChange: controllerField.onChange })) })) : field.type === "enum[]" ? (_jsx(Controller, { control: form.control, name: fieldKey, render: ({ field: controllerField }) => (_jsx(EnumListInput, { id: fieldKey, value: controllerField.value, field: field, readOnly: field.readOnly, onChange: controllerField.onChange })) })) : field.type === "font" ? (_jsx(Controller, { control: form.control, name: fieldKey, render: ({ field: controllerField }) => (_jsx(FontPickerField, { id: fieldKey, value: controllerField.value, label: field.label, description: field.description, readOnly: field.readOnly, fonts: fonts ?? [], loading: fontsLoading, onChange: controllerField.onChange, onRefreshFonts: onRefreshFonts })) })) : isMultilineField(fieldKey, field) ? (_jsx("textarea", { id: fieldKey, rows: 5, readOnly: field.readOnly, ...form.register(fieldKey) })) : (_jsx("input", { id: fieldKey, type: "text", readOnly: field.readOnly, ...form.register(fieldKey) })), !hideUpload && uploads?.[fieldKey] && onUpload && !field.readOnly ? (_jsx(ImageUploadControl, { meta: uploads[fieldKey], multiple: field.type === "file[]", onUpload: async (files) => {
43
+ }, name: controllerField.name, ref: controllerField.ref })) })) : field.type === "datetime" ? (_jsx(Controller, { control: form.control, name: fieldKey, render: ({ field: controllerField }) => (_jsx(DatetimeInput, { id: fieldKey, name: controllerField.name, inputRef: controllerField.ref, value: controllerField.value, readOnly: field.readOnly, onBlur: controllerField.onBlur, onChange: controllerField.onChange })) })) : field.type === "enum" ? (_jsx(Controller, { control: form.control, name: fieldKey, render: ({ field: controllerField }) => (_jsx(EnumInput, { id: fieldKey, value: controllerField.value, field: field, readOnly: field.readOnly, onChange: controllerField.onChange })) })) : field.type === "enum[]" ? (_jsx(Controller, { control: form.control, name: fieldKey, render: ({ field: controllerField }) => (_jsx(EnumListInput, { id: fieldKey, value: controllerField.value, field: field, readOnly: field.readOnly, onChange: controllerField.onChange })) })) : field.type === "font" ? (_jsx(Controller, { control: form.control, name: fieldKey, render: ({ field: controllerField }) => (_jsx(FontPickerField, { id: fieldKey, value: controllerField.value, label: field.label, description: field.description, readOnly: field.readOnly, fonts: fonts ?? [], loading: fontsLoading, onChange: controllerField.onChange, onRefreshFonts: onRefreshFonts })) })) : field.type === "reference" && client ? (_jsx(Controller, { control: form.control, name: fieldKey, render: ({ field: controllerField }) => (_jsx(ReferenceInput, { id: fieldKey, value: controllerField.value, field: field, client: client, readOnly: field.readOnly, onChange: controllerField.onChange })) })) : isMultilineField(fieldKey, field) ? (_jsx("textarea", { id: fieldKey, rows: 5, readOnly: field.readOnly, ...form.register(fieldKey) })) : (_jsx("input", { id: fieldKey, type: "text", readOnly: field.readOnly, ...form.register(fieldKey) })), !hideUpload && uploads?.[fieldKey] && onUpload && !field.readOnly ? (_jsx(ImageUploadControl, { meta: uploads[fieldKey], multiple: field.type === "file[]", onUpload: async (files) => {
42
44
  const uploaded = await onUpload(fieldKey, files);
43
45
  const urls = uploaded
44
46
  .map((item) => item.url)
@@ -1,4 +1,4 @@
1
1
  import type { ConfigFormProps } from "./types";
2
2
  export type { ConfigFormProps, ConfigFormVariant } from "./types";
3
- export declare function ConfigForm({ schema, value, onSave, submitLabel, variant, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, onChange, hideActions, }: ConfigFormProps): import("react").JSX.Element;
3
+ export declare function ConfigForm({ schema, value, onSave, submitLabel, variant, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, onChange, hideActions, client, canWrite, revisionsEnabled, onPublish, canPublish, }: ConfigFormProps): import("react").JSX.Element;
4
4
  //# sourceMappingURL=ConfigForm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigForm.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/ConfigForm.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAElE,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,MAAM,EACN,WAAW,EACX,OAAkB,EAClB,OAAO,EACP,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,KAAK,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,QAAQ,EACR,WAAW,GACZ,EAAE,eAAe,+BAqIjB"}
1
+ {"version":3,"file":"ConfigForm.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/ConfigForm.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAElE,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,MAAM,EACN,WAAW,EACX,OAAkB,EAClB,OAAO,EACP,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,KAAK,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAe,EACf,gBAAwB,EACxB,SAAS,EACT,UAAkB,GACnB,EAAE,eAAe,+BA2LjB"}
@@ -7,7 +7,7 @@ import { useToast } from "../../../hooks/useToast";
7
7
  import { buildZodSchema, groupFields, withSpecVisibility, withSpecVisibilityValues, } from "./helpers";
8
8
  import { RecordConfigForm } from "./RecordConfigForm";
9
9
  import { SettingsConfigForm } from "./SettingsConfigForm";
10
- export function ConfigForm({ schema, value, onSave, submitLabel, variant = "config", uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, onChange, hideActions, }) {
10
+ export function ConfigForm({ schema, value, onSave, submitLabel, variant = "config", uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, onChange, hideActions, client, canWrite = true, revisionsEnabled = false, onPublish, canPublish = false, }) {
11
11
  const { register, clear } = useSaveBar();
12
12
  const { push: pushToast } = useToast();
13
13
  const editorSchema = useMemo(() => (variant === "record" ? withSpecVisibility(schema) : schema), [schema, variant]);
@@ -18,14 +18,21 @@ export function ConfigForm({ schema, value, onSave, submitLabel, variant = "conf
18
18
  const groups = useMemo(() => groupFields(editorSchema, variant), [editorSchema, variant]);
19
19
  const [status, setStatus] = useState(null);
20
20
  const [tone, setTone] = useState();
21
+ const [publishing, setPublishing] = useState(false);
21
22
  const form = useForm({
22
23
  resolver: zodResolver(zodSchema),
23
24
  defaultValues: editorValue,
24
25
  });
25
26
  const watched = useWatch({ control: form.control });
26
27
  useEffect(() => {
27
- onChange?.((watched ?? {}));
28
- }, [watched, onChange]);
28
+ if (!onChange)
29
+ return;
30
+ const subscription = form.watch((values) => {
31
+ onChange((values ?? {}));
32
+ });
33
+ onChange((form.getValues() ?? {}));
34
+ return () => subscription.unsubscribe();
35
+ }, [form, onChange]);
29
36
  useEffect(() => {
30
37
  form.reset(editorValue);
31
38
  }, [editorValue, form]);
@@ -34,16 +41,24 @@ export function ConfigForm({ schema, value, onSave, submitLabel, variant = "conf
34
41
  setStatus(null);
35
42
  setTone(undefined);
36
43
  };
44
+ const saveLabel = submitLabel ?? (revisionsEnabled ? "Save draft" : "Save");
37
45
  const onSubmit = form.handleSubmit(async (data) => {
38
- setStatus("Saving…");
46
+ if (!canWrite)
47
+ return;
48
+ setStatus(revisionsEnabled ? "Saving draft…" : "Saving…");
39
49
  setTone(undefined);
40
50
  register({ saving: true, isDirty: true, visible: true });
41
51
  try {
42
52
  await onSave(data);
43
- setStatus("Saved");
53
+ const nextStatus = revisionsEnabled
54
+ ? "Draft saved — not live until you publish"
55
+ : "Saved";
56
+ setStatus(nextStatus);
44
57
  setTone("ok");
45
58
  form.reset(data);
46
- pushToast("Changes saved", "ok");
59
+ pushToast(revisionsEnabled
60
+ ? "Draft saved. Publish to update the live storefront."
61
+ : "Changes saved", "ok");
47
62
  }
48
63
  catch (error) {
49
64
  const message = error instanceof Error ? error.message : "Save failed";
@@ -55,20 +70,51 @@ export function ConfigForm({ schema, value, onSave, submitLabel, variant = "conf
55
70
  register({ saving: false });
56
71
  }
57
72
  });
73
+ const handlePublish = async () => {
74
+ if (!onPublish || !canPublish)
75
+ return;
76
+ setPublishing(true);
77
+ setStatus("Publishing…");
78
+ setTone(undefined);
79
+ register({ publishing: true, visible: true });
80
+ try {
81
+ await onPublish();
82
+ setStatus("Published");
83
+ setTone("ok");
84
+ pushToast("Published to live storefront", "ok");
85
+ }
86
+ catch (error) {
87
+ const message = error instanceof Error ? error.message : "Publish failed";
88
+ setStatus(message);
89
+ setTone("danger");
90
+ pushToast(message, "danger");
91
+ }
92
+ finally {
93
+ setPublishing(false);
94
+ register({ publishing: false });
95
+ }
96
+ };
58
97
  const isDirty = form.formState.isDirty;
98
+ const showPublish = Boolean(revisionsEnabled && canPublish && onPublish);
59
99
  useEffect(() => {
60
100
  if (hideActions) {
61
101
  clear();
62
102
  return;
63
103
  }
64
104
  register({
65
- visible: isDirty,
105
+ visible: isDirty || Boolean(status) || showPublish,
66
106
  isDirty,
67
- saving: status === "Saving…",
68
- message: status ?? undefined,
69
- tone,
70
- onSave: () => void onSubmit(),
107
+ saving: status === "Saving…" || status === "Saving draft…",
108
+ publishing,
109
+ message: !canWrite && isDirty
110
+ ? "Missing config.write capability"
111
+ : (status ?? undefined),
112
+ tone: !canWrite && isDirty ? "danger" : tone,
113
+ saveLabel,
114
+ onSave: canWrite ? () => void onSubmit() : undefined,
71
115
  onDiscard,
116
+ publishLabel: "Publish",
117
+ onPublish: showPublish ? () => void handlePublish() : undefined,
72
118
  });
73
119
  return () => clear();
74
120
  }, [
@@ -80,17 +126,22 @@ export function ConfigForm({ schema, value, onSave, submitLabel, variant = "conf
80
126
  onDiscard,
81
127
  register,
82
128
  clear,
129
+ canWrite,
130
+ saveLabel,
131
+ showPublish,
132
+ publishing,
83
133
  ]);
84
134
  useEffect(() => {
85
135
  const onKeyDown = (event) => {
86
136
  if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "s") {
87
137
  event.preventDefault();
88
- void onSubmit();
138
+ if (canWrite)
139
+ void onSubmit();
89
140
  }
90
141
  };
91
142
  window.addEventListener("keydown", onKeyDown);
92
143
  return () => window.removeEventListener("keydown", onKeyDown);
93
- }, [onSubmit]);
144
+ }, [onSubmit, canWrite]);
94
145
  const shared = {
95
146
  schema: editorSchema,
96
147
  groups,
@@ -105,12 +156,13 @@ export function ConfigForm({ schema, value, onSave, submitLabel, variant = "conf
105
156
  fontsLoading,
106
157
  onListFonts,
107
158
  onRefreshFonts,
159
+ client,
108
160
  onSubmit,
109
161
  isDirty,
110
162
  status,
111
163
  tone,
112
164
  onDiscard,
113
- submitLabel,
165
+ submitLabel: saveLabel,
114
166
  hideActions: true,
115
167
  };
116
168
  if (variant === "record") {
@@ -1,5 +1,5 @@
1
1
  import type { UseFormReturn } from "react-hook-form";
2
- import type { FieldSchema, ResourceUploadMeta } from "@vertebr/client";
2
+ import type { FieldSchema, ResourceUploadMeta, VertebrClient } from "@vertebr/client";
3
3
  import type { FieldGroup, GalleryHandlers } from "./types";
4
4
  export type RecordConfigFormProps = GalleryHandlers & {
5
5
  schema: Record<string, FieldSchema>;
@@ -11,6 +11,7 @@ export type RecordConfigFormProps = GalleryHandlers & {
11
11
  url: string;
12
12
  name?: string;
13
13
  }>>;
14
+ client?: VertebrClient;
14
15
  onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
15
16
  isDirty: boolean;
16
17
  status: string | null;
@@ -19,5 +20,5 @@ export type RecordConfigFormProps = GalleryHandlers & {
19
20
  submitLabel?: string;
20
21
  hideActions?: boolean;
21
22
  };
22
- export declare function RecordConfigForm({ schema, groups, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, onSubmit, isDirty, status, tone, onDiscard, submitLabel, hideActions, }: RecordConfigFormProps): import("react").JSX.Element;
23
+ export declare function RecordConfigForm({ schema, groups, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, client, onSubmit, isDirty, status, tone, onDiscard, submitLabel, hideActions, }: RecordConfigFormProps): import("react").JSX.Element;
23
24
  //# sourceMappingURL=RecordConfigForm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RecordConfigForm.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/RecordConfigForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAYvE,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG;IACpD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACpD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;IACvB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,QAAQ,EACR,OAAO,EACP,MAAM,EACN,IAAI,EACJ,SAAS,EACT,WAAW,EACX,WAAW,GACZ,EAAE,qBAAqB,+BAsJvB"}
1
+ {"version":3,"file":"RecordConfigForm.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/RecordConfigForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAYtF,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG;IACpD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACpD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;IACvB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,EACN,IAAI,EACJ,SAAS,EACT,WAAW,EACX,WAAW,GACZ,EAAE,qBAAqB,+BAuJvB"}
@@ -5,7 +5,7 @@ import { ConfigField } from "./ConfigField";
5
5
  import { ConfigFormActions } from "./ConfigFormActions";
6
6
  import { VisibilityEyeButton } from "../VisibilityEye";
7
7
  import { findPrimaryImageKey, firstImageUrl, groupVisibilityKey, isStockField, } from "./helpers";
8
- export function RecordConfigForm({ schema, groups, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, onSubmit, isDirty, status, tone, onDiscard, submitLabel, hideActions, }) {
8
+ export function RecordConfigForm({ schema, groups, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, client, onSubmit, isDirty, status, tone, onDiscard, submitLabel, hideActions, }) {
9
9
  const imageKey = findPrimaryImageKey(schema, watched);
10
10
  const imageValue = imageKey ? firstImageUrl(watched?.[imageKey]) ?? "" : "";
11
11
  const asideGroups = groups.filter((group) => /^(Media|Display|Status)$/i.test(group.id));
@@ -20,6 +20,7 @@ export function RecordConfigForm({ schema, groups, watched, form, uploads, onUpl
20
20
  galleryUpload,
21
21
  onListGallery,
22
22
  onUploadGallery,
23
+ client,
23
24
  };
24
25
  return (_jsxs("form", { className: "vertebr-form", "data-variant": "record", onSubmit: onSubmit, children: [_jsx("div", { className: "vertebr-form-scroll", children: _jsxs("div", { className: "vertebr-record-layout", children: [_jsxs("aside", { className: "vertebr-record-aside", children: [_jsx("div", { className: "vertebr-record-preview", children: imageValue && looksLikeUrl(imageValue) ? (_jsx("img", { src: imageValue, alt: "" })) : (_jsx("div", { className: "vertebr-record-preview-empty", children: "No image" })) }), imageKey && uploads?.[imageKey] && onUpload ? (_jsx(ImageUploadControl, { meta: uploads[imageKey], label: "Drop a new image or browse", onUpload: async (files) => {
25
26
  const [first] = await onUpload(imageKey, files);
@@ -1,5 +1,5 @@
1
1
  import type { UseFormReturn } from "react-hook-form";
2
- import type { FieldSchema, ResourceUploadMeta } from "@vertebr/client";
2
+ import type { FieldSchema, ResourceUploadMeta, VertebrClient } from "@vertebr/client";
3
3
  import type { FieldGroup, FontLibraryHandlers, GalleryHandlers } from "./types";
4
4
  export type SettingsConfigFormProps = GalleryHandlers & FontLibraryHandlers & {
5
5
  schema: Record<string, FieldSchema>;
@@ -11,6 +11,7 @@ export type SettingsConfigFormProps = GalleryHandlers & FontLibraryHandlers & {
11
11
  url: string;
12
12
  name?: string;
13
13
  }>>;
14
+ client?: VertebrClient;
14
15
  onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
15
16
  isDirty: boolean;
16
17
  status: string | null;
@@ -19,5 +20,5 @@ export type SettingsConfigFormProps = GalleryHandlers & FontLibraryHandlers & {
19
20
  submitLabel?: string;
20
21
  hideActions?: boolean;
21
22
  };
22
- export declare function SettingsConfigForm({ schema, groups, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, onSubmit, isDirty, status, tone, onDiscard, submitLabel, hideActions, }: SettingsConfigFormProps): import("react").JSX.Element;
23
+ export declare function SettingsConfigForm({ schema, groups, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, client, onSubmit, isDirty, status, tone, onDiscard, submitLabel, hideActions, }: SettingsConfigFormProps): import("react").JSX.Element;
23
24
  //# sourceMappingURL=SettingsConfigForm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsConfigForm.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/SettingsConfigForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAIvE,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEhF,MAAM,MAAM,uBAAuB,GAAG,eAAe,GACnD,mBAAmB,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACpD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;IACvB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,KAAK,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,QAAQ,EACR,OAAO,EACP,MAAM,EACN,IAAI,EACJ,SAAS,EACT,WAAW,EACX,WAAW,GACZ,EAAE,uBAAuB,+BA8FzB"}
1
+ {"version":3,"file":"SettingsConfigForm.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/SettingsConfigForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAItF,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEhF,MAAM,MAAM,uBAAuB,GAAG,eAAe,GACnD,mBAAmB,GAAG;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACpD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;IACvB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEJ,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,KAAK,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,EACN,IAAI,EACJ,SAAS,EACT,WAAW,EACX,WAAW,GACZ,EAAE,uBAAuB,+BAgGzB"}
@@ -2,11 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ConfigField } from "./ConfigField";
3
3
  import { ConfigFormActions } from "./ConfigFormActions";
4
4
  import { isBooleanOnlyGroup } from "./helpers/fields";
5
- export function SettingsConfigForm({ schema, groups, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, onSubmit, isDirty, status, tone, onDiscard, submitLabel, hideActions, }) {
5
+ export function SettingsConfigForm({ schema, groups, watched, form, uploads, onUpload, galleryUpload, onListGallery, onUploadGallery, fonts, fontsLoading, onListFonts, onRefreshFonts, client, onSubmit, isDirty, status, tone, onDiscard, submitLabel, hideActions, }) {
6
6
  const singleGroup = groups.length === 1;
7
7
  return (_jsxs("form", { className: "vertebr-form", "data-variant": "config", onSubmit: onSubmit, children: [_jsx("div", { className: "vertebr-form-scroll", children: groups.map((group) => {
8
8
  const toggleList = isBooleanOnlyGroup(group.fields);
9
9
  const showSectionHead = !singleGroup || (group.id !== "General" && group.fields.length > 0);
10
- return (_jsxs("div", { className: "vertebr-form-section", "data-plain": singleGroup && !showSectionHead ? "true" : undefined, children: [showSectionHead ? (_jsxs("div", { className: "vertebr-form-section-head", children: [_jsx("h3", { children: group.label }), _jsx("span", { className: "vertebr-form-section-count", children: group.fields.length })] })) : null, _jsx("div", { className: "vertebr-form-fields", "data-layout": toggleList ? "settings" : undefined, children: toggleList ? (_jsx("ul", { className: "vertebr-settings-list", children: group.fields.map(([key, field]) => (_jsx(ConfigField, { fieldKey: key, field: field, groupLabel: group.label, variant: "config", schema: schema, watched: watched, form: form, uploads: uploads, onUpload: onUpload, galleryUpload: galleryUpload, onListGallery: onListGallery, onUploadGallery: onUploadGallery, fonts: fonts, fontsLoading: fontsLoading, onListFonts: onListFonts, onRefreshFonts: onRefreshFonts, settingsRow: true }, key))) })) : (group.fields.map(([key, field]) => (_jsx(ConfigField, { fieldKey: key, field: field, groupLabel: group.label, variant: "config", schema: schema, watched: watched, form: form, uploads: uploads, onUpload: onUpload, galleryUpload: galleryUpload, onListGallery: onListGallery, onUploadGallery: onUploadGallery, fonts: fonts, fontsLoading: fontsLoading, onListFonts: onListFonts, onRefreshFonts: onRefreshFonts }, key)))) })] }, group.id));
10
+ return (_jsxs("div", { className: "vertebr-form-section", "data-plain": singleGroup && !showSectionHead ? "true" : undefined, children: [showSectionHead ? (_jsxs("div", { className: "vertebr-form-section-head", children: [_jsx("h3", { children: group.label }), _jsx("span", { className: "vertebr-form-section-count", children: group.fields.length })] })) : null, _jsx("div", { className: "vertebr-form-fields", "data-layout": toggleList ? "settings" : undefined, children: toggleList ? (_jsx("ul", { className: "vertebr-settings-list", children: group.fields.map(([key, field]) => (_jsx(ConfigField, { fieldKey: key, field: field, groupLabel: group.label, variant: "config", schema: schema, watched: watched, form: form, uploads: uploads, onUpload: onUpload, galleryUpload: galleryUpload, onListGallery: onListGallery, onUploadGallery: onUploadGallery, fonts: fonts, fontsLoading: fontsLoading, onListFonts: onListFonts, onRefreshFonts: onRefreshFonts, client: client, settingsRow: true }, key))) })) : (group.fields.map(([key, field]) => (_jsx(ConfigField, { fieldKey: key, field: field, groupLabel: group.label, variant: "config", schema: schema, watched: watched, form: form, uploads: uploads, onUpload: onUpload, galleryUpload: galleryUpload, onListGallery: onListGallery, onUploadGallery: onUploadGallery, fonts: fonts, fontsLoading: fontsLoading, onListFonts: onListFonts, onRefreshFonts: onRefreshFonts, client: client }, key)))) })] }, group.id));
11
11
  }) }), hideActions ? null : (_jsx(ConfigFormActions, { form: form, isDirty: isDirty, status: status, tone: tone, onDiscard: onDiscard, submitLabel: submitLabel }))] }));
12
12
  }
@@ -1,4 +1,4 @@
1
- import type { FieldSchema, FontLibraryItem, GalleryItem, ResourceUploadMeta } from "@vertebr/client";
1
+ import type { FieldSchema, FontLibraryItem, GalleryItem, ResourceUploadMeta, VertebrClient } from "@vertebr/client";
2
2
  export type ConfigFormVariant = "config" | "record";
3
3
  export type ConfigFormProps = {
4
4
  schema: Record<string, FieldSchema>;
@@ -26,6 +26,19 @@ export type ConfigFormProps = {
26
26
  onChange?: (value: Record<string, unknown>) => void;
27
27
  /** Hide Save / Discard — parent owns submit. */
28
28
  hideActions?: boolean;
29
+ /** Used by `reference` fields for typeahead lookup. */
30
+ client?: VertebrClient;
31
+ /** When false, save actions are disabled (missing write capability). */
32
+ canWrite?: boolean;
33
+ /**
34
+ * When true, Save creates a draft (not live). Save bar labels and
35
+ * optional Publish action reflect that.
36
+ */
37
+ revisionsEnabled?: boolean;
38
+ /** Publish the current draft revision to live. */
39
+ onPublish?: () => Promise<void>;
40
+ /** Show Publish when a draft revision is available. */
41
+ canPublish?: boolean;
29
42
  };
30
43
  export type FieldEntry = [string, FieldSchema];
31
44
  export type FieldGroup = {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErG,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,sDAAsD;IACtD,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACpD,aAAa,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC;IAChE,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7C,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5D,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC/C,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACpD,gDAAgD;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,eAAe,EACf,eAAe,GAAG,eAAe,GAAG,iBAAiB,CACtD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,eAAe,EACf,OAAO,GAAG,cAAc,GAAG,aAAa,GAAG,gBAAgB,CAC5D,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/config/form/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,aAAa,EACd,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,sDAAsD;IACtD,QAAQ,CAAC,EAAE,CACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,IAAI,EAAE,KACV,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACpD,aAAa,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC;IAChE,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7C,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5D,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC/C,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACpD,gDAAgD;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uDAAuD;IACvD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,eAAe,EACf,eAAe,GAAG,eAAe,GAAG,iBAAiB,CACtD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,eAAe,EACf,OAAO,GAAG,cAAc,GAAG,aAAa,GAAG,gBAAgB,CAC5D,CAAC"}
@@ -22,6 +22,12 @@ type ResourcePanelProps = {
22
22
  onPreviewMail?: (rowId: string, actionId: string, input?: Record<string, unknown>) => Promise<MailPreviewResponse>;
23
23
  collectionActions?: Record<string, ResourceActionMeta>;
24
24
  onCollectionAction?: (actionId: string, input?: Record<string, unknown>) => Promise<unknown>;
25
+ bulkActions?: Record<string, ResourceActionMeta>;
26
+ onBulkAction?: (actionId: string, rowIds: string[], input?: Record<string, unknown>) => Promise<unknown>;
27
+ listQuery?: boolean | Record<string, FieldSchema>;
28
+ total?: number;
29
+ searchQuery?: string;
30
+ onSearchChange?: (q: string) => void;
25
31
  onUpload?: (field: string, files: File[]) => Promise<Array<{
26
32
  url: string;
27
33
  name?: string;
@@ -32,7 +38,7 @@ type ResourcePanelProps = {
32
38
  initialEditRowId?: string;
33
39
  onEditRowIdChange?: (rowId: string | null) => void;
34
40
  };
35
- export declare function ResourcePanel({ schema, items, permissions, actions, label, uploads, rowIdKeys, storageKey, onUpdate, onCreate, onDelete, onAction, onActionDone, onPreviewMail, collectionActions, onCollectionAction, onUpload, galleryUpload, onListGallery, onUploadGallery, initialEditRowId, onEditRowIdChange, }: ResourcePanelProps): import("react").JSX.Element;
41
+ export declare function ResourcePanel({ schema, items, permissions, actions, label, uploads, rowIdKeys, storageKey, onUpdate, onCreate, onDelete, onAction, onActionDone, onPreviewMail, collectionActions, onCollectionAction, bulkActions, onBulkAction, listQuery, total, searchQuery, onSearchChange, onUpload, galleryUpload, onListGallery, onUploadGallery, initialEditRowId, onEditRowIdChange, }: ResourcePanelProps): import("react").JSX.Element;
36
42
  /** @deprecated Prefer ResourcePanel */
37
43
  export declare function ResourceTable(props: {
38
44
  schema: Record<string, FieldSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceTable.d.ts","sourceRoot":"","sources":["../../../src/components/resources/ResourceTable.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResourceTable.d.ts","sourceRoot":"","sources":["../../../src/components/resources/ResourceTable.tsx"],"names":[],"mappings":"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"}