@griddo/ax 11.11.8-rc.1 → 11.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/config/jest/componentsMock.js +5 -7
  2. package/package.json +2 -2
  3. package/src/__tests__/components/Browser/Browser.test.tsx +87 -438
  4. package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +3 -1
  5. package/src/__tests__/components/Fields/Button/Button.test.tsx +27 -29
  6. package/src/__tests__/components/ResizePanel/ResizePanel.test.tsx +1 -1
  7. package/src/components/Browser/index.tsx +149 -294
  8. package/src/components/Browser/style.tsx +6 -75
  9. package/src/components/Button/index.tsx +1 -2
  10. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +4 -2
  11. package/src/components/Fields/AsyncSelect/style.tsx +0 -13
  12. package/src/components/Fields/FieldGroup/index.tsx +2 -5
  13. package/src/components/Fields/FieldGroup/style.tsx +7 -32
  14. package/src/components/Fields/HeadingField/index.tsx +2 -2
  15. package/src/components/Fields/HiddenField/style.tsx +1 -1
  16. package/src/components/Fields/NumberField/index.tsx +16 -15
  17. package/src/components/Fields/NumberField/style.tsx +0 -2
  18. package/src/components/Fields/ReferenceField/index.tsx +1 -1
  19. package/src/components/Fields/Select/index.tsx +1 -5
  20. package/src/components/Fields/Select/style.tsx +0 -56
  21. package/src/components/Fields/SummaryButton/index.tsx +9 -18
  22. package/src/components/Fields/SummaryButton/style.tsx +2 -1
  23. package/src/components/Fields/TagsField/index.tsx +9 -8
  24. package/src/components/Fields/UrlField/index.tsx +27 -26
  25. package/src/components/Fields/index.tsx +0 -2
  26. package/src/components/FloatingPanel/index.tsx +2 -5
  27. package/src/components/FloatingPanel/style.tsx +1 -2
  28. package/src/components/IconAction/index.tsx +1 -1
  29. package/src/components/MainWrapper/AppBar/index.tsx +1 -8
  30. package/src/components/MainWrapper/index.tsx +1 -7
  31. package/src/components/Notification/index.tsx +2 -2
  32. package/src/components/PageFinder/index.tsx +1 -1
  33. package/src/components/ResizePanel/index.tsx +3 -4
  34. package/src/components/ResizePanel/style.tsx +1 -1
  35. package/src/components/SearchField/style.tsx +2 -2
  36. package/src/components/SideModal/index.tsx +1 -2
  37. package/src/components/Tabs/index.tsx +4 -13
  38. package/src/components/Tabs/style.tsx +8 -7
  39. package/src/components/Toast/index.tsx +2 -4
  40. package/src/components/Tooltip/index.tsx +3 -4
  41. package/src/components/index.tsx +0 -8
  42. package/src/forms/fields.tsx +68 -70
  43. package/src/hooks/forms.tsx +1 -22
  44. package/src/hooks/index.tsx +3 -13
  45. package/src/hooks/modals.tsx +15 -103
  46. package/src/hooks/users.tsx +8 -25
  47. package/src/modules/Forms/atoms.tsx +2 -2
  48. package/src/modules/FramePreview/index.tsx +16 -55
  49. package/src/modules/FramePreview/style.tsx +2 -34
  50. package/src/modules/GlobalEditor/Editor/index.tsx +3 -37
  51. package/src/modules/GlobalEditor/PageBrowser/index.tsx +2 -19
  52. package/src/modules/GlobalEditor/Preview/index.tsx +2 -0
  53. package/src/modules/GlobalEditor/Preview/style.tsx +1 -1
  54. package/src/modules/GlobalEditor/index.tsx +57 -119
  55. package/src/modules/PageEditor/Editor/index.tsx +2 -33
  56. package/src/modules/PageEditor/PageBrowser/index.tsx +2 -20
  57. package/src/modules/PageEditor/Preview/index.tsx +2 -0
  58. package/src/modules/PageEditor/Preview/style.tsx +1 -1
  59. package/src/modules/PageEditor/atoms.tsx +1 -1
  60. package/src/modules/PageEditor/index.tsx +66 -130
  61. package/src/modules/PublicPreview/index.tsx +2 -5
  62. package/src/schemas/pages/GlobalPage.ts +70 -87
  63. package/src/schemas/pages/Page.ts +70 -87
  64. package/src/types/index.tsx +0 -12
  65. package/src/__tests__/components/Browser/Browser.utils.test.ts +0 -55
  66. package/src/__tests__/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/ErrorItem.test.tsx +0 -158
  67. package/src/__tests__/components/HeadingsPreviewModal/ErrorsBanner/ErrorsBanner.test.tsx +0 -90
  68. package/src/__tests__/components/HeadingsPreviewModal/HeadingsPreviewModal.test.tsx +0 -178
  69. package/src/__tests__/components/HeadingsPreviewModal/HeadingsPreviewModal.utils.test.tsx +0 -150
  70. package/src/__tests__/components/KeywordsPreviewModal/KeywordItem/KeywordItem.test.tsx +0 -91
  71. package/src/__tests__/components/KeywordsPreviewModal/KeywordsPreviewModal.test.tsx +0 -122
  72. package/src/__tests__/components/KeywordsPreviewModal/KeywordsPreviewModal.utils.test.ts +0 -15
  73. package/src/__tests__/components/KeywordsPreviewModal/atoms.test.tsx +0 -101
  74. package/src/__tests__/modules/FramePreview/FramePreview.test.tsx +0 -318
  75. package/src/__tests__/modules/FramePreview/FramePreview.utils.test.ts +0 -242
  76. package/src/__tests__/modules/FramePreview/HeadingsOverlay/HeadingsOverlay.test.tsx +0 -185
  77. package/src/components/Browser/utils.tsx +0 -13
  78. package/src/components/Fields/SEOPreview/index.tsx +0 -36
  79. package/src/components/Fields/SEOPreview/style.tsx +0 -24
  80. package/src/components/FloatingNote/index.tsx +0 -35
  81. package/src/components/FloatingNote/style.tsx +0 -26
  82. package/src/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/index.tsx +0 -85
  83. package/src/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/style.tsx +0 -80
  84. package/src/components/HeadingsPreviewModal/ErrorsBanner/index.tsx +0 -57
  85. package/src/components/HeadingsPreviewModal/ErrorsBanner/style.tsx +0 -82
  86. package/src/components/HeadingsPreviewModal/HeadingItem/index.tsx +0 -71
  87. package/src/components/HeadingsPreviewModal/HeadingItem/style.tsx +0 -77
  88. package/src/components/HeadingsPreviewModal/index.tsx +0 -146
  89. package/src/components/HeadingsPreviewModal/style.tsx +0 -82
  90. package/src/components/HeadingsPreviewModal/utils.tsx +0 -257
  91. package/src/components/KeywordsPreviewModal/KeywordItem/index.tsx +0 -46
  92. package/src/components/KeywordsPreviewModal/KeywordItem/style.tsx +0 -64
  93. package/src/components/KeywordsPreviewModal/atoms.tsx +0 -96
  94. package/src/components/KeywordsPreviewModal/index.tsx +0 -99
  95. package/src/components/KeywordsPreviewModal/style.tsx +0 -87
  96. package/src/components/KeywordsPreviewModal/utils.tsx +0 -22
  97. package/src/modules/FramePreview/HeadingsOverlay/index.tsx +0 -113
  98. package/src/modules/FramePreview/HeadingsOverlay/style.tsx +0 -24
  99. package/src/modules/FramePreview/utils.tsx +0 -140
