diff --git a/platform/core/src/index.js b/platform/core/src/index.js
index 9ffa1c70a..acfdd3fbf 100644
--- a/platform/core/src/index.js
+++ b/platform/core/src/index.js
@@ -30,8 +30,9 @@ import {
//
DicomMetadataStore,
DisplaySetService,
- ToolBarSerivce,
+ ToolBarSerivce, // TODO: Typo
MeasurementService,
+ ViewportGridService,
} from './services';
import IWebApiDataSource from './DataSources/IWebApiDataSource';
@@ -70,7 +71,8 @@ const OHIF = {
UIViewportDialogService,
DisplaySetService,
MeasurementService,
- ToolBarSerivce,
+ ToolBarSerivce, // TODO: TYPO
+ ViewportGridService,
IWebApiDataSource,
DicomMetadataStore,
//
@@ -112,6 +114,7 @@ export {
DisplaySetService,
MeasurementService,
ToolBarSerivce,
+ ViewportGridService,
IWebApiDataSource,
DicomMetadataStore,
ViewModelProvider,
diff --git a/platform/core/src/services/ViewportGridService/ViewportGridService.js b/platform/core/src/services/ViewportGridService/ViewportGridService.js
new file mode 100644
index 000000000..b4b213969
--- /dev/null
+++ b/platform/core/src/services/ViewportGridService/ViewportGridService.js
@@ -0,0 +1,54 @@
+const name = 'ViewportGridService';
+
+const publicAPI = {
+ name,
+ hide: _hide,
+ show: _show,
+ setServiceImplementation,
+};
+
+const serviceImplementation = {
+ _hide: () => console.warn('hide() NOT IMPLEMENTED'),
+ _show: () => console.warn('show() NOT IMPLEMENTED'),
+};
+
+function _show({ viewportIndex, type, message, actions, onSubmit }) {
+ return serviceImplementation._show({
+ viewportIndex,
+ type,
+ message,
+ actions,
+ onSubmit,
+ });
+}
+
+function _hide() {
+ return serviceImplementation._hide();
+}
+
+function setServiceImplementation({
+ hide: hideImplementation,
+ show: showImplementation,
+}) {
+ if (hideImplementation) {
+ serviceImplementation._hide = hideImplementation;
+ }
+ if (showImplementation) {
+ serviceImplementation._show = showImplementation;
+ }
+}
+
+export default {
+ name,
+ create: ({ configuration = {} }) => {
+ return publicAPI;
+ },
+};
+
+// initialState={{
+// numRows: 1,
+// numCols: 1,
+// viewports: [],
+// activeViewportIndex: 0,
+// }}
+// reducer={viewportGridReducer}
diff --git a/platform/core/src/services/ViewportGridService/index.js b/platform/core/src/services/ViewportGridService/index.js
index e69de29bb..47d083531 100644
--- a/platform/core/src/services/ViewportGridService/index.js
+++ b/platform/core/src/services/ViewportGridService/index.js
@@ -0,0 +1,3 @@
+import ViewportGridService from './ViewportGridService';
+
+export default ViewportGridService;
diff --git a/platform/core/src/services/index.js b/platform/core/src/services/index.js
index 96ecfb4d5..3862a2554 100644
--- a/platform/core/src/services/index.js
+++ b/platform/core/src/services/index.js
@@ -7,6 +7,7 @@ import UIViewportDialogService from './UIViewportDialogService';
import DicomMetadataStore from './DicomMetadataStore';
import DisplaySetService from './DisplaySetService';
import ToolBarSerivce from './ToolBarService';
+import ViewportGridService from './ViewportGridService';
export {
MeasurementService,
@@ -18,4 +19,5 @@ export {
DicomMetadataStore,
DisplaySetService,
ToolBarSerivce,
+ ViewportGridService,
};
diff --git a/platform/ui/src/contextProviders/ViewportGridProvider.jsx b/platform/ui/src/contextProviders/ViewportGridProvider.jsx
index c56268cc4..b718d5145 100644
--- a/platform/ui/src/contextProviders/ViewportGridProvider.jsx
+++ b/platform/ui/src/contextProviders/ViewportGridProvider.jsx
@@ -1,20 +1,141 @@
-import React, { createContext, useContext, useReducer } from 'react';
-
-// export const VIEWPORT_GRID_DEFAULT_VALUE = {
-// numCols: 1,
-// numRows: 1,
-// activeViewportIndex: 0,
-// viewports: [],
-// };
+import React, {
+ createContext,
+ useCallback,
+ useContext,
+ useEffect,
+ useReducer,
+} from 'react';
+import PropTypes from 'prop-types';
export const ViewportGridContext = createContext();
-export function ViewportGridProvider({ reducer, initialState, children }) {
+// export function ViewportGridProvider({ reducer, initialState, children }) {
+// return (
+//
+// {children}
+//
+// );
+// }
+
+export function ViewportGridProvider({ children, service }) {
+ const DEFAULT_STATE = {
+ numRows: 1,
+ numCols: 1,
+ viewports: [],
+ activeViewportIndex: 0,
+ };
+
+ const viewportGridReducer = (state, action) => {
+ switch (action.type) {
+ case 'SET_ACTIVE_VIEWPORT_INDEX':
+ return { ...state, ...{ activeViewportIndex: action.payload } };
+ case 'SET_DISPLAYSET_FOR_VIEWPORT': {
+ const { viewportIndex, displaySetInstanceUID } = action.payload;
+ const viewports = state.viewports.slice();
+
+ viewports[viewportIndex] = { displaySetInstanceUID };
+
+ return { ...state, ...{ viewports } };
+ }
+ case 'SET_LAYOUT': {
+ const { numCols, numRows } = action.payload;
+ const numPanes = numCols * numRows;
+ const viewports = state.viewports.slice();
+ const activeViewportIndex =
+ state.activeViewportIndex >= numPanes ? 0 : state.activeViewportIndex;
+
+ while (viewports.length < numPanes) {
+ viewports.push({});
+ }
+ while (viewports.length > numPanes) {
+ viewports.pop();
+ }
+
+ return {
+ ...state,
+ ...{ activeViewportIndex, numCols, numRows, viewports },
+ };
+ }
+ default:
+ return action.payload;
+ }
+ };
+
+ const [viewportGridState, dispatch] = useReducer(
+ DEFAULT_STATE,
+ viewportGridReducer
+ );
+
+ const getState = useCallback(() => viewportGridState, [viewportGridState]);
+ const setActiveViewportIndex = useCallback(
+ index => dispatch({ type: 'SET_ACTIVE_VIEWPORT_INDEX', payload: index }),
+ [dispatch]
+ );
+ const setDisplaysetForViewport = useCallback(
+ ({ viewportIndex, displaySetInstanceUID }) =>
+ dispatch({
+ type: 'SET_DISPLAYSET_FOR_VIEWPORT',
+ payload: {
+ viewportIndex,
+ displaySetInstanceUID,
+ },
+ }),
+ [dispatch]
+ );
+
+ const setLayout = useCallback(
+ ({ numCols, numRows }) =>
+ dispatch({
+ type: 'SET_LAYOUT',
+ payload: {
+ numCols,
+ numRows,
+ },
+ }),
+ [dispatch]
+ );
+
+ /**
+ * Sets the implementation of a modal service that can be used by extensions.
+ *
+ * @returns void
+ */
+ useEffect(() => {
+ if (service) {
+ service.setServiceImplementation({
+ getState,
+ setActiveViewportIndex,
+ setDisplaysetForViewport,
+ setLayout,
+ });
+ }
+ }, [
+ getState,
+ service,
+ setActiveViewportIndex,
+ setDisplaysetForViewport,
+ setLayout,
+ ]);
+
+ const api = {
+ // getState,
+ setActiveViewportIndex,
+ setDisplaysetForViewport,
+ setLayout,
+ };
+
return (
-
+
{children}
);
}
+ViewportGridProvider.propTypes = {
+ children: PropTypes.any,
+ service: PropTypes.shape({
+ setServiceImplementation: PropTypes.func,
+ }).isRequired,
+};
+
export const useViewportGrid = () => useContext(ViewportGridContext);
diff --git a/platform/viewer/src/App.jsx b/platform/viewer/src/App.jsx
index 969977107..01f1e3a3d 100644
--- a/platform/viewer/src/App.jsx
+++ b/platform/viewer/src/App.jsx
@@ -54,60 +54,14 @@ function App({ config, defaultExtensions }) {
UIModalService,
UINotificationService,
UIViewportDialogService,
+ ViewportGridService, // TODO: Should this be a "UI" Service?
} = servicesManager.services;
- // A UI Service may need to use the ViewportGrid context
- const viewportGridReducer = (state, action) => {
- console.log(state, action);
-
- switch (action.type) {
- case 'SET_ACTIVE_VIEWPORT_INDEX':
- return { ...state, ...{ activeViewportIndex: action.payload } };
- case 'SET_DISPLAYSET_FOR_VIEWPORT': {
- const { viewportIndex, displaySetInstanceUID } = action.payload;
- const viewports = state.viewports.slice();
-
- viewports[viewportIndex] = { displaySetInstanceUID };
-
- return { ...state, ...{ viewports } };
- }
- case 'SET_LAYOUT': {
- const { numCols, numRows } = action.payload;
- const numPanes = numCols * numRows;
- const viewports = state.viewports.slice();
- const activeViewportIndex =
- state.activeViewportIndex >= numPanes ? 0 : state.activeViewportIndex;
-
- while (viewports.length < numPanes) {
- viewports.push({});
- }
- while (viewports.length > numPanes) {
- viewports.pop();
- }
-
- return {
- ...state,
- ...{ activeViewportIndex, numCols, numRows, viewports },
- };
- }
- default:
- return action.payload;
- }
- };
-
return (
-
+
diff --git a/platform/viewer/src/appInit.js b/platform/viewer/src/appInit.js
index ef8c16641..2f5433f54 100644
--- a/platform/viewer/src/appInit.js
+++ b/platform/viewer/src/appInit.js
@@ -10,6 +10,7 @@ import {
MeasurementService,
DisplaySetService,
ToolBarSerivce,
+ ViewportGridService,
// utils,
// redux as reduxOHIF,
} from '@ohif/core';
@@ -51,6 +52,7 @@ function appInit(appConfigOrFunc, defaultExtensions) {
MeasurementService,
DisplaySetService,
ToolBarSerivce,
+ ViewportGridService,
]);
/**