feat(Mode): Ability to overwrite mode configuration and small improvements (#3580)

This commit is contained in:
Igor Octaviano 2023-08-08 11:05:20 -03:00 committed by GitHub
parent 58d38495f0
commit 0493a0d587
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 77 additions and 11 deletions

View File

@ -50,13 +50,16 @@ function ViewerLayout({
// dataSourceIdx === -1
// ? undefined
// : `datasources=${pathname.substring(dataSourceIdx + 1)}`;
// Todo: Handle parameters in a better way.
const query = new URLSearchParams(window.location.search);
const configUrl = query.get('configUrl');
const dataSourceName = pathname.substring(dataSourceIdx + 1);
const existingDataSource = extensionManager.getDataSources(dataSourceName);
const searchQuery = new URLSearchParams();
if (dataSourceIdx !== -1) {
if (dataSourceIdx !== -1 && existingDataSource) {
searchQuery.append('datasources', pathname.substring(dataSourceIdx + 1));
}
@ -66,7 +69,7 @@ function ViewerLayout({
navigate({
pathname: '/',
search: decodeURIComponent(searchQuery.toString()),
search: decodeURIComponent(searchQuery.toString())
});
};

View File

@ -63,7 +63,7 @@ const extensionDependencies = {
'@ohif/extension-dicom-video': '^3.0.1',
};
function modeFactory() {
function modeFactory({ modeConfiguration }) {
let _activatePanelTriggersSubscriptions = [];
return {
// TODO: We're using this as a route segment
@ -244,6 +244,7 @@ function modeFactory() {
dicomRt.sopClassHandler,
],
hotkeys: [...hotkeys.defaults.hotkeyBindings],
...modeConfiguration,
};
}

View File

@ -36,7 +36,7 @@ const extensionDependencies = {
'@ohif/extension-dicom-microscopy': '^3.0.0',
};
function modeFactory() {
function modeFactory({ modeConfiguration }) {
return {
// TODO: We're using this as a route segment
// We should not be.
@ -130,6 +130,7 @@ function modeFactory() {
dicompdf.sopClassHandler,
],
hotkeys: [...hotkeys.defaults.hotkeyBindings],
...modeConfiguration,
};
}

View File

@ -238,6 +238,7 @@ function modeFactory({ modeConfiguration }) {
hangingProtocol: tmtv.hangingProtocol,
sopClassHandlers: [ohif.sopClassHandler],
hotkeys: [...hotkeys.defaults.hotkeyBindings],
...modeConfiguration,
};
}

View File

@ -108,12 +108,12 @@ async function appInit(appConfigOrFunc, defaultExtensions, defaultModes) {
if (mode.modeFactory) {
// If the appConfig contains configuration for this mode, use it.
const modeConfig =
appConfig.modeConfig && appConfig.modeConfig[i]
? appConfig.modeConfig[id]
const modeConfiguration =
appConfig.modesConfiguration && appConfig.modesConfiguration[id]
? appConfig.modesConfiguration[id]
: {};
mode = mode.modeFactory(modeConfig);
mode = mode.modeFactory({ modeConfiguration });
}
if (modesById.has(id)) continue;

View File

@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
import { DicomMetadataStore, ServicesManager, utils } from '@ohif/core';
import { DragAndDropProvider, ImageViewerProvider } from '@ohif/ui';
import { useSearchParams } from '@hooks';
import { useAppConfig } from '@state';
import ViewportGrid from '@components/ViewportGrid';
import Compose from './Compose';
import getStudies from './studiesList';
@ -93,6 +94,8 @@ export default function ModeRoute({
commandsManager,
hotkeysManager,
}) {
const [appConfig] = useAppConfig();
// Parse route params/querystring
const location = useLocation();
@ -313,6 +316,7 @@ export default function ModeRoute({
servicesManager,
extensionManager,
commandsManager,
appConfig,
});
// use the URL hangingProtocolId if it exists, otherwise use the one
@ -403,6 +407,7 @@ export default function ModeRoute({
mode?.onModeExit?.({
servicesManager,
extensionManager,
appConfig,
});
} catch (e) {
console.warn('mode exit failure', e);

View File

@ -361,7 +361,7 @@ function WorkList({
query.append('configUrl', filterValues.configUrl);
}
query.append('StudyInstanceUIDs', studyInstanceUid);
return (
return mode.displayName && (
<Link
className={isValidMode ? '' : 'cursor-not-allowed'}
key={i}

View File

@ -6,7 +6,10 @@ export default function formatPN(name) {
return;
}
const nameToUse = name.Alphabetic ?? name;
let nameToUse = name.Alphabetic ?? name;
if (typeof nameToUse === 'object') {
nameToUse = '';
}
// Convert the first ^ to a ', '. String.replace() only affects
// the first appearance of the character.

View File

@ -119,6 +119,58 @@ Here are a list of some options available:
- `omitQuotationForMultipartRequest`: Some servers (e.g., .NET) require the `multipart/related` request to be sent without quotation marks. Defaults to `false`. If your server doesn't require this, then setting this flag to `true` might improve performance (by removing the need for preflight requests). Also note that
if auth headers are used, a preflight request is required.
- `maxNumRequests`: The maximum number of requests to allow in parallel. It is an object with keys of `interaction`, `thumbnail`, and `prefetch`. You can specify a specific number for each type.
- `modesConfiguration`: Allows overriding modes configuration.
- Example config:
```js
modesConfiguration: {
'@ohif/mode-longitudinal': {
displayName: 'Custom Name',
routeName: 'customRouteName',
routes: [
{
path: 'customPath',
layoutTemplate: () => {
/** Custom Layout */
return {
id: ohif.layout,
props: {
leftPanels: [tracked.thumbnailList],
rightPanels: [dicomSeg.panel, tracked.measurements],
rightPanelDefaultClosed: true,
viewports: [
{
namespace: tracked.viewport,
displaySetsToDisplay: [ohif.sopClassHandler],
},
],
},
};
},
},
],
}
},
```
Note: Although the mode configuration is passed to the mode factory function, it is up to the particular mode itself if its going to use it to allow overwriting its original configuration e.g.
```js
function modeFactory({ modeConfiguration }) {
return {
id,
routeName: 'viewer',
displayName: 'Basic Viewer',
...
onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
...
},
/**
* This mode allows its configuration to be overwritten by
* destructuring the modeConfiguration value from the mode fatory function
* at the end of the mode configuration definition.
*/
...modeConfiguration,
};
}
```
- `showLoadingIndicator`: (default to true), if set to false, the loading indicator will not be shown when navigating between studies.
- `dangerouslyUseDynamicConfig`: Dynamic config allows user to pass `configUrl` query string. This allows to load config without recompiling application. If the `configUrl` query string is passed, the worklist and modes will load from the referenced json rather than the default .env config. If there is no `configUrl` path provided, the default behaviour is used and there should not be any deviation from current user experience.<br/>
Points to consider while using `dangerouslyUseDynamicConfig`:<br/>