@griddo/ax 10.1.17 → 10.1.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "10.1.17",
4
+ "version": "10.1.19",
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": "313e1ffd9455748c8e4c5f5ac3357ecd174d5ba1"
233
+ "gitHead": "7b99a17e8f0cedc777f2b51bcfdbd93b540862fd"
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 it's already translated", () => {
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 component if it's already translated but can be translated", () => {
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 { lang, autoTranslation, getPageTranslation, content, isIATranslated, setIsTranslated } = props;
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 { canBeTranslated } = content;
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 = () => setIsTranslated(false);
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
- {isIATranslated && !canBeTranslated && (
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
- isIATranslated: boolean;
104
+ structuredDataForm: any | null;
105
+ isPageIATranslated: boolean;
106
+ isDataContentIATranslated: boolean;
93
107
  getPageTranslation: (langID: number) => Promise<boolean>;
94
- setIsTranslated: (isTranslated: boolean) => Promise<void>;
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
- setIsTranslated: pageEditorActions.setIsTranslated,
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
- isIATranslated: state.pageEditor.isIATranslated
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
- const isHeader = selectedDefault === "Headers";
96
- isHeader ? setHeader(id) : setFooter(id);
97
- getValues();
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
- fields &&
78
- fields.map((field: any, i: number) => {
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) => setIsNewStructuredData(value);
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
  }