cloudmr-ux 0.0.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.
Files changed (60) hide show
  1. package/README.md +30 -0
  2. package/dist/index.css +17 -0
  3. package/dist/index.js +174 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.modern.js +167 -0
  6. package/dist/index.modern.js.map +1 -0
  7. package/package.json +99 -0
  8. package/src/.eslintrc +5 -0
  9. package/src/common/components/Cmr-components/avatar/Avatar.scss +0 -0
  10. package/src/common/components/Cmr-components/avatar/Avatar.tsx +25 -0
  11. package/src/common/components/Cmr-components/button/Button.scss +0 -0
  12. package/src/common/components/Cmr-components/button/Button.tsx +14 -0
  13. package/src/common/components/Cmr-components/checkbox/Checkbox.scss +11 -0
  14. package/src/common/components/Cmr-components/checkbox/Checkbox.tsx +29 -0
  15. package/src/common/components/Cmr-components/collapse/Collapse.scss +3 -0
  16. package/src/common/components/Cmr-components/collapse/Collapse.tsx +75 -0
  17. package/src/common/components/Cmr-components/dialogue/Confirmation.tsx +48 -0
  18. package/src/common/components/Cmr-components/dialogue/DeletionDialog.tsx +61 -0
  19. package/src/common/components/Cmr-components/dialogue/EditConfirmation.tsx +72 -0
  20. package/src/common/components/Cmr-components/double-slider/DualSlider.tsx +198 -0
  21. package/src/common/components/Cmr-components/double-slider/InvertibleDualSlider.tsx +224 -0
  22. package/src/common/components/Cmr-components/dropdown/Dropdown.scss +36 -0
  23. package/src/common/components/Cmr-components/dropdown/Dropdown.tsx +83 -0
  24. package/src/common/components/Cmr-components/gui-slider/ControlledSlider.tsx +139 -0
  25. package/src/common/components/Cmr-components/gui-slider/Slider.tsx +170 -0
  26. package/src/common/components/Cmr-components/header/Header.scss +20 -0
  27. package/src/common/components/Cmr-components/header/Header.tsx +101 -0
  28. package/src/common/components/Cmr-components/input/Input.scss +0 -0
  29. package/src/common/components/Cmr-components/input/Input.tsx +39 -0
  30. package/src/common/components/Cmr-components/input-number/InputNumber.scss +0 -0
  31. package/src/common/components/Cmr-components/input-number/InputNumber.tsx +29 -0
  32. package/src/common/components/Cmr-components/label/Label.scss +13 -0
  33. package/src/common/components/Cmr-components/label/Label.tsx +20 -0
  34. package/src/common/components/Cmr-components/option/Option.scss +0 -0
  35. package/src/common/components/Cmr-components/option/Option.tsx +24 -0
  36. package/src/common/components/Cmr-components/panel/Panel.scss +0 -0
  37. package/src/common/components/Cmr-components/panel/Panel.tsx +54 -0
  38. package/src/common/components/Cmr-components/progress/Progress.scss +0 -0
  39. package/src/common/components/Cmr-components/progress/Progress.tsx +38 -0
  40. package/src/common/components/Cmr-components/radio/Radio.scss +0 -0
  41. package/src/common/components/Cmr-components/radio/Radio.tsx +23 -0
  42. package/src/common/components/Cmr-components/radio-group/RadioGroup.scss +0 -0
  43. package/src/common/components/Cmr-components/radio-group/RadioGroup.tsx +32 -0
  44. package/src/common/components/Cmr-components/rename/edit.tsx +94 -0
  45. package/src/common/components/Cmr-components/select/Select.scss +3 -0
  46. package/src/common/components/Cmr-components/select/Select.tsx +33 -0
  47. package/src/common/components/Cmr-components/select-upload/SelectUpload.scss +0 -0
  48. package/src/common/components/Cmr-components/select-upload/SelectUpload.tsx +133 -0
  49. package/src/common/components/Cmr-components/slider/Slider.scss +0 -0
  50. package/src/common/components/Cmr-components/slider/Slider.tsx +66 -0
  51. package/src/common/components/Cmr-components/spin/Spin.scss +0 -0
  52. package/src/common/components/Cmr-components/spin/Spin.tsx +31 -0
  53. package/src/common/components/Cmr-components/tooltip/Tooltip.scss +0 -0
  54. package/src/common/components/Cmr-components/tooltip/Tooltip.tsx +50 -0
  55. package/src/common/components/Cmr-components/upload/Upload.scss +5 -0
  56. package/src/common/components/Cmr-components/upload/Upload.tsx +188 -0
  57. package/src/common/components/Cmr-components/upload/UploadWindow.tsx +355 -0
  58. package/src/index.js +8 -0
  59. package/src/index.test.js +7 -0
  60. package/src/styles.module.css +9 -0
