@griddo/ax 11.15.7 → 11.15.8
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 +2 -2
- package/src/__tests__/components/Fields/Wysiwyg/Wysiwyg.atoms.test.tsx +409 -0
- package/src/__tests__/components/Fields/Wysiwyg/Wysiwyg.helpers.test.tsx +418 -0
- package/src/__tests__/components/Fields/Wysiwyg/Wysiwyg.test.tsx +776 -29
- package/src/__tests__/components/FieldsBehavior/FieldsBehavior.test.tsx +368 -11
- package/src/__tests__/modules/Users/UserList/UserList.test.tsx +6 -6
- package/src/components/Fields/IntegrationsField/IntegrationItem/atoms.tsx +14 -5
- package/src/components/Fields/IntegrationsField/IntegrationItem/index.tsx +1 -8
- package/src/components/Fields/UrlField/index.tsx +5 -4
- package/src/components/Fields/Wysiwyg/atoms.tsx +140 -0
- package/src/components/Fields/Wysiwyg/config.tsx +190 -9
- package/src/components/Fields/Wysiwyg/helpers.tsx +54 -1
- package/src/components/Fields/Wysiwyg/index.tsx +210 -61
- package/src/components/Fields/Wysiwyg/style.tsx +32 -1
- package/src/components/Fields/Wysiwyg/vendors.tsx +0 -1
- package/src/components/FieldsBehavior/index.tsx +66 -31
- package/src/components/Icon/components/Sync.js +16 -0
- package/src/components/Icon/svgs/Sync.svg +3 -0
- package/src/components/RestoreModal/index.tsx +1 -3
- package/src/components/ScheduleModal/index.tsx +3 -3
- package/src/components/TableList/index.tsx +5 -3
- package/src/containers/FileDrive/actions.tsx +5 -5
- package/src/containers/Forms/actions.tsx +40 -38
- package/src/containers/Gallery/actions.tsx +27 -27
- package/src/containers/Integrations/actions.tsx +2 -2
- package/src/containers/Navigation/Defaults/actions.tsx +1 -1
- package/src/containers/PageEditor/actions.tsx +3 -5
- package/src/containers/Redirects/actions.tsx +2 -2
- package/src/containers/Sites/actions.tsx +15 -8
- package/src/containers/StructuredData/actions.tsx +5 -5
- package/src/containers/Users/actions.tsx +2 -2
- package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +36 -43
- package/src/modules/Categories/CategoriesList/CategoryPanel/index.tsx +15 -11
- package/src/modules/Categories/CategoriesList/atoms.tsx +42 -12
- package/src/modules/Categories/CategoriesList/index.tsx +8 -30
- package/src/modules/Content/PageItem/index.tsx +6 -5
- package/src/modules/Content/atoms.tsx +7 -3
- package/src/modules/Content/index.tsx +8 -16
- package/src/modules/FileDrive/FileModal/DetailPanel/index.tsx +14 -14
- package/src/modules/FileDrive/FolderItem/index.tsx +46 -54
- package/src/modules/FileDrive/GridItem/index.tsx +32 -37
- package/src/modules/FileDrive/ListItem/index.tsx +31 -37
- package/src/modules/FileDrive/atoms.tsx +59 -12
- package/src/modules/FileDrive/index.tsx +88 -98
- package/src/modules/Forms/FormCategoriesList/CategoryItem/index.tsx +42 -34
- package/src/modules/Forms/FormCategoriesList/atoms.tsx +17 -6
- package/src/modules/Forms/FormCategoriesList/index.tsx +30 -34
- package/src/modules/Forms/FormEditor/index.tsx +14 -6
- package/src/modules/Forms/FormList/FormItem/index.tsx +5 -1
- package/src/modules/Forms/FormList/index.tsx +15 -9
- package/src/modules/Forms/atoms.tsx +7 -4
- package/src/modules/GlobalEditor/atoms.tsx +77 -0
- package/src/modules/GlobalEditor/index.tsx +24 -7
- package/src/modules/MediaGallery/FolderItem/index.tsx +36 -52
- package/src/modules/MediaGallery/GridItem/index.tsx +27 -38
- package/src/modules/MediaGallery/ImageModal/DetailPanel/index.tsx +13 -13
- package/src/modules/MediaGallery/ImageModal/index.tsx +2 -16
- package/src/modules/MediaGallery/ListItem/index.tsx +25 -37
- package/src/modules/MediaGallery/atoms.tsx +84 -15
- package/src/modules/MediaGallery/index.tsx +62 -122
- package/src/modules/Navigation/Defaults/Item/atoms.tsx +2 -4
- package/src/modules/Navigation/Defaults/Item/index.tsx +80 -94
- package/src/modules/Navigation/Defaults/atoms.tsx +179 -7
- package/src/modules/Navigation/Defaults/index.tsx +51 -18
- package/src/modules/Navigation/Defaults/style.tsx +10 -7
- package/src/modules/Navigation/Menus/List/Table/Item/atoms.tsx +33 -19
- package/src/modules/Navigation/Menus/List/Table/Item/index.tsx +18 -19
- package/src/modules/Navigation/Menus/List/Table/index.tsx +15 -13
- package/src/modules/Navigation/Menus/List/index.tsx +1 -1
- package/src/modules/PageEditor/atoms.tsx +14 -11
- package/src/modules/PageEditor/index.tsx +11 -16
- package/src/modules/Redirects/RedirectItem/index.tsx +37 -39
- package/src/modules/Redirects/atoms.tsx +58 -12
- package/src/modules/Redirects/index.tsx +30 -58
- package/src/modules/Settings/Integrations/IntegrationItem/CopyModal/index.tsx +1 -1
- package/src/modules/Settings/Integrations/IntegrationItem/index.tsx +57 -69
- package/src/modules/Settings/Integrations/atoms.tsx +72 -8
- package/src/modules/Settings/Integrations/index.tsx +34 -48
- package/src/modules/StructuredData/Form/index.tsx +25 -8
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/atoms.tsx +26 -75
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +15 -33
- package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +63 -41
- package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/style.tsx +13 -8
- package/src/modules/StructuredData/StructuredDataList/index.tsx +11 -16
- package/src/modules/StructuredData/{StructuredDataList/atoms.tsx → atoms.tsx} +25 -28
- package/src/modules/Users/UserList/UserItem/index.tsx +18 -35
- package/src/modules/Users/UserList/atoms.tsx +61 -0
- package/src/modules/Users/UserList/index.tsx +12 -32
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
1
|
import { connect } from "react-redux";
|
|
3
2
|
|
|
4
|
-
import
|
|
5
|
-
import { useModal, usePermission } from "@ax/hooks";
|
|
3
|
+
import { CheckField } from "@ax/components";
|
|
6
4
|
import { appActions } from "@ax/containers/App";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import { menuActions, navigationActions } from "@ax/containers/Navigation";
|
|
6
|
+
import { useModals, usePermissions } from "@ax/hooks";
|
|
7
|
+
import type { ICheck, ILanguage, INavigation, INavigationLanguage, IRootState } from "@ax/types";
|
|
9
8
|
|
|
9
|
+
import { DeleteModal, RenameModal, SetDefaultModal } from "../atoms";
|
|
10
10
|
import { Translations } from "./atoms";
|
|
11
11
|
|
|
12
12
|
import * as S from "./style";
|
|
@@ -32,22 +32,28 @@ const DefaultItem = (props: IProps): JSX.Element => {
|
|
|
32
32
|
toggleReplaceModal,
|
|
33
33
|
getMenus,
|
|
34
34
|
hoverCheck,
|
|
35
|
+
isSaving,
|
|
35
36
|
} = props;
|
|
36
37
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
const { isOpen: isRenameOpened, toggleModal: toggleRenameModal } = useModal();
|
|
40
|
-
const { isOpen: isDefaultOpened, toggleModal: toggleDefaultModal } = useModal();
|
|
38
|
+
const { isOpen, toggleModal } = useModals(["rename", "default", "delete"]);
|
|
41
39
|
|
|
42
40
|
const { locale } = lang;
|
|
43
41
|
const { navigationLanguages, type } = defaultContent;
|
|
44
42
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
const isAllowedTo = usePermissions({
|
|
44
|
+
editHeaders: "navigation.editSiteHeaders",
|
|
45
|
+
editFooters: "navigation.editSiteFooters",
|
|
46
|
+
createHeaders: "navigation.createSiteHeaders",
|
|
47
|
+
createFooters: "navigation.createSiteFooters",
|
|
48
|
+
deleteHeaders: "navigation.deleteSiteHeaders",
|
|
49
|
+
deleteFooters: "navigation.deleteSiteFooters",
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
console.log(navigationLanguages, "langs");
|
|
53
|
+
|
|
54
|
+
const isAllowedToEdit = type === "header" ? isAllowedTo.editHeaders : isAllowedTo.editFooters;
|
|
55
|
+
const isAllowedToCreate = type === "header" ? isAllowedTo.createHeaders : isAllowedTo.createFooters;
|
|
56
|
+
const isAllowedToDelete = type === "header" ? isAllowedTo.deleteHeaders : isAllowedTo.deleteFooters;
|
|
51
57
|
|
|
52
58
|
const goToEditor = () => {
|
|
53
59
|
handleClick(defaultContent);
|
|
@@ -56,8 +62,8 @@ const DefaultItem = (props: IProps): JSX.Element => {
|
|
|
56
62
|
|
|
57
63
|
const handleOnChange = (value: ICheck) => onChange(value);
|
|
58
64
|
|
|
59
|
-
const handleRenameItem = () => {
|
|
60
|
-
const updatedItem = { ...defaultContent, title:
|
|
65
|
+
const handleRenameItem = (newTitle: string) => {
|
|
66
|
+
const updatedItem = { ...defaultContent, title: newTitle };
|
|
61
67
|
updateNavigation(defaultContent.id!, updatedItem);
|
|
62
68
|
};
|
|
63
69
|
|
|
@@ -65,38 +71,43 @@ const DefaultItem = (props: IProps): JSX.Element => {
|
|
|
65
71
|
|
|
66
72
|
const handleErrorAction = () => toggleReplaceModal();
|
|
67
73
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
const isTranslated = navigationLanguages.length > 1;
|
|
75
|
+
|
|
76
|
+
const handleDeleteConfirm = async (deleteAllVersions: boolean) => {
|
|
77
|
+
const idsToDelete: number | number[] = deleteAllVersions
|
|
78
|
+
? navigationLanguages.map((nav) => nav.navigationId)
|
|
79
|
+
: defaultContent.id!;
|
|
80
|
+
|
|
81
|
+
const deleted = await deleteNavigation(idsToDelete, defaultContent.type, handleErrorAction);
|
|
82
|
+
setDeletedNav(idsToDelete);
|
|
71
83
|
if (deleted) {
|
|
72
84
|
toggleToast();
|
|
85
|
+
toggleModal("delete");
|
|
73
86
|
}
|
|
74
87
|
};
|
|
75
88
|
|
|
76
|
-
const renameOption =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
: undefined;
|
|
89
|
+
const renameOption = isAllowedToEdit
|
|
90
|
+
? {
|
|
91
|
+
label: "Rename",
|
|
92
|
+
icon: "edit",
|
|
93
|
+
action: () => toggleModal("rename"),
|
|
94
|
+
}
|
|
95
|
+
: undefined;
|
|
96
|
+
|
|
97
|
+
const deleteOption = isAllowedToDelete
|
|
98
|
+
? {
|
|
99
|
+
label: "Delete",
|
|
100
|
+
icon: "delete",
|
|
101
|
+
action: () => toggleModal("delete"),
|
|
102
|
+
}
|
|
103
|
+
: undefined;
|
|
93
104
|
|
|
94
105
|
const setAsDefaultOption =
|
|
95
|
-
!defaultContent.setAsDefault &&
|
|
106
|
+
!defaultContent.setAsDefault && isAllowedToEdit
|
|
96
107
|
? {
|
|
97
108
|
label: "Set as default",
|
|
98
109
|
icon: "modules",
|
|
99
|
-
action:
|
|
110
|
+
action: () => toggleModal("default"),
|
|
100
111
|
}
|
|
101
112
|
: undefined;
|
|
102
113
|
|
|
@@ -117,17 +128,6 @@ const DefaultItem = (props: IProps): JSX.Element => {
|
|
|
117
128
|
|
|
118
129
|
const currentLanguages = getCurrentLanguages();
|
|
119
130
|
|
|
120
|
-
const handleCloseModal = () => {
|
|
121
|
-
setInputValue("");
|
|
122
|
-
toggleRenameModal();
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const mainRenameModalAction = { title: "Rename", onClick: handleRenameItem, disabled: !inputValue.trim() };
|
|
126
|
-
const secondaryRenameModalAction = { title: "Cancel", onClick: handleCloseModal };
|
|
127
|
-
|
|
128
|
-
const mainDefaultModalAction = { title: "Yes, set as default", onClick: handleSetDefault };
|
|
129
|
-
const secondaryDefaultModalAction = { title: "Cancel", onClick: toggleDefaultModal };
|
|
130
|
-
|
|
131
131
|
const getSelectedNavLanguage = (navLanguages: INavigationLanguage[], language: ILanguage) =>
|
|
132
132
|
navLanguages.find((navLang) => navLang.languageId === language.id);
|
|
133
133
|
|
|
@@ -148,11 +148,11 @@ const DefaultItem = (props: IProps): JSX.Element => {
|
|
|
148
148
|
setHistoryPush("/sites/navigations/editor", true);
|
|
149
149
|
};
|
|
150
150
|
|
|
151
|
-
const availableLanguages =
|
|
151
|
+
const availableLanguages = isAllowedToCreate ? languages : currentLanguages;
|
|
152
152
|
|
|
153
153
|
return (
|
|
154
154
|
<>
|
|
155
|
-
<S.DefaultRow role="rowgroup" selected={isSelected} clickable={
|
|
155
|
+
<S.DefaultRow role="rowgroup" selected={isSelected} clickable={isAllowedToEdit}>
|
|
156
156
|
<S.CheckCell role="cell">
|
|
157
157
|
<CheckField
|
|
158
158
|
name="check"
|
|
@@ -179,45 +179,26 @@ const DefaultItem = (props: IProps): JSX.Element => {
|
|
|
179
179
|
<S.StyledActionMenu icon="more" options={menuOptions} />
|
|
180
180
|
</S.ActionCell>
|
|
181
181
|
</S.DefaultRow>
|
|
182
|
-
<
|
|
183
|
-
isOpen={
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
) : null}
|
|
203
|
-
</Modal>
|
|
204
|
-
<Modal
|
|
205
|
-
isOpen={isDefaultOpened}
|
|
206
|
-
hide={toggleDefaultModal}
|
|
207
|
-
title={`Default ${defaultContent.component}`}
|
|
208
|
-
secondaryAction={secondaryDefaultModalAction}
|
|
209
|
-
mainAction={mainDefaultModalAction}
|
|
210
|
-
size="S"
|
|
211
|
-
>
|
|
212
|
-
{isDefaultOpened ? (
|
|
213
|
-
<S.ModalContent>
|
|
214
|
-
<p>
|
|
215
|
-
There is already a header defined as default. If you change it to this one, it will be shown on all the
|
|
216
|
-
pages on this site. Are you sure your want to make this change?
|
|
217
|
-
</p>
|
|
218
|
-
</S.ModalContent>
|
|
219
|
-
) : null}
|
|
220
|
-
</Modal>
|
|
182
|
+
<RenameModal
|
|
183
|
+
isOpen={isOpen("rename")}
|
|
184
|
+
toggleModal={() => toggleModal("rename")}
|
|
185
|
+
defaultContent={defaultContent}
|
|
186
|
+
onRename={handleRenameItem}
|
|
187
|
+
/>
|
|
188
|
+
<SetDefaultModal
|
|
189
|
+
isOpen={isOpen("default")}
|
|
190
|
+
toggleModal={() => toggleModal("default")}
|
|
191
|
+
defaultContent={defaultContent}
|
|
192
|
+
onSetDefault={handleSetDefault}
|
|
193
|
+
/>
|
|
194
|
+
<DeleteModal
|
|
195
|
+
isOpen={isOpen("delete")}
|
|
196
|
+
toggleModal={() => toggleModal("delete")}
|
|
197
|
+
isTranslated={isTranslated}
|
|
198
|
+
title={defaultContent.title}
|
|
199
|
+
onDelete={handleDeleteConfirm}
|
|
200
|
+
isDeleting={isSaving}
|
|
201
|
+
/>
|
|
221
202
|
</>
|
|
222
203
|
);
|
|
223
204
|
};
|
|
@@ -232,8 +213,8 @@ interface IProps {
|
|
|
232
213
|
isSelected: boolean;
|
|
233
214
|
toggleToast(): void;
|
|
234
215
|
onChange: (e: any) => void;
|
|
235
|
-
setDeletedNav(item: number): void;
|
|
236
|
-
deleteNavigation(navID: number, type: string, errorAction: () => void): Promise<boolean>;
|
|
216
|
+
setDeletedNav(item: number | number[]): void;
|
|
217
|
+
deleteNavigation(navID: number | number[], type: string, errorAction: () => void): Promise<boolean>;
|
|
237
218
|
setDefaultNavigation(navID: number, type: string): void;
|
|
238
219
|
setLanguage(lang: { locale: string; id: number | null }): void;
|
|
239
220
|
createNewTranslation(isNewTranslation: boolean): void;
|
|
@@ -242,8 +223,13 @@ interface IProps {
|
|
|
242
223
|
toggleReplaceModal: () => void;
|
|
243
224
|
getMenus(): Promise<void>;
|
|
244
225
|
hoverCheck: boolean;
|
|
226
|
+
isSaving: boolean;
|
|
245
227
|
}
|
|
246
228
|
|
|
229
|
+
const mapStateToProps = (state: IRootState) => ({
|
|
230
|
+
isSaving: state.app.isSaving,
|
|
231
|
+
});
|
|
232
|
+
|
|
247
233
|
const mapDispatchToProps = {
|
|
248
234
|
updateNavigation: navigationActions.updateNavigation,
|
|
249
235
|
deleteNavigation: navigationActions.deleteNavigation,
|
|
@@ -255,4 +241,4 @@ const mapDispatchToProps = {
|
|
|
255
241
|
getMenus: menuActions.getMenus,
|
|
256
242
|
};
|
|
257
243
|
|
|
258
|
-
export default connect(
|
|
244
|
+
export default connect(mapStateToProps, mapDispatchToProps)(DefaultItem);
|
|
@@ -1,28 +1,200 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
|
|
4
|
+
import { FieldsBehavior, Modal } from "@ax/components";
|
|
5
|
+
import type { IModal, INavigation } from "@ax/types";
|
|
6
|
+
|
|
2
7
|
import * as S from "./style";
|
|
3
8
|
|
|
4
9
|
const NavigationModulesWarning = (props: INavigationModulesWarning): JSX.Element => {
|
|
5
10
|
const { goTo } = props;
|
|
6
11
|
|
|
12
|
+
const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {
|
|
13
|
+
if (e.key === "Enter") {
|
|
14
|
+
goTo();
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
7
18
|
return (
|
|
8
19
|
<S.NavigationModulesWarning>
|
|
9
20
|
<S.NavigationModulesTitle>Navigation Modules</S.NavigationModulesTitle>
|
|
10
21
|
<S.NavigationModulesDescription>
|
|
11
22
|
Create as many headers as you need for your site. You can decide on which page to use each one. To change the
|
|
12
23
|
header design, you have to go to{" "}
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
</span>
|
|
17
|
-
</S.SiteSettingsLink>
|
|
24
|
+
<button type="button" onClick={goTo} onKeyDown={handleKeyDown} tabIndex={0}>
|
|
25
|
+
Site Settings
|
|
26
|
+
</button>
|
|
18
27
|
.
|
|
19
28
|
</S.NavigationModulesDescription>
|
|
20
29
|
</S.NavigationModulesWarning>
|
|
21
30
|
);
|
|
22
31
|
};
|
|
23
32
|
|
|
33
|
+
const DeleteModal = (props: IDeleteModal): JSX.Element => {
|
|
34
|
+
const { isOpen, toggleModal, isTranslated, title, onDelete, isDeleting, itemCount } = props;
|
|
35
|
+
const [deleteAllVersions, setDeleteAllVersions] = useState(false);
|
|
36
|
+
|
|
37
|
+
const isBulkDelete = itemCount && itemCount > 1;
|
|
38
|
+
|
|
39
|
+
const options = [
|
|
40
|
+
{
|
|
41
|
+
title: "Delete only this version",
|
|
42
|
+
name: "deletePage",
|
|
43
|
+
value: false,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: "Delete all languages versions",
|
|
47
|
+
name: "deleteAll",
|
|
48
|
+
value: true,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const itemTitle = title ? <strong>{title}</strong> : "this";
|
|
53
|
+
|
|
54
|
+
const mainAction = {
|
|
55
|
+
title: isDeleting ? "Deleting" : "Delete",
|
|
56
|
+
onClick: () => onDelete(deleteAllVersions),
|
|
57
|
+
disabled: isDeleting,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const secondaryAction = { title: "Cancel", onClick: toggleModal };
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<Modal
|
|
64
|
+
isOpen={isOpen}
|
|
65
|
+
hide={toggleModal}
|
|
66
|
+
title="Delete navigation?"
|
|
67
|
+
secondaryAction={secondaryAction}
|
|
68
|
+
mainAction={mainAction}
|
|
69
|
+
size="S"
|
|
70
|
+
height="auto"
|
|
71
|
+
>
|
|
72
|
+
{isTranslated ? (
|
|
73
|
+
<>
|
|
74
|
+
<S.ModalContent>
|
|
75
|
+
<p>
|
|
76
|
+
{isBulkDelete ? (
|
|
77
|
+
<>
|
|
78
|
+
You are going to delete <strong>{itemCount} navigations</strong> that have some translations
|
|
79
|
+
associated. Choose if you want to delete all languages versions or only this one.
|
|
80
|
+
</>
|
|
81
|
+
) : (
|
|
82
|
+
<>
|
|
83
|
+
You are going to delete {itemTitle} navigation that have some translations associated. Choose if you
|
|
84
|
+
want to delete all languages versions or only this one.
|
|
85
|
+
</>
|
|
86
|
+
)}
|
|
87
|
+
</p>
|
|
88
|
+
<FieldsBehavior
|
|
89
|
+
name="removeAllVersions"
|
|
90
|
+
fieldType="RadioGroup"
|
|
91
|
+
value={deleteAllVersions}
|
|
92
|
+
options={options}
|
|
93
|
+
onChange={setDeleteAllVersions}
|
|
94
|
+
/>
|
|
95
|
+
</S.ModalContent>
|
|
96
|
+
</>
|
|
97
|
+
) : (
|
|
98
|
+
<S.ModalContent>
|
|
99
|
+
{isBulkDelete ? (
|
|
100
|
+
<>
|
|
101
|
+
Are you sure you want to delete <strong>{itemCount} navigations</strong>?
|
|
102
|
+
</>
|
|
103
|
+
) : (
|
|
104
|
+
<>Are you sure you want to delete {itemTitle} navigation?</>
|
|
105
|
+
)}
|
|
106
|
+
</S.ModalContent>
|
|
107
|
+
)}
|
|
108
|
+
</Modal>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const RenameModal = (props: IRenameModal): JSX.Element => {
|
|
113
|
+
const { isOpen, toggleModal, defaultContent, onRename } = props;
|
|
114
|
+
const [inputValue, setInputValue] = useState("");
|
|
115
|
+
|
|
116
|
+
const handleClose = () => {
|
|
117
|
+
setInputValue("");
|
|
118
|
+
toggleModal();
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const handleRename = () => {
|
|
122
|
+
onRename(inputValue);
|
|
123
|
+
handleClose();
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<Modal
|
|
128
|
+
isOpen={isOpen}
|
|
129
|
+
hide={handleClose}
|
|
130
|
+
title={`Rename ${defaultContent.component}`}
|
|
131
|
+
secondaryAction={{ title: "Cancel", onClick: handleClose }}
|
|
132
|
+
mainAction={{ title: "Rename", onClick: handleRename, disabled: !inputValue.trim() }}
|
|
133
|
+
size="S"
|
|
134
|
+
height="auto"
|
|
135
|
+
>
|
|
136
|
+
{isOpen ? (
|
|
137
|
+
<S.ModalContent>
|
|
138
|
+
<FieldsBehavior
|
|
139
|
+
fieldType="TextField"
|
|
140
|
+
name="name"
|
|
141
|
+
title="Name"
|
|
142
|
+
mandatory={true}
|
|
143
|
+
value={inputValue}
|
|
144
|
+
onChange={setInputValue}
|
|
145
|
+
placeholder={`Type a new name for the ${defaultContent.type}`}
|
|
146
|
+
/>
|
|
147
|
+
</S.ModalContent>
|
|
148
|
+
) : null}
|
|
149
|
+
</Modal>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const SetDefaultModal = (props: ISetDefaultModal): JSX.Element => {
|
|
154
|
+
const { isOpen, toggleModal, defaultContent, onSetDefault } = props;
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<Modal
|
|
158
|
+
isOpen={isOpen}
|
|
159
|
+
hide={toggleModal}
|
|
160
|
+
title={`Default ${defaultContent.component}`}
|
|
161
|
+
secondaryAction={{ title: "Cancel", onClick: toggleModal }}
|
|
162
|
+
mainAction={{ title: "Yes, set as default", onClick: onSetDefault }}
|
|
163
|
+
size="S"
|
|
164
|
+
height="auto"
|
|
165
|
+
>
|
|
166
|
+
{isOpen ? (
|
|
167
|
+
<S.ModalContent>
|
|
168
|
+
<p>
|
|
169
|
+
There is already a header defined as default. If you change it to this one, it will be shown on all the
|
|
170
|
+
pages on this site. Are you sure your want to make this change?
|
|
171
|
+
</p>
|
|
172
|
+
</S.ModalContent>
|
|
173
|
+
) : null}
|
|
174
|
+
</Modal>
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
|
|
24
178
|
interface INavigationModulesWarning {
|
|
25
179
|
goTo(): void;
|
|
26
180
|
}
|
|
27
181
|
|
|
28
|
-
|
|
182
|
+
interface IDeleteModal extends IModal {
|
|
183
|
+
isTranslated: boolean;
|
|
184
|
+
title?: string;
|
|
185
|
+
onDelete: (deleteAllVersions: boolean) => void;
|
|
186
|
+
isDeleting?: boolean;
|
|
187
|
+
itemCount?: number;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
interface IRenameModal extends IModal {
|
|
191
|
+
defaultContent: INavigation;
|
|
192
|
+
onRename: (value: string) => void;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
interface ISetDefaultModal extends IModal {
|
|
196
|
+
defaultContent: INavigation;
|
|
197
|
+
onSetDefault: () => void;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export { NavigationModulesWarning, DeleteModal, RenameModal, SetDefaultModal };
|
|
@@ -5,10 +5,10 @@ import { ErrorToast, MainWrapper, Notification, TableList, Toast } from "@ax/com
|
|
|
5
5
|
import { appActions } from "@ax/containers/App";
|
|
6
6
|
import { menuActions, navigationActions } from "@ax/containers/Navigation";
|
|
7
7
|
import { capitalize, isMultipleNavigationModules } from "@ax/helpers";
|
|
8
|
-
import { useBulkSelection,
|
|
8
|
+
import { useBulkSelection, useModals, usePermissions, useToast } from "@ax/hooks";
|
|
9
9
|
import type { IFooter, IHeader, ILanguage, INavigation, IRootState, ISite } from "@ax/types";
|
|
10
10
|
|
|
11
|
-
import { NavigationModulesWarning } from "./atoms";
|
|
11
|
+
import { DeleteModal, NavigationModulesWarning } from "./atoms";
|
|
12
12
|
import BulkHeader from "./BulkHeader";
|
|
13
13
|
import DefaultItem from "./Item";
|
|
14
14
|
import DefaultNav from "./Nav";
|
|
@@ -38,9 +38,9 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
38
38
|
getMenus,
|
|
39
39
|
resetDefaultsValues,
|
|
40
40
|
currentSiteInfo,
|
|
41
|
+
isSaving,
|
|
41
42
|
} = props;
|
|
42
43
|
|
|
43
|
-
const [isBulkLoading, setIsBulkLoading] = useState(false);
|
|
44
44
|
const [page, setPage] = useState(1);
|
|
45
45
|
const [deletedNav, setDeletedNav] = useState<number | number[] | null>(null);
|
|
46
46
|
const [updatedPages, setUpdatedPages] = useState<number | null>(null);
|
|
@@ -49,10 +49,17 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
49
49
|
const [isScrolling, setIsScrolling] = useState(false);
|
|
50
50
|
const tableRef = useRef<HTMLDivElement>(null);
|
|
51
51
|
const [isNavigationNotificationOpen, setIsNavigationNotificationOpen] = useState(false);
|
|
52
|
-
const { isOpen
|
|
52
|
+
const { isOpen, toggleModal } = useModals(["replace", "delete"]);
|
|
53
53
|
|
|
54
|
-
const
|
|
55
|
-
|
|
54
|
+
const isAllowedTo = usePermissions({
|
|
55
|
+
createHeaders: "navigation.createSiteHeaders",
|
|
56
|
+
createFooters: "navigation.createSiteFooters",
|
|
57
|
+
deleteHeaders: "navigation.deleteSiteHeaders",
|
|
58
|
+
deleteFooters: "navigation.deleteSiteFooters",
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const isAllowedToCreate = selectedDefault === "Headers" ? isAllowedTo.createHeaders : isAllowedTo.createFooters;
|
|
62
|
+
const isAllowedToDelete = selectedDefault === "Headers" ? isAllowedTo.deleteHeaders : isAllowedTo.deleteFooters;
|
|
56
63
|
|
|
57
64
|
const navIds = useMemo(() => currentDefaultsContent?.map((nav) => nav.id), [currentDefaultsContent]);
|
|
58
65
|
|
|
@@ -162,16 +169,32 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
162
169
|
togglePagesToast();
|
|
163
170
|
};
|
|
164
171
|
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
172
|
+
const handleBulkDeleteConfirm = async (deleteAllVersions: boolean) => {
|
|
173
|
+
let idsToDelete = selectedItems.all;
|
|
174
|
+
if (deleteAllVersions) {
|
|
175
|
+
const allTranslationIds = new Set(selectedItems.all);
|
|
176
|
+
selectedItems.all.forEach((id) => {
|
|
177
|
+
const nav = currentDefaultsContent?.find((n) => n.id === id);
|
|
178
|
+
nav?.navigationLanguages.forEach((lang) => {
|
|
179
|
+
allTranslationIds.add(lang.navigationId);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
idsToDelete = Array.from(allTranslationIds);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const deleted = await deleteNavigation(idsToDelete, currentType, () => toggleModal("replace"));
|
|
186
|
+
setDeletedNav(idsToDelete);
|
|
169
187
|
if (deleted) {
|
|
170
188
|
toggleToast();
|
|
189
|
+
toggleModal("delete");
|
|
190
|
+
resetBulkSelection();
|
|
171
191
|
}
|
|
172
|
-
setIsBulkLoading(false);
|
|
173
192
|
};
|
|
174
193
|
|
|
194
|
+
const hasAnyTranslation = currentDefaultsContent?.some(
|
|
195
|
+
(nav) => selectedItems.all.includes(nav.id) && nav.navigationLanguages.length > 1,
|
|
196
|
+
);
|
|
197
|
+
|
|
175
198
|
const onScroll = (e: React.UIEvent<HTMLDivElement>) => setIsScrolling((e.target as HTMLDivElement).scrollTop > 0);
|
|
176
199
|
|
|
177
200
|
const bulkActions = isAllowedToDelete
|
|
@@ -179,7 +202,7 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
179
202
|
{
|
|
180
203
|
icon: "delete",
|
|
181
204
|
text: "delete",
|
|
182
|
-
action:
|
|
205
|
+
action: () => toggleModal("delete"),
|
|
183
206
|
},
|
|
184
207
|
]
|
|
185
208
|
: [];
|
|
@@ -196,7 +219,7 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
196
219
|
checkState={checkState}
|
|
197
220
|
isScrolling={isScrolling}
|
|
198
221
|
setHoverCheck={setHoverCheck}
|
|
199
|
-
isLoading={
|
|
222
|
+
isLoading={isSaving}
|
|
200
223
|
/>
|
|
201
224
|
),
|
|
202
225
|
[
|
|
@@ -210,7 +233,7 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
210
233
|
checkState,
|
|
211
234
|
isScrolling,
|
|
212
235
|
setHoverCheck,
|
|
213
|
-
|
|
236
|
+
isSaving,
|
|
214
237
|
],
|
|
215
238
|
);
|
|
216
239
|
|
|
@@ -262,7 +285,7 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
262
285
|
onChange={addToBulkSelection}
|
|
263
286
|
handleClick={setContent}
|
|
264
287
|
setHistoryPush={setHistoryPush}
|
|
265
|
-
toggleReplaceModal={
|
|
288
|
+
toggleReplaceModal={() => toggleModal("replace")}
|
|
266
289
|
hoverCheck={checkState.hoverCheck}
|
|
267
290
|
/>
|
|
268
291
|
);
|
|
@@ -272,15 +295,23 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
272
295
|
{isVisible && <Toast {...toastProps} />}
|
|
273
296
|
{isPagesVisible && <Toast {...toastPagesProps} />}
|
|
274
297
|
</S.DefaultListWrapper>
|
|
275
|
-
{
|
|
298
|
+
{isOpen("replace") && (
|
|
276
299
|
<ReplaceNavModal
|
|
277
|
-
isOpen={
|
|
278
|
-
toggleModal={
|
|
300
|
+
isOpen={isOpen("replace")}
|
|
301
|
+
toggleModal={() => toggleModal("replace")}
|
|
279
302
|
type={currentType}
|
|
280
303
|
navID={deletedNav}
|
|
281
304
|
toggleToast={handleToast}
|
|
282
305
|
/>
|
|
283
306
|
)}
|
|
307
|
+
<DeleteModal
|
|
308
|
+
isOpen={isOpen("delete")}
|
|
309
|
+
toggleModal={() => toggleModal("delete")}
|
|
310
|
+
isTranslated={hasAnyTranslation || false}
|
|
311
|
+
onDelete={handleBulkDeleteConfirm}
|
|
312
|
+
isDeleting={isSaving}
|
|
313
|
+
itemCount={selectedItems.all.length}
|
|
314
|
+
/>
|
|
284
315
|
</MainWrapper>
|
|
285
316
|
);
|
|
286
317
|
};
|
|
@@ -292,6 +323,7 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
292
323
|
currentDefaultsContent: state.navigation.currentDefaultsContent,
|
|
293
324
|
totalItems: state.navigation.totalItems,
|
|
294
325
|
currentSiteInfo: state.sites.currentSiteInfo,
|
|
326
|
+
isSaving: state.app.isSaving,
|
|
295
327
|
});
|
|
296
328
|
|
|
297
329
|
interface IDispatchProps {
|
|
@@ -315,6 +347,7 @@ interface IDefaultsProps {
|
|
|
315
347
|
currentDefaultsContent: INavigation[];
|
|
316
348
|
totalItems: number;
|
|
317
349
|
currentSiteInfo: ISite | null;
|
|
350
|
+
isSaving: boolean;
|
|
318
351
|
}
|
|
319
352
|
|
|
320
353
|
type IProps = IDefaultsProps & IDispatchProps;
|
|
@@ -32,14 +32,17 @@ const NavigationModulesTitle = styled.div`
|
|
|
32
32
|
|
|
33
33
|
const NavigationModulesDescription = styled.div`
|
|
34
34
|
${(p) => p.theme.textStyle.uiM};
|
|
35
|
+
button {
|
|
36
|
+
${(p) => p.theme.textStyle.uiS};
|
|
37
|
+
color: ${(p) => p.theme.color.interactive01};
|
|
38
|
+
}
|
|
35
39
|
`;
|
|
36
40
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
cursor: pointer;
|
|
41
|
+
const ModalContent = styled.div`
|
|
42
|
+
padding: ${(p) => p.theme.spacing.m};
|
|
43
|
+
|
|
44
|
+
p {
|
|
45
|
+
margin-bottom: ${(p) => p.theme.spacing.m};
|
|
43
46
|
}
|
|
44
47
|
`;
|
|
45
48
|
|
|
@@ -50,5 +53,5 @@ export {
|
|
|
50
53
|
NavigationModulesWarning,
|
|
51
54
|
NavigationModulesTitle,
|
|
52
55
|
NavigationModulesDescription,
|
|
53
|
-
|
|
56
|
+
ModalContent,
|
|
54
57
|
};
|