cloudmr-ux 4.3.7 → 4.3.8
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/CmrComponents/niivue-contrast-adjustments/NiivueContrastAdjustments.js +4 -4
- package/dist/CmrComponents/niivue-slice-position/NiivueSlicePosition.js +2 -2
- package/dist/CmrComponents/niivue-viewer/CloudMrNiivuePanel.d.ts +38 -0
- package/dist/CmrComponents/niivue-viewer/CloudMrNiivuePanel.js +197 -0
- package/dist/CmrComponents/niivue-viewer/CloudMrNiivueViewer.d.ts +41 -0
- package/dist/CmrComponents/niivue-viewer/CloudMrNiivueViewer.js +1239 -0
- package/dist/CmrComponents/niivue-viewer/ColorPicker.d.ts +1 -0
- package/dist/CmrComponents/niivue-viewer/ColorPicker.js +65 -0
- package/dist/CmrComponents/niivue-viewer/Layer.d.ts +1 -0
- package/dist/CmrComponents/niivue-viewer/Layer.js +122 -0
- package/dist/CmrComponents/niivue-viewer/LayersPanel.d.ts +1 -0
- package/dist/CmrComponents/niivue-viewer/LayersPanel.js +107 -0
- package/dist/CmrComponents/niivue-viewer/Niivue.css +8 -0
- package/dist/CmrComponents/niivue-viewer/NiivuePatcher.d.ts +2 -0
- package/dist/CmrComponents/niivue-viewer/NiivuePatcher.js +1402 -0
- package/dist/CmrComponents/niivue-viewer/NumberPicker.d.ts +1 -0
- package/dist/CmrComponents/niivue-viewer/NumberPicker.js +40 -0
- package/dist/CmrComponents/niivue-viewer/SettingsPanel.d.ts +1 -0
- package/dist/CmrComponents/niivue-viewer/SettingsPanel.js +30 -0
- package/dist/CmrComponents/niivue-viewer/Switch.d.ts +1 -0
- package/dist/CmrComponents/niivue-viewer/Switch.js +27 -0
- package/dist/CmrComponents/niivue-viewer/Toolbar.d.ts +48 -0
- package/dist/CmrComponents/niivue-viewer/Toolbar.js +276 -0
- package/dist/CmrComponents/niivue-viewer/Toolbar.scss +40 -0
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/DrawColorPlatte.d.ts +2 -0
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/DrawColorPlatte.js +61 -0
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/EraserPlatte.d.ts +2 -0
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/EraserPlatte.js +56 -0
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/MaskPlatte.d.ts +2 -0
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/MaskPlatte.js +148 -0
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/MroDrawToolkit.d.ts +1 -0
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/MroDrawToolkit.js +177 -0
- package/dist/CmrComponents/niivue-viewer/niivuePenType.d.ts +10 -0
- package/dist/CmrComponents/niivue-viewer/niivuePenType.js +10 -0
- package/dist/core/common/components/NiivueTools/NiivuePatcher.d.ts +2 -0
- package/dist/core/common/components/NiivueTools/components/ControlThemes.d.ts +1 -0
- package/dist/core/common/components/NiivueTools/components/ControlThemes.js +123 -0
- package/dist/core/common/components/NiivueTools/components/Example.d.ts +10 -0
- package/dist/core/common/components/NiivueTools/components/Example.js +326 -0
- package/dist/core/common/components/NiivueTools/components/ImageList.d.ts +1 -0
- package/dist/core/common/components/NiivueTools/components/ImageList.js +22 -0
- package/dist/core/common/components/NiivueTools/components/ImageListItem.d.ts +1 -0
- package/dist/core/common/components/NiivueTools/components/ImageListItem.js +103 -0
- package/dist/core/common/components/NiivueTools/main.d.ts +1 -0
- package/dist/core/common/components/NiivueTools/main.js +16 -0
- package/dist/core/common/components/NiivueTools/util.d.ts +21 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function NumberPicker(props: any): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { Box } from "@mui/material";
|
|
14
|
+
import { Typography } from "@mui/material";
|
|
15
|
+
import { Input } from "@mui/material";
|
|
16
|
+
import React from "react";
|
|
17
|
+
export function NumberPicker(props) {
|
|
18
|
+
var _a = React.useState(props.value), value = _a[0], setValue = _a[1];
|
|
19
|
+
React.useEffect(function () {
|
|
20
|
+
setValue(props.value);
|
|
21
|
+
}, []);
|
|
22
|
+
function handleNumberInput(event) {
|
|
23
|
+
var v = event.target.value;
|
|
24
|
+
if (v < props.min) {
|
|
25
|
+
v = props.min;
|
|
26
|
+
}
|
|
27
|
+
if (v > props.max) {
|
|
28
|
+
v = props.max;
|
|
29
|
+
}
|
|
30
|
+
setValue(v);
|
|
31
|
+
props.onChange(v);
|
|
32
|
+
}
|
|
33
|
+
return (_jsxs(Box, __assign({ sx: {
|
|
34
|
+
display: 'flex'
|
|
35
|
+
}, m: 1 }, { children: [_jsx(Typography, __assign({ style: {
|
|
36
|
+
marginRight: 'auto'
|
|
37
|
+
} }, { children: props.title })), _jsx(Input, { disableUnderline: true, type: 'number', style: { width: '50px', height: '20px' }, onInput: handleNumberInput, value: value, inputProps: {
|
|
38
|
+
step: props.step
|
|
39
|
+
} })] })));
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function SettingsPanel(props: any): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { Drawer } from "@mui/material";
|
|
14
|
+
import { Box } from "@mui/material";
|
|
15
|
+
import { IconButton } from "@mui/material";
|
|
16
|
+
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
|
|
17
|
+
export function SettingsPanel(props) {
|
|
18
|
+
return (_jsx(Drawer, __assign({ open: props.open, variant: "temporary", anchor: "right", sx: {
|
|
19
|
+
width: props.width
|
|
20
|
+
} }, { children: _jsxs(Box, __assign({ sx: {
|
|
21
|
+
width: props.width,
|
|
22
|
+
role: 'presentation',
|
|
23
|
+
display: 'flex',
|
|
24
|
+
flexDirection: 'column',
|
|
25
|
+
justifyContent: 'flex-start'
|
|
26
|
+
} }, { children: [_jsx(Box, __assign({ sx: {
|
|
27
|
+
display: 'flex',
|
|
28
|
+
marginBottom: '10px'
|
|
29
|
+
} }, { children: _jsx(IconButton, __assign({ onClick: props.toggleMenu, style: { marginRight: 'auto' } }, { children: _jsx(ArrowForwardIcon, {}) })) })), props.children] })) })));
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function NVSwitch(props: any): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { Box } from "@mui/material";
|
|
14
|
+
import { Typography } from "@mui/material";
|
|
15
|
+
import { Switch } from "@mui/material";
|
|
16
|
+
import React from "react";
|
|
17
|
+
export default function NVSwitch(props) {
|
|
18
|
+
function handleChange() {
|
|
19
|
+
props.onChange();
|
|
20
|
+
}
|
|
21
|
+
return (_jsxs(Box, __assign({ sx: {
|
|
22
|
+
display: 'flex',
|
|
23
|
+
alignItems: 'center'
|
|
24
|
+
}, m: 1 }, { children: [_jsx(Typography, __assign({ onClick: handleChange, style: {
|
|
25
|
+
marginRight: 'auto'
|
|
26
|
+
} }, { children: props.title })), _jsx(Switch, { checked: props.checked, onChange: handleChange })] })));
|
|
27
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ROI } from "../../core/features/rois/roiTypes";
|
|
3
|
+
interface ToolbarProps {
|
|
4
|
+
nv: any;
|
|
5
|
+
nvUpdateSliceType: any;
|
|
6
|
+
sliceType: string;
|
|
7
|
+
toggleLayers: React.MouseEventHandler<HTMLButtonElement> | undefined;
|
|
8
|
+
toggleSettings: React.MouseEventHandler<HTMLButtonElement> | undefined;
|
|
9
|
+
volumes: {
|
|
10
|
+
url: string;
|
|
11
|
+
name: string;
|
|
12
|
+
alias: string;
|
|
13
|
+
}[];
|
|
14
|
+
selectedVolume: number;
|
|
15
|
+
setSelectedVolume: (index: number) => void;
|
|
16
|
+
showColorBar: boolean;
|
|
17
|
+
toggleColorBar: () => void;
|
|
18
|
+
rois: ROI[];
|
|
19
|
+
selectedROI: number;
|
|
20
|
+
setSelectedROI: (selected: number) => void;
|
|
21
|
+
refreshROI: () => void;
|
|
22
|
+
showCrosshair: boolean;
|
|
23
|
+
toggleShowCrosshair: () => void;
|
|
24
|
+
dragMode: string;
|
|
25
|
+
setDragMode: (dragMode: string) => void;
|
|
26
|
+
radiological: boolean;
|
|
27
|
+
toggleRadiological: () => void;
|
|
28
|
+
saveROI: (callback: () => void, preSaving: () => void) => void;
|
|
29
|
+
complexMode: string;
|
|
30
|
+
setComplexMode: (complexMode: string) => void;
|
|
31
|
+
complexOptions: string[];
|
|
32
|
+
labelsVisible: boolean;
|
|
33
|
+
toggleLabelsVisible: () => void;
|
|
34
|
+
saving: boolean;
|
|
35
|
+
setSaving: (saving: boolean) => void;
|
|
36
|
+
drawingChanged: boolean;
|
|
37
|
+
resampleImage?: () => void;
|
|
38
|
+
/** Bearer token for authenticated ROI delete */
|
|
39
|
+
accessToken: string | undefined;
|
|
40
|
+
/** Current pipeline id (for ROI refresh after delete/save) */
|
|
41
|
+
pipelineId: string | undefined;
|
|
42
|
+
/** Full URL for ROI DELETE API */
|
|
43
|
+
roiDeleteUrl: string;
|
|
44
|
+
/** Refetch ROI list after server mutation */
|
|
45
|
+
refreshPipelineRois: () => Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
export default function Toolbar(props: ToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
49
|
+
import { Fragment, useState } from 'react';
|
|
50
|
+
import { Box, Button, CircularProgress, Stack, Switch, Tooltip, Typography } from "@mui/material";
|
|
51
|
+
import { IconButton, FormControl, Select, MenuItem, InputLabel } from "@mui/material";
|
|
52
|
+
import SettingsIcon from '@mui/icons-material/Settings';
|
|
53
|
+
import HomeIcon from '@mui/icons-material/Home';
|
|
54
|
+
import CenterFocusStrongIcon from '@mui/icons-material/CenterFocusStrong';
|
|
55
|
+
import ZoomInMapIcon from '@mui/icons-material/ZoomInMap';
|
|
56
|
+
import ZoomInIcon from '@mui/icons-material/ZoomIn';
|
|
57
|
+
import ZoomOutIcon from '@mui/icons-material/ZoomOut';
|
|
58
|
+
import Brightness6Icon from '@mui/icons-material/Brightness6';
|
|
59
|
+
import DeleteIcon from "@mui/icons-material/Delete";
|
|
60
|
+
import CmrConfirmation from "../dialogue/Confirmation";
|
|
61
|
+
import axios from "axios";
|
|
62
|
+
export default function Toolbar(props) {
|
|
63
|
+
var _this = this;
|
|
64
|
+
var saving = props.saving, setSaving = props.setSaving;
|
|
65
|
+
function handleSliceTypeChange(e) {
|
|
66
|
+
var newSliceType = e.target.value;
|
|
67
|
+
var nvUpdateSliceType = props.nvUpdateSliceType;
|
|
68
|
+
nvUpdateSliceType(newSliceType);
|
|
69
|
+
}
|
|
70
|
+
// let dragModes = ["Pan","Measurement","Contrast",'None'];
|
|
71
|
+
var dragModes = [
|
|
72
|
+
{ value: "pan", label: "Zoom and Pan" },
|
|
73
|
+
{ value: "measurement", label: "Slice and Measurement" },
|
|
74
|
+
{ value: "contrast", label: "Slice and Contrast" },
|
|
75
|
+
{ value: "none", label: "Slice and None" }
|
|
76
|
+
];
|
|
77
|
+
var _a = useState(false), roiDeleteOpen = _a[0], setRoiDeleteOpen = _a[1];
|
|
78
|
+
var _b = useState(undefined), roiDeleteMsg = _b[0], setRoiDeleteMsg = _b[1];
|
|
79
|
+
var _c = useState(function () { return function () { }; }), roiDeleteConfirm = _c[0], setRoiDeleteConfirm = _c[1];
|
|
80
|
+
// const deleteROI= createAsyncThunk('DeleteROI', async (arg: { accessToken: string, jobId: string }) => {
|
|
81
|
+
// // const data = { jobId: arg.jobId }; // No need to stringify, axios will handle it
|
|
82
|
+
// const config = {
|
|
83
|
+
// headers: {
|
|
84
|
+
// 'Content-Type': 'application/json',
|
|
85
|
+
// 'Authorization': `Bearer ${arg.accessToken}`
|
|
86
|
+
// },
|
|
87
|
+
// params: {
|
|
88
|
+
// id: arg.jobId // Send jobId as a query parameter
|
|
89
|
+
// }
|
|
90
|
+
// };
|
|
91
|
+
// const response = await axios.delete(`${JOBS_DELETE_API}`, config);
|
|
92
|
+
// console.log(response);
|
|
93
|
+
// if (response.status == 200)
|
|
94
|
+
// getUpstreamJobs(arg.accessToken);
|
|
95
|
+
// });
|
|
96
|
+
return (_jsx(Box, __assign({ sx: { display: 'flex', flexDirection: 'column', width: '100%' } }, { children: props.volumes[props.selectedVolume] != undefined && _jsxs(Fragment, { children: [_jsxs(Box, __assign({ sx: {
|
|
97
|
+
display: 'flex',
|
|
98
|
+
width: '100%',
|
|
99
|
+
flexDirection: 'row',
|
|
100
|
+
justifyItems: 'left',
|
|
101
|
+
alignItems: 'center',
|
|
102
|
+
backgroundColor: 'white',
|
|
103
|
+
flexWrap: 'wrap'
|
|
104
|
+
} }, { children: [_jsxs(FormControl, __assign({ size: 'small', sx: {
|
|
105
|
+
m: 2,
|
|
106
|
+
minWidth: 120
|
|
107
|
+
} }, { children: [_jsx(InputLabel, __assign({ id: "slice-type-label" }, { children: "Opened Volume" })), _jsx(Select, __assign({ labelId: "slice-type-label", id: "slice-type", value: props.selectedVolume, label: "Opened Volume", onChange: function (e) { return props.setSelectedVolume(Number(e.target.value)); } }, { children: props.volumes.map(function (value, index) {
|
|
108
|
+
return _jsx(MenuItem, __assign({ value: index }, { children: value.alias }));
|
|
109
|
+
}) }))] })), _jsxs(FormControl, __assign({ size: 'small', sx: {
|
|
110
|
+
m: 2,
|
|
111
|
+
minWidth: 120
|
|
112
|
+
} }, { children: [_jsx(InputLabel, __assign({ id: "slice-type-label" }, { children: "Orientation" })), _jsxs(Select, __assign({ labelId: "slice-type-label", id: "slice-type", value: props.sliceType, label: "Orientation", onChange: handleSliceTypeChange }, { children: [_jsx(MenuItem, __assign({ value: 'axial' }, { children: "Axial" })), _jsx(MenuItem, __assign({ value: 'coronal' }, { children: "Coronal" })), _jsx(MenuItem, __assign({ value: 'sagittal' }, { children: "Sagittal" })), _jsx(MenuItem, __assign({ value: 'multi' }, { children: "Multi" })), _jsx(MenuItem, __assign({ value: '3d' }, { children: "3D" }))] }))] })), _jsxs(FormControl, __assign({ size: 'small', sx: {
|
|
113
|
+
m: 2,
|
|
114
|
+
minWidth: 180
|
|
115
|
+
} }, { children: [_jsx(InputLabel, __assign({ id: "drag-mode-label" }, { children: "Scroll and Right Click Drag" })), _jsx(Select, __assign({ labelId: "drag-mode-label", id: "drag-mode", value: props.dragMode, label: "Scroll and Right Click Drag", onChange: function (e) {
|
|
116
|
+
console.log(e.target.value);
|
|
117
|
+
props.setDragMode(e.target.value);
|
|
118
|
+
} }, { children: dragModes.map(function (mode, index) { return (_jsx(MenuItem, __assign({ value: mode.value }, { children: mode.label }), index)); }) }))] })), _jsxs(FormControl, __assign({ size: 'small', sx: {
|
|
119
|
+
m: 2,
|
|
120
|
+
minWidth: 120
|
|
121
|
+
} }, { children: [_jsx(InputLabel, __assign({ id: "slice-type-label" }, { children: "Display Mode" })), _jsx(Select, __assign({ labelId: "slice-type-label", id: "slice-type", value: props.complexMode, label: "Display Mode", onChange: function (e) { return props.setComplexMode(e.target.value); } }, { children: props.complexOptions.map(function (value) {
|
|
122
|
+
return _jsx(MenuItem, __assign({ value: value }, { children: value.charAt(0).toUpperCase() + value.slice(1) }));
|
|
123
|
+
}) }))] })), _jsxs(FormControl, __assign({ size: "small", sx: { m: 2, minWidth: 160 } }, { children: [_jsx(InputLabel, __assign({ id: "roi-layer-label" }, { children: "ROI Layer" })), _jsx(Select, __assign({ labelId: "roi-layer-label", id: "roi-layer", value: props.selectedROI, label: "Opened ROIs",
|
|
124
|
+
// Only text in the closed preview (no icon)
|
|
125
|
+
renderValue: function (selected) {
|
|
126
|
+
var _a, _b, _c;
|
|
127
|
+
// handle no selection or invalid index
|
|
128
|
+
if (selected === undefined || selected === null || isNaN(Number(selected))) {
|
|
129
|
+
return '';
|
|
130
|
+
}
|
|
131
|
+
var idx = Number(selected);
|
|
132
|
+
return (_c = (_b = (_a = props.rois) === null || _a === void 0 ? void 0 : _a[idx]) === null || _b === void 0 ? void 0 : _b.filename) !== null && _c !== void 0 ? _c : '';
|
|
133
|
+
}, MenuProps: {
|
|
134
|
+
// optional: nicer menu width to fit long names + icon
|
|
135
|
+
PaperProps: { sx: { minWidth: 280 } }
|
|
136
|
+
} }, { children: props.rois.map(function (value, index) { return (_jsxs(MenuItem, __assign({ value: index, onClick: function () { return props.setSelectedROI(Number(index)); }, sx: {
|
|
137
|
+
display: 'flex',
|
|
138
|
+
alignItems: 'center',
|
|
139
|
+
gap: 1
|
|
140
|
+
} }, { children: [_jsx(Box, __assign({ sx: { flexGrow: 1, overflow: 'hidden', textOverflow: 'ellipsis' } }, { children: value.filename })), _jsx(IconButton, __assign({ size: "small",
|
|
141
|
+
// prevent selecting/closing when clicking the icon
|
|
142
|
+
onMouseDown: function (e) { return e.stopPropagation(); }, onClick: function (e) {
|
|
143
|
+
e.stopPropagation();
|
|
144
|
+
setRoiDeleteMsg("You are about to delete \u201C".concat(value.filename, "\u201D"));
|
|
145
|
+
setRoiDeleteConfirm(function () {
|
|
146
|
+
return function () { return __awaiter(_this, void 0, void 0, function () {
|
|
147
|
+
var error_1;
|
|
148
|
+
var _a, _b, _c;
|
|
149
|
+
return __generator(this, function (_d) {
|
|
150
|
+
switch (_d.label) {
|
|
151
|
+
case 0:
|
|
152
|
+
_d.trys.push([0, 4, , 5]);
|
|
153
|
+
// Make delete call to the endpoint
|
|
154
|
+
return [4 /*yield*/, axios["delete"](props.roiDeleteUrl, {
|
|
155
|
+
headers: {
|
|
156
|
+
Authorization: "Bearer ".concat(props.accessToken)
|
|
157
|
+
},
|
|
158
|
+
data: {
|
|
159
|
+
roi_id: value.id
|
|
160
|
+
}
|
|
161
|
+
})];
|
|
162
|
+
case 1:
|
|
163
|
+
// Make delete call to the endpoint
|
|
164
|
+
_d.sent();
|
|
165
|
+
if (!props.pipelineId) return [3 /*break*/, 3];
|
|
166
|
+
return [4 /*yield*/, props.refreshPipelineRois()];
|
|
167
|
+
case 2:
|
|
168
|
+
_d.sent();
|
|
169
|
+
_d.label = 3;
|
|
170
|
+
case 3:
|
|
171
|
+
// Clear client drawing if we just deleted the applied ROI
|
|
172
|
+
if (props.selectedROI === index) {
|
|
173
|
+
props.nv.closeDrawing();
|
|
174
|
+
(_b = (_a = props.nv).drawScene) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
175
|
+
}
|
|
176
|
+
// Always refresh the histogram + ROI table after any deletion
|
|
177
|
+
(_c = props.resampleImage) === null || _c === void 0 ? void 0 : _c.call(props);
|
|
178
|
+
console.log("Deleted ROI: ".concat(value.filename));
|
|
179
|
+
return [3 /*break*/, 5];
|
|
180
|
+
case 4:
|
|
181
|
+
error_1 = _d.sent();
|
|
182
|
+
console.error("Failed to delete ROI:", error_1);
|
|
183
|
+
return [3 /*break*/, 5];
|
|
184
|
+
case 5: return [2 /*return*/];
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}); };
|
|
188
|
+
});
|
|
189
|
+
setRoiDeleteOpen(true);
|
|
190
|
+
} }, { children: _jsx(DeleteIcon, { fontSize: "small" }) }))] }), index)); }) }))] })), _jsx(CmrConfirmation, { name: "Delete ROI Layer", message: roiDeleteMsg, open: roiDeleteOpen, setOpen: setRoiDeleteOpen, cancellable: true, cancelText: "Cancel", confirmText: "Delete", color: "error", confirmCallback: function () {
|
|
191
|
+
roiDeleteConfirm();
|
|
192
|
+
} }), _jsx(Button, __assign({ variant: 'contained', disabled: !props.drawingChanged, endIcon: saving && _jsx(CircularProgress, { sx: { color: 'white' }, size: 20 }), onClick: function () {
|
|
193
|
+
if (saving)
|
|
194
|
+
return;
|
|
195
|
+
props.saveROI(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
196
|
+
return __generator(this, function (_a) {
|
|
197
|
+
switch (_a.label) {
|
|
198
|
+
case 0:
|
|
199
|
+
if (!props.pipelineId) return [3 /*break*/, 2];
|
|
200
|
+
return [4 /*yield*/, props.refreshPipelineRois()];
|
|
201
|
+
case 1:
|
|
202
|
+
_a.sent();
|
|
203
|
+
_a.label = 2;
|
|
204
|
+
case 2:
|
|
205
|
+
setSaving(false);
|
|
206
|
+
return [2 /*return*/];
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}); }, function () {
|
|
210
|
+
setSaving(true);
|
|
211
|
+
});
|
|
212
|
+
} }, { children: "Save Drawing Layer" })), _jsx(IconButton, __assign({ onClick: props.toggleSettings, style: { marginLeft: 'auto' } }, { children: _jsx(SettingsIcon, {}) }))] })), _jsxs(Box, __assign({ sx: {
|
|
213
|
+
display: 'flex',
|
|
214
|
+
width: '100%',
|
|
215
|
+
flexDirection: 'row',
|
|
216
|
+
justifyItems: 'left',
|
|
217
|
+
alignItems: 'center',
|
|
218
|
+
backgroundColor: 'white',
|
|
219
|
+
flexWrap: 'wrap'
|
|
220
|
+
} }, { children: [_jsxs(Box, __assign({ sx: {
|
|
221
|
+
display: 'flex',
|
|
222
|
+
alignItems: 'center'
|
|
223
|
+
}, m: 1 }, { children: [_jsx(Typography, __assign({ style: {
|
|
224
|
+
marginRight: 'auto'
|
|
225
|
+
} }, { children: "Neurological" })), _jsx(Switch, { defaultChecked: false, checked: !props.radiological, onChange: props.toggleRadiological })] })), _jsxs(Box, __assign({ sx: {
|
|
226
|
+
display: 'flex',
|
|
227
|
+
alignItems: 'center'
|
|
228
|
+
}, m: 1 }, { children: [_jsx(Typography, __assign({ style: {
|
|
229
|
+
marginRight: 'auto'
|
|
230
|
+
} }, { children: "Show Crosshair" })), _jsx(Switch, { defaultChecked: true, checked: props.showCrosshair, onChange: props.toggleShowCrosshair })] })), _jsxs(Box, __assign({ sx: {
|
|
231
|
+
display: 'flex',
|
|
232
|
+
alignItems: 'center'
|
|
233
|
+
}, m: 1 }, { children: [_jsx(Typography, __assign({ style: {
|
|
234
|
+
marginRight: 'auto'
|
|
235
|
+
} }, { children: "Show Color Bar" })), _jsx(Switch, { checked: props.showColorBar, onChange: props.toggleColorBar })] })), _jsxs(Box, __assign({ sx: {
|
|
236
|
+
display: 'flex',
|
|
237
|
+
alignItems: 'center'
|
|
238
|
+
}, m: 1 }, { children: [_jsx(Typography, __assign({ style: {
|
|
239
|
+
marginRight: 'auto'
|
|
240
|
+
} }, { children: "Labels Visible" })), _jsx(Switch, { defaultChecked: false, checked: props.labelsVisible, onChange: props.toggleLabelsVisible })] })), _jsx(Box, { sx: { flex: 1 } }), _jsxs(Stack, __assign({ flexDirection: 'row', alignItems: 'center', sx: { m: 2, gap: 0.5 } }, { children: [_jsx(Tooltip, __assign({ title: 'Reset Views', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.resetScene(); } }, { children: _jsx(HomeIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Recenter Views', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.recenter(); } }, { children: _jsx(CenterFocusStrongIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Reset Zooms', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.resetZoom(); } }, { children: _jsx(ZoomInMapIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Reset Contrast', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () {
|
|
241
|
+
var _a, _b;
|
|
242
|
+
props.nv.resetContrast();
|
|
243
|
+
props.nv.setGamma(1.0); // engine reset
|
|
244
|
+
(_b = (_a = props.nv).onResetGamma) === null || _b === void 0 ? void 0 : _b.call(_a); // UI reset: bumps gammaKey + sets gamma=1.0
|
|
245
|
+
} }, { children: _jsx(Brightness6Icon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Zoom Out', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () {
|
|
246
|
+
var scene = props.nv.scene;
|
|
247
|
+
var current = scene.pan2Dxyzmm[3];
|
|
248
|
+
var next = Math.max(0.1, current - 0.1);
|
|
249
|
+
var delta = current - next;
|
|
250
|
+
scene.pan2Dxyzmm[3] = next;
|
|
251
|
+
var mm = props.nv.frac2mm(scene.crosshairPos);
|
|
252
|
+
scene.pan2Dxyzmm[0] += delta * mm[0];
|
|
253
|
+
scene.pan2Dxyzmm[1] += delta * mm[1];
|
|
254
|
+
scene.pan2Dxyzmm[2] += delta * mm[2];
|
|
255
|
+
props.nv.drawScene();
|
|
256
|
+
}, size: "small", sx: {
|
|
257
|
+
border: '1px solid',
|
|
258
|
+
borderColor: 'divider',
|
|
259
|
+
borderRadius: 1
|
|
260
|
+
} }, { children: _jsx(ZoomOutIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Zoom In', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () {
|
|
261
|
+
var scene = props.nv.scene;
|
|
262
|
+
var current = scene.pan2Dxyzmm[3];
|
|
263
|
+
var next = current + 0.1;
|
|
264
|
+
var delta = current - next;
|
|
265
|
+
scene.pan2Dxyzmm[3] = next;
|
|
266
|
+
var mm = props.nv.frac2mm(scene.crosshairPos);
|
|
267
|
+
scene.pan2Dxyzmm[0] += delta * mm[0];
|
|
268
|
+
scene.pan2Dxyzmm[1] += delta * mm[1];
|
|
269
|
+
scene.pan2Dxyzmm[2] += delta * mm[2];
|
|
270
|
+
props.nv.drawScene();
|
|
271
|
+
}, size: "small", sx: {
|
|
272
|
+
border: '1px solid',
|
|
273
|
+
borderColor: 'divider',
|
|
274
|
+
borderRadius: 1
|
|
275
|
+
} }, { children: _jsx(ZoomInIcon, {}) })) }))] }))] }))] }) })));
|
|
276
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
.lil-gui {
|
|
2
|
+
--background-color: #ffffff;
|
|
3
|
+
--text-color: #3d3d3d;
|
|
4
|
+
--title-background-color: #333;
|
|
5
|
+
--title-text-color: #fff;
|
|
6
|
+
--widget-color: #f0f0f0;
|
|
7
|
+
--hover-color: #f0f0f0;
|
|
8
|
+
--focus-color: #fafafa;
|
|
9
|
+
--number-color: #000000;
|
|
10
|
+
--string-color: #8da300;
|
|
11
|
+
--width: '100%';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.lil-gui .controller > .name{
|
|
15
|
+
font-size:12pt;
|
|
16
|
+
}
|
|
17
|
+
.lil-gui .title {
|
|
18
|
+
font-size:14pt;
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
padding-left: 5pt;
|
|
22
|
+
border-top-right-radius:4px;
|
|
23
|
+
border-top-left-radius:4px;
|
|
24
|
+
font-weight: normal;
|
|
25
|
+
height: 28pt;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.title {
|
|
29
|
+
font-size:16px;
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
padding-left: 10pt;
|
|
33
|
+
border-top-right-radius:4px;
|
|
34
|
+
border-top-left-radius:4px;
|
|
35
|
+
font-weight: normal;
|
|
36
|
+
height: 30pt;
|
|
37
|
+
background: #333;
|
|
38
|
+
color: #fff;
|
|
39
|
+
// margin-bottom: 4px;
|
|
40
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared ROI label color row (NiiVue pen indices 1–6). Used by pen, rectangle, and ellipse tools.
|
|
3
|
+
*/
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { Stack, IconButton } from "@mui/material";
|
|
6
|
+
import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
|
|
7
|
+
var __assign = function () {
|
|
8
|
+
__assign =
|
|
9
|
+
Object.assign ||
|
|
10
|
+
function (t) {
|
|
11
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
12
|
+
s = arguments[i];
|
|
13
|
+
for (var p in s)
|
|
14
|
+
if (Object.prototype.hasOwnProperty.call(s, p))
|
|
15
|
+
t[p] = s[p];
|
|
16
|
+
}
|
|
17
|
+
return t;
|
|
18
|
+
};
|
|
19
|
+
return __assign.apply(this, arguments);
|
|
20
|
+
};
|
|
21
|
+
var DrawColorPlatte = function (_a) {
|
|
22
|
+
var expanded = _a.expanded, updateDrawPen = _a.updateDrawPen, setDrawingEnabled = _a.setDrawingEnabled;
|
|
23
|
+
var filledOptions = [
|
|
24
|
+
_jsx(FiberManualRecordIcon, { sx: { color: "red" } }, "f0"),
|
|
25
|
+
_jsx(FiberManualRecordIcon, { sx: { color: "green" } }, "f1"),
|
|
26
|
+
_jsx(FiberManualRecordIcon, { sx: { color: "blue" } }, "f2"),
|
|
27
|
+
_jsx(FiberManualRecordIcon, { sx: { color: "yellow" } }, "f3"),
|
|
28
|
+
_jsx(FiberManualRecordIcon, { sx: { color: "cyan" } }, "f4"),
|
|
29
|
+
_jsx(FiberManualRecordIcon, { sx: { color: "#e81ce8" } }, "f5"),
|
|
30
|
+
];
|
|
31
|
+
return _jsxs(Stack, __assign({
|
|
32
|
+
style: {
|
|
33
|
+
position: "absolute",
|
|
34
|
+
top: "100%",
|
|
35
|
+
left: 0,
|
|
36
|
+
zIndex: 1500,
|
|
37
|
+
border: "".concat(expanded ? "1px" : 0, " solid #bbb"),
|
|
38
|
+
maxWidth: expanded ? 300 : 0,
|
|
39
|
+
overflow: expanded ? "visible" : "hidden",
|
|
40
|
+
borderRadius: "16px",
|
|
41
|
+
borderTopLeftRadius: "6pt",
|
|
42
|
+
borderTopRightRadius: "6pt",
|
|
43
|
+
background: "#333"
|
|
44
|
+
},
|
|
45
|
+
direction: "column"
|
|
46
|
+
}, {
|
|
47
|
+
children: [
|
|
48
|
+
_jsx(Stack, __assign({ direction: "row" }, {
|
|
49
|
+
children: filledOptions.map(function (value, index) {
|
|
50
|
+
return _jsx(IconButton, __assign({
|
|
51
|
+
onClick: function () {
|
|
52
|
+
updateDrawPen({ target: { value: index + 1 } });
|
|
53
|
+
setDrawingEnabled(true);
|
|
54
|
+
}
|
|
55
|
+
}, { children: value }), index);
|
|
56
|
+
})
|
|
57
|
+
})),
|
|
58
|
+
]
|
|
59
|
+
}));
|
|
60
|
+
};
|
|
61
|
+
export default DrawColorPlatte;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Stack, IconButton } from "@mui/material";
|
|
3
|
+
import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
|
|
4
|
+
import FiberManualRecordOutlinedIcon from "@mui/icons-material/FiberManualRecordOutlined";
|
|
5
|
+
var __assign = function () {
|
|
6
|
+
__assign =
|
|
7
|
+
Object.assign ||
|
|
8
|
+
function (t) {
|
|
9
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
10
|
+
s = arguments[i];
|
|
11
|
+
for (var p in s)
|
|
12
|
+
if (Object.prototype.hasOwnProperty.call(s, p))
|
|
13
|
+
t[p] = s[p];
|
|
14
|
+
}
|
|
15
|
+
return t;
|
|
16
|
+
};
|
|
17
|
+
return __assign.apply(this, arguments);
|
|
18
|
+
};
|
|
19
|
+
var EraserPlatte = function (_a) {
|
|
20
|
+
var expandEraseOptions = _a.expandEraseOptions, updateDrawPen = _a.updateDrawPen, setDrawingEnabled = _a.setDrawingEnabled;
|
|
21
|
+
var eraseOptions = [
|
|
22
|
+
_jsx(FiberManualRecordIcon, { style: { color: "white" } }, "e0"),
|
|
23
|
+
_jsx(FiberManualRecordOutlinedIcon, { style: { color: "white" } }, "e1"),
|
|
24
|
+
];
|
|
25
|
+
return _jsxs(Stack, __assign({
|
|
26
|
+
style: {
|
|
27
|
+
position: "absolute",
|
|
28
|
+
top: "100%",
|
|
29
|
+
left: 0,
|
|
30
|
+
zIndex: 1500,
|
|
31
|
+
border: "".concat(expandEraseOptions ? "1px" : 0, " solid #bbb"),
|
|
32
|
+
maxWidth: expandEraseOptions ? 300 : 0,
|
|
33
|
+
overflow: expandEraseOptions ? "visible" : "hidden",
|
|
34
|
+
borderRadius: "16px",
|
|
35
|
+
borderTopLeftRadius: "6pt",
|
|
36
|
+
borderTopRightRadius: "6pt",
|
|
37
|
+
background: "#333",
|
|
38
|
+
width: 150
|
|
39
|
+
},
|
|
40
|
+
direction: "column"
|
|
41
|
+
}, {
|
|
42
|
+
children: [
|
|
43
|
+
_jsx(Stack, __assign({ direction: "row", style: { justifyContent: "center" } }, {
|
|
44
|
+
children: eraseOptions.map(function (value, index) {
|
|
45
|
+
return _jsx(IconButton, __assign({
|
|
46
|
+
onClick: function () {
|
|
47
|
+
updateDrawPen({ target: { value: index === 0 ? 8 : 0 } });
|
|
48
|
+
setDrawingEnabled(true);
|
|
49
|
+
}
|
|
50
|
+
}, { children: value }), index);
|
|
51
|
+
})
|
|
52
|
+
})),
|
|
53
|
+
]
|
|
54
|
+
}));
|
|
55
|
+
};
|
|
56
|
+
export default EraserPlatte;
|