@griddo/ax 1.66.3 → 1.66.4
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/package.json +2 -2
- package/src/api/pages.tsx +15 -3
- package/src/api/redirects.tsx +4 -2
- package/src/api/sites.tsx +4 -2
- package/src/components/Browser/index.tsx +3 -1
- package/src/components/Browser/style.tsx +2 -2
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +0 -1
- package/src/components/ErrorCenter/index.tsx +8 -5
- package/src/components/ErrorCenter/style.tsx +21 -8
- package/src/components/Fields/ColorPicker/index.tsx +1 -0
- package/src/components/Fields/LinkField/index.tsx +85 -0
- package/src/components/Fields/ReferenceField/ItemList/index.tsx +5 -1
- package/src/components/Fields/ReferenceField/index.tsx +18 -14
- package/src/components/Fields/UrlField/index.tsx +13 -1
- package/src/components/Fields/index.tsx +2 -0
- package/src/components/FieldsBehavior/index.tsx +14 -1
- package/src/components/Icon/components/Copy.js +14 -0
- package/src/components/Icon/svgs/Copy2.svg +3 -0
- package/src/components/MainWrapper/AppBar/index.tsx +21 -10
- package/src/components/MainWrapper/AppBar/style.tsx +11 -3
- package/src/components/MainWrapper/index.tsx +2 -0
- package/src/components/Modal/style.tsx +0 -1
- package/src/components/SearchField/index.tsx +36 -4
- package/src/components/SearchField/style.tsx +23 -10
- package/src/components/SideModal/style.tsx +6 -6
- package/src/components/TableFilters/StatusFilter/index.tsx +2 -2
- package/src/components/index.tsx +2 -0
- package/src/containers/App/actions.tsx +3 -7
- package/src/containers/PageEditor/actions.tsx +91 -22
- package/src/containers/PageEditor/constants.tsx +1 -1
- package/src/containers/PageEditor/interfaces.tsx +6 -6
- package/src/containers/PageEditor/reducer.tsx +4 -4
- package/src/containers/PageEditor/utils.tsx +2 -1
- package/src/containers/Sites/actions.tsx +35 -23
- package/src/containers/Sites/constants.tsx +1 -0
- package/src/containers/Sites/interfaces.tsx +6 -0
- package/src/containers/Sites/reducer.tsx +4 -0
- package/src/forms/editor.tsx +34 -1
- package/src/forms/errors.tsx +1 -0
- package/src/forms/index.tsx +15 -1
- package/src/forms/validators.tsx +168 -9
- package/src/guards/error/index.tsx +1 -1
- package/src/helpers/dataPacks.tsx +8 -1
- package/src/helpers/index.tsx +2 -1
- package/src/modules/Content/PageItem/index.tsx +54 -4
- package/src/modules/Content/atoms.tsx +41 -3
- package/src/modules/Content/index.tsx +111 -64
- package/src/modules/Content/style.tsx +8 -1
- package/src/modules/GlobalEditor/Editor/index.tsx +3 -1
- package/src/modules/GlobalEditor/PageBrowser/index.tsx +3 -0
- package/src/modules/GlobalEditor/index.tsx +8 -6
- package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/index.tsx +8 -0
- package/src/modules/PageEditor/Editor/index.tsx +6 -2
- package/src/modules/PageEditor/PageBrowser/index.tsx +3 -0
- package/src/modules/PageEditor/index.tsx +29 -15
- package/src/modules/Redirects/index.tsx +40 -10
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +1 -1
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/index.tsx +1 -1
- package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +1 -1
- package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +1 -1
- package/src/modules/Sites/index.tsx +3 -3
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +1 -1
- package/src/modules/StructuredData/StructuredDataList/atoms.tsx +1 -1
- package/src/modules/Users/Profile/index.tsx +3 -4
- package/src/modules/Users/UserCreate/SiteItem/index.tsx +1 -1
- package/src/modules/Users/UserCreate/SiteItem/style.tsx +1 -1
- package/src/modules/Users/UserForm/style.tsx +3 -3
- package/src/modules/Users/UserList/UserItem/index.tsx +3 -1
- package/src/modules/Users/UserList/hooks.tsx +1 -1
- package/src/modules/Users/UserList/index.tsx +2 -2
- package/src/types/index.tsx +16 -3
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { Icon } from "@ax/components";
|
|
2
2
|
import React, { useState } from "react";
|
|
3
|
+
import { Select } from "../Fields";
|
|
3
4
|
|
|
4
5
|
import * as S from "./style";
|
|
5
6
|
|
|
6
7
|
const SearchField = (props: IProps): JSX.Element => {
|
|
7
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
onChange,
|
|
10
|
+
placeholder,
|
|
11
|
+
closeOnInactive = false,
|
|
12
|
+
searchOnEnter = true,
|
|
13
|
+
disabled = false,
|
|
14
|
+
searchFilters,
|
|
15
|
+
onFilterChange,
|
|
16
|
+
} = props;
|
|
8
17
|
|
|
9
18
|
const [isOpen, setIsOpen] = useState(false);
|
|
10
19
|
const [inputValue, setInputValue] = useState("");
|
|
20
|
+
const initState = searchFilters && searchFilters[0] ? searchFilters[0].value : "";
|
|
21
|
+
const [selectValue, setSelectValue] = useState<string>(initState);
|
|
11
22
|
|
|
12
23
|
const toggleField = () => setIsOpen(!isOpen);
|
|
13
24
|
|
|
@@ -36,12 +47,32 @@ const SearchField = (props: IProps): JSX.Element => {
|
|
|
36
47
|
}
|
|
37
48
|
};
|
|
38
49
|
|
|
50
|
+
const handleSelectChange = (value: string) => {
|
|
51
|
+
setSelectValue(value);
|
|
52
|
+
onFilterChange && onFilterChange(value);
|
|
53
|
+
};
|
|
54
|
+
|
|
39
55
|
const showField = isOpen || !closeOnInactive;
|
|
40
56
|
|
|
41
57
|
return (
|
|
42
58
|
<S.Wrapper>
|
|
43
59
|
{showField ? (
|
|
44
|
-
<S.FieldWrapper>
|
|
60
|
+
<S.FieldWrapper closeOnInactive={closeOnInactive} disabled={disabled}>
|
|
61
|
+
{searchFilters && searchFilters.length && (
|
|
62
|
+
<>
|
|
63
|
+
<S.FilterWrapper>
|
|
64
|
+
<Select
|
|
65
|
+
name="filterSelect"
|
|
66
|
+
value={selectValue}
|
|
67
|
+
options={searchFilters}
|
|
68
|
+
onChange={handleSelectChange}
|
|
69
|
+
type="inline"
|
|
70
|
+
placeholder="Filter by"
|
|
71
|
+
/>
|
|
72
|
+
</S.FilterWrapper>
|
|
73
|
+
<S.Separator />
|
|
74
|
+
</>
|
|
75
|
+
)}
|
|
45
76
|
<S.Input
|
|
46
77
|
type="text"
|
|
47
78
|
value={inputValue}
|
|
@@ -50,7 +81,6 @@ const SearchField = (props: IProps): JSX.Element => {
|
|
|
50
81
|
placeholder={placeholder}
|
|
51
82
|
closeOnInactive={closeOnInactive}
|
|
52
83
|
disabled={disabled}
|
|
53
|
-
autoFocus
|
|
54
84
|
/>
|
|
55
85
|
{inputValue.trim() !== "" && searchOnEnter && <S.HelpText>Press ENTER</S.HelpText>}
|
|
56
86
|
{closeOnInactive || inputValue.length > 0 ? (
|
|
@@ -78,6 +108,8 @@ interface IProps {
|
|
|
78
108
|
closeOnInactive?: boolean;
|
|
79
109
|
searchOnEnter?: boolean;
|
|
80
110
|
disabled?: boolean;
|
|
111
|
+
searchFilters?: any;
|
|
112
|
+
onFilterChange?(filter: string): void;
|
|
81
113
|
}
|
|
82
114
|
|
|
83
|
-
export default SearchField;
|
|
115
|
+
export default SearchField;
|
|
@@ -5,15 +5,9 @@ const Wrapper = styled.div`
|
|
|
5
5
|
width: 100%;
|
|
6
6
|
`;
|
|
7
7
|
|
|
8
|
-
const FieldWrapper = styled.div
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
${(p) => p.theme.textStyle.fieldContent};
|
|
12
|
-
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
13
|
-
background-color: ${(p) => p.theme.color.interactiveBackground};
|
|
14
|
-
width: 100%;
|
|
15
|
-
height: ${(p) => p.theme.spacing.l};
|
|
16
|
-
padding-left: ${(p) => p.theme.spacing.xs};
|
|
8
|
+
const FieldWrapper = styled.div<{ closeOnInactive: boolean; disabled: boolean }>`
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
17
11
|
border-color: ${(p) =>
|
|
18
12
|
p.disabled
|
|
19
13
|
? p.theme.color.interactiveDisabled
|
|
@@ -23,6 +17,16 @@ const Input = styled.input<{ closeOnInactive: boolean; disabled: boolean }>`
|
|
|
23
17
|
border-width: ${(p) => (p.closeOnInactive ? "0 0 1px" : "1px")};
|
|
24
18
|
border-style: solid;
|
|
25
19
|
border-radius: ${(p) => (p.closeOnInactive ? 0 : p.theme.radii.s)};
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const Input = styled.input<{ closeOnInactive: boolean; disabled: boolean }>`
|
|
23
|
+
${(p) => p.theme.textStyle.fieldContent};
|
|
24
|
+
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
25
|
+
background-color: ${(p) => p.theme.color.interactiveBackground};
|
|
26
|
+
flex: 1 1 auto;
|
|
27
|
+
height: ${(p) => p.theme.spacing.l};
|
|
28
|
+
padding-left: ${(p) => p.theme.spacing.xs};
|
|
29
|
+
border: none;
|
|
26
30
|
|
|
27
31
|
&:active,
|
|
28
32
|
&:focus {
|
|
@@ -66,4 +70,13 @@ const IconCloseWrapper = styled.div`
|
|
|
66
70
|
transform: translateY(-50%);
|
|
67
71
|
`;
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
const FilterWrapper = styled.div``;
|
|
74
|
+
|
|
75
|
+
const Separator = styled.div`
|
|
76
|
+
border-right: 1px solid ${(p) => p.theme.color.uiLine};
|
|
77
|
+
height: ${(p) => p.theme.spacing.m};
|
|
78
|
+
margin-right: ${(p) => p.theme.spacing.xs};
|
|
79
|
+
margin-left: ${(p) => p.theme.spacing.s};
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
export { Wrapper, IconSearchWrapper, FieldWrapper, Input, HelpText, IconCloseWrapper, FilterWrapper, Separator };
|
|
@@ -11,7 +11,8 @@ const Wrapper = styled.div<{ optionsType?: string }>`
|
|
|
11
11
|
|
|
12
12
|
height: 100vh;
|
|
13
13
|
background: ${(p) => p.theme.colors.uiBackground01};
|
|
14
|
-
box-shadow: ${(p) =>
|
|
14
|
+
box-shadow: ${(p) =>
|
|
15
|
+
p.optionsType && placeRight.includes(p.optionsType) ? p.theme.shadow.rightPanel : p.theme.shadow.leftPanel};
|
|
15
16
|
padding-bottom: calc(${(p) => p.theme.spacing.m} * 2);
|
|
16
17
|
`;
|
|
17
18
|
|
|
@@ -31,11 +32,10 @@ const Header = styled.div`
|
|
|
31
32
|
}
|
|
32
33
|
`;
|
|
33
34
|
|
|
34
|
-
const Title = styled.h6
|
|
35
|
-
`;
|
|
35
|
+
const Title = styled.h6``;
|
|
36
36
|
|
|
37
37
|
const ColumnsWrapper = styled.div`
|
|
38
|
-
display:flex;
|
|
38
|
+
display: flex;
|
|
39
39
|
`;
|
|
40
40
|
|
|
41
41
|
const Content = styled.div`
|
|
@@ -64,11 +64,11 @@ const FeaturedWrapper = styled.div`
|
|
|
64
64
|
`;
|
|
65
65
|
|
|
66
66
|
const SearchWrapper = styled.div`
|
|
67
|
-
width: ${p => `calc(${p.theme.spacing.xl} * 4)`};
|
|
67
|
+
width: ${(p) => `calc(${p.theme.spacing.xl} * 4)`};
|
|
68
68
|
`;
|
|
69
69
|
|
|
70
70
|
const Link = styled.div<{ active: boolean }>`
|
|
71
|
-
color: ${p => p.active ? p.theme.color.textHighEmphasis : p.theme.color.textMediumEmphasis};
|
|
71
|
+
color: ${(p) => (p.active ? p.theme.color.textHighEmphasis : p.theme.color.textMediumEmphasis)};
|
|
72
72
|
`;
|
|
73
73
|
|
|
74
74
|
const ButtonWrapper = styled.div`
|
|
@@ -4,7 +4,7 @@ import { Icon, FloatingMenu, ListTitle, ListItem } from "@ax/components";
|
|
|
4
4
|
|
|
5
5
|
import * as S from "./style";
|
|
6
6
|
|
|
7
|
-
const StatusFilter = (props: IStatusFilterProps) => {
|
|
7
|
+
const StatusFilter = (props: IStatusFilterProps): JSX.Element => {
|
|
8
8
|
const { sortItems, sortedState, isStructuredData } = props;
|
|
9
9
|
const { isAscending, sortedByDate } = sortedState;
|
|
10
10
|
const value = isStructuredData ? "date" : "modified";
|
|
@@ -46,7 +46,7 @@ const StatusFilter = (props: IStatusFilterProps) => {
|
|
|
46
46
|
|
|
47
47
|
interface IStatusFilterProps {
|
|
48
48
|
sortedState: any;
|
|
49
|
-
sortItems(orderPointer: string, isAscendent: boolean):
|
|
49
|
+
sortItems(orderPointer: string, isAscendent: boolean): void;
|
|
50
50
|
isStructuredData?: boolean;
|
|
51
51
|
}
|
|
52
52
|
|
package/src/components/index.tsx
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
HeadingField,
|
|
14
14
|
HiddenField,
|
|
15
15
|
ImageField,
|
|
16
|
+
LinkField,
|
|
16
17
|
NoteField,
|
|
17
18
|
NumberField,
|
|
18
19
|
RadioField,
|
|
@@ -105,6 +106,7 @@ export {
|
|
|
105
106
|
HeadingField,
|
|
106
107
|
HiddenField,
|
|
107
108
|
ImageField,
|
|
109
|
+
LinkField,
|
|
108
110
|
NoteField,
|
|
109
111
|
NumberField,
|
|
110
112
|
RadioField,
|
|
@@ -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
|
};
|
|
@@ -26,6 +26,10 @@ import {
|
|
|
26
26
|
replaceElements,
|
|
27
27
|
findFieldsErrors,
|
|
28
28
|
getParentKey,
|
|
29
|
+
checkMaxModules,
|
|
30
|
+
checkH1content,
|
|
31
|
+
parseValidationErrors,
|
|
32
|
+
findPackagesActivationErrors,
|
|
29
33
|
} from "@ax/forms";
|
|
30
34
|
import { appActions } from "@ax/containers/App";
|
|
31
35
|
import { navigationActions } from "@ax/containers/Navigation";
|
|
@@ -50,8 +54,8 @@ import {
|
|
|
50
54
|
SET_VALIDATED,
|
|
51
55
|
SET_SITE_PAGE_ID,
|
|
52
56
|
SET_USER_EDITING,
|
|
53
|
-
SET_LAST_ELEMENT_ADDED_ID,
|
|
54
57
|
SET_COPY_MODULE,
|
|
58
|
+
SET_LAST_ELEMENT_ADDED_ID,
|
|
55
59
|
} from "./constants";
|
|
56
60
|
|
|
57
61
|
import {
|
|
@@ -85,11 +89,11 @@ import {
|
|
|
85
89
|
ISetSitePageID,
|
|
86
90
|
ISetUserEditing,
|
|
87
91
|
pageStatus,
|
|
88
|
-
ISetLastElementAddedId,
|
|
89
92
|
ISetCopyModule,
|
|
93
|
+
ISetLastElementAddedId,
|
|
90
94
|
} from "./interfaces";
|
|
91
95
|
|
|
92
|
-
const { setIsLoading, setIsSaving } = appActions;
|
|
96
|
+
const { setIsLoading, setIsSaving, handleError } = appActions;
|
|
93
97
|
const { getSiteDefaults, getDefaults } = navigationActions;
|
|
94
98
|
|
|
95
99
|
// AUDIT: THIS FILE IS WAY TOO LONG - LOOK FOR A REFACTOR SOLUTION
|
|
@@ -167,14 +171,14 @@ function setUserEditing(userEditing: IUserEditing | null): ISetUserEditing {
|
|
|
167
171
|
return { type: SET_USER_EDITING, payload: { userEditing } };
|
|
168
172
|
}
|
|
169
173
|
|
|
170
|
-
function setLastElementAddedId(lastElementAddedId: null | number): ISetLastElementAddedId {
|
|
171
|
-
return { type: SET_LAST_ELEMENT_ADDED_ID, payload: { lastElementAddedId } };
|
|
172
|
-
}
|
|
173
|
-
|
|
174
174
|
function setCopyModule(moduleCopy: Record<string, unknown> | null): ISetCopyModule {
|
|
175
175
|
return { type: SET_COPY_MODULE, payload: { moduleCopy } };
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
function setLastElementAddedId(lastElementAddedId: null | number): ISetLastElementAddedId {
|
|
179
|
+
return { type: SET_LAST_ELEMENT_ADDED_ID, payload: { lastElementAddedId } };
|
|
180
|
+
}
|
|
181
|
+
|
|
178
182
|
function setTranslatedParent(): (dispatch: Dispatch, getState: any) => void {
|
|
179
183
|
return async (dispatch, getState) => {
|
|
180
184
|
try {
|
|
@@ -197,7 +201,7 @@ function setTranslatedParent(): (dispatch: Dispatch, getState: any) => void {
|
|
|
197
201
|
const translatedParentId = translatedParent && translatedParent[0] ? translatedParent[0].pageId : null;
|
|
198
202
|
updateEditorContent(selectedEditorID, "parent", translatedParentId)(dispatch, getState);
|
|
199
203
|
},
|
|
200
|
-
handleError: (response: any) =>
|
|
204
|
+
handleError: (response: any) => handleError(response)(dispatch),
|
|
201
205
|
};
|
|
202
206
|
|
|
203
207
|
const callback = async () => pages.getPageLanguages(parent, site, entity);
|
|
@@ -551,18 +555,29 @@ function getPageLanguages(pageID: number, siteID: number | null, entity?: string
|
|
|
551
555
|
};
|
|
552
556
|
}
|
|
553
557
|
|
|
554
|
-
function duplicatePage(pageID: number, data: any): (dispatch:
|
|
558
|
+
function duplicatePage(pageID: number, data: any, siteID?: number): (dispatch: Dispatch) => Promise<boolean> {
|
|
555
559
|
return async (dispatch) => {
|
|
556
560
|
try {
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
561
|
+
const responseActions = {
|
|
562
|
+
handleSuccess: (data: any) => {
|
|
563
|
+
if (!siteID) {
|
|
564
|
+
dispatch(setCurrentPageID(data.id));
|
|
565
|
+
dispatch(setCurrentPageStatus("offline"));
|
|
566
|
+
}
|
|
567
|
+
return true;
|
|
568
|
+
},
|
|
569
|
+
handleError: (response: any) => {
|
|
570
|
+
appActions.handleError(response)(dispatch);
|
|
571
|
+
return false;
|
|
572
|
+
},
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
const callback = async () => pages.duplicatePage(pageID, data, siteID);
|
|
576
|
+
|
|
577
|
+
return await handleRequest(callback, responseActions, [])(dispatch);
|
|
564
578
|
} catch (e) {
|
|
565
|
-
console.log(e);
|
|
579
|
+
console.log(e);
|
|
580
|
+
return false;
|
|
566
581
|
}
|
|
567
582
|
};
|
|
568
583
|
}
|
|
@@ -617,6 +632,13 @@ function addModule(
|
|
|
617
632
|
): (dispatch: Dispatch, getState: any) => void {
|
|
618
633
|
return (dispatch, getState) => {
|
|
619
634
|
const { editorContent, sections, editorID } = getStateValues(getState);
|
|
635
|
+
|
|
636
|
+
const { isMaxModules, errorMessage } = checkMaxModules(editorContent, type);
|
|
637
|
+
if (isMaxModules) {
|
|
638
|
+
handleError({ text: errorMessage })(dispatch);
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
|
|
620
642
|
const componentModule = {
|
|
621
643
|
editorID,
|
|
622
644
|
type,
|
|
@@ -691,7 +713,7 @@ function replaceElementsInCollection(newValue: string, reference: string): (disp
|
|
|
691
713
|
|
|
692
714
|
function deleteModule(editorID: number, key?: string): (dispatch: Dispatch, getState: any) => void {
|
|
693
715
|
return (dispatch, getState) => {
|
|
694
|
-
const { sections, editorContent } = getStateValues(getState);
|
|
716
|
+
const { sections, editorContent, errors } = getStateValues(getState);
|
|
695
717
|
|
|
696
718
|
const updatedSections: any = [...sections];
|
|
697
719
|
const { parent, grandParent } = findByEditorID(updatedSections, editorID);
|
|
@@ -707,6 +729,10 @@ function deleteModule(editorID: number, key?: string): (dispatch: Dispatch, getS
|
|
|
707
729
|
...editorContent,
|
|
708
730
|
};
|
|
709
731
|
|
|
732
|
+
if (errors.length) {
|
|
733
|
+
validatePage()(dispatch, getState);
|
|
734
|
+
}
|
|
735
|
+
|
|
710
736
|
generatePageContent(updatedPageContent, dispatch, getState);
|
|
711
737
|
|
|
712
738
|
dispatch(setLastElementAddedId(null));
|
|
@@ -719,6 +745,13 @@ function duplicateModule(editorID: number, key?: string): (dispatch: Dispatch, g
|
|
|
719
745
|
|
|
720
746
|
const updatedSections: any = [...sections];
|
|
721
747
|
const { element: originalItem, parent, grandParent } = findByEditorID(updatedSections, editorID);
|
|
748
|
+
|
|
749
|
+
const { isMaxModules, errorMessage } = checkMaxModules(editorContent, originalItem.component);
|
|
750
|
+
if (isMaxModules) {
|
|
751
|
+
handleError({ text: errorMessage })(dispatch);
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
|
|
722
755
|
const parentModule = Array.isArray(parent) ? grandParent : parent;
|
|
723
756
|
|
|
724
757
|
const parentKey = key ? key : getParentKey(parentModule, editorID);
|
|
@@ -1025,16 +1058,52 @@ function getTemplateConfig(template: string): (dispatch: Dispatch, getState: any
|
|
|
1025
1058
|
};
|
|
1026
1059
|
}
|
|
1027
1060
|
|
|
1028
|
-
function validatePage(publish
|
|
1061
|
+
function validatePage(publish?: boolean, browserRef?: any): (dispatch: Dispatch, getState: any) => Promise<boolean> {
|
|
1029
1062
|
return async (dispatch, getState) => {
|
|
1030
1063
|
try {
|
|
1031
1064
|
const { editorContent } = getStateValues(getState);
|
|
1032
1065
|
|
|
1033
|
-
const
|
|
1034
|
-
|
|
1035
|
-
|
|
1066
|
+
const {
|
|
1067
|
+
dataPacks: { modules, templates },
|
|
1068
|
+
pageEditor,
|
|
1069
|
+
} = getState();
|
|
1070
|
+
|
|
1071
|
+
const page = getPageData(getState, false);
|
|
1072
|
+
const { values } = parseData(page, false);
|
|
1073
|
+
|
|
1074
|
+
let errors: IErrorItem[] = [];
|
|
1075
|
+
|
|
1076
|
+
const responseActions = {
|
|
1077
|
+
handleSuccess: (data: any) => {
|
|
1078
|
+
const apiErrors = parseValidationErrors(data, editorContent);
|
|
1079
|
+
errors = [...errors, ...apiErrors];
|
|
1080
|
+
},
|
|
1081
|
+
handleError: () => console.log("Error en page check"),
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
const callback = async () => pages.pageCheck(values);
|
|
1085
|
+
|
|
1086
|
+
await handleRequest(callback, responseActions, [])(dispatch);
|
|
1087
|
+
|
|
1088
|
+
const fieldErrors = findFieldsErrors(editorContent);
|
|
1089
|
+
errors = [...errors, ...fieldErrors];
|
|
1090
|
+
const packagesActivationErrors = findPackagesActivationErrors(pageEditor, modules, templates);
|
|
1091
|
+
errors = packagesActivationErrors ? [...errors, packagesActivationErrors] : errors;
|
|
1092
|
+
|
|
1093
|
+
let warnings: IErrorItem[] = [];
|
|
1094
|
+
if (browserRef && browserRef.current) {
|
|
1095
|
+
const h1Warning = checkH1content(browserRef.current);
|
|
1096
|
+
warnings = h1Warning ? [...warnings, h1Warning] : warnings;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
const allErrors = [...errors, ...warnings];
|
|
1100
|
+
|
|
1101
|
+
dispatch(setErrors(allErrors));
|
|
1102
|
+
if (!allErrors.length) {
|
|
1036
1103
|
!publish && dispatch(setValidated(true));
|
|
1037
1104
|
return true;
|
|
1105
|
+
} else if (publish && !errors.length) {
|
|
1106
|
+
return true;
|
|
1038
1107
|
} else {
|
|
1039
1108
|
dispatch(setValidated(false));
|
|
1040
1109
|
return false;
|
|
@@ -18,8 +18,8 @@ export const SET_ERRORS = `${NAME}/SET_ERRORS`;
|
|
|
18
18
|
export const SET_VALIDATED = `${NAME}/SET_VALIDATED`;
|
|
19
19
|
export const SET_SITE_PAGE_ID = `${NAME}/SET_SITE_PAGE_ID`;
|
|
20
20
|
export const SET_USER_EDITING = `${NAME}/SET_USER_EDITING`;
|
|
21
|
-
export const SET_LAST_ELEMENT_ADDED_ID = `${NAME}/SET_LAST_ELEMENT_ADDED_ID`;
|
|
22
21
|
export const SET_COPY_MODULE = `${NAME}/SET_COPY_MODULE`;
|
|
22
|
+
export const SET_LAST_ELEMENT_ADDED_ID = `${NAME}/SET_LAST_ELEMENT_ADDED_ID`;
|
|
23
23
|
|
|
24
24
|
export const INITIAL_TEMPLATE = "BasicTemplate";
|
|
25
25
|
export const MULTIMEDIA_COMPONENTS = ["LinkableImage", "Video"];
|
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
SET_VALIDATED,
|
|
18
18
|
SET_SITE_PAGE_ID,
|
|
19
19
|
SET_USER_EDITING,
|
|
20
|
-
SET_LAST_ELEMENT_ADDED_ID,
|
|
21
20
|
SET_COPY_MODULE,
|
|
21
|
+
SET_LAST_ELEMENT_ADDED_ID,
|
|
22
22
|
} from "./constants";
|
|
23
23
|
import { IBreadcrumbItem, ISchema, IPage, IErrorItem, IUserEditing } from "@ax/types";
|
|
24
24
|
|
|
@@ -112,16 +112,16 @@ export interface ISetUserEditing {
|
|
|
112
112
|
payload: { userEditing: IUserEditing | null };
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
export interface ISetLastElementAddedId {
|
|
116
|
-
type: typeof SET_LAST_ELEMENT_ADDED_ID;
|
|
117
|
-
payload: { lastElementAddedId: null | number };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
115
|
export interface ISetCopyModule {
|
|
121
116
|
type: typeof SET_COPY_MODULE;
|
|
122
117
|
payload: { moduleCopy: Record<string, unknown> | null };
|
|
123
118
|
}
|
|
124
119
|
|
|
120
|
+
export interface ISetLastElementAddedId {
|
|
121
|
+
type: typeof SET_LAST_ELEMENT_ADDED_ID;
|
|
122
|
+
payload: { lastElementAddedId: null | number };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
125
|
export interface IFieldProps {
|
|
126
126
|
id: number;
|
|
127
127
|
key: string;
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
SET_VALIDATED,
|
|
21
21
|
SET_SITE_PAGE_ID,
|
|
22
22
|
SET_USER_EDITING,
|
|
23
|
-
SET_LAST_ELEMENT_ADDED_ID,
|
|
24
23
|
SET_COPY_MODULE,
|
|
24
|
+
SET_LAST_ELEMENT_ADDED_ID,
|
|
25
25
|
} from "./constants";
|
|
26
26
|
|
|
27
27
|
import { PageEditorActionsCreators } from "./interfaces";
|
|
@@ -45,8 +45,8 @@ export interface IPageEditorState {
|
|
|
45
45
|
validated: boolean;
|
|
46
46
|
sitePageID: number | null;
|
|
47
47
|
userEditing: IUserEditing | null;
|
|
48
|
-
lastElementAddedId: null | number;
|
|
49
48
|
moduleCopy: { date: string; element: Record<string, unknown> } | null;
|
|
49
|
+
lastElementAddedId: null | number;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export const initialState = {
|
|
@@ -68,8 +68,8 @@ export const initialState = {
|
|
|
68
68
|
validated: false,
|
|
69
69
|
sitePageID: null,
|
|
70
70
|
userEditing: null,
|
|
71
|
-
lastElementAddedId: null,
|
|
72
71
|
moduleCopy: null,
|
|
72
|
+
lastElementAddedId: null,
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
export function reducer(state = initialState, action: PageEditorActionsCreators): IPageEditorState {
|
|
@@ -93,8 +93,8 @@ export function reducer(state = initialState, action: PageEditorActionsCreators)
|
|
|
93
93
|
case SET_VALIDATED:
|
|
94
94
|
case SET_SITE_PAGE_ID:
|
|
95
95
|
case SET_USER_EDITING:
|
|
96
|
-
case SET_LAST_ELEMENT_ADDED_ID:
|
|
97
96
|
case SET_COPY_MODULE:
|
|
97
|
+
case SET_LAST_ELEMENT_ADDED_ID:
|
|
98
98
|
return { ...state, ...action.payload };
|
|
99
99
|
default:
|
|
100
100
|
return state;
|
|
@@ -38,7 +38,7 @@ const getTemplateValues = (template: any) => {
|
|
|
38
38
|
|
|
39
39
|
export const getStateValues = (getState: any) => {
|
|
40
40
|
const {
|
|
41
|
-
pageEditor: { editorContent: pageContent, selectedEditorID, selectedContent, template },
|
|
41
|
+
pageEditor: { editorContent: pageContent, selectedEditorID, selectedContent, template, errors },
|
|
42
42
|
} = getState();
|
|
43
43
|
const { editorContent, header, footer } = pageContent;
|
|
44
44
|
|
|
@@ -53,6 +53,7 @@ export const getStateValues = (getState: any) => {
|
|
|
53
53
|
editorID,
|
|
54
54
|
template,
|
|
55
55
|
selectedContent,
|
|
56
|
+
errors,
|
|
56
57
|
};
|
|
57
58
|
};
|
|
58
59
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Dispatch } from "redux";
|
|
2
2
|
import {
|
|
3
3
|
SET_SITES,
|
|
4
|
+
SET_SITES_BY_LANG,
|
|
4
5
|
SET_CURRENT_SITE_INFO,
|
|
5
6
|
SET_CURRENT_SITE_PAGES,
|
|
6
7
|
SET_FILTER,
|
|
@@ -11,6 +12,7 @@ import {
|
|
|
11
12
|
} from "./constants";
|
|
12
13
|
import {
|
|
13
14
|
ISetSitesAction,
|
|
15
|
+
ISetSitesByLangAction,
|
|
14
16
|
ISetCurrentSiteInfoAction,
|
|
15
17
|
ISetCurrentSitePagesAction,
|
|
16
18
|
ISetFilter,
|
|
@@ -42,6 +44,10 @@ function setSites(sitesList: ISite[]): ISetSitesAction {
|
|
|
42
44
|
return { type: SET_SITES, payload: { sites: sitesList } };
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
function setSitesByLang(sitesList: ISite[]): ISetSitesByLangAction {
|
|
48
|
+
return { type: SET_SITES_BY_LANG, payload: { sitesByLang: sitesList } };
|
|
49
|
+
}
|
|
50
|
+
|
|
45
51
|
function setCurrentSiteInfo(currentSiteInfo: ISite): ISetCurrentSiteInfoAction {
|
|
46
52
|
return { type: SET_CURRENT_SITE_INFO, payload: { currentSiteInfo } };
|
|
47
53
|
}
|
|
@@ -67,20 +73,34 @@ function setSavedSiteInfo(savedSiteInfo: ISite): ISetSavedSiteInfoAction {
|
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
// TODO: hay que controlar que cuando da error la API borrar los sites ya guardados y sacar el error (ver los siguientes FIXME)
|
|
70
|
-
function getSites(
|
|
76
|
+
function getSites(): (dispatch: Dispatch) => Promise<void> {
|
|
71
77
|
return async (dispatch) => {
|
|
72
78
|
try {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
dispatch(setIsLoading(false));
|
|
79
|
+
const responseActions = {
|
|
80
|
+
handleSuccess: (data: any) => dispatch(setSites(data)),
|
|
81
|
+
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
82
|
+
};
|
|
83
|
+
const callback = async () => sites.getAllSites();
|
|
84
|
+
|
|
85
|
+
await handleRequest(callback, responseActions, [])(dispatch);
|
|
81
86
|
} catch (e) {
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
console.log(e);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function getSitesByLang(language: number): (dispatch: Dispatch) => Promise<void> {
|
|
93
|
+
return async (dispatch) => {
|
|
94
|
+
try {
|
|
95
|
+
const responseActions = {
|
|
96
|
+
handleSuccess: (data: any) => dispatch(setSitesByLang(data)),
|
|
97
|
+
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
98
|
+
};
|
|
99
|
+
const callback = async () => sites.getAllSites(language);
|
|
100
|
+
|
|
101
|
+
await handleRequest(callback, responseActions, [])(dispatch);
|
|
102
|
+
} catch (e) {
|
|
103
|
+
console.log(e);
|
|
84
104
|
}
|
|
85
105
|
};
|
|
86
106
|
}
|
|
@@ -306,10 +326,7 @@ function deleteSite(siteID: number): (dispatch: Dispatch, getState: any) => Prom
|
|
|
306
326
|
try {
|
|
307
327
|
const response = await sites.deleteSite(siteID);
|
|
308
328
|
if (isReqOk(response.status)) {
|
|
309
|
-
|
|
310
|
-
app: { token },
|
|
311
|
-
} = getState();
|
|
312
|
-
getSites(token)(dispatch);
|
|
329
|
+
getSites()(dispatch);
|
|
313
330
|
}
|
|
314
331
|
} catch (e) {
|
|
315
332
|
console.log(e); // TODO: capturar error bien
|
|
@@ -322,10 +339,7 @@ function publishSite(siteID: number): (dispatch: Dispatch, getState: any) => Pro
|
|
|
322
339
|
try {
|
|
323
340
|
const response = await sites.publishSite(siteID);
|
|
324
341
|
if (isReqOk(response.status)) {
|
|
325
|
-
|
|
326
|
-
app: { token },
|
|
327
|
-
} = getState();
|
|
328
|
-
getSites(token)(dispatch);
|
|
342
|
+
getSites()(dispatch);
|
|
329
343
|
}
|
|
330
344
|
} catch (e) {
|
|
331
345
|
console.log(e); // TODO: capturar error bien
|
|
@@ -338,10 +352,7 @@ function unpublishSite(siteID: number): (dispatch: Dispatch, getState: any) => P
|
|
|
338
352
|
try {
|
|
339
353
|
const response = await sites.unpublishSite(siteID);
|
|
340
354
|
if (isReqOk(response.status)) {
|
|
341
|
-
|
|
342
|
-
app: { token },
|
|
343
|
-
} = getState();
|
|
344
|
-
getSites(token)(dispatch);
|
|
355
|
+
getSites()(dispatch);
|
|
345
356
|
}
|
|
346
357
|
} catch (e) {
|
|
347
358
|
console.log(e); // TODO: capturar error bien
|
|
@@ -464,6 +475,7 @@ export {
|
|
|
464
475
|
setTotalItems,
|
|
465
476
|
setCurrentSiteLanguages,
|
|
466
477
|
getSites,
|
|
478
|
+
getSitesByLang,
|
|
467
479
|
setSiteInfo,
|
|
468
480
|
getFilteredContent,
|
|
469
481
|
getSitePages,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const NAME = "sites";
|
|
2
2
|
|
|
3
3
|
export const SET_SITES = `${NAME}/SET_SITES`;
|
|
4
|
+
export const SET_SITES_BY_LANG = `${NAME}/SET_SITES_BY_LANG`;
|
|
4
5
|
export const SET_CURRENT_SITE_INFO = `${NAME}/SET_CURRENT_SITE_INFO`;
|
|
5
6
|
export const SET_CURRENT_SITE_PAGES = `${NAME}/SET_CURRENT_SITE_PAGES`;
|
|
6
7
|
export const SET_FILTER: string | null = `${NAME}/SET_FILTER`;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SET_SITES,
|
|
3
|
+
SET_SITES_BY_LANG,
|
|
3
4
|
SET_CURRENT_SITE_INFO,
|
|
4
5
|
SET_CURRENT_SITE_PAGES,
|
|
5
6
|
SET_FILTER,
|
|
@@ -20,6 +21,11 @@ export interface ISetSitesAction {
|
|
|
20
21
|
payload: { sites: ISite[] };
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
export interface ISetSitesByLangAction {
|
|
25
|
+
type: typeof SET_SITES_BY_LANG;
|
|
26
|
+
payload: { sitesByLang: ISite[] };
|
|
27
|
+
}
|
|
28
|
+
|
|
23
29
|
export interface ISetCurrentSiteInfoAction {
|
|
24
30
|
type: typeof SET_CURRENT_SITE_INFO;
|
|
25
31
|
payload: { currentSiteInfo: ISite };
|