@griddo/ax 1.55.14 → 1.56.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/package.json +2 -2
- package/src/GlobalStore.tsx +3 -0
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +6 -0
- package/src/components/Fields/ArrayFieldGroup/ArrayFieldInline/index.tsx +16 -12
- package/src/components/Fields/ArrayFieldGroup/ArrayFieldItem/index.tsx +17 -15
- package/src/components/Fields/ConditionalField/index.tsx +1 -3
- package/src/components/Fields/FileField/index.tsx +1 -1
- package/src/components/Fields/Wysiwyg/config.tsx +0 -1
- package/src/components/Fields/Wysiwyg/index.tsx +16 -5
- package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +110 -99
- package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +75 -55
- package/src/components/Gallery/GalleryPanel/index.tsx +14 -8
- package/src/components/Gallery/index.tsx +113 -151
- package/src/components/Gallery/style.tsx +40 -10
- package/src/components/MainWrapper/AppBar/index.tsx +1 -0
- package/src/components/Toast/index.tsx +15 -9
- package/src/components/Toast/style.tsx +2 -2
- package/src/containers/Gallery/actions.tsx +171 -0
- package/src/containers/Gallery/constants.tsx +18 -0
- package/src/containers/Gallery/index.tsx +7 -0
- package/src/containers/Gallery/interfaces.tsx +41 -0
- package/src/containers/Gallery/reducer.tsx +78 -0
- package/src/containers/PageEditor/actions.tsx +15 -5
- package/src/containers/StructuredData/actions.tsx +4 -21
- package/src/forms/fields.tsx +19 -6
- package/src/guards/error/index.tsx +3 -1
- package/src/modules/Content/HeaderMenus/Live/index.tsx +6 -5
- package/src/modules/Sites/SitesList/index.tsx +1 -1
- package/src/modules/StructuredData/Form/ConnectedField/index.tsx +2 -4
- package/src/modules/StructuredData/Form/index.tsx +10 -6
- package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Live/index.tsx +1 -1
- package/src/types/index.tsx +20 -0
- package/src/components/Gallery/store.tsx +0 -186
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import styled from "styled-components";
|
|
2
2
|
|
|
3
|
-
const gutter = "
|
|
4
|
-
const
|
|
3
|
+
const gutter = "6px";
|
|
4
|
+
const imageSizes: Record<string, number> = {
|
|
5
|
+
"S": 2.5,
|
|
6
|
+
"L": 4,
|
|
7
|
+
"P": 1.75
|
|
8
|
+
}
|
|
5
9
|
|
|
6
10
|
export const Wrapper = styled.div`
|
|
7
11
|
display: flex;
|
|
@@ -53,6 +57,7 @@ export const GalleryWrapper = styled.div`
|
|
|
53
57
|
overflow: auto;
|
|
54
58
|
padding-right: ${gutter};
|
|
55
59
|
min-height: calc(100% - ${p => p.theme.spacing.xl} * 2);
|
|
60
|
+
position: relative;
|
|
56
61
|
`;
|
|
57
62
|
|
|
58
63
|
export const IconChecked = styled.div`
|
|
@@ -86,26 +91,37 @@ export const IconUnchecked = styled.div`
|
|
|
86
91
|
export const Grid = styled.div`
|
|
87
92
|
display: flex;
|
|
88
93
|
flex-flow: row wrap;
|
|
94
|
+
align-content: flex-start;
|
|
95
|
+
align-items: stretch;
|
|
89
96
|
padding: ${p => p.theme.spacing.m};
|
|
90
97
|
margin: 0 -${gutter};
|
|
91
98
|
margin-top: -${gutter};
|
|
92
99
|
border-right: 1px solid ${p => p.theme.color.uiLine};
|
|
93
100
|
min-height: calc(100% + ${gutter});
|
|
101
|
+
|
|
102
|
+
&::after {
|
|
103
|
+
content: "";
|
|
104
|
+
flex: auto;
|
|
105
|
+
}
|
|
94
106
|
`;
|
|
95
107
|
|
|
96
|
-
export const GridItem = styled.div
|
|
97
|
-
width: calc(100% / ${columns});
|
|
108
|
+
export const GridItem = styled.div<{ orientation: string }>`
|
|
98
109
|
padding-left: ${gutter};
|
|
99
110
|
padding-top: ${gutter};
|
|
111
|
+
flex: ${p => p.orientation === "P" ? 0 : 1};
|
|
112
|
+
|
|
113
|
+
&:last-child {
|
|
114
|
+
flex: 0;
|
|
115
|
+
}
|
|
100
116
|
`;
|
|
101
117
|
|
|
102
|
-
export const ImageWrapper = styled.div<{ selected: boolean }>`
|
|
118
|
+
export const ImageWrapper = styled.div<{ selected: boolean, orientation: string }>`
|
|
103
119
|
position: relative;
|
|
104
|
-
width: ${p => `calc(${p.theme.spacing.
|
|
105
|
-
|
|
120
|
+
min-width: ${p => `calc(${p.theme.spacing.l} * ${imageSizes[p.orientation]})`};
|
|
121
|
+
width: ${p => p.orientation === "P" ? `calc(${p.theme.spacing.l} * ${imageSizes["P"]})` : "auto"};
|
|
122
|
+
height: ${p => `calc(${p.theme.spacing.l} * ${imageSizes["S"]})`};
|
|
106
123
|
border: 1px solid;
|
|
107
124
|
border-color: ${p => (p.selected === true ? p.theme.color.interactive02 : p.theme.color.uiLine)};
|
|
108
|
-
border-radius: 4px;
|
|
109
125
|
:before {
|
|
110
126
|
content: "";
|
|
111
127
|
position: absolute;
|
|
@@ -116,7 +132,6 @@ export const ImageWrapper = styled.div<{ selected: boolean }>`
|
|
|
116
132
|
opacity: ${p => (p.selected === true ? 1 : 0)};
|
|
117
133
|
transition: opacity 0.1s;
|
|
118
134
|
background-color: ${p => (p.selected === true ? p.theme.color.overlay : `transparent`)};
|
|
119
|
-
border-radius: 4px;
|
|
120
135
|
}
|
|
121
136
|
:hover {
|
|
122
137
|
cursor: pointer;
|
|
@@ -133,7 +148,6 @@ export const ImageWrapper = styled.div<{ selected: boolean }>`
|
|
|
133
148
|
width: 100%;
|
|
134
149
|
height: 100%;
|
|
135
150
|
object-fit: cover;
|
|
136
|
-
border-radius: 4px;
|
|
137
151
|
}
|
|
138
152
|
${IconChecked} {
|
|
139
153
|
display: ${p => (p.selected === true ? `block` : 0)};
|
|
@@ -156,10 +170,26 @@ export const LoadingWrapper = styled.div`
|
|
|
156
170
|
export const LoaderWrapper = styled.div`
|
|
157
171
|
width: 100%;
|
|
158
172
|
text-align: center;
|
|
173
|
+
margin-bottom: ${p => p.theme.spacing.s};
|
|
159
174
|
`;
|
|
160
175
|
|
|
161
176
|
export const EmptyWrapper = styled.div`
|
|
162
177
|
display: flex;
|
|
163
178
|
align-items: center;
|
|
164
179
|
margin: auto;
|
|
180
|
+
align-content: center;
|
|
181
|
+
padding: ${p => p.theme.spacing.m};
|
|
182
|
+
margin: 0 -${gutter};
|
|
183
|
+
margin-top: -${gutter};
|
|
184
|
+
border-right: 1px solid ${p => p.theme.color.uiLine};
|
|
185
|
+
min-height: calc(100% + ${gutter});
|
|
186
|
+
`;
|
|
187
|
+
|
|
188
|
+
export const NotificationWrapper = styled.div`
|
|
189
|
+
width: 100%;
|
|
190
|
+
position: absolute;
|
|
191
|
+
top: 0;
|
|
192
|
+
left: 0;
|
|
193
|
+
right: 0;
|
|
194
|
+
z-index: 2;
|
|
165
195
|
`;
|
|
@@ -84,6 +84,7 @@ const AppBar = (props: IProps): JSX.Element => {
|
|
|
84
84
|
if (pageLanguages && !getCurrentLanguage(item.locale)) {
|
|
85
85
|
setNewTranslation(true);
|
|
86
86
|
languageActions.getContent && currentPageID && languageActions.getContent(currentPageID);
|
|
87
|
+
languageActions.getDataContent && currentPageID && languageActions.getDataContent(currentPageID);
|
|
87
88
|
}
|
|
88
89
|
};
|
|
89
90
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useRef } from "react";
|
|
1
|
+
import React, { useRef, useEffect } from "react";
|
|
2
2
|
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { Button, IconAction } from "@ax/components";
|
|
@@ -10,22 +10,28 @@ const Toast = (props: IProps) => {
|
|
|
10
10
|
const toast = useRef<any>(null);
|
|
11
11
|
|
|
12
12
|
let temp: any;
|
|
13
|
-
const setTemp = () => (temp = setTimeout(() => setIsVisible(false),
|
|
14
|
-
const stopTemp = () => clearTimeout(temp);
|
|
13
|
+
const setTemp = (time: number) => (temp = setTimeout(() => setIsVisible(false), time));
|
|
15
14
|
|
|
16
15
|
const close = () => {
|
|
17
16
|
toast.current.classList.add("close-animation");
|
|
18
|
-
setTemp();
|
|
19
|
-
stopTemp();
|
|
17
|
+
setTemp(1000);
|
|
20
18
|
};
|
|
21
19
|
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
setTemp(5000);
|
|
22
|
+
return () => clearTimeout(temp);
|
|
23
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
22
26
|
return createPortal(
|
|
23
27
|
<S.Wrapper ref={toast}>
|
|
24
28
|
<S.Text>{message}</S.Text>
|
|
25
29
|
<S.Buttons>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
{action &&
|
|
31
|
+
<Button type="button" buttonStyle="lineInverse" onClick={action}>
|
|
32
|
+
Undo
|
|
33
|
+
</Button>
|
|
34
|
+
}
|
|
29
35
|
<IconAction icon="close" onClick={close} inversed={true} />
|
|
30
36
|
</S.Buttons>
|
|
31
37
|
</S.Wrapper>,
|
|
@@ -34,7 +40,7 @@ const Toast = (props: IProps) => {
|
|
|
34
40
|
};
|
|
35
41
|
|
|
36
42
|
interface IProps {
|
|
37
|
-
action
|
|
43
|
+
action?: () => void;
|
|
38
44
|
message: string;
|
|
39
45
|
setIsVisible: (visibility: boolean) => void;
|
|
40
46
|
}
|
|
@@ -8,8 +8,8 @@ const Wrapper = styled.div`
|
|
|
8
8
|
justify-content: space-between;
|
|
9
9
|
align-items: center;
|
|
10
10
|
border-radius: 4px;
|
|
11
|
-
position:
|
|
12
|
-
z-index:
|
|
11
|
+
position: fixed;
|
|
12
|
+
z-index: 1100;
|
|
13
13
|
bottom: ${p => p.theme.spacing.m};
|
|
14
14
|
left: ${p => `calc(${p.theme.spacing.m} * 4)`};
|
|
15
15
|
padding-left: ${p => p.theme.spacing.m};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { Dispatch } from "redux";
|
|
2
|
+
|
|
3
|
+
import { handleRequest, isReqOk, compressImage } from "@ax/helpers";
|
|
4
|
+
import { images, sites } from "@ax/api";
|
|
5
|
+
import { IGetSiteImages, IImage, IImageForm, IRootState } from "@ax/types";
|
|
6
|
+
import { appActions } from "@ax/containers/App";
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
SET_DATA,
|
|
10
|
+
SET_IS_LOADING,
|
|
11
|
+
SET_IS_SAVING,
|
|
12
|
+
SET_IS_UPLOADING,
|
|
13
|
+
SET_UPLOAD_SUCCESS,
|
|
14
|
+
SET_UPLOAD_ERROR,
|
|
15
|
+
} from "./constants";
|
|
16
|
+
import {
|
|
17
|
+
ISetData,
|
|
18
|
+
ISetIsLoading,
|
|
19
|
+
ISetIsSaving,
|
|
20
|
+
ISetIsUploading,
|
|
21
|
+
ISetUploadSuccess,
|
|
22
|
+
ISetUploadError,
|
|
23
|
+
} from "./interfaces";
|
|
24
|
+
import { IData, IIsLoading, IIsSaving } from "./reducer";
|
|
25
|
+
|
|
26
|
+
const thumbWidth = 192;
|
|
27
|
+
const thumbHeight = 144;
|
|
28
|
+
const maxSize = 10; // MB
|
|
29
|
+
|
|
30
|
+
function setData(data: IData): ISetData {
|
|
31
|
+
return { type: SET_DATA, payload: { data } };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function setIsLoading(isLoading: IIsLoading): ISetIsLoading {
|
|
35
|
+
return { type: SET_IS_LOADING, payload: { isLoading } };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function setIsSaving(isSaving: IIsSaving): ISetIsSaving {
|
|
39
|
+
return { type: SET_IS_SAVING, payload: { isSaving } };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function setIsUploading(isUploading: boolean): ISetIsUploading {
|
|
43
|
+
return { type: SET_IS_UPLOADING, payload: { isUploading } };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function setUploadSuccess(isSuccess: boolean): ISetUploadSuccess {
|
|
47
|
+
return { type: SET_UPLOAD_SUCCESS, payload: { isUploading: false, isSuccess } };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function setUploadError(errorMsg = ""): ISetUploadError {
|
|
51
|
+
return { type: SET_UPLOAD_ERROR, payload: { inDropZone: false, isUploading: false, isError: true, errorMsg } };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getSiteImages(props: IGetSiteImages): (dispatch: Dispatch, getState: () => IRootState) => Promise<void> {
|
|
55
|
+
return async (dispatch, getState) => {
|
|
56
|
+
const {
|
|
57
|
+
gallery: { data },
|
|
58
|
+
} = getState();
|
|
59
|
+
const { site, page = 1, items, query, search, more = false } = props;
|
|
60
|
+
try {
|
|
61
|
+
dispatch(setIsLoading({ init: !more, more }));
|
|
62
|
+
const result = await sites.getSiteImages(site, page, items, thumbWidth, thumbHeight, query, search);
|
|
63
|
+
if (isReqOk(result.status)) {
|
|
64
|
+
const images = [...result.data.items];
|
|
65
|
+
if (more) images.unshift(...data.items);
|
|
66
|
+
dispatch(
|
|
67
|
+
setData({
|
|
68
|
+
items: images,
|
|
69
|
+
page,
|
|
70
|
+
isImageSelected: false,
|
|
71
|
+
imageSelected: null,
|
|
72
|
+
isFinished: result.data.items.length < items,
|
|
73
|
+
})
|
|
74
|
+
);
|
|
75
|
+
dispatch(setIsLoading({ init: false, more: false }));
|
|
76
|
+
dispatch(setUploadSuccess(false));
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
console.log(e);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function selectImage(item: IImage): (dispatch: Dispatch, getState: () => IRootState) => Promise<void> {
|
|
85
|
+
return async (dispatch, getState) => {
|
|
86
|
+
const {
|
|
87
|
+
gallery: { data },
|
|
88
|
+
} = getState();
|
|
89
|
+
if (data.imageSelected === item) {
|
|
90
|
+
dispatch(setData({ ...data, imageSelected: null, isImageSelected: false }));
|
|
91
|
+
} else {
|
|
92
|
+
dispatch(setData({ ...data, imageSelected: item, isImageSelected: true }));
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function uploadImage(imageFile: File, site: number | string): (dispatch: Dispatch) => Promise<IImage> {
|
|
98
|
+
return async (dispatch) => {
|
|
99
|
+
try {
|
|
100
|
+
dispatch(setIsUploading(true));
|
|
101
|
+
const imageSize = imageFile.size / (1024 * 1024);
|
|
102
|
+
const image = imageSize >= maxSize ? await compressImage(imageFile, 9999, 9999, maxSize, false) : imageFile;
|
|
103
|
+
const form = new FormData();
|
|
104
|
+
form.append("file", image);
|
|
105
|
+
site && form.append("site", JSON.stringify(site));
|
|
106
|
+
const result = await images.createImage(form);
|
|
107
|
+
if (isReqOk(result.status)) {
|
|
108
|
+
dispatch(setIsUploading(false));
|
|
109
|
+
dispatch(setUploadSuccess(true));
|
|
110
|
+
// dispatch(setInDropZone(false));
|
|
111
|
+
return { ...result.data, file: image };
|
|
112
|
+
} else {
|
|
113
|
+
dispatch(setUploadError("Error uploading image"));
|
|
114
|
+
}
|
|
115
|
+
} catch (e) {
|
|
116
|
+
console.log(e);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function uploadError(error: string): (dispatch: Dispatch) => Promise<void> {
|
|
122
|
+
return async (dispatch) => {
|
|
123
|
+
dispatch(setUploadError(error));
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function updateImage(
|
|
128
|
+
imageID: number,
|
|
129
|
+
imageData: IImageForm,
|
|
130
|
+
add?: boolean
|
|
131
|
+
): (dispatch: Dispatch, getState: () => IRootState) => Promise<void> {
|
|
132
|
+
return async (dispatch, getState) => {
|
|
133
|
+
const {
|
|
134
|
+
gallery: { isSaving },
|
|
135
|
+
} = getState();
|
|
136
|
+
dispatch(setIsSaving({ ...isSaving, save: true, saveAdd: !!add }));
|
|
137
|
+
try {
|
|
138
|
+
const result = await images.updateImage(imageID, imageData);
|
|
139
|
+
if (isReqOk(result.status)) {
|
|
140
|
+
console.log(result.data, "data");
|
|
141
|
+
dispatch(setData({ ...result.data, isImageSelected: false, imageSelected: null }));
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
144
|
+
console.log(e);
|
|
145
|
+
}
|
|
146
|
+
dispatch(setIsSaving({ ...isSaving, save: false, saveAdd: false }));
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function deleteImage(imageID: number): (dispatch: Dispatch, getState: () => IRootState) => Promise<boolean> {
|
|
151
|
+
return async (dispatch) => {
|
|
152
|
+
try {
|
|
153
|
+
const responseActions = {
|
|
154
|
+
handleSuccess: () => true,
|
|
155
|
+
handleError: (response: any) => {
|
|
156
|
+
appActions.handleError(response)(dispatch);
|
|
157
|
+
return false;
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const callback = async () => images.deleteImage(imageID);
|
|
162
|
+
|
|
163
|
+
return await handleRequest(callback, responseActions, [])(dispatch);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
console.log(e);
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export { setIsLoading, getSiteImages, uploadImage, updateImage, deleteImage, selectImage, uploadError };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const NAME = "gallery";
|
|
2
|
+
|
|
3
|
+
const SET_DATA = `${NAME}/SET_DATA`;
|
|
4
|
+
const SET_IS_LOADING = `${NAME}/SET_IS_LOADING`;
|
|
5
|
+
const SET_IS_SAVING = `${NAME}/SET_IS_SAVING`;
|
|
6
|
+
const SET_IS_UPLOADING = `${NAME}/SET_IS_UPLOADING`;
|
|
7
|
+
const SET_UPLOAD_SUCCESS = `${NAME}/SET_UPLOAD_SUCCESS`;
|
|
8
|
+
const SET_UPLOAD_ERROR = `${NAME}/SET_UPLOAD_ERROR`;
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
NAME,
|
|
12
|
+
SET_DATA,
|
|
13
|
+
SET_IS_LOADING,
|
|
14
|
+
SET_IS_SAVING,
|
|
15
|
+
SET_IS_UPLOADING,
|
|
16
|
+
SET_UPLOAD_SUCCESS,
|
|
17
|
+
SET_UPLOAD_ERROR,
|
|
18
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IData, IIsLoading, IIsSaving } from "./reducer";
|
|
2
|
+
import {
|
|
3
|
+
SET_DATA,
|
|
4
|
+
SET_IS_LOADING,
|
|
5
|
+
SET_IS_SAVING,
|
|
6
|
+
SET_IS_UPLOADING,
|
|
7
|
+
SET_UPLOAD_SUCCESS,
|
|
8
|
+
SET_UPLOAD_ERROR,
|
|
9
|
+
} from "./constants";
|
|
10
|
+
|
|
11
|
+
export interface ISetData {
|
|
12
|
+
type: typeof SET_DATA;
|
|
13
|
+
payload: { data: IData };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ISetIsLoading {
|
|
17
|
+
type: typeof SET_IS_LOADING;
|
|
18
|
+
payload: { isLoading: IIsLoading };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ISetIsSaving {
|
|
22
|
+
type: typeof SET_IS_SAVING;
|
|
23
|
+
payload: { isSaving: IIsSaving };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ISetIsUploading {
|
|
27
|
+
type: typeof SET_IS_UPLOADING;
|
|
28
|
+
payload: { isUploading: boolean };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ISetUploadSuccess {
|
|
32
|
+
type: typeof SET_UPLOAD_SUCCESS;
|
|
33
|
+
payload: { isUploading: boolean, isSuccess: boolean };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ISetUploadError {
|
|
37
|
+
type: typeof SET_UPLOAD_ERROR;
|
|
38
|
+
payload: { inDropZone: boolean, isUploading: boolean, isError: boolean, errorMsg: string };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type GalleryActionsCreators = ISetData & ISetIsLoading & ISetIsSaving & ISetIsUploading & ISetUploadSuccess & ISetUploadError;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { IImage } from "@ax/types";
|
|
2
|
+
import {
|
|
3
|
+
SET_DATA,
|
|
4
|
+
SET_IS_LOADING,
|
|
5
|
+
SET_IS_SAVING,
|
|
6
|
+
SET_IS_UPLOADING,
|
|
7
|
+
SET_UPLOAD_SUCCESS,
|
|
8
|
+
SET_UPLOAD_ERROR,
|
|
9
|
+
} from "./constants";
|
|
10
|
+
import { GalleryActionsCreators } from "./interfaces";
|
|
11
|
+
|
|
12
|
+
export interface IData {
|
|
13
|
+
items: IImage[];
|
|
14
|
+
isImageSelected: boolean;
|
|
15
|
+
imageSelected: IImage | null;
|
|
16
|
+
page: number;
|
|
17
|
+
isFinished: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface IIsLoading {
|
|
21
|
+
init: boolean;
|
|
22
|
+
more: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface IIsSaving {
|
|
26
|
+
save: boolean;
|
|
27
|
+
saveAdd: boolean;
|
|
28
|
+
delete: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface IGalleryState {
|
|
32
|
+
data: IData;
|
|
33
|
+
isLoading: IIsLoading;
|
|
34
|
+
isSaving: IIsSaving;
|
|
35
|
+
isUploading: boolean;
|
|
36
|
+
isSuccess: boolean;
|
|
37
|
+
isError: boolean;
|
|
38
|
+
errorMsg: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const initialState = {
|
|
42
|
+
data: {
|
|
43
|
+
items: [],
|
|
44
|
+
isImageSelected: false,
|
|
45
|
+
imageSelected: null,
|
|
46
|
+
page: 1,
|
|
47
|
+
isFinished: false,
|
|
48
|
+
},
|
|
49
|
+
isLoading: {
|
|
50
|
+
init: false,
|
|
51
|
+
more: false,
|
|
52
|
+
},
|
|
53
|
+
isSaving: {
|
|
54
|
+
save: false,
|
|
55
|
+
saveAdd: false,
|
|
56
|
+
delete: false
|
|
57
|
+
},
|
|
58
|
+
isUploading: false,
|
|
59
|
+
isSuccess: false,
|
|
60
|
+
isError: false,
|
|
61
|
+
errorMsg: "",
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export function reducer(state = initialState, action: GalleryActionsCreators): IGalleryState {
|
|
65
|
+
switch (action.type) {
|
|
66
|
+
case SET_DATA:
|
|
67
|
+
case SET_IS_LOADING:
|
|
68
|
+
case SET_IS_SAVING:
|
|
69
|
+
case SET_IS_UPLOADING:
|
|
70
|
+
case SET_UPLOAD_SUCCESS:
|
|
71
|
+
case SET_UPLOAD_ERROR:
|
|
72
|
+
return { ...state, ...action.payload };
|
|
73
|
+
default:
|
|
74
|
+
return state;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { initialState as galleryInitialState, reducer as galleryReducer };
|
|
@@ -173,8 +173,13 @@ const setRootEditorID = (dispatch: Dispatch, getState: any) => {
|
|
|
173
173
|
};
|
|
174
174
|
|
|
175
175
|
function generateNewPage(dispatch: Dispatch, getState: any, baseSchema: string) {
|
|
176
|
-
const {
|
|
177
|
-
|
|
176
|
+
const {
|
|
177
|
+
structuredData: {
|
|
178
|
+
structuredData: { site },
|
|
179
|
+
},
|
|
180
|
+
pageEditor: { template },
|
|
181
|
+
app: { lang },
|
|
182
|
+
} = getState();
|
|
178
183
|
|
|
179
184
|
let page = getDefaultSchema(baseSchema);
|
|
180
185
|
const parsedPageData = parseData(page, true);
|
|
@@ -182,7 +187,7 @@ function generateNewPage(dispatch: Dispatch, getState: any, baseSchema: string)
|
|
|
182
187
|
const pageStructuredData = getStructuredDataFromPage(site);
|
|
183
188
|
const structuredData = pageStructuredData && getCurrentPageStructuredData(template, pageStructuredData);
|
|
184
189
|
|
|
185
|
-
page = { ...parsedPageData, template: currentTemplate };
|
|
190
|
+
page = { ...parsedPageData, template: currentTemplate, language: lang.id };
|
|
186
191
|
|
|
187
192
|
if (structuredData) {
|
|
188
193
|
page.structuredData = structuredData.id;
|
|
@@ -250,6 +255,12 @@ function getPage(pageID?: number, global?: boolean): (dispatch: Dispatch, getSta
|
|
|
250
255
|
|
|
251
256
|
if (global) page["component"] = component;
|
|
252
257
|
|
|
258
|
+
const pageLiveStatus = page.draftFromPage
|
|
259
|
+
? pageStatus.MODIFIED
|
|
260
|
+
: isNewTranslation
|
|
261
|
+
? pageStatus.OFFLINE
|
|
262
|
+
: page.liveStatus.status;
|
|
263
|
+
|
|
253
264
|
if (isReqOk(response.status)) {
|
|
254
265
|
setRootEditorID(dispatch, getState);
|
|
255
266
|
generatePageContent(page, dispatch, getState);
|
|
@@ -257,8 +268,7 @@ function getPage(pageID?: number, global?: boolean): (dispatch: Dispatch, getSta
|
|
|
257
268
|
dispatch(setCurrentPageID(page.id));
|
|
258
269
|
dispatch(setTemplateConfig(page.templateConfig));
|
|
259
270
|
dispatch(setUserEditing(page.editing));
|
|
260
|
-
|
|
261
|
-
dispatch(setCurrentPageStatus(liveStatus));
|
|
271
|
+
dispatch(setCurrentPageStatus(pageLiveStatus));
|
|
262
272
|
}
|
|
263
273
|
} else {
|
|
264
274
|
if (!isNewTranslation) {
|
|
@@ -291,7 +291,6 @@ function createStructuredDataContent(
|
|
|
291
291
|
const {
|
|
292
292
|
app: { lang },
|
|
293
293
|
sites: { currentSiteInfo },
|
|
294
|
-
structuredData: { currentFilter },
|
|
295
294
|
} = getState();
|
|
296
295
|
|
|
297
296
|
dataContent = {
|
|
@@ -300,15 +299,8 @@ function createStructuredDataContent(
|
|
|
300
299
|
relatedSite: currentSiteInfo && currentSiteInfo.id,
|
|
301
300
|
};
|
|
302
301
|
|
|
303
|
-
const params = { ...DEFAULT_PARAMS, dataID: currentFilter };
|
|
304
|
-
|
|
305
|
-
const siteID = currentSiteInfo && currentSiteInfo.id;
|
|
306
|
-
|
|
307
302
|
const responseActions = {
|
|
308
|
-
handleSuccess: (response: any) =>
|
|
309
|
-
getStructuredDataContents(params, siteID)(dispatch, getState);
|
|
310
|
-
dispatch(setForm(response));
|
|
311
|
-
},
|
|
303
|
+
handleSuccess: (response: any) => dispatch(setForm(response)),
|
|
312
304
|
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
313
305
|
};
|
|
314
306
|
|
|
@@ -325,22 +317,13 @@ function createStructuredDataContent(
|
|
|
325
317
|
|
|
326
318
|
function updateStructuredDataContent(
|
|
327
319
|
structuredDataContent: IStructuredDataContent
|
|
328
|
-
): (dispatch: Dispatch
|
|
329
|
-
return async (dispatch
|
|
320
|
+
): (dispatch: Dispatch) => Promise<void> {
|
|
321
|
+
return async (dispatch) => {
|
|
330
322
|
try {
|
|
331
|
-
const {
|
|
332
|
-
structuredData: { currentFilter },
|
|
333
|
-
sites: { currentSiteInfo },
|
|
334
|
-
} = getState();
|
|
335
|
-
|
|
336
|
-
const params = { ...DEFAULT_PARAMS, dataID: currentFilter };
|
|
337
|
-
|
|
338
|
-
const siteID = currentSiteInfo && currentSiteInfo.id;
|
|
339
|
-
|
|
340
323
|
const dataContent = prepareStructuredDataContent(structuredDataContent);
|
|
341
324
|
|
|
342
325
|
const responseActions = {
|
|
343
|
-
handleSuccess: () =>
|
|
326
|
+
handleSuccess: (response: any) => dispatch(setForm(response)),
|
|
344
327
|
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
345
328
|
};
|
|
346
329
|
|
package/src/forms/fields.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { FieldContainer, FieldsBehavior } from "@ax/components";
|
|
|
3
3
|
import { IErrorItem, IPage } from "@ax/types";
|
|
4
4
|
|
|
5
5
|
const getInnerFields = (
|
|
6
|
-
innerFields: any,
|
|
6
|
+
innerFields: any[],
|
|
7
7
|
innerActions: any,
|
|
8
8
|
selectedContent: IPage,
|
|
9
9
|
isTemplateActivated: boolean,
|
|
@@ -49,22 +49,35 @@ const getInnerFields = (
|
|
|
49
49
|
);
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
const getStructuredDataInnerFields = (
|
|
52
|
+
const getStructuredDataInnerFields = (
|
|
53
|
+
innerFields: any[],
|
|
54
|
+
content: any,
|
|
55
|
+
updateValue: (value: Record<string, unknown>) => void
|
|
56
|
+
) => {
|
|
53
57
|
let fieldArr: any[] = [];
|
|
54
58
|
|
|
55
59
|
return (
|
|
56
60
|
innerFields &&
|
|
57
61
|
innerFields.map((singleFieldProps: any) => {
|
|
58
|
-
const { key } = singleFieldProps;
|
|
62
|
+
const { key, type, fields } = singleFieldProps;
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
const handleChange = (newValue: any) => {
|
|
65
|
+
updateValue({ [key]: newValue });
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const value = content && content[key];
|
|
69
|
+
|
|
70
|
+
if (type === "ConditionalField" || type === "ArrayFieldGroup") {
|
|
71
|
+
fieldArr = getStructuredDataInnerFields(fields, content, updateValue);
|
|
62
72
|
}
|
|
63
73
|
|
|
64
74
|
const fieldProps = {
|
|
75
|
+
value,
|
|
65
76
|
objKey: key,
|
|
66
|
-
fieldType:
|
|
77
|
+
fieldType: type,
|
|
67
78
|
innerFields: fieldArr,
|
|
79
|
+
field: singleFieldProps,
|
|
80
|
+
onChange: handleChange,
|
|
68
81
|
...singleFieldProps,
|
|
69
82
|
};
|
|
70
83
|
|
|
@@ -24,7 +24,9 @@ const ErrorGuard = (props: IProps) => {
|
|
|
24
24
|
const isBlocking = blockingErrors.includes(code);
|
|
25
25
|
|
|
26
26
|
const createErrorNotification = () => {
|
|
27
|
-
const
|
|
27
|
+
const errorElements = document.querySelectorAll("#error");
|
|
28
|
+
const lastErrorElement = errorElements.length - 1;
|
|
29
|
+
const domNode = errorElements[lastErrorElement] || document.getElementById("default-error");
|
|
28
30
|
|
|
29
31
|
const isMultiple = Array.isArray(text);
|
|
30
32
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import React, { useState, useEffect } from "react";
|
|
2
2
|
|
|
3
3
|
import { CheckGroup, Icon, FloatingMenu, ListTitle } from "@ax/components";
|
|
4
|
-
|
|
5
4
|
import { checkgroups } from "@ax/api";
|
|
6
|
-
|
|
7
5
|
import { areEquals, isReqOk } from "@ax/helpers";
|
|
6
|
+
import { IPageLiveStatus } from "@ax/types";
|
|
8
7
|
|
|
9
8
|
import * as S from "./style";
|
|
10
9
|
|
|
11
|
-
const Live = (
|
|
10
|
+
const Live = (props: ILiveProps): JSX.Element => {
|
|
11
|
+
const { filterItems } = props;
|
|
12
|
+
|
|
12
13
|
const filters: Array<{ name: string; value: string; title: string; icon?: string }> = [
|
|
13
14
|
{
|
|
14
15
|
name: "all",
|
|
@@ -37,9 +38,9 @@ const Live = ({ filterItems }: ILiveProps) => {
|
|
|
37
38
|
useEffect(() => {
|
|
38
39
|
getLiveStatusValues()
|
|
39
40
|
.then((items) => {
|
|
40
|
-
items.forEach((item:
|
|
41
|
+
items.forEach((item: IPageLiveStatus) => {
|
|
41
42
|
const newFilter = {
|
|
42
|
-
name: item.
|
|
43
|
+
name: item.status,
|
|
43
44
|
value: item.status,
|
|
44
45
|
title: item.title,
|
|
45
46
|
icon: item.status,
|