@griddo/ax 1.61.7 → 1.62.2

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 (73) hide show
  1. package/package.json +2 -2
  2. package/src/components/ActionMenu/style.tsx +1 -0
  3. package/src/components/ConfigPanel/Form/ConnectedField/NavConnectedField/index.tsx +3 -1
  4. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +17 -2
  5. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/TemplateManager/index.tsx +3 -0
  6. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +3 -0
  7. package/src/components/ConfigPanel/Form/index.tsx +3 -1
  8. package/src/components/ConfigPanel/NavigationForm/Field/index.tsx +3 -1
  9. package/src/components/ConfigPanel/NavigationForm/index.tsx +3 -2
  10. package/src/components/ConfigPanel/index.tsx +4 -1
  11. package/src/components/ElementsTooltip/index.tsx +22 -8
  12. package/src/components/ElementsTooltip/style.tsx +6 -4
  13. package/src/components/FieldContainer/index.tsx +1 -0
  14. package/src/components/Fields/AnalyticsField/PageAnalytics/atoms.tsx +3 -2
  15. package/src/components/Fields/AnalyticsField/PageAnalytics/index.tsx +3 -3
  16. package/src/components/Fields/AnalyticsField/StructuredDataAnalytics/atoms.tsx +3 -2
  17. package/src/components/Fields/AnalyticsField/StructuredDataAnalytics/index.tsx +3 -3
  18. package/src/components/Fields/ColorPicker/index.tsx +28 -3
  19. package/src/components/Fields/ComponentArray/MixableComponentArray/AddItemButton/index.tsx +3 -1
  20. package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +4 -0
  21. package/src/components/Fields/ComponentArray/SameComponentArray/index.tsx +3 -0
  22. package/src/components/Fields/ComponentContainer/EmptyContainer/index.tsx +3 -1
  23. package/src/components/Fields/ComponentContainer/index.tsx +4 -0
  24. package/src/components/Fields/FieldGroup/index.tsx +4 -3
  25. package/src/components/Fields/FileField/index.tsx +0 -7
  26. package/src/components/Fields/ImageField/style.tsx +1 -0
  27. package/src/components/Fields/ReferenceField/AutoPanel/AutoItem/style.tsx +0 -1
  28. package/src/components/Fields/TextArea/index.tsx +14 -3
  29. package/src/components/Fields/VisualUniqueSelection/ImageSelection/index.tsx +8 -2
  30. package/src/components/Fields/VisualUniqueSelection/ScrollableSelection/index.tsx +8 -4
  31. package/src/components/Fields/VisualUniqueSelection/utils.tsx +30 -0
  32. package/src/components/Gallery/index.tsx +10 -4
  33. package/src/components/MainWrapper/AppBar/style.tsx +0 -2
  34. package/src/components/MainWrapper/style.tsx +5 -3
  35. package/src/components/SideModal/SideModalOption/index.tsx +5 -4
  36. package/src/components/SideModal/index.tsx +19 -14
  37. package/src/containers/Analytics/actions.tsx +23 -1
  38. package/src/containers/Analytics/reducer.tsx +2 -0
  39. package/src/containers/Sites/actions.tsx +15 -5
  40. package/src/forms/fields.tsx +7 -2
  41. package/src/helpers/images.tsx +2 -5
  42. package/src/helpers/index.tsx +6 -0
  43. package/src/helpers/schemas.tsx +14 -2
  44. package/src/helpers/thumbnails.tsx +3 -3
  45. package/src/modules/Analytics/DimensionItem/index.tsx +2 -2
  46. package/src/modules/Analytics/DimensionPanel/index.tsx +60 -33
  47. package/src/modules/Analytics/DimensionPanel/style.tsx +10 -1
  48. package/src/modules/Analytics/GroupPanel/index.tsx +22 -5
  49. package/src/modules/Analytics/GroupPanel/style.tsx +1 -1
  50. package/src/modules/Analytics/index.tsx +8 -8
  51. package/src/modules/App/Routing/NavMenu/style.tsx +2 -0
  52. package/src/modules/Content/OptionTable/index.tsx +5 -2
  53. package/src/modules/Content/PageItem/index.tsx +2 -2
  54. package/src/modules/Content/index.tsx +7 -3
  55. package/src/modules/GlobalEditor/Editor/index.tsx +5 -1
  56. package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/index.tsx +1 -1
  57. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/index.tsx +5 -1
  58. package/src/modules/PageEditor/Editor/index.tsx +5 -1
  59. package/src/modules/Settings/Analytics/atoms.tsx +132 -0
  60. package/src/modules/Settings/Analytics/index.tsx +109 -0
  61. package/src/modules/Settings/Analytics/style.tsx +107 -0
  62. package/src/modules/Settings/ContentTypes/DataPacks/AddModal/index.tsx +10 -4
  63. package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +30 -20
  64. package/src/modules/Settings/ContentTypes/DataPacks/Item/index.tsx +12 -6
  65. package/src/modules/StructuredData/Form/ConnectedField/index.tsx +4 -2
  66. package/src/modules/StructuredData/Form/index.tsx +16 -3
  67. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +1 -1
  68. package/src/modules/StructuredData/StructuredDataList/OptionTable/index.tsx +7 -1
  69. package/src/modules/StructuredData/StructuredDataList/index.tsx +2 -2
  70. package/src/routes/site.tsx +6 -0
  71. package/src/schemas/pages/GlobalPage.tsx +13 -2
  72. package/src/schemas/pages/Page.tsx +13 -2
  73. package/src/types/index.tsx +1 -0
