@griddo/ax 11.10.41 → 11.10.42
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/components/BulkSelectionOptions/index.tsx +78 -28
- package/src/components/BulkSelectionOptions/style.tsx +7 -1
- package/src/components/BulkSelectionOptions/utils.tsx +25 -0
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +2 -2
- package/src/components/ConfigPanel/GlobalPageForm/index.tsx +14 -4
- package/src/components/ConfigPanel/index.tsx +6 -0
- package/src/components/Fields/ComponentArray/SameComponentArray/index.tsx +9 -9
- package/src/components/Fields/ReferenceField/ItemList/Item/index.tsx +5 -6
- package/src/components/Fields/ReferenceField/ItemList/Item/style.tsx +16 -10
- package/src/components/Fields/ReferenceField/ManualPanel/Item/index.tsx +3 -4
- package/src/components/Fields/ReferenceField/ManualPanel/Item/style.tsx +7 -1
- package/src/components/Fields/VisualUniqueSelection/ScrollableSelection/index.tsx +3 -3
- package/src/components/Fields/VisualUniqueSelection/index.tsx +2 -4
- package/src/components/FloatingMenu/index.tsx +5 -5
- package/src/components/Loader/components/SmallCircle.js +29 -0
- package/src/components/Loader/index.tsx +3 -2
- package/src/components/MainWrapper/AppBar/atoms.tsx +4 -6
- package/src/components/MainWrapper/AppBar/index.tsx +14 -12
- package/src/components/MainWrapper/AppBar/style.tsx +23 -18
- package/src/components/MainWrapper/index.tsx +3 -3
- package/src/components/OcassionalToast/index.tsx +1 -1
- package/src/components/OcassionalToast/style.tsx +6 -0
- package/src/components/PageFinder/SelectionListItem/index.tsx +5 -4
- package/src/components/PageFinder/SelectionListItem/style.tsx +7 -1
- package/src/components/PageFinder/index.tsx +1 -0
- package/src/constants/index.ts +27 -0
- package/src/forms/elements.tsx +8 -24
- package/src/forms/index.tsx +0 -2
- package/src/helpers/containerEvaluations.tsx +5 -0
- package/src/helpers/content.ts +35 -0
- package/src/helpers/index.tsx +91 -89
- package/src/helpers/strings.tsx +19 -0
- package/src/helpers/types.ts +1 -0
- package/src/hooks/forms.tsx +2 -1
- package/src/locales/en-US.ts +29 -0
- package/src/locales/es-ES.ts +29 -0
- package/src/locales/index.ts +11 -0
- package/src/modules/Categories/CategoriesList/BulkHeader/index.tsx +5 -0
- package/src/modules/Categories/CategoriesList/index.tsx +10 -4
- package/src/modules/Content/BulkHeader/index.tsx +11 -0
- package/src/modules/Content/PageItem/index.tsx +1 -0
- package/src/modules/Content/atoms.tsx +1 -1
- package/src/modules/Content/index.tsx +27 -2
- package/src/modules/FileDrive/BulkGridHeader/index.tsx +6 -1
- package/src/modules/FileDrive/BulkListHeader/index.tsx +5 -0
- package/src/modules/FileDrive/index.tsx +10 -0
- package/src/modules/Forms/FormCategoriesList/BulkHeader/index.tsx +15 -2
- package/src/modules/Forms/FormCategoriesList/index.tsx +8 -0
- package/src/modules/Forms/FormEditor/index.tsx +10 -1
- package/src/modules/Forms/FormList/BulkHeader/index.tsx +5 -0
- package/src/modules/Forms/FormList/index.tsx +12 -3
- package/src/modules/Forms/FormUseModal/FormUseItem/index.tsx +1 -2
- package/src/modules/Forms/FormUseModal/index.tsx +3 -3
- package/src/modules/GlobalEditor/index.tsx +1 -0
- package/src/modules/MediaGallery/BulkGridHeader/index.tsx +6 -1
- package/src/modules/MediaGallery/BulkListHeader/index.tsx +15 -2
- package/src/modules/MediaGallery/index.tsx +47 -36
- package/src/modules/Navigation/Defaults/BulkHeader/index.tsx +5 -0
- package/src/modules/Navigation/Defaults/index.tsx +26 -23
- package/src/modules/PageEditor/Editor/index.tsx +6 -0
- package/src/modules/PageEditor/index.tsx +52 -0
- package/src/modules/Redirects/BulkHeader/index.tsx +6 -1
- package/src/modules/Redirects/index.tsx +7 -2
- package/src/modules/Settings/Integrations/BulkHeader/index.tsx +5 -0
- package/src/modules/Settings/Integrations/index.tsx +7 -1
- package/src/modules/Sites/SitesList/ListView/BulkHeader/index.tsx +5 -0
- package/src/modules/Sites/SitesList/index.tsx +7 -2
- package/src/modules/StructuredData/Form/index.tsx +1 -0
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +5 -0
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/atoms.tsx +3 -2
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +17 -11
- package/src/modules/StructuredData/StructuredDataList/index.tsx +6 -0
- package/src/modules/Users/Roles/BulkHeader/index.tsx +5 -0
- package/src/modules/Users/Roles/index.tsx +6 -1
- package/src/modules/Users/UserList/BulkHeader/index.tsx +5 -0
- package/src/modules/Users/UserList/index.tsx +12 -7
- package/tsconfig.paths.json +4 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { itemLabel } from "@ax/constants";
|
|
1
2
|
import type { IBulkSelectedItems } from "@ax/hooks";
|
|
2
3
|
import type { IBulkAction } from "@ax/types";
|
|
3
4
|
|
|
@@ -6,7 +7,8 @@ import GridHeader from "./GridHeader";
|
|
|
6
7
|
import * as S from "./style";
|
|
7
8
|
|
|
8
9
|
const BulkGridHeader = (props: IBulkHeaderProps): JSX.Element => {
|
|
9
|
-
const { showBulk, checkState, selectItems, selectAllItems, totalItems, bulkActions, selectedItems } =
|
|
10
|
+
const { showBulk, checkState, selectItems, selectAllItems, totalItems, bulkActions, selectedItems, isLoading } =
|
|
11
|
+
props;
|
|
10
12
|
|
|
11
13
|
return showBulk ? (
|
|
12
14
|
<S.BulkWrapper>
|
|
@@ -17,6 +19,8 @@ const BulkGridHeader = (props: IBulkHeaderProps): JSX.Element => {
|
|
|
17
19
|
selectItems={selectItems}
|
|
18
20
|
totalItems={totalItems}
|
|
19
21
|
selectedItems={selectedItems}
|
|
22
|
+
isLoading={isLoading}
|
|
23
|
+
itemLabel={itemLabel.IMAGE}
|
|
20
24
|
/>
|
|
21
25
|
</S.BulkWrapper>
|
|
22
26
|
) : (
|
|
@@ -32,6 +36,7 @@ export interface IBulkHeaderProps {
|
|
|
32
36
|
totalItems: number;
|
|
33
37
|
bulkActions: IBulkAction[];
|
|
34
38
|
selectedItems: IBulkSelectedItems;
|
|
39
|
+
isLoading: boolean;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
export default BulkGridHeader;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { itemLabel } from "@ax/constants";
|
|
1
2
|
import type { IBulkSelectedItems } from "@ax/hooks";
|
|
2
3
|
import type { IBulkAction } from "@ax/types";
|
|
3
4
|
|
|
@@ -6,8 +7,17 @@ import TableHeader from "./TableHeader";
|
|
|
6
7
|
import * as S from "./style";
|
|
7
8
|
|
|
8
9
|
const BulkListHeader = (props: IBulkHeaderProps): JSX.Element => {
|
|
9
|
-
const {
|
|
10
|
-
|
|
10
|
+
const {
|
|
11
|
+
showBulk,
|
|
12
|
+
checkState,
|
|
13
|
+
selectItems,
|
|
14
|
+
selectAllItems,
|
|
15
|
+
totalItems,
|
|
16
|
+
bulkActions,
|
|
17
|
+
setHoverCheck,
|
|
18
|
+
selectedItems,
|
|
19
|
+
isLoading,
|
|
20
|
+
} = props;
|
|
11
21
|
|
|
12
22
|
return showBulk ? (
|
|
13
23
|
<S.BulkWrapper>
|
|
@@ -18,6 +28,8 @@ const BulkListHeader = (props: IBulkHeaderProps): JSX.Element => {
|
|
|
18
28
|
selectItems={selectItems}
|
|
19
29
|
totalItems={totalItems}
|
|
20
30
|
selectedItems={selectedItems}
|
|
31
|
+
isLoading={isLoading}
|
|
32
|
+
itemLabel={itemLabel.IMAGE}
|
|
21
33
|
/>
|
|
22
34
|
</S.BulkWrapper>
|
|
23
35
|
) : (
|
|
@@ -40,6 +52,7 @@ export interface IBulkHeaderProps {
|
|
|
40
52
|
bulkActions: IBulkAction[];
|
|
41
53
|
setHoverCheck: (state: boolean) => void;
|
|
42
54
|
selectedItems: IBulkSelectedItems;
|
|
55
|
+
isLoading: boolean;
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
export default BulkListHeader;
|
|
@@ -86,10 +86,11 @@ const MediaGallery = (props: IProps) => {
|
|
|
86
86
|
const firstPage = 1;
|
|
87
87
|
const lastPage = Math.ceil(totalItems / itemsPerPage);
|
|
88
88
|
const [page, setPage] = useState(firstPage);
|
|
89
|
+
const [isBulkLoading, setIsBulkLoading] = useState(false);
|
|
89
90
|
const [isPanelOpen, setPanelOpen] = useState(false);
|
|
90
91
|
const [fileSelected, setFileSelected] = useState<IImage | null>(null);
|
|
91
92
|
const [selectedFolder, setSelectedFolder] = useState<number | null>(currentFolderID || null);
|
|
92
|
-
const imagesIds
|
|
93
|
+
const imagesIds = items?.map((image) => image.id) || [];
|
|
93
94
|
const [galleryItems, setGalleryItems] = useState<number[]>(imagesIds);
|
|
94
95
|
const [galleryDelete, setGalleryDelete] = useState(true);
|
|
95
96
|
const [progressItems, setProgressItems] = useState<IProgressState>({
|
|
@@ -381,6 +382,7 @@ const MediaGallery = (props: IProps) => {
|
|
|
381
382
|
};
|
|
382
383
|
|
|
383
384
|
const handleBulkDeleteFile = async () => {
|
|
385
|
+
setIsBulkLoading(true);
|
|
384
386
|
const params = getParams();
|
|
385
387
|
const resetedParams = { ...params, page: firstPage, infinite: false, loading: true };
|
|
386
388
|
const isDeleted = await deleteImage(selectedItems.all, resetedParams);
|
|
@@ -389,18 +391,22 @@ const MediaGallery = (props: IProps) => {
|
|
|
389
391
|
resetBulkSelection();
|
|
390
392
|
}
|
|
391
393
|
toggleDeleteModal();
|
|
394
|
+
setIsBulkLoading(false);
|
|
392
395
|
};
|
|
393
396
|
|
|
394
397
|
const handleMoveImage = async (imageID: number, folderID: number | "root") => {
|
|
398
|
+
setIsBulkLoading(true);
|
|
395
399
|
const params = getParams();
|
|
396
400
|
const resetedParams = { ...params, page: firstPage, infinite: false, loading: true };
|
|
397
401
|
const isMoved = await moveImage(imageID, folderID, resetedParams);
|
|
398
402
|
if (isMoved) {
|
|
399
403
|
toggleToast("1 Image moved to a folder");
|
|
400
404
|
}
|
|
405
|
+
setIsBulkLoading(false);
|
|
401
406
|
};
|
|
402
407
|
|
|
403
408
|
const handleBulkMoveFile = async () => {
|
|
409
|
+
setIsBulkLoading(true);
|
|
404
410
|
const params = getParams();
|
|
405
411
|
const resetedParams = { ...params, page: firstPage, infinite: false, loading: true };
|
|
406
412
|
const isMoved = await moveImage(selectedItems.all, selectedFolder || "root", resetedParams);
|
|
@@ -410,6 +416,7 @@ const MediaGallery = (props: IProps) => {
|
|
|
410
416
|
setSelectedFolder(0);
|
|
411
417
|
resetBulkSelection();
|
|
412
418
|
}
|
|
419
|
+
setIsBulkLoading(false);
|
|
413
420
|
};
|
|
414
421
|
|
|
415
422
|
const handleBulkEditFile = () => {
|
|
@@ -435,9 +442,11 @@ const MediaGallery = (props: IProps) => {
|
|
|
435
442
|
};
|
|
436
443
|
|
|
437
444
|
const handleDownloadBulk = async () => {
|
|
445
|
+
setIsBulkLoading(true);
|
|
438
446
|
const fileName = isSiteView ? `${currentSiteInfo.name}-images.zip` : "global-images.zip";
|
|
439
447
|
await downloadImages(selectedItems.all, true, fileName);
|
|
440
448
|
resetBulkSelection();
|
|
449
|
+
setIsBulkLoading(false);
|
|
441
450
|
};
|
|
442
451
|
|
|
443
452
|
const handleUpdateCurrentFolder = (folderID: number | null) => {
|
|
@@ -513,6 +522,7 @@ const MediaGallery = (props: IProps) => {
|
|
|
513
522
|
bulkActions={bulkActions}
|
|
514
523
|
setHoverCheck={setHoverCheck}
|
|
515
524
|
selectedItems={selectedItems}
|
|
525
|
+
isLoading={isBulkLoading}
|
|
516
526
|
/>
|
|
517
527
|
);
|
|
518
528
|
|
|
@@ -525,23 +535,23 @@ const MediaGallery = (props: IProps) => {
|
|
|
525
535
|
<UploadItem uploadPercentage={progress} grid={true} key={index} />
|
|
526
536
|
))}
|
|
527
537
|
{items?.map((image: IImage) => {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
538
|
+
const isItemSelected = isSelected(image.id);
|
|
539
|
+
return (
|
|
540
|
+
<GridItem
|
|
541
|
+
image={image}
|
|
542
|
+
isSelected={isItemSelected}
|
|
543
|
+
onChange={addToBulkSelection}
|
|
544
|
+
key={`${image.name}${image.id}`}
|
|
545
|
+
onClick={handleClick}
|
|
546
|
+
onDelete={handleDeleteFile}
|
|
547
|
+
onMove={handleMoveImage}
|
|
548
|
+
currentFolderID={currentFolderID}
|
|
549
|
+
isAllowedToDelete={allowedToDeleteFile}
|
|
550
|
+
isAllowedToEdit={allowedToEditFile}
|
|
551
|
+
isAllowedToMove={!isRoot || (isRoot && (folders.length > 0 || isSearching))}
|
|
552
|
+
/>
|
|
553
|
+
);
|
|
554
|
+
})}
|
|
545
555
|
</S.GridWrapper>
|
|
546
556
|
);
|
|
547
557
|
|
|
@@ -566,24 +576,24 @@ const MediaGallery = (props: IProps) => {
|
|
|
566
576
|
<UploadItem uploadPercentage={progress} grid={false} key={index} />
|
|
567
577
|
))}
|
|
568
578
|
{items?.map((image: IImage) => {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
579
|
+
const isItemSelected = isSelected(image.id);
|
|
580
|
+
return (
|
|
581
|
+
<ListItem
|
|
582
|
+
image={image}
|
|
583
|
+
isSelected={isItemSelected}
|
|
584
|
+
onChange={addToBulkSelection}
|
|
585
|
+
key={`${image.name}${image.id}`}
|
|
586
|
+
onClick={handleClick}
|
|
587
|
+
onDelete={handleDeleteFile}
|
|
588
|
+
onMove={handleMoveImage}
|
|
589
|
+
currentFolderID={currentFolderID}
|
|
590
|
+
isAllowedToDelete={allowedToDeleteFile}
|
|
591
|
+
isAllowedToEdit={allowedToEditFile}
|
|
592
|
+
isAllowedToMove={!isRoot || (isRoot && (folders.length > 0 || isSearching))}
|
|
593
|
+
hoverCheck={checkState.hoverCheck}
|
|
594
|
+
/>
|
|
595
|
+
);
|
|
596
|
+
})}
|
|
587
597
|
</>
|
|
588
598
|
</TableList>
|
|
589
599
|
);
|
|
@@ -770,6 +780,7 @@ const MediaGallery = (props: IProps) => {
|
|
|
770
780
|
selectItems={selectItems}
|
|
771
781
|
bulkActions={bulkActions}
|
|
772
782
|
selectedItems={selectedItems}
|
|
783
|
+
isLoading={isBulkLoading}
|
|
773
784
|
/>
|
|
774
785
|
)}
|
|
775
786
|
{!hasFolders && isRoot && !isSearching && <NewFolderButton />}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BulkSelectionOptions } from "@ax/components";
|
|
2
|
+
import { itemLabel } from "@ax/constants";
|
|
2
3
|
import type { IBulkSelectedItems } from "@ax/hooks";
|
|
3
4
|
|
|
4
5
|
import TableHeader from "./TableHeader";
|
|
@@ -14,6 +15,7 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
14
15
|
isScrolling,
|
|
15
16
|
setHoverCheck,
|
|
16
17
|
selectedItems,
|
|
18
|
+
isLoading,
|
|
17
19
|
} = props;
|
|
18
20
|
|
|
19
21
|
return showBulk ? (
|
|
@@ -23,6 +25,8 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
23
25
|
selectItems={selectItems}
|
|
24
26
|
totalItems={totalItems}
|
|
25
27
|
selectedItems={selectedItems}
|
|
28
|
+
isLoading={isLoading}
|
|
29
|
+
itemLabel={itemLabel.NAVIGATION}
|
|
26
30
|
/>
|
|
27
31
|
) : (
|
|
28
32
|
<TableHeader
|
|
@@ -45,6 +49,7 @@ interface IProps {
|
|
|
45
49
|
isScrolling: boolean;
|
|
46
50
|
setHoverCheck: (state: boolean) => void;
|
|
47
51
|
selectedItems: IBulkSelectedItems;
|
|
52
|
+
isLoading: boolean;
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
export default BulkHeader;
|
|
@@ -13,6 +13,7 @@ import BulkHeader from "./BulkHeader";
|
|
|
13
13
|
import DefaultItem from "./Item";
|
|
14
14
|
import DefaultNav from "./Nav";
|
|
15
15
|
import ReplaceNavModal from "./ReplaceNavModal";
|
|
16
|
+
|
|
16
17
|
import * as S from "./style";
|
|
17
18
|
|
|
18
19
|
const DefaultsList = (props: IProps): JSX.Element => {
|
|
@@ -36,6 +37,7 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
36
37
|
currentSiteInfo,
|
|
37
38
|
} = props;
|
|
38
39
|
|
|
40
|
+
const [isBulkLoading, setIsBulkLoading] = useState(false);
|
|
39
41
|
const [page, setPage] = useState(1);
|
|
40
42
|
const [deletedNav, setDeletedNav] = useState<number | number[] | null>(null);
|
|
41
43
|
const [updatedPages, setUpdatedPages] = useState<number | null>(null);
|
|
@@ -51,7 +53,7 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
51
53
|
const isAllowedToDeleteHeaders = usePermission("navigation.deleteSiteHeaders") && selectedDefault === "Headers";
|
|
52
54
|
const isAllowedToDeleteFooters = usePermission("navigation.deleteSiteFooters") && selectedDefault === "Footers";
|
|
53
55
|
|
|
54
|
-
const navIds = currentDefaultsContent
|
|
56
|
+
const navIds = currentDefaultsContent?.map((nav: any) => nav.id);
|
|
55
57
|
|
|
56
58
|
const {
|
|
57
59
|
resetBulkSelection,
|
|
@@ -108,8 +110,7 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
108
110
|
// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
|
|
109
111
|
useEffect(() => {
|
|
110
112
|
const isNavigationModulesChanged =
|
|
111
|
-
currentSiteInfo &&
|
|
112
|
-
currentSiteInfo.navigationModules?.[currentType] &&
|
|
113
|
+
currentSiteInfo?.navigationModules?.[currentType] &&
|
|
113
114
|
currentDefaultsContent.some(
|
|
114
115
|
(navigation) => navigation.component !== currentSiteInfo?.navigationModules[currentType],
|
|
115
116
|
);
|
|
@@ -175,11 +176,13 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
175
176
|
const handleErrorAction = () => toggleReplaceModal();
|
|
176
177
|
|
|
177
178
|
const bulkDelete = async () => {
|
|
179
|
+
setIsBulkLoading(true);
|
|
178
180
|
const deleted = await deleteNavigation(selectedItems.all, currentType, handleErrorAction);
|
|
179
181
|
setDeletedNav(selectedItems.all);
|
|
180
182
|
if (deleted) {
|
|
181
183
|
toggleToast();
|
|
182
184
|
}
|
|
185
|
+
setIsBulkLoading(false);
|
|
183
186
|
};
|
|
184
187
|
|
|
185
188
|
const unselectAllItems = () => resetBulkSelection();
|
|
@@ -212,6 +215,7 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
212
215
|
checkState={checkState}
|
|
213
216
|
isScrolling={isScrolling}
|
|
214
217
|
setHoverCheck={setHoverCheck}
|
|
218
|
+
isLoading={isBulkLoading}
|
|
215
219
|
/>
|
|
216
220
|
);
|
|
217
221
|
|
|
@@ -248,26 +252,25 @@ const DefaultsList = (props: IProps): JSX.Element => {
|
|
|
248
252
|
hasFixedHeader={true}
|
|
249
253
|
tableRef={tableRef}
|
|
250
254
|
>
|
|
251
|
-
{currentDefaultsContent
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
})}
|
|
255
|
+
{currentDefaultsContent?.map((defaultContent: IHeader | IFooter) => {
|
|
256
|
+
const isItemSelected = isSelected(defaultContent.id);
|
|
257
|
+
return (
|
|
258
|
+
<DefaultItem
|
|
259
|
+
defaultContent={defaultContent}
|
|
260
|
+
key={defaultContent.id}
|
|
261
|
+
languages={siteLanguages}
|
|
262
|
+
lang={lang}
|
|
263
|
+
toggleToast={toggleToast}
|
|
264
|
+
setDeletedNav={setDeletedNav}
|
|
265
|
+
isSelected={isItemSelected}
|
|
266
|
+
onChange={addToBulkSelection}
|
|
267
|
+
handleClick={setContent}
|
|
268
|
+
setHistoryPush={setHistoryPush}
|
|
269
|
+
toggleReplaceModal={toggleReplaceModal}
|
|
270
|
+
hoverCheck={checkState.hoverCheck}
|
|
271
|
+
/>
|
|
272
|
+
);
|
|
273
|
+
})}
|
|
271
274
|
</TableList>
|
|
272
275
|
</S.TableWrapper>
|
|
273
276
|
{isVisible && <Toast {...toastProps} />}
|
|
@@ -43,6 +43,8 @@ const Editor = (props: IProps) => {
|
|
|
43
43
|
content,
|
|
44
44
|
isEditLive,
|
|
45
45
|
isDisabled,
|
|
46
|
+
isDirty,
|
|
47
|
+
onNavigateWithDirty,
|
|
46
48
|
} = props;
|
|
47
49
|
|
|
48
50
|
if (!site) {
|
|
@@ -101,6 +103,8 @@ const Editor = (props: IProps) => {
|
|
|
101
103
|
footer={footer}
|
|
102
104
|
isEditLive={isEditLive}
|
|
103
105
|
isDisabled={isDisabled}
|
|
106
|
+
isDirty={isDirty}
|
|
107
|
+
onNavigateWithDirty={onNavigateWithDirty}
|
|
104
108
|
/>
|
|
105
109
|
}
|
|
106
110
|
/>
|
|
@@ -146,6 +150,8 @@ interface IPageBrowserDispatchProps {
|
|
|
146
150
|
browserRef: any;
|
|
147
151
|
isEditLive: boolean;
|
|
148
152
|
isDisabled: boolean;
|
|
153
|
+
isDirty?: boolean;
|
|
154
|
+
onNavigateWithDirty?: (navigateCallback: () => void) => void;
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -93,6 +93,8 @@ const PageEditor = (props: IProps) => {
|
|
|
93
93
|
const { isOpen: isScheduleOpen, toggleModal: toggleScheduleModal } = useModal();
|
|
94
94
|
const { isOpen: isCancelScheduleOpen, toggleModal: toggleCancelScheduleModal } = useModal();
|
|
95
95
|
const { isOpen: isRestoreOpen, toggleModal: toggleRestoreModal } = useModal();
|
|
96
|
+
const { isOpen: isDirtyNavigateOpen, toggleModal: toggleDirtyNavigateModal } = useModal();
|
|
97
|
+
const [pendingNavigateCallback, setPendingNavigateCallback] = useState<(() => void) | null>(null);
|
|
96
98
|
const [errorPagesChecked, setErrorPagesChecked] = useState(false);
|
|
97
99
|
const browserRef = useRef<HTMLDivElement>(null);
|
|
98
100
|
|
|
@@ -616,6 +618,40 @@ const PageEditor = (props: IProps) => {
|
|
|
616
618
|
}
|
|
617
619
|
};
|
|
618
620
|
|
|
621
|
+
const onNavigateWithDirty = (navigateCallback: () => void) => {
|
|
622
|
+
setPendingNavigateCallback(() => navigateCallback);
|
|
623
|
+
toggleDirtyNavigateModal();
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
const handleConfirmDirtyNavigation = () => {
|
|
627
|
+
toggleDirtyNavigateModal();
|
|
628
|
+
if (pendingNavigateCallback) {
|
|
629
|
+
pendingNavigateCallback();
|
|
630
|
+
setPendingNavigateCallback(null);
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
const handleCancelDirtyNavigation = () => {
|
|
635
|
+
toggleDirtyNavigateModal();
|
|
636
|
+
setPendingNavigateCallback(null);
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
const dirtyNavigateModalText = (
|
|
640
|
+
<>
|
|
641
|
+
Some content <strong>is not saved</strong> on this page.
|
|
642
|
+
</>
|
|
643
|
+
);
|
|
644
|
+
|
|
645
|
+
const mainDirtyNavigateAction = {
|
|
646
|
+
title: "Yes, discard changes",
|
|
647
|
+
onClick: handleConfirmDirtyNavigation,
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
const secondaryDirtyNavigateAction = {
|
|
651
|
+
title: "Cancel",
|
|
652
|
+
onClick: handleCancelDirtyNavigation,
|
|
653
|
+
};
|
|
654
|
+
|
|
619
655
|
return isLoading ? (
|
|
620
656
|
<Loading />
|
|
621
657
|
) : (
|
|
@@ -642,6 +678,7 @@ const PageEditor = (props: IProps) => {
|
|
|
642
678
|
tabs={tabsPreview}
|
|
643
679
|
isDirty={isDirty}
|
|
644
680
|
scheduledPublication={editorContent?.publicationScheduled}
|
|
681
|
+
isSaving={isSaving}
|
|
645
682
|
>
|
|
646
683
|
{selectedTab === "edit" ? (
|
|
647
684
|
<>
|
|
@@ -693,6 +730,8 @@ const PageEditor = (props: IProps) => {
|
|
|
693
730
|
setNotification={setNotification}
|
|
694
731
|
isEditLive={isEditLive}
|
|
695
732
|
isDisabled={isDeleted}
|
|
733
|
+
isDirty={isDirty}
|
|
734
|
+
onNavigateWithDirty={onNavigateWithDirty}
|
|
696
735
|
/>
|
|
697
736
|
</S.Content>
|
|
698
737
|
</>
|
|
@@ -766,6 +805,19 @@ const PageEditor = (props: IProps) => {
|
|
|
766
805
|
restorePage: handleRestorePage,
|
|
767
806
|
}}
|
|
768
807
|
/>
|
|
808
|
+
<Modal
|
|
809
|
+
isOpen={isDirtyNavigateOpen}
|
|
810
|
+
hide={handleCancelDirtyNavigation}
|
|
811
|
+
size="S"
|
|
812
|
+
title="Unsaved changes"
|
|
813
|
+
mainAction={mainDirtyNavigateAction}
|
|
814
|
+
secondaryAction={secondaryDirtyNavigateAction}
|
|
815
|
+
>
|
|
816
|
+
<S.ModalContent>
|
|
817
|
+
{dirtyNavigateModalText} If you exit without saving it, it will be lost. Do you want to discard
|
|
818
|
+
your changes?
|
|
819
|
+
</S.ModalContent>
|
|
820
|
+
</Modal>
|
|
769
821
|
</MainWrapper>
|
|
770
822
|
</>
|
|
771
823
|
);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BulkSelectionOptions } from "@ax/components";
|
|
2
|
+
import { itemLabel } from "@ax/constants";
|
|
2
3
|
import type { IQueryValue } from "@ax/types";
|
|
3
4
|
|
|
4
|
-
import { IBulkSelectedItems } from "src/hooks/bulk";
|
|
5
|
+
import type { IBulkSelectedItems } from "src/hooks/bulk";
|
|
5
6
|
|
|
6
7
|
import TableHeader from "./TableHeader";
|
|
7
8
|
|
|
@@ -21,6 +22,7 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
21
22
|
sortedListStatus,
|
|
22
23
|
setHoverCheck,
|
|
23
24
|
selectedItems,
|
|
25
|
+
isLoading,
|
|
24
26
|
} = props;
|
|
25
27
|
|
|
26
28
|
const bulkActions = [
|
|
@@ -38,6 +40,8 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
38
40
|
selectItems={selectItems}
|
|
39
41
|
totalItems={totalItems}
|
|
40
42
|
selectedItems={selectedItems}
|
|
43
|
+
isLoading={isLoading}
|
|
44
|
+
itemLabel={itemLabel.REDIRECT}
|
|
41
45
|
/>
|
|
42
46
|
) : (
|
|
43
47
|
<TableHeader
|
|
@@ -70,6 +74,7 @@ interface IProps {
|
|
|
70
74
|
sortedListStatus: { isAscending: boolean; sortedByDate: boolean };
|
|
71
75
|
setHoverCheck: (state: boolean) => void;
|
|
72
76
|
selectedItems: IBulkSelectedItems;
|
|
77
|
+
isLoading: boolean;
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
export default BulkHeader;
|
|
@@ -21,9 +21,10 @@ import BulkHeader from "./BulkHeader";
|
|
|
21
21
|
import { useFilterQuery, useSortedListStatus } from "./hooks";
|
|
22
22
|
import RedirectItem from "./RedirectItem";
|
|
23
23
|
import RedirectPanel from "./RedirectPanel";
|
|
24
|
-
import * as S from "./style";
|
|
25
24
|
import { getSortedListStatus } from "./utils";
|
|
26
25
|
|
|
26
|
+
import * as S from "./style";
|
|
27
|
+
|
|
27
28
|
const Redirects = (props: IProps): JSX.Element => {
|
|
28
29
|
const {
|
|
29
30
|
navItems,
|
|
@@ -45,6 +46,7 @@ const Redirects = (props: IProps): JSX.Element => {
|
|
|
45
46
|
const firstPage = 1;
|
|
46
47
|
const [page, setPage] = useState(1);
|
|
47
48
|
const [isScrolling, setIsScrolling] = useState(false);
|
|
49
|
+
const [isBulkLoading, setIsBulkLoading] = useState(false);
|
|
48
50
|
const [isOpenedSecond, setIsOpenedSecond] = useState(false);
|
|
49
51
|
const { isOpen, toggleModal } = useModal();
|
|
50
52
|
const { isOpen: isOpenDelete, toggleModal: toggleModalDelete } = useModal();
|
|
@@ -73,7 +75,7 @@ const Redirects = (props: IProps): JSX.Element => {
|
|
|
73
75
|
|
|
74
76
|
const [formValues, setFormValues] = useState<IRedirect>(initState);
|
|
75
77
|
|
|
76
|
-
const redIds = redirects
|
|
78
|
+
const redIds = redirects?.map((red: any) => red.id);
|
|
77
79
|
|
|
78
80
|
const getParams = useCallback(() => {
|
|
79
81
|
const params = {
|
|
@@ -127,11 +129,13 @@ const Redirects = (props: IProps): JSX.Element => {
|
|
|
127
129
|
} = useBulkSelection(redIds);
|
|
128
130
|
|
|
129
131
|
const bulkDelete = async () => {
|
|
132
|
+
setIsBulkLoading(true);
|
|
130
133
|
const deleted = await deleteRedirect(selectedItems.all);
|
|
131
134
|
if (deleted) {
|
|
132
135
|
toggleToast();
|
|
133
136
|
}
|
|
134
137
|
toggleModalDelete();
|
|
138
|
+
setIsBulkLoading(false);
|
|
135
139
|
};
|
|
136
140
|
|
|
137
141
|
const unselectAllItems = () => resetBulkSelection();
|
|
@@ -174,6 +178,7 @@ const Redirects = (props: IProps): JSX.Element => {
|
|
|
174
178
|
sortedListStatus={sortedListStatus}
|
|
175
179
|
setHoverCheck={setHoverCheck}
|
|
176
180
|
selectedItems={selectedItems}
|
|
181
|
+
isLoading={isBulkLoading}
|
|
177
182
|
/>
|
|
178
183
|
);
|
|
179
184
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BulkSelectionOptions } from "@ax/components";
|
|
2
|
+
import { itemLabel } from "@ax/constants";
|
|
2
3
|
import type { IBulkSelectedItems } from "@ax/hooks";
|
|
3
4
|
import type { IQueryValue } from "@ax/types";
|
|
4
5
|
|
|
@@ -17,6 +18,7 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
17
18
|
bulkActions,
|
|
18
19
|
setHoverCheck,
|
|
19
20
|
selectedItems,
|
|
21
|
+
isLoading,
|
|
20
22
|
} = props;
|
|
21
23
|
|
|
22
24
|
return showBulk ? (
|
|
@@ -26,6 +28,8 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
26
28
|
selectItems={selectItems}
|
|
27
29
|
totalItems={totalItems}
|
|
28
30
|
selectedItems={selectedItems}
|
|
31
|
+
isLoading={isLoading}
|
|
32
|
+
itemLabel={itemLabel.ADDON}
|
|
29
33
|
/>
|
|
30
34
|
) : (
|
|
31
35
|
<TableHeader
|
|
@@ -52,6 +56,7 @@ interface IProps {
|
|
|
52
56
|
bulkActions: { icon: string; text: string; action: () => void }[];
|
|
53
57
|
setHoverCheck: (state: boolean) => void;
|
|
54
58
|
selectedItems: IBulkSelectedItems;
|
|
59
|
+
isLoading: boolean;
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
export default BulkHeader;
|
|
@@ -45,6 +45,7 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
45
45
|
throw new Error(`ERROR: User reached Integrations with null site info`);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
const [isBulkLoading, setIsBulkLoading] = useState(false);
|
|
48
49
|
const [isScrolling, setIsScrolling] = useState(false);
|
|
49
50
|
const tableRef = useRef<HTMLDivElement>(null);
|
|
50
51
|
const { setFiltersSelection, resetFilterQuery, filterValues, filterQuery, isFiltered } = useFilterQuery();
|
|
@@ -125,6 +126,7 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
125
126
|
} = useBulkSelection(filteredIntegrationsIds);
|
|
126
127
|
|
|
127
128
|
const bulkDelete = async () => {
|
|
129
|
+
setIsBulkLoading(true);
|
|
128
130
|
const params = getParams();
|
|
129
131
|
const deleted = await deleteIntegration(selectedItems.all, params);
|
|
130
132
|
if (deleted) {
|
|
@@ -132,9 +134,11 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
132
134
|
}
|
|
133
135
|
toggleModalDelete();
|
|
134
136
|
resetBulkSelection();
|
|
137
|
+
setIsBulkLoading(false);
|
|
135
138
|
};
|
|
136
139
|
|
|
137
140
|
const bulkDeactivate = async () => {
|
|
141
|
+
setIsBulkLoading(true);
|
|
138
142
|
const params = getParams();
|
|
139
143
|
const changed = await changeIntegrationState(selectedItems.all, false, params);
|
|
140
144
|
if (changed) {
|
|
@@ -142,6 +146,7 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
142
146
|
}
|
|
143
147
|
toggleModalDeactivate();
|
|
144
148
|
resetBulkSelection();
|
|
149
|
+
setIsBulkLoading(false);
|
|
145
150
|
};
|
|
146
151
|
|
|
147
152
|
const unselectAllItems = () => resetBulkSelection();
|
|
@@ -185,6 +190,7 @@ const Integrations = (props: IIntegrationsProps): JSX.Element => {
|
|
|
185
190
|
bulkActions={bulkActions}
|
|
186
191
|
setHoverCheck={setHoverCheck}
|
|
187
192
|
selectedItems={selectedItems}
|
|
193
|
+
isLoading={isBulkLoading}
|
|
188
194
|
/>
|
|
189
195
|
);
|
|
190
196
|
|
|
@@ -326,7 +332,7 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
326
332
|
isLoading: state.app.isLoading,
|
|
327
333
|
integrations: state.integrations.integrations,
|
|
328
334
|
totalItems: state.integrations.totalItems,
|
|
329
|
-
currentSite: state.sites.currentSiteInfo
|
|
335
|
+
currentSite: state.sites.currentSiteInfo?.id ?? null,
|
|
330
336
|
});
|
|
331
337
|
|
|
332
338
|
const mapDispatchToProps = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BulkSelectionOptions } from "@ax/components";
|
|
2
|
+
import { itemLabel } from "@ax/constants";
|
|
2
3
|
import type { IBulkSelectedItems } from "@ax/hooks";
|
|
3
4
|
import { usePermission } from "@ax/hooks";
|
|
4
5
|
import type { IQueryValue } from "@ax/types";
|
|
@@ -22,6 +23,7 @@ const BulkHeader = (props: IBulkHeaderProps): JSX.Element => {
|
|
|
22
23
|
filterValues,
|
|
23
24
|
setHoverCheck,
|
|
24
25
|
selectedItems,
|
|
26
|
+
isLoading,
|
|
25
27
|
} = props;
|
|
26
28
|
|
|
27
29
|
const allowedToPublishSite = usePermission("general.publishSite");
|
|
@@ -54,6 +56,8 @@ const BulkHeader = (props: IBulkHeaderProps): JSX.Element => {
|
|
|
54
56
|
selectItems={selectItems}
|
|
55
57
|
totalItems={totalItems}
|
|
56
58
|
selectedItems={selectedItems}
|
|
59
|
+
isLoading={isLoading}
|
|
60
|
+
itemLabel={itemLabel.SITE}
|
|
57
61
|
/>
|
|
58
62
|
</S.BulkWrapper>
|
|
59
63
|
) : (
|
|
@@ -85,6 +89,7 @@ export interface IBulkHeaderProps {
|
|
|
85
89
|
filterValues: Record<string, IQueryValue[]>;
|
|
86
90
|
setHoverCheck: (state: boolean) => void;
|
|
87
91
|
selectedItems: IBulkSelectedItems;
|
|
92
|
+
isLoading: boolean;
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
export default BulkHeader;
|