@anji-dashing/dam-solution-v2 5.8.175 → 5.8.176
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/build/AssetType/AddFieldProperties.js +53 -13
- package/build/AssetType/EditAssetTemplate.js +2 -2
- package/build/AssetType/FieldsSection.d.ts +2 -1
- package/build/AssetType/FieldsSection.js +8 -3
- package/build/CreateClient/CreateClientBtn.d.ts +2 -1
- package/build/CreateClient/CreateClientBtn.js +9 -2
- package/build/CreateClient/CreateClientForm.js +108 -47
- package/build/CreateClient/index.d.ts +1 -0
- package/build/CreateClient/index.js +7 -5
- package/build/MyDrive/BulkUploadModal.js +3 -5
- package/build/MyDrive/FolderListView.js +1 -1
- package/build/MyDrive/FolderTree.js +25 -4
- package/build/MyDrive/MyDriveMainContainer.d.ts +1 -1
- package/build/MyDrive/MyDriveMainContainer.js +9 -6
- package/build/MyDrive/fileDetails/FileDetails.js +27 -7
- package/build/MyDrive/fileDetails/FileHeader.js +2 -4
- package/build/MyDrive/fileDetails/FileViewer.js +2 -2
- package/build/MyDrive/fileDetails/MetaForm.d.ts +6 -1
- package/build/MyDrive/fileDetails/MetaForm.js +46 -9
- package/build/MyDrive/fileDetails/Previewdetails.js +1 -3
- package/build/MyDrive/files/MapFile.d.ts +2 -1
- package/build/MyDrive/files/MapFile.js +10 -4
- package/build/MyDrive/index.d.ts +3 -1
- package/build/MyDrive/index.js +2 -0
- package/build/MyDrive/routes.d.ts +1 -1
- package/build/hocs/DamConfigContext.js +2 -1
- package/package.json +1 -1
|
@@ -214,13 +214,42 @@ export default function AddFieldProperties({ field, setCurrentFieldIndex, onUpda
|
|
|
214
214
|
setDisabledReason(null);
|
|
215
215
|
}, 100);
|
|
216
216
|
}, [field, form]);
|
|
217
|
+
// Strip time from dayjs (set to midnight) - used when "Allow time" is toggled OFF
|
|
218
|
+
const stripTimeFromDayjs = (d) => {
|
|
219
|
+
if (!d || typeof d.hour !== "function")
|
|
220
|
+
return d;
|
|
221
|
+
return d.hour(0).minute(0).second(0).millisecond(0);
|
|
222
|
+
};
|
|
217
223
|
// Update defaultValueInput whenever form values change
|
|
218
|
-
const handleFormValuesChange = () => {
|
|
224
|
+
const handleFormValuesChange = (changedValues, allValues) => {
|
|
219
225
|
var _a;
|
|
220
|
-
const formValues = form.getFieldsValue(true);
|
|
226
|
+
const formValues = allValues !== null && allValues !== void 0 ? allValues : form.getFieldsValue(true);
|
|
221
227
|
const defaultName = currentInputType === null || currentInputType === void 0 ? void 0 : currentInputType.defaultName;
|
|
228
|
+
// When "Allow time" is toggled OFF for DATE/DATE_RANGE, strip time from defaultValue
|
|
229
|
+
const settings = get(formValues, "inputTypeSettings", {});
|
|
230
|
+
const allowTime = !!get(settings, `${InputSupportedTypes.ALLOW_TIME}.allow`);
|
|
231
|
+
const allowTimeChanged = changedValues && get(changedValues, "inputTypeSettings");
|
|
232
|
+
if (allowTimeChanged &&
|
|
233
|
+
!allowTime &&
|
|
234
|
+
(defaultName === InputTypes.DATE || defaultName === InputTypes.DATE_RANGE)) {
|
|
235
|
+
const currentDefault = get(formValues, "defaultValue");
|
|
236
|
+
if (currentDefault) {
|
|
237
|
+
let normalized = null;
|
|
238
|
+
if (defaultName === InputTypes.DATE_RANGE && isArray(currentDefault)) {
|
|
239
|
+
normalized = [
|
|
240
|
+
stripTimeFromDayjs(first(currentDefault)),
|
|
241
|
+
stripTimeFromDayjs(nth(currentDefault, 1)),
|
|
242
|
+
];
|
|
243
|
+
}
|
|
244
|
+
else if (defaultName === InputTypes.DATE) {
|
|
245
|
+
normalized = stripTimeFromDayjs(currentDefault);
|
|
246
|
+
}
|
|
247
|
+
if (normalized !== null) {
|
|
248
|
+
form.setFieldValue("defaultValue", normalized);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
222
252
|
const options = ((_a = formValues.options) === null || _a === void 0 ? void 0 : _a.filter((opt) => (opt === null || opt === void 0 ? void 0 : opt.label) && (opt === null || opt === void 0 ? void 0 : opt.value))) || [];
|
|
223
|
-
const settings = formValues.inputTypeSettings || {};
|
|
224
253
|
const isOptionsBasedField = includes([InputTypes.SELECT, InputTypes.CHECKBOX, InputTypes.RADIO], defaultName);
|
|
225
254
|
if (isOptionsBasedField && options.length === 0) {
|
|
226
255
|
// Don't show Default Value field if no options exist
|
|
@@ -280,6 +309,11 @@ export default function AddFieldProperties({ field, setCurrentFieldIndex, onUpda
|
|
|
280
309
|
if ((defaultName === InputTypes.DATE ||
|
|
281
310
|
defaultName === InputTypes.DATE_RANGE) &&
|
|
282
311
|
settings[InputSupportedTypes.ALLOW_TIME] !== undefined) {
|
|
312
|
+
const hasNonZeroTime = (d) => {
|
|
313
|
+
if (!d || typeof d.hour !== "function")
|
|
314
|
+
return false;
|
|
315
|
+
return d.hour() !== 0 || d.minute() !== 0 || d.second() !== 0;
|
|
316
|
+
};
|
|
283
317
|
rules.push({
|
|
284
318
|
validator: (_, value) => {
|
|
285
319
|
const allowTime = !!get(settings, `${InputSupportedTypes.ALLOW_TIME}.allow`);
|
|
@@ -291,10 +325,13 @@ export default function AddFieldProperties({ field, setCurrentFieldIndex, onUpda
|
|
|
291
325
|
typeof value.hour === "function" &&
|
|
292
326
|
typeof value.minute === "function" &&
|
|
293
327
|
typeof value.second === "function";
|
|
328
|
+
// When time is allowed: accept any moment with time methods (including 00:00:00 - midnight is valid)
|
|
329
|
+
// Only reject if value lacks time methods (e.g. date-only format)
|
|
294
330
|
if (allowTime && !hasTimeMethods) {
|
|
295
331
|
return Promise.reject("Please select a date with time (hour/minute/second).");
|
|
296
332
|
}
|
|
297
|
-
|
|
333
|
+
// When time is not allowed: strip time (handled in onValuesChange) - reject only if still has non-zero time
|
|
334
|
+
if (!allowTime && hasNonZeroTime(value)) {
|
|
298
335
|
return Promise.reject("Time is not allowed. Please select only a date.");
|
|
299
336
|
}
|
|
300
337
|
}
|
|
@@ -309,10 +346,13 @@ export default function AddFieldProperties({ field, setCurrentFieldIndex, onUpda
|
|
|
309
346
|
typeof end.hour === "function" &&
|
|
310
347
|
typeof end.minute === "function" &&
|
|
311
348
|
typeof end.second === "function";
|
|
349
|
+
// When time is allowed: accept any moment with time methods (including 00:00:00 - midnight is valid)
|
|
350
|
+
// Only reject if start or end lacks time methods
|
|
312
351
|
if (allowTime && (!startHasTimeMethods || !endHasTimeMethods)) {
|
|
313
352
|
return Promise.reject("Please select both start and end dates with time.");
|
|
314
353
|
}
|
|
315
|
-
|
|
354
|
+
// When time is not allowed: strip time (handled in onValuesChange) - reject only if still has non-zero time
|
|
355
|
+
if (!allowTime && (hasNonZeroTime(start) || hasNonZeroTime(end))) {
|
|
316
356
|
return Promise.reject("Time is not allowed. Please select only dates.");
|
|
317
357
|
}
|
|
318
358
|
}
|
|
@@ -348,12 +388,12 @@ export default function AddFieldProperties({ field, setCurrentFieldIndex, onUpda
|
|
|
348
388
|
InputTypes.TEAM,
|
|
349
389
|
InputTypes.CHECKBOX,
|
|
350
390
|
InputTypes.RADIO,
|
|
351
|
-
], get(currentInputType, "defaultName")) && (_jsx(OptionsField, { field: field, supportedTypes: get(currentInputType, "supportedTypes", []), currentInputType: currentInputType }))] })] }),
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
391
|
+
], get(currentInputType, "defaultName")) && (_jsx(OptionsField, { field: field, supportedTypes: get(currentInputType, "supportedTypes", []), currentInputType: currentInputType }))] })] }), _jsx(Form.Item, { className: "md-lib-flex md-lib-flex-col md-lib-items-end md-lib-absolute md-lib-bottom-0 md-lib-right-0 md-lib-pr-4 md-lib-pb-4", children: _jsxs("div", { className: "md-lib-flex md-lib-items-center", children: [_jsx(Button, { color: "primary", variant: "text", onClick: () => {
|
|
392
|
+
if (onCancel && index !== null) {
|
|
393
|
+
onCancel(index);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
setCurrentFieldIndex(null);
|
|
397
|
+
}
|
|
398
|
+
}, size: "large", children: "Cancel" }), _jsx(Button, { color: "primary", htmlType: "submit", className: "md-lib-ml-2 md-lib-border-primaryColor md-lib-text-primaryColor", size: "large", loading: loading, disabled: !isFormValid || loading, title: disabledReason || undefined, children: "Update" })] }) })] }) })] }));
|
|
359
399
|
}
|
|
@@ -218,13 +218,13 @@ export default function EditAssetTemplate({ assetTemplate, inputTypes, }) {
|
|
|
218
218
|
{
|
|
219
219
|
key: "1",
|
|
220
220
|
label: "Fields",
|
|
221
|
-
children: (_jsx(AddWidgets, { name: name, inputTypes: inputTypes, transformInputTypePayload: transformInputTypePayload, currentFieldIndex: currentFieldIndex, setState: setState, fields: fields, imagePickerOutputFormat: imagePickerOutputFormat, setCurrentFieldIndex: (value) => setState((prevState) => (Object.assign(Object.assign({}, prevState), { currentFieldIndex: value }))), showOutputFormat: false })),
|
|
221
|
+
children: (_jsx(AddWidgets, { name: name, inputTypes: inputTypes, transformInputTypePayload: transformInputTypePayload, currentFieldIndex: currentFieldIndex, setState: setState, fields: fields, imagePickerOutputFormat: imagePickerOutputFormat, setCurrentFieldIndex: (value) => setState((prevState) => (Object.assign(Object.assign({}, prevState), { currentFieldIndex: value }))), showOutputFormat: false, assetId: id || get(assetTemplate, "_id") })),
|
|
222
222
|
},
|
|
223
223
|
{
|
|
224
224
|
key: "2",
|
|
225
225
|
label: "Image picker output format",
|
|
226
226
|
disabled: fields.length === 0,
|
|
227
|
-
children: (_jsx(AddWidgets, { name: name, inputTypes: inputTypes, transformInputTypePayload: transformInputTypePayload, currentFieldIndex: currentFieldIndex, setState: setState, fields: fields, imagePickerOutputFormat: imagePickerOutputFormat, setCurrentFieldIndex: (value) => setState((prevState) => (Object.assign(Object.assign({}, prevState), { currentFieldIndex: value }))), showOutputFormat: true })),
|
|
227
|
+
children: (_jsx(AddWidgets, { name: name, inputTypes: inputTypes, transformInputTypePayload: transformInputTypePayload, currentFieldIndex: currentFieldIndex, setState: setState, fields: fields, imagePickerOutputFormat: imagePickerOutputFormat, setCurrentFieldIndex: (value) => setState((prevState) => (Object.assign(Object.assign({}, prevState), { currentFieldIndex: value }))), showOutputFormat: true, assetId: id || get(assetTemplate, "_id") })),
|
|
228
228
|
},
|
|
229
229
|
];
|
|
230
230
|
// console.log("edit asset template", fields, imagePickerOutputFormat);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SetStateAction } from "react";
|
|
2
2
|
import { InputTypeEntity } from "../utilities/constants/interface";
|
|
3
3
|
export declare const getWidgetIcon: (defaultName: string | undefined | null) => import("react-icons").IconType | null;
|
|
4
|
-
export default function FieldsSection({ name, inputTypes, transformInputTypePayload, currentFieldIndex, setCurrentFieldIndex, fields, setState, showOutputFormat, imagePickerOutputFormat, }: {
|
|
4
|
+
export default function FieldsSection({ name, inputTypes, transformInputTypePayload, currentFieldIndex, setCurrentFieldIndex, fields, setState, showOutputFormat, imagePickerOutputFormat, assetId: assetIdProp, }: {
|
|
5
5
|
name: string;
|
|
6
6
|
inputTypes: InputTypeEntity[];
|
|
7
7
|
transformInputTypePayload: (values: any, field: InputTypeEntity, mapId: string) => void;
|
|
@@ -11,4 +11,5 @@ export default function FieldsSection({ name, inputTypes, transformInputTypePayl
|
|
|
11
11
|
setState: React.Dispatch<SetStateAction<any>>;
|
|
12
12
|
showOutputFormat: boolean;
|
|
13
13
|
imagePickerOutputFormat: InputTypeEntity[];
|
|
14
|
+
assetId?: string;
|
|
14
15
|
}): JSX.Element;
|
|
@@ -76,8 +76,9 @@ export const getWidgetIcon = (defaultName) => {
|
|
|
76
76
|
return null;
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
|
-
export default function FieldsSection({ name, inputTypes, transformInputTypePayload, currentFieldIndex, setCurrentFieldIndex, fields, setState, showOutputFormat, imagePickerOutputFormat, }) {
|
|
80
|
-
const { id } = useAppParams();
|
|
79
|
+
export default function FieldsSection({ name, inputTypes, transformInputTypePayload, currentFieldIndex, setCurrentFieldIndex, fields, setState, showOutputFormat, imagePickerOutputFormat, assetId: assetIdProp, }) {
|
|
80
|
+
const { id: idFromParams } = useAppParams();
|
|
81
|
+
const assetId = assetIdProp !== null && assetIdProp !== void 0 ? assetIdProp : idFromParams;
|
|
81
82
|
const [fieldState, setFieldState] = useState({
|
|
82
83
|
showConfirmModal: false,
|
|
83
84
|
selectedField: null,
|
|
@@ -166,9 +167,13 @@ export default function FieldsSection({ name, inputTypes, transformInputTypePayl
|
|
|
166
167
|
}
|
|
167
168
|
};
|
|
168
169
|
const onDeleteExistedField = () => __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
if (!assetId) {
|
|
171
|
+
showNotification("Asset ID is missing. Unable to delete field.", NotificationStatus.ERROR);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
169
174
|
setFieldState((prevState) => (Object.assign(Object.assign({}, prevState), { loading: true })));
|
|
170
175
|
try {
|
|
171
|
-
const response = yield api.delete(DELETE_ASSET_FIELD_URL.replace(":assetId",
|
|
176
|
+
const response = yield api.delete(DELETE_ASSET_FIELD_URL.replace(":assetId", assetId).replace(":id", get(selectedField, "_id")));
|
|
172
177
|
const updatedFields = filter(fields, (field, index) => get(field, "_id") !== get(selectedField, "_id"));
|
|
173
178
|
const updatedImagePickerOutputFormat = filter(imagePickerOutputFormat, (field, index) => get(field, "mapId") !== get(selectedField, "mapId"));
|
|
174
179
|
setState((prevState) => (Object.assign(Object.assign({}, prevState), { fields: updatedFields, currentFieldIndex: null, imagePickerOutputFormat: updatedImagePickerOutputFormat })));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
declare const CreateClient: ({ onSuccess, clientSubdomain, teamsApi, username, password, existingClientData, }: {
|
|
1
|
+
declare const CreateClient: ({ onSuccess, onRefreshSuccess, clientSubdomain, teamsApi, username, password, existingClientData, }: {
|
|
2
2
|
onSuccess: (data: any) => void;
|
|
3
|
+
onRefreshSuccess?: (data: any) => void;
|
|
3
4
|
clientSubdomain: string;
|
|
4
5
|
teamsApi: string;
|
|
5
6
|
username: string;
|
|
@@ -18,7 +18,7 @@ import { showNotification } from "../common/notifications";
|
|
|
18
18
|
import { NotificationStatus } from "../utilities/constants/interface";
|
|
19
19
|
import { SOMETHING_WENT_WRONG } from "../utilities/constants/messages";
|
|
20
20
|
import { get } from "lodash";
|
|
21
|
-
const CreateClient = ({ onSuccess, clientSubdomain, teamsApi, username, password, existingClientData, }) => {
|
|
21
|
+
const CreateClient = ({ onSuccess, onRefreshSuccess, clientSubdomain, teamsApi, username, password, existingClientData, }) => {
|
|
22
22
|
const [showForm, setShowForm] = useState(false);
|
|
23
23
|
const [refreshingKey, setRefreshingKey] = useState(false);
|
|
24
24
|
const isEditMode = !!existingClientData;
|
|
@@ -32,6 +32,10 @@ const CreateClient = ({ onSuccess, clientSubdomain, teamsApi, username, password
|
|
|
32
32
|
showNotification("Access key and secret key are required to refresh", NotificationStatus.ERROR);
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
|
+
if (!(damConfig === null || damConfig === void 0 ? void 0 : damConfig.accessToken)) {
|
|
36
|
+
showNotification("Authentication token is not available. Please wait for the page to load or try again.", NotificationStatus.ERROR);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
35
39
|
setRefreshingKey(true);
|
|
36
40
|
try {
|
|
37
41
|
const response = yield api.put(REFRESH_KEY_URL, {
|
|
@@ -40,7 +44,10 @@ const CreateClient = ({ onSuccess, clientSubdomain, teamsApi, username, password
|
|
|
40
44
|
});
|
|
41
45
|
setRefreshingKey(false);
|
|
42
46
|
showNotification(get(response, "data.message", "Key refreshed successfully"), NotificationStatus.SUCCESS);
|
|
43
|
-
if (
|
|
47
|
+
if (onRefreshSuccess) {
|
|
48
|
+
onRefreshSuccess(response === null || response === void 0 ? void 0 : response.data);
|
|
49
|
+
}
|
|
50
|
+
else if (onSuccess) {
|
|
44
51
|
onSuccess(response === null || response === void 0 ? void 0 : response.data);
|
|
45
52
|
}
|
|
46
53
|
}
|
|
@@ -152,66 +152,105 @@ const CreateClientForm = ({ teamsApi, username, password, toggleShow, onSuccess,
|
|
|
152
152
|
fetchClientData();
|
|
153
153
|
}, [isEditMode, existingClientData === null || existingClientData === void 0 ? void 0 : existingClientData.brandId, existingClientData === null || existingClientData === void 0 ? void 0 : existingClientData.subdomain, api, form]);
|
|
154
154
|
const onFinish = (data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
155
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
155
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
156
156
|
try {
|
|
157
|
-
// Use teamsApiDetails from clientData if available (from API response), otherwise use props
|
|
158
|
-
const teamsApiDetailsFromData = get(clientData, "teamsApiDetails", {});
|
|
159
|
-
const finalTeamsApi = teamsApiDetailsFromData.teamsApi || teamsApi;
|
|
160
|
-
const finalUsername = teamsApiDetailsFromData.username || username;
|
|
161
|
-
const finalPassword = teamsApiDetailsFromData.password || password;
|
|
162
|
-
// Convert adminTeams to strings for API (API expects strings like ["547"] not numbers like [547])
|
|
163
|
-
const adminTeamsAsStrings = Array.isArray(data.adminTeams)
|
|
164
|
-
? data.adminTeams.map((team) => String(team))
|
|
165
|
-
: [];
|
|
166
|
-
const values = Object.assign(Object.assign({}, data), { adminTeams: adminTeamsAsStrings, showFilePreview: (_a = data.showFilePreview) !== null && _a !== void 0 ? _a : false, accessKey: appType == "reactJs"
|
|
167
|
-
? process.env.REACT_APP_MIXDRIVE_CLIENT_PARENT_ACCESS_KEY
|
|
168
|
-
: process.env.NEXT_PUBLIC_MIXDRIVE_CLIENT_PARENT_ACCESS_KEY, secretKey: appType == "reactJs"
|
|
169
|
-
? process.env.REACT_APP_MIXDRIVE_CLIENT_PARENT_SECRET_KEY
|
|
170
|
-
: process.env.NEXT_PUBLIC_MIXDRIVE_CLIENT_PARENT_SECRET_KEY, parentSubdomain: appType == "reactJs"
|
|
171
|
-
? process.env.REACT_APP_MIXDRIVE_CLIENT_PARENT_SUBDOMAIN
|
|
172
|
-
: process.env.NEXT_PUBLIC_MIXDRIVE_CLIENT_PARENT_SUBDOMAIN, teamsApiDetails: {
|
|
173
|
-
teamsApi: finalTeamsApi,
|
|
174
|
-
username: finalUsername,
|
|
175
|
-
password: finalPassword,
|
|
176
|
-
}, damLocationDetails: damLocationType === "external"
|
|
177
|
-
? {
|
|
178
|
-
bucket: (_b = data === null || data === void 0 ? void 0 : data.damLocationDetails) === null || _b === void 0 ? void 0 : _b.bucket,
|
|
179
|
-
locationType: "EXTERNAL",
|
|
180
|
-
rootPath: (_c = data === null || data === void 0 ? void 0 : data.damLocationDetails) === null || _c === void 0 ? void 0 : _c.rootPath,
|
|
181
|
-
accessKeyId: (_d = data === null || data === void 0 ? void 0 : data.damLocationDetails) === null || _d === void 0 ? void 0 : _d.accessKeyId,
|
|
182
|
-
secretAccessKey: (_e = data === null || data === void 0 ? void 0 : data.damLocationDetails) === null || _e === void 0 ? void 0 : _e.secretAccessKey,
|
|
183
|
-
url: (_f = data === null || data === void 0 ? void 0 : data.damLocationDetails) === null || _f === void 0 ? void 0 : _f.url,
|
|
184
|
-
region: (_g = data === null || data === void 0 ? void 0 : data.damLocationDetails) === null || _g === void 0 ? void 0 : _g.region,
|
|
185
|
-
}
|
|
186
|
-
: {
|
|
187
|
-
locationType: "INTERNAL",
|
|
188
|
-
rootPath: (_h = data === null || data === void 0 ? void 0 : data.damLocationDetails) === null || _h === void 0 ? void 0 : _h.rootPath,
|
|
189
|
-
} });
|
|
190
157
|
setLoading(true);
|
|
191
158
|
let response;
|
|
192
159
|
const baseUrl = getBaseUrl(appType);
|
|
193
160
|
if (isEditMode && brandIdForUpdate && authToken) {
|
|
194
|
-
//
|
|
195
|
-
const
|
|
161
|
+
// Edit mode: send only changed fields via PUT
|
|
162
|
+
const adminTeamsAsStrings = Array.isArray(data.adminTeams)
|
|
163
|
+
? data.adminTeams.map((team) => String(team))
|
|
164
|
+
: [];
|
|
165
|
+
const existingAdminTeams = (get(clientData, "adminTeams", []) || []).map((t) => String(t));
|
|
166
|
+
const arraysEqual = (a, b) => {
|
|
167
|
+
const sa = [...a].sort();
|
|
168
|
+
const sb = [...b].sort();
|
|
169
|
+
return sa.length === sb.length && sa.every((v, i) => v === sb[i]);
|
|
170
|
+
};
|
|
171
|
+
const accessTypesChanged = JSON.stringify([...(data.accessTypes || [])].sort()) !==
|
|
172
|
+
JSON.stringify([...(get(clientData, "accessTypes", []) || [])].sort());
|
|
173
|
+
const payload = {};
|
|
174
|
+
if (data.name !== get(clientData, "name"))
|
|
175
|
+
payload.name = data.name;
|
|
176
|
+
if (accessTypesChanged)
|
|
177
|
+
payload.accessTypes = data.accessTypes || [];
|
|
178
|
+
if (!arraysEqual(adminTeamsAsStrings, existingAdminTeams))
|
|
179
|
+
payload.adminTeams = adminTeamsAsStrings;
|
|
180
|
+
if (((_a = data.showFilePreview) !== null && _a !== void 0 ? _a : false) !== get(clientData, "showFilePreview", false))
|
|
181
|
+
payload.showFilePreview = (_b = data.showFilePreview) !== null && _b !== void 0 ? _b : false;
|
|
182
|
+
if (Object.keys(payload).length === 0) {
|
|
183
|
+
setLoading(false);
|
|
184
|
+
showNotification("No changes to save", NotificationStatus.INFO);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const putResponse = yield axios.put(`${baseUrl}/brands/${brandIdForUpdate}`, payload, {
|
|
196
188
|
headers: {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
189
|
+
Authorization: `Bearer ${authToken}`,
|
|
190
|
+
"Content-Type": "application/json",
|
|
191
|
+
accept: "application/json, text/plain, */*",
|
|
192
|
+
},
|
|
201
193
|
});
|
|
202
194
|
// Extract data from axios response (API returns { data: {...} } or { data: { data: {...} } })
|
|
203
195
|
response = get(putResponse, "data.data", get(putResponse, "data", putResponse));
|
|
204
196
|
}
|
|
205
197
|
else {
|
|
206
|
-
// Create new client: POST to /brands/sub-brand
|
|
198
|
+
// Create new client: POST to /brands/sub-brand (full payload required)
|
|
199
|
+
const teamsApiDetailsFromData = clientData ? get(clientData, "teamsApiDetails", {}) : {};
|
|
200
|
+
const finalTeamsApi = teamsApiDetailsFromData.teamsApi || teamsApi;
|
|
201
|
+
const finalUsername = teamsApiDetailsFromData.username || username;
|
|
202
|
+
const finalPassword = teamsApiDetailsFromData.password || password;
|
|
203
|
+
const adminTeamsAsStrings = Array.isArray(data.adminTeams)
|
|
204
|
+
? data.adminTeams.map((team) => String(team))
|
|
205
|
+
: [];
|
|
206
|
+
const formDamLocation = data === null || data === void 0 ? void 0 : data.damLocationDetails;
|
|
207
|
+
const damLocationDetails = damLocationType === "external"
|
|
208
|
+
? {
|
|
209
|
+
bucket: formDamLocation === null || formDamLocation === void 0 ? void 0 : formDamLocation.bucket,
|
|
210
|
+
locationType: "EXTERNAL",
|
|
211
|
+
rootPath: formDamLocation === null || formDamLocation === void 0 ? void 0 : formDamLocation.rootPath,
|
|
212
|
+
accessKeyId: formDamLocation === null || formDamLocation === void 0 ? void 0 : formDamLocation.accessKeyId,
|
|
213
|
+
secretAccessKey: formDamLocation === null || formDamLocation === void 0 ? void 0 : formDamLocation.secretAccessKey,
|
|
214
|
+
url: formDamLocation === null || formDamLocation === void 0 ? void 0 : formDamLocation.url,
|
|
215
|
+
region: formDamLocation === null || formDamLocation === void 0 ? void 0 : formDamLocation.region,
|
|
216
|
+
}
|
|
217
|
+
: {
|
|
218
|
+
locationType: "INTERNAL",
|
|
219
|
+
rootPath: formDamLocation === null || formDamLocation === void 0 ? void 0 : formDamLocation.rootPath,
|
|
220
|
+
};
|
|
221
|
+
const values = Object.assign(Object.assign({}, data), { adminTeams: adminTeamsAsStrings, showFilePreview: (_c = data.showFilePreview) !== null && _c !== void 0 ? _c : false, accessKey: appType == "reactJs"
|
|
222
|
+
? process.env.REACT_APP_MIXDRIVE_CLIENT_PARENT_ACCESS_KEY
|
|
223
|
+
: process.env.NEXT_PUBLIC_MIXDRIVE_CLIENT_PARENT_ACCESS_KEY, secretKey: appType == "reactJs"
|
|
224
|
+
? process.env.REACT_APP_MIXDRIVE_CLIENT_PARENT_SECRET_KEY
|
|
225
|
+
: process.env.NEXT_PUBLIC_MIXDRIVE_CLIENT_PARENT_SECRET_KEY, parentSubdomain: appType == "reactJs"
|
|
226
|
+
? process.env.REACT_APP_MIXDRIVE_CLIENT_PARENT_SUBDOMAIN
|
|
227
|
+
: process.env.NEXT_PUBLIC_MIXDRIVE_CLIENT_PARENT_SUBDOMAIN, teamsApiDetails: {
|
|
228
|
+
teamsApi: finalTeamsApi,
|
|
229
|
+
username: finalUsername,
|
|
230
|
+
password: finalPassword,
|
|
231
|
+
}, damLocationDetails });
|
|
207
232
|
response = yield api.post(CREATE_SUB_BRAND, values);
|
|
208
233
|
}
|
|
209
234
|
setLoading(false);
|
|
210
|
-
showNotification((
|
|
211
|
-
|
|
235
|
+
showNotification((_d = response === null || response === void 0 ? void 0 : response.message) !== null && _d !== void 0 ? _d : (get(response, "message") || CREATE_SUCCESS), NotificationStatus.SUCCESS);
|
|
236
|
+
// Call onSuccess before closing drawer so parent can show its toast (e.g. d1-admin, ThemePage)
|
|
237
|
+
// Parent expects accessKey, secretKey, subdomain - always provide when in edit mode
|
|
212
238
|
if (onSuccess) {
|
|
213
|
-
|
|
239
|
+
const successData = isEditMode
|
|
240
|
+
? Object.assign(Object.assign(Object.assign({}, response === null || response === void 0 ? void 0 : response.data), response), { accessKey: (_f = (_e = existingClientData === null || existingClientData === void 0 ? void 0 : existingClientData.accessKey) !== null && _e !== void 0 ? _e : get(response, "accessKey")) !== null && _f !== void 0 ? _f : get(clientData, "accessKey"), secretKey: (_h = (_g = existingClientData === null || existingClientData === void 0 ? void 0 : existingClientData.secretKey) !== null && _g !== void 0 ? _g : get(response, "secretKey")) !== null && _h !== void 0 ? _h : get(clientData, "secretKey"), subdomain: (_l = (_k = (_j = data === null || data === void 0 ? void 0 : data.subdomain) !== null && _j !== void 0 ? _j : existingClientData === null || existingClientData === void 0 ? void 0 : existingClientData.subdomain) !== null && _k !== void 0 ? _k : get(response, "subdomain")) !== null && _l !== void 0 ? _l : get(clientData, "subdomain") }) : (_m = response === null || response === void 0 ? void 0 : response.data) !== null && _m !== void 0 ? _m : response;
|
|
241
|
+
// Guard: parent (e.g. ThemePage.onCreateDamClient) accesses data.accessKey - never pass undefined
|
|
242
|
+
const safeData = successData && typeof successData === "object"
|
|
243
|
+
? successData
|
|
244
|
+
: isEditMode && existingClientData
|
|
245
|
+
? {
|
|
246
|
+
accessKey: existingClientData.accessKey,
|
|
247
|
+
secretKey: existingClientData.secretKey,
|
|
248
|
+
subdomain: existingClientData.subdomain,
|
|
249
|
+
}
|
|
250
|
+
: {};
|
|
251
|
+
onSuccess(safeData);
|
|
214
252
|
}
|
|
253
|
+
toggleShow();
|
|
215
254
|
}
|
|
216
255
|
catch (error) {
|
|
217
256
|
setLoading(false);
|
|
@@ -300,7 +339,7 @@ const CreateClientForm = ({ teamsApi, username, password, toggleShow, onSuccess,
|
|
|
300
339
|
required: true,
|
|
301
340
|
message: "Team Ids is required",
|
|
302
341
|
},
|
|
303
|
-
], children: _jsx(Select, { showSearch: true, mode: "multiple", placeholder: "Team Ids", options: filteredTeams, optionFilterProp: "key" }) }), _jsxs(Form.Item, { label: "DAM Location Details", name: "damLocationDetails", children: [_jsx(Form.Item, { label: "Type", name: ["damLocationDetails", "type"], rules: [
|
|
342
|
+
], children: _jsx(Select, { showSearch: true, mode: "multiple", placeholder: "Team Ids", options: filteredTeams, optionFilterProp: "key" }) }), !isEditMode && (_jsxs(Form.Item, { label: "DAM Location Details", name: "damLocationDetails", children: [_jsx(Form.Item, { label: "Type", name: ["damLocationDetails", "type"], rules: [
|
|
304
343
|
{
|
|
305
344
|
required: true,
|
|
306
345
|
message: "Type is required",
|
|
@@ -337,11 +376,33 @@ const CreateClientForm = ({ teamsApi, username, password, toggleShow, onSuccess,
|
|
|
337
376
|
required: damLocationType === "external",
|
|
338
377
|
message: "Region is required",
|
|
339
378
|
},
|
|
340
|
-
], children: _jsx(Input, { placeholder: "Region", disabled: damLocationType === "internal" }) })] }))] }), _jsx(Form.Item, { label: "Subdomain", name: "subdomain", rules: [
|
|
379
|
+
], children: _jsx(Input, { placeholder: "Region", disabled: damLocationType === "internal" }) })] }))] })), _jsx(Form.Item, { label: "Subdomain", name: "subdomain", rules: [
|
|
341
380
|
{
|
|
342
381
|
required: true,
|
|
343
382
|
message: "Subdomain is required",
|
|
344
383
|
},
|
|
345
|
-
], children: _jsx(Input, { placeholder: "Subdomain" }) }), _jsx(Form.Item, { name: "showFilePreview", valuePropName: "checked", initialValue: false, children: _jsx(Checkbox, { children: "Show File Preview Editor" }) }), _jsx(Form.Item, {
|
|
384
|
+
], children: _jsx(Input, { placeholder: "Subdomain", disabled: isEditMode }) }), _jsx(Form.Item, { name: "showFilePreview", valuePropName: "checked", initialValue: false, children: _jsx(Checkbox, { children: "Show File Preview Editor" }) }), _jsx(Form.Item, { shouldUpdate: true, style: { marginBottom: 0 }, children: () => {
|
|
385
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
386
|
+
const values = form.getFieldsValue(true);
|
|
387
|
+
const hasName = !!((_a = values === null || values === void 0 ? void 0 : values.name) === null || _a === void 0 ? void 0 : _a.trim());
|
|
388
|
+
const hasAccessTypes = Array.isArray(values === null || values === void 0 ? void 0 : values.accessTypes) && values.accessTypes.length > 0;
|
|
389
|
+
const hasAdminTeams = Array.isArray(values === null || values === void 0 ? void 0 : values.adminTeams) && values.adminTeams.length > 0;
|
|
390
|
+
const hasSubdomain = !!((_b = values === null || values === void 0 ? void 0 : values.subdomain) === null || _b === void 0 ? void 0 : _b.trim());
|
|
391
|
+
const baseValid = hasName && hasAccessTypes && hasAdminTeams && hasSubdomain;
|
|
392
|
+
let damLocationValid = true;
|
|
393
|
+
if (!isEditMode) {
|
|
394
|
+
const dl = (values === null || values === void 0 ? void 0 : values.damLocationDetails) || {};
|
|
395
|
+
damLocationValid = !!((dl === null || dl === void 0 ? void 0 : dl.type) && ((_c = dl === null || dl === void 0 ? void 0 : dl.rootPath) === null || _c === void 0 ? void 0 : _c.trim()));
|
|
396
|
+
if (damLocationValid && damLocationType === "external") {
|
|
397
|
+
damLocationValid = !!(((_d = dl === null || dl === void 0 ? void 0 : dl.bucket) === null || _d === void 0 ? void 0 : _d.trim()) &&
|
|
398
|
+
((_e = dl === null || dl === void 0 ? void 0 : dl.accessKeyId) === null || _e === void 0 ? void 0 : _e.trim()) &&
|
|
399
|
+
((_f = dl === null || dl === void 0 ? void 0 : dl.secretAccessKey) === null || _f === void 0 ? void 0 : _f.trim()) &&
|
|
400
|
+
((_g = dl === null || dl === void 0 ? void 0 : dl.url) === null || _g === void 0 ? void 0 : _g.trim()) &&
|
|
401
|
+
((_h = dl === null || dl === void 0 ? void 0 : dl.region) === null || _h === void 0 ? void 0 : _h.trim()));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
const isFormValid = baseValid && damLocationValid;
|
|
405
|
+
return (_jsx(Button, { htmlType: "submit", type: "primary", block: true, loading: loading, disabled: !isFormValid, children: "Submit" }));
|
|
406
|
+
} })] })) }));
|
|
346
407
|
};
|
|
347
408
|
export default CreateClientForm;
|
|
@@ -5,14 +5,16 @@ import { ThemeModes } from "../utilities/constants/interface";
|
|
|
5
5
|
import CreateClient from "./CreateClientBtn";
|
|
6
6
|
import ToastProvider from "../hocs/ToastProvider";
|
|
7
7
|
function App(props) {
|
|
8
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
9
|
+
// Use existingClientData as fallback so login API gets token for keys/refresh APIs
|
|
8
10
|
const config = {
|
|
9
|
-
damAccessKey: props === null || props === void 0 ? void 0 : props.accessKey,
|
|
10
|
-
secretKey: props === null || props === void 0 ? void 0 : props.secretKey,
|
|
11
|
-
subdomain: props === null || props === void 0 ? void 0 : props.subdomain,
|
|
12
|
-
teamIds: props === null || props === void 0 ? void 0 : props.teamIds,
|
|
11
|
+
damAccessKey: (_a = props === null || props === void 0 ? void 0 : props.accessKey) !== null && _a !== void 0 ? _a : (_b = props === null || props === void 0 ? void 0 : props.existingClientData) === null || _b === void 0 ? void 0 : _b.accessKey,
|
|
12
|
+
secretKey: (_c = props === null || props === void 0 ? void 0 : props.secretKey) !== null && _c !== void 0 ? _c : (_d = props === null || props === void 0 ? void 0 : props.existingClientData) === null || _d === void 0 ? void 0 : _d.secretKey,
|
|
13
|
+
subdomain: (_g = (_e = props === null || props === void 0 ? void 0 : props.subdomain) !== null && _e !== void 0 ? _e : (_f = props === null || props === void 0 ? void 0 : props.existingClientData) === null || _f === void 0 ? void 0 : _f.subdomain) !== null && _g !== void 0 ? _g : props === null || props === void 0 ? void 0 : props.clientSubdomain,
|
|
14
|
+
teamIds: (_h = props === null || props === void 0 ? void 0 : props.teamIds) !== null && _h !== void 0 ? _h : (((_j = props === null || props === void 0 ? void 0 : props.existingClientData) === null || _j === void 0 ? void 0 : _j.brandId) ? [props.existingClientData.brandId] : []),
|
|
13
15
|
styles: props === null || props === void 0 ? void 0 : props.styles,
|
|
14
16
|
appType: props === null || props === void 0 ? void 0 : props.appType,
|
|
15
17
|
};
|
|
16
|
-
return (_jsx(DamConfigProvider, { config: config, children: _jsxs(ThemeProvider, { styles: props === null || props === void 0 ? void 0 : props.styles, sessionTheme: ThemeModes.LIGHT, children: [_jsx(CreateClient, { teamsApi: props === null || props === void 0 ? void 0 : props.teamsApi, username: props === null || props === void 0 ? void 0 : props.username, password: props === null || props === void 0 ? void 0 : props.password, clientSubdomain: props === null || props === void 0 ? void 0 : props.clientSubdomain, onSuccess: props === null || props === void 0 ? void 0 : props.onSuccess, existingClientData: props === null || props === void 0 ? void 0 : props.existingClientData }), _jsx(ToastProvider, {})] }) }));
|
|
18
|
+
return (_jsx(DamConfigProvider, { config: config, children: _jsxs(ThemeProvider, { styles: props === null || props === void 0 ? void 0 : props.styles, sessionTheme: ThemeModes.LIGHT, children: [_jsx(CreateClient, { teamsApi: props === null || props === void 0 ? void 0 : props.teamsApi, username: props === null || props === void 0 ? void 0 : props.username, password: props === null || props === void 0 ? void 0 : props.password, clientSubdomain: props === null || props === void 0 ? void 0 : props.clientSubdomain, onSuccess: props === null || props === void 0 ? void 0 : props.onSuccess, onRefreshSuccess: props === null || props === void 0 ? void 0 : props.onRefreshSuccess, existingClientData: props === null || props === void 0 ? void 0 : props.existingClientData }), _jsx(ToastProvider, {})] }) }));
|
|
17
19
|
}
|
|
18
20
|
export default App;
|
|
@@ -43,7 +43,6 @@ const BulkUploadModal = ({ toggleUpload, userEmail, folderId, thumbnailsOnly, })
|
|
|
43
43
|
const [form] = Form.useForm();
|
|
44
44
|
const emailValue = Form.useWatch("email", form);
|
|
45
45
|
const zipFileUrlValue = Form.useWatch("zip_file_url", form);
|
|
46
|
-
const emailsValue = Form.useWatch("emails", form);
|
|
47
46
|
const isSubmitDisabled = useMemo(() => {
|
|
48
47
|
if (loading)
|
|
49
48
|
return true;
|
|
@@ -51,9 +50,9 @@ const BulkUploadModal = ({ toggleUpload, userEmail, folderId, thumbnailsOnly, })
|
|
|
51
50
|
const hasAssetFile = assetsSourceType === "zip"
|
|
52
51
|
? assetFile && !assetFileError
|
|
53
52
|
: !!(zipFileUrlValue === null || zipFileUrlValue === void 0 ? void 0 : zipFileUrlValue.trim());
|
|
54
|
-
const hasEmails = Array.isArray(
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
const hasEmails = Array.isArray(emailValue) &&
|
|
54
|
+
emailValue.length > 0 &&
|
|
55
|
+
emailValue.every((e) => get(validateEmail(e), "valid"));
|
|
57
56
|
return !hasAssetFile || !hasEmails;
|
|
58
57
|
}
|
|
59
58
|
const hasAssetType = !!assetTypeId;
|
|
@@ -74,7 +73,6 @@ const BulkUploadModal = ({ toggleUpload, userEmail, folderId, thumbnailsOnly, })
|
|
|
74
73
|
assetsSourceType,
|
|
75
74
|
emailValue,
|
|
76
75
|
zipFileUrlValue,
|
|
77
|
-
emailsValue,
|
|
78
76
|
]);
|
|
79
77
|
useEffect(() => {
|
|
80
78
|
onFetchAssetTemplates();
|
|
@@ -152,7 +152,7 @@ const FolderListView = ({ folders, foldersFetching, hasNextPage, fetchNextPage,
|
|
|
152
152
|
}
|
|
153
153
|
return groupBy(sortedFolders, (folder) => formatGroupDate(get(folder, "updatedAt")));
|
|
154
154
|
}, [sortedFolders, sortByKey]);
|
|
155
|
-
return (_jsxs("div", { className: "md-lib-space-y-6 md-lib-relative ", children: [_jsxs("div", { className: "md-lib-flex md-lib-justify-between md-lib-items-center md-lib-px-2 md-lib-min-w-fit md-lib-gap-2 mb-lib-sticky md-lib-top-0 md-lib-bg-white dark:md-lib-bg-darkPrimary", children: [!isImagePicker && type !== DriveModes.FOLDERS && (_jsx("div", { className: "md-lib-w-6", children: ((searchKey && searchValue) || (metadataKey && metadataValue)) && (_jsx("div", { className: "md-lib-p-1 md-lib-border md-lib-rounded md-lib-border-borderColor dark:md-lib-border-darkBorderColor md-lib-cursor-pointer", children: _jsx(Tooltip, { title: "Clear filter", children: _jsx(ClearFilterIcon, { fill: get(theme, "variables.primaryColor"), onClick: () => {
|
|
155
|
+
return (_jsxs("div", { className: "md-lib-space-y-6 md-lib-relative ", children: [_jsxs("div", { className: "md-lib-flex md-lib-justify-between md-lib-items-center md-lib-px-2 md-lib-min-w-fit md-lib-gap-2 mb-lib-sticky md-lib-top-0 md-lib-bg-white dark:md-lib-bg-darkPrimary", style: { position: "sticky", top: '0' }, children: [!isImagePicker && type !== DriveModes.FOLDERS && (_jsx("div", { className: "md-lib-w-6", children: ((searchKey && searchValue) || (metadataKey && metadataValue)) && (_jsx("div", { className: "md-lib-p-1 md-lib-border md-lib-rounded md-lib-border-borderColor dark:md-lib-border-darkBorderColor md-lib-cursor-pointer", children: _jsx(Tooltip, { title: "Clear filter", children: _jsx(ClearFilterIcon, { fill: get(theme, "variables.primaryColor"), onClick: () => {
|
|
156
156
|
onSearch({
|
|
157
157
|
searchKey: "",
|
|
158
158
|
searchValue: "",
|
|
@@ -232,13 +232,34 @@ function FolderTree({ currentRootId, expandedKeys, selectedKeys, handleExpand, s
|
|
|
232
232
|
prevCurrentRootIdRef.current = currentRootId;
|
|
233
233
|
}
|
|
234
234
|
else {
|
|
235
|
-
|
|
235
|
+
// When folders is empty and we have a subfolder ID (e.g. from URL refresh),
|
|
236
|
+
// fetch root first so the full tree is visible, then expand to the selected folder
|
|
237
|
+
if (folders.length === 0 && currentRootId !== rootFolderId) {
|
|
238
|
+
// Don't set prevCurrentRootIdRef yet - we need to re-run when folders is populated
|
|
239
|
+
fetchFolders(rootFolderId);
|
|
240
|
+
}
|
|
241
|
+
else if (currentRootId === rootFolderId || folders.length === 0) {
|
|
236
242
|
prevCurrentRootIdRef.current = currentRootId;
|
|
237
243
|
fetchFolders(currentRootId);
|
|
238
244
|
}
|
|
239
245
|
else {
|
|
240
|
-
|
|
241
|
-
|
|
246
|
+
// Folder not in tree - it may be a nested subfolder (e.g. "Books Sub folder" under "Book")
|
|
247
|
+
// Fetch children for top-level folders until the target appears in the tree
|
|
248
|
+
console.log('## Folder not in tree - fetching children to find nested subfolder:', currentRootId);
|
|
249
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
setState((s) => (Object.assign(Object.assign({}, s), { loading: true })));
|
|
251
|
+
for (const folder of folders) {
|
|
252
|
+
const fid = get(folder, "_id");
|
|
253
|
+
if (!fid)
|
|
254
|
+
continue;
|
|
255
|
+
const hasChildrenLoaded = isArray(folder.children) && folder.children.length > 0;
|
|
256
|
+
if (!hasChildrenLoaded) {
|
|
257
|
+
yield fetchFolderChildren(fid);
|
|
258
|
+
// Effect will re-run when folders update; if target is now in tree, we'll expand
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
setState((s) => (Object.assign(Object.assign({}, s), { loading: false })));
|
|
262
|
+
}))();
|
|
242
263
|
}
|
|
243
264
|
}
|
|
244
265
|
}
|
|
@@ -247,7 +268,7 @@ function FolderTree({ currentRootId, expandedKeys, selectedKeys, handleExpand, s
|
|
|
247
268
|
console.log('## FolderTree useEffect - globalSearch changed, refetching root folder');
|
|
248
269
|
fetchFolders(currentRootId);
|
|
249
270
|
}
|
|
250
|
-
}, [currentRootId, globalSearch]);
|
|
271
|
+
}, [currentRootId, globalSearch, folders]);
|
|
251
272
|
// ✅ Handle sort dropdown
|
|
252
273
|
const handleSortChange = (value) => {
|
|
253
274
|
setState((prevState) => {
|
|
@@ -2,5 +2,5 @@ import { type FolderTypes } from "../utilities/FoldersContext";
|
|
|
2
2
|
export default function MyDriveMainContainer({ folders, setFolders, onFolderChange, }: {
|
|
3
3
|
folders: FolderTypes[];
|
|
4
4
|
setFolders: React.Dispatch<React.SetStateAction<FolderTypes[]>>;
|
|
5
|
-
onFolderChange?: (folderId: string) => void;
|
|
5
|
+
onFolderChange?: (folderId: string | undefined) => void;
|
|
6
6
|
}): JSX.Element;
|
|
@@ -20,13 +20,13 @@ export default function MyDriveMainContainer({ folders, setFolders, onFolderChan
|
|
|
20
20
|
// Priority: URL params > Props from ParamsProvider > rootFolderId from config
|
|
21
21
|
if (params === null || params === void 0 ? void 0 : params.folderId) {
|
|
22
22
|
console.log('## Setting selectedKeys from params.folderId:', params.folderId);
|
|
23
|
-
setSelectedKeys(params.folderId);
|
|
23
|
+
setSelectedKeys(Array.isArray(params.folderId) ? params.folderId : [params.folderId]);
|
|
24
24
|
initializedFromParamsRef.current = true;
|
|
25
25
|
}
|
|
26
|
-
else if (!(params === null || params === void 0 ? void 0 : params.folderId) && rootFolderId && !selectedKeys && !initializedFromParamsRef.current) {
|
|
26
|
+
else if (!(params === null || params === void 0 ? void 0 : params.folderId) && rootFolderId && !(selectedKeys === null || selectedKeys === void 0 ? void 0 : selectedKeys.length) && !initializedFromParamsRef.current) {
|
|
27
27
|
// Only set to rootFolderId if no params AND selectedKeys is empty AND we haven't initialized from params
|
|
28
28
|
console.log('## No params.folderId and no selectedKeys, using rootFolderId:', rootFolderId);
|
|
29
|
-
setSelectedKeys(rootFolderId);
|
|
29
|
+
setSelectedKeys([rootFolderId]);
|
|
30
30
|
}
|
|
31
31
|
}, [params === null || params === void 0 ? void 0 : params.folderId, params === null || params === void 0 ? void 0 : params.id, params === null || params === void 0 ? void 0 : params.parentId]);
|
|
32
32
|
// Priority: selectedKeys > params > rootFolderId
|
|
@@ -51,13 +51,16 @@ export default function MyDriveMainContainer({ folders, setFolders, onFolderChan
|
|
|
51
51
|
setExpandedKeys(map(keys, (k) => k.toString()));
|
|
52
52
|
};
|
|
53
53
|
// Wrapper function to handle both string and string[] for setSelectedKeys
|
|
54
|
+
// Also updates URL via onFolderChange so folder persists on refresh
|
|
54
55
|
const handleSetSelectedKeys = (keys) => {
|
|
55
56
|
const next = typeof keys === "string" ? [keys] : keys;
|
|
56
57
|
setSelectedKeys(next);
|
|
57
58
|
const singleFolderId = Array.isArray(next) && next.length === 1 ? next[0] : null;
|
|
58
|
-
if (
|
|
59
|
-
|
|
59
|
+
if (onFolderChange) {
|
|
60
|
+
// Update URL: subfolder id for subfolders, undefined for root/My Drive (so URL stays /digital-asset-management)
|
|
61
|
+
const urlFolderId = singleFolderId && singleFolderId !== rootFolderId ? singleFolderId : undefined;
|
|
62
|
+
onFolderChange(urlFolderId);
|
|
60
63
|
}
|
|
61
64
|
};
|
|
62
|
-
return (_jsxs(FoldersProvider, { value: { setFolders, folders, globalSearch }, children: [_jsx(FolderTree, { currentRootId: currentRootId, handleExpand: handleExpand, setSelectedKeys:
|
|
65
|
+
return (_jsxs(FoldersProvider, { value: { setFolders, folders, globalSearch }, children: [_jsx(FolderTree, { currentRootId: currentRootId, handleExpand: handleExpand, setSelectedKeys: handleSetSelectedKeys, expandedKeys: expandedKeys, selectedKeys: selectedKeys, folders: folders, setExpandedKeys: setExpandedKeys, setFolders: setFolders, setGlobalSearch: setGlobalSearch, globalSearch: globalSearch }), _jsx("div", { className: "md-lib-h-[inherit] md-lib-overflow-x-auto", children: _jsx(DriveContainer, { parentFolderId: selectedFolderId, globalSearch: globalSearch, setGlobalSearch: setGlobalSearch, setSelectedKeys: handleSetSelectedKeys }) })] }));
|
|
63
66
|
}
|
|
@@ -31,6 +31,7 @@ const FileDetails = ({ open, handleClose, file, files, fileIds, onCloseSelection
|
|
|
31
31
|
console.log("## FileDetails - files:", files, "file:", file, "initialFile:", initialFile, "fileIds:", fileIds, "initialFileId:", initialFileId);
|
|
32
32
|
const { id } = useAppParams();
|
|
33
33
|
const damConfig = useDamConfig();
|
|
34
|
+
const headerHeight = get(damConfig, "headerHeight", 0) || 0;
|
|
34
35
|
const api = useMemo(() => createApiClient(damConfig), [damConfig]);
|
|
35
36
|
const [state, setState] = useState({
|
|
36
37
|
visible: false,
|
|
@@ -108,18 +109,37 @@ const FileDetails = ({ open, handleClose, file, files, fileIds, onCloseSelection
|
|
|
108
109
|
setState((prevState) => (Object.assign(Object.assign({}, prevState), { visible: false })));
|
|
109
110
|
}
|
|
110
111
|
}, [open]);
|
|
112
|
+
// Lock body scroll when preview modal is open so drive page files don't scroll behind it
|
|
113
|
+
// Add body class so host app can lower header z-index and let preview modal appear above it
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (open && visible) {
|
|
116
|
+
const prevBodyOverflow = document.body.style.overflow;
|
|
117
|
+
const prevHtmlOverflow = document.documentElement.style.overflow;
|
|
118
|
+
document.body.style.overflow = "hidden";
|
|
119
|
+
document.documentElement.style.overflow = "hidden";
|
|
120
|
+
document.body.classList.add("dam-preview-open");
|
|
121
|
+
return () => {
|
|
122
|
+
document.body.style.overflow = prevBodyOverflow;
|
|
123
|
+
document.documentElement.style.overflow = prevHtmlOverflow;
|
|
124
|
+
document.body.classList.remove("dam-preview-open");
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}, [open, visible]);
|
|
111
128
|
if (!open && !visible)
|
|
112
129
|
return null;
|
|
113
|
-
const
|
|
130
|
+
const modalStyle = headerHeight > 0
|
|
131
|
+
? { top: headerHeight, left: 0, right: 0, bottom: 0, height: `calc(100vh - ${headerHeight}px)` }
|
|
132
|
+
: undefined;
|
|
133
|
+
const modalContent = (_jsxs("div", { className: `md-lib-fixed md-lib-z-[1000] md-lib-w-screen md-lib-bg-white dark:md-lib-bg-darkPrimary md-lib-text-black dark:md-lib-text-white md-lib-flex md-lib-flex-col md-lib-transform md-lib-transition-all md-lib-duration-300 md-lib-ease-in-out ${headerHeight === 0 ? "md-lib-inset-0 md-lib-h-screen" : ""} ${open && visible
|
|
114
134
|
? "md-lib-opacity-100 md-lib-translate-y-0"
|
|
115
|
-
: "md-lib-opacity-0 md-lib-translate-y-4"}`, onTransitionEnd: () => {
|
|
135
|
+
: "md-lib-opacity-0 md-lib-translate-y-4"}`, style: modalStyle, onTransitionEnd: () => {
|
|
116
136
|
if (!open)
|
|
117
137
|
setState((prevState) => (Object.assign(Object.assign({}, prevState), { visible: false })));
|
|
118
|
-
}, children: [_jsx(FileDetailsHeader, { handleClose: handleClose, file: currentFile, onCloseSelection: onCloseSelection }), isFetching ? (_jsx(Loader, {})) : (_jsx(FileViewer, { file: currentFile, hasPrev: (!!files && currentIndex > 0) ||
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
138
|
+
}, children: [_jsx("div", { className: "md-lib-shrink-0", children: _jsx(FileDetailsHeader, { handleClose: handleClose, file: currentFile, onCloseSelection: onCloseSelection }) }), _jsx("div", { className: "md-lib-flex-1 md-lib-min-h-0 md-lib-overflow-auto", children: isFetching ? (_jsx(Loader, {})) : (_jsx(FileViewer, { file: currentFile, hasPrev: (!!files && currentIndex > 0) ||
|
|
139
|
+
(!!fileIds && fileIds.length > 1 && currentIndex > 0) ||
|
|
140
|
+
!!get(currentFile, "prevFileId"), hasNext: (!!files && currentIndex < get(files, "length", 0) - 1) ||
|
|
141
|
+
(!!fileIds && fileIds.length > 1 && currentIndex < fileIds.length - 1) ||
|
|
142
|
+
!!get(currentFile, "nextFileId"), onPrev: handlePrevious, onNext: handleNext, handleClose: handleClose })) })] }));
|
|
123
143
|
return ReactDOM.createPortal(modalContent, document.body);
|
|
124
144
|
};
|
|
125
145
|
export default FileDetails;
|
|
@@ -2,20 +2,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Button } from "antd";
|
|
3
3
|
import { IoIosClose } from "react-icons/io";
|
|
4
4
|
import { BsDownload } from "react-icons/bs";
|
|
5
|
-
import {
|
|
5
|
+
import { NotificationStatus, } from "../../utilities/constants/interface";
|
|
6
6
|
import { get } from "lodash";
|
|
7
7
|
import { showNotification } from "../../common/notifications";
|
|
8
8
|
import { INVALID_URL } from "../../utilities/constants/messages";
|
|
9
9
|
import FileMenuOptions from "../FileMenuOptions";
|
|
10
10
|
import { useDamConfig } from "../../hocs/DamConfigContext";
|
|
11
|
-
import useAppParams from "../../utilities/useAppParams";
|
|
12
11
|
const IoIosCloseIcon = IoIosClose;
|
|
13
12
|
const BsDownloadIcon = BsDownload;
|
|
14
13
|
const FileDetailsHeader = ({ handleClose, file, onCloseSelection, }) => {
|
|
15
14
|
const damConfig = useDamConfig();
|
|
16
15
|
const { isAdmin } = damConfig;
|
|
17
|
-
|
|
18
|
-
return (_jsxs("div", { className: "md-lib-bg-white dark:md-lib-bg-darkPrimaryHoverColor md-lib-py-3 md-lib-px-5 md-lib-border-b md-lib-border-borderColor dark:md-lib-border-darkBorderColor 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: [!id && type !== DriveModes.FILE && (_jsx(IoIosCloseIcon, { className: "md-lib-text-textColor dark:md-lib-text-darkTextColor md-lib-cursor-pointer", size: 24, onClick: handleClose })), !!file && (_jsx("h4", { className: "md-lib-font-semibold md-lib-text-textColor dark:md-lib-text-darkTextColor md-lib-text-base md-lib-truncate md-lib-max-w-[calc(100vw-180px)]", title: get(file, "name", "N/A"), children: get(file, "name", "N/A") }))] }), !!file && (_jsxs("div", { className: "md-lib-flex md-lib-items-center md-lib-gap-4", children: [_jsx(FileMenuOptions, { file: file, fileIds: get(file, "_id") ? [get(file, "_id")] : [], onCloseSelection: onCloseSelection, fileModal: true }), _jsx(Button, { size: "large", className: "md-lib-bg-secondaryColor dark:md-lib-bg-darkSecondaryColor hover:md-lib-bg-secondaryHoverColor dark:hover:md-lib-bg-darkSecondaryColor md-lib-border-none", onClick: () => {
|
|
16
|
+
return (_jsxs("div", { className: "md-lib-bg-white dark:md-lib-bg-darkPrimaryHoverColor md-lib-py-3 md-lib-px-5 md-lib-border-b md-lib-border-borderColor dark:md-lib-border-darkBorderColor 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(IoIosCloseIcon, { className: "md-lib-text-textColor dark:md-lib-text-darkTextColor md-lib-cursor-pointer", size: 24, onClick: () => handleClose === null || handleClose === void 0 ? void 0 : handleClose(), "aria-label": "Close" }), !!file && (_jsx("h4", { className: "md-lib-font-semibold md-lib-text-textColor dark:md-lib-text-darkTextColor md-lib-text-base md-lib-truncate md-lib-max-w-[calc(100vw-180px)]", title: get(file, "name", "N/A"), children: get(file, "name", "N/A") }))] }), !!file && (_jsxs("div", { className: "md-lib-flex md-lib-items-center md-lib-gap-4", children: [_jsx(FileMenuOptions, { file: file, fileIds: get(file, "_id") ? [get(file, "_id")] : [], onCloseSelection: onCloseSelection, fileModal: true }), _jsx(Button, { size: "large", className: "md-lib-bg-secondaryColor dark:md-lib-bg-darkSecondaryColor hover:md-lib-bg-secondaryHoverColor dark:hover:md-lib-bg-darkSecondaryColor md-lib-border-none", onClick: () => {
|
|
19
17
|
const url = get(file, "downloadUrl") || get(file, "s3Url") || get(file, "thumbnailUrl");
|
|
20
18
|
if (!url) {
|
|
21
19
|
showNotification(INVALID_URL, NotificationStatus.ERROR);
|
|
@@ -11,7 +11,7 @@ const FileViewer = ({ file, onNext, onPrev, hasNext, hasPrev, handleClose, }) =>
|
|
|
11
11
|
const damConfig = useDamConfig();
|
|
12
12
|
const brand = damConfig === null || damConfig === void 0 ? void 0 : damConfig.brand;
|
|
13
13
|
const showFilePreview = get(brand, "showFilePreview", false);
|
|
14
|
-
const [metadataOpen, setMetadataOpen] = useState(
|
|
15
|
-
return (_jsx(Layout, { className: "md-lib-h-full", children: _jsxs(Content, { className: "md-lib-flex md-lib-h-full md-lib-w-full", children: [_jsx("div", { className: `md-lib-flex md-lib-items-center md-lib-justify-center md-lib-relative md-lib-bg-textColorActive dark:md-lib-bg-darkSecondaryColor md-lib-min-h-full ${metadataOpen ? "md-lib-flex-1" : "md-lib-flex-1 md-lib-w-full"}`, children: _jsx(PreviewDetails, { file: file, hasNext: hasNext, hasPrev: hasPrev, onNext: onNext, onPrev: onPrev, showFilePreview: showFilePreview }) }),
|
|
14
|
+
const [metadataOpen, setMetadataOpen] = useState(true);
|
|
15
|
+
return (_jsx(Layout, { className: "md-lib-h-full", children: _jsxs(Content, { className: "md-lib-flex md-lib-h-full md-lib-w-full", children: [_jsx("div", { className: `md-lib-flex md-lib-items-center md-lib-justify-center md-lib-relative md-lib-bg-textColorActive dark:md-lib-bg-darkSecondaryColor md-lib-min-h-full ${metadataOpen ? "md-lib-flex-1" : "md-lib-flex-1 md-lib-w-full"}`, children: _jsx(PreviewDetails, { file: file, hasNext: hasNext, hasPrev: hasPrev, onNext: onNext, onPrev: onPrev, showFilePreview: showFilePreview }) }), _jsxs(_Fragment, { children: [_jsx(Button, { type: "text", className: "md-lib-shrink-0 md-lib-flex md-lib-items-center md-lib-justify-center md-lib-w-10 md-lib-h-10 md-lib-rounded-none md-lib-bg-black/50 hover:md-lib-bg-black/70 dark:md-lib-bg-white/20 dark:hover:md-lib-bg-white/30 md-lib-text-white md-lib-border-0 md-lib-self-start md-lib-mt-4", onClick: () => setMetadataOpen((prev) => !prev), "aria-label": metadataOpen ? "Hide Metadata" : "Show Metadata", children: metadataOpen ? (_jsx(RightOutlined, { className: "md-lib-text-lg" })) : (_jsx(LeftOutlined, { className: "md-lib-text-lg" })) }), metadataOpen && (_jsx("div", { className: "md-lib-w-[400px] md-lib-min-w-[320px] md-lib-shrink-0 md-lib-border-l md-lib-border-borderColor dark:md-lib-border-darkBorderColor md-lib-bg-backgroundColor dark:md-lib-bg-darkPrimary md-lib-overflow-y-auto", children: _jsx(MapFile, { fromUpload: false, filesList: file ? [file] : [], handleCancel: handleClose ? () => handleClose() : undefined, canEdit: showFilePreview }) }))] })] }) }));
|
|
16
16
|
};
|
|
17
17
|
export default FileViewer;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
import type { FormInstance } from "antd";
|
|
2
3
|
import { BrandUserEntity, MetaDataFieldEntity } from "../../utilities/constants/interface";
|
|
3
4
|
export declare const buildInitialValues: (formData: Record<string, any>, metaFields: MetaDataFieldEntity[], isEditMode: boolean) => {
|
|
4
5
|
[x: string]: any;
|
|
5
6
|
};
|
|
6
|
-
export declare const getFormItem: (item: MetaDataFieldEntity, fromDefaultValue: boolean, userOptions?: BrandUserEntity[]
|
|
7
|
+
export declare const getFormItem: (item: MetaDataFieldEntity, fromDefaultValue: boolean, userOptions?: BrandUserEntity[], teamOptions?: {
|
|
8
|
+
label: React.ReactNode;
|
|
9
|
+
value: string;
|
|
10
|
+
key?: string;
|
|
11
|
+
}[]) => JSX.Element | null;
|
|
7
12
|
declare const MetaForm: ({ metaFields, metaData, form, isEditMode, }: {
|
|
8
13
|
metaFields: MetaDataFieldEntity[];
|
|
9
14
|
metaData: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo } from "react";
|
|
3
|
-
import { Form, Input, InputNumber, DatePicker, Select, Checkbox, Radio, } from "antd";
|
|
3
|
+
import { Form, Input, InputNumber, DatePicker, Select, Checkbox, Radio, Typography, } from "antd";
|
|
4
4
|
import { find, first, get, includes, isArray, isNumber, map, mapValues, nth, } from "lodash";
|
|
5
5
|
import dayjs from "dayjs";
|
|
6
6
|
import { InputSupportedTypes, InputTypes, } from "../../utilities/constants/interface";
|
|
@@ -42,7 +42,7 @@ export const buildInitialValues = (formData, metaFields, isEditMode) => {
|
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
|
-
export const getFormItem = (item, fromDefaultValue, userOptions) => {
|
|
45
|
+
export const getFormItem = (item, fromDefaultValue, userOptions, teamOptions) => {
|
|
46
46
|
const name = get(item, "_id");
|
|
47
47
|
const label = get(item, "name");
|
|
48
48
|
const placeholder = get(item, "placeholder", "");
|
|
@@ -112,10 +112,12 @@ export const getFormItem = (item, fromDefaultValue, userOptions) => {
|
|
|
112
112
|
// VALUE_RANGE
|
|
113
113
|
if (defaultName === InputTypes.NUMBERS &&
|
|
114
114
|
get(settings, "VALUE_RANGE.allow")) {
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
const
|
|
115
|
+
const minRaw = get(settings, "VALUE_RANGE.minValue");
|
|
116
|
+
const maxRaw = get(settings, "VALUE_RANGE.maxValue");
|
|
117
|
+
const min = minRaw != null && minRaw !== "" ? Number(minRaw) : undefined;
|
|
118
|
+
const max = maxRaw != null && maxRaw !== "" ? Number(maxRaw) : undefined;
|
|
119
|
+
const hasMin = isNumber(min) && !Number.isNaN(min);
|
|
120
|
+
const hasMax = isNumber(max) && !Number.isNaN(max);
|
|
119
121
|
let message = "";
|
|
120
122
|
if (hasMin && hasMax) {
|
|
121
123
|
message = `Must be between ${min} and ${max}.`;
|
|
@@ -126,7 +128,24 @@ export const getFormItem = (item, fromDefaultValue, userOptions) => {
|
|
|
126
128
|
else if (!hasMin && hasMax) {
|
|
127
129
|
message = `Maximum value is ${max}.`;
|
|
128
130
|
}
|
|
129
|
-
rules.push(
|
|
131
|
+
rules.push({
|
|
132
|
+
validator: (_, value) => {
|
|
133
|
+
if (value === undefined || value === null || value === "") {
|
|
134
|
+
return Promise.resolve();
|
|
135
|
+
}
|
|
136
|
+
const num = Number(value);
|
|
137
|
+
if (Number.isNaN(num)) {
|
|
138
|
+
return Promise.reject(new Error("Must be a valid number."));
|
|
139
|
+
}
|
|
140
|
+
if (hasMin && num < min) {
|
|
141
|
+
return Promise.reject(new Error(message || `Minimum value is ${min}.`));
|
|
142
|
+
}
|
|
143
|
+
if (hasMax && num > max) {
|
|
144
|
+
return Promise.reject(new Error(message || `Maximum value is ${max}.`));
|
|
145
|
+
}
|
|
146
|
+
return Promise.resolve();
|
|
147
|
+
},
|
|
148
|
+
});
|
|
130
149
|
}
|
|
131
150
|
switch (defaultName) {
|
|
132
151
|
case InputTypes.TEXT:
|
|
@@ -163,6 +182,11 @@ export const getFormItem = (item, fromDefaultValue, userOptions) => {
|
|
|
163
182
|
return false;
|
|
164
183
|
}, placeholder: placeholder, options: userOptions, optionFilterProp: "children" }) }, name));
|
|
165
184
|
case InputTypes.TEAM:
|
|
185
|
+
return (_jsx(Form.Item, { name: itemName, label: label, rules: rules, children: _jsx(Select, { mode: get(settings, InputSupportedTypes.ALLOW_MULTIPLE)
|
|
186
|
+
? "multiple"
|
|
187
|
+
: undefined, allowClear: !!get(settings, InputSupportedTypes.ALLOW_CLEAR), showSearch: !!get(settings, InputSupportedTypes.SEARCHABLE), filterOption: (input, option) => ((option === null || option === void 0 ? void 0 : option.key) || String((option === null || option === void 0 ? void 0 : option.value) || ""))
|
|
188
|
+
.toLowerCase()
|
|
189
|
+
.indexOf(input.toLowerCase()) >= 0, placeholder: placeholder, options: teamOptions || [], optionFilterProp: "key" }) }, name));
|
|
166
190
|
case InputTypes.SELECT:
|
|
167
191
|
return (_jsx(Form.Item, { name: itemName, label: label, rules: rules, children: _jsx(Select, { mode: get(settings, InputSupportedTypes.ALLOW_MULTIPLE)
|
|
168
192
|
? "multiple"
|
|
@@ -185,6 +209,19 @@ const MetaForm = ({ metaFields, metaData, form, isEditMode, }) => {
|
|
|
185
209
|
const brandId = get(brand, "_id");
|
|
186
210
|
const queryClient = useQueryClient();
|
|
187
211
|
const brandUsers = getCurrentBrandUsers(queryClient, brandId);
|
|
212
|
+
const teamOptions = useMemo(() => {
|
|
213
|
+
const externalTeams = (teams || []).filter((team) => get(team, "id") != null || get(team, "_id") != null);
|
|
214
|
+
return map(externalTeams, (team) => {
|
|
215
|
+
const teamId = get(team, "id") || get(team, "_id");
|
|
216
|
+
const teamName = get(team, "name", "");
|
|
217
|
+
const teamType = get(team, "type", "");
|
|
218
|
+
return {
|
|
219
|
+
label: (_jsxs(Typography.Text, { style: { display: "flex" }, children: [teamId, " ", teamName, " ", _jsx("span", { style: { marginLeft: "auto" }, children: teamType })] })),
|
|
220
|
+
value: teamId,
|
|
221
|
+
key: `${teamId} - ${teamName} - ${teamType}`,
|
|
222
|
+
};
|
|
223
|
+
});
|
|
224
|
+
}, [teams]);
|
|
188
225
|
useEffect(() => {
|
|
189
226
|
const formData = {
|
|
190
227
|
metadata: buildInitialValues(metaData, metaFields, isEditMode),
|
|
@@ -194,6 +231,6 @@ const MetaForm = ({ metaFields, metaData, form, isEditMode, }) => {
|
|
|
194
231
|
const userOptions = useMemo(() => {
|
|
195
232
|
return map(brandUsers, (user) => getUserAvatar(user));
|
|
196
233
|
}, [brandUsers, brandId]);
|
|
197
|
-
return (_jsx(_Fragment, { children: metaFields.map((item) => getFormItem(item, false, userOptions)) }));
|
|
234
|
+
return (_jsx(_Fragment, { children: metaFields.map((item) => getFormItem(item, false, userOptions, teamOptions)) }));
|
|
198
235
|
};
|
|
199
236
|
export default MetaForm;
|
|
@@ -5,12 +5,10 @@ import { get, startsWith } from "lodash";
|
|
|
5
5
|
import ImageViewer from "./ImageViewer";
|
|
6
6
|
import { useMemo } from "react";
|
|
7
7
|
import VideoPlayer from "./VideoPlayer";
|
|
8
|
-
import useAppParams from "../../utilities/useAppParams";
|
|
9
8
|
// const PDFViewer = lazy(() => import("./PdfViewer"));
|
|
10
9
|
const GoArrowLeftIcon = GoArrowLeft;
|
|
11
10
|
const GoArrowRightIcon = GoArrowRight;
|
|
12
11
|
const PreviewDetails = ({ file, hasPrev, hasNext, onPrev, onNext, showFilePreview, }) => {
|
|
13
|
-
const { id } = useAppParams();
|
|
14
12
|
const mimetype = get(file, "mimetype", "");
|
|
15
13
|
const fileComponent = useMemo(() => {
|
|
16
14
|
if (startsWith(mimetype, "image/")) {
|
|
@@ -48,6 +46,6 @@ const PreviewDetails = ({ file, hasPrev, hasNext, onPrev, onNext, showFilePrevie
|
|
|
48
46
|
);
|
|
49
47
|
}
|
|
50
48
|
}, [mimetype, file]);
|
|
51
|
-
return (_jsxs(_Fragment, { children: [fileComponent,
|
|
49
|
+
return (_jsxs(_Fragment, { children: [fileComponent, _jsx(Button, { icon: _jsx(GoArrowLeftIcon, { size: 24 }), className: "md-lib-h-11 md-lib-bg-white !md-lib-w-12 md-lib-rounded-lg md-lib-text-textColor dark:md-lib-text-darkTextColor dark:md-lib-bg-darkPrimary md-lib-absolute md-lib-left-6 md-lib-top-1/2 -md-lib-translate-y-1/2", onClick: onPrev, disabled: !hasPrev }), _jsx(Button, { icon: _jsx(GoArrowRightIcon, { size: 24 }), className: "md-lib-h-11 md-lib-bg-white !md-lib-w-12 md-lib-rounded-lg md-lib-text-textColor dark:md-lib-text-darkTextColor dark:md-lib-bg-darkPrimary md-lib-absolute md-lib-right-6 md-lib-top-1/2 -md-lib-translate-y-1/2", onClick: onNext, disabled: !hasNext })] }));
|
|
52
50
|
};
|
|
53
51
|
export default PreviewDetails;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { FileEntity, ResponseFile } from "../../utilities/constants/interface";
|
|
2
|
-
declare function MapFile({ open, handleCancel, filesList, fromUpload, parentFolderId, }: {
|
|
2
|
+
declare function MapFile({ open, handleCancel, filesList, fromUpload, parentFolderId, canEdit, }: {
|
|
3
3
|
open?: boolean;
|
|
4
4
|
handleCancel?: (shouldDelete?: boolean) => void;
|
|
5
5
|
filesList: ResponseFile[] | FileEntity[];
|
|
6
6
|
fromUpload?: boolean;
|
|
7
7
|
parentFolderId?: string;
|
|
8
|
+
canEdit?: boolean;
|
|
8
9
|
}): JSX.Element;
|
|
9
10
|
export default MapFile;
|
|
@@ -27,7 +27,7 @@ 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, parentFolderId, }) {
|
|
30
|
+
function MapFile({ open, handleCancel, filesList, fromUpload, parentFolderId, canEdit = true, }) {
|
|
31
31
|
const { folderId, type } = useAppParams();
|
|
32
32
|
const damConfig = useDamConfig();
|
|
33
33
|
const externalTeams = (damConfig === null || damConfig === void 0 ? void 0 : damConfig.teams) || [];
|
|
@@ -231,9 +231,15 @@ function MapFile({ open, handleCancel, filesList, fromUpload, parentFolderId, })
|
|
|
231
231
|
},
|
|
232
232
|
});
|
|
233
233
|
};
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
const preventEnterSubmit = (e) => {
|
|
235
|
+
if (e.key === "Enter" && e.target instanceof HTMLElement) {
|
|
236
|
+
const tagName = e.target.tagName.toLowerCase();
|
|
237
|
+
if (tagName !== "textarea") {
|
|
238
|
+
e.preventDefault();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
const getMetadataForm = (_jsxs(Form, { layout: "vertical", form: form, scrollToFirstError: true, onFinish: fromUpload ? handleSubmit : handleUpdate, onKeyDown: preventEnterSubmit, className: "md-lib-m-2", disabled: !canEdit, children: [_jsx(AssetSelectionFormItem, { handleAssetTemplateChange: handleAssetTemplateChange, assetOptions: assetOptions, assetsLoading: assetsLoading }), selectedAssetTemplate && (_jsxs(_Fragment, { children: [_jsx(Form.Item, { name: "teamIds", label: "Teams", children: _jsx(Select, { options: teamOptions, placeholder: "Select teams", mode: "multiple", onChange: (val) => onChangeTeams(val), style: { width: "100%" }, showSearch: true, optionFilterProp: "key" }) }), _jsx(Form.Item, { name: "expiryDate", label: "Expiry Date", children: _jsx(DatePicker, { placeholder: "Expiry Date", style: { width: "100%" } }) }), _jsx(Metadata, { asset: selectedAssetTemplate, form: form, file: (filesList === null || filesList === void 0 ? void 0 : filesList[0]) || null })] })), _jsxs("div", { className: "md-lib-flex md-lib-items-center md-lib-justify-end md-lib-gap-3", children: [_jsx(Button, { onClick: handleCancelWithConfirmation, children: canEdit ? "Cancel" : "Close" }), canEdit && (_jsx(Button, { disabled: !selectedAssetTemplate, type: "primary", loading: loading || updateFileMutation.isLoading, htmlType: "submit", children: "Save" }))] })] }));
|
|
237
243
|
return (_jsx(_Fragment, { children: fromUpload ? (_jsx(Drawer, { title: "Metadata", open: open, onClose: handleCancelWithConfirmation, maskClosable: false, children: getMetadataForm })) : (_jsxs("div", { className: "md-lib-p-2 md-lib-overflow-y-scroll md-lib-max-h-[calc(100vh-65px)]", children: [_jsx("p", { className: "md-lib-text-lg md-lib-font-semibold", children: "Metadata" }), getMetadataForm] })) }));
|
|
238
244
|
}
|
|
239
245
|
export default MapFile;
|
package/build/MyDrive/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ declare function App(props: {
|
|
|
11
11
|
parentId?: string;
|
|
12
12
|
showSubfolders?: boolean;
|
|
13
13
|
userEmail?: string;
|
|
14
|
-
onFolderChange?: (folderId: string) => void;
|
|
14
|
+
onFolderChange?: (folderId: string | undefined) => void;
|
|
15
|
+
/** Height of host app header (e.g. navbar) in px. When set, preview modal positions below it instead of covering. */
|
|
16
|
+
headerHeight?: number;
|
|
15
17
|
}): JSX.Element;
|
|
16
18
|
export default App;
|
package/build/MyDrive/index.js
CHANGED
|
@@ -23,6 +23,7 @@ function App(props) {
|
|
|
23
23
|
parentId: props === null || props === void 0 ? void 0 : props.parentId,
|
|
24
24
|
showSubfolders: props === null || props === void 0 ? void 0 : props.showSubfolders,
|
|
25
25
|
routerVersion: props === null || props === void 0 ? void 0 : props.routerVersion,
|
|
26
|
+
headerHeight: props === null || props === void 0 ? void 0 : props.headerHeight,
|
|
26
27
|
}), [
|
|
27
28
|
props === null || props === void 0 ? void 0 : props.accessKey,
|
|
28
29
|
props === null || props === void 0 ? void 0 : props.secretKey,
|
|
@@ -35,6 +36,7 @@ function App(props) {
|
|
|
35
36
|
props === null || props === void 0 ? void 0 : props.id,
|
|
36
37
|
props === null || props === void 0 ? void 0 : props.parentId,
|
|
37
38
|
props === null || props === void 0 ? void 0 : props.showSubfolders,
|
|
39
|
+
props === null || props === void 0 ? void 0 : props.headerHeight,
|
|
38
40
|
]);
|
|
39
41
|
const [folders, setFolders] = useState([]);
|
|
40
42
|
if (typeof window !== "undefined" && !window.process) {
|
|
@@ -4,7 +4,7 @@ type AppRoutesProps = {
|
|
|
4
4
|
folders: FolderTypes[];
|
|
5
5
|
setFolders: React.Dispatch<React.SetStateAction<FolderTypes[]>>;
|
|
6
6
|
routerVersion: 4 | 5 | 6;
|
|
7
|
-
onFolderChange?: (folderId: string) => void;
|
|
7
|
+
onFolderChange?: (folderId: string | undefined) => void;
|
|
8
8
|
};
|
|
9
9
|
export default function AppRoutes({ folders, setFolders, routerVersion, onFolderChange, }: AppRoutesProps): JSX.Element;
|
|
10
10
|
export {};
|
|
@@ -19,7 +19,7 @@ import { SUBSCRIPTION_EXPIRED_ERROR_MESSAGE } from "./appConstants";
|
|
|
19
19
|
const DamConfigContext = createContext(null);
|
|
20
20
|
export const DamConfigProvider = ({ children, config }) => {
|
|
21
21
|
// console.log(config);
|
|
22
|
-
const { damAccessKey, secretKey, subdomain, teamIds, appType, initialRootFolderId } = config;
|
|
22
|
+
const { damAccessKey, secretKey, subdomain, teamIds, appType, initialRootFolderId, headerHeight } = config;
|
|
23
23
|
const [accessToken, setAccessToken] = useState(null);
|
|
24
24
|
const [user, setDamUser] = useState(null);
|
|
25
25
|
const [brand, setBrand] = useState(null);
|
|
@@ -148,6 +148,7 @@ export const DamConfigProvider = ({ children, config }) => {
|
|
|
148
148
|
rootFolderId,
|
|
149
149
|
teams,
|
|
150
150
|
isAdmin,
|
|
151
|
+
headerHeight: headerHeight !== null && headerHeight !== void 0 ? headerHeight : 0,
|
|
151
152
|
}, children: loading ? (_jsx(Loader, {})) : (_jsx(_Fragment, { children: showPaymentErr ? (_jsx("div", { className: "flex items-center justify-center h-[calc(100vh-200px)]", children: _jsx("p", { className: "text-sm font-medium text-textColor dark:text-darkTextColor", children: SUBSCRIPTION_EXPIRED_ERROR_MESSAGE }) })) : (children) })) }));
|
|
152
153
|
};
|
|
153
154
|
export const useDamConfig = () => useContext(DamConfigContext);
|