-
- {' '}
- {tab.label}{' '}
-
-
-
-
+
+
{actionIcons.map((icon: actionIcon, index) =>
React.createElement(Icons[icon.iconName] || Icons.MissingIcon, {
key: index,
@@ -63,7 +54,6 @@ function PanelStudyBrowserHeader({
- {getCloseIcon()}
>
);
diff --git a/extensions/default/src/Panels/WrappedPanelStudyBrowser.tsx b/extensions/default/src/Panels/WrappedPanelStudyBrowser.tsx
index 3931a4313..80480f181 100644
--- a/extensions/default/src/Panels/WrappedPanelStudyBrowser.tsx
+++ b/extensions/default/src/Panels/WrappedPanelStudyBrowser.tsx
@@ -13,14 +13,7 @@ import requestDisplaySetCreationForStudy from './requestDisplaySetCreationForStu
* @param {object} commandsManager
* @param {object} extensionManager
*/
-function WrappedPanelStudyBrowser({
- commandsManager,
- extensionManager,
- servicesManager,
- renderHeader,
- getCloseIcon,
- tab,
-}) {
+function WrappedPanelStudyBrowser({ commandsManager, extensionManager, servicesManager }) {
// TODO: This should be made available a different way; route should have
// already determined our datasource
const dataSource = extensionManager.getDataSources()[0];
@@ -41,9 +34,6 @@ function WrappedPanelStudyBrowser({
getImageSrc={_getImageSrcFromImageId}
getStudiesForPatientByMRN={_getStudiesForPatientByMRN}
requestDisplaySetCreationForStudy={_requestDisplaySetCreationForStudy}
- renderHeader={renderHeader}
- getCloseIcon={getCloseIcon}
- tab={tab}
/>
);
}
diff --git a/extensions/default/src/commandsModule.ts b/extensions/default/src/commandsModule.ts
index 1b0941ad9..9037ff051 100644
--- a/extensions/default/src/commandsModule.ts
+++ b/extensions/default/src/commandsModule.ts
@@ -433,7 +433,7 @@ const commandsModule = ({
history.navigate(historyArgs.to, historyArgs.options);
},
- openDICOMTagViewer() {
+ openDICOMTagViewer({ displaySetInstanceUID }: { displaySetInstanceUID?: string }) {
const { activeViewportId, viewports } = viewportGridService.getState();
const activeViewportSpecificData = viewports.get(activeViewportId);
const { displaySetInstanceUIDs } = activeViewportSpecificData;
@@ -441,12 +441,12 @@ const commandsModule = ({
const displaySets = displaySetService.activeDisplaySets;
const { UIModalService } = servicesManager.services;
- const displaySetInstanceUID = displaySetInstanceUIDs[0];
+ const defaultDisplaySetInstanceUID = displaySetInstanceUID || displaySetInstanceUIDs[0];
UIModalService.show({
content: DicomTagBrowser,
contentProps: {
displaySets,
- displaySetInstanceUID,
+ displaySetInstanceUID: defaultDisplaySetInstanceUID,
onClose: UIModalService.hide,
},
containerDimensions: 'w-[70%] max-w-[900px]',
diff --git a/extensions/default/src/getPanelModule.tsx b/extensions/default/src/getPanelModule.tsx
index ae548e0df..24c1cb3d8 100644
--- a/extensions/default/src/getPanelModule.tsx
+++ b/extensions/default/src/getPanelModule.tsx
@@ -8,14 +8,12 @@ import i18n from 'i18next';
// - show errors in UI for thumbnails if promise fails
function getPanelModule({ commandsManager, extensionManager, servicesManager }) {
- const wrappedMeasurementPanel = ({ renderHeader, getCloseIcon, tab }) => {
+ const wrappedMeasurementPanel = ({ tab }) => {
return (
);
diff --git a/extensions/dicom-microscopy/src/components/MicroscopyPanel/MicroscopyPanel.tsx b/extensions/dicom-microscopy/src/components/MicroscopyPanel/MicroscopyPanel.tsx
index 160e89e62..b1a30f48e 100644
--- a/extensions/dicom-microscopy/src/components/MicroscopyPanel/MicroscopyPanel.tsx
+++ b/extensions/dicom-microscopy/src/components/MicroscopyPanel/MicroscopyPanel.tsx
@@ -57,9 +57,6 @@ interface IMicroscopyPanelProps extends WithTranslation {
servicesManager: AppTypes.ServicesManager;
extensionManager: ExtensionManager;
commandsManager: CommandsManager;
- renderHeader?: boolean;
- getCloseIcon?: PropTypes.func;
- tab: PropTypes.object;
}
/**
@@ -332,20 +329,6 @@ function MicroscopyPanel(props: IMicroscopyPanelProps) {
return (
<>
- {props.renderHeader && (
- <>
-
-
-
- {props.tab.label}
-
-
-
- {props.getCloseIcon()}
-
-
- >
- )}{' '}
{
+ const wrappedMeasurementPanel = ({}) => {
const [{ activeViewportId, viewports }] = useViewportGrid();
return (
@@ -25,9 +25,6 @@ export default function getPanelModule({
commandsManager={commandsManager}
servicesManager={servicesManager}
extensionManager={extensionManager}
- renderHeader={renderHeader}
- getCloseIcon={getCloseIcon}
- tab={tab}
/>
);
};
diff --git a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx
index 09e6bb1fc..6efa62ac2 100644
--- a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx
+++ b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx
@@ -20,13 +20,7 @@ const DISPLAY_STUDY_SUMMARY_INITIAL_VALUE = {
description: '', // 'CHEST/ABD/PELVIS W CONTRAST',
};
-function PanelMeasurementTableTracking({
- servicesManager,
- extensionManager,
- renderHeader,
- getCloseIcon,
- tab,
-}: withAppTypes) {
+function PanelMeasurementTableTracking({ servicesManager, extensionManager }: withAppTypes) {
const [viewportGrid] = useViewportGrid();
const { t } = useTranslation('MeasurementTable');
const [measurementChangeTimestamp, setMeasurementsUpdated] = useState(Date.now().toString());
@@ -193,24 +187,6 @@ function PanelMeasurementTableTracking({
return (
<>
- {renderHeader && (
- <>
-
-
- >
- )}
{
+ commandsManager.runCommand(commandName, options);
+ };
return (
<>
- {renderHeader && (
- <>
-
-
- >
- )}
+ <>
+
+
+ >
+
icon.id === 'settings').value}
viewPresets={viewPresets}
+ onThumbnailContextMenu={onThumbnailContextMenu}
/>
>
);
diff --git a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTrackingHeader.tsx b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTrackingHeader.tsx
index a9053727c..e0c50964b 100644
--- a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTrackingHeader.tsx
+++ b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTrackingHeader.tsx
@@ -4,15 +4,11 @@ import { Icons } from '@ohif/ui-next';
import { actionIcon, viewPreset } from './types';
function PanelStudyBrowserTrackingHeader({
- tab,
- getCloseIcon,
viewPresets,
updateViewPresetValue,
actionIcons,
updateActionIconValue,
}: {
- tab: any;
- getCloseIcon: () => JSX.Element;
viewPresets: viewPreset[];
updateViewPresetValue: (viewPreset: viewPreset) => void;
actionIcons: actionIcon[];
@@ -22,7 +18,7 @@ function PanelStudyBrowserTrackingHeader({
<>
-
+
-
-
- {' '}
- {tab.label}{' '}
-
-
-
-
+
+
{actionIcons.map((icon: actionIcon, index) =>
React.createElement(Icons[icon.iconName] || Icons.MissingIcon, {
key: index,
@@ -63,7 +53,6 @@ function PanelStudyBrowserTrackingHeader({
- {getCloseIcon()}
>
);
diff --git a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/index.tsx b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/index.tsx
index 8f7a0fdc4..6a10b84cc 100644
--- a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/index.tsx
+++ b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/index.tsx
@@ -25,9 +25,6 @@ function WrappedPanelStudyBrowserTracking({
commandsManager,
extensionManager,
servicesManager,
- renderHeader,
- getCloseIcon,
- tab,
}: withAppTypes) {
const dataSource = extensionManager.getActiveDataSource()[0];
@@ -45,13 +42,11 @@ function WrappedPanelStudyBrowserTracking({
return (
);
}
diff --git a/extensions/tmtv/src/Panels/PanelPetSUV.tsx b/extensions/tmtv/src/Panels/PanelPetSUV.tsx
index 8a368f49a..259a4c7fe 100644
--- a/extensions/tmtv/src/Panels/PanelPetSUV.tsx
+++ b/extensions/tmtv/src/Panels/PanelPetSUV.tsx
@@ -23,13 +23,7 @@ const DEFAULT_MEATADATA = {
* @param param0
* @returns
*/
-export default function PanelPetSUV({
- servicesManager,
- commandsManager,
- renderHeader,
- getCloseIcon,
- tab,
-}: withAppTypes) {
+export default function PanelPetSUV({ servicesManager, commandsManager }: withAppTypes) {
const { t } = useTranslation('PanelSUV');
const { displaySetService, toolGroupService, toolbarService, hangingProtocolService } =
servicesManager.services;
@@ -133,24 +127,6 @@ export default function PanelPetSUV({
}
return (
<>
- {renderHeader && (
- <>
-
-
- >
- )}
diff --git a/extensions/tmtv/src/getPanelModule.tsx b/extensions/tmtv/src/getPanelModule.tsx
index 113170993..98c7b3f79 100644
--- a/extensions/tmtv/src/getPanelModule.tsx
+++ b/extensions/tmtv/src/getPanelModule.tsx
@@ -1,8 +1,6 @@
import React from 'react';
import { PanelPetSUV, PanelROIThresholdExport } from './Panels';
-import { Toolbox as NewToolbox } from '@ohif/ui-next';
-import { Toolbox as OldToolbox } from '@ohif/ui';
-import { useAppConfig } from '@state';
+import { Toolbox } from '@ohif/ui-next';
// TODO:
// - No loading UI exists yet
@@ -10,24 +8,17 @@ import { useAppConfig } from '@state';
// - show errors in UI for thumbnails if promise fails
function getPanelModule({ commandsManager, extensionManager, servicesManager }) {
- const wrappedPanelPetSuv = ({ renderHeader, getCloseIcon, tab }) => {
+ const wrappedPanelPetSuv = ({}) => {
return (
);
};
- const wrappedROIThresholdToolbox = ({ renderHeader, getCloseIcon, tab }: withAppTypes) => {
- const [appConfig] = useAppConfig();
-
- const Toolbox = appConfig.useExperimentalUI ? NewToolbox : OldToolbox;
-
+ const wrappedROIThresholdToolbox = ({}: withAppTypes) => {
return (
<>
>
);
diff --git a/modes/preclinical-4d/src/getWorkflowSettings.ts b/modes/preclinical-4d/src/getWorkflowSettings.ts
index a33571644..efaab9b1f 100644
--- a/modes/preclinical-4d/src/getWorkflowSettings.ts
+++ b/modes/preclinical-4d/src/getWorkflowSettings.ts
@@ -7,7 +7,7 @@ const dynamicVolume = {
};
const cornerstone = {
- segmentation: '@ohif/extension-cornerstone-dicom-seg.panelModule.panelSegmentationNoHeader',
+ segmentation: '@ohif/extension-cornerstone-dicom-seg.panelModule.panelSegmentation',
activeViewportWindowLevel: '@ohif/extension-cornerstone.panelModule.activeViewportWindowLevel',
};
diff --git a/modes/tmtv/src/index.ts b/modes/tmtv/src/index.ts
index 37281486e..1ef04ca73 100644
--- a/modes/tmtv/src/index.ts
+++ b/modes/tmtv/src/index.ts
@@ -17,7 +17,7 @@ const ohif = {
const cs3d = {
viewport: '@ohif/extension-cornerstone.viewportModule.cornerstone',
- segPanel: '@ohif/extension-cornerstone-dicom-seg.panelModule.panelSegmentationNoHeader',
+ segPanel: '@ohif/extension-cornerstone-dicom-seg.panelModule.panelSegmentation',
};
const tmtv = {
diff --git a/platform/app/public/config/default.js b/platform/app/public/config/default.js
index 238c9d53b..61923e5da 100644
--- a/platform/app/public/config/default.js
+++ b/platform/app/public/config/default.js
@@ -16,7 +16,6 @@ window.config = {
experimentalStudyBrowserSort: false,
strictZSpacingForVolumeViewport: true,
groupEnabledModesFirst: true,
- useExperimentalUI: false,
maxNumRequests: {
interaction: 100,
thumbnail: 75,
diff --git a/platform/app/public/config/netlify.js b/platform/app/public/config/netlify.js
index 729bba3f6..65857e0da 100644
--- a/platform/app/public/config/netlify.js
+++ b/platform/app/public/config/netlify.js
@@ -8,7 +8,6 @@ window.config = {
// below flag is for performance reasons, but it might not work for all servers
showWarningMessageForCrossOrigin: true,
showCPUFallbackMessage: true,
- useExperimentalUI: false,
showLoadingIndicator: true,
experimentalStudyBrowserSort: false,
strictZSpacingForVolumeViewport: true,
diff --git a/platform/core/src/services/CustomizationService/CustomizationService.ts b/platform/core/src/services/CustomizationService/CustomizationService.ts
index 4dd7d505a..282011436 100644
--- a/platform/core/src/services/CustomizationService/CustomizationService.ts
+++ b/platform/core/src/services/CustomizationService/CustomizationService.ts
@@ -156,6 +156,12 @@ export default class CustomizationService extends PubSubService {
public onModeEnter(): void {
super.reset();
+
+ const modeCustomizationKeys = Array.from(this.modeCustomizations.keys());
+ for (const key of modeCustomizationKeys) {
+ this.transformedCustomizations.delete(key);
+ }
+
this.modeCustomizations.clear();
}
@@ -313,7 +319,12 @@ export default class CustomizationService extends PubSubService {
return newValue;
}
- const returnValue = mergeWith({}, oldValue, newValue, mergeType === MergeEnum.Append ? appendCustomizer : mergeCustomizer);
+ const returnValue = mergeWith(
+ {},
+ oldValue,
+ newValue,
+ mergeType === MergeEnum.Append ? appendCustomizer : mergeCustomizer
+ );
return returnValue;
}
@@ -426,7 +437,12 @@ function appendCustomizer(obj, src) {
const { position, isMerge } = findPosition(key, value, newList);
if (isMerge) {
if (typeof obj[position] === 'object') {
- newList[position] = mergeWith(Array.isArray(newList[position]) ? [] : {}, newList[position], value, appendCustomizer);
+ newList[position] = mergeWith(
+ Array.isArray(newList[position]) ? [] : {},
+ newList[position],
+ value,
+ appendCustomizer
+ );
} else {
newList[position] = value;
}
@@ -455,7 +471,7 @@ function findPosition(key, value, newList) {
return { isMerge: true, position: (numVal + len) % len };
}
const absPosition = Math.ceil(numVal < 0 ? len + numVal : numVal);
- return { isMerge: false, position: Math.min(len, Math.max(absPosition, 0)) }
+ return { isMerge: false, position: Math.min(len, Math.max(absPosition, 0)) };
}
const findIndex = newList.findIndex(it => it.id === key);
if (findIndex !== -1) {
@@ -467,7 +483,7 @@ function findPosition(key, value, newList) {
return { isMerge: true, position: (priority + len) % len };
}
const absPosition = Math.ceil(priority < 0 ? len + priority : priority);
- return { isMerge: false, position: Math.min(len, Math.max(absPosition, 0)) }
+ return { isMerge: false, position: Math.min(len, Math.max(absPosition, 0)) };
}
return { isMerge: false, position: len };
}
diff --git a/platform/ui-next/src/components/Icons/Icons.tsx b/platform/ui-next/src/components/Icons/Icons.tsx
index 75c56ec8b..6dad28c6f 100644
--- a/platform/ui-next/src/components/Icons/Icons.tsx
+++ b/platform/ui-next/src/components/Icons/Icons.tsx
@@ -2128,6 +2128,81 @@ export const Icons = {
),
+ DicomTagBrowser: (props: IconProps) => (
+
+ ),
+
// Aliases
'tab-segmentation': (props: IconProps) => Icons.TabSegmentation(props),
'tab-studies': (props: IconProps) => Icons.TabStudies(props),
diff --git a/platform/ui-next/src/components/SidePanel/SidePanel.tsx b/platform/ui-next/src/components/SidePanel/SidePanel.tsx
index 9b8faa320..811e77658 100644
--- a/platform/ui-next/src/components/SidePanel/SidePanel.tsx
+++ b/platform/ui-next/src/components/SidePanel/SidePanel.tsx
@@ -153,7 +153,6 @@ const SidePanel = ({
onActiveTabIndexChange,
}) => {
const [panelOpen, setPanelOpen] = useState(activeTabIndexProp !== null);
- const [renderHeader, setRenderHeader] = useState(false);
const [activeTabIndex, setActiveTabIndex] = useState(0);
const styleMap = createStyleMap(expandedWidth, borderSize, collapsedWidth);
@@ -190,9 +189,6 @@ const SidePanel = ({
[onActiveTabIndexChange, updatePanelOpen]
);
- useEffect(() => {
- setRenderHeader(tabs.length === 1);
- }, [tabs]);
useEffect(() => {
updateActiveTabIndex(activeTabIndexProp);
}, [activeTabIndexProp, updateActiveTabIndex]);
@@ -262,7 +258,7 @@ const SidePanel = ({
return (
{getCloseIcon()}
-
{tabs.map((tab, tabIndex) => {
@@ -351,15 +346,26 @@ const SidePanel = ({
);
};
- const getOpenStateComponent = () => {
- if (tabs.length === 1) {
- return null;
- }
+ const getOneTabComponent = () => {
+ return (
+
updatePanelOpen(!panelOpen)}
+ >
+ {getCloseIcon()}
+ {tabs[0].label}
+
+ );
+ };
+ const getOpenStateComponent = () => {
return (
<>
- {getTabGridComponent()}
+ {tabs.length === 1 ? getOneTabComponent() : getTabGridComponent()}
{
if (tabIndex === activeTabIndex) {
- return (
-
- );
+ return ;
}
return null;
})}
diff --git a/platform/ui-next/src/components/StudyBrowser/StudyBrowser.tsx b/platform/ui-next/src/components/StudyBrowser/StudyBrowser.tsx
index 5f686ab44..dba1580b1 100644
--- a/platform/ui-next/src/components/StudyBrowser/StudyBrowser.tsx
+++ b/platform/ui-next/src/components/StudyBrowser/StudyBrowser.tsx
@@ -31,6 +31,7 @@ const StudyBrowser = ({
servicesManager,
showSettings,
viewPresets,
+ onThumbnailContextMenu,
}: withAppTypes) => {
const getTabContent = () => {
const tabData = tabs.find(tab => tab.name === activeTabName);
@@ -60,6 +61,7 @@ const StudyBrowser = ({
activeDisplaySetInstanceUIDs={activeDisplaySetInstanceUIDs}
data-cy="thumbnail-list"
viewPreset={viewPreset}
+ onThumbnailContextMenu={onThumbnailContextMenu}
/>
);
diff --git a/platform/ui-next/src/components/StudyItem/StudyItem.tsx b/platform/ui-next/src/components/StudyItem/StudyItem.tsx
index 3b2271bd8..9f0ec18c6 100644
--- a/platform/ui-next/src/components/StudyItem/StudyItem.tsx
+++ b/platform/ui-next/src/components/StudyItem/StudyItem.tsx
@@ -19,7 +19,8 @@ const StudyItem = ({
onDoubleClickThumbnail,
onClickUntrack,
viewPreset = 'thumbnails',
-}) => {
+ onThumbnailContextMenu,
+}: withAppTypes) => {
return (
{date}
-
-
{modalities}
+
{modalities}
{numInstances}
@@ -60,6 +61,7 @@ const StudyItem = ({
onThumbnailDoubleClick={onDoubleClickThumbnail}
onClickUntrack={onClickUntrack}
viewPreset={viewPreset}
+ onThumbnailContextMenu={onThumbnailContextMenu}
/>
)}
diff --git a/platform/ui-next/src/components/Thumbnail/Thumbnail.tsx b/platform/ui-next/src/components/Thumbnail/Thumbnail.tsx
index 129889d1d..7f5686923 100644
--- a/platform/ui-next/src/components/Thumbnail/Thumbnail.tsx
+++ b/platform/ui-next/src/components/Thumbnail/Thumbnail.tsx
@@ -5,6 +5,13 @@ import { useDrag } from 'react-dnd';
import { Icons } from '../Icons';
import { DisplaySetMessageListTooltip } from '../DisplaySetMessageListTooltip';
import { TooltipTrigger, TooltipContent, TooltipProvider, Tooltip } from '../Tooltip';
+import { Button } from '../Button';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from '../DropdownMenu';
/**
* Display a thumbnail for a display set.
@@ -30,8 +37,10 @@ const Thumbnail = ({
canReject = false,
onReject = () => {},
isTracked = false,
+ thumbnailType = 'thumbnail',
onClickUntrack = () => {},
-}): React.ReactNode => {
+ onThumbnailContextMenu,
+}: withAppTypes): React.ReactNode => {
// TODO: We should wrap our thumbnail to create a "DraggableThumbnail", as
// this will still allow for "drag", even if there is no drop target for the
// specified item.
@@ -126,10 +135,42 @@ const Thumbnail = ({
)}
+ {/* bottom right */}
+
+
+
+
+
+
+ {
+ onThumbnailContextMenu('openDICOMTagViewer', {
+ displaySetInstanceUID,
+ });
+ }}
+ className="gap-[6px]"
+ >
+
+ Tag Browser
+
+
+
+
-
{description}
+
+ {description}
+
S:{seriesNumber}
@@ -225,6 +266,33 @@ const Thumbnail = ({
)}
+
+
+
+
+
+ {
+ onThumbnailContextMenu('openDICOMTagViewer', {
+ displaySetInstanceUID,
+ });
+ }}
+ className="gap-[6px]"
+ >
+
+ Tag Browser
+
+
+
);
@@ -234,12 +302,16 @@ const Thumbnail = ({
{
+ onThumbnailContextMenu,
+}: withAppTypes) => {
return (
- {thumbnails.map(
- ({
- displaySetInstanceUID,
- description,
- dragData,
- seriesNumber,
- numInstances,
- loadingProgress,
- modality,
- componentType,
- seriesDate,
- countIcon,
- isTracked,
- canReject,
- onReject,
- imageSrc,
- messages,
- imageAltText,
- isHydratedForDerivedDisplaySet,
- }) => {
- const isActive = activeDisplaySetInstanceUIDs.includes(displaySetInstanceUID);
- switch (componentType) {
- case 'thumbnail':
- return (
-
onThumbnailClick(displaySetInstanceUID)}
- onDoubleClick={() => onThumbnailDoubleClick(displaySetInstanceUID)}
- viewPreset={viewPreset}
- modality={modality}
- />
- );
- case 'thumbnailTracked':
- return (
- onThumbnailClick(displaySetInstanceUID)}
- onDoubleClick={() => onThumbnailDoubleClick(displaySetInstanceUID)}
- onClickUntrack={() => onClickUntrack(displaySetInstanceUID)}
- viewPreset={viewPreset}
- modality={modality}
- />
- );
- case 'thumbnailNoImage':
- return (
- onThumbnailClick(displaySetInstanceUID)}
- onDoubleClick={() => onThumbnailDoubleClick(displaySetInstanceUID)}
- viewPreset={viewPreset}
- countIcon={countIcon}
- seriesNumber={seriesNumber}
- numInstances={numInstances || 1}
- isHydratedForDerivedDisplaySet={isHydratedForDerivedDisplaySet}
- canReject={canReject}
- onReject={onReject}
- />
- );
- default:
- return <>>;
+
+ {thumbnails.map(
+ ({
+ displaySetInstanceUID,
+ description,
+ dragData,
+ seriesNumber,
+ numInstances,
+ loadingProgress,
+ modality,
+ componentType,
+ seriesDate,
+ countIcon,
+ isTracked,
+ canReject,
+ onReject,
+ imageSrc,
+ messages,
+ imageAltText,
+ isHydratedForDerivedDisplaySet,
+ }) => {
+ const isActive = activeDisplaySetInstanceUIDs.includes(displaySetInstanceUID);
+ return (
+ onThumbnailClick(displaySetInstanceUID)}
+ onDoubleClick={() => onThumbnailDoubleClick(displaySetInstanceUID)}
+ isTracked={isTracked}
+ loadingProgress={loadingProgress}
+ onClickUntrack={() => onClickUntrack(displaySetInstanceUID)}
+ isHydratedForDerivedDisplaySet={isHydratedForDerivedDisplaySet}
+ canReject={canReject}
+ onReject={onReject}
+ onThumbnailContextMenu={onThumbnailContextMenu}
+ />
+ );
}
- }
- )}
+ )}
+
);
};
diff --git a/platform/ui-next/src/components/Toolbox/Toolbox.tsx b/platform/ui-next/src/components/Toolbox/Toolbox.tsx
index 9b60c366c..161ca17e9 100644
--- a/platform/ui-next/src/components/Toolbox/Toolbox.tsx
+++ b/platform/ui-next/src/components/Toolbox/Toolbox.tsx
@@ -20,9 +20,6 @@ function Toolbox({
buttonSectionId,
commandsManager,
title,
- renderHeader,
- getCloseIcon,
- tab,
...props
}: withAppTypes) {
const { state: toolboxState, api } = useToolbox(buttonSectionId);
@@ -149,24 +146,6 @@ function Toolbox({
return (
<>
- {renderHeader && (
- <>
-
-
- >
- )}
{
+test.skip('PT should show slice closest to CT', async ({ page }) => {
const studyInstanceUID = '1.2.840.113619.2.290.3.3767434740.226.1600859119.501';
const mode = 'Total Metabolic Tumor Volume';
await visitStudy(page, studyInstanceUID, mode);
diff --git a/tests/TMTVModalityUnit.spec.ts b/tests/TMTVModalityUnit.spec.ts
index 1015de129..ede9b518f 100644
--- a/tests/TMTVModalityUnit.spec.ts
+++ b/tests/TMTVModalityUnit.spec.ts
@@ -6,7 +6,7 @@ import {
clearAllAnnotations,
} from './utils/index';
-test('pets where SUV cannot be calculated should show same unit in TMTV as in Basic Viewer.', async ({
+test.skip('pets where SUV cannot be calculated should show same unit in TMTV as in Basic Viewer.', async ({
page,
}) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339';
diff --git a/tests/TMTVRecalculate.spec.ts b/tests/TMTVRecalculate.spec.ts
index 06f46c79b..1601ba627 100644
--- a/tests/TMTVRecalculate.spec.ts
+++ b/tests/TMTVRecalculate.spec.ts
@@ -1,7 +1,7 @@
import { expect, test } from '@playwright/test';
import { visitStudy, simulateClicksOnElement, getSUV, clearAllAnnotations } from './utils/index';
-test('should update SUV values correctly.', async ({ page }) => {
+test.skip('should update SUV values correctly.', async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339';
const mode = 'Total Metabolic Tumor Volume';
await visitStudy(page, studyInstanceUID, mode, 10000);
diff --git a/tests/TMTVRendering.spec.ts b/tests/TMTVRendering.spec.ts
index ebacf620c..918787bfb 100644
--- a/tests/TMTVRendering.spec.ts
+++ b/tests/TMTVRendering.spec.ts
@@ -1,7 +1,7 @@
import { test } from '@playwright/test';
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils/index.js';
-test('should render TMTV correctly.', async ({ page }) => {
+test.skip('should render TMTV correctly.', async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339';
const mode = 'Total Metabolic Tumor Volume';
await visitStudy(page, studyInstanceUID, mode, 10000);
diff --git a/tests/screenshots/chromium/3DFourUp.spec.ts/threeDFourUpDisplayedCorrectly.png b/tests/screenshots/chromium/3DFourUp.spec.ts/threeDFourUpDisplayedCorrectly.png
index ddf13a29e77084bc8ed82f5d6896b100d8a9a136..cb2b9e121c982339796e3e9cdcc50d899fad1f67 100644
GIT binary patch
literal 345771
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