@griddo/ax 10.3.20 → 10.3.22
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/webpackSchemas.config.js +1 -0
- package/package.json +3 -2
- package/src/components/Fields/Wysiwyg/config.tsx +2 -7
- package/src/components/Fields/Wysiwyg/index.tsx +1 -0
- package/src/components/Gallery/index.tsx +5 -5
- package/src/components/MainWrapper/AppBar/style.tsx +1 -0
- package/src/containers/FileDrive/actions.tsx +2 -2
- package/src/containers/FileDrive/interfaces.tsx +1 -1
- package/src/containers/FileDrive/reducer.tsx +2 -2
- package/src/containers/PageEditor/actions.tsx +7 -2
- package/src/containers/StructuredData/actions.tsx +6 -2
- package/src/containers/StructuredData/utils.tsx +2 -2
- package/src/forms/editor.tsx +3 -3
- package/src/modules/Content/OptionTable/index.tsx +21 -7
- package/src/modules/Content/OptionTable/style.tsx +25 -1
- package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/index.tsx +1 -1
- package/src/modules/FileDrive/index.tsx +5 -6
- package/src/modules/PageEditor/index.tsx +1 -1
- package/src/schemas/pages/Page.tsx +1 -0
|
@@ -25,6 +25,7 @@ const createConfig = ({ input, output }) => ({
|
|
|
25
25
|
loader: "babel-loader",
|
|
26
26
|
options: {
|
|
27
27
|
presets: [["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript"],
|
|
28
|
+
plugins: ["@babel/plugin-proposal-optional-chaining"],
|
|
28
29
|
},
|
|
29
30
|
},
|
|
30
31
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@griddo/ax",
|
|
3
3
|
"description": "Griddo Author Experience",
|
|
4
|
-
"version": "10.3.
|
|
4
|
+
"version": "10.3.22",
|
|
5
5
|
"authors": [
|
|
6
6
|
"Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
|
|
7
7
|
"Carlos Torres <carlos.torres@secuoyas.com>",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@atlaskit/tree": "^8.2.0",
|
|
43
|
+
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
|
|
43
44
|
"@babel/preset-react": "^7.14.5",
|
|
44
45
|
"@pmmmwh/react-refresh-webpack-plugin": "0.5.0-rc.0",
|
|
45
46
|
"@styled-system/prop-types": "5.1.2",
|
|
@@ -230,5 +231,5 @@
|
|
|
230
231
|
"publishConfig": {
|
|
231
232
|
"access": "public"
|
|
232
233
|
},
|
|
233
|
-
"gitHead": "
|
|
234
|
+
"gitHead": "1016e656a2fb09acc98c3576dcbc3f092bd85ee1"
|
|
234
235
|
}
|
|
@@ -44,14 +44,10 @@ const buttons = [
|
|
|
44
44
|
[
|
|
45
45
|
"bold",
|
|
46
46
|
"italic",
|
|
47
|
-
"paragraphFormat",
|
|
48
47
|
"formatUL",
|
|
49
|
-
"quote",
|
|
50
|
-
"alignLeft",
|
|
51
|
-
"alignCenter",
|
|
52
48
|
"insertLink",
|
|
53
|
-
"
|
|
54
|
-
"
|
|
49
|
+
"paragraphFormat",
|
|
50
|
+
paragraphStyles ? "paragraphStyle" : undefined,
|
|
55
51
|
],
|
|
56
52
|
];
|
|
57
53
|
|
|
@@ -85,7 +81,6 @@ const wysiwygConfig = {
|
|
|
85
81
|
imageResize: false,
|
|
86
82
|
linkEditButtons: ["linkOpen", "linkEdit", "linkRemove"],
|
|
87
83
|
videoInsertButtons: ["videoBack", "|", "videoByURL", "videoEmbed"],
|
|
88
|
-
imageUpload: true,
|
|
89
84
|
imageAllowedTypes: ["jpeg", "jpg", "png", "svg"],
|
|
90
85
|
imageMaxSize: 20 * 1024 * 1024,
|
|
91
86
|
imageManagerLoadURL: `${process.env.REACT_APP_API_ENDPOINT}/images/wysiwyg`,
|
|
@@ -34,6 +34,7 @@ const Wysiwyg = (props: IWysiwygProps): JSX.Element => {
|
|
|
34
34
|
const dynamicConfig = {
|
|
35
35
|
placeholderText: placeholder,
|
|
36
36
|
toolbarButtons: full ? buttonsFull : buttons,
|
|
37
|
+
imageUpload: full ? true : false,
|
|
37
38
|
requestHeaders: {
|
|
38
39
|
Authorization: `bearer ${token}`,
|
|
39
40
|
},
|
|
@@ -26,13 +26,13 @@ const Gallery = (props: IProps): JSX.Element => {
|
|
|
26
26
|
|
|
27
27
|
const tabs: string[] = [];
|
|
28
28
|
if (site && isAllowedToAccessGlobalImages) {
|
|
29
|
-
tabs.unshift(...["
|
|
29
|
+
tabs.unshift(...["Site", "Global"]);
|
|
30
30
|
}
|
|
31
|
-
const [selectedTab, setSelectedTab] = useState(site ? "
|
|
31
|
+
const [selectedTab, setSelectedTab] = useState(site ? "Site" : "Global");
|
|
32
32
|
const [selectedImage, setSelectedImage] = useState<IImage | null>(null);
|
|
33
|
-
const
|
|
33
|
+
const isSiteTab = selectedTab === "Site";
|
|
34
34
|
const isGlobalTab = selectedTab === "Global";
|
|
35
|
-
const galleryScope =
|
|
35
|
+
const galleryScope = isSiteTab && site ? site.id : "global";
|
|
36
36
|
|
|
37
37
|
const validFormats = ["jpeg", "jpg", "png", "svg", "gif"];
|
|
38
38
|
|
|
@@ -217,7 +217,7 @@ const Gallery = (props: IProps): JSX.Element => {
|
|
|
217
217
|
imageSelected={selectedImage}
|
|
218
218
|
validFormats={validFormats}
|
|
219
219
|
setImage={setImage}
|
|
220
|
-
isGlobalTab={!
|
|
220
|
+
isGlobalTab={!isSiteTab}
|
|
221
221
|
scope={galleryScope}
|
|
222
222
|
selectedTab={selectedTab}
|
|
223
223
|
refreshImages={refreshImages}
|
|
@@ -141,6 +141,7 @@ const Header = styled.section<{ inversed?: boolean }>`
|
|
|
141
141
|
background: ${(p) => (p.inversed ? p.theme.color.uiMainMenuBackground : p.theme.color.uiBackground02)};
|
|
142
142
|
display: flex;
|
|
143
143
|
padding-right: ${(p) => p.theme.spacing.s};
|
|
144
|
+
margin-bottom: 1px;
|
|
144
145
|
border-bottom: ${(p) => `1px solid ${p.theme.color.uiLine}`};
|
|
145
146
|
|
|
146
147
|
button:first-child {
|
|
@@ -59,7 +59,7 @@ function setDisplayMode(displayMode: "grid" | "list"): ISetDisplayMode {
|
|
|
59
59
|
return { type: SET_DISPLAY_MODE, payload: { displayMode } };
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function setSelectedTab(selectedTab: "
|
|
62
|
+
function setSelectedTab(selectedTab: "site" | "global"): ISetSelectedTab {
|
|
63
63
|
return { type: SET_SELECTED_TAB, payload: { selectedTab } };
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -328,7 +328,7 @@ function updateDisplayMode(displayMode: "grid" | "list"): (dispatch: Dispatch) =
|
|
|
328
328
|
};
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
-
function updateTab(tab: "
|
|
331
|
+
function updateTab(tab: "site" | "global"): (dispatch: Dispatch) => Promise<void> {
|
|
332
332
|
return async (dispatch) => {
|
|
333
333
|
dispatch(setSelectedTab(tab));
|
|
334
334
|
};
|
|
@@ -53,7 +53,7 @@ export interface ISetDisplayMode {
|
|
|
53
53
|
|
|
54
54
|
export interface ISetSelectedTab {
|
|
55
55
|
type: typeof SET_SELECTED_TAB;
|
|
56
|
-
payload: { selectedTab: "
|
|
56
|
+
payload: { selectedTab: "site" | "global" };
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export type FileDriveActionsCreators = ISetCurrentFolderContent;
|
|
@@ -21,7 +21,7 @@ export interface IFileDriveState {
|
|
|
21
21
|
isError: boolean;
|
|
22
22
|
errorMsg: string;
|
|
23
23
|
displayMode: "grid" | "list";
|
|
24
|
-
selectedTab: "
|
|
24
|
+
selectedTab: "site" | "global";
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export const initialState: IFileDriveState = {
|
|
@@ -34,7 +34,7 @@ export const initialState: IFileDriveState = {
|
|
|
34
34
|
isError: false,
|
|
35
35
|
errorMsg: "",
|
|
36
36
|
displayMode: "grid",
|
|
37
|
-
selectedTab: "
|
|
37
|
+
selectedTab: "site",
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
export function reducer(state = initialState, action: any): IFileDriveState {
|
|
@@ -402,11 +402,16 @@ function savePage(
|
|
|
402
402
|
selectedEditorID,
|
|
403
403
|
isNewTranslation,
|
|
404
404
|
editorContent: { header, footer, templateConfig, template },
|
|
405
|
+
lastTimeout,
|
|
405
406
|
},
|
|
406
407
|
sites: { currentSiteInfo },
|
|
407
408
|
app: { lang },
|
|
408
409
|
} = getState();
|
|
409
410
|
|
|
411
|
+
if (lastTimeout) {
|
|
412
|
+
clearTimeout(lastTimeout);
|
|
413
|
+
}
|
|
414
|
+
|
|
410
415
|
const rootEditorID = 0;
|
|
411
416
|
const { values: page, id } = getPageData(getState, false);
|
|
412
417
|
const values = evalueComputedFields(page);
|
|
@@ -1012,14 +1017,14 @@ function updateEditorContent(
|
|
|
1012
1017
|
setSelectedContent(updatedSelectedContent);
|
|
1013
1018
|
dispatch(setEditorContent(updatedEditorContent));
|
|
1014
1019
|
|
|
1015
|
-
if(lastTimeout){
|
|
1020
|
+
if (lastTimeout) {
|
|
1016
1021
|
clearTimeout(lastTimeout);
|
|
1017
1022
|
}
|
|
1018
1023
|
|
|
1019
1024
|
const timeoutId = setTimeout(() => {
|
|
1020
1025
|
updatedEditorContent = evalueComputedFields(updatedEditorContent);
|
|
1021
1026
|
generatePageContent(updatedEditorContent, dispatch, getState);
|
|
1022
|
-
},
|
|
1027
|
+
}, 1500);
|
|
1023
1028
|
|
|
1024
1029
|
dispatch(setLastTimeout(timeoutId));
|
|
1025
1030
|
|
|
@@ -340,7 +340,9 @@ function createStructuredDataContent(
|
|
|
340
340
|
} = getState();
|
|
341
341
|
|
|
342
342
|
let dataContent = prepareStructuredDataContent(structuredDataContent);
|
|
343
|
-
|
|
343
|
+
if (Array.isArray(schema.fields)) {
|
|
344
|
+
dataContent = evalueDataComputedFields(structuredDataContent, schema.fields);
|
|
345
|
+
}
|
|
344
346
|
|
|
345
347
|
dataContent = {
|
|
346
348
|
...dataContent,
|
|
@@ -374,7 +376,9 @@ function updateStructuredDataContent(
|
|
|
374
376
|
} = getState();
|
|
375
377
|
|
|
376
378
|
let dataContent = prepareStructuredDataContent(structuredDataContent);
|
|
377
|
-
|
|
379
|
+
if (Array.isArray(schema.fields)) {
|
|
380
|
+
dataContent = evalueDataComputedFields(structuredDataContent, schema.fields);
|
|
381
|
+
}
|
|
378
382
|
|
|
379
383
|
const responseActions = {
|
|
380
384
|
handleSuccess: (response: any) => dispatch(setForm(response)),
|
|
@@ -32,9 +32,9 @@ const getTaxonomies = (data: IStructuredData[]) => data.filter((item: IStructure
|
|
|
32
32
|
const getTypes = (data: IStructuredData[]) => data.filter((item: IStructuredData) => !item.taxonomy);
|
|
33
33
|
const filterStructuredDataByID = (data: any, id: string) => data.find((item: any) => item.id === id);
|
|
34
34
|
|
|
35
|
-
const evalueDataComputedFields = (structuredData: any,
|
|
35
|
+
const evalueDataComputedFields = (structuredData: any, fields: any[]) => {
|
|
36
36
|
const updatedData = deepClone(structuredData);
|
|
37
|
-
|
|
37
|
+
fields.forEach((field: ISchemaField) => {
|
|
38
38
|
if (field.hasOwnProperty("computed")) {
|
|
39
39
|
const computedFunction = eval(`(${field.computed})`);
|
|
40
40
|
updatedData.content[field.key] = computedFunction(structuredData.content);
|
package/src/forms/editor.tsx
CHANGED
|
@@ -203,13 +203,13 @@ const evalueComputedFields = (page: any) => {
|
|
|
203
203
|
const updatedPage = deepClone(page);
|
|
204
204
|
const pageSchemaContent = getTemplate(page.template.templateType).content;
|
|
205
205
|
pageSchemaContent.forEach((field: any) => {
|
|
206
|
-
if(field.hasOwnProperty("computed")){
|
|
206
|
+
if (field.hasOwnProperty("computed")) {
|
|
207
207
|
updatedPage.template[field.key] = field.computed(page);
|
|
208
208
|
}
|
|
209
|
-
})
|
|
209
|
+
});
|
|
210
210
|
|
|
211
211
|
return updatedPage;
|
|
212
|
-
}
|
|
212
|
+
};
|
|
213
213
|
|
|
214
214
|
export {
|
|
215
215
|
parseData,
|
|
@@ -29,7 +29,9 @@ const OptionTable = (props: IOptionTableProps): JSX.Element => {
|
|
|
29
29
|
|
|
30
30
|
const filterOptionsByDataPack = (value: string) => {
|
|
31
31
|
return values.filter((item: any) => {
|
|
32
|
-
return
|
|
32
|
+
return (
|
|
33
|
+
item.editable !== false && (item.dataPacks ? item.dataPacks.includes(value.toUpperCase()) : item.type === value)
|
|
34
|
+
);
|
|
33
35
|
});
|
|
34
36
|
};
|
|
35
37
|
|
|
@@ -101,12 +103,19 @@ const OptionTable = (props: IOptionTableProps): JSX.Element => {
|
|
|
101
103
|
const currentGlobalStructuredData = structuredData.global.find((data: any) =>
|
|
102
104
|
data.schema.templates?.includes(name)
|
|
103
105
|
);
|
|
104
|
-
|
|
105
|
-
if (currentGlobalStructuredData) {
|
|
106
|
+
const currentLocalStructuredData = structuredData.site.find((data: any) => data.schema.templates?.includes(name));
|
|
107
|
+
if (currentGlobalStructuredData || currentLocalStructuredData) {
|
|
106
108
|
filteredOptionsByDataPack = filteredOptionsByDataPack.map((option: any) => {
|
|
107
109
|
if (option.mode !== "detail") return option;
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
+
const optionType = option.type;
|
|
111
|
+
const currentStructuredDataId = currentGlobalStructuredData?.id || currentLocalStructuredData?.id;
|
|
112
|
+
if (currentStructuredDataId?.toLowerCase() === optionType.toLowerCase()) {
|
|
113
|
+
const title = currentGlobalStructuredData
|
|
114
|
+
? `Get ${currentGlobalStructuredData.title} from Global`
|
|
115
|
+
: currentLocalStructuredData?.title;
|
|
116
|
+
return { ...option, title };
|
|
117
|
+
}
|
|
118
|
+
return option;
|
|
110
119
|
});
|
|
111
120
|
const globalOptionIdx = filteredOptionsByDataPack.findIndex((option: any) => option.mode === "detail");
|
|
112
121
|
const globalOption = filteredOptionsByDataPack.splice(globalOptionIdx, 1);
|
|
@@ -114,6 +123,11 @@ const OptionTable = (props: IOptionTableProps): JSX.Element => {
|
|
|
114
123
|
}
|
|
115
124
|
});
|
|
116
125
|
|
|
126
|
+
filteredOptionsByDataPack.sort((ele: any, comp: any) => {
|
|
127
|
+
// Use localeCompare to compare strings alphabetically
|
|
128
|
+
return ele.title.localeCompare(comp.title);
|
|
129
|
+
});
|
|
130
|
+
|
|
117
131
|
setValues(filteredOptionsByDataPack);
|
|
118
132
|
const firstOption = filteredOptionsByDataPack[0] && filteredOptionsByDataPack[0].value;
|
|
119
133
|
selectOption(firstOption, filteredOptionsByDataPack);
|
|
@@ -128,7 +142,7 @@ const OptionTable = (props: IOptionTableProps): JSX.Element => {
|
|
|
128
142
|
|
|
129
143
|
return (
|
|
130
144
|
<S.Table>
|
|
131
|
-
<S.
|
|
145
|
+
<S.LeftColumn>
|
|
132
146
|
{filters.map((item: any, i: number) => {
|
|
133
147
|
const displayFilteredOptions = () => state.selectedType !== item.type && displayOptions(item);
|
|
134
148
|
const isSelected = item.value === state.selectedType;
|
|
@@ -141,7 +155,7 @@ const OptionTable = (props: IOptionTableProps): JSX.Element => {
|
|
|
141
155
|
</MenuItem>
|
|
142
156
|
);
|
|
143
157
|
})}
|
|
144
|
-
</S.
|
|
158
|
+
</S.LeftColumn>
|
|
145
159
|
<S.Column>
|
|
146
160
|
<RadioGroup options={state.columnValues} onChange={selectOption} value={state.selectedOption} name="" />
|
|
147
161
|
</S.Column>
|
|
@@ -30,6 +30,30 @@ export const Column = styled.div`
|
|
|
30
30
|
}
|
|
31
31
|
`;
|
|
32
32
|
|
|
33
|
+
export const LeftColumn = styled.div`
|
|
34
|
+
width: calc(${(p) => p.theme.spacing.m} * 8);
|
|
35
|
+
padding: 0 ${(p) => p.theme.spacing.m};
|
|
36
|
+
height: calc(100% - ${(p) => p.theme.spacing.m});
|
|
37
|
+
&:first-child {
|
|
38
|
+
::-webkit-scrollbar {
|
|
39
|
+
-webkit-appearance: none;
|
|
40
|
+
width: 2px;
|
|
41
|
+
height: 100%;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
::-webkit-scrollbar-thumb {
|
|
45
|
+
border-radius: 4px;
|
|
46
|
+
background-color: ${(p) => p.theme.color.iconNonActive};
|
|
47
|
+
}
|
|
48
|
+
border-right: 1px solid ${(p) => p.theme.color.uiLine};
|
|
49
|
+
overflow: scroll;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&:last-child {
|
|
53
|
+
padding-bottom: ${(p) => p.theme.spacing.s};
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
|
|
33
57
|
export const NavLink = styled.a`
|
|
34
58
|
text-transform: capitalize;
|
|
35
59
|
&.selected {
|
|
@@ -66,4 +90,4 @@ export const Actions = styled.div`
|
|
|
66
90
|
button {
|
|
67
91
|
margin-left: ${(p) => p.theme.spacing.s};
|
|
68
92
|
}
|
|
69
|
-
`;
|
|
93
|
+
`;
|
|
@@ -114,7 +114,7 @@ const UsageContent = (props: IProps) => {
|
|
|
114
114
|
interface IProps {
|
|
115
115
|
file: IFile;
|
|
116
116
|
currentSiteID: number | null;
|
|
117
|
-
selectedTab: "
|
|
117
|
+
selectedTab: "site" | "global";
|
|
118
118
|
setHistoryPush(page: string, isEditor: boolean): Promise<void>;
|
|
119
119
|
setCurrentPageID(currentPageID: number | null): ISetCurrentPageIDAction;
|
|
120
120
|
getSite(siteID: number): Promise<void>;
|
|
@@ -35,7 +35,6 @@ import { useFilterQuery, useSortedListStatus } from "./hooks";
|
|
|
35
35
|
import { getSortedListStatus } from "./utils";
|
|
36
36
|
import Type from "./FileFilters/Type";
|
|
37
37
|
import SortBy from "./FileFilters/SortBy";
|
|
38
|
-
import Usage from "./FileFilters/Usage";
|
|
39
38
|
import UploadItem from "./UploadItem";
|
|
40
39
|
|
|
41
40
|
import * as S from "./style";
|
|
@@ -159,7 +158,7 @@ const FileDrive = (props: IProps) => {
|
|
|
159
158
|
useLayoutEffect(() => {
|
|
160
159
|
return () => {
|
|
161
160
|
updateCurrentFolder(null);
|
|
162
|
-
updateTab("
|
|
161
|
+
updateTab("site");
|
|
163
162
|
};
|
|
164
163
|
}, []);
|
|
165
164
|
|
|
@@ -194,7 +193,7 @@ const FileDrive = (props: IProps) => {
|
|
|
194
193
|
selectAllItems,
|
|
195
194
|
} = useBulkSelection(filesIds);
|
|
196
195
|
|
|
197
|
-
const handleSelectedTab = (tab: "
|
|
196
|
+
const handleSelectedTab = (tab: "site" | "global") => {
|
|
198
197
|
if (tab !== selectedTab) {
|
|
199
198
|
setSearchQuery("");
|
|
200
199
|
updateCurrentFolder(null);
|
|
@@ -567,7 +566,7 @@ const FileDrive = (props: IProps) => {
|
|
|
567
566
|
|
|
568
567
|
const foldersIcon = isPanelOpen ? <Icon name="closePanel" size="24" /> : <Icon name="openPanel" size="24" />;
|
|
569
568
|
|
|
570
|
-
const tabs = ["
|
|
569
|
+
const tabs = ["site", "global"];
|
|
571
570
|
|
|
572
571
|
const NewFolderButton = () =>
|
|
573
572
|
allowedToAddFile ? (
|
|
@@ -764,7 +763,7 @@ interface IProps {
|
|
|
764
763
|
currentSiteID: number | null;
|
|
765
764
|
breadcrumb: IFolderTree[];
|
|
766
765
|
displayMode: "grid" | "list";
|
|
767
|
-
selectedTab: "
|
|
766
|
+
selectedTab: "site" | "global";
|
|
768
767
|
getFolderContent(params: IGetFolderParams): Promise<void>;
|
|
769
768
|
getFoldersTree(siteID: number | "global"): Promise<void>;
|
|
770
769
|
updateCurrentFolder(folderID: number | null): void;
|
|
@@ -773,7 +772,7 @@ interface IProps {
|
|
|
773
772
|
deleteFile(fileID: number | number[], siteID: number | "global"): Promise<boolean>;
|
|
774
773
|
moveFile(fileID: number | number[], folderID: number, siteID: number | "global"): Promise<boolean>;
|
|
775
774
|
updateDisplayMode(displayMode: "grid" | "list"): Promise<void>;
|
|
776
|
-
updateTab(tab: "
|
|
775
|
+
updateTab(tab: "site" | "global"): Promise<void>;
|
|
777
776
|
downloadFiles(fileID: number | number[], zip: boolean, fileName?: string): Promise<void>;
|
|
778
777
|
uploadFile: (
|
|
779
778
|
docFiles: File | File[],
|