@bindu-dashing/dam-solution-v2 5.8.63 → 5.8.65

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.
@@ -18,6 +18,17 @@ import { useTheme } from "../hocs/ThemeContext";
18
18
  import { InputTypes } from "../utilities/constants/interface";
19
19
  import Loader from "../common/loader/loader";
20
20
  import useAppParams from "../utilities/useAppParams";
21
+ // Fallback to useParams if useAppParams doesn't work
22
+ let useParamsFallback = () => ({});
23
+ try {
24
+ const rrd = require("react-router-dom");
25
+ if (rrd.useParams) {
26
+ useParamsFallback = rrd.useParams;
27
+ }
28
+ }
29
+ catch (_a) {
30
+ // Fallback if react-router-dom not available
31
+ }
21
32
  export default function CreateOrEditAssetTemplate() {
22
33
  const [state, setState] = useState({
23
34
  inputTypesLoading: false,
@@ -30,12 +41,15 @@ export default function CreateOrEditAssetTemplate() {
30
41
  const { variables } = useTheme();
31
42
  const api = useMemo(() => createApiClient(damConfig), [damConfig]);
32
43
  const params = useAppParams();
44
+ const routeParams = useParamsFallback();
45
+ // Merge params from both sources, routeParams take precedence
46
+ const mergedParams = useMemo(() => (Object.assign(Object.assign({}, params), routeParams)), [params, routeParams]);
33
47
  useEffect(() => {
34
48
  getInputTypesData();
35
49
  }, []);
36
50
  useEffect(() => {
37
51
  getTemplateData();
38
- }, [params]);
52
+ }, [mergedParams]);
39
53
  const getInputTypesData = () => __awaiter(this, void 0, void 0, function* () {
40
54
  setState((prevState) => {
41
55
  return Object.assign(Object.assign({}, prevState), { inputTypesLoading: true });
@@ -59,7 +73,13 @@ export default function CreateOrEditAssetTemplate() {
59
73
  return Object.assign(Object.assign({}, prevState), { templateData: true });
60
74
  });
61
75
  try {
62
- const response = yield api.get(FETCH_ASSET_URL.replace(":assetId", get(params, "id") || ""));
76
+ const assetId = get(mergedParams, "id") || "";
77
+ if (!assetId) {
78
+ console.error("Asset ID is missing from route parameters");
79
+ setState((prevState) => (Object.assign(Object.assign({}, prevState), { templatesDataLoading: false })));
80
+ return;
81
+ }
82
+ const response = yield api.get(FETCH_ASSET_URL.replace(":assetId", assetId));
63
83
  setState((prevState) => {
64
84
  return Object.assign(Object.assign({}, prevState), { templateData: get(response, "data", []), templatesDataLoading: false });
65
85
  });
@@ -26,12 +26,27 @@ import { useDamConfig } from "../hocs/DamConfigContext";
26
26
  import { createApiClient } from "../hocs/configureAxios";
27
27
  import useAppNavigate from "../utilities/useAppNavigate";
28
28
  import useAppParams from "../utilities/useAppParams";
29
+ // Fallback to useParams if useAppParams doesn't work
30
+ let useParamsFallback = () => ({});
31
+ try {
32
+ const rrd = require("react-router-dom");
33
+ if (rrd.useParams) {
34
+ useParamsFallback = rrd.useParams;
35
+ }
36
+ }
37
+ catch (_a) {
38
+ // Fallback if react-router-dom not available
39
+ }
29
40
  const { Paragraph } = Typography;
30
41
  const IoMdCloseIcon = IoMdClose;
31
42
  const FiEdit2Icon = FiEdit2;
32
43
  const FiSaveIcon = FiSave;
33
44
  export default function EditAssetTemplate({ assetTemplate, inputTypes, }) {
34
- const { id } = useAppParams();
45
+ const params = useAppParams();
46
+ const routeParams = useParamsFallback();
47
+ // Merge params from both sources, routeParams take precedence
48
+ const mergedParams = useMemo(() => (Object.assign(Object.assign({}, params), routeParams)), [params, routeParams]);
49
+ const id = mergedParams.id || params.id;
35
50
  const navigate = useAppNavigate();
36
51
  const damConfig = useDamConfig();
37
52
  const api = useMemo(() => createApiClient(damConfig), [damConfig]);
@@ -105,6 +120,11 @@ export default function EditAssetTemplate({ assetTemplate, inputTypes, }) {
105
120
  const handleSaveTemplate = () => __awaiter(this, void 0, void 0, function* () {
106
121
  const imagePickerOutputFormatHasErrors = validateImagePickerOutputFormat();
107
122
  if (!imagePickerOutputFormatHasErrors) {
123
+ if (!id) {
124
+ console.error("Asset ID is missing from route parameters");
125
+ showNotification("Asset ID is missing. Please navigate from the assets list.", NotificationStatus.ERROR);
126
+ return;
127
+ }
108
128
  setState((prevState) => (Object.assign(Object.assign({}, prevState), { loading: true })));
109
129
  try {
110
130
  const response = yield api.put(FETCH_ASSET_URL.replace(":assetId", id), {
@@ -6,6 +6,7 @@ import { ThemeProvider } from "../hocs/ThemeContext";
6
6
  import { ThemeModes } from "../utilities/constants/interface";
7
7
  import AppRoutes from "./routes";
8
8
  import ToastProvider from "../hocs/ToastProvider";
9
+ import { ParamsProvider } from "../utilities/useAppParams";
9
10
  import process from "process";
10
11
  function App(props) {
11
12
  const config = {
@@ -19,6 +20,6 @@ function App(props) {
19
20
  if (typeof window !== "undefined" && !window.process) {
20
21
  window.process = process;
21
22
  }
22
- return (_jsx(DamConfigProvider, { config: config, children: _jsxs(ThemeProvider, { styles: props === null || props === void 0 ? void 0 : props.styles, sessionTheme: ThemeModes.LIGHT, children: [_jsx(MemoryRouter, { initialEntries: ["/"], children: _jsx(AppRoutes, { routerVersion: (props === null || props === void 0 ? void 0 : props.routerVersion) || 6 }) }), _jsx(ToastProvider, {})] }) }));
23
+ return (_jsx(DamConfigProvider, { config: config, children: _jsxs(ThemeProvider, { styles: props === null || props === void 0 ? void 0 : props.styles, sessionTheme: ThemeModes.LIGHT, children: [_jsx(MemoryRouter, { initialEntries: ["/"], children: _jsx(ParamsProvider, { children: _jsx(AppRoutes, { routerVersion: (props === null || props === void 0 ? void 0 : props.routerVersion) || 6 }) }) }), _jsx(ToastProvider, {})] }) }));
23
24
  }
24
25
  export default App;
@@ -44,9 +44,7 @@ const AddDrive = ({ parentFolderId }) => {
44
44
  const { brand, rootFolderId } = damConfig;
45
45
  const brandId = get(brand, "_id");
46
46
  const { folderId } = useAppParams();
47
- // Use parentFolderId (current folder from selection) > folderId (from URL) > rootFolderId
48
47
  const currentFolderId = parentFolderId || folderId || rootFolderId;
49
- console.log('## currentFolderId', currentFolderId, 'parentFolderId', parentFolderId, 'folderId', folderId, 'rootFolderId', rootFolderId);
50
48
  const fileInputRef = useRef(null);
51
49
  const api = useMemo(() => createApiClient(damConfig), [damConfig]);
52
50
  const [state, setState] = useState({
@@ -168,6 +166,6 @@ const AddDrive = ({ parentFolderId }) => {
168
166
  },
169
167
  ];
170
168
  const toggleGenerateThumbnails = () => setState((prevState) => (Object.assign(Object.assign({}, prevState), { showGenerateThumbnails: !prevState.showGenerateThumbnails })));
171
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "md-lib-flex md-lib-gap-3", children: [_jsx(CustomButton, { label: "Generate Thumbnails", icon: _jsx(RiGalleryLineIcon, {}), size: "large", onClick: toggleGenerateThumbnails }), _jsx(Dropdown, { menu: { items }, trigger: ["click"], placement: "bottomRight", children: _jsxs(Button, { icon: _jsx(GoPlusIcon, { size: 16 }), type: "primary", size: "large", children: ["Add ", _jsx(MdKeyboardArrowDownIconIcon, {})] }) })] }), _jsx("input", { ref: fileInputRef, type: "file", style: { display: 'none' }, onChange: handleNativeFileUpload }), openFolderModal && (_jsx(AddFolder, { open: openFolderModal, handleCancel: toggleFolderModal, parentFolderId: currentFolderId })), openMapFile && (_jsx(MapFile, { open: openMapFile, handleCancel: toggleOpenMapFile, filesList: filesList, fromUpload: true })), showUploadStatus && (_jsx(UploadStatusModal, { open: showUploadStatus, statusList: uploadStatusList, onClose: () => setState((prevState) => (Object.assign(Object.assign({}, prevState), { showUploadStatus: false }))) })), openBlukUploadModal && (_jsx(BulkUploadModal, { toggleUpload: toggleFolderBulkModal, folderId: currentFolderId })), showGenerateThumbnails && (_jsx(BulkUploadModal, { toggleUpload: toggleGenerateThumbnails, thumbnailsOnly: true, folderId: currentFolderId }))] }));
169
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "md-lib-flex md-lib-gap-3", children: [_jsx(CustomButton, { label: "Generate Thumbnails", icon: _jsx(RiGalleryLineIcon, {}), size: "large", onClick: toggleGenerateThumbnails }), _jsx(Dropdown, { menu: { items }, trigger: ["click"], placement: "bottomRight", children: _jsxs(Button, { icon: _jsx(GoPlusIcon, { size: 16 }), type: "primary", size: "large", children: ["Add ", _jsx(MdKeyboardArrowDownIconIcon, {})] }) })] }), _jsx("input", { ref: fileInputRef, type: "file", style: { display: 'none' }, onChange: handleNativeFileUpload }), openFolderModal && (_jsx(AddFolder, { open: openFolderModal, handleCancel: toggleFolderModal, parentFolderId: currentFolderId })), openMapFile && (_jsx(MapFile, { open: openMapFile, handleCancel: toggleOpenMapFile, filesList: filesList, fromUpload: true, parentFolderId: currentFolderId })), showUploadStatus && (_jsx(UploadStatusModal, { open: showUploadStatus, statusList: uploadStatusList, onClose: () => setState((prevState) => (Object.assign(Object.assign({}, prevState), { showUploadStatus: false }))) })), openBlukUploadModal && (_jsx(BulkUploadModal, { toggleUpload: toggleFolderBulkModal, folderId: currentFolderId })), showGenerateThumbnails && (_jsx(BulkUploadModal, { toggleUpload: toggleGenerateThumbnails, thumbnailsOnly: true, folderId: currentFolderId }))] }));
172
170
  };
173
171
  export default AddDrive;
@@ -29,7 +29,6 @@ function AddFolder({ open, handleCancel, folder, file, onCloseSelection, fileMod
29
29
  const { folderId, type } = useAppParams();
30
30
  const damConfig = useDamConfig();
31
31
  const { rootFolderId } = damConfig;
32
- // Use parentFolderId (current folder from selection) > folderId (from URL) > rootFolderId
33
32
  const currentFolderId = parentFolderId || folderId || rootFolderId;
34
33
  const api = useMemo(() => createApiClient(damConfig), [damConfig]);
35
34
  const [state, setState] = useState({ loading: false });
@@ -41,36 +41,28 @@ const FolderGridView = ({ folders, foldersFetching, hasNextPage, fetchNextPage,
41
41
  }
42
42
  }
43
43
  else {
44
- // Check if this is a double click (same item clicked within timer window)
45
44
  const isDoubleClick = clickTimer.current !== null && lastClickedId.current === id;
46
45
  if (isDoubleClick) {
47
- // Double click detected - clear timer and handle double click action
48
46
  if (clickTimer.current) {
49
47
  clearTimeout(clickTimer.current);
50
48
  }
51
49
  clickTimer.current = null;
52
50
  lastClickedId.current = null;
53
51
  if (fileType === EntityType.FOLDER) {
54
- // Double click on folder: update tree selection (similar to FolderTree's handleSelect)
55
- // This will automatically update the DriveContainer to show the folder's contents
56
52
  if (setSelectedKeys) {
57
53
  setSelectedKeys(id);
58
54
  }
59
55
  }
60
56
  else if (fileType === EntityType.FILE && type !== DriveModes.TRASH) {
61
- // Double click on file: show preview
62
57
  setState((prevState) => (Object.assign(Object.assign({}, prevState), { selectedFile: folder, showPreviewModal: true })));
63
58
  }
64
59
  return;
65
60
  }
66
- // Single click - set timer for selection
67
61
  if (clickTimer.current) {
68
- // Different item clicked, clear previous timer
69
62
  clearTimeout(clickTimer.current);
70
63
  }
71
64
  lastClickedId.current = id;
72
65
  clickTimer.current = setTimeout(() => {
73
- // Single click action: toggle selection
74
66
  if (fileType === EntityType.FILE) {
75
67
  const alreadySelected = includes(selectedFileIds, id);
76
68
  setSelectedItems({
@@ -79,10 +79,8 @@ const FolderListView = ({ folders, foldersFetching, hasNextPage, fetchNextPage,
79
79
  }
80
80
  }
81
81
  else {
82
- // Check if this is a double click (same item clicked within timer window)
83
82
  const isDoubleClick = clickTimer.current !== null && lastClickedId.current === id;
84
83
  if (isDoubleClick) {
85
- // Double click detected - clear timer and handle double click action
86
84
  if (clickTimer.current) {
87
85
  clearTimeout(clickTimer.current);
88
86
  }
@@ -90,26 +88,20 @@ const FolderListView = ({ folders, foldersFetching, hasNextPage, fetchNextPage,
90
88
  lastClickedId.current = null;
91
89
  console.log('## isDoubleClick', isDoubleClick, id, fileType);
92
90
  if (fileType === EntityType.FOLDER) {
93
- // Double click on folder: update tree selection (similar to FolderTree's handleSelect)
94
- // This will automatically update the DriveContainer to show the folder's contents
95
91
  if (setSelectedKeys) {
96
92
  setSelectedKeys(id);
97
93
  }
98
94
  }
99
95
  else if (fileType === EntityType.FILE && type !== DriveModes.TRASH) {
100
- // Double click on file: show preview
101
96
  setState((prevState) => (Object.assign(Object.assign({}, prevState), { selectedFile: folder, showPreviewModal: true })));
102
97
  }
103
98
  return;
104
99
  }
105
- // Single click - set timer for selection
106
100
  if (clickTimer.current) {
107
- // Different item clicked, clear previous timer
108
101
  clearTimeout(clickTimer.current);
109
102
  }
110
103
  lastClickedId.current = id;
111
104
  clickTimer.current = setTimeout(() => {
112
- // Single click action: toggle selection
113
105
  if (fileType === EntityType.FILE) {
114
106
  const alreadySelected = includes(selectedFileIds, id);
115
107
  setSelectedItems({
@@ -179,7 +179,6 @@ function FolderTree({ currentRootId, expandedKeys, selectedKeys, handleExpand, s
179
179
  }
180
180
  return false;
181
181
  };
182
- // Helper to find the path (all parent IDs) to a folder in the tree
183
182
  const findPathToFolder = (folderId, tree, path = []) => {
184
183
  for (const folder of tree) {
185
184
  const currentPath = [...path, folder._id];
@@ -221,10 +220,8 @@ function FolderTree({ currentRootId, expandedKeys, selectedKeys, handleExpand, s
221
220
  if (!existingFolder || !isArray(existingFolder.children) || existingFolder.children.length === 0) {
222
221
  fetchFolderChildren(currentRootId);
223
222
  }
224
- // Expand the tree to show the path to the selected folder
225
223
  const pathToFolder = findPathToFolder(currentRootId, folders);
226
224
  if (pathToFolder && pathToFolder.length > 0) {
227
- // Remove the folder itself from the path (we only need to expand parents)
228
225
  const parentPath = pathToFolder.slice(0, -1);
229
226
  if (parentPath.length > 0) {
230
227
  const currentExpanded = isArray(expandedKeys) ? expandedKeys : [expandedKeys].filter(Boolean);
@@ -233,25 +230,16 @@ function FolderTree({ currentRootId, expandedKeys, selectedKeys, handleExpand, s
233
230
  console.log('## Expanding path to folder:', parentPath);
234
231
  }
235
232
  }
236
- // Update ref to prevent re-triggering
237
233
  prevCurrentRootIdRef.current = currentRootId;
238
234
  }
239
235
  else {
240
- // Folder not in tree - only replace tree if it's the root folder or folders is empty
241
- // For subfolders clicked from list view, keep existing tree structure to avoid replacing it
242
236
  if (currentRootId === rootFolderId || folders.length === 0) {
243
- // Root folder or empty tree - fetch as new root
244
237
  prevCurrentRootIdRef.current = currentRootId;
245
238
  fetchFolders(currentRootId);
246
239
  }
247
240
  else {
248
- // Subfolder not in tree but tree has content - keep existing tree structure
249
- // The DriveContainer will handle showing the folder contents based on parentFolderId
250
- // This prevents replacing the entire tree when clicking folders from list view
251
241
  console.log('## Folder not in tree but tree has content - keeping existing tree structure');
252
242
  prevCurrentRootIdRef.current = currentRootId;
253
- // Don't call fetchFolders here to avoid replacing the tree
254
- // The folder contents will be shown by DriveContainer based on parentFolderId
255
243
  }
256
244
  }
257
245
  }
@@ -1,8 +1,9 @@
1
1
  import { FileEntity, ResponseFile } from "../../utilities/constants/interface";
2
- declare function MapFile({ open, handleCancel, filesList, fromUpload, }: {
2
+ declare function MapFile({ open, handleCancel, filesList, fromUpload, parentFolderId, }: {
3
3
  open?: boolean;
4
4
  handleCancel?: () => void;
5
5
  filesList: ResponseFile[] | FileEntity[];
6
6
  fromUpload?: boolean;
7
+ parentFolderId?: string;
7
8
  }): JSX.Element;
8
9
  export default MapFile;
@@ -27,12 +27,13 @@ import { DATE_FORMAT, DATE_WITH_TIME_FORMAT } from "../../hocs/appConstants";
27
27
  import dayjs from "dayjs";
28
28
  import useAppNavigate from "../../utilities/useAppNavigate";
29
29
  import { addQueryParams } from "../../hocs/helpers";
30
- function MapFile({ open, handleCancel, filesList, fromUpload, }) {
30
+ function MapFile({ open, handleCancel, filesList, fromUpload, parentFolderId, }) {
31
31
  const { folderId, type } = useAppParams();
32
32
  const damConfig = useDamConfig();
33
33
  const externalTeams = (damConfig === null || damConfig === void 0 ? void 0 : damConfig.teams) || [];
34
34
  const { rootFolderId, brand } = damConfig;
35
35
  const brandId = get(brand, "_id");
36
+ const currentFolderId = parentFolderId || folderId || rootFolderId;
36
37
  const queryClient = useQueryClient();
37
38
  const [form] = Form.useForm();
38
39
  const api = useMemo(() => createApiClient(damConfig), [damConfig]);
@@ -92,7 +93,7 @@ function MapFile({ open, handleCancel, filesList, fromUpload, }) {
92
93
  mutationFn: updateFile,
93
94
  onSuccess: (response) => {
94
95
  invalidateData(queryClient, QueryKeys.FILE, get(file, "_id"));
95
- invalidateData(queryClient, generateFoldersQueryKey(type), folderId ? folderId : rootFolderId);
96
+ invalidateData(queryClient, generateFoldersQueryKey(type), currentFolderId);
96
97
  setState((prevState) => (Object.assign(Object.assign({}, prevState), { editTemplate: false, editForm: false })));
97
98
  showNotification(get(response, "data.message", UPDATE_SUCCESS), NotificationStatus.SUCCESS);
98
99
  },
@@ -115,7 +116,7 @@ function MapFile({ open, handleCancel, filesList, fromUpload, }) {
115
116
  const formattedValues = getFormattedMetadata(values);
116
117
  const expiryDate = values.expiryDate || null;
117
118
  delete values.expiryDate;
118
- const response = yield api.post(CREATE_FILE_URL, Object.assign(Object.assign({}, values), { folderId: folderId || rootFolderId, files: map(filesList, (file) => {
119
+ const response = yield api.post(CREATE_FILE_URL, Object.assign(Object.assign({}, values), { folderId: currentFolderId, files: map(filesList, (file) => {
119
120
  const fileData = {
120
121
  name: get(file, "name"),
121
122
  path: get(file, "filePath"),
@@ -136,8 +137,8 @@ function MapFile({ open, handleCancel, filesList, fromUpload, }) {
136
137
  showNotification(get(error, "message", SOMETHING_WENT_WRONG), NotificationStatus.ERROR);
137
138
  }
138
139
  finally {
139
- invalidateData(queryClient, QueryKeys.FILE, folderId || rootFolderId);
140
- invalidateData(queryClient, QueryKeys.FOLDERS, folderId || rootFolderId);
140
+ invalidateData(queryClient, QueryKeys.FILE, currentFolderId);
141
+ invalidateData(queryClient, QueryKeys.FOLDERS, currentFolderId);
141
142
  setState((prevState) => (Object.assign(Object.assign({}, prevState), { loading: false })));
142
143
  }
143
144
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bindu-dashing/dam-solution-v2",
3
- "version": "5.8.63",
3
+ "version": "5.8.65",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.0.1",
6
6
  "@emoji-mart/data": "^1.2.1",