fix(Browser history): fixed NPE when navigating a study via browser history and history navigation is now available via the navigateHistory command (#3337)

* fix(Browser history):
- fixed an NPE when navigating to a different study via the URL
- exposed browser history navigation via a command

* Added documentation for the navigateHistory command.
Moved the history object from UI to viewer.
This commit is contained in:
Joe Boccanfuso 2023-04-27 10:46:23 -04:00 committed by GitHub
parent eea0ed487b
commit 51cb0519fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 88 additions and 1 deletions

View File

@ -11,6 +11,8 @@ import findViewportsByPosition, {
} from './findViewportsByPosition';
import { ContextMenuProps } from './CustomizeableContextMenu/types';
import { NavigateHistory } from './types/commandModuleTypes';
import { history } from '@ohif/viewer';
const { subscribeToNextViewportGridChange } = utils;
@ -480,6 +482,28 @@ const commandsModule = ({
}
},
/**
* Exposes the browser history navigation used by OHIF. This command can be used to either replace or
* push a new entry into the browser history. For example, the following will replace the current
* browser history entry with the specified relative URL which changes the study displayed to the
* study with study instance UID 1.2.3. Note that as a result of using `options.replace = true`, the
* page prior to invoking this command cannot be returned to via the browser back button.
*
* navigateHistory({
* to: 'viewer?StudyInstanceUIDs=1.2.3',
* options: { replace: true },
* });
*
* @param historyArgs - arguments for the history function;
* the `to` property is the URL;
* the `options.replace` is a boolean indicating if the current browser history entry
* should be replaced or a new entry pushed onto the history (stack); the default value
* for `replace` is false
*/
navigateHistory(historyArgs: NavigateHistory) {
history.navigate(historyArgs.to, historyArgs.options);
},
openDICOMTagViewer() {
const { activeViewportIndex, viewports } = viewportGridService.getState();
const activeViewportSpecificData = viewports[activeViewportIndex];
@ -540,6 +564,11 @@ const commandsModule = ({
storeContexts: [],
options: {},
},
navigateHistory: {
commandFn: actions.navigateHistory,
storeContexts: [],
options: {},
},
nextStage: {
commandFn: actions.deltaStage,
storeContexts: [],

View File

@ -0,0 +1,6 @@
export type NavigateHistory = {
to: string; // the URL to navigate to
options?: {
replace?: boolean; // replace or add/push to history?
};
};

View File

@ -149,6 +149,10 @@ function TrackedMeasurementsContextProvider(
activeViewport.displaySetInstanceUIDs[0]
);
if (!displaySet) {
return;
}
// If this is an SR produced by our SR SOPClassHandler,
// and it hasn't been loaded yet, do that now so we
// can check if it can be rehydrated or not.

View File

@ -313,3 +313,34 @@ function modeFactory() {
};
}
```
> How can I navigate to (or show) a different study via the browser history/URL?
There is a command that does this: `navigateHistory`. It takes an object
argument with the `NavigateHistory` type:
```
export type NavigateHistory = {
to: string; // the URL to navigate to
options?: {
replace?: boolean; // replace or add/push to history?
};
};
```
For instance one could bind a hot key to this command to show a specific study
like this...
```
{
commandName: 'navigateHistory',
commandOptions: {
to:
'/viewer?StudyInstanceUIDs=1.2.3',
},
context: 'DEFAULT',
label: 'Nav Study',
keys: ['n'],
isEditable: true,
},
```

View File

@ -5,6 +5,8 @@ import 'regenerator-runtime/runtime';
import App from './App';
import React from 'react';
import ReactDOM from 'react-dom';
import { history } from './utils/history';
/**
* EXTENSIONS AND MODES
* =================
@ -34,3 +36,5 @@ loadDynamicImports().then(() => {
ReactDOM.render(app, document.getElementById('root'));
});
});
export { history };

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState, useRef } from 'react';
import { useParams, useLocation } from 'react-router';
import { useParams, useLocation, useNavigate } from 'react-router';
import PropTypes from 'prop-types';
// TODO: DicomMetadataStore should be injected?
import { DicomMetadataStore, ServicesManager, utils } from '@ohif/core';
@ -8,6 +8,7 @@ import { useQuery, useSearchParams } from '@hooks';
import ViewportGrid from '@components/ViewportGrid';
import Compose from './Compose';
import getStudies from './studiesList';
import { history } from '../../utils/history';
const { getSplitParam } = utils;
@ -105,6 +106,9 @@ export default function ModeRoute({
const locationRef = useRef(null);
const isMounted = useRef(false);
// Expose the react router dom navigation.
history.navigate = useNavigate();
if (location !== locationRef.current) {
layoutTemplateData.current = null;
locationRef.current = location;

View File

@ -0,0 +1,9 @@
import { NavigateFunction } from 'react-router';
type History = {
navigate: NavigateFunction;
};
export const history: History = {
navigate: null,
};