@griddo/ax 11.10.26 → 11.10.28

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": "11.10.26",
4
+ "version": "11.10.28",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Diego M. Béjar <diego.bejar@secuoyas.com>",
@@ -217,5 +217,5 @@
217
217
  "publishConfig": {
218
218
  "access": "public"
219
219
  },
220
- "gitHead": "c99dbeedbc37a73271ebe02d303176b3f5aaf5d9"
220
+ "gitHead": "2538b0107483e8b1c85fad2daa8d2513e1ccaf09"
221
221
  }
@@ -1,8 +1,8 @@
1
- import React from "react";
2
1
  import { connect } from "react-redux";
3
2
 
4
- import { IDataPack, IErrorItem, ILanguage, IRootState, ISchemaField, ISite, IThemeElements } from "@ax/types";
5
3
  import { filterThemeModules, getModuleCategories } from "@ax/helpers";
4
+ import type { IDataPack, IErrorItem, ILanguage, IRootState, ISchemaField, ISite, IThemeElements } from "@ax/types";
5
+
6
6
  import Field from "../Field";
7
7
 
8
8
  import * as S from "./style";
@@ -1,20 +1,20 @@
1
- import React, { memo, useEffect } from "react";
1
+ import { memo, useEffect } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
+ import { pageEditorActions } from "@ax/containers/PageEditor";
4
5
  import {
5
- getTemplate,
6
- isModuleDisabled,
7
- slugify,
8
6
  areEqual,
9
7
  filterThemeModules,
10
- isTemplateExcludedFromTheme,
11
8
  getFormTemplate,
9
+ getTemplate,
10
+ isModuleDisabled,
11
+ isTemplateExcludedFromTheme,
12
+ slugify,
12
13
  } from "@ax/helpers";
13
- import { IRootState } from "@ax/types";
14
- import { pageEditorActions } from "@ax/containers/PageEditor";
14
+ import type { IRootState } from "@ax/types";
15
15
 
16
- import TemplateManager from "./TemplateManager";
17
16
  import Field from "./Field";
17
+ import TemplateManager from "./TemplateManager";
18
18
 
