@prenta/admin 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +5 -56
- package/dist/AdminRoot.js.map +1 -1
- package/dist/__tests__/components/breakpoint-controls.render.test.js +4 -4
- package/dist/__tests__/components/breakpoint-controls.render.test.js.map +1 -1
- package/dist/__tests__/lib/canvas-edit-chrome.test.js +1 -22
- package/dist/__tests__/lib/canvas-edit-chrome.test.js.map +1 -1
- package/dist/__tests__/lib/open-public-site-tab.test.d.ts +2 -0
- package/dist/__tests__/lib/open-public-site-tab.test.d.ts.map +1 -0
- package/dist/__tests__/lib/open-public-site-tab.test.js +64 -0
- package/dist/__tests__/lib/open-public-site-tab.test.js.map +1 -0
- package/dist/__tests__/lib/preview-bridge.test.js +19 -79
- package/dist/__tests__/lib/preview-bridge.test.js.map +1 -1
- package/dist/__tests__/lib/view-site-chrome.test.d.ts +2 -0
- package/dist/__tests__/lib/view-site-chrome.test.d.ts.map +1 -0
- package/dist/__tests__/lib/view-site-chrome.test.js +69 -0
- package/dist/__tests__/lib/view-site-chrome.test.js.map +1 -0
- package/dist/__tests__/router/admin-routes.test.js +4 -0
- package/dist/__tests__/router/admin-routes.test.js.map +1 -1
- package/dist/__tests__/views/canvas-review-mode.render.test.js +11 -1
- package/dist/__tests__/views/canvas-review-mode.render.test.js.map +1 -1
- package/dist/__tests__/views/canvas-surface-shared.test.js +0 -16
- package/dist/__tests__/views/canvas-surface-shared.test.js.map +1 -1
- package/dist/__tests__/views/editor-top-bar.render.test.js +52 -22
- package/dist/__tests__/views/editor-top-bar.render.test.js.map +1 -1
- package/dist/__tests__/views/page-section-editor.test.js +53 -18
- package/dist/__tests__/views/page-section-editor.test.js.map +1 -1
- package/dist/__tests__/views/post-section-editor.test.js +23 -0
- package/dist/__tests__/views/post-section-editor.test.js.map +1 -1
- package/dist/components/BreakpointPicker.d.ts +3 -2
- package/dist/components/BreakpointPicker.d.ts.map +1 -1
- package/dist/components/BreakpointPicker.js +5 -3
- package/dist/components/BreakpointPicker.js.map +1 -1
- package/dist/components/CanvasEditTip.js +1 -1
- package/dist/components/CanvasEditTip.js.map +1 -1
- package/dist/lib/canvas-edit-chrome.d.ts +0 -17
- package/dist/lib/canvas-edit-chrome.d.ts.map +1 -1
- package/dist/lib/canvas-edit-chrome.js +0 -62
- package/dist/lib/canvas-edit-chrome.js.map +1 -1
- package/dist/lib/editor-preview.d.ts +4 -1
- package/dist/lib/editor-preview.d.ts.map +1 -1
- package/dist/lib/editor-preview.js +4 -1
- package/dist/lib/editor-preview.js.map +1 -1
- package/dist/lib/open-public-site-tab.d.ts +14 -0
- package/dist/lib/open-public-site-tab.d.ts.map +1 -0
- package/dist/lib/open-public-site-tab.js +46 -0
- package/dist/lib/open-public-site-tab.js.map +1 -0
- package/dist/lib/preview-bridge.d.ts +7 -74
- package/dist/lib/preview-bridge.d.ts.map +1 -1
- package/dist/lib/preview-bridge.js +12 -73
- package/dist/lib/preview-bridge.js.map +1 -1
- package/dist/lib/view-site-chrome.d.ts +19 -0
- package/dist/lib/view-site-chrome.d.ts.map +1 -0
- package/dist/lib/view-site-chrome.js +24 -0
- package/dist/lib/view-site-chrome.js.map +1 -0
- package/dist/router/admin-routes.d.ts.map +1 -1
- package/dist/router/admin-routes.js +0 -2
- package/dist/router/admin-routes.js.map +1 -1
- package/dist/views/page-editor/EditorCanvas.d.ts +2 -3
- package/dist/views/page-editor/EditorCanvas.d.ts.map +1 -1
- package/dist/views/page-editor/EditorCanvas.js +2 -2
- package/dist/views/page-editor/EditorCanvas.js.map +1 -1
- package/dist/views/page-editor/EditorTopBar.d.ts +15 -17
- package/dist/views/page-editor/EditorTopBar.d.ts.map +1 -1
- package/dist/views/page-editor/EditorTopBar.js +20 -21
- package/dist/views/page-editor/EditorTopBar.js.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.d.ts +1 -7
- package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.js +36 -141
- package/dist/views/page-editor/PageSectionEditor.js.map +1 -1
- package/dist/views/page-editor/StructureNotice.d.ts +2 -5
- package/dist/views/page-editor/StructureNotice.d.ts.map +1 -1
- package/dist/views/page-editor/StructureNotice.js +6 -10
- package/dist/views/page-editor/StructureNotice.js.map +1 -1
- package/dist/views/page-editor/sections/SectionRenderer.d.ts +1 -1
- package/dist/views/page-editor/sections/SectionRenderer.d.ts.map +1 -1
- package/dist/views/page-editor/sections/SectionRenderer.js +2 -1
- package/dist/views/page-editor/sections/SectionRenderer.js.map +1 -1
- package/dist/views/post-editor/PostEditorCanvas.d.ts +2 -4
- package/dist/views/post-editor/PostEditorCanvas.d.ts.map +1 -1
- package/dist/views/post-editor/PostEditorCanvas.js +3 -3
- package/dist/views/post-editor/PostEditorCanvas.js.map +1 -1
- package/dist/views/post-editor/PostSectionEditor.d.ts +1 -15
- package/dist/views/post-editor/PostSectionEditor.d.ts.map +1 -1
- package/dist/views/post-editor/PostSectionEditor.js +36 -128
- package/dist/views/post-editor/PostSectionEditor.js.map +1 -1
- package/dist/views/settings/SeoSettingsTab.d.ts.map +1 -1
- package/dist/views/settings/SeoSettingsTab.js +2 -1
- package/dist/views/settings/SeoSettingsTab.js.map +1 -1
- package/dist/views/settings/SiteInformationCard.d.ts.map +1 -1
- package/dist/views/settings/SiteInformationCard.js +3 -1
- package/dist/views/settings/SiteInformationCard.js.map +1 -1
- package/package.json +6 -6
- package/src/AdminRoot.tsx +0 -70
- package/src/__tests__/components/breakpoint-controls.render.test.tsx +6 -4
- package/src/__tests__/lib/canvas-edit-chrome.test.ts +0 -27
- package/src/__tests__/lib/open-public-site-tab.test.ts +74 -0
- package/src/__tests__/lib/preview-bridge.test.ts +21 -110
- package/src/__tests__/lib/view-site-chrome.test.ts +80 -0
- package/src/__tests__/router/admin-routes.test.ts +5 -0
- package/src/__tests__/views/canvas-review-mode.render.test.tsx +14 -1
- package/src/__tests__/views/canvas-surface-shared.test.ts +0 -19
- package/src/__tests__/views/editor-top-bar.render.test.tsx +104 -22
- package/src/__tests__/views/page-section-editor.test.tsx +65 -22
- package/src/__tests__/views/post-section-editor.test.tsx +35 -0
- package/src/components/BreakpointPicker.tsx +6 -3
- package/src/components/CanvasEditTip.tsx +2 -2
- package/src/lib/canvas-edit-chrome.ts +0 -64
- package/src/lib/editor-preview.ts +4 -1
- package/src/lib/open-public-site-tab.ts +57 -0
- package/src/lib/preview-bridge.ts +11 -157
- package/src/lib/view-site-chrome.ts +46 -0
- package/src/router/admin-routes.ts +0 -2
- package/src/styles/theme.css +4 -4
- package/src/views/page-editor/EditorCanvas.tsx +2 -7
- package/src/views/page-editor/EditorTopBar.tsx +85 -82
- package/src/views/page-editor/PageSectionEditor.tsx +83 -220
- package/src/views/page-editor/StructureNotice.tsx +7 -42
- package/src/views/page-editor/sections/SectionRenderer.tsx +5 -2
- package/src/views/post-editor/PostEditorCanvas.tsx +3 -9
- package/src/views/post-editor/PostSectionEditor.tsx +71 -195
- package/src/views/settings/SeoSettingsTab.tsx +21 -0
- package/src/views/settings/SiteInformationCard.tsx +7 -0
- package/dist/__tests__/views/use-site-preview.render.test.d.ts +0 -2
- package/dist/__tests__/views/use-site-preview.render.test.d.ts.map +0 -1
- package/dist/__tests__/views/use-site-preview.render.test.js +0 -120
- package/dist/__tests__/views/use-site-preview.render.test.js.map +0 -1
- package/dist/views/page-editor/PagePreview.d.ts +0 -13
- package/dist/views/page-editor/PagePreview.d.ts.map +0 -1
- package/dist/views/page-editor/PagePreview.js +0 -46
- package/dist/views/page-editor/PagePreview.js.map +0 -1
- package/dist/views/page-editor/SitePreviewFrame.d.ts +0 -43
- package/dist/views/page-editor/SitePreviewFrame.d.ts.map +0 -1
- package/dist/views/page-editor/SitePreviewFrame.js +0 -165
- package/dist/views/page-editor/SitePreviewFrame.js.map +0 -1
- package/dist/views/page-editor/useSitePreview.d.ts +0 -47
- package/dist/views/page-editor/useSitePreview.d.ts.map +0 -1
- package/dist/views/page-editor/useSitePreview.js +0 -96
- package/dist/views/page-editor/useSitePreview.js.map +0 -1
- package/dist/views/post-editor/PostPreview.d.ts +0 -14
- package/dist/views/post-editor/PostPreview.d.ts.map +0 -1
- package/dist/views/post-editor/PostPreview.js +0 -63
- package/dist/views/post-editor/PostPreview.js.map +0 -1
- package/src/__tests__/views/use-site-preview.render.test.tsx +0 -164
- package/src/views/page-editor/PagePreview.tsx +0 -105
- package/src/views/page-editor/SitePreviewFrame.tsx +0 -250
- package/src/views/page-editor/useSitePreview.ts +0 -158
- package/src/views/post-editor/PostPreview.tsx +0 -125
|
@@ -20,20 +20,16 @@ import {
|
|
|
20
20
|
savePostDraft,
|
|
21
21
|
toggleSectionVisibility,
|
|
22
22
|
updateSectionContent,
|
|
23
|
-
updateSectionContentAtPath,
|
|
24
23
|
updateSectionMeta,
|
|
25
24
|
validatePost,
|
|
26
25
|
type EditorPost,
|
|
27
26
|
type PostHeaderConfig,
|
|
28
27
|
type ValidationResult,
|
|
29
28
|
} from '../../lib/post-editor-service.js'
|
|
30
|
-
import {
|
|
29
|
+
import { SharePreviewLinkDialog } from '../../components/SharePreviewLinkDialog.js'
|
|
31
30
|
import { defaultPostHeader } from '@prenta/core/page-sections'
|
|
32
|
-
import {
|
|
33
|
-
|
|
34
|
-
buildPublicUrl,
|
|
35
|
-
createPreviewToken,
|
|
36
|
-
} from '../../lib/preview-link.js'
|
|
31
|
+
import { openPublicSiteTab } from '../../lib/open-public-site-tab.js'
|
|
32
|
+
import type { ViewSiteIntent } from '../../lib/view-site-chrome.js'
|
|
37
33
|
import { usePublicSiteUrl } from '../../hooks/usePublicSiteUrl.js'
|
|
38
34
|
import {
|
|
39
35
|
hasCanvasRenderer,
|
|
@@ -42,17 +38,14 @@ import {
|
|
|
42
38
|
} from '../page-editor/sections/index.js'
|
|
43
39
|
import { DEFAULT_VIEWPORT, type ViewportId } from '../page-editor/viewports.js'
|
|
44
40
|
import { EditorTopBar, type SaveState } from '../page-editor/EditorTopBar.js'
|
|
45
|
-
import { SitePreviewFrame } from '../page-editor/SitePreviewFrame.js'
|
|
46
|
-
import { useSitePreview } from '../page-editor/useSitePreview.js'
|
|
47
41
|
import { SectionsList } from '../page-editor/SectionsPanel.js'
|
|
48
42
|
import { SectionEditForm } from '../page-editor/SectionEditForm.js'
|
|
49
43
|
import { ValidationSummary } from '../page-editor/ValidationSummary.js'
|
|
50
|
-
import { resolveDefaultSitePreview } from '../../lib/editor-preview.js'
|
|
51
44
|
import { buildEditorContentHtml, computeLiveSeoScore } from '../../lib/editor-seo-content.js'
|
|
52
45
|
import { snapshotBaseline, type ReflowBaseline } from '../../lib/reflow-baseline.js'
|
|
53
46
|
import { ReflowContext } from '../page-editor/reflow-context.js'
|
|
54
47
|
import type { Zoom } from '../../lib/breakpoints.js'
|
|
55
|
-
import {
|
|
48
|
+
import { inspectorIdFromFieldPath } from '../../lib/preview-bridge.js'
|
|
56
49
|
import { PostEditorCanvas } from './PostEditorCanvas.js'
|
|
57
50
|
import { PostFieldsModal, type PostFieldConfig } from './PostFieldsModal.js'
|
|
58
51
|
|
|
@@ -68,7 +61,6 @@ interface EditorConfig {
|
|
|
68
61
|
| undefined
|
|
69
62
|
>
|
|
70
63
|
seo?: { siteUrl?: string }
|
|
71
|
-
admin?: { editor?: { defaultSitePreview?: boolean | { pages?: boolean; posts?: boolean } } }
|
|
72
64
|
}
|
|
73
65
|
|
|
74
66
|
/** The slice of the admin session this editor reads. */
|
|
@@ -83,12 +75,6 @@ interface PostSectionEditorProps {
|
|
|
83
75
|
config?: EditorConfig
|
|
84
76
|
session?: EditorSession
|
|
85
77
|
onNavigate: (path: string) => void
|
|
86
|
-
/**
|
|
87
|
-
* Open a preview route in a new browser tab. `prepare` runs before the tab
|
|
88
|
-
* navigates (used to save an unsaved draft first); returning `false` cancels
|
|
89
|
-
* the open. Falls back to in-tab navigation when not provided.
|
|
90
|
-
*/
|
|
91
|
-
onOpenPreview?: (path: string, prepare?: () => Promise<boolean | void> | boolean | void) => void
|
|
92
78
|
}
|
|
93
79
|
|
|
94
80
|
function deriveCan(session: EditorSession | undefined): {
|
|
@@ -111,7 +97,6 @@ export function PostSectionEditor({
|
|
|
111
97
|
config,
|
|
112
98
|
session,
|
|
113
99
|
onNavigate,
|
|
114
|
-
onOpenPreview,
|
|
115
100
|
}: PostSectionEditorProps) {
|
|
116
101
|
const [post, setPost] = useState<EditorPost | null>(null)
|
|
117
102
|
const [header, setHeader] = useState<PostHeaderConfig>(defaultPostHeader())
|
|
@@ -121,13 +106,6 @@ export function PostSectionEditor({
|
|
|
121
106
|
const [selectedId, setSelectedId] = useState<string | null>(null)
|
|
122
107
|
/** Canvas field click — focused after the inspector mounts for `selectedId`. */
|
|
123
108
|
const [pendingFocusPath, setPendingFocusPath] = useState<string | null>(null)
|
|
124
|
-
/** Bump to skip the next `prenta-preview:sections` echo after a canvas text edit. */
|
|
125
|
-
const [suppressSectionsEcho, setSuppressSectionsEcho] = useState(0)
|
|
126
|
-
/** Canvas image Replace — opens MediaPickerModal for this field path. */
|
|
127
|
-
const [canvasMediaTarget, setCanvasMediaTarget] = useState<{
|
|
128
|
-
sectionId: string
|
|
129
|
-
fieldPath: string
|
|
130
|
-
} | null>(null)
|
|
131
109
|
const [viewport, setViewport] = useState<ViewportId>(DEFAULT_VIEWPORT)
|
|
132
110
|
const [zoom, setZoom] = useState<Zoom>('fit')
|
|
133
111
|
/** Scale the canvas measured — reported upward so the zoom chip shows a real %. */
|
|
@@ -151,6 +129,7 @@ export function PostSectionEditor({
|
|
|
151
129
|
const [historyOpen, setHistoryOpen] = useState(false)
|
|
152
130
|
const [confirmPublish, setConfirmPublish] = useState(false)
|
|
153
131
|
const [scheduleOpen, setScheduleOpen] = useState(false)
|
|
132
|
+
const [shareOpen, setShareOpen] = useState(false)
|
|
154
133
|
const [leaveTarget, setLeaveTarget] = useState<string | null>(null)
|
|
155
134
|
const [validation, setValidation] = useState<ValidationResult | null>(null)
|
|
156
135
|
|
|
@@ -170,13 +149,15 @@ export function PostSectionEditor({
|
|
|
170
149
|
|
|
171
150
|
const { canEdit, canPublish } = useMemo(() => deriveCan(session), [session])
|
|
172
151
|
const customRenderers = useAdminSectionRenderers()
|
|
173
|
-
const { siteUrl: publicSiteUrl } = usePublicSiteUrl(config?.seo?.siteUrl)
|
|
152
|
+
const { siteUrl: publicSiteUrl, matchesAdminOrigin } = usePublicSiteUrl(config?.seo?.siteUrl)
|
|
174
153
|
|
|
175
154
|
const typeLabel = useMemo(() => {
|
|
176
155
|
const col = config?.collections?.[postType]
|
|
177
156
|
return col?.labels?.singular ?? postType
|
|
178
157
|
}, [config, postType])
|
|
179
158
|
|
|
159
|
+
const urlPrefix = config?.collections?.[postType]?.urlPrefix ?? postType
|
|
160
|
+
|
|
180
161
|
// A misconfigured post-type collection (missing the fields the editor
|
|
181
162
|
// writes) would silently drop content on save — detect it up front.
|
|
182
163
|
// Memoized to a string/null so the load effect can depend on it without
|
|
@@ -390,21 +371,6 @@ export function PostSectionEditor({
|
|
|
390
371
|
}
|
|
391
372
|
}, [post, documentId, postType, onNavigate])
|
|
392
373
|
|
|
393
|
-
// Inline branded preview — Next builder canvas (same origin as admin).
|
|
394
|
-
// "View on site" still uses publicSiteUrl for the Astro/public apex.
|
|
395
|
-
const sitePreview = useSitePreview({
|
|
396
|
-
collection: postType,
|
|
397
|
-
documentId: post?.id,
|
|
398
|
-
slug: post?.slug,
|
|
399
|
-
urlPrefix: config?.collections?.[postType]?.urlPrefix ?? postType,
|
|
400
|
-
dirty,
|
|
401
|
-
saveState,
|
|
402
|
-
saveDraft: handleSaveDraft,
|
|
403
|
-
defaultActive: resolveDefaultSitePreview(config?.admin?.editor, 'posts'),
|
|
404
|
-
})
|
|
405
|
-
|
|
406
|
-
const sitePreviewAvailable = Boolean(post?.id && post?.slug)
|
|
407
|
-
|
|
408
374
|
const requestPublish = useCallback(() => {
|
|
409
375
|
if (!post) return
|
|
410
376
|
const result = validatePost(post, true)
|
|
@@ -510,32 +476,11 @@ export function PostSectionEditor({
|
|
|
510
476
|
setRailTab('sections')
|
|
511
477
|
setPendingFocusPath(fieldPath ?? null)
|
|
512
478
|
// Toggles, because selection is now disclosure — see the note on the page
|
|
513
|
-
// editor's copy. A `fieldPath` means
|
|
514
|
-
//
|
|
479
|
+
// editor's copy. A `fieldPath` means a canvas field click, which must
|
|
480
|
+
// open rather than toggle.
|
|
515
481
|
setSelectedId((current) => (fieldPath ? id : current === id ? null : id))
|
|
516
482
|
}, [])
|
|
517
483
|
|
|
518
|
-
const handleCanvasEdit = useCallback(
|
|
519
|
-
(edit: { sectionId: string; fieldPath: string; value: string }) => {
|
|
520
|
-
if (!canEdit) return
|
|
521
|
-
setSuppressSectionsEcho((n) => n + 1)
|
|
522
|
-
mutateSections((s) =>
|
|
523
|
-
updateSectionContentAtPath(s, edit.sectionId, edit.fieldPath, edit.value),
|
|
524
|
-
)
|
|
525
|
-
setSelectedId(edit.sectionId)
|
|
526
|
-
},
|
|
527
|
-
[canEdit, mutateSections],
|
|
528
|
-
)
|
|
529
|
-
|
|
530
|
-
const handleCanvasRequestMedia = useCallback(
|
|
531
|
-
(request: { sectionId: string; fieldPath: string }) => {
|
|
532
|
-
if (!canEdit) return
|
|
533
|
-
setSelectedId(request.sectionId)
|
|
534
|
-
setCanvasMediaTarget(request)
|
|
535
|
-
},
|
|
536
|
-
[canEdit],
|
|
537
|
-
)
|
|
538
|
-
|
|
539
484
|
// After a canvas field click, focus the matching inspector input once painted.
|
|
540
485
|
useEffect(() => {
|
|
541
486
|
if (!pendingFocusPath || !selectedId) return
|
|
@@ -555,78 +500,37 @@ export function PostSectionEditor({
|
|
|
555
500
|
[dirty, onNavigate],
|
|
556
501
|
)
|
|
557
502
|
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
503
|
+
const handleViewOnSite = useCallback(
|
|
504
|
+
(intent: ViewSiteIntent) => {
|
|
505
|
+
if (!post?.id || !post.slug) {
|
|
506
|
+
toast.error('Save the post before viewing it on the site')
|
|
507
|
+
return
|
|
508
|
+
}
|
|
509
|
+
void openPublicSiteTab({
|
|
510
|
+
intent,
|
|
511
|
+
siteUrl: publicSiteUrl,
|
|
512
|
+
collection: postType,
|
|
513
|
+
documentId: post.id,
|
|
514
|
+
slug: post.slug,
|
|
515
|
+
urlPrefix,
|
|
516
|
+
data: { path: (post as { path?: string }).path },
|
|
517
|
+
dirty,
|
|
518
|
+
saveDraft: handleSaveDraft,
|
|
519
|
+
}).catch((err) => {
|
|
520
|
+
toast.error(err instanceof Error ? err.message : 'Failed to open the site')
|
|
521
|
+
})
|
|
522
|
+
},
|
|
523
|
+
[post, postType, urlPrefix, dirty, handleSaveDraft, publicSiteUrl],
|
|
524
|
+
)
|
|
572
525
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
return
|
|
579
|
-
}
|
|
580
|
-
// Published → open the LIVE post directly (no preview token, no forced
|
|
581
|
-
// save). Pending edits stay previewable via the eye + globe.
|
|
582
|
-
if (post.status === 'PUBLISHED') {
|
|
583
|
-
window.open(
|
|
584
|
-
buildPublicUrl({
|
|
585
|
-
siteUrl: publicSiteUrl,
|
|
586
|
-
urlPrefix: config?.collections?.[postType]?.urlPrefix ?? postType,
|
|
587
|
-
slug: post.slug,
|
|
588
|
-
data: { path: (post as { path?: string }).path },
|
|
589
|
-
}),
|
|
590
|
-
'_blank',
|
|
591
|
-
'noopener',
|
|
592
|
-
)
|
|
593
|
-
return
|
|
594
|
-
}
|
|
595
|
-
const tab = window.open('about:blank', '_blank')
|
|
596
|
-
if (!tab) {
|
|
597
|
-
toast.error('Enable pop-ups for this site to open the preview in a new tab.')
|
|
598
|
-
return
|
|
526
|
+
const handleShare = useCallback(async () => {
|
|
527
|
+
if (!post?.id) return
|
|
528
|
+
if (dirty) {
|
|
529
|
+
const ok = await handleSaveDraft()
|
|
530
|
+
if (!ok) return
|
|
599
531
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
if (dirty) {
|
|
603
|
-
const ok = await handleSaveDraft()
|
|
604
|
-
if (!ok) {
|
|
605
|
-
tab.close()
|
|
606
|
-
return
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
const { token } = await createPreviewToken(postType, post.id!)
|
|
610
|
-
const urlPrefix = config?.collections?.[postType]?.urlPrefix ?? postType
|
|
611
|
-
const target = buildPublicPreviewUrl({
|
|
612
|
-
siteUrl: publicSiteUrl,
|
|
613
|
-
urlPrefix,
|
|
614
|
-
slug: post.slug,
|
|
615
|
-
data: { path: (post as { path?: string }).path },
|
|
616
|
-
token,
|
|
617
|
-
})
|
|
618
|
-
try {
|
|
619
|
-
tab.opener = null
|
|
620
|
-
} catch {
|
|
621
|
-
/* same-origin guard */
|
|
622
|
-
}
|
|
623
|
-
tab.location.replace(target)
|
|
624
|
-
} catch (err) {
|
|
625
|
-
tab.close()
|
|
626
|
-
toast.error(err instanceof Error ? err.message : 'Failed to open site preview')
|
|
627
|
-
}
|
|
628
|
-
})()
|
|
629
|
-
}, [post, postType, dirty, config, handleSaveDraft, publicSiteUrl])
|
|
532
|
+
setShareOpen(true)
|
|
533
|
+
}, [post, dirty, handleSaveDraft])
|
|
630
534
|
|
|
631
535
|
// ─── Render states ───────────────────────────────────────────────────
|
|
632
536
|
if (loading) {
|
|
@@ -693,16 +597,14 @@ export function PostSectionEditor({
|
|
|
693
597
|
viewport={viewport}
|
|
694
598
|
backLabel="Posts"
|
|
695
599
|
onViewport={setViewport}
|
|
696
|
-
{
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
{}
|
|
700
|
-
: { zoom, canvasScale, onZoom: setZoom })}
|
|
600
|
+
zoom={zoom}
|
|
601
|
+
canvasScale={canvasScale}
|
|
602
|
+
onZoom={setZoom}
|
|
701
603
|
onBack={() => guardedNavigate('/posts')}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
604
|
+
onViewOnSite={post.id && post.slug ? handleViewOnSite : undefined}
|
|
605
|
+
onShare={post.id ? handleShare : undefined}
|
|
606
|
+
hasPublicSiteUrl={Boolean(publicSiteUrl)}
|
|
607
|
+
matchesAdminOrigin={matchesAdminOrigin}
|
|
706
608
|
onHistory={post.id ? () => setHistoryOpen(true) : undefined}
|
|
707
609
|
onOpenSettings={() => setFieldsOpen(true)}
|
|
708
610
|
onOpenSeo={handleToggleSeo}
|
|
@@ -801,34 +703,18 @@ export function PostSectionEditor({
|
|
|
801
703
|
</EditorRail>
|
|
802
704
|
|
|
803
705
|
<div className="flex-1 overflow-hidden">
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
/>
|
|
817
|
-
) : (
|
|
818
|
-
<PostEditorCanvas
|
|
819
|
-
sections={post.sections}
|
|
820
|
-
header={header}
|
|
821
|
-
context={context}
|
|
822
|
-
selectedId={selectedId}
|
|
823
|
-
viewport={viewport}
|
|
824
|
-
zoom={zoom}
|
|
825
|
-
onScaleChange={setCanvasScale}
|
|
826
|
-
onCanvasElement={setCanvasEl}
|
|
827
|
-
onSelect={handleSelectSection}
|
|
828
|
-
structuralTypes={structuralTypes}
|
|
829
|
-
sitePreviewAvailable={sitePreviewAvailable && !sitePreview.active}
|
|
830
|
-
/>
|
|
831
|
-
)}
|
|
706
|
+
<PostEditorCanvas
|
|
707
|
+
sections={post.sections}
|
|
708
|
+
header={header}
|
|
709
|
+
context={context}
|
|
710
|
+
selectedId={selectedId}
|
|
711
|
+
viewport={viewport}
|
|
712
|
+
zoom={zoom}
|
|
713
|
+
onScaleChange={setCanvasScale}
|
|
714
|
+
onCanvasElement={setCanvasEl}
|
|
715
|
+
onSelect={handleSelectSection}
|
|
716
|
+
structuralTypes={structuralTypes}
|
|
717
|
+
/>
|
|
832
718
|
</div>
|
|
833
719
|
</div>
|
|
834
720
|
</ReflowContext.Provider>
|
|
@@ -874,6 +760,19 @@ export function PostSectionEditor({
|
|
|
874
760
|
/>
|
|
875
761
|
)}
|
|
876
762
|
|
|
763
|
+
{post.id && (
|
|
764
|
+
<SharePreviewLinkDialog
|
|
765
|
+
collectionSlug={postType}
|
|
766
|
+
documentId={post.id}
|
|
767
|
+
documentSlug={post.slug}
|
|
768
|
+
documentPath={(post as { path?: string }).path}
|
|
769
|
+
siteUrl={publicSiteUrl}
|
|
770
|
+
urlPrefix={urlPrefix}
|
|
771
|
+
open={shareOpen}
|
|
772
|
+
onClose={() => setShareOpen(false)}
|
|
773
|
+
/>
|
|
774
|
+
)}
|
|
775
|
+
|
|
877
776
|
<ConfirmDialog
|
|
878
777
|
open={leaveTarget !== null}
|
|
879
778
|
onClose={() => setLeaveTarget(null)}
|
|
@@ -889,29 +788,6 @@ export function PostSectionEditor({
|
|
|
889
788
|
cancelLabel="Stay"
|
|
890
789
|
destructive
|
|
891
790
|
/>
|
|
892
|
-
|
|
893
|
-
<MediaPickerModal
|
|
894
|
-
open={canvasMediaTarget !== null}
|
|
895
|
-
onClose={() => setCanvasMediaTarget(null)}
|
|
896
|
-
accept="image/*"
|
|
897
|
-
onSelectItem={(item) => {
|
|
898
|
-
if (!canvasMediaTarget) return
|
|
899
|
-
const { sectionId, fieldPath } = canvasMediaTarget
|
|
900
|
-
const { widthPath, heightPath } = companionDimensionPaths(fieldPath)
|
|
901
|
-
mutateSections((s) => {
|
|
902
|
-
let next = updateSectionContentAtPath(s, sectionId, fieldPath, item.url)
|
|
903
|
-
if (typeof item.width === 'number') {
|
|
904
|
-
next = updateSectionContentAtPath(next, sectionId, widthPath, item.width)
|
|
905
|
-
}
|
|
906
|
-
if (typeof item.height === 'number') {
|
|
907
|
-
next = updateSectionContentAtPath(next, sectionId, heightPath, item.height)
|
|
908
|
-
}
|
|
909
|
-
return next
|
|
910
|
-
})
|
|
911
|
-
setCanvasMediaTarget(null)
|
|
912
|
-
}}
|
|
913
|
-
onSelect={() => setCanvasMediaTarget(null)}
|
|
914
|
-
/>
|
|
915
791
|
</ErrorBoundary>
|
|
916
792
|
)
|
|
917
793
|
}
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
Upload,
|
|
14
14
|
X,
|
|
15
15
|
} from 'lucide-react'
|
|
16
|
+
import { siteUrlMatchesAdminOrigin } from '../../lib/preview-link.js'
|
|
16
17
|
import { MediaPickerModal } from '../../components/MediaPickerModal.js'
|
|
17
18
|
import { SEOConfigPanel } from '../../components/SEOConfigPanel.js'
|
|
18
19
|
import {
|
|
@@ -125,6 +126,26 @@ export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
|
|
|
125
126
|
|
|
126
127
|
<SettingsValidationSummary issues={seo.issues} />
|
|
127
128
|
|
|
129
|
+
{!seo.siteUrl ? (
|
|
130
|
+
<div
|
|
131
|
+
role="status"
|
|
132
|
+
className="border-warning/30 bg-warning/10 text-warning flex items-start gap-2 rounded-lg border p-4 text-sm"
|
|
133
|
+
>
|
|
134
|
+
<AlertTriangle size={16} className="mt-0.5 shrink-0" aria-hidden="true" />
|
|
135
|
+
Set the public site URL in Settings → General. View site and Share stay disabled until it
|
|
136
|
+
is set.
|
|
137
|
+
</div>
|
|
138
|
+
) : siteUrlMatchesAdminOrigin(seo.siteUrl) ? (
|
|
139
|
+
<div
|
|
140
|
+
role="status"
|
|
141
|
+
className="border-warning/30 bg-warning/10 text-warning flex items-start gap-2 rounded-lg border p-4 text-sm"
|
|
142
|
+
>
|
|
143
|
+
<AlertTriangle size={16} className="mt-0.5 shrink-0" aria-hidden="true" />
|
|
144
|
+
This origin is the admin, not the public site. Set the public site URL to the live apex —
|
|
145
|
+
View site and Share stay disabled while it matches this CMS host.
|
|
146
|
+
</div>
|
|
147
|
+
) : null}
|
|
148
|
+
|
|
128
149
|
<MetaDefaultsCard seo={seo} canEdit={canEdit} />
|
|
129
150
|
<OrganizationCard seo={seo} canEdit={canEdit} />
|
|
130
151
|
<SearchEngineVerificationCard seo={seo} canEdit={canEdit} />
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useId } from 'react'
|
|
4
4
|
import { CheckCircle2 } from 'lucide-react'
|
|
5
|
+
import { siteUrlMatchesAdminOrigin } from '../../lib/preview-link.js'
|
|
5
6
|
import { SettingsCard, SettingsSourceBadge } from './components.js'
|
|
6
7
|
import type {
|
|
7
8
|
GeneralSettingsForm,
|
|
@@ -37,6 +38,7 @@ export function SiteInformationCard({
|
|
|
37
38
|
const urlIssue = issues.find((i) => i.field === 'siteUrl')
|
|
38
39
|
const urlEditable = sources.siteUrl?.editable !== false && canEdit
|
|
39
40
|
const urlValid = !urlIssue && form.siteUrl.trim().length > 0
|
|
41
|
+
const urlIsAdminOrigin = siteUrlMatchesAdminOrigin(form.siteUrl)
|
|
40
42
|
|
|
41
43
|
return (
|
|
42
44
|
<SettingsCard title="Site Information" description="Your site's name, tagline, and public URL.">
|
|
@@ -99,6 +101,11 @@ export function SiteInformationCard({
|
|
|
99
101
|
>
|
|
100
102
|
{urlIssue.message}
|
|
101
103
|
</p>
|
|
104
|
+
) : urlIsAdminOrigin ? (
|
|
105
|
+
<p role="status" className="text-warning mt-1 text-sm">
|
|
106
|
+
This origin is the admin, not the public site. Set the public apex (Astro or the live
|
|
107
|
+
Next site), not this CMS host — View site and Share will stay disabled until you do.
|
|
108
|
+
</p>
|
|
102
109
|
) : urlValid ? (
|
|
103
110
|
<p className="text-muted-foreground mt-1 flex items-center gap-1.5 text-sm">
|
|
104
111
|
<CheckCircle2 size={13} className="text-success" aria-hidden="true" />
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-site-preview.render.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/views/use-site-preview.render.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } 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
|
-
/**
|
|
6
|
-
* useSitePreview — drives the inline branded preview (iframe of the public
|
|
7
|
-
* site rendering a draft). Pins: token minted + URL built on activation,
|
|
8
|
-
* unsaved drafts are persisted first (a failed save cancels activation), and
|
|
9
|
-
* the frame reloads (reloadKey bump) after each completed save.
|
|
10
|
-
*/
|
|
11
|
-
const createPreviewToken = vi.fn(async () => ({
|
|
12
|
-
token: 'tok-123',
|
|
13
|
-
expiresAt: '2026-06-19T00:00:00Z',
|
|
14
|
-
}));
|
|
15
|
-
vi.mock('../../lib/preview-link.js', () => ({
|
|
16
|
-
createPreviewToken: (...args) => createPreviewToken(...args),
|
|
17
|
-
buildPublicPreviewUrl: ({ siteUrl, urlPrefix, slug, path, token }) => {
|
|
18
|
-
const p = path === '/' || path === '' ? '/' : path || `${urlPrefix ? `/${urlPrefix}` : ''}/${slug}`;
|
|
19
|
-
return p === '/'
|
|
20
|
-
? `${siteUrl}/?preview=${token}`
|
|
21
|
-
: `${siteUrl}${p.startsWith('/') ? p : `/${p}`}?preview=${token}`;
|
|
22
|
-
},
|
|
23
|
-
resolveSiteUrl: (u) => u ?? 'https://fallback.test',
|
|
24
|
-
}));
|
|
25
|
-
vi.mock('sonner', () => ({
|
|
26
|
-
toast: { error: vi.fn(), success: vi.fn() },
|
|
27
|
-
}));
|
|
28
|
-
const { useSitePreview } = await import('../../views/page-editor/useSitePreview.js');
|
|
29
|
-
const { toast } = await import('sonner');
|
|
30
|
-
function Harness({ documentId = 'doc-1', slug = 'about', dirty = false, saveState = 'idle', saveDraft = vi.fn(async () => true), defaultActive = false, }) {
|
|
31
|
-
const sp = useSitePreview({
|
|
32
|
-
collection: 'pages',
|
|
33
|
-
documentId,
|
|
34
|
-
slug,
|
|
35
|
-
urlPrefix: '',
|
|
36
|
-
// Canvas defaults to window.location.origin (Next builder / CMS host).
|
|
37
|
-
dirty,
|
|
38
|
-
saveState,
|
|
39
|
-
saveDraft,
|
|
40
|
-
defaultActive,
|
|
41
|
-
});
|
|
42
|
-
return (_jsxs("div", { children: [_jsx("button", { type: "button", onClick: sp.toggle, children: "toggle" }), _jsx("output", { "data-testid": "state", children: JSON.stringify({ active: sp.active, url: sp.url, reloadKey: sp.reloadKey }) })] }));
|
|
43
|
-
}
|
|
44
|
-
function state() {
|
|
45
|
-
return JSON.parse(screen.getByTestId('state').textContent ?? '{}');
|
|
46
|
-
}
|
|
47
|
-
beforeEach(() => {
|
|
48
|
-
createPreviewToken.mockClear();
|
|
49
|
-
vi.mocked(toast.error).mockClear();
|
|
50
|
-
});
|
|
51
|
-
describe('useSitePreview', () => {
|
|
52
|
-
it('mints a token and builds the canvas draft URL on activation', async () => {
|
|
53
|
-
render(_jsx(Harness, {}));
|
|
54
|
-
fireEvent.click(screen.getByText('toggle'));
|
|
55
|
-
expect(state().active).toBe(true);
|
|
56
|
-
await waitFor(() => {
|
|
57
|
-
expect(state().url).toBe(`${window.location.origin}/about?preview=tok-123`);
|
|
58
|
-
});
|
|
59
|
-
expect(createPreviewToken).toHaveBeenCalledWith('pages', 'doc-1');
|
|
60
|
-
});
|
|
61
|
-
it('saves a dirty draft before minting; a failed save cancels activation', async () => {
|
|
62
|
-
const saveDraft = vi.fn(async () => false);
|
|
63
|
-
render(_jsx(Harness, { dirty: true, saveDraft: saveDraft }));
|
|
64
|
-
fireEvent.click(screen.getByText('toggle'));
|
|
65
|
-
await waitFor(() => expect(saveDraft).toHaveBeenCalled());
|
|
66
|
-
await waitFor(() => expect(state().active).toBe(false));
|
|
67
|
-
expect(createPreviewToken).not.toHaveBeenCalled();
|
|
68
|
-
});
|
|
69
|
-
it('refuses to activate for unsaved documents', () => {
|
|
70
|
-
render(_jsx(Harness, { documentId: null }));
|
|
71
|
-
fireEvent.click(screen.getByText('toggle'));
|
|
72
|
-
expect(state().active).toBe(false);
|
|
73
|
-
expect(toast.error).toHaveBeenCalled();
|
|
74
|
-
});
|
|
75
|
-
it('toggles back to the canvas on second click', async () => {
|
|
76
|
-
render(_jsx(Harness, {}));
|
|
77
|
-
fireEvent.click(screen.getByText('toggle'));
|
|
78
|
-
await waitFor(() => expect(state().url).not.toBeNull());
|
|
79
|
-
fireEvent.click(screen.getByText('toggle'));
|
|
80
|
-
expect(state().active).toBe(false);
|
|
81
|
-
});
|
|
82
|
-
it('auto-activates when defaultActive is true', async () => {
|
|
83
|
-
render(_jsx(Harness, { defaultActive: true }));
|
|
84
|
-
await waitFor(() => {
|
|
85
|
-
expect(state().active).toBe(true);
|
|
86
|
-
expect(state().url).toBe(`${window.location.origin}/about?preview=tok-123`);
|
|
87
|
-
});
|
|
88
|
-
expect(createPreviewToken).toHaveBeenCalledWith('pages', 'doc-1');
|
|
89
|
-
});
|
|
90
|
-
it('honors an explicit canvasUrl override', async () => {
|
|
91
|
-
function CanvasHarness() {
|
|
92
|
-
const sp = useSitePreview({
|
|
93
|
-
collection: 'pages',
|
|
94
|
-
documentId: 'doc-1',
|
|
95
|
-
slug: 'about',
|
|
96
|
-
urlPrefix: '',
|
|
97
|
-
canvasUrl: 'https://cms.test',
|
|
98
|
-
dirty: false,
|
|
99
|
-
saveState: 'idle',
|
|
100
|
-
saveDraft: vi.fn(async () => true),
|
|
101
|
-
});
|
|
102
|
-
return (_jsx("button", { type: "button", onClick: sp.toggle, children: sp.url ?? 'none' }));
|
|
103
|
-
}
|
|
104
|
-
render(_jsx(CanvasHarness, {}));
|
|
105
|
-
fireEvent.click(screen.getByRole('button'));
|
|
106
|
-
await waitFor(() => {
|
|
107
|
-
expect(screen.getByRole('button').textContent).toBe('https://cms.test/about?preview=tok-123');
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
it('bumps reloadKey after a save completes while the preview is open', async () => {
|
|
111
|
-
const { rerender } = render(_jsx(Harness, { saveState: "idle" }));
|
|
112
|
-
fireEvent.click(screen.getByText('toggle'));
|
|
113
|
-
await waitFor(() => expect(state().url).not.toBeNull());
|
|
114
|
-
expect(state().reloadKey).toBe(0);
|
|
115
|
-
rerender(_jsx(Harness, { saveState: "saving" }));
|
|
116
|
-
rerender(_jsx(Harness, { saveState: "saved" }));
|
|
117
|
-
await waitFor(() => expect(state().reloadKey).toBe(1));
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
//# sourceMappingURL=use-site-preview.render.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-site-preview.render.test.js","sourceRoot":"","sources":["../../../src/__tests__/views/use-site-preview.render.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
interface PagePreviewProps {
|
|
2
|
-
documentId: string;
|
|
3
|
-
onNavigate: (path: string) => void;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Clean, chrome-free render of a page using the SAME section renderers as
|
|
7
|
-
* the editor canvas — so the preview reflects what will actually ship.
|
|
8
|
-
* Only visible sections are rendered (hidden sections are omitted, exactly
|
|
9
|
-
* as the public page would behave).
|
|
10
|
-
*/
|
|
11
|
-
export declare function PagePreview({ documentId, onNavigate }: PagePreviewProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
-
export {};
|
|
13
|
-
//# sourceMappingURL=PagePreview.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PagePreview.d.ts","sourceRoot":"","sources":["../../../src/views/page-editor/PagePreview.tsx"],"names":[],"mappings":"AAOA,UAAU,gBAAgB;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,gBAAgB,2CAsFvE"}
|