diff --git a/extensions/cornerstone/src/commandsModule.js b/extensions/cornerstone/src/commandsModule.js
index 318abe9ab..35947091e 100644
--- a/extensions/cornerstone/src/commandsModule.js
+++ b/extensions/cornerstone/src/commandsModule.js
@@ -242,6 +242,18 @@ const commandsModule = ({ servicesManager }) => {
setCornerstoneLayout: () => {
setCornerstoneLayout();
},
+ setWindowLevel: ({ viewports, window, level }) => {
+ const enabledElement = getEnabledElement(viewports.activeViewportIndex);
+
+ if (enabledElement) {
+ let viewport = cornerstone.getViewport(enabledElement);
+ viewport.voi = {
+ windowWidth: Number(window),
+ windowCenter: Number(level),
+ };
+ cornerstone.setViewport(enabledElement, viewport);
+ }
+ },
};
const definitions = {
@@ -347,6 +359,11 @@ const commandsModule = ({ servicesManager }) => {
options: {},
context: 'VIEWER',
},
+ setWindowLevel: {
+ commandFn: actions.setWindowLevel,
+ storeContexts: ['viewports'],
+ options: {},
+ },
};
return {
diff --git a/platform/core/src/redux/actions.js b/platform/core/src/redux/actions.js
index 4ac0c14b7..259e91ca1 100644
--- a/platform/core/src/redux/actions.js
+++ b/platform/core/src/redux/actions.js
@@ -10,6 +10,7 @@ import {
SET_VIEWPORT_ACTIVE,
SET_VIEWPORT_LAYOUT,
SET_VIEWPORT_LAYOUT_AND_DATA,
+ SET_USER_PREFERENCES,
} from './constants/ActionTypes.js';
/**
@@ -89,7 +90,7 @@ export const clearStudyLoadingProgress = progressId => ({
});
export const setUserPreferences = state => ({
- type: 'SET_USER_PREFERENCES',
+ type: SET_USER_PREFERENCES,
state,
});
diff --git a/platform/core/src/redux/constants/ActionTypes.js b/platform/core/src/redux/constants/ActionTypes.js
index 4a9cdccf4..e5167beb9 100644
--- a/platform/core/src/redux/constants/ActionTypes.js
+++ b/platform/core/src/redux/constants/ActionTypes.js
@@ -20,3 +20,8 @@ export const SET_SERVERS = 'SET_SERVERS';
* EXTENSIONS
*/
export const SET_EXTENSION_DATA = 'SET_EXTENSION_DATA';
+
+/**
+ * PREFERENCES
+ * */
+export const SET_USER_PREFERENCES = 'SET_USER_PREFERENCES';
diff --git a/platform/core/src/redux/reducers/preferences.js b/platform/core/src/redux/reducers/preferences.js
index 0af7754ab..2ec01c917 100644
--- a/platform/core/src/redux/reducers/preferences.js
+++ b/platform/core/src/redux/reducers/preferences.js
@@ -1,25 +1,30 @@
-import cloneDeep from 'lodash.clonedeep';
-
const defaultState = {
windowLevelData: {
- // order, description, window (int), level (int)
- // 0: { description: 'Soft tissue', window: '', level: '' },
+ 1: { description: 'Soft tissue', window: '550', level: '40' },
+ 2: { description: 'Lung', window: '150', level: '-600' },
+ 3: { description: 'Liver', window: '150', level: '90' },
+ 4: { description: 'Bone', window: '2500', level: '480' },
+ 5: { description: 'Brain', window: '80', level: '40' },
+ 6: { description: 'Trest', window: '1', level: '1' },
+ 7: { description: '', window: '', level: '' },
+ 8: { description: '', window: '', level: '' },
+ 9: { description: '', window: '', level: '' },
+ 10: { description: '', window: '', level: '' },
},
generalPreferences: {
// language: 'en-US'
},
};
-const preferences = (state, action) => {
+const preferences = (state = defaultState, action) => {
switch (action.type) {
case 'SET_USER_PREFERENCES': {
- const newState = action.state || cloneDeep(defaultState);
-
- return Object.assign({}, state, newState);
+ return Object.assign({}, state, action.state);
}
default:
- return cloneDeep(state) || cloneDeep(defaultState);
+ return state;
}
};
+export { defaultState };
export default preferences;
diff --git a/platform/core/src/redux/reducers/preferences.test.js b/platform/core/src/redux/reducers/preferences.test.js
new file mode 100644
index 000000000..fc81eaaac
--- /dev/null
+++ b/platform/core/src/redux/reducers/preferences.test.js
@@ -0,0 +1,31 @@
+import { Reducer } from 'redux-testkit';
+
+import reducer, { defaultState } from './preferences';
+import { SET_USER_PREFERENCES } from './../constants/ActionTypes.js';
+
+describe('preferences reducer', () => {
+ it('should return the initial state', () => {
+ expect(reducer(undefined, {})).toEqual(defaultState);
+ });
+
+ it('should set user preferences state and properly merge with current state', () => {
+ const initialState = defaultState;
+
+ const action = {
+ type: SET_USER_PREFERENCES,
+ state: { generalPreferences: { language: 'es' } },
+ };
+
+ const expectedState = {
+ windowLevelData: defaultState.windowLevelData,
+ generalPreferences: {
+ language: 'es',
+ },
+ };
+
+ Reducer(reducer)
+ .withState(initialState)
+ .expect(action)
+ .toReturnState(expectedState);
+ });
+});
diff --git a/platform/ui/src/components/tabComponents/TabComponents.js b/platform/ui/src/components/tabComponents/TabComponents.js
index c706bf499..5f312e0d1 100644
--- a/platform/ui/src/components/tabComponents/TabComponents.js
+++ b/platform/ui/src/components/tabComponents/TabComponents.js
@@ -46,7 +46,7 @@ function TabComponents({ tabs, customProps = {} }) {
{tabs.map((tab, index) => {
- const { name, hidden } = tab;
+ const { name, hidden = false } = tab;
return (
!hidden && (
-
{tabs.map((tab, index) => {
- const { Component, customProps: tabCustomProps, hidden } = tab;
+ const {
+ Component,
+ customProps: tabCustomProps,
+ hidden = false,
+ } = tab;
return (
!hidden && (
{
cy.get('.HotkeysPreferences').within(() => {
cy.contains('Rotate Right') // label we're looking for
.parent()
- .find('.errorMessage')
+ .find('.preferencesInputErrorMessage')
.as('errorMsg')
.should('have.text', '"Invert" is already using the "i" shortcut.');
});
@@ -440,7 +440,7 @@ describe('OHIF User Preferences', () => {
cy.get('.HotkeysPreferences').within(() => {
cy.contains('Rotate Right') // label we're looking for
.parent()
- .find('.errorMessage')
+ .find('.preferencesInputErrorMessage')
.as('errorMsg')
.should('have.text', '"ctrl+z" shortcut combination is not allowed');
});
@@ -461,7 +461,7 @@ describe('OHIF User Preferences', () => {
cy.get('.HotkeysPreferences').within(() => {
cy.contains('Zoom Out') // label we're looking for
.parent()
- .find('.errorMessage')
+ .find('.preferencesInputErrorMessage')
.as('errorMsg')
.should(
'have.text',
diff --git a/platform/viewer/public/config/default.js b/platform/viewer/public/config/default.js
index 063ff45bf..b65812b5a 100644
--- a/platform/viewer/public/config/default.js
+++ b/platform/viewer/public/config/default.js
@@ -69,6 +69,52 @@ window.config = {
},
// ~ Cornerstone Tools
{ commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
+ // ~ Window level presets
+ {
+ commandName: 'windowLevelPreset1',
+ label: 'W/L Preset 1',
+ keys: ['1'],
+ },
+ {
+ commandName: 'windowLevelPreset2',
+ label: 'W/L Preset 2',
+ keys: ['2'],
+ },
+ {
+ commandName: 'windowLevelPreset3',
+ label: 'W/L Preset 3',
+ keys: ['3'],
+ },
+ {
+ commandName: 'windowLevelPreset4',
+ label: 'W/L Preset 4',
+ keys: ['4'],
+ },
+ {
+ commandName: 'windowLevelPreset5',
+ label: 'W/L Preset 5',
+ keys: ['5'],
+ },
+ {
+ commandName: 'windowLevelPreset6',
+ label: 'W/L Preset 6',
+ keys: ['6'],
+ },
+ {
+ commandName: 'windowLevelPreset7',
+ label: 'W/L Preset 7',
+ keys: ['7'],
+ },
+ {
+ commandName: 'windowLevelPreset8',
+ label: 'W/L Preset 8',
+ keys: ['8'],
+ },
+ {
+ commandName: 'windowLevelPreset9',
+ label: 'W/L Preset 9',
+ keys: ['9'],
+ },
],
cornerstoneExtensionConfig: {},
};
diff --git a/platform/viewer/public/config/demo.js b/platform/viewer/public/config/demo.js
index 1fd296898..bf7640f55 100644
--- a/platform/viewer/public/config/demo.js
+++ b/platform/viewer/public/config/demo.js
@@ -58,6 +58,52 @@ window.config = {
keys: ['pageup'],
},
{ commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
+ // ~ Window level presets
+ {
+ commandName: 'windowLevelPreset1',
+ label: 'W/L Preset 1',
+ keys: ['1'],
+ },
+ {
+ commandName: 'windowLevelPreset2',
+ label: 'W/L Preset 2',
+ keys: ['2'],
+ },
+ {
+ commandName: 'windowLevelPreset3',
+ label: 'W/L Preset 3',
+ keys: ['3'],
+ },
+ {
+ commandName: 'windowLevelPreset4',
+ label: 'W/L Preset 4',
+ keys: ['4'],
+ },
+ {
+ commandName: 'windowLevelPreset5',
+ label: 'W/L Preset 5',
+ keys: ['5'],
+ },
+ {
+ commandName: 'windowLevelPreset6',
+ label: 'W/L Preset 6',
+ keys: ['6'],
+ },
+ {
+ commandName: 'windowLevelPreset7',
+ label: 'W/L Preset 7',
+ keys: ['7'],
+ },
+ {
+ commandName: 'windowLevelPreset8',
+ label: 'W/L Preset 8',
+ keys: ['8'],
+ },
+ {
+ commandName: 'windowLevelPreset9',
+ label: 'W/L Preset 9',
+ keys: ['9'],
+ },
],
i18n: {
LOCIZE_PROJECTID: 'a8da3f9a-e467-4dd6-af33-474d582a0294',
diff --git a/platform/viewer/public/config/netlify.js b/platform/viewer/public/config/netlify.js
index d041010c5..81bdd0188 100644
--- a/platform/viewer/public/config/netlify.js
+++ b/platform/viewer/public/config/netlify.js
@@ -64,6 +64,52 @@ window.config = {
},
// ~ Cornerstone Tools
{ commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
+ // ~ Window level presets
+ {
+ commandName: 'windowLevelPreset1',
+ label: 'W/L Preset 1',
+ keys: ['1'],
+ },
+ {
+ commandName: 'windowLevelPreset2',
+ label: 'W/L Preset 2',
+ keys: ['2'],
+ },
+ {
+ commandName: 'windowLevelPreset3',
+ label: 'W/L Preset 3',
+ keys: ['3'],
+ },
+ {
+ commandName: 'windowLevelPreset4',
+ label: 'W/L Preset 4',
+ keys: ['4'],
+ },
+ {
+ commandName: 'windowLevelPreset5',
+ label: 'W/L Preset 5',
+ keys: ['5'],
+ },
+ {
+ commandName: 'windowLevelPreset6',
+ label: 'W/L Preset 6',
+ keys: ['6'],
+ },
+ {
+ commandName: 'windowLevelPreset7',
+ label: 'W/L Preset 7',
+ keys: ['7'],
+ },
+ {
+ commandName: 'windowLevelPreset8',
+ label: 'W/L Preset 8',
+ keys: ['8'],
+ },
+ {
+ commandName: 'windowLevelPreset9',
+ label: 'W/L Preset 9',
+ keys: ['9'],
+ },
],
i18n: {
LOCIZE_PROJECTID: 'a8da3f9a-e467-4dd6-af33-474d582a0294',
diff --git a/platform/viewer/src/appExtensions/GenericViewerCommands/commandsModule.js b/platform/viewer/src/appExtensions/GenericViewerCommands/commandsModule.js
index 7c9bd790c..fbc0da7e4 100644
--- a/platform/viewer/src/appExtensions/GenericViewerCommands/commandsModule.js
+++ b/platform/viewer/src/appExtensions/GenericViewerCommands/commandsModule.js
@@ -1,74 +1,140 @@
-import { redux, utils } from '@ohif/core';
+import { redux } from '@ohif/core';
import store from './../../store';
-const { setViewportActive, setActiveViewportSpecificData } = redux.actions;
-const actions = {
- updateActiveViewport: ({ viewports, direction }) => {
- const { viewportSpecificData, activeViewportIndex } = viewports;
- const maxIndex = Object.keys(viewportSpecificData).length - 1;
+const commandsModule = ({ commandsManager }) => {
+ const { setViewportActive, setActiveViewportSpecificData } = redux.actions;
- let newIndex = activeViewportIndex + direction;
- newIndex = newIndex > maxIndex ? 0 : newIndex;
- newIndex = newIndex < 0 ? maxIndex : newIndex;
+ const actions = {
+ updateActiveViewport: ({ viewports, direction }) => {
+ const { viewportSpecificData, activeViewportIndex } = viewports;
+ const maxIndex = Object.keys(viewportSpecificData).length - 1;
- store.dispatch(setViewportActive(newIndex));
- },
- updateViewportDisplaySet: ({ viewports, direction }) => {
- const viewportSpecificData = { ...viewports.viewportSpecificData };
- const activeViewport = viewportSpecificData[viewports.activeViewportIndex];
- const studyMetadata = utils.studyMetadataManager.get(
- activeViewport.studyInstanceUid
- );
+ let newIndex = activeViewportIndex + direction;
+ newIndex = newIndex > maxIndex ? 0 : newIndex;
+ newIndex = newIndex < 0 ? maxIndex : newIndex;
- if (!studyMetadata) {
- return;
- }
+ store.dispatch(setViewportActive(newIndex));
+ },
+ setWindowLevelPreset: ({ viewports, preset }) => {
+ const state = store.getState();
+ const { preferences = {} } = state;
+ const { window, level } =
+ preferences.windowLevelData && preferences.windowLevelData[preset];
- const allDisplaySets = studyMetadata.getDisplaySets();
- const currentDisplaySetIndex = allDisplaySets.findIndex(
- displaySet =>
- displaySet.displaySetInstanceUid ===
- activeViewport.displaySetInstanceUid
- );
- if (currentDisplaySetIndex < 0) {
- return;
- }
+ if (window && level) {
+ commandsManager.runCommand('setWindowLevel', {
+ viewports,
+ window,
+ level,
+ });
+ }
+ },
+ updateViewportDisplaySet: ({ viewports, direction }) => {
+ const viewportSpecificData = { ...viewports.viewportSpecificData };
+ const activeViewport =
+ viewportSpecificData[viewports.activeViewportIndex];
+ const studyMetadata = utils.studyMetadataManager.get(
+ activeViewport.studyInstanceUid
+ );
- const newDisplaySetIndex = currentDisplaySetIndex + direction;
- const newDisplaySetData = allDisplaySets[newDisplaySetIndex];
- if (!newDisplaySetData) {
- return;
- }
+ if (!studyMetadata) {
+ return;
+ }
- store.dispatch(setActiveViewportSpecificData(newDisplaySetData));
- },
+ const allDisplaySets = studyMetadata.getDisplaySets();
+ const currentDisplaySetIndex = allDisplaySets.findIndex(
+ displaySet =>
+ displaySet.displaySetInstanceUid ===
+ activeViewport.displaySetInstanceUid
+ );
+ if (currentDisplaySetIndex < 0) {
+ return;
+ }
+
+ const newDisplaySetIndex = currentDisplaySetIndex + direction;
+ const newDisplaySetData = allDisplaySets[newDisplaySetIndex];
+ if (!newDisplaySetData) {
+ return;
+ }
+
+ store.dispatch(setActiveViewportSpecificData(newDisplaySetData));
+ },
+ };
+
+ const definitions = {
+ // Next/Previous active viewport
+ incrementActiveViewport: {
+ commandFn: actions.updateActiveViewport,
+ storeContexts: ['viewports'],
+ options: { direction: 1 },
+ },
+ decrementActiveViewport: {
+ commandFn: actions.updateActiveViewport,
+ storeContexts: ['viewports'],
+ options: { direction: -1 },
+ },
+ // Window level Presets
+ windowLevelPreset1: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 1 },
+ },
+ windowLevelPreset2: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 2 },
+ },
+ windowLevelPreset3: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 3 },
+ },
+ windowLevelPreset4: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 4 },
+ },
+ windowLevelPreset5: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 5 },
+ },
+ windowLevelPreset6: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 6 },
+ },
+ windowLevelPreset7: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 7 },
+ },
+ windowLevelPreset8: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 8 },
+ },
+ windowLevelPreset9: {
+ commandFn: actions.setWindowLevelPreset,
+ storeContexts: ['viewports'],
+ options: { preset: 9 },
+ },
+ nextViewportDisplaySet: {
+ commandFn: actions.updateViewportDisplaySet,
+ storeContexts: ['viewports'],
+ options: { direction: 1 },
+ },
+ previousViewportDisplaySet: {
+ commandFn: actions.updateViewportDisplaySet,
+ storeContexts: ['viewports'],
+ options: { direction: -1 },
+ },
+ };
+
+ return {
+ definitions,
+ defaultContext: 'VIEWER',
+ };
};
-const definitions = {
- // Next/Previous active viewport
- incrementActiveViewport: {
- commandFn: actions.updateActiveViewport,
- storeContexts: ['viewports'],
- options: { direction: 1 },
- },
- decrementActiveViewport: {
- commandFn: actions.updateActiveViewport,
- storeContexts: ['viewports'],
- options: { direction: -1 },
- },
- nextViewportDisplaySet: {
- commandFn: actions.updateViewportDisplaySet,
- storeContexts: ['viewports'],
- options: { direction: 1 },
- },
- previousViewportDisplaySet: {
- commandFn: actions.updateViewportDisplaySet,
- storeContexts: ['viewports'],
- options: { direction: -1 },
- },
-};
-
-export default {
- definitions,
- defaultContext: 'VIEWER',
-};
+export default commandsModule;
diff --git a/platform/viewer/src/appExtensions/GenericViewerCommands/index.js b/platform/viewer/src/appExtensions/GenericViewerCommands/index.js
index 042fa32b1..866055a79 100644
--- a/platform/viewer/src/appExtensions/GenericViewerCommands/index.js
+++ b/platform/viewer/src/appExtensions/GenericViewerCommands/index.js
@@ -2,7 +2,7 @@ import commandsModule from './commandsModule.js';
export default {
id: 'generic-viewer-commands',
- getCommandsModule() {
- return commandsModule;
+ getCommandsModule({ commandsManager }) {
+ return commandsModule({ commandsManager });
},
};
diff --git a/platform/viewer/src/components/UserPreferences/HotkeysPreferences.js b/platform/viewer/src/components/UserPreferences/HotkeysPreferences.js
index 1800ee89c..fc8151075 100644
--- a/platform/viewer/src/components/UserPreferences/HotkeysPreferences.js
+++ b/platform/viewer/src/components/UserPreferences/HotkeysPreferences.js
@@ -168,9 +168,11 @@ function HotkeysPreferences({ onClose }) {
keys={keys}
modifier_keys={MODIFIER_KEYS}
handleChange={handleChange}
- classNames={'hotkeyInput'}
+ classNames={'preferencesInput'}
>
- {errorMessage}
+
+ {errorMessage}
+
);
diff --git a/platform/viewer/src/components/UserPreferences/HotkeysPreferences.styl b/platform/viewer/src/components/UserPreferences/HotkeysPreferences.styl
index e55870a28..75acde085 100644
--- a/platform/viewer/src/components/UserPreferences/HotkeysPreferences.styl
+++ b/platform/viewer/src/components/UserPreferences/HotkeysPreferences.styl
@@ -2,11 +2,6 @@
display: flex
padding: 20px
- .errorMessage
- color: var(--state-error-text)
- font-size: 10px
- text-transform: uppercase
-
.hotkeyTable
display: flex
flex-direction: row
@@ -40,28 +35,6 @@
flex-basis: 0
flex-grow: 1.5
- .hotkeyInput
- font-weight: 400
- cursor: pointer
- transition: background-color .3s ease,border-color .3s ease
- background-color: var(--ui-gray)
- color: var(--text-primary-color)
- border-color: var(--ui-border-coolor)
- border: 0
- border-radius: 2px
- font-size: 14px
- height: 30px
- width: 100%
- line-height: 16px
- padding: 8px 9px 6px
- text-align: center
-
- .hotkeyInput:focus
- border-color: var(--active-color)
- background-color: var(--ui-gray-dark)
- box-shadow: 0 0 0 2px var(--active-color) !important
- outline: 0
-
.hotkeyLabel
padding: 5px 15px 5px 0
text-align: right
@@ -69,5 +42,5 @@
flex-grow: 1.5
.stateError
- .hotkeyInput
+ .preferencesInput
background-color: var(--state-error)
diff --git a/platform/viewer/src/components/UserPreferences/UserPreferences.js b/platform/viewer/src/components/UserPreferences/UserPreferences.js
index dda64ba5d..a5f245945 100644
--- a/platform/viewer/src/components/UserPreferences/UserPreferences.js
+++ b/platform/viewer/src/components/UserPreferences/UserPreferences.js
@@ -8,24 +8,23 @@ import { HotkeysPreferences } from './HotkeysPreferences';
import { WindowLevelPreferences } from './WindowLevelPreferences';
import { GeneralPreferences } from './GeneralPreferences';
+import './UserPreferences.styl';
+
const tabs = [
{
name: 'Hotkeys',
Component: HotkeysPreferences,
customProps: {},
- hidden: false,
},
{
name: 'General',
Component: GeneralPreferences,
customProps: {},
- hidden: false,
},
{
name: 'Window Level',
Component: WindowLevelPreferences,
customProps: {},
- hidden: true,
},
];
diff --git a/platform/viewer/src/components/UserPreferences/UserPreferences.styl b/platform/viewer/src/components/UserPreferences/UserPreferences.styl
new file mode 100644
index 000000000..8b5eef5ff
--- /dev/null
+++ b/platform/viewer/src/components/UserPreferences/UserPreferences.styl
@@ -0,0 +1,26 @@
+.preferencesInputErrorMessage
+ color: var(--state-error-text)
+ font-size: 10px
+ text-transform: uppercase
+
+.preferencesInput
+ font-weight: 400
+ cursor: pointer
+ transition: background-color .3s ease,border-color .3s ease
+ background-color: var(--ui-gray)
+ color: var(--text-primary-color)
+ border-color: var(--ui-border-coolor)
+ border: 0
+ border-radius: 2px
+ font-size: 14px
+ height: 30px
+ width: 100%
+ line-height: 16px
+ padding: 8px 9px 6px
+ text-align: center
+
+.preferencesInput:focus
+ border-color: var(--active-color)
+ background-color: var(--ui-gray-dark)
+ box-shadow: 0 0 0 2px var(--active-color) !important
+ outline: 0
diff --git a/platform/viewer/src/components/UserPreferences/WindowLevelPreferences.js b/platform/viewer/src/components/UserPreferences/WindowLevelPreferences.js
index e3e0cc547..744c2bc9f 100644
--- a/platform/viewer/src/components/UserPreferences/WindowLevelPreferences.js
+++ b/platform/viewer/src/components/UserPreferences/WindowLevelPreferences.js
@@ -1,19 +1,115 @@
-import React from 'react';
+import React, { useState } from 'react';
import PropTypes from 'prop-types';
+import { useSelector, useDispatch } from 'react-redux';
+import { redux } from '@ohif/core';
-import { TabFooter } from '@ohif/ui';
+import { TabFooter, useSnackbarContext } from '@ohif/ui';
import { useTranslation } from 'react-i18next';
+const { actions } = redux;
+
+import './WindowLevelPreferences.styl';
+
function WindowLevelPreferences({ onClose }) {
+ const dispatch = useDispatch();
+
+ const windowLevelData = useSelector(state => {
+ const { preferences = {} } = state;
+ const { windowLevelData } = preferences;
+
+ return windowLevelData;
+ });
+
+ const [state, setState] = useState({
+ values: { ...windowLevelData },
+ });
+
const { t } = useTranslation('UserPreferencesModal');
const onResetPreferences = () => {};
- const onSave = () => {};
const hasErrors = false;
+ const onSave = () => {
+ dispatch(actions.setUserPreferences({ windowLevelData: state.values }));
+
+ onClose();
+
+ snackbar.show({
+ message: t('SaveMessage'),
+ type: 'success',
+ });
+ };
+
+ const snackbar = useSnackbarContext();
+
+ const handleInputChange = event => {
+ const $target = event.target;
+ const { key, inputname } = $target.dataset;
+ const inputValue = $target.value;
+
+ if (!state.values[key] || !state.values[key][inputname]) {
+ return;
+ }
+
+ setState(prevState => ({
+ ...prevState,
+ values: {
+ ...prevState.values,
+ [key]: {
+ ...prevState.values[key],
+ [inputname]: inputValue,
+ },
+ },
+ }));
+ };
return (
- Component content: {name}
- TDB!
+
+
+
+
Preset
+
Description
+
Window
+
Level
+
+ {Object.keys(state.values).map((key, index) => {
+ return (
+
+
{key}
+
+
+
+
+
+
+
+
+
+
+ );
+ })}
+
+