@griddo/ax 10.4.26 → 10.4.27

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 (30) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/ConfigPanel/Header/Header.test.tsx +3 -0
  3. package/src/components/ConfigPanel/Form/index.tsx +16 -11
  4. package/src/components/ConfigPanel/Form/style.tsx +15 -6
  5. package/src/components/ConfigPanel/GlobalPageForm/index.tsx +1 -1
  6. package/src/components/ConfigPanel/Header/index.tsx +55 -7
  7. package/src/components/ConfigPanel/Header/style.tsx +9 -1
  8. package/src/components/ConfigPanel/NavigationForm/Field/index.tsx +3 -3
  9. package/src/components/ConfigPanel/NavigationForm/index.tsx +2 -1
  10. package/src/components/ConfigPanel/index.tsx +10 -2
  11. package/src/components/EmptyState/style.tsx +9 -9
  12. package/src/components/ErrorToast/index.tsx +3 -4
  13. package/src/components/ErrorToast/style.tsx +8 -11
  14. package/src/components/Fields/ArrayFieldGroup/index.tsx +5 -1
  15. package/src/components/Fields/Wysiwyg/style.tsx +4 -0
  16. package/src/components/Image/index.tsx +1 -1
  17. package/src/components/ResizePanel/style.tsx +1 -1
  18. package/src/containers/App/reducer.tsx +2 -2
  19. package/src/containers/Navigation/Defaults/actions.tsx +12 -8
  20. package/src/containers/Navigation/Defaults/constants.tsx +0 -1
  21. package/src/containers/Navigation/Defaults/interfaces.tsx +0 -5
  22. package/src/containers/Navigation/Defaults/reducer.tsx +0 -3
  23. package/src/containers/PageEditor/actions.tsx +4 -1
  24. package/src/containers/PageEditor/reducer.tsx +1 -1
  25. package/src/modules/GlobalEditor/index.tsx +1 -1
  26. package/src/modules/GlobalEditor/style.tsx +1 -1
  27. package/src/modules/PageEditor/index.tsx +1 -1
  28. package/src/modules/PageEditor/style.tsx +1 -1
  29. package/src/modules/Sites/SitesList/GridView/GridSiteItem/style.tsx +0 -1
  30. package/src/modules/Sites/SitesList/style.tsx +2 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "10.4.26",
4
+ "version": "10.4.27",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Carlos Torres <carlos.torres@secuoyas.com>",
@@ -232,5 +232,5 @@
232
232
  "publishConfig": {
233
233
  "access": "public"
234
234
  },
235
- "gitHead": "7d1e693daf9d8513d856ebfd8be6a0dbe41aa74a"
235
+ "gitHead": "6185dbf170ba4bbe1a1d63873b06e6fd9624fd75"
236
236
  }
