@anji-dashing/dam-solution-v2 5.8.173
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/README.md +53 -0
- package/build/AssetType/AddFieldProperties.d.ts +10 -0
- package/build/AssetType/AddFieldProperties.js +359 -0
- package/build/AssetType/AssetTemplatesTable.d.ts +10 -0
- package/build/AssetType/AssetTemplatesTable.js +172 -0
- package/build/AssetType/CreateAssetTemplate.d.ts +3 -0
- package/build/AssetType/CreateAssetTemplate.js +70 -0
- package/build/AssetType/CreateOrEditAssetTemplate.d.ts +1 -0
- package/build/AssetType/CreateOrEditAssetTemplate.js +100 -0
- package/build/AssetType/DraggedField.d.ts +14 -0
- package/build/AssetType/DraggedField.js +58 -0
- package/build/AssetType/EditAssetTemplate.d.ts +5 -0
- package/build/AssetType/EditAssetTemplate.js +257 -0
- package/build/AssetType/FieldsSection.d.ts +14 -0
- package/build/AssetType/FieldsSection.js +268 -0
- package/build/AssetType/assetTemplatesContainer.d.ts +2 -0
- package/build/AssetType/assetTemplatesContainer.js +71 -0
- package/build/AssetType/fieldProperties/DateField.d.ts +5 -0
- package/build/AssetType/fieldProperties/DateField.js +23 -0
- package/build/AssetType/fieldProperties/NumberField.d.ts +5 -0
- package/build/AssetType/fieldProperties/NumberField.js +91 -0
- package/build/AssetType/fieldProperties/OptionsField.d.ts +6 -0
- package/build/AssetType/fieldProperties/OptionsField.js +55 -0
- package/build/AssetType/fieldProperties/TextField.d.ts +5 -0
- package/build/AssetType/fieldProperties/TextField.js +92 -0
- package/build/AssetType/index.d.ts +11 -0
- package/build/AssetType/index.js +25 -0
- package/build/AssetType/routes.d.ts +3 -0
- package/build/AssetType/routes.js +17 -0
- package/build/BookView/ProductDescription.d.ts +4 -0
- package/build/BookView/ProductDescription.js +20 -0
- package/build/BookView/bookDetail.d.ts +4 -0
- package/build/BookView/bookDetail.js +106 -0
- package/build/BookView/bookInfo.d.ts +4 -0
- package/build/BookView/bookInfo.js +17 -0
- package/build/BookView/description.d.ts +4 -0
- package/build/BookView/description.js +5 -0
- package/build/BookView/index.d.ts +10 -0
- package/build/BookView/index.js +23 -0
- package/build/CreateClient/CreateClientBtn.d.ts +14 -0
- package/build/CreateClient/CreateClientBtn.js +54 -0
- package/build/CreateClient/CreateClientForm.d.ts +15 -0
- package/build/CreateClient/CreateClientForm.js +347 -0
- package/build/CreateClient/index.d.ts +20 -0
- package/build/CreateClient/index.js +18 -0
- package/build/ImagePicker/MetaFieldOptions.d.ts +14 -0
- package/build/ImagePicker/MetaFieldOptions.js +75 -0
- package/build/ImagePicker/TestImagePickerModal.d.ts +8 -0
- package/build/ImagePicker/TestImagePickerModal.js +72 -0
- package/build/ImagePicker/TestImgFromMetaData.d.ts +7 -0
- package/build/ImagePicker/TestImgFromMetaData.js +82 -0
- package/build/ImagePicker/imagePickerComponent.d.ts +6 -0
- package/build/ImagePicker/imagePickerComponent.js +63 -0
- package/build/ImagePicker/index.d.ts +13 -0
- package/build/ImagePicker/index.js +24 -0
- package/build/ImagePicker/routes.d.ts +6 -0
- package/build/ImagePicker/routes.js +17 -0
- package/build/ImagePickerFilters/ImagePickerFiltersComponent.d.ts +8 -0
- package/build/ImagePickerFilters/ImagePickerFiltersComponent.js +223 -0
- package/build/ImagePickerFilters/index.d.ts +12 -0
- package/build/ImagePickerFilters/index.js +19 -0
- package/build/MyDrive/ActionBar.d.ts +8 -0
- package/build/MyDrive/ActionBar.js +190 -0
- package/build/MyDrive/AddDrive.d.ts +5 -0
- package/build/MyDrive/AddDrive.js +189 -0
- package/build/MyDrive/AddFolder.d.ts +11 -0
- package/build/MyDrive/AddFolder.js +165 -0
- package/build/MyDrive/BreadCrumbList.d.ts +10 -0
- package/build/MyDrive/BreadCrumbList.js +81 -0
- package/build/MyDrive/BulkUploadModal.d.ts +2 -0
- package/build/MyDrive/BulkUploadModal.js +324 -0
- package/build/MyDrive/DriveContainer.d.ts +14 -0
- package/build/MyDrive/DriveContainer.js +343 -0
- package/build/MyDrive/FileDownloadHistory.d.ts +7 -0
- package/build/MyDrive/FileDownloadHistory.js +107 -0
- package/build/MyDrive/FileMenuOptions.d.ts +11 -0
- package/build/MyDrive/FileMenuOptions.js +450 -0
- package/build/MyDrive/FilesGridView.d.ts +9 -0
- package/build/MyDrive/FilesGridView.js +25 -0
- package/build/MyDrive/FolderGridView.d.ts +20 -0
- package/build/MyDrive/FolderGridView.js +95 -0
- package/build/MyDrive/FolderListView.d.ts +26 -0
- package/build/MyDrive/FolderListView.js +226 -0
- package/build/MyDrive/FolderMenuOptions.d.ts +5 -0
- package/build/MyDrive/FolderMenuOptions.js +350 -0
- package/build/MyDrive/FolderTree.d.ts +8 -0
- package/build/MyDrive/FolderTree.js +479 -0
- package/build/MyDrive/ImageEditor/EditImage.d.ts +6 -0
- package/build/MyDrive/ImageEditor/EditImage.js +97 -0
- package/build/MyDrive/ImageEditor/EditImageModal.d.ts +8 -0
- package/build/MyDrive/ImageEditor/EditImageModal.js +30 -0
- package/build/MyDrive/ImageEditor/TuiImageEditor.d.ts +10 -0
- package/build/MyDrive/ImageEditor/TuiImageEditor.js +99 -0
- package/build/MyDrive/ImagePickerBreadCrumbList.d.ts +8 -0
- package/build/MyDrive/ImagePickerBreadCrumbList.js +35 -0
- package/build/MyDrive/ImagePickerDrive.d.ts +1 -0
- package/build/MyDrive/ImagePickerDrive.js +41 -0
- package/build/MyDrive/MyDriveMainContainer.d.ts +6 -0
- package/build/MyDrive/MyDriveMainContainer.js +63 -0
- package/build/MyDrive/SearchFilter.d.ts +8 -0
- package/build/MyDrive/SearchFilter.js +73 -0
- package/build/MyDrive/ShareBtn.d.ts +5 -0
- package/build/MyDrive/ShareBtn.js +19 -0
- package/build/MyDrive/ToggleView.d.ts +4 -0
- package/build/MyDrive/ToggleView.js +12 -0
- package/build/MyDrive/UploadStatusModal.d.ts +12 -0
- package/build/MyDrive/UploadStatusModal.js +52 -0
- package/build/MyDrive/fileDetails/CommentEntity.d.ts +8 -0
- package/build/MyDrive/fileDetails/CommentEntity.js +102 -0
- package/build/MyDrive/fileDetails/Comments.d.ts +6 -0
- package/build/MyDrive/fileDetails/Comments.js +65 -0
- package/build/MyDrive/fileDetails/Compliance.d.ts +2 -0
- package/build/MyDrive/fileDetails/Compliance.js +18 -0
- package/build/MyDrive/fileDetails/CreateComment.d.ts +7 -0
- package/build/MyDrive/fileDetails/CreateComment.js +48 -0
- package/build/MyDrive/fileDetails/Editor.d.ts +6 -0
- package/build/MyDrive/fileDetails/Editor.js +55 -0
- package/build/MyDrive/fileDetails/EmojiPicker.d.ts +5 -0
- package/build/MyDrive/fileDetails/EmojiPicker.js +6 -0
- package/build/MyDrive/fileDetails/FileDetails.d.ts +11 -0
- package/build/MyDrive/fileDetails/FileDetails.js +125 -0
- package/build/MyDrive/fileDetails/FileHeader.d.ts +7 -0
- package/build/MyDrive/fileDetails/FileHeader.js +27 -0
- package/build/MyDrive/fileDetails/FileViewer.d.ts +10 -0
- package/build/MyDrive/fileDetails/FileViewer.js +17 -0
- package/build/MyDrive/fileDetails/ImageOptions.d.ts +2 -0
- package/build/MyDrive/fileDetails/ImageOptions.js +44 -0
- package/build/MyDrive/fileDetails/ImageViewer.d.ts +6 -0
- package/build/MyDrive/fileDetails/ImageViewer.js +16 -0
- package/build/MyDrive/fileDetails/ManageFile.d.ts +7 -0
- package/build/MyDrive/fileDetails/ManageFile.js +34 -0
- package/build/MyDrive/fileDetails/MetaForm.d.ts +15 -0
- package/build/MyDrive/fileDetails/MetaForm.js +199 -0
- package/build/MyDrive/fileDetails/Metadata.d.ts +8 -0
- package/build/MyDrive/fileDetails/Metadata.js +52 -0
- package/build/MyDrive/fileDetails/PdfOptions.d.ts +9 -0
- package/build/MyDrive/fileDetails/PdfOptions.js +35 -0
- package/build/MyDrive/fileDetails/PdfViewer.d.ts +8 -0
- package/build/MyDrive/fileDetails/PdfViewer.js +18 -0
- package/build/MyDrive/fileDetails/Previewdetails.d.ts +10 -0
- package/build/MyDrive/fileDetails/Previewdetails.js +53 -0
- package/build/MyDrive/fileDetails/VideoPlayer.d.ts +4 -0
- package/build/MyDrive/fileDetails/VideoPlayer.js +21 -0
- package/build/MyDrive/files/AssetSelectionFormItem.d.ts +7 -0
- package/build/MyDrive/files/AssetSelectionFormItem.js +14 -0
- package/build/MyDrive/files/FolderTabs.d.ts +6 -0
- package/build/MyDrive/files/FolderTabs.js +90 -0
- package/build/MyDrive/files/MapFile.d.ts +9 -0
- package/build/MyDrive/files/MapFile.js +239 -0
- package/build/MyDrive/files/MoveToAnotherFolder.d.ts +9 -0
- package/build/MyDrive/files/MoveToAnotherFolder.js +67 -0
- package/build/MyDrive/filesListView.d.ts +2 -0
- package/build/MyDrive/filesListView.js +57 -0
- package/build/MyDrive/index.d.ts +16 -0
- package/build/MyDrive/index.js +50 -0
- package/build/MyDrive/routes.d.ts +10 -0
- package/build/MyDrive/routes.js +12 -0
- package/build/PenView/PenDetails.d.ts +4 -0
- package/build/PenView/PenDetails.js +114 -0
- package/build/PenView/ProductDescription.d.ts +5 -0
- package/build/PenView/ProductDescription.js +51 -0
- package/build/PenView/index.d.ts +10 -0
- package/build/PenView/index.js +23 -0
- package/build/RefreshKey/RefreshKeyBtn.d.ts +1 -0
- package/build/RefreshKey/RefreshKeyBtn.js +42 -0
- package/build/RefreshKey/index.d.ts +9 -0
- package/build/RefreshKey/index.js +23 -0
- package/build/ShoesView/ProductDescription.d.ts +4 -0
- package/build/ShoesView/ProductDescription.js +25 -0
- package/build/ShoesView/ShoeDetails.d.ts +4 -0
- package/build/ShoesView/ShoeDetails.js +96 -0
- package/build/ShoesView/index.d.ts +10 -0
- package/build/ShoesView/index.js +23 -0
- package/build/common/Button.d.ts +2 -0
- package/build/common/Button.js +18 -0
- package/build/common/CustomElements.d.ts +98 -0
- package/build/common/CustomElements.js +77 -0
- package/build/common/LoadMoreItems.d.ts +7 -0
- package/build/common/LoadMoreItems.js +33 -0
- package/build/common/RenderFormItem.d.ts +42 -0
- package/build/common/RenderFormItem.js +98 -0
- package/build/common/RenderThumnail.d.ts +7 -0
- package/build/common/RenderThumnail.js +6 -0
- package/build/common/deleteModal.d.ts +1 -0
- package/build/common/deleteModal.js +12 -0
- package/build/common/folders/TypeAndDateFilters.d.ts +13 -0
- package/build/common/folders/TypeAndDateFilters.js +66 -0
- package/build/common/folders/getFolderOrFileIcon.d.ts +2 -0
- package/build/common/folders/getFolderOrFileIcon.js +41 -0
- package/build/common/loader/CustomLoader.d.ts +7 -0
- package/build/common/loader/CustomLoader.js +8 -0
- package/build/common/loader/loader.d.ts +1 -0
- package/build/common/loader/loader.js +6 -0
- package/build/common/notifications.d.ts +2 -0
- package/build/common/notifications.js +30 -0
- package/build/common/steps.d.ts +4 -0
- package/build/common/steps.js +7 -0
- package/build/hocs/AppProvider.d.ts +3 -0
- package/build/hocs/AppProvider.js +11 -0
- package/build/hocs/DamConfigContext.d.ts +2 -0
- package/build/hocs/DamConfigContext.js +153 -0
- package/build/hocs/ThemeContext.d.ts +15 -0
- package/build/hocs/ThemeContext.js +131 -0
- package/build/hocs/ToastProvider.d.ts +2 -0
- package/build/hocs/ToastProvider.js +6 -0
- package/build/hocs/appConstants.d.ts +124 -0
- package/build/hocs/appConstants.js +211 -0
- package/build/hocs/configureAxios.d.ts +2 -0
- package/build/hocs/configureAxios.js +65 -0
- package/build/hocs/helpers.d.ts +17 -0
- package/build/hocs/helpers.js +201 -0
- package/build/index.d.ts +12 -0
- package/build/index.js +12 -0
- package/build/react-query/hooks/brand-hooks.d.ts +3 -0
- package/build/react-query/hooks/brand-hooks.js +10 -0
- package/build/react-query/hooks/folder-hooks.d.ts +7 -0
- package/build/react-query/hooks/folder-hooks.js +119 -0
- package/build/react-query/services/brand-services.d.ts +4 -0
- package/build/react-query/services/brand-services.js +41 -0
- package/build/react-query/services/file-services.d.ts +43 -0
- package/build/react-query/services/file-services.js +69 -0
- package/build/react-query/services/folder-services.d.ts +46 -0
- package/build/react-query/services/folder-services.js +87 -0
- package/build/react-query/services/image-picker-services.d.ts +5 -0
- package/build/react-query/services/image-picker-services.js +47 -0
- package/build/settings/InviteTeamModal.d.ts +12 -0
- package/build/settings/InviteTeamModal.js +174 -0
- package/build/settings/UpdateInvitationAccessType.d.ts +9 -0
- package/build/settings/UpdateInvitationAccessType.js +96 -0
- package/build/settings/getUserAvatar.d.ts +7 -0
- package/build/settings/getUserAvatar.js +11 -0
- package/build/style.css +1 -0
- package/build/types/assetType.d.ts +8 -0
- package/build/types/assetType.js +1 -0
- package/build/ui/pageTitle.d.ts +3 -0
- package/build/ui/pageTitle.js +4 -0
- package/build/utilities/FoldersContext.d.ts +16 -0
- package/build/utilities/FoldersContext.js +15 -0
- package/build/utilities/NavigatorProvider.d.ts +2 -0
- package/build/utilities/NavigatorProvider.js +10 -0
- package/build/utilities/constants/apiUrls.d.ts +97 -0
- package/build/utilities/constants/apiUrls.js +117 -0
- package/build/utilities/constants/imageUrls.d.ts +6 -0
- package/build/utilities/constants/imageUrls.js +6 -0
- package/build/utilities/constants/interface.d.ts +371 -0
- package/build/utilities/constants/interface.js +142 -0
- package/build/utilities/constants/messages.d.ts +55 -0
- package/build/utilities/constants/messages.js +55 -0
- package/build/utilities/constants/queryKeys.d.ts +16 -0
- package/build/utilities/constants/queryKeys.js +33 -0
- package/build/utilities/constants/routes.d.ts +22 -0
- package/build/utilities/constants/routes.js +22 -0
- package/build/utilities/helpers/validators.d.ts +12 -0
- package/build/utilities/helpers/validators.js +89 -0
- package/build/utilities/useAppNavigate.d.ts +2 -0
- package/build/utilities/useAppNavigate.js +35 -0
- package/build/utilities/useAppParams.d.ts +8 -0
- package/build/utilities/useAppParams.js +72 -0
- package/package.json +93 -0
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
|
+
import { Button, Dropdown, Grid, Input, Select, Tooltip, Tree } from "antd";
|
|
12
|
+
import { useEffect, useMemo, useState, useRef } from "react";
|
|
13
|
+
import { get, map, isArray, isObject, cloneDeep, first, sortBy, } from "lodash";
|
|
14
|
+
import { FaAngleLeft, FaAngleRight } from "react-icons/fa";
|
|
15
|
+
import { deleteFolders, } from "../react-query/services/folder-services";
|
|
16
|
+
import { generateFoldersQueryKey, invalidateData, } from "../utilities/constants/queryKeys";
|
|
17
|
+
import { createApiClient } from "../hocs/configureAxios";
|
|
18
|
+
import { useDamConfig } from "../hocs/DamConfigContext";
|
|
19
|
+
import { AiOutlineSortDescending } from "react-icons/ai";
|
|
20
|
+
import { AiOutlineSortAscending } from "react-icons/ai";
|
|
21
|
+
import CustomLoader from "../common/loader/CustomLoader";
|
|
22
|
+
import { useMutation, useQueryClient } from "react-query";
|
|
23
|
+
import { DeleteOutlined, EditOutlined, MoreOutlined } from "@ant-design/icons";
|
|
24
|
+
import { DeleteConfirmationModal } from "../common/CustomElements";
|
|
25
|
+
import { DELETE_CONFIRMATION_MESSAGE, DELETE_OK_TEXT, DELETE_SUCCESS, SOMETHING_WENT_WRONG, } from "../utilities/constants/messages";
|
|
26
|
+
import { NotificationStatus, } from "../utilities/constants/interface";
|
|
27
|
+
import { showNotification } from "../common/notifications";
|
|
28
|
+
import { useParams } from "react-router-dom";
|
|
29
|
+
import AddFolder from "./AddFolder";
|
|
30
|
+
import { FETCH_FOLDER_URL, SORT_FOLDERS_URL, } from "../utilities/constants/apiUrls";
|
|
31
|
+
import { RiDraggable } from "react-icons/ri";
|
|
32
|
+
import { FaShuffle } from "react-icons/fa6";
|
|
33
|
+
import { IoIosSearch } from "react-icons/io";
|
|
34
|
+
const { DirectoryTree } = Tree;
|
|
35
|
+
const { Option } = Select;
|
|
36
|
+
const FaAngleLeftbtn = FaAngleLeft;
|
|
37
|
+
const FaAngleRightbtn = FaAngleRight;
|
|
38
|
+
const RiDraggablebtn = RiDraggable;
|
|
39
|
+
const AiOutlineSortDescendingbtn = AiOutlineSortDescending;
|
|
40
|
+
const AiOutlineSortAscendingbtn = AiOutlineSortAscending;
|
|
41
|
+
const GrSortIcon = FaShuffle;
|
|
42
|
+
const IoIosSearchIcon = IoIosSearch;
|
|
43
|
+
// ✅ Helper to insert children into the correct folder recursively
|
|
44
|
+
const insertSubfolders = (tree, parentId, childrenToInsert) => {
|
|
45
|
+
console.log('## insertSubfolders', tree, parentId, childrenToInsert);
|
|
46
|
+
const newTree = map(tree, (node) => {
|
|
47
|
+
if (node._id === parentId) {
|
|
48
|
+
return Object.assign(Object.assign({}, node), { children: childrenToInsert });
|
|
49
|
+
}
|
|
50
|
+
if (isArray(node.children)) {
|
|
51
|
+
return Object.assign(Object.assign({}, node), { children: insertSubfolders(node.children, parentId, childrenToInsert) });
|
|
52
|
+
}
|
|
53
|
+
return node;
|
|
54
|
+
});
|
|
55
|
+
console.log('## newTree', newTree);
|
|
56
|
+
return newTree;
|
|
57
|
+
};
|
|
58
|
+
const sortFoldersRecursively = (folders, sortByField, // ✅ which field to sort
|
|
59
|
+
order = "asc") => {
|
|
60
|
+
if (!folders)
|
|
61
|
+
return [];
|
|
62
|
+
const sorted = sortBy(folders, (f) => {
|
|
63
|
+
var _a, _b;
|
|
64
|
+
if (sortByField === "name") {
|
|
65
|
+
return (_b = (_a = f.name) === null || _a === void 0 ? void 0 : _a.toLowerCase) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
66
|
+
}
|
|
67
|
+
if (sortByField === "createdAt") {
|
|
68
|
+
return new Date(f.createdAt).getTime();
|
|
69
|
+
}
|
|
70
|
+
return f.name; // fallback
|
|
71
|
+
});
|
|
72
|
+
const result = order === "desc" ? [...sorted].reverse() : sorted;
|
|
73
|
+
return result.map((f) => (Object.assign(Object.assign({}, f), { children: isArray(f.children)
|
|
74
|
+
? sortFoldersRecursively(f.children, sortByField, order)
|
|
75
|
+
: f.children })));
|
|
76
|
+
};
|
|
77
|
+
// ✅ Helper to insert children into the correct folder recursively
|
|
78
|
+
const insertSubfoldersRecursively = (tree) => {
|
|
79
|
+
const newTree = map(tree, (node) => {
|
|
80
|
+
if (isArray(node.children)) {
|
|
81
|
+
return Object.assign(Object.assign({}, node), { children: insertSubfoldersRecursively(node.children) });
|
|
82
|
+
}
|
|
83
|
+
return node;
|
|
84
|
+
});
|
|
85
|
+
return newTree;
|
|
86
|
+
};
|
|
87
|
+
function FolderTree({ currentRootId, expandedKeys, selectedKeys, handleExpand, setSelectedKeys, folders, setFolders, setExpandedKeys, setGlobalSearch, globalSearch, }) {
|
|
88
|
+
const { folderId, id, type } = useParams();
|
|
89
|
+
const damConfig = useDamConfig();
|
|
90
|
+
const { rootFolderId } = damConfig;
|
|
91
|
+
const api = useMemo(() => createApiClient(damConfig), [damConfig]);
|
|
92
|
+
const { useBreakpoint } = Grid;
|
|
93
|
+
const [collapse, setCollapse] = useState(false);
|
|
94
|
+
const screens = useBreakpoint();
|
|
95
|
+
const queryClient = useQueryClient();
|
|
96
|
+
const [state, setState] = useState({
|
|
97
|
+
showConfirmationModal: false,
|
|
98
|
+
showEditModal: false,
|
|
99
|
+
selectedFolder: {},
|
|
100
|
+
loading: false,
|
|
101
|
+
isSorting: false,
|
|
102
|
+
enableDrag: false,
|
|
103
|
+
sortMode: "name",
|
|
104
|
+
sortOrder: "asc",
|
|
105
|
+
tempFolders: [],
|
|
106
|
+
parentFolder: {},
|
|
107
|
+
globalSearchValue: "",
|
|
108
|
+
});
|
|
109
|
+
const { showConfirmationModal, showEditModal, selectedFolder, loading, isSorting, enableDrag, sortMode, sortOrder, tempFolders, parentFolder, globalSearchValue, } = state;
|
|
110
|
+
// Fetch children for a specific folder and insert them into the tree (same logic as fetchFolders)
|
|
111
|
+
const fetchFolderChildren = (folderId) => __awaiter(this, void 0, void 0, function* () {
|
|
112
|
+
try {
|
|
113
|
+
setState((prevState) => {
|
|
114
|
+
return Object.assign(Object.assign({}, prevState), { loading: true });
|
|
115
|
+
});
|
|
116
|
+
const response = yield api.get(`${FETCH_FOLDER_URL.replace(":folderId", folderId)}?isPagination=false&includeFiles=false&includeSubFoldersCount=true&fetchMainFolders=true&globalSearch=`);
|
|
117
|
+
const newFolders = get(response, "data.folders", []);
|
|
118
|
+
// Simply use the same logic as fetchFolders - sort and insert recursively
|
|
119
|
+
const sorted = sortFoldersRecursively(newFolders, "name", sortOrder);
|
|
120
|
+
const newChildren = insertSubfoldersRecursively(sorted);
|
|
121
|
+
console.log('## Fetching children for folder:', folderId, 'New children:', newChildren);
|
|
122
|
+
// Insert the fetched children into the clicked folder in the tree
|
|
123
|
+
setFolders((prevFolders) => {
|
|
124
|
+
return insertSubfolders(prevFolders, folderId, newChildren);
|
|
125
|
+
});
|
|
126
|
+
setState((prevState) => {
|
|
127
|
+
return Object.assign(Object.assign({}, prevState), { loading: false });
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
showNotification(get(error, "message", SOMETHING_WENT_WRONG), NotificationStatus.ERROR);
|
|
132
|
+
setState((prevState) => {
|
|
133
|
+
return Object.assign(Object.assign({}, prevState), { loading: false });
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
const fetchFolders = (fid) => __awaiter(this, void 0, void 0, function* () {
|
|
138
|
+
try {
|
|
139
|
+
setState((prevState) => {
|
|
140
|
+
return Object.assign(Object.assign({}, prevState), { loading: true });
|
|
141
|
+
});
|
|
142
|
+
const response = yield api.get(`${FETCH_FOLDER_URL.replace(":folderId", fid)}?isPagination=false&includeFiles=false&includeSubFoldersCount=true&fetchMainFolders=true&globalSearch=${fid == rootFolderId ? globalSearch : ""}`);
|
|
143
|
+
const newFolders = get(response, "data.folders", []);
|
|
144
|
+
const folderInfo = get(response, "data.folder", {});
|
|
145
|
+
console.log('## newFolders', response, newFolders, fid, rootFolderId, globalSearch);
|
|
146
|
+
if (fid === rootFolderId) {
|
|
147
|
+
setFolders(sortFoldersRecursively(newFolders, "name", sortOrder));
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
// Simply use folder info from API response and newFolders as children
|
|
151
|
+
const sorted = sortFoldersRecursively(newFolders, "name", sortOrder);
|
|
152
|
+
console.log('## Folder info:', folderInfo, 'New children:', insertSubfoldersRecursively(sorted));
|
|
153
|
+
const newChildren = insertSubfoldersRecursively(sorted);
|
|
154
|
+
setFolders([Object.assign(Object.assign({}, folderInfo), { children: newChildren })]);
|
|
155
|
+
}
|
|
156
|
+
setState((prevState) => {
|
|
157
|
+
return Object.assign(Object.assign({}, prevState), { parentFolder: get(response, "data.folder", {}), loading: false, globalSearchValue: globalSearch || "" });
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
showNotification(get(error, "message", SOMETHING_WENT_WRONG), NotificationStatus.ERROR);
|
|
162
|
+
setState((prevState) => {
|
|
163
|
+
return Object.assign(Object.assign({}, prevState), { loading: false });
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
// Helper to check if a folder exists in the current tree
|
|
168
|
+
const folderExistsInTree = (folderId, tree) => {
|
|
169
|
+
for (const folder of tree) {
|
|
170
|
+
if (folder._id === folderId) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
if (isArray(folder.children)) {
|
|
174
|
+
if (folderExistsInTree(folderId, folder.children)) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return false;
|
|
180
|
+
};
|
|
181
|
+
const findPathToFolder = (folderId, tree, path = []) => {
|
|
182
|
+
for (const folder of tree) {
|
|
183
|
+
const currentPath = [...path, folder._id];
|
|
184
|
+
if (folder._id === folderId) {
|
|
185
|
+
return currentPath;
|
|
186
|
+
}
|
|
187
|
+
if (isArray(folder.children)) {
|
|
188
|
+
const found = findPathToFolder(folderId, folder.children, currentPath);
|
|
189
|
+
if (found)
|
|
190
|
+
return found;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
};
|
|
195
|
+
// ✅ Load on mount & when currentRootId changes
|
|
196
|
+
// Use ref to track previous currentRootId to prevent unnecessary fetches
|
|
197
|
+
const prevCurrentRootIdRef = useRef(null);
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
if (currentRootId && currentRootId !== prevCurrentRootIdRef.current) {
|
|
200
|
+
console.log('## FolderTree useEffect - currentRootId changed from', prevCurrentRootIdRef.current, 'to', currentRootId, 'rootFolderId:', rootFolderId);
|
|
201
|
+
// If the folder is already in the tree, don't replace the entire tree
|
|
202
|
+
// Just fetch its children if needed
|
|
203
|
+
if (folders.length > 0 && folderExistsInTree(currentRootId, folders)) {
|
|
204
|
+
console.log('## Folder already in tree, fetching children only');
|
|
205
|
+
// Check if folder already has children loaded
|
|
206
|
+
const findFolder = (tree, id) => {
|
|
207
|
+
for (const folder of tree) {
|
|
208
|
+
if (folder._id === id)
|
|
209
|
+
return folder;
|
|
210
|
+
if (isArray(folder.children)) {
|
|
211
|
+
const found = findFolder(folder.children, id);
|
|
212
|
+
if (found)
|
|
213
|
+
return found;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
};
|
|
218
|
+
const existingFolder = findFolder(folders, currentRootId);
|
|
219
|
+
if (!existingFolder || !isArray(existingFolder.children) || existingFolder.children.length === 0) {
|
|
220
|
+
fetchFolderChildren(currentRootId);
|
|
221
|
+
}
|
|
222
|
+
const pathToFolder = findPathToFolder(currentRootId, folders);
|
|
223
|
+
if (pathToFolder && pathToFolder.length > 0) {
|
|
224
|
+
const parentPath = pathToFolder.slice(0, -1);
|
|
225
|
+
if (parentPath.length > 0) {
|
|
226
|
+
const currentExpanded = isArray(expandedKeys) ? expandedKeys : [expandedKeys].filter(Boolean);
|
|
227
|
+
const newExpanded = [...new Set([...currentExpanded, ...parentPath])];
|
|
228
|
+
setExpandedKeys(newExpanded);
|
|
229
|
+
console.log('## Expanding path to folder:', parentPath);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
prevCurrentRootIdRef.current = currentRootId;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
if (currentRootId === rootFolderId || folders.length === 0) {
|
|
236
|
+
prevCurrentRootIdRef.current = currentRootId;
|
|
237
|
+
fetchFolders(currentRootId);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
console.log('## Folder not in tree but tree has content - keeping existing tree structure');
|
|
241
|
+
prevCurrentRootIdRef.current = currentRootId;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else if (globalSearch !== globalSearchValue && currentRootId === rootFolderId) {
|
|
246
|
+
// Only refetch on global search change if we're on root folder
|
|
247
|
+
console.log('## FolderTree useEffect - globalSearch changed, refetching root folder');
|
|
248
|
+
fetchFolders(currentRootId);
|
|
249
|
+
}
|
|
250
|
+
}, [currentRootId, globalSearch]);
|
|
251
|
+
// ✅ Handle sort dropdown
|
|
252
|
+
const handleSortChange = (value) => {
|
|
253
|
+
setState((prevState) => {
|
|
254
|
+
return Object.assign(Object.assign({}, prevState), { sortMode: value });
|
|
255
|
+
});
|
|
256
|
+
if (value === "custom") {
|
|
257
|
+
const customSorted = sortBy(folders, (f) => { var _a; return (_a = f.sortOrder) !== null && _a !== void 0 ? _a : 0; });
|
|
258
|
+
setState((prevState) => {
|
|
259
|
+
return Object.assign(Object.assign({}, prevState), { tempFolders: cloneDeep(customSorted) });
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
setFolders((prev) => sortFoldersRecursively([...prev], value, sortOrder));
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
const handleSortOrderChange = (value) => {
|
|
267
|
+
setState((prevState) => {
|
|
268
|
+
return Object.assign(Object.assign({}, prevState), { sortOrder: value });
|
|
269
|
+
});
|
|
270
|
+
setFolders((prev) => sortFoldersRecursively([...prev], sortMode, value));
|
|
271
|
+
};
|
|
272
|
+
const toggleEnableDrag = () => {
|
|
273
|
+
setState((prev) => (Object.assign(Object.assign({}, prev), { enableDrag: true })));
|
|
274
|
+
};
|
|
275
|
+
const toggleEditModal = (folder = {}) => setState((prev) => (Object.assign(Object.assign({}, prev), { selectedFolder: folder, showEditModal: !prev.showEditModal })));
|
|
276
|
+
const toggleDeleteModal = (folder = {}) => setState((prev) => (Object.assign(Object.assign({}, prev), { selectedFolder: folder, showConfirmationModal: !prev.showConfirmationModal })));
|
|
277
|
+
const getFoldersTree = (folders = []) => {
|
|
278
|
+
console.log('## folders', folders);
|
|
279
|
+
const transform = (tree = []) => map(tree, (folder) => {
|
|
280
|
+
const key = get(folder, "_id", "");
|
|
281
|
+
const name = get(folder, "name", "");
|
|
282
|
+
const menuItems = [
|
|
283
|
+
{
|
|
284
|
+
key: "rename",
|
|
285
|
+
icon: _jsx(EditOutlined, {}),
|
|
286
|
+
label: "Rename",
|
|
287
|
+
onClick: (e) => {
|
|
288
|
+
e.domEvent.stopPropagation();
|
|
289
|
+
toggleEditModal(folder);
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
key: "delete",
|
|
294
|
+
icon: _jsx(DeleteOutlined, {}),
|
|
295
|
+
danger: true,
|
|
296
|
+
label: "Delete",
|
|
297
|
+
onClick: (e) => {
|
|
298
|
+
e.domEvent.stopPropagation();
|
|
299
|
+
toggleDeleteModal(folder);
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
];
|
|
303
|
+
const title = (_jsxs("div", { className: "md-lib-flex md-lib-items-center md-lib-justify-between md-lib-h-[33px]", children: [sortMode === "custom" && enableDrag && _jsx(RiDraggablebtn, {}), _jsx(Tooltip, { title: name, children: _jsx("span", { className: "md-lib-truncate md-lib-max-w-[180px] md-lib-cursor-pointer md-lib-ml-2", children: name }) }), _jsx(Dropdown, { menu: { items: menuItems }, trigger: ["click"], children: _jsx(MoreOutlined, { className: "md-lib-cursor-pointer md-lib-ml-1 md-lib-mt-[3px]", onClick: (e) => {
|
|
304
|
+
e.stopPropagation(); // prevent folder select
|
|
305
|
+
} }) })] }));
|
|
306
|
+
let children = null;
|
|
307
|
+
const rawChildren = get(folder, "children");
|
|
308
|
+
if (isArray(rawChildren)) {
|
|
309
|
+
children = transform(rawChildren);
|
|
310
|
+
}
|
|
311
|
+
else if (isObject(rawChildren)) {
|
|
312
|
+
children = transform([rawChildren]);
|
|
313
|
+
}
|
|
314
|
+
return { key, title, children };
|
|
315
|
+
});
|
|
316
|
+
return transform(folders);
|
|
317
|
+
};
|
|
318
|
+
const toggleMenu = () => {
|
|
319
|
+
setCollapse(!collapse);
|
|
320
|
+
};
|
|
321
|
+
const tree = useMemo(() => {
|
|
322
|
+
return map(get(parentFolder, "tree", []), (item) => get(item, "_id")).filter((item) => {
|
|
323
|
+
return get(item, "_id") !== rootFolderId;
|
|
324
|
+
});
|
|
325
|
+
}, [parentFolder]);
|
|
326
|
+
// Wrapper for handleExpand that also fetches children when a folder is expanded
|
|
327
|
+
const handleExpandWithFetch = (keys) => {
|
|
328
|
+
handleExpand(keys);
|
|
329
|
+
const newExpanded = map(keys, (k) => k.toString());
|
|
330
|
+
const currentExpanded = isArray(expandedKeys) ? expandedKeys : [expandedKeys].filter(Boolean);
|
|
331
|
+
const newlyExpanded = newExpanded.filter(id => !currentExpanded.includes(id));
|
|
332
|
+
// Fetch children for newly expanded folders using the same simple logic
|
|
333
|
+
newlyExpanded.forEach(expandedId => {
|
|
334
|
+
if (expandedId !== rootFolderId && expandedId !== currentRootId) {
|
|
335
|
+
fetchFolderChildren(expandedId);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
};
|
|
339
|
+
const handleSelect = (keys) => {
|
|
340
|
+
// console.log("keys", keys);
|
|
341
|
+
const selected = map(keys, (k) => k.toString());
|
|
342
|
+
// console.log("selected", selected);
|
|
343
|
+
setSelectedKeys(selected);
|
|
344
|
+
if (get(selected, "length") > 0) {
|
|
345
|
+
const selectedId = selected[get(selected, "length", 0) - 1];
|
|
346
|
+
console.log('## selectedId', selectedId);
|
|
347
|
+
// If the selected folder is not the root folder, fetch its children
|
|
348
|
+
if (selectedId !== rootFolderId && selectedId !== currentRootId) {
|
|
349
|
+
fetchFolderChildren(selectedId);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
useEffect(() => {
|
|
354
|
+
// console.log(tree);
|
|
355
|
+
setExpandedKeys(tree);
|
|
356
|
+
}, [tree]);
|
|
357
|
+
// console.log("tree", tree, selectedKeys, treeData);
|
|
358
|
+
const onDeleteSuccess = (message, deletedId) => {
|
|
359
|
+
setFolders((prevFolders) => {
|
|
360
|
+
const removeFolderRecursively = (folders) => {
|
|
361
|
+
return folders
|
|
362
|
+
.map((f) => {
|
|
363
|
+
// recurse into children first
|
|
364
|
+
const updatedChildren = Array.isArray(f.children)
|
|
365
|
+
? removeFolderRecursively(f.children)
|
|
366
|
+
: f.children;
|
|
367
|
+
return Object.assign(Object.assign({}, f), { children: updatedChildren });
|
|
368
|
+
})
|
|
369
|
+
.filter((f) => f._id !== deletedId); // filter AFTER recursion
|
|
370
|
+
};
|
|
371
|
+
return removeFolderRecursively(prevFolders);
|
|
372
|
+
});
|
|
373
|
+
invalidateData(queryClient, generateFoldersQueryKey(type), folderId ? folderId : id ? id : rootFolderId);
|
|
374
|
+
if (deletedId === folderId || deletedId === id) {
|
|
375
|
+
// Navigate to root folder using state instead of URL
|
|
376
|
+
setSelectedKeys(rootFolderId);
|
|
377
|
+
}
|
|
378
|
+
showNotification(message, NotificationStatus.SUCCESS);
|
|
379
|
+
};
|
|
380
|
+
const onFailure = (message) => {
|
|
381
|
+
showNotification(message, NotificationStatus.ERROR);
|
|
382
|
+
};
|
|
383
|
+
useEffect(() => {
|
|
384
|
+
if (!folderId || folderId === rootFolderId) {
|
|
385
|
+
setSelectedKeys([]);
|
|
386
|
+
setExpandedKeys([]);
|
|
387
|
+
}
|
|
388
|
+
}, [folderId]);
|
|
389
|
+
const deleteFolderMutation = useMutation({
|
|
390
|
+
mutationFn: deleteFolders,
|
|
391
|
+
onSuccess: (response, variables) => {
|
|
392
|
+
toggleDeleteModal();
|
|
393
|
+
onDeleteSuccess(get(response, "data.message", DELETE_SUCCESS), first(get(variables, "folderIds", [])));
|
|
394
|
+
},
|
|
395
|
+
onError: (error) => {
|
|
396
|
+
onFailure(get(error, "message", SOMETHING_WENT_WRONG));
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
const onDeleteFolder = () => {
|
|
400
|
+
deleteFolderMutation.mutate({
|
|
401
|
+
folderIds: [get(selectedFolder, "_id")],
|
|
402
|
+
api,
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
// ✅ Drag & drop for parent only
|
|
406
|
+
const onDrop = (info) => {
|
|
407
|
+
const dragKey = info.dragNode.key;
|
|
408
|
+
const dropKey = info.node.key;
|
|
409
|
+
const newData = [...tempFolders];
|
|
410
|
+
const dragIndex = newData.findIndex((f) => f._id === dragKey);
|
|
411
|
+
const dropIndex = newData.findIndex((f) => f._id === dropKey);
|
|
412
|
+
if (dragIndex === -1 || dropIndex === -1)
|
|
413
|
+
return;
|
|
414
|
+
const dragged = newData[dragIndex];
|
|
415
|
+
newData.splice(dragIndex, 1);
|
|
416
|
+
newData.splice(dropIndex, 0, dragged);
|
|
417
|
+
// console.log("sorted data", newData);
|
|
418
|
+
setState((prevState) => {
|
|
419
|
+
return Object.assign(Object.assign({}, prevState), { tempFolders: newData });
|
|
420
|
+
});
|
|
421
|
+
};
|
|
422
|
+
// ✅ Save custom order
|
|
423
|
+
const handleSave = () => __awaiter(this, void 0, void 0, function* () {
|
|
424
|
+
setState((prevState) => {
|
|
425
|
+
return Object.assign(Object.assign({}, prevState), { isSorting: true });
|
|
426
|
+
});
|
|
427
|
+
try {
|
|
428
|
+
const response = yield api.put(SORT_FOLDERS_URL, {
|
|
429
|
+
folders: tempFolders.map((f, i) => ({
|
|
430
|
+
folderId: f._id,
|
|
431
|
+
sortOrder: i + 1,
|
|
432
|
+
})),
|
|
433
|
+
});
|
|
434
|
+
setFolders(tempFolders.map((f, i) => (Object.assign(Object.assign({}, f), { sortOrder: i + 1 }))));
|
|
435
|
+
if (response) {
|
|
436
|
+
showNotification(get(response, "data.message", ""), NotificationStatus.SUCCESS);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
catch (e) {
|
|
440
|
+
console.error(e);
|
|
441
|
+
if (e === null || e === void 0 ? void 0 : e.message) {
|
|
442
|
+
showNotification(e === null || e === void 0 ? void 0 : e.message, NotificationStatus.ERROR);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
finally {
|
|
446
|
+
setState((prevState) => {
|
|
447
|
+
return Object.assign(Object.assign({}, prevState), { isSorting: false, enableDrag: false });
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
const handleCancel = () => {
|
|
452
|
+
setState((prevState) => {
|
|
453
|
+
const customSorted = sortBy(folders, (f) => { var _a; return (_a = f.sortOrder) !== null && _a !== void 0 ? _a : 0; });
|
|
454
|
+
return Object.assign(Object.assign({}, prevState), { tempFolders: cloneDeep(customSorted), sortMode: "custom", enableDrag: false });
|
|
455
|
+
});
|
|
456
|
+
};
|
|
457
|
+
console.log('## folders in FolderTree', tempFolders, folders);
|
|
458
|
+
return (_jsxs(_Fragment, { children: [!screens.md && collapse && (_jsxs("div", { className: `md-lib-bg-textColorActive dark:md-lib-bg-darkSecondaryColor md-lib-p-1 md-lib-rounded md-lib-absolute md-lib-top-16 md-lib-left-1`, children: [" ", _jsx(FaAngleRightbtn, { size: 24, className: "md-lib-text-textColor dark:md-lib-text-darkTextColor", onClick: toggleMenu })] })), _jsxs("div", { className: `md-lib-border-r md-lib-inline-table md-lib-border-borderColor dark:md-lib-border-darkBorderColor md-lib-bg-white dark:md-lib-bg-darkPrimaryHoverColor md-lib-px-2 md-lib-pt-1 md-lib-max-h-[calc(100%-76px)] md-lib-overflow-x-auto ${!screens.md &&
|
|
459
|
+
"md-lib-absolute md-lib-left-0 md-lib-z-30 md-lib-h-full"} ${!screens.md && collapse && "!-md-lib-left-full"}`, children: [!screens.md && !collapse && (_jsxs("div", { className: `md-lib-bg-textColorActive dark:md-lib-bg-darkSecondaryColor md-lib-p-1 md-lib-rounded md-lib-absolute md-lib-top-1 md-lib-right-1 md-lib-z-50`, children: [" ", _jsx(FaAngleLeftbtn, { size: 24, className: "md-lib-text-textColor dark:md-lib-text-darkTextColor", onClick: toggleMenu })] })), _jsx("div", { className: "md-lib-mb-2", children: _jsx(Input, { placeholder: "Search files (min. 2 characters required)", onChange: (e) => setState((prevState) => {
|
|
460
|
+
return Object.assign(Object.assign({}, prevState), { globalSearchValue: e.target.value });
|
|
461
|
+
}), value: globalSearchValue, prefix: _jsx(IoIosSearchIcon, {}), onPressEnter: () => {
|
|
462
|
+
if (globalSearchValue.length >= 2 || !globalSearchValue) {
|
|
463
|
+
setGlobalSearch(globalSearchValue);
|
|
464
|
+
// Navigate to root folder using state instead of URL
|
|
465
|
+
setSelectedKeys(rootFolderId);
|
|
466
|
+
}
|
|
467
|
+
} }) }), !enableDrag && (_jsx("p", { className: "md-lib-text-xs md-lib-text-secondaryTextColor md-lib-mb-1 md-lib-font-400", children: "Sort By:" })), _jsxs("div", { className: "md-lib-flex md-lib-justify-between md-lib-items-center md-lib-mb-3 md-lib-gap-2", children: [!enableDrag && (_jsxs(Select, { value: sortMode, onChange: handleSortChange, style: { width: 200 }, children: [_jsx(Option, { value: "name", children: "Name" }), _jsx(Option, { value: "createdAt", children: "Created At" }), _jsx(Option, { value: "custom", children: "Custom Order" })] })), sortMode !== "custom" && (_jsx(Tooltip, { title: sortOrder === "desc" ? "Ascending" : "Descending", children: _jsx(Button, { onClick: () => {
|
|
468
|
+
if (sortOrder === "desc") {
|
|
469
|
+
handleSortOrderChange("asc");
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
handleSortOrderChange("desc");
|
|
473
|
+
}
|
|
474
|
+
}, icon: sortOrder == "desc" ? (_jsx(AiOutlineSortAscendingbtn, { className: "md-lib-cursor-pointer" })) : (_jsx(AiOutlineSortDescendingbtn, { className: "md-lib-cursor-pointer" })) }) })), sortMode === "custom" && !enableDrag && !globalSearch && (_jsx(Tooltip, { title: "Enable Drag", children: _jsx(Button, { icon: _jsx(GrSortIcon, {}), onClick: toggleEnableDrag }) })), enableDrag && (_jsxs("div", { className: "md-lib-flex md-lib-gap-2 md-lib-ml-2", children: [_jsx(Button, { type: "primary", onClick: handleSave, loading: isSorting, children: "Save" }), _jsx(Button, { onClick: handleCancel, children: "Cancel" })] })), loading && _jsx(CustomLoader, {})] }), _jsx("div", { style: { height: "calc(100% - 228px)", overflow: "auto", }, children: _jsx(DirectoryTree, { treeData: getFoldersTree(sortMode === "custom" ? tempFolders : folders), draggable: {
|
|
475
|
+
icon: true,
|
|
476
|
+
nodeDraggable: (node) => sortMode === "custom" && enableDrag ? !(node === null || node === void 0 ? void 0 : node.parentId) : false,
|
|
477
|
+
}, onDrop: sortMode === "custom" && enableDrag ? onDrop : undefined, blockNode: true, showIcon: false, selectable: !enableDrag, selectedKeys: isArray(selectedKeys) ? selectedKeys : [selectedKeys], expandedKeys: expandedKeys, onSelect: handleSelect, onExpand: handleExpandWithFetch }) })] }), showConfirmationModal && (_jsx(DeleteConfirmationModal, { showDeleteModal: showConfirmationModal, toggleDeleteModal: toggleDeleteModal, okText: DELETE_OK_TEXT, description: DELETE_CONFIRMATION_MESSAGE.replace(":action", "delete").replace(":entity", get(selectedFolder, "name", "this folder")), onOk: onDeleteFolder, loading: loading })), showEditModal && (_jsx(AddFolder, { open: showEditModal, handleCancel: toggleEditModal, folder: selectedFolder }))] }));
|
|
478
|
+
}
|
|
479
|
+
export default FolderTree;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
12
|
+
import { GoArrowLeft } from "react-icons/go";
|
|
13
|
+
import { PiFloppyDisk } from "react-icons/pi";
|
|
14
|
+
import TuiImageEditor from "./TuiImageEditor";
|
|
15
|
+
import { useMemo, useRef, useState } from "react";
|
|
16
|
+
import { NotificationStatus, } from "../../utilities/constants/interface";
|
|
17
|
+
import { get } from "lodash";
|
|
18
|
+
import CustomButton from "../../common/Button";
|
|
19
|
+
import { showNotification } from "../../common/notifications";
|
|
20
|
+
import { FILE_UPLOAD_ERROR, SOMETHING_WENT_WRONG, UPDATE_SUCCESS, } from "../../utilities/constants/messages";
|
|
21
|
+
import { SAVE_EDITED_FILE_THUMBNAIL_URL, SAVE_EDITED_FILE_URL, } from "../../utilities/constants/apiUrls";
|
|
22
|
+
import axios from "axios";
|
|
23
|
+
import { generateFoldersQueryKey, invalidateData, QueryKeys, } from "../../utilities/constants/queryKeys";
|
|
24
|
+
import { useQueryClient } from "react-query";
|
|
25
|
+
import { useDamConfig } from "../../hocs/DamConfigContext";
|
|
26
|
+
import { createApiClient } from "../../hocs/configureAxios";
|
|
27
|
+
import useAppParams from "../../utilities/useAppParams";
|
|
28
|
+
const GoArrowLeftIcon = GoArrowLeft;
|
|
29
|
+
const PiFloppyDiskIcon = PiFloppyDisk;
|
|
30
|
+
const ImageEditorComponent = ({ file, handleClose, }) => {
|
|
31
|
+
const queryClient = useQueryClient();
|
|
32
|
+
const damConfig = useDamConfig();
|
|
33
|
+
const { rootFolderId } = damConfig;
|
|
34
|
+
const api = useMemo(() => createApiClient(damConfig), [damConfig]);
|
|
35
|
+
const { type, folderId } = useAppParams();
|
|
36
|
+
const [state, setState] = useState({
|
|
37
|
+
loading: false,
|
|
38
|
+
});
|
|
39
|
+
const { loading } = state;
|
|
40
|
+
const editorRef = useRef(null);
|
|
41
|
+
const handleSave = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
+
var _a;
|
|
43
|
+
const editedFile = yield ((_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.getEditedFile());
|
|
44
|
+
if (editedFile) {
|
|
45
|
+
setState((prevState) => (Object.assign(Object.assign({}, prevState), { loading: true })));
|
|
46
|
+
try {
|
|
47
|
+
const response = yield api.put(SAVE_EDITED_FILE_URL, {
|
|
48
|
+
path: get(file, "s3Path"),
|
|
49
|
+
});
|
|
50
|
+
const url = get(response, "data");
|
|
51
|
+
if (url) {
|
|
52
|
+
try {
|
|
53
|
+
const response = yield axios.put(url, editedFile, {
|
|
54
|
+
headers: {
|
|
55
|
+
"Content-Type": get(editedFile, "mimetype"),
|
|
56
|
+
"Access-Control-Allow-Origin": "*",
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
if (get(response, "status") === 200) {
|
|
60
|
+
try {
|
|
61
|
+
const result = yield api.put(SAVE_EDITED_FILE_THUMBNAIL_URL.replace(":fileId", get(file, "_id")), {});
|
|
62
|
+
invalidateData(queryClient, generateFoldersQueryKey(type), folderId ? folderId : rootFolderId);
|
|
63
|
+
invalidateData(queryClient, QueryKeys.FILE, get(file, "_id"));
|
|
64
|
+
showNotification(UPDATE_SUCCESS, NotificationStatus.SUCCESS);
|
|
65
|
+
handleClose();
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
showNotification(get(error, "message", FILE_UPLOAD_ERROR), NotificationStatus.ERROR);
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
setState((prevState) => (Object.assign(Object.assign({}, prevState), { loading: false })));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
showNotification(get(error, "message", FILE_UPLOAD_ERROR), NotificationStatus.ERROR);
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
setState((prevState) => (Object.assign(Object.assign({}, prevState), { loading: false })));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
showNotification(FILE_UPLOAD_ERROR, NotificationStatus.ERROR);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
showNotification(get(error, "message", SOMETHING_WENT_WRONG), NotificationStatus.ERROR);
|
|
88
|
+
setState((prevState) => (Object.assign(Object.assign({}, prevState), { loading: false })));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
showNotification("Error while saving image", NotificationStatus.ERROR);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "md-lib-bg-darkPrimaryBg md-lib-py-3 md-lib-px-5 md-lib-flex md-lib-justify-between md-lib-items-center", children: [_jsxs("div", { className: "md-lib-flex md-lib-items-center md-lib-gap-5", children: [_jsx(GoArrowLeftIcon, { className: "md-lib-text-darkTextColor", size: 24, onClick: handleClose }), _jsx("h4", { className: "md-lib-font-semibold md-lib-text-darkTextColor md-lib-text-base md-lib-truncate md-lib-w-96", title: get(file, "name", "N/A"), children: get(file, "name", "N/A") })] }), _jsxs("div", { className: "md-lib-flex md-lib-items-center md-lib-gap-4", children: [_jsx(CustomButton, { size: "large", onClick: handleClose, label: "Cancel", type: "default", className: "md-lib-bg-secondaryColor md-lib-hover:bg-secondaryHoverColor md-lib-border-none" }), _jsx(CustomButton, { size: "large", type: "primary", icon: _jsx(PiFloppyDiskIcon, { size: 24 }), onClick: handleSave, label: "Save", loading: loading })] })] }), _jsx(TuiImageEditor, { ref: editorRef, file: file, path: get(file, "s3Path") })] }));
|
|
96
|
+
};
|
|
97
|
+
export default ImageEditorComponent;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { FileEntity } from "../../utilities/constants/interface";
|
|
3
|
+
declare const EditImageModal: ({ open, handleClose, file, }: {
|
|
4
|
+
handleClose: () => void;
|
|
5
|
+
open: boolean;
|
|
6
|
+
file: FileEntity;
|
|
7
|
+
}) => React.ReactPortal | null;
|
|
8
|
+
export default EditImageModal;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import ReactDOM from "react-dom";
|
|
4
|
+
import ImageEditorComponent from "./EditImage";
|
|
5
|
+
import useAppParams from "../../utilities/useAppParams";
|
|
6
|
+
const EditImageModal = ({ open, handleClose, file, }) => {
|
|
7
|
+
const { id } = useAppParams();
|
|
8
|
+
const [state, setState] = useState({
|
|
9
|
+
visible: false,
|
|
10
|
+
});
|
|
11
|
+
const { visible } = state;
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (open) {
|
|
14
|
+
setTimeout(() => setState((prevState) => (Object.assign(Object.assign({}, prevState), { visible: true }))), 10);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
setState((prevState) => (Object.assign(Object.assign({}, prevState), { visible: false })));
|
|
18
|
+
}
|
|
19
|
+
}, [open]);
|
|
20
|
+
if (!open && !visible)
|
|
21
|
+
return null;
|
|
22
|
+
const modalContent = (_jsx("div", { className: `md-lib-fixed md-lib-inset-0 md-lib-z-[1001] md-lib-w-screen md-lib-h-screen md-lib-bg-white dark:md-lib-bg-darkPrimary md-lib-text-black dark:md-lib-text-white md-lib-overflow-auto md-lib-transform md-lib-transition-all md-lib-duration-300 md-lib-ease-in-out ${open && visible
|
|
23
|
+
? "md-lib-opacity-100 md-lib-translate-y-0"
|
|
24
|
+
: "md-lib-opacity-0 md-lib-translate-y-4"}`, onTransitionEnd: () => {
|
|
25
|
+
if (!open)
|
|
26
|
+
setState((prevState) => (Object.assign(Object.assign({}, prevState), { visible: false })));
|
|
27
|
+
}, children: _jsx(ImageEditorComponent, { file: file, handleClose: handleClose }) }));
|
|
28
|
+
return ReactDOM.createPortal(modalContent, document.body);
|
|
29
|
+
};
|
|
30
|
+
export default EditImageModal;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FileEntity } from "../../utilities/constants/interface";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import "tui-image-editor/dist/tui-image-editor.css";
|
|
4
|
+
declare const TuiImageEditor: React.ForwardRefExoticComponent<{
|
|
5
|
+
file: FileEntity;
|
|
6
|
+
path: string;
|
|
7
|
+
} & React.RefAttributes<{
|
|
8
|
+
getEditedFile: () => Promise<File | null>;
|
|
9
|
+
}>>;
|
|
10
|
+
export default TuiImageEditor;
|