fix(core): Address 3D reconstruction and Android compatibility issues and clean up 4D data mode (#4762)
This commit is contained in:
1 parent
4d06a7d286
commit
149d6d049c
32 files changed
+529
-529
No files matched your search
@@ -54,7 +54,7 @@
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.4",
|
||||
"@cornerstonejs/codec-openjph": "^2.4.5",
|
||||
"@cornerstonejs/dicom-image-loader": "^2.17.2",
|
||||
"@cornerstonejs/dicom-image-loader": "^2.19.3",
|
||||
"@emotion/serialize": "^1.1.3",
|
||||
"@ohif/core": "3.10.0-beta.91",
|
||||
"@ohif/extension-cornerstone": "3.10.0-beta.91",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.4",
|
||||
"@cornerstonejs/codec-openjph": "^2.4.5",
|
||||
"@cornerstonejs/dicom-image-loader": "^2.17.2",
|
||||
"@cornerstonejs/dicom-image-loader": "^2.19.3",
|
||||
"@ohif/ui": "3.10.0-beta.91",
|
||||
"cornerstone-math": "0.1.9",
|
||||
"dicom-parser": "^1.8.21"
|
||||
|
||||
@@ -285,14 +285,25 @@ export default class HangingProtocolService extends PubSubService {
|
||||
* @param protocolId - the id of the protocol
|
||||
* @returns protocol - the protocol with the given id
|
||||
*/
|
||||
public getProtocolById(protocolId: string): HangingProtocol.Protocol {
|
||||
public getProtocolById(protocolId: string, caseInsensitive = true): HangingProtocol.Protocol {
|
||||
if (!protocolId) {
|
||||
return;
|
||||
}
|
||||
if (protocolId === this.protocol?.id) {
|
||||
return this.protocol;
|
||||
}
|
||||
const protocol = this.protocols.get(protocolId);
|
||||
|
||||
let protocol = this.protocols.get(protocolId);
|
||||
if (!protocol && caseInsensitive) {
|
||||
const lowerCaseId = protocolId.toLowerCase();
|
||||
for (const [key] of this.protocols) {
|
||||
if (key.toLowerCase() === lowerCaseId) {
|
||||
protocol = this.getProtocolById(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!protocol) {
|
||||
throw new Error(`No protocol ${protocolId} found`);
|
||||
}
|
||||
@@ -533,8 +544,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
}
|
||||
|
||||
_validateProtocol(protocol: HangingProtocol.Protocol): HangingProtocol.Protocol {
|
||||
protocol.id = protocol.id || protocol.name;
|
||||
protocol.name = protocol.name || protocol.id;
|
||||
protocol.name = protocol.name ?? protocol.id;
|
||||
const { stages } = protocol;
|
||||
|
||||
if (!stages) {
|
||||
|
||||
@@ -15,7 +15,6 @@ be centered, and not draggable. They're commonly used when:
|
||||
If you're curious about the DOs and DON'Ts of dialogs and modals, check out this
|
||||
article: ["Best Practices for Modals / Overlays / Dialog Windows"][ux-article]
|
||||
|
||||
customComponent: The modal service allows users to provide their own Modal UI using the customComponents.
|
||||
|
||||
|
||||
<div style={{padding:"56.25% 0 0 0", position:"relative"}}>
|
||||
@@ -38,12 +37,17 @@ is expected to support, [check out it's interface in `@ohif/core`][interface]
|
||||
| Implementation | Consumer |
|
||||
| ---------------------------------- | --------- |
|
||||
| [Modal Provider][modal-provider]\* | Modal.jsx |
|
||||
| customComponent | user extensions via setServiceImplementation({customComponent: Modal}) |
|
||||
|
||||
`*` - Denotes maintained by OHIF
|
||||
| customComponent | user extensions via `setServiceImplementation({customComponent: Modal})` |
|
||||
|
||||
|
||||
|
||||
### Custom Component
|
||||
If you would like to customize the modal component that OHIF uses, you can register your own
|
||||
component with the `customComponent` property.
|
||||
|
||||
```js
|
||||
setServiceImplementation({customComponent: Modal})
|
||||
```
|
||||
|
||||
|
||||
> 3rd Party implementers may be added to this table via pull requests.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import Numeric from '../../../../ui-next/src/components/Numeric';
|
||||
import Icons from '../../../../ui-next/src/components/Icons';
|
||||
import ShowcaseRow from './ShowcaseRow';
|
||||
@@ -7,6 +7,9 @@ import ShowcaseRow from './ShowcaseRow';
|
||||
* NumericShowcase component displays Numeric variants and examples
|
||||
*/
|
||||
export default function NumericShowcase() {
|
||||
const [controlledValue, setControlledValue] = useState(0);
|
||||
const [controlledValues, setControlledValues] = useState([0, 100] as [number, number]);
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
{/* Basic Number Input */}
|
||||
@@ -14,19 +17,26 @@ export default function NumericShowcase() {
|
||||
title="Numeric - Number Input"
|
||||
description="Basic number input with min, max and a label"
|
||||
code={`
|
||||
<Numeric.Container mode="number" min={0} max={10} onChange={onChange}>
|
||||
<Numeric.Container mode="number" min={0} max={10} onChange={val => console.debug('Value changed:', val)}>
|
||||
<div className="flex flex-row items-center space-x-2">
|
||||
<Numeric.Label>Width</Numeric.Label>
|
||||
<Numeric.NumberInput />
|
||||
</div>
|
||||
</Numeric.Container>
|
||||
|
||||
<Numeric.Container mode="number" min={0} max={100} onChange={onChange}>
|
||||
<Numeric.Label className="text-secondary-foreground text-sm font-bold">Bolder</Numeric.Label>
|
||||
<Numeric.Container mode="number" className="space-y-1" min={0} max={100} onChange={val => console.debug('Value changed:', val)}>
|
||||
<Numeric.Label className="text-muted-foreground text-sm font-bold">Bolder</Numeric.Label>
|
||||
<Numeric.NumberInput className="w-12" />
|
||||
</Numeric.Container>
|
||||
|
||||
<Numeric.Container mode="number" className="flex flex-row items-center justify-between" onChange={onChange} min={0} value={123465789} max={10000000000000}>
|
||||
<Numeric.Container
|
||||
mode="number"
|
||||
className="flex flex-row items-center justify-between"
|
||||
onChange={val => console.debug('Value changed:', val)}
|
||||
min={0}
|
||||
value={123465789}
|
||||
max={10000000000000}
|
||||
>
|
||||
<Numeric.Label className="flex flex-row items-center">
|
||||
<Icons.Add />
|
||||
With Icon
|
||||
@@ -82,18 +92,37 @@ export default function NumericShowcase() {
|
||||
title="Numeric - Single Range"
|
||||
description="Single range slider with optional number input"
|
||||
code={`
|
||||
<Numeric.Container mode="singleRange" min={0} max={100} step={1} value={50} onChange={onChange}>
|
||||
// For controlled component
|
||||
const [controlledValue, setControlledValue] = useState(0);
|
||||
|
||||
<Numeric.Container mode="singleRange" min={0} max={100} onChange={val => console.debug('Value changed:', val)}>
|
||||
<Numeric.Label>Brightness</Numeric.Label>
|
||||
<Numeric.SingleRange showNumberInput />
|
||||
</Numeric.Container>
|
||||
|
||||
<Numeric.Container mode="singleRange" min={-50} max={50} step={1} value={0} className="flex flex-row items-center" onChange={onChange}>
|
||||
<Numeric.Container
|
||||
mode="singleRange"
|
||||
min={-50}
|
||||
max={50}
|
||||
step={1}
|
||||
defaultValue={0}
|
||||
className="flex flex-row items-center"
|
||||
onChange={val => console.debug('Value changed:', val)}
|
||||
>
|
||||
<Numeric.Label showValue>Contrast</Numeric.Label>
|
||||
<Numeric.SingleRange />
|
||||
</Numeric.Container>
|
||||
|
||||
<Numeric.Container mode="singleRange" min={0} max={100} step={1} value={50} className="flex flex-row items-center space-x-2" onChange={onChange}>
|
||||
<Numeric.Label>Something Else </Numeric.Label>
|
||||
<Numeric.Container
|
||||
mode="singleRange"
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
value={controlledValue}
|
||||
className="flex flex-row items-center space-x-2"
|
||||
onChange={val => setControlledValue(val as number)}
|
||||
>
|
||||
<Numeric.Label>Controlled State (Parent) </Numeric.Label>
|
||||
<Numeric.SingleRange showNumberInput />
|
||||
</Numeric.Container>`}
|
||||
>
|
||||
@@ -102,8 +131,6 @@ export default function NumericShowcase() {
|
||||
mode="singleRange"
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
value={50}
|
||||
onChange={val => console.debug('Value changed:', val)}
|
||||
>
|
||||
<Numeric.Label>Brightness</Numeric.Label>
|
||||
@@ -115,7 +142,7 @@ export default function NumericShowcase() {
|
||||
min={-50}
|
||||
max={50}
|
||||
step={1}
|
||||
value={0}
|
||||
defaultValue={0}
|
||||
className="flex flex-row items-center"
|
||||
onChange={val => console.debug('Value changed:', val)}
|
||||
>
|
||||
@@ -128,11 +155,11 @@ export default function NumericShowcase() {
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
value={50}
|
||||
value={controlledValue}
|
||||
className="flex flex-row items-center space-x-2"
|
||||
onChange={val => console.debug('Value changed:', val)}
|
||||
onChange={val => setControlledValue(val as number)}
|
||||
>
|
||||
<Numeric.Label>Something Else </Numeric.Label>
|
||||
<Numeric.Label>Controlled State (Parent) </Numeric.Label>
|
||||
<Numeric.SingleRange showNumberInput />
|
||||
</Numeric.Container>
|
||||
</div>
|
||||
@@ -143,18 +170,44 @@ export default function NumericShowcase() {
|
||||
title="Numeric - Double Range"
|
||||
description="Double range slider for selecting a range of values"
|
||||
code={`
|
||||
<Numeric.Container mode="doubleRange" min={0} max={100} step={1} values={[30, 70]} onChange={onChange}>
|
||||
// For controlled component
|
||||
const [controlledValues, setControlledValues] = useState<[number, number]>([0, 100]);
|
||||
|
||||
<Numeric.Container
|
||||
mode="doubleRange"
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
className="space-y-1"
|
||||
onChange={vals => console.debug('Values changed:', vals)}
|
||||
>
|
||||
<Numeric.Label showValue>Window Width/Level</Numeric.Label>
|
||||
<Numeric.DoubleRange />
|
||||
</Numeric.Container>
|
||||
|
||||
<Numeric.Container mode="doubleRange" min={0} max={100} step={1} values={[30, 70]}>
|
||||
<Numeric.Container
|
||||
mode="doubleRange"
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
defaultValues={[30, 70]}
|
||||
className="space-y-1"
|
||||
onChange={vals => console.debug('Values changed:', vals)}
|
||||
>
|
||||
<Numeric.Label>Window Width/Level</Numeric.Label>
|
||||
<Numeric.DoubleRange showNumberInputs />
|
||||
</Numeric.Container>
|
||||
|
||||
<Numeric.Container mode="doubleRange" min={0} max={100} step={1} values={[30, 70]} className="flex flex-row items-center space-x-2" onChange={onChange}>
|
||||
<Numeric.Label>Inline double slider</Numeric.Label>
|
||||
<Numeric.Container
|
||||
mode="doubleRange"
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
values={controlledValues}
|
||||
className="flex flex-row items-center space-x-2"
|
||||
onChange={vals => setControlledValues(vals as [number, number])}
|
||||
>
|
||||
<Numeric.Label>Controlled State (Parent) </Numeric.Label>
|
||||
<Numeric.DoubleRange />
|
||||
</Numeric.Container>`}
|
||||
>
|
||||
@@ -164,7 +217,6 @@ export default function NumericShowcase() {
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
values={[30, 70]}
|
||||
className="space-y-1"
|
||||
onChange={vals => console.debug('Values changed:', vals)}
|
||||
>
|
||||
@@ -177,8 +229,9 @@ export default function NumericShowcase() {
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
values={[30, 70]}
|
||||
defaultValues={[30, 70]}
|
||||
className="space-y-1"
|
||||
onChange={vals => console.debug('Values changed:', vals)}
|
||||
>
|
||||
<Numeric.Label>Window Width/Level</Numeric.Label>
|
||||
<Numeric.DoubleRange showNumberInputs />
|
||||
@@ -189,11 +242,11 @@ export default function NumericShowcase() {
|
||||
min={0}
|
||||
max={100}
|
||||
step={1}
|
||||
values={[30, 70]}
|
||||
values={controlledValues}
|
||||
className="flex flex-row items-center space-x-2"
|
||||
onChange={vals => console.debug('Values changed:', vals)}
|
||||
onChange={vals => setControlledValues(vals as [number, number])}
|
||||
>
|
||||
<Numeric.Label>Inline double slider</Numeric.Label>
|
||||
<Numeric.Label>Controlled State (Parent) </Numeric.Label>
|
||||
<Numeric.DoubleRange />
|
||||
</Numeric.Container>
|
||||
</div>
|
||||
@@ -204,17 +257,35 @@ export default function NumericShowcase() {
|
||||
title="Numeric - Combined Examples"
|
||||
description="Different modes and configurations working together"
|
||||
code={`
|
||||
<Numeric.Container mode="number" min={0} max={10} step={0.1}>
|
||||
<Numeric.Container
|
||||
mode="number"
|
||||
min={0}
|
||||
max={10}
|
||||
step={0.1}
|
||||
className="space-y-1"
|
||||
>
|
||||
<Numeric.Label>Zoom Factor</Numeric.Label>
|
||||
<Numeric.NumberInput />
|
||||
</Numeric.Container>
|
||||
|
||||
<Numeric.Container mode="singleRange" min={0} max={360} step={1}>
|
||||
<Numeric.Container
|
||||
mode="singleRange"
|
||||
min={0}
|
||||
max={360}
|
||||
step={1}
|
||||
className="space-y-1"
|
||||
>
|
||||
<Numeric.Label showValue>Rotation</Numeric.Label>
|
||||
<Numeric.SingleRange showNumberInput />
|
||||
</Numeric.Container>
|
||||
|
||||
<Numeric.Container mode="doubleRange" min={-1000} max={3000} values={[1000, 2000]} step={10}>
|
||||
<Numeric.Container
|
||||
mode="doubleRange"
|
||||
min={-1000}
|
||||
max={3000}
|
||||
step={10}
|
||||
className="space-y-1"
|
||||
>
|
||||
<Numeric.Label showValue>CT Window</Numeric.Label>
|
||||
<Numeric.DoubleRange showNumberInputs />
|
||||
</Numeric.Container>`}
|
||||
@@ -246,7 +317,6 @@ export default function NumericShowcase() {
|
||||
mode="doubleRange"
|
||||
min={-1000}
|
||||
max={3000}
|
||||
values={[1000, 2000]}
|
||||
step={10}
|
||||
className="space-y-1"
|
||||
>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Numeric.tsx
|
||||
import React, { createContext, useContext, useState, useCallback, PropsWithChildren } from 'react';
|
||||
import React, { createContext, useContext, useCallback, PropsWithChildren } from 'react';
|
||||
import { useControllableState } from '@radix-ui/react-use-controllable-state';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { Input } from '../Input/Input';
|
||||
import { Slider } from '../Slider/Slider';
|
||||
@@ -23,8 +24,10 @@ const NumericMetaContext = createContext<NumericMetaContextValue | null>(null);
|
||||
---------------------------------------------------------------------------*/
|
||||
interface NumericMetaContainerProps {
|
||||
mode: 'number' | 'singleRange' | 'doubleRange';
|
||||
value?: number; // for single-value usage
|
||||
values?: [number, number]; // for double-range usage
|
||||
value?: number; // for controlled single-value usage from parent
|
||||
defaultValue?: number; // for uncontrolled single-value usage
|
||||
values?: [number, number]; // for controlled double-range usage from parent
|
||||
defaultValues?: [number, number]; // for uncontrolled double-range usage
|
||||
onChange?: (val: number | [number, number]) => void;
|
||||
min?: number;
|
||||
max?: number;
|
||||
@@ -34,8 +37,10 @@ interface NumericMetaContainerProps {
|
||||
|
||||
function NumericMetaContainer({
|
||||
mode,
|
||||
value = 0,
|
||||
values = [0, 100],
|
||||
value,
|
||||
defaultValue,
|
||||
values,
|
||||
defaultValues,
|
||||
onChange,
|
||||
min = 0,
|
||||
max = 100,
|
||||
@@ -43,26 +48,46 @@ function NumericMetaContainer({
|
||||
className,
|
||||
children,
|
||||
}: PropsWithChildren<NumericMetaContainerProps>) {
|
||||
// Initialize state with props but don't update automatically
|
||||
const [internalSingleValue, setInternalSingleValue] = useState<number>(value);
|
||||
const [internalDoubleValue, setInternalDoubleValue] = useState<[number, number]>(values);
|
||||
// Calculate default values based on min and max
|
||||
const calculatedDefaultValue = defaultValue ?? min + (max - min) / 2;
|
||||
const calculatedDefaultValues = defaultValues ?? [
|
||||
min + (max - min) * 0.3,
|
||||
min + (max - min) * 0.7,
|
||||
];
|
||||
|
||||
// Use useControllableState for both single and double values
|
||||
const [internalSingleValue, setInternalSingleValue] = useControllableState({
|
||||
prop: mode === 'number' || mode === 'singleRange' ? value : undefined,
|
||||
defaultProp: calculatedDefaultValue,
|
||||
onChange: newVal => {
|
||||
if (mode === 'number' || mode === 'singleRange') {
|
||||
onChange?.(newVal);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const [internalDoubleValue, setInternalDoubleValue] = useControllableState({
|
||||
prop: mode === 'doubleRange' ? values : undefined,
|
||||
defaultProp: calculatedDefaultValues,
|
||||
onChange: newVals => {
|
||||
if (mode === 'doubleRange') {
|
||||
onChange?.(newVals);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const handleSingleChange = useCallback(
|
||||
(newVal: number) => {
|
||||
setInternalSingleValue(newVal);
|
||||
onChange?.(newVal);
|
||||
},
|
||||
[onChange]
|
||||
[setInternalSingleValue]
|
||||
);
|
||||
|
||||
const handleDoubleChange = useCallback(
|
||||
(newVals: [number, number]) => {
|
||||
// Update internal state
|
||||
setInternalDoubleValue(newVals);
|
||||
// Notify parent if onChange is provided
|
||||
onChange?.(newVals);
|
||||
},
|
||||
[onChange]
|
||||
[setInternalDoubleValue]
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -99,6 +99,7 @@ import {
|
||||
ToolButtonListItem,
|
||||
ToolButtonListDivider,
|
||||
Toolbox,
|
||||
Numeric,
|
||||
} from './components';
|
||||
import { DataRow } from './components/DataRow';
|
||||
|
||||
@@ -223,4 +224,5 @@ export {
|
||||
Toolbox,
|
||||
useToolbox,
|
||||
utils,
|
||||
Numeric,
|
||||
};
|
||||
@@ -19,8 +19,8 @@ export type CinePlayerProps = {
|
||||
onClose: () => void;
|
||||
updateDynamicInfo?: () => void;
|
||||
dynamicInfo?: {
|
||||
timePointIndex: number;
|
||||
numTimePoints: number;
|
||||
dimensionGroupNumber: number;
|
||||
numDimensionGroups: number;
|
||||
label?: string;
|
||||
};
|
||||
};
|
||||
@@ -41,7 +41,7 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
|
||||
dynamicInfo = {},
|
||||
updateDynamicInfo,
|
||||
}) => {
|
||||
const isDynamic = !!dynamicInfo?.numTimePoints;
|
||||
const isDynamic = !!dynamicInfo?.numDimensionGroups;
|
||||
const [frameRate, setFrameRate] = useState(defaultFrameRate);
|
||||
const debouncedSetFrameRate = useCallback(debounce(onFrameRateChange, 100), [onFrameRateChange]);
|
||||
|
||||
@@ -59,14 +59,14 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
|
||||
setFrameRate(defaultFrameRate);
|
||||
}, [defaultFrameRate]);
|
||||
|
||||
const handleTimePointChange = useCallback(
|
||||
(newIndex: number) => {
|
||||
const handleDimensionGroupNumberChange = useCallback(
|
||||
(newGroupNumber: number) => {
|
||||
if (isDynamic && dynamicInfo) {
|
||||
// Here, you would update the component's state or context that controls the current time point index
|
||||
// For demonstration, assuming a hypothetical function that updates the time point index
|
||||
updateDynamicInfo({
|
||||
...dynamicInfo,
|
||||
timePointIndex: newIndex,
|
||||
dimensionGroupNumber: newGroupNumber,
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -77,10 +77,10 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
|
||||
<div className={className}>
|
||||
{isDynamic && dynamicInfo && (
|
||||
<InputRange
|
||||
value={dynamicInfo.timePointIndex}
|
||||
onChange={handleTimePointChange}
|
||||
minValue={0}
|
||||
maxValue={dynamicInfo.numTimePoints - 1}
|
||||
value={dynamicInfo.dimensionGroupNumber}
|
||||
onChange={handleDimensionGroupNumberChange}
|
||||
minValue={1}
|
||||
maxValue={dynamicInfo.numDimensionGroups}
|
||||
step={1}
|
||||
containerClassName="mb-3 w-full"
|
||||
labelClassName="text-xs text-white"
|
||||
@@ -107,8 +107,8 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
|
||||
<div className="min-w-16 max-w-44 flex flex-col text-white">
|
||||
{/* Add Tailwind classes for monospace font and center alignment */}
|
||||
<div className="text-[11px]">
|
||||
<span className="w-2 text-white">{dynamicInfo.timePointIndex}</span>{' '}
|
||||
<span className="text-aqua-pale">{`/${dynamicInfo.numTimePoints}`}</span>
|
||||
<span className="w-2 text-white">{dynamicInfo.dimensionGroupNumber}</span>{' '}
|
||||
<span className="text-aqua-pale">{`/${dynamicInfo.numDimensionGroups}`}</span>
|
||||
</div>
|
||||
<div className="text-aqua-pale text-xs">{dynamicInfo.label}</div>
|
||||
</div>
|
||||
@@ -180,8 +180,8 @@ CinePlayer.propTypes = {
|
||||
onClose: PropTypes.func,
|
||||
isDynamic: PropTypes.bool,
|
||||
dynamicInfo: PropTypes.shape({
|
||||
timePointIndex: PropTypes.number,
|
||||
numTimePoints: PropTypes.number,
|
||||
dimensionGroupNumber: PropTypes.number,
|
||||
numDimensionGroups: PropTypes.number,
|
||||
label: PropTypes.string,
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Types } from '@ohif/core';
|
||||
|
||||
import MeasurementItem from './MeasurementItem';
|
||||
|
||||
const MeasurementTable = ({
|
||||
data = [],
|
||||
@@ -17,9 +14,9 @@ const MeasurementTable = ({
|
||||
const { t } = useTranslation('MeasurementTable');
|
||||
const amount = data.length;
|
||||
|
||||
const itemCustomization = customizationService.getCustomization('MeasurementItem');
|
||||
|
||||
const CustomMeasurementItem = itemCustomization.content;
|
||||
const CustomMeasurementItem = customizationService.getCustomization(
|
||||
'microscopyPanel.measurementItem'
|
||||
);
|
||||
|
||||
const onMeasurementDeleteHandler = ({ uid }) => {
|
||||
const measurement = measurementService.getMeasurement(uid);
|
||||
|
||||
Reference in new issue
Block a user