cloudmr-ux 4.4.0 → 4.4.1

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.
@@ -180,6 +180,6 @@ var CmrUpload = function (_a) {
180
180
  :
181
181
  (props.uploadButtonName ? props.uploadButtonName : "Upload"), " "] }))
182
182
  :
183
- _jsxs(Button, __assign({ fullWidth: props.fullWidth, style: props.style, variant: "contained", sx: { overflowWrap: 'inherit' }, color: 'primary', disabled: true }, { children: ["Uploading ", progress, "%"] })), _jsx(UploadWindow, { open: open, setOpen: setOpen, upload: upload, fileExtension: props.fileExtension, template: { showFileName: true, showFileSize: true } })] }));
183
+ _jsxs(Button, __assign({ fullWidth: props.fullWidth, style: props.style, variant: "contained", sx: { overflowWrap: 'inherit' }, color: 'primary', disabled: true }, { children: ["Uploading ", progress, "%"] })), _jsx(UploadWindow, { open: open, setOpen: setOpen, upload: upload, maxCount: props.maxCount, fileExtension: props.fileExtension, template: { showFileName: true, showFileSize: true } })] }));
184
184
  };
185
185
  export default CmrUpload;
@@ -4,6 +4,7 @@ interface UploadWindowProps {
4
4
  upload: (file: File, fileAlias: string, fileDatabase: string) => Promise<number>;
5
5
  open: boolean;
6
6
  setOpen: React.Dispatch<React.SetStateAction<boolean>>;
7
+ maxCount: number;
7
8
  fileExtension?: string | string[];
8
9
  template?: {
9
10
  showFileName?: boolean;
@@ -11,5 +12,5 @@ interface UploadWindowProps {
11
12
  showFileSize?: boolean;
12
13
  };
13
14
  }
14
- export default function CmrUploadWindow({ upload, open, setOpen, fileExtension, template, }: UploadWindowProps): import("react/jsx-runtime").JSX.Element;
15
+ export default function CmrUploadWindow({ upload, open, setOpen, maxCount, fileExtension, template, }: UploadWindowProps): import("react/jsx-runtime").JSX.Element;
15
16
  export {};
@@ -9,6 +9,51 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
49
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
50
+ if (ar || !(i in from)) {
51
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
52
+ ar[i] = from[i];
53
+ }
54
+ }
55
+ return to.concat(ar || Array.prototype.slice.call(from));
56
+ };
12
57
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
58
  import * as React from 'react';
14
59
  import Button from '@mui/material/Button';
@@ -20,25 +65,72 @@ import DialogContentText from '@mui/material/DialogContentText';
20
65
  import DialogTitle from '@mui/material/DialogTitle';
21
66
  import Typography from '@mui/material/Typography';
22
67
  import Box from "@mui/material/Box";
23
- import { Alert, Collapse, MenuItem } from "@mui/material";
68
+ import { Alert, Collapse, IconButton, List, ListItem, ListItemText, MenuItem } from "@mui/material";
69
+ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
24
70
  import './Upload.css';
25
71
  import CmrLabel from "../label/Label";
