Skip to main content
Version: 3.9.0-beta.40 (Latest)

Module: Layout Template

Overview​

LayoutTemplates are a new concept in v3 that modes use to control the layout of a route. A layout template is a React component that is given a set of managers that define apis to access toolbar state, commands, and hotkeys, as well as props defined by the layout template.

For instance the default LayoutTemplate takes in leftPanels, rightPanels and viewports as props, which it uses to build its view.

In addition, layout template has complete control over the structure of the application. You could have tools down the left side, or a strict guided workflow with tools set programmatically, the choice is yours for your use case.

const getLayoutTemplateModule = (/* ... */) => [
{
id: 'exampleLayout',
name: 'exampleLayout',
component: ExampleLayoutComponent,
},
];

The props that are passed to layoutTemplate are managers and service, along with the defined mode left/right panels, mode's defined viewports and OHIF ViewportGridComp. LayoutTemplate leverages extensionManager to grab typed extension module entries: *.getModuleEntry(id)

A simplified code for Default extension's layout template is:

extensions/default/src/ViewerLayout/index.jsx
import React from 'react';
import { SidePanel } from '@ohif/ui';

function Toolbar({ servicesManager }) {
const { ToolBarService } = servicesManager.services;

return (
<>
// ToolBarService.getButtonSection('primary') to get toolbarButtons
{toolbarButtons.map((toolDef, index) => {
const { id, Component, componentProps } = toolDef;
return (
<Component
key={id}
id={id}
{...componentProps}
bState={buttonState}
isActive={isActive}
onInteraction={args => ToolBarService.recordInteraction(args)}
/>
);
})}
</>
);
}

function ViewerLayout({
// From Extension Module Params
extensionManager,
servicesManager,
hotkeysManager,
commandsManager,
// From Modes
leftPanels,
rightPanels,
viewports,
ViewportGridComp,
}) {
const getPanelData = id => {
const entry = extensionManager.getModuleEntry(id);
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>
<Toolbar servicesManager={servicesManager} />

<div>
{/* LEFT SIDEPANELS */}
<SidePanel
side="left"
defaultComponentOpen={leftPanelComponents[0].name}
childComponents={leftPanelComponents}
/>

{/* TOOLBAR + GRID */}
<ViewportGridComp
servicesManager={servicesManager}
viewportComponents={viewportComponents}
commandsManager={commandsManager}
/>

{/* Right SIDEPANELS */}
<SidePanel
side="right"
defaultComponentOpen={rightPanelComponents[0].name}
childComponents={rightPanelComponents}
/>
</div>
</div>
);
}

Overview Video​