@actuate-media/cms-admin 0.76.6 → 0.77.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 (41) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/__tests__/lib/preview-link.test.d.ts +2 -0
  3. package/dist/__tests__/lib/preview-link.test.d.ts.map +1 -0
  4. package/dist/__tests__/lib/preview-link.test.js +27 -0
  5. package/dist/__tests__/lib/preview-link.test.js.map +1 -0
  6. package/dist/__tests__/views/editor-top-bar.render.test.js +19 -0
  7. package/dist/__tests__/views/editor-top-bar.render.test.js.map +1 -1
  8. package/dist/__tests__/views/form-editor.render.test.d.ts +2 -0
  9. package/dist/__tests__/views/form-editor.render.test.d.ts.map +1 -0
  10. package/dist/__tests__/views/form-editor.render.test.js +146 -0
  11. package/dist/__tests__/views/form-editor.render.test.js.map +1 -0
  12. package/dist/actuate-admin.css +1 -1
  13. package/dist/lib/forms-service.d.ts +15 -3
  14. package/dist/lib/forms-service.d.ts.map +1 -1
  15. package/dist/lib/forms-service.js.map +1 -1
  16. package/dist/lib/preview-link.d.ts +7 -0
  17. package/dist/lib/preview-link.d.ts.map +1 -1
  18. package/dist/lib/preview-link.js +16 -0
  19. package/dist/lib/preview-link.js.map +1 -1
  20. package/dist/views/FormEditor.d.ts.map +1 -1
  21. package/dist/views/FormEditor.js +211 -116
  22. package/dist/views/FormEditor.js.map +1 -1
  23. package/dist/views/page-editor/EditorTopBar.d.ts.map +1 -1
  24. package/dist/views/page-editor/EditorTopBar.js +6 -1
  25. package/dist/views/page-editor/EditorTopBar.js.map +1 -1
  26. package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -1
  27. package/dist/views/page-editor/PageSectionEditor.js +14 -1
  28. package/dist/views/page-editor/PageSectionEditor.js.map +1 -1
  29. package/dist/views/post-editor/PostSectionEditor.d.ts.map +1 -1
  30. package/dist/views/post-editor/PostSectionEditor.js +11 -1
  31. package/dist/views/post-editor/PostSectionEditor.js.map +1 -1
  32. package/package.json +9 -9
  33. package/src/__tests__/lib/preview-link.test.ts +39 -0
  34. package/src/__tests__/views/editor-top-bar.render.test.tsx +22 -0
  35. package/src/__tests__/views/form-editor.render.test.tsx +186 -0
  36. package/src/lib/forms-service.ts +16 -1
  37. package/src/lib/preview-link.ts +21 -0
  38. package/src/views/FormEditor.tsx +655 -510
  39. package/src/views/page-editor/EditorTopBar.tsx +11 -4
  40. package/src/views/page-editor/PageSectionEditor.tsx +18 -0
  41. package/src/views/post-editor/PostSectionEditor.tsx +15 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @actuate-media/cms-admin
2
2
 
3
+ ## 0.77.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 21aa417: Consolidate the two form-editing surfaces onto the typed Forms API and make GA4 form analytics work end-to-end.
8
+
9
+ **cms-admin** — The Edit Form page is rebuilt as the canonical full-page form editor, backed by the same typed Forms API as the Forms list's inline Schema pane (no more legacy `/collections/forms` writes that bypassed schema versioning). It now covers everything in one place: Details (name/description/status + post-submit confirmation), Fields (versioned schema editor), **Notifications** (previously only reachable from the Schema pane), Analytics (GA4), Embed, and Integrations (webhooks). Confirmation settings now persist to `successMessage` / `redirectUrl` — the fields the public submission pipeline actually reads (the old editor wrote a `confirmation` object the runtime ignored). New forms are created through `POST /forms`, gaining slug generation, an initial schema version, and notification defaults, then route into the full editor.
10
+
11
+ **cms-core** — `FormDefinition` gains a sanitized `analytics` (GA4) config, persisted via the forms service (`createForm` / `updateForm` / `duplicateForm`) and exposed on the public form schema only when tracking is enabled. New `normalizeAnalyticsConfig` export and a client-safe `@actuate-media/cms-core/forms/analytics` subpath export.
12
+
13
+ **sections-react** — `<ActuateForm>` now fires GA4 `form_start` / `form_submit` / `form_error` events (with optional conversion value) when the form has analytics enabled. Also fixes the success state to read the submit endpoint's `confirmation` _object_ (`{ type, message, redirectUrl }`) — previously it was treated as a string, which broke the success message and ignored server-driven redirects. New `resolveSubmitOutcome` helper with regression coverage.
14
+
15
+ **plugin-forms** — The `forms` collection field map now declares every key the typed forms service persists (`description`, `notificationSettings`, `embedSettings`, `spamSettings`, `successMessage`, `redirectUrl`, `analytics`, `activeSchemaVersionId`, …). The data layer strips undeclared keys on write, so consumer apps registering this plugin would previously drop notification/embed/spam settings silently. Status options now match the typed `FormStatus` (`active` / `draft` / `archived`).
16
+
17
+ ## 0.76.7
18
+
19
+ ### Patch Changes
20
+
21
+ - 172ee9a: Editor "view on site" now opens the LIVE page for published documents.
22
+
23
+ The external-link button in the editor top bar always opened a token-gated
24
+ **draft** preview (`?preview=<token>`), even when the document was published — so
25
+ there was no quick way to reach the actual live page. It's now status-aware:
26
+ - **Published** → opens the real live URL in a new tab (no preview token, no
27
+ forced save — instant), labeled **"View live"**.
28
+ - **Not yet public** (draft / scheduled / archived) → the existing token-gated
29
+ draft preview, labeled "View draft on site".
30
+
31
+ The eye (canvas) and globe (inline site preview) continue to preview your pending
32
+ edits, so all three toolbar actions now have distinct jobs: edit-preview,
33
+ accurate in-place draft preview, and jump-to-live. Adds `buildPublicUrl()`
34
+ (home-style slugs collapse to `/`). Applies to both the page and post editors.
35
+
3
36
  ## 0.76.6
