@griddo/ax 11.7.13 → 11.8.0-rc.1
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/package.json +3 -2
- package/src/GlobalStore.tsx +3 -0
- package/src/api/index.tsx +4 -0
- package/src/api/logs.tsx +97 -0
- package/src/api/navigation.tsx +1 -1
- package/src/api/pages.tsx +1 -1
- package/src/api/schemas.tsx +18 -0
- package/src/api/users.tsx +17 -0
- package/src/components/ConfigPanel/Form/ConnectedField/NavConnectedField/index.tsx +3 -2
- package/src/components/ConfigPanel/Form/index.tsx +3 -1
- package/src/components/ConfigPanel/index.tsx +3 -0
- package/src/components/Fields/SummaryButton/index.tsx +6 -4
- package/src/components/Fields/TimeField/style.tsx +0 -1
- package/src/components/Fields/TranslateButton/index.tsx +3 -0
- package/src/components/FloatingMenu/index.tsx +25 -1
- package/src/components/FloatingMenu/style.tsx +3 -2
- package/src/components/LanguageMenu/index.tsx +1 -1
- package/src/components/MainWrapper/AppBar/index.tsx +4 -3
- package/src/components/RestoreModal/index.tsx +51 -0
- package/src/components/RestoreModal/style.tsx +7 -0
- package/src/components/SearchField/index.tsx +1 -1
- package/src/components/SearchField/style.tsx +4 -4
- package/src/components/TableFilters/CheckGroupFilter/index.tsx +42 -5
- package/src/components/TableFilters/CheckGroupFilter/style.tsx +8 -1
- package/src/components/TableFilters/SiteFilter/index.tsx +26 -57
- package/src/components/Tag/index.tsx +6 -3
- package/src/components/Tag/style.tsx +2 -2
- package/src/components/index.tsx +2 -0
- package/src/containers/ActivityLog/actions.tsx +262 -0
- package/src/containers/ActivityLog/constants.tsx +6 -0
- package/src/containers/ActivityLog/index.tsx +4 -0
- package/src/containers/ActivityLog/interfaces.tsx +12 -0
- package/src/containers/ActivityLog/reducer.tsx +25 -0
- package/src/containers/Navigation/Defaults/actions.tsx +4 -3
- package/src/containers/StructuredData/actions.tsx +7 -4
- package/src/containers/StructuredData/interfaces.tsx +2 -8
- package/src/containers/StructuredData/reducer.tsx +2 -8
- package/src/containers/Users/actions.tsx +22 -19
- package/src/modules/ActivityLog/DetailModal/index.tsx +108 -0
- package/src/modules/ActivityLog/DetailModal/style.tsx +52 -0
- package/src/modules/ActivityLog/DownloadModal/index.tsx +104 -0
- package/src/modules/ActivityLog/DownloadModal/style.tsx +12 -0
- package/src/modules/ActivityLog/ItemGroup/index.tsx +27 -0
- package/src/modules/ActivityLog/ItemGroup/style.tsx +39 -0
- package/src/modules/ActivityLog/ItemLog/EventItem/index.tsx +167 -0
- package/src/modules/ActivityLog/ItemLog/EventItem/style.tsx +79 -0
- package/src/modules/ActivityLog/ItemLog/index.tsx +24 -0
- package/src/modules/ActivityLog/ItemLogUser/UserItem/EventItem/index.tsx +170 -0
- package/src/modules/ActivityLog/ItemLogUser/UserItem/EventItem/style.tsx +79 -0
- package/src/modules/ActivityLog/ItemLogUser/UserItem/index.tsx +46 -0
- package/src/modules/ActivityLog/ItemLogUser/UserItem/style.tsx +60 -0
- package/src/modules/ActivityLog/ItemLogUser/index.tsx +25 -0
- package/src/modules/ActivityLog/LogFilters/ContentFilter/index.tsx +79 -0
- package/src/modules/ActivityLog/LogFilters/DateFilter/index.tsx +91 -0
- package/src/modules/ActivityLog/LogFilters/DateFilter/style.tsx +208 -0
- package/src/modules/ActivityLog/LogFilters/EventFilter/index.tsx +80 -0
- package/src/modules/ActivityLog/LogFilters/OrderFilter/index.tsx +49 -0
- package/src/modules/ActivityLog/LogFilters/OrderFilter/style.tsx +35 -0
- package/src/modules/ActivityLog/LogFilters/UserFilter/index.tsx +79 -0
- package/src/modules/ActivityLog/TableHeader/index.tsx +72 -0
- package/src/modules/ActivityLog/TableHeader/style.tsx +73 -0
- package/src/modules/ActivityLog/constants.tsx +10 -0
- package/src/modules/ActivityLog/hooks.tsx +53 -0
- package/src/modules/ActivityLog/index.tsx +313 -0
- package/src/modules/ActivityLog/style.tsx +57 -0
- package/src/modules/ActivityLog/utils.tsx +31 -0
- package/src/modules/Categories/CategoriesList/index.tsx +1 -1
- package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/index.tsx +3 -0
- package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/index.tsx +3 -0
- package/src/modules/Forms/FormEditor/Editor/index.tsx +5 -2
- package/src/modules/Forms/FormEditor/index.tsx +20 -3
- package/src/modules/GlobalEditor/Editor/index.tsx +3 -0
- package/src/modules/GlobalEditor/index.tsx +48 -9
- package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +3 -1
- package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/index.tsx +4 -1
- package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +45 -6
- package/src/modules/PageEditor/Editor/index.tsx +4 -1
- package/src/modules/PageEditor/index.tsx +46 -7
- package/src/modules/Redirects/BulkHeader/TableHeader/style.tsx +1 -7
- package/src/modules/StructuredData/Form/index.tsx +56 -7
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +2 -2
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +2 -8
- package/src/modules/StructuredData/StructuredDataList/hooks.tsx +9 -9
- package/src/modules/StructuredData/StructuredDataList/index.tsx +3 -4
- package/src/modules/Users/Roles/index.tsx +0 -2
- package/src/modules/Users/UserEdit/index.tsx +12 -28
- package/src/modules/Users/UserList/BulkHeader/TableHeader/style.tsx +1 -0
- package/src/modules/Users/UserList/UserItem/index.tsx +10 -25
- package/src/modules/Users/UserList/index.tsx +8 -10
- package/src/routes/multisite.tsx +9 -0
- package/src/themes/theme.json +2 -1
- package/src/types/forms.tsx +1 -0
- package/src/types/index.tsx +8 -0
- package/src/types/logs.tsx +12 -0
- package/src/components/TableFilters/SiteFilter/style.tsx +0 -28
|
@@ -49,11 +49,20 @@ const FormEditor = (props: IProps) => {
|
|
|
49
49
|
setSelectedContent,
|
|
50
50
|
} = props;
|
|
51
51
|
|
|
52
|
-
const {
|
|
52
|
+
const {
|
|
53
|
+
id,
|
|
54
|
+
title,
|
|
55
|
+
state,
|
|
56
|
+
dataLanguages,
|
|
57
|
+
formInUse,
|
|
58
|
+
deleted = false,
|
|
59
|
+
} = formContent || { dataLanguages: [], formInUse: null };
|
|
53
60
|
const formStatus = state === "active" ? "active" : "offline";
|
|
54
61
|
const isTranslated = dataLanguages.length > 1;
|
|
55
62
|
const isSiteView = !!currentSiteInfo;
|
|
56
63
|
const errorNotificationText = "There are some errors on the form so you can not publish yet. Please review them.";
|
|
64
|
+
const deletedNotificationText =
|
|
65
|
+
"This form has been deleted and can’t be edited. It will be permanently removed from the trash after 30 days.";
|
|
57
66
|
const isPublishedForm = state === "active";
|
|
58
67
|
|
|
59
68
|
const formLanguages: ILanguage[] = [];
|
|
@@ -64,6 +73,8 @@ const FormEditor = (props: IProps) => {
|
|
|
64
73
|
}
|
|
65
74
|
});
|
|
66
75
|
|
|
76
|
+
const availableLanguages = deleted ? formLanguages : isSiteView ? siteLangs : globalLangs;
|
|
77
|
+
|
|
67
78
|
const [notification, setNotification] = useState<INotification | null>(null);
|
|
68
79
|
const [deleteAllVersions, setDeleteAllVersions] = useState(false);
|
|
69
80
|
const [errors, setErrors] = useState<IErrorItem[]>([]);
|
|
@@ -227,7 +238,7 @@ const FormEditor = (props: IProps) => {
|
|
|
227
238
|
const downArrowMenu = {
|
|
228
239
|
button: isAllowedToPublishForm ? publishButton : undefined,
|
|
229
240
|
options: menuOptions,
|
|
230
|
-
displayed:
|
|
241
|
+
displayed: !deleted,
|
|
231
242
|
};
|
|
232
243
|
|
|
233
244
|
const modalText = (
|
|
@@ -274,7 +285,7 @@ const FormEditor = (props: IProps) => {
|
|
|
274
285
|
pageStatus={formStatus}
|
|
275
286
|
language={lang}
|
|
276
287
|
languageAction={handleLanguage}
|
|
277
|
-
availableLanguages={
|
|
288
|
+
availableLanguages={availableLanguages}
|
|
278
289
|
currentLanguages={formLanguages}
|
|
279
290
|
currentPageID={0}
|
|
280
291
|
fullWidth={true}
|
|
@@ -295,6 +306,11 @@ const FormEditor = (props: IProps) => {
|
|
|
295
306
|
/>
|
|
296
307
|
</S.NotificationWrapper>
|
|
297
308
|
)}
|
|
309
|
+
{deleted && (
|
|
310
|
+
<S.NotificationWrapper>
|
|
311
|
+
<Notification type="error" text={deletedNotificationText} />
|
|
312
|
+
</S.NotificationWrapper>
|
|
313
|
+
)}
|
|
298
314
|
<ErrorToast size="l" fixed />
|
|
299
315
|
<S.Content>
|
|
300
316
|
<Editor
|
|
@@ -304,6 +320,7 @@ const FormEditor = (props: IProps) => {
|
|
|
304
320
|
browserRef={browserRef}
|
|
305
321
|
setNotification={setNotification}
|
|
306
322
|
setErrors={setErrors}
|
|
323
|
+
isDisabled={deleted}
|
|
307
324
|
/>
|
|
308
325
|
</S.Content>
|
|
309
326
|
</MainWrapper>
|
|
@@ -32,6 +32,7 @@ const Editor = (props: IProps) => {
|
|
|
32
32
|
browserRef,
|
|
33
33
|
setNotification,
|
|
34
34
|
isEditLive,
|
|
35
|
+
isDisabled,
|
|
35
36
|
} = props;
|
|
36
37
|
|
|
37
38
|
const actions = {
|
|
@@ -68,6 +69,7 @@ const Editor = (props: IProps) => {
|
|
|
68
69
|
userEditing={userEditing}
|
|
69
70
|
theme={theme}
|
|
70
71
|
isEditLive={isEditLive}
|
|
72
|
+
isDisabled={isDisabled}
|
|
71
73
|
/>
|
|
72
74
|
}
|
|
73
75
|
/>
|
|
@@ -104,6 +106,7 @@ interface IPageBrowserDispatchProps {
|
|
|
104
106
|
theme: string;
|
|
105
107
|
browserRef: any;
|
|
106
108
|
isEditLive: boolean;
|
|
109
|
+
isDisabled: boolean;
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
ErrorPage,
|
|
23
23
|
CancelScheduleModal,
|
|
24
24
|
ScheduleModal,
|
|
25
|
+
RestoreModal,
|
|
25
26
|
} from "@ax/components";
|
|
26
27
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
27
28
|
import { structuredDataActions } from "@ax/containers/StructuredData";
|
|
@@ -64,6 +65,8 @@ const GlobalEditor = (props: IProps) => {
|
|
|
64
65
|
currentSiteErrorPages,
|
|
65
66
|
getUserCurrentPermissions,
|
|
66
67
|
schedulePublication,
|
|
68
|
+
restorePage,
|
|
69
|
+
schemaVersion,
|
|
67
70
|
} = props;
|
|
68
71
|
|
|
69
72
|
const isAllowedToPublishPages = usePermission("global.globalData.publishUnpublishAllGlobalData");
|
|
@@ -83,6 +86,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
83
86
|
const [scheduleDate, setScheduleDate] = useState({ date: dateToString(new Date(), "yyy/MM/dd"), time: "12:00 am" });
|
|
84
87
|
const { isOpen: isScheduleOpen, toggleModal: toggleScheduleModal } = useModal();
|
|
85
88
|
const { isOpen: isCancelScheduleOpen, toggleModal: toggleCancelScheduleModal } = useModal();
|
|
89
|
+
const { isOpen: isRestoreOpen, toggleModal: toggleRestoreModal } = useModal();
|
|
86
90
|
const browserRef = useRef<HTMLDivElement>(null);
|
|
87
91
|
|
|
88
92
|
const isPublished = props.pageStatus === pageStatus.PUBLISHED || props.pageStatus === pageStatus.UPLOAD_PENDING;
|
|
@@ -92,11 +96,21 @@ const GlobalEditor = (props: IProps) => {
|
|
|
92
96
|
const structuredData = editorContent ? editorContent.structuredData : "";
|
|
93
97
|
const isEditLive = isPublished && hasDraft;
|
|
94
98
|
const isScheduled = props.pageStatus === pageStatus.SCHEDULED;
|
|
99
|
+
const isDeleted = editorContent.deleted;
|
|
95
100
|
|
|
96
101
|
const errorNotificationText =
|
|
97
102
|
"There are some errors on the page so you can not publish yet. Please review them in the error panel.";
|
|
98
103
|
const validatedNotificationText = "Everything seems ok, you can publish the page.";
|
|
99
104
|
|
|
105
|
+
const deletedNotificationText =
|
|
106
|
+
"This page has been deleted and can’t be edited. It will be permanently removed from the trash after 30 days.";
|
|
107
|
+
const globalNotificationText = "You’ re working on the Global Page. Make sure you want to make changes to this page.";
|
|
108
|
+
|
|
109
|
+
const modifiedNotificationText =
|
|
110
|
+
"You made some changes to the Live version that aren't implemented on this Draft. Check it out before you continue working.";
|
|
111
|
+
|
|
112
|
+
const backLinkRoute = "/data";
|
|
113
|
+
|
|
100
114
|
const theme = getDefaultTheme();
|
|
101
115
|
|
|
102
116
|
useEffect(() => {
|
|
@@ -359,7 +373,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
359
373
|
}
|
|
360
374
|
|
|
361
375
|
const downArrowMenu = {
|
|
362
|
-
displayed: !isReadOnly,
|
|
376
|
+
displayed: !isReadOnly && !isDeleted,
|
|
363
377
|
button: isAllowedToPublishPages ? getPublishButton(props.pageStatus) : undefined,
|
|
364
378
|
options: menuOptions,
|
|
365
379
|
};
|
|
@@ -460,13 +474,6 @@ const GlobalEditor = (props: IProps) => {
|
|
|
460
474
|
}
|
|
461
475
|
};
|
|
462
476
|
|
|
463
|
-
const globalNotificationText = "You’ re working on the Global Page. Make sure you want to make changes to this page.";
|
|
464
|
-
|
|
465
|
-
const modifiedNotificationText =
|
|
466
|
-
"You made some changes to the Live version that aren't implemented on this Draft. Check it out before you continue working.";
|
|
467
|
-
|
|
468
|
-
const backLinkRoute = "/data";
|
|
469
|
-
|
|
470
477
|
const handleGoBack = () => {
|
|
471
478
|
props.setHistoryPush(backLinkRoute, false);
|
|
472
479
|
};
|
|
@@ -536,6 +543,14 @@ const GlobalEditor = (props: IProps) => {
|
|
|
536
543
|
}
|
|
537
544
|
};
|
|
538
545
|
|
|
546
|
+
const handleRestorePage = async () => {
|
|
547
|
+
const isRestored = await restorePage(pageID);
|
|
548
|
+
if (isRestored) {
|
|
549
|
+
isRestoreOpen && toggleRestoreModal();
|
|
550
|
+
await getPage(pageID);
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
|
|
539
554
|
return isLoading ? (
|
|
540
555
|
<Loading />
|
|
541
556
|
) : (
|
|
@@ -551,7 +566,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
551
566
|
pageStatus={props.pageStatus}
|
|
552
567
|
language={lang}
|
|
553
568
|
languageAction={handleLanguage}
|
|
554
|
-
availableLanguages={isAllowedToCreatePages ? globalLangs : filteredLanguages}
|
|
569
|
+
availableLanguages={isAllowedToCreatePages && !isDeleted ? globalLangs : filteredLanguages}
|
|
555
570
|
currentLanguages={contentLanguages}
|
|
556
571
|
currentPageID={pageID}
|
|
557
572
|
fullWidth={true}
|
|
@@ -571,6 +586,16 @@ const GlobalEditor = (props: IProps) => {
|
|
|
571
586
|
<Notification type="warning" text={modifiedNotificationText} />
|
|
572
587
|
</S.NotificationWrapper>
|
|
573
588
|
)}
|
|
589
|
+
{isDeleted && (
|
|
590
|
+
<S.NotificationWrapper>
|
|
591
|
+
<Notification
|
|
592
|
+
type="error"
|
|
593
|
+
text={deletedNotificationText}
|
|
594
|
+
btnText="Restore page"
|
|
595
|
+
onClick={toggleRestoreModal}
|
|
596
|
+
/>
|
|
597
|
+
</S.NotificationWrapper>
|
|
598
|
+
)}
|
|
574
599
|
{sitePageID && (
|
|
575
600
|
<S.NotificationWrapper>
|
|
576
601
|
<Notification type="info" text={globalNotificationText} btnText="Go Back" onClick={goBackToSite} />
|
|
@@ -597,6 +622,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
597
622
|
browserRef={browserRef}
|
|
598
623
|
setNotification={setNotification}
|
|
599
624
|
isEditLive={isEditLive}
|
|
625
|
+
isDisabled={isDeleted}
|
|
600
626
|
/>
|
|
601
627
|
</S.Content>
|
|
602
628
|
</>
|
|
@@ -651,6 +677,15 @@ const GlobalEditor = (props: IProps) => {
|
|
|
651
677
|
mainModalAction={mainCancelScheduleModalAction}
|
|
652
678
|
secondaryModalAction={secondaryCancelScheduleModalAction}
|
|
653
679
|
/>
|
|
680
|
+
<RestoreModal
|
|
681
|
+
isOpen={isRestoreOpen}
|
|
682
|
+
toggleModal={toggleRestoreModal}
|
|
683
|
+
{...{
|
|
684
|
+
isChild: false,
|
|
685
|
+
hasIssues: schemaVersion !== editorContent.schemaVersionTimestamp,
|
|
686
|
+
restorePage: handleRestorePage,
|
|
687
|
+
}}
|
|
688
|
+
/>
|
|
654
689
|
</MainWrapper>
|
|
655
690
|
</>
|
|
656
691
|
);
|
|
@@ -674,6 +709,7 @@ const mapStateToProps = (state: IRootState): IPageEditorStateProps => ({
|
|
|
674
709
|
isNewTranslation: state.pageEditor.isNewTranslation,
|
|
675
710
|
currentSiteErrorPages: state.sites.currentSiteErrorPages,
|
|
676
711
|
skipReviewOnPublish: state.app.globalSettings.skipReviewOnPublish,
|
|
712
|
+
schemaVersion: state.structuredData.schemaVersion,
|
|
677
713
|
});
|
|
678
714
|
|
|
679
715
|
interface IPageEditorStateProps {
|
|
@@ -694,6 +730,7 @@ interface IPageEditorStateProps {
|
|
|
694
730
|
isNewTranslation: boolean;
|
|
695
731
|
currentSiteErrorPages: number[];
|
|
696
732
|
skipReviewOnPublish?: boolean;
|
|
733
|
+
schemaVersion: string;
|
|
697
734
|
}
|
|
698
735
|
|
|
699
736
|
const mapDispatchToProps = {
|
|
@@ -714,6 +751,7 @@ const mapDispatchToProps = {
|
|
|
714
751
|
discardDraft: pageEditorActions.discardDraft,
|
|
715
752
|
getUserCurrentPermissions: usersActions.getUserCurrentPermissions,
|
|
716
753
|
schedulePublication: pageEditorActions.schedulePublication,
|
|
754
|
+
restorePage: pageEditorActions.restorePage,
|
|
717
755
|
};
|
|
718
756
|
|
|
719
757
|
interface IPageEditorDispatchProps {
|
|
@@ -734,6 +772,7 @@ interface IPageEditorDispatchProps {
|
|
|
734
772
|
discardDraft(): Promise<void>;
|
|
735
773
|
getUserCurrentPermissions(): Promise<void>;
|
|
736
774
|
schedulePublication(date: string | null, isDraft: boolean): Promise<boolean>;
|
|
775
|
+
restorePage(id: number | number[]): Promise<boolean>;
|
|
737
776
|
}
|
|
738
777
|
|
|
739
778
|
type IProps = IPageEditorStateProps & IPageEditorDispatchProps & RouteComponentProps;
|
|
@@ -6,7 +6,7 @@ import { Browser } from "@ax/components";
|
|
|
6
6
|
import { ILanguage, IRootState, ISite, ISocialState } from "@ax/types";
|
|
7
7
|
|
|
8
8
|
const DefaultsBrowser = (props: IProps) => {
|
|
9
|
-
const { socials, cloudinaryName, content, currentSiteInfo, siteLangs, browserRef, actions } = props;
|
|
9
|
+
const { socials, cloudinaryName, content, currentSiteInfo, siteLangs, browserRef, actions, isDisabled } = props;
|
|
10
10
|
|
|
11
11
|
if (!currentSiteInfo) {
|
|
12
12
|
throw new Error(`ERROR: User reached Page Editor with null site info`);
|
|
@@ -28,6 +28,7 @@ const DefaultsBrowser = (props: IProps) => {
|
|
|
28
28
|
siteLangs={siteLangs}
|
|
29
29
|
siteID={siteID}
|
|
30
30
|
actions={actions}
|
|
31
|
+
disabled={isDisabled}
|
|
31
32
|
/>
|
|
32
33
|
);
|
|
33
34
|
};
|
|
@@ -35,6 +36,7 @@ const DefaultsBrowser = (props: IProps) => {
|
|
|
35
36
|
interface IDefaultsBrowserProps {
|
|
36
37
|
actions: any;
|
|
37
38
|
browserRef?: React.RefObject<HTMLDivElement>;
|
|
39
|
+
isDisabled: boolean;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
interface IDefaultsBrowserStateProps {
|
|
@@ -28,6 +28,7 @@ const Editor = (props: IProps) => {
|
|
|
28
28
|
isLoading,
|
|
29
29
|
site,
|
|
30
30
|
browserRef,
|
|
31
|
+
isDisabled,
|
|
31
32
|
} = props;
|
|
32
33
|
|
|
33
34
|
if (!site) {
|
|
@@ -50,7 +51,7 @@ const Editor = (props: IProps) => {
|
|
|
50
51
|
|
|
51
52
|
return (
|
|
52
53
|
<ResizePanel
|
|
53
|
-
leftPanel={<DefaultsBrowser browserRef={browserRef} actions={actions} />}
|
|
54
|
+
leftPanel={<DefaultsBrowser browserRef={browserRef} actions={actions} isDisabled={isDisabled} />}
|
|
54
55
|
rightPanel={
|
|
55
56
|
<ConfigPanel
|
|
56
57
|
schema={schema}
|
|
@@ -65,6 +66,7 @@ const Editor = (props: IProps) => {
|
|
|
65
66
|
isLoading={isLoading}
|
|
66
67
|
isEditable={true}
|
|
67
68
|
theme={site.theme}
|
|
69
|
+
isDisabled={isDisabled}
|
|
68
70
|
/>
|
|
69
71
|
}
|
|
70
72
|
/>
|
|
@@ -96,6 +98,7 @@ interface IPageBrowserDispatchProps {
|
|
|
96
98
|
pasteModule(editorID: number, key: string, modulesToPaste: IModule[]): Promise<{ error?: INotification }>;
|
|
97
99
|
setNotification: (notification: INotification) => void;
|
|
98
100
|
browserRef?: React.RefObject<HTMLDivElement>;
|
|
101
|
+
isDisabled: boolean;
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -8,7 +8,7 @@ import { RouteLeavingGuard } from "@ax/guards";
|
|
|
8
8
|
|
|
9
9
|
import { appActions } from "@ax/containers/App";
|
|
10
10
|
import { navigationActions, menuActions } from "@ax/containers/Navigation";
|
|
11
|
-
import { ErrorPage, ErrorToast, Loading, MainWrapper, Modal, Notification } from "@ax/components";
|
|
11
|
+
import { ErrorPage, ErrorToast, Loading, MainWrapper, Modal, Notification, RestoreModal } from "@ax/components";
|
|
12
12
|
import Editor from "./Editor";
|
|
13
13
|
|
|
14
14
|
import * as S from "./style";
|
|
@@ -34,13 +34,18 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
34
34
|
setHistoryPush,
|
|
35
35
|
getMenus,
|
|
36
36
|
currentSiteInfo,
|
|
37
|
+
restoreNavigation,
|
|
37
38
|
} = props;
|
|
38
39
|
|
|
39
40
|
const [notification, setNotification] = useState<INotification | null>(null);
|
|
40
41
|
const { isOpen, toggleModal } = useModal();
|
|
42
|
+
const { isOpen: isRestoreOpen, toggleModal: toggleRestoreModal } = useModal();
|
|
41
43
|
const { isDirty, setIsDirty, resetDirty } = useIsDirty(editorContent, isNewTranslation);
|
|
42
44
|
const currentDefaultNav = currentDefaultsContent.find((item: any) => item.setAsDefault);
|
|
43
45
|
const isNew = !editorContent?.id;
|
|
46
|
+
const isDeleted = !!editorContent?.deleted;
|
|
47
|
+
|
|
48
|
+
const deletedNotificationText = `This ${editorContent?.type} has been deleted and can’t be edited. It will be permanently removed from the trash after 30 days.`;
|
|
44
49
|
|
|
45
50
|
const currentLanguages: ILanguage[] = [];
|
|
46
51
|
navLanguages?.forEach((navLang) => {
|
|
@@ -57,7 +62,8 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
57
62
|
const isAllowedToCreateFooters = usePermission("navigation.createSiteFooters") && selectedDefault === "Footers";
|
|
58
63
|
|
|
59
64
|
useEffect(() => {
|
|
60
|
-
getValues();
|
|
65
|
+
const handleGetValues = async () => await getValues();
|
|
66
|
+
handleGetValues();
|
|
61
67
|
if (isNew) {
|
|
62
68
|
setIsDirty(false);
|
|
63
69
|
}
|
|
@@ -133,11 +139,20 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
133
139
|
}
|
|
134
140
|
};
|
|
135
141
|
|
|
142
|
+
const handleRestorePage = async () => {
|
|
143
|
+
const isRestored = await restoreNavigation(editorContent.id, editorContent.type);
|
|
144
|
+
if (isRestored) {
|
|
145
|
+
isRestoreOpen && toggleRestoreModal();
|
|
146
|
+
await getValues();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
136
150
|
const leavingGuardText = (
|
|
137
151
|
<>
|
|
138
152
|
Some content <strong>is not saved</strong> on this page.
|
|
139
153
|
</>
|
|
140
154
|
);
|
|
155
|
+
|
|
141
156
|
const setDefaultModalText = editorContent && (
|
|
142
157
|
<p>{`There is already a ${editorContent.type} defined as default. If you change it to this one, it will be shown on all the pages on this site. Are you sure your want to make this change?`}</p>
|
|
143
158
|
);
|
|
@@ -146,16 +161,19 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
146
161
|
const secondaryModalAction = { title: "Cancel", onClick: toggleModal };
|
|
147
162
|
const goBack = (path: string) => setHistoryPush(path, true);
|
|
148
163
|
|
|
149
|
-
const availableLanguages =
|
|
164
|
+
const availableLanguages =
|
|
165
|
+
(isAllowedToCreateHeaders || isAllowedToCreateFooters) && !isDeleted ? siteLanguages : currentLanguages;
|
|
166
|
+
|
|
167
|
+
const backLinkRoute = "/sites/navigations/modules";
|
|
150
168
|
|
|
151
169
|
return isLoading ? (
|
|
152
170
|
<Loading />
|
|
153
171
|
) : (
|
|
154
172
|
<>
|
|
155
|
-
<RouteLeavingGuard when={isDirty} action={goBack} text={leavingGuardText} />
|
|
173
|
+
<RouteLeavingGuard when={isDirty || isSaving} action={goBack} text={leavingGuardText} />
|
|
156
174
|
<MainWrapper
|
|
157
175
|
title={editorContent.title}
|
|
158
|
-
backLink={
|
|
176
|
+
backLink={backLinkRoute}
|
|
159
177
|
rightButton={rightButtonProps}
|
|
160
178
|
fixedAppBar={true}
|
|
161
179
|
language={lang}
|
|
@@ -175,6 +193,16 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
175
193
|
/>
|
|
176
194
|
</S.NotificationWrapper>
|
|
177
195
|
)}
|
|
196
|
+
{isDeleted && (
|
|
197
|
+
<S.NotificationWrapper>
|
|
198
|
+
<Notification
|
|
199
|
+
type="error"
|
|
200
|
+
text={deletedNotificationText}
|
|
201
|
+
btnText={`Restore ${editorContent?.type}`}
|
|
202
|
+
onClick={toggleRestoreModal}
|
|
203
|
+
/>
|
|
204
|
+
</S.NotificationWrapper>
|
|
205
|
+
)}
|
|
178
206
|
<ErrorToast size="l" />
|
|
179
207
|
<Modal
|
|
180
208
|
isOpen={isOpen}
|
|
@@ -187,8 +215,17 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
187
215
|
{isOpen ? <S.ModalContent>{setDefaultModalText}</S.ModalContent> : null}
|
|
188
216
|
</Modal>
|
|
189
217
|
<S.Content>
|
|
190
|
-
<Editor browserRef={browserRef} setNotification={setNotification} />
|
|
218
|
+
<Editor browserRef={browserRef} setNotification={setNotification} isDisabled={isDeleted} />
|
|
191
219
|
</S.Content>
|
|
220
|
+
<RestoreModal
|
|
221
|
+
isOpen={isRestoreOpen}
|
|
222
|
+
toggleModal={toggleRestoreModal}
|
|
223
|
+
{...{
|
|
224
|
+
isChild: false,
|
|
225
|
+
hasIssues: false,
|
|
226
|
+
restorePage: handleRestorePage,
|
|
227
|
+
}}
|
|
228
|
+
/>
|
|
192
229
|
</MainWrapper>
|
|
193
230
|
</>
|
|
194
231
|
);
|
|
@@ -235,6 +272,7 @@ const mapDispatchToProps = {
|
|
|
235
272
|
setHeader: navigationActions.setHeader,
|
|
236
273
|
setFooter: navigationActions.setFooter,
|
|
237
274
|
getMenus: menuActions.getMenus,
|
|
275
|
+
restoreNavigation: navigationActions.restoreNavigation,
|
|
238
276
|
};
|
|
239
277
|
|
|
240
278
|
interface IDispatchProps {
|
|
@@ -247,6 +285,7 @@ interface IDispatchProps {
|
|
|
247
285
|
setHeader(id: number | null): void;
|
|
248
286
|
setFooter(id: number | null): void;
|
|
249
287
|
getMenus(): Promise<void>;
|
|
288
|
+
restoreNavigation(navID: number | number[], type: string): Promise<boolean>;
|
|
250
289
|
}
|
|
251
290
|
|
|
252
291
|
type IProps = IStateProps & IDispatchProps;
|
|
@@ -43,6 +43,7 @@ const Editor = (props: IProps) => {
|
|
|
43
43
|
restorePageNavigation,
|
|
44
44
|
content,
|
|
45
45
|
isEditLive,
|
|
46
|
+
isDisabled,
|
|
46
47
|
} = props;
|
|
47
48
|
|
|
48
49
|
if (!site) {
|
|
@@ -73,7 +74,7 @@ const Editor = (props: IProps) => {
|
|
|
73
74
|
leftPanel={
|
|
74
75
|
<PageBrowser
|
|
75
76
|
isTemplateActivated={isTemplateActivated}
|
|
76
|
-
isReadOnly={isReadOnly || isEditLive}
|
|
77
|
+
isReadOnly={isReadOnly || isEditLive || isDisabled}
|
|
77
78
|
browserRef={browserRef}
|
|
78
79
|
/>
|
|
79
80
|
}
|
|
@@ -100,6 +101,7 @@ const Editor = (props: IProps) => {
|
|
|
100
101
|
header={header}
|
|
101
102
|
footer={footer}
|
|
102
103
|
isEditLive={isEditLive}
|
|
104
|
+
isDisabled={isDisabled}
|
|
103
105
|
/>
|
|
104
106
|
}
|
|
105
107
|
/>
|
|
@@ -144,6 +146,7 @@ interface IPageBrowserDispatchProps {
|
|
|
144
146
|
isReadOnly: boolean;
|
|
145
147
|
browserRef: any;
|
|
146
148
|
isEditLive: boolean;
|
|
149
|
+
isDisabled: boolean;
|
|
147
150
|
}
|
|
148
151
|
|
|
149
152
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
ErrorPage,
|
|
22
22
|
CancelScheduleModal,
|
|
23
23
|
ScheduleModal,
|
|
24
|
+
RestoreModal,
|
|
24
25
|
} from "@ax/components";
|
|
25
26
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
26
27
|
import { appActions } from "@ax/containers/App";
|
|
@@ -65,6 +66,8 @@ const PageEditor = (props: IProps) => {
|
|
|
65
66
|
currentSiteErrorPages,
|
|
66
67
|
schedulePublication,
|
|
67
68
|
setCurrentPageID,
|
|
69
|
+
restorePage,
|
|
70
|
+
schemaVersion,
|
|
68
71
|
} = props;
|
|
69
72
|
|
|
70
73
|
const isAllowedToPublishPages = usePermission("content.publishUnpublishPages");
|
|
@@ -86,6 +89,7 @@ const PageEditor = (props: IProps) => {
|
|
|
86
89
|
const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();
|
|
87
90
|
const { isOpen: isScheduleOpen, toggleModal: toggleScheduleModal } = useModal();
|
|
88
91
|
const { isOpen: isCancelScheduleOpen, toggleModal: toggleCancelScheduleModal } = useModal();
|
|
92
|
+
const { isOpen: isRestoreOpen, toggleModal: toggleRestoreModal } = useModal();
|
|
89
93
|
const [errorPagesChecked, setErrorPagesChecked] = useState(false);
|
|
90
94
|
const browserRef = useRef<HTMLDivElement>(null);
|
|
91
95
|
|
|
@@ -102,10 +106,18 @@ const PageEditor = (props: IProps) => {
|
|
|
102
106
|
const canBeUnpublished = editorContent && editorContent.canBeUnpublished;
|
|
103
107
|
const deleteHelpText = !canBeUnpublished ? "This is the canonical site of the page. You cannot unpublish it." : null;
|
|
104
108
|
const isScheduled = !!editorContent && !!editorContent.publicationScheduled;
|
|
109
|
+
const isDeleted = editorContent.deleted;
|
|
105
110
|
|
|
106
111
|
const errorNotificationText =
|
|
107
112
|
"There are some errors on the page so you can not publish yet. Please review them in the error panel.";
|
|
108
113
|
const validatedNotificationText = "Everything seems ok, you can publish the page.";
|
|
114
|
+
const modifiedNotificationText =
|
|
115
|
+
"You made some changes to the Live version that aren't implemented on this Draft. Check it out before you continue working.";
|
|
116
|
+
|
|
117
|
+
const deletedNotificationText =
|
|
118
|
+
"This page has been deleted and can’t be edited. It will be permanently removed from the trash after 30 days.";
|
|
119
|
+
|
|
120
|
+
const backLinkRoute = "/sites/pages";
|
|
109
121
|
|
|
110
122
|
useEffect(() => {
|
|
111
123
|
const { pageID, getPage, setTab, sendPagePing } = props;
|
|
@@ -369,7 +381,7 @@ const PageEditor = (props: IProps) => {
|
|
|
369
381
|
}
|
|
370
382
|
|
|
371
383
|
const downArrowMenu = {
|
|
372
|
-
displayed: !isReadOnly,
|
|
384
|
+
displayed: !isReadOnly && !isDeleted,
|
|
373
385
|
button: isAllowedToPublishPages ? getPublishButton(props.pageStatus) : undefined,
|
|
374
386
|
options: !isGlobal ? menuOptions : [],
|
|
375
387
|
};
|
|
@@ -415,7 +427,7 @@ const PageEditor = (props: IProps) => {
|
|
|
415
427
|
}
|
|
416
428
|
|
|
417
429
|
let availableLanguages = siteLanguages;
|
|
418
|
-
if (!isTemplateActivated || hasDeactivatedModules || !isAllowedToCreatePages) {
|
|
430
|
+
if (!isTemplateActivated || hasDeactivatedModules || !isAllowedToCreatePages || isDeleted) {
|
|
419
431
|
const pageLanguagesIDs = pageLanguages.map((language) => language.languageId);
|
|
420
432
|
availableLanguages = siteLanguages.filter((language) => {
|
|
421
433
|
return pageLanguagesIDs.includes(language.id);
|
|
@@ -505,11 +517,6 @@ const PageEditor = (props: IProps) => {
|
|
|
505
517
|
}
|
|
506
518
|
};
|
|
507
519
|
|
|
508
|
-
const modifiedNotificationText =
|
|
509
|
-
"You made some changes to the Live version that aren't implemented on this Draft. Check it out before you continue working.";
|
|
510
|
-
|
|
511
|
-
const backLinkRoute = "/sites/pages";
|
|
512
|
-
|
|
513
520
|
const handleGoBack = () => {
|
|
514
521
|
props.setHistoryPush(backLinkRoute, false);
|
|
515
522
|
};
|
|
@@ -584,6 +591,14 @@ const PageEditor = (props: IProps) => {
|
|
|
584
591
|
}
|
|
585
592
|
};
|
|
586
593
|
|
|
594
|
+
const handleRestorePage = async () => {
|
|
595
|
+
const isRestored = await restorePage(pageID);
|
|
596
|
+
if (isRestored) {
|
|
597
|
+
isRestoreOpen && toggleRestoreModal();
|
|
598
|
+
await getPage(pageID);
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
|
|
587
602
|
return isLoading ? (
|
|
588
603
|
<Loading />
|
|
589
604
|
) : (
|
|
@@ -623,6 +638,16 @@ const PageEditor = (props: IProps) => {
|
|
|
623
638
|
/>
|
|
624
639
|
</S.NotificationWrapper>
|
|
625
640
|
)}
|
|
641
|
+
{isDeleted && (
|
|
642
|
+
<S.NotificationWrapper>
|
|
643
|
+
<Notification
|
|
644
|
+
type="error"
|
|
645
|
+
text={deletedNotificationText}
|
|
646
|
+
btnText="Restore page"
|
|
647
|
+
onClick={toggleRestoreModal}
|
|
648
|
+
/>
|
|
649
|
+
</S.NotificationWrapper>
|
|
650
|
+
)}
|
|
626
651
|
{isLivePageChanged && (
|
|
627
652
|
<S.NotificationWrapper>
|
|
628
653
|
<Notification type="warning" text={modifiedNotificationText} />
|
|
@@ -650,6 +675,7 @@ const PageEditor = (props: IProps) => {
|
|
|
650
675
|
browserRef={browserRef}
|
|
651
676
|
setNotification={setNotification}
|
|
652
677
|
isEditLive={isEditLive}
|
|
678
|
+
isDisabled={isDeleted}
|
|
653
679
|
/>
|
|
654
680
|
</S.Content>
|
|
655
681
|
</>
|
|
@@ -711,6 +737,15 @@ const PageEditor = (props: IProps) => {
|
|
|
711
737
|
mainModalAction={mainCancelScheduleModalAction}
|
|
712
738
|
secondaryModalAction={secondaryCancelScheduleModalAction}
|
|
713
739
|
/>
|
|
740
|
+
<RestoreModal
|
|
741
|
+
isOpen={isRestoreOpen}
|
|
742
|
+
toggleModal={toggleRestoreModal}
|
|
743
|
+
{...{
|
|
744
|
+
isChild: false,
|
|
745
|
+
hasIssues: schemaVersion !== editorContent.schemaVersionTimestamp,
|
|
746
|
+
restorePage: handleRestorePage,
|
|
747
|
+
}}
|
|
748
|
+
/>
|
|
714
749
|
</MainWrapper>
|
|
715
750
|
</>
|
|
716
751
|
);
|
|
@@ -736,6 +771,7 @@ const mapStateToProps = (state: IRootState): IPageEditorStateProps => ({
|
|
|
736
771
|
isNewTranslation: state.pageEditor.isNewTranslation,
|
|
737
772
|
currentSiteErrorPages: state.sites.currentSiteErrorPages,
|
|
738
773
|
skipReviewOnPublish: state.app.globalSettings.skipReviewOnPublish,
|
|
774
|
+
schemaVersion: state.structuredData.schemaVersion,
|
|
739
775
|
});
|
|
740
776
|
|
|
741
777
|
interface IPageEditorStateProps {
|
|
@@ -758,6 +794,7 @@ interface IPageEditorStateProps {
|
|
|
758
794
|
currentSiteErrorPages: number[];
|
|
759
795
|
skipReviewOnPublish?: boolean;
|
|
760
796
|
schema: any;
|
|
797
|
+
schemaVersion: string;
|
|
761
798
|
}
|
|
762
799
|
|
|
763
800
|
const mapDispatchToProps = {
|
|
@@ -779,6 +816,7 @@ const mapDispatchToProps = {
|
|
|
779
816
|
deleteBulk: pageEditorActions.deleteBulk,
|
|
780
817
|
schedulePublication: pageEditorActions.schedulePublication,
|
|
781
818
|
setCurrentPageID: pageEditorActions.setCurrentPageID,
|
|
819
|
+
restorePage: pageEditorActions.restorePage,
|
|
782
820
|
};
|
|
783
821
|
|
|
784
822
|
interface IPageEditorDispatchProps {
|
|
@@ -800,6 +838,7 @@ interface IPageEditorDispatchProps {
|
|
|
800
838
|
deleteBulk(ids: number[]): Promise<boolean>;
|
|
801
839
|
schedulePublication(date: string | null, isDraft: boolean): Promise<boolean>;
|
|
802
840
|
setCurrentPageID: (currentPageID: number | null) => void;
|
|
841
|
+
restorePage(id: number | number[]): Promise<boolean>;
|
|
803
842
|
}
|
|
804
843
|
|
|
805
844
|
type IProps = IPageEditorStateProps & IPageEditorDispatchProps & RouteComponentProps;
|