@@ -0,0 +1,101 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import './Header.scss';
3
+ import { Link, useNavigate } from 'react-router-dom';
4
+
5
+ interface MenuItem{
6
+ path: string
7
+ title: string
8
+ }
9
+
10
+ const Header = ({siteTitle, authentication,handleLogout,menuList}:{
11
+ siteTitle:string,
12
+ authentication: {email:string, accessToken: string}
13
+ menuList: MenuItem[],
14
+ handleLogout: ()=>void
15
+ }) => {
16
+ const navigate = useNavigate();
17
+ const currPath = navigate.name;
18
+ const [menuSelect, setMenuSelect] = useState(siteTitle);
19
+ const { email, accessToken } = authentication;
20
+ console.log(authentication);
21
+
22
+ useEffect(() => {
23
+ for (let item of menuList) {
24
+ console.log(item.path);
25
+ console.log(currPath);
26
+ if (item.path === currPath) setMenuSelect(item.title);
27
+ }
28
+ }, [currPath]);
29
+
30
+ const handleMenuChange = (info: MenuItem,navigate:any) => {
31
+ if (currPath === info.path) return;
32
+ navigate(info.path);
33
+ for (let item of menuList) {
34
+ if (item.path === info.path){
35
+ setMenuSelect(item.title);
36
+ }
37
+ }
38
+ return false;
39
+ };
40
+
41
+ return (
42
+ <nav className="navbar navbar-expand-md navbar-dark bg-dark shadow-sm" style={{background: '#000000'}}>
43
+ {/*add small-margin to className to align header content to the ends*/}
44
+ <div className="container-xl">
45
+ <Link to="/" className="navbar-brand">
46
+ {siteTitle}
47
+ </Link>
48
+ <button className="navbar-toggler" type="button" data-bs-toggle="collapse"
49
+ data-bs-target="#navbarToggleExternalContent" aria-controls="navbarToggleExternalContent"
50
+ aria-expanded="false" aria-label="Toggle navigation">
51
+ <span className="navbar-toggler-icon"></span>
52
+ </button>
53
+
54
+ <div className="collapse navbar-collapse" id="navbarToggleExternalContent">
55
+ {/* Left Side Of Navbar */}
56
+ <ul className="navbar-nav">
57
+ {menuList.map((menuItem)=>{
58
+ return <li className={`nav-item${(menuItem.title==menuSelect)?' active':''}`} key={menuItem.path}>
59
+ <a className='nav-link' style={{cursor:'pointer'}} onClick={(event)=>{
60
+ switch(menuItem.title) {
61
+ case 'Bug Report':
62
+ window.open('https://github.com/cloudmrhub-com/mroptimum/issues')
63
+ // window.location.href='https://github.com/cloudmrhub-com/mroptimum/issues';
64
+ return;
65
+ }
66
+ event.preventDefault();
67
+ handleMenuChange(menuItem, navigate)
68
+ }} >
69
+ {menuItem.title}
70
+ </a>
71
+ </li>;
72
+ })}
73
+ </ul>
74
+
75
+ {/**Right Side Of Navbar **/}
76
+ {authentication.accessToken!='' &&(
77
+ <ul className="navbar-nav ms-auto">
78
+ {/** Authentication Links **/}
79
+ <li className="nav-item dropdown">
80
+ <button className="nav-link dropdown-toggle" type="button"
81
+ id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
82
+ {email} <span className="caret"></span>
83
+ </button>
84
+ <ul className="dropdown-menu" aria-labelledby="dropdownMenuButton">
85
+ <li><button className="dropdown-item"
86
+ onClick={(event)=>{event.preventDefault();
87
+ handleLogout();}}>
88
+ Logout
89
+ </button></li>
90
+ </ul>
91
+ </li>
92
+ </ul>)}
93
+ </div>
94
+ </div>
95
+ </nav>
96
+ );
97
+ };
98
+
99
+ export default Header;
100
+ export type { MenuItem };
101
+
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import './Input.scss';
3
+ import { Input } from 'antd';
4
+ import { SizeType } from 'antd/lib/config-provider/SizeContext';
5
+ import { LiteralUnion } from 'antd/lib/_util/type';
6
+
7
+ interface CmrInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix' | 'type'> {
8
+ defaultValue?: string;
9
+ id?: string;
10
+ maxLength?: number;
11
+ size?: SizeType;
12
+ value?: string;
13
+ type?: any;
14
+ prefix?: React.ReactNode;
15
+ bordered?: boolean;
16
+ onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
17
+ onPressEnter?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
18
+ }
19
+
20
+ export const CmrInput = (props: CmrInputProps) => {
21
+ const { defaultValue, id, maxLength, size, value, type, prefix, bordered, onChange, onPressEnter, ...rest } = props;
22
+
23
+ return (
24
+ <Input
25
+ defaultValue={defaultValue}
26
+ id={id}
27
+ maxLength={maxLength}
28
+ size={size}
29
+ value={value}
30
+ type={type}
31
+ prefix={prefix}
32
+ bordered={bordered}
33
+ onChange={onChange}
34
+ onPressEnter={onPressEnter}
35
+ {...rest}
36
+ />
37
+ );
38
+ };
39
+
@@ -0,0 +1,29 @@
1
+ import React, {CSSProperties} from 'react';
2
+ import './InputNumber.scss';
3
+ import { InputNumber } from 'antd';
4
+ import { SizeType } from 'antd/lib/config-provider/SizeContext';
5
+
6
+ interface CmrInputNumberProps {
7
+ defaultValue?: number;
8
+ disabled?: boolean;
9
+ keyboard?: boolean;
10
+ max?: number;
11
+ min?: number;
12
+ size?: SizeType;
13
+ value?: number;
14
+ onChange?: (value: number|null) => void;
15
+ children?: React.ReactNode;
16
+ style?: CSSProperties;
17
+ }
18
+
19
+ const CmrInputNumber = (props: CmrInputNumberProps) => {
20
+ const { defaultValue, style, max, min, value, onChange, children, ...rest } = props;
21
+
22
+ return (
23
+ <InputNumber defaultValue={defaultValue} max={max} style={style} min={min} value={value} onChange={onChange} {...rest}>
24
+ {children}
25
+ </InputNumber>
26
+ );
27
+ };
28
+
29
+ export default CmrInputNumber;
@@ -0,0 +1,13 @@
1
+ .cmr-label {
2
+ display: flex;
3
+ align-items: center;
4
+ font-style: normal;
5
+ font-weight: 500;
6
+ color: #707683;
7
+ padding-right: 10px;
8
+ }
9
+
10
+ .asterik {
11
+ color: red !important;
12
+ margin-left: 4px;
13
+ }
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import './Label.scss';
3
+
4
+ interface CmrLabelProps extends React.HTMLAttributes<HTMLDivElement>{
5
+ required?: boolean;
6
+ children?: any;
7
+ }
8
+
9
+ const CmrLabel = (props: CmrLabelProps) => {
10
+ const { children, required = false } = props;
11
+
12
+ return (
13
+ <label className="cmr-label" style={{fontSize:'16px', ...props.style}}>
14
+ {children}
15
+ {required && <span className="asterik">*</span>}
16
+ </label>
17
+ );
18
+ };
19
+
20
+ export default CmrLabel;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Select } from 'antd';
3
+ import './Option.scss';
4
+
5
+ const { Option } = Select;
6
+
7
+ interface CmrOptionProps {
8
+ title?: string;
9
+ value: string | number;
10
+ disabled?: boolean;
11
+ children?: any;
12
+ }
13
+
14
+ const CmrOption = (props: CmrOptionProps) => {
15
+ const { title, value, disabled, children, ...rest } = props;
16
+
17
+ return (
18
+ <Option title={title} value={value} disabled={disabled} {...rest}>
19
+ {children}
20
+ </Option>
21
+ );
22
+ };
23
+
24
+ export default CmrOption;
@@ -0,0 +1,54 @@
1
+ import React, {ReactNode, useState} from 'react';
2
+ import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp';
3
+ import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
4
+
5
+ interface CmrPanelProps extends React.HTMLAttributes<HTMLDivElement>{
6
+ activeKey?: string|string[];
7
+ header: string|undefined;
8
+ children: ReactNode;
9
+ panelKey?: number;
10
+ onToggle?: (key: number|undefined) => void;
11
+ expanded?: boolean;
12
+ cardProps?: React.HTMLAttributes<HTMLDivElement>;
13
+ }
14
+ const CmrPanel = function(props:CmrPanelProps){
15
+ let {expanded, onToggle} = props;
16
+ const toggle = ()=>{
17
+ if(onToggle)
18
+ onToggle(props.panelKey);
19
+ };
20
+ return <div className={`card ${props.className}`}>
21
+ <div className="card-header" style={{background: "white", display:props.header==undefined?'none':undefined}}>
22
+ <div className="row align-items-center">
23
+ <div className="col">{props.header}
24
+ </div>
25
+ {onToggle&&<div className="col text-end">
26
+ <span className="react-collapse float-end btn"
27
+ onClick={(e) => {
28
+ toggle();
29
+ }}>
30
+ {(!expanded)?
31
+ <ArrowDropDownIcon/>:
32
+ <ArrowDropUpIcon/>
33
+ }
34
+ </span>
35
+ </div>}
36
+ </div>
37
+ </div>
38
+ {
39
+ (!expanded)?
40
+ <div className={`card-body m-0 ${props.cardProps?.className}`} style={
41
+ {maxHeight:'0',padding:'0', opacity:'0',overflow:'hidden',
42
+ visibility:'collapse',transition:'all 0.5s'}}>
43
+ {props.children}
44
+ </div>
45
+ :
46
+ <div className={`card-body m-5 ${props.cardProps?.className}`} style={
47
+ {maxHeight:undefined,padding:undefined, opacity:'1',
48
+ visibility:'visible',transition:'all 0.5s'}}>
49
+ {props.children}
50
+ </div>}
51
+ </div>;
52
+ }
53
+
54
+ export default CmrPanel;
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import './Progress.scss';
3
+ import { Progress } from 'antd';
4
+ import { ProgressGradient, ProgressType, SuccessProps } from 'antd/lib/progress/progress';
5
+
6
+ declare const ProgressStatuses: ['normal', 'exception', 'active', 'success'];
7
+
8
+ interface CmrProgressProps {
9
+ percent?: number;
10
+ showInfo?: boolean;
11
+ status?: typeof ProgressStatuses[number];
12
+ strokeColor?: string | ProgressGradient;
13
+ strokeLinecap?: 'butt' | 'square' | 'round';
14
+ success?: SuccessProps;
15
+ trailColor?: string;
16
+ type?: ProgressType;
17
+ }
18
+
19
+ const CmrProgress = (props: CmrProgressProps) => {
20
+ const { percent, showInfo, status, strokeColor, strokeLinecap, success, trailColor, type, ...rest } = props;
21
+
22
+ return (
23
+ <Progress
24
+ percent={percent}
25
+ showInfo={showInfo}
26
+ status={status}
27
+ strokeColor={strokeColor}
28
+ strokeLinecap={strokeLinecap}
29
+ success={success}
30
+ trailColor={trailColor}
31
+ type={type}
32
+ style={{marginBottom: '5pt'}}
33
+ {...rest}
34
+ />
35
+ );
36
+ };
37
+
38
+ export default CmrProgress;
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import './Radio.scss';
3
+ import { Radio } from 'antd';
4
+
5
+ interface CmrRadioProps {
6
+ checked?: boolean;
7
+ defaultChecked?: boolean;
8
+ disabled?: boolean;
9
+ value?: any;
10
+ children?: any;
11
+ }
12
+
13
+ const CmrRadio = (props: CmrRadioProps) => {
14
+ const { checked, defaultChecked, disabled, value, children, ...rest } = props;
15
+
16
+ return (
17
+ <Radio checked={checked} defaultChecked={defaultChecked} disabled={disabled} value={value} {...rest}>
18
+ {children}
19
+ </Radio>
20
+ );
21
+ };
22
+
23
+ export default CmrRadio;
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import './RadioGroup.scss';
3
+ import { Radio } from 'antd';
4
+ import { RadioChangeEvent } from 'antd/lib/radio/interface';
5
+
6
+ interface CmrRadioGroupProps {
7
+ defaultValue?: any;
8
+ disabled?: boolean;
9
+ name?: string;
10
+ value?: any;
11
+ onChange?: (e: RadioChangeEvent) => void;
12
+ children?: React.ReactNode;
13
+ }
14
+
15
+ const CmrRadioGroup = (props: CmrRadioGroupProps) => {
16
+ const { defaultValue, disabled, name, value, onChange, children, ...rest } = props;
17
+
18
+ return (
19
+ <Radio.Group
20
+ defaultValue={defaultValue}
21
+ disabled={disabled}
22
+ name={name}
23
+ value={value}
24
+ onChange={onChange}
25
+ {...rest}
26
+ >
27
+ {children}
28
+ </Radio.Group>
29
+ );
30
+ };
31
+
32
+ export default CmrRadioGroup;
@@ -0,0 +1,94 @@
1
+ import * as React from 'react';
2
+ import Button from '@mui/material/Button';
3
+ import TextField from '@mui/material/TextField';
4
+ import Dialog from '@mui/material/Dialog';
5
+ import DialogActions from '@mui/material/DialogActions';
6
+ import DialogContent from '@mui/material/DialogContent';
7
+ import DialogContentText from '@mui/material/DialogContentText';
8
+ import DialogTitle from '@mui/material/DialogTitle';
9
+ import CmrButton from "../button/Button";
10
+ import {useEffect} from "react";
11
+
12
+ export default function CmrNameDialog(props: {originalName: string; renamingCallback:(alias:string)=>Promise<boolean>, open:boolean, setOpen:(open:boolean)=>void}) {
13
+ let {originalName,open, setOpen} = props;
14
+ const [helperText, setHelperText] = React.useState('');
15
+ const [text, setText] = React.useState(originalName);
16
+ const [error, setError] = React.useState(false);
17
+
18
+ const renamingCallback = props.renamingCallback;
19
+
20
+ const handleClose = () => {
21
+ setOpen(false);
22
+ };
23
+
24
+ useEffect(() => {
25
+ checkError(originalName);
26
+ }, [originalName]);
27
+
28
+ const handleConfirm = async () => {
29
+ // if(!error)
30
+ if(await renamingCallback(text))
31
+ handleClose();
32
+ };
33
+
34
+ const handleTextFieldChange=(e: { target: { value: string; }; })=>{
35
+ setText( e.target.value);
36
+ checkError(e.target.value);
37
+ }
38
+ const checkError=(text: string)=>{
39
+ const fileNameRegex = /^[a-zA-Z0-9_\-]+\.[a-zA-Z]{1,5}$/;
40
+ let newExtension = text.split('.').pop();
41
+ let orgExtension = (originalName.indexOf('.')>=0)? originalName.split('.').pop(): '?';
42
+ if(!fileNameRegex.test(text)){
43
+ setError(true);
44
+ if(text.indexOf('.')<0){
45
+ setHelperText('Invalid file name, needs a valid extension.');
46
+ }else{
47
+ setHelperText('Invalid file name, please check.');
48
+ }
49
+ }else if(newExtension!==orgExtension){
50
+ setHelperText(`You are modifying your file extension from .${orgExtension} to .${newExtension}.`);
51
+ setError(false);
52
+ }else{
53
+ setError(false);
54
+ setHelperText('');
55
+ }
56
+ }
57
+
58
+ return (
59
+ <div>
60
+ <Dialog open={open} onClose={handleClose} fullWidth
61
+ maxWidth="xs">
62
+ <DialogTitle>
63
+ Renaming file {originalName} to:
64
+ </DialogTitle>
65
+ <DialogContent>
66
+ {/*<DialogContentText>*/}
67
+ {/* Renaming file {originalName} to:*/}
68
+ {/*</DialogContentText>*/}
69
+
70
+ <TextField
71
+ autoFocus
72
+ margin="dense"
73
+ id="name"
74
+ // type="file"
75
+ defaultValue = {originalName}
76
+ onFocus={event => {
77
+ event.target.select();
78
+ }}
79
+ fullWidth
80
+ inputProps={{style: {fontSize: "16pt"}}}
81
+ variant="standard"
82
+ onChange={handleTextFieldChange}
83
+ error={error}
84
+ helperText={helperText}
85
+ />
86
+ </DialogContent>
87
+ <DialogActions>
88
+ <CmrButton variant={"outlined"} color={'inherit'} sx={{color:'#333'}} onClick={handleClose}>Cancel</CmrButton>
89
+ <CmrButton variant={"contained"} color={'primary'} onClick={handleConfirm}>Confirm</CmrButton>
90
+ </DialogActions>
91
+ </Dialog>
92
+ </div>
93
+ );
94
+ }
@@ -0,0 +1,3 @@
1
+ .ant-select {
2
+ width: 120px;
3
+ }
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import './Select.scss';
3
+ import { Select } from 'antd';
4
+
5
+ interface CmrSelectProps {
6
+ id?: string;
7
+ className?: string;
8
+ value?: Array<string | number> | string | number;
9
+ defaultValue?: Array<string | number> | string | number;
10
+ disabled?: boolean;
11
+ onChange?: (value: any) => void;
12
+ children?: any;
13
+ }
14
+
15
+ const CmrSelect = (props: CmrSelectProps) => {
16
+ const { id, className, value, defaultValue, disabled, onChange, children, ...rest } = props;
17
+
18
+ return (
19
+ <Select
20
+ id={id}
21
+ className={className}
22
+ value={value}
23
+ defaultValue={defaultValue}
24
+ disabled={disabled}
25
+ onChange={onChange}
26
+ {...rest}
27
+ >
28
+ {children}
29
+ </Select>
30
+ );
31
+ };
32
+
33
+ export default CmrSelect;
@@ -0,0 +1,133 @@
1
+ import React, {Fragment, useState} from "react";
2
+ import CMRUpload, {CMRUploadProps, LambdaFile} from '../upload/Upload';
3
+ import {Alert, AlertTitle, Button, Collapse, InputLabel, MenuItem} from "@mui/material";
4
+ import Select, {SelectChangeEvent} from "@mui/material/Select";
5
+ import Dialog from "@mui/material/Dialog";
6
+ import DialogTitle from "@mui/material/DialogTitle";
7
+ import DialogContent from "@mui/material/DialogContent";
8
+ import DialogContentText from "@mui/material/DialogContentText";
9
+ import DialogActions from "@mui/material/DialogActions";
10
+ import CmrTooltip from "../tooltip/Tooltip";
11
+ import Box from "@mui/material/Box";
12
+ import {uploadData} from "../../../../features/data/dataActionCreation";
13
+ import {useAppDispatch, useAppSelector} from "../../../../features/hooks";
14
+ import {AxiosResponse} from "axios";
15
+
16
+ interface CMRSelectUploadProps extends CMRUploadProps{
17
+ /**
18
+ * A selection of currently uploaded files
19
+ */
20
+ fileSelection: UploadedFile[];
21
+ onSelected: (file?: UploadedFile)=>void;
22
+ chosenFile?: string;
23
+ buttonText?: string;
24
+ /**
25
+ * Enforces the extension of selected files
26
+ */
27
+ fileExtension?:string;
28
+ }
29
+
30
+ interface UploadedFile {
31
+ id: number;
32
+ fileName: string;
33
+ link: string;
34
+ md5?: string;
35
+ size: string;
36
+ status: string;
37
+ createdAt: string;
38
+ updatedAt: string;
39
+ database: string;
40
+ location: string;
41
+ }
42
+
43
+ /**
44
+ * Select from a set of uploaded files or upload new
45
+ */
46
+ const CMRSelectUpload = (props: CMRSelectUploadProps) => {
47
+
48
+ let [open, setOpen] = React.useState(false);
49
+ let [fileIndex, selectFileIndex] = React.useState(-1);
50
+ let [uploading, setUploading] = React.useState(false);
51
+ const [progress, setProgress] = React.useState(0);
52
+ const handleClickOpen = () => {
53
+ selectFileIndex(-1);
54
+ setOpen(true);
55
+ };
56
+
57
+ const handleClose = () => {
58
+ setOpen(false);
59
+ };
60
+
61
+ const handleChange = (event: SelectChangeEvent<number>) => {
62
+ //@ts-ignore
63
+ selectFileIndex(event.target.value);
64
+ };
65
+
66
+ const onSet = ()=>{
67
+ props.onSelected(props.fileSelection[fileIndex]);
68
+ setOpen(false);
69
+ }
70
+ const selectionDialog = <Dialog open={open} onClose={handleClose}>
71
+ <DialogTitle>Upload or select</DialogTitle>
72
+ <DialogContent sx={{width: 520}}>
73
+ <DialogContentText sx={{pl:1, pr:1, pb:0}}>
74
+ {(uploading)?"Please wait for the upload to finish.":"Upload a new file or select from previously uploaded files:"}
75
+ </DialogContentText>
76
+ <DialogContent sx={{p:1}}>
77
+ <Select
78
+ value={fileIndex}
79
+ onChange={handleChange}
80
+ disabled={uploading}
81
+ inputProps={{ 'aria-label': 'Without label' }}
82
+ sx={{width: '100%'}}
83
+ >
84
+ <MenuItem value={-1}>
85
+ <em>Select or upload a new file to proceed</em>
86
+ </MenuItem>
87
+ {((props.fileSelection!=undefined? props.fileSelection: [])).map((option,index) => (
88
+ <MenuItem key={index} value={index}>
89
+ {option.fileName}
90
+ </MenuItem>
91
+ ))}
92
+ </Select>
93
+ </DialogContent>
94
+ <Box sx={{pt:2, justifyContent:'center',display:'flex', padding:'8px'}}>
95
+ {(!uploading)&&<Button fullWidth sx={{marginRight:'8px'}} variant="contained" color="success" onClick={onSet}>
96
+ Select
97
+ </Button>}
98
+ {fileIndex==-1&& <CMRUpload {...props} color="info" fullWidth onUploaded={(res, file)=>{
99
+ console.log("calling Setup level on uploaded");
100
+ console.log(props.onUploaded);
101
+ selectFileIndex(props.fileSelection.length);
102
+ props.onUploaded(res, file);
103
+ setOpen(false);
104
+ }} fileExtension = {props.fileExtension}
105
+ uploadHandler={props.uploadHandler}
106
+ uploadStarted={()=>{
107
+ setUploading(true);
108
+ props.onSelected(undefined);
109
+ }}
110
+ uploadProgressed={(progress)=>{
111
+ setOpen(false);
112
+ setProgress(progress);
113
+ }}
114
+ uploadEnded={()=>setUploading(false)}
115
+ ></CMRUpload>}
116
+ <Button fullWidth variant="outlined" color="inherit" sx={{color:'#333', marginLeft:'8px'}} onClick={handleClose}> Cancel</Button>
117
+ </Box>
118
+ </DialogContent>
119
+ </Dialog>;
120
+ return <Fragment>
121
+ {uploading?<Button variant={"contained"} style={{...props.style, textTransform:'none'}} sx={{overflowWrap:'inherit'}} color={'primary'} disabled={uploading}>
122
+ Uploading {progress}%
123
+ </Button>:<Button variant={(props.chosenFile==undefined)?"contained":"outlined"} color="info" onClick={handleClickOpen} sx={{marginRight:'10pt'}}
124
+ style={{...props.style, textTransform:'none'}}>
125
+ {(props.chosenFile==undefined)?
126
+ (props.buttonText?props.buttonText:"Choose")
127
+ :props.chosenFile}
128
+ </Button>}
129
+ {selectionDialog}
130
+ </Fragment>;
131
+ };
132
+
133
+ export default CMRSelectUpload;