@griddo/ax 1.62.6 → 1.63.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/package.json +6 -5
- package/src/GlobalStore.tsx +1 -1
- package/src/Style/index.tsx +2 -0
- package/src/api/pages.tsx +20 -0
- package/src/api/utils.tsx +5 -2
- package/src/components/Browser/index.tsx +144 -39
- package/src/components/Browser/style.tsx +47 -11
- package/src/components/ConfigPanel/index.tsx +3 -3
- package/src/components/Fields/RichText/index.tsx +2 -2
- package/src/components/Fields/UrlField/utils.tsx +10 -1
- package/src/components/Icon/components/Desktop.js +9 -4
- package/src/components/Icon/components/Phone.js +4 -4
- package/src/components/Icon/components/Share.js +12 -0
- package/src/components/Icon/components/Tablet.js +4 -4
- package/src/components/Icon/svgs/Share.svg +3 -0
- package/src/components/MainWrapper/AppBar/index.tsx +19 -7
- package/src/components/MainWrapper/AppBar/style.tsx +20 -4
- package/src/components/MainWrapper/index.tsx +1 -1
- package/src/components/SideModal/index.tsx +1 -1
- package/src/components/TableFilters/DateFilter/index.tsx +48 -0
- package/src/components/TableFilters/DateFilter/style.tsx +29 -0
- package/src/components/TableFilters/index.tsx +2 -0
- package/src/components/Tabs/index.tsx +17 -7
- package/src/components/Tabs/style.tsx +29 -16
- package/src/components/Tooltip/index.tsx +1 -1
- package/src/components/Tooltip/style.tsx +2 -0
- package/src/components/index.tsx +2 -0
- package/src/containers/App/reducer.tsx +3 -1
- package/src/containers/Navigation/Defaults/actions.tsx +2 -1
- package/src/containers/PageEditor/actions.tsx +65 -10
- package/src/containers/Settings/DataPacks/actions.tsx +4 -1
- package/src/containers/Sites/actions.tsx +3 -1
- package/src/helpers/dates.tsx +3 -4
- package/src/helpers/index.tsx +2 -0
- package/src/helpers/strings.tsx +38 -7
- package/src/hooks/forms.tsx +1 -2
- package/src/index.tsx +2 -2
- package/src/modules/Content/OptionTable/index.tsx +29 -2
- package/src/modules/Content/PageItem/index.tsx +11 -2
- package/src/modules/Content/index.tsx +9 -0
- package/src/modules/GlobalEditor/Editor/index.tsx +7 -9
- package/src/modules/GlobalEditor/{Editor/PageBrowser → PageBrowser}/index.tsx +14 -6
- package/src/modules/GlobalEditor/Preview/index.tsx +19 -0
- package/src/modules/GlobalEditor/Preview/style.tsx +9 -0
- package/src/modules/GlobalEditor/index.tsx +41 -9
- package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +5 -1
- package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +9 -7
- package/src/modules/PageEditor/Editor/index.tsx +5 -5
- package/src/modules/PageEditor/{Editor/PageBrowser → PageBrowser}/index.tsx +11 -4
- package/src/modules/PageEditor/Preview/index.tsx +14 -0
- package/src/modules/PageEditor/Preview/style.tsx +9 -0
- package/src/modules/PageEditor/index.tsx +40 -16
- package/src/modules/PublicPreview/index.tsx +92 -0
- package/src/modules/PublicPreview/style.tsx +18 -0
- package/src/modules/Redirects/BulkHeader/TableHeader/index.tsx +16 -3
- package/src/modules/Redirects/BulkHeader/TableHeader/style.tsx +9 -3
- package/src/modules/Redirects/BulkHeader/index.tsx +7 -1
- package/src/modules/Redirects/RedirectItem/index.tsx +4 -0
- package/src/modules/Redirects/RedirectItem/style.tsx +19 -3
- package/src/modules/Redirects/atoms.tsx +0 -1
- package/src/modules/Redirects/hooks.tsx +67 -0
- package/src/modules/Redirects/index.tsx +23 -9
- package/src/modules/Redirects/utils.tsx +10 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/Field/index.tsx +107 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/Field/style.tsx +54 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/index.tsx +66 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/style.tsx +42 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +58 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +41 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/index.tsx +93 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/style.tsx +25 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/index.tsx +48 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/style.tsx +53 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/index.tsx +40 -36
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/style.tsx +4 -5
- package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +4 -4
- package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +5 -1
- package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/atoms.tsx +0 -0
- package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/index.tsx +20 -11
- package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/style.tsx +6 -0
- package/src/modules/Settings/{SeoSettings → SeoAnalyticsSettings}/index.tsx +11 -4
- package/src/routes/publicRoutes.tsx +3 -1
- package/src/routes/site.tsx +14 -10
- package/src/types/index.tsx +9 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React, { useReducer, useEffect, useLayoutEffect } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
|
|
4
|
+
import { IDataPack, IRootState } from "@ax/types";
|
|
4
5
|
import { structuredDataActions } from "@ax/containers/StructuredData";
|
|
5
6
|
import { getStructuredDataTitle, getThumbnailProps, isGlobalStructuredData } from "@ax/helpers";
|
|
7
|
+
import { dataPacksActions } from "@ax/containers/Settings";
|
|
6
8
|
import { MenuItem, RadioGroup } from "@ax/components";
|
|
7
9
|
|
|
8
10
|
import { reducer, IOptionTableStore, setColumnValues, setShowThumbnail, setSelectedType, setOption } from "./store";
|
|
@@ -10,7 +12,17 @@ import { reducer, IOptionTableStore, setColumnValues, setShowThumbnail, setSelec
|
|
|
10
12
|
import * as S from "./style";
|
|
11
13
|
|
|
12
14
|
const OptionTable = (props: IOptionTableProps): JSX.Element => {
|
|
13
|
-
const {
|
|
15
|
+
const {
|
|
16
|
+
selectData,
|
|
17
|
+
selectPage,
|
|
18
|
+
filters,
|
|
19
|
+
values,
|
|
20
|
+
selectedValue,
|
|
21
|
+
setIsStructuredData,
|
|
22
|
+
theme,
|
|
23
|
+
getDataPack,
|
|
24
|
+
dataPacks,
|
|
25
|
+
} = props;
|
|
14
26
|
|
|
15
27
|
const filterOptions = (value: string, objKey: string) => values.filter((item: any) => item[objKey] === value);
|
|
16
28
|
const currentOption = filterOptions(selectedValue, "value");
|
|
@@ -50,6 +62,14 @@ const OptionTable = (props: IOptionTableProps): JSX.Element => {
|
|
|
50
62
|
// eslint-disable-next-line
|
|
51
63
|
}, []);
|
|
52
64
|
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (currentType !== "static") {
|
|
67
|
+
const dataPack = dataPacks.find((pack) => pack.templates.some((template) => template.id === state.selectedOption));
|
|
68
|
+
dataPack && getDataPack(dataPack.id);
|
|
69
|
+
}
|
|
70
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
|
+
}, [state.selectedOption]);
|
|
72
|
+
|
|
53
73
|
const setValue = (value: string, isStructuredData: boolean) => {
|
|
54
74
|
setIsStructuredData(isStructuredData);
|
|
55
75
|
isStructuredData ? selectData(value) : selectPage(value);
|
|
@@ -133,14 +153,21 @@ interface IOptionTableProps {
|
|
|
133
153
|
selectData: (value: string) => void;
|
|
134
154
|
selectPage: (value: string) => void;
|
|
135
155
|
setIsStructuredData: (isActive: boolean) => void;
|
|
156
|
+
getDataPack: (id: string) => void;
|
|
136
157
|
filters: any;
|
|
137
158
|
values: any;
|
|
138
159
|
selectedValue: string;
|
|
139
160
|
theme: string;
|
|
161
|
+
dataPacks: IDataPack[];
|
|
140
162
|
}
|
|
141
163
|
|
|
164
|
+
const mapStateToProps = (state: IRootState) => ({
|
|
165
|
+
dataPacks: state.dataPacks.activated,
|
|
166
|
+
});
|
|
167
|
+
|
|
142
168
|
const mapDispatchToProps = {
|
|
143
169
|
setIsStructuredData: structuredDataActions.setIsActive,
|
|
170
|
+
getDataPack: dataPacksActions.getSiteDataPack,
|
|
144
171
|
};
|
|
145
172
|
|
|
146
|
-
export default connect(
|
|
173
|
+
export default connect(mapStateToProps, mapDispatchToProps)(OptionTable);
|
|
@@ -2,7 +2,7 @@ import React, { memo, useState } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { useModal } from "@ax/hooks";
|
|
4
4
|
import { getHumanLastModifiedDate, getTemplateDisplayName, slugify } from "@ax/helpers";
|
|
5
|
-
import { IPage, ISite, ISavePageParams, ICheck, IColumn } from "@ax/types";
|
|
5
|
+
import { IPage, ISite, ISavePageParams, ICheck, IColumn, IDataPack } from "@ax/types";
|
|
6
6
|
import { pageStatus, ISetCurrentPageIDAction } from "@ax/containers/PageEditor/interfaces";
|
|
7
7
|
|
|
8
8
|
import {
|
|
@@ -32,6 +32,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
32
32
|
categoryColumns,
|
|
33
33
|
categoryColors,
|
|
34
34
|
addCategoryColors,
|
|
35
|
+
dataPacks,
|
|
35
36
|
} = props;
|
|
36
37
|
const { isSelected, siteLanguages, page, lang } = item;
|
|
37
38
|
const {
|
|
@@ -45,6 +46,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
45
46
|
languageActions,
|
|
46
47
|
duplicatePage,
|
|
47
48
|
removePageFromSite,
|
|
49
|
+
getDataPack,
|
|
48
50
|
} = functions;
|
|
49
51
|
const { locale } = lang;
|
|
50
52
|
const {
|
|
@@ -78,9 +80,14 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
78
80
|
|
|
79
81
|
const setRoute = (path: string) => setHistoryPush(path, true);
|
|
80
82
|
|
|
81
|
-
const goToPage = () => {
|
|
83
|
+
const goToPage = async () => {
|
|
82
84
|
const pageID = page.haveDraftPage ? page.haveDraftPage : page.id;
|
|
83
85
|
setCurrentPageID(pageID);
|
|
86
|
+
|
|
87
|
+
const { templateId } = item.page;
|
|
88
|
+
const dataPack = dataPacks.find((pack) => pack.templates.some((template) => template.id === templateId));
|
|
89
|
+
dataPack && await getDataPack(dataPack.id);
|
|
90
|
+
|
|
84
91
|
setRoute("pages/editor");
|
|
85
92
|
};
|
|
86
93
|
|
|
@@ -540,6 +547,7 @@ interface IPageItemProps {
|
|
|
540
547
|
setCurrentPageID(currentPageID: number | null): ISetCurrentPageIDAction;
|
|
541
548
|
duplicatePage(pageID: number, data: any): Promise<void>;
|
|
542
549
|
removePageFromSite(pageID: number): Promise<boolean>;
|
|
550
|
+
getDataPack: (id: string) => Promise<void>;
|
|
543
551
|
};
|
|
544
552
|
activatedTemplates: any[];
|
|
545
553
|
toggleToast(): void;
|
|
@@ -548,6 +556,7 @@ interface IPageItemProps {
|
|
|
548
556
|
columns: Record<string, IColumn>;
|
|
549
557
|
categoryColors: any;
|
|
550
558
|
addCategoryColors(cats: string[]): void;
|
|
559
|
+
dataPacks: IDataPack[];
|
|
551
560
|
}
|
|
552
561
|
|
|
553
562
|
export default memo(PageItem);
|
|
@@ -23,6 +23,7 @@ import { sitesActions } from "@ax/containers/Sites";
|
|
|
23
23
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
24
24
|
import { structuredDataActions } from "@ax/containers/StructuredData";
|
|
25
25
|
import { INITIAL_TEMPLATE } from "@ax/containers/PageEditor/constants";
|
|
26
|
+
import { dataPacksActions } from "@ax/containers/Settings";
|
|
26
27
|
import {
|
|
27
28
|
ISetCurrentPageIDAction,
|
|
28
29
|
ISetCurrentPageStatusAction,
|
|
@@ -80,6 +81,8 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
80
81
|
resetPageEditor,
|
|
81
82
|
removePageFromSite,
|
|
82
83
|
importPageFromGlobal,
|
|
84
|
+
getDataPack,
|
|
85
|
+
dataPacks,
|
|
83
86
|
} = props;
|
|
84
87
|
|
|
85
88
|
!currentSiteInfo && setHistoryPush("/sites", false);
|
|
@@ -470,6 +473,7 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
470
473
|
duplicatePage,
|
|
471
474
|
removePageFromSite,
|
|
472
475
|
languageActions: pageLanguageActions,
|
|
476
|
+
getDataPack: getDataPack,
|
|
473
477
|
};
|
|
474
478
|
|
|
475
479
|
return (
|
|
@@ -484,6 +488,7 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
484
488
|
columns={columnsState}
|
|
485
489
|
categoryColors={categoryColors}
|
|
486
490
|
addCategoryColors={addCategoryColors}
|
|
491
|
+
dataPacks={dataPacks}
|
|
487
492
|
/>
|
|
488
493
|
);
|
|
489
494
|
});
|
|
@@ -637,6 +642,7 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
637
642
|
activatedDataPacks: state.dataPacks.activated,
|
|
638
643
|
activatedTemplates: state.dataPacks.templates,
|
|
639
644
|
isLoading: state.app.isLoading,
|
|
645
|
+
dataPacks: state.dataPacks.activated,
|
|
640
646
|
});
|
|
641
647
|
|
|
642
648
|
interface IDispatchProps {
|
|
@@ -664,6 +670,7 @@ interface IDispatchProps {
|
|
|
664
670
|
resetPageEditor(): Promise<void>;
|
|
665
671
|
removePageFromSite(pageID: number | number[], refresh?: boolean): Promise<boolean>;
|
|
666
672
|
importPageFromGlobal(pageID: number | number[]): Promise<boolean>;
|
|
673
|
+
getDataPack: (id: string) => Promise<void>;
|
|
667
674
|
}
|
|
668
675
|
|
|
669
676
|
const mapDispatchToProps = {
|
|
@@ -690,6 +697,7 @@ const mapDispatchToProps = {
|
|
|
690
697
|
resetPageEditor: pageEditorActions.resetPageEditor,
|
|
691
698
|
removePageFromSite: sitesActions.removePageFromSite,
|
|
692
699
|
importPageFromGlobal: sitesActions.importPageFromGlobal,
|
|
700
|
+
getDataPack: dataPacksActions.getSiteDataPack,
|
|
693
701
|
};
|
|
694
702
|
|
|
695
703
|
interface IPagesProps {
|
|
@@ -710,6 +718,7 @@ interface IPagesProps {
|
|
|
710
718
|
activatedDataPacks: IDataPack[];
|
|
711
719
|
activatedTemplates: any[];
|
|
712
720
|
isLoading: boolean;
|
|
721
|
+
dataPacks: IDataPack[];
|
|
713
722
|
}
|
|
714
723
|
|
|
715
724
|
type IProps = IPagesProps & IDispatchProps;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
|
-
import { themes } from "components";
|
|
4
3
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
5
4
|
import { ConfigPanel, ResizePanel } from "@ax/components";
|
|
6
5
|
import { IBreadcrumbItem, IRootState, ISchema, IUserEditing } from "@ax/types";
|
|
7
|
-
import PageBrowser from "
|
|
6
|
+
import PageBrowser from "../PageBrowser";
|
|
8
7
|
|
|
9
8
|
const Editor = (props: IProps) => {
|
|
10
9
|
const {
|
|
@@ -25,8 +24,9 @@ const Editor = (props: IProps) => {
|
|
|
25
24
|
isLoading,
|
|
26
25
|
isGlobal,
|
|
27
26
|
isEditable,
|
|
28
|
-
|
|
27
|
+
isReadOnly,
|
|
29
28
|
userEditing,
|
|
29
|
+
theme,
|
|
30
30
|
} = props;
|
|
31
31
|
|
|
32
32
|
const actions = {
|
|
@@ -39,12 +39,9 @@ const Editor = (props: IProps) => {
|
|
|
39
39
|
replaceElementsInCollectionAction: replaceElementsInCollection,
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const defaultTheme = themes.find((theme: any) => theme.default);
|
|
43
|
-
const theme = defaultTheme ? defaultTheme.value : themes[0].value;
|
|
44
|
-
|
|
45
42
|
return (
|
|
46
43
|
<ResizePanel
|
|
47
|
-
leftPanel={<PageBrowser
|
|
44
|
+
leftPanel={<PageBrowser isReadOnly={isReadOnly} theme={theme} />}
|
|
48
45
|
rightPanel={
|
|
49
46
|
<ConfigPanel
|
|
50
47
|
schema={schema}
|
|
@@ -59,7 +56,7 @@ const Editor = (props: IProps) => {
|
|
|
59
56
|
isPage={true}
|
|
60
57
|
isGlobal={isGlobal}
|
|
61
58
|
isEditable={isEditable}
|
|
62
|
-
|
|
59
|
+
isReadOnly={isReadOnly}
|
|
63
60
|
userEditing={userEditing}
|
|
64
61
|
theme={theme}
|
|
65
62
|
/>
|
|
@@ -91,7 +88,8 @@ interface IPageBrowserDispatchProps {
|
|
|
91
88
|
replaceElementsInCollection(newValue: string, reference: string): void;
|
|
92
89
|
isGlobal: boolean;
|
|
93
90
|
isEditable: boolean;
|
|
94
|
-
|
|
91
|
+
isReadOnly: boolean;
|
|
92
|
+
theme: string;
|
|
95
93
|
}
|
|
96
94
|
|
|
97
95
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
4
|
-
import { themes } from "components";
|
|
5
4
|
|
|
6
5
|
import { Browser } from "@ax/components";
|
|
7
6
|
import { IBreadcrumbItem, ILanguage, IRootState, ISchema, ISocialState } from "@ax/types";
|
|
@@ -10,13 +9,16 @@ const PageBrowser = (props: IProps) => {
|
|
|
10
9
|
const {
|
|
11
10
|
socials,
|
|
12
11
|
cloudinaryName,
|
|
12
|
+
damDomain,
|
|
13
13
|
content: {
|
|
14
14
|
editorContent: { path, slug, canonicalSite },
|
|
15
15
|
},
|
|
16
16
|
selectedEditorID,
|
|
17
17
|
setSelectedContent,
|
|
18
18
|
globalLangs,
|
|
19
|
-
|
|
19
|
+
theme,
|
|
20
|
+
isReadOnly,
|
|
21
|
+
isPreview,
|
|
20
22
|
} = props;
|
|
21
23
|
|
|
22
24
|
const slugWithSlash = slug ? (slug.startsWith("/") ? slug : `/${slug}`) : "";
|
|
@@ -31,11 +33,13 @@ const PageBrowser = (props: IProps) => {
|
|
|
31
33
|
selectedEditorID={selectedEditorID}
|
|
32
34
|
setSelectedContent={setSelectedContent}
|
|
33
35
|
url={url}
|
|
34
|
-
theme={
|
|
36
|
+
theme={theme}
|
|
35
37
|
cloudinaryName={cloudinaryName}
|
|
38
|
+
damDomain={damDomain}
|
|
36
39
|
siteLangs={globalLangs}
|
|
37
|
-
disabled={
|
|
40
|
+
disabled={isReadOnly}
|
|
38
41
|
siteID={canonicalSite}
|
|
42
|
+
isPreview={isPreview}
|
|
39
43
|
/>
|
|
40
44
|
);
|
|
41
45
|
};
|
|
@@ -45,7 +49,8 @@ interface IEditorStateProps {
|
|
|
45
49
|
content: any;
|
|
46
50
|
selectedEditorID: number;
|
|
47
51
|
socials: ISocialState;
|
|
48
|
-
cloudinaryName: string;
|
|
52
|
+
cloudinaryName: string | null;
|
|
53
|
+
damDomain: string | null;
|
|
49
54
|
globalLangs: ILanguage[];
|
|
50
55
|
schema: ISchema | Record<string, unknown>;
|
|
51
56
|
breadcrumb: IBreadcrumbItem[];
|
|
@@ -55,7 +60,9 @@ interface IEditorStateProps {
|
|
|
55
60
|
|
|
56
61
|
interface IPageBrowserDispatchProps {
|
|
57
62
|
setSelectedContent(editorID: number): void;
|
|
58
|
-
|
|
63
|
+
theme: string;
|
|
64
|
+
isReadOnly: boolean;
|
|
65
|
+
isPreview?: boolean;
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -65,6 +72,7 @@ const mapStateToProps = (state: IRootState): IEditorStateProps => ({
|
|
|
65
72
|
selectedEditorID: state.pageEditor.selectedEditorID as number,
|
|
66
73
|
socials: state.social,
|
|
67
74
|
cloudinaryName: state.app.globalSettings.cloudinaryName,
|
|
75
|
+
damDomain: state.app.globalSettings.damDomain,
|
|
68
76
|
globalLangs: state.app.globalLangs,
|
|
69
77
|
schema: state.pageEditor.schema,
|
|
70
78
|
breadcrumb: state.pageEditor.breadcrumb,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import PageBrowser from "../PageBrowser";
|
|
4
|
+
import * as S from "./style";
|
|
5
|
+
|
|
6
|
+
const PreviewBrowser = (props: IProps) => {
|
|
7
|
+
const { theme } = props;
|
|
8
|
+
return (
|
|
9
|
+
<S.BrowserWrapper>
|
|
10
|
+
<PageBrowser isReadOnly={true} isPreview={true} theme={theme} />
|
|
11
|
+
</S.BrowserWrapper>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
interface IProps {
|
|
16
|
+
theme: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default PreviewBrowser;
|
|
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react";
|
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
import { RouteComponentProps } from "react-router-dom";
|
|
4
4
|
|
|
5
|
+
import { themes } from "components";
|
|
5
6
|
import { IErrorItem, IRootState, ISavePageParams, IUserEditing } from "@ax/types";
|
|
6
7
|
import { MainWrapper, Loading, ErrorToast, Notification, Modal } from "@ax/components";
|
|
7
8
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
@@ -12,6 +13,7 @@ import { pageStatus } from "@ax/containers/PageEditor/interfaces";
|
|
|
12
13
|
import { RouteLeavingGuard } from "@ax/guards";
|
|
13
14
|
import { useIsDirty, useModal } from "@ax/hooks";
|
|
14
15
|
import Editor from "./Editor";
|
|
16
|
+
import Preview from "./Preview";
|
|
15
17
|
|
|
16
18
|
import * as S from "./style";
|
|
17
19
|
|
|
@@ -43,13 +45,18 @@ const GlobalEditor = (props: IProps) => {
|
|
|
43
45
|
|
|
44
46
|
const { isOpen, toggleModal } = useModal();
|
|
45
47
|
const { isOpen: isUnpublishOpen, toggleModal: toggleUnpublishModal } = useModal();
|
|
46
|
-
const [
|
|
48
|
+
const [isReadOnly, setIsReadOnly] = useState(false);
|
|
49
|
+
const [selectedTab, setSelectedTab] = useState("edit");
|
|
47
50
|
const { isDirty, setIsDirty, resetDirty } = useIsDirty(editorContent.editorContent, isNewTranslation);
|
|
48
51
|
|
|
49
52
|
const isPublished = props.pageStatus === pageStatus.PUBLISHED || props.pageStatus === pageStatus.UPLOAD_PENDING;
|
|
50
53
|
const isDraft = props.pageStatus === pageStatus.MODIFIED;
|
|
51
54
|
const hasDraft = editorContent.editorContent && editorContent.editorContent.haveDraftPage;
|
|
52
55
|
const isLivePageChanged = editorContent.editorContent && editorContent.editorContent.liveChanged;
|
|
56
|
+
const structuredData = editorContent.editorContent ? editorContent.editorContent.structuredData : "";
|
|
57
|
+
|
|
58
|
+
const defaultTheme = themes.find((theme: any) => theme.default);
|
|
59
|
+
const theme = defaultTheme ? defaultTheme.value : themes[0].value;
|
|
53
60
|
|
|
54
61
|
useEffect(() => {
|
|
55
62
|
const { pageID, getPage, setTab, setCurrentSiteInfo, sendPagePing, setStructuredDataFilter } = props;
|
|
@@ -72,13 +79,18 @@ const GlobalEditor = (props: IProps) => {
|
|
|
72
79
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
73
80
|
}, []);
|
|
74
81
|
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
resetDirty();
|
|
84
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85
|
+
}, [lang]);
|
|
86
|
+
|
|
75
87
|
useEffect(() => {
|
|
76
88
|
const { pageID, sendPagePing, currentUserID } = props;
|
|
77
89
|
if (userEditing && userEditing.id !== currentUserID) {
|
|
78
|
-
|
|
90
|
+
setIsReadOnly(true);
|
|
79
91
|
!isOpen && toggleModal();
|
|
80
92
|
} else {
|
|
81
|
-
|
|
93
|
+
setIsReadOnly(false);
|
|
82
94
|
pageID && sendPagePing(pageID);
|
|
83
95
|
isOpen && toggleModal();
|
|
84
96
|
}
|
|
@@ -196,9 +208,14 @@ const GlobalEditor = (props: IProps) => {
|
|
|
196
208
|
}
|
|
197
209
|
};
|
|
198
210
|
|
|
211
|
+
const handleNewTranlation = (isNewTranslation: boolean) => {
|
|
212
|
+
setSelectedTab("edit");
|
|
213
|
+
createNewTranslation && createNewTranslation(isNewTranslation);
|
|
214
|
+
};
|
|
215
|
+
|
|
199
216
|
const languageActions = {
|
|
200
217
|
setLanguage,
|
|
201
|
-
createNewTranslation,
|
|
218
|
+
createNewTranslation: handleNewTranlation,
|
|
202
219
|
getContent: getPage,
|
|
203
220
|
};
|
|
204
221
|
|
|
@@ -221,7 +238,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
221
238
|
: undefined;
|
|
222
239
|
|
|
223
240
|
const downArrowMenu = {
|
|
224
|
-
displayed: !
|
|
241
|
+
displayed: !isReadOnly,
|
|
225
242
|
button: getPublishButton(props.pageStatus),
|
|
226
243
|
options: [
|
|
227
244
|
{
|
|
@@ -281,7 +298,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
281
298
|
|
|
282
299
|
const rightButtonProps = {
|
|
283
300
|
label: isSaving ? "Saving" : getSaveLabel(),
|
|
284
|
-
disabled: (!isDirty && pageID !== null && !isNewTranslation) || isSaving ||
|
|
301
|
+
disabled: (!isDirty && pageID !== null && !isNewTranslation) || isSaving || isReadOnly,
|
|
285
302
|
action: handleSavePage,
|
|
286
303
|
};
|
|
287
304
|
|
|
@@ -352,6 +369,15 @@ const GlobalEditor = (props: IProps) => {
|
|
|
352
369
|
|
|
353
370
|
const mainUnpublishAction = { title: "Ok", onClick: toggleUnpublishModal };
|
|
354
371
|
|
|
372
|
+
const tabsPreview = {
|
|
373
|
+
icons: [
|
|
374
|
+
{ name: "edit", text: "Edit mode" },
|
|
375
|
+
{ name: "view", text: "Preview mode" },
|
|
376
|
+
],
|
|
377
|
+
selectedTab,
|
|
378
|
+
action: (tab: string) => setSelectedTab(tab),
|
|
379
|
+
};
|
|
380
|
+
|
|
355
381
|
return isLoading ? (
|
|
356
382
|
<Loading />
|
|
357
383
|
) : (
|
|
@@ -359,6 +385,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
359
385
|
<RouteLeavingGuard when={isDirty} action={goToPages} text={modalText} />
|
|
360
386
|
<MainWrapper
|
|
361
387
|
title={pageName}
|
|
388
|
+
subtitle={structuredData}
|
|
362
389
|
backLink={backLinkRoute}
|
|
363
390
|
rightButton={rightButtonProps}
|
|
364
391
|
downArrowMenu={downArrowMenu}
|
|
@@ -375,6 +402,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
375
402
|
inversed={true}
|
|
376
403
|
isFromEditor={true}
|
|
377
404
|
pageStatusActions={pageStatusActions}
|
|
405
|
+
tabs={tabsPreview}
|
|
378
406
|
>
|
|
379
407
|
{errors.length > 0 && (
|
|
380
408
|
<S.NotificationWrapper>
|
|
@@ -402,9 +430,13 @@ const GlobalEditor = (props: IProps) => {
|
|
|
402
430
|
</S.NotificationWrapper>
|
|
403
431
|
)}
|
|
404
432
|
<ErrorToast size="l" />
|
|
405
|
-
|
|
406
|
-
<
|
|
407
|
-
|
|
433
|
+
{selectedTab === "edit" ? (
|
|
434
|
+
<S.Content>
|
|
435
|
+
<Editor isGlobal={true} isEditable={isEditable} isReadOnly={isReadOnly} theme={theme} />
|
|
436
|
+
</S.Content>
|
|
437
|
+
) : (
|
|
438
|
+
<Preview theme={theme} />
|
|
439
|
+
)}
|
|
408
440
|
<Modal
|
|
409
441
|
isOpen={isOpen}
|
|
410
442
|
hide={toggleModal}
|
|
@@ -9,6 +9,7 @@ const DefaultsBrowser = (props: IProps) => {
|
|
|
9
9
|
const {
|
|
10
10
|
socials,
|
|
11
11
|
cloudinaryName,
|
|
12
|
+
damDomain,
|
|
12
13
|
content,
|
|
13
14
|
selectedEditorID,
|
|
14
15
|
setSelectedContent,
|
|
@@ -28,6 +29,7 @@ const DefaultsBrowser = (props: IProps) => {
|
|
|
28
29
|
url={content.slug}
|
|
29
30
|
theme={theme}
|
|
30
31
|
cloudinaryName={cloudinaryName}
|
|
32
|
+
damDomain={damDomain}
|
|
31
33
|
siteLangs={siteLangs}
|
|
32
34
|
siteID={siteID}
|
|
33
35
|
/>
|
|
@@ -40,7 +42,8 @@ interface IEditorStateProps {
|
|
|
40
42
|
selectedEditorID: number;
|
|
41
43
|
currentSiteInfo: any;
|
|
42
44
|
socials: ISocialState;
|
|
43
|
-
cloudinaryName: string;
|
|
45
|
+
cloudinaryName: string | null;
|
|
46
|
+
damDomain: string | null;
|
|
44
47
|
siteLangs: ILanguage[];
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -56,6 +59,7 @@ const mapStateToProps = (state: IRootState): IEditorStateProps => ({
|
|
|
56
59
|
currentSiteInfo: state.sites.currentSiteInfo,
|
|
57
60
|
socials: state.social,
|
|
58
61
|
cloudinaryName: state.app.globalSettings.cloudinaryName,
|
|
62
|
+
damDomain: state.app.globalSettings.damDomain,
|
|
59
63
|
siteLangs: state.sites.currentSiteLanguages,
|
|
60
64
|
});
|
|
61
65
|
|
|
@@ -31,15 +31,12 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
31
31
|
setHeader,
|
|
32
32
|
setFooter,
|
|
33
33
|
setHistoryPush,
|
|
34
|
-
header,
|
|
35
|
-
footer,
|
|
36
34
|
} = props;
|
|
37
35
|
|
|
38
36
|
const { isOpen, toggleModal } = useModal();
|
|
39
37
|
const { isDirty, setIsDirty, resetDirty } = useIsDirty(editorContent, isNewTranslation);
|
|
40
|
-
|
|
41
38
|
const currentDefaultNav = currentDefaultsContent.find((item: any) => item.setAsDefault);
|
|
42
|
-
const isNew = !
|
|
39
|
+
const isNew = !editorContent?.id || null;
|
|
43
40
|
const isSetAsDefault = editorContent && editorContent.setAsDefault;
|
|
44
41
|
|
|
45
42
|
useEffect(() => {
|
|
@@ -50,6 +47,11 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
50
47
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
51
48
|
}, []);
|
|
52
49
|
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
resetDirty();
|
|
52
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
|
+
}, [lang]);
|
|
54
|
+
|
|
53
55
|
const save = () => {
|
|
54
56
|
isNew || isNewTranslation
|
|
55
57
|
? createNavigation().then((isSaved: boolean) => {
|
|
@@ -76,8 +78,8 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
76
78
|
};
|
|
77
79
|
|
|
78
80
|
const rightButtonProps = {
|
|
79
|
-
label: !isDirty ? "Saved" : isSaving ? "Saving" : "Save",
|
|
80
|
-
disabled:
|
|
81
|
+
label: !isDirty && !isNewTranslation && !isNew ? "Saved" : isSaving ? "Saving" : "Save",
|
|
82
|
+
disabled: (!isDirty && !isNewTranslation && !isNew) || isSaving,
|
|
81
83
|
action: () => saveButtonAction(),
|
|
82
84
|
};
|
|
83
85
|
|
|
@@ -88,7 +90,7 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
88
90
|
};
|
|
89
91
|
|
|
90
92
|
const createNewTranslation = (isNewTranslation: boolean) => {
|
|
91
|
-
setIsDirty(
|
|
93
|
+
setIsDirty(true);
|
|
92
94
|
createTranslation(isNewTranslation);
|
|
93
95
|
};
|
|
94
96
|
|
|
@@ -6,7 +6,7 @@ import { sitesActions } from "@ax/containers/Sites";
|
|
|
6
6
|
import { appActions } from "@ax/containers/App";
|
|
7
7
|
import { ConfigPanel, ResizePanel } from "@ax/components";
|
|
8
8
|
import { IBreadcrumbItem, IRootState, ISchema, ISite, IUserEditing } from "@ax/types";
|
|
9
|
-
import PageBrowser from "
|
|
9
|
+
import PageBrowser from "../PageBrowser";
|
|
10
10
|
|
|
11
11
|
const Editor = (props: IProps) => {
|
|
12
12
|
const {
|
|
@@ -32,7 +32,7 @@ const Editor = (props: IProps) => {
|
|
|
32
32
|
setHistoryPush,
|
|
33
33
|
getGlobalFromLocalPage,
|
|
34
34
|
saveCurrentSiteInfo,
|
|
35
|
-
|
|
35
|
+
isReadOnly,
|
|
36
36
|
userEditing,
|
|
37
37
|
site,
|
|
38
38
|
} = props;
|
|
@@ -51,7 +51,7 @@ const Editor = (props: IProps) => {
|
|
|
51
51
|
|
|
52
52
|
return (
|
|
53
53
|
<ResizePanel
|
|
54
|
-
leftPanel={<PageBrowser isTemplateActivated={isTemplateActivated}
|
|
54
|
+
leftPanel={<PageBrowser isTemplateActivated={isTemplateActivated} isReadOnly={isReadOnly} />}
|
|
55
55
|
rightPanel={
|
|
56
56
|
<ConfigPanel
|
|
57
57
|
schema={schema}
|
|
@@ -68,7 +68,7 @@ const Editor = (props: IProps) => {
|
|
|
68
68
|
isEditable={isEditable}
|
|
69
69
|
pageTitle={pageTitle}
|
|
70
70
|
setHistoryPush={setHistoryPush}
|
|
71
|
-
|
|
71
|
+
isReadOnly={isReadOnly}
|
|
72
72
|
userEditing={userEditing}
|
|
73
73
|
theme={site.theme}
|
|
74
74
|
/>
|
|
@@ -106,7 +106,7 @@ interface IPageBrowserDispatchProps {
|
|
|
106
106
|
isGlobal: boolean;
|
|
107
107
|
isEditable: boolean;
|
|
108
108
|
pageTitle: string;
|
|
109
|
-
|
|
109
|
+
isReadOnly: boolean;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -9,6 +9,7 @@ const PageBrowser = (props: IProps) => {
|
|
|
9
9
|
const {
|
|
10
10
|
socials,
|
|
11
11
|
cloudinaryName,
|
|
12
|
+
damDomain,
|
|
12
13
|
content: {
|
|
13
14
|
editorContent: { path, slug },
|
|
14
15
|
header,
|
|
@@ -19,13 +20,14 @@ const PageBrowser = (props: IProps) => {
|
|
|
19
20
|
currentSiteInfo: { theme, id: siteID },
|
|
20
21
|
siteLangs,
|
|
21
22
|
isTemplateActivated,
|
|
22
|
-
|
|
23
|
+
isReadOnly,
|
|
24
|
+
isPreview,
|
|
23
25
|
} = props;
|
|
24
26
|
|
|
25
27
|
const slugWithSlash = slug ? (slug.startsWith("/") ? slug : `/${slug}`) : "";
|
|
26
28
|
const pathWithoutSlash = path ? (path.endsWith("/") ? path.slice(0, -1) : path) : "";
|
|
27
29
|
const url = `${pathWithoutSlash}${slugWithSlash}`;
|
|
28
|
-
const disabled = isTemplateActivated === false ||
|
|
30
|
+
const disabled = isTemplateActivated === false || isReadOnly;
|
|
29
31
|
|
|
30
32
|
return (
|
|
31
33
|
<Browser
|
|
@@ -39,9 +41,11 @@ const PageBrowser = (props: IProps) => {
|
|
|
39
41
|
url={url}
|
|
40
42
|
theme={theme}
|
|
41
43
|
cloudinaryName={cloudinaryName}
|
|
44
|
+
damDomain={damDomain}
|
|
42
45
|
siteLangs={siteLangs}
|
|
43
46
|
disabled={disabled}
|
|
44
47
|
siteID={siteID}
|
|
48
|
+
isPreview={isPreview}
|
|
45
49
|
/>
|
|
46
50
|
);
|
|
47
51
|
};
|
|
@@ -52,7 +56,8 @@ interface IEditorStateProps {
|
|
|
52
56
|
selectedEditorID: number;
|
|
53
57
|
currentSiteInfo: any;
|
|
54
58
|
socials: ISocialState;
|
|
55
|
-
cloudinaryName: string;
|
|
59
|
+
cloudinaryName: string | null;
|
|
60
|
+
damDomain: string | null;
|
|
56
61
|
siteLangs: ILanguage[];
|
|
57
62
|
schema: ISchema | Record<string, unknown>;
|
|
58
63
|
breadcrumb: IBreadcrumbItem[];
|
|
@@ -63,7 +68,8 @@ interface IEditorStateProps {
|
|
|
63
68
|
interface IPageBrowserDispatchProps {
|
|
64
69
|
setSelectedContent(editorID: number): void;
|
|
65
70
|
isTemplateActivated: boolean;
|
|
66
|
-
|
|
71
|
+
isReadOnly: boolean;
|
|
72
|
+
isPreview?: boolean;
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -74,6 +80,7 @@ const mapStateToProps = (state: IRootState): IEditorStateProps => ({
|
|
|
74
80
|
currentSiteInfo: state.sites.currentSiteInfo,
|
|
75
81
|
socials: state.social,
|
|
76
82
|
cloudinaryName: state.app.globalSettings.cloudinaryName,
|
|
83
|
+
damDomain: state.app.globalSettings.damDomain,
|
|
77
84
|
siteLangs: state.sites.currentSiteLanguages,
|
|
78
85
|
schema: state.pageEditor.schema,
|
|
79
86
|
breadcrumb: state.pageEditor.breadcrumb,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import PageBrowser from "../PageBrowser";
|
|
4
|
+
import * as S from "./style";
|
|
5
|
+
|
|
6
|
+
const PreviewBrowser = () => {
|
|
7
|
+
return (
|
|
8
|
+
<S.BrowserWrapper>
|
|
9
|
+
<PageBrowser isTemplateActivated={true} isReadOnly={true} isPreview={true} />
|
|
10
|
+
</S.BrowserWrapper>
|
|
11
|
+
);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default PreviewBrowser;
|