@griddo/ax 10.1.17 → 10.1.18
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/__tests__/components/Fields/TranslateButton/TranslateButton.test.tsx +93 -4
- package/src/api/structuredData.tsx +13 -0
- package/src/components/Fields/TranslateButton/index.tsx +31 -11
- package/src/components/Fields/TranslateButton/style.tsx +2 -1
- package/src/components/Gallery/index.tsx +1 -1
- package/src/components/MainWrapper/AppBar/index.tsx +12 -12
- package/src/components/MainWrapper/index.tsx +2 -2
- package/src/containers/StructuredData/actions.tsx +56 -0
- package/src/containers/StructuredData/constants.tsx +2 -0
- package/src/containers/StructuredData/interfaces.tsx +6 -0
- package/src/containers/StructuredData/reducer.tsx +4 -0
- package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +7 -5
- package/src/modules/StructuredData/Form/ConnectedField/index.tsx +4 -1
- package/src/modules/StructuredData/Form/index.tsx +23 -13
- package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@griddo/ax",
|
|
3
3
|
"description": "Griddo Author Experience",
|
|
4
|
-
"version": "10.1.
|
|
4
|
+
"version": "10.1.18",
|
|
5
5
|
"authors": [
|
|
6
6
|
"Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
|
|
7
7
|
"Carlos Torres <carlos.torres@secuoyas.com>",
|
|
@@ -230,5 +230,5 @@
|
|
|
230
230
|
"publishConfig": {
|
|
231
231
|
"access": "public"
|
|
232
232
|
},
|
|
233
|
-
"gitHead": "
|
|
233
|
+
"gitHead": "45dd9a08a80a8f7f7cbb6d55ce151e72a75215b3"
|
|
234
234
|
}
|
|
@@ -16,10 +16,32 @@ const mockStore = configureStore(middlewares);
|
|
|
16
16
|
const defaultProps = mock<ITranslateButtonProps>();
|
|
17
17
|
|
|
18
18
|
describe("Translate Button component rendering", () => {
|
|
19
|
-
it("should render the component", () => {
|
|
19
|
+
it("should render the component in page editor", () => {
|
|
20
20
|
const initialStore = {
|
|
21
21
|
app: { globalSettings: { autoTranslation: true } },
|
|
22
22
|
pageEditor: { editorContent: { canBeTranslated: true }, isIATranslated: false },
|
|
23
|
+
structuredData: { form: null, isIATranslated: false },
|
|
24
|
+
};
|
|
25
|
+
const store = mockStore(initialStore);
|
|
26
|
+
|
|
27
|
+
render(
|
|
28
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
29
|
+
<TranslateButton {...defaultProps} />
|
|
30
|
+
</ThemeProvider>,
|
|
31
|
+
{ store }
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const translateButtonWrapper = screen.getByTestId("translate-button-wrapper");
|
|
35
|
+
expect(translateButtonWrapper).toBeTruthy();
|
|
36
|
+
const translatedNotificationWrapper = screen.queryByTestId("translated-notification-wrapper");
|
|
37
|
+
expect(translatedNotificationWrapper).toBeFalsy();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should render the component in structured data editor", () => {
|
|
41
|
+
const initialStore = {
|
|
42
|
+
app: { globalSettings: { autoTranslation: true } },
|
|
43
|
+
pageEditor: { editorContent: null, isIATranslated: false },
|
|
44
|
+
structuredData: { form: { canBeTranslated: true }, isIATranslated: false },
|
|
23
45
|
};
|
|
24
46
|
const store = mockStore(initialStore);
|
|
25
47
|
|
|
@@ -40,6 +62,7 @@ describe("Translate Button component rendering", () => {
|
|
|
40
62
|
const initialStore = {
|
|
41
63
|
app: { globalSettings: { autoTranslation: false } },
|
|
42
64
|
pageEditor: { editorContent: { canBeTranslated: true }, isIATranslated: false },
|
|
65
|
+
structuredData: { form: null, isIATranslated: false },
|
|
43
66
|
};
|
|
44
67
|
const store = mockStore(initialStore);
|
|
45
68
|
|
|
@@ -56,10 +79,32 @@ describe("Translate Button component rendering", () => {
|
|
|
56
79
|
expect(translateButtonWrapper).toBeFalsy();
|
|
57
80
|
});
|
|
58
81
|
|
|
59
|
-
it("should not render the component if can't be translated", () => {
|
|
82
|
+
it("should not render the component if page can't be translated", () => {
|
|
60
83
|
const initialStore = {
|
|
61
84
|
app: { globalSettings: { autoTranslation: true } },
|
|
62
85
|
pageEditor: { editorContent: { canBeTranslated: false }, isIATranslated: false },
|
|
86
|
+
structuredData: { form: null, isIATranslated: false },
|
|
87
|
+
};
|
|
88
|
+
const store = mockStore(initialStore);
|
|
89
|
+
|
|
90
|
+
render(
|
|
91
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
92
|
+
<TranslateButton {...defaultProps} />
|
|
93
|
+
</ThemeProvider>,
|
|
94
|
+
{ store }
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const translateButtonWrapper = screen.queryByTestId("translate-button-wrapper");
|
|
98
|
+
const translatedNotificationWrapper = screen.queryByTestId("translated-notification-wrapper");
|
|
99
|
+
expect(translatedNotificationWrapper).toBeFalsy();
|
|
100
|
+
expect(translateButtonWrapper).toBeFalsy();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("should not render the component if structured data can't be translated", () => {
|
|
104
|
+
const initialStore = {
|
|
105
|
+
app: { globalSettings: { autoTranslation: true } },
|
|
106
|
+
pageEditor: { editorContent: null, isIATranslated: false },
|
|
107
|
+
structuredData: { form: { canBeTranslated: false }, isIATranslated: false },
|
|
63
108
|
};
|
|
64
109
|
const store = mockStore(initialStore);
|
|
65
110
|
|
|
@@ -76,10 +121,11 @@ describe("Translate Button component rendering", () => {
|
|
|
76
121
|
expect(translateButtonWrapper).toBeFalsy();
|
|
77
122
|
});
|
|
78
123
|
|
|
79
|
-
it("should render the notification if
|
|
124
|
+
it("should render the notification if page is already translated", () => {
|
|
80
125
|
const initialStore = {
|
|
81
126
|
app: { globalSettings: { autoTranslation: true } },
|
|
82
127
|
pageEditor: { editorContent: { canBeTranslated: false }, isIATranslated: true },
|
|
128
|
+
structuredData: { form: null, isIATranslated: false },
|
|
83
129
|
};
|
|
84
130
|
const store = mockStore(initialStore);
|
|
85
131
|
|
|
@@ -96,10 +142,53 @@ describe("Translate Button component rendering", () => {
|
|
|
96
142
|
expect(translateButtonWrapper).toBeFalsy();
|
|
97
143
|
});
|
|
98
144
|
|
|
99
|
-
it("should render the
|
|
145
|
+
it("should render the notification if structured data is already translated", () => {
|
|
146
|
+
const initialStore = {
|
|
147
|
+
app: { globalSettings: { autoTranslation: true } },
|
|
148
|
+
pageEditor: { editorContent: null, isIATranslated: false },
|
|
149
|
+
structuredData: { form: { canBeTranslated: false }, isIATranslated: true },
|
|
150
|
+
};
|
|
151
|
+
const store = mockStore(initialStore);
|
|
152
|
+
|
|
153
|
+
render(
|
|
154
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
155
|
+
<TranslateButton {...defaultProps} />
|
|
156
|
+
</ThemeProvider>,
|
|
157
|
+
{ store }
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const translateButtonWrapper = screen.queryByTestId("translate-button-wrapper");
|
|
161
|
+
const translatedNotificationWrapper = screen.queryByTestId("translated-notification-wrapper");
|
|
162
|
+
expect(translatedNotificationWrapper).toBeTruthy();
|
|
163
|
+
expect(translateButtonWrapper).toBeFalsy();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("should render the component if page is already translated but can be translated", () => {
|
|
100
167
|
const initialStore = {
|
|
101
168
|
app: { globalSettings: { autoTranslation: true } },
|
|
102
169
|
pageEditor: { editorContent: { canBeTranslated: true }, isIATranslated: true },
|
|
170
|
+
structuredData: { form: null, isIATranslated: false },
|
|
171
|
+
};
|
|
172
|
+
const store = mockStore(initialStore);
|
|
173
|
+
|
|
174
|
+
render(
|
|
175
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
176
|
+
<TranslateButton {...defaultProps} />
|
|
177
|
+
</ThemeProvider>,
|
|
178
|
+
{ store }
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const translateButtonWrapper = screen.getByTestId("translate-button-wrapper");
|
|
182
|
+
expect(translateButtonWrapper).toBeTruthy();
|
|
183
|
+
const translatedNotificationWrapper = screen.queryByTestId("translated-notification-wrapper");
|
|
184
|
+
expect(translatedNotificationWrapper).toBeFalsy();
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("should render the component if structured data is already translated but can be translated", () => {
|
|
188
|
+
const initialStore = {
|
|
189
|
+
app: { globalSettings: { autoTranslation: true } },
|
|
190
|
+
pageEditor: { editorContent: null, isIATranslated: false },
|
|
191
|
+
structuredData: { form: { canBeTranslated: true }, isIATranslated: true },
|
|
103
192
|
};
|
|
104
193
|
const store = mockStore(initialStore);
|
|
105
194
|
|
|
@@ -79,6 +79,11 @@ const SERVICES: { [key: string]: IServiceConfig } = {
|
|
|
79
79
|
endpoint: ["/site/", "/structured_data"],
|
|
80
80
|
method: "GET",
|
|
81
81
|
},
|
|
82
|
+
CONTENT_AI_TRANSLATION: {
|
|
83
|
+
...template,
|
|
84
|
+
endpoint: "/translations/structured_data_content/",
|
|
85
|
+
method: "POST",
|
|
86
|
+
},
|
|
82
87
|
};
|
|
83
88
|
|
|
84
89
|
const getData = (token: string | null, siteID?: number | null) => {
|
|
@@ -231,6 +236,13 @@ const getContentTypes = (siteID: number | null, lang?: number): Promise<AxiosRes
|
|
|
231
236
|
return sendRequest(SERVICES.GET_CONTENT_TYPES, null, dataHeader);
|
|
232
237
|
};
|
|
233
238
|
|
|
239
|
+
const getDataContentTranslation = async (data: any, langID: number) => {
|
|
240
|
+
const { host, endpoint } = SERVICES.CONTENT_AI_TRANSLATION;
|
|
241
|
+
SERVICES.CONTENT_AI_TRANSLATION.dynamicUrl = `${host}${endpoint}${langID}`;
|
|
242
|
+
|
|
243
|
+
return sendRequest(SERVICES.CONTENT_AI_TRANSLATION, { ...data });
|
|
244
|
+
};
|
|
245
|
+
|
|
234
246
|
export default {
|
|
235
247
|
getData,
|
|
236
248
|
getDataContent,
|
|
@@ -247,4 +259,5 @@ export default {
|
|
|
247
259
|
setDataStatusBulk,
|
|
248
260
|
getContentTypes,
|
|
249
261
|
getDataContentBulk,
|
|
262
|
+
getDataContentTranslation,
|
|
250
263
|
};
|
|
@@ -4,13 +4,25 @@ import { Icon, Modal } from "@ax/components";
|
|
|
4
4
|
import { useModal } from "@ax/hooks";
|
|
5
5
|
import { IRootState } from "@ax/types";
|
|
6
6
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
7
|
+
import { structuredDataActions } from "@ax/containers/StructuredData";
|
|
7
8
|
|
|
8
9
|
import * as S from "./style";
|
|
9
10
|
|
|
10
11
|
const TranslateButton = (props: ITranslateButtonProps): JSX.Element => {
|
|
11
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
lang,
|
|
14
|
+
autoTranslation,
|
|
15
|
+
getPageTranslation,
|
|
16
|
+
content,
|
|
17
|
+
isPageIATranslated,
|
|
18
|
+
isDataContentIATranslated,
|
|
19
|
+
setIsPageTranslated,
|
|
20
|
+
structuredDataForm,
|
|
21
|
+
getDataContentTranslation,
|
|
22
|
+
setIsContentTranslated,
|
|
23
|
+
} = props;
|
|
12
24
|
|
|
13
|
-
const
|
|
25
|
+
const canBeTranslated = !!structuredDataForm ? structuredDataForm.canBeTranslated : content.canBeTranslated;
|
|
14
26
|
|
|
15
27
|
const initialState = {
|
|
16
28
|
isLoading: false,
|
|
@@ -23,21 +35,21 @@ const TranslateButton = (props: ITranslateButtonProps): JSX.Element => {
|
|
|
23
35
|
const handleClick = async () => {
|
|
24
36
|
toggleModal();
|
|
25
37
|
setState((state) => ({ ...state, isLoading: true, error: false }));
|
|
26
|
-
const generated = await getPageTranslation(lang);
|
|
38
|
+
const generated = !!structuredDataForm ? await getDataContentTranslation(lang) : await getPageTranslation(lang);
|
|
27
39
|
setState((state) => ({ ...state, isLoading: false }));
|
|
28
40
|
if (!generated) {
|
|
29
41
|
setState((state) => ({ ...state, error: true }));
|
|
30
42
|
}
|
|
31
43
|
};
|
|
32
44
|
|
|
33
|
-
const handleClose = () =>
|
|
45
|
+
const handleClose = () => !!structuredDataForm ? setIsContentTranslated(false) : setIsPageTranslated(false);
|
|
34
46
|
|
|
35
47
|
const buttonText = state.isLoading ? "Processing..." : "Translate page with AI";
|
|
36
48
|
|
|
37
49
|
return (
|
|
38
50
|
<>
|
|
39
|
-
{
|
|
40
|
-
<S.Wrapper data-testid="translated-notification-wrapper">
|
|
51
|
+
{(isPageIATranslated || isDataContentIATranslated) && !canBeTranslated && (
|
|
52
|
+
<S.Wrapper data-testid="translated-notification-wrapper" isSmall={false}>
|
|
41
53
|
<S.NotificationContent>
|
|
42
54
|
<S.Text>This page is translated with Artificial Intelligence.</S.Text>
|
|
43
55
|
<S.IconWrapper onClick={handleClose}>
|
|
@@ -48,7 +60,7 @@ const TranslateButton = (props: ITranslateButtonProps): JSX.Element => {
|
|
|
48
60
|
)}
|
|
49
61
|
{autoTranslation && canBeTranslated ? (
|
|
50
62
|
<>
|
|
51
|
-
<S.Wrapper data-testid="translate-button-wrapper">
|
|
63
|
+
<S.Wrapper data-testid="translate-button-wrapper" isSmall={!!structuredDataForm}>
|
|
52
64
|
<S.Text>
|
|
53
65
|
Using <strong>Artificial Intelligence</strong>, you can translate the page automatically.
|
|
54
66
|
</S.Text>
|
|
@@ -89,20 +101,28 @@ export interface ITranslateButtonProps {
|
|
|
89
101
|
lang: number;
|
|
90
102
|
autoTranslation: boolean;
|
|
91
103
|
content: any;
|
|
92
|
-
|
|
104
|
+
structuredDataForm: any | null;
|
|
105
|
+
isPageIATranslated: boolean;
|
|
106
|
+
isDataContentIATranslated: boolean;
|
|
93
107
|
getPageTranslation: (langID: number) => Promise<boolean>;
|
|
94
|
-
|
|
108
|
+
getDataContentTranslation: (langID: number) => Promise<boolean>;
|
|
109
|
+
setIsPageTranslated: (isTranslated: boolean) => Promise<void>;
|
|
110
|
+
setIsContentTranslated: (isTranslated: boolean) => Promise<void>;
|
|
95
111
|
}
|
|
96
112
|
|
|
97
113
|
const mapDispatchToProps = {
|
|
98
114
|
getPageTranslation: pageEditorActions.getPageTranslation,
|
|
99
|
-
|
|
115
|
+
setIsPageTranslated: pageEditorActions.setIsTranslated,
|
|
116
|
+
getDataContentTranslation: structuredDataActions.getDataContentTranslation,
|
|
117
|
+
setIsContentTranslated: structuredDataActions.setIsTranslated,
|
|
100
118
|
};
|
|
101
119
|
|
|
102
120
|
const mapStateToProps = (state: IRootState) => ({
|
|
103
121
|
autoTranslation: state.app.globalSettings.autoTranslation,
|
|
104
122
|
content: state.pageEditor.editorContent,
|
|
105
|
-
|
|
123
|
+
isPageIATranslated: state.pageEditor.isIATranslated,
|
|
124
|
+
isDataContentIATranslated: state.structuredData.isIATranslated,
|
|
125
|
+
structuredDataForm: state.structuredData.form,
|
|
106
126
|
});
|
|
107
127
|
|
|
108
128
|
export default connect(mapStateToProps, mapDispatchToProps)(TranslateButton);
|
|
@@ -2,10 +2,11 @@ import React from "react";
|
|
|
2
2
|
import styled from "styled-components";
|
|
3
3
|
import { Button } from "@ax/components";
|
|
4
4
|
|
|
5
|
-
const Wrapper = styled.div
|
|
5
|
+
const Wrapper = styled.div<{ isSmall: boolean }>`
|
|
6
6
|
background-color: ${(p) => p.theme.color.uiBackground03};
|
|
7
7
|
padding: ${(p) => p.theme.spacing.s};
|
|
8
8
|
border-radius: ${(p) => p.theme.radii.s};
|
|
9
|
+
max-width: ${(p) => (p.isSmall ? "320px" : "auto")};
|
|
9
10
|
`;
|
|
10
11
|
|
|
11
12
|
const Text = styled.div`
|
|
@@ -29,7 +29,7 @@ const Gallery = (props: IProps): JSX.Element => {
|
|
|
29
29
|
const isGlobalTab = selectedTab === "Global";
|
|
30
30
|
const galleryScope = isLocalTab ? site.id : "global";
|
|
31
31
|
|
|
32
|
-
const validFormats = ["jpeg", "jpg", "png", "svg"];
|
|
32
|
+
const validFormats = ["jpeg", "jpg", "png", "svg", "gif"];
|
|
33
33
|
|
|
34
34
|
const galleryRef = useRef<HTMLDivElement>(null);
|
|
35
35
|
|
|
@@ -64,29 +64,29 @@ const AppBar = (props: IProps): JSX.Element => {
|
|
|
64
64
|
const getCurrentLanguage = (lang: string) =>
|
|
65
65
|
pageLanguages && pageLanguages.find((pageLang: any) => pageLang.locale === lang);
|
|
66
66
|
|
|
67
|
-
const handleLanguage = (item: any) => () => {
|
|
67
|
+
const handleLanguage = (item: any) => async () => {
|
|
68
68
|
if (!languageActions || !languageActions.setLanguage) return;
|
|
69
69
|
|
|
70
|
-
const setNewTranslation = (isNewTranslation: boolean) => {
|
|
71
|
-
languageActions.createNewTranslation && languageActions.createNewTranslation(isNewTranslation);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
70
|
const lang = {
|
|
75
71
|
locale: item.locale,
|
|
76
72
|
id: item.id,
|
|
77
73
|
};
|
|
78
74
|
|
|
75
|
+
const setNewTranslation = (isNewTranslation: boolean) => {
|
|
76
|
+
languageActions.createNewTranslation && languageActions.createNewTranslation(isNewTranslation, lang);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
79
|
languageActions.setLanguage(lang);
|
|
80
80
|
const currentLanguage = getCurrentLanguage(item.locale);
|
|
81
81
|
|
|
82
82
|
if (languageActions.getContent && currentLanguage) {
|
|
83
83
|
setNewTranslation(false);
|
|
84
84
|
const id = currentLanguage && currentLanguage.pageId ? currentLanguage.pageId : currentLanguage.navigationId;
|
|
85
|
-
currentLanguage && languageActions.getContent(id);
|
|
85
|
+
currentLanguage && (await languageActions.getContent(id));
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
if (languageActions.getDataContent && currentLanguage) {
|
|
89
|
-
currentLanguage && languageActions.getDataContent(currentLanguage.dataID);
|
|
89
|
+
currentLanguage && (await languageActions.getDataContent(currentLanguage.dataID));
|
|
90
90
|
setNewTranslation(false);
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -95,9 +95,9 @@ const AppBar = (props: IProps): JSX.Element => {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
if (pageLanguages && !getCurrentLanguage(item.locale)) {
|
|
98
|
+
languageActions.getDataContent && currentPageID && (await languageActions.getDataContent(currentPageID));
|
|
98
99
|
setNewTranslation(true);
|
|
99
100
|
languageActions.getContent && currentPageID && languageActions.getContent(currentPageID);
|
|
100
|
-
languageActions.getDataContent && currentPageID && languageActions.getDataContent(currentPageID);
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
103
|
|
|
@@ -270,10 +270,10 @@ export interface IAppBarProps {
|
|
|
270
270
|
pageLanguages?: any[];
|
|
271
271
|
languageActions?: {
|
|
272
272
|
setLanguage?(lang: { locale: string; id: number | null }): void;
|
|
273
|
-
createNewTranslation?(isNewTranslation: boolean): void;
|
|
274
|
-
getContent?(id?: number): void
|
|
275
|
-
getSiteContent?(page?: number, itemsPerPage?: number): void
|
|
276
|
-
getDataContent?(dataID: number): void
|
|
273
|
+
createNewTranslation?(isNewTranslation: boolean, lang: { locale: string; id: number }): void;
|
|
274
|
+
getContent?(id?: number): Promise<void>;
|
|
275
|
+
getSiteContent?(page?: number, itemsPerPage?: number): Promise<void>;
|
|
276
|
+
getDataContent?(dataID: number): Promise<void>;
|
|
277
277
|
} | null;
|
|
278
278
|
additionalClass?: string;
|
|
279
279
|
inversed?: boolean;
|
|
@@ -40,8 +40,8 @@ export interface IWrapperProps {
|
|
|
40
40
|
languageActions?: {
|
|
41
41
|
setLanguage?(lang: { locale: string; id: number | null }): void;
|
|
42
42
|
setIsNewTranslation?(isNewTranslation: boolean): void;
|
|
43
|
-
getContent?(id?: number): void
|
|
44
|
-
getDataContent?(dataID?: number): void
|
|
43
|
+
getContent?(id?: number): Promise<void>;
|
|
44
|
+
getDataContent?(dataID?: number): Promise<void>;
|
|
45
45
|
} | null;
|
|
46
46
|
searchAction?(query: string): void;
|
|
47
47
|
filterSearchAction?(filter: string): void;
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
SET_ERRORS,
|
|
18
18
|
SET_VALIDATED,
|
|
19
19
|
SET_CONTENT_FILTERS,
|
|
20
|
+
SET_IS_IA_TRANSLATED,
|
|
20
21
|
} from "./constants";
|
|
21
22
|
|
|
22
23
|
import {
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
ISetErrors,
|
|
33
34
|
ISetValidated,
|
|
34
35
|
ISetContentFilters,
|
|
36
|
+
ISetIsIATranslated,
|
|
35
37
|
} from "./interfaces";
|
|
36
38
|
import { prepareStructuredDataContent, getTaxonomies, filterStructuredDataByID, getTypes } from "./utils";
|
|
37
39
|
import {
|
|
@@ -115,6 +117,10 @@ function setContentFilters(contentFilters: Record<string, IStructuredDataQueryVa
|
|
|
115
117
|
return { type: SET_CONTENT_FILTERS, payload: { contentFilters } };
|
|
116
118
|
}
|
|
117
119
|
|
|
120
|
+
function setIsIATranslated(isIATranslated: boolean): ISetIsIATranslated {
|
|
121
|
+
return { type: SET_IS_IA_TRANSLATED, payload: { isIATranslated } };
|
|
122
|
+
}
|
|
123
|
+
|
|
118
124
|
function updateFormValue(valueObj: any): (dispatch: Dispatch, getState: any) => void {
|
|
119
125
|
return (dispatch, getState) => {
|
|
120
126
|
const {
|
|
@@ -138,6 +144,7 @@ function resetForm(setDefault?: boolean): (dispatch: Dispatch, getState: any) =>
|
|
|
138
144
|
dispatch(setErrors([]));
|
|
139
145
|
dispatch(setValidated(false));
|
|
140
146
|
dispatch(setCurrentDataID(null));
|
|
147
|
+
dispatch(setIsIATranslated(false));
|
|
141
148
|
};
|
|
142
149
|
}
|
|
143
150
|
|
|
@@ -561,6 +568,52 @@ function deleteError(error: IErrorItem): (dispatch: Dispatch, getState: any) =>
|
|
|
561
568
|
};
|
|
562
569
|
}
|
|
563
570
|
|
|
571
|
+
function getDataContentTranslation(langID: number): (dispatch: Dispatch, getState: any) => Promise<boolean> {
|
|
572
|
+
return async (dispatch, getState) => {
|
|
573
|
+
try {
|
|
574
|
+
const {
|
|
575
|
+
structuredData: { form },
|
|
576
|
+
} = getState();
|
|
577
|
+
|
|
578
|
+
const responseActions = {
|
|
579
|
+
handleSuccess: (data: IStructuredDataContent) => {
|
|
580
|
+
const newForm = {...data, canBeTranslated: false };
|
|
581
|
+
dispatch(setForm(newForm));
|
|
582
|
+
dispatch(setIsIATranslated(true));
|
|
583
|
+
},
|
|
584
|
+
handleError: () => console.log("Error en GetDataContentTranslation"),
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
const callback = async () => structuredData.getDataContentTranslation(form, langID);
|
|
588
|
+
|
|
589
|
+
return await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
|
|
590
|
+
} catch (e) {
|
|
591
|
+
console.log(e);
|
|
592
|
+
return false;
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
function setFormValues(values: any): (dispatch: Dispatch) => Promise<void> {
|
|
598
|
+
return async (dispatch) => {
|
|
599
|
+
try {
|
|
600
|
+
dispatch(updateForm(values));
|
|
601
|
+
} catch (e) {
|
|
602
|
+
console.log("Error", e);
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
function setIsTranslated(isTranslated: boolean): (dispatch: Dispatch) => Promise<void> {
|
|
608
|
+
return async (dispatch) => {
|
|
609
|
+
try {
|
|
610
|
+
dispatch(setIsIATranslated(isTranslated));
|
|
611
|
+
} catch (e) {
|
|
612
|
+
console.log("Error", e);
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
|
|
564
617
|
export {
|
|
565
618
|
setIsActive,
|
|
566
619
|
setCategories,
|
|
@@ -593,4 +646,7 @@ export {
|
|
|
593
646
|
validateForm,
|
|
594
647
|
deleteError,
|
|
595
648
|
setContentFilters,
|
|
649
|
+
getDataContentTranslation,
|
|
650
|
+
setFormValues,
|
|
651
|
+
setIsTranslated,
|
|
596
652
|
};
|
|
@@ -16,6 +16,7 @@ const SET_SCHEMA_VERSION: string | null = `${NAME}/SET_SCHEMA_VERSION`;
|
|
|
16
16
|
const SET_ERRORS = `${NAME}/SET_ERRORS`;
|
|
17
17
|
const SET_VALIDATED = `${NAME}/SET_VALIDATED`;
|
|
18
18
|
const SET_CONTENT_FILTERS = `${NAME}/SET_CONTENT_FILTERS`;
|
|
19
|
+
const SET_IS_IA_TRANSLATED = `${NAME}/SET_IS_IA_TRANSLATED`;
|
|
19
20
|
|
|
20
21
|
const ITEMS_PER_PAGE = 50;
|
|
21
22
|
|
|
@@ -47,4 +48,5 @@ export {
|
|
|
47
48
|
SET_ERRORS,
|
|
48
49
|
SET_VALIDATED,
|
|
49
50
|
SET_CONTENT_FILTERS,
|
|
51
|
+
SET_IS_IA_TRANSLATED
|
|
50
52
|
};
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
SET_ERRORS,
|
|
14
14
|
SET_VALIDATED,
|
|
15
15
|
SET_CONTENT_FILTERS,
|
|
16
|
+
SET_IS_IA_TRANSLATED,
|
|
16
17
|
} from "./constants";
|
|
17
18
|
|
|
18
19
|
import { IStructuredData, IStructuredDataContent, ICategory, IErrorItem, IStructuredDataQueryValues } from "@ax/types";
|
|
@@ -86,6 +87,11 @@ export interface ISetContentFilters {
|
|
|
86
87
|
payload: { contentFilters: Record<string, IStructuredDataQueryValues> | null };
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
export interface ISetIsIATranslated {
|
|
91
|
+
type: typeof SET_IS_IA_TRANSLATED;
|
|
92
|
+
payload: { isIATranslated: boolean };
|
|
93
|
+
}
|
|
94
|
+
|
|
89
95
|
export type CategoryActionsCreators = ISetCategories & ISetCurrentData;
|
|
90
96
|
|
|
91
97
|
export type StructuredDataActionsCreators = CategoryActionsCreators &
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
SET_ERRORS,
|
|
17
17
|
SET_VALIDATED,
|
|
18
18
|
SET_CONTENT_FILTERS,
|
|
19
|
+
SET_IS_IA_TRANSLATED,
|
|
19
20
|
} from "./constants";
|
|
20
21
|
|
|
21
22
|
import { StructuredDataActionsCreators } from "./interfaces";
|
|
@@ -36,6 +37,7 @@ export interface IStructuredDataState {
|
|
|
36
37
|
errors: IErrorItem[];
|
|
37
38
|
validated: boolean;
|
|
38
39
|
contentFilters: Record<string, IStructuredDataQueryValues> | null;
|
|
40
|
+
isIATranslated: boolean;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
export const initialState = {
|
|
@@ -54,6 +56,7 @@ export const initialState = {
|
|
|
54
56
|
errors: [],
|
|
55
57
|
validated: false,
|
|
56
58
|
contentFilters: null,
|
|
59
|
+
isIATranslated: false,
|
|
57
60
|
};
|
|
58
61
|
|
|
59
62
|
export function reducer(state = initialState, action: StructuredDataActionsCreators): IStructuredDataState {
|
|
@@ -74,6 +77,7 @@ export function reducer(state = initialState, action: StructuredDataActionsCreat
|
|
|
74
77
|
case SET_ERRORS:
|
|
75
78
|
case SET_VALIDATED:
|
|
76
79
|
case SET_CONTENT_FILTERS:
|
|
80
|
+
case SET_IS_IA_TRANSLATED:
|
|
77
81
|
return { ...state, ...action.payload };
|
|
78
82
|
default:
|
|
79
83
|
return state;
|
|
@@ -91,10 +91,12 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
91
91
|
action: () => saveButtonAction(),
|
|
92
92
|
};
|
|
93
93
|
|
|
94
|
-
const getNavigation = (id: number) => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
const getNavigation = (id: number): Promise<void> => {
|
|
95
|
+
return new Promise(async () => {
|
|
96
|
+
const isHeader = selectedDefault === "Headers";
|
|
97
|
+
isHeader ? setHeader(id) : setFooter(id);
|
|
98
|
+
await getValues();
|
|
99
|
+
});
|
|
98
100
|
};
|
|
99
101
|
|
|
100
102
|
const createNewTranslation = (isNewTranslation: boolean) => {
|
|
@@ -212,7 +214,7 @@ const mapDispatchToProps = {
|
|
|
212
214
|
interface IDispatchProps {
|
|
213
215
|
setHistoryPush(path: string, isEditor?: boolean): void;
|
|
214
216
|
setLanguage?(lang: { locale: string; id: number | null }): void;
|
|
215
|
-
getValues(): void
|
|
217
|
+
getValues(): Promise<void>;
|
|
216
218
|
createNavigation(navHtml?: HTMLDivElement | null): Promise<boolean>;
|
|
217
219
|
updateNavigation(navID: number, data: any, fromEditor?: boolean, navHtml?: HTMLDivElement | null): Promise<boolean>;
|
|
218
220
|
createTranslation(isNewTranslation: boolean): void;
|
|
@@ -9,7 +9,7 @@ import { getStructuredDataInnerFields } from "@ax/forms";
|
|
|
9
9
|
import * as S from "./style";
|
|
10
10
|
|
|
11
11
|
const ConnectedField = (props: IProps) => {
|
|
12
|
-
const { field, site, form, fieldKey, updateFormValue, disabled, errors, deleteError, theme } = props;
|
|
12
|
+
const { field, site, form, fieldKey, updateFormValue, disabled, errors, deleteError, theme, lang } = props;
|
|
13
13
|
|
|
14
14
|
const value = form?.content && form.content[fieldKey];
|
|
15
15
|
const error = errors.find((err: any) => err.key === field.key);
|
|
@@ -38,6 +38,7 @@ const ConnectedField = (props: IProps) => {
|
|
|
38
38
|
deleteError,
|
|
39
39
|
theme,
|
|
40
40
|
delayed: false,
|
|
41
|
+
lang: lang.id,
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
return (
|
|
@@ -57,11 +58,13 @@ interface IProps {
|
|
|
57
58
|
updateFormValue: (value: any) => void;
|
|
58
59
|
deleteError: (error: IErrorItem) => void;
|
|
59
60
|
theme: string;
|
|
61
|
+
lang: { locale: string; id: number };
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
const mapStateToProps = (state: IRootState) => ({
|
|
63
65
|
form: state.structuredData.form,
|
|
64
66
|
errors: state.structuredData.errors,
|
|
67
|
+
lang: state.app.lang,
|
|
65
68
|
});
|
|
66
69
|
|
|
67
70
|
const mapDispatchToProps = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
|
|
4
|
-
import { IDataPack, IErrorItem, INotification, IRootState, ISite } from "@ax/types";
|
|
4
|
+
import { IDataPack, IErrorItem, ILanguage, INotification, IRootState, ISite } from "@ax/types";
|
|
5
5
|
import { structuredDataActions } from "@ax/containers/StructuredData";
|
|
6
6
|
import { MainWrapper, ErrorToast, Notification, Loading } from "@ax/components";
|
|
7
7
|
import { getActivatedDataPacksIds, getDefaultTheme } from "@ax/helpers";
|
|
@@ -37,10 +37,10 @@ const Form = (props: IProps) => {
|
|
|
37
37
|
setDataStatus,
|
|
38
38
|
deleteStructuredDataContent,
|
|
39
39
|
errors,
|
|
40
|
-
validated,
|
|
41
40
|
validateForm,
|
|
42
41
|
currentStructuredDataId,
|
|
43
42
|
skipReviewOnPublish,
|
|
43
|
+
setFormValues,
|
|
44
44
|
} = props;
|
|
45
45
|
|
|
46
46
|
const [isNewStructuredData, setIsNewStructuredData] = useState(!currentStructuredDataId);
|
|
@@ -49,6 +49,15 @@ const Form = (props: IProps) => {
|
|
|
49
49
|
|
|
50
50
|
const { fields } = schema;
|
|
51
51
|
|
|
52
|
+
const fieldsTranslate = [
|
|
53
|
+
{
|
|
54
|
+
title: "",
|
|
55
|
+
type: "TranslateButton",
|
|
56
|
+
key: "translate",
|
|
57
|
+
},
|
|
58
|
+
...fields,
|
|
59
|
+
];
|
|
60
|
+
|
|
52
61
|
const activatedDataPacksIds = getActivatedDataPacksIds(activatedDataPacks);
|
|
53
62
|
const isDisabled =
|
|
54
63
|
currentStructuredData.local &&
|
|
@@ -74,8 +83,8 @@ const Form = (props: IProps) => {
|
|
|
74
83
|
}, []);
|
|
75
84
|
|
|
76
85
|
const Fields =
|
|
77
|
-
|
|
78
|
-
|
|
86
|
+
fieldsTranslate &&
|
|
87
|
+
fieldsTranslate.map((field: any, i: number) => {
|
|
79
88
|
const { type, key } = field;
|
|
80
89
|
if (key === "title") {
|
|
81
90
|
title = form?.content && form.content[key] ? form.content[key] : "";
|
|
@@ -100,17 +109,12 @@ const Form = (props: IProps) => {
|
|
|
100
109
|
const status = isNewStructuredData ? true : form.draft;
|
|
101
110
|
|
|
102
111
|
let payload: any = {
|
|
112
|
+
...form,
|
|
103
113
|
structuredData: currentStructuredData ? currentStructuredData.id : null,
|
|
104
|
-
content: form.content,
|
|
105
114
|
draft: publish === true ? false : status,
|
|
106
115
|
relatedSite: currentSite ? currentSite.id : null,
|
|
107
|
-
entity: form.entity ? form.entity : null,
|
|
108
116
|
};
|
|
109
117
|
|
|
110
|
-
if (!isNewStructuredData) {
|
|
111
|
-
payload = { ...payload, ...form };
|
|
112
|
-
}
|
|
113
|
-
|
|
114
118
|
let saved = false;
|
|
115
119
|
if (isNewStructuredData) {
|
|
116
120
|
saved = await createStructuredDataContent(payload);
|
|
@@ -137,7 +141,13 @@ const Form = (props: IProps) => {
|
|
|
137
141
|
|
|
138
142
|
const inversed = !currentSite;
|
|
139
143
|
|
|
140
|
-
const createNewTranslation = (value: boolean) =>
|
|
144
|
+
const createNewTranslation = async (value: boolean, lang: { locale: string; id: number }) => {
|
|
145
|
+
const isUsedLang = currentLanguages.find((currentLang: ILanguage) => currentLang.id === lang.id);
|
|
146
|
+
if (!isUsedLang) {
|
|
147
|
+
setFormValues({ ...form, canBeTranslated: true });
|
|
148
|
+
setIsNewStructuredData(value);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
141
151
|
|
|
142
152
|
const languageActions = {
|
|
143
153
|
setLanguage,
|
|
@@ -320,7 +330,6 @@ interface IProps {
|
|
|
320
330
|
lang: { locale: string; id: number | null };
|
|
321
331
|
activatedDataPacks: IDataPack[];
|
|
322
332
|
errors: IErrorItem[];
|
|
323
|
-
validated: boolean;
|
|
324
333
|
currentStructuredDataId: number | null;
|
|
325
334
|
skipReviewOnPublish?: boolean;
|
|
326
335
|
createStructuredDataContent: (payload: any) => Promise<boolean>;
|
|
@@ -332,6 +341,7 @@ interface IProps {
|
|
|
332
341
|
setDataStatus(id: number, status: string): Promise<boolean>;
|
|
333
342
|
deleteStructuredDataContent(id: number): Promise<boolean>;
|
|
334
343
|
validateForm(publish?: boolean): Promise<boolean>;
|
|
344
|
+
setFormValues(form: any): Promise<void>;
|
|
335
345
|
}
|
|
336
346
|
|
|
337
347
|
const mapStateToProps = (state: IRootState) => ({
|
|
@@ -348,7 +358,6 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
348
358
|
currentSite: state.sites.currentSiteInfo && state.sites.currentSiteInfo.id,
|
|
349
359
|
activatedDataPacks: state.dataPacks.activated,
|
|
350
360
|
errors: state.structuredData.errors,
|
|
351
|
-
validated: state.structuredData.validated,
|
|
352
361
|
skipReviewOnPublish: state.app.globalSettings.skipReviewOnPublish,
|
|
353
362
|
});
|
|
354
363
|
|
|
@@ -362,6 +371,7 @@ const mapDispatchToProps = {
|
|
|
362
371
|
setDataStatus: structuredDataActions.setStatusStructuredDataContent,
|
|
363
372
|
deleteStructuredDataContent: structuredDataActions.deleteStructuredDataContent,
|
|
364
373
|
validateForm: structuredDataActions.validateForm,
|
|
374
|
+
setFormValues: structuredDataActions.setFormValues,
|
|
365
375
|
};
|
|
366
376
|
|
|
367
377
|
export default connect(mapStateToProps, mapDispatchToProps)(Form);
|
|
@@ -121,7 +121,7 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
121
121
|
const isNew = currentLanguages.find((l) => l.id === language.id) ? false : true;
|
|
122
122
|
|
|
123
123
|
if (isNew) {
|
|
124
|
-
updateForm({ ...structuredData, id: null, language: id });
|
|
124
|
+
updateForm({ ...structuredData, id: null, language: id, canBeTranslated: true });
|
|
125
125
|
} else {
|
|
126
126
|
getDataContent(dataId, lang);
|
|
127
127
|
}
|