4
37
 
5
38
  ### Patch Changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=preview-link.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-link.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/preview-link.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { buildPublicUrl, buildPublicPreviewUrl } from '../../lib/preview-link.js';
3
+ describe('buildPublicUrl (live URL — no preview token)', () => {
4
+ it('builds a top-level page URL', () => {
5
+ expect(buildPublicUrl({ siteUrl: 'https://example.com', urlPrefix: '', slug: 'about' })).toBe('https://example.com/about');
6
+ });
7
+ it('includes the collection url prefix for posts', () => {
8
+ expect(buildPublicUrl({ siteUrl: 'https://example.com', urlPrefix: 'blog', slug: 'my-post' })).toBe('https://example.com/blog/my-post');
9
+ });
10
+ it('collapses home-style slugs to the site root', () => {
11
+ for (const slug of ['home', 'index', '']) {
12
+ expect(buildPublicUrl({ siteUrl: 'https://example.com', urlPrefix: '', slug })).toBe('https://example.com');
13
+ }
14
+ });
15
+ it('normalizes stray slashes on the site url, prefix, and slug', () => {
16
+ expect(buildPublicUrl({ siteUrl: 'https://example.com/', urlPrefix: '/blog/', slug: '/my-post/' })).toBe('https://example.com/blog/my-post');
17
+ });
18
+ it('carries NO preview token, unlike buildPublicPreviewUrl', () => {
19
+ const parts = { siteUrl: 'https://example.com', urlPrefix: 'blog', slug: 'my-post' };
20
+ const live = buildPublicUrl(parts);
21
+ const draft = buildPublicPreviewUrl({ ...parts, token: 'tok-123' });
22
+ expect(live).not.toContain('preview=');
23
+ expect(draft).toContain('preview=tok-123');
24
+ expect(draft.startsWith(live)).toBe(true);
25
+ });
26
+ });
27
+ //# sourceMappingURL=preview-link.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-link.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/preview-link.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAEjF,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAC3F,2BAA2B,CAC5B,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CACJ,cAAc,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CACvF,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;YACzC,MAAM,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAClF,qBAAqB,CACtB,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,CACJ,cAAc,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAC5F,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;QACpF,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,KAAK,GAAG,qBAAqB,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;QACnE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QACtC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QAC1C,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -55,4 +55,23 @@ describe('EditorTopBar publish gating', () => {
55
55
  expect(screen.getByRole('button', { name: 'Schedule publish' }).disabled).toBe(true);
56
56
  });
57
57
  });
