import './ViewportGrid.css'; import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { utils } from '@ohif/core'; // import ViewportPane from './ViewportPane.js'; import DefaultViewport from './DefaultViewport.js'; import EmptyViewport from './EmptyViewport.js'; const { loadAndCacheDerivedDisplaySets } = utils; const ViewportGrid = function (props) { const { activeViewportIndex, availablePlugins, defaultPlugin: defaultPluginName, layout, numRows, numColumns, setViewportData, studies, viewportData, children, } = props; const rowSize = 100 / numRows; const colSize = 100 / numColumns; // http://grid.malven.co/ if (!viewportData || !viewportData.length) { return null; } useEffect(() => { viewportData.forEach(displaySet => { loadAndCacheDerivedDisplaySets(displaySet, studies); }); }, [studies, viewportData]); const getViewportPanes = () => layout.viewports.map((layout, viewportIndex) => { const displaySet = viewportData[viewportIndex]; if (!displaySet) { return null; } const data = { displaySet, studies, }; // JAMES TODO: // Use whichever plugin is currently in use in the panel // unless nothing is specified. If nothing is specified // and the display set has a plugin specified, use that. // // TODO: Change this logic to: // - Plugins define how capable they are of displaying a SopClass // - When updating a panel, ensure that the currently enabled plugin // in the viewport is capable of rendering this display set. If not // then use the most capable available plugin const pluginName = !layout.plugin && displaySet && displaySet.plugin ? displaySet.plugin : layout.plugin; const ViewportComponent = _getViewportComponent( data, // Why do we pass this as `ViewportData`, when that's not really what it is? viewportIndex, children, availablePlugins, pluginName, defaultPluginName ); return ( {ViewportComponent} ); }); const ViewportPanes = React.useMemo(getViewportPanes, [ layout, viewportData, studies, children, availablePlugins, defaultPluginName, setViewportData, activeViewportIndex, ]); return (
{ViewportPanes}
); }; ViewportGrid.propTypes = { viewportData: PropTypes.array.isRequired, supportsDrop: PropTypes.bool.isRequired, activeViewportIndex: PropTypes.number.isRequired, layout: PropTypes.object.isRequired, availablePlugins: PropTypes.object.isRequired, setViewportData: PropTypes.func.isRequired, studies: PropTypes.array, children: PropTypes.node, defaultPlugin: PropTypes.string, numRows: PropTypes.number.isRequired, numColumns: PropTypes.number.isRequired, }; ViewportGrid.defaultProps = { viewportData: [], numRows: 1, numColumns: 1, layout: { viewports: [{}], }, activeViewportIndex: 0, supportsDrop: true, availablePlugins: { DefaultViewport, }, defaultPlugin: 'defaultViewportPlugin', }; /** * * * @param {*} plugin * @param {*} viewportData * @param {*} viewportIndex * @param {*} children * @returns */ function _getViewportComponent( viewportData, viewportIndex, children, availablePlugins, pluginName, defaultPluginName ) { if (viewportData.displaySet) { pluginName = pluginName || defaultPluginName; const ViewportComponent = availablePlugins[pluginName]; if (!ViewportComponent) { throw new Error( `No Viewport Component available for name ${pluginName}. Available plugins: ${JSON.stringify(availablePlugins)}` ); } return ( ); } return ; } export default ViewportGrid;