Files
ohif-viewer/platform/app/src/App.tsx
2025-03-07 13:47:44 +07:00

196 lines
5.3 KiB
TypeScript

// External
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import i18n from '@ohif/i18n';
import { I18nextProvider } from 'react-i18next';
import { BrowserRouter } from 'react-router-dom';
import Compose from './routes/Mode/Compose';
import {
ExtensionManager,
CommandsManager,
HotkeysManager,
ServiceProvidersManager,
} from '@ohif/core';
import {
DialogProvider,
Modal,
ModalProvider,
ThemeWrapper,
ViewportDialogProvider,
ViewportGridProvider,
CineProvider,
UserAuthenticationProvider,
ToolboxProvider,
} from '@ohif/ui';
import {
ThemeWrapper as ThemeWrapperNext,
NotificationProvider,
TooltipProvider,
} from '@ohif/ui-next';
// Viewer Project
// TODO: Should this influence study list?
import { AppConfigProvider } from '@state';
import createRoutes from './routes';
import appInit from './appInit.js';
import OpenIdConnectRoutes from './utils/OpenIdConnectRoutes';
import { ShepherdJourneyProvider } from 'react-shepherd';
let commandsManager: CommandsManager,
extensionManager: ExtensionManager,
servicesManager: AppTypes.ServicesManager,
serviceProvidersManager: ServiceProvidersManager,
hotkeysManager: HotkeysManager;
function App({
config = {
/**
* Relative route from domain root that OHIF instance is installed at.
* For example:
*
* Hosted at: https://ohif.org/where-i-host-the/viewer/
* Value: `/where-i-host-the/viewer/`
* */
routerBaseName: '/',
/**
*
*/
showLoadingIndicator: true,
showStudyList: true,
oidc: [],
extensions: [],
},
defaultExtensions = [],
defaultModes = [],
}) {
const [init, setInit] = useState(null);
useEffect(() => {
const run = async () => {
appInit(config, defaultExtensions, defaultModes).then(setInit).catch(console.error);
};
run();
}, []);
if (!init) {
return null;
}
// Set above for named export
commandsManager = init.commandsManager;
extensionManager = init.extensionManager;
servicesManager = init.servicesManager;
serviceProvidersManager = init.serviceProvidersManager;
hotkeysManager = init.hotkeysManager;
// Set appConfig
const appConfigState = init.appConfig;
const { routerBasename, modes, dataSources, oidc, showStudyList } = appConfigState;
// get the maximum 3D texture size
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
if (gl) {
const max3DTextureSize = gl.getParameter(gl.MAX_3D_TEXTURE_SIZE);
appConfigState.max3DTextureSize = max3DTextureSize;
}
const {
uiDialogService,
uiModalService,
uiViewportDialogService,
viewportGridService,
cineService,
userAuthenticationService,
uiNotificationService,
customizationService,
} = servicesManager.services;
const providers = [
[AppConfigProvider, { value: appConfigState }],
[UserAuthenticationProvider, { service: userAuthenticationService }],
[I18nextProvider, { i18n }],
[ThemeWrapperNext],
[ThemeWrapper],
[ToolboxProvider],
[ViewportGridProvider, { service: viewportGridService }],
[ViewportDialogProvider, { service: uiViewportDialogService }],
[CineProvider, { service: cineService }],
[NotificationProvider, { service: uiNotificationService }],
[TooltipProvider],
[DialogProvider, { service: uiDialogService }],
[ModalProvider, { service: uiModalService, modal: Modal }],
[ShepherdJourneyProvider],
];
// Loop through and register each of the service providers registered with the ServiceProvidersManager.
const providersFromManager = Object.entries(serviceProvidersManager.providers);
if (providersFromManager.length > 0) {
providersFromManager.forEach(([serviceName, provider]) => {
providers.push([provider, { service: servicesManager.services[serviceName] }]);
});
}
const CombinedProviders = ({ children }) => Compose({ components: providers, children });
let authRoutes = null;
// Should there be a generic call to init on the extension manager?
customizationService.init(extensionManager);
// Use config to create routes
const appRoutes = createRoutes({
modes,
dataSources,
extensionManager,
servicesManager,
commandsManager,
hotkeysManager,
routerBasename,
showStudyList,
});
if (oidc) {
authRoutes = (
<OpenIdConnectRoutes
oidc={oidc}
routerBasename={routerBasename}
userAuthenticationService={userAuthenticationService}
/>
);
}
return (
<CombinedProviders>
<BrowserRouter basename={routerBasename}>
{authRoutes}
{appRoutes}
</BrowserRouter>
</CombinedProviders>
);
}
App.propTypes = {
config: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({
routerBasename: PropTypes.string.isRequired,
oidc: PropTypes.array,
whiteLabeling: PropTypes.object,
extensions: PropTypes.array,
}),
]).isRequired,
/* Extensions that are "bundled" or "baked-in" to the application.
* These would be provided at build time as part of they entry point. */
defaultExtensions: PropTypes.array,
/* Modes that are "bundled" or "baked-in" to the application.
* These would be provided at build time as part of they entry point. */
defaultModes: PropTypes.array,
};
export default App;
export { commandsManager, extensionManager, servicesManager };