@@ -2,20 +2,24 @@ import React, { useEffect, useState } from "react";
2
2
 
3
3
  import { IDimension } from "@ax/types";
4
4
  import { FloatingPanel, Button, FieldsBehavior, NoteField } from "@ax/components";
5
- import { camelize, splitAndJoin } from "@ax/helpers";
5
+ import { camelize, capitalize, splitAndJoin, splitCamelCase } from "@ax/helpers";
6
6
 
7
7
  import * as S from "./style";
8
8
 
9
9
  const DimensionPanel = (props: IProps): JSX.Element => {
10
10
  const { isOpen, toggleModal, item, setDimensionItem } = props;
11
11
 
12
- const [type, setType] = useState("dimensionsAndValues");
12
+ const isOnlyDimensions = item && ["", "null"].includes(item.values);
13
+ const typeInitialState = isOnlyDimensions ? "onlyDimensions" : "dimensionsAndValues";
14
+ const [type, setType] = useState(typeInitialState);
13
15
  const [name, setName] = useState("");
14
16
  const [values, setValues] = useState("");
17
+ const [errors, setErrors] = useState({ name: false, values: false });
15
18
 
16
19
  const resetState = () => {
17
- setType("dimensionsAndValues");
18
- setName(item?.name || "");
20
+ setType(typeInitialState);
21
+ setName(item ? splitCamelCase(item.name) : "");
22
+ setErrors({ name: false, values: false });
19
23
 
20
24
  const values = splitAndJoin(item?.values, ";", ";");
21
25
  const _values = values === "null" ? "" : values;
@@ -32,15 +36,29 @@ const DimensionPanel = (props: IProps): JSX.Element => {
32
36
  }, [type]);
33
37
 
34
38
  const editItemAction = () => {
35
- setDimensionItem({ ...item, name: camelize(name), values });
39
+ setDimensionItem({
40
+ ...item,
41
+ name: capitalize(camelize(name)),
42
+ values
43
+ });
36
44
  toggleModal();
37
45
  };
38
46
 
47
+ const validateFields = () => {
48
+ const errorFields = {
49
+ name: !name.length,
50
+ values: type === "dimensionsAndValues" && !values.length
51
+ }
52
+ setErrors(errorFields);
53
+ const isFieldsValid = Object.values(errorFields).every((error) => !error);
54
+ isFieldsValid && editItemAction();
55
+ }
56
+
39
57
  const title = item ? "Update Dimension" : "Add Dimension";
40
58
 
41
59
  const editButton = {
42
60
  label: title,
43
- action: editItemAction,
61
+ action: validateFields,
44
62
  };
45
63
 
46
64
  const typeOptions = [
@@ -61,36 +79,45 @@ const DimensionPanel = (props: IProps): JSX.Element => {
61
79
 
62
80
  return (
63
81
  <FloatingPanel title={title} toggleModal={toggleModal} isOpen={isOpen}>
64
- <FieldsBehavior
65
- name="removeItemChildren"
66
- fieldType="RadioGroup"
67
- title="Dimension type"
68
- value={type}
69
- options={typeOptions}
70
- onChange={setType}
71
- mandatory
72
- />
73
- <S.NoteWrapper>
74
- <NoteField value={{ text: noteText, title: noteTitle }} />
75
- </S.NoteWrapper>
76
- <FieldsBehavior
77
- title="Dimension"
78
- name="name"
79
- fieldType="TextField"
80
- value={name}
81
- onChange={setName}
82
- mandatory
83
- />
84
- {type === "dimensionsAndValues" ? (
82
+ <S.ContentWrapper>
83
+ <FieldsBehavior
84
+ name="removeItemChildren"
85
+ fieldType="RadioGroup"
86
+ title="Dimension type"
87
+ value={type}
88
+ options={typeOptions}
89
+ onChange={setType}
90
+ mandatory
91
+ />
92
+ <S.NoteWrapper>
93
+ <NoteField value={{ text: noteText, title: noteTitle }} />
94
+ </S.NoteWrapper>
85
95
  <FieldsBehavior
86
- title="Values"
87
- name="values"
88
- fieldType="TextArea"
89
- value={values}
90
- onChange={setValues}
96
+ title="Dimension"
97
+ name="name"
98
+ fieldType="TextField"
99
+ value={name}
100
+ onChange={setName}
91
101
  mandatory
102
+ validators={{ mandatory: true }}
103
+ error={errors.name}
104
+ placeholder="Type a Dimension Name"
92
105
  />
93
- ) : <></>}
106
+ {type === "dimensionsAndValues" ? (
107
+ <FieldsBehavior
108
+ title="Values"
109
+ name="values"
110
+ fieldType="TextArea"
111
+ value={values}
112
+ onChange={setValues}
113
+ mandatory
114
+ validators={{ mandatory: true }}
115
+ error={errors.values}
116
+ placeholder="Type any value that you need. &#10;Separate them with ;&#10;&#19;&#10;Example: English; Spanish; German; French"
117
+ rows={4}
118
+ />
119
+ ) : <></>}
120
+ </S.ContentWrapper>
94
121
  <S.Footer>
95
122
  <Button className="button" type="button" onClick={editButton.action}>
96
123
  {editButton.label}
@@ -11,4 +11,13 @@ const NoteWrapper = styled.div`
11
11
 
12
12
  `
13
13
 
14
- export { Footer, NoteWrapper };
14
+ const ContentWrapper = styled.div`
15
+ height: calc(100% - ${(p) => p.theme.spacing.s} * 10);
16
+ overflow-y: scroll;
17
+ border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
18
+ position: absolute;
19
+ left: 0;
20
+ padding: 0 ${(p) => p.theme.spacing.m} ${(p) => p.theme.spacing.s} ${(p) => p.theme.spacing.m};
21
+ `;
22
+
23
+ export { Footer, NoteWrapper, ContentWrapper };
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
2
2
 
3
3
  import { IDimension, IDimensionsGroup } from "@ax/types";
4
4
  import { FloatingPanel, Button, FieldsBehavior, CheckGroup, RadioGroup } from "@ax/components";
5
- import { splitAndTrim } from "@ax/helpers";
5
+ import { splitAndTrim, splitCamelCase } from "@ax/helpers";
6
6
 
7
7
  import * as S from "./style";
8
8
  import { getTemplateOptions } from "./utils";
@@ -14,10 +14,12 @@ const GroupPanel = (props: IProps): JSX.Element => {
14
14
  const [selectedDimensions, setSelectedDimensions] = useState<(string | never)[]>(["all"]);
15
15
  const [selectedTemplates, setSelectedTemplates] = useState<(string | never)[]>([]);
16
16
  const [hasTemplate, setHasTemplate] = useState(false);
17
+ const [errors, setErrors] = useState({ name: false });
17
18
 
18
19
  const templates = getTemplateOptions();
19
20
  const resetState = () => {
20
21
  setName(item?.name || "");
22
+ setErrors({ name: false });
21
23
 
22
24
  const dimensionOptions = [];
23
25
  const dimensionsArr = splitAndTrim(item?.dimensions, ";");
@@ -60,11 +62,20 @@ const GroupPanel = (props: IProps): JSX.Element => {
60
62
  toggleModal();
61
63
  };
62
64
 
65
+ const validateFields = () => {
66
+ const errorFields = {
67
+ name: !name.length,
68
+ }
69
+ setErrors(errorFields);
70
+ const isFieldsValid = Object.values(errorFields).every((error) => !error);
71
+ isFieldsValid && editItemAction();
72
+ }
73
+
63
74
  const title = item ? "Update Dimensions Group" : "Create Dimensions Group";
64
75
 
65
76
  const editButton = {
66
77
  label: title,
67
- action: editItemAction,
78
+ action: validateFields,
68
79
  };
69
80
 
70
81
  const initialDimensionOption = {
@@ -75,7 +86,11 @@ const GroupPanel = (props: IProps): JSX.Element => {
75
86
  const dimensionOptions = [{ ...initialDimensionOption }];
76
87
  dimensions?.forEach((dimension) => {
77
88
  const { name } = dimension;
78
- const option = { name, value: name, title: name };
89
+ const option = {
90
+ name: name,
91
+ value: name,
92
+ title: splitCamelCase(name)
93
+ };
79
94
  return dimensionOptions.push(option);
80
95
  });
81
96
 
@@ -115,12 +130,14 @@ const GroupPanel = (props: IProps): JSX.Element => {
115
130
  <FloatingPanel title={title} toggleModal={toggleModal} isOpen={isOpen}>
116
131
  <S.ContentWrapper>
117
132
  <FieldsBehavior
118
- title="Dimension"
133
+ title="Name"
119
134
  name="name"
120
135
  fieldType="TextField"
121
136
  value={name}
122
137
  onChange={setName}
123
138
  mandatory
139
+ validators={{ mandatory: true }}
140
+ error={errors.name}
124
141
  />
125
142
  <S.Divider />
126
143
  <S.Heading>
@@ -136,7 +153,7 @@ const GroupPanel = (props: IProps): JSX.Element => {
136
153
  />
137
154
  <S.Divider />
138
155
  <S.Heading $spaceBetween>
139
- <S.HeadingText>Dimensions</S.HeadingText>
156
+ <S.HeadingText>Associated to a template</S.HeadingText>
140
157
  <S.RadioTemplate>
141
158
  <RadioGroup
142
159
  name="hasTemplate"
@@ -24,12 +24,12 @@ const Divider = styled.div`
24
24
  `;
25
25
 
26
26
  const Heading = styled.div<{ $spaceBetween?: boolean }>`
27
- ${(p) => p.theme.textStyle.headingXS};
28
27
  display: flex;
29
28
  justify-content: ${(p) => p.$spaceBetween ? "space-between" : "flex-start"};
30
29
  `;
31
30
 
32
31
  const HeadingText = styled.div`
32
+ ${(p) => p.theme.textStyle.headingXS};
33
33
  color: ${(p) => p.theme.color.textHighEmphasis};
34
34
  `;
35
35
 
@@ -22,7 +22,6 @@ const Analytics = (props: IProps): JSX.Element => {
22
22
  analytics,
23
23
  getAnalytics,
24
24
  setHistoryPush,
25
- site,
26
25
  updateAnalytics,
27
26
  } = props;
28
27
 
@@ -31,22 +30,24 @@ const Analytics = (props: IProps): JSX.Element => {
31
30
  const { isOpen: isDimensionOpen, toggleModal: toggleDimensionModal } = useModal();
32
31
  const { isOpen: isGroupOpen, toggleModal: toggleGroupModal } = useModal();
33
32
 
34
- const { scriptCode, dimensions, groups } = analyticsState;
33
+ const { dimensions, groups } = analyticsState;
35
34
 
36
35
  const changeScriptCode = (scriptCode: string) => setAnalyticsState((state) => ({ ...state, scriptCode }));
37
36
  const changeDimensions = (dimensions: IDimension[]) => setAnalyticsState((state) => ({ ...state, dimensions }));
38
37
  const changeGroups = (groups: IDimensionsGroup[]) => setAnalyticsState((state) => ({ ...state, groups }));
39
38
 
40
39
  useEffect(() => {
41
- getAnalytics(site?.id);
42
- }, [getAnalytics, site?.id]);
40
+ getAnalytics();
41
+ // eslint-disable-next-line react-hooks/exhaustive-deps
42
+ }, []);
43
43
 
44
44
  useEffect(() => {
45
45
  setAnalyticsState(analytics);
46
+ // eslint-disable-next-line react-hooks/exhaustive-deps
46
47
  }, [analytics]);
47
48
 
48
49
  const handleSave = async () => {
49
- const isSaved = await updateAnalytics(analyticsState, site?.id);
50
+ const isSaved = await updateAnalytics(analyticsState);
50
51
  if (isSaved) resetDirty();
51
52
  };
52
53
 
@@ -138,9 +139,10 @@ const Analytics = (props: IProps): JSX.Element => {
138
139
  title="Analytics Tracking ID or Script Code"
139
140
  name="scriptCode"
140
141
  fieldType="TextArea"
141
- value={scriptCode || ""}
142
+ value={analytics.scriptCode}
142
143
  onChange={changeScriptCode}
143
144
  placeholder="Type the Google Analytics or Google Tag Manager code."
145
+ rows={3}
144
146
  />
145
147
  </S.ScriptCodeWrapper>
146
148
  <S.SettingsWrapper>
@@ -180,7 +182,6 @@ const mapStateToProps = (state: IRootState) => ({
180
182
  isSaving: state.app.isSaving,
181
183
  isLoading: state.app.isLoading,
182
184
  analytics: state.analytics,
183
- site: state.sites.currentSiteInfo,
184
185
  });
185
186
 
186
187
  const mapDispatchToProps = {
@@ -193,7 +194,6 @@ interface IAnalyticsProps {
193
194
  isSaving: boolean;
194
195
  isLoading: boolean;
195
196
  analytics: IAnalytics;
196
- site: any;
197
197
  }
198
198
 
199
199
  interface IDispatchProps {
@@ -22,6 +22,8 @@ export const Home = styled.div<{ type: string; isSite: boolean; isOpened: boolea
22
22
  display: flex;
23
23
  align-items: center;
24
24
  justify-content: ${(p) => (p.isOpened ? "flex-start" : "center")};
25
+ border-right: 1px solid ${(p) => p.theme.color.uiLine};
26
+ margin-right: -1px;
25
27
 
26
28
  & + ul {
27
29
  margin-top: ${(p) => p.theme.spacing.s};
@@ -10,7 +10,7 @@ import { reducer, IOptionTableStore, setColumnValues, setShowThumbnail, setSelec
10
10
  import * as S from "./style";
11
11
 
12
12
  const OptionTable = (props: IOptionTableProps): JSX.Element => {
13
- const { selectData, selectPage, filters, values, selectedValue, setIsStructuredData } = props;
13
+ const { selectData, selectPage, filters, values, selectedValue, setIsStructuredData, theme } = props;
14
14
 
15
15
  const filterOptions = (value: string, objKey: string) => values.filter((item: any) => item[objKey] === value);
16
16
  const currentOption = filterOptions(selectedValue, "value");
@@ -66,7 +66,9 @@ const OptionTable = (props: IOptionTableProps): JSX.Element => {
66
66
  };
67
67
 
68
68
  const thumbnailProps =
69
- state.showThumbnail && isOptionInType(filteredByTypeOptions) && getThumbnailProps(state.selectedOption, true);
69
+ state.showThumbnail &&
70
+ isOptionInType(filteredByTypeOptions) &&
71
+ getThumbnailProps(state.selectedOption, true, theme);
70
72
 
71
73
  const displayOptions = (item: any) => {
72
74
  const { value } = item;
@@ -134,6 +136,7 @@ interface IOptionTableProps {
134
136
  filters: any;
135
137
  values: any;
136
138
  selectedValue: string;
139
+ theme: string;
137
140
  }
138
141
 
139
142
  const mapDispatchToProps = {
@@ -270,8 +270,8 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
270
270
  isGlobal && !manuallyImported
271
271
  ? "This page has been provided by subscription. You cannot remove it."
272
272
  : canBeUnpublished === false
273
- ? "This is the canonical site of the page. You cannot remove it."
274
- : null;
273
+ ? "This is the canonical site of the page. You cannot remove it."
274
+ : null;
275
275
 
276
276
  let menuOptions: IPageOption[] = [
277
277
  {
@@ -13,6 +13,7 @@ import {
13
13
  ICheck,
14
14
  IGetSitePagesParams,
15
15
  IColumn,
16
+ ISite,
16
17
  } from "@ax/types";
17
18
  import { MainWrapper, Modal, TableList, ErrorToast, Toast, EmptyState } from "@ax/components";
18
19
  import { getFilteredStructuredData, isGlobalStructuredData, isStructuredDataFromPage } from "@ax/helpers";
@@ -204,7 +205,9 @@ const Content = (props: IProps): JSX.Element => {
204
205
  const getSiteContent = useCallback(
205
206
  (filterQuery?: any) => {
206
207
  const params = getParams();
207
- isStructuredData ? getStructuredDataContents(params, params.siteID) : getPages(params, filterQuery);
208
+ isStructuredData && params.siteID
209
+ ? getStructuredDataContents(params, params.siteID)
210
+ : getPages(params, filterQuery);
208
211
  },
209
212
  // eslint-disable-next-line react-hooks/exhaustive-deps
210
213
  [getParams, getSitePages, getStructuredDataContents, currentSiteInfo, isStructuredData, lang]
@@ -255,7 +258,7 @@ const Content = (props: IProps): JSX.Element => {
255
258
  setEmptyStateProps(emptyState);
256
259
  }
257
260
  // eslint-disable-next-line react-hooks/exhaustive-deps
258
- }, [isLoading]);
261
+ }, [isLoading, currentSitePages]);
259
262
 
260
263
  const addNewData = () => {
261
264
  resetForm();
@@ -599,6 +602,7 @@ const Content = (props: IProps): JSX.Element => {
599
602
  filters={options.filters}
600
603
  values={options.values}
601
604
  selectedValue={selectedOption}
605
+ theme={currentSiteInfo.theme}
602
606
  />
603
607
  </Modal>
604
608
  <Modal
@@ -690,7 +694,7 @@ const mapDispatchToProps = {
690
694
 
691
695
  interface IPagesProps {
692
696
  isData: boolean;
693
- currentSiteInfo: any;
697
+ currentSiteInfo: ISite;
694
698
  currentSitePages: IPage[];
695
699
  filter: any;
696
700
  template: string;
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { connect } from "react-redux";
3
+ import { themes } from "components";
3
4
  import { pageEditorActions } from "@ax/containers/PageEditor";
4
-
5
5
  import { ConfigPanel, ResizePanel } from "@ax/components";
6
6
  import { IBreadcrumbItem, IRootState, ISchema, IUserEditing } from "@ax/types";
7
7
  import PageBrowser from "./PageBrowser";
@@ -39,6 +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
+
42
45
  return (
43
46
  <ResizePanel
44
47
  leftPanel={<PageBrowser isPreviewMode={isPreviewMode} />}
@@ -58,6 +61,7 @@ const Editor = (props: IProps) => {
58
61
  isEditable={isEditable}
59
62
  isPreviewMode={isPreviewMode}
60
63
  userEditing={userEditing}
64
+ theme={theme}
61
65
  />
62
66
  }
63
67
  />
@@ -24,7 +24,7 @@ const RobotsPanel = (props: IProps): JSX.Element => {
24
24
  action: editItemAction,
25
25
  };
26
26
 
27
- const placeholder = "User-agent: * \nDisallow: *";
27
+ const placeholder = "User-agent: * \nAllow: *";
28
28
 
29
29
  return (
30
30
  <FloatingPanel title={title} toggleModal={toggleModal} isOpen={isOpen}>
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
3
3
  import { navigationActions } from "@ax/containers/Navigation/Defaults";
4
4
 
5
5
  import { ResizePanel, ConfigPanel } from "@ax/components";
6
- import { IBreadcrumbItem, IRootState, ISchema } from "@ax/types";
6
+ import { IBreadcrumbItem, IRootState, ISchema, ISite } from "@ax/types";
7
7
  import DefaultsBrowser from "./DefaultsBrowser";
8
8
 
9
9
  const Editor = (props: IProps) => {
@@ -22,6 +22,7 @@ const Editor = (props: IProps) => {
22
22
  setSelectedTab,
23
23
  selectedTab,
24
24
  isLoading,
25
+ site,
25
26
  } = props;
26
27
 
27
28
  const actions = {
@@ -49,6 +50,7 @@ const Editor = (props: IProps) => {
49
50
  isPage={false}
50
51
  isLoading={isLoading}
51
52
  isEditable={true}
53
+ theme={site.theme}
52
54
  />
53
55
  }
54
56
  />
@@ -63,6 +65,7 @@ interface IEditorStateProps {
63
65
  activatedModules: string[];
64
66
  selectedTab: string;
65
67
  isLoading: boolean;
68
+ site: ISite;
66
69
  }
67
70
 
68
71
  interface IPageBrowserDispatchProps {
@@ -85,6 +88,7 @@ const mapStateToProps = (state: IRootState): IEditorStateProps => ({
85
88
  activatedModules: state.dataPacks.modules,
86
89
  selectedTab: state.navigation.tab,
87
90
  isLoading: state.app.isLoading,
91
+ site: state.sites.currentSiteInfo,
88
92
  });
89
93
 
90
94
  const mapDispatchToProps = {
@@ -5,7 +5,7 @@ import { pageEditorActions } from "@ax/containers/PageEditor";
5
5
  import { sitesActions } from "@ax/containers/Sites";
6
6
  import { appActions } from "@ax/containers/App";
7
7
  import { ConfigPanel, ResizePanel } from "@ax/components";
8
- import { IBreadcrumbItem, IRootState, ISchema, IUserEditing } from "@ax/types";
8
+ import { IBreadcrumbItem, IRootState, ISchema, ISite, IUserEditing } from "@ax/types";
9
9
  import PageBrowser from "./PageBrowser";
10
10
 
11
11
  const Editor = (props: IProps) => {
@@ -34,6 +34,7 @@ const Editor = (props: IProps) => {
34
34
  saveCurrentSiteInfo,
35
35
  isPreviewMode,
36
36
  userEditing,
37
+ site,
37
38
  } = props;
38
39
 
39
40
  const actions = {
@@ -69,6 +70,7 @@ const Editor = (props: IProps) => {
69
70
  setHistoryPush={setHistoryPush}
70
71
  isPreviewMode={isPreviewMode}
71
72
  userEditing={userEditing}
73
+ theme={site.theme}
72
74
  />
73
75
  }
74
76
  />
@@ -84,6 +86,7 @@ interface IEditorStateProps {
84
86
  selectedTab: string;
85
87
  isLoading: boolean;
86
88
  userEditing: IUserEditing | null;
89
+ site: ISite;
87
90
  }
88
91
 
89
92
  interface IPageBrowserDispatchProps {
@@ -116,6 +119,7 @@ const mapStateToProps = (state: IRootState): IEditorStateProps => ({
116
119
  selectedTab: state.pageEditor.tab,
117
120
  isLoading: state.app.isLoading,
118
121
  userEditing: state.pageEditor.userEditing,
122
+ site: state.sites.currentSiteInfo,
119
123
  });
120
124
 
121
125
  const mapDispatchToProps = {
@@ -0,0 +1,132 @@
1
+ import React from "react";
2
+
3
+ import { Button } from "@ax/components";
4
+ import { FieldsBehavior } from "@ax/components";
5
+ import { IDimension, IDimensionsGroup } from "@ax/types";
6
+ import { splitAndTrim, splitAndJoin } from "@ax/helpers";
7
+
8
+ import * as S from "./style";
9
+
10
+
11
+ const Warning = (props: IWarning): JSX.Element => {
12
+ const { setShowWarning } = props;
13
+
14
+ const warningText = "Analytics has Global settings. If you need, you can change the Analytics ID for this site. If you have already defined a project for this site in GTM, you don't need to define it here. You cannot edit the Dimensions and Values here, only view them.";
15
+
16
+ const handleButtonClick = () => {
17
+ setShowWarning(false);
18
+ }
19
+
20
+ return (
21
+ <>
22
+ <S.WarningHeading>Analytics</S.WarningHeading>
23
+ <S.WarningText>{warningText}</S.WarningText>
24
+ <Button type="button" buttonStyle="solid" onClick={handleButtonClick}>
25
+ Define Site Analytics
26
+ </Button>
27
+ </>
28
+ );
29
+ };
30
+
31
+ const ScriptCode = (props: IScriptCode): JSX.Element => {
32
+ const { scriptCode, setScriptCode } = props;
33
+
34
+ return (
35
+ <S.ScriptCodeWrapper>
36
+ <FieldsBehavior
37
+ title="Analytics Script Code"
38
+ name="siteScriptCode"
39
+ fieldType="TextArea"
40
+ value={scriptCode}
41
+ onChange={setScriptCode}
42
+ placeholder="Type the Google Analytics or Google Tag Manager code."
43
+ />
44
+ </S.ScriptCodeWrapper>
45
+ )
46
+ }
47
+
48
+ const Dimensions = (props: IDimensions): JSX.Element => {
49
+ const { dimensions } = props;
50
+
51
+ const heading = "Data Layer configuration";
52
+ const description = (
53
+ <>
54
+ You cannot edit the Dimensions and Values here, only view them. To edit them, you have to go to <strong>Global Settings</strong>.
55
+ </>
56
+ );
57
+
58
+ const Dimension = (props: IDimension) => {
59
+ const { name, values } = props;
60
+ const hasValues = !["", ";null;"].includes(values);
61
+ const getValues = () => splitAndTrim(values, ";").map((value) => `${value}; `);
62
+ return (
63
+ <S.Component>
64
+ <S.ComponentName>{name}</S.ComponentName>
65
+ <S.ComponentValues>{hasValues ? getValues() : "The value is defined on page"}</S.ComponentValues>
66
+ </S.Component>
67
+ )
68
+ }
69
+
70
+ return <>
71
+ <S.Heading>{heading}</S.Heading>
72
+ <S.Description>{description}</S.Description>
73
+ <S.ComponentsWrapper itemsSize={1 / 2}>
74
+ {dimensions.map((dimension, idx) => (
75
+ <Dimension key={idx} {...dimension} />
76
+ ))}
77
+ </S.ComponentsWrapper>
78
+ </>
79
+ }
80
+
81
+ const Groups = (props: IGroups): JSX.Element => {
82
+ const { groups } = props;
83
+
84
+ const heading = "Dimensions group by content";
85
+ const description = "In global, you can create groups with the dimensions to measure on a page based on its content. You can not edit them here. Only view them.";
86
+
87
+ const Group = (props: IDimensionsGroup) => {
88
+ const { name, dimensions, templates } = props;
89
+ const getDimensions = () => splitAndTrim(dimensions, ";").map((value, idx) => <p key={idx}>{value}</p>);
90
+ const contentType = splitAndJoin(templates, ";", ", ");
91
+ const hasContentType = !["null", ""].includes(contentType);
92
+ const contentTypeText = hasContentType ? <span>{contentType}</span> : "NO";
93
+ return (
94
+ <S.Component>
95
+ <div>
96
+ <S.ComponentName>{name}</S.ComponentName>
97
+ <S.ComponentValues>{getDimensions()}</S.ComponentValues>
98
+ </div>
99
+ <S.ContentType>Content type: {contentTypeText}</S.ContentType>
100
+ </S.Component>
101
+ )
102
+ }
103
+
104
+ return <>
105
+ <S.Heading>{heading}</S.Heading>
106
+ <S.Description>{description}</S.Description>
107
+ <S.ComponentsWrapper itemsSize={1 / 3}>
108
+ {groups.map((group, idx) => (
109
+ <Group key={idx} {...group} />
110
+ ))}
111
+ </S.ComponentsWrapper>
112
+ </>
113
+ }
114
+
115
+ interface IWarning {
116
+ setShowWarning: React.Dispatch<React.SetStateAction<boolean>>;
117
+ }
118
+
119
+ interface IScriptCode {
120
+ scriptCode: string | null;
121
+ setScriptCode: React.Dispatch<React.SetStateAction<string>>;
122
+ }
123
+
124
+ interface IDimensions {
125
+ dimensions: IDimension[];
126
+ }
127
+
128
+ interface IGroups {
129
+ groups: IDimensionsGroup[];
130
+ }
131
+
132
+ export { Warning, ScriptCode, Dimensions, Groups };