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 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 import_jsx_runtime8 = require("react/jsx-runtime");
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, import_jsx_runtime8.jsx)("div", { style: style ?? { height: "400px", width: "100%" }, className: className ?? "", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
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 jsx8 } from "react/jsx-runtime";
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__ */ jsx8("div", { style: style ?? { height: "400px", width: "100%" }, className: className ?? "", children: /* @__PURE__ */ jsx8(
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.6",
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",