19
19
  const PageConnectedField = (props: any): JSX.Element => {
20
20
  const {
@@ -168,9 +168,12 @@ const PageConnectedField = (props: any): JSX.Element => {
168
168
  }
169
169
 
170
170
  if (isTemplate || isFormTemplate) {
171
- const template = isFormTemplate
172
- ? getFormTemplate(selectedContent[field.key].templateType)
173
- : getTemplate(selectedContent[field.key].templateType);
171
+ const templateType = selectedContent[field.key]?.templateType;
172
+ const template = isFormTemplate ? getFormTemplate(templateType) : getTemplate(templateType);
173
+
174
+ if (!template) {
175
+ return <></>;
176
+ }
174
177
 
175
178
  return (
176
179
  <TemplateManager
@@ -1,34 +1,49 @@
1
1
  import FroalaEditor from "froala-editor";
2
+
2
3
  import { getLanguageMenuHtml, getRichTextConfig, parseClassNames } from "./helpers";
3
4
  import { languages } from "./languages";
4
5
 
5
6
  const API_URL = process.env.GRIDDO_API_URL || process.env.REACT_APP_API_ENDPOINT;
6
- const richTextConfig = getRichTextConfig();
7
- const paragraphStyles = richTextConfig?.paragraphStyles ? parseClassNames(richTextConfig.paragraphStyles) : undefined;
8
- const tableStyles = richTextConfig?.tableStyles ? parseClassNames(richTextConfig.tableStyles) : undefined;
9
- const tableCellStyles = richTextConfig?.tableCellStyles ? parseClassNames(richTextConfig.tableCellStyles) : undefined;
10
7
 
11
- const miscButtons = [
12
- "underline",
13
- "textColor",
14
- "formatOLSimple",
15
- "specialCharacters",
16
- "insertHR",
17
- "alignLeft",
18
- "alignRight",
19
- "alignJustify",
20
- "outdent",
21
- "indent",
22
- "undo",
23
- "redo",
24
- "selectAll",
25
- "html",
26
- "insertTable",
27
- paragraphStyles ? "paragraphStyle" : undefined,
28
- "langDropdown",
29
- ];
8
+ // Lazy getters para evitar acceder a schemas antes de que carguen
9
+ const getRichTextConfigLazy = () => getRichTextConfig();
10
+ const getParagraphStyles = () => {
11
+ const config = getRichTextConfigLazy();
12
+ return config?.paragraphStyles ? parseClassNames(config.paragraphStyles) : undefined;
13
+ };
14
+ const getTableStyles = () => {
15
+ const config = getRichTextConfigLazy();
16
+ return config?.tableStyles ? parseClassNames(config.tableStyles) : undefined;
17
+ };
18
+ const getTableCellStyles = () => {
19
+ const config = getRichTextConfigLazy();
20
+ return config?.tableCellStyles ? parseClassNames(config.tableCellStyles) : undefined;
21
+ };
30
22
 
31
- const buttonsFull = {
23
+ const getMiscButtons = () => {
24
+ const paragraphStyles = getParagraphStyles();
25
+ return [
26
+ "underline",
27
+ "textColor",
28
+ "formatOLSimple",
29
+ "specialCharacters",
30
+ "insertHR",
31
+ "alignLeft",
32
+ "alignRight",
33
+ "alignJustify",
34
+ "outdent",
35
+ "indent",
36
+ "undo",
37
+ "redo",
38
+ "selectAll",
39
+ "html",
40
+ "insertTable",
41
+ paragraphStyles ? "paragraphStyle" : undefined,
42
+ "langDropdown",
43
+ ];
44
+ };
45
+
46
+ const getButtonsFull = () => ({
32
47
  moreText: {
33
48
  buttons: ["bold", "italic", "paragraphFormat", "formatUL", "quote", "alignCenter"],
34
49
  buttonsVisible: 6,
@@ -38,27 +53,30 @@ const buttonsFull = {
38
53
  buttonsVisible: 5,
39
54
  },
40
55
  moreMisc: {
41
- buttons: miscButtons,
56
+ buttons: getMiscButtons(),
42
57
  align: "right",
43
58
  buttonsVisible: 0,
44
59
  },
45
- };
60
+ });
46
61
 
47
- const buttons = [
48
- [
49
- "bold",
50
- "italic",
51
- "formatUL",
52
- "insertLink",
53
- "paragraphFormat",
54
- paragraphStyles ? "paragraphStyle" : undefined,
55
- "langDropdown",
56
- ],
57
- ];
62
+ const getButtons = () => {
63
+ const paragraphStyles = getParagraphStyles();
64
+ return [
65
+ [
66
+ "bold",
67
+ "italic",
68
+ "formatUL",
69
+ "insertLink",
70
+ "paragraphFormat",
71
+ paragraphStyles ? "paragraphStyle" : undefined,
72
+ "langDropdown",
73
+ ],
74
+ ];
75
+ };
58
76
 
59
- const inlineToolbar = ["langDropdown", "undo", "redo"];
77
+ const getInlineToolbar = () => ["langDropdown", "undo", "redo"];
60
78
 
61
- const wysiwygConfig = {
79
+ const getWysiwygConfig = () => ({
62
80
  key: process.env.GRIDDO_FROALA_KEY || process.env.REACT_APP_FROALA_KEY,
63
81
  // pastePlain: false,
64
82
  pasteDeniedAttrs: ["class", "id", "style", "dir"],
@@ -92,11 +110,11 @@ const wysiwygConfig = {
92
110
  imageMaxSize: 20 * 1024 * 1024,
93
111
  imageManagerLoadURL: `${API_URL}/images/wysiwyg`,
94
112
  requestWithCORS: false,
95
- paragraphStyles,
96
- tableStyles,
97
- tableCellStyles,
113
+ paragraphStyles: getParagraphStyles(),
114
+ tableStyles: getTableStyles(),
115
+ tableCellStyles: getTableCellStyles(),
98
116
  imageUploadRemoteUrls: false,
99
- };
117
+ });
100
118
 
101
119
  FroalaEditor.DefineIcon("langIcon", {
102
120
  PATH: "m12.87 15.07-2.54-2.51.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04ZM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12Zm-2.62 7 1.62-4.33L19.12 17h-3.24Z",
@@ -110,7 +128,10 @@ FroalaEditor.RegisterCommand("langDropdown", {
110
128
  undo: true,
111
129
  focus: true,
112
130
  refreshAfterCallback: true,
113
- html: () => getLanguageMenuHtml(richTextConfig?.editorLangs ? richTextConfig.editorLangs : languages),
131
+ html: () => {
132
+ const config = getRichTextConfigLazy();
133
+ return getLanguageMenuHtml(config?.editorLangs ? config.editorLangs : languages);
134
+ },
114
135
  callback: function (_cmd: any, val: string) {
115
136
  const html = this.selection.text();
116
137
  if (val !== "") {
@@ -121,4 +142,9 @@ FroalaEditor.RegisterCommand("langDropdown", {
121
142
  },
122
143
  });
123
144
 
124
- export { buttonsFull, buttons, inlineToolbar, wysiwygConfig };
145
+ export {
146
+ getButtonsFull as buttonsFull,
147
+ getButtons as buttons,
148
+ getInlineToolbar as inlineToolbar,
149
+ getWysiwygConfig as wysiwygConfig,
150
+ };
@@ -1,12 +1,15 @@
1
- import { connect } from "react-redux";
2
1
  import FroalaEditorComponent from "react-froala-wysiwyg";
3
- import FroalaEditor from "froala-editor";
4
- import { decodeEntities } from "@ax/helpers";
5
- import type { IImage, ISite, IRootState } from "@ax/types";
2
+ import { connect } from "react-redux";
3
+
6
4
  import { galleryActions } from "@ax/containers/Gallery";
5
+ import { decodeEntities } from "@ax/helpers";
6
+ import type { IImage, IRootState, ISite } from "@ax/types";
7
+
8
+ import FroalaEditor from "froala-editor";
7
9
 
8
- import { wysiwygConfig, buttons, buttonsFull, inlineToolbar } from "./config";
10
+ import { buttons, buttonsFull, inlineToolbar, wysiwygConfig } from "./config";
9
11
  import "./vendors";
12
+
10
13
  import * as S from "./style";
11
14
 
12
15
  const Wysiwyg = (props: IWysiwygProps): JSX.Element => {
@@ -36,10 +39,10 @@ const Wysiwyg = (props: IWysiwygProps): JSX.Element => {
36
39
 
37
40
  const dynamicConfig = {
38
41
  placeholderText: placeholder,
39
- toolbarButtons: inline ? inlineToolbar : full ? buttonsFull : buttons,
42
+ toolbarButtons: inline ? inlineToolbar() : full ? buttonsFull() : buttons(),
40
43
  toolbarInline: inline,
41
44
  charCounterCount: !inline,
42
- imageUpload: !!(full && !inline ),
45
+ imageUpload: !!(full && !inline),
43
46
  multiLine: !inline,
44
47
  enter: inline ? FroalaEditor.ENTER_BR : FroalaEditor.ENTER_P,
45
48
  requestHeaders: {
@@ -74,7 +77,7 @@ const Wysiwyg = (props: IWysiwygProps): JSX.Element => {
74
77
  },
75
78
  };
76
79
 
77
- const config = { ...wysiwygConfig, ...dynamicConfig };
80
+ const config = { ...wysiwygConfig(), ...dynamicConfig };
78
81
 
79
82
  return (
80
83
  <S.EditorWrapper error={error} disabled={disabled} data-testid="wysiwyg-wrapper">
@@ -1,37 +1,38 @@
1
- import { useEffect, useState, useRef } from "react";
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { withErrorBoundary } from "react-error-boundary";
2
3
  import { connect } from "react-redux";
3
4
  import type { RouteComponentProps } from "react-router-dom";
4
- import { withErrorBoundary } from "react-error-boundary";
5
5
 
6
- import type {
7
- IErrorItem,
8
- INotification,
9
- IRootState,
10
- ISavePageParams,
11
- IUserEditing,
12
- IPageLanguage,
13
- ILanguage,
14
- } from "@ax/types";
15
6
  import {
16
- MainWrapper,
17
- Loading,
7
+ CancelScheduleModal,
8
+ ErrorPage,
18
9
  ErrorToast,
19
- Notification,
10
+ Loading,
11
+ MainWrapper,
20
12
  Modal,
21
- ErrorPage,
22
- CancelScheduleModal,
23
- ScheduleModal,
24
- RestoreModal,
13
+ Notification,
25
14
  OcassionalToast,
15
+ RestoreModal,
16
+ ScheduleModal,
26
17
  } from "@ax/components";
27
- import { pageEditorActions } from "@ax/containers/PageEditor";
28
18
  import { appActions } from "@ax/containers/App";
29
19
  import { navigationActions } from "@ax/containers/Navigation";
20
+ import { pageEditorActions } from "@ax/containers/PageEditor";
30
21
  import { pageStatus } from "@ax/containers/PageEditor/interfaces";
22
+ import { dataPacksActions } from "@ax/containers/Settings/DataPacks";
31
23
  import { RouteLeavingGuard } from "@ax/guards";
24
+ import { dateToString, getDeactivatedModules, isModuleDisabled } from "@ax/helpers";
32
25
  import { useIsDirty, useModal, usePermission } from "@ax/hooks";
33
- import { isModuleDisabled, getDeactivatedModules, dateToString } from "@ax/helpers";
34
- import { dataPacksActions } from "@ax/containers/Settings/DataPacks";
26
+ import type {
27
+ IErrorItem,
28
+ ILanguage,
29
+ INotification,
30
+ IPageLanguage,
31
+ IRootState,
32
+ ISavePageParams,
33
+ IUserEditing,
34
+ } from "@ax/types";
35
+
35
36
  import { DeleteModal } from "./atoms";
36
37
  import Editor from "./Editor";
37
38
  import Preview from "./Preview";
@@ -123,9 +124,13 @@ const PageEditor = (props: IProps) => {
123
124
 
124
125
  // biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
125
126
  useEffect(() => {
126
- const { pageID, getPage, setTab, sendPagePing } = props;
127
+ const { pageID, getPage, setTab, sendPagePing, loadSchemas } = props;
127
128
  const defaultTab = "content";
128
- const handleGetPage = async () => await getPage(pageID);
129
+ const handleGetPage = async () => {
130
+ // Cargar schemas primero si no están cargados (por ejemplo si se hace F5 en la página)
131
+ await loadSchemas();
132
+ await getPage(pageID);
133
+ };
129
134
 
130
135
  setTab(defaultTab);
131
136
  resetDirty();
@@ -193,7 +198,7 @@ const PageEditor = (props: IProps) => {
193
198
  const isSaved =
194
199
  pageID && !isNewTranslation
195
200
  ? await updatePageStatus([pageID], pageStatus.UPLOAD_PENDING)
196
- : await savePage({publishPage});
201
+ : await savePage({ publishPage });
197
202
 
198
203
  if (isSaved) {
199
204
  resetDirty();
@@ -213,7 +218,7 @@ const PageEditor = (props: IProps) => {
213
218
  status: pageStatus.UPLOAD_PENDING,
214
219
  };
215
220
 
216
- const isSaved = await savePage({publishPage});
221
+ const isSaved = await savePage({ publishPage });
217
222
  if (isSaved) {
218
223
  resetDirty();
219
224
  }
@@ -247,7 +252,7 @@ const PageEditor = (props: IProps) => {
247
252
  const validated = skipReviewOnPublish ? true : await validatePage(true);
248
253
 
249
254
  if (validated) {
250
- const isSaved = await savePage({publishDraft: true});
255
+ const isSaved = await savePage({ publishDraft: true });
251
256
  if (isSaved) resetDirty();
252
257
  } else {
253
258
  setNotification({ text: errorNotificationText, type: "error" });
@@ -270,7 +275,7 @@ const PageEditor = (props: IProps) => {
270
275
  const handleCreateDraft = async () => {
271
276
  const { savePage } = props;
272
277
 
273
- const isSaved = await savePage({createDraft: true});
278
+ const isSaved = await savePage({ createDraft: true });
274
279
  if (isSaved) resetDirty();
275
280
  };
276
281
 
@@ -394,8 +399,8 @@ const PageEditor = (props: IProps) => {
394
399
 
395
400
  const isSaved = await savePage({ setToast });
396
401
  if (isSaved) {
397
- resetDirty();
398
- setToastMsg(null);
402
+ resetDirty();
403
+ setToastMsg(null);
399
404
  }
400
405
  };
401
406
 
@@ -561,11 +566,11 @@ const PageEditor = (props: IProps) => {
561
566
  : [{ name: "view", text: "Preview mode" }];
562
567
 
563
568
  const handleSelectedTab = async (tab: string) => {
564
- if(tab === "view" && (!isPublished || isDraft)){
569
+ if (tab === "view" && (!isPublished || isDraft)) {
565
570
  handleSavePage(setToastMsg);
566
571
  }
567
572
  setSelectedTab(tab);
568
- }
573
+ };
569
574
 
570
575
  const tabsPreview = {
571
576
  icons: tabIcons,
@@ -710,9 +715,8 @@ const PageEditor = (props: IProps) => {
710
715
  {isOpen && (
711
716
  <S.ModalContent>
712
717
  <p>
713
- <strong>{userEditing?.name}</strong> is currently working on this page. You can preview
714
- the page but <strong>you cannot make changes to it</strong> until {userEditing?.name}{" "}
715
- leaves the page.
718
+ <strong>{userEditing?.name}</strong> is currently working on this page. You can preview the page but{" "}
719
+ <strong>you cannot make changes to it</strong> until {userEditing?.name} leaves the page.
716
720
  </p>
717
721
  </S.ModalContent>
718
722
  )}
@@ -822,6 +826,7 @@ const mapDispatchToProps = {
822
826
  updatePageStatus: pageEditorActions.updatePageStatus,
823
827
  setHistoryPush: appActions.setHistoryPush,
824
828
  setLanguage: appActions.setLanguage,
829
+ loadSchemas: appActions.loadSchemas,
825
830
  createNewTranslation: pageEditorActions.createNewTranslation,
826
831
  setTab: pageEditorActions.setTab,
827
832
  getSiteDataPackbyTemplate: dataPacksActions.getSiteDataPackbyTemplate,
@@ -838,12 +843,18 @@ const mapDispatchToProps = {
838
843
 
839
844
  interface IPageEditorDispatchProps {
840
845
  getPage(pageID?: number): Promise<void>;
841
- savePage(data?: { createDraft?: boolean; publishPage?: { status: string }; publishDraft?: boolean; setToast?: (msg: string) => void }): Promise<boolean>;
846
+ savePage(data?: {
847
+ createDraft?: boolean;
848
+ publishPage?: { status: string };
849
+ publishDraft?: boolean;
850
+ setToast?: (msg: string) => void;
851
+ }): Promise<boolean>;
842
852
  deletePage(params?: ISavePageParams): Promise<boolean>;
843
853
  validatePage(publish?: boolean): Promise<boolean>;
844
854
  updatePageStatus(id: number[], status: string): Promise<boolean>;
845
855
  setHistoryPush(path: string, isEditor: boolean): void;
846
856
  setLanguage(lang: { locale: string; id: number | null }): void;
857
+ loadSchemas(): Promise<boolean>;
847
858
  createNewTranslation(isNewTranslation: boolean): void;
848
859
  setTab(tab: string): void;
849
860
  getSiteDataPackbyTemplate(templateType: string): void;
@@ -7,7 +7,6 @@ import { dataPacksActions } from "@ax/containers/Settings/DataPacks";
7
7
  import { sitesActions } from "@ax/containers/Sites";
8
8
  import { structuredDataActions } from "@ax/containers/StructuredData";
9
9
  import { usersActions } from "@ax/containers/Users";
10
- import { schemasService } from "@ax/services";
11
10
  import type { IGetRoles, ILanguage, IRootState, ISite } from "@ax/types";
12
11
 
13
12
  import SitesList from "./SitesList";
@@ -35,7 +34,6 @@ const Sites = (props: ISitesProps): JSX.Element => {
35
34
 
36
35
  // Cargar schemas primero (después del login)
37
36
  await loadSchemas();
38
- console.log("------------SCHEMAS LOADED-----------");
39
37
 
40
38
  setCurrentSiteInfo(null);
41
39
  updateCurrentSearch("");