fix: User Preferences Issues (#1207)

* fix: study list translations

* Don't render until translations are ready

* Try to wait for translations to load

* Use null to render "nothing"

* Try toggling useSuspense off up a layer

* logging

* Remove useSuspense false flags

* DO NOT OPEN A PR WITH IT.
Experimental changes only.
Try to solve issues with useTranslation hooks
 #Please enter the commit message for your changes. Lines starting

* Remove unecessary changes

* feat: 🎸 useMedia hook to not use one more prop for upd state vl

* docs: Add license scan report and status (#1161)

Signed-off-by: fossabot <badges@fossa.io>

* fix: 🐛 Fix for JS breaking on header (#1164)

* feat: 🎸 Code review and refact

Revised code based on PRs(variable alias,...). Changed hook for
useMedia. Now, it provides two hooks: one to get displayMediaSize and
other to get Entity(component, objects...) based on displayMediaSize.
Implemented a similar solution for state manager to store
mediaQueryList(s) and displaySize for app.

* feat: 🎸 Fine tunning on mediaQuery value, fixed issue about it

* fix: 🐛 Fixed issue and refactoring

Fixed js exception and also refactoring userPreferences components to
functional component

* fix: 🐛 Code review. Localstorage fix minor bugs

* fix: 🐛 Ensure hotkey lower case always

* fix: translation switcher

* chore(release): publish [skip ci]

 - @ohif/extension-vtk@0.53.6
 - @ohif/ui@0.62.1
 - @ohif/viewer@2.8.2

* Add new modal service

* Change serviceManager prop to servicesManager

* CR Update: fix casing and add required proptypes to providers

* CR Update: Improve ohifmodal proptypes

* CR Update: Fix typo in extensionmanager

* CR Update: add default props to service and check service in provider

* Refactor modal provider to better use its own state

* ci: don't build our master branch (#1177)

* ci: don't build our master branch

* Add netlify-cli as a dev dependency

* ci: trying a sheltered merge flow for promotions

* Use modal instead of modal context

* Ci/promotable builds (#1179)

* ci: don't build our master branch

* Add netlify-cli as a dev dependency

* ci: trying a sheltered merge flow for promotions

* ci: try building with QUICK_BUILD flag

* Change modal children order

* Ci/promotable builds (#1180)

* ci: don't build our master branch

* Add netlify-cli as a dev dependency

* ci: trying a sheltered merge flow for promotions

* ci: try building with QUICK_BUILD flag

* Try using ~/repo prefix in command

* Ci/promotable builds (#1181)

* ci: don't build our master branch

* Add netlify-cli as a dev dependency

* ci: trying a sheltered merge flow for promotions

* ci: try building with QUICK_BUILD flag

* Try using ~/repo prefix in command

* ci: make sure netlify command is available

* Ci/promotable builds (#1182)

* ci: don't build our master branch

* Add netlify-cli as a dev dependency

* ci: trying a sheltered merge flow for promotions

* ci: try building with QUICK_BUILD flag

* Try using ~/repo prefix in command

* ci: make sure netlify command is available

* ci: use sudo for global command

* Fix OHIFModal proptypes

* Ci/promotable builds (#1183)

* ci: don't build our master branch

* Add netlify-cli as a dev dependency

* ci: trying a sheltered merge flow for promotions

* ci: try building with QUICK_BUILD flag

* Try using ~/repo prefix in command

* ci: make sure netlify command is available

* ci: use sudo for global command

* Inline personal access token w/ env var

* Ci/promotable builds (#1184)

* ci: don't build our master branch

* Add netlify-cli as a dev dependency

* ci: trying a sheltered merge flow for promotions

* ci: try building with QUICK_BUILD flag

* Try using ~/repo prefix in command

* ci: make sure netlify command is available

* ci: use sudo for global command

* Inline personal access token w/ env var

* ci: workaround for sudo limitations

* ci: restore release workflow (#1185)

* ci: don't build our master branch

* Add netlify-cli as a dev dependency

* ci: trying a sheltered merge flow for promotions

* ci: try building with QUICK_BUILD flag

* Try using ~/repo prefix in command

* ci: make sure netlify command is available

* ci: use sudo for global command

* Inline personal access token w/ env var

* ci: workaround for sudo limitations

* ci: restore release workflow

* Pass services to each module, improve tests

* Add servicesManager test and registerServices method

* Fix key warning of snackbar elements

* Remove netlify-cli; we';ll install this on CI server

* Update staging and prod netlify site IDs

* Clean up NPM_PUBLISH step

* Clean up DOCS_PUBLISH step

* Clean up Deploy workflow

* Custom executor to override cypress config

* Spacing

* Use an existing docker hub image

* Switch to npx instead of digging into npm bin location

* Remove e2e test before prod deploy

* Add workflow images

* docs: continous integrationn

* Add default props to modal

* chore(release): publish [skip ci]

 - @ohif/extension-cornerstone@1.5.1
 - @ohif/extension-vtk@0.53.7
 - @ohif/core@1.9.1
 - @ohif/ui@0.62.2
 - @ohif/viewer@2.8.3

* chore(release): publish [skip ci]

 - @ohif/extension-vtk@0.53.8
 - @ohif/core@1.10.0
 - @ohif/ui@0.62.3
 - @ohif/viewer@2.8.4

* ci: Redirect site traffic to index.html if file is not resolved

* ci: fix typo

* fix: 🐛 Code review. Remove 'global state' for displaySize

* fix: 🐛 Code review. Ref back to useMedia and pass value down

Code review. Ref back to useMedia and pass value down (components)
instead of creating a specialized hook to tied any component on it

* fix: translation switcher

* fix

* cleanup

* add missed translation

* fix: 🐛 Code review

* fix: 🐛 Fix unit tests

* fix: 🐛 Fix unit test

* fix: 🐛 Code merge solve conflicts. Missing files changes

* Merge from master. Missing files changes

* feat: 🎸 Code review. Fix issues with DatePicker

Fixed at least the minimum issue with datePicker and update some content
on every translation changed

* fix: 🐛 Code review. Style fix on modal

* fixes in general preferences after merge

* fix

* export default i18n language

* translation fixes

* increase snackbar zindex

* initialize language

* WIP propagate props<>state fixes

* fix state propagation

* remove hotkey error when reset default

* fix datePicker

* i18n updates

* fix i18n strings

* fix reset default -- set right input value

* fix default language

* fix e2e for user preferences

* small fix datePicker props

* remove i18n from window -- debugging purposes only

* lint fixes
This commit is contained in:
Rodrigo Antinarelli authored and Danny Brown committed 2019-11-28 00:48:27 -05:00
1 parent fd1a9e2abe
commit 1df21a9e07
31 files changed
+1332 -737

No files matched your search

+24 -2
View File
@@ -23,6 +23,7 @@ import {
createUIModalService,
createUIDialogService,
utils,
redux as reduxOHIF
} from '@ohif/core';
import i18n from '@ohif/i18n';
@@ -45,6 +46,7 @@ import OHIFStandaloneViewer from './OHIFStandaloneViewer';
/** Store */
import { getActiveContexts } from './store/layout/selectors.js';
import store from './store';
const { setUserPreferences } = reduxOHIF.actions;
/** Contexts */
import WhiteLabellingContext from './context/WhiteLabellingContext';
@@ -221,9 +223,29 @@ function _initExtensions(extensions, hotkeys) {
const mergedExtensions = defaultExtensions.concat(extensions);
extensionManager.registerExtensions(mergedExtensions);
const { hotkeyDefinitions = {} } = store.getState().preferences || {};
let updateStore = false;
let hotkeysToUse = hotkeyDefinitions;
// Must run after extension commands are registered
if (hotkeys) {
hotkeysManager.setHotkeys(hotkeys, true);
// if there is no hotkeys from localStorate set up from config
if (!Object.keys(hotkeyDefinitions).length) {
hotkeysToUse = hotkeys;
updateStore = true;
}
if (hotkeysToUse) {
hotkeysManager.setHotkeys(hotkeysToUse);
// set default based on app config
hotkeysManager.setDefaultHotKeys(hotkeys);
if (updateStore) {
const { hotkeyDefinitions } = hotkeysManager;
const windowLevelData = {};
store.dispatch(
setUserPreferences({ windowLevelData, hotkeyDefinitions })
);
}
}
}
+73 -72
View File
@@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React, { useState, useEffect } from 'react';
import { Link, withRouter } from 'react-router-dom';
import { withTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
@@ -11,49 +11,37 @@ import './Header.css';
// Context
import AppContext from './../../context/AppContext';
class Header extends Component {
static contextType = AppContext;
static propTypes = {
home: PropTypes.bool.isRequired,
location: PropTypes.object.isRequired,
children: PropTypes.node,
t: PropTypes.func.isRequired,
userManager: PropTypes.object,
user: PropTypes.object,
modal: PropTypes.object,
};
function Header(props) {
const {
t,
user,
userManager,
modal: { show },
home,
location,
children,
} = props;
static defaultProps = {
home: true,
children: OHIFLogo(),
};
const [options, setOptions] = useState([]);
constructor(props) {
super(props);
this.state = { isOpen: false };
this.loadOptions();
}
loadOptions() {
const { t, user, userManager, modal } = this.props;
this.options = [
useEffect(() => {
const optionsValue = [
{
title: t('About'),
icon: { name: 'info' },
onClick: () =>
modal.show({
show({
content: AboutContent,
title: t('OHIF Viewer - About'),
}),
},
{
title: 'Preferences ',
title: t('Preferences'),
icon: {
name: 'user',
},
onClick: () =>
modal.show({
show({
content: ConnectedUserPreferencesForm,
title: t('User Preferences'),
}),
@@ -61,61 +49,74 @@ class Header extends Component {
];
if (user && userManager) {
this.options.push({
optionsValue.push({
title: t('Logout'),
icon: { name: 'power-off' },
onClick: () => userManager.signoutRedirect(),
});
}
}
setOptions(optionsValue);
}, [setOptions, show, t, user, userManager]);
const { appConfig = {} } = AppContext;
const showStudyList =
appConfig.showStudyList !== undefined ? appConfig.showStudyList : true;
// ANTD -- Hamburger, Drawer, Menu
render() {
const { t, home, location, children } = this.props;
const { appConfig = {} } = this.context;
const showStudyList =
appConfig.showStudyList !== undefined ? appConfig.showStudyList : true;
return (
<>
<div className="notification-bar">{t('INVESTIGATIONAL USE ONLY')}</div>
<div className={`entry-header ${home ? 'header-big' : ''}`}>
<div className="header-left-box">
{location && location.studyLink && (
<Link
to={location.studyLink}
className="header-btn header-viewerLink"
>
{t('Back to Viewer')}
</Link>
)}
return (
<>
<div className="notification-bar">{t('INVESTIGATIONAL USE ONLY')}</div>
<div className={`entry-header ${home ? 'header-big' : ''}`}>
<div className="header-left-box">
{location && location.studyLink && (
<Link
to={location.studyLink}
className="header-btn header-viewerLink"
>
{t('Back to Viewer')}
</Link>
)}
{children}
{children}
{showStudyList && !home && (
<Link
className="header-btn header-studyListLinkSection"
to={{
pathname: '/',
state: { studyLink: location.pathname },
}}
>
{t('Study list')}
</Link>
)}
</div>
<div className="header-menu">
<span className="research-use">
{t('INVESTIGATIONAL USE ONLY')}
</span>
<Dropdown title={t('Options')} list={this.options} align="right" />
</div>
{showStudyList && !home && (
<Link
className="header-btn header-studyListLinkSection"
to={{
pathname: '/',
state: { studyLink: location.pathname },
}}
>
{t('Study list')}
</Link>
)}
</div>
</>
);
}
<div className="header-menu">
<span className="research-use">{t('INVESTIGATIONAL USE ONLY')}</span>
<Dropdown title={t('Options')} list={options} align="right" />
</div>
</div>
</>
);
}
Header.propTypes = {
home: PropTypes.bool.isRequired,
location: PropTypes.object.isRequired,
children: PropTypes.node,
t: PropTypes.func.isRequired,
userManager: PropTypes.object,
user: PropTypes.object,
modal: PropTypes.object,
};
Header.defaultProps = {
home: true,
children: OHIFLogo(),
};
export default withTranslation(['Header', 'AboutModal'])(
withRouter(withModal(Header))
);
@@ -1,17 +1,7 @@
import Header from '../components/Header/Header.js';
import { connect } from 'react-redux';
import { hotkeysManager } from '../App.js';
const mapStateToProps = state => {
const { hotkeyDefinitions = [] } = state.preferences || {};
const _hotkeyDefinitions =
hotkeyDefinitions.length > 0
? hotkeyDefinitions
: hotkeysManager.hotkeyDefaults;
hotkeysManager.setHotkeys(_hotkeyDefinitions);
return {
user: state.oidc && state.oidc.user,
};
@@ -1,34 +1,48 @@
import { connect } from 'react-redux';
import { UserPreferencesForm } from '@ohif/ui';
import OHIF from '@ohif/core';
import i18n from '@ohif/i18n';
import { hotkeysManager } from '../App.js';
const { setUserPreferences } = OHIF.redux.actions;
const mapStateToProps = (state, ownProps) => {
const hotkeyDefinitions =
state.preferences.hotkeyDefinitions.length > 0
? state.preferences.hotkeyDefinitions
: hotkeysManager.hotkeyDefaults;
hotkeysManager.setHotkeys(hotkeyDefinitions);
const { defaultLanguage } = i18n;
const { hotkeyDefinitions, windowLevelData = {}, generalPreferences } =
state.preferences || {};
const { hotkeyDefaults } = hotkeysManager;
return {
onClose: ownProps.hide,
windowLevelData: state.preferences ? state.preferences.windowLevelData : {},
windowLevelData,
hotkeyDefinitions,
generalPreferences,
hotkeysManager,
hotkeyDefaults,
defaultLanguage,
};
};
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onSave: ({ windowLevelData, hotkeyDefinitions }) => {
onSave: ({ windowLevelData, hotkeyDefinitions, generalPreferences }) => {
// TODO improve this strategy on windowLevel implementation
hotkeysManager.setHotkeys(hotkeyDefinitions);
const { language } = generalPreferences;
// set new language
i18n.changeLanguage(language);
ownProps.hide();
dispatch(setUserPreferences({ windowLevelData, hotkeyDefinitions }));
},
onResetToDefaults: () => {
hotkeysManager.restoreDefaultBindings();
ownProps.hide();
dispatch(setUserPreferences());
dispatch(
setUserPreferences({
windowLevelData,
hotkeyDefinitions,
generalPreferences,
})
);
},
};
};
+1 -1
View File
@@ -30,7 +30,7 @@
--snackbar-info: rgba(54, 156, 199, 0.9);
/** z-Index **/
--snackbar-zIndex: 10;
--snackbar-zIndex: 1075;
/** DatePicker Colors **/
--datePicker-input-background: #2c363f;