58
+ describe('EditorTopBar view-on-site vs view-live', () => {
59
+ it('labels the external-link button "View draft on site" for a draft', () => {
60
+ render(_jsx(EditorTopBar, { ...baseProps, status: "DRAFT", onViewOnSite: vi.fn() }));
61
+ expect(screen.getByRole('button', { name: 'View draft on site' })).toBeTruthy();
62
+ expect(screen.queryByRole('button', { name: 'View live page' })).toBeNull();
63
+ });
64
+ it('labels it "View live page" for a published document and calls the handler', () => {
65
+ const onViewOnSite = vi.fn();
66
+ render(_jsx(EditorTopBar, { ...baseProps, status: "PUBLISHED", onViewOnSite: onViewOnSite }));
67
+ const btn = screen.getByRole('button', { name: 'View live page' });
68
+ fireEvent.click(btn);
69
+ expect(onViewOnSite).toHaveBeenCalledOnce();
70
+ expect(screen.queryByRole('button', { name: 'View draft on site' })).toBeNull();
71
+ });
72
+ it('hides the button when onViewOnSite is omitted (unsaved doc)', () => {
73
+ render(_jsx(EditorTopBar, { ...baseProps, status: "PUBLISHED" }));
74
+ expect(screen.queryByRole('button', { name: /View (live|draft)/ })).toBeNull();
75
+ });
76
+ });
58
77
  //# sourceMappingURL=editor-top-bar.render.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-top-bar.render.test.js","sourceRoot":"","sources":["../../../src/__tests__/views/editor-top-bar.render.test.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editor-top-bar.render.test.js","sourceRoot":"","sources":["../../../src/__tests__/views/editor-top-bar.render.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=form-editor.render.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-editor.render.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/views/form-editor.render.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,146 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @vitest-environment happy-dom
