-
+
{
- toolBarManager.addButtons([
+ init: ({ servicesManager, extensionManager }) => {
+ const { ToolBarService } = servicesManager.services;
+ ToolBarService.init(extensionManager);
+ ToolBarService.addButtons([
{
id: 'Zoom',
namespace: 'org.ohif.cornerstone.toolbarModule.Zoom',
@@ -53,7 +55,7 @@ export default function mode({ modeConfiguration }) {
]);
// Could import layout selector here from org.ohif.default (when it exists!)
- toolBarManager.setToolBarLayout([
+ ToolBarService.setToolBarLayout([
// Primary
{
tools: ['Zoom', 'Levels', 'Pan', 'Capture', 'Layout'],
diff --git a/platform/core/src/ToolBarManager.js b/platform/core/src/ToolBarManager.js
deleted file mode 100644
index 0c585d8d0..000000000
--- a/platform/core/src/ToolBarManager.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export default class toolBarManager {
- constructor(extensionManager) {
- this.buttons = {};
- this.extensionManager = extensionManager;
- }
-
- addButtons(buttons) {
- buttons.forEach(button => {
- const buttonDefinition = this.extensionManager.getModuleEntry(
- button.namespace
- );
-
- const id = button.id || buttonDefinition.id;
-
- this.buttons[id] = buttonDefinition;
- });
- }
-
- setToolBarLayout(layouts) {
- const toolBarLayout = [];
-
- layouts.forEach(layout => {
- const toolBarDefinitions = { tools: [], moreTools: [] };
-
- const { tools, moreTools } = layout;
-
- tools &&
- tools.forEach(element => {
- const button = this.buttons[element];
-
- toolBarDefinitions.tools.push(button);
- });
-
- moreTools &&
- moreTools.forEach(element => {
- const button = this.buttons[element];
-
- toolBarDefinitions.moreTools.push(button);
- });
-
- toolBarLayout.push(toolBarDefinitions);
- });
-
- // TODO -> Change this to a service. => emit an event to subscribers to update the toolbar layout.
- }
-}
diff --git a/platform/core/src/ToolbarLayoutContext.js b/platform/core/src/ToolbarLayoutContext.js
deleted file mode 100644
index c88419831..000000000
--- a/platform/core/src/ToolbarLayoutContext.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import React, { Component, useContext } from 'react';
-
-/// TODO MAKE THIS PRETTY DANNY
-
-const ToolbarLayoutContext = React.createContext({
- toolBarLayout: [],
- setToolBarLayout: () => {},
-});
-
-ToolbarLayoutContext.displayName = 'ToolbarLayoutContext';
-
-class ToolbarLayoutProvider extends Component {
- state = {
- toolBarLayout: [],
- };
-
- render() {
- const setToolBarLayout = toolBarLayout => {
- this.setState({ toolBarLayout });
- };
-
- return (
-
- {this.props.children}
-
- );
- }
-}
-
-const useToolbarLayout = () => useContext(ToolbarLayoutContext);
-
-export default ToolbarLayoutContext;
-
-export { ToolbarLayoutProvider, useToolbarLayout };
diff --git a/platform/core/src/index.js b/platform/core/src/index.js
index a00f76d99..09067349b 100644
--- a/platform/core/src/index.js
+++ b/platform/core/src/index.js
@@ -20,12 +20,7 @@ import studies from './studies/';
import ui from './ui';
import user from './user.js';
import dicomMetadataStore from './dicomMetadataStore';
-import ToolBarManager from './ToolBarManager';
import { ViewModelProvider, useViewModel } from './ViewModelContext';
-import {
- ToolbarLayoutProvider,
- useToolbarLayout,
-} from './ToolbarLayoutContext';
import utils, { hotkeys } from './utils/';
import {
@@ -35,6 +30,7 @@ import {
UINotificationService,
UIViewportDialogService,
DisplaySetService,
+ ToolBarSerivce,
} from './services';
import IWebApiDataSource from './DataSources/IWebApiDataSource';
@@ -73,10 +69,10 @@ const OHIF = {
UIViewportDialogService,
DisplaySetService,
MeasurementService,
+ ToolBarSerivce,
IWebApiDataSource,
dicomMetadataStore,
//
- ToolBarManager,
ViewModelProvider,
useViewModel,
};
@@ -114,13 +110,11 @@ export {
UIViewportDialogService,
DisplaySetService,
MeasurementService,
+ ToolBarSerivce,
IWebApiDataSource,
dicomMetadataStore,
- ToolBarManager,
ViewModelProvider,
useViewModel,
- ToolbarLayoutProvider,
- useToolbarLayout,
};
export { OHIF };
diff --git a/platform/core/src/services/ToolBarService/ToolBarService.js b/platform/core/src/services/ToolBarService/ToolBarService.js
index 00650b066..0eb0056ef 100644
--- a/platform/core/src/services/ToolBarService/ToolBarService.js
+++ b/platform/core/src/services/ToolBarService/ToolBarService.js
@@ -1,5 +1,9 @@
import pubSubServiceInterface from '../pubSubServiceInterface';
+const EVENTS = {
+ TOOL_BAR_MODIFIED: 'event::toolBarService:toolBarModified',
+};
+
export default class ToolBarService {
constructor() {
this.displaySets = {};
@@ -26,6 +30,23 @@ export default class ToolBarService {
});
}
+ /**
+ * Broadcasts displaySetService changes.
+ *
+ * @param {string} eventName The event name
+ * @return void
+ */
+ _broadcastChange = (eventName, callbackProps) => {
+ const hasListeners = Object.keys(this.listeners).length > 0;
+ const hasCallbacks = Array.isArray(this.listeners[eventName]);
+
+ if (hasListeners && hasCallbacks) {
+ this.listeners[eventName].forEach(listener => {
+ listener.callback(callbackProps);
+ });
+ }
+ };
+
setToolBarLayout(layouts) {
const toolBarLayout = [];
@@ -51,6 +72,8 @@ export default class ToolBarService {
toolBarLayout.push(toolBarDefinitions);
});
- // TODO -> Change this to a service. => emit an event to subscribers to update the toolbar layout.
+ this.toolBarLayout = toolBarLayout;
+
+ this._broadcastChange(this.EVENTS.TOOL_BAR_MODIFIED, toolBarLayout);
}
}
diff --git a/platform/core/src/services/ToolBarService/index.js b/platform/core/src/services/ToolBarService/index.js
new file mode 100644
index 000000000..bbe3dd317
--- /dev/null
+++ b/platform/core/src/services/ToolBarService/index.js
@@ -0,0 +1,8 @@
+import ToolBarService from './ToolBarService';
+
+export default {
+ name: 'ToolBarService',
+ create: ({ configuration = {} }) => {
+ return new ToolBarService();
+ },
+};
diff --git a/platform/core/src/services/index.js b/platform/core/src/services/index.js
index 6487ed1c3..70eadd0d7 100644
--- a/platform/core/src/services/index.js
+++ b/platform/core/src/services/index.js
@@ -5,6 +5,7 @@ import UIModalService from './UIModalService';
import UINotificationService from './UINotificationService';
import UIViewportDialogService from './UIViewportDialogService';
import DisplaySetService from './DisplaySetService';
+import ToolBarSerivce from './ToolBarService';
export {
MeasurementService,
@@ -14,4 +15,5 @@ export {
UINotificationService,
UIViewportDialogService,
DisplaySetService,
+ ToolBarSerivce,
};
diff --git a/platform/viewer/public/config/idc.js b/platform/viewer/public/config/idc.js
index 204fa4d0e..07c9383c6 100644
--- a/platform/viewer/public/config/idc.js
+++ b/platform/viewer/public/config/idc.js
@@ -1,19 +1,48 @@
-window.config = function(props) {
- var servicesManager = props.servicesManager;
-
- return {
- routerBasename: '/',
- enableGoogleCloudAdapter: true,
- enableGoogleCloudAdapterUI: false,
- showStudyList: true,
- httpErrorHandler: error => {
- // This is 429 when rejected from the public idc sandbox too often.
- console.warn(error.status);
-
- // Could use services manager here to bring up a dialog/modal if needed.
- console.warn('test, navigate to https://ohif.org/');
- window.location = 'https://ohif.org/';
+window.config = {
+ routerBasename: '/',
+ enableGoogleCloudAdapter: true,
+ servers: {
+ // This is an array, but we'll only use the first entry for now
+ dicomWeb: [],
+ },
+ // This is an array, but we'll only use the first entry for now
+ oidc: [
+ {
+ // ~ REQUIRED
+ // Authorization Server URL
+ authority: 'https://accounts.google.com',
+ client_id:
+ '723928408739-k9k9r3i44j32rhu69vlnibipmmk9i57p.apps.googleusercontent.com',
+ redirect_uri: '/callback', // `OHIFStandaloneViewer.js`
+ response_type: 'id_token token',
+ scope:
+ 'email profile openid https://www.googleapis.com/auth/cloudplatformprojects.readonly https://www.googleapis.com/auth/cloud-healthcare', // email profile openid
+ // ~ OPTIONAL
+ post_logout_redirect_uri: '/logout-redirect.html',
+ revoke_uri: 'https://accounts.google.com/o/oauth2/revoke?token=',
+ automaticSilentRenew: true,
+ revokeAccessTokenOnSignout: true,
},
- healthcareApiEndpoint: 'https://idc-sandbox-002.appspot.com/v1beta1',
- };
+ ],
+ studyListFunctionsEnabled: true,
};
+
+// window.config = function(props) {
+// var servicesManager = props.servicesManager;
+
+// return {
+// routerBasename: '/',
+// enableGoogleCloudAdapter: true,
+// enableGoogleCloudAdapterUI: false,
+// showStudyList: true,
+// httpErrorHandler: error => {
+// // This is 429 when rejected from the public idc sandbox too often.
+// console.warn(error.status);
+
+// // Could use services manager here to bring up a dialog/modal if needed.
+// console.warn('test, navigate to https://ohif.org/');
+// window.location = 'https://ohif.org/';
+// },
+// healthcareApiEndpoint: 'https://idc-sandbox-002.appspot.com/v1beta1',
+// };
+// };
diff --git a/platform/viewer/src/appInit.js b/platform/viewer/src/appInit.js
index e47abcce5..62fcf2c51 100644
--- a/platform/viewer/src/appInit.js
+++ b/platform/viewer/src/appInit.js
@@ -8,6 +8,7 @@ import {
UIDialogService,
MeasurementService,
DisplaySetService,
+ ToolBarSerivce,
// utils,
// redux as reduxOHIF,
} from '@ohif/core';
@@ -45,6 +46,7 @@ function appInit(appConfigOrFunc, defaultExtensions) {
UIDialogService,
MeasurementService,
DisplaySetService,
+ ToolBarSerivce,
]);
/**
diff --git a/platform/viewer/src/routes/Mode/DisplaySetCreator.jsx b/platform/viewer/src/routes/Mode/DisplaySetCreator.jsx
deleted file mode 100644
index 19b24647b..000000000
--- a/platform/viewer/src/routes/Mode/DisplaySetCreator.jsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { useEffect, useCallback } from 'react';
-import {
- displaySetManager,
- ToolBarManager,
- useViewModel,
- useToolbarLayout,
-} from '@ohif/core';
-
-export default function DisplaySetCreator({
- location,
- mode,
- dataSourceName,
- extensionManager,
- DisplaySetService,
-}) {
- console.warn('DisplaySetCreator rerendering');
- const { routes, sopClassHandlers } = mode;
- const dataSources = extensionManager.getDataSources(dataSourceName);
- // TODO: For now assume one unique datasource.
-
- const dataSource = dataSources[0];
- const route = routes[0];
-
- // Add toolbar state to the view model context?
- const { displaySetInstanceUIDs, setDisplaySetInstanceUIDs } = useViewModel();
-
- const { toolBarLayout, setToolBarLayout } = useToolbarLayout();
-
- useEffect(() => {
- let toolBarManager = new ToolBarManager(extensionManager, setToolBarLayout);
- route.init({ toolBarManager });
- }, [mode, dataSourceName, location]);
-
- const createDisplaySets = useCallback(() => {
- // Add SOPClassHandlers to a new SOPClassManager.
- displaySetManager.init(extensionManager, sopClassHandlers, {
- displaySetInstanceUIDs,
- setDisplaySetInstanceUIDs,
- });
-
- const queryParams = location.search;
-
- // Call the data source to start building the view model?
- dataSource.retrieve.series.metadata(
- queryParams,
- displaySetManager.makeDisplaySets
- );
- }, [displaySetInstanceUIDs, location]);
-
- useEffect(() => {
- createDisplaySets();
- }, [mode, dataSourceName, location]);
-
- return null;
-}
diff --git a/platform/viewer/src/routes/Mode/Mode.jsx b/platform/viewer/src/routes/Mode/Mode.jsx
index e238f6ac4..22cc1c5df 100644
--- a/platform/viewer/src/routes/Mode/Mode.jsx
+++ b/platform/viewer/src/routes/Mode/Mode.jsx
@@ -72,10 +72,15 @@ export default function ModeRoute({
}
useEffect(() => {
- // TODO -> Make this into a service
- let toolBarManager = new ToolBarManager(extensionManager); //, setToolBarLayout);
- route.init({ toolBarManager });
- }, [mode, dataSourceName, location]);
+ route.init({ servicesManager, extensionManager });
+ }, [
+ mode,
+ dataSourceName,
+ location,
+ route,
+ servicesManager,
+ extensionManager,
+ ]);
// This queries for series, but... What does it do with them?
useEffect(() => {
@@ -90,11 +95,19 @@ export default function ModeRoute({
queryParams,
DisplaySetService.makeDisplaySets
);
- }, [mode, dataSourceName, location]);
+ }, [
+ mode,
+ dataSourceName,
+ location,
+ DisplaySetService,
+ extensionManager,
+ sopClassHandlers,
+ dataSource.retrieve.series,
+ ]);
const reducer = (state, action) => {
console.log(state, action);
- }
+ };
return (
{/* TODO: extensionManager is already provided to the extension module.
- * Use it from there instead of passing as a prop here.
- */}
+ * Use it from there instead of passing as a prop here.
+ */}