@griddo/ax 11.11.7 → 11.11.8-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/config/jest/componentsMock.js +7 -5
  2. package/package.json +2 -2
  3. package/src/__tests__/components/Browser/Browser.test.tsx +438 -87
  4. package/src/__tests__/components/Browser/Browser.utils.test.ts +55 -0
  5. package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +1 -3
  6. package/src/__tests__/components/Fields/Button/Button.test.tsx +29 -27
  7. package/src/__tests__/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/ErrorItem.test.tsx +158 -0
  8. package/src/__tests__/components/HeadingsPreviewModal/ErrorsBanner/ErrorsBanner.test.tsx +90 -0
  9. package/src/__tests__/components/HeadingsPreviewModal/HeadingsPreviewModal.test.tsx +178 -0
  10. package/src/__tests__/components/HeadingsPreviewModal/HeadingsPreviewModal.utils.test.tsx +150 -0
  11. package/src/__tests__/components/KeywordsPreviewModal/KeywordItem/KeywordItem.test.tsx +91 -0
  12. package/src/__tests__/components/KeywordsPreviewModal/KeywordsPreviewModal.test.tsx +122 -0
  13. package/src/__tests__/components/KeywordsPreviewModal/KeywordsPreviewModal.utils.test.ts +15 -0
  14. package/src/__tests__/components/KeywordsPreviewModal/atoms.test.tsx +101 -0
  15. package/src/__tests__/components/ResizePanel/ResizePanel.test.tsx +1 -1
  16. package/src/__tests__/modules/FramePreview/FramePreview.test.tsx +318 -0
  17. package/src/__tests__/modules/FramePreview/FramePreview.utils.test.ts +242 -0
  18. package/src/__tests__/modules/FramePreview/HeadingsOverlay/HeadingsOverlay.test.tsx +185 -0
  19. package/src/components/Browser/index.tsx +294 -144
  20. package/src/components/Browser/style.tsx +75 -6
  21. package/src/components/Browser/utils.tsx +13 -0
  22. package/src/components/BrowserContent/index.tsx +2 -2
  23. package/src/components/Button/index.tsx +2 -1
  24. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +2 -4
  25. package/src/components/Fields/AsyncSelect/style.tsx +13 -0
  26. package/src/components/Fields/FieldGroup/index.tsx +5 -2
  27. package/src/components/Fields/FieldGroup/style.tsx +32 -7
  28. package/src/components/Fields/HeadingField/index.tsx +2 -2
  29. package/src/components/Fields/HiddenField/style.tsx +1 -1
  30. package/src/components/Fields/NumberField/index.tsx +15 -16
  31. package/src/components/Fields/NumberField/style.tsx +2 -0
  32. package/src/components/Fields/ReferenceField/index.tsx +1 -1
  33. package/src/components/Fields/SEOPreview/index.tsx +36 -0
  34. package/src/components/Fields/SEOPreview/style.tsx +24 -0
  35. package/src/components/Fields/Select/index.tsx +5 -1
  36. package/src/components/Fields/Select/style.tsx +56 -0
  37. package/src/components/Fields/SummaryButton/index.tsx +18 -9
  38. package/src/components/Fields/SummaryButton/style.tsx +1 -2
  39. package/src/components/Fields/TagsField/index.tsx +8 -9
  40. package/src/components/Fields/UrlField/index.tsx +26 -27
  41. package/src/components/Fields/index.tsx +2 -0
  42. package/src/components/FloatingNote/index.tsx +35 -0
  43. package/src/components/FloatingNote/style.tsx +26 -0
  44. package/src/components/FloatingPanel/index.tsx +5 -2
  45. package/src/components/FloatingPanel/style.tsx +2 -1
  46. package/src/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/index.tsx +85 -0
  47. package/src/components/HeadingsPreviewModal/ErrorsBanner/ErrorItem/style.tsx +80 -0
  48. package/src/components/HeadingsPreviewModal/ErrorsBanner/index.tsx +57 -0
  49. package/src/components/HeadingsPreviewModal/ErrorsBanner/style.tsx +82 -0
  50. package/src/components/HeadingsPreviewModal/HeadingItem/index.tsx +71 -0
  51. package/src/components/HeadingsPreviewModal/HeadingItem/style.tsx +77 -0
  52. package/src/components/HeadingsPreviewModal/index.tsx +146 -0
  53. package/src/components/HeadingsPreviewModal/style.tsx +82 -0
  54. package/src/components/HeadingsPreviewModal/utils.tsx +257 -0
  55. package/src/components/IconAction/index.tsx +1 -1
  56. package/src/components/KeywordsPreviewModal/KeywordItem/index.tsx +46 -0
  57. package/src/components/KeywordsPreviewModal/KeywordItem/style.tsx +64 -0
  58. package/src/components/KeywordsPreviewModal/atoms.tsx +96 -0
  59. package/src/components/KeywordsPreviewModal/index.tsx +99 -0
  60. package/src/components/KeywordsPreviewModal/style.tsx +87 -0
  61. package/src/components/KeywordsPreviewModal/utils.tsx +22 -0
  62. package/src/components/MainWrapper/AppBar/index.tsx +8 -1
  63. package/src/components/MainWrapper/index.tsx +7 -1
  64. package/src/components/Notification/index.tsx +2 -2
  65. package/src/components/OcassionalToast/index.tsx +8 -1
  66. package/src/components/OcassionalToast/style.tsx +15 -1
  67. package/src/components/PageFinder/index.tsx +1 -1
  68. package/src/components/ResizePanel/index.tsx +4 -3
  69. package/src/components/ResizePanel/style.tsx +1 -1
  70. package/src/components/SearchField/style.tsx +2 -2
  71. package/src/components/SideModal/index.tsx +2 -1
  72. package/src/components/Tabs/index.tsx +13 -4
  73. package/src/components/Tabs/style.tsx +7 -8
  74. package/src/components/Toast/index.tsx +4 -2
  75. package/src/components/Tooltip/index.tsx +4 -3
  76. package/src/components/index.tsx +8 -2
  77. package/src/forms/fields.tsx +70 -68
  78. package/src/hooks/forms.tsx +22 -1
  79. package/src/hooks/index.tsx +13 -3
  80. package/src/hooks/modals.tsx +103 -15
  81. package/src/hooks/users.tsx +25 -8
  82. package/src/modules/Forms/atoms.tsx +2 -2
  83. package/src/modules/FramePreview/HeadingsOverlay/index.tsx +113 -0
  84. package/src/modules/FramePreview/HeadingsOverlay/style.tsx +24 -0
  85. package/src/modules/FramePreview/index.tsx +55 -16
  86. package/src/modules/FramePreview/style.tsx +34 -2
  87. package/src/modules/FramePreview/utils.tsx +140 -0
  88. package/src/modules/GlobalEditor/Editor/index.tsx +37 -3
  89. package/src/modules/GlobalEditor/PageBrowser/index.tsx +19 -2
  90. package/src/modules/GlobalEditor/Preview/index.tsx +0 -2
  91. package/src/modules/GlobalEditor/Preview/style.tsx +1 -1
  92. package/src/modules/GlobalEditor/index.tsx +119 -57
  93. package/src/modules/PageEditor/Editor/index.tsx +33 -2
  94. package/src/modules/PageEditor/PageBrowser/index.tsx +20 -2
  95. package/src/modules/PageEditor/Preview/index.tsx +0 -2
  96. package/src/modules/PageEditor/Preview/style.tsx +1 -1
  97. package/src/modules/PageEditor/atoms.tsx +1 -1
  98. package/src/modules/PageEditor/index.tsx +130 -66
  99. package/src/modules/PublicPreview/index.tsx +8 -5
  100. package/src/schemas/pages/GlobalPage.ts +87 -70
  101. package/src/schemas/pages/Page.ts +87 -70
  102. package/src/types/index.tsx +12 -0
  103. package/src/components/PageInfoBanner/index.tsx +0 -38
  104. package/src/components/PageInfoBanner/styles.tsx +0 -40
