@griddo/ax 11.15.7 → 11.15.8-rc.0
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
|
@@ -4,7 +4,7 @@ import { connect } from "react-redux";
|
|
|
4
4
|
import { EmptyState, ErrorToast, FilterTagsBar, MainWrapper, TableList, Toast } from "@ax/components";
|
|
5
5
|
import { appActions } from "@ax/containers/App";
|
|
6
6
|
import { integrationsActions } from "@ax/containers/Integrations";
|
|
7
|
-
import { useBulkSelection, useEmptyState,
|
|
7
|
+
import { useBulkSelection, useEmptyState, useModals, usePermissions, useToast } from "@ax/hooks";
|
|
8
8
|
import type { IEmptyStateProps, IIntegration, IQueryValue, IRootState } from "@ax/types";
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -33,6 +33,7 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
33
33
|
integrations,
|
|
34
34
|
totalItems,
|
|
35
35
|
currentSite,
|
|
36
|
+
isSaving,
|
|
36
37
|
resetIntegrations,
|
|
37
38
|
deleteIntegration,
|
|
38
39
|
changeIntegrationState,
|
|
@@ -45,12 +46,10 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
45
46
|
throw new Error(`ERROR: User reached Integrations with null site info`);
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
const [isBulkLoading, setIsBulkLoading] = useState(false);
|
|
49
49
|
const [isScrolling, setIsScrolling] = useState(false);
|
|
50
50
|
const tableRef = useRef<HTMLDivElement>(null);
|
|
51
51
|
const { setFiltersSelection, resetFilterQuery, filterValues, filterQuery, isFiltered } = useFilterQuery();
|
|
52
|
-
const { isOpen
|
|
53
|
-
const { isOpen: isOpenDeactivate, toggleModal: toggleModalDeactivate } = useModal();
|
|
52
|
+
const { isOpen, toggleModal } = useModals(["delete", "deactivate"]);
|
|
54
53
|
const {
|
|
55
54
|
isVisible: isVisibleDelete,
|
|
56
55
|
toggleToast: toggleToastDelete,
|
|
@@ -64,9 +63,11 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
64
63
|
state: stateToastChange,
|
|
65
64
|
} = useToast();
|
|
66
65
|
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
const isAllowedTo = usePermissions({
|
|
67
|
+
manage: "general.manageSiteThirdPartyIntegrations",
|
|
68
|
+
deactivate: "general.deactivateSiteThirdPartyIntegrations",
|
|
69
|
+
delete: "general.deleteSiteThirdPartyIntegrations",
|
|
70
|
+
});
|
|
70
71
|
|
|
71
72
|
const sensors = useSensors(
|
|
72
73
|
useSensor(PointerSensor, {
|
|
@@ -126,27 +127,23 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
126
127
|
} = useBulkSelection(filteredIntegrationsIds);
|
|
127
128
|
|
|
128
129
|
const bulkDelete = async () => {
|
|
129
|
-
setIsBulkLoading(true);
|
|
130
130
|
const params = getParams();
|
|
131
131
|
const deleted = await deleteIntegration(selectedItems.all, params);
|
|
132
132
|
if (deleted) {
|
|
133
133
|
toggleToastDelete({ total: selectedItems.all.length });
|
|
134
134
|
}
|
|
135
|
-
|
|
135
|
+
toggleModal("delete");
|
|
136
136
|
resetBulkSelection();
|
|
137
|
-
setIsBulkLoading(false);
|
|
138
137
|
};
|
|
139
138
|
|
|
140
139
|
const bulkDeactivate = async () => {
|
|
141
|
-
setIsBulkLoading(true);
|
|
142
140
|
const params = getParams();
|
|
143
141
|
const changed = await changeIntegrationState(selectedItems.all, false, params);
|
|
144
142
|
if (changed) {
|
|
145
143
|
toggleToastChange({ total: selectedItems.all.length, active: false });
|
|
146
144
|
}
|
|
147
|
-
|
|
145
|
+
toggleModal("deactivate");
|
|
148
146
|
resetBulkSelection();
|
|
149
|
-
setIsBulkLoading(false);
|
|
150
147
|
};
|
|
151
148
|
|
|
152
149
|
const unselectAllItems = () => resetBulkSelection();
|
|
@@ -158,22 +155,21 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
158
155
|
const filterItems = async (filterPointer: string, filtersSelected: IQueryValue[]) =>
|
|
159
156
|
setFiltersSelection(filterPointer, filtersSelected);
|
|
160
157
|
|
|
161
|
-
const bulkActions: { icon: string; text: string; action: () => void | Promise<void> }[] =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (isAllowedToDeactivateIntegrations) {
|
|
158
|
+
const bulkActions: { icon: string; text: string; action: () => void | Promise<void> }[] = isAllowedTo.delete
|
|
159
|
+
? [
|
|
160
|
+
{
|
|
161
|
+
icon: "delete",
|
|
162
|
+
text: "delete",
|
|
163
|
+
action: () => toggleModal("delete"),
|
|
164
|
+
},
|
|
165
|
+
]
|
|
166
|
+
: [];
|
|
167
|
+
|
|
168
|
+
if (isAllowedTo.deactivate) {
|
|
173
169
|
bulkActions.push({
|
|
174
170
|
icon: "deactivate",
|
|
175
171
|
text: "Deactivate",
|
|
176
|
-
action:
|
|
172
|
+
action: () => toggleModal("deactivate"),
|
|
177
173
|
});
|
|
178
174
|
}
|
|
179
175
|
|
|
@@ -190,7 +186,7 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
190
186
|
bulkActions={bulkActions}
|
|
191
187
|
setHoverCheck={setHoverCheck}
|
|
192
188
|
selectedItems={selectedItems}
|
|
193
|
-
isLoading={
|
|
189
|
+
isLoading={isSaving}
|
|
194
190
|
/>
|
|
195
191
|
);
|
|
196
192
|
|
|
@@ -209,18 +205,6 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
209
205
|
}
|
|
210
206
|
};
|
|
211
207
|
|
|
212
|
-
const mainDeleteModalAction = {
|
|
213
|
-
title: isBulkLoading ? "Deleting" : "Delete",
|
|
214
|
-
onClick: bulkDelete,
|
|
215
|
-
disabled: isBulkLoading,
|
|
216
|
-
};
|
|
217
|
-
const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };
|
|
218
|
-
|
|
219
|
-
const mainDeactivateModalAction = {
|
|
220
|
-
title: "Deactivate",
|
|
221
|
-
onClick: bulkDeactivate,
|
|
222
|
-
};
|
|
223
|
-
const secondaryDeactivateModalAction = { title: "Cancel", onClick: toggleModalDeactivate };
|
|
224
208
|
|
|
225
209
|
const deletedToastProps = {
|
|
226
210
|
setIsVisible: setIsVisibleDelete,
|
|
@@ -234,7 +218,7 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
234
218
|
}`,
|
|
235
219
|
};
|
|
236
220
|
|
|
237
|
-
const rightButtonProps =
|
|
221
|
+
const rightButtonProps = isAllowedTo.manage
|
|
238
222
|
? {
|
|
239
223
|
label: "New Custom Code",
|
|
240
224
|
action: () => setHistoryPush(`/sites/settings/addons/new`),
|
|
@@ -310,20 +294,20 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
310
294
|
</S.ContentWrapper>
|
|
311
295
|
</S.Wrapper>
|
|
312
296
|
<DeleteModal
|
|
313
|
-
isOpen={
|
|
314
|
-
toggleModal={
|
|
315
|
-
|
|
316
|
-
|
|
297
|
+
isOpen={isOpen("delete")}
|
|
298
|
+
toggleModal={() => toggleModal("delete")}
|
|
299
|
+
onDelete={bulkDelete}
|
|
300
|
+
isDeleting={isSaving}
|
|
317
301
|
integrations={integrations}
|
|
318
302
|
selectedIds={selectedItems.all}
|
|
319
303
|
/>
|
|
320
304
|
<DeactivateModal
|
|
321
|
-
isOpen={
|
|
322
|
-
toggleModal={
|
|
323
|
-
secondaryModalAction={secondaryDeactivateModalAction}
|
|
324
|
-
mainModalAction={mainDeactivateModalAction}
|
|
305
|
+
isOpen={isOpen("deactivate")}
|
|
306
|
+
toggleModal={() => toggleModal("deactivate")}
|
|
325
307
|
integrations={integrations}
|
|
326
308
|
selectedIds={selectedItems.all}
|
|
309
|
+
onDeactivate={bulkDeactivate}
|
|
310
|
+
isDeactivating={isSaving}
|
|
327
311
|
/>
|
|
328
312
|
</MainWrapper>
|
|
329
313
|
);
|
|
@@ -334,6 +318,7 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
334
318
|
integrations: state.integrations.integrations,
|
|
335
319
|
totalItems: state.integrations.totalItems,
|
|
336
320
|
currentSite: state.sites.currentSiteInfo?.id ?? null,
|
|
321
|
+
isSaving: state.app.isSaving,
|
|
337
322
|
});
|
|
338
323
|
|
|
339
324
|
const mapDispatchToProps = {
|
|
@@ -351,6 +336,7 @@ interface IStateProps {
|
|
|
351
336
|
integrations: IIntegration[];
|
|
352
337
|
totalItems: number;
|
|
353
338
|
currentSite: number | null;
|
|
339
|
+
isSaving: boolean;
|
|
354
340
|
}
|
|
355
341
|
|
|
356
342
|
interface IDispatchProps {
|
|
@@ -27,6 +27,7 @@ import type {
|
|
|
27
27
|
ISite,
|
|
28
28
|
} from "@ax/types";
|
|
29
29
|
|
|
30
|
+
import { DeleteModal } from "../atoms";
|
|
30
31
|
import ConnectedField from "./ConnectedField";
|
|
31
32
|
|
|
32
33
|
import * as S from "./style";
|
|
@@ -70,12 +71,16 @@ const Form = (props: IProps) => {
|
|
|
70
71
|
const { isOpen: isScheduleOpen, toggleModal: toggleScheduleModal } = useModal();
|
|
71
72
|
const { isOpen: isCancelScheduleOpen, toggleModal: toggleCancelScheduleModal } = useModal();
|
|
72
73
|
const { isOpen: isRestoreOpen, toggleModal: toggleRestoreModal } = useModal();
|
|
74
|
+
const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();
|
|
75
|
+
const [isDeleting, setIsDeleting] = useState(false);
|
|
76
|
+
const [deleteAllVersions, setDeleteAllVersions] = useState(false);
|
|
73
77
|
const { isDirty, resetDirty, setIsDirty } = useIsDirty(form);
|
|
74
78
|
const path = site ? "/sites/pages" : "/data";
|
|
75
79
|
|
|
76
80
|
const { fields } = schema;
|
|
77
81
|
const inversed = !site;
|
|
78
82
|
const languages = site ? siteLanguages : globalLangs;
|
|
83
|
+
const arePagesTranslated = (form?.dataLanguages?.length ?? 0) > 1;
|
|
79
84
|
|
|
80
85
|
const fieldsTranslate: ISchemaField[] = [
|
|
81
86
|
{
|
|
@@ -207,12 +212,14 @@ const Form = (props: IProps) => {
|
|
|
207
212
|
setHistoryPush("/sites/settings/content-types", false);
|
|
208
213
|
};
|
|
209
214
|
|
|
210
|
-
const removeItem = () => {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
215
|
+
const removeItem = async () => {
|
|
216
|
+
setIsDeleting(true);
|
|
217
|
+
const deleted = await deleteStructuredDataContent(form.id);
|
|
218
|
+
setIsDeleting(false);
|
|
219
|
+
toggleDeleteModal();
|
|
220
|
+
if (deleted) {
|
|
221
|
+
setHistoryPush(path, true);
|
|
222
|
+
}
|
|
216
223
|
};
|
|
217
224
|
|
|
218
225
|
const publishItem = async () => {
|
|
@@ -280,7 +287,7 @@ const Form = (props: IProps) => {
|
|
|
280
287
|
{
|
|
281
288
|
label: "Delete",
|
|
282
289
|
icon: "delete",
|
|
283
|
-
action:
|
|
290
|
+
action: toggleDeleteModal,
|
|
284
291
|
},
|
|
285
292
|
],
|
|
286
293
|
};
|
|
@@ -350,7 +357,7 @@ const Form = (props: IProps) => {
|
|
|
350
357
|
onClick: toggleCancelScheduleModal,
|
|
351
358
|
};
|
|
352
359
|
|
|
353
|
-
return isLoading ? (
|
|
360
|
+
return isLoading && !isDeleting ? (
|
|
354
361
|
<Loading />
|
|
355
362
|
) : (
|
|
356
363
|
<>
|
|
@@ -421,6 +428,16 @@ const Form = (props: IProps) => {
|
|
|
421
428
|
mainModalAction={mainCancelScheduleModalAction}
|
|
422
429
|
secondaryModalAction={secondaryCancelScheduleModalAction}
|
|
423
430
|
/>
|
|
431
|
+
<DeleteModal
|
|
432
|
+
isOpen={isDeleteOpen}
|
|
433
|
+
toggleModal={toggleDeleteModal}
|
|
434
|
+
title={title || "this item"}
|
|
435
|
+
arePagesTranslated={arePagesTranslated}
|
|
436
|
+
deleteAllVersions={deleteAllVersions}
|
|
437
|
+
setDeleteAllVersions={setDeleteAllVersions}
|
|
438
|
+
onDelete={removeItem}
|
|
439
|
+
isDeleting={isDeleting}
|
|
440
|
+
/>
|
|
424
441
|
<RestoreModal
|
|
425
442
|
isOpen={isRestoreOpen}
|
|
426
443
|
toggleModal={toggleRestoreModal}
|
|
@@ -1,74 +1,13 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import type React from "react";
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import { Modal, FieldsBehavior, ErrorToast } from "@ax/components";
|
|
3
|
+
import { ErrorToast, FieldsBehavior, Modal } from "@ax/components";
|
|
5
4
|
import { slugify } from "@ax/helpers";
|
|
5
|
+
import type { IModal } from "@ax/types";
|
|
6
6
|
|
|
7
7
|
import * as S from "./style";
|
|
8
8
|
|
|
9
|
-
const DeleteModal = (props: IDeleteModal): JSX.Element => {
|
|
10
|
-
const {
|
|
11
|
-
isOpen,
|
|
12
|
-
toggleModal,
|
|
13
|
-
mainModalAction,
|
|
14
|
-
secondaryModalAction,
|
|
15
|
-
title,
|
|
16
|
-
isTranslated,
|
|
17
|
-
deleteAllVersions,
|
|
18
|
-
setDeleteAllVersions,
|
|
19
|
-
} = props;
|
|
20
|
-
|
|
21
|
-
const options = [
|
|
22
|
-
{
|
|
23
|
-
title: "Delete only this version",
|
|
24
|
-
name: "deletePage",
|
|
25
|
-
value: false,
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
title: "Delete all languages versions",
|
|
29
|
-
name: "deleteAll",
|
|
30
|
-
value: true,
|
|
31
|
-
},
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<Modal
|
|
36
|
-
isOpen={isOpen}
|
|
37
|
-
hide={toggleModal}
|
|
38
|
-
title="Delete Global Data?"
|
|
39
|
-
secondaryAction={secondaryModalAction}
|
|
40
|
-
mainAction={mainModalAction}
|
|
41
|
-
size="S"
|
|
42
|
-
>
|
|
43
|
-
{isTranslated ? (
|
|
44
|
-
<>
|
|
45
|
-
<S.ModalContent>
|
|
46
|
-
<p>
|
|
47
|
-
Are you sure you want to delete <strong>{title}</strong> page? If you delete it, this page does not appear
|
|
48
|
-
in the sites associated. Also, this page has some translations associated.
|
|
49
|
-
</p>
|
|
50
|
-
<FieldsBehavior
|
|
51
|
-
name="removeAllVersions"
|
|
52
|
-
fieldType="RadioGroup"
|
|
53
|
-
value={deleteAllVersions}
|
|
54
|
-
options={options}
|
|
55
|
-
onChange={setDeleteAllVersions}
|
|
56
|
-
/>
|
|
57
|
-
</S.ModalContent>
|
|
58
|
-
</>
|
|
59
|
-
) : (
|
|
60
|
-
<S.ModalContent>
|
|
61
|
-
Are you sure you want to delete <strong>{title}</strong> page? If you delete it, this page does not appear in
|
|
62
|
-
the sites associated. This action <strong>cannot be undone</strong>.
|
|
63
|
-
</S.ModalContent>
|
|
64
|
-
)}
|
|
65
|
-
</Modal>
|
|
66
|
-
);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
9
|
const DuplicateModal = (props: IDuplicateModal): JSX.Element => {
|
|
70
|
-
const { isOpen, toggleModal,
|
|
71
|
-
props;
|
|
10
|
+
const { isOpen, toggleModal, duplicateModalState, setDuplicateModalState, onDuplicate, isSaving } = props;
|
|
72
11
|
|
|
73
12
|
const handleNameChange = (value: string) => {
|
|
74
13
|
setDuplicateModalState({ title: value, slug: slugify(value) });
|
|
@@ -78,6 +17,19 @@ const DuplicateModal = (props: IDuplicateModal): JSX.Element => {
|
|
|
78
17
|
setDuplicateModalState((state: { title: string; slug: string }) => ({ ...state, slug: value }));
|
|
79
18
|
};
|
|
80
19
|
|
|
20
|
+
const handleCloseDuplicate = () => {
|
|
21
|
+
toggleModal();
|
|
22
|
+
setDuplicateModalState({ title: "", slug: "" });
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const mainModalAction = {
|
|
26
|
+
title: isSaving ? "Duplicating" : "Duplicate",
|
|
27
|
+
onClick: onDuplicate,
|
|
28
|
+
disabled: !duplicateModalState.title.trim() || !duplicateModalState.slug.trim() || isSaving,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const secondaryModalAction = { title: "Cancel", onClick: handleCloseDuplicate };
|
|
32
|
+
|
|
81
33
|
return (
|
|
82
34
|
<Modal
|
|
83
35
|
isOpen={isOpen}
|
|
@@ -110,8 +62,10 @@ const DuplicateModal = (props: IDuplicateModal): JSX.Element => {
|
|
|
110
62
|
);
|
|
111
63
|
};
|
|
112
64
|
|
|
113
|
-
const UnpublishModal = (props:
|
|
114
|
-
const { isOpen, toggleModal
|
|
65
|
+
const UnpublishModal = (props: IUnpublishModal): JSX.Element => {
|
|
66
|
+
const { isOpen, toggleModal } = props;
|
|
67
|
+
|
|
68
|
+
const mainModalAction = { title: "Ok", onClick: toggleModal };
|
|
115
69
|
|
|
116
70
|
return (
|
|
117
71
|
<Modal isOpen={isOpen} hide={toggleModal} title="Unpublish Modified Page" mainAction={mainModalAction} size="S">
|
|
@@ -125,16 +79,13 @@ const UnpublishModal = (props: IModal): JSX.Element => {
|
|
|
125
79
|
);
|
|
126
80
|
};
|
|
127
81
|
|
|
128
|
-
interface IDeleteModal extends IModal {
|
|
129
|
-
title: string;
|
|
130
|
-
isTranslated: boolean;
|
|
131
|
-
deleteAllVersions: boolean;
|
|
132
|
-
setDeleteAllVersions: React.Dispatch<React.SetStateAction<boolean>>;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
82
|
interface IDuplicateModal extends IModal {
|
|
136
83
|
duplicateModalState: { title: string; slug: string };
|
|
137
84
|
setDuplicateModalState: React.Dispatch<React.SetStateAction<{ title: string; slug: string }>>;
|
|
85
|
+
onDuplicate: () => void;
|
|
86
|
+
isSaving: boolean;
|
|
138
87
|
}
|
|
139
88
|
|
|
140
|
-
|
|
89
|
+
interface IUnpublishModal extends IModal {}
|
|
90
|
+
|
|
91
|
+
export { DuplicateModal, UnpublishModal };
|
|
@@ -34,7 +34,8 @@ import type {
|
|
|
34
34
|
ISchemaField,
|
|
35
35
|
} from "@ax/types";
|
|
36
36
|
|
|
37
|
-
import { DeleteModal
|
|
37
|
+
import { DeleteModal } from "../../atoms";
|
|
38
|
+
import { DuplicateModal, UnpublishModal } from "./atoms";
|
|
38
39
|
import { getCurrentLanguages } from "./utils";
|
|
39
40
|
|
|
40
41
|
import * as S from "./style";
|
|
@@ -292,27 +293,8 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
292
293
|
|
|
293
294
|
menuOptions = globalPage.liveStatus?.status === pageStatus.PUBLISHED ? [viewOption, ...menuOptions] : menuOptions;
|
|
294
295
|
|
|
295
|
-
const handleCloseDuplicate = () => {
|
|
296
|
-
toggleModal("duplicate");
|
|
297
|
-
setDuplicateModalState({ title: "", slug: "" });
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
const mainDuplicateModalAction = {
|
|
301
|
-
title: "Duplicate",
|
|
302
|
-
onClick: handleDuplicatePage,
|
|
303
|
-
disabled: !duplicateModalState.title.trim() || !duplicateModalState.slug.trim() || isSaving,
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
const secondaryDuplicateModalAction = { title: "Cancel", onClick: handleCloseDuplicate };
|
|
307
|
-
|
|
308
296
|
const isTranslated = globalPage.pageLanguages.length > 1;
|
|
309
297
|
|
|
310
|
-
const mainDeleteModalAction = {
|
|
311
|
-
title: "Delete page",
|
|
312
|
-
onClick: removeItem,
|
|
313
|
-
};
|
|
314
|
-
const secondaryDeleteModalAction = { title: "Cancel", onClick: () => toggleModal("delete") };
|
|
315
|
-
|
|
316
298
|
const currentLanguages = getCurrentLanguages(languages, pageLanguages);
|
|
317
299
|
|
|
318
300
|
const changeLanguage = (language: { locale: string; id: number | null }) => {
|
|
@@ -376,8 +358,6 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
376
358
|
|
|
377
359
|
const getLiveStatus = () => (isScheduledPub ? "scheduled" : haveDraftPage ? "modified" : liveStatus.status);
|
|
378
360
|
|
|
379
|
-
const mainUnpublishAction = { title: "Ok", onClick: () => toggleModal("unpublish") };
|
|
380
|
-
|
|
381
361
|
const CategoryColumns = buildCategoryColumns(
|
|
382
362
|
categoryColumns,
|
|
383
363
|
activeColumns,
|
|
@@ -445,22 +425,22 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
445
425
|
<DuplicateModal
|
|
446
426
|
isOpen={isOpen("duplicate")}
|
|
447
427
|
toggleModal={() => toggleModal("duplicate")}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
{
|
|
428
|
+
duplicateModalState={duplicateModalState}
|
|
429
|
+
setDuplicateModalState={setDuplicateModalState}
|
|
430
|
+
onDuplicate={handleDuplicatePage}
|
|
431
|
+
isSaving={isSaving}
|
|
451
432
|
/>
|
|
452
433
|
<DeleteModal
|
|
453
434
|
isOpen={isOpen("delete")}
|
|
454
435
|
toggleModal={() => toggleModal("delete")}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
{
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
toggleModal={() => toggleModal("unpublish")}
|
|
462
|
-
mainModalAction={mainUnpublishAction}
|
|
436
|
+
title={globalPage.title}
|
|
437
|
+
arePagesTranslated={isTranslated}
|
|
438
|
+
deleteAllVersions={deleteAllVersions}
|
|
439
|
+
setDeleteAllVersions={setDeleteAllVersions}
|
|
440
|
+
onDelete={removeItem}
|
|
441
|
+
isDeleting={isSaving}
|
|
463
442
|
/>
|
|
443
|
+
<UnpublishModal isOpen={isOpen("unpublish")} toggleModal={() => toggleModal("unpublish")} />
|
|
464
444
|
</>
|
|
465
445
|
);
|
|
466
446
|
};
|
|
@@ -504,6 +484,8 @@ interface IGlobalPageItemProps {
|
|
|
504
484
|
skipReview?: boolean;
|
|
505
485
|
hoverCheck?: boolean;
|
|
506
486
|
isSaving: boolean;
|
|
487
|
+
isDeleting?: boolean;
|
|
488
|
+
onDeletingChange?(isDeleting: boolean): void;
|
|
507
489
|
}
|
|
508
490
|
|
|
509
491
|
const mapStateToProps = (state: IRootState) => ({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
1
2
|
import { connect } from "react-redux";
|
|
2
3
|
|
|
3
4
|
import { CheckField, Flag, FloatingMenu, Icon, LanguageMenu, Tooltip, TruncatedTooltip } from "@ax/components";
|
|
@@ -9,7 +10,7 @@ import {
|
|
|
9
10
|
getHumanLastModifiedDate,
|
|
10
11
|
getScheduleFormatDate,
|
|
11
12
|
} from "@ax/helpers";
|
|
12
|
-
import { usePermissions } from "@ax/hooks";
|
|
13
|
+
import { useModal, usePermissions } from "@ax/hooks";
|
|
13
14
|
import type {
|
|
14
15
|
ICheck,
|
|
15
16
|
IColumn,
|
|
@@ -23,6 +24,7 @@ import type {
|
|
|
23
24
|
IStructuredDataContent,
|
|
24
25
|
} from "@ax/types";
|
|
25
26
|
|
|
27
|
+
import { DeleteModal } from "../../atoms";
|
|
26
28
|
import { getPermission } from "./utils";
|
|
27
29
|
|
|
28
30
|
import * as S from "./style";
|
|
@@ -54,6 +56,7 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
54
56
|
currentSiteInfo,
|
|
55
57
|
hoverCheck,
|
|
56
58
|
getDataContent,
|
|
59
|
+
isSaving,
|
|
57
60
|
} = props;
|
|
58
61
|
|
|
59
62
|
const isPrivateData = currentStructuredData?.private || false;
|
|
@@ -66,11 +69,15 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
66
69
|
deletePages: getPermission("delete", isGlobal, isPrivateData),
|
|
67
70
|
});
|
|
68
71
|
|
|
72
|
+
const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();
|
|
73
|
+
const [deleteAllVersions, setDeleteAllVersions] = useState(false);
|
|
74
|
+
|
|
69
75
|
const { locale } = lang;
|
|
70
76
|
const { dataLanguages, publicationScheduled } = structuredData;
|
|
71
77
|
|
|
72
78
|
const isScheduledPub = !!publicationScheduled && structuredData.draft;
|
|
73
79
|
const activeColumns = columns.filter((col) => col.show).map((col) => col.id);
|
|
80
|
+
const arePagesTranslated = dataLanguages.length > 1;
|
|
74
81
|
|
|
75
82
|
const publishedTooltip: Record<string, string> = {
|
|
76
83
|
active: "Live",
|
|
@@ -88,13 +95,14 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
88
95
|
|
|
89
96
|
const handleOnChange = (value: ICheck) => onChange(value);
|
|
90
97
|
|
|
91
|
-
const removeItem = async () =>
|
|
92
|
-
deleteStructuredDataContent(structuredData.id)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
const removeItem = async () => {
|
|
99
|
+
const deleted = await deleteStructuredDataContent(structuredData.id);
|
|
100
|
+
if (deleted) {
|
|
101
|
+
setDeletedItem(structuredData.id);
|
|
102
|
+
toggleToast();
|
|
103
|
+
}
|
|
104
|
+
toggleDeleteModal();
|
|
105
|
+
};
|
|
98
106
|
|
|
99
107
|
const publishItem = async () => setDataStatus(structuredData.id, "undraft");
|
|
100
108
|
|
|
@@ -200,7 +208,7 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
200
208
|
menuOptions.push({
|
|
201
209
|
label: "delete",
|
|
202
210
|
icon: "delete",
|
|
203
|
-
action:
|
|
211
|
+
action: toggleDeleteModal,
|
|
204
212
|
});
|
|
205
213
|
}
|
|
206
214
|
|
|
@@ -222,38 +230,50 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
222
230
|
);
|
|
223
231
|
|
|
224
232
|
return (
|
|
225
|
-
|
|
226
|
-
<S.
|
|
227
|
-
<
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
<
|
|
236
|
-
<
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
<
|
|
242
|
-
<
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
<S.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
<S.
|
|
255
|
-
|
|
256
|
-
|
|
233
|
+
<>
|
|
234
|
+
<S.StructuredDataRow role="rowgroup" selected={isSelected} disabled={!isEditable}>
|
|
235
|
+
<S.CheckCell role="cell">
|
|
236
|
+
<CheckField
|
|
237
|
+
name="check"
|
|
238
|
+
value={structuredData.id}
|
|
239
|
+
checked={isSelected || hoverCheck}
|
|
240
|
+
onChange={handleOnChange}
|
|
241
|
+
/>
|
|
242
|
+
</S.CheckCell>
|
|
243
|
+
<S.NameCell role="cell" onClick={_handleClick}>
|
|
244
|
+
<TruncatedTooltip content={structuredData.content.title} expanded top={1}>
|
|
245
|
+
<S.Title>{structuredData.content.title}</S.Title>
|
|
246
|
+
</TruncatedTooltip>
|
|
247
|
+
</S.NameCell>
|
|
248
|
+
{activeColumns.includes("live") && (
|
|
249
|
+
<S.LiveCell role="cell" onClick={_handleClick}>
|
|
250
|
+
<Tooltip content={publishedTooltip[checkStatus()]}>
|
|
251
|
+
<Icon name={checkStatus()} />
|
|
252
|
+
</Tooltip>
|
|
253
|
+
</S.LiveCell>
|
|
254
|
+
)}
|
|
255
|
+
{CategoryColumns}
|
|
256
|
+
{activeColumns.includes("status") && (
|
|
257
|
+
<S.StatusCell role="cell" onClick={_handleClick}>
|
|
258
|
+
<S.ModDate>{`Mod. ${getHumanLastModifiedDate(structuredData.modified)}`}</S.ModDate>
|
|
259
|
+
</S.StatusCell>
|
|
260
|
+
)}
|
|
261
|
+
{activeColumns.includes("translation") && <S.TransCell role="cell">{translations}</S.TransCell>}
|
|
262
|
+
<S.ActionsCell role="cell">
|
|
263
|
+
<S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />
|
|
264
|
+
</S.ActionsCell>
|
|
265
|
+
</S.StructuredDataRow>
|
|
266
|
+
<DeleteModal
|
|
267
|
+
isOpen={isDeleteOpen}
|
|
268
|
+
toggleModal={toggleDeleteModal}
|
|
269
|
+
title={structuredData.content.title}
|
|
270
|
+
arePagesTranslated={arePagesTranslated}
|
|
271
|
+
deleteAllVersions={deleteAllVersions}
|
|
272
|
+
setDeleteAllVersions={setDeleteAllVersions}
|
|
273
|
+
onDelete={removeItem}
|
|
274
|
+
isDeleting={isSaving}
|
|
275
|
+
/>
|
|
276
|
+
</>
|
|
257
277
|
);
|
|
258
278
|
};
|
|
259
279
|
|
|
@@ -283,11 +303,13 @@ interface IStructuredDataItemProps {
|
|
|
283
303
|
setCurrentDataID(id: number | null): void;
|
|
284
304
|
currentSiteInfo: ISite | null;
|
|
285
305
|
hoverCheck?: boolean;
|
|
306
|
+
isSaving: boolean;
|
|
286
307
|
}
|
|
287
308
|
|
|
288
309
|
const mapStateToProps = (state: IRootState) => ({
|
|
289
310
|
currentStructuredData: state.structuredData.currentStructuredData,
|
|
290
311
|
currentSiteInfo: state.sites.currentSiteInfo,
|
|
312
|
+
isSaving: state.app.isSaving,
|
|
291
313
|
});
|
|
292
314
|
|
|
293
315
|
const mapDispatchToProps = {
|