@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.
- package/config/griddo-config/index.js +1 -0
- package/package.json +2 -2
- package/src/Style/index.tsx +10 -8
- package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +10 -8
- package/src/__tests__/components/ConfigPanel/Form/ConnectedField/PageConnectedField/PageConnectedField.test.tsx +86 -8
- package/src/__tests__/components/SideModal/SideModal.test.tsx +64 -0
- package/src/__tests__/hooks/useSchemas.test.tsx +224 -0
- package/src/__tests__/services/SchemasService.test.ts +135 -0
- package/src/api/schemas.tsx +11 -1
- package/src/components/ConfigPanel/GlobalPageForm/index.tsx +11 -17
- package/src/components/Fields/Wysiwyg/helpers.tsx +14 -4
- package/src/components/Loader/components/Dots.js +4 -5
- package/src/components/PageFinder/index.tsx +15 -9
- package/src/components/ResizePanel/index.tsx +13 -3
- package/src/components/ResizePanel/style.tsx +2 -9
- package/src/containers/App/actions.tsx +96 -24
- package/src/containers/App/constants.tsx +7 -0
- package/src/containers/App/interfaces.tsx +26 -8
- package/src/containers/App/reducer.tsx +24 -9
- package/src/containers/Sites/actions.tsx +49 -49
- package/src/forms/editor.tsx +4 -3
- package/src/helpers/index.tsx +76 -94
- package/src/helpers/schemas.tsx +144 -36
- package/src/helpers/structuredData.tsx +36 -7
- package/src/helpers/themes.tsx +26 -8
- package/src/hooks/index.tsx +5 -0
- package/src/hooks/useSchemas.ts +151 -0
- package/src/locales/en-US.ts +1 -0
- package/src/locales/es-ES.ts +1 -0
- package/src/modules/Analytics/GroupPanel/index.tsx +9 -6
- package/src/modules/Analytics/GroupPanel/utils.tsx +12 -28
- package/src/modules/Content/PageItem/index.tsx +33 -36
- package/src/modules/Content/index.tsx +34 -30
- package/src/modules/Content/utils.tsx +16 -12
- package/src/modules/Forms/FormEditor/index.tsx +13 -14
- package/src/modules/FramePreview/index.tsx +8 -8
- package/src/modules/GlobalEditor/index.tsx +57 -42
- package/src/modules/MediaGallery/ImageModal/index.tsx +15 -9
- package/src/modules/MediaGallery/ImageModal/style.tsx +16 -1
- package/src/modules/PublicPreview/index.tsx +4 -3
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +4 -5
- package/src/modules/Settings/Globals/index.tsx +10 -11
- package/src/modules/Sites/index.tsx +13 -5
- package/src/modules/StructuredData/Form/index.tsx +25 -29
- package/src/modules/StructuredData/StructuredDataList/OptionTable/index.tsx +15 -6
- package/src/modules/StructuredData/StructuredDataList/index.tsx +22 -14
- package/src/modules/StructuredData/StructuredDataList/utils.tsx +12 -11
- package/src/schemas/index.tsx +5 -4
- package/src/schemas/pages/Page.ts +308 -0
- package/src/schemas/pages/index.ts +9 -0
- package/src/services/SchemasService.ts +240 -0
- package/src/services/index.ts +9 -0
- package/src/types/index.tsx +48 -39
- package/tsconfig.paths.json +1 -0
- package/src/schemas/pages/Page.tsx +0 -301
- package/src/schemas/pages/index.tsx +0 -5
- /package/src/schemas/pages/{FormPage.tsx → FormPage.ts} +0 -0
- /package/src/schemas/pages/{GlobalPage.tsx → GlobalPage.ts} +0 -0
package/src/helpers/themes.tsx
CHANGED
|
@@ -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
|
-
|
|
2
|
+
import { schemasService } from "@ax/services";
|
|
3
|
+
import type { IDataPack, IGriddoTheme, ITemplateOption, IThemeElements } from "@ax/types";
|
|
6
4
|
|
|
7
5
|
const getDefaultTheme = (): string => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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[] => {
|
package/src/hooks/index.tsx
CHANGED
|
@@ -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 };
|
package/src/locales/en-US.ts
CHANGED
package/src/locales/es-ES.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
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
|
|
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
|
-
|
|
95
|
+
dimensionOptions.push(option);
|
|
93
96
|
});
|
|
94
97
|
|
|
95
98
|
const setDimensions = (selection: any) => {
|
|
@@ -1,31 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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 {
|
|
35
|
+
import { useTheme } from "styled-components";
|
|
38
36
|
|
|
39
|
-
import
|
|
37
|
+
import { CopyModal, DeleteModal } from "../atoms";
|
|
40
38
|
|
|
41
|
-
|
|
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
|
|
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
|
-
(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
|
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
|
|
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 ||
|
|
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
|
|
177
|
-
const dataIds = currentDataContent
|
|
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
|
|
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
|
|
187
|
-
|
|
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 =
|
|
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
|
|
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 {
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
72
|
-
const mode = currSchema.type
|
|
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
|
}
|