@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
|
@@ -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
|
|
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
|
-
|
|
57
|
+
let menuOptions = !canDuplicate ? [deleteOpt] : [duplicateOpt, deleteOpt];
|
|
58
|
+
menuOptions = isModule ? [...menuOptions, copyOpt] : menuOptions;
|
|
45
59
|
|
|
46
60
|
return (
|
|
47
|
-
|
|
48
|
-
<S.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
20
|
-
|
|
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={
|
|
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.
|
|
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
|
-
<
|
|
78
|
+
<S.ButtonWrapper>
|
|
77
79
|
<Button type="button" onClick={handleClick} buttonStyle="line">
|
|
78
80
|
{`Add ${name}`}
|
|
79
81
|
</Button>
|
|
80
|
-
</
|
|
82
|
+
</S.ButtonWrapper>
|
|
81
83
|
</div>
|
|
82
84
|
);
|
|
83
85
|
};
|
|
@@ -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
|
|
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";
|
|
@@ -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
|
|
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
|
-
|
|
79
|
-
|
|
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}
|
package/src/components/Fields/ComponentArray/MixableComponentArray/PasteModuleButton/index.tsx
CHANGED
|
@@ -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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
167
|
-
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
)}
|