Compare commits

...
Author SHA1 Message Date
ohif-bot 4bbf24b250 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.4.0
 - @ohif/extension-vtk@1.2.19
 - @ohif/core@2.5.0
 - @ohif/ui@1.3.0
 - @ohif/viewer@3.7.0
2020-02-20 22:04:03 +00:00
Gustavo André Lelis ebc01a8ca2 feat: #1342 - Window level tab (#1429)
* WindowLevel preset code changes

* Remove localStorage code as its already being saved and some small refactor on reducer/action

* Creating unit tests for preferences reducer

* Fix cypress after class naming change

* Make hidden false as default for tab components

* Remove addUserPreferences

* Small refactor to use commandsManager from getCommandsModule instead of getting it from App.js
2020-02-20 16:25:26 -05:00
ohif-bot 4fd0c6dfcb chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.3.1
 - @ohif/viewer@3.6.3
2020-02-14 20:56:06 +00:00
Gustavo André Lelis 06a4af06fa fix: Creating 2 commands to activate zoom tool and also to move between displaySets (#1446) 2020-02-14 15:54:08 -05:00
28 changed files with 612 additions and 123 deletions

No files matched your search

+22
View File
@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.4.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.3.1...@ohif/extension-cornerstone@2.4.0) (2020-02-20)
### Features
* [#1342](https://github.com/OHIF/Viewers/issues/1342) - Window level tab ([#1429](https://github.com/OHIF/Viewers/issues/1429)) ([ebc01a8](https://github.com/OHIF/Viewers/commit/ebc01a8ca238d5a3437b44d81f75aa8a5e8d0574))
## [2.3.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.3.0...@ohif/extension-cornerstone@2.3.1) (2020-02-14)
### Bug Fixes
* Creating 2 commands to activate zoom tool and also to move between displaySets ([#1446](https://github.com/OHIF/Viewers/issues/1446)) ([06a4af0](https://github.com/OHIF/Viewers/commit/06a4af06faaecf6fa06ccd90cdfa879ee8d53053))
# [2.3.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.2.2...@ohif/extension-cornerstone@2.3.0) (2020-02-10)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone",
"version": "2.3.0",
"version": "2.4.0",
"description": "OHIF extension for Cornerstone",
"author": "OHIF",
"license": "MIT",
+23 -17
View File
@@ -74,10 +74,6 @@ const commandsModule = ({ servicesManager }) => {
}
cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 });
},
updateViewportDisplaySet: ({ direction }) => {
// TODO
console.warn('updateDisplaySet: ', direction);
},
clearAnnotations: ({ viewports }) => {
const element = getEnabledElement(viewports.activeViewportIndex);
if (!element) {
@@ -245,7 +241,19 @@ 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 = {
@@ -334,30 +342,28 @@ const commandsModule = ({ servicesManager }) => {
storeContexts: ['viewports'],
options: {},
},
// TODO: First/Last image
// Next/Previous series/DisplaySet
nextViewportDisplaySet: {
commandFn: actions.updateViewportDisplaySet,
storeContexts: [],
options: { direction: 1 },
},
previousViewportDisplaySet: {
commandFn: actions.updateViewportDisplaySet,
storeContexts: [],
options: { direction: -1 },
},
// TOOLS
setToolActive: {
commandFn: actions.setToolActive,
storeContexts: [],
options: {},
},
setZoomTool: {
commandFn: actions.setToolActive,
storeContexts: [],
options: { toolName: 'Zoom' },
},
setCornerstoneLayout: {
commandFn: actions.setCornerstoneLayout,
storeContexts: [],
options: {},
context: 'VIEWER',
},
setWindowLevel: {
commandFn: actions.setWindowLevel,
storeContexts: ['viewports'],
options: {},
},
};
return {
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.2.19](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.2.18...@ohif/extension-vtk@1.2.19) (2020-02-20)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.2.18](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.2.17...@ohif/extension-vtk@1.2.18) (2020-02-12)
**Note:** Version bump only for package @ohif/extension-vtk
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-vtk",
"version": "1.2.18",
"version": "1.2.19",
"description": "OHIF extension for VTK.js",
"author": "OHIF",
"license": "MIT",
@@ -52,8 +52,8 @@
"react-vtkjs-viewport": "^0.8.3"
},
"devDependencies": {
"@ohif/core": "^2.4.1",
"@ohif/ui": "^1.2.1",
"@ohif/core": "^2.5.0",
"@ohif/ui": "^1.3.0",
"cornerstone-tools": "^4.12.0",
"cornerstone-wado-image-loader": "^3.0.0",
"dicom-parser": "^1.8.3",
+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.5.0](https://github.com/OHIF/Viewers/compare/@ohif/core@2.4.1...@ohif/core@2.5.0) (2020-02-20)
### Features
* [#1342](https://github.com/OHIF/Viewers/issues/1342) - Window level tab ([#1429](https://github.com/OHIF/Viewers/issues/1429)) ([ebc01a8](https://github.com/OHIF/Viewers/commit/ebc01a8ca238d5a3437b44d81f75aa8a5e8d0574))
## [2.4.1](https://github.com/OHIF/Viewers/compare/@ohif/core@2.4.0...@ohif/core@2.4.1) (2020-02-12)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/core",
"version": "2.4.1",
"version": "2.5.0",
"description": "Generic business logic for web-based medical imaging applications",
"author": "OHIF Core Team",
"license": "MIT",
+2 -1
View File
@@ -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,
});
@@ -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';
@@ -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;
@@ -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);
});
});
+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.3.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.2.1...@ohif/ui@1.3.0) (2020-02-20)
### Features
* [#1342](https://github.com/OHIF/Viewers/issues/1342) - Window level tab ([#1429](https://github.com/OHIF/Viewers/issues/1429)) ([ebc01a8](https://github.com/OHIF/Viewers/commit/ebc01a8ca238d5a3437b44d81f75aa8a5e8d0574))
## [1.2.1](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.2.0...@ohif/ui@1.2.1) (2020-02-12)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/ui",
"version": "1.2.1",
"version": "1.3.0",
"description": "A set of React components for Medical Imaging Viewers",
"author": "OHIF Contributors",
"license": "MIT",
@@ -46,7 +46,7 @@ function TabComponents({ tabs, customProps = {} }) {
<div className="dialog-separator-after">
<ul className="nav nav-tabs">
{tabs.map((tab, index) => {
const { name, hidden } = tab;
const { name, hidden = false } = tab;
return (
!hidden && (
<li
@@ -70,7 +70,11 @@ function TabComponents({ tabs, customProps = {} }) {
</div>
</div>
{tabs.map((tab, index) => {
const { Component, customProps: tabCustomProps, hidden } = tab;
const {
Component,
customProps: tabCustomProps,
hidden = false,
} = tab;
return (
!hidden && (
<div
+22
View File
@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.7.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.6.3...@ohif/viewer@3.7.0) (2020-02-20)
### Features
* [#1342](https://github.com/OHIF/Viewers/issues/1342) - Window level tab ([#1429](https://github.com/OHIF/Viewers/issues/1429)) ([ebc01a8](https://github.com/OHIF/Viewers/commit/ebc01a8ca238d5a3437b44d81f75aa8a5e8d0574))
## [3.6.3](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.6.2...@ohif/viewer@3.6.3) (2020-02-14)
### Bug Fixes
* Creating 2 commands to activate zoom tool and also to move between displaySets ([#1446](https://github.com/OHIF/Viewers/issues/1446)) ([06a4af0](https://github.com/OHIF/Viewers/commit/06a4af06faaecf6fa06ccd90cdfa879ee8d53053))
## [3.6.2](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.6.1...@ohif/viewer@3.6.2) (2020-02-12)
@@ -419,7 +419,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', '"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',
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/viewer",
"version": "3.6.2",
"version": "3.7.0",
"description": "OHIF Viewer",
"author": "OHIF Contributors",
"license": "MIT",
@@ -47,15 +47,15 @@
},
"dependencies": {
"@babel/runtime": "^7.5.5",
"@ohif/core": "^2.4.1",
"@ohif/extension-cornerstone": "^2.3.0",
"@ohif/core": "^2.5.0",
"@ohif/extension-cornerstone": "^2.4.0",
"@ohif/extension-dicom-html": "^1.1.0",
"@ohif/extension-dicom-microscopy": "^0.50.6",
"@ohif/extension-dicom-pdf": "^1.0.1",
"@ohif/extension-lesion-tracker": "^0.2.0",
"@ohif/extension-vtk": "^1.2.18",
"@ohif/extension-vtk": "^1.2.19",
"@ohif/i18n": "^0.52.6",
"@ohif/ui": "^1.2.1",
"@ohif/ui": "^1.3.0",
"@tanem/react-nprogress": "^1.1.25",
"classnames": "^2.2.6",
"core-js": "^3.2.1",
+48 -2
View File
@@ -58,17 +58,63 @@ window.config = {
// firstImage
// lastImage
{
commandName: 'nextViewportDisplaySet',
commandName: 'previousViewportDisplaySet',
label: 'Previous Series',
keys: ['pagedown'],
},
{
commandName: 'previousViewportDisplaySet',
commandName: 'nextViewportDisplaySet',
label: 'Next Series',
keys: ['pageup'],
},
// ~ 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: {},
};
+48 -2
View File
@@ -48,16 +48,62 @@ window.config = {
{ commandName: 'nextImage', label: 'Next Image', keys: ['down'] },
{ commandName: 'previousImage', label: 'Previous Image', keys: ['up'] },
{
commandName: 'nextViewportDisplaySet',
commandName: 'previousViewportDisplaySet',
label: 'Previous Series',
keys: ['pagedown'],
},
{
commandName: 'previousViewportDisplaySet',
commandName: 'nextViewportDisplaySet',
label: 'Next Series',
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',
+48 -2
View File
@@ -53,17 +53,63 @@ window.config = {
// firstImage
// lastImage
{
commandName: 'nextViewportDisplaySet',
commandName: 'previousViewportDisplaySet',
label: 'Previous Series',
keys: ['pagedown'],
},
{
commandName: 'previousViewportDisplaySet',
commandName: 'nextViewportDisplaySet',
label: 'Next Series',
keys: ['pageup'],
},
// ~ 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',
@@ -1,39 +1,140 @@
import { redux } from "@ohif/core";
import store from "./../../store";
const { setViewportActive } = redux.actions;
import { redux } from '@ohif/core';
import store from './../../store';
const actions = {
updateViewportDisplaySet: ({ direction }) => {
// TODO
// console.warn('updateDisplaySet: ', direction);
},
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));
}
let newIndex = activeViewportIndex + direction;
newIndex = newIndex > maxIndex ? 0 : newIndex;
newIndex = newIndex < 0 ? maxIndex : newIndex;
store.dispatch(setViewportActive(newIndex));
},
setWindowLevelPreset: ({ viewports, preset }) => {
const state = store.getState();
const { preferences = {} } = state;
const { window, level } =
preferences.windowLevelData && preferences.windowLevelData[preset];
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
);
if (!studyMetadata) {
return;
}
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 }
}
};
export default {
definitions,
defaultContext: "VIEWER"
};
export default commandsModule;
@@ -2,7 +2,7 @@ import commandsModule from './commandsModule.js';
export default {
id: 'generic-viewer-commands',
getCommandsModule() {
return commandsModule;
getCommandsModule({ commandsManager }) {
return commandsModule({ commandsManager });
},
};
@@ -168,9 +168,11 @@ function HotkeysPreferences({ onClose }) {
keys={keys}
modifier_keys={MODIFIER_KEYS}
handleChange={handleChange}
classNames={'hotkeyInput'}
classNames={'preferencesInput'}
></HotkeyField>
<span className="errorMessage">{errorMessage}</span>
<span className="preferencesInputErrorMessage">
{errorMessage}
</span>
</div>
</div>
);
@@ -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)
@@ -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,
},
];
@@ -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
@@ -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 (
<React.Fragment>
<div className="">Component content: {name}</div>
<div className="">TDB!</div>
<div className="WindowLevelPreferences">
<div className="wlColumn">
<div className="wlRow header">
<div className="wlColumn preset">Preset</div>
<div className="wlColumn description">Description</div>
<div className="wlColumn window">Window</div>
<div className="wlColumn level">Level</div>
</div>
{Object.keys(state.values).map((key, index) => {
return (
<div className="wlRow" key={key}>
<div className="wlColumn preset">{key}</div>
<div className="wlColumn description">
<input
type="text"
className="preferencesInput"
value={state.values[key].description}
data-key={key}
data-inputname="description"
onChange={handleInputChange}
/>
</div>
<div className="wlColumn window">
<input
type="number"
className="preferencesInput"
value={state.values[key].window}
data-key={key}
data-inputname="window"
onChange={handleInputChange}
/>
</div>
<div className="wlColumn level">
<input
type="number"
className="preferencesInput"
value={state.values[key].level}
data-key={key}
data-inputname="level"
onChange={handleInputChange}
/>
</div>
</div>
);
})}
</div>
</div>
<TabFooter
onResetPreferences={onResetPreferences}
onSave={onSave}
@@ -0,0 +1,28 @@
.WindowLevelPreferences
display: flex
padding: 20px 0
text-align: center
.wlColumn
display: flex
flex-direction: column
flex-basis: 0
flex-grow: 1.5
margin: 0 5px
.wlRow
display: flex
flex-direction: row
margin: 5px 0
.header
.preset
flex-grow: 0.5
.window,
.level
flex-grow: 1
.description
flex-grow: 2