@griddo/ax 11.11.8-rc.1 → 11.12.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/config/jest/componentsMock.js +5 -7
- package/package.json +2 -2
- package/src/__tests__/components/Browser/Browser.test.tsx +87 -438
- package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +3 -1
- package/src/__tests__/components/Fields/Button/Button.test.tsx +27 -29
- package/src/__tests__/components/ResizePanel/ResizePanel.test.tsx +1 -1
- package/src/components/Browser/index.tsx +149 -294
- package/src/components/Browser/style.tsx +6 -75
- package/src/components/Button/index.tsx +1 -2
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +4 -2
- package/src/components/Fields/AsyncSelect/style.tsx +0 -13
- package/src/components/Fields/FieldGroup/index.tsx +2 -5
- package/src/components/Fields/FieldGroup/style.tsx +7 -32
- package/src/components/Fields/HeadingField/index.tsx +2 -2
- package/src/components/Fields/HiddenField/style.tsx +1 -1
- package/src/components/Fields/NumberField/index.tsx +16 -15
- package/src/components/Fields/NumberField/style.tsx +0 -2
- package/src/components/Fields/ReferenceField/index.tsx +1 -1
- package/src/components/Fields/Select/index.tsx +1 -5
- package/src/components/Fields/Select/style.tsx +0 -56
- package/src/components/Fields/SummaryButton/index.tsx +9 -18
- package/src/components/Fields/SummaryButton/style.tsx +2 -1
- package/src/components/Fields/TagsField/index.tsx +9 -8
- package/src/components/Fields/UrlField/index.tsx +27 -26
- package/src/components/Fields/index.tsx +0 -2
- package/src/components/FloatingPanel/index.tsx +2 -5
- package/src/components/FloatingPanel/style.tsx +1 -2
- package/src/components/IconAction/index.tsx +1 -1
- package/src/components/MainWrapper/AppBar/index.tsx +1 -8
- package/src/components/MainWrapper/index.tsx +1 -7
- package/src/components/Notification/index.tsx +2 -2
- package/src/components/PageFinder/index.tsx +1 -1
- package/src/components/ResizePanel/index.tsx +3 -4
- package/src/components/ResizePanel/style.tsx +1 -1
- package/src/components/SearchField/style.tsx +2 -2
- package/src/components/SideModal/index.tsx +1 -2
- package/src/components/Tabs/index.tsx +4 -13
- package/src/components/Tabs/style.tsx +8 -7
- package/src/components/Toast/index.tsx +2 -4
- package/src/components/Tooltip/index.tsx +3 -4
- package/src/components/index.tsx +0 -8
- package/src/forms/fields.tsx +68 -70
- package/src/hooks/forms.tsx +1 -22
- package/src/hooks/index.tsx +3 -13
- package/src/hooks/modals.tsx +15 -103
- package/src/hooks/users.tsx +8 -25
- package/src/modules/Forms/atoms.tsx +2 -2
- package/src/modules/FramePreview/index.tsx +16 -55
- package/src/modules/FramePreview/style.tsx +2 -34
- package/src/modules/GlobalEditor/Editor/index.tsx +3 -37
- package/src/modules/GlobalEditor/PageBrowser/index.tsx +2 -19
- package/src/modules/GlobalEditor/Preview/index.tsx +2 -0
- package/src/modules/GlobalEditor/Preview/style.tsx +1 -1
- package/src/modules/GlobalEditor/index.tsx +57 -119
- package/src/modules/PageEditor/Editor/index.tsx +2 -33
- package/src/modules/PageEditor/PageBrowser/index.tsx +2 -20
- package/src/modules/PageEditor/Preview/index.tsx +2 -0
- package/src/modules/PageEditor/Preview/style.tsx +1 -1
- package/src/modules/PageEditor/atoms.tsx +1 -1
- package/src/modules/PageEditor/index.tsx +66 -130
- package/src/modules/PublicPreview/index.tsx +2 -5
- package/src/schemas/pages/GlobalPage.ts +70 -87
- package/src/schemas/pages/Page.ts +70 -87
- package/src/types/index.tsx +0 -12
- package/src/__tests__/components/Browser/Browser.utils.test.ts +0 -55
- package/src/__tests__/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/ErrorItem.test.tsx +0 -158
- package/src/__tests__/components/HeadingsPreviewModal/ErrorsBanner/ErrorsBanner.test.tsx +0 -90
- package/src/__tests__/components/HeadingsPreviewModal/HeadingsPreviewModal.test.tsx +0 -178
- package/src/__tests__/components/HeadingsPreviewModal/HeadingsPreviewModal.utils.test.tsx +0 -150
- package/src/__tests__/components/KeywordsPreviewModal/KeywordItem/KeywordItem.test.tsx +0 -91
- package/src/__tests__/components/KeywordsPreviewModal/KeywordsPreviewModal.test.tsx +0 -122
- package/src/__tests__/components/KeywordsPreviewModal/KeywordsPreviewModal.utils.test.ts +0 -15
- package/src/__tests__/components/KeywordsPreviewModal/atoms.test.tsx +0 -101
- package/src/__tests__/modules/FramePreview/FramePreview.test.tsx +0 -318
- package/src/__tests__/modules/FramePreview/FramePreview.utils.test.ts +0 -242
- package/src/__tests__/modules/FramePreview/HeadingsOverlay/HeadingsOverlay.test.tsx +0 -185
- package/src/components/Browser/utils.tsx +0 -13
- package/src/components/Fields/SEOPreview/index.tsx +0 -36
- package/src/components/Fields/SEOPreview/style.tsx +0 -24
- package/src/components/FloatingNote/index.tsx +0 -35
- package/src/components/FloatingNote/style.tsx +0 -26
- package/src/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/index.tsx +0 -85
- package/src/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/style.tsx +0 -80
- package/src/components/HeadingsPreviewModal/ErrorsBanner/index.tsx +0 -57
- package/src/components/HeadingsPreviewModal/ErrorsBanner/style.tsx +0 -82
- package/src/components/HeadingsPreviewModal/HeadingItem/index.tsx +0 -71
- package/src/components/HeadingsPreviewModal/HeadingItem/style.tsx +0 -77
- package/src/components/HeadingsPreviewModal/index.tsx +0 -146
- package/src/components/HeadingsPreviewModal/style.tsx +0 -82
- package/src/components/HeadingsPreviewModal/utils.tsx +0 -257
- package/src/components/KeywordsPreviewModal/KeywordItem/index.tsx +0 -46
- package/src/components/KeywordsPreviewModal/KeywordItem/style.tsx +0 -64
- package/src/components/KeywordsPreviewModal/atoms.tsx +0 -96
- package/src/components/KeywordsPreviewModal/index.tsx +0 -99
- package/src/components/KeywordsPreviewModal/style.tsx +0 -87
- package/src/components/KeywordsPreviewModal/utils.tsx +0 -22
- package/src/modules/FramePreview/HeadingsOverlay/index.tsx +0 -113
- package/src/modules/FramePreview/HeadingsOverlay/style.tsx +0 -24
- package/src/modules/FramePreview/utils.tsx +0 -140
|
@@ -2,7 +2,7 @@ import { connect } from "react-redux";
|
|
|
2
2
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
3
3
|
|
|
4
4
|
import { Browser } from "@ax/components";
|
|
5
|
-
import type {
|
|
5
|
+
import type { ILanguage, IRootState, ISite, ISocialState } from "@ax/types";
|
|
6
6
|
|
|
7
7
|
const PageBrowser = (props: IProps) => {
|
|
8
8
|
const {
|
|
@@ -16,16 +16,10 @@ const PageBrowser = (props: IProps) => {
|
|
|
16
16
|
isReadOnly,
|
|
17
17
|
isPreview,
|
|
18
18
|
browserRef,
|
|
19
|
-
isHeadingsPreviewOpen = false,
|
|
20
|
-
isKeywordsPreviewOpen = false,
|
|
21
|
-
headingsFilter,
|
|
22
|
-
keywordsFilter,
|
|
23
19
|
deleteModule,
|
|
24
20
|
duplicateModule,
|
|
25
21
|
copyModule,
|
|
26
22
|
setScrollEditorID,
|
|
27
|
-
toggleHeadingsPreview,
|
|
28
|
-
toggleKeywordsPreview,
|
|
29
23
|
} = props;
|
|
30
24
|
|
|
31
25
|
if (!currentSiteInfo) {
|
|
@@ -37,8 +31,7 @@ const PageBrowser = (props: IProps) => {
|
|
|
37
31
|
const slugWithSlash = slug ? (slug.startsWith("/") ? slug : `/${slug}`) : "";
|
|
38
32
|
const pathWithoutSlash = path ? (path.endsWith("/") ? path.slice(0, -1) : path) : "";
|
|
39
33
|
const url = `${pathWithoutSlash}${slugWithSlash}`;
|
|
40
|
-
const disabled = isTemplateActivated === false || isReadOnly
|
|
41
|
-
const editorType = isHeadingsPreviewOpen ? "headings" : isKeywordsPreviewOpen ? "keywords" : "page";
|
|
34
|
+
const disabled = isTemplateActivated === false || isReadOnly;
|
|
42
35
|
|
|
43
36
|
const actions = {
|
|
44
37
|
deleteModuleAction: deleteModule,
|
|
@@ -65,11 +58,6 @@ const PageBrowser = (props: IProps) => {
|
|
|
65
58
|
showIframe={true}
|
|
66
59
|
browserRef={browserRef}
|
|
67
60
|
actions={actions}
|
|
68
|
-
editorType={editorType}
|
|
69
|
-
toggleHeadingsPreview={toggleHeadingsPreview}
|
|
70
|
-
toggleKeywordsPreview={toggleKeywordsPreview}
|
|
71
|
-
headingFilter={headingsFilter}
|
|
72
|
-
keywordsFilter={keywordsFilter}
|
|
73
61
|
/>
|
|
74
62
|
);
|
|
75
63
|
};
|
|
@@ -90,16 +78,10 @@ interface IPageBrowserDispatchProps {
|
|
|
90
78
|
isReadOnly: boolean;
|
|
91
79
|
isPreview?: boolean;
|
|
92
80
|
browserRef?: any;
|
|
93
|
-
isHeadingsPreviewOpen?: boolean;
|
|
94
|
-
isKeywordsPreviewOpen?: boolean;
|
|
95
|
-
headingsFilter?: HeadingFilter;
|
|
96
|
-
keywordsFilter?: string[];
|
|
97
81
|
deleteModule(editorID: number[]): void;
|
|
98
82
|
duplicateModule(editorID: number[]): number;
|
|
99
83
|
copyModule(editorID: number[]): number | boolean;
|
|
100
84
|
setScrollEditorID(editorID: number | null): void;
|
|
101
|
-
toggleHeadingsPreview?(): void;
|
|
102
|
-
toggleKeywordsPreview?(): void;
|
|
103
85
|
}
|
|
104
86
|
|
|
105
87
|
type IProps = IPageBrowserStateProps & IPageBrowserDispatchProps;
|
|
@@ -7,8 +7,6 @@ import {
|
|
|
7
7
|
CancelScheduleModal,
|
|
8
8
|
ErrorPage,
|
|
9
9
|
ErrorToast,
|
|
10
|
-
HeadingsPreviewModal,
|
|
11
|
-
KeywordsPreviewModal,
|
|
12
10
|
Loading,
|
|
13
11
|
MainWrapper,
|
|
14
12
|
Modal,
|
|
@@ -24,9 +22,8 @@ import { pageStatus } from "@ax/containers/PageEditor/interfaces";
|
|
|
24
22
|
import { dataPacksActions } from "@ax/containers/Settings/DataPacks";
|
|
25
23
|
import { RouteLeavingGuard } from "@ax/guards";
|
|
26
24
|
import { dateToString, getDeactivatedModules, isModuleDisabled } from "@ax/helpers";
|
|
27
|
-
import { useIsDirty,
|
|
25
|
+
import { useIsDirty, useModal, usePermission } from "@ax/hooks";
|
|
28
26
|
import type {
|
|
29
|
-
HeadingFilter,
|
|
30
27
|
IErrorItem,
|
|
31
28
|
ILanguage,
|
|
32
29
|
INotification,
|
|
@@ -73,18 +70,15 @@ const PageEditor = (props: IProps) => {
|
|
|
73
70
|
setCurrentPageID,
|
|
74
71
|
restorePage,
|
|
75
72
|
schemaVersion,
|
|
76
|
-
updateEditorContent,
|
|
77
73
|
} = props;
|
|
78
74
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
editContentPages: "content.editContentPages",
|
|
85
|
-
});
|
|
75
|
+
const isAllowedToPublishPages = usePermission("content.publishUnpublishPages");
|
|
76
|
+
const isAllowedToCreatePages = usePermission("content.createPages");
|
|
77
|
+
const isAllowedToDeletePage = usePermission("content.deletePages");
|
|
78
|
+
const isAllowedToDeletePublishedPage = usePermission("content.deletePublishedPages");
|
|
79
|
+
const isAllowedToEditContentPage = usePermission("content.editContentPages");
|
|
86
80
|
|
|
87
|
-
const defaultTab =
|
|
81
|
+
const defaultTab = isAllowedToEditContentPage ? "edit" : "view";
|
|
88
82
|
|
|
89
83
|
const [deleteAllVersions, setDeleteAllVersions] = useState(false);
|
|
90
84
|
const [isReadOnly, setIsReadOnly] = useState(false);
|
|
@@ -92,26 +86,18 @@ const PageEditor = (props: IProps) => {
|
|
|
92
86
|
const [notification, setNotification] = useState<INotification | null>(null);
|
|
93
87
|
const [toastMsg, setToastMsg] = useState<string | null>(null);
|
|
94
88
|
const [scheduleDate, setScheduleDate] = useState({ date: dateToString(new Date(), "yyy/MM/dd"), time: "12:00 am" });
|
|
89
|
+
const { isDirty, setIsDirty, resetDirty } = useIsDirty(editorContent, isNewTranslation);
|
|
90
|
+
const { isOpen, toggleModal } = useModal();
|
|
91
|
+
const { isOpen: isUnpublishOpen, toggleModal: toggleUnpublishModal } = useModal();
|
|
92
|
+
const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();
|
|
93
|
+
const { isOpen: isScheduleOpen, toggleModal: toggleScheduleModal } = useModal();
|
|
94
|
+
const { isOpen: isCancelScheduleOpen, toggleModal: toggleCancelScheduleModal } = useModal();
|
|
95
|
+
const { isOpen: isRestoreOpen, toggleModal: toggleRestoreModal } = useModal();
|
|
96
|
+
const { isOpen: isDirtyNavigateOpen, toggleModal: toggleDirtyNavigateModal } = useModal();
|
|
95
97
|
const [pendingNavigateCallback, setPendingNavigateCallback] = useState<(() => void) | null>(null);
|
|
96
98
|
const [errorPagesChecked, setErrorPagesChecked] = useState(false);
|
|
97
|
-
const [headingsFilter, setHeadingsFilter] = useState<HeadingFilter>("all");
|
|
98
|
-
const [keywordsFilter, setKeywordsFilter] = useState<string[]>([]);
|
|
99
99
|
const browserRef = useRef<HTMLDivElement>(null);
|
|
100
100
|
|
|
101
|
-
const { isOpen, toggleModal } = useModals([
|
|
102
|
-
"userEditing",
|
|
103
|
-
"unpublish",
|
|
104
|
-
"delete",
|
|
105
|
-
"schedule",
|
|
106
|
-
"cancelSchedule",
|
|
107
|
-
"restore",
|
|
108
|
-
"headingsPreview",
|
|
109
|
-
"keywordsPreview",
|
|
110
|
-
"dirtyNavigate",
|
|
111
|
-
]);
|
|
112
|
-
|
|
113
|
-
const { isDirty, setIsDirty, resetDirty } = useIsDirty(editorContent, isNewTranslation);
|
|
114
|
-
|
|
115
101
|
const isGlobal = editorContent && editorContent.origin === "GLOBAL";
|
|
116
102
|
const isEditable = editorContent?.editable;
|
|
117
103
|
const isPublished = props.pageStatus === pageStatus.PUBLISHED || props.pageStatus === pageStatus.UPLOAD_PENDING;
|
|
@@ -121,13 +107,11 @@ const PageEditor = (props: IProps) => {
|
|
|
121
107
|
const isTranslated = pageLanguages.length > 1;
|
|
122
108
|
const structuredData = editorContent ? editorContent.structuredData : "";
|
|
123
109
|
const isEditLive = isPublished && hasDraft;
|
|
124
|
-
const isAllowedToDelete =
|
|
125
|
-
(isPublished && isAllowedTo.deletePublishedPages) || (!isPublished && isAllowedTo.deletePages);
|
|
110
|
+
const isAllowedToDelete = (isPublished && isAllowedToDeletePublishedPage) || (!isPublished && isAllowedToDeletePage);
|
|
126
111
|
const canBeUnpublished = editorContent?.canBeUnpublished;
|
|
127
112
|
const deleteHelpText = !canBeUnpublished ? "This is the canonical site of the page. You cannot unpublish it." : null;
|
|
128
113
|
const isScheduled = !!editorContent && !!editorContent.publicationScheduled;
|
|
129
114
|
const isDeleted = editorContent.deleted;
|
|
130
|
-
const defaultContentTab = "content";
|
|
131
115
|
|
|
132
116
|
const errorNotificationText =
|
|
133
117
|
"There are some errors on the page so you can not publish yet. Please review them in the error panel.";
|
|
@@ -142,13 +126,13 @@ const PageEditor = (props: IProps) => {
|
|
|
142
126
|
|
|
143
127
|
// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
|
|
144
128
|
useEffect(() => {
|
|
145
|
-
const { pageID, getPage, sendPagePing } = props;
|
|
146
|
-
|
|
129
|
+
const { pageID, getPage, setTab, sendPagePing } = props;
|
|
130
|
+
const defaultTab = "content";
|
|
147
131
|
const handleGetPage = async () => {
|
|
148
132
|
await getPage(pageID);
|
|
149
133
|
};
|
|
150
134
|
|
|
151
|
-
setTab(
|
|
135
|
+
setTab(defaultTab);
|
|
152
136
|
resetDirty();
|
|
153
137
|
setToastMsg(null);
|
|
154
138
|
handleGetPage();
|
|
@@ -168,11 +152,11 @@ const PageEditor = (props: IProps) => {
|
|
|
168
152
|
const { pageID, sendPagePing, currentUserID } = props;
|
|
169
153
|
if (userEditing && userEditing.id !== currentUserID) {
|
|
170
154
|
setIsReadOnly(true);
|
|
171
|
-
!isOpen
|
|
155
|
+
!isOpen && toggleModal();
|
|
172
156
|
} else {
|
|
173
157
|
setIsReadOnly(false);
|
|
174
158
|
pageID && sendPagePing(pageID);
|
|
175
|
-
isOpen
|
|
159
|
+
isOpen && toggleModal();
|
|
176
160
|
}
|
|
177
161
|
}, [userEditing]);
|
|
178
162
|
|
|
@@ -195,7 +179,7 @@ const PageEditor = (props: IProps) => {
|
|
|
195
179
|
const allPageVersions = pageLanguages.map((lang: IPageLanguage) => lang.pageId);
|
|
196
180
|
const isDeleted = deleteAllVersions ? await deleteBulk(allPageVersions) : await deletePage();
|
|
197
181
|
|
|
198
|
-
|
|
182
|
+
toggleDeleteModal();
|
|
199
183
|
if (isDeleted) {
|
|
200
184
|
setRoute(path);
|
|
201
185
|
}
|
|
@@ -281,7 +265,7 @@ const PageEditor = (props: IProps) => {
|
|
|
281
265
|
discardDraft();
|
|
282
266
|
};
|
|
283
267
|
|
|
284
|
-
const
|
|
268
|
+
const handleDiscarChanges = () => {
|
|
285
269
|
const { getPage, pageID } = props;
|
|
286
270
|
resetDirty();
|
|
287
271
|
|
|
@@ -301,7 +285,7 @@ const PageEditor = (props: IProps) => {
|
|
|
301
285
|
const saved = await schedulePublication(dateString, isDraft);
|
|
302
286
|
if (saved) {
|
|
303
287
|
resetDirty();
|
|
304
|
-
|
|
288
|
+
toggleScheduleModal();
|
|
305
289
|
}
|
|
306
290
|
};
|
|
307
291
|
|
|
@@ -310,7 +294,7 @@ const PageEditor = (props: IProps) => {
|
|
|
310
294
|
if (saved) {
|
|
311
295
|
setScheduleDate({ date: "", time: "12:00 am" });
|
|
312
296
|
resetDirty();
|
|
313
|
-
|
|
297
|
+
toggleCancelScheduleModal();
|
|
314
298
|
}
|
|
315
299
|
};
|
|
316
300
|
|
|
@@ -331,7 +315,7 @@ const PageEditor = (props: IProps) => {
|
|
|
331
315
|
}
|
|
332
316
|
: {
|
|
333
317
|
label: status === pageStatus.UPLOAD_PENDING ? "Cancel publication" : "Unpublish",
|
|
334
|
-
action: hasDraft ?
|
|
318
|
+
action: hasDraft ? toggleUnpublishModal : unpublishPage,
|
|
335
319
|
disabled: !canBeUnpublished,
|
|
336
320
|
helpText: deleteHelpText,
|
|
337
321
|
};
|
|
@@ -348,24 +332,24 @@ const PageEditor = (props: IProps) => {
|
|
|
348
332
|
|
|
349
333
|
const menuOptions = [];
|
|
350
334
|
|
|
351
|
-
if (
|
|
335
|
+
if (isAllowedToPublishPages && !isScheduled && !isPublished && props.pageStatus !== pageStatus.OFFLINE_PENDING) {
|
|
352
336
|
menuOptions.push({
|
|
353
337
|
label: "Schedule",
|
|
354
338
|
icon: "calendar",
|
|
355
|
-
action:
|
|
339
|
+
action: toggleScheduleModal,
|
|
356
340
|
});
|
|
357
341
|
}
|
|
358
342
|
|
|
359
|
-
if (
|
|
343
|
+
if (isAllowedToPublishPages && isScheduled) {
|
|
360
344
|
menuOptions.push({
|
|
361
345
|
label: "Cancel Schedule",
|
|
362
346
|
icon: "cancelEvent",
|
|
363
|
-
action:
|
|
347
|
+
action: toggleCancelScheduleModal,
|
|
364
348
|
});
|
|
365
349
|
}
|
|
366
350
|
|
|
367
351
|
if (
|
|
368
|
-
|
|
352
|
+
isAllowedToEditContentPage &&
|
|
369
353
|
(props.pageStatus === pageStatus.PUBLISHED ||
|
|
370
354
|
props.pageStatus === pageStatus.OFFLINE ||
|
|
371
355
|
props.pageStatus === pageStatus.OFFLINE_PENDING ||
|
|
@@ -379,19 +363,19 @@ const PageEditor = (props: IProps) => {
|
|
|
379
363
|
});
|
|
380
364
|
}
|
|
381
365
|
|
|
382
|
-
if (props.pageStatus === pageStatus.PUBLISHED && !hasDraft && isDirty &&
|
|
366
|
+
if (props.pageStatus === pageStatus.PUBLISHED && !hasDraft && isDirty && isAllowedToPublishPages) {
|
|
383
367
|
menuOptions.push({
|
|
384
368
|
label: "Unpublish",
|
|
385
369
|
icon: "offline",
|
|
386
|
-
action: isDraft ?
|
|
370
|
+
action: isDraft ? toggleUnpublishModal : unpublishPage,
|
|
387
371
|
});
|
|
388
372
|
}
|
|
389
373
|
|
|
390
|
-
if (
|
|
374
|
+
if (isAllowedToEditContentPage && !isScheduled && (isDraft || (isPublished && isDirty))) {
|
|
391
375
|
menuOptions.push({
|
|
392
376
|
label: "Discard changes",
|
|
393
377
|
icon: "close",
|
|
394
|
-
action: isDraft ? handleDiscardDraft :
|
|
378
|
+
action: isDraft ? handleDiscardDraft : handleDiscarChanges,
|
|
395
379
|
});
|
|
396
380
|
}
|
|
397
381
|
|
|
@@ -399,13 +383,13 @@ const PageEditor = (props: IProps) => {
|
|
|
399
383
|
menuOptions.push({
|
|
400
384
|
label: "Delete page",
|
|
401
385
|
icon: "delete",
|
|
402
|
-
action:
|
|
386
|
+
action: toggleDeleteModal,
|
|
403
387
|
});
|
|
404
388
|
}
|
|
405
389
|
|
|
406
390
|
const downArrowMenu = {
|
|
407
391
|
displayed: !isReadOnly && !isDeleted,
|
|
408
|
-
button:
|
|
392
|
+
button: isAllowedToPublishPages ? getPublishButton(props.pageStatus) : undefined,
|
|
409
393
|
options: !isGlobal ? menuOptions : [],
|
|
410
394
|
};
|
|
411
395
|
|
|
@@ -453,7 +437,7 @@ const PageEditor = (props: IProps) => {
|
|
|
453
437
|
}
|
|
454
438
|
|
|
455
439
|
let availableLanguages = siteLanguages;
|
|
456
|
-
if (!isTemplateActivated || hasDeactivatedModules || !
|
|
440
|
+
if (!isTemplateActivated || hasDeactivatedModules || !isAllowedToCreatePages || isDeleted) {
|
|
457
441
|
const pageLanguagesIDs = pageLanguages.map((language) => language.languageId);
|
|
458
442
|
availableLanguages = siteLanguages.filter((language) => {
|
|
459
443
|
return pageLanguagesIDs.includes(language.id);
|
|
@@ -478,7 +462,7 @@ const PageEditor = (props: IProps) => {
|
|
|
478
462
|
}
|
|
479
463
|
};
|
|
480
464
|
|
|
481
|
-
const rightButtonProps =
|
|
465
|
+
const rightButtonProps = isAllowedToEditContentPage
|
|
482
466
|
? {
|
|
483
467
|
label: isSaving ? "Saving" : getSaveLabel(),
|
|
484
468
|
disabled:
|
|
@@ -555,33 +539,33 @@ const PageEditor = (props: IProps) => {
|
|
|
555
539
|
props.setHistoryPush(backLinkRoute, false);
|
|
556
540
|
};
|
|
557
541
|
|
|
558
|
-
const mainAction = { title: "Preview Page", onClick:
|
|
542
|
+
const mainAction = { title: "Preview Page", onClick: toggleModal };
|
|
559
543
|
const secondaryAction = { title: "Ok, go back", onClick: handleGoBack };
|
|
560
544
|
|
|
561
|
-
const mainUnpublishAction = { title: "Ok", onClick:
|
|
545
|
+
const mainUnpublishAction = { title: "Ok", onClick: toggleUnpublishModal };
|
|
562
546
|
|
|
563
547
|
const mainDeleteModalAction = {
|
|
564
548
|
title: "Delete page",
|
|
565
549
|
onClick: removePage,
|
|
566
550
|
};
|
|
567
551
|
|
|
568
|
-
const secondaryDeleteModalAction = { title: "Cancel", onClick:
|
|
552
|
+
const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleDeleteModal };
|
|
569
553
|
|
|
570
554
|
const mainScheduleModalAction = {
|
|
571
555
|
title: "Schedule",
|
|
572
556
|
onClick: handleSchedulePublication,
|
|
573
557
|
};
|
|
574
558
|
|
|
575
|
-
const secondaryScheduleModalAction = { title: "Cancel", onClick:
|
|
559
|
+
const secondaryScheduleModalAction = { title: "Cancel", onClick: toggleScheduleModal };
|
|
576
560
|
|
|
577
561
|
const mainCancelScheduleModalAction = {
|
|
578
562
|
title: "Cancel Schedule",
|
|
579
563
|
onClick: handleCancelSchedulePublication,
|
|
580
564
|
};
|
|
581
565
|
|
|
582
|
-
const secondaryCancelScheduleModalAction = { title: "Back", onClick:
|
|
566
|
+
const secondaryCancelScheduleModalAction = { title: "Back", onClick: toggleCancelScheduleModal };
|
|
583
567
|
|
|
584
|
-
const tabIcons =
|
|
568
|
+
const tabIcons = isAllowedToEditContentPage
|
|
585
569
|
? [
|
|
586
570
|
{ name: "edit", text: "Edit mode" },
|
|
587
571
|
{ name: "view", text: "Preview mode" },
|
|
@@ -599,7 +583,6 @@ const PageEditor = (props: IProps) => {
|
|
|
599
583
|
icons: tabIcons,
|
|
600
584
|
selectedTab,
|
|
601
585
|
action: (tab: string) => handleSelectedTab(tab),
|
|
602
|
-
disabled: isOpen("headingsPreview") || isOpen("keywordsPreview"),
|
|
603
586
|
};
|
|
604
587
|
|
|
605
588
|
const contentLanguages: ILanguage[] = [];
|
|
@@ -627,7 +610,7 @@ const PageEditor = (props: IProps) => {
|
|
|
627
610
|
await getPage(selectedPageLanguage.pageId, false, isDraft);
|
|
628
611
|
resetDirty();
|
|
629
612
|
} else {
|
|
630
|
-
|
|
613
|
+
isAllowedToEditContentPage && setSelectedTab("edit");
|
|
631
614
|
createNewTranslation(true);
|
|
632
615
|
await getPage(pageID);
|
|
633
616
|
}
|
|
@@ -636,40 +619,18 @@ const PageEditor = (props: IProps) => {
|
|
|
636
619
|
const handleRestorePage = async () => {
|
|
637
620
|
const isRestored = await restorePage(pageID);
|
|
638
621
|
if (isRestored) {
|
|
639
|
-
|
|
622
|
+
isRestoreOpen && toggleRestoreModal();
|
|
640
623
|
await getPage(pageID);
|
|
641
624
|
}
|
|
642
625
|
};
|
|
643
626
|
|
|
644
|
-
const handleAddKeywords = (newKeywords: string[]) => {
|
|
645
|
-
const keywords: string[] = [...editorContent.metaKeywords, ...newKeywords];
|
|
646
|
-
updateEditorContent(0, "metaKeywords", keywords);
|
|
647
|
-
handleSavePage();
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
const handledeleteKeyword = (keyword: string) => {
|
|
651
|
-
const newKeywords = (editorContent.metaKeywords as string[]).filter((key) => key !== keyword);
|
|
652
|
-
updateEditorContent(0, "metaKeywords", newKeywords);
|
|
653
|
-
handleSavePage();
|
|
654
|
-
};
|
|
655
|
-
|
|
656
|
-
const handleToggleHeadingsEditor = () => {
|
|
657
|
-
toggleModal("headingsPreview");
|
|
658
|
-
setTab(defaultContentTab);
|
|
659
|
-
};
|
|
660
|
-
|
|
661
|
-
const handleToggleKeywordsEditor = () => {
|
|
662
|
-
toggleModal("keywordsPreview");
|
|
663
|
-
setTab(defaultContentTab);
|
|
664
|
-
};
|
|
665
|
-
|
|
666
627
|
const onNavigateWithDirty = (navigateCallback: () => void) => {
|
|
667
628
|
setPendingNavigateCallback(() => navigateCallback);
|
|
668
|
-
|
|
629
|
+
toggleDirtyNavigateModal();
|
|
669
630
|
};
|
|
670
631
|
|
|
671
632
|
const handleConfirmDirtyNavigation = () => {
|
|
672
|
-
|
|
633
|
+
toggleDirtyNavigateModal();
|
|
673
634
|
if (pendingNavigateCallback) {
|
|
674
635
|
pendingNavigateCallback();
|
|
675
636
|
setPendingNavigateCallback(null);
|
|
@@ -677,7 +638,7 @@ const PageEditor = (props: IProps) => {
|
|
|
677
638
|
};
|
|
678
639
|
|
|
679
640
|
const handleCancelDirtyNavigation = () => {
|
|
680
|
-
|
|
641
|
+
toggleDirtyNavigateModal();
|
|
681
642
|
setPendingNavigateCallback(null);
|
|
682
643
|
};
|
|
683
644
|
|
|
@@ -743,7 +704,7 @@ const PageEditor = (props: IProps) => {
|
|
|
743
704
|
type="error"
|
|
744
705
|
text={deletedNotificationText}
|
|
745
706
|
btnText="Restore page"
|
|
746
|
-
onClick={
|
|
707
|
+
onClick={toggleRestoreModal}
|
|
747
708
|
/>
|
|
748
709
|
</S.NotificationWrapper>
|
|
749
710
|
)}
|
|
@@ -775,12 +736,6 @@ const PageEditor = (props: IProps) => {
|
|
|
775
736
|
setNotification={setNotification}
|
|
776
737
|
isEditLive={isEditLive}
|
|
777
738
|
isDisabled={isDeleted}
|
|
778
|
-
toggleHeadingsPreview={handleToggleHeadingsEditor}
|
|
779
|
-
isHeadingsPreviewOpen={isOpen("headingsPreview")}
|
|
780
|
-
headingsFilter={headingsFilter}
|
|
781
|
-
toggleKeywordsPreview={handleToggleKeywordsEditor}
|
|
782
|
-
isKeywordsPreviewOpen={isOpen("keywordsPreview")}
|
|
783
|
-
keywordsFilter={keywordsFilter}
|
|
784
739
|
isDirty={isDirty}
|
|
785
740
|
onNavigateWithDirty={onNavigateWithDirty}
|
|
786
741
|
/>
|
|
@@ -794,14 +749,14 @@ const PageEditor = (props: IProps) => {
|
|
|
794
749
|
)}
|
|
795
750
|
|
|
796
751
|
<Modal
|
|
797
|
-
isOpen={isOpen
|
|
798
|
-
hide={
|
|
752
|
+
isOpen={isOpen}
|
|
753
|
+
hide={toggleModal}
|
|
799
754
|
size="S"
|
|
800
755
|
title="This page is currently being edited"
|
|
801
756
|
mainAction={mainAction}
|
|
802
757
|
secondaryAction={secondaryAction}
|
|
803
758
|
>
|
|
804
|
-
{isOpen
|
|
759
|
+
{isOpen && (
|
|
805
760
|
<S.ModalContent>
|
|
806
761
|
<p>
|
|
807
762
|
<strong>{userEditing?.name}</strong> is currently working on this page. You can preview the page but{" "}
|
|
@@ -811,13 +766,13 @@ const PageEditor = (props: IProps) => {
|
|
|
811
766
|
)}
|
|
812
767
|
</Modal>
|
|
813
768
|
<Modal
|
|
814
|
-
isOpen={
|
|
815
|
-
hide={
|
|
769
|
+
isOpen={isUnpublishOpen}
|
|
770
|
+
hide={toggleUnpublishModal}
|
|
816
771
|
size="S"
|
|
817
772
|
title="Unpublish Modified Page"
|
|
818
773
|
mainAction={mainUnpublishAction}
|
|
819
774
|
>
|
|
820
|
-
{
|
|
775
|
+
{isUnpublishOpen && (
|
|
821
776
|
<S.ModalContent>
|
|
822
777
|
<p>
|
|
823
778
|
There are some saved changes that are not published on this page. To Unpublish this page,{" "}
|
|
@@ -827,54 +782,37 @@ const PageEditor = (props: IProps) => {
|
|
|
827
782
|
)}
|
|
828
783
|
</Modal>
|
|
829
784
|
<DeleteModal
|
|
830
|
-
isOpen={
|
|
831
|
-
toggleModal={
|
|
785
|
+
isOpen={isDeleteOpen}
|
|
786
|
+
toggleModal={toggleDeleteModal}
|
|
832
787
|
mainModalAction={mainDeleteModalAction}
|
|
833
788
|
secondaryModalAction={secondaryDeleteModalAction}
|
|
834
789
|
{...{ isTranslated, deleteAllVersions, setDeleteAllVersions }}
|
|
835
790
|
/>
|
|
836
791
|
<ScheduleModal
|
|
837
|
-
isOpen={
|
|
838
|
-
toggleModal={
|
|
792
|
+
isOpen={isScheduleOpen}
|
|
793
|
+
toggleModal={toggleScheduleModal}
|
|
839
794
|
mainModalAction={mainScheduleModalAction}
|
|
840
795
|
secondaryModalAction={secondaryScheduleModalAction}
|
|
841
796
|
scheduleDate={scheduleDate}
|
|
842
797
|
setScheduleDate={setScheduleDate}
|
|
843
798
|
/>
|
|
844
799
|
<CancelScheduleModal
|
|
845
|
-
isOpen={
|
|
846
|
-
toggleModal={
|
|
800
|
+
isOpen={isCancelScheduleOpen}
|
|
801
|
+
toggleModal={toggleCancelScheduleModal}
|
|
847
802
|
mainModalAction={mainCancelScheduleModalAction}
|
|
848
803
|
secondaryModalAction={secondaryCancelScheduleModalAction}
|
|
849
804
|
/>
|
|
850
805
|
<RestoreModal
|
|
851
|
-
isOpen={
|
|
852
|
-
toggleModal={
|
|
806
|
+
isOpen={isRestoreOpen}
|
|
807
|
+
toggleModal={toggleRestoreModal}
|
|
853
808
|
{...{
|
|
854
809
|
isChild: false,
|
|
855
810
|
hasIssues: schemaVersion !== editorContent.schemaVersionTimestamp,
|
|
856
811
|
restorePage: handleRestorePage,
|
|
857
812
|
}}
|
|
858
813
|
/>
|
|
859
|
-
<HeadingsPreviewModal
|
|
860
|
-
isOpen={isOpen("headingsPreview")}
|
|
861
|
-
toggleModal={handleToggleHeadingsEditor}
|
|
862
|
-
browserRef={browserRef}
|
|
863
|
-
headingsFilter={headingsFilter}
|
|
864
|
-
setHeadingsFilter={setHeadingsFilter}
|
|
865
|
-
/>
|
|
866
|
-
<KeywordsPreviewModal
|
|
867
|
-
isOpen={isOpen("keywordsPreview")}
|
|
868
|
-
toggleModal={handleToggleKeywordsEditor}
|
|
869
|
-
browserRef={browserRef}
|
|
870
|
-
keywords={editorContent?.metaKeywords || []}
|
|
871
|
-
keywordsFilter={keywordsFilter}
|
|
872
|
-
setKeywordsFilter={setKeywordsFilter}
|
|
873
|
-
addKeywords={handleAddKeywords}
|
|
874
|
-
deleteKeyword={handledeleteKeyword}
|
|
875
|
-
/>
|
|
876
814
|
<Modal
|
|
877
|
-
isOpen={
|
|
815
|
+
isOpen={isDirtyNavigateOpen}
|
|
878
816
|
hide={handleCancelDirtyNavigation}
|
|
879
817
|
size="S"
|
|
880
818
|
title="Unsaved changes"
|
|
@@ -957,7 +895,6 @@ const mapDispatchToProps = {
|
|
|
957
895
|
schedulePublication: pageEditorActions.schedulePublication,
|
|
958
896
|
setCurrentPageID: pageEditorActions.setCurrentPageID,
|
|
959
897
|
restorePage: pageEditorActions.restorePage,
|
|
960
|
-
updateEditorContent: pageEditorActions.updateEditorContent,
|
|
961
898
|
};
|
|
962
899
|
|
|
963
900
|
interface IPageEditorDispatchProps {
|
|
@@ -985,7 +922,6 @@ interface IPageEditorDispatchProps {
|
|
|
985
922
|
schedulePublication(date: string | null, isDraft: boolean): Promise<boolean>;
|
|
986
923
|
setCurrentPageID: (currentPageID: number | null) => void;
|
|
987
924
|
restorePage(id: number | number[]): Promise<boolean>;
|
|
988
|
-
updateEditorContent(selectedEditorID: number, key: string, value: any): void;
|
|
989
925
|
}
|
|
990
926
|
|
|
991
927
|
type IProps = IPageEditorStateProps & IPageEditorDispatchProps & RouteComponentProps;
|
|
@@ -67,12 +67,9 @@ const PublicPreview = () => {
|
|
|
67
67
|
|
|
68
68
|
if (isLoading || !state) return <Loading />;
|
|
69
69
|
|
|
70
|
-
const setBrowserRef = (ref: any) => {
|
|
71
|
-
(window as any).browserRef = ref;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
70
|
return (
|
|
75
|
-
|
|
71
|
+
// biome-ignore lint/suspicious/noAssignInExpressions: TODO: fix this
|
|
72
|
+
<S.Wrapper ref={(ref: any) => ((window as any).browserRef = ref)}>
|
|
76
73
|
<BrowserContent
|
|
77
74
|
cloudinaryName={state?.cloudinaryName}
|
|
78
75
|
theme={theme}
|