@griddo/ax 11.10.23 → 11.10.24

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.
Files changed (58) hide show
  1. package/config/griddo-config/index.js +1 -0
  2. package/package.json +2 -2
  3. package/src/Style/index.tsx +10 -8
  4. package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +10 -8
  5. package/src/__tests__/components/ConfigPanel/Form/ConnectedField/PageConnectedField/PageConnectedField.test.tsx +86 -8
  6. package/src/__tests__/components/SideModal/SideModal.test.tsx +64 -0
  7. package/src/__tests__/hooks/useSchemas.test.tsx +224 -0
  8. package/src/__tests__/services/SchemasService.test.ts +135 -0
  9. package/src/api/schemas.tsx +11 -1
  10. package/src/components/ConfigPanel/GlobalPageForm/index.tsx +11 -17
  11. package/src/components/Fields/Wysiwyg/helpers.tsx +14 -4
  12. package/src/components/Loader/components/Dots.js +4 -5
  13. package/src/components/PageFinder/index.tsx +15 -9
  14. package/src/components/ResizePanel/index.tsx +13 -3
  15. package/src/components/ResizePanel/style.tsx +2 -9
  16. package/src/containers/App/actions.tsx +96 -24
  17. package/src/containers/App/constants.tsx +7 -0
  18. package/src/containers/App/interfaces.tsx +26 -8
  19. package/src/containers/App/reducer.tsx +24 -9
  20. package/src/containers/Sites/actions.tsx +49 -49
  21. package/src/forms/editor.tsx +4 -3
  22. package/src/helpers/index.tsx +76 -94
  23. package/src/helpers/schemas.tsx +144 -36
  24. package/src/helpers/structuredData.tsx +36 -7
  25. package/src/helpers/themes.tsx +26 -8
  26. package/src/hooks/index.tsx +5 -0
  27. package/src/hooks/useSchemas.ts +151 -0
  28. package/src/locales/en-US.ts +1 -0
  29. package/src/locales/es-ES.ts +1 -0
  30. package/src/modules/Analytics/GroupPanel/index.tsx +9 -6
  31. package/src/modules/Analytics/GroupPanel/utils.tsx +12 -28
  32. package/src/modules/Content/PageItem/index.tsx +33 -36
  33. package/src/modules/Content/index.tsx +34 -30
  34. package/src/modules/Content/utils.tsx +16 -12
  35. package/src/modules/Forms/FormEditor/index.tsx +13 -14
  36. package/src/modules/FramePreview/index.tsx +8 -8
  37. package/src/modules/GlobalEditor/index.tsx +57 -42
  38. package/src/modules/MediaGallery/ImageModal/index.tsx +15 -9
  39. package/src/modules/MediaGallery/ImageModal/style.tsx +16 -1
  40. package/src/modules/PublicPreview/index.tsx +4 -3
  41. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +4 -5
  42. package/src/modules/Settings/Globals/index.tsx +10 -11
  43. package/src/modules/Sites/index.tsx +13 -5
  44. package/src/modules/StructuredData/Form/index.tsx +25 -29
  45. package/src/modules/StructuredData/StructuredDataList/OptionTable/index.tsx +15 -6
  46. package/src/modules/StructuredData/StructuredDataList/index.tsx +22 -14
  47. package/src/modules/StructuredData/StructuredDataList/utils.tsx +12 -11
  48. package/src/schemas/index.tsx +5 -4
  49. package/src/schemas/pages/Page.ts +308 -0
  50. package/src/schemas/pages/index.ts +9 -0
  51. package/src/services/SchemasService.ts +240 -0
  52. package/src/services/index.ts +9 -0
  53. package/src/types/index.tsx +48 -39
  54. package/tsconfig.paths.json +1 -0
  55. package/src/schemas/pages/Page.tsx +0 -301
  56. package/src/schemas/pages/index.tsx +0 -5
  57. /package/src/schemas/pages/{FormPage.tsx → FormPage.ts} +0 -0
  58. /package/src/schemas/pages/{GlobalPage.tsx → GlobalPage.ts} +0 -0
@@ -1,17 +1,35 @@
1
- import { IDataPack, IGriddoTheme, ITemplateOption, IThemeElements } from "@ax/types";
2
- import { config } from "components";
3
1
  import { getSchema } from "@ax/helpers";
