@griddo/ax 1.67.10 → 1.68.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 (121) hide show
  1. package/config/jest/componentsMock.js +1528 -27
  2. package/package.json +2 -2
  3. package/src/__mocks__/reducers/app.tsx +10 -0
  4. package/src/__mocks__/reducers/sites.tsx +10 -0
  5. package/src/__tests__/{AnalyticsField.test.tsx → components/Fields/AnalyticsField/AnalyticsField.test.tsx} +5 -5
  6. package/src/__tests__/{PageAnalytics.test.tsx → components/Fields/AnalyticsField/PageAnalytics/PageAnalytics.test.tsx} +2 -2
  7. package/src/__tests__/{StructuredDataAnalytics.test.tsx → components/Fields/AnalyticsField/StructuredDataAnalytics/StructuredDataAnalytics.test.tsx} +2 -2
  8. package/src/__tests__/{ArrayFieldGroup.test.tsx → components/Fields/ArrayFieldGroup/ArrayFieldGroup.test.tsx} +2 -2
  9. package/src/__tests__/{AsyncCheckGroup.test.tsx → components/Fields/AsyncCheckGroup/AsyncCheckGroup.test.tsx} +2 -2
  10. package/src/__tests__/{AsyncSelect.test.tsx → components/Fields/AsyncSelect/AsyncSelect.test.tsx} +2 -2
  11. package/src/__tests__/{CheckField.test.tsx → components/Fields/CheckField/CheckField.test.tsx} +2 -2
  12. package/src/__tests__/{CheckGroup.test.tsx → components/Fields/CheckGroup/CheckGroup.test.tsx} +2 -2
  13. package/src/__tests__/components/Fields/ColorPicker/ColorPicker.test.tsx +195 -0
  14. package/src/__tests__/components/Fields/ComponentArray/ComponentArray.test.tsx +184 -0
  15. package/src/__tests__/components/Fields/ComponentArray/MixableComponentArray/MixableComponentArray.test.tsx +315 -0
  16. package/src/__tests__/components/Fields/ComponentArray/MixableComponentArray/PasteModuleButton/PasteModuleButton.test.tsx +95 -0
  17. package/src/__tests__/components/Fields/ComponentArray/SameComponentArray/SameComponentArray.test.tsx +225 -0
  18. package/src/__tests__/{FieldGroup.test.tsx → components/Fields/FieldGroup/FieldGroup.test.tsx} +2 -2
  19. package/src/__tests__/components/Fields/FieldsDivider/FieldsDivider.test.tsx +24 -0
  20. package/src/__tests__/components/Fields/FileField/FileField.test.tsx +135 -0
  21. package/src/__tests__/{HeadingField.test.tsx → components/Fields/HeadingField/HeadingField.test.tsx} +2 -2
  22. package/src/__tests__/components/Fields/HiddenField/HiddenField.test.tsx +76 -0
  23. package/src/__tests__/components/Fields/MultiCheckSelect/MultiCheckSelect.test.tsx +70 -0
  24. package/src/__tests__/components/Fields/NoteField/NoteField.test.tsx +67 -0
  25. package/src/__tests__/components/Fields/NumberField/NumberField.test.tsx +109 -0
  26. package/src/__tests__/components/Fields/RadioField/RadioField.test.tsx +106 -0
  27. package/src/__tests__/components/Fields/RichText/RichText.test.tsx +52 -0
  28. package/src/__tests__/components/Fields/Select/Select.test.tsx +75 -0
  29. package/src/__tests__/components/Fields/SliderField/SliderField.test.tsx +82 -0
  30. package/src/__tests__/{TagField.test.tsx → components/Fields/TagField/TagField.test.tsx} +2 -2
  31. package/src/__tests__/{TextArea.test.tsx → components/Fields/TextArea/TextArea.test.tsx} +2 -2
  32. package/src/__tests__/{TextField.test.tsx → components/Fields/TextField/TextField.test.tsx} +2 -2
  33. package/src/__tests__/components/Fields/ToggleField/ToggleField.test.tsx +100 -0
  34. package/src/__tests__/{UniqueCheck.test.tsx → components/Fields/UniqueCheck/UniqueCheck.test.tsx} +2 -2
  35. package/src/__tests__/components/Fields/UrlField/UrlField.test.tsx +446 -0
  36. package/src/__tests__/components/Fields/UrlField/mockedAxios.ts +2214 -0
  37. package/src/__tests__/components/Fields/VisualUniqueSelection/ImageSelection/ImageSelection.test.tsx +99 -0
  38. package/src/__tests__/components/Fields/VisualUniqueSelection/ScrollableSelection/ScrollableSelection.test.tsx +176 -0
  39. package/src/__tests__/components/Fields/VisualUniqueSelection/VisualUniqueSelection.test.tsx +78 -0
  40. package/src/components/ActionMenu/index.tsx +1 -0
  41. package/src/components/Browser/index.tsx +39 -47
  42. package/src/components/Browser/style.tsx +15 -15
  43. package/src/components/BrowserContent/index.tsx +78 -0
  44. package/src/components/ConfigPanel/Form/ConnectedField/NavConnectedField/index.tsx +3 -5
  45. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +2 -6
  46. package/src/components/ConfigPanel/Header/index.tsx +28 -11
  47. package/src/components/ConfigPanel/index.tsx +2 -2
  48. package/src/components/ErrorCenter/index.tsx +11 -4
  49. package/src/components/Fields/ArrayFieldGroup/index.tsx +4 -2
  50. package/src/components/Fields/ArrayFieldGroup/style.tsx +7 -0
  51. package/src/components/Fields/AsyncCheckGroup/index.tsx +1 -1
  52. package/src/components/Fields/CheckField/index.tsx +1 -1
  53. package/src/components/Fields/ColorPicker/Picker/index.tsx +9 -3
  54. package/src/components/Fields/ColorPicker/index.tsx +4 -9
  55. package/src/components/Fields/ComponentArray/MixableComponentArray/PasteModuleButton/index.tsx +2 -1
  56. package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +27 -22
  57. package/src/components/Fields/ComponentArray/MixableComponentArray/style.tsx +3 -38
  58. package/src/components/Fields/ComponentArray/SameComponentArray/index.tsx +3 -2
  59. package/src/components/Fields/ComponentArray/SameComponentArray/style.tsx +1 -28
  60. package/src/components/Fields/ComponentArray/helpers.tsx +1 -1
  61. package/src/components/Fields/ComponentContainer/index.tsx +3 -1
  62. package/src/components/Fields/FileField/FileDragAndDrop/index.tsx +1 -1
  63. package/src/components/Fields/FileField/FileDragAndDrop/style.tsx +2 -3
  64. package/src/components/Fields/FileField/index.tsx +6 -6
  65. package/src/components/Fields/HiddenField/index.tsx +3 -3
  66. package/src/components/Fields/MultiCheckSelect/index.tsx +8 -27
  67. package/src/components/Fields/NoteField/index.tsx +3 -3
  68. package/src/components/Fields/NumberField/index.tsx +6 -3
  69. package/src/components/Fields/RadioField/index.tsx +10 -2
  70. package/src/components/Fields/ReferenceField/index.tsx +8 -1
  71. package/src/components/Fields/ReferenceField/style.tsx +5 -0
  72. package/src/components/Fields/RichText/index.tsx +1 -1
  73. package/src/components/Fields/SliderField/index.tsx +11 -7
  74. package/src/components/Fields/ToggleField/index.tsx +12 -3
  75. package/src/components/Fields/UrlField/PageFinder/SelectionListItem/index.tsx +1 -1
  76. package/src/components/Fields/UrlField/index.tsx +6 -4
  77. package/src/components/Fields/UrlField/style.tsx +4 -2
  78. package/src/components/Fields/VisualOption/index.tsx +10 -2
  79. package/src/components/Fields/VisualUniqueSelection/ImageSelection/index.tsx +2 -2
  80. package/src/components/Fields/VisualUniqueSelection/ScrollableSelection/index.tsx +4 -3
  81. package/src/components/Fields/VisualUniqueSelection/ScrollableSelection/style.tsx +1 -1
  82. package/src/components/Fields/VisualUniqueSelection/index.tsx +3 -3
  83. package/src/components/FieldsBehavior/index.tsx +4 -4
  84. package/src/components/FieldsBehavior/style.tsx +5 -12
  85. package/src/components/FloatingMenu/index.tsx +8 -4
  86. package/src/components/Loader/index.tsx +12 -8
  87. package/src/components/MainWrapper/AppBar/index.tsx +1 -0
  88. package/src/components/MainWrapper/index.tsx +1 -0
  89. package/src/components/Toast/index.tsx +1 -1
  90. package/src/components/Tooltip/index.tsx +1 -1
  91. package/src/components/index.tsx +2 -0
  92. package/src/containers/App/actions.tsx +3 -7
  93. package/src/containers/PageEditor/actions.tsx +36 -5
  94. package/src/forms/editor.tsx +35 -1
  95. package/src/forms/fields.tsx +6 -2
  96. package/src/forms/index.tsx +2 -0
  97. package/src/forms/validators.tsx +29 -8
  98. package/src/guards/error/index.tsx +1 -1
  99. package/src/helpers/containerEvaluations.tsx +32 -4
  100. package/src/helpers/index.tsx +2 -0
  101. package/src/helpers/structuredData.tsx +2 -2
  102. package/src/hooks/forms.tsx +1 -28
  103. package/src/hooks/index.tsx +1 -2
  104. package/src/modules/FramePreview/index.tsx +70 -36
  105. package/src/modules/FramePreview/style.tsx +3 -0
  106. package/src/modules/GlobalEditor/PageBrowser/index.tsx +2 -7
  107. package/src/modules/GlobalEditor/index.tsx +8 -6
  108. package/src/modules/GlobalEditor/style.tsx +1 -1
  109. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +0 -4
  110. package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +3 -2
  111. package/src/modules/PageEditor/PageBrowser/index.tsx +1 -4
  112. package/src/modules/PageEditor/index.tsx +6 -6
  113. package/src/modules/PublicPreview/index.tsx +17 -34
  114. package/src/modules/PublicPreview/style.tsx +0 -2
  115. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +0 -4
  116. package/src/modules/Sites/index.tsx +1 -1
  117. package/src/modules/StructuredData/Form/ConnectedField/index.tsx +1 -1
  118. package/src/modules/StructuredData/Form/index.tsx +3 -1
  119. package/src/modules/StructuredData/StructuredDataList/index.tsx +1 -0
  120. package/src/schemas/pages/GlobalPage.tsx +1 -0
  121. package/src/types/index.tsx +1 -0
