import React, { Component } from 'react' import { BrowserRouter as Router } from 'react-router-dom' import { Provider } from 'react-redux' import { createStore, combineReducers } from 'redux' import PropTypes from 'prop-types' import OHIF from 'ohif-core' import './config' import ui from './redux/ui.js' import OHIFStandaloneViewer from './OHIFStandaloneViewer' import WhiteLabellingContext from './WhiteLabellingContext' import OHIFCornerstoneExtension from 'ohif-cornerstone-extension' import OHIFVTKExtension from 'ohif-vtk-extension' import OHIFDicomPDFExtension from 'ohif-dicom-pdf-extension' import OHIFDicomHtmlExtension from 'ohif-dicom-html-extension' import OHIFDicomMicroscopyExtension from 'ohif-dicom-microscopy-extension' import { loadUser, OidcProvider, createUserManager, reducer as oidcReducer, } from 'redux-oidc' import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader' const { ExtensionManager } = OHIF.extensions const Icons = 'icons.svg' const { reducers, localStorage } = OHIF.redux reducers.ui = ui reducers.oidc = oidcReducer const combined = combineReducers(reducers) const store = createStore(combined, localStorage.loadState()) store.subscribe(() => { localStorage.saveState({ preferences: store.getState().preferences, }) }) const defaultButtons = [ { command: 'StackScroll', type: 'tool', text: 'Stack Scroll', svgUrl: `${Icons}#icon-tools-stack-scroll`, active: false, }, { command: 'Zoom', type: 'tool', text: 'Zoom', svgUrl: `${Icons}#icon-tools-zoom`, active: false, }, { command: 'Wwwc', type: 'tool', text: 'Levels', svgUrl: `${Icons}#icon-tools-levels`, active: true, }, { command: 'Pan', type: 'tool', text: 'Pan', svgUrl: `${Icons}#icon-tools-pan`, active: false, }, { command: 'Length', type: 'tool', text: 'Length', svgUrl: `${Icons}#icon-tools-measure-temp`, active: false, }, /*{ command: 'Annotate', type: 'tool', text: 'Annotate', svgUrl: `${Icons}#icon-tools-measure-non-target`, active: false },*/ { command: 'Angle', type: 'tool', text: 'Angle', iconClasses: 'fa fa-angle-left', active: false, }, { command: 'Bidirectional', type: 'tool', text: 'Bidirectional', svgUrl: `${Icons}#icon-tools-measure-target`, active: false, }, { command: 'Brush', type: 'tool', text: 'Brush', iconClasses: 'fa fa-circle', active: false, }, { command: 'FreehandMouse', type: 'tool', text: 'Freehand', iconClasses: 'fa fa-star', active: false, }, { command: 'reset', type: 'command', text: 'Reset', svgUrl: `${Icons}#icon-tools-reset`, active: false, }, ] const buttonsAction = OHIF.redux.actions.setAvailableButtons(defaultButtons) store.dispatch(buttonsAction) const availableTools = [ { name: 'Pan', mouseButtonMasks: [1, 4] }, { name: 'Zoom', mouseButtonMasks: [1, 2] }, { name: 'Wwwc', mouseButtonMasks: [1] }, { name: 'Bidirectional', mouseButtonMasks: [1] }, { name: 'Length', mouseButtonMasks: [1] }, { name: 'Angle', mouseButtonMasks: [1] }, { name: 'StackScroll', mouseButtonMasks: [1] }, { name: 'Brush', mouseButtonMasks: [1] }, { name: 'FreehandMouse', mouseButtonMasks: [1] }, { name: 'PanMultiTouch' }, { name: 'ZoomTouchPinch' }, { name: 'StackScrollMouseWheel' }, { name: 'StackScrollMultiTouch' }, ] const toolAction = OHIF.redux.actions.setExtensionData('cornerstone', { availableTools, }) store.dispatch(toolAction) /** TODO: extensions should be passed in as prop as soon as we have the extensions as separate packages and then registered by ExtensionsManager */ const extensions = [ new OHIFCornerstoneExtension(), new OHIFVTKExtension(), new OHIFDicomPDFExtension(), new OHIFDicomHtmlExtension(), new OHIFDicomMicroscopyExtension(), ] ExtensionManager.registerExtensions(store, extensions) // TODO[react] Use a provider when the whole tree is React window.store = store function handleServers(servers) { if (servers) { OHIF.utils.addServers(servers, store) } } function handleOIDC(oidc) { if (!oidc) { return } const oidcClient = oidc[0] const settings = { authority: oidcClient.authServerUrl, client_id: oidcClient.clientId, redirect_uri: oidcClient.authRedirectUri, silent_redirect_uri: '/silent-refresh.html', post_logout_redirect_uri: oidcClient.postLogoutRedirectUri, response_type: oidcClient.responseType, scope: 'email profile openid', // Note: Request must have scope 'openid' to be considered an OpenID Connect request automaticSilentRenew: true, revokeAccessTokenOnSignout: true, filterProtocolClaims: true, loadUserInfo: true, extraQueryParams: oidcClient.extraQueryParams, } const userManager = createUserManager(settings) loadUser(store, userManager) return userManager } function handleWebWorkerInit(basename) { const config = { maxWebWorkers: Math.max(navigator.hardwareConcurrency - 1, 1), startWebWorkersOnDemand: true, webWorkerPath: basename + '/cornerstoneWADOImageLoaderWebWorker.min.js', taskConfiguration: { decodeTask: { loadCodecsOnStartup: true, initializeCodecsOnStartup: false, codecsPath: basename + '/cornerstoneWADOImageLoaderCodecs.min.js', usePDFJS: false, strict: false, }, }, } cornerstoneWADOImageLoader.webWorkerManager.initialize(config) } /** * Set or update the HTML Base tag present on the document * to point to the provided ROOT Url. * * @param rootUrl */ function updateBaseTag(rootUrl) { const bases = document.getElementsByTagName('base') let baseHref = rootUrl baseHref += baseHref.endsWith('/') ? '' : '/' if (bases.length > 1) { throw new Error('For some reason there is more than one base tag present.') } else if (bases.length === 1) { bases[0].href = baseHref } else { document.write(``) } } class App extends Component { static propTypes = { servers: PropTypes.object, oidc: PropTypes.array, routerBasename: PropTypes.string, rootUrl: PropTypes.string, userManager: PropTypes.object, location: PropTypes.object, } static defaultProps = { whiteLabelling: {}, } constructor(props) { super(props) this.userManager = handleOIDC(this.props.oidc) handleServers(this.props.servers) handleWebWorkerInit(this.props.rootUrl) updateBaseTag(this.props.rootUrl) } render() { const userManager = this.userManager if (userManager) { return ( ) } return ( ) } } export default App