@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.
Files changed (84) hide show
  1. package/package.json +6 -5
  2. package/src/GlobalStore.tsx +1 -1
  3. package/src/Style/index.tsx +2 -0
  4. package/src/api/pages.tsx +20 -0
  5. package/src/api/utils.tsx +5 -2
  6. package/src/components/Browser/index.tsx +144 -39
  7. package/src/components/Browser/style.tsx +47 -11
  8. package/src/components/ConfigPanel/index.tsx +3 -3
  9. package/src/components/Fields/RichText/index.tsx +2 -2
  10. package/src/components/Fields/UrlField/utils.tsx +10 -1
  11. package/src/components/Icon/components/Desktop.js +9 -4
  12. package/src/components/Icon/components/Phone.js +4 -4
  13. package/src/components/Icon/components/Share.js +12 -0
  14. package/src/components/Icon/components/Tablet.js +4 -4
  15. package/src/components/Icon/svgs/Share.svg +3 -0
  16. package/src/components/MainWrapper/AppBar/index.tsx +19 -7
  17. package/src/components/MainWrapper/AppBar/style.tsx +20 -4
  18. package/src/components/MainWrapper/index.tsx +1 -1
  19. package/src/components/SideModal/index.tsx +1 -1
  20. package/src/components/TableFilters/DateFilter/index.tsx +48 -0
  21. package/src/components/TableFilters/DateFilter/style.tsx +29 -0
  22. package/src/components/TableFilters/index.tsx +2 -0
  23. package/src/components/Tabs/index.tsx +17 -7
  24. package/src/components/Tabs/style.tsx +29 -16
  25. package/src/components/Tooltip/index.tsx +1 -1
  26. package/src/components/Tooltip/style.tsx +2 -0
  27. package/src/components/index.tsx +2 -0
  28. package/src/containers/App/reducer.tsx +3 -1
  29. package/src/containers/Navigation/Defaults/actions.tsx +2 -1
  30. package/src/containers/PageEditor/actions.tsx +65 -10
  31. package/src/containers/Settings/DataPacks/actions.tsx +4 -1
  32. package/src/containers/Sites/actions.tsx +3 -1
  33. package/src/helpers/dates.tsx +3 -4
  34. package/src/helpers/index.tsx +2 -0
  35. package/src/helpers/strings.tsx +38 -7
  36. package/src/hooks/forms.tsx +1 -2
  37. package/src/index.tsx +2 -2
  38. package/src/modules/Content/OptionTable/index.tsx +29 -2
  39. package/src/modules/Content/PageItem/index.tsx +11 -2
  40. package/src/modules/Content/index.tsx +9 -0
  41. package/src/modules/GlobalEditor/Editor/index.tsx +7 -9
  42. package/src/modules/GlobalEditor/{Editor/PageBrowser → PageBrowser}/index.tsx +14 -6
  43. package/src/modules/GlobalEditor/Preview/index.tsx +19 -0
  44. package/src/modules/GlobalEditor/Preview/style.tsx +9 -0
  45. package/src/modules/GlobalEditor/index.tsx +41 -9
  46. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +5 -1
  47. package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +9 -7
  48. package/src/modules/PageEditor/Editor/index.tsx +5 -5
  49. package/src/modules/PageEditor/{Editor/PageBrowser → PageBrowser}/index.tsx +11 -4
  50. package/src/modules/PageEditor/Preview/index.tsx +14 -0
  51. package/src/modules/PageEditor/Preview/style.tsx +9 -0
  52. package/src/modules/PageEditor/index.tsx +40 -16
  53. package/src/modules/PublicPreview/index.tsx +92 -0
  54. package/src/modules/PublicPreview/style.tsx +18 -0
  55. package/src/modules/Redirects/BulkHeader/TableHeader/index.tsx +16 -3
  56. package/src/modules/Redirects/BulkHeader/TableHeader/style.tsx +9 -3
  57. package/src/modules/Redirects/BulkHeader/index.tsx +7 -1
  58. package/src/modules/Redirects/RedirectItem/index.tsx +4 -0
  59. package/src/modules/Redirects/RedirectItem/style.tsx +19 -3
  60. package/src/modules/Redirects/atoms.tsx +0 -1
  61. package/src/modules/Redirects/hooks.tsx +67 -0
  62. package/src/modules/Redirects/index.tsx +23 -9
  63. package/src/modules/Redirects/utils.tsx +10 -0
  64. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/Field/index.tsx +107 -0
  65. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/Field/style.tsx +54 -0
  66. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/index.tsx +66 -0
  67. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/style.tsx +42 -0
  68. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +58 -0
  69. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +41 -0
  70. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/index.tsx +93 -0
  71. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/style.tsx +25 -0
  72. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/index.tsx +48 -0
  73. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/style.tsx +53 -0
  74. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/index.tsx +40 -36
  75. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/style.tsx +4 -5
  76. package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +4 -4
  77. package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +5 -1
  78. package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/atoms.tsx +0 -0
  79. package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/index.tsx +20 -11
  80. package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/style.tsx +6 -0
  81. package/src/modules/Settings/{SeoSettings → SeoAnalyticsSettings}/index.tsx +11 -4
  82. package/src/routes/publicRoutes.tsx +3 -1
  83. package/src/routes/site.tsx +14 -10
  84. 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 { selectData, selectPage, filters, values, selectedValue, setIsStructuredData, theme } = props;
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(null, mapDispatchToProps)(OptionTable);
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 "./PageBrowser";
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
- isPreviewMode,
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 isPreviewMode={isPreviewMode} />}
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
- isPreviewMode={isPreviewMode}
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
- isPreviewMode: boolean;
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
- isPreviewMode,
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={themes[0]}
36
+ theme={theme}
35
37
  cloudinaryName={cloudinaryName}
38
+ damDomain={damDomain}
36
39
  siteLangs={globalLangs}
37
- disabled={isPreviewMode}
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
- isPreviewMode: boolean;
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;
@@ -0,0 +1,9 @@
1
+ import styled from "styled-components";
2
+
3
+ const BrowserWrapper = styled.div`
4
+ background-color: ${(p) => p.theme.color.uiBackground01};
5
+ height: calc(100% - 44px);
6
+ width: 100%;
7
+ `;
8
+
9
+ export { BrowserWrapper };
@@ -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 [isPreviewMode, setIsPreviewMode] = useState(false);
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
- setIsPreviewMode(true);
90
+ setIsReadOnly(true);
79
91
  !isOpen && toggleModal();
80
92
  } else {
81
- setIsPreviewMode(false);
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: !isPreviewMode,
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 || isPreviewMode,
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
- <S.Content>
406
- <Editor isGlobal={true} isEditable={isEditable} isPreviewMode={isPreviewMode} />
407
- </S.Content>
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 = !header && !footer;
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: isSaving || !isDirty,
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(false);
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 "./PageBrowser";
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
- isPreviewMode,
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} isPreviewMode={isPreviewMode} />}
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
- isPreviewMode={isPreviewMode}
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
- isPreviewMode: boolean;
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
- isPreviewMode,
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 || isPreviewMode;
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
- isPreviewMode: boolean;
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;