@griddo/ax 1.64.9 → 1.65.1
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/components/CategoryCell/style.tsx +3 -2
- package/src/components/Fields/FieldGroup/index.test.tsx +61 -0
- package/src/components/Fields/FieldGroup/index.tsx +7 -5
- package/src/components/Fields/ImageField/index.tsx +7 -2
- package/src/components/FloatingPanel/index.tsx +12 -2
- package/src/components/Modal/style.tsx +3 -3
- package/src/components/SideModal/index.tsx +6 -1
- package/src/components/SideModal/style.tsx +7 -2
- package/src/components/TableFilters/CategoryFilter/index.tsx +1 -1
- package/src/components/TableFilters/DateFilter/index.tsx +7 -4
- package/src/components/TableFilters/LiveFilter/index.tsx +1 -1
- package/src/components/TableFilters/NameFilter/index.tsx +7 -4
- package/src/components/TableFilters/SiteFilter/index.tsx +1 -1
- package/src/components/TableFilters/StatusFilter/index.tsx +7 -4
- package/src/components/TableFilters/TranslationsFilter/index.tsx +1 -1
- package/src/components/TableFilters/TypeFilter/index.tsx +2 -2
- package/src/containers/Navigation/Menu/reducer.tsx +2 -1
- package/src/containers/PageEditor/actions.tsx +9 -8
- package/src/containers/StructuredData/actions.tsx +4 -3
- package/src/forms/errors.tsx +1 -0
- package/src/forms/index.tsx +2 -2
- package/src/forms/validators.tsx +55 -41
- package/src/modules/Content/PageItem/index.tsx +2 -1
- package/src/modules/CreatePass/index.tsx +4 -2
- package/src/modules/GlobalEditor/index.tsx +48 -35
- package/src/modules/Navigation/Menus/List/Table/Item/index.tsx +1 -0
- package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/index.tsx +16 -5
- package/src/modules/Navigation/Menus/List/Table/SidePanel/index.tsx +31 -22
- package/src/modules/Navigation/Menus/List/Table/SidePanel/style.tsx +18 -2
- package/src/modules/PageEditor/index.tsx +47 -34
- package/src/modules/Sites/SitesList/index.tsx +15 -6
- package/src/modules/StructuredData/Form/index.tsx +29 -21
- package/src/modules/StructuredData/StructuredDataList/utils.tsx +1 -1
- package/src/types/index.tsx +3 -1
|
@@ -399,7 +399,8 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
399
399
|
const CategoryColumns =
|
|
400
400
|
isGlobal &&
|
|
401
401
|
categoryColumns.map((col: any) => {
|
|
402
|
-
const
|
|
402
|
+
const fromVal = col.from.includes(".") ? col.from.split(".")[1] : col.from;
|
|
403
|
+
const type = structuredDataContent && (structuredDataContent[fromVal] || structuredDataContent[col.from]);
|
|
403
404
|
const categories = Array.isArray(type) && type.map((cat: any) => cat.label || cat.title);
|
|
404
405
|
return (
|
|
405
406
|
activeColumns.includes(col.key) && (
|
|
@@ -6,7 +6,7 @@ import { isReqOk } from "@ax/helpers";
|
|
|
6
6
|
import { global } from "@ax/api";
|
|
7
7
|
import { appActions } from "@ax/containers/App";
|
|
8
8
|
import { usersActions } from "@ax/containers/Users";
|
|
9
|
-
import { Button, FieldsBehavior } from "@ax/components";
|
|
9
|
+
import { Button, FieldsBehavior, ErrorToast } from "@ax/components";
|
|
10
10
|
|
|
11
11
|
import * as S from "./style";
|
|
12
12
|
|
|
@@ -55,7 +55,7 @@ const CreatePass = (props: IProps) => {
|
|
|
55
55
|
<S.Subtitle>Welcome to Griddo</S.Subtitle>
|
|
56
56
|
<S.Title>Create your password</S.Title>
|
|
57
57
|
</S.Header>
|
|
58
|
-
|
|
58
|
+
<ErrorToast />
|
|
59
59
|
<S.Form onSubmit={handleSubmit}>
|
|
60
60
|
<FieldsBehavior
|
|
61
61
|
fieldType="TextField"
|
|
@@ -64,6 +64,7 @@ const CreatePass = (props: IProps) => {
|
|
|
64
64
|
mandatory={true}
|
|
65
65
|
value={state.pass1}
|
|
66
66
|
onChange={handlePass1Change}
|
|
67
|
+
validators={{ mandatory: true }}
|
|
67
68
|
/>
|
|
68
69
|
<FieldsBehavior
|
|
69
70
|
fieldType="TextField"
|
|
@@ -72,6 +73,7 @@ const CreatePass = (props: IProps) => {
|
|
|
72
73
|
mandatory={true}
|
|
73
74
|
value={state.pass2}
|
|
74
75
|
onChange={handlePass2Change}
|
|
76
|
+
validators={{ isSamePass: state.pass1, mandatory: true }}
|
|
75
77
|
/>
|
|
76
78
|
<Button type="submit" disabled={!validPasswords}>
|
|
77
79
|
Create and log in
|
|
@@ -103,7 +103,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
103
103
|
const { deletePage } = props;
|
|
104
104
|
const path = "/sites/pages";
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
deletePage().then((deleted: boolean) => {
|
|
107
107
|
if (deleted) {
|
|
108
108
|
setRoute(path);
|
|
109
109
|
}
|
|
@@ -111,68 +111,81 @@ const GlobalEditor = (props: IProps) => {
|
|
|
111
111
|
};
|
|
112
112
|
|
|
113
113
|
const publishPage = async () => {
|
|
114
|
-
const { updatePageStatus, savePage, pageID } = props;
|
|
114
|
+
const { updatePageStatus, savePage, pageID, validatePage } = props;
|
|
115
115
|
|
|
116
|
-
const
|
|
117
|
-
status: pageStatus.UPLOAD_PENDING,
|
|
118
|
-
};
|
|
116
|
+
const validated = await validatePage(true);
|
|
119
117
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
if (validated) {
|
|
119
|
+
const publishPage = {
|
|
120
|
+
status: pageStatus.UPLOAD_PENDING,
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
pageID
|
|
124
|
+
? updatePageStatus([pageID], pageStatus.UPLOAD_PENDING)
|
|
125
|
+
: savePage(false, publishPage).then((isSaved: boolean) => {
|
|
126
|
+
if (isSaved) {
|
|
127
|
+
resetDirty();
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
127
131
|
};
|
|
128
132
|
|
|
129
133
|
const publishChanges = async () => {
|
|
130
|
-
const { savePage } = props;
|
|
134
|
+
const { savePage, validatePage } = props;
|
|
131
135
|
|
|
132
|
-
const
|
|
133
|
-
status: pageStatus.UPLOAD_PENDING,
|
|
134
|
-
};
|
|
136
|
+
const validated = await validatePage(true);
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
138
|
+
if (validated) {
|
|
139
|
+
const publishPage = {
|
|
140
|
+
status: pageStatus.UPLOAD_PENDING,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
savePage(false, publishPage).then((isSaved: boolean) => {
|
|
144
|
+
if (isSaved) {
|
|
145
|
+
resetDirty();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
141
149
|
};
|
|
142
150
|
|
|
143
|
-
const unpublishPage =
|
|
151
|
+
const unpublishPage = () => {
|
|
144
152
|
const { updatePageStatus, pageID } = props;
|
|
145
153
|
|
|
146
|
-
|
|
154
|
+
updatePageStatus([pageID], pageStatus.OFFLINE_PENDING);
|
|
147
155
|
};
|
|
148
156
|
|
|
149
|
-
const cancelPublishPage =
|
|
157
|
+
const cancelPublishPage = () => {
|
|
150
158
|
const { updatePageStatus, pageID } = props;
|
|
151
159
|
|
|
152
|
-
|
|
160
|
+
updatePageStatus([pageID], pageStatus.OFFLINE);
|
|
153
161
|
};
|
|
154
162
|
|
|
155
|
-
const reviewPage =
|
|
163
|
+
const reviewPage = () => {
|
|
156
164
|
const { validatePage } = props;
|
|
157
|
-
|
|
165
|
+
validatePage();
|
|
158
166
|
};
|
|
159
167
|
|
|
160
168
|
const handlePublishDraft = async () => {
|
|
161
|
-
const { savePage } = props;
|
|
162
|
-
|
|
163
|
-
|
|
169
|
+
const { savePage, validatePage } = props;
|
|
170
|
+
|
|
171
|
+
const validated = await validatePage(true);
|
|
172
|
+
|
|
173
|
+
if (validated) {
|
|
174
|
+
const isSaved = await savePage(false, null, true);
|
|
175
|
+
if (isSaved) resetDirty();
|
|
176
|
+
}
|
|
164
177
|
};
|
|
165
178
|
|
|
166
|
-
const handleDiscardDraft =
|
|
179
|
+
const handleDiscardDraft = () => {
|
|
167
180
|
const { discardDraft } = props;
|
|
168
181
|
resetDirty();
|
|
169
|
-
|
|
182
|
+
discardDraft();
|
|
170
183
|
};
|
|
171
184
|
|
|
172
|
-
const handleDiscarChanges =
|
|
185
|
+
const handleDiscarChanges = () => {
|
|
173
186
|
const { getPage, pageID } = props;
|
|
174
187
|
resetDirty();
|
|
175
|
-
|
|
188
|
+
getPage(pageID, true);
|
|
176
189
|
};
|
|
177
190
|
|
|
178
191
|
const getPublishButton = (status: string) => {
|
|
@@ -536,7 +549,7 @@ interface IPageEditorDispatchProps {
|
|
|
536
549
|
getPage(pageID?: number, global?: boolean): Promise<void>;
|
|
537
550
|
savePage(createDraft: boolean, publishPage?: any, publishDraft?: boolean): Promise<boolean>;
|
|
538
551
|
deletePage(params?: ISavePageParams): Promise<boolean>;
|
|
539
|
-
validatePage(): Promise<boolean>;
|
|
552
|
+
validatePage(publish?: boolean): Promise<boolean>;
|
|
540
553
|
updatePageStatus(id: number[], status: string): Promise<boolean>;
|
|
541
554
|
setHistoryPush(path: string, isEditor: boolean): void;
|
|
542
555
|
setLanguage?(lang: { locale: string; id: number | null }): void;
|
|
@@ -51,6 +51,7 @@ const Item = (props: IItemProps): JSX.Element => {
|
|
|
51
51
|
updateFormValue({ itemLink: item.url });
|
|
52
52
|
updateFormValue({ itemLabel: item.label });
|
|
53
53
|
updateFormValue({ itemAuxText: item.auxText });
|
|
54
|
+
updateFormValue({ itemImage: item.image });
|
|
54
55
|
updateFormValue({ type });
|
|
55
56
|
updateFormValue({ headerStyle });
|
|
56
57
|
updateFormValue({ footerStyle });
|
|
@@ -5,17 +5,18 @@ import { menuActions } from "@ax/containers/Navigation";
|
|
|
5
5
|
import { sitesActions } from "@ax/containers/Sites";
|
|
6
6
|
import { FieldsBehavior } from "@ax/components";
|
|
7
7
|
|
|
8
|
-
import { IRootState, IMenuForm } from "@ax/types";
|
|
8
|
+
import { IRootState, IMenuForm, IImage } from "@ax/types";
|
|
9
9
|
|
|
10
10
|
const Form = (props: IProps): JSX.Element => {
|
|
11
|
-
const { form, updateForm, toggleSecondaryPanel } = props;
|
|
11
|
+
const { form, updateForm, toggleSecondaryPanel, setIsGalleryOpened } = props;
|
|
12
12
|
|
|
13
|
-
const { itemLink, itemLabel, itemAuxText, type } = form;
|
|
13
|
+
const { itemLink, itemLabel, itemAuxText, type, itemImage } = form;
|
|
14
14
|
|
|
15
15
|
const setLinkValue = (value: any) => updateForm({ itemLink: value });
|
|
16
16
|
const setLabelValue = (value: string) => updateForm({ itemLabel: value });
|
|
17
17
|
const setAuxTextValue = (value: string) => updateForm({ itemAuxText: value });
|
|
18
18
|
const setTypeValue = (value: string) => updateForm({ type: value });
|
|
19
|
+
const setImageValue = (value: IImage) => updateForm({ itemImage: value });
|
|
19
20
|
|
|
20
21
|
const typeLinkOptions = [
|
|
21
22
|
{
|
|
@@ -36,8 +37,8 @@ const Form = (props: IProps): JSX.Element => {
|
|
|
36
37
|
<>
|
|
37
38
|
<FieldsBehavior
|
|
38
39
|
title="Type"
|
|
39
|
-
fieldType="RadioGroup"
|
|
40
40
|
name="quantityGroup"
|
|
41
|
+
fieldType="RadioGroup"
|
|
41
42
|
options={typeLinkOptions}
|
|
42
43
|
value={typeLink}
|
|
43
44
|
onChange={setTypeValue}
|
|
@@ -50,7 +51,16 @@ const Form = (props: IProps): JSX.Element => {
|
|
|
50
51
|
value={itemLabel || ""}
|
|
51
52
|
onChange={setLabelValue}
|
|
52
53
|
/>
|
|
53
|
-
{type
|
|
54
|
+
{type !== "link" ? (
|
|
55
|
+
<FieldsBehavior
|
|
56
|
+
title="Image"
|
|
57
|
+
name="image"
|
|
58
|
+
fieldType="ImageField"
|
|
59
|
+
value={itemImage || null}
|
|
60
|
+
onChange={setImageValue}
|
|
61
|
+
setIsGalleryOpened={setIsGalleryOpened}
|
|
62
|
+
/>
|
|
63
|
+
) : (
|
|
54
64
|
<>
|
|
55
65
|
<FieldsBehavior
|
|
56
66
|
title="Auxiliar Text"
|
|
@@ -90,6 +100,7 @@ interface IStateProps {
|
|
|
90
100
|
|
|
91
101
|
interface IFormProps {
|
|
92
102
|
toggleSecondaryPanel(): any;
|
|
103
|
+
setIsGalleryOpened?: (isGalleryOpened: boolean) => void;
|
|
93
104
|
}
|
|
94
105
|
interface IDispatchProps {
|
|
95
106
|
updateForm(value: any): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState } from "react";
|
|
2
2
|
|
|
3
3
|
import { connect } from "react-redux";
|
|
4
4
|
import { menuActions } from "@ax/containers/Navigation";
|
|
@@ -14,30 +14,37 @@ const SidePanel = (props: IProps): JSX.Element => {
|
|
|
14
14
|
const { isOpen, isOpenedSecond, toggleModal, toggleSecondaryPanel, addMenuItem, updateMenuItem, item, edit, form } =
|
|
15
15
|
props;
|
|
16
16
|
|
|
17
|
-
const { itemLabel, itemLink, itemAuxText, type, headerStyle, footerStyle } = form;
|
|
17
|
+
const { itemLabel, itemLink, itemImage, itemAuxText, type, headerStyle, footerStyle } = form;
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const [isGalleryOpened, setIsGalleryOpened] = useState(false);
|
|
20
|
+
|
|
21
|
+
const setIsOpenedGallery = () => {
|
|
22
|
+
setIsGalleryOpened(!isGalleryOpened);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
let menuItem: any = {
|
|
20
26
|
label: itemLabel,
|
|
21
27
|
url: itemLink,
|
|
28
|
+
image: itemImage,
|
|
22
29
|
auxText: itemAuxText,
|
|
23
30
|
component: "Menu",
|
|
24
31
|
config: { type, headerStyle, footerStyle },
|
|
25
32
|
};
|
|
26
33
|
|
|
27
|
-
|
|
34
|
+
menuItem.children = edit && item ? item.children : [];
|
|
28
35
|
|
|
29
36
|
if (edit && item && item.id) {
|
|
30
|
-
|
|
37
|
+
menuItem = { ...menuItem, id: item.id };
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
const addItemAction = () => {
|
|
34
|
-
addMenuItem(
|
|
41
|
+
addMenuItem(menuItem);
|
|
35
42
|
toggleModal();
|
|
36
43
|
};
|
|
37
44
|
|
|
38
45
|
const editItemAction = () => {
|
|
39
|
-
|
|
40
|
-
updateMenuItem(
|
|
46
|
+
menuItem = { ...menuItem, editorID: item && item.editorID };
|
|
47
|
+
updateMenuItem(menuItem);
|
|
41
48
|
toggleModal();
|
|
42
49
|
};
|
|
43
50
|
|
|
@@ -61,19 +68,21 @@ const SidePanel = (props: IProps): JSX.Element => {
|
|
|
61
68
|
toggleModal={toggleModal}
|
|
62
69
|
isOpen={isOpen}
|
|
63
70
|
isOpenedSecond={isOpenedSecond}
|
|
71
|
+
closeOnOutsideClick={!isGalleryOpened}
|
|
64
72
|
handlePanel={toggleSecondaryPanel}
|
|
65
73
|
>
|
|
66
|
-
<
|
|
74
|
+
<S.FormWrapper>
|
|
75
|
+
<Form toggleSecondaryPanel={toggleSecondaryPanel} setIsGalleryOpened={setIsOpenedGallery} />
|
|
76
|
+
</S.FormWrapper>
|
|
67
77
|
<S.Footer>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)}
|
|
78
|
+
<Button
|
|
79
|
+
className="button"
|
|
80
|
+
type="button"
|
|
81
|
+
onClick={edit ? editButton.action : addButton.action}
|
|
82
|
+
disabled={edit ? editButton.disabled : addButton.disabled}
|
|
83
|
+
>
|
|
84
|
+
{edit ? editButton.label : addButton.label}
|
|
85
|
+
</Button>
|
|
77
86
|
</S.Footer>
|
|
78
87
|
</FloatingPanel>
|
|
79
88
|
);
|
|
@@ -99,13 +108,13 @@ interface ISidePanelProps {
|
|
|
99
108
|
edit?: boolean;
|
|
100
109
|
isOpen: boolean;
|
|
101
110
|
isOpenedSecond: boolean;
|
|
102
|
-
toggleSecondaryPanel()
|
|
103
|
-
toggleModal()
|
|
111
|
+
toggleSecondaryPanel: () => void;
|
|
112
|
+
toggleModal: () => void;
|
|
104
113
|
}
|
|
105
114
|
|
|
106
115
|
interface IDispatchProps {
|
|
107
|
-
addMenuItem(
|
|
108
|
-
updateMenuItem(
|
|
116
|
+
addMenuItem(menuItem: any): void;
|
|
117
|
+
updateMenuItem(menuItem: any): void;
|
|
109
118
|
}
|
|
110
119
|
|
|
111
120
|
type IProps = IDispatchProps & ISidePanelProps & IStateProps;
|
|
@@ -2,6 +2,22 @@ import styled from "styled-components";
|
|
|
2
2
|
|
|
3
3
|
export const Footer = styled.div`
|
|
4
4
|
position: absolute;
|
|
5
|
-
bottom:
|
|
6
|
-
|
|
5
|
+
bottom: 0;
|
|
6
|
+
width: 100%;
|
|
7
|
+
right: 0;
|
|
8
|
+
height: 73px;
|
|
9
|
+
background: ${(p) => p.theme.colors.uiBackground01};
|
|
10
|
+
z-index: 3;
|
|
11
|
+
& button {
|
|
12
|
+
position: absolute;
|
|
13
|
+
right: ${(p) => p.theme.spacing.m};
|
|
14
|
+
bottom: ${(p) => p.theme.spacing.m};
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export const FormWrapper = styled.div`
|
|
19
|
+
height: calc(100% - ${(p) => p.theme.spacing.s} - 73px);
|
|
20
|
+
overflow: auto;
|
|
21
|
+
margin: -${(p) => p.theme.spacing.m};
|
|
22
|
+
padding: ${(p) => p.theme.spacing.m};
|
|
7
23
|
`;
|
|
@@ -115,69 +115,82 @@ const PageEditor = (props: IProps) => {
|
|
|
115
115
|
};
|
|
116
116
|
|
|
117
117
|
const publishPage = async () => {
|
|
118
|
-
const { updatePageStatus, savePage, pageID } = props;
|
|
118
|
+
const { updatePageStatus, savePage, pageID, validatePage } = props;
|
|
119
119
|
|
|
120
|
-
const
|
|
121
|
-
status: pageStatus.UPLOAD_PENDING,
|
|
122
|
-
};
|
|
120
|
+
const validated = await validatePage(true);
|
|
123
121
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
122
|
+
if (validated) {
|
|
123
|
+
const publishPage = {
|
|
124
|
+
status: pageStatus.UPLOAD_PENDING,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
pageID
|
|
128
|
+
? updatePageStatus([pageID], pageStatus.UPLOAD_PENDING)
|
|
129
|
+
: savePage(false, publishPage).then((isSaved: boolean) => {
|
|
130
|
+
if (isSaved) {
|
|
131
|
+
resetDirty();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
131
135
|
};
|
|
132
136
|
|
|
133
137
|
const publishChanges = async () => {
|
|
134
|
-
const { savePage } = props;
|
|
138
|
+
const { savePage, validatePage } = props;
|
|
135
139
|
|
|
136
|
-
const
|
|
137
|
-
status: pageStatus.UPLOAD_PENDING,
|
|
138
|
-
};
|
|
140
|
+
const validated = await validatePage(true);
|
|
139
141
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
142
|
+
if (validated) {
|
|
143
|
+
const publishPage = {
|
|
144
|
+
status: pageStatus.UPLOAD_PENDING,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
savePage(false, publishPage).then((isSaved: boolean) => {
|
|
148
|
+
if (isSaved) {
|
|
149
|
+
resetDirty();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
145
153
|
};
|
|
146
154
|
|
|
147
|
-
const unpublishPage =
|
|
155
|
+
const unpublishPage = () => {
|
|
148
156
|
const { updatePageStatus, pageID } = props;
|
|
149
157
|
|
|
150
|
-
|
|
158
|
+
updatePageStatus([pageID], pageStatus.OFFLINE_PENDING);
|
|
151
159
|
};
|
|
152
160
|
|
|
153
|
-
const cancelPublishPage =
|
|
161
|
+
const cancelPublishPage = () => {
|
|
154
162
|
const { updatePageStatus, pageID } = props;
|
|
155
163
|
|
|
156
|
-
|
|
164
|
+
updatePageStatus([pageID], pageStatus.OFFLINE);
|
|
157
165
|
};
|
|
158
166
|
|
|
159
|
-
const reviewPage =
|
|
167
|
+
const reviewPage = () => {
|
|
160
168
|
const { validatePage } = props;
|
|
161
|
-
|
|
169
|
+
validatePage();
|
|
162
170
|
};
|
|
163
171
|
|
|
164
172
|
const handlePublishDraft = async () => {
|
|
165
|
-
const { savePage } = props;
|
|
166
|
-
|
|
167
|
-
|
|
173
|
+
const { savePage, validatePage } = props;
|
|
174
|
+
|
|
175
|
+
const validated = await validatePage(true);
|
|
176
|
+
|
|
177
|
+
if (validated) {
|
|
178
|
+
const isSaved = await savePage(false, null, true);
|
|
179
|
+
if (isSaved) resetDirty();
|
|
180
|
+
}
|
|
168
181
|
};
|
|
169
182
|
|
|
170
|
-
const handleDiscardDraft =
|
|
183
|
+
const handleDiscardDraft = () => {
|
|
171
184
|
const { discardDraft } = props;
|
|
172
185
|
resetDirty();
|
|
173
|
-
|
|
186
|
+
discardDraft();
|
|
174
187
|
};
|
|
175
188
|
|
|
176
|
-
const handleDiscarChanges =
|
|
189
|
+
const handleDiscarChanges = () => {
|
|
177
190
|
const { getPage, pageID } = props;
|
|
178
191
|
resetDirty();
|
|
179
192
|
|
|
180
|
-
|
|
193
|
+
getPage(pageID);
|
|
181
194
|
};
|
|
182
195
|
|
|
183
196
|
const getPublishButton = (status: string) => {
|
|
@@ -596,7 +609,7 @@ interface IPageEditorDispatchProps {
|
|
|
596
609
|
getPage(pageID?: number): Promise<void>;
|
|
597
610
|
savePage(createDraft: boolean, publishPage?: any, publishDraft?: boolean): Promise<boolean>;
|
|
598
611
|
deletePage(params?: ISavePageParams): Promise<boolean>;
|
|
599
|
-
validatePage(): Promise<boolean>;
|
|
612
|
+
validatePage(publish?: boolean): Promise<boolean>;
|
|
600
613
|
updatePageStatus(id: number[], status: string): Promise<boolean>;
|
|
601
614
|
setHistoryPush(path: string, isEditor: boolean): void;
|
|
602
615
|
setLanguage?(lang: { locale: string; id: number | null }): void;
|
|
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
|
|
|
3
3
|
|
|
4
4
|
import { appActions } from "@ax/containers/App";
|
|
5
5
|
import { sitesActions } from "@ax/containers/Sites";
|
|
6
|
-
import { ISettingsForm, ISite } from "@ax/types";
|
|
6
|
+
import { IRootState, ISettingsForm, ISite, IUser } from "@ax/types";
|
|
7
7
|
import { useModal } from "@ax/hooks";
|
|
8
8
|
import { MainWrapper, Modal, ErrorToast } from "@ax/components";
|
|
9
9
|
|
|
@@ -13,7 +13,7 @@ import SiteItem from "./SiteItem";
|
|
|
13
13
|
import * as S from "./style";
|
|
14
14
|
|
|
15
15
|
const SitesList = (props: IProps): JSX.Element => {
|
|
16
|
-
const { sites, saveSettings, setHistoryPush } = props;
|
|
16
|
+
const { sites, saveSettings, setHistoryPush, currentUser } = props;
|
|
17
17
|
|
|
18
18
|
const initialState = {
|
|
19
19
|
name: "",
|
|
@@ -50,13 +50,17 @@ const SitesList = (props: IProps): JSX.Element => {
|
|
|
50
50
|
const mainAction = { title: "Create site", onClick: saveSiteSettings, disabled: isSubmitDisabled };
|
|
51
51
|
const secondaryAction = { title: "Cancel", onClick: toggleModal };
|
|
52
52
|
|
|
53
|
+
const userHasSite = (siteID: number) => currentUser.sites.includes("all") || currentUser.sites.includes(siteID);
|
|
54
|
+
|
|
53
55
|
return (
|
|
54
56
|
<MainWrapper title="Sites" rightButton={rightButtonProps}>
|
|
55
57
|
<ErrorToast />
|
|
56
58
|
<S.Sites>
|
|
57
|
-
{sites
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
{sites
|
|
60
|
+
.filter((site: ISite) => userHasSite(site.id))
|
|
61
|
+
.map((site: ISite) => (
|
|
62
|
+
<SiteItem key={site.id} site={site} />
|
|
63
|
+
))}
|
|
60
64
|
</S.Sites>
|
|
61
65
|
<Modal
|
|
62
66
|
isOpen={isOpen}
|
|
@@ -74,8 +78,13 @@ const SitesList = (props: IProps): JSX.Element => {
|
|
|
74
78
|
|
|
75
79
|
interface ISitesProps {
|
|
76
80
|
sites: ISite[];
|
|
81
|
+
currentUser: IUser;
|
|
77
82
|
}
|
|
78
83
|
|
|
84
|
+
const mapStateToProps = (state: IRootState) => ({
|
|
85
|
+
currentUser: state.users.currentUser,
|
|
86
|
+
});
|
|
87
|
+
|
|
79
88
|
interface IDispatchProps {
|
|
80
89
|
setHistoryPush(path: string, isEditor?: boolean): void;
|
|
81
90
|
saveSettings(form: ISettingsForm): Promise<boolean>;
|
|
@@ -88,4 +97,4 @@ const mapDispatchToProps = {
|
|
|
88
97
|
|
|
89
98
|
type IProps = ISitesProps & IDispatchProps;
|
|
90
99
|
|
|
91
|
-
export default connect(
|
|
100
|
+
export default connect(mapStateToProps, mapDispatchToProps)(SitesList);
|
|
@@ -38,6 +38,7 @@ const Form = (props: IProps) => {
|
|
|
38
38
|
deleteStructuredDataContent,
|
|
39
39
|
errors,
|
|
40
40
|
validated,
|
|
41
|
+
validateForm,
|
|
41
42
|
} = props;
|
|
42
43
|
|
|
43
44
|
const [isNewStructuredData, setIsNewStructuredData] = useState(!form.id);
|
|
@@ -75,29 +76,33 @@ const Form = (props: IProps) => {
|
|
|
75
76
|
});
|
|
76
77
|
|
|
77
78
|
const handleSave = async (publish?: boolean) => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
const validated = publish ? await validateForm(true) : true;
|
|
80
|
+
|
|
81
|
+
if (validated) {
|
|
82
|
+
setIsSavedData(true);
|
|
83
|
+
const status = isNewStructuredData ? true : form.draft;
|
|
84
|
+
|
|
85
|
+
let payload: any = {
|
|
86
|
+
structuredData: currentStructuredData ? currentStructuredData.id : null,
|
|
87
|
+
content: form.content,
|
|
88
|
+
draft: publish === true ? false : status,
|
|
89
|
+
relatedSite: currentSite ? currentSite.id : null,
|
|
90
|
+
entity: form.entity ? form.entity : null,
|
|
91
|
+
};
|
|
88
92
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
if (!isNewStructuredData) {
|
|
94
|
+
payload = { ...payload, ...form };
|
|
95
|
+
}
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
let saved = false;
|
|
98
|
+
if (isNewStructuredData) {
|
|
99
|
+
saved = await createStructuredDataContent(payload);
|
|
100
|
+
saved && setIsNewStructuredData(false);
|
|
101
|
+
} else {
|
|
102
|
+
saved = await updateStructuredDataContent(payload);
|
|
103
|
+
}
|
|
104
|
+
saved && resetDirty();
|
|
99
105
|
}
|
|
100
|
-
saved && resetDirty();
|
|
101
106
|
};
|
|
102
107
|
|
|
103
108
|
const getSaveLabel = () => {
|
|
@@ -171,6 +176,9 @@ const Form = (props: IProps) => {
|
|
|
171
176
|
};
|
|
172
177
|
|
|
173
178
|
const publishItem = async () => {
|
|
179
|
+
const validated = await validateForm(true);
|
|
180
|
+
if (!validated) return;
|
|
181
|
+
|
|
174
182
|
if (!isNewStructuredData) {
|
|
175
183
|
setDataStatus(form.id, "undraft").then((updated: boolean) => {
|
|
176
184
|
if (updated) {
|
|
@@ -306,7 +314,7 @@ interface IProps {
|
|
|
306
314
|
getSiteDataPack(packID: string): void;
|
|
307
315
|
setDataStatus(id: number, status: string): Promise<boolean>;
|
|
308
316
|
deleteStructuredDataContent(id: number): Promise<boolean>;
|
|
309
|
-
validateForm(): Promise<boolean>;
|
|
317
|
+
validateForm(publish?: boolean): Promise<boolean>;
|
|
310
318
|
}
|
|
311
319
|
|
|
312
320
|
const mapStateToProps = (state: IRootState) => ({
|
|
@@ -113,7 +113,7 @@ const getSortedListStatus = (orderPointer: string, isAscending: boolean) => {
|
|
|
113
113
|
isAscending,
|
|
114
114
|
sortedByTitle: orderPointer === "title",
|
|
115
115
|
sortedByURL: orderPointer === "slug",
|
|
116
|
-
sortedByDate:
|
|
116
|
+
sortedByDate: ["modified", "date"].includes(orderPointer),
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
return sortedListStatus;
|
package/src/types/index.tsx
CHANGED
|
@@ -314,6 +314,7 @@ export interface IMenuItem {
|
|
|
314
314
|
url: any;
|
|
315
315
|
auxText: string;
|
|
316
316
|
children: any[];
|
|
317
|
+
image?: IImage | string | null;
|
|
317
318
|
isExpanded?: boolean;
|
|
318
319
|
config: IMenuItemConfig | null;
|
|
319
320
|
parentEditorID?: number;
|
|
@@ -329,6 +330,7 @@ export interface IMenuForm {
|
|
|
329
330
|
itemLink: any;
|
|
330
331
|
itemLabel: string;
|
|
331
332
|
itemAuxText: string;
|
|
333
|
+
itemImage: IImage | string | null;
|
|
332
334
|
type: string;
|
|
333
335
|
headerStyle: string;
|
|
334
336
|
footerStyle: string;
|
|
@@ -535,7 +537,7 @@ export interface IUser {
|
|
|
535
537
|
enabled?: boolean;
|
|
536
538
|
timezone?: string;
|
|
537
539
|
status?: string;
|
|
538
|
-
sites
|
|
540
|
+
sites: (number | string)[];
|
|
539
541
|
}
|
|
540
542
|
|
|
541
543
|
export interface ISelectOption {
|