OHIF-276: Fix UI performance issues related to ToolbarService (#1969)

This commit is contained in:
Erik Ziegler 2020-08-17 10:19:12 +02:00 committed by GitHub
parent e4092d0349
commit ae3d05ebf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -4,56 +4,10 @@ import { SidePanel, ErrorBoundary } from '@ohif/ui';
import Header from './Header.jsx'; import Header from './Header.jsx';
import NestedMenu from './ToolbarButtonNestedMenu.jsx'; import NestedMenu from './ToolbarButtonNestedMenu.jsx';
function ViewerLayout({ // TODO: Having ToolbarPrimary and ToolbarSecondary is ugly, but
// From Extension Module Params // these are going to be unified shortly so this is good enough for now.
extensionManager, function ToolbarPrimary({servicesManager}) {
servicesManager,
commandsManager,
// From Modes
leftPanels,
rightPanels,
viewports,
children,
ViewportGridComp,
}) {
const { ToolBarService } = servicesManager.services; const { ToolBarService } = servicesManager.services;
/**
* Set body classes (tailwindcss) that don't allow vertical
* or horizontal overflow (no scrolling). Also guarantee window
* is sized to our viewport.
*/
useEffect(() => {
document.body.classList.add('bg-black');
document.body.classList.add('overflow-hidden');
return () => {
document.body.classList.remove('bg-black');
document.body.classList.remove('overflow-hidden');
};
}, []);
const getPanelData = id => {
const entry = extensionManager.getModuleEntry(id);
// TODO, not sure why sidepanel content has to be JSX, and not a children prop?
const content = entry.component;
return {
iconName: entry.iconName,
iconLabel: entry.iconLabel,
label: entry.label,
name: entry.name,
content,
};
};
const getViewportComponentData = viewportComponent => {
const entry = extensionManager.getModuleEntry(viewportComponent.namespace);
return {
component: entry.component,
displaySetsToDisplay: viewportComponent.displaySetsToDisplay,
};
};
const defaultTool = { const defaultTool = {
icon: 'tool-more-menu', icon: 'tool-more-menu',
label: 'More', label: 'More',
@ -99,15 +53,7 @@ function ViewerLayout({
return unsubscribe; return unsubscribe;
}, [ToolBarService]); }, [ToolBarService]);
const leftPanelComponents = leftPanels.map(getPanelData); return <>
const rightPanelComponents = rightPanels.map(getPanelData);
const viewportComponents = viewports.map(getViewportComponentData);
return (
<div>
<Header>
<ErrorBoundary context="Primary Toolbar">
<div className="relative flex justify-center">
{toolbars.primary.map((toolDef, index) => { {toolbars.primary.map((toolDef, index) => {
const isNested = Array.isArray(toolDef); const isNested = Array.isArray(toolDef);
if (!isNested) { if (!isNested) {
@ -133,6 +79,125 @@ function ViewerLayout({
); );
} }
})} })}
</>
}
function ToolbarSecondary({servicesManager}) {
const { ToolBarService } = servicesManager.services;
const defaultTool = {
icon: 'tool-more-menu',
label: 'More',
isActive: false,
};
const [toolbars, setToolbars] = useState({ primary: [], secondary: [] });
const [activeTool, setActiveTool] = useState(defaultTool);
const setActiveToolHandler = (tool, isNested) => {
setActiveTool(isNested ? tool : defaultTool);
};
const onPrimaryClickHandler = (evt, btn) => {
if (
btn.props &&
btn.props.commands &&
evt.value &&
btn.props.commands[evt.value]
) {
const { commandName, commandOptions } = btn.props.commands[evt.value];
commandsManager.runCommand(commandName, commandOptions);
}
};
useEffect(() => {
const { unsubscribe } = ToolBarService.subscribe(
ToolBarService.EVENTS.TOOL_BAR_MODIFIED,
() => {
console.warn('~~~ TOOL BAR MODIFIED EVENT CAUGHT');
const updatedToolbars = {
primary: ToolBarService.getButtonSection('primary', {
onClick: onPrimaryClickHandler,
setActiveTool: setActiveToolHandler,
}),
secondary: ToolBarService.getButtonSection('secondary', {
setActiveTool: setActiveToolHandler,
}),
};
setToolbars(updatedToolbars);
}
);
return unsubscribe;
}, [ToolBarService]);
return <>
{toolbars.secondary.map(toolDef => {
const { id, Component, componentProps } = toolDef;
return <Component key={id} id={id} {...componentProps} />;
})}
</>
}
function ViewerLayout({
// From Extension Module Params
extensionManager,
servicesManager,
commandsManager,
// From Modes
leftPanels,
rightPanels,
viewports,
children,
ViewportGridComp,
}) {
/**
* Set body classes (tailwindcss) that don't allow vertical
* or horizontal overflow (no scrolling). Also guarantee window
* is sized to our viewport.
*/
useEffect(() => {
document.body.classList.add('bg-black');
document.body.classList.add('overflow-hidden');
return () => {
document.body.classList.remove('bg-black');
document.body.classList.remove('overflow-hidden');
};
}, []);
const getPanelData = id => {
const entry = extensionManager.getModuleEntry(id);
// TODO, not sure why sidepanel content has to be JSX, and not a children prop?
const content = entry.component;
return {
iconName: entry.iconName,
iconLabel: entry.iconLabel,
label: entry.label,
name: entry.name,
content,
};
};
const getViewportComponentData = viewportComponent => {
const entry = extensionManager.getModuleEntry(viewportComponent.namespace);
return {
component: entry.component,
displaySetsToDisplay: viewportComponent.displaySetsToDisplay,
};
};
const leftPanelComponents = leftPanels.map(getPanelData);
const rightPanelComponents = rightPanels.map(getPanelData);
const viewportComponents = viewports.map(getViewportComponentData);
return (
<div>
<Header>
<ErrorBoundary context="Primary Toolbar">
<div className="relative flex justify-center">
<ToolbarPrimary servicesManager={servicesManager}/>
</div> </div>
</ErrorBoundary> </ErrorBoundary>
</Header> </Header>
@ -155,10 +220,7 @@ function ViewerLayout({
<div className="flex h-12 border-b border-transparent flex-2 w-100"> <div className="flex h-12 border-b border-transparent flex-2 w-100">
<ErrorBoundary context="Secondary Toolbar"> <ErrorBoundary context="Secondary Toolbar">
<div className="flex items-center w-full px-3 bg-primary-dark"> <div className="flex items-center w-full px-3 bg-primary-dark">
{toolbars.secondary.map(toolDef => { <ToolbarSecondary servicesManager={servicesManager}/>
const { id, Component, componentProps } = toolDef;
return <Component key={id} id={id} {...componentProps} />;
})}
</div> </div>
</ErrorBoundary> </ErrorBoundary>
</div> </div>