@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.
- package/config/jest/componentsMock.js +1528 -27
- package/package.json +2 -2
- package/src/__mocks__/reducers/app.tsx +10 -0
- package/src/__mocks__/reducers/sites.tsx +10 -0
- package/src/__tests__/{AnalyticsField.test.tsx → components/Fields/AnalyticsField/AnalyticsField.test.tsx} +5 -5
- package/src/__tests__/{PageAnalytics.test.tsx → components/Fields/AnalyticsField/PageAnalytics/PageAnalytics.test.tsx} +2 -2
- package/src/__tests__/{StructuredDataAnalytics.test.tsx → components/Fields/AnalyticsField/StructuredDataAnalytics/StructuredDataAnalytics.test.tsx} +2 -2
- package/src/__tests__/{ArrayFieldGroup.test.tsx → components/Fields/ArrayFieldGroup/ArrayFieldGroup.test.tsx} +2 -2
- package/src/__tests__/{AsyncCheckGroup.test.tsx → components/Fields/AsyncCheckGroup/AsyncCheckGroup.test.tsx} +2 -2
- package/src/__tests__/{AsyncSelect.test.tsx → components/Fields/AsyncSelect/AsyncSelect.test.tsx} +2 -2
- package/src/__tests__/{CheckField.test.tsx → components/Fields/CheckField/CheckField.test.tsx} +2 -2
- package/src/__tests__/{CheckGroup.test.tsx → components/Fields/CheckGroup/CheckGroup.test.tsx} +2 -2
- package/src/__tests__/components/Fields/ColorPicker/ColorPicker.test.tsx +195 -0
- package/src/__tests__/components/Fields/ComponentArray/ComponentArray.test.tsx +184 -0
- package/src/__tests__/components/Fields/ComponentArray/MixableComponentArray/MixableComponentArray.test.tsx +315 -0
- package/src/__tests__/components/Fields/ComponentArray/MixableComponentArray/PasteModuleButton/PasteModuleButton.test.tsx +95 -0
- package/src/__tests__/components/Fields/ComponentArray/SameComponentArray/SameComponentArray.test.tsx +225 -0
- package/src/__tests__/{FieldGroup.test.tsx → components/Fields/FieldGroup/FieldGroup.test.tsx} +2 -2
- package/src/__tests__/components/Fields/FieldsDivider/FieldsDivider.test.tsx +24 -0
- package/src/__tests__/components/Fields/FileField/FileField.test.tsx +135 -0
- package/src/__tests__/{HeadingField.test.tsx → components/Fields/HeadingField/HeadingField.test.tsx} +2 -2
- package/src/__tests__/components/Fields/HiddenField/HiddenField.test.tsx +76 -0
- package/src/__tests__/components/Fields/MultiCheckSelect/MultiCheckSelect.test.tsx +70 -0
- package/src/__tests__/components/Fields/NoteField/NoteField.test.tsx +67 -0
- package/src/__tests__/components/Fields/NumberField/NumberField.test.tsx +109 -0
- package/src/__tests__/components/Fields/RadioField/RadioField.test.tsx +106 -0
- package/src/__tests__/components/Fields/RichText/RichText.test.tsx +52 -0
- package/src/__tests__/components/Fields/Select/Select.test.tsx +75 -0
- package/src/__tests__/components/Fields/SliderField/SliderField.test.tsx +82 -0
- package/src/__tests__/{TagField.test.tsx → components/Fields/TagField/TagField.test.tsx} +2 -2
- package/src/__tests__/{TextArea.test.tsx → components/Fields/TextArea/TextArea.test.tsx} +2 -2
- package/src/__tests__/{TextField.test.tsx → components/Fields/TextField/TextField.test.tsx} +2 -2
- package/src/__tests__/components/Fields/ToggleField/ToggleField.test.tsx +100 -0
- package/src/__tests__/{UniqueCheck.test.tsx → components/Fields/UniqueCheck/UniqueCheck.test.tsx} +2 -2
- package/src/__tests__/components/Fields/UrlField/UrlField.test.tsx +446 -0
- package/src/__tests__/components/Fields/UrlField/mockedAxios.ts +2214 -0
- package/src/__tests__/components/Fields/VisualUniqueSelection/ImageSelection/ImageSelection.test.tsx +99 -0
- package/src/__tests__/components/Fields/VisualUniqueSelection/ScrollableSelection/ScrollableSelection.test.tsx +176 -0
- package/src/__tests__/components/Fields/VisualUniqueSelection/VisualUniqueSelection.test.tsx +78 -0
- package/src/components/ActionMenu/index.tsx +1 -0
- package/src/components/Browser/index.tsx +39 -47
- package/src/components/Browser/style.tsx +15 -15
- package/src/components/BrowserContent/index.tsx +78 -0
- package/src/components/ConfigPanel/Form/ConnectedField/NavConnectedField/index.tsx +3 -5
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +2 -6
- package/src/components/ConfigPanel/Header/index.tsx +28 -11
- package/src/components/ConfigPanel/index.tsx +2 -2
- package/src/components/ErrorCenter/index.tsx +11 -4
- package/src/components/Fields/ArrayFieldGroup/index.tsx +4 -2
- package/src/components/Fields/ArrayFieldGroup/style.tsx +7 -0
- package/src/components/Fields/AsyncCheckGroup/index.tsx +1 -1
- package/src/components/Fields/CheckField/index.tsx +1 -1
- package/src/components/Fields/ColorPicker/Picker/index.tsx +9 -3
- package/src/components/Fields/ColorPicker/index.tsx +4 -9
- package/src/components/Fields/ComponentArray/MixableComponentArray/PasteModuleButton/index.tsx +2 -1
- package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +27 -22
- package/src/components/Fields/ComponentArray/MixableComponentArray/style.tsx +3 -38
- package/src/components/Fields/ComponentArray/SameComponentArray/index.tsx +3 -2
- package/src/components/Fields/ComponentArray/SameComponentArray/style.tsx +1 -28
- package/src/components/Fields/ComponentArray/helpers.tsx +1 -1
- package/src/components/Fields/ComponentContainer/index.tsx +3 -1
- package/src/components/Fields/FileField/FileDragAndDrop/index.tsx +1 -1
- package/src/components/Fields/FileField/FileDragAndDrop/style.tsx +2 -3
- package/src/components/Fields/FileField/index.tsx +6 -6
- package/src/components/Fields/HiddenField/index.tsx +3 -3
- package/src/components/Fields/MultiCheckSelect/index.tsx +8 -27
- package/src/components/Fields/NoteField/index.tsx +3 -3
- package/src/components/Fields/NumberField/index.tsx +6 -3
- package/src/components/Fields/RadioField/index.tsx +10 -2
- package/src/components/Fields/ReferenceField/index.tsx +8 -1
- package/src/components/Fields/ReferenceField/style.tsx +5 -0
- package/src/components/Fields/RichText/index.tsx +1 -1
- package/src/components/Fields/SliderField/index.tsx +11 -7
- package/src/components/Fields/ToggleField/index.tsx +12 -3
- package/src/components/Fields/UrlField/PageFinder/SelectionListItem/index.tsx +1 -1
- package/src/components/Fields/UrlField/index.tsx +6 -4
- package/src/components/Fields/UrlField/style.tsx +4 -2
- package/src/components/Fields/VisualOption/index.tsx +10 -2
- package/src/components/Fields/VisualUniqueSelection/ImageSelection/index.tsx +2 -2
- package/src/components/Fields/VisualUniqueSelection/ScrollableSelection/index.tsx +4 -3
- package/src/components/Fields/VisualUniqueSelection/ScrollableSelection/style.tsx +1 -1
- package/src/components/Fields/VisualUniqueSelection/index.tsx +3 -3
- package/src/components/FieldsBehavior/index.tsx +4 -4
- package/src/components/FieldsBehavior/style.tsx +5 -12
- package/src/components/FloatingMenu/index.tsx +8 -4
- package/src/components/Loader/index.tsx +12 -8
- package/src/components/MainWrapper/AppBar/index.tsx +1 -0
- package/src/components/MainWrapper/index.tsx +1 -0
- package/src/components/Toast/index.tsx +1 -1
- package/src/components/Tooltip/index.tsx +1 -1
- package/src/components/index.tsx +2 -0
- package/src/containers/App/actions.tsx +3 -7
- package/src/containers/PageEditor/actions.tsx +36 -5
- package/src/forms/editor.tsx +35 -1
- package/src/forms/fields.tsx +6 -2
- package/src/forms/index.tsx +2 -0
- package/src/forms/validators.tsx +29 -8
- package/src/guards/error/index.tsx +1 -1
- package/src/helpers/containerEvaluations.tsx +32 -4
- package/src/helpers/index.tsx +2 -0
- package/src/helpers/structuredData.tsx +2 -2
- package/src/hooks/forms.tsx +1 -28
- package/src/hooks/index.tsx +1 -2
- package/src/modules/FramePreview/index.tsx +70 -36
- package/src/modules/FramePreview/style.tsx +3 -0
- package/src/modules/GlobalEditor/PageBrowser/index.tsx +2 -7
- package/src/modules/GlobalEditor/index.tsx +8 -6
- package/src/modules/GlobalEditor/style.tsx +1 -1
- package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +0 -4
- package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +3 -2
- package/src/modules/PageEditor/PageBrowser/index.tsx +1 -4
- package/src/modules/PageEditor/index.tsx +6 -6
- package/src/modules/PublicPreview/index.tsx +17 -34
- package/src/modules/PublicPreview/style.tsx +0 -2
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +0 -4
- package/src/modules/Sites/index.tsx +1 -1
- package/src/modules/StructuredData/Form/ConnectedField/index.tsx +1 -1
- package/src/modules/StructuredData/Form/index.tsx +3 -1
- package/src/modules/StructuredData/StructuredDataList/index.tsx +1 -0
- package/src/schemas/pages/GlobalPage.tsx +1 -0
- package/src/types/index.tsx +1 -0
|
@@ -7,9 +7,9 @@ const NoteField = (props: INoteFieldProps): JSX.Element => {
|
|
|
7
7
|
const { title, text } = value;
|
|
8
8
|
|
|
9
9
|
return (
|
|
10
|
-
<S.Wrapper className={className}>
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
<S.Wrapper className={className} data-testid="noteFieldWrapper">
|
|
11
|
+
{title && <S.Title data-testid="title">{title}</S.Title>}
|
|
12
|
+
<S.Text>{text}</S.Text>
|
|
13
13
|
</S.Wrapper>
|
|
14
14
|
);
|
|
15
15
|
};
|
|
@@ -13,6 +13,7 @@ const NumberField = (props: INumberFieldProps): JSX.Element => {
|
|
|
13
13
|
useEffect(() => {
|
|
14
14
|
setInputValue(strValue);
|
|
15
15
|
}, [strValue]);
|
|
16
|
+
|
|
16
17
|
const setValue = (value: string, eventType: string) => {
|
|
17
18
|
const floatValue = parseFloat(value);
|
|
18
19
|
setInputValue(value);
|
|
@@ -45,6 +46,7 @@ const NumberField = (props: INumberFieldProps): JSX.Element => {
|
|
|
45
46
|
setValue(e.target.value, e.type);
|
|
46
47
|
handleValidation && handleValidation(e.target.value, validators);
|
|
47
48
|
};
|
|
49
|
+
|
|
48
50
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
49
51
|
setValue(e.target.value, e.type);
|
|
50
52
|
error && handleValidation && handleValidation(e.target.value, validators);
|
|
@@ -54,7 +56,7 @@ const NumberField = (props: INumberFieldProps): JSX.Element => {
|
|
|
54
56
|
const decreaseValue = () => handleClick("ArrowDown");
|
|
55
57
|
|
|
56
58
|
return (
|
|
57
|
-
<S.FieldWrapper error={error}>
|
|
59
|
+
<S.FieldWrapper error={error} data-testid="conditional-field-wrapper">
|
|
58
60
|
<S.Input
|
|
59
61
|
type="number"
|
|
60
62
|
value={inputValue}
|
|
@@ -65,12 +67,13 @@ const NumberField = (props: INumberFieldProps): JSX.Element => {
|
|
|
65
67
|
min={minValue}
|
|
66
68
|
max={maxValue}
|
|
67
69
|
disabled={disabled}
|
|
70
|
+
data-testid="input"
|
|
68
71
|
/>
|
|
69
72
|
<S.QuantityNav error={error} disabled={disabled}>
|
|
70
|
-
<S.ArrowUp onClick={increaseValue}>
|
|
73
|
+
<S.ArrowUp onClick={increaseValue} data-testid="arrow-up">
|
|
71
74
|
<Icon name="UpArrow" />
|
|
72
75
|
</S.ArrowUp>
|
|
73
|
-
<S.ArrowDown onClick={decreaseValue}>
|
|
76
|
+
<S.ArrowDown onClick={decreaseValue} data-testid="arrow-down">
|
|
74
77
|
<Icon name="DownArrow" />
|
|
75
78
|
</S.ArrowDown>
|
|
76
79
|
</S.QuantityNav>
|
|
@@ -12,10 +12,18 @@ const RadioField = (props: IRadioFieldProps): JSX.Element => {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
return (
|
|
15
|
-
<S.Wrapper>
|
|
15
|
+
<S.Wrapper data-testid="radio-field-wrapper">
|
|
16
16
|
<S.Label>
|
|
17
17
|
{title}
|
|
18
|
-
<S.Input
|
|
18
|
+
<S.Input
|
|
19
|
+
type="radio"
|
|
20
|
+
name={name}
|
|
21
|
+
value={value}
|
|
22
|
+
checked={checked}
|
|
23
|
+
disabled={disabled}
|
|
24
|
+
onChange={handleChange}
|
|
25
|
+
data-testid="radio-field-input"
|
|
26
|
+
/>
|
|
19
27
|
<S.CheckMark checked={checked} error={error} />
|
|
20
28
|
</S.Label>
|
|
21
29
|
</S.Wrapper>
|
|
@@ -32,6 +32,7 @@ const ReferenceField = (props: IProps) => {
|
|
|
32
32
|
maxItems,
|
|
33
33
|
resetValidation,
|
|
34
34
|
handleValidation,
|
|
35
|
+
mandatory,
|
|
35
36
|
} = props;
|
|
36
37
|
|
|
37
38
|
const { isOpen, toggleModal } = useModal();
|
|
@@ -178,9 +179,14 @@ const ReferenceField = (props: IProps) => {
|
|
|
178
179
|
|
|
179
180
|
const manualItems = !isAuto && value && Array.isArray(value.fixed) ? value.fixed.length : 0;
|
|
180
181
|
|
|
182
|
+
const Asterisk = () => (mandatory ? <S.Asterisk>*</S.Asterisk> : null);
|
|
183
|
+
|
|
181
184
|
return (
|
|
182
185
|
<S.Wrapper>
|
|
183
|
-
<S.Label>
|
|
186
|
+
<S.Label>
|
|
187
|
+
Elements
|
|
188
|
+
<Asterisk />
|
|
189
|
+
</S.Label>
|
|
184
190
|
<S.ModeWrapper>
|
|
185
191
|
{!singleMode && (
|
|
186
192
|
<Select
|
|
@@ -224,6 +230,7 @@ interface IProps {
|
|
|
224
230
|
maxItems?: number;
|
|
225
231
|
resetValidation?: () => void;
|
|
226
232
|
handleValidation?: (value: string, validators?: Record<string, unknown>) => void;
|
|
233
|
+
mandatory: boolean;
|
|
227
234
|
}
|
|
228
235
|
|
|
229
236
|
const mapStateToProps = (state: IRootState) => ({
|
|
@@ -11,6 +11,10 @@ const Label = styled.div`
|
|
|
11
11
|
border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
|
|
12
12
|
`;
|
|
13
13
|
|
|
14
|
+
const Asterisk = styled.span`
|
|
15
|
+
color: ${(p) => p.theme.color.error};
|
|
16
|
+
`;
|
|
17
|
+
|
|
14
18
|
const ActionWrapper = styled.div`
|
|
15
19
|
position: absolute;
|
|
16
20
|
right: 0;
|
|
@@ -53,6 +57,7 @@ const SingleModeText = styled.span`
|
|
|
53
57
|
`;
|
|
54
58
|
|
|
55
59
|
export {
|
|
60
|
+
Asterisk,
|
|
56
61
|
Wrapper,
|
|
57
62
|
Label,
|
|
58
63
|
ActionWrapper,
|
|
@@ -89,7 +89,7 @@ const RichText = (props: IRichTextProps): JSX.Element => {
|
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
return (
|
|
92
|
-
<S.EditorWrapper error={error} disabled={disabled}>
|
|
92
|
+
<S.EditorWrapper error={error} disabled={disabled} data-testid="rich-text-wrapper">
|
|
93
93
|
<Editor
|
|
94
94
|
editorState={editorState}
|
|
95
95
|
toolbarClassName="richTextToolbar"
|
|
@@ -9,7 +9,7 @@ const SliderField = (props: ITextFieldProps): JSX.Element => {
|
|
|
9
9
|
const val = typeof value === "undefined" ? defaultValue : value;
|
|
10
10
|
|
|
11
11
|
useEffect(() => {
|
|
12
|
-
|
|
12
|
+
onChange(Number(val));
|
|
13
13
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
14
14
|
}, []);
|
|
15
15
|
|
|
@@ -17,22 +17,26 @@ const SliderField = (props: ITextFieldProps): JSX.Element => {
|
|
|
17
17
|
if (bubbleRef.current) {
|
|
18
18
|
bubbleRef.current.style.left = setBubbleLeft();
|
|
19
19
|
}
|
|
20
|
-
});
|
|
20
|
+
}, [bubbleRef]);
|
|
21
21
|
|
|
22
22
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
23
23
|
const newValue = e.target.value;
|
|
24
24
|
onChange(Number(newValue));
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
const setBubbleLeft = () => {
|
|
28
28
|
const half = Number(((val - min) * 100) / (max - min));
|
|
29
29
|
return `calc(${half}% + (${8 - half * 0.16}px))`;
|
|
30
|
-
}
|
|
30
|
+
};
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
|
-
<S.Slider>
|
|
34
|
-
<S.Bubble ref={bubbleRef}>
|
|
35
|
-
|
|
33
|
+
<S.Slider data-testid="sliderComponent">
|
|
34
|
+
<S.Bubble data-testid="bubbleComponent" ref={bubbleRef}>
|
|
35
|
+
{prefix && `${prefix} `}
|
|
36
|
+
{val}
|
|
37
|
+
{suffix && ` ${suffix}`}
|
|
38
|
+
</S.Bubble>
|
|
39
|
+
<S.Input data-testid="inputComponent" value={value} min={min} max={max} step={step} onChange={handleChange} />
|
|
36
40
|
</S.Slider>
|
|
37
41
|
);
|
|
38
42
|
};
|
|
@@ -13,9 +13,18 @@ const ToggleField = (props: IToggleFieldProps): JSX.Element => {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
return (
|
|
16
|
-
<S.Wrapper>
|
|
17
|
-
<S.Input
|
|
18
|
-
|
|
16
|
+
<S.Wrapper data-testid="toggle-field-wrapper">
|
|
17
|
+
<S.Input
|
|
18
|
+
id="toggle"
|
|
19
|
+
type="checkbox"
|
|
20
|
+
name={name}
|
|
21
|
+
value={value || false}
|
|
22
|
+
checked={checked}
|
|
23
|
+
disabled={disabled}
|
|
24
|
+
onChange={handleChange}
|
|
25
|
+
data-testid="toggle-field-input"
|
|
26
|
+
/>
|
|
27
|
+
<S.Label htmlFor="toggle" />
|
|
19
28
|
</S.Wrapper>
|
|
20
29
|
);
|
|
21
30
|
};
|
|
@@ -13,7 +13,7 @@ const SelectionListItem = (props: ISelectionListItemProps): JSX.Element => {
|
|
|
13
13
|
const pageType = type || "Page";
|
|
14
14
|
|
|
15
15
|
return (
|
|
16
|
-
<S.ListItem onClick={handleOnClick}>
|
|
16
|
+
<S.ListItem onClick={handleOnClick} data-testid="selection-list-item">
|
|
17
17
|
<S.Header>
|
|
18
18
|
<S.Type>{pageType}</S.Type>
|
|
19
19
|
<S.Date>{getFormattedDateWithTimezone(date, "d MMM Y")}</S.Date>
|
|
@@ -129,7 +129,9 @@ const UrlField = (props: IUrlFieldProps): JSX.Element => {
|
|
|
129
129
|
if (pageID) {
|
|
130
130
|
field = (
|
|
131
131
|
<S.PageSelectedWrapper>
|
|
132
|
-
<S.PageField onClick={handleOnClick}
|
|
132
|
+
<S.PageField onClick={handleOnClick} data-testid="page-field">
|
|
133
|
+
{internalPageName && `- ${internalPageName} -`}
|
|
134
|
+
</S.PageField>
|
|
133
135
|
<S.IconWrapper>
|
|
134
136
|
<IconAction icon="unlink" onClick={handleReset} disabled={disabled} />
|
|
135
137
|
</S.IconWrapper>
|
|
@@ -162,7 +164,7 @@ const UrlField = (props: IUrlFieldProps): JSX.Element => {
|
|
|
162
164
|
];
|
|
163
165
|
|
|
164
166
|
return (
|
|
165
|
-
|
|
167
|
+
<S.UrlFieldWrapper data-testid="url-field-wrapper">
|
|
166
168
|
{field}
|
|
167
169
|
{value && value.linkTo && isTabsVisible && (
|
|
168
170
|
<S.AnchorWrapper>
|
|
@@ -217,11 +219,11 @@ const UrlField = (props: IUrlFieldProps): JSX.Element => {
|
|
|
217
219
|
>
|
|
218
220
|
<PageFinder onClick={handleSetPage} isOpen={isOpen} />
|
|
219
221
|
</FloatingPanel>
|
|
220
|
-
|
|
222
|
+
</S.UrlFieldWrapper>
|
|
221
223
|
);
|
|
222
224
|
};
|
|
223
225
|
|
|
224
|
-
interface IUrlFieldProps {
|
|
226
|
+
export interface IUrlFieldProps {
|
|
225
227
|
value: IUrlField | null;
|
|
226
228
|
title: string;
|
|
227
229
|
onChange: (value: IUrlField | null) => void;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import styled from "styled-components";
|
|
2
2
|
|
|
3
|
+
const UrlFieldWrapper = styled.div``;
|
|
4
|
+
|
|
3
5
|
const PageSelectedWrapper = styled.div`
|
|
4
6
|
display: flex;
|
|
5
7
|
box-shadow: ${(p) => p.theme.shadow.shadowS};
|
|
@@ -33,7 +35,7 @@ const IconWrapper = styled.div`
|
|
|
33
35
|
transform: translate(-50%, -50%);
|
|
34
36
|
svg {
|
|
35
37
|
width: ${(p) => p.theme.spacing.m};
|
|
36
|
-
height: ${(p) => p.theme.spacing.m}
|
|
38
|
+
height: ${(p) => p.theme.spacing.m};
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
`;
|
|
@@ -52,4 +54,4 @@ const AnchorWrapper = styled.div`
|
|
|
52
54
|
margin-top: ${(p) => p.theme.spacing.s};
|
|
53
55
|
`;
|
|
54
56
|
|
|
55
|
-
export { PageSelectedWrapper, PageField, IconWrapper, AdvancedWrapper, AnchorWrapper };
|
|
57
|
+
export { PageSelectedWrapper, PageField, IconWrapper, AdvancedWrapper, AnchorWrapper, UrlFieldWrapper };
|
|
@@ -9,9 +9,17 @@ const VisualOption = ({ value, onChange, name, label, checked, img, disabled }:
|
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
11
|
<S.Label>
|
|
12
|
-
<S.RadioButton
|
|
12
|
+
<S.RadioButton
|
|
13
|
+
data-testid="radioButtons"
|
|
14
|
+
type="radio"
|
|
15
|
+
name={name}
|
|
16
|
+
value={value}
|
|
17
|
+
checked={checked}
|
|
18
|
+
onChange={handleChange}
|
|
19
|
+
disabled={disabled}
|
|
20
|
+
/>
|
|
13
21
|
<S.ImageWrapper active={checked} disabled={disabled}>
|
|
14
|
-
<S.Image src={img}/>
|
|
22
|
+
<S.Image src={img} />
|
|
15
23
|
</S.ImageWrapper>
|
|
16
24
|
</S.Label>
|
|
17
25
|
);
|
|
@@ -13,7 +13,7 @@ const ImageSelection = (props: IImageSelectionProps): JSX.Element => {
|
|
|
13
13
|
const handleChange = (newValue: string) => onChange(newValue);
|
|
14
14
|
|
|
15
15
|
return (
|
|
16
|
-
<S.Wrapper columns={columns}>
|
|
16
|
+
<S.Wrapper columns={columns} data-testid="imageSelectionComponent">
|
|
17
17
|
{mappedOptions.map((option: any, index: number) => (
|
|
18
18
|
<VisualOption
|
|
19
19
|
value={option.value}
|
|
@@ -30,7 +30,7 @@ const ImageSelection = (props: IImageSelectionProps): JSX.Element => {
|
|
|
30
30
|
);
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
interface IImageSelectionProps {
|
|
33
|
+
export interface IImageSelectionProps {
|
|
34
34
|
value: string;
|
|
35
35
|
title: string;
|
|
36
36
|
onChange: (value: string) => void;
|
|
@@ -39,7 +39,7 @@ const ScrollableSelection = (props: IScrollableSelectionProps): JSX.Element => {
|
|
|
39
39
|
}, [carouselRef, columns]);
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
|
-
<S.Wrapper>
|
|
42
|
+
<S.Wrapper data-testid="scrollableSelectionComponent">
|
|
43
43
|
<S.Carousel ref={carouselRef}>
|
|
44
44
|
{mappedOptions.map((option: IScrollableUniqueSelectionFieldOptionsProps, index: number) => (
|
|
45
45
|
<S.CarouselItem width={carouselItemWidth} columns={columns} key={index}>
|
|
@@ -62,7 +62,7 @@ const ScrollableSelection = (props: IScrollableSelectionProps): JSX.Element => {
|
|
|
62
62
|
</S.MoveButton>
|
|
63
63
|
<S.DotGroup>
|
|
64
64
|
{[...Array(slides)].map((_, i) => (
|
|
65
|
-
<S.Dot selected={i === carouselIndex} key={i}></S.Dot>
|
|
65
|
+
<S.Dot data-testid="dotSelected" selected={i === carouselIndex} key={i}></S.Dot>
|
|
66
66
|
))}
|
|
67
67
|
</S.DotGroup>
|
|
68
68
|
<S.MoveButton>
|
|
@@ -74,7 +74,7 @@ const ScrollableSelection = (props: IScrollableSelectionProps): JSX.Element => {
|
|
|
74
74
|
);
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
interface IScrollableSelectionProps {
|
|
77
|
+
export interface IScrollableSelectionProps {
|
|
78
78
|
value: string;
|
|
79
79
|
title: string;
|
|
80
80
|
onChange: (value: string) => void;
|
|
@@ -87,6 +87,7 @@ interface IScrollableSelectionProps {
|
|
|
87
87
|
selectedContent: any;
|
|
88
88
|
reference?: string;
|
|
89
89
|
theme: string;
|
|
90
|
+
elementUniqueSelection: boolean;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
interface IScrollableUniqueSelectionFieldOptionsProps {
|
|
@@ -45,7 +45,7 @@ export const Dot = styled.div<{ selected: boolean }>`
|
|
|
45
45
|
background-color: ${(p) => (p.selected ? p.theme.color.uiSiteMenu : p.theme.color.uiLine)};
|
|
46
46
|
`;
|
|
47
47
|
|
|
48
|
-
export const MoveButton = styled.
|
|
48
|
+
export const MoveButton = styled.div`
|
|
49
49
|
background-color: transparent;
|
|
50
50
|
border: 0;
|
|
51
51
|
`;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import ImageSelection from "./ImageSelection";
|
|
4
|
-
import ScrollableSelection from "./ScrollableSelection";
|
|
3
|
+
import ImageSelection, { IImageSelectionProps } from "./ImageSelection";
|
|
4
|
+
import ScrollableSelection, { IScrollableSelectionProps } from "./ScrollableSelection";
|
|
5
5
|
|
|
6
|
-
const VisualUniqueSelection = (props:
|
|
6
|
+
const VisualUniqueSelection = (props: IImageSelectionProps & IScrollableSelectionProps): JSX.Element => {
|
|
7
7
|
const { elementUniqueSelection = false } = props;
|
|
8
8
|
const Component = elementUniqueSelection ? ScrollableSelection : ImageSelection;
|
|
9
9
|
|
|
@@ -40,7 +40,7 @@ const FieldsBehavior = (props: any): JSX.Element => {
|
|
|
40
40
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
41
|
}, [editorID, error]);
|
|
42
42
|
|
|
43
|
-
const helpTextWrapper = message ? <S.HelpText>{message}</S.HelpText> : "";
|
|
43
|
+
const helpTextWrapper = message ? <S.HelpText error={errorField}>{message}</S.HelpText> : "";
|
|
44
44
|
const isComponentArray = fieldType === "ComponentArray";
|
|
45
45
|
const isComponentContainer = fieldType === "ComponentContainer";
|
|
46
46
|
const hasMultipleOptions: boolean = whiteList && whiteList.length > 1;
|
|
@@ -79,8 +79,8 @@ const FieldsBehavior = (props: any): JSX.Element => {
|
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
return (
|
|
82
|
-
<S.Wrapper
|
|
83
|
-
<S.Content data-testid="contentWrapper"
|
|
82
|
+
<S.Wrapper className={wrapperClass} showTitle={showTitle} id={objKey}>
|
|
83
|
+
<S.Content error={errorField} data-testid="contentWrapper">
|
|
84
84
|
<Field
|
|
85
85
|
{...props}
|
|
86
86
|
showAdvanced={showAdvanced}
|
|
@@ -91,7 +91,7 @@ const FieldsBehavior = (props: any): JSX.Element => {
|
|
|
91
91
|
</S.Content>
|
|
92
92
|
<S.Header className="fieldHeader">
|
|
93
93
|
{showTitle && (
|
|
94
|
-
<S.Label htmlFor={name}>
|
|
94
|
+
<S.Label htmlFor={name} error={errorField}>
|
|
95
95
|
{title} <Asterisk />
|
|
96
96
|
</S.Label>
|
|
97
97
|
)}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import styled from "styled-components";
|
|
2
2
|
|
|
3
|
-
export const Label = styled.label
|
|
3
|
+
export const Label = styled.label<{ error: boolean | undefined }>`
|
|
4
4
|
${(p) => p.theme.textStyle?.fieldLabel};
|
|
5
|
-
color: ${(p) => p.theme.color?.textMediumEmphasis};
|
|
5
|
+
color: ${(p) => (p.error === true ? p.theme.color?.error : p.theme.color?.textMediumEmphasis)};
|
|
6
6
|
display: block;
|
|
7
7
|
margin-bottom: ${(p) => p.theme.spacing?.xs};
|
|
8
8
|
`;
|
|
@@ -11,9 +11,9 @@ export const Asterisk = styled.span`
|
|
|
11
11
|
color: ${(p) => p.theme.color?.error};
|
|
12
12
|
`;
|
|
13
13
|
|
|
14
|
-
export const HelpText = styled.div
|
|
14
|
+
export const HelpText = styled.div<{ error: boolean | undefined }>`
|
|
15
15
|
${(p) => p.theme.textStyle.uiXS};
|
|
16
|
-
color: ${(p) => p.theme.color?.textMediumEmphasis};
|
|
16
|
+
color: ${(p) => (p.error === true ? p.theme.color?.error : p.theme.color?.textMediumEmphasis)};
|
|
17
17
|
`;
|
|
18
18
|
|
|
19
19
|
export const Header = styled.div`
|
|
@@ -30,19 +30,12 @@ export const Icons = styled.div`
|
|
|
30
30
|
display: flex;
|
|
31
31
|
`;
|
|
32
32
|
|
|
33
|
-
export const Wrapper = styled.div<{
|
|
33
|
+
export const Wrapper = styled.div<{ showTitle: boolean | undefined }>`
|
|
34
34
|
position: relative;
|
|
35
35
|
margin-bottom: ${(p) => p.theme.spacing?.m};
|
|
36
36
|
padding-top: ${(p) => (p.showTitle ? p.theme.spacing?.m : 0)};
|
|
37
37
|
width: 100%;
|
|
38
38
|
|
|
39
|
-
${HelpText} {
|
|
40
|
-
color: ${(p) => (p.error === true ? p.theme.color?.error : p.theme.color?.textMediumEmphasis)};
|
|
41
|
-
}
|
|
42
|
-
${Label} {
|
|
43
|
-
color: ${(p) => (p.error === true ? p.theme.color?.error : p.theme.color?.textMediumEmphasis)};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
39
|
&:hover > .fieldHeader ${Icons} {
|
|
47
40
|
opacity: 1;
|
|
48
41
|
}
|
|
@@ -57,15 +57,19 @@ const FloatingMenu = (props: IProps) => {
|
|
|
57
57
|
useHandleClickOutside(isOpen, handleClickOutside);
|
|
58
58
|
|
|
59
59
|
return (
|
|
60
|
-
<S.Wrapper
|
|
60
|
+
<S.Wrapper
|
|
61
|
+
ref={wrapper}
|
|
62
|
+
onClick={handleClick}
|
|
63
|
+
onMouseEnter={handleMouseEnter}
|
|
64
|
+
onMouseLeave={handleMouseLeave}
|
|
65
|
+
data-testid="floating-menu"
|
|
66
|
+
>
|
|
61
67
|
<S.ButtonWrapper ref={button}>
|
|
62
68
|
<Button />
|
|
63
69
|
</S.ButtonWrapper>
|
|
64
70
|
{isOpen && (
|
|
65
71
|
<S.MenuWrapper isInAppBar={isInAppBar} ref={menuOptions} position={position} offset={offset}>
|
|
66
|
-
<S.Menu>
|
|
67
|
-
{children}
|
|
68
|
-
</S.Menu>
|
|
72
|
+
<S.Menu>{children}</S.Menu>
|
|
69
73
|
</S.MenuWrapper>
|
|
70
74
|
)}
|
|
71
75
|
</S.Wrapper>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import Circle from "./components/Circle";
|
|
4
|
+
import Dots from "./components/Dots";
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const components: Record<string, () => JSX.Element> = { Circle, Dots };
|
|
7
|
+
|
|
8
|
+
const Loader = (props: IProps): JSX.Element => {
|
|
7
9
|
const name = props.name
|
|
8
10
|
.replace(".svg", "")
|
|
9
11
|
.split("-")
|
|
@@ -11,12 +13,14 @@ const Loader = (props: IProps) => {
|
|
|
11
13
|
.join("");
|
|
12
14
|
|
|
13
15
|
const { size = "70" } = props;
|
|
16
|
+
const elementProps = {
|
|
17
|
+
height: size,
|
|
18
|
+
width: size,
|
|
19
|
+
viewBox: "0 0 100 100",
|
|
20
|
+
};
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<Svg height={size} width={size} viewBox="0 0 100 100" />
|
|
18
|
-
);
|
|
19
|
-
}
|
|
22
|
+
return React.createElement(components[name], elementProps);
|
|
23
|
+
};
|
|
20
24
|
|
|
21
25
|
interface IStateProps {
|
|
22
26
|
name: string;
|
|
@@ -25,7 +25,7 @@ const Toast = (props: IProps) => {
|
|
|
25
25
|
|
|
26
26
|
return createPortal(
|
|
27
27
|
<S.Wrapper ref={toast}>
|
|
28
|
-
<S.Text>{message}</S.Text>
|
|
28
|
+
<S.Text data-testid="toastMessage">{message}</S.Text>
|
|
29
29
|
<S.Buttons>
|
|
30
30
|
{action &&
|
|
31
31
|
<Button type="button" buttonStyle="lineInverse" onClick={action}>
|
|
@@ -78,7 +78,7 @@ const Tooltip = (props: IProps): JSX.Element => {
|
|
|
78
78
|
if (!content) return children;
|
|
79
79
|
|
|
80
80
|
return (
|
|
81
|
-
<S.Tooltip onMouseEnter={showTip} onMouseLeave={hideTip} onMouseDown={handleClick}>
|
|
81
|
+
<S.Tooltip data-testid="tooltipComponent" onMouseEnter={showTip} onMouseLeave={hideTip} onMouseDown={handleClick}>
|
|
82
82
|
<div ref={childrenRef}>{children}</div>
|
|
83
83
|
<S.Tip
|
|
84
84
|
active={active}
|
package/src/components/index.tsx
CHANGED
|
@@ -47,6 +47,7 @@ import ActionMenu from "./ActionMenu";
|
|
|
47
47
|
import Avatar from "./Avatar";
|
|
48
48
|
import Breadcrumb from "./Breadcrumb";
|
|
49
49
|
import Browser from "./Browser";
|
|
50
|
+
import BrowserContent from "./BrowserContent";
|
|
50
51
|
import BulkSelectionOptions from "./BulkSelectionOptions";
|
|
51
52
|
import Button from "./Button";
|
|
52
53
|
import CategoryCell from "./CategoryCell";
|
|
@@ -140,6 +141,7 @@ export {
|
|
|
140
141
|
Avatar,
|
|
141
142
|
Breadcrumb,
|
|
142
143
|
Browser,
|
|
144
|
+
BrowserContent,
|
|
143
145
|
BulkSelectionOptions,
|
|
144
146
|
Button,
|
|
145
147
|
CategoryCell,
|
|
@@ -99,14 +99,10 @@ function resetError(): ISetErrorAction {
|
|
|
99
99
|
|
|
100
100
|
function handleError(response: any): (dispatch: Dispatch) => Promise<void> {
|
|
101
101
|
return async (dispatch) => {
|
|
102
|
-
const {
|
|
103
|
-
data: { code, message },
|
|
104
|
-
btnText,
|
|
105
|
-
actionsBelow,
|
|
106
|
-
} = response;
|
|
102
|
+
const { data, btnText, actionsBelow, text } = response;
|
|
107
103
|
const error = {
|
|
108
|
-
code,
|
|
109
|
-
text: message,
|
|
104
|
+
code: data?.code,
|
|
105
|
+
text: data?.message || text,
|
|
110
106
|
btnText,
|
|
111
107
|
actionsBelow,
|
|
112
108
|
};
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
checkH1content,
|
|
30
30
|
parseValidationErrors,
|
|
31
31
|
findPackagesActivationErrors,
|
|
32
|
+
checkMaxModules,
|
|
32
33
|
} from "@ax/forms";
|
|
33
34
|
import { appActions } from "@ax/containers/App";
|
|
34
35
|
import { navigationActions } from "@ax/containers/Navigation";
|
|
@@ -100,6 +101,15 @@ const { getSiteDefaults, getDefaults } = navigationActions;
|
|
|
100
101
|
// FIXME: CHECK EDITOR CONTENT STRUCTURE (editorContent.editorContent)
|
|
101
102
|
|
|
102
103
|
function setEditorContent(editorContent: IPage | Record<string, unknown>): ISetEditorContent {
|
|
104
|
+
const iframe = document.querySelector("iframe");
|
|
105
|
+
iframe?.contentWindow?.postMessage(
|
|
106
|
+
{
|
|
107
|
+
type: "content-update",
|
|
108
|
+
message: editorContent,
|
|
109
|
+
},
|
|
110
|
+
"*"
|
|
111
|
+
);
|
|
112
|
+
|
|
103
113
|
return { type: SET_EDITOR_CONTENT, payload: { editorContent } };
|
|
104
114
|
}
|
|
105
115
|
|
|
@@ -654,6 +664,13 @@ function addModule(
|
|
|
654
664
|
): (dispatch: Dispatch, getState: any) => void {
|
|
655
665
|
return (dispatch, getState) => {
|
|
656
666
|
const { editorContent, sections, editorID } = getStateValues(getState);
|
|
667
|
+
|
|
668
|
+
const { isMaxModules, errorMessage } = checkMaxModules(editorContent, type);
|
|
669
|
+
if (isMaxModules) {
|
|
670
|
+
handleError({ text: errorMessage })(dispatch);
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
|
|
657
674
|
const componentModule = {
|
|
658
675
|
editorID,
|
|
659
676
|
type,
|
|
@@ -763,6 +780,13 @@ function duplicateModule(editorID: number, key?: string): (dispatch: Dispatch, g
|
|
|
763
780
|
|
|
764
781
|
const updatedSections: any = [...sections];
|
|
765
782
|
const { element: originalItem, parent, grandParent } = findByEditorID(updatedSections, editorID);
|
|
783
|
+
|
|
784
|
+
const { isMaxModules, errorMessage } = checkMaxModules(editorContent, originalItem.component);
|
|
785
|
+
if (isMaxModules) {
|
|
786
|
+
handleError({ text: errorMessage })(dispatch);
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
|
|
766
790
|
const parentModule = Array.isArray(parent) ? grandParent : parent;
|
|
767
791
|
|
|
768
792
|
const parentKey = key ? key : getParentKey(parentModule, editorID);
|
|
@@ -814,6 +838,15 @@ function pasteModule(editorID: number): (dispatch: Dispatch, getState: any) => P
|
|
|
814
838
|
|
|
815
839
|
const { sections, editorContent } = getStateValues(getState);
|
|
816
840
|
|
|
841
|
+
const { isMaxModules, errorMessage } = checkMaxModules(editorContent, moduleCopy.element.component);
|
|
842
|
+
if (isMaxModules && errorMessage) {
|
|
843
|
+
const error: INotification = {
|
|
844
|
+
type: "error",
|
|
845
|
+
text: errorMessage,
|
|
846
|
+
};
|
|
847
|
+
return { error };
|
|
848
|
+
}
|
|
849
|
+
|
|
817
850
|
const updatedSections: any = [...sections];
|
|
818
851
|
const { element: originalElement } = findByEditorID(updatedSections, editorID);
|
|
819
852
|
|
|
@@ -1069,7 +1102,7 @@ function getTemplateConfig(template: string): (dispatch: Dispatch, getState: any
|
|
|
1069
1102
|
};
|
|
1070
1103
|
}
|
|
1071
1104
|
|
|
1072
|
-
function validatePage(publish?: boolean
|
|
1105
|
+
function validatePage(publish?: boolean): (dispatch: Dispatch, getState: any) => Promise<boolean> {
|
|
1073
1106
|
return async (dispatch, getState) => {
|
|
1074
1107
|
try {
|
|
1075
1108
|
const { editorContent } = getStateValues(getState);
|
|
@@ -1104,10 +1137,8 @@ function validatePage(publish?: boolean, browserRef?: any): (dispatch: Dispatch,
|
|
|
1104
1137
|
errors = packagesActivationErrors ? [...errors, packagesActivationErrors] : errors;
|
|
1105
1138
|
|
|
1106
1139
|
let warnings: IErrorItem[] = [];
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
warnings = h1Warning ? [...warnings, h1Warning] : warnings;
|
|
1110
|
-
}
|
|
1140
|
+
const h1Warning = checkH1content();
|
|
1141
|
+
warnings = h1Warning ? [...warnings, h1Warning] : warnings;
|
|
1111
1142
|
|
|
1112
1143
|
const allErrors = [...errors, ...warnings];
|
|
1113
1144
|
|