Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions extensions/default/src/commandsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -540,6 +564,11 @@ const commandsModule = ({
storeContexts: [],
options: {},
},
navigateHistory: {
commandFn: actions.navigateHistory,
storeContexts: [],
options: {},
},
nextStage: {
commandFn: actions.deltaStage,
storeContexts: [],
Expand Down
6 changes: 6 additions & 0 deletions extensions/default/src/types/commandModuleTypes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type NavigateHistory = {
to: string; // the URL to navigate to
options?: {
replace?: boolean; // replace or add/push to history?
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
31 changes: 31 additions & 0 deletions platform/docs/docs/platform/modes/routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
```
4 changes: 4 additions & 0 deletions platform/viewer/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
* =================
Expand Down Expand Up @@ -34,3 +36,5 @@ loadDynamicImports().then(() => {
ReactDOM.render(app, document.getElementById('root'));
});
});

export { history };
6 changes: 5 additions & 1 deletion platform/viewer/src/routes/Mode/Mode.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions platform/viewer/src/utils/history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NavigateFunction } from 'react-router';

type History = {
navigate: NavigateFunction;
};

export const history: History = {
navigate: null,
};