feat(new-study-panel): default to list view for non thumbnail series, change default fitler to all, and add more menu to thumbnail items with a dicom tag browser (#4417)

This commit is contained in:
Ibrahim authored and GitHub committed 2024-10-18 11:42:44 -04:00
1 parent 1d0259451f
commit a7fd9fa5bf
74 files changed
+361 -478

No files matched your search

@@ -1,7 +1,5 @@
import React, { useEffect, useState, useCallback } from 'react';
import { SidePanel as NewSidePanel } from '@ohif/ui-next';
import { SidePanel as OldSidePanel } from '@ohif/ui';
import { useAppConfig } from '@state';
import { SidePanel } from '@ohif/ui-next';
import { Types } from '@ohif/core';
export type SidePanelWithServicesProps = {
@@ -28,7 +26,6 @@ const SidePanelWithServices = ({
const [hasBeenOpened, setHasBeenOpened] = useState(false);
const [activeTabIndex, setActiveTabIndex] = useState(activeTabIndexProp);
const [tabs, setTabs] = useState(tabsProp ?? panelService.getPanels(side));
const [appConfig] = useAppConfig();
const handleSidePanelOpen = useCallback(() => {
setHasBeenOpened(true);
@@ -78,8 +75,6 @@ const SidePanelWithServices = ({
};
}, [tabs, hasBeenOpened, panelService]);
const SidePanel = appConfig?.useExperimentalUI ? NewSidePanel : OldSidePanel;
return (
<SidePanel
{...props}
@@ -25,9 +25,6 @@ export default function PanelMeasurementTable({
servicesManager,
commandsManager,
extensionManager,
renderHeader,
getCloseIcon,
tab,
}: withAppTypes): React.FunctionComponent {
const { t } = useTranslation('MeasurementTable');
@@ -216,24 +213,6 @@ export default function PanelMeasurementTable({
return (
<>
{renderHeader && (
<>
<div className="bg-primary-dark flex select-none rounded-t pt-1.5 pb-[2px]">
<div className="flex h-[24px] w-full cursor-pointer select-none justify-center self-center text-[14px]">
<div className="text-primary-active flex grow cursor-pointer select-none justify-center self-center text-[13px]">
<span>{tab.label}</span>
</div>
</div>
{getCloseIcon()}
</div>
<Separator
orientation="horizontal"
className="bg-black"
thickness="2px"
/>
</>
)}
<div
className="ohif-scrollbar overflow-y-auto overflow-x-hidden"
data-cy={'measurements-panel'}
@@ -1,10 +1,8 @@
import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { useImageViewer, useViewportGrid } from '@ohif/ui';
import { StudyBrowser as NewStudyBrowser } from '@ohif/ui-next';
import { StudyBrowser as OldStudyBrowser } from '@ohif/ui';
import { StudyBrowser } from '@ohif/ui-next';
import { utils } from '@ohif/core';
import { useAppConfig } from '@state';
import { useNavigate } from 'react-router-dom';
import { Separator } from '@ohif/ui-next';
import { PanelStudyBrowserHeader } from './PanelStudyBrowserHeader';
@@ -22,14 +20,11 @@ function PanelStudyBrowser({
getStudiesForPatientByMRN,
requestDisplaySetCreationForStudy,
dataSource,
renderHeader,
getCloseIcon,
tab,
commandsManager,
}: withAppTypes) {
const { hangingProtocolService, displaySetService, uiNotificationService, customizationService } =
servicesManager.services;
const navigate = useNavigate();
const [appConfig] = useAppConfig();
// Normally you nest the components so the tree isn't so deep, and the data
// doesn't have to have such an intense shape. This works well enough for now.
@@ -37,7 +32,7 @@ function PanelStudyBrowser({
const { StudyInstanceUIDs } = useImageViewer();
const [{ activeViewportId, viewports, isHangingProtocolLayout }, viewportGridService] =
useViewportGrid();
const [activeTabName, setActiveTabName] = useState('primary');
const [activeTabName, setActiveTabName] = useState('all');
const [expandedStudyInstanceUIDs, setExpandedStudyInstanceUIDs] = useState([
...StudyInstanceUIDs,
]);
@@ -285,27 +280,26 @@ function PanelStudyBrowser({
const activeDisplaySetInstanceUIDs = viewports.get(activeViewportId)?.displaySetInstanceUIDs;
const StudyBrowser = appConfig?.useExperimentalUI ? NewStudyBrowser : OldStudyBrowser;
const onThumbnailContextMenu = (commandName, options) => {
commandsManager.runCommand(commandName, options);
};
return (
<>
{renderHeader && (
<>
<PanelStudyBrowserHeader
tab={tab}
getCloseIcon={getCloseIcon}
viewPresets={viewPresets}
updateViewPresetValue={updateViewPresetValue}
actionIcons={actionIcons}
updateActionIconValue={updateActionIconValue}
/>
<Separator
orientation="horizontal"
className="bg-black"
thickness="2px"
/>
</>
)}
<>
<PanelStudyBrowserHeader
viewPresets={viewPresets}
updateViewPresetValue={updateViewPresetValue}
actionIcons={actionIcons}
updateActionIconValue={updateActionIconValue}
/>
<Separator
orientation="horizontal"
className="bg-black"
thickness="2px"
/>
</>
<StudyBrowser
tabs={tabs}
servicesManager={servicesManager}
@@ -319,6 +313,7 @@ function PanelStudyBrowser({
}}
showSettings={actionIcons.find(icon => icon.id === 'settings').value}
viewPresets={viewPresets}
onThumbnailContextMenu={onThumbnailContextMenu}
/>
</>
);
@@ -4,15 +4,11 @@ import { Icons } from '@ohif/ui-next';
import { actionIcon, viewPreset } from './types';
function PanelStudyBrowserHeader({
tab,
getCloseIcon,
viewPresets,
updateViewPresetValue,
actionIcons,
updateActionIconValue,
}: {
tab: any;
getCloseIcon: () => JSX.Element;
viewPresets: viewPreset[];
updateViewPresetValue: (viewPreset: viewPreset) => void;
actionIcons: actionIcon[];
@@ -22,7 +18,7 @@ function PanelStudyBrowserHeader({
<>
<div className="bg-muted flex h-[40px] select-none rounded-t p-2">
<div className={'flex h-[24px] w-full select-none justify-center self-center text-[14px]'}>
<div className="flex w-full items-center justify-between">
<div className="flex w-full items-center gap-[10px]">
<div className="flex h-full items-center justify-center">
<ToggleGroup
type="single"
@@ -45,13 +41,8 @@ function PanelStudyBrowserHeader({
</ToggleGroup>
</div>
<div className="text-muted-foreground flex items-center justify-center">
{' '}
<span>{tab.label}</span>{' '}
</div>
<div className="mr-[30px] flex items-center justify-center">
<div className="flex items-center space-x-1">
<div className="flex items-center justify-center">
<div className="text-primary-active flex items-center space-x-1">
{actionIcons.map((icon: actionIcon, index) =>
React.createElement(Icons[icon.iconName] || Icons.MissingIcon, {
key: index,
@@ -63,7 +54,6 @@ function PanelStudyBrowserHeader({
</div>
</div>
</div>
{getCloseIcon()}
</div>
</>
);
@@ -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}
/>
);
}
+3 -3
View File
@@ -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]',
+1 -3
View File
@@ -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 (
<PanelMeasurementTable
commandsManager={commandsManager}
servicesManager={servicesManager}
extensionManager={extensionManager}
renderHeader={renderHeader}
getCloseIcon={getCloseIcon}
tab={tab}
/>
);