diff --git a/extensions/default/src/ViewerLayout/ViewerHeader.tsx b/extensions/default/src/ViewerLayout/ViewerHeader.tsx
new file mode 100644
index 000000000..6b7f5bfd3
--- /dev/null
+++ b/extensions/default/src/ViewerLayout/ViewerHeader.tsx
@@ -0,0 +1,118 @@
+import React from 'react';
+import { useNavigate } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+import { useLocation } from 'react-router';
+
+import { ErrorBoundary, UserPreferences, AboutModal, Header, useModal } from '@ohif/ui';
+import i18n from '@ohif/i18n';
+import { hotkeys } from '@ohif/core';
+import { useAppConfig } from '@state';
+import Toolbar from '../Toolbar/Toolbar';
+
+const { availableLanguages, defaultLanguage, currentLanguage } = i18n;
+
+function ViewerHeader({ hotkeysManager, extensionManager, servicesManager }) {
+ const [appConfig] = useAppConfig();
+ const navigate = useNavigate();
+ const location = useLocation();
+
+ const onClickReturnButton = () => {
+ const { pathname } = location;
+ const dataSourceIdx = pathname.indexOf('/', 1);
+ 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 && existingDataSource) {
+ searchQuery.append('datasources', pathname.substring(dataSourceIdx + 1));
+ }
+
+ if (configUrl) {
+ searchQuery.append('configUrl', configUrl);
+ }
+
+ navigate({
+ pathname: '/',
+ search: decodeURIComponent(searchQuery.toString()),
+ });
+ };
+
+ const { t } = useTranslation();
+ const { show, hide } = useModal();
+ const { hotkeyDefinitions, hotkeyDefaults } = hotkeysManager;
+ const versionNumber = process.env.VERSION_NUMBER;
+ const commitHash = process.env.COMMIT_HASH;
+
+ const menuOptions = [
+ {
+ title: t('Header:About'),
+ icon: 'info',
+ onClick: () =>
+ show({
+ content: AboutModal,
+ title: 'About OHIF Viewer',
+ contentProps: { versionNumber, commitHash },
+ }),
+ },
+ {
+ title: t('Header:Preferences'),
+ icon: 'settings',
+ onClick: () =>
+ show({
+ title: t('UserPreferencesModal:User Preferences'),
+ content: UserPreferences,
+ contentProps: {
+ hotkeyDefaults: hotkeysManager.getValidHotkeyDefinitions(hotkeyDefaults),
+ hotkeyDefinitions,
+ currentLanguage: currentLanguage(),
+ availableLanguages,
+ defaultLanguage,
+ onCancel: () => {
+ hotkeys.stopRecord();
+ hotkeys.unpause();
+ hide();
+ },
+ onSubmit: ({ hotkeyDefinitions, language }) => {
+ if (language.value !== currentLanguage().value) {
+ i18n.changeLanguage(language.value);
+ }
+ hotkeysManager.setHotkeys(hotkeyDefinitions);
+ hide();
+ },
+ onReset: () => hotkeysManager.restoreDefaultBindings(),
+ hotkeysModule: hotkeys,
+ },
+ }),
+ },
+ ];
+
+ if (appConfig.oidc) {
+ menuOptions.push({
+ title: t('Header:Logout'),
+ icon: 'power-off',
+ onClick: async () => {
+ navigate(`/logout?redirect_uri=${encodeURIComponent(window.location.href)}`);
+ },
+ });
+ }
+
+ return (
+
+ );
+}
+
+export default ViewerHeader;
diff --git a/extensions/default/src/ViewerLayout/index.tsx b/extensions/default/src/ViewerLayout/index.tsx
index 7feb08be4..d7e4335ca 100644
--- a/extensions/default/src/ViewerLayout/index.tsx
+++ b/extensions/default/src/ViewerLayout/index.tsx
@@ -1,24 +1,10 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
-import { useNavigate } from 'react-router-dom';
-import { useTranslation } from 'react-i18next';
-import { useLocation } from 'react-router';
-import {
- SidePanel,
- ErrorBoundary,
- UserPreferences,
- AboutModal,
- Header,
- useModal,
- LoadingIndicatorProgress,
-} from '@ohif/ui';
-import i18n from '@ohif/i18n';
-import { ServicesManager, HangingProtocolService, hotkeys, CommandsManager } from '@ohif/core';
+import { SidePanel, ErrorBoundary, LoadingIndicatorProgress } from '@ohif/ui';
+import { ServicesManager, HangingProtocolService, CommandsManager } from '@ohif/core';
import { useAppConfig } from '@state';
-import Toolbar from '../Toolbar/Toolbar';
-
-const { availableLanguages, defaultLanguage, currentLanguage } = i18n;
+import ViewerHeader from './ViewerHeader';
function ViewerLayout({
// From Extension Module Params
@@ -35,100 +21,9 @@ function ViewerLayout({
rightPanelDefaultClosed = false,
}): React.FunctionComponent {
const [appConfig] = useAppConfig();
- const navigate = useNavigate();
- const location = useLocation();
-
- const onClickReturnButton = () => {
- const { pathname } = location;
- const dataSourceIdx = pathname.indexOf('/', 1);
- // const search =
- // 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 && existingDataSource) {
- searchQuery.append('datasources', pathname.substring(dataSourceIdx + 1));
- }
-
- if (configUrl) {
- searchQuery.append('configUrl', configUrl);
- }
-
- navigate({
- pathname: '/',
- search: decodeURIComponent(searchQuery.toString()),
- });
- };
-
- const { t } = useTranslation();
- const { show, hide } = useModal();
-
- const [showLoadingIndicator, setShowLoadingIndicator] = useState(appConfig.showLoadingIndicator);
const { hangingProtocolService } = servicesManager.services;
-
- const { hotkeyDefinitions, hotkeyDefaults } = hotkeysManager;
- const versionNumber = process.env.VERSION_NUMBER;
- const commitHash = process.env.COMMIT_HASH;
-
- const menuOptions = [
- {
- title: t('Header:About'),
- icon: 'info',
- onClick: () =>
- show({
- content: AboutModal,
- title: 'About OHIF Viewer',
- contentProps: { versionNumber, commitHash },
- }),
- },
- {
- title: t('Header:Preferences'),
- icon: 'settings',
- onClick: () =>
- show({
- title: t('UserPreferencesModal:User Preferences'),
- content: UserPreferences,
- contentProps: {
- hotkeyDefaults: hotkeysManager.getValidHotkeyDefinitions(hotkeyDefaults),
- hotkeyDefinitions,
- currentLanguage: currentLanguage(),
- availableLanguages,
- defaultLanguage,
- onCancel: () => {
- hotkeys.stopRecord();
- hotkeys.unpause();
- hide();
- },
- onSubmit: ({ hotkeyDefinitions, language }) => {
- i18n.changeLanguage(language.value);
- hotkeysManager.setHotkeys(hotkeyDefinitions);
- hide();
- },
- onReset: () => hotkeysManager.restoreDefaultBindings(),
- hotkeysModule: hotkeys,
- },
- }),
- },
- ];
-
- if (appConfig.oidc) {
- menuOptions.push({
- title: t('Header:Logout'),
- icon: 'power-off',
- onClick: async () => {
- navigate(`/logout?redirect_uri=${encodeURIComponent(window.location.href)}`);
- },
- });
- }
+ const [showLoadingIndicator, setShowLoadingIndicator] = useState(appConfig.showLoadingIndicator);
/**
* Set body classes (tailwindcss) that don't allow vertical
@@ -210,18 +105,11 @@ function ViewerLayout({
return (
-
+
{
- i18n.changeLanguage(state.language.value);
+ if (state.language.value !== currentLanguage().value) {
+ i18n.changeLanguage(state.language.value);
+ }
hotkeysManager.setHotkeys(state.hotkeyDefinitions);
hide();
},