4
-
5
- const themes = config.schemas.config.themes;
2
+ import { schemasService } from "@ax/services";
3
+ import type { IDataPack, IGriddoTheme, ITemplateOption, IThemeElements } from "@ax/types";
6
4
 
7
5
  const getDefaultTheme = (): string => {
8
- const defaultTheme = (themes as IGriddoTheme[]).find((theme) => theme.default);
9
- const theme = defaultTheme ? defaultTheme.value : themes[0].value;
10
- return theme;
6
+ if (!schemasService.isLoaded()) {
7
+ return "NON-THEME-SELECTED";
8
+ }
9
+
10
+ try {
11
+ const themes = schemasService.getSchemas().config.themes;
12
+ const defaultTheme = (themes as IGriddoTheme[]).find((theme) => theme.default);
13
+ const theme = defaultTheme ? defaultTheme.value : themes[0].value;
14
+ return theme || "NON-THEME-SELECTED";
15
+ } catch (e) {
16
+ console.error(`[helpers/themes] getDefaultTheme failed to get schemas:`, e);
17
+ return "NON-THEME-SELECTED";
18
+ }
11
19
  };
12
20
 
13
21
  const getThemeElements = (theme: string): IThemeElements | undefined => {
14
- return (themes as IGriddoTheme[]).find((griddoTheme) => griddoTheme.value === theme)?.elements;
22
+ if (!schemasService.isLoaded()) {
23
+ return { include: {}, exclude: {} };
24
+ }
25
+
26
+ try {
27
+ const themes = schemasService.getSchemas().config.themes;
28
+ return (themes as IGriddoTheme[]).find((griddoTheme) => griddoTheme.value === theme)?.elements;
29
+ } catch (e) {
30
+ console.error(`[helpers/themes] getThemeElements failed to get schemas:`, e);
31
+ return { include: {}, exclude: {} };
32
+ }
15
33
  };
16
34
 
