feat(4D): Add 4D dynamic volume rendering and new pre-clinical 4d pt/ct mode (#3664)

Co-authored-by: Alireza <ar.sedghi@gmail.com>
Co-authored-by: Neil <neil.a.macphee@gmail.com>
This commit is contained in:
authored and GitHub committed 2024-04-09 23:57:34 -04:00
1 parent dc0b183dd4
commit d57e8bc157
200 files changed
+9589 -2178

No files matched your search

@@ -6,13 +6,11 @@ import { useLocation } from 'react-router';
import { ErrorBoundary, UserPreferences, AboutModal, Header, useModal } from '@ohif/ui';
import i18n from '@ohif/i18n';
import { hotkeys } from '@ohif/core';
import { useAppConfig } from '@state';
import { Toolbar } from '../Toolbar/Toolbar';
const { availableLanguages, defaultLanguage, currentLanguage } = i18n;
function ViewerHeader({ hotkeysManager, extensionManager, servicesManager }) {
const [appConfig] = useAppConfig();
function ViewerHeader({ hotkeysManager, extensionManager, servicesManager, appConfig }) {
const navigate = useNavigate();
const location = useLocation();
@@ -107,6 +105,13 @@ function ViewerHeader({ hotkeysManager, extensionManager, servicesManager }) {
WhiteLabeling={appConfig.whiteLabeling}
showPatientInfo={appConfig.showPatientInfo}
servicesManager={servicesManager}
Secondary={
<Toolbar
servicesManager={servicesManager}
buttonSection="secondary"
/>
}
appConfig={appConfig}
>
<ErrorBoundary context="Primary Toolbar">
<div className="relative flex justify-center">
+42 -36
View File
@@ -1,12 +1,7 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import {
SidePanel,
ErrorBoundary,
LoadingIndicatorProgress,
InvestigationalUseDialog,
} from '@ohif/ui';
import { ErrorBoundary, LoadingIndicatorProgress, InvestigationalUseDialog } from '@ohif/ui';
import { ServicesManager, HangingProtocolService, CommandsManager } from '@ohif/core';
import { useAppConfig } from '@state';
import ViewerHeader from './ViewerHeader';
@@ -21,16 +16,24 @@ function ViewerLayout({
// From Modes
viewports,
ViewportGridComp,
leftPanels = [],
rightPanels = [],
leftPanelDefaultClosed = false,
rightPanelDefaultClosed = false,
leftPanelClosed = false,
rightPanelClosed = false,
}): React.FunctionComponent {
const [appConfig] = useAppConfig();
const { hangingProtocolService } = servicesManager.services;
const { panelService, hangingProtocolService } = servicesManager.services;
const [showLoadingIndicator, setShowLoadingIndicator] = useState(appConfig.showLoadingIndicator);
const hasPanels = useCallback(
(side): boolean => !!panelService.getPanels(side).length,
[panelService]
);
const [hasRightPanels, setHasRightPanels] = useState(hasPanels('right'));
const [hasLeftPanels, setHasLeftPanels] = useState(hasPanels('left'));
const [leftPanelClosedState, setLeftPanelClosed] = useState(leftPanelClosed);
const [rightPanelClosedState, setRightPanelClosed] = useState(rightPanelClosed);
/**
* Set body classes (tailwindcss) that don't allow vertical
* or horizontal overflow (no scrolling). Also guarantee window
@@ -57,20 +60,6 @@ function ViewerLayout({
return { entry, content: entry.component };
};
const getPanelData = id => {
const { content, entry } = getComponent(id);
return {
id: entry.id,
iconName: entry.iconName,
iconLabel: entry.iconLabel,
label: entry.label,
name: entry.name,
content,
contexts: entry.contexts,
};
};
useEffect(() => {
const { unsubscribe } = hangingProtocolService.subscribe(
HangingProtocolService.EVENTS.PROTOCOL_CHANGED,
@@ -97,8 +86,26 @@ function ViewerLayout({
};
};
const leftPanelComponents = leftPanels.map(getPanelData);
const rightPanelComponents = rightPanels.map(getPanelData);
useEffect(() => {
const { unsubscribe } = panelService.subscribe(
panelService.EVENTS.PANELS_CHANGED,
({ options }) => {
setHasLeftPanels(hasPanels('left'));
setHasRightPanels(hasPanels('right'));
if (options?.leftPanelClosed !== undefined) {
setLeftPanelClosed(options.leftPanelClosed);
}
if (options?.rightPanelClosed !== undefined) {
setRightPanelClosed(options.rightPanelClosed);
}
}
);
return () => {
unsubscribe();
};
}, [panelService, hasPanels]);
const viewportComponents = viewports.map(getViewportComponentData);
return (
@@ -107,6 +114,7 @@ function ViewerLayout({
hotkeysManager={hotkeysManager}
extensionManager={extensionManager}
servicesManager={servicesManager}
appConfig={appConfig}
/>
<div
className="relative flex w-full flex-row flex-nowrap items-stretch overflow-hidden bg-black"
@@ -115,12 +123,11 @@ function ViewerLayout({
<React.Fragment>
{showLoadingIndicator && <LoadingIndicatorProgress className="h-full w-full bg-black" />}
{/* LEFT SIDEPANELS */}
{leftPanelComponents.length ? (
{hasLeftPanels ? (
<ErrorBoundary context="Left Panel">
<SidePanelWithServices
side="left"
activeTabIndex={leftPanelDefaultClosed ? null : 0}
tabs={leftPanelComponents}
activeTabIndex={leftPanelClosedState ? null : 0}
servicesManager={servicesManager}
/>
</ErrorBoundary>
@@ -137,12 +144,11 @@ function ViewerLayout({
</ErrorBoundary>
</div>
</div>
{rightPanelComponents.length ? (
{hasRightPanels ? (
<ErrorBoundary context="Right Panel">
<SidePanelWithServices
side="right"
activeTabIndex={rightPanelDefaultClosed ? null : 0}
tabs={rightPanelComponents}
activeTabIndex={rightPanelClosedState ? null : 0}
servicesManager={servicesManager}
/>
</ErrorBoundary>
@@ -165,8 +171,8 @@ ViewerLayout.propTypes = {
// From modes
leftPanels: PropTypes.array,
rightPanels: PropTypes.array,
leftPanelDefaultClosed: PropTypes.bool.isRequired,
rightPanelDefaultClosed: PropTypes.bool.isRequired,
leftPanelClosed: PropTypes.bool.isRequired,
rightPanelClosed: PropTypes.bool.isRequired,
/** Responsible for rendering our grid of viewports; provided by consuming application */
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
viewports: PropTypes.array,