cloudmr-ux 1.0.6 → 1.0.7
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/dist/index.css +26 -0
- package/dist/index.d.ts +83 -2
- package/dist/index.js +471 -2
- package/dist/index.mjs +470 -2
- package/package.json +2 -1
package/dist/index.css
CHANGED
|
@@ -146,6 +146,32 @@
|
|
|
146
146
|
margin-bottom: 4px;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
/* src/CmrComponents/upload/Upload.css */
|
|
150
|
+
.btn-info {
|
|
151
|
+
color: #ffffff;
|
|
152
|
+
--bs-btn-hover-color: #ffffff;
|
|
153
|
+
--bs-btn-color: #ffffff;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* src/CmrComponents/label/Label.css */
|
|
157
|
+
.cmr-label {
|
|
158
|
+
display: flex;
|
|
159
|
+
align-items: center;
|
|
160
|
+
font-style: normal;
|
|
161
|
+
font-weight: 400;
|
|
162
|
+
font-family:
|
|
163
|
+
"Inter",
|
|
164
|
+
"Roboto",
|
|
165
|
+
"Helvetica",
|
|
166
|
+
"Arial",
|
|
167
|
+
sans-serif;
|
|
168
|
+
padding-right: 10px;
|
|
169
|
+
}
|
|
170
|
+
.asterik {
|
|
171
|
+
color: red !important;
|
|
172
|
+
margin-left: 4px;
|
|
173
|
+
}
|
|
174
|
+
|
|
149
175
|
/* src/CmrTable/CmrTable.css */
|
|
150
176
|
.css-1lymaxv-MuiDataGrid-root .MuiDataGrid-columnHeader:focus-within,
|
|
151
177
|
.css-1lymaxv-MuiDataGrid-root .MuiDataGrid-cell:focus-within {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ButtonProps } from '@mui/material';
|
|
2
|
+
import { ButtonProps, SxProps, Theme } from '@mui/material';
|
|
3
3
|
import React, { ChangeEvent, ReactNode, CSSProperties, FC } from 'react';
|
|
4
4
|
import { SizeType } from 'antd/lib/config-provider/SizeContext';
|
|
5
5
|
import { CollapsibleType } from 'antd/es/collapse/CollapsePanel';
|
|
6
6
|
import { ExpandIconPosition } from 'antd/es/collapse/Collapse';
|
|
7
|
+
import { AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
7
8
|
import { DataGridProps } from '@mui/x-data-grid';
|
|
8
9
|
|
|
9
10
|
declare const CmrButton: (props: ButtonProps) => react_jsx_runtime.JSX.Element;
|
|
@@ -83,6 +84,86 @@ interface CmrPanelProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
83
84
|
}
|
|
84
85
|
declare const CmrPanel: (props: CmrPanelProps) => react_jsx_runtime.JSX.Element;
|
|
85
86
|
|
|
87
|
+
interface LambdaFile {
|
|
88
|
+
"filename": string;
|
|
89
|
+
"filetype": string;
|
|
90
|
+
"filesize": string;
|
|
91
|
+
"filemd5": string;
|
|
92
|
+
"file": File;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Consists of general settings for upload component
|
|
96
|
+
* functionalities and call back methods evoked
|
|
97
|
+
* for specific interactions
|
|
98
|
+
*/
|
|
99
|
+
interface CMRUploadProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
100
|
+
retains?: boolean;
|
|
101
|
+
maxCount: number;
|
|
102
|
+
changeNameAfterUpload?: boolean;
|
|
103
|
+
onRemove?: (removedFile: File) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Allows access to file content prior to uploading.
|
|
106
|
+
* If returned value from the method is false,
|
|
107
|
+
* prevents the file upload process. Called before
|
|
108
|
+
* create payload.
|
|
109
|
+
* @param file
|
|
110
|
+
*/
|
|
111
|
+
beforeUpload?: (file: File) => Promise<boolean>;
|
|
112
|
+
/**
|
|
113
|
+
* This or uploadHandler must be specified
|
|
114
|
+
* @param file
|
|
115
|
+
* @param fileAlias
|
|
116
|
+
* @param fileDatabase
|
|
117
|
+
*/
|
|
118
|
+
createPayload?: (file: File, fileAlias: string, fileDatabase: string) => (Promise<{
|
|
119
|
+
destination: string;
|
|
120
|
+
lambdaFile: LambdaFile;
|
|
121
|
+
file: File;
|
|
122
|
+
config: AxiosRequestConfig;
|
|
123
|
+
} | undefined>);
|
|
124
|
+
onUploadProgressUpdate?: (loaded: number, total: number) => void | undefined;
|
|
125
|
+
onUploaded: (res: AxiosResponse, file: File) => Promise<void> | void;
|
|
126
|
+
sx?: SxProps<Theme> | undefined;
|
|
127
|
+
rest?: any;
|
|
128
|
+
fileExtension?: string;
|
|
129
|
+
uploadStarted?: () => void;
|
|
130
|
+
uploadEnded?: () => void;
|
|
131
|
+
uploadFailed?: () => void;
|
|
132
|
+
uploadProgressed?: (progress: number) => void;
|
|
133
|
+
/**
|
|
134
|
+
* Override this to replace the default behavior of uploading
|
|
135
|
+
* @param file
|
|
136
|
+
* @param fileAlias
|
|
137
|
+
* @param fileDatabase
|
|
138
|
+
* @param onProgress
|
|
139
|
+
* @param onUploaded
|
|
140
|
+
*/
|
|
141
|
+
uploadHandler?: (file: File, fileAlias: string, fileDatabase: string, onProgress?: (progress: number) => void, onUploaded?: (res: AxiosResponse, file: File) => void) => Promise<number>;
|
|
142
|
+
fullWidth?: boolean;
|
|
143
|
+
style?: any;
|
|
144
|
+
/**
|
|
145
|
+
* Displays upload button instead of uploaded file after upload
|
|
146
|
+
* if set to reusable
|
|
147
|
+
*/
|
|
148
|
+
reusable?: boolean;
|
|
149
|
+
uploadButtonName?: string;
|
|
150
|
+
/**
|
|
151
|
+
* Processes the uploaded file before performing the upload;
|
|
152
|
+
* @return file/undefined/statuscode undefined to fail the upload, return File
|
|
153
|
+
* to pass the processed file, return number to indicate error code
|
|
154
|
+
* and return to upload window.
|
|
155
|
+
* @param file
|
|
156
|
+
*/
|
|
157
|
+
preprocess?: (file: File) => Promise<File | undefined | number>;
|
|
158
|
+
color?: "inherit" | "primary" | "secondary" | "success" | "error" | "info" | "warning";
|
|
159
|
+
}
|
|
160
|
+
declare const CmrUpload: {
|
|
161
|
+
(props: CMRUploadProps): react_jsx_runtime.JSX.Element;
|
|
162
|
+
defaultProps: {
|
|
163
|
+
changeNameAfterUpload: boolean;
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
|
|
86
167
|
interface CmrTableProps extends Omit<DataGridProps, 'rows'> {
|
|
87
168
|
dataSource: any[];
|
|
88
169
|
idAlias?: string;
|
|
@@ -93,4 +174,4 @@ interface CmrTableProps extends Omit<DataGridProps, 'rows'> {
|
|
|
93
174
|
|
|
94
175
|
declare const CmrTable: FC<CmrTableProps>;
|
|
95
176
|
|
|
96
|
-
export { CmrButton, CmrCheckbox, CmrCollapse, CmrInput, CmrPanel, CmrRadioGroup, CmrSelect, CmrTable, CmrTableProps };
|
|
177
|
+
export { CmrUpload as CMRUpload, CmrButton, CmrCheckbox, CmrCollapse, CmrInput, CmrPanel, CmrRadioGroup, CmrSelect, CmrTable, CmrTableProps, LambdaFile };
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
CMRUpload: () => Upload_default,
|
|
33
34
|
CmrButton: () => CmrButton,
|
|
34
35
|
CmrCheckbox: () => CmrCheckbox,
|
|
35
36
|
CmrCollapse: () => Collapse_default,
|
|
@@ -290,9 +291,476 @@ var CmrPanel = function(props) {
|
|
|
290
291
|
};
|
|
291
292
|
var Panel_default = CmrPanel;
|
|
292
293
|
|
|
294
|
+
// src/CmrComponents/upload/Upload.tsx
|
|
295
|
+
var import_react4 = __toESM(require("react"));
|
|
296
|
+
var import_material7 = require("@mui/material");
|
|
297
|
+
|
|
298
|
+
// src/CmrComponents/upload/UploadWindow.tsx
|
|
299
|
+
var React4 = __toESM(require("react"));
|
|
300
|
+
var import_Button = __toESM(require("@mui/material/Button"));
|
|
301
|
+
var import_TextField = __toESM(require("@mui/material/TextField"));
|
|
302
|
+
var import_Dialog = __toESM(require("@mui/material/Dialog"));
|
|
303
|
+
var import_DialogActions = __toESM(require("@mui/material/DialogActions"));
|
|
304
|
+
var import_DialogContent = __toESM(require("@mui/material/DialogContent"));
|
|
305
|
+
var import_DialogContentText = __toESM(require("@mui/material/DialogContentText"));
|
|
306
|
+
var import_DialogTitle = __toESM(require("@mui/material/DialogTitle"));
|
|
307
|
+
var import_Typography = __toESM(require("@mui/material/Typography"));
|
|
308
|
+
var import_Box = __toESM(require("@mui/material/Box"));
|
|
309
|
+
var import_material6 = require("@mui/material");
|
|
310
|
+
|
|
311
|
+
// src/CmrComponents/label/Label.tsx
|
|
312
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
313
|
+
var CmrLabel = (props) => {
|
|
314
|
+
const { children, required = false } = props;
|
|
315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "cmr-label", style: { fontSize: "16px", ...props.style }, children: [
|
|
316
|
+
children,
|
|
317
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "asterik", children: "*" })
|
|
318
|
+
] });
|
|
319
|
+
};
|
|
320
|
+
var Label_default = CmrLabel;
|
|
321
|
+
|
|
322
|
+
// src/CmrComponents/upload/UploadWindow.tsx
|
|
323
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
324
|
+
function UploadWindow({
|
|
325
|
+
upload,
|
|
326
|
+
open,
|
|
327
|
+
setOpen,
|
|
328
|
+
fileExtension,
|
|
329
|
+
template = { showFileName: true, showDatabase: true, showFileSize: true }
|
|
330
|
+
// default values
|
|
331
|
+
}) {
|
|
332
|
+
const [fileOriginalName, setFileOriginalName] = React4.useState("");
|
|
333
|
+
const [fileAlias, setFileAlias] = React4.useState("/");
|
|
334
|
+
const [fileSize, setFileSize] = React4.useState("0 MB");
|
|
335
|
+
const [warningText, setWarningText] = React4.useState("Unknown Status");
|
|
336
|
+
const [infoOpen, setInfoOpen] = React4.useState(false);
|
|
337
|
+
const [locationSelection, setLocationSelection] = React4.useState("s3");
|
|
338
|
+
const [infoStyle, setInfoStyle] = React4.useState("info");
|
|
339
|
+
const [uploadedFiles, setUploaded] = React4.useState([]);
|
|
340
|
+
const [UpBtnDisabled, setUpBtnDisabled] = React4.useState(false);
|
|
341
|
+
const [UpBtnText, setUpBtnText] = React4.useState("Upload");
|
|
342
|
+
const [uploadBoxWarning, setUploadBoxWarning] = React4.useState(void 0);
|
|
343
|
+
const handleClickOpen = () => {
|
|
344
|
+
setOpen(true);
|
|
345
|
+
};
|
|
346
|
+
const handleClose = () => {
|
|
347
|
+
setOpen(false);
|
|
348
|
+
};
|
|
349
|
+
const getExtension = (fileName) => {
|
|
350
|
+
if (fileName == void 0)
|
|
351
|
+
return;
|
|
352
|
+
return fileName.split(".").pop();
|
|
353
|
+
};
|
|
354
|
+
const handleConfirm = () => {
|
|
355
|
+
if (uploadedFiles.length === 0) {
|
|
356
|
+
setInfoOpen(true);
|
|
357
|
+
setInfoStyle("error");
|
|
358
|
+
setWarningText("Must select files to upload!");
|
|
359
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (fileAlias.length === 0) {
|
|
363
|
+
setInfoOpen(true);
|
|
364
|
+
setInfoStyle("error");
|
|
365
|
+
setWarningText("File name can't be empty");
|
|
366
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
setOpen(false);
|
|
370
|
+
upload(uploadedFiles[0], fileAlias, locationSelection).then((response) => {
|
|
371
|
+
console.log(response);
|
|
372
|
+
if (response > 0) {
|
|
373
|
+
setInfoOpen(true);
|
|
374
|
+
if (response === 200) {
|
|
375
|
+
setInfoStyle("success");
|
|
376
|
+
setWarningText("Upload successful");
|
|
377
|
+
setTimeout(() => {
|
|
378
|
+
setInfoOpen(false);
|
|
379
|
+
setOpen(false);
|
|
380
|
+
}, 1e3);
|
|
381
|
+
setUpBtnDisabled(false);
|
|
382
|
+
setUpBtnText("Upload");
|
|
383
|
+
} else if (response === 413) {
|
|
384
|
+
setInfoStyle("error");
|
|
385
|
+
setWarningText("File size limit exceeded");
|
|
386
|
+
setTimeout(() => {
|
|
387
|
+
setInfoOpen(false);
|
|
388
|
+
setUpBtnDisabled(false);
|
|
389
|
+
setUpBtnText("Upload");
|
|
390
|
+
}, 2e3);
|
|
391
|
+
} else if (response === 500) {
|
|
392
|
+
setInfoStyle("error");
|
|
393
|
+
setWarningText("Internal server error");
|
|
394
|
+
setTimeout(() => {
|
|
395
|
+
setInfoOpen(false);
|
|
396
|
+
setUpBtnDisabled(false);
|
|
397
|
+
setUpBtnText("Upload");
|
|
398
|
+
}, 1500);
|
|
399
|
+
setOpen(true);
|
|
400
|
+
} else if (response === 400) {
|
|
401
|
+
setInfoStyle("warning");
|
|
402
|
+
setWarningText("File upload cancelled");
|
|
403
|
+
setTimeout(() => {
|
|
404
|
+
setInfoOpen(false);
|
|
405
|
+
setUpBtnDisabled(false);
|
|
406
|
+
setUpBtnText("Upload");
|
|
407
|
+
}, 1e3);
|
|
408
|
+
setOpen(true);
|
|
409
|
+
} else {
|
|
410
|
+
setInfoStyle("warning");
|
|
411
|
+
setWarningText("Unknown status");
|
|
412
|
+
setTimeout(() => {
|
|
413
|
+
setInfoOpen(false);
|
|
414
|
+
setUpBtnDisabled(false);
|
|
415
|
+
setUpBtnText("Upload");
|
|
416
|
+
}, 2e3);
|
|
417
|
+
setOpen(true);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}).catch((error) => {
|
|
421
|
+
setUpBtnDisabled(false);
|
|
422
|
+
setUpBtnText("Upload");
|
|
423
|
+
setInfoOpen(true);
|
|
424
|
+
setInfoStyle("error");
|
|
425
|
+
setWarningText("Upload unsuccessful: " + error.message);
|
|
426
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
427
|
+
console.error("Error:", error);
|
|
428
|
+
});
|
|
429
|
+
setUpBtnDisabled(true);
|
|
430
|
+
setUpBtnText("Uploading");
|
|
431
|
+
};
|
|
432
|
+
const changeFileName = (e) => {
|
|
433
|
+
setFileAlias(e.target.value);
|
|
434
|
+
};
|
|
435
|
+
function loadFiles(files) {
|
|
436
|
+
if (files.length == 0) {
|
|
437
|
+
setInfoOpen(true);
|
|
438
|
+
setInfoStyle("warning");
|
|
439
|
+
setWarningText("No file selected");
|
|
440
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
if (files.length > 1) {
|
|
444
|
+
setInfoOpen(true);
|
|
445
|
+
setInfoStyle("warning");
|
|
446
|
+
setWarningText("Only accepts one file at a time");
|
|
447
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
let file = files[0];
|
|
451
|
+
setUploaded([file]);
|
|
452
|
+
function readFile(file2) {
|
|
453
|
+
setFileOriginalName(file2.name);
|
|
454
|
+
setFileAlias(file2.name);
|
|
455
|
+
const units = [
|
|
456
|
+
"B",
|
|
457
|
+
"KB",
|
|
458
|
+
"MB",
|
|
459
|
+
"GB",
|
|
460
|
+
"TB",
|
|
461
|
+
"PB",
|
|
462
|
+
"EB",
|
|
463
|
+
"ZB",
|
|
464
|
+
"YB"
|
|
465
|
+
];
|
|
466
|
+
let numberOfBytes = file2.size;
|
|
467
|
+
const exponent = Math.min(
|
|
468
|
+
Math.floor(Math.log(numberOfBytes) / Math.log(1024)),
|
|
469
|
+
units.length - 1
|
|
470
|
+
);
|
|
471
|
+
const approx = numberOfBytes / 1024 ** exponent;
|
|
472
|
+
const output = exponent === 0 ? `${numberOfBytes} bytes` : `${approx.toFixed(3)} ${units[exponent]}`;
|
|
473
|
+
setFileSize(output);
|
|
474
|
+
}
|
|
475
|
+
readFile(file);
|
|
476
|
+
}
|
|
477
|
+
let initialized = false;
|
|
478
|
+
let fileInput = (inputRef) => {
|
|
479
|
+
if (initialized)
|
|
480
|
+
return;
|
|
481
|
+
inputRef.addEventListener("dragover", function(e) {
|
|
482
|
+
e.stopPropagation();
|
|
483
|
+
e.preventDefault();
|
|
484
|
+
if (e.dataTransfer.files) {
|
|
485
|
+
let draggedFiles = e.dataTransfer.files;
|
|
486
|
+
if (draggedFiles.length > 1) {
|
|
487
|
+
setUploadBoxWarning("Only one file can be uploaded at a time");
|
|
488
|
+
} else if (fileExtension != void 0 && draggedFiles.length != 0 && getExtension(draggedFiles[0].name) != fileExtension) {
|
|
489
|
+
setUploadBoxWarning(`Only accepting files with extension ${fileExtension}`);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
e.dataTransfer.dropEffect = "copy";
|
|
493
|
+
});
|
|
494
|
+
inputRef.addEventListener("drop", function(e) {
|
|
495
|
+
e.stopPropagation();
|
|
496
|
+
e.preventDefault();
|
|
497
|
+
setUploadBoxWarning(void 0);
|
|
498
|
+
let files = e.dataTransfer.files;
|
|
499
|
+
if (files.length > 1) {
|
|
500
|
+
setInfoOpen(true);
|
|
501
|
+
setInfoStyle("warning");
|
|
502
|
+
setWarningText("Only one file can be uploaded at a time");
|
|
503
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
504
|
+
return;
|
|
505
|
+
} else if (fileExtension != void 0 && `.${getExtension(files[0].name)}` != fileExtension) {
|
|
506
|
+
setInfoOpen(true);
|
|
507
|
+
setInfoStyle("warning");
|
|
508
|
+
setWarningText(`Only accepting files with extension ${fileExtension}`);
|
|
509
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
loadFiles(files);
|
|
513
|
+
});
|
|
514
|
+
inputRef.addEventListener("dragleave", () => {
|
|
515
|
+
setUploadBoxWarning(void 0);
|
|
516
|
+
});
|
|
517
|
+
initialized = true;
|
|
518
|
+
};
|
|
519
|
+
const fileInputClick = (e) => {
|
|
520
|
+
const fileElem = document.getElementById("file-window");
|
|
521
|
+
e.preventDefault();
|
|
522
|
+
if (fileElem) {
|
|
523
|
+
fileElem.click();
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
const loadSelectedFiles = (e) => {
|
|
527
|
+
e.preventDefault();
|
|
528
|
+
const fileElem = document.getElementById("file-window");
|
|
529
|
+
loadFiles(fileElem.files);
|
|
530
|
+
};
|
|
531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_Dialog.default, { open, onClose: handleClose, children: [
|
|
532
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_DialogTitle.default, { children: "File Upload" }),
|
|
533
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_DialogContent.default, { children: [
|
|
534
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_DialogContentText.default, {}),
|
|
535
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_DialogContent.default, { dividers: true, children: [
|
|
536
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
537
|
+
import_Box.default,
|
|
538
|
+
{
|
|
539
|
+
width: 500,
|
|
540
|
+
height: 250,
|
|
541
|
+
style: {
|
|
542
|
+
borderStyle: "dashed",
|
|
543
|
+
borderRadius: "5pt",
|
|
544
|
+
borderColor: uploadBoxWarning == void 0 ? "lightGray" : "#BA3C3C"
|
|
545
|
+
},
|
|
546
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_Typography.default, { component: "div", style: { height: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
547
|
+
import_Box.default,
|
|
548
|
+
{
|
|
549
|
+
style: {
|
|
550
|
+
display: "flex",
|
|
551
|
+
flexDirection: "column",
|
|
552
|
+
justifyContent: "center",
|
|
553
|
+
alignItems: "center",
|
|
554
|
+
height: "100%"
|
|
555
|
+
},
|
|
556
|
+
onClick: fileInputClick,
|
|
557
|
+
ref: fileInput,
|
|
558
|
+
children: [
|
|
559
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_Typography.default, { variant: "body1", align: "center", style: { marginTop: "auto" }, children: [
|
|
560
|
+
"Drag & Drop or Click to Upload Your File Here ",
|
|
561
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("sup", { children: "*" })
|
|
562
|
+
] }),
|
|
563
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_Typography.default, { 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." })
|
|
564
|
+
]
|
|
565
|
+
}
|
|
566
|
+
) })
|
|
567
|
+
}
|
|
568
|
+
),
|
|
569
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
570
|
+
"input",
|
|
571
|
+
{
|
|
572
|
+
type: "file",
|
|
573
|
+
id: "file-window",
|
|
574
|
+
multiple: true,
|
|
575
|
+
accept: fileExtension == void 0 ? "*" : fileExtension,
|
|
576
|
+
style: { display: "none" },
|
|
577
|
+
onChange: loadSelectedFiles
|
|
578
|
+
}
|
|
579
|
+
),
|
|
580
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_Box.default, { component: "form", sx: { "& .MuiTextField-root": { m: 2, width: "25ch", mb: 0 } }, children: [
|
|
581
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
582
|
+
template.showFileName && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
583
|
+
import_TextField.default,
|
|
584
|
+
{
|
|
585
|
+
required: true,
|
|
586
|
+
style: { marginTop: "30px" },
|
|
587
|
+
label: `File Alias:`,
|
|
588
|
+
value: fileAlias,
|
|
589
|
+
variant: "standard",
|
|
590
|
+
onChange: changeFileName
|
|
591
|
+
}
|
|
592
|
+
),
|
|
593
|
+
fileOriginalName != "" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Label_default, { style: { marginLeft: "16px", fontSize: "9pt", color: "#267833" }, children: fileOriginalName }),
|
|
594
|
+
template.showDatabase && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
595
|
+
import_TextField.default,
|
|
596
|
+
{
|
|
597
|
+
select: true,
|
|
598
|
+
label: "Database:",
|
|
599
|
+
defaultValue: "s3",
|
|
600
|
+
helperText: "Upstream Storage Location",
|
|
601
|
+
variant: "standard",
|
|
602
|
+
children: [{ value: "s3", label: "S3" }].map((option) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material6.MenuItem, { value: option.value, children: option.label }, option.value))
|
|
603
|
+
}
|
|
604
|
+
)
|
|
605
|
+
] }),
|
|
606
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
607
|
+
template.showFileSize && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
608
|
+
import_TextField.default,
|
|
609
|
+
{
|
|
610
|
+
label: "File Size:",
|
|
611
|
+
value: fileSize,
|
|
612
|
+
InputProps: {
|
|
613
|
+
readOnly: true
|
|
614
|
+
},
|
|
615
|
+
variant: "standard"
|
|
616
|
+
}
|
|
617
|
+
),
|
|
618
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material6.Collapse, { in: infoOpen, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material6.Alert, { severity: infoStyle, sx: { m: 1 }, children: warningText }) })
|
|
619
|
+
] })
|
|
620
|
+
] })
|
|
621
|
+
] }),
|
|
622
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_DialogActions.default, { children: [
|
|
623
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
624
|
+
import_Button.default,
|
|
625
|
+
{
|
|
626
|
+
color: "inherit",
|
|
627
|
+
sx: { color: "#333" },
|
|
628
|
+
disabled: UpBtnDisabled,
|
|
629
|
+
onClick: handleClose,
|
|
630
|
+
children: "Cancel"
|
|
631
|
+
}
|
|
632
|
+
),
|
|
633
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
634
|
+
import_Button.default,
|
|
635
|
+
{
|
|
636
|
+
variant: "contained",
|
|
637
|
+
disabled: UpBtnDisabled,
|
|
638
|
+
onClick: handleConfirm,
|
|
639
|
+
children: UpBtnText
|
|
640
|
+
}
|
|
641
|
+
)
|
|
642
|
+
] })
|
|
643
|
+
] })
|
|
644
|
+
] }) });
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// src/CmrComponents/upload/Upload.tsx
|
|
648
|
+
var import_axios = __toESM(require("axios"));
|
|
649
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
650
|
+
var CmrUpload = (props) => {
|
|
651
|
+
let [open, setOpen] = (0, import_react4.useState)(false);
|
|
652
|
+
let [uploading, setUploading] = (0, import_react4.useState)(false);
|
|
653
|
+
let [progress, setProgress] = (0, import_react4.useState)(0);
|
|
654
|
+
let [uploadedFile, setUploadedFile] = (0, import_react4.useState)(void 0);
|
|
655
|
+
const upload = async (file, fileAlias, fileDatabase) => {
|
|
656
|
+
setUploading(true);
|
|
657
|
+
const onProgress = (progress2) => {
|
|
658
|
+
let percentage = progress2 * 99;
|
|
659
|
+
props.uploadProgressed && props.uploadProgressed(+percentage.toFixed(2));
|
|
660
|
+
setProgress(+percentage.toFixed(2));
|
|
661
|
+
};
|
|
662
|
+
if (props.uploadStarted)
|
|
663
|
+
props.uploadStarted();
|
|
664
|
+
let status = 0;
|
|
665
|
+
if (props.beforeUpload != void 0 && !await props.beforeUpload(file)) {
|
|
666
|
+
if (props.uploadEnded)
|
|
667
|
+
props.uploadEnded();
|
|
668
|
+
setUploading(false);
|
|
669
|
+
return 200;
|
|
670
|
+
}
|
|
671
|
+
if (props.preprocess) {
|
|
672
|
+
let processed = await props.preprocess(file);
|
|
673
|
+
if (processed == void 0)
|
|
674
|
+
return failUpload();
|
|
675
|
+
if (typeof processed == "number") {
|
|
676
|
+
setUploading(false);
|
|
677
|
+
return processed;
|
|
678
|
+
}
|
|
679
|
+
file = processed;
|
|
680
|
+
}
|
|
681
|
+
if (props.uploadHandler != void 0) {
|
|
682
|
+
status = await props.uploadHandler(file, fileAlias, fileDatabase, onProgress, props.onUploaded);
|
|
683
|
+
setUploadedFile(props.reusable ? void 0 : file.name);
|
|
684
|
+
} else if (props.createPayload) {
|
|
685
|
+
let payload = await props.createPayload(file, fileAlias, fileDatabase);
|
|
686
|
+
if (payload == void 0) {
|
|
687
|
+
return failUpload();
|
|
688
|
+
}
|
|
689
|
+
payload.config.onUploadProgress = (progressEvent) => {
|
|
690
|
+
if (progressEvent.total == void 0)
|
|
691
|
+
return;
|
|
692
|
+
onProgress(progressEvent.loaded / progressEvent.total);
|
|
693
|
+
};
|
|
694
|
+
const res = await import_axios.default.post(payload.destination, payload.lambdaFile, payload.config);
|
|
695
|
+
status = res.status;
|
|
696
|
+
if (status === 200) {
|
|
697
|
+
console.log(res.data);
|
|
698
|
+
await import_axios.default.put(res.data.upload_url, payload.file, {
|
|
699
|
+
headers: {
|
|
700
|
+
"Content-Type": payload.file.type
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
await props.onUploaded(res, payload.file);
|
|
704
|
+
setUploadedFile(props.reusable ? void 0 : payload.file.name);
|
|
705
|
+
}
|
|
706
|
+
} else {
|
|
707
|
+
return failUpload();
|
|
708
|
+
}
|
|
709
|
+
if (props.uploadEnded)
|
|
710
|
+
props.uploadEnded();
|
|
711
|
+
setUploading(false);
|
|
712
|
+
setProgress(0);
|
|
713
|
+
return status;
|
|
714
|
+
};
|
|
715
|
+
function failUpload() {
|
|
716
|
+
setUploading(false);
|
|
717
|
+
setProgress(0);
|
|
718
|
+
if (props.uploadFailed)
|
|
719
|
+
return props.uploadFailed();
|
|
720
|
+
return 0;
|
|
721
|
+
}
|
|
722
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react4.default.Fragment, { children: [
|
|
723
|
+
!uploading ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
724
|
+
import_material7.Button,
|
|
725
|
+
{
|
|
726
|
+
fullWidth: props.fullWidth,
|
|
727
|
+
style: props.style,
|
|
728
|
+
variant: uploadedFile == void 0 ? "contained" : "outlined",
|
|
729
|
+
onClick: () => {
|
|
730
|
+
setOpen(true);
|
|
731
|
+
},
|
|
732
|
+
color: props.color || "primary",
|
|
733
|
+
sx: props.sx,
|
|
734
|
+
children: [
|
|
735
|
+
props.changeNameAfterUpload ? uploadedFile === void 0 ? props.uploadButtonName ? props.uploadButtonName : "Upload" : uploadedFile : props.uploadButtonName ? props.uploadButtonName : "Upload",
|
|
736
|
+
" "
|
|
737
|
+
]
|
|
738
|
+
}
|
|
739
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_material7.Button, { fullWidth: props.fullWidth, style: props.style, variant: "contained", sx: { overflowWrap: "inherit" }, color: "primary", disabled: true, children: [
|
|
740
|
+
"Uploading ",
|
|
741
|
+
progress,
|
|
742
|
+
"%"
|
|
743
|
+
] }),
|
|
744
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
745
|
+
UploadWindow,
|
|
746
|
+
{
|
|
747
|
+
open,
|
|
748
|
+
setOpen,
|
|
749
|
+
upload,
|
|
750
|
+
fileExtension: props.fileExtension,
|
|
751
|
+
template: { showFileName: true, showFileSize: true }
|
|
752
|
+
}
|
|
753
|
+
)
|
|
754
|
+
] });
|
|
755
|
+
};
|
|
756
|
+
CmrUpload.defaultProps = {
|
|
757
|
+
changeNameAfterUpload: true
|
|
758
|
+
};
|
|
759
|
+
var Upload_default = CmrUpload;
|
|
760
|
+
|
|
293
761
|
// src/CmrTable/CmrTable.tsx
|
|
294
762
|
var import_x_data_grid = require("@mui/x-data-grid");
|
|
295
|
-
var
|
|
763
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
296
764
|
var CmrTable = (props) => {
|
|
297
765
|
const {
|
|
298
766
|
dataSource,
|
|
@@ -304,7 +772,7 @@ var CmrTable = (props) => {
|
|
|
304
772
|
showCheckbox = true,
|
|
305
773
|
...rest
|
|
306
774
|
} = props;
|
|
307
|
-
return /* @__PURE__ */ (0,
|
|
775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: style ?? { height: "400px", width: "100%" }, className: className ?? "", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
308
776
|
import_x_data_grid.DataGrid,
|
|
309
777
|
{
|
|
310
778
|
rows: dataSource ? dataSource.map((row) => ({
|
|
@@ -330,6 +798,7 @@ var CmrTable_default = CmrTable;
|
|
|
330
798
|
var CmrTable2 = CmrTable_default;
|
|
331
799
|
// Annotate the CommonJS export names for ESM import in node:
|
|
332
800
|
0 && (module.exports = {
|
|
801
|
+
CMRUpload,
|
|
333
802
|
CmrButton,
|
|
334
803
|
CmrCheckbox,
|
|
335
804
|
CmrCollapse,
|
package/dist/index.mjs
CHANGED
|
@@ -253,9 +253,476 @@ var CmrPanel = function(props) {
|
|
|
253
253
|
};
|
|
254
254
|
var Panel_default = CmrPanel;
|
|
255
255
|
|
|
256
|
+
// src/CmrComponents/upload/Upload.tsx
|
|
257
|
+
import React5, { useState as useState4 } from "react";
|
|
258
|
+
import { Button as Button3 } from "@mui/material";
|
|
259
|
+
|
|
260
|
+
// src/CmrComponents/upload/UploadWindow.tsx
|
|
261
|
+
import * as React4 from "react";
|
|
262
|
+
import Button2 from "@mui/material/Button";
|
|
263
|
+
import TextField from "@mui/material/TextField";
|
|
264
|
+
import Dialog from "@mui/material/Dialog";
|
|
265
|
+
import DialogActions from "@mui/material/DialogActions";
|
|
266
|
+
import DialogContent from "@mui/material/DialogContent";
|
|
267
|
+
import DialogContentText from "@mui/material/DialogContentText";
|
|
268
|
+
import DialogTitle from "@mui/material/DialogTitle";
|
|
269
|
+
import Typography from "@mui/material/Typography";
|
|
270
|
+
import Box from "@mui/material/Box";
|
|
271
|
+
import { Alert, Collapse, MenuItem as MenuItem2 } from "@mui/material";
|
|
272
|
+
|
|
273
|
+
// src/CmrComponents/label/Label.tsx
|
|
274
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
275
|
+
var CmrLabel = (props) => {
|
|
276
|
+
const { children, required = false } = props;
|
|
277
|
+
return /* @__PURE__ */ jsxs4("label", { className: "cmr-label", style: { fontSize: "16px", ...props.style }, children: [
|
|
278
|
+
children,
|
|
279
|
+
required && /* @__PURE__ */ jsx8("span", { className: "asterik", children: "*" })
|
|
280
|
+
] });
|
|
281
|
+
};
|
|
282
|
+
var Label_default = CmrLabel;
|
|
283
|
+
|
|
284
|
+
// src/CmrComponents/upload/UploadWindow.tsx
|
|
285
|
+
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
286
|
+
function UploadWindow({
|
|
287
|
+
upload,
|
|
288
|
+
open,
|
|
289
|
+
setOpen,
|
|
290
|
+
fileExtension,
|
|
291
|
+
template = { showFileName: true, showDatabase: true, showFileSize: true }
|
|
292
|
+
// default values
|
|
293
|
+
}) {
|
|
294
|
+
const [fileOriginalName, setFileOriginalName] = React4.useState("");
|
|
295
|
+
const [fileAlias, setFileAlias] = React4.useState("/");
|
|
296
|
+
const [fileSize, setFileSize] = React4.useState("0 MB");
|
|
297
|
+
const [warningText, setWarningText] = React4.useState("Unknown Status");
|
|
298
|
+
const [infoOpen, setInfoOpen] = React4.useState(false);
|
|
299
|
+
const [locationSelection, setLocationSelection] = React4.useState("s3");
|
|
300
|
+
const [infoStyle, setInfoStyle] = React4.useState("info");
|
|
301
|
+
const [uploadedFiles, setUploaded] = React4.useState([]);
|
|
302
|
+
const [UpBtnDisabled, setUpBtnDisabled] = React4.useState(false);
|
|
303
|
+
const [UpBtnText, setUpBtnText] = React4.useState("Upload");
|
|
304
|
+
const [uploadBoxWarning, setUploadBoxWarning] = React4.useState(void 0);
|
|
305
|
+
const handleClickOpen = () => {
|
|
306
|
+
setOpen(true);
|
|
307
|
+
};
|
|
308
|
+
const handleClose = () => {
|
|
309
|
+
setOpen(false);
|
|
310
|
+
};
|
|
311
|
+
const getExtension = (fileName) => {
|
|
312
|
+
if (fileName == void 0)
|
|
313
|
+
return;
|
|
314
|
+
return fileName.split(".").pop();
|
|
315
|
+
};
|
|
316
|
+
const handleConfirm = () => {
|
|
317
|
+
if (uploadedFiles.length === 0) {
|
|
318
|
+
setInfoOpen(true);
|
|
319
|
+
setInfoStyle("error");
|
|
320
|
+
setWarningText("Must select files to upload!");
|
|
321
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (fileAlias.length === 0) {
|
|
325
|
+
setInfoOpen(true);
|
|
326
|
+
setInfoStyle("error");
|
|
327
|
+
setWarningText("File name can't be empty");
|
|
328
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
setOpen(false);
|
|
332
|
+
upload(uploadedFiles[0], fileAlias, locationSelection).then((response) => {
|
|
333
|
+
console.log(response);
|
|
334
|
+
if (response > 0) {
|
|
335
|
+
setInfoOpen(true);
|
|
336
|
+
if (response === 200) {
|
|
337
|
+
setInfoStyle("success");
|
|
338
|
+
setWarningText("Upload successful");
|
|
339
|
+
setTimeout(() => {
|
|
340
|
+
setInfoOpen(false);
|
|
341
|
+
setOpen(false);
|
|
342
|
+
}, 1e3);
|
|
343
|
+
setUpBtnDisabled(false);
|
|
344
|
+
setUpBtnText("Upload");
|
|
345
|
+
} else if (response === 413) {
|
|
346
|
+
setInfoStyle("error");
|
|
347
|
+
setWarningText("File size limit exceeded");
|
|
348
|
+
setTimeout(() => {
|
|
349
|
+
setInfoOpen(false);
|
|
350
|
+
setUpBtnDisabled(false);
|
|
351
|
+
setUpBtnText("Upload");
|
|
352
|
+
}, 2e3);
|
|
353
|
+
} else if (response === 500) {
|
|
354
|
+
setInfoStyle("error");
|
|
355
|
+
setWarningText("Internal server error");
|
|
356
|
+
setTimeout(() => {
|
|
357
|
+
setInfoOpen(false);
|
|
358
|
+
setUpBtnDisabled(false);
|
|
359
|
+
setUpBtnText("Upload");
|
|
360
|
+
}, 1500);
|
|
361
|
+
setOpen(true);
|
|
362
|
+
} else if (response === 400) {
|
|
363
|
+
setInfoStyle("warning");
|
|
364
|
+
setWarningText("File upload cancelled");
|
|
365
|
+
setTimeout(() => {
|
|
366
|
+
setInfoOpen(false);
|
|
367
|
+
setUpBtnDisabled(false);
|
|
368
|
+
setUpBtnText("Upload");
|
|
369
|
+
}, 1e3);
|
|
370
|
+
setOpen(true);
|
|
371
|
+
} else {
|
|
372
|
+
setInfoStyle("warning");
|
|
373
|
+
setWarningText("Unknown status");
|
|
374
|
+
setTimeout(() => {
|
|
375
|
+
setInfoOpen(false);
|
|
376
|
+
setUpBtnDisabled(false);
|
|
377
|
+
setUpBtnText("Upload");
|
|
378
|
+
}, 2e3);
|
|
379
|
+
setOpen(true);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}).catch((error) => {
|
|
383
|
+
setUpBtnDisabled(false);
|
|
384
|
+
setUpBtnText("Upload");
|
|
385
|
+
setInfoOpen(true);
|
|
386
|
+
setInfoStyle("error");
|
|
387
|
+
setWarningText("Upload unsuccessful: " + error.message);
|
|
388
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
389
|
+
console.error("Error:", error);
|
|
390
|
+
});
|
|
391
|
+
setUpBtnDisabled(true);
|
|
392
|
+
setUpBtnText("Uploading");
|
|
393
|
+
};
|
|
394
|
+
const changeFileName = (e) => {
|
|
395
|
+
setFileAlias(e.target.value);
|
|
396
|
+
};
|
|
397
|
+
function loadFiles(files) {
|
|
398
|
+
if (files.length == 0) {
|
|
399
|
+
setInfoOpen(true);
|
|
400
|
+
setInfoStyle("warning");
|
|
401
|
+
setWarningText("No file selected");
|
|
402
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
if (files.length > 1) {
|
|
406
|
+
setInfoOpen(true);
|
|
407
|
+
setInfoStyle("warning");
|
|
408
|
+
setWarningText("Only accepts one file at a time");
|
|
409
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
let file = files[0];
|
|
413
|
+
setUploaded([file]);
|
|
414
|
+
function readFile(file2) {
|
|
415
|
+
setFileOriginalName(file2.name);
|
|
416
|
+
setFileAlias(file2.name);
|
|
417
|
+
const units = [
|
|
418
|
+
"B",
|
|
419
|
+
"KB",
|
|
420
|
+
"MB",
|
|
421
|
+
"GB",
|
|
422
|
+
"TB",
|
|
423
|
+
"PB",
|
|
424
|
+
"EB",
|
|
425
|
+
"ZB",
|
|
426
|
+
"YB"
|
|
427
|
+
];
|
|
428
|
+
let numberOfBytes = file2.size;
|
|
429
|
+
const exponent = Math.min(
|
|
430
|
+
Math.floor(Math.log(numberOfBytes) / Math.log(1024)),
|
|
431
|
+
units.length - 1
|
|
432
|
+
);
|
|
433
|
+
const approx = numberOfBytes / 1024 ** exponent;
|
|
434
|
+
const output = exponent === 0 ? `${numberOfBytes} bytes` : `${approx.toFixed(3)} ${units[exponent]}`;
|
|
435
|
+
setFileSize(output);
|
|
436
|
+
}
|
|
437
|
+
readFile(file);
|
|
438
|
+
}
|
|
439
|
+
let initialized = false;
|
|
440
|
+
let fileInput = (inputRef) => {
|
|
441
|
+
if (initialized)
|
|
442
|
+
return;
|
|
443
|
+
inputRef.addEventListener("dragover", function(e) {
|
|
444
|
+
e.stopPropagation();
|
|
445
|
+
e.preventDefault();
|
|
446
|
+
if (e.dataTransfer.files) {
|
|
447
|
+
let draggedFiles = e.dataTransfer.files;
|
|
448
|
+
if (draggedFiles.length > 1) {
|
|
449
|
+
setUploadBoxWarning("Only one file can be uploaded at a time");
|
|
450
|
+
} else if (fileExtension != void 0 && draggedFiles.length != 0 && getExtension(draggedFiles[0].name) != fileExtension) {
|
|
451
|
+
setUploadBoxWarning(`Only accepting files with extension ${fileExtension}`);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
e.dataTransfer.dropEffect = "copy";
|
|
455
|
+
});
|
|
456
|
+
inputRef.addEventListener("drop", function(e) {
|
|
457
|
+
e.stopPropagation();
|
|
458
|
+
e.preventDefault();
|
|
459
|
+
setUploadBoxWarning(void 0);
|
|
460
|
+
let files = e.dataTransfer.files;
|
|
461
|
+
if (files.length > 1) {
|
|
462
|
+
setInfoOpen(true);
|
|
463
|
+
setInfoStyle("warning");
|
|
464
|
+
setWarningText("Only one file can be uploaded at a time");
|
|
465
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
466
|
+
return;
|
|
467
|
+
} else if (fileExtension != void 0 && `.${getExtension(files[0].name)}` != fileExtension) {
|
|
468
|
+
setInfoOpen(true);
|
|
469
|
+
setInfoStyle("warning");
|
|
470
|
+
setWarningText(`Only accepting files with extension ${fileExtension}`);
|
|
471
|
+
setTimeout(() => setInfoOpen(false), 2500);
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
loadFiles(files);
|
|
475
|
+
});
|
|
476
|
+
inputRef.addEventListener("dragleave", () => {
|
|
477
|
+
setUploadBoxWarning(void 0);
|
|
478
|
+
});
|
|
479
|
+
initialized = true;
|
|
480
|
+
};
|
|
481
|
+
const fileInputClick = (e) => {
|
|
482
|
+
const fileElem = document.getElementById("file-window");
|
|
483
|
+
e.preventDefault();
|
|
484
|
+
if (fileElem) {
|
|
485
|
+
fileElem.click();
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
const loadSelectedFiles = (e) => {
|
|
489
|
+
e.preventDefault();
|
|
490
|
+
const fileElem = document.getElementById("file-window");
|
|
491
|
+
loadFiles(fileElem.files);
|
|
492
|
+
};
|
|
493
|
+
return /* @__PURE__ */ jsx9("div", { children: /* @__PURE__ */ jsxs5(Dialog, { open, onClose: handleClose, children: [
|
|
494
|
+
/* @__PURE__ */ jsx9(DialogTitle, { children: "File Upload" }),
|
|
495
|
+
/* @__PURE__ */ jsxs5(DialogContent, { children: [
|
|
496
|
+
/* @__PURE__ */ jsx9(DialogContentText, {}),
|
|
497
|
+
/* @__PURE__ */ jsxs5(DialogContent, { dividers: true, children: [
|
|
498
|
+
/* @__PURE__ */ jsx9(
|
|
499
|
+
Box,
|
|
500
|
+
{
|
|
501
|
+
width: 500,
|
|
502
|
+
height: 250,
|
|
503
|
+
style: {
|
|
504
|
+
borderStyle: "dashed",
|
|
505
|
+
borderRadius: "5pt",
|
|
506
|
+
borderColor: uploadBoxWarning == void 0 ? "lightGray" : "#BA3C3C"
|
|
507
|
+
},
|
|
508
|
+
children: /* @__PURE__ */ jsx9(Typography, { component: "div", style: { height: "100%" }, children: /* @__PURE__ */ jsxs5(
|
|
509
|
+
Box,
|
|
510
|
+
{
|
|
511
|
+
style: {
|
|
512
|
+
display: "flex",
|
|
513
|
+
flexDirection: "column",
|
|
514
|
+
justifyContent: "center",
|
|
515
|
+
alignItems: "center",
|
|
516
|
+
height: "100%"
|
|
517
|
+
},
|
|
518
|
+
onClick: fileInputClick,
|
|
519
|
+
ref: fileInput,
|
|
520
|
+
children: [
|
|
521
|
+
/* @__PURE__ */ jsxs5(Typography, { variant: "body1", align: "center", style: { marginTop: "auto" }, children: [
|
|
522
|
+
"Drag & Drop or Click to Upload Your File Here ",
|
|
523
|
+
/* @__PURE__ */ jsx9("sup", { children: "*" })
|
|
524
|
+
] }),
|
|
525
|
+
/* @__PURE__ */ jsx9(Typography, { 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." })
|
|
526
|
+
]
|
|
527
|
+
}
|
|
528
|
+
) })
|
|
529
|
+
}
|
|
530
|
+
),
|
|
531
|
+
/* @__PURE__ */ jsx9(
|
|
532
|
+
"input",
|
|
533
|
+
{
|
|
534
|
+
type: "file",
|
|
535
|
+
id: "file-window",
|
|
536
|
+
multiple: true,
|
|
537
|
+
accept: fileExtension == void 0 ? "*" : fileExtension,
|
|
538
|
+
style: { display: "none" },
|
|
539
|
+
onChange: loadSelectedFiles
|
|
540
|
+
}
|
|
541
|
+
),
|
|
542
|
+
/* @__PURE__ */ jsxs5(Box, { component: "form", sx: { "& .MuiTextField-root": { m: 2, width: "25ch", mb: 0 } }, children: [
|
|
543
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
544
|
+
template.showFileName && /* @__PURE__ */ jsx9(
|
|
545
|
+
TextField,
|
|
546
|
+
{
|
|
547
|
+
required: true,
|
|
548
|
+
style: { marginTop: "30px" },
|
|
549
|
+
label: `File Alias:`,
|
|
550
|
+
value: fileAlias,
|
|
551
|
+
variant: "standard",
|
|
552
|
+
onChange: changeFileName
|
|
553
|
+
}
|
|
554
|
+
),
|
|
555
|
+
fileOriginalName != "" && /* @__PURE__ */ jsx9(Label_default, { style: { marginLeft: "16px", fontSize: "9pt", color: "#267833" }, children: fileOriginalName }),
|
|
556
|
+
template.showDatabase && /* @__PURE__ */ jsx9(
|
|
557
|
+
TextField,
|
|
558
|
+
{
|
|
559
|
+
select: true,
|
|
560
|
+
label: "Database:",
|
|
561
|
+
defaultValue: "s3",
|
|
562
|
+
helperText: "Upstream Storage Location",
|
|
563
|
+
variant: "standard",
|
|
564
|
+
children: [{ value: "s3", label: "S3" }].map((option) => /* @__PURE__ */ jsx9(MenuItem2, { value: option.value, children: option.label }, option.value))
|
|
565
|
+
}
|
|
566
|
+
)
|
|
567
|
+
] }),
|
|
568
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
569
|
+
template.showFileSize && /* @__PURE__ */ jsx9(
|
|
570
|
+
TextField,
|
|
571
|
+
{
|
|
572
|
+
label: "File Size:",
|
|
573
|
+
value: fileSize,
|
|
574
|
+
InputProps: {
|
|
575
|
+
readOnly: true
|
|
576
|
+
},
|
|
577
|
+
variant: "standard"
|
|
578
|
+
}
|
|
579
|
+
),
|
|
580
|
+
/* @__PURE__ */ jsx9(Collapse, { in: infoOpen, children: /* @__PURE__ */ jsx9(Alert, { severity: infoStyle, sx: { m: 1 }, children: warningText }) })
|
|
581
|
+
] })
|
|
582
|
+
] })
|
|
583
|
+
] }),
|
|
584
|
+
/* @__PURE__ */ jsxs5(DialogActions, { children: [
|
|
585
|
+
/* @__PURE__ */ jsx9(
|
|
586
|
+
Button2,
|
|
587
|
+
{
|
|
588
|
+
color: "inherit",
|
|
589
|
+
sx: { color: "#333" },
|
|
590
|
+
disabled: UpBtnDisabled,
|
|
591
|
+
onClick: handleClose,
|
|
592
|
+
children: "Cancel"
|
|
593
|
+
}
|
|
594
|
+
),
|
|
595
|
+
/* @__PURE__ */ jsx9(
|
|
596
|
+
Button2,
|
|
597
|
+
{
|
|
598
|
+
variant: "contained",
|
|
599
|
+
disabled: UpBtnDisabled,
|
|
600
|
+
onClick: handleConfirm,
|
|
601
|
+
children: UpBtnText
|
|
602
|
+
}
|
|
603
|
+
)
|
|
604
|
+
] })
|
|
605
|
+
] })
|
|
606
|
+
] }) });
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// src/CmrComponents/upload/Upload.tsx
|
|
610
|
+
import axios from "axios";
|
|
611
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
612
|
+
var CmrUpload = (props) => {
|
|
613
|
+
let [open, setOpen] = useState4(false);
|
|
614
|
+
let [uploading, setUploading] = useState4(false);
|
|
615
|
+
let [progress, setProgress] = useState4(0);
|
|
616
|
+
let [uploadedFile, setUploadedFile] = useState4(void 0);
|
|
617
|
+
const upload = async (file, fileAlias, fileDatabase) => {
|
|
618
|
+
setUploading(true);
|
|
619
|
+
const onProgress = (progress2) => {
|
|
620
|
+
let percentage = progress2 * 99;
|
|
621
|
+
props.uploadProgressed && props.uploadProgressed(+percentage.toFixed(2));
|
|
622
|
+
setProgress(+percentage.toFixed(2));
|
|
623
|
+
};
|
|
624
|
+
if (props.uploadStarted)
|
|
625
|
+
props.uploadStarted();
|
|
626
|
+
let status = 0;
|
|
627
|
+
if (props.beforeUpload != void 0 && !await props.beforeUpload(file)) {
|
|
628
|
+
if (props.uploadEnded)
|
|
629
|
+
props.uploadEnded();
|
|
630
|
+
setUploading(false);
|
|
631
|
+
return 200;
|
|
632
|
+
}
|
|
633
|
+
if (props.preprocess) {
|
|
634
|
+
let processed = await props.preprocess(file);
|
|
635
|
+
if (processed == void 0)
|
|
636
|
+
return failUpload();
|
|
637
|
+
if (typeof processed == "number") {
|
|
638
|
+
setUploading(false);
|
|
639
|
+
return processed;
|
|
640
|
+
}
|
|
641
|
+
file = processed;
|
|
642
|
+
}
|
|
643
|
+
if (props.uploadHandler != void 0) {
|
|
644
|
+
status = await props.uploadHandler(file, fileAlias, fileDatabase, onProgress, props.onUploaded);
|
|
645
|
+
setUploadedFile(props.reusable ? void 0 : file.name);
|
|
646
|
+
} else if (props.createPayload) {
|
|
647
|
+
let payload = await props.createPayload(file, fileAlias, fileDatabase);
|
|
648
|
+
if (payload == void 0) {
|
|
649
|
+
return failUpload();
|
|
650
|
+
}
|
|
651
|
+
payload.config.onUploadProgress = (progressEvent) => {
|
|
652
|
+
if (progressEvent.total == void 0)
|
|
653
|
+
return;
|
|
654
|
+
onProgress(progressEvent.loaded / progressEvent.total);
|
|
655
|
+
};
|
|
656
|
+
const res = await axios.post(payload.destination, payload.lambdaFile, payload.config);
|
|
657
|
+
status = res.status;
|
|
658
|
+
if (status === 200) {
|
|
659
|
+
console.log(res.data);
|
|
660
|
+
await axios.put(res.data.upload_url, payload.file, {
|
|
661
|
+
headers: {
|
|
662
|
+
"Content-Type": payload.file.type
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
await props.onUploaded(res, payload.file);
|
|
666
|
+
setUploadedFile(props.reusable ? void 0 : payload.file.name);
|
|
667
|
+
}
|
|
668
|
+
} else {
|
|
669
|
+
return failUpload();
|
|
670
|
+
}
|
|
671
|
+
if (props.uploadEnded)
|
|
672
|
+
props.uploadEnded();
|
|
673
|
+
setUploading(false);
|
|
674
|
+
setProgress(0);
|
|
675
|
+
return status;
|
|
676
|
+
};
|
|
677
|
+
function failUpload() {
|
|
678
|
+
setUploading(false);
|
|
679
|
+
setProgress(0);
|
|
680
|
+
if (props.uploadFailed)
|
|
681
|
+
return props.uploadFailed();
|
|
682
|
+
return 0;
|
|
683
|
+
}
|
|
684
|
+
return /* @__PURE__ */ jsxs6(React5.Fragment, { children: [
|
|
685
|
+
!uploading ? /* @__PURE__ */ jsxs6(
|
|
686
|
+
Button3,
|
|
687
|
+
{
|
|
688
|
+
fullWidth: props.fullWidth,
|
|
689
|
+
style: props.style,
|
|
690
|
+
variant: uploadedFile == void 0 ? "contained" : "outlined",
|
|
691
|
+
onClick: () => {
|
|
692
|
+
setOpen(true);
|
|
693
|
+
},
|
|
694
|
+
color: props.color || "primary",
|
|
695
|
+
sx: props.sx,
|
|
696
|
+
children: [
|
|
697
|
+
props.changeNameAfterUpload ? uploadedFile === void 0 ? props.uploadButtonName ? props.uploadButtonName : "Upload" : uploadedFile : props.uploadButtonName ? props.uploadButtonName : "Upload",
|
|
698
|
+
" "
|
|
699
|
+
]
|
|
700
|
+
}
|
|
701
|
+
) : /* @__PURE__ */ jsxs6(Button3, { fullWidth: props.fullWidth, style: props.style, variant: "contained", sx: { overflowWrap: "inherit" }, color: "primary", disabled: true, children: [
|
|
702
|
+
"Uploading ",
|
|
703
|
+
progress,
|
|
704
|
+
"%"
|
|
705
|
+
] }),
|
|
706
|
+
/* @__PURE__ */ jsx10(
|
|
707
|
+
UploadWindow,
|
|
708
|
+
{
|
|
709
|
+
open,
|
|
710
|
+
setOpen,
|
|
711
|
+
upload,
|
|
712
|
+
fileExtension: props.fileExtension,
|
|
713
|
+
template: { showFileName: true, showFileSize: true }
|
|
714
|
+
}
|
|
715
|
+
)
|
|
716
|
+
] });
|
|
717
|
+
};
|
|
718
|
+
CmrUpload.defaultProps = {
|
|
719
|
+
changeNameAfterUpload: true
|
|
720
|
+
};
|
|
721
|
+
var Upload_default = CmrUpload;
|
|
722
|
+
|
|
256
723
|
// src/CmrTable/CmrTable.tsx
|
|
257
724
|
import { DataGrid } from "@mui/x-data-grid";
|
|
258
|
-
import { jsx as
|
|
725
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
259
726
|
var CmrTable = (props) => {
|
|
260
727
|
const {
|
|
261
728
|
dataSource,
|
|
@@ -267,7 +734,7 @@ var CmrTable = (props) => {
|
|
|
267
734
|
showCheckbox = true,
|
|
268
735
|
...rest
|
|
269
736
|
} = props;
|
|
270
|
-
return /* @__PURE__ */
|
|
737
|
+
return /* @__PURE__ */ jsx11("div", { style: style ?? { height: "400px", width: "100%" }, className: className ?? "", children: /* @__PURE__ */ jsx11(
|
|
271
738
|
DataGrid,
|
|
272
739
|
{
|
|
273
740
|
rows: dataSource ? dataSource.map((row) => ({
|
|
@@ -292,6 +759,7 @@ var CmrTable_default = CmrTable;
|
|
|
292
759
|
// src/index.ts
|
|
293
760
|
var CmrTable2 = CmrTable_default;
|
|
294
761
|
export {
|
|
762
|
+
Upload_default as CMRUpload,
|
|
295
763
|
CmrButton,
|
|
296
764
|
CmrCheckbox,
|
|
297
765
|
Collapse_default as CmrCollapse,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudmr-ux",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"author": "erosmontin@gmail.com",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "erosmontin/cloudmr-ux",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"@mui/material": "^5.14.2",
|
|
32
32
|
"@mui/x-data-grid": "^6.10.1",
|
|
33
33
|
"antd": "^5.22.1",
|
|
34
|
+
"axios": "^1.9.0",
|
|
34
35
|
"css-loader": "^7.1.2",
|
|
35
36
|
"sass": "^1.81.0",
|
|
36
37
|
"sass-loader": "^16.0.3",
|