17
35
  const filterThemeModules = (themeElements: IThemeElements | null, elements: string[]): string[] => {
@@ -7,9 +7,11 @@ import { useHandleClickOutside, useModal, useToast } from "./modals";
7
7
  import { useNetworkStatus } from "./network";
8
8
  import { useResizable } from "./resize";
9
9
  import { useGlobalPermission, usePermission } from "./users";
10
+ import { useDefaultTheme, useSchemas, useSchemasUI, useThemes } from "./useSchemas";
10
11
  import { useWindowSize } from "./window";
11
12
 
12
13
  export {
14
+ useDefaultTheme,
13
15
  useModal,
14
16
  useHandleClickOutside,
15
17
  useDebounce,
@@ -30,5 +32,8 @@ export {
30
32
  useOnMessageReceivedFromIframe,
31
33
  useOnMessageReceivedFromOutside,
32
34
  useNetworkStatus,
35
+ useSchemas,
36
+ useSchemasUI,
37
+ useThemes,
33
38
  type IBulkSelectedItems,
34
39
  };
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Hooks para acceder a los schemas del sistema.
3
+ *
4
+ * Este módulo proporciona una serie de hooks personalizados que facilitan el acceso
5
+ * a los schemas de la instancia.
6
+ *
7
+ * Hooks disponibles:
8
+ * - useSchemas: Hook principal que carga y proporciona acceso a todos los schemas
9
+ * - useSchemasUI: Hook especializado para acceder solo a los schemas de UI (modules, components, templates)
10
+ * - useThemes: Hook para obtener la lista de themes disponibles
11
+ * - useDefaultTheme: Hook para obtener el theme por defecto configurado en la instancia
12
+ */
13
+
14
+ import { useEffect, useMemo } from "react";
15
+ import { useDispatch, useSelector } from "react-redux";
16
+
17
+ import { loadSchemas } from "@ax/containers/App/actions";
18
+ import { type ISchemas, type ISchemasConfig, type IUISchemas, schemasService } from "@ax/services";
19
+ import type { IRootState } from "@ax/types";
20
+
21
+ /**
22
+ * Hook para acceder a todos los schemas.
23
+ * Carga automáticamente los schemas si no están disponibles.
24
+ *
25
+ * @example
26
+ * const { schemas, isLoading, error } = useSchemas();
27
+ *
28
+ * if (isLoading) return <Loader />;
29
+ * if (error) return <Error message={error} />;
30
+ *
31
+ * const modules = schemas.ui.modules;
32
+ */
33
+ const useSchemas = (): UseSchemasResult => {
34
+ const dispatch = useDispatch();
35
+ const { schemasLoading, schemasError } = useSelector((state: IRootState) => state.app);
36
+
37
+ // Este useEffect despacha la acción loadSchemas() para cargar los schemas
38
+ // globales si aún no están disponibles en el servicio.
39
+ useEffect(() => {
40
+ dispatch(loadSchemas());
41
+ }, [dispatch]);
42
+
43
+ let schemas: ISchemas | null = null;
44
+ const isLoaded = schemasService.isLoaded();
45
+
46
+ if (isLoaded) {
47
+ try {
48
+ schemas = schemasService.getSchemas();
49
+ } catch (e) {
50
+ console.error(`[useSchemas] isLoaded() returned true but getSchemas() failed:`, e);
51
+ schemas = null;
52
+ }
53
+ }
54
+
55
+ return {
56
+ schemas,
57
+ isLoading: schemasLoading,
58
+ error: schemasError,
59
+ };
60
+ };
61
+
62
+ /**
63
+ * Hook para acceder solo a los schemas de UI (modules, components, templates).
64
+ *
65
+ * @example
66
+ * const { schemas, isLoading } = useSchemasUI();
67
+ *
68
+ * if (isLoading || !schemas) return <Loader />;
69
+ *
70
+ * const moduleSchema = schemas.modules["BasicModule"];
71
+ */
72
+ const useSchemasUI = (): UseSchemasUIResult => {
73
+ const { schemas, isLoading, error } = useSchemas();
74
+
75
+ return {
76
+ schemas: schemas?.ui ?? null,
77
+ isLoading,
78
+ error,
79
+ };
80
+ };
81
+
82
+ /**
83
+ * Hook para acceder a los themes disponibles.
84
+ *
85
+ * @example
86
+ * const { themes, isLoading } = useThemes();
87
+ *
88
+ * if (isLoading || !themes) return <Loader />;
89
+ *
90
+ * const defaultTheme = themes.find(t => t.default);
91
+ */
92
+ const useThemes = (): UseThemesResult => {
93
+ const { schemas, isLoading, error } = useSchemas();
94
+
95
+ return {
96
+ themes: schemas?.config.themes ?? [],
97
+ isLoading,
98
+ error,
99
+ };
100
+ };
101
+
102
+ /**
103
+ * Hook para obtener el theme por defecto.
104
+ * Espera a que los schemas estén cargados antes de retornar el theme.
105
+ *
106
+ * @example
107
+ * const { defaultTheme, isLoading } = useDefaultTheme();
108
+ *
109
+ * if (isLoading) return <Loader />;
110
+ *
111
+ * // Usar defaultTheme
112
+ */
113
+ const useDefaultTheme = (): { defaultTheme: string; isLoading: boolean; error: string | null } => {
114
+ const { schemas, isLoading, error } = useSchemas();
115
+
116
+ const defaultTheme = useMemo(() => {
117
+ if (!schemas) {
118
+ return "NON-THEME-SELECTED";
119
+ }
120
+
121
+ const themes = schemas.config.themes;
122
+ const defaultThemeObj = (themes as any[]).find((theme: any) => theme.default);
123
+ return defaultThemeObj ? defaultThemeObj.value : themes[0]?.value || "NON-THEME-SELECTED";
124
+ }, [schemas]);
125
+
126
+ return {
127
+ defaultTheme,
128
+ isLoading,
129
+ error,
130
+ };
131
+ };
132
+
133
+ interface UseSchemasResult {
134
+ schemas: ISchemas | null;
135
+ isLoading: boolean;
136
+ error: string | null;
137
+ }
138
+
139
+ interface UseSchemasUIResult {
140
+ schemas: IUISchemas | null;
141
+ isLoading: boolean;
142
+ error: string | null;
143
+ }
144
+
145
+ interface UseThemesResult {
146
+ themes: ISchemasConfig["themes"] | [];
147
+ isLoading: boolean;
148
+ error: string | null;
149
+ }
150
+
151
+ export { useSchemas, useSchemasUI, useThemes, useDefaultTheme };
@@ -15,6 +15,7 @@ export const enUS = {
15
15
  search: "Search",
16
16
  noResults: "No results found",
17
17
  copyUrl: "Copy URL",
18
+ filterByPageType: "Filter by page type",
18
19
  },
19
20
  fields: {
20
21
  tags: {
@@ -15,6 +15,7 @@ export const esES = {
15
15
  search: "Buscar",
16
16
  noResults: "No se encontraron resultados",
17
17
  copyUrl: "Copiar URL",
18
+ filterByPageType: "Filtrar por tipo de página",
18
19
  },
19
20
  fields: {
20
21
  tags: {
@@ -1,12 +1,14 @@
1
- import React, { useState, useEffect } from "react";
1
+ import { useEffect, useState } from "react";
2
2
 
3
- import { IDimension, IDimensionsGroup } from "@ax/types";
4
- import { FloatingPanel, Button, FieldsBehavior, CheckGroup, RadioGroup } from "@ax/components";
3
+ import { Button, CheckGroup, FieldsBehavior, FloatingPanel, RadioGroup } from "@ax/components";
5
4
  import { splitAndTrim } from "@ax/helpers";
5
+ import { useSchemasUI } from "@ax/hooks";
6
+ import type { IDimension, IDimensionsGroup } from "@ax/types";
6
7
 
7
- import * as S from "./style";
8
8
  import { getTemplateOptions } from "./utils";
9
9
 
10
+ import * as S from "./style";
11
+
10
12
  const GroupPanel = (props: IProps): JSX.Element => {
11
13
  const { isOpen, toggleModal, item, setGroupItem, dimensions } = props;
12
14
 
@@ -16,7 +18,8 @@ const GroupPanel = (props: IProps): JSX.Element => {
16
18
  const [hasTemplate, setHasTemplate] = useState(false);
17
19
  const [errors, setErrors] = useState({ name: false });
18
20
 
19
- const templates = getTemplateOptions();
21
+ const { schemas } = useSchemasUI();
22
+ const templates = getTemplateOptions(schemas);
20
23
  const resetState = () => {
21
24
  setName(item?.name || "");
22
25
  setErrors({ name: false });
@@ -89,7 +92,7 @@ const GroupPanel = (props: IProps): JSX.Element => {
89
92
  value: name,
90
93
  title: name,
91
94
  };
92
- return dimensionOptions.push(option);
95
+ dimensionOptions.push(option);
93
96
  });
94
97
 
95
98
  const setDimensions = (selection: any) => {
@@ -1,31 +1,15 @@
1
- import { config } from "components";
2
-
3
- const schemas = config.schemas.ui;
4
-
5
- const getTemplateOptions = (): ITemplateOption[] => {
6
- const { templates } = schemas;
7
- const templatesOptionsValues: ITemplateOption[] = [];
8
-
9
- Object.keys(templates).forEach((schema: string) => {
10
- const currSchema = templates[schema];
11
- const { component, displayName } = currSchema;
12
-
13
- !!currSchema.type &&
14
- ["list", "detail"].includes(currSchema.type.mode) &&
15
- templatesOptionsValues.push({
16
- name: component,
17
- title: displayName,
18
- value: component,
19
- });
20
- });
21
-
22
- return templatesOptionsValues;
1
+ import type { IUISchemas } from "@ax/services";
2
+
3
+ const getTemplateOptions = (schemas: IUISchemas | null) => {
4
+ if (!schemas) return [];
5
+
6
+ return Object.values(schemas.templates)
7
+ .filter((template) => template.type?.mode && ["list", "detail"].includes(template.type.mode))
8
+ .map(({ component, displayName }) => ({
9
+ name: component,
10
+ title: displayName,
11
+ value: component,
12
+ }));
23
13
  };
24
14
 
25
- interface ITemplateOption {
26
- name: string;
27
- title: string;
28
- value: string;
29
- }
30
-
31
15
  export { getTemplateOptions };
@@ -1,44 +1,42 @@
1
1
  import React, { useRef, useState } from "react";
2
2
  import { connect } from "react-redux";
3
- import { config } from "components";
4
- import { useTheme } from "styled-components";
5
3
 
6
- import { useAdaptiveText, useModal, usePermission } from "@ax/hooks";
7
- import { getHumanLastModifiedDate, getScheduleFormatDate, getTemplateDisplayName, slugify } from "@ax/helpers";
8
- import {
9
- IPage,
10
- ISite,
11
- ISavePageParams,
12
- ICheck,
13
- IColumn,
14
- IPageLanguage,
15
- IDataPack,
16
- ILanguage,
17
- ISchemaField,
18
- IRootState,
19
- } from "@ax/types";
20
- import { pageStatus, ISetCurrentPageIDAction } from "@ax/containers/PageEditor/interfaces";
21
4
  import {
5
+ CategoryCell,
22
6
  CheckField,
7
+ ErrorToast,
23
8
  FieldsBehavior,
9
+ Flag,
24
10
  FloatingMenu,
25
11
  Icon,
26
- Flag,
27
12
  LanguageMenu,
28
13
  Modal,
29
14
  Tag,
30
15
  Tooltip,
31
- CategoryCell,
32
- ErrorToast,
33
16
  } from "@ax/components";
34
- import { pageEditorActions } from "@ax/containers/PageEditor";
35
17
  import { appActions } from "@ax/containers/App";
18
+ import { pageEditorActions } from "@ax/containers/PageEditor";
19
+ import { type ISetCurrentPageIDAction, pageStatus } from "@ax/containers/PageEditor/interfaces";
20
+ import { getHumanLastModifiedDate, getScheduleFormatDate, getTemplateDisplayName, slugify } from "@ax/helpers";
21
+ import { useAdaptiveText, useModal, usePermission, useSchemasUI } from "@ax/hooks";
22
+ import type {
23
+ ICheck,
24
+ IColumn,
25
+ IDataPack,
26
+ ILanguage,
27
+ IPage,
28
+ IPageLanguage,
29
+ IRootState,
30
+ ISavePageParams,
31
+ ISchemaField,
32
+ ISite,
33
+ } from "@ax/types";
36
34
 
37
- import { DeleteModal, CopyModal } from "../atoms";
35
+ import { useTheme } from "styled-components";
38
36
 
39
- import * as S from "./style";
37
+ import { CopyModal, DeleteModal } from "../atoms";
40
38
 
41
- const schemas = config.schemas.ui;
39
+ import * as S from "./style";
42
40
 
43
41
  const PageItem = (props: IPageItemProps): JSX.Element => {
44
42
  const {
@@ -93,6 +91,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
93
91
  } = page;
94
92
 
95
93
  const displayName = getTemplateDisplayName(templateId);
94
+ const { schemas } = useSchemasUI();
96
95
 
97
96
  const initValue = { title: "", slug: "" };
98
97
  const [site, setSite] = useState(null);
@@ -118,7 +117,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
118
117
  const isAllowedToDeletePublishedPage = usePermission("content.deletePublishedPages");
119
118
  const isAllowedToEditContentPage = usePermission("content.editContentPages");
120
119
 
121
- const currentTemplateDataPacks = schemas.templates[templateId].dataPacks;
120
+ const currentTemplateDataPacks = schemas?.templates[templateId].dataPacks;
122
121
 
123
122
  const isCopyable = !currentTemplateDataPacks;
124
123
  const isGlobal = origin === "GLOBAL";
@@ -265,15 +264,13 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
265
264
  const getCurrentPageLanguages = () => {
266
265
  const languages: ILanguage[] = [];
267
266
 
268
- pageLanguages.forEach(
269
- (pageLang: IPageLanguage) =>
270
- siteLanguages &&
271
- siteLanguages.forEach((siteLang) => {
272
- if (siteLang.id === pageLang.languageId) {
273
- languages.push(siteLang);
274
- }
275
- }),
276
- );
267
+ pageLanguages.forEach((pageLang) => {
268
+ siteLanguages?.forEach((siteLang) => {
269
+ if (siteLang.id === pageLang.languageId) {
270
+ languages.push(siteLang);
271
+ }
272
+ });
273
+ });
277
274
 
278
275
  return languages;
279
276
  };
@@ -313,7 +310,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
313
310
 
314
311
  if (!isTemplateActivated || isGlobal || !isAllowedToCreatePages) {
315
312
  const pageLanguagesIDs = pageLanguages.map((language: IPageLanguage) => language.languageId);
316
- availableLanguages = siteLanguages && siteLanguages.filter((language) => pageLanguagesIDs.includes(language.id));
313
+ availableLanguages = siteLanguages?.filter((language) => pageLanguagesIDs.includes(language.id));
317
314
  }
318
315
 
319
316
  const languageMenu = () => (
@@ -495,7 +492,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
495
492
  return <React.Fragment key={col.key} />;
496
493
  }
497
494
 
498
- const type: any = structuredDataContent && structuredDataContent[col.key];
495
+ const type: any = structuredDataContent?.[col.key];
499
496
 
500
497
  if (typeof type !== "object") {
501
498
  return (
@@ -2,10 +2,6 @@ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react
2
2
  import { connect } from "react-redux";
3
3
  import { useHistory, useLocation } from "react-router-dom";
4
4
 
5
- import { config } from "components";
6
-
7
- const schemas = config.schemas.ui;
8
-
9
5
  import {
10
6
  EmptyState,
11
7
  ErrorToast,
@@ -18,23 +14,31 @@ import {
18
14
  Toast,
19
15
  } from "@ax/components";
20
16
  import { appActions } from "@ax/containers/App";
21
- import { IError } from "@ax/containers/App/reducer";
17
+ import type { IError } from "@ax/containers/App/reducer";
22
18
  import { integrationsActions } from "@ax/containers/Integrations";
23
19
  import { navigationActions } from "@ax/containers/Navigation/Defaults";
24
20
  import { pageEditorActions } from "@ax/containers/PageEditor";
25
21
  import { INITIAL_TEMPLATE } from "@ax/containers/PageEditor/constants";
26
22
  import {
27
- ISetCurrentPageIDAction,
28
- ISetCurrentPageNameAction,
29
- ISetCurrentPageStatusAction,
23
+ type ISetCurrentPageIDAction,
24
+ type ISetCurrentPageNameAction,
25
+ type ISetCurrentPageStatusAction,
30
26
  pageStatus,
31
27
  } from "@ax/containers/PageEditor/interfaces";
32
28
  import { dataPacksActions } from "@ax/containers/Settings";
33
29
  import { sitesActions } from "@ax/containers/Sites";
34
30
  import { structuredDataActions } from "@ax/containers/StructuredData";
35
31
  import { getMaxColumns, isGlobalStructuredData, isStructuredDataFromPage, updateColumns } from "@ax/helpers";
36
- import { useBulkSelection, useCategoryColors, useModal, usePermission, useToast, useWindowSize } from "@ax/hooks";
37
32
  import {
33
+ useBulkSelection,
34
+ useCategoryColors,
35
+ useModal,
36
+ usePermission,
37
+ useSchemasUI,
38
+ useToast,
39
+ useWindowSize,
40
+ } from "@ax/hooks";
41
+ import type {
38
42
  ICheck,
39
43
  IDataPack,
40
44
  IEmptyStateProps,
@@ -64,7 +68,6 @@ import { useFilterQuery, useSortedListStatus } from "./hooks";
64
68
  import OptionTable from "./OptionTable";
65
69
  import PageImporter from "./PageImporter";
66
70
  import PageItem from "./PageItem";
67
- import * as S from "./style";
68
71
  import {
69
72
  filterByStatus,
70
73
  getColumns,
@@ -74,6 +77,8 @@ import {
74
77
  getSortedListStatus,
75
78
  } from "./utils";
76
79
 
80
+ import * as S from "./style";
81
+
77
82
  // TODO: Make this monster manageable
78
83
  const Content = (props: IProps): JSX.Element => {
79
84
  const {
@@ -169,23 +174,22 @@ const Content = (props: IProps): JSX.Element => {
169
174
  const baseFilters = ["unique-pages", "basic", "list", "static"];
170
175
  const isStructuredData = !baseFilters.includes(filter) && !checkFromPage;
171
176
  const isGlobalPages = !baseFilters.includes(filter) && checkFromPage;
172
- const isDataEditable = !isStructuredData || (currentStructuredData && currentStructuredData.editable);
177
+ const isDataEditable = (!isStructuredData || currentStructuredData?.editable) ?? null;
173
178
  const isDataPrivate = currentStructuredData?.private || false;
174
179
  const isDataExportable = currentStructuredData?.exportable || false;
175
180
 
176
- const pagesIds = currentSitePages && currentSitePages.map((page: any) => page.id);
177
- const dataIds = currentDataContent && currentDataContent.map((data: any) => data.id);
181
+ const pagesIds = currentSitePages?.map((page) => page.id);
182
+ const dataIds = currentDataContent?.map((data) => data.id);
178
183
  const contentIds = isStructuredData ? dataIds : pagesIds;
179
- const currentSitePagesTemplatesIds = allSitePages && allSitePages.map((page: any) => page.templateId);
184
+ const currentSitePagesTemplatesIds = allSitePages?.map((page) => page.templateId);
180
185
  const currentSitesByLang = sitesByLang?.filter(
181
186
  (site: ISite) =>
182
187
  user?.isSuperAdmin ||
183
188
  user?.roles.find((siteRole: ISiteRoles) => siteRole.siteId === site.id || siteRole.siteId === "all"),
184
189
  );
185
- const categoryColumns: ISchemaField[] =
186
- currentStructuredData && currentStructuredData.schema
187
- ? currentStructuredData.schema.fields.filter((field: ISchemaField) => field.showList)
188
- : [];
190
+ const categoryColumns: ISchemaField[] = currentStructuredData?.schema
191
+ ? currentStructuredData.schema.fields.filter((field: ISchemaField) => field.showList)
192
+ : [];
189
193
 
190
194
  const [page, setPage] = useState(firstPage);
191
195
  const lastPage = Math.ceil(totalItems / itemsPerPage);
@@ -369,7 +373,7 @@ const Content = (props: IProps): JSX.Element => {
369
373
  }, [filterValues]);
370
374
 
371
375
  useEffect(() => {
372
- const errorCode = (error && error.code) || undefined;
376
+ const errorCode = error?.code ?? undefined;
373
377
  if (errorCode === 400 && errorRef.current) {
374
378
  errorRef.current.scrollIntoView({
375
379
  behavior: "smooth",
@@ -418,11 +422,11 @@ const Content = (props: IProps): JSX.Element => {
418
422
 
419
423
  const addNewPage = () => {
420
424
  const selectedTemplate = schemas?.templates[template];
421
- const { singleInstance, displayName } = selectedTemplate;
425
+ const { singleInstance, displayName } = selectedTemplate || {};
422
426
  const isAlreadyActive = currentSitePagesTemplatesIds.includes(template);
423
427
 
424
428
  if (singleInstance && isAlreadyActive) {
425
- setTemplateInstanceError({ error: true, templateName: displayName });
429
+ setTemplateInstanceError({ error: true, templateName: displayName || "" });
426
430
  toggleNewModal();
427
431
  } else {
428
432
  setTemplateInstanceError({ error: false, templateName: "" });
@@ -599,7 +603,7 @@ const Content = (props: IProps): JSX.Element => {
599
603
 
600
604
  const goToData = (item: any) => {
601
605
  const isFromPage = !!item.relatedPage;
602
- let path;
606
+ let path: string;
603
607
 
604
608
  if (isFromPage) {
605
609
  setCurrentPageID(item.relatedPage.pageId);
@@ -613,8 +617,7 @@ const Content = (props: IProps): JSX.Element => {
613
617
  };
614
618
 
615
619
  const mapStructuredData = () =>
616
- currentDataContent &&
617
- currentDataContent.map((item: any) => {
620
+ currentDataContent?.map((item) => {
618
621
  const handleClick = () => goToData(item);
619
622
  const isItemSelected = isSelected(item.id);
620
623
  return (
@@ -639,12 +642,13 @@ const Content = (props: IProps): JSX.Element => {
639
642
  );
640
643
  });
641
644
 
645
+ const { schemas } = useSchemasUI();
646
+
642
647
  const mapPages = () =>
643
- currentSitePages &&
644
- currentSitePages.map((pageItem: IPage) => {
648
+ currentSitePages?.map((pageItem) => {
645
649
  const isItemSelected = isSelected(pageItem.id);
646
650
  const selectedTemplate = schemas?.templates[pageItem.templateId];
647
- const { singleInstance } = selectedTemplate;
651
+ const { singleInstance } = selectedTemplate || {};
648
652
  const isAlreadyActive = currentSitePagesTemplatesIds.includes(template);
649
653
  const isDuplicable = !singleInstance || (singleInstance && !isAlreadyActive);
650
654
 
@@ -753,8 +757,8 @@ const Content = (props: IProps): JSX.Element => {
753
757
  const title = currentSiteInfo ? currentSiteInfo.name : `Site Content`;
754
758
 
755
759
  const options = {
756
- filters: getOptionFilters(structuredData, activatedDataPacks),
757
- values: getOptionValues(structuredData),
760
+ filters: getOptionFilters(structuredData, activatedDataPacks, schemas),
761
+ values: getOptionValues(structuredData, schemas),
758
762
  };
759
763
 
760
764
  const selectedOption = isStructuredData ? filter : template;
@@ -769,7 +773,7 @@ const Content = (props: IProps): JSX.Element => {
769
773
  const onScroll = (e: any) => setIsScrolling(e.target.scrollTop > 0);
770
774
 
771
775
  const selectedOptionObject = options.values.find((option) => option.value === selectedOption);
772
- const selectedOptionType = selectedOptionObject.type.toUpperCase();
776
+ const selectedOptionType = selectedOptionObject?.type.toUpperCase();
773
777
  const isOptionGlobal = selectedOptionType !== "STATIC" && isGlobalStructuredData(selectedOptionType);
774
778
  const isOptionImportable =
775
779
  !isData && isOptionGlobal && isStructuredDataFromPage(selectedOptionType) && selectedOptionObject.mode === "detail";
@@ -1,11 +1,9 @@
1
- import { config } from "components";
2
- import { arrayInsert, getActivatedDataPacksIds } from "@ax/helpers";
3
1
  import { pageStatus } from "@ax/containers/PageEditor/interfaces";
4
- import { IColumn, IDataPack, IPage, ISchemaField, IStructuredData } from "@ax/types";
5
-
6
- const schemas = config.schemas.ui;
2
+ import { arrayInsert, getActivatedDataPacksIds } from "@ax/helpers";
3
+ import type { IUISchemas } from "@ax/services";
4
+ import type { IColumn, IDataPack, IPage, ISchemaField, IStructuredData } from "@ax/types";
7
5
 
8
- const getTemplatesFilters = (activatedDataPacks: IDataPack[]) => {
6
+ const getTemplatesFilters = (activatedDataPacks: IDataPack[], schemas: IUISchemas) => {
9
7
  const activatedDataPacksIds = getActivatedDataPacksIds(activatedDataPacks);
10
8
  const { templates } = schemas;
11
9
 
@@ -61,15 +59,17 @@ const mapStructuredOptions = (options: any[]) => {
61
59
  });
62
60
  };
63
61
 
64
- const getOptionValues = (options: IStructuredData[]) => {
62
+ const getOptionValues = (options: IStructuredData[], schemas: IUISchemas | null) => {
65
63
  const templatesOptionsValues: any = [];
66
- const { templates } = schemas;
64
+ const { templates } = schemas || {};
65
+
66
+ if (!templates) return [];
67
67
 
68
68
  Object.keys(templates).forEach((schema: any) => {
69
69
  const currSchema = templates[schema];
70
70
  const { component, displayName, dataPacks } = currSchema;
71
- const type = currSchema.type && currSchema.type.value && currSchema.type.value.toLowerCase();
72
- const mode = currSchema.type && currSchema.type.mode;
71
+ const type = currSchema.type?.value?.toLowerCase();
72
+ const mode = currSchema.type?.mode;
73
73
 
74
74
  !!currSchema.type &&
75
75
  templatesOptionsValues.push({
@@ -85,9 +85,11 @@ const getOptionValues = (options: IStructuredData[]) => {
85
85
  return [...templatesOptionsValues, ...mapStructuredOptions(options)];
86
86
  };
87
87
 
88
- const getOptionFilters = (options: IStructuredData[], activatedDataPacks: IDataPack[]) => {
88
+ const getOptionFilters = (options: IStructuredData[], activatedDataPacks: IDataPack[], schemas: IUISchemas | null) => {
89
+ if (!schemas) return [];
90
+
89
91
  const pureOptions = options.filter((option: IStructuredData) => !option.fromPage);
90
- const { staticFilters, dataPackFilters } = getTemplatesFilters(activatedDataPacks);
92
+ const { staticFilters, dataPackFilters } = getTemplatesFilters(activatedDataPacks, schemas);
91
93
  const activatedDataPacksIds = getActivatedDataPacksIds(activatedDataPacks);
92
94
 
93
95
  const mappedOptions = pureOptions.flatMap((option: IStructuredData) =>
@@ -102,6 +104,8 @@ const getOptionFilters = (options: IStructuredData[], activatedDataPacks: IDataP
102
104
  value: currentDataPack.id,
103
105
  isData: true,
104
106
  };
107
+
108
+ // biome-ignore lint/performance/noAccumulatingSpread: TODO: fix this
105
109
  return [...acc, option];
106
110
  }
107
111
  }