3
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
4
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
5
+ // Drive the editor through a mocked forms-service so the test owns the data
6
+ // and can assert that every tab persists through the typed Forms API (the
7
+ // same backend as the Forms list's Schema pane — no more legacy
8
+ // /collections/forms writes).
9
+ const FORM = {
10
+ id: 'f1',
11
+ name: 'Contact Us',
12
+ slug: 'contact-us',
13
+ description: 'General contact',
14
+ status: 'active',
15
+ fields: [
16
+ { id: 'c1', label: 'Full Name', key: 'name', type: 'text', required: true, sortOrder: 0 },
17
+ { id: 'c2', label: 'Email', key: 'email', type: 'email', required: true, sortOrder: 1 },
18
+ ],
19
+ successMessage: 'Thanks for reaching out!',
20
+ redirectUrl: '',
21
+ analytics: { enabled: false },
22
+ totalEntries: 3,
23
+ notifyEnabled: true,
24
+ };
25
+ const fetchFormById = vi.fn(async (_id) => ({ ...FORM }));
26
+ const fetchFormSchema = vi.fn(async (_id) => ({
27
+ fields: FORM.fields,
28
+ activeVersionId: 'v1',
29
+ versions: [],
30
+ }));
31
+ const updateForm = vi.fn(async (_id, patch) => ({
32
+ data: { ...FORM, ...patch },
33
+ }));
34
+ const saveFormSchema = vi.fn(async (_id, _fields) => ({ data: {} }));
35
+ const createForm = vi.fn(async (payload) => ({
36
+ data: { ...FORM, id: 'new-form-id', ...payload },
37
+ }));
38
+ const fetchNotificationSettings = vi.fn(async (_id) => ({
39
+ enabled: true,
40
+ recipients: ['team@example.com'],
41
+ }));
42
+ const updateNotificationSettings = vi.fn(async () => ({ data: {} }));
43
+ const fetchEmbedSettings = vi.fn(async () => ({}));
44
+ const fetchFormWebhooks = vi.fn(async () => []);
45
+ vi.mock('../../lib/forms-service.js', () => ({
46
+ fetchFormById: (id) => fetchFormById(id),
47
+ fetchFormSchema: (id) => fetchFormSchema(id),
48
+ updateForm: (id, patch) => updateForm(id, patch),
49
+ saveFormSchema: (id, fields) => saveFormSchema(id, fields),
50
+ createForm: (payload) => createForm(payload),
51
+ fetchNotificationSettings: (id) => fetchNotificationSettings(id),
52
+ updateNotificationSettings: () => updateNotificationSettings(),
53
+ fetchEmbedSettings: () => fetchEmbedSettings(),
54
+ updateEmbedSettings: vi.fn(async () => ({ data: {} })),
55
+ fetchFormWebhooks: () => fetchFormWebhooks(),
56
+ createFormWebhook: vi.fn(async () => ({ data: {} })),
57
+ updateFormWebhook: vi.fn(async () => ({ data: {} })),
58
+ deleteFormWebhook: vi.fn(async () => ({})),
59
+ testFormWebhook: vi.fn(async () => ({ data: { ok: true } })),
60
+ }));
61
+ vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn(), loading: vi.fn() } }));
62
+ const { FormEditor } = await import('../../views/FormEditor.js');
63
+ // Radix Tabs activates on mousedown (button 0), not a bare click.
64
+ function selectTab(name) {
65
+ const tab = screen.getByRole('tab', { name });
66
+ fireEvent.mouseDown(tab, { button: 0 });
67
+ fireEvent.click(tab);
68
+ }
69
+ beforeEach(() => {
70
+ fetchFormById.mockClear();
71
+ fetchFormSchema.mockClear();
72
+ updateForm.mockClear();
73
+ saveFormSchema.mockClear();
74
+ createForm.mockClear();
75
+ fetchNotificationSettings.mockClear();
76
+ });
77
+ describe('FormEditor (existing form)', () => {
78
+ it('loads through the typed Forms API and renders every settings tab', async () => {
79
+ render(_jsx(FormEditor, { formId: "f1", onNavigate: () => { } }));
80
+ expect(await screen.findByRole('heading', { name: 'Contact Us' })).toBeTruthy();
81
+ expect(fetchFormById).toHaveBeenCalledWith('f1');
82
+ expect(fetchFormSchema).toHaveBeenCalledWith('f1');
83
+ const tabs = screen.getAllByRole('tab').map((t) => t.textContent);
84
+ expect(tabs).toEqual([
85
+ 'Details',
86
+ 'Fields',
87
+ 'Notifications',
88
+ 'Analytics',
89
+ 'Embed',
90
+ 'Integrations',
91
+ ]);
92
+ });
93
+ it('saves details (message confirmation clears the redirect URL)', async () => {
94
+ render(_jsx(FormEditor, { formId: "f1", onNavigate: () => { } }));
95
+ await screen.findByRole('heading', { name: 'Contact Us' });
96
+ fireEvent.change(screen.getByLabelText(/Form Name/), { target: { value: 'Contact' } });
97
+ fireEvent.click(screen.getByRole('button', { name: /Save Details/ }));
98
+ await waitFor(() => expect(updateForm).toHaveBeenCalledWith('f1', expect.objectContaining({
99
+ name: 'Contact',
100
+ status: 'active',
101
+ successMessage: 'Thanks for reaching out!',
102
+ redirectUrl: '',
103
+ })));
104
+ });
105
+ it('exposes notification settings from the editor (the old editor had none)', async () => {
106
+ render(_jsx(FormEditor, { formId: "f1", onNavigate: () => { } }));
107
+ await screen.findByRole('heading', { name: 'Contact Us' });
108
+ selectTab('Notifications');
109
+ await waitFor(() => expect(fetchNotificationSettings).toHaveBeenCalledWith('f1'));
110
+ expect(await screen.findByText('Enable notifications')).toBeTruthy();
111
+ });
112
+ it('persists GA4 analytics through the typed update endpoint', async () => {
113
+ render(_jsx(FormEditor, { formId: "f1", onNavigate: () => { } }));
114
+ await screen.findByRole('heading', { name: 'Contact Us' });
115
+ selectTab('Analytics');
116
+ fireEvent.click(await screen.findByRole('switch', { name: /Google Analytics 4/ }));
117
+ fireEvent.click(screen.getByRole('button', { name: /Save Analytics/ }));
118
+ await waitFor(() => expect(updateForm).toHaveBeenCalledWith('f1', {
119
+ analytics: expect.objectContaining({ enabled: true }),
120
+ }));
121
+ });
122
+ it('saves the field schema through the versioned schema endpoint', async () => {
123
+ render(_jsx(FormEditor, { formId: "f1", onNavigate: () => { } }));
124
+ await screen.findByRole('heading', { name: 'Contact Us' });
125
+ selectTab('Fields');
126
+ fireEvent.click(await screen.findByRole('button', { name: 'Add Field' }));
127
+ fireEvent.click(screen.getByRole('button', { name: /Save Schema/ }));
128
+ await waitFor(() => expect(saveFormSchema).toHaveBeenCalledWith('f1', expect.arrayContaining([expect.objectContaining({ key: 'name' })])));
129
+ });
130
+ });
131
+ describe('FormEditor (new form)', () => {
132
+ it('creates through the typed API and routes into the full editor', async () => {
133
+ const onNavigate = vi.fn();
134
+ render(_jsx(FormEditor, { onNavigate: onNavigate }));
135
+ fireEvent.change(screen.getByLabelText(/Form Name/), { target: { value: 'Newsletter' } });
136
+ fireEvent.click(screen.getByRole('button', { name: /Create Form/ }));
137
+ await waitFor(() => expect(createForm).toHaveBeenCalledWith(expect.objectContaining({ name: 'Newsletter', status: 'active' })));
138
+ await waitFor(() => expect(onNavigate).toHaveBeenCalledWith('/forms/new-form-id/edit'));
139
+ });
140
+ it('disables Create until a name is entered', () => {
141
+ render(_jsx(FormEditor, { onNavigate: () => { } }));
142
+ const create = screen.getByRole('button', { name: /Create Form/ });
143
+ expect(create.disabled).toBe(true);
144
+ });
145
+ });
146
+ //# sourceMappingURL=form-editor.render.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-editor.render.test.js","sourceRoot":"","sources":["../../../src/__tests__/views/form-editor.render.test.tsx"],"names":[],"mappings":"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"}