@@ -1,17 +1,22 @@
1
1
  import React, { memo } from "react";
2
2
 
3
3
  import { IBreadcrumbItem } from "@ax/types";
4
- import { Breadcrumb } from "@ax/components";
4
+ import { Breadcrumb, Toast } from "@ax/components";
5
+ import { useToast } from "@ax/hooks";
5
6
 
6
7
  import * as S from "./style";
7
8
 
8
9
  const Header = (props: IProps) => {
9
10
  const { breadcrumb, schema, selectedParent, activatedModules, actions, setSelectedContent } = props;
10
- const { duplicateModuleAction, deleteModuleAction } = actions;
11
+ const { duplicateModuleAction, deleteModuleAction, copyModuleAction } = actions;
11
12
  const title = breadcrumb[breadcrumb.length - 1].displayName;
12
13
  const component = breadcrumb[breadcrumb.length - 1].component;
13
14
  const editorID = breadcrumb[breadcrumb.length - 1].editorID;
14
15
  const parentID = breadcrumb.length > 1 ? breadcrumb[breadcrumb.length - 2].editorID : breadcrumb[0].editorID;
16
+ const isModule = schema.schemaType === "module";
17
+ const isInArray = Array.isArray(selectedParent);
18
+
19
+ const { isVisible, toggleToast, setIsVisible } = useToast();
15
20
 
16
21
  const removeItem = () => {
17
22
  setSelectedContent(parentID);
@@ -23,6 +28,11 @@ const Header = (props: IProps) => {
23
28
  setSelectedContent(parentID);
24
29
  };
25
30
 
31
+ const copyItem = () => {
32
+ const isCopied = copyModuleAction(editorID);
33
+ isCopied && toggleToast();
34
+ };
35
+
26
36
  const duplicateOpt = {
27
37
  label: "duplicate",
28
38
  icon: "duplicate",
@@ -35,20 +45,27 @@ const Header = (props: IProps) => {
35
45
  action: removeItem,
36
46
  };
37
47
 
38
- const isInArray = Array.isArray(selectedParent);
48
+ const copyOpt = {
49
+ label: "copy",
50
+ icon: "copy",
51
+ action: copyItem,
52
+ };
39
53
 
40
- const isModuleDeactivated =
41
- schema.schemaType === "module" && isInArray && activatedModules && !activatedModules.includes(component);
54
+ const isModuleDeactivated = isModule && isInArray && activatedModules && !activatedModules.includes(component);
42
55
  const canDuplicate = !isModuleDeactivated;
43
56
 
44
- const menuOptions = !canDuplicate ? [deleteOpt] : [duplicateOpt, deleteOpt];
57
+ let menuOptions = !canDuplicate ? [deleteOpt] : [duplicateOpt, deleteOpt];
58
+ menuOptions = isModule ? [...menuOptions, copyOpt] : menuOptions;
45
59
 
46
60
  return (
47
- <S.HeaderWrapper>
48
- <S.Title>{title}</S.Title>
49
- <Breadcrumb breadcrumb={breadcrumb} setSelectedContent={setSelectedContent} />
50
- {isInArray && <S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />}
51
- </S.HeaderWrapper>
61
+ <>
62
+ <S.HeaderWrapper>
63
+ <S.Title>{title}</S.Title>
64
+ <Breadcrumb breadcrumb={breadcrumb} setSelectedContent={setSelectedContent} />
65
+ {isInArray && <S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />}
66
+ </S.HeaderWrapper>
67
+ {isVisible && <Toast message="1 module copied to clipboard" setIsVisible={setIsVisible} />}
68
+ </>
52
69
  );
53
70
  };
54
71
 
@@ -1,14 +1,14 @@
1
1
  import React, { useEffect, useRef } from "react";
2
- import { isEmptyObj } from "@ax/helpers";
3
2
 
3
+ import { isEmptyObj } from "@ax/helpers";
4
4
  import { Loading } from "@ax/components";
5
- import Header from "./Header";
6
5
  import { IBreadcrumbItem, IUserEditing } from "@ax/types";
7
6
 
8
7
  import Form from "./Form";
9
8
  import NavigationForm from "./NavigationForm";
10
9
  import GlobalPageForm from "./GlobalPageForm";
11
10
  import PreviewForm from "./PreviewForm";
11
+ import Header from "./Header";
12
12
 
13
13
  import * as S from "./style";
14
14
 
@@ -16,14 +16,19 @@ const ErrorCenter = (props: IProps): JSX.Element => {
16
16
 
17
17
  const getErrorItem = (item: IErrorItem): JSX.Element => {
18
18
  const handleClick = () => {
19
- actions?.goToError(item.editorID, item.tab, item.template);
20
- goToElement(item.key);
19
+ if (item.hasDeactivatedPackage) {
20
+ actions?.goToPackage();
21
+ } else {
22
+ item.editorID && actions?.goToError(item.editorID, item.tab, item.template);
23
+ goToElement(item.key);
24
+ }
21
25
  };
22
26
 
23
27
  const icon = item.type === "warning" ? "warning" : "alert";
28
+ const isClicable = !!item.editorID || !!item.hasDeactivatedPackage || !!item.key;
24
29
 
25
30
  return (
26
- <S.Wrapper key={`${item.editorID}${item.key}`} clickable={!!item.editorID} onClick={handleClick}>
31
+ <S.Wrapper key={`${item.editorID}${item.key}`} clickable={isClicable} onClick={handleClick}>
27
32
  <S.Header type={item.type}>
28
33
  <Icon name={icon} size="16" />
29
34
  <S.Type>{item.type}</S.Type>
@@ -31,7 +36,8 @@ const ErrorCenter = (props: IProps): JSX.Element => {
31
36
  <S.Content>
32
37
  <S.Title>{item.message}</S.Title>
33
38
  <S.Subtitle>{item.name}</S.Subtitle>
34
- {item.editorID && <S.Link>Go to field</S.Link>}
39
+ {isClicable && !item.hasDeactivatedPackage && <S.Link>Go to field</S.Link>}
40
+ {isClicable && item.hasDeactivatedPackage && <S.Link>Go to package</S.Link>}
35
41
  </S.Content>
36
42
  </S.Wrapper>
37
43
  );
@@ -49,6 +55,7 @@ interface IProps {
49
55
  errors: IErrorItem[];
50
56
  actions?: {
51
57
  goToError(editorID: number | null, tab: string, template: boolean): void;
58
+ goToPackage(): void;
52
59
  };
53
60
  }
54
61
 
@@ -5,6 +5,8 @@ import { Button, FieldsDivider } from "@ax/components";
5
5
  import ArrayFieldItem from "./ArrayFieldItem";
6
6
  import ArrayFieldInline from "./ArrayFieldInline";
7
7
 
8
+ import * as S from "./style";
9
+
8
10
  const ArrayFieldGroup = (props: IProps): JSX.Element => {
9
11
  const { value, name, innerFields, onChange, divider, arrayType } = props;
10
12
 
@@ -73,11 +75,11 @@ const ArrayFieldGroup = (props: IProps): JSX.Element => {
73
75
  );
74
76
  })}
75
77
  </div>
76
- <div>
78
+ <S.ButtonWrapper>
77
79
  <Button type="button" onClick={handleClick} buttonStyle="line">
78
80
  {`Add ${name}`}
79
81
  </Button>
80
- </div>
82
+ </S.ButtonWrapper>
81
83
  </div>
82
84
  );
83
85
  };
@@ -0,0 +1,7 @@
1
+ import styled from "styled-components";
2
+
3
+ const ButtonWrapper = styled.div`
4
+ margin-bottom: ${(p) => p.theme.spacing.xs};
5
+ `;
6
+
7
+ export { ButtonWrapper };
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
2
2
 
3
3
  import { checkgroups } from "@ax/api";
4
4
  import { isReqOk } from "@ax/helpers";
5
- import { CheckField } from "@ax/components";
5
+ import CheckField from "@ax/components/Fields/CheckField";
6
6
  import { ISite, ICheck } from "@ax/types";
7
7
 
8
8
  import * as S from "./style";
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { ICheck } from "@ax/types";
3
- import { Icon } from "@ax/components";
3
+ import Icon from "@ax/components/Icon";
4
4
 
5
5
  import * as S from "./style";
6
6
 
@@ -57,17 +57,23 @@ const Picker = (props: IProps): JSX.Element => {
57
57
  const gridColors = colors ? colors : defaultColors;
58
58
 
59
59
  return (
60
- <S.Wrapper>
60
+ <S.Wrapper data-testid="pickerWrapper">
61
61
  <S.Cover background={color} light={isLight(color)}>
62
62
  {color}
63
63
  </S.Cover>
64
64
  <S.Grid>
65
65
  {gridColors.map((item: string) => (
66
- <S.GridItem key={item} background={item} onClick={handleClick(item)} selected={item === color} />
66
+ <S.GridItem
67
+ data-testid="gridItem"
68
+ key={item}
69
+ background={item}
70
+ onClick={handleClick(item)}
71
+ selected={item === color}
72
+ />
67
73
  ))}
68
74
  </S.Grid>
69
75
  <S.InputWrapper>
70
- <S.Input type="text" value={inputValue} onChange={handleChange} />
76
+ <S.Input data-testid="inputPicker" type="text" value={inputValue} onChange={handleChange} />
71
77
  </S.InputWrapper>
72
78
  </S.Wrapper>
73
79
  );
@@ -30,7 +30,6 @@ const ColorPicker = (props: IProps): JSX.Element => {
30
30
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
31
31
  let inputValue = e.target.value;
32
32
  dispatch({ inputValue });
33
-
34
33
  const re3 = /^#[0-9a-fA-F]{3}$/;
35
34
  const re6 = /^#[0-9a-fA-F]{6}$/;
36
35
 
@@ -42,7 +41,6 @@ const ColorPicker = (props: IProps): JSX.Element => {
42
41
  dispatch({ color: inputValue });
43
42
  onChange(inputValue);
44
43
  }
45
-
46
44
  error && handleValidation && handleValidation(inputValue, { colorHex: true });
47
45
  };
48
46
 
@@ -75,19 +73,16 @@ const ColorPicker = (props: IProps): JSX.Element => {
75
73
  if (defaultOptions(colorOptions) || !themeExists) return defaultsOptions;
76
74
 
77
75
  // Si options tiene el theme, devuelve las options de ese theme.
78
- if (themeExists) {
79
- const optionsObj = colorOptions.find((entry) => entry.theme === theme);
80
- return optionsObj && optionsObj.options;
81
- }
82
-
83
- return [];
76
+ const optionsObj = colorOptions.find((entry) => entry.theme === theme);
77
+ return optionsObj && optionsObj.options;
84
78
  };
85
79
 
86
80
  return (
87
- <S.Wrapper ref={wrapper}>
81
+ <S.Wrapper ref={wrapper} data-testid="colorPickerWrapper">
88
82
  <S.InputWrapper>
89
83
  <S.ColorWrapper background={state.color} />
90
84
  <S.Input
85
+ data-testid="inputPickerWrapper"
91
86
  type="text"
92
87
  value={state.inputValue}
93
88
  onChange={handleInputChange}
@@ -15,8 +15,9 @@ const PasteModuleButton = (props: IProps): JSX.Element => {
15
15
  if (pasteResult.error) {
16
16
  const { type, text } = pasteResult.error;
17
17
  setNotification && setNotification({ type, text });
18
+ } else {
19
+ toggleToast();
18
20
  }
19
- toggleToast();
20
21
  } else {
21
22
  const notification: INotification = {
22
23
  type: "error",
@@ -35,10 +35,12 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
35
35
  } = props;
36
36
 
37
37
  const moduleCopyComponent = moduleCopy?.element.component;
38
+
38
39
  const availableDataPackModule = availableDataPacks?.reduce((prev: any, curr: any) => {
39
40
  const packModule = curr.modules.find((module: any) => module.id === moduleCopyComponent);
40
41
  return prev || packModule;
41
42
  }, null);
43
+
42
44
  const isModuleCopyUnavailable =
43
45
  availableDataPackModule &&
44
46
  !whiteList.includes(moduleCopyComponent) &&
@@ -88,9 +90,9 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
88
90
  };
89
91
 
90
92
  const showAddItemButton = (!maxItems || fixedValue.length < maxItems) && !disabled;
91
-
92
93
  const timeSinceModuleCopy = !!moduleCopy && differenceInSeconds(new Date(), new Date(moduleCopy.date));
93
94
  const eightHoursInSeconds = 8 * 60 * 60;
95
+
94
96
  const showPasteModuleButton =
95
97
  showAddItemButton &&
96
98
  isModuleArr &&
@@ -111,31 +113,33 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
111
113
  </S.Title>
112
114
  <S.ItemRow>
113
115
  <S.Subtitle>{fixedValue && fixedValue.length} items</S.Subtitle>
114
- {showPasteModuleButton && (
115
- <PasteModuleButton
116
- editorID={editorID}
117
- isModuleCopyUnavailable={isModuleCopyUnavailable}
118
- pasteModule={actions.pasteModuleAction}
119
- setNotification={actions.setNotificationAction}
120
- setHistoryPush={setHistoryPush}
121
- />
122
- )}
123
- {showAddItemButton && !disabled && (
124
- <AddItemButton
125
- isOpen={isOpen}
126
- toggleModal={toggleModal}
127
- whiteList={whiteList}
128
- categories={categories}
129
- handleClick={handleAdd}
130
- isModuleArr={isModuleArr}
131
- theme={theme}
132
- />
133
- )}
116
+ <S.ActionsWrapper data-testid="mixableComponentWrapper">
117
+ {showPasteModuleButton && (
118
+ <PasteModuleButton
119
+ editorID={editorID}
120
+ isModuleCopyUnavailable={isModuleCopyUnavailable}
121
+ pasteModule={actions.pasteModuleAction}
122
+ setNotification={actions.setNotificationAction}
123
+ setHistoryPush={setHistoryPush}
124
+ />
125
+ )}
126
+ {showAddItemButton && !disabled && (
127
+ <AddItemButton
128
+ isOpen={isOpen}
129
+ toggleModal={toggleModal}
130
+ whiteList={whiteList}
131
+ categories={categories}
132
+ handleClick={handleAdd}
133
+ isModuleArr={isModuleArr}
134
+ theme={theme}
135
+ />
136
+ )}
137
+ </S.ActionsWrapper>
134
138
  </S.ItemRow>
135
139
  {fixedValue &&
136
140
  fixedValue.map((element: any, i: number) => {
137
141
  const { editorID } = element;
138
- const { moduleTitle, isModuleDeactivated, componentTitle, displayName } = getComponentProps(
142
+ const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule } = getComponentProps(
139
143
  element,
140
144
  activatedModules,
141
145
  isModuleArr
@@ -161,6 +165,7 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
161
165
  canDuplicate={showAddItemButton && !isModuleDeactivated}
162
166
  parentKey={objKey}
163
167
  theme={theme}
168
+ isModule={isModule}
164
169
  />
165
170
  );
166
171
  })}
@@ -9,36 +9,8 @@ const Title = styled.p`
9
9
  border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
10
10
  `;
11
11
 
12
- const Component = styled.button`
13
- ${(p) => p.theme.textStyle.fieldLabel};
14
- color: ${(p) => p.theme.color.textHighEmphasis};
15
- display: block;
16
- height: ${(p) => p.theme.spacing.l};
17
- background: ${(p) => p.theme.color.uiBackground02};
18
- border: 1px solid transparent;
19
- width: 100%;
20
- text-align: left;
21
- cursor: pointer;
22
- margin-bottom: ${(p) => p.theme.spacing.xs};
23
- padding: 0 ${(p) => p.theme.spacing.s};
24
- border-radius: ${(p) => p.theme.radii.s};
25
- box-shadow: ${(p) => p.theme.shadow.field};
26
-
27
- &:hover {
28
- background: ${(p) => p.theme.color.overlayHoverPrimary};
29
- }
30
-
31
- &:focus,
32
- &:active {
33
- background: ${(p) => p.theme.color.overlayFocusPrimary};
34
- border: 1px solid ${(p) => p.theme.color.interactive01};
35
- outline: none;
36
- }
37
- `;
38
-
39
12
  const ItemRow = styled.div`
40
13
  display: flex;
41
- justify-content: space-between;
42
14
  align-items: center;
43
15
  margin-bottom: ${(p) => p.theme.spacing.xs};
44
16
  `;
@@ -54,15 +26,8 @@ const Asterisk = styled.span`
54
26
 
55
27
  const ActionsWrapper = styled.div`
56
28
  display: flex;
57
- gap: ${(p) => p.theme.spacing.xxs};
29
+ margin-left: auto;
30
+ align-items: center;
58
31
  `;
59
32
 
60
- export {
61
- Wrapper,
62
- Title,
63
- Component,
64
- ItemRow,
65
- Subtitle,
66
- Asterisk,
67
- ActionsWrapper
68
- };
33
+ export { Wrapper, Title, ItemRow, Subtitle, Asterisk, ActionsWrapper };
@@ -58,7 +58,7 @@ const SameComponentArray = (props: ISameComponentArrayProps): JSX.Element => {
58
58
  const Asterisk = () => (mandatory ? <S.Asterisk>*</S.Asterisk> : null);
59
59
 
60
60
  return (
61
- <S.Wrapper>
61
+ <S.Wrapper data-testid="sameComponentWrapper">
62
62
  <S.Title>
63
63
  {title} <Asterisk />
64
64
  </S.Title>
@@ -72,7 +72,7 @@ const SameComponentArray = (props: ISameComponentArrayProps): JSX.Element => {
72
72
  Array.isArray(value) &&
73
73
  value.map((element: any, i: number) => {
74
74
  const { editorID } = element;
75
- const { moduleTitle, isModuleDeactivated, componentTitle, displayName } = getComponentProps(
75
+ const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule } = getComponentProps(
76
76
  element,
77
77
  activatedModules,
78
78
  isModuleArr
@@ -96,6 +96,7 @@ const SameComponentArray = (props: ISameComponentArrayProps): JSX.Element => {
96
96
  canDuplicate={showAddItemButton && !isModuleDeactivated}
97
97
  parentKey={objKey}
98
98
  theme={theme}
99
+ isModule={isModule}
99
100
  />
100
101
  );
101
102
  })}
@@ -9,33 +9,6 @@ const Title = styled.p`
9
9
  border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
10
10
  `;
11
11
 
12
- const Component = styled.button`
13
- ${(p) => p.theme.textStyle.fieldLabel};
14
- color: ${(p) => p.theme.color.textHighEmphasis};
15
- display: block;
16
- height: ${(p) => p.theme.spacing.l};
17
- background: ${(p) => p.theme.color.uiBackground02};
18
- border: 1px solid transparent;
19
- width: 100%;
20
- text-align: left;
21
- cursor: pointer;
22
- margin-bottom: ${(p) => p.theme.spacing.xs};
23
- padding: 0 ${(p) => p.theme.spacing.s};
24
- border-radius: ${(p) => p.theme.radii.s};
25
- box-shadow: ${(p) => p.theme.shadow.field};
26
-
27
- &:hover {
28
- background: ${(p) => p.theme.color.overlayHoverPrimary};
29
- }
30
-
31
- &:focus,
32
- &:active {
33
- background: ${(p) => p.theme.color.overlayFocusPrimary};
34
- border: 1px solid ${(p) => p.theme.color.interactive01};
35
- outline: none;
36
- }
37
- `;
38
-
39
12
  const ItemRow = styled.div`
40
13
  display: flex;
41
14
  justify-content: space-between;
@@ -52,4 +25,4 @@ const Asterisk = styled.span`
52
25
  color: ${(p) => p.theme.color.error};
53
26
  `;
54
27
 
55
- export { Wrapper, Title, Component, ItemRow, Subtitle, Asterisk };
28
+ export { Wrapper, Title, ItemRow, Subtitle, Asterisk };
@@ -23,7 +23,7 @@ const getComponentProps = (element: any, activatedModules: string[], isModuleArr
23
23
  const componentTitle = !isModule && displayName !== title && title;
24
24
  const isModuleDeactivated = isModuleArr && activatedModules && !activatedModules.includes(component);
25
25
 
26
- return { moduleTitle, isModuleDeactivated, componentTitle, displayName };
26
+ return { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule };
27
27
  };
28
28
 
29
29
  const containerToComponentArray = (value: Record<string, IComponent>): IComponent[] =>
@@ -30,6 +30,7 @@ const ComponentContainer = (props: IComponentContainerProps): JSX.Element => {
30
30
  theme,
31
31
  canReplace,
32
32
  actionReplace,
33
+ isModule,
33
34
  } = props;
34
35
 
35
36
  const { isVisible, toggleToast, setIsVisible } = useToast();
@@ -107,7 +108,7 @@ const ComponentContainer = (props: IComponentContainerProps): JSX.Element => {
107
108
  };
108
109
 
109
110
  const actionArrayMenuOptions = [
110
- copyOpt,
111
+ ...(isModule ? [copyOpt] : []),
111
112
  ...(canDuplicate ? [duplicateOpt] : []),
112
113
  deleteOpt,
113
114
  ...(canReplace ? [replaceOpt] : []),
@@ -216,6 +217,7 @@ interface IComponentContainerProps {
216
217
  theme: string;
217
218
  canReplace?: boolean;
218
219
  actionReplace?: () => void;
220
+ isModule?: boolean;
219
221
  }
220
222
 
221
223
  export default ComponentContainer;
@@ -108,7 +108,7 @@ const FileDragAndDrop = (props: IProps) => {
108
108
  const errorWrapper = state.errorMsg ? <S.ErrorMsg>{state.errorMsg}</S.ErrorMsg> : null;
109
109
 
110
110
  return (
111
- <S.Wrapper>
111
+ <S.Wrapper data-testid="file-drag-and-drop-wrapper">
112
112
  <S.DragAndDropWrapper
113
113
  inDropZone={state.inDropZone}
114
114
  uploading={state.isUploading}
@@ -163,9 +163,8 @@ export const FilesInput = styled.input<{ ref: any }>`
163
163
  display: none;
164
164
  `;
165
165
 
166
- export const FilesButton = styled((props) => <Button {...props} />).attrs((props: any) => ({
167
- ref: props.ref,
168
- }))<{ ref: any }>`
166
+ const _Button: any = React.forwardRef((props: any, ref?: React.Ref<HTMLDivElement>) => <Button {...props} />);
167
+ export const FilesButton = styled(_Button)`
169
168
  margin-top: ${(p) => p.theme.spacing.xs};
170
169
  margin-bottom: ${(p) => p.theme.spacing.xs};
171
170
  `;
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from "react";
1
+ import React from "react";
2
2
 
3
3
  import { useModal } from "@ax/hooks";
4
4
  import { formatBytes, getFormattedDateWithTimezone } from "@ax/helpers";
@@ -7,7 +7,7 @@ import FileDragAndDrop from "./FileDragAndDrop";
7
7
 
8
8
  import * as S from "./style";
9
9
 
10
- const FileField = (props: IProps) => {
10
+ const FileField = (props: IFileFieldProps): JSX.Element => {
11
11
  const { disabled, value, onChange } = props;
12
12
 
13
13
  const { isOpen, toggleModal } = useModal(false);
@@ -61,7 +61,7 @@ const FileField = (props: IProps) => {
61
61
 
62
62
  return (
63
63
  <>
64
- <S.FileDataWrapper>
64
+ <S.FileDataWrapper data-testid="file-data-wrapper">
65
65
  <S.FileName>{fileName}</S.FileName>
66
66
  <S.FileData>
67
67
  <div>Uploaded: {fileDate}</div>
@@ -69,7 +69,7 @@ const FileField = (props: IProps) => {
69
69
  </S.FileData>
70
70
  </S.FileDataWrapper>
71
71
  {value && value.url && (
72
- <S.TextFieldWrapper>
72
+ <S.TextFieldWrapper data-testid="text-field-wrapper">
73
73
  <TextField
74
74
  name="url"
75
75
  value={value.url}
@@ -82,7 +82,7 @@ const FileField = (props: IProps) => {
82
82
  )}
83
83
  {!value && (
84
84
  <>
85
- <S.Field onClick={handleClick}>
85
+ <S.Field onClick={handleClick} data-testid="field-icon-wrapper">
86
86
  <S.IconWrapper>
87
87
  <Icon name="File" size="24" />
88
88
  </S.IconWrapper>
@@ -106,7 +106,7 @@ const FileField = (props: IProps) => {
106
106
  );
107
107
  };
108
108
 
109
- interface IProps {
109
+ export interface IFileFieldProps {
110
110
  value: any;
111
111
  onChange: (value: any) => void;
112
112
  disabled?: boolean;
@@ -4,13 +4,13 @@ import * as S from "./style";
4
4
 
5
5
  import { Icon, Tooltip } from "@ax/components";
6
6
 
7
- const HiddenField = ({ title, showField, hasMultipleOptions }: IHiddenFieldProps) => {
7
+ const HiddenField = ({ title, showField, hasMultipleOptions }: IHiddenFieldProps): JSX.Element => {
8
8
  return hasMultipleOptions ? (
9
- <S.WrapperMultipleOptions onClick={showField}>
9
+ <S.WrapperMultipleOptions onClick={showField} data-testid="field-multiple-options">
10
10
  <Icon name="add" />
11
11
  </S.WrapperMultipleOptions>
12
12
  ) : (
13
- <S.Wrapper onClick={showField}>
13
+ <S.Wrapper onClick={showField} data-testid="field-single-option">
14
14
  <S.Label>{title}</S.Label>
15
15
  <Tooltip content="Show">
16
16
  <Icon name="add" />
@@ -1,23 +1,14 @@
1
1
  import React, { useState, memo } from "react";
2
2
 
3
3
  import { ISite } from "@ax/types";
4
- import { AsyncCheckGroup, CheckGroup } from "@ax/components";
4
+ import AsyncCheckGroup from "@ax/components/Fields/AsyncCheckGroup";
5
+ import CheckGroup from "@ax/components/Fields/CheckGroup";
5
6
 
6
7
  import * as S from "./style";
7
8
 
8
9
  const MultiCheckSelect = (props: IProps) => {
9
- const {
10
- placeholder,
11
- source,
12
- value,
13
- onChange,
14
- site,
15
- className,
16
- mandatory,
17
- options,
18
- selectAllOption,
19
- floating,
20
- } = props;
10
+ const { placeholder, source, value, onChange, site, className, mandatory, options, selectAllOption, floating } =
11
+ props;
21
12
 
22
13
  const [isOpen, setIsOpen] = useState(false);
23
14
 
@@ -26,27 +17,17 @@ const MultiCheckSelect = (props: IProps) => {
26
17
  const Asterisk = () => (mandatory ? <S.Asterisk>*</S.Asterisk> : null);
27
18
 
28
19
  return (
29
- <S.Wrapper className={className}>
30
- <S.Field isOpen={isOpen} onClick={handleClick}>
20
+ <S.Wrapper className={className} data-testid="multi-check-select-wrapper">
21
+ <S.Field isOpen={isOpen} onClick={handleClick} data-testid="field">
31
22
  {placeholder} <Asterisk />
32
23
  </S.Field>
33
24
  {isOpen && (
34
25
  <S.DropDown floating={floating}>
35
26
  {options && (
36
- <CheckGroup
37
- options={options}
38
- value={value}
39
- onChange={onChange}
40
- selectAllOption={selectAllOption}
41
- />
27
+ <CheckGroup options={options} value={value} onChange={onChange} selectAllOption={selectAllOption} />
42
28
  )}
43
29
  {source && (
44
- <AsyncCheckGroup
45
- source={source}
46
- site={site}
47
- value={value}
48
- onChange={onChange}
49
- fullHeight={true} />
30
+ <AsyncCheckGroup source={source} site={site} value={value} onChange={onChange} fullHeight={true} />
50
31
  )}
51
32
  </S.DropDown>
52
33
  )}