@@ -1,22 +1,23 @@
1
- import { cleanup, fireEvent, render, screen } from "@testing-library/react";
2
- import { mock } from "jest-mock-extended";
1
+ import React from "react";
2
+
3
3
  import { ThemeProvider } from "styled-components";
4
+ import { mock } from "jest-mock-extended";
5
+ import { render, screen, cleanup, fireEvent } from "@testing-library/react";
4
6
  import "@testing-library/jest-dom";
5
7
 
6
- import Button, { type IButtonProps } from "@ax/components/Button";
8
+ import Button, { IButtonProps } from "@ax/components/Button";
7
9
  import { parseTheme } from "@ax/helpers";
8
10
  import globalTheme from "@ax/themes/theme.json";
9
11
 
10
12
  afterEach(cleanup);
11
13
 
12
- const createDefaultProps = (): IButtonProps => mock<IButtonProps>();
14
+ const defaultProps = mock<IButtonProps>();
13
15
 
14
16
  describe("Button component rendering", () => {
15
17
  it("should render the component with the default button and no icon", () => {
16
- const props = createDefaultProps();
17
18
  render(
18
19
  <ThemeProvider theme={parseTheme(globalTheme)}>
19
- <Button {...props} />
20
+ <Button {...defaultProps} />
20
21
  </ThemeProvider>,
21
22
  );
22
23
 
@@ -27,13 +28,12 @@ describe("Button component rendering", () => {
27
28
  });
28
29
 
29
30
  it("should render the component with the text button and an icon", () => {
30
- const props = createDefaultProps();
31
- props.buttonStyle = "text";
32
- props.icon = "delete";
31
+ defaultProps.buttonStyle = "text";
32
+ defaultProps.icon = "delete";
33
33
 
34
34
  render(
35
35
  <ThemeProvider theme={parseTheme(globalTheme)}>
36
- <Button {...props} />
36
+ <Button {...defaultProps} />
37
37
  </ThemeProvider>,
38
38
  );
39
39
 
@@ -44,11 +44,10 @@ describe("Button component rendering", () => {
44
44
  });
45
45
 
46
46
  it("should render the component with the line button", () => {
47
- const props = createDefaultProps();
48
- props.buttonStyle = "line";
47
+ defaultProps.buttonStyle = "line";
49
48
  render(
50
49
  <ThemeProvider theme={parseTheme(globalTheme)}>
51
- <Button {...props} />
50
+ <Button {...defaultProps} />
52
51
  </ThemeProvider>,
53
52
  );
54
53
 
@@ -57,12 +56,10 @@ describe("Button component rendering", () => {
57
56
  });
58
57
 
59
58
  it("should render the component with a className", () => {
60
- const props = createDefaultProps();
61
- props.className = "my-class";
62
- props.buttonStyle = "line";
59
+ defaultProps.className = "my-class";
63
60
  render(
64
61
  <ThemeProvider theme={parseTheme(globalTheme)}>
65
- <Button {...props} />
62
+ <Button {...defaultProps} />
66
63
  </ThemeProvider>,
67
64
  );
68
65
 
@@ -72,11 +69,10 @@ describe("Button component rendering", () => {
72
69
  });
73
70
 
74
71
  it("should render the children", () => {
75
- const props = createDefaultProps();
76
- props.children = "el texto";
72
+ defaultProps.children = "el texto";
77
73
  render(
78
74
  <ThemeProvider theme={parseTheme(globalTheme)}>
79
- <Button {...props} />
75
+ <Button {...defaultProps} />
80
76
  </ThemeProvider>,
81
77
  );
82
78
 
@@ -84,12 +80,13 @@ describe("Button component rendering", () => {
84
80
  });
85
81
 
86
82
  it("should trigger the onClick action", () => {
87
- const props = createDefaultProps();
88
- props.buttonStyle = "lineInverse";
89
- const handleOnClickMock = props.onClick as jest.MockedFunction<(e: React.MouseEvent<HTMLButtonElement>) => void>;
83
+ defaultProps.buttonStyle = "lineInverse";
84
+ const handleOnClickMock = defaultProps.onClick as jest.MockedFunction<
85
+ (e: React.MouseEvent<HTMLButtonElement>) => void
86
+ >;
90
87
  render(
91
88
  <ThemeProvider theme={parseTheme(globalTheme)}>
92
- <Button {...props} />
89
+ <Button {...defaultProps} />
93
90
  </ThemeProvider>,
94
91
  );
95
92
 
@@ -100,13 +97,14 @@ describe("Button component rendering", () => {
100
97
  });
101
98
 
102
99
  it("should not trigger the onClick action if the button is disabled", () => {
103
- const props = createDefaultProps();
104
- props.buttonStyle = "lineInverse";
105
- props.disabled = true;
106
- const handleOnClickMock = props.onClick as jest.MockedFunction<(e: React.MouseEvent<HTMLButtonElement>) => void>;
100
+ defaultProps.buttonStyle = "lineInverse";
101
+ defaultProps.disabled = true;
102
+ const handleOnClickMock = defaultProps.onClick as jest.MockedFunction<
103
+ (e: React.MouseEvent<HTMLButtonElement>) => void
104
+ >;
107
105
  render(
108
106
  <ThemeProvider theme={parseTheme(globalTheme)}>
109
- <Button {...props} />
107
+ <Button {...defaultProps} />
110
108
  </ThemeProvider>,
111
109
  );
112
110
 
@@ -151,6 +151,6 @@ describe("ResizePanel mouse events", () => {
151
151
  fireEvent.mouseUp(window);
152
152
 
153
153
  const width = getComputedStyle(rightPanel).width;
154
- expect(width).toBe("368px");
154
+ expect(width).toBe("344px");
155
155
  });
156
156
  });
@@ -1,36 +1,20 @@
1
- import { useEffect, useMemo, useRef, useState } from "react";
1
+ import { useEffect, useState } from "react";
2
2
 
3
3
  import type { IShareData } from "@ax/api";
4
4
  import { shareToken as shareTokenApi } from "@ax/api";
5
- import { BrowserContent, Icon, OcassionalToast, Select, SharePageModal, Toast, Tooltip } from "@ax/components";
5
+ import { OcassionalToast } from "@ax/components";
6
6
  import { findByEditorID } from "@ax/forms";
7
7
  import { DEV_NOW, getShareTokenInfo } from "@ax/helpers";
8
8
  import { useModal, useOnMessageReceivedFromIframe, useToast } from "@ax/hooks";
9
- import type { HeadingFilter } from "@ax/types";
10
9
 
11
- import { calcAutoZoom, calcDefaultResolution } from "./utils";
10
+ import BrowserContent from "../BrowserContent";
11
+ import Icon from "../Icon";
12
+ import SharePageModal from "../SharePageModal";
13
+ import Toast from "../Toast";
14
+ import Tooltip from "../Tooltip";
12
15
 
13
16
  import * as S from "./style";
14
17
 
15
- const DEFAULT_RESOLUTION = "1280px";
16
-
17
- const resolutionOptions = [
18
- { value: "1920px", label: "1920px" },
19
- { value: "1440px", label: "1440px" },
20
- { value: "1280px", label: "1280px" },
21
- { value: "1024px", label: "1024px" },
22
- { value: "768px", label: "768px" },
23
- { value: "360px", label: "360px" },
24
- ];
25
-
26
- const zoomOptions = [
27
- { value: "reset", label: "Reset" },
28
- { value: "100", label: "100%" },
29
- { value: "75", label: "75%" },
30
- { value: "50", label: "50%" },
31
- { value: "25", label: "25%" },
32
- ];
33
-
34
18
  const Browser = (props: IBrowserProps): JSX.Element => {
35
19
  const {
36
20
  url,
@@ -49,27 +33,15 @@ const Browser = (props: IBrowserProps): JSX.Element => {
49
33
  browserRef,
50
34
  actions,
51
35
  editorType = "page",
52
- headingFilter,
53
- keywordsFilter,
54
- toggleHeadingsPreview,
55
- toggleKeywordsPreview,
56
36
  } = props;
57
37
 
58
38
  const { id, entity, haveDraftPage } = content;
59
39
  const domain = window.location.origin;
60
- const headingFilterParam = !headingFilter || headingFilter === "all" ? "" : `&headingFilter=${headingFilter}`;
61
- const keywordsFilterParam = !keywordsFilter || !keywordsFilter.length ? "" : `&keywordFilter=${keywordsFilter}`;
40
+ const urlPreview = `${domain}/editor/page-preview?preview=${!!isPreview}&disabled=${!!disabled}&type=${editorType}`;
62
41
  const isPageEditor = editorType === "page";
63
42
  const isFormEditor = editorType === "form";
64
- const isHeadingsEditor = editorType === "headings";
65
- const isKeywordsEditor = editorType === "keywords";
66
43
 
67
- const frameWrapperRef = useRef<HTMLDivElement>(null);
68
-
69
- const [previewResolution, setPreviewResolution] = useState("desktop");
70
- const [dimensions, setDimensions] = useState({ resolution: DEFAULT_RESOLUTION, zoom: "100" });
71
-
72
- const urlPreview = `${domain}/editor/page-preview?preview=${!!isPreview}&disabled=${!!disabled}&type=${editorType}${headingFilterParam}${keywordsFilterParam}`;
44
+ const [resolution, setResolution] = useState("desktop");
73
45
  const { isVisible, toggleToast, setIsVisible, state: toastState } = useToast();
74
46
  const { isOpen: isShareOpen, toggleModal: toggleSharePageModal } = useModal(false, true);
75
47
  const [shareData, setShareData] = useState<IShareData | null>(null);
@@ -81,24 +53,6 @@ const Browser = (props: IBrowserProps): JSX.Element => {
81
53
  useEffect(() => {
82
54
  localStorage.setItem("selectedID", "0");
83
55
  (window as any).browserRef = null;
84
-
85
- const el = frameWrapperRef.current;
86
- if (!el) return;
87
-
88
- let lastWidth = 0;
89
- const observer = new ResizeObserver(([entry]) => {
90
- const containerWidth = entry.contentRect.width;
91
- if (containerWidth > 0 && Math.abs(containerWidth - lastWidth) > 20) {
92
- lastWidth = containerWidth;
93
- const resolution = calcDefaultResolution(containerWidth, resolutionOptions);
94
- const newZoom = calcAutoZoom(containerWidth, resolution);
95
- setDimensions({ resolution, zoom: newZoom });
96
- }
97
- });
98
-
99
- observer.observe(el);
100
-
101
- return () => observer.disconnect();
102
56
  }, []);
103
57
 
104
58
  // Fetch share data when in preview mode
@@ -131,254 +85,159 @@ const Browser = (props: IBrowserProps): JSX.Element => {
131
85
  }
132
86
  };
133
87
 
134
- const getWidth = (res: string) => {
135
- if (!isPreview) return dimensions.resolution;
136
-
137
- switch (res) {
138
- case "tablet":
139
- return "768px";
140
- case "phone":
141
- return "425px";
142
- default:
143
- return "100%";
144
- }
88
+ const deleteModuleSelected = (editorID: number) => {
89
+ actions?.setSelectedContentAction(0);
90
+ actions?.deleteModuleAction?.([editorID]);
145
91
  };
146
92
 
147
- const moduleActions = useMemo(
148
- () => ({
149
- deleteModuleAction: (editorID: number) => {
150
- actions?.setSelectedContentAction(0);
151
- actions?.deleteModuleAction?.([editorID]);
152
- },
153
- duplicateModuleAction: (editorID: number) => {
154
- const duplicatedEditorID = actions?.duplicateModuleAction?.([editorID]);
155
- duplicatedEditorID && actions?.setSelectedContentAction(duplicatedEditorID);
156
- },
157
- copyModuleAction: (editorID: number) => {
158
- const isCopied = actions?.copyModuleAction?.([editorID]);
159
- isCopied && toggleToast("1 module copied to clipboard");
160
- },
161
- }),
162
- [actions, toggleToast],
163
- );
164
-
165
- const maxFittingZoom = parseInt(calcAutoZoom(frameWrapperRef.current?.clientWidth ?? 0, dimensions.resolution));
166
- const zoomOptionsWithDisabled = useMemo(() => {
167
- const isCurrentZoomInOptions = zoomOptions.some((opt) => opt.value === dimensions.zoom);
168
- return [
169
- ...(!isCurrentZoomInOptions ? [{ value: dimensions.zoom, label: `${dimensions.zoom}%` }] : []),
170
- ...zoomOptions.map((option) => ({
171
- ...option,
172
- isDisabled: option.value === "reset" ? !isCurrentZoomInOptions : parseInt(option.value) > maxFittingZoom,
173
- })),
174
- ];
175
- }, [dimensions.zoom, maxFittingZoom]);
176
-
177
- const handleResolutionChange = (resolution: string) => {
178
- const containerWidth = frameWrapperRef.current?.clientWidth ?? 0;
179
- setDimensions({ resolution, zoom: calcAutoZoom(containerWidth, resolution) });
93
+ const duplicateModuleSelected = (editorID: number) => {
94
+ const duplicatedEditorID = actions?.duplicateModuleAction?.([editorID]);
95
+ duplicatedEditorID && actions?.setSelectedContentAction(duplicatedEditorID);
180
96
  };
181
97
 
182
- const handleZoomChange = (zoom: string) => {
183
- if (zoom === "reset") {
184
- const containerWidth = frameWrapperRef.current?.clientWidth ?? 0;
185
- setDimensions((prev) => ({ ...prev, zoom: calcAutoZoom(containerWidth, prev.resolution) }));
186
- } else {
187
- setDimensions((prev) => ({ ...prev, zoom }));
188
- }
98
+ const copyModuleSelected = (editorID: number) => {
99
+ const isCopied = actions?.copyModuleAction?.([editorID]);
100
+ isCopied && toggleToast("1 module copied to clipboard");
189
101
  };
190
102
 
191
- const scaledWidth = !isPreview
192
- ? Math.floor(parseInt(dimensions.resolution) * (parseInt(dimensions.zoom) / 100))
193
- : undefined;
194
-
195
- const isCompact = scaledWidth !== undefined && scaledWidth <= 400;
196
- const floatingNoteConfig = isHeadingsEditor
197
- ? { label: "Headings", onClick: toggleHeadingsPreview }
198
- : isKeywordsEditor
199
- ? { label: "Keywords", onClick: toggleKeywordsPreview }
200
- : null;
103
+ const moduleActions = {
104
+ deleteModuleAction: deleteModuleSelected,
105
+ duplicateModuleAction: duplicateModuleSelected,
106
+ copyModuleAction: copyModuleSelected,
107
+ };
201
108
 
202
109
  return (
203
- <S.OuterContainer ref={frameWrapperRef}>
204
- <S.BrowserWrapper data-testid="browser-wrapper" ref={browserRef} scaledWidth={scaledWidth} isPreview={isPreview}>
205
- {(isPageEditor || isHeadingsEditor || isKeywordsEditor) && (
206
- <S.NavBar>
207
- <S.NavUrl>{url}</S.NavUrl>
208
- {isPreview ? (
209
- <S.NavActions data-testid="nav-actions-wrapper">
210
- <S.IconWrapper
211
- data-testid="icon-wrapper-browser"
212
- onClick={haveDraftPage ? undefined : toggleSharePageModal}
213
- active={!haveDraftPage}
110
+ <S.BrowserWrapper data-testid="browser-wrapper" ref={browserRef}>
111
+ {isPageEditor && (
112
+ <S.NavBar>
113
+ <S.NavUrl>{url}</S.NavUrl>
114
+ {isPreview && (
115
+ <S.NavActions data-testid="nav-actions-wrapper">
116
+ <S.IconWrapper
117
+ data-testid="icon-wrapper-browser"
118
+ onClick={haveDraftPage ? undefined : toggleSharePageModal}
119
+ active={!haveDraftPage}
120
+ >
121
+ <Tooltip
122
+ hideOnClick={!haveDraftPage}
123
+ content={
124
+ haveDraftPage ? "Only available for drafts. This page already has a public URL." : "Share draft"
125
+ }
126
+ bottom
214
127
  >
215
- <Tooltip
216
- hideOnClick={!haveDraftPage}
217
- content={
218
- haveDraftPage ? "Only available for drafts. This page already has a public URL." : "Share draft"
219
- }
220
- bottom
221
- >
222
- <Icon name="share" size="24" />
223
- </Tooltip>
224
- </S.IconWrapper>
225
- <S.IconWrapper active={previewResolution === "desktop"} onClick={() => setPreviewResolution("desktop")}>
226
- <Tooltip content="Desktop" bottom>
227
- <Icon name="desktop" size="24" />
228
- </Tooltip>
229
- </S.IconWrapper>
230
- <S.IconWrapper
231
- data-testid="icon-res-tablet"
232
- active={previewResolution === "tablet"}
233
- onClick={() => setPreviewResolution("tablet")}
234
- >
235
- <Tooltip content="Tablet" bottom>
236
- <Icon name="tablet" size="24" />
237
- </Tooltip>
238
- </S.IconWrapper>
239
- <S.IconWrapper
240
- data-testid="icon-res-phone"
241
- active={previewResolution === "phone"}
242
- onClick={() => setPreviewResolution("phone")}
243
- >
244
- <Tooltip content="Mobile" bottom>
245
- <Icon name="phone" size="24" />
246
- </Tooltip>
247
- </S.IconWrapper>
248
- </S.NavActions>
249
- ) : (
250
- <S.NavActions data-testid="nav-actions-wrapper">
251
- <S.ResolutionWrapper>
252
- <S.SelectLabel>Screen</S.SelectLabel>
253
- <Select
254
- name="resolution"
255
- options={resolutionOptions}
256
- value={dimensions.resolution}
257
- onChange={handleResolutionChange}
258
- type="round"
259
- offSet="30%"
260
- mandatory
261
- />
262
- </S.ResolutionWrapper>
263
- <S.ZoomWrapper>
264
- <Select
265
- name="zoom"
266
- options={zoomOptionsWithDisabled}
267
- value={dimensions.zoom}
268
- onChange={handleZoomChange}
269
- type="round"
270
- mandatory
271
- />
272
- </S.ZoomWrapper>
273
- </S.NavActions>
274
- )}
275
- </S.NavBar>
276
- )}
277
- {showIframe ? (
278
- <S.ContentWrapper>
279
- {floatingNoteConfig && (
280
- <S.StyledFloatingNote
281
- message={`You are viewing the ${floatingNoteConfig.label} editor${isCompact ? "" : " of this page"}`}
282
- btnText={isCompact ? "Back" : "Back to Page Editor"}
283
- onClick={floatingNoteConfig.onClick}
284
- $compact={isCompact}
285
- />
286
- )}
287
- <S.FrameWrapper
288
- hasBorder={isPageEditor || isHeadingsEditor || isKeywordsEditor}
289
- isFormEditor={isFormEditor}
290
- data-testid="navbar-iframe-wrapper"
291
- >
292
- {isPreview ? (
293
- <iframe
294
- title="Preview"
295
- width={getWidth(previewResolution)}
296
- height="100%"
297
- src={urlPreview}
298
- loading="lazy"
299
- className="frame-content"
300
- />
301
- ) : (
302
- <div
303
- style={{
304
- width: `${scaledWidth}px`,
305
- height: "100%",
306
- overflow: "hidden",
307
- flexShrink: 0,
308
- }}
309
- >
310
- <iframe
311
- title="Preview"
312
- width={dimensions.resolution}
313
- src={urlPreview}
314
- loading="lazy"
315
- className="frame-content"
316
- style={{
317
- display: "block",
318
- transform: `scale(${parseInt(dimensions.zoom) / 100})`,
319
- transformOrigin: "0 0",
320
- height: `${Math.round(100 / (parseInt(dimensions.zoom) / 100))}%`,
321
- }}
322
- />
323
- </div>
324
- )}
325
- </S.FrameWrapper>
326
- </S.ContentWrapper>
327
- ) : (
328
- <S.Wrapper data-testid="browser-content-wrapper" className="browser-content">
329
- <BrowserContent
330
- cloudinaryName={cloudinaryName}
331
- theme={theme}
332
- socials={socials}
333
- siteLangs={siteLangs}
334
- selectEditorID={selectEditorID}
335
- siteID={siteID}
336
- isPage={isPage}
337
- content={content}
338
- header={header}
339
- footer={footer}
340
- languageID={content.language}
341
- pageLanguages={content.pageLanguages}
342
- moduleActions={moduleActions}
343
- renderer="editor"
344
- />
345
- </S.Wrapper>
346
- )}
347
- {isVisible && <Toast message={toastState} setIsVisible={setIsVisible} />}
348
- {isPreview && shareData && tokenInfo && (
349
- <OcassionalToast
350
- message={
351
- <>
352
- {tokenInfo.tokenHasExpired
353
- ? `Access to this draft link expired on ${tokenInfo.tokenExpirationDate}. You need to generate a `
354
- : `This draft link expires on ${tokenInfo.tokenExpirationDate}. ${tokenInfo.tokenCanBeRenewed ? "Renew it" : "Open details"}${" "}`}
355
- <button type="button" onClick={toggleSharePageModal}>
356
- <strong style={{ textDecoration: "underline" }}>
357
- {tokenInfo.tokenHasExpired ? "new one" : "here"}
358
- </strong>
359
- </button>
360
- </>
361
- }
362
- icon={tokenInfo.tokenHasExpired ? "hide" : "view"}
128
+ <Icon name="share" size="24" />
129
+ </Tooltip>
130
+ </S.IconWrapper>
131
+ <S.IconWrapper active={resolution === "desktop"} onClick={() => setResolution("desktop")}>
132
+ <Tooltip content="Desktop" bottom>
133
+ <Icon name="desktop" size="24" />
134
+ </Tooltip>
135
+ </S.IconWrapper>
136
+ <S.IconWrapper
137
+ data-testid="icon-res-tablet"
138
+ active={resolution === "tablet"}
139
+ onClick={() => setResolution("tablet")}
140
+ >
141
+ <Tooltip content="Tablet" bottom>
142
+ <Icon name="tablet" size="24" />
143
+ </Tooltip>
144
+ </S.IconWrapper>
145
+ <S.IconWrapper
146
+ data-testid="icon-res-phone"
147
+ active={resolution === "phone"}
148
+ onClick={() => setResolution("phone")}
149
+ >
150
+ <Tooltip content="Mobile" bottom>
151
+ <Icon name="phone" size="24" />
152
+ </Tooltip>
153
+ </S.IconWrapper>
154
+ </S.NavActions>
155
+ )}
156
+ </S.NavBar>
157
+ )}
158
+
159
+ {showIframe ? (
160
+ <S.FrameWrapper hasBorder={isPageEditor} isFormEditor={isFormEditor} data-testid="navbar-iframe-wrapper">
161
+ <iframe
162
+ title="Preview"
163
+ width={getWidth(resolution)}
164
+ height="100%"
165
+ src={urlPreview}
166
+ loading="lazy"
167
+ className="frame-content"
363
168
  />
364
- )}
365
-
366
- {isPreview && (
367
- <SharePageModal
368
- pageTitle={content.title}
369
- isOpen={isShareOpen}
370
- hide={toggleSharePageModal}
371
- pageID={id}
372
- entity={entity}
373
- shareData={shareData}
374
- onShareChange={setShareData}
169
+ </S.FrameWrapper>
170
+ ) : (
171
+ <S.Wrapper
172
+ data-testid="browser-content-wrapper"
173
+ // biome-ignore lint/suspicious/noAssignInExpressions: TODO: fix this
174
+ ref={(ref: any) => ((window as any).browserRef = ref)}
175
+ className="browser-content"
176
+ >
177
+ <BrowserContent
178
+ cloudinaryName={cloudinaryName}
179
+ theme={theme}
180
+ socials={socials}
181
+ siteLangs={siteLangs}
182
+ selectEditorID={selectEditorID}
183
+ siteID={siteID}
184
+ isPage={isPage}
185
+ content={content}
186
+ header={header}
187
+ footer={footer}
188
+ languageID={content.language}
189
+ pageLanguages={content.pageLanguages}
190
+ moduleActions={moduleActions}
191
+ renderer="editor"
375
192
  />
376
- )}
377
- </S.BrowserWrapper>
378
- </S.OuterContainer>
193
+ </S.Wrapper>
194
+ )}
195
+
196
+ {isVisible && <Toast message={toastState} setIsVisible={setIsVisible} />}
197
+
198
+ {isPreview && shareData && tokenInfo && (
199
+ <OcassionalToast
200
+ message={
201
+ <>
202
+ {tokenInfo.tokenHasExpired
203
+ ? `Access to this draft link expired on ${tokenInfo.tokenExpirationDate}. You need to generate a `
204
+ : `This draft link expires on ${tokenInfo.tokenExpirationDate}. ${tokenInfo.tokenCanBeRenewed ? "Renew it" : "Open details"}${" "}`}
205
+ <button type="button" onClick={toggleSharePageModal}>
206
+ <strong style={{ textDecoration: "underline" }}>
207
+ {tokenInfo.tokenHasExpired ? "new one" : "here"}
208
+ </strong>
209
+ </button>
210
+ </>
211
+ }
212
+ icon={tokenInfo.tokenHasExpired ? "hide" : "view"}
213
+ />
214
+ )}
215
+
216
+ {isPreview && (
217
+ <SharePageModal
218
+ pageTitle={content.title}
219
+ isOpen={isShareOpen}
220
+ hide={toggleSharePageModal}
221
+ pageID={id}
222
+ entity={entity}
223
+ shareData={shareData}
224
+ onShareChange={setShareData}
225
+ />
226
+ )}
227
+ </S.BrowserWrapper>
379
228
  );
380
229
  };
381
230
 
231
+ function getWidth(res: string) {
232
+ switch (res) {
233
+ case "tablet":
234
+ return "768px";
235
+ case "phone":
236
+ return "425px";
237
+ default:
238
+ return "100%";
239
+ }
240
+ }
382
241
  export interface IBrowserProps {
383
242
  content: any;
384
243
  header?: any;
@@ -394,11 +253,7 @@ export interface IBrowserProps {
394
253
  isPreview?: boolean;
395
254
  showIframe?: boolean;
396
255
  browserRef?: React.RefObject<HTMLDivElement>;
397
- editorType?: "form" | "page" | "headings" | "keywords";
398
- headingFilter?: HeadingFilter;
399
- keywordsFilter?: string[];
400
- toggleHeadingsPreview?(): void;
401
- toggleKeywordsPreview?(): void;
256
+ editorType?: "form" | "page";
402
257
  actions?: {
403
258
  setSelectedContentAction(editorID: number): void;
404
259
  deleteModuleAction?(editorID: number[]): void;