@@ -1,3 +1,4 @@
1
+ import { useEffect } from "react";
1
2
  import { connect } from "react-redux";
2
3
 
3
4
  import { BrowserContent, Loading, Toast } from "@ax/components";
@@ -8,6 +9,9 @@ import { getDefaultTheme } from "@ax/helpers";
8
9
  import { useOnMessageReceivedFromOutside, useToast, useURLSearchParam } from "@ax/hooks";
9
10
  import type { FormContent, ILanguage, IRootState, ISite, ISocialState } from "@ax/types";
10
11
 
12
+ import HeadingsOverlay from "./HeadingsOverlay";
13
+ import { observeAndAddIdsToHeadings, observeAndHighlightKeywords } from "./utils";
14
+
11
15
  import * as S from "./style";
12
16
 
13
17
  const FramePreview = (props: IProps) => {
@@ -29,11 +33,19 @@ const FramePreview = (props: IProps) => {
29
33
  copyModule,
30
34
  } = props;
31
35
 
32
- const isPreview = useURLSearchParam("preview");
33
- const isDisabled = useURLSearchParam("disabled");
36
+ const previewParam = useURLSearchParam("preview");
37
+ const disabledParam = useURLSearchParam("disabled");
34
38
  const type = useURLSearchParam("type");
35
- document.body.classList.add("preview");
39
+ const headingFilter = useURLSearchParam("headingFilter");
40
+ const keywordFilter = useURLSearchParam("keywordFilter");
41
+
42
+ const isPreviewMode = previewParam === "true";
43
+ const isDisabled = disabledParam === "true";
36
44
  const isForm = type === "form";
45
+ const isHeadingsEditor = type === "headings";
46
+ const isKeywordsEditor = type === "keywords";
47
+ const keywords: string[] = pageContent?.metaKeywords || [];
48
+ const filteredKeywords = keywordFilter ? [keywordFilter] : keywords;
37
49
  const setSelectedContent = isForm ? setSelectedFormContent : setSelectedPageContent;
38
50
  const setContent = isForm ? setFormContent : setEditorContent;
39
51
  const content = isForm ? formContent : pageContent;
@@ -42,15 +54,40 @@ const FramePreview = (props: IProps) => {
42
54
  const { isVisible, toggleToast, setIsVisible, state: toastState } = useToast();
43
55
  useOnMessageReceivedFromOutside(setContent, setSelectedContent);
44
56
 
45
- window.addEventListener("mousemove", (e) => {
46
- window.parent.postMessage(
47
- {
48
- type: "iframe-mousemove",
49
- clientX: e.clientX,
50
- },
51
- "*",
52
- );
53
- });
57
+ useEffect(() => {
58
+ document.body.classList.add("preview");
59
+
60
+ const handleMouseMove = (e: MouseEvent) => {
61
+ window.parent.postMessage(
62
+ {
63
+ type: "iframe-mousemove",
64
+ clientX: e.clientX,
65
+ },
66
+ "*",
67
+ );
68
+ };
69
+
70
+ window.addEventListener("mousemove", handleMouseMove);
71
+ return () => window.removeEventListener("mousemove", handleMouseMove);
72
+ }, []);
73
+
74
+ useEffect(() => {
75
+ if (isDisabled) {
76
+ localStorage.setItem("selectedID", "0");
77
+ }
78
+ }, [isDisabled]);
79
+
80
+ useEffect(() => {
81
+ if (isHeadingsEditor) {
82
+ return observeAndAddIdsToHeadings(document.body, headingFilter);
83
+ }
84
+ }, [isHeadingsEditor, headingFilter]);
85
+
86
+ useEffect(() => {
87
+ if (isKeywordsEditor) {
88
+ return observeAndHighlightKeywords(document.body, filteredKeywords);
89
+ }
90
+ }, [isKeywordsEditor, filteredKeywords]);
54
91
 
55
92
  const selectEditorID = (
56
93
  selectedComponent: { editorID: number; component: any; type: string; parentEditorID: number },
@@ -67,7 +104,7 @@ const FramePreview = (props: IProps) => {
67
104
 
68
105
  const isNavigationModule = ["header", "footer"].includes(selectedComponent.type);
69
106
 
70
- if (isPreview === "false" && (isDisabled === "false" || isNavigationModule)) {
107
+ if (!isPreviewMode && (!isDisabled || isNavigationModule)) {
71
108
  window.parent.postMessage({ type: "module-click", message: editorID }, "*");
72
109
  setSelectedContent?.(editorID);
73
110
  }
@@ -84,7 +121,7 @@ const FramePreview = (props: IProps) => {
84
121
  const theme = currentSiteInfo ? currentSiteInfo.theme : globalTheme;
85
122
  const langs = currentSiteInfo ? siteLangs : globalLangs;
86
123
  const siteID = currentSiteInfo ? currentSiteInfo.id : canonicalSite;
87
- const renderer = isForm ? "forms" : isPreview === "true" ? "preview" : "editor";
124
+ const renderer = isForm ? "forms" : isPreviewMode ? "preview" : "editor";
88
125
 
89
126
  const deleteModuleSelected = (editorID: number) => {
90
127
  window.parent.postMessage({ type: "module-delete", message: editorID }, "*");
@@ -112,8 +149,8 @@ const FramePreview = (props: IProps) => {
112
149
  if (isLoading) return <Loading />;
113
150
 
114
151
  return (
115
- // biome-ignore lint/suspicious/noAssignInExpressions: TODO: fix this
116
- <S.Wrapper ref={(ref: any) => ((window as any).browserRef = ref)}>
152
+ <S.Wrapper>
153
+ <S.GlobalScrollStyle />
117
154
  <BrowserContent
118
155
  cloudinaryName={cloudinaryName}
119
156
  theme={theme}
@@ -131,6 +168,8 @@ const FramePreview = (props: IProps) => {
131
168
  renderer={renderer}
132
169
  selectHoverEditorID={selectHoverEditorID}
133
170
  />
171
+ {isHeadingsEditor && <S.Velo />}
172
+ {isHeadingsEditor && <HeadingsOverlay headingFilter={headingFilter} />}
134
173
  {isVisible && <Toast message={toastState} setIsVisible={setIsVisible} />}
135
174
  </S.Wrapper>
136
175
  );
@@ -1,4 +1,20 @@
1
- import styled from "styled-components";
1
+ import styled, { createGlobalStyle } from "styled-components";
2
+
3
+ const GlobalScrollStyle = createGlobalStyle`
4
+ body.preview {
5
+ overflow-x: hidden;
6
+ }
7
+
8
+ body.preview::-webkit-scrollbar {
9
+ -webkit-appearance: none;
10
+ width: 4px;
11
+ }
12
+
13
+ body.preview::-webkit-scrollbar-thumb {
14
+ border-radius: 4px;
15
+ background-color: ${(p: any) => p.theme.colors.iconNonActive};
16
+ }
17
+ `;
2
18
 
3
19
  const Wrapper = styled.div`
4
20
  scroll-behavior: smooth;
@@ -12,6 +28,22 @@ const Wrapper = styled.div`
12
28
  body.preview:not(&) {
13
29
  min-width: 0 !important;
14
30
  }
31
+
32
+ .gdd-keyword {
33
+ background-color: #FFEF9A !important;
34
+ color: #1C1547 !important;
35
+ padding: ${(p) => `0 ${p.theme.spacing.xxs}`};
36
+ }
37
+ `;
38
+
39
+ const Velo = styled.div`
40
+ position: fixed;
41
+ top: 0;
42
+ left: 0;
43
+ height: 100%;
44
+ right: 0;
45
+ background: rgba(255, 255, 255, 0.4);
46
+ z-index: 1000;
15
47
  `;
16
48
 
17
- export { Wrapper };
49
+ export { Wrapper, Velo, GlobalScrollStyle };
@@ -0,0 +1,140 @@
1
+ const addIdsToHeadings = (container: HTMLElement, headingFilter: string | null): void => {
2
+ const selected = headingFilter ? headingFilter : "h1, h2, h3, h4, h5, h6";
3
+ const headings = container.querySelectorAll<HTMLElement>(selected);
4
+
5
+ headings.forEach((heading, index) => {
6
+ const text = heading.textContent?.trim();
7
+ if (!text) return;
8
+
9
+ heading.dataset.griddoid = `heading-${index + 1}`;
10
+ });
11
+ };
12
+
13
+ const observeAndAddIdsToHeadings = (container: HTMLElement, headingFilter: string | null): (() => void) => {
14
+ addIdsToHeadings(container, headingFilter);
15
+
16
+ const observer = new MutationObserver(() => {
17
+ addIdsToHeadings(container, headingFilter);
18
+ });
19
+
20
+ observer.observe(container, {
21
+ childList: true,
22
+ subtree: true,
23
+ });
24
+
25
+ return () => observer.disconnect();
26
+ };
27
+
28
+ const KEYWORD_HIGHLIGHT_CLASS = "gdd-keyword";
29
+
30
+ const removeKeywordHighlights = (container: HTMLElement): void => {
31
+ const marks = container.querySelectorAll<HTMLElement>(`mark.${KEYWORD_HIGHLIGHT_CLASS}`);
32
+
33
+ marks.forEach((mark) => {
34
+ const parent = mark.parentNode;
35
+ if (!parent) return;
36
+ parent.replaceChild(document.createTextNode(mark.textContent || ""), mark);
37
+ parent.normalize();
38
+ });
39
+ };
40
+
41
+ const buildKeywordsRegex = (keywords: string[]): RegExp | null => {
42
+ const escapedKeywords = keywords
43
+ .filter((k) => k.trim())
44
+ .sort((a, b) => b.length - a.length)
45
+ .map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
46
+
47
+ if (!escapedKeywords.length) return null;
48
+
49
+ return new RegExp(`(${escapedKeywords.join("|")})`, "gi");
50
+ };
51
+
52
+ const collectTextNodes = (container: HTMLElement): Text[] => {
53
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, {
54
+ acceptNode: (node) => {
55
+ const parent = node.parentElement;
56
+ if (!parent) return NodeFilter.FILTER_REJECT;
57
+ if (["SCRIPT", "STYLE"].includes(parent.tagName)) return NodeFilter.FILTER_REJECT;
58
+ if (parent.classList.contains(KEYWORD_HIGHLIGHT_CLASS)) return NodeFilter.FILTER_REJECT;
59
+ return NodeFilter.FILTER_ACCEPT;
60
+ },
61
+ });
62
+
63
+ const textNodes: Text[] = [];
64
+ let current = walker.nextNode();
65
+ while (current) {
66
+ textNodes.push(current as Text);
67
+ current = walker.nextNode();
68
+ }
69
+
70
+ return textNodes;
71
+ };
72
+
73
+ const wrapMatches = (text: string, regex: RegExp): DocumentFragment => {
74
+ const fragment = document.createDocumentFragment();
75
+ let lastIndex = 0;
76
+ let match = regex.exec(text);
77
+
78
+ while (match !== null) {
79
+ if (match.index > lastIndex) {
80
+ fragment.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));
81
+ }
82
+
83
+ const mark = document.createElement("mark");
84
+ mark.className = KEYWORD_HIGHLIGHT_CLASS;
85
+ mark.textContent = match[0];
86
+ fragment.appendChild(mark);
87
+
88
+ lastIndex = regex.lastIndex;
89
+ match = regex.exec(text);
90
+ }
91
+
92
+ if (lastIndex < text.length) {
93
+ fragment.appendChild(document.createTextNode(text.slice(lastIndex)));
94
+ }
95
+
96
+ return fragment;
97
+ };
98
+
99
+ const highlightKeywords = (container: HTMLElement, keywords: string[]): void => {
100
+ removeKeywordHighlights(container);
101
+
102
+ const regex = buildKeywordsRegex(keywords);
103
+ if (!regex) return;
104
+
105
+ const textNodes = collectTextNodes(container);
106
+
107
+ for (const textNode of textNodes) {
108
+ const text = textNode.textContent || "";
109
+ if (!regex.test(text)) continue;
110
+ regex.lastIndex = 0;
111
+
112
+ const fragment = wrapMatches(text, regex);
113
+ textNode.parentNode?.replaceChild(fragment, textNode);
114
+ }
115
+ };
116
+
117
+ const observeAndHighlightKeywords = (container: HTMLElement, keywords: string[]): (() => void) => {
118
+ const observer = new MutationObserver(() => {
119
+ observer.disconnect();
120
+ highlightKeywords(container, keywords);
121
+ observer.observe(container, { childList: true, subtree: true });
122
+ });
123
+
124
+ highlightKeywords(container, keywords);
125
+ observer.observe(container, { childList: true, subtree: true });
126
+
127
+ return () => {
128
+ observer.disconnect();
129
+ removeKeywordHighlights(container);
130
+ };
131
+ };
132
+
133
+ export {
134
+ addIdsToHeadings,
135
+ observeAndAddIdsToHeadings,
136
+ highlightKeywords,
137
+ removeKeywordHighlights,
138
+ observeAndHighlightKeywords,
139
+ KEYWORD_HIGHLIGHT_CLASS,
140
+ };
@@ -1,8 +1,15 @@
1
- import React from "react";
2
1
  import { connect } from "react-redux";
3
2
  import { pageEditorActions } from "@ax/containers/PageEditor";
4
3
  import { ConfigPanel, ResizePanel } from "@ax/components";
5
- import { IBreadcrumbItem, IModule, INotification, IRootState, ISchema, IUserEditing } from "@ax/types";
4
+ import type {
5
+ HeadingFilter,
6
+ IBreadcrumbItem,
7
+ IModule,
8
+ INotification,
9
+ IRootState,
10
+ ISchema,
11
+ IUserEditing,
12
+ } from "@ax/types";
6
13
  import PageBrowser from "../PageBrowser";
7
14
 
8
15
  const Editor = (props: IProps) => {
@@ -33,6 +40,12 @@ const Editor = (props: IProps) => {
33
40
  setNotification,
34
41
  isEditLive,
35
42
  isDisabled,
43
+ toggleHeadingsPreview,
44
+ toggleKeywordsPreview,
45
+ isHeadingsPreviewOpen,
46
+ isKeywordsPreviewOpen,
47
+ headingsFilter,
48
+ keywordsFilter,
36
49
  } = props;
37
50
 
38
51
  const actions = {
@@ -46,11 +59,26 @@ const Editor = (props: IProps) => {
46
59
  copyModuleAction: copyModule,
47
60
  pasteModuleAction: pasteModule,
48
61
  setNotificationAction: setNotification,
62
+ toggleHeadingsPreviewAction: toggleHeadingsPreview,
63
+ toggleKeywordsPreviewAction: toggleKeywordsPreview,
49
64
  };
50
65
 
51
66
  return (
52
67
  <ResizePanel
53
- leftPanel={<PageBrowser isReadOnly={isReadOnly || isEditLive} theme={theme} browserRef={browserRef} />}
68
+ disabled={isHeadingsPreviewOpen || isKeywordsPreviewOpen}
69
+ leftPanel={
70
+ <PageBrowser
71
+ isReadOnly={isReadOnly || isEditLive}
72
+ theme={theme}
73
+ browserRef={browserRef}
74
+ isHeadingsPreviewOpen={isHeadingsPreviewOpen}
75
+ toggleHeadingsPreview={toggleHeadingsPreview}
76
+ headingsFilter={headingsFilter}
77
+ toggleKeywordsPreview={toggleKeywordsPreview}
78
+ isKeywordsPreviewOpen={isKeywordsPreviewOpen}
79
+ keywordsFilter={keywordsFilter}
80
+ />
81
+ }
54
82
  rightPanel={
55
83
  <ConfigPanel
56
84
  schema={schema}
@@ -100,6 +128,8 @@ interface IPageBrowserDispatchProps {
100
128
  copyModule(editorID: number[]): boolean | number;
101
129
  pasteModule(editorID: number, key: string, modulesToPaste: IModule[]): Promise<{ error?: INotification }>;
102
130
  setNotification: (notification: INotification) => void;
131
+ toggleHeadingsPreview: () => void;
132
+ toggleKeywordsPreview: () => void;
103
133
  isGlobal: boolean;
104
134
  isEditable: boolean;
105
135
  isReadOnly: boolean;
@@ -107,6 +137,10 @@ interface IPageBrowserDispatchProps {
107
137
  browserRef: any;
108
138
  isEditLive: boolean;
109
139
  isDisabled: boolean;
140
+ isHeadingsPreviewOpen: boolean;
141
+ isKeywordsPreviewOpen: boolean;
142
+ headingsFilter: HeadingFilter;
143
+ keywordsFilter: string[];
110
144
  }
111
145
 
112
146
  type IProps = IEditorStateProps & IPageBrowserDispatchProps;
@@ -1,8 +1,7 @@
1
1
  import { connect } from "react-redux";
2
2
  import { pageEditorActions } from "@ax/containers/PageEditor";
3
-
4
3
  import { Browser } from "@ax/components";
5
- import type { ILanguage, IRootState, ISchema, ISocialState } from "@ax/types";
4
+ import type { HeadingFilter, ILanguage, IRootState, ISchema, ISocialState } from "@ax/types";
6
5
 
7
6
  const PageBrowser = (props: IProps) => {
8
7
  const {
@@ -15,15 +14,22 @@ const PageBrowser = (props: IProps) => {
15
14
  isReadOnly,
16
15
  isPreview,
17
16
  browserRef,
17
+ isHeadingsPreviewOpen = false,
18
+ isKeywordsPreviewOpen = false,
19
+ headingsFilter,
20
+ keywordsFilter,
18
21
  deleteModule,
19
22
  duplicateModule,
20
23
  copyModule,
21
24
  setScrollEditorID,
25
+ toggleHeadingsPreview,
26
+ toggleKeywordsPreview,
22
27
  } = props;
23
28
 
24
29
  const slugWithSlash = slug ? (slug.startsWith("/") ? slug : `/${slug}`) : "";
25
30
  const pathWithoutSlash = path ? (path.endsWith("/") ? path.slice(0, -1) : path) : "";
26
31
  const url = `${pathWithoutSlash}${slugWithSlash}`;
32
+ const editorType = isHeadingsPreviewOpen ? "headings" : isKeywordsPreviewOpen ? "keywords" : "page";
27
33
 
28
34
  const actions = {
29
35
  deleteModuleAction: deleteModule,
@@ -48,6 +54,11 @@ const PageBrowser = (props: IProps) => {
48
54
  showIframe={true}
49
55
  browserRef={browserRef}
50
56
  actions={actions}
57
+ editorType={editorType}
58
+ toggleHeadingsPreview={toggleHeadingsPreview}
59
+ headingFilter={headingsFilter}
60
+ toggleKeywordsPreview={toggleKeywordsPreview}
61
+ keywordsFilter={keywordsFilter}
51
62
  />
52
63
  );
53
64
  };
@@ -68,10 +79,16 @@ interface IPageBrowserDispatchProps {
68
79
  isReadOnly: boolean;
69
80
  isPreview?: boolean;
70
81
  browserRef?: any;
82
+ isHeadingsPreviewOpen?: boolean;
83
+ isKeywordsPreviewOpen?: boolean;
84
+ headingsFilter?: HeadingFilter;
85
+ keywordsFilter?: string[];
71
86
  deleteModule(editorID: number[]): void;
72
87
  duplicateModule(editorID: number[]): number;
73
88
  copyModule(editorID: number[]): number | boolean;
74
89
  setScrollEditorID(editorID: number | null): void;
90
+ toggleHeadingsPreview?(): void;
91
+ toggleKeywordsPreview?(): void;
75
92
  }
76
93
 
77
94
  type IProps = IPageBrowserStateProps & IPageBrowserDispatchProps;
@@ -1,5 +1,3 @@
1
- import React from "react";
2
-
3
1
  import PageBrowser from "../PageBrowser";
4
2
  import * as S from "./style";
5
3
 
@@ -2,7 +2,7 @@ import styled from "styled-components";
2
2
 
3
3
  const BrowserWrapper = styled.div`
4
4
  background-color: ${(p) => p.theme.color.uiBackground01};
5
- height: calc(100% - 44px);
5
+ height: 100%;
6
6
  width: 100%;
7
7
  `;
8
8