72
+ function formatFileSize(numberOfBytes) {
73
+ var units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
74
+ var exponent = Math.min(Math.floor(Math.log(numberOfBytes) / Math.log(1024)), units.length - 1);
75
+ var approx = numberOfBytes / Math.pow(1024, exponent);
76
+ return exponent === 0
77
+ ? "".concat(numberOfBytes, " bytes")
78
+ : "".concat(approx.toFixed(3), " ").concat(units[exponent]);
79
+ }
80
+ function responseStatusMessage(response) {
81
+ if (response === 200) {
82
+ return { style: 'success', text: 'Upload successful', reopen: false };
83
+ }
84
+ if (response === 413) {
85
+ return { style: 'error', text: 'File size limit exceeded', reopen: true };
86
+ }
87
+ if (response === 500) {
88
+ return { style: 'error', text: 'Internal server error', reopen: true };
89
+ }
90
+ if (response === 400) {
91
+ return { style: 'warning', text: 'File upload cancelled', reopen: true };
92
+ }
93
+ return { style: 'warning', text: 'Unknown status', reopen: true };
94
+ }
26
95
  export default function CmrUploadWindow(_a) {
27
- var upload = _a.upload, open = _a.open, setOpen = _a.setOpen, fileExtension = _a.fileExtension, _b = _a.template, template = _b === void 0 ? { showFileName: true, showDatabase: true, showFileSize: true } : _b;
28
- var _c = React.useState(''), fileOriginalName = _c[0], setFileOriginalName = _c[1];
29
- var _d = React.useState('/'), fileAlias = _d[0], setFileAlias = _d[1];
30
- var _e = React.useState('0 MB'), fileSize = _e[0], setFileSize = _e[1];
31
- var _f = React.useState('Unknown Status'), warningText = _f[0], setWarningText = _f[1];
32
- var _g = React.useState(false), infoOpen = _g[0], setInfoOpen = _g[1];
33
- var _h = React.useState('s3'), locationSelection = _h[0], setLocationSelection = _h[1];
34
- var _j = React.useState('info'), infoStyle = _j[0], setInfoStyle = _j[1];
35
- var _k = React.useState([]), uploadedFiles = _k[0], setUploaded = _k[1];
36
- var _l = React.useState(false), UpBtnDisabled = _l[0], setUpBtnDisabled = _l[1];
37
- var _m = React.useState('Upload'), UpBtnText = _m[0], setUpBtnText = _m[1];
38
- var _o = React.useState(undefined), uploadBoxWarning = _o[0], setUploadBoxWarning = _o[1];
39
- var handleClickOpen = function () {
40
- setOpen(true);
96
+ var _this = this;
97
+ var upload = _a.upload, open = _a.open, setOpen = _a.setOpen, maxCount = _a.maxCount, fileExtension = _a.fileExtension, _b = _a.template, template = _b === void 0 ? { showFileName: true, showDatabase: true, showFileSize: true } : _b;
98
+ var _c = React.useState(''), fileAlias = _c[0], setFileAlias = _c[1];
99
+ var _d = React.useState('0 MB'), fileSize = _d[0], setFileSize = _d[1];
100
+ var _e = React.useState('Unknown Status'), warningText = _e[0], setWarningText = _e[1];
101
+ var _f = React.useState(false), infoOpen = _f[0], setInfoOpen = _f[1];
102
+ var locationSelection = React.useState('s3')[0];
103
+ var _g = React.useState('info'), infoStyle = _g[0], setInfoStyle = _g[1];
104
+ var _h = React.useState([]), selectedFiles = _h[0], setSelectedFiles = _h[1];
105
+ var _j = React.useState(false), UpBtnDisabled = _j[0], setUpBtnDisabled = _j[1];
106
+ var _k = React.useState('Upload'), UpBtnText = _k[0], setUpBtnText = _k[1];
107
+ var _l = React.useState(undefined), uploadBoxWarning = _l[0], setUploadBoxWarning = _l[1];
108
+ var fileInputRef = React.useRef(null);
109
+ var allowsMultiple = maxCount > 1;
110
+ var showAlert = function (style, text, durationMs) {
111
+ if (durationMs === void 0) { durationMs = 2500; }
112
+ setInfoOpen(true);
113
+ setInfoStyle(style);
114
+ setWarningText(text);
115
+ setTimeout(function () { return setInfoOpen(false); }, durationMs);
116
+ };
117
+ var resetSelection = function () {
118
+ setSelectedFiles([]);
119
+ setFileAlias('');
120
+ setFileSize('0 MB');
121
+ setUploadBoxWarning(undefined);
122
+ if (fileInputRef.current) {
123
+ fileInputRef.current.value = '';
124
+ }
41
125
  };
126
+ React.useEffect(function () {
127
+ if (open) {
128
+ resetSelection();
129
+ setUpBtnDisabled(false);
130
+ setUpBtnText('Upload');
131
+ setInfoOpen(false);
132
+ }
133
+ }, [open]);
42
134
  var handleClose = function () {
43
135
  setOpen(false);
44
136
  };
@@ -49,238 +141,213 @@ export default function CmrUploadWindow(_a) {
49
141
  if (Array.isArray(allowed)) {
50
142
  return allowed.some(function (ext) { return name.endsWith(ext.startsWith('.') ? ext : '.' + ext); });
51
143
  }
144
+ return name.endsWith(allowed.startsWith('.') ? allowed : '.' + allowed);
145
+ };
146
+ var INVALID_ALIAS_REGEX = /[ ,:%><]/;
147
+ var syncSingleFileFields = function (files) {
148
+ if (files.length === 1) {
149
+ setFileAlias(files[0].name);
150
+ setFileSize(formatFileSize(files[0].size));
151
+ }
152
+ else if (files.length > 1) {
153
+ var totalBytes = files.reduce(function (sum, f) { return sum + f.size; }, 0);
154
+ setFileSize(formatFileSize(totalBytes));
155
+ }
52
156
  else {
53
- return name.endsWith(allowed.startsWith('.') ? allowed : '.' + allowed);
157
+ setFileAlias('');
158
+ setFileSize('0 MB');
54
159
  }
55
160
  };
56
- var getExtension = function (fileName) {
57
- if (fileName == undefined)
58
- return;
59
- return fileName.split('.').pop();
60
- };
61
- var INVALID_ALIAS_REGEX = /[ ,:%><]/;
62
- var handleConfirm = function () {
63
- if (uploadedFiles.length === 0) {
64
- setInfoOpen(true);
65
- setInfoStyle('error');
66
- setWarningText('Must select files to upload!');
67
- setTimeout(function () { return setInfoOpen(false); }, 2500);
68
- return;
161
+ var filterAndCapFiles = function (incoming) {
162
+ var files = __spreadArray([], incoming, true);
163
+ if (fileExtension !== undefined) {
164
+ var rejected = files.filter(function (f) { return !checkExtension(f.name, fileExtension); });
165
+ if (rejected.length > 0) {
166
+ showAlert('warning', rejected.length === 1
167
+ ? "\"".concat(rejected[0].name, "\" has an unsupported extension")
168
+ : "".concat(rejected.length, " file(s) skipped due to unsupported extension"), 4000);
169
+ }
170
+ files = files.filter(function (f) { return checkExtension(f.name, fileExtension); });
171
+ }
172
+ if (files.length === 0) {
173
+ showAlert('warning', 'No valid files selected');
174
+ return [];
175
+ }
176
+ if (files.length > maxCount) {
177
+ showAlert('warning', maxCount === 1
178
+ ? 'Only one file can be uploaded at a time'
179
+ : "Only the first ".concat(maxCount, " files will be uploaded"), 4000);
180
+ files = files.slice(0, maxCount);
69
181
  }
70
- if (fileAlias.length === 0) {
71
- setInfoOpen(true);
72
- setInfoStyle('error');
73
- setWarningText("File name can't be empty");
74
- setTimeout(function () { return setInfoOpen(false); }, 2500);
182
+ return files;
183
+ };
184
+ var loadFiles = function (incoming) {
185
+ var raw = Array.from(incoming);
186
+ if (raw.length === 0) {
187
+ showAlert('warning', 'No file selected');
75
188
  return;
76
189
  }
77
- // Validate File Alias characters
78
- if (INVALID_ALIAS_REGEX.test(fileAlias)) {
79
- setInfoOpen(true);
80
- setInfoStyle('error');
81
- setWarningText("Alias contains invalid characters ( , : % > < or spaces )");
82
- setTimeout(function () { return setInfoOpen(false); }, 10000);
190
+ var files = filterAndCapFiles(raw);
191
+ if (files.length === 0) {
83
192
  return;
84
193
  }
85
- setOpen(false);
86
- upload(uploadedFiles[0], fileAlias, locationSelection).then(function (response) {
87
- console.log(response);
88
- //Update image with another ajax
89
- if (response > 0) {
90
- setInfoOpen(true);
91
- if (response === 200) {
92
- setInfoStyle('success');
93
- setWarningText("Upload successful");
94
- setTimeout(function () {
95
- setInfoOpen(false);
96
- setOpen(false);
97
- }, 1000);
194
+ setSelectedFiles(files);
195
+ syncSingleFileFields(files);
196
+ setUploadBoxWarning(undefined);
197
+ };
198
+ var removeFileAt = function (index) {
199
+ setSelectedFiles(function (prev) {
200
+ var next = prev.filter(function (_, i) { return i !== index; });
201
+ syncSingleFileFields(next);
202
+ return next;
203
+ });
204
+ };
205
+ var handleConfirm = function () { return __awaiter(_this, void 0, void 0, function () {
206
+ var isSingle, alias, total, successCount, lastFailure, i, file, fileAliasForUpload, response, error_1;
207
+ var _a, _b;
208
+ return __generator(this, function (_c) {
209
+ switch (_c.label) {
210
+ case 0:
211
+ if (selectedFiles.length === 0) {
212
+ showAlert('error', 'Must select files to upload!');
213
+ return [2 /*return*/];
214
+ }
215
+ isSingle = selectedFiles.length === 1;
216
+ alias = isSingle ? fileAlias : '';
217
+ if (isSingle) {
218
+ if (alias.length === 0) {
219
+ showAlert('error', "File name can't be empty");
220
+ return [2 /*return*/];
221
+ }
222
+ if (INVALID_ALIAS_REGEX.test(alias)) {
223
+ showAlert('error', 'Alias contains invalid characters ( , : % > < or spaces )', 10000);
224
+ return [2 /*return*/];
225
+ }
226
+ }
227
+ setUpBtnDisabled(true);
228
+ setUpBtnText('Uploading');
229
+ setOpen(false);
230
+ total = selectedFiles.length;
231
+ successCount = 0;
232
+ lastFailure = null;
233
+ i = 0;
234
+ _c.label = 1;
235
+ case 1:
236
+ if (!(i < total)) return [3 /*break*/, 6];
237
+ file = selectedFiles[i];
238
+ fileAliasForUpload = isSingle ? alias : file.name;
239
+ if (total > 1) {
240
+ setUpBtnText("Uploading ".concat(i + 1, "/").concat(total));
241
+ }
242
+ _c.label = 2;
243
+ case 2:
244
+ _c.trys.push([2, 4, , 5]);
245
+ return [4 /*yield*/, upload(file, fileAliasForUpload, locationSelection)];
246
+ case 3:
247
+ response = _c.sent();
248
+ if (response === 200) {
249
+ successCount++;
250
+ }
251
+ else {
252
+ lastFailure = responseStatusMessage(response);
253
+ }
254
+ return [3 /*break*/, 5];
255
+ case 4:
256
+ error_1 = _c.sent();
257
+ lastFailure = {
258
+ style: 'error',
259
+ text: "Upload unsuccessful: ".concat(error_1 instanceof Error ? error_1.message : String(error_1)),
260
+ reopen: true
261
+ };
262
+ return [3 /*break*/, 5];
263
+ case 5:
264
+ i++;
265
+ return [3 /*break*/, 1];
266
+ case 6:
98
267
  setUpBtnDisabled(false);
99
268
  setUpBtnText('Upload');
100
- }
101
- else if (response === 413) {
102
- setInfoStyle('error');
103
- setWarningText("File size limit exceeded");
104
- setTimeout(function () {
105
- setInfoOpen(false);
106
- setUpBtnDisabled(false);
107
- setUpBtnText('Upload');
108
- }, 2000);
109
- }
110
- else if (response === 500) {
111
- setInfoStyle('error');
112
- setWarningText("Internal server error");
113
- setTimeout(function () {
114
- setInfoOpen(false);
115
- setUpBtnDisabled(false);
116
- setUpBtnText('Upload');
117
- }, 1500);
118
- setOpen(true);
119
- }
120
- else if (response === 400) {
121
- setInfoStyle('warning');
122
- setWarningText("File upload cancelled");
123
- setTimeout(function () {
124
- setInfoOpen(false);
125
- setUpBtnDisabled(false);
126
- setUpBtnText('Upload');
127
- }, 1000);
128
- setOpen(true);
129
- }
130
- else {
131
- setInfoStyle('warning');
132
- setWarningText("Unknown status");
133
- setTimeout(function () {
134
- setInfoOpen(false);
135
- setUpBtnDisabled(false);
136
- setUpBtnText('Upload');
137
- }, 2000);
138
- setOpen(true);
139
- }
269
+ resetSelection();
270
+ if (successCount === total) {
271
+ showAlert('success', total === 1 ? 'Upload successful' : "".concat(total, " files uploaded successfully"), 2000);
272
+ }
273
+ else if (successCount === 0) {
274
+ setOpen(true);
275
+ showAlert((_a = lastFailure === null || lastFailure === void 0 ? void 0 : lastFailure.style) !== null && _a !== void 0 ? _a : 'error', (_b = lastFailure === null || lastFailure === void 0 ? void 0 : lastFailure.text) !== null && _b !== void 0 ? _b : 'Upload failed', 4000);
276
+ }
277
+ else {
278
+ setOpen(true);
279
+ showAlert('warning', "".concat(successCount, " of ").concat(total, " files uploaded successfully"), 4000);
280
+ }
281
+ return [2 /*return*/];
140
282
  }
141
- })["catch"](function (error) {
142
- setUpBtnDisabled(false);
143
- setUpBtnText('Upload');
144
- setInfoOpen(true);
145
- setInfoStyle('error');
146
- setWarningText("Upload unsuccessful: " + error.message);
147
- setTimeout(function () { return setInfoOpen(false); }, 2500);
148
- console.error('Error:', error);
149
283
  });
150
- setUpBtnDisabled(true);
151
- setUpBtnText('Uploading');
152
- };
284
+ }); };
153
285
  var changeFileName = function (e) {
154
- // @ts-ignore
155
286
  setFileAlias(e.target.value);
156
287
  };
157
- function loadFiles(files) {
158
- if (files.length == 0) {
159
- setInfoOpen(true);
160
- setInfoStyle('warning');
161
- setWarningText('No file selected');
162
- setTimeout(function () { return setInfoOpen(false); }, 2500);
163
- return;
164
- }
165
- if (files.length > 1) {
166
- setInfoOpen(true);
167
- setInfoStyle('warning');
168
- setWarningText('Only accepts one file at a time');
169
- setTimeout(function () { return setInfoOpen(false); }, 2500);
170
- return;
171
- }
172
- var file = files[0];
173
- setUploaded([file]);
174
- // let reader = new FileReader();
175
- // reader.onload =
176
- function readFile(file) {
177
- setFileOriginalName(file.name);
178
- setFileAlias(file.name);
179
- var units = [
180
- "B",
181
- "KB",
182
- "MB",
183
- "GB",
184
- "TB",
185
- "PB",
186
- "EB",
187
- "ZB",
188
- "YB",
189
- ];
190
- var numberOfBytes = file.size;
191
- var exponent = Math.min(Math.floor(Math.log(numberOfBytes) / Math.log(1024)), units.length - 1);
192
- var approx = numberOfBytes / Math.pow(1024, exponent);
193
- var output = exponent === 0
194
- ? "".concat(numberOfBytes, " bytes")
195
- : "".concat(approx.toFixed(3), " ").concat(units[exponent]);
196
- setFileSize(output);
197
- }
198
- readFile(file); // start reading the file data.
199
- }
200
- var initialized = false;
201
- var fileInput = function (inputRef) {
202
- if (initialized)
203
- return;
204
- inputRef.addEventListener('dragover', function (e) {
205
- e.stopPropagation();
206
- e.preventDefault();
207
- // @ts-ignore
208
- if (e.dataTransfer.files) {
209
- // @ts-ignore
210
- var draggedFiles = e.dataTransfer.files;
211
- if (draggedFiles.length > 1) {
212
- setUploadBoxWarning('Only one file can be uploaded at a time');
213
- }
214
- else if (fileExtension != undefined && draggedFiles.length !== 0 &&
215
- !checkExtension(draggedFiles[0].name, fileExtension)) {
216
- setUploadBoxWarning("Only accepting files with extension(s): ".concat(Array.isArray(fileExtension) ? fileExtension.join(', ') : fileExtension));
217
- }
288
+ var handleDragOver = function (e) {
289
+ e.preventDefault();
290
+ e.stopPropagation();
291
+ if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
292
+ var dragged = Array.from(e.dataTransfer.files);
293
+ if (maxCount === 1 && dragged.length > 1) {
294
+ setUploadBoxWarning('Only one file can be uploaded at a time');
218
295
  }
219
- // @ts-ignore
220
- e.dataTransfer.dropEffect = 'copy';
221
- });
222
- // Get file data on drop
223
- inputRef.addEventListener('drop', function (e) {
224
- e.stopPropagation();
225
- e.preventDefault();
226
- // setUploadBoxWarning(undefined);
227
- setTimeout(function () {
228
- setUploadBoxWarning(undefined);
229
- }, 10000);
230
- // @ts-ignore
231
- var files = e.dataTransfer.files; // Array of all files
232
- if (files.length > 1) {
233
- setInfoOpen(true);
234
- setInfoStyle('warning');
235
- setWarningText('Only one file can be uploaded at a time');
236
- setTimeout(function () { return setInfoOpen(false); }, 2500);
237
- return;
296
+ else if (maxCount > 1 && dragged.length > maxCount) {
297
+ setUploadBoxWarning("You can upload up to ".concat(maxCount, " files at a time"));
238
298
  }
239
299
  else if (fileExtension !== undefined &&
240
- !checkExtension(files[0].name, fileExtension)) {
241
- setInfoOpen(true);
242
- setInfoStyle('warning');
243
- setWarningText("Only accepting files with extension(s): ".concat(Array.isArray(fileExtension) ? fileExtension.join(', ') : fileExtension));
244
- setTimeout(function () { return setInfoOpen(false); }, 2500);
245
- return;
300
+ dragged.some(function (f) { return !checkExtension(f.name, fileExtension); })) {
301
+ setUploadBoxWarning("Only accepting files with extension(s): ".concat(Array.isArray(fileExtension) ? fileExtension.join(', ') : fileExtension));
246
302
  }
247
- // @ts-ignore
248
- loadFiles(files);
249
- });
250
- inputRef.addEventListener('dragleave', function () {
251
- setUploadBoxWarning(undefined);
252
- });
253
- initialized = true;
303
+ else {
304
+ setUploadBoxWarning(undefined);
305
+ }
306
+ }
307
+ e.dataTransfer.dropEffect = 'copy';
254
308
  };
255
- var fileInputClick = function (e) {
256
- var fileElem = document.getElementById("file-window");
309
+ var handleDrop = function (e) {
257
310
  e.preventDefault();
258
- if (fileElem) {
259
- fileElem.click();
311
+ e.stopPropagation();
312
+ setTimeout(function () { return setUploadBoxWarning(undefined); }, 10000);
313
+ if (e.dataTransfer.files) {
314
+ loadFiles(e.dataTransfer.files);
260
315
  }
261
316
  };
317
+ var handleDragLeave = function () {
318
+ setUploadBoxWarning(undefined);
319
+ };
320
+ var fileInputClick = function (e) {
321
+ var _a;
322
+ e.preventDefault();
323
+ (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
324
+ };
262
325
  var loadSelectedFiles = function (e) {
263
326
  e.preventDefault();
264
- var fileElem = document.getElementById('file-window');
265
- // @ts-ignore
266
- loadFiles(fileElem.files);
327
+ if (e.target.files) {
328
+ loadFiles(e.target.files);
329
+ }
267
330
  };
268
- // @ts-ignore
269
- return (_jsx("div", { children: _jsxs(Dialog, __assign({ open: open, onClose: handleClose }, { children: [_jsx(DialogTitle, { children: "File Upload" }), _jsxs(DialogContent, { children: [_jsx(DialogContentText, {}), _jsxs(DialogContent, __assign({ dividers: true }, { children: [_jsx(Box, __assign({ width: 500, height: 250, style: {
331
+ var dropZoneLabel = allowsMultiple
332
+ ? "Drag & Drop or Click to Upload Up to ".concat(maxCount, " Files Here")
333
+ : 'Drag & Drop or Click to Upload Your File Here';
334
+ return (_jsx("div", { children: _jsxs(Dialog, __assign({ open: open, onClose: handleClose, maxWidth: "sm", fullWidth: true }, { children: [_jsx(DialogTitle, { children: "File Upload" }), _jsxs(DialogContent, { children: [_jsx(DialogContentText, {}), _jsxs(DialogContent, __assign({ dividers: true }, { children: [_jsx(Box, __assign({ width: "100%", minHeight: 250, style: {
270
335
  borderStyle: 'dashed',
271
336
  borderRadius: '5pt',
272
- borderColor: (uploadBoxWarning == undefined) ? 'lightGray' : '#BA3C3C'
337
+ borderColor: uploadBoxWarning == undefined ? 'lightGray' : '#BA3C3C'
273
338
  } }, { children: _jsx(Typography, __assign({ component: "div", style: { height: '100%' } }, { children: _jsxs(Box, __assign({ style: {
274
339
  display: 'flex',
275
340
  flexDirection: 'column',
276
341
  justifyContent: 'center',
277
342
  alignItems: 'center',
278
- height: '100%'
279
- }, onClick: fileInputClick, ref: fileInput }, { children: [_jsxs(Typography, __assign({ variant: "body1", align: "center", style: { marginTop: 'auto' } }, { children: ["Drag & Drop or Click to Upload Your File Here ", _jsx("sup", { children: "*" })] })), _jsx(Typography, __assign({ variant: "body2", align: "center", style: { marginTop: 'auto', fontSize: '0.8rem', fontStyle: 'italic' } }, { children: "* Warning: The file you are uploading may contain sensitive information protected under privacy laws. Please ensure all PHI is anonymized before proceeding.Before proceeding. The user is the sole responsible for data anonymization." }))] })) })) })), _jsx("input", { type: "file", id: "file-window", multiple: true, accept: fileExtension === undefined
343
+ height: '100%',
344
+ minHeight: 250,
345
+ cursor: 'pointer'
346
+ }, onClick: fileInputClick, onDragOver: handleDragOver, onDrop: handleDrop, onDragLeave: handleDragLeave }, { children: [_jsxs(Typography, __assign({ variant: "body1", align: "center", style: { marginTop: 'auto' } }, { children: [dropZoneLabel, " ", _jsx("sup", { children: "*" })] })), _jsx(Typography, __assign({ variant: "body2", align: "center", style: { marginTop: 'auto', fontSize: '0.8rem', fontStyle: 'italic' } }, { children: "* Warning: The file you are uploading may contain sensitive information protected under privacy laws. Please ensure all PHI is anonymized before proceeding.Before proceeding. The user is the sole responsible for data anonymization." }))] })) })) })), _jsx("input", { ref: fileInputRef, type: "file", multiple: allowsMultiple, accept: fileExtension === undefined
280
347
  ? '*'
281
348
  : Array.isArray(fileExtension)
282
349
  ? fileExtension.join(',')
283
- : fileExtension, style: { display: 'none' }, onChange: loadSelectedFiles }), _jsxs(Box, __assign({ component: "form", sx: { '& .MuiTextField-root': { m: 2, width: '25ch', mb: 0 } } }, { children: [_jsxs("div", { children: [template.showFileName && (_jsx(TextField, { required: true, style: { marginTop: '30px' }, label: "File Alias:", value: fileAlias, variant: "standard", onChange: changeFileName })), fileOriginalName != '' && _jsx(CmrLabel, __assign({ style: { marginLeft: '16px', fontSize: '9pt', color: '#267833' } }, { children: fileOriginalName })), template.showDatabase && (_jsx(TextField, __assign({ select: true, label: "Database:", defaultValue: "s3", helperText: "Upstream Storage Location", variant: "standard" }, { children: [{ value: 's3', label: 'S3' }].map(function (option) { return (_jsx(MenuItem, __assign({ value: option.value }, { children: option.label }), option.value)); }) })))] }), _jsxs("div", { children: [template.showFileSize && (_jsx(TextField, { label: "File Size:", value: fileSize, InputProps: {
350
+ : fileExtension, style: { display: 'none' }, onChange: loadSelectedFiles }), selectedFiles.length > 1 && (_jsx(Box, __assign({ sx: { mt: 2, maxHeight: 180, overflowY: 'auto', border: '1px solid #E6E6EA', borderRadius: 1 } }, { children: _jsx(List, __assign({ dense: true, disablePadding: true }, { children: selectedFiles.map(function (file, index) { return (_jsx(ListItem, __assign({ secondaryAction: _jsx(IconButton, __assign({ edge: "end", "aria-label": "remove", onClick: function () { return removeFileAt(index); } }, { children: _jsx(DeleteOutlineIcon, { fontSize: "small" }) })) }, { children: _jsx(ListItemText, { primary: file.name, secondary: formatFileSize(file.size) }) }), "".concat(file.name, "-").concat(file.lastModified, "-").concat(index))); }) })) }))), _jsxs(Box, __assign({ component: "form", sx: { '& .MuiTextField-root': { m: 2, width: '25ch', mb: 0 } } }, { children: [_jsxs("div", { children: [template.showFileName && selectedFiles.length === 1 && (_jsx(TextField, { required: true, style: { marginTop: '30px' }, label: "File Alias:", value: fileAlias, variant: "standard", onChange: changeFileName })), selectedFiles.length === 1 && (_jsx(CmrLabel, __assign({ style: { marginLeft: '16px', fontSize: '9pt', color: '#267833' } }, { children: selectedFiles[0].name }))), template.showFileName && selectedFiles.length > 1 && (_jsxs(CmrLabel, __assign({ style: { marginLeft: '16px', marginTop: '16px', fontSize: '9pt', color: '#267833' } }, { children: [selectedFiles.length, " files selected \u2014 each will upload using its original filename"] }))), template.showDatabase && (_jsx(TextField, __assign({ select: true, label: "Database:", defaultValue: "s3", helperText: "Upstream Storage Location", variant: "standard" }, { children: [{ value: 's3', label: 'S3' }].map(function (option) { return (_jsx(MenuItem, __assign({ value: option.value }, { children: option.label }), option.value)); }) })))] }), _jsxs("div", { children: [template.showFileSize && selectedFiles.length > 0 && (_jsx(TextField, { label: selectedFiles.length > 1 ? 'Total Size:' : 'File Size:', value: fileSize, InputProps: {
284
351
  readOnly: true
285
- }, variant: "standard" })), _jsx(Collapse, __assign({ "in": infoOpen }, { children: _jsx(Alert, __assign({ severity: infoStyle, sx: { m: 1 } }, { children: warningText })) }))] })] }))] })), _jsxs(DialogActions, { children: [_jsx(Button, __assign({ variant: "outlined", disabled: UpBtnDisabled, onClick: handleClose }, { children: "Cancel" })), _jsx(Button, __assign({ variant: 'contained', disabled: UpBtnDisabled, onClick: handleConfirm }, { children: UpBtnText }))] })] })] })) }));
352
+ }, variant: "standard" })), _jsx(Collapse, __assign({ "in": infoOpen }, { children: _jsx(Alert, __assign({ severity: infoStyle, sx: { m: 1 } }, { children: warningText })) }))] })] }))] })), _jsxs(DialogActions, { children: [_jsx(Button, __assign({ variant: "outlined", disabled: UpBtnDisabled, onClick: handleClose }, { children: "Cancel" })), _jsxs(Button, __assign({ variant: "contained", disabled: UpBtnDisabled || selectedFiles.length === 0, onClick: handleConfirm }, { children: [UpBtnText, selectedFiles.length > 1 ? " (".concat(selectedFiles.length, ")") : ''] }))] })] })] })) }));
286
353
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudmr-ux",
3
- "version": "4.4.0",
3
+ "version": "4.4.1",
4
4
  "author": "erosmontin@gmail.com",
5
5
  "license": "MIT",
6
6
  "repository": "erosmontin/cloudmr-ux",