@@ -104,6 +104,9 @@ defaultProps.breadcrumb = [
104
104
 
105
105
  defaultProps.activatedModules = ["TextField"];
106
106
 
107
+ defaultProps.headerRef = { current: { offsetHeight: 63, offsetTop: 24 } } as React.RefObject<HTMLDivElement>;
108
+ const setHeaderHeightMock = defaultProps.setHeaderHeight as jest.MockedFunction<(height: number) => void>;
109
+
107
110
  describe("Header component rendering", () => {
108
111
  it("should render component", () => {
109
112
  render(
@@ -21,17 +21,19 @@ export const Form = (props: IFormProps): JSX.Element => {
21
21
  header,
22
22
  footer,
23
23
  isEditLive,
24
+ headerHeight,
24
25
  } = props;
25
26
 
26
- const isAllowedToEditPageContent =
27
- (!isGlobal && usePermission("content.editContentPages")) ||
28
- (isGlobal && usePermission("global.globalData.editAllGlobalData"));
27
+ const isAllowedToEditSitePages = usePermission("content.editContentPages");
28
+ const isAllowedToEditGlobalData = usePermission("global.globalData.editAllGlobalData");
29
+ const isAllowedToEditConfigPages = usePermission("content.editConfigPages");
30
+ const isAllowedToEditSiteSeo = usePermission("seoAnalytics.editSeoAnalyticsPages");
31
+ const isAllowedToEditGlobalSeo = usePermission("global.seoAnalytics.editSeoAnalyticsInGlobalPages");
32
+
33
+ const isAllowedToEditPageContent = (!isGlobal && isAllowedToEditSitePages) || (isGlobal && isAllowedToEditGlobalData);
29
34
  const isAllowedToEditPageConfig =
30
- (!isGlobal && usePermission("content.editConfigPages")) ||
31
- (isGlobal && usePermission("global.globalData.editAllGlobalData"));
32
- const isAllowedToEditPageSEO =
33
- (!isGlobal && usePermission("seoAnalytics.editSeoAnalyticsPages")) ||
34
- (isGlobal && usePermission("global.seoAnalytics.editSeoAnalyticsInGlobalPages"));
35
+ (!isGlobal && isAllowedToEditConfigPages) || (isGlobal && isAllowedToEditGlobalData);
36
+ const isAllowedToEditPageSEO = (!isGlobal && isAllowedToEditSiteSeo) || (isGlobal && isAllowedToEditGlobalSeo);
35
37
 
36
38
  const tabContent = schema.configTabs.find((tab: ISchemaTab) => tab.title === selectedTab);
37
39
  const setTab = (tab: string) => setSelectedTab(tab);
@@ -99,8 +101,10 @@ export const Form = (props: IFormProps): JSX.Element => {
99
101
  actions.restorePageNavigationAction && actions.restorePageNavigationAction("footer");
100
102
 
101
103
  return (
102
- <section data-testid="form-section">
103
- <Tabs tabs={tabs} active={selectedTab} setSelectedTab={setTab} />
104
+ <S.Wrapper data-testid="form-section">
105
+ <S.TabsWrapper headerHeight={headerHeight}>
106
+ <Tabs tabs={tabs} active={selectedTab} setSelectedTab={setTab} />
107
+ </S.TabsWrapper>
104
108
  {selectedTab === "content" && isEditLive && (
105
109
  <S.FieldWrapper>
106
110
  There are some changes in the <strong>draft associated</strong> with this page. Before making changes to the
@@ -126,7 +130,7 @@ export const Form = (props: IFormProps): JSX.Element => {
126
130
  </S.FieldWrapper>
127
131
  )}
128
132
  {tabContent && tabContent.fields.map((field: ISchemaField) => generateFields(field))}
129
- </section>
133
+ </S.Wrapper>
130
134
  );
131
135
  };
132
136
 
@@ -143,6 +147,7 @@ export interface IFormProps {
143
147
  header?: number | null;
144
148
  footer?: number | null;
145
149
  isEditLive?: boolean;
150
+ headerHeight: number;
146
151
  }
147
152
 
148
153
  export default Form;
@@ -1,13 +1,15 @@
1
1
  import styled from "styled-components";
2
2
 
3
+ const Wrapper = styled.section``;
4
+
3
5
  const FieldWrapper = styled.div`
6
+ ${(p) => p.theme.textStyle.uiXS};
4
7
  margin-top: ${(p) => p.theme.spacing.s};
5
8
  margin-bottom: ${(p) => p.theme.spacing.s};
6
- background-color: ${(p) => p.theme.color?.uiBackground03};
7
- padding: ${(p) => p.theme.spacing?.s};
8
- border-radius: ${(p) => p.theme.radii?.s};
9
- ${(p) => p.theme.textStyle?.uiXS};
10
- color: ${(p) => p.theme.color?.textMediumEmphasis};
9
+ background-color: ${(p) => p.theme.color.uiBackground03};
10
+ padding: ${(p) => p.theme.spacing.s};
11
+ border-radius: ${(p) => p.theme.radii.s};
12
+ color: ${(p) => p.theme.color.textMediumEmphasis};
11
13
  `;
12
14
 
13
15
  const Link = styled.span`
@@ -16,4 +18,11 @@ const Link = styled.span`
16
18
  color: ${(p) => p.theme.color?.interactive01};
17
19
  `;
18
20
 
19
- export { FieldWrapper, Link };
21
+ const TabsWrapper = styled.div<{ headerHeight: number }>`
22
+ background-color: ${(p) => p.theme.color.uiBackground01};
23
+ position: sticky;
24
+ top: ${(p) => (p.headerHeight ? `calc(63px + ${p.headerHeight}px)` : "63px")};
25
+ z-index: 3;
26
+ `;
27
+
28
+ export { Wrapper, FieldWrapper, Link, TabsWrapper };
@@ -11,7 +11,7 @@ import * as S from "./style";
11
11
 
12
12
  const noteText = "This is Global content and you cannot edit it here. To do so, you must go to the Global page";
13
13
  const noteTitle = "Global content";
14
- const errorText = "You don't have the permissions to edit the original content."
14
+ const errorText = "You don't have the permissions to edit the original content.";
15
15
 
16
16
  const GlobalPageForm = (props: IGlobalPageFormProps): JSX.Element => {
17
17
  const { selectedTab, setSelectedTab, schema, pageTitle, setHistoryPush, actions, header, footer } = props;
@@ -1,13 +1,24 @@
1
- import React, { memo } from "react";
1
+ import React, { memo, useCallback, useEffect, useState } from "react";
2
2
 
3
- import { IBreadcrumbItem } from "@ax/types";
3
+ import { IBreadcrumbItem, ISchema } from "@ax/types";
4
4
  import { Breadcrumb, Toast } from "@ax/components";
5
5
  import { useToast } from "@ax/hooks";
6
6
 
7
7
  import * as S from "./style";
8
8
 
9
9
  const Header = (props: IHeaderProps) => {
10
- const { breadcrumb, schema, selectedParent, activatedModules, actions, setSelectedContent } = props;
10
+ const {
11
+ breadcrumb,
12
+ schema,
13
+ selectedParent,
14
+ activatedModules,
15
+ actions,
16
+ headerRef,
17
+ setSelectedContent,
18
+ setHeaderHeight,
19
+ hasStickyHeader,
20
+ } = props;
21
+
11
22
  const { duplicateModuleAction, deleteModuleAction, copyModuleAction } = actions;
12
23
  const title = breadcrumb[breadcrumb.length - 1].displayName;
13
24
  const component = breadcrumb[breadcrumb.length - 1].component;
@@ -17,6 +28,40 @@ const Header = (props: IHeaderProps) => {
17
28
  const isInArray = Array.isArray(selectedParent);
18
29
 
19
30
  const { isVisible, toggleToast, setIsVisible } = useToast();
31
+ const [y, setY] = useState(window.scrollY);
32
+ const [scrollDown, setScrollDown] = useState(false);
33
+
34
+ const handleNavigation = useCallback(
35
+ (e: Event) => {
36
+ const window = e.currentTarget as Window;
37
+ const height = headerRef.current ? headerRef.current.offsetHeight + headerRef.current.offsetTop : 0;
38
+ if (isInArray && y > window.scrollY) {
39
+ setHeaderHeight(height);
40
+ setScrollDown(false);
41
+ } else if (y > height && y < window.scrollY) {
42
+ setHeaderHeight(0);
43
+ setScrollDown(true);
44
+ }
45
+ setY(window.scrollY);
46
+ },
47
+ [y, headerRef, setHeaderHeight, isInArray]
48
+ );
49
+
50
+ useEffect(() => {
51
+ setY(window.scrollY);
52
+ window.addEventListener("scroll", handleNavigation);
53
+ return () => {
54
+ window.removeEventListener("scroll", handleNavigation);
55
+ };
56
+ }, [handleNavigation]);
57
+
58
+ useEffect(() => {
59
+ if (headerRef.current) {
60
+ const height = headerRef.current.offsetHeight + headerRef.current.offsetTop;
61
+ setHeaderHeight(height);
62
+ window.scrollTo(0, 0);
63
+ }
64
+ }, [headerRef, breadcrumb, setHeaderHeight]);
20
65
 
21
66
  const removeItem = () => {
22
67
  setSelectedContent(parentID);
@@ -58,19 +103,19 @@ const Header = (props: IHeaderProps) => {
58
103
  menuOptions = isModule ? [...menuOptions, copyOpt] : menuOptions;
59
104
 
60
105
  return (
61
- <>
62
- <S.HeaderWrapper data-testid="header-config-wrapper">
106
+ <S.Wrapper scrollDown={scrollDown || !hasStickyHeader}>
107
+ <S.HeaderWrapper data-testid="header-config-wrapper" ref={headerRef}>
63
108
  <S.Title>{title}</S.Title>
64
109
  <Breadcrumb breadcrumb={breadcrumb} setSelectedContent={setSelectedContent} />
65
110
  {isInArray && <S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />}
66
111
  </S.HeaderWrapper>
67
112
  {isVisible && <Toast message="1 module copied to clipboard" setIsVisible={setIsVisible} />}
68
- </>
113
+ </S.Wrapper>
69
114
  );
70
115
  };
71
116
 
72
117
  export interface IHeaderProps {
73
- schema: any;
118
+ schema: ISchema;
74
119
  actions: {
75
120
  deleteModuleAction: (editorID: number[], key?: string) => void;
76
121
  duplicateModuleAction: (editorID: number[], key?: string) => number;
@@ -80,6 +125,9 @@ export interface IHeaderProps {
80
125
  selectedParent: any;
81
126
  activatedModules: string[];
82
127
  setSelectedContent(editorID: number): void;
128
+ headerRef: React.RefObject<HTMLDivElement>;
129
+ setHeaderHeight(height: number): void;
130
+ hasStickyHeader: boolean;
83
131
  }
84
132
 
85
133
  export default memo(Header);
@@ -1,6 +1,14 @@
1
1
  import styled from "styled-components";
2
2
  import { ActionMenu } from "@ax/components";
3
3
 
4
+ const Wrapper = styled.div<{ scrollDown: boolean }>`
5
+ padding-top: ${(p) => p.theme.spacing.m};
6
+ background-color: ${(p) => p.theme.color.uiBackground01};
7
+ position: ${(p) => (p.scrollDown ? "relative" : "sticky")};
8
+ top: ${(p) => (p.scrollDown ? "0" : "63px")};
9
+ z-index: 3;
10
+ `;
11
+
4
12
  const HeaderWrapper = styled.div`
5
13
  display: flex;
6
14
  flex-direction: column;
@@ -19,4 +27,4 @@ const StyledActionMenu = styled(ActionMenu)`
19
27
  top: 0;
20
28
  `;
21
29
 
22
- export { HeaderWrapper, Title, StyledActionMenu };
30
+ export { Wrapper, HeaderWrapper, Title, StyledActionMenu };
@@ -93,10 +93,10 @@ const Field = (props: IProps) => {
93
93
 
94
94
  const handleReplace = (option: any) => {
95
95
  const optionID = option.isDefault ? null : option.id;
96
- updateEditorContent(pageEditorID, type, optionID);
96
+ type && updateEditorContent(pageEditorID, type, optionID);
97
97
  };
98
98
 
99
- const handleRemove = () => removeNavigationFromPage(type);
99
+ const handleRemove = () => type && removeNavigationFromPage(type);
100
100
 
101
101
  const actionMenuOptions = [
102
102
  {
@@ -137,7 +137,7 @@ const Field = (props: IProps) => {
137
137
  };
138
138
 
139
139
  export interface IField {
140
- type: string;
140
+ type?: string;
141
141
  theme: string;
142
142
  }
143
143
 
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
 
3
3
  import { NoteField } from "@ax/components";
4
+ import { ISchema } from "@ax/types";
4
5
  import Field from "./Field";
5
6
 
6
7
  import * as S from "./style";
@@ -24,7 +25,7 @@ const NavigationForm = (props: INavigationFormProps): JSX.Element => {
24
25
  };
25
26
 
26
27
  export interface INavigationFormProps {
27
- schema: any;
28
+ schema: ISchema;
28
29
  theme: string;
29
30
  }
30
31
 
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef } from "react";
1
+ import React, { useEffect, useRef, useState } from "react";
2
2
 
3
3
  import { isEmptyObj } from "@ax/helpers";
4
4
  import { Loading } from "@ax/components";
@@ -39,6 +39,8 @@ const ConfigPanel = (props: IStateProps): JSX.Element => {
39
39
  } = props;
40
40
 
41
41
  const wrapperRef = useRef<HTMLDivElement>(null);
42
+ const headerRef = useRef<HTMLDivElement>(null);
43
+ const [headerHeight, setHeaderHeight] = useState<number>(0);
42
44
 
43
45
  useEffect(() => {
44
46
  if (lastElementAddedId && wrapperRef.current) {
@@ -50,9 +52,11 @@ const ConfigPanel = (props: IStateProps): JSX.Element => {
50
52
  if (isLoading || isEmptyObj(schema)) {
51
53
  return <Loading />;
52
54
  }
53
- const showNavigationForm = navigationModulesTypes.includes(schema.type) && isPage;
55
+ const showNavigationForm = schema.type !== undefined && navigationModulesTypes.includes(schema.type) && isPage;
54
56
  const isGlobalPageNotEditable = isGlobal && isPage && !isEditable;
55
57
 
58
+ const hasStickyHeader = !isReadOnly && !isGlobalPageNotEditable && !showNavigationForm;
59
+
56
60
  const getForm = () => {
57
61
  if (isReadOnly) {
58
62
  return <PreviewForm setSelectedTab={setSelectedTab} selectedTab={selectedTab} userEditing={userEditing} />;
@@ -86,6 +90,7 @@ const ConfigPanel = (props: IStateProps): JSX.Element => {
86
90
  header={header}
87
91
  footer={footer}
88
92
  isEditLive={isEditLive}
93
+ headerHeight={headerHeight}
89
94
  />
90
95
  );
91
96
  }
@@ -100,6 +105,9 @@ const ConfigPanel = (props: IStateProps): JSX.Element => {
100
105
  selectedParent={selectedParent}
101
106
  activatedModules={activatedModules}
102
107
  setSelectedContent={setSelectedContent}
108
+ headerRef={headerRef}
109
+ setHeaderHeight={setHeaderHeight}
110
+ hasStickyHeader={hasStickyHeader}
103
111
  />
104
112
  {getForm()}
105
113
  </S.Wrapper>
@@ -11,11 +11,11 @@ const Wrapper = styled.div`
11
11
 
12
12
  const IconWrapper = styled.div`
13
13
  position: relative;
14
- margin-bottom: ${p => p.theme.spacing.m};
15
- background-color: ${p => p.theme.colors.uiBackground03};
14
+ margin-bottom: ${(p) => p.theme.spacing.m};
15
+ background-color: ${(p) => p.theme.colors.uiBackground03};
16
16
  border-radius: 50%;
17
- width: ${p => p.theme.spacing.xl};
18
- height: ${p => p.theme.spacing.xl};
17
+ width: ${(p) => p.theme.spacing.xl};
18
+ height: ${(p) => p.theme.spacing.xl};
19
19
  svg {
20
20
  position: absolute;
21
21
  top: 50%;
@@ -25,18 +25,18 @@ const IconWrapper = styled.div`
25
25
  `;
26
26
 
27
27
  const Title = styled.div`
28
- ${p => p.theme.textStyle.headingS};
28
+ ${(p) => p.theme.textStyle.headingS};
29
29
  color: ${(p) => p.theme.color.textHighEmphasis};
30
- margin-bottom: ${p => p.theme.spacing.xs};
30
+ margin-bottom: ${(p) => p.theme.spacing.xs};
31
31
  `;
32
32
 
33
33
  const Text = styled.div`
34
- ${p => p.theme.textStyle.uiM};
34
+ ${(p) => p.theme.textStyle.uiM};
35
35
  color: ${(p) => p.theme.color.textMediumEmphasis};
36
- margin-bottom: ${p => p.theme.spacing.m};
36
+ margin-bottom: ${(p) => p.theme.spacing.m};
37
37
  text-align: center;
38
38
  `;
39
39
 
40
40
  const ActionWrapper = styled.div``;
41
41
 
42
- export { Wrapper, IconWrapper, Title, Text, ActionWrapper }
42
+ export { Wrapper, IconWrapper, Title, Text, ActionWrapper };
@@ -2,15 +2,14 @@ import React, { forwardRef } from "react";
2
2
 
3
3
  import * as S from "./style";
4
4
 
5
- const ErrorToast = (props: IProps, ref: any) => {
6
- const { size } = props;
7
-
8
- return <S.ErrorWrapper id="error" data-testid="error-wrapper" size={size} ref={ref} />;
5
+ const ErrorToast = (props: IProps) => {
6
+ return <S.ErrorWrapper id="error" data-testid="error-wrapper" {...props} />;
9
7
  };
10
8
 
11
9
  export interface IProps {
12
10
  size?: string;
13
11
  ref?: any;
12
+ fixed?: boolean;
14
13
  }
15
14
 
16
15
  export default forwardRef(ErrorToast);
@@ -1,17 +1,16 @@
1
1
  import styled from "styled-components";
2
2
 
3
-
4
- const ErrorWrapper = styled.div<{ size?: string}>`
5
- position: ${p => p.size ? "absolute" : "initial"};
6
- top: 0;
7
- left: ${p => {
8
- switch(p.size) {
3
+ const ErrorWrapper = styled.div<{ size?: string; fixed?: boolean }>`
4
+ position: ${(p) => (p.fixed ? "fixed" : p.size ? "absolute" : "sticky")};
5
+ top: ${(p) => (p.fixed ? p.theme.spacing.xl : "0")};
6
+ left: ${(p) => {
7
+ switch (p.size) {
9
8
  case "l":
10
9
  return 0;
11
10
  case "m":
12
- return p => `calc(${p.theme.spacing.m} * 3 + ${p.theme.spacing.s})`;
11
+ return (p) => `calc(${p.theme.spacing.m} * 3 + ${p.theme.spacing.s})`;
13
12
  case "s":
14
- return p => `calc(${p.theme.spacing.m} * 3 + ${p.theme.spacing.s} + (${p.theme.spacing.m} * 10))`;
13
+ return (p) => `calc(${p.theme.spacing.m} * 3 + ${p.theme.spacing.s} + (${p.theme.spacing.m} * 10))`;
15
14
  default:
16
15
  return 0;
17
16
  }
@@ -20,6 +19,4 @@ const ErrorWrapper = styled.div<{ size?: string}>`
20
19
  z-index: 1100;
21
20
  `;
22
21
 
23
- export {
24
- ErrorWrapper
25
- };
22
+ export { ErrorWrapper };
@@ -1,4 +1,4 @@
1
- import React, { useState } from "react";
1
+ import React, { useState, useEffect } from "react";
2
2
  import { v4 as uuidv4 } from "uuid";
3
3
 
4
4
  import { Button, FieldsDivider } from "@ax/components";
@@ -19,6 +19,10 @@ const ArrayFieldGroup = (props: IProps): JSX.Element => {
19
19
  const [items, setItems] = useState(initialValueMapped);
20
20
  const [isOpen, setIsOpen] = useState<number | null>(null);
21
21
 
22
+ useEffect(() => {
23
+ setItems(value);
24
+ }, [value]);
25
+
22
26
  const handleClick = () => {
23
27
  const newItems = [...items, { id: uuidv4() }];
24
28
  setItems(newItems);
@@ -55,6 +55,10 @@ export const EditorWrapper = styled.div<{ error: boolean | undefined; disabled?:
55
55
  .fr-btn-grp {
56
56
  margin: 0 10px;
57
57
  }
58
+
59
+ .fr-popup.fr-desktop.fr-active {
60
+ margin-left: -70px;
61
+ }
58
62
  }
59
63
  .fr-second-toolbar {
60
64
  border-color: ${(p) =>
@@ -19,7 +19,7 @@ const Image = (props: ICloudinaryImageProps | GriddoImageCommonProps) => {
19
19
  if (isCloudinary(url)) {
20
20
  const cloudinaryProps = props as ICloudinaryImageProps;
21
21
  const cloudinaryUrl = createCloudinaryUrl({ props: cloudinaryProps });
22
- return <img src={cloudinaryUrl} data-testid="image-wrapper" />;
22
+ return <img src={cloudinaryUrl} alt={cloudinaryProps.alt} data-testid="image-wrapper" />;
23
23
  } else {
24
24
  const griddoProps = { ...DAM_DEFAULTS, ...props } as GriddoImageCommonProps;
25
25
  return <GriddoImage {...griddoProps} />;
@@ -14,7 +14,7 @@ export const LeftPanel = styled.section`
14
14
  export const RightPanel = styled.section<{ width: number }>`
15
15
  display: flex;
16
16
  position: relative;
17
- padding: ${(p) => p.theme.spacing.m};
17
+ padding: ${(p) => `0 ${p.theme.spacing.m} ${p.theme.spacing.m} ${p.theme.spacing.m}`};
18
18
  flex-shrink: 0;
19
19
  width: ${(p) => p.width}px;
20
20
  min-width: 344px;
@@ -29,8 +29,8 @@ export interface IAppState {
29
29
  hasAnimation: boolean;
30
30
  }
31
31
  export interface IError {
32
- code?: any;
33
- text: any;
32
+ code?: number;
33
+ text: string;
34
34
  btnText?: string | undefined;
35
35
  actionsBelow?: boolean | undefined;
36
36
  subErrors?: any[];
@@ -52,7 +52,6 @@ import {
52
52
  SET_SELECTED_PARENT,
53
53
  SET_COPY_MODULE,
54
54
  SET_NAV_PAGES,
55
- RESET_DEFAULTS_STORE,
56
55
  } from "./constants";
57
56
 
58
57
  import {
@@ -68,7 +67,6 @@ import {
68
67
  ISetSelectedParent,
69
68
  ISetCopyModule,
70
69
  ISetNavPages,
71
- IResetDefaultsStore,
72
70
  } from "./interfaces";
73
71
 
74
72
  const { setIsLoading } = appActions;
@@ -137,10 +135,6 @@ function setNavPages(navigationPages: INavPages): ISetNavPages {
137
135
  return { type: SET_NAV_PAGES, payload: { navigationPages } };
138
136
  }
139
137
 
140
- function resetDefaultsStore(): IResetDefaultsStore {
141
- return { type: RESET_DEFAULTS_STORE };
142
- }
143
-
144
138
  // API RELATED FUNCTIONS
145
139
 
146
140
  function getHeaders(params: any): (dispatch: Dispatch, getState: any) => Promise<void> {
@@ -833,9 +827,19 @@ function setSelectedTab(tab: string): (dispatch: Dispatch) => Promise<void> {
833
827
  function resetDefaultsValues(): (dispatch: Dispatch) => Promise<void> {
834
828
  return async (dispatch) => {
835
829
  try {
836
- dispatch(resetDefaultsStore());
830
+ dispatch(setEditorContent(null));
831
+ dispatch(setBreadcrumb([]));
832
+ dispatch(setSchema({}));
833
+ dispatch(setSelectedDefaultContent({}));
834
+ dispatch(setSelectedEditorID(0));
835
+ dispatch(setTab("content"));
836
+ dispatch(setHeader(null));
837
+ dispatch(setFooter(null));
838
+ dispatch(setCurrentNavigationLanguages([]));
839
+ dispatch(setIsNewTranslation(false));
840
+ dispatch(setCurrentDefaultsContent([]));
837
841
  } catch (e) {
838
- console.log("Error", e);
842
+ console.log("Error", e); //TODO
839
843
  }
840
844
  };
841
845
  }
@@ -16,6 +16,5 @@ export const SET_CURRENT_NAVIGATION_LANGUAGES = `${NAME}/SET_CURRENT_NAVIGATION_
16
16
  export const SET_IS_NEW_TRANSLATION = `${NAME}/SET_IS_NEW_TRANSLATION`;
17
17
  export const SET_COPY_MODULE = `${NAME}/SET_COPY_MODULE`;
18
18
  export const SET_NAV_PAGES = `${NAME}/SET_NAV_PAGES`;
19
- export const RESET_DEFAULTS_STORE = `${NAME}/RESET_DEFAULTS_STORE`;
20
19
 
21
20
  export const ITEMS_PER_PAGE = 50;
@@ -15,7 +15,6 @@ import {
15
15
  SET_SELECTED_PARENT,
16
16
  SET_COPY_MODULE,
17
17
  SET_NAV_PAGES,
18
- RESET_DEFAULTS_STORE,
19
18
  } from "./constants";
20
19
 
21
20
  export interface ISetEditorContent {
@@ -93,10 +92,6 @@ export interface ISetNavPages {
93
92
  payload: { navigationPages: INavPages };
94
93
  }
95
94
 
96
- export interface IResetDefaultsStore {
97
- type: typeof RESET_DEFAULTS_STORE;
98
- }
99
-
100
95
  export type NavigationActionsCreators = ISetEditorContent &
101
96
  ISetBreadcrumb &
102
97
  ISetSchema &
@@ -17,7 +17,6 @@ import {
17
17
  SET_SELECTED_PARENT,
18
18
  SET_COPY_MODULE,
19
19
  SET_NAV_PAGES,
20
- RESET_DEFAULTS_STORE,
21
20
  } from "./constants";
22
21
  import { NavigationActionsCreators } from "./interfaces";
23
22
 
@@ -80,8 +79,6 @@ export function reducer(state = initialState, action: any): INavigationState {
80
79
  case SET_COPY_MODULE:
81
80
  case SET_NAV_PAGES:
82
81
  return { ...state, ...action.payload };
83
- case RESET_DEFAULTS_STORE:
84
- return { ...initialState };
85
82
  default:
86
83
  return state;
87
84
  }
@@ -1133,7 +1133,10 @@ function updateBreadcrumb(editorID: number): any {
1133
1133
  const navigationIds = [header?.editorID, footer?.editorID];
1134
1134
  if (navigationIds.includes(editorID)) {
1135
1135
  const rootBreadcrumb = { editorID: 0, displayName: "Page", component: "Page" };
1136
- newBreadcrumb.unshift(rootBreadcrumb);
1136
+ const rootExists = newBreadcrumb.some(
1137
+ (breadcrumb: { editorID: number }) => breadcrumb.editorID === rootBreadcrumb.editorID
1138
+ );
1139
+ !rootExists && newBreadcrumb.unshift(rootBreadcrumb);
1137
1140
  }
1138
1141
 
1139
1142
  dispatch(setBreadcrumb(newBreadcrumb));
@@ -106,7 +106,7 @@ export function reducer(state = initialState, action: any): IPageEditorState {
106
106
  case SET_LAST_TIMEOUT:
107
107
  return { ...state, ...action.payload };
108
108
  case RESET_PAGE_EDITOR_STORE:
109
- return { ...initialState };
109
+ return { ...initialState, moduleCopy: state.moduleCopy };
110
110
  default:
111
111
  return state;
112
112
  }
@@ -481,7 +481,7 @@ const GlobalEditor = (props: IProps) => {
481
481
  />
482
482
  </S.NotificationWrapper>
483
483
  )}
484
- <ErrorToast size="l" />
484
+ <ErrorToast size="l" fixed />
485
485
  <S.Content>
486
486
  <Editor
487
487
  isGlobal={true}
@@ -11,7 +11,7 @@ const NotificationWrapper = styled.div`
11
11
  top: ${(p) => `calc(${p.theme.spacing.s} * 4)`};
12
12
  left: 0;
13
13
  right: 0;
14
- z-index: 3;
14
+ z-index: 4;
15
15
  `;
16
16
 
17
17
  const ModalContent = styled.div`
@@ -544,7 +544,7 @@ const PageEditor = (props: IProps) => {
544
544
  />
545
545
  </S.NotificationWrapper>
546
546
  )}
547
- <ErrorToast size="l" />
547
+ <ErrorToast size="l" fixed />
548
548
  <S.Content>
549
549
  <Editor
550
550
  isTemplateActivated={isTemplateActivated}
@@ -11,7 +11,7 @@ const NotificationWrapper = styled.div`
11
11
  top: ${(p) => `calc(${p.theme.spacing.s} * 4)`};
12
12
  left: 0;
13
13
  right: 0;
14
- z-index: 2;
14
+ z-index: 4;
15
15
  `;
16
16
 
17
17
  const ModalContent = styled.div`
@@ -54,5 +54,4 @@ const ModalContent = styled.div`
54
54
  }
55
55
  `;
56
56
 
57
-
58
57
  export { SiteWrapper, Wrapper, Title, IconsWrapper, StyledActionMenu, ModalContent };
@@ -154,9 +154,11 @@ const EmptyStateWrapper = styled.div`
154
154
  `;
155
155
 
156
156
  const ImageWrapper = styled.div<{ borderRadius?: boolean }>`
157
+ height: 199px;
157
158
  img {
158
159
  border-radius: ${(p) => (p.borderRadius ? p.theme.spacing.xs : 0)};
159
160
  object-fit: cover;
161
+ height: 100%;
160
162
  }
161
163
  `;
162
164