Merge pull request #414 from dannyrb/fix/broken-icons-link

fix(App.js): Fixed broken toolbar icons not rendering with base tag r…
This commit is contained in:
Danny Brown 2019-05-01 13:37:26 -04:00 committed by GitHub
commit efcdad7e67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 237 additions and 198 deletions

View File

@ -1,21 +1,23 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { ToolbarSection } from 'react-viewerbase'; import { ToolbarSection } from 'react-viewerbase';
import OHIF from 'ohif-core' import OHIF from 'ohif-core';
const { setToolActive } = OHIF.redux.actions; const { setToolActive } = OHIF.redux.actions;
const Icons = 'icons.svg'; const Icons = `${window.config.routerBasename}/icons.svg`;
const mapStateToProps = state => { const mapStateToProps = state => {
const activeButton = state.tools.buttons.find(tool => tool.active === true); const activeButton = state.tools.buttons.find(tool => tool.active === true);
return { return {
buttons: [ { buttons: [
command: 'Rotate', {
type: 'tool', command: 'Rotate',
text: 'Rotate', type: 'tool',
svgUrl: `${Icons}#3d-rotate`, text: 'Rotate',
active: true svgUrl: `${Icons}#3d-rotate`,
}], active: true
}
],
activeCommand: 'Rotate' activeCommand: 'Rotate'
}; };
}; };

View File

@ -47,14 +47,3 @@ export ROOT_URL=$DEPLOY_PRIME_URL/demo
mkdir ./docs/latest/_book/demo/ mkdir ./docs/latest/_book/demo/
yarn install yarn install
yarn build:web:ci yarn build:web:ci
# OLD DEPLOY
# cd example
# yarn install
# yarn run prepare
# sed -i "s,http://localhost:5000,${ROOT_URL},g" index.html
# sed -i 's,"routerBasename": "/","routerBasename": "/demo",g' index.html
# rm -rf node_modules
# NEW DEPLOY
# cpx 'build/*' docs/latest/_book/demo --verbose

View File

@ -15,11 +15,11 @@ import OHIFDicomHtmlExtension from 'ohif-dicom-html-extension'
import OHIFDicomMicroscopyExtension from 'ohif-dicom-microscopy-extension' import OHIFDicomMicroscopyExtension from 'ohif-dicom-microscopy-extension'
import { OidcProvider, reducer as oidcReducer } from 'redux-oidc' import { OidcProvider, reducer as oidcReducer } from 'redux-oidc'
import { import {
getDefaultToolbarButtons,
getUserManagerForOpenIdConnectClient, getUserManagerForOpenIdConnectClient,
initWebWorkers, initWebWorkers,
} from './utils/index.js' } from './utils/index.js'
const Icons = 'icons.svg'
const { ExtensionManager } = OHIF.extensions const { ExtensionManager } = OHIF.extensions
const { reducers, localStorage } = OHIF.redux const { reducers, localStorage } = OHIF.redux
@ -35,90 +35,6 @@ store.subscribe(() => {
}) })
}) })
const defaultButtons = [
{
command: 'StackScroll',
type: 'tool',
text: 'Stack Scroll',
svgUrl: `${Icons}#icon-tools-stack-scroll`,
active: false,
},
{
command: 'Zoom',
type: 'tool',
text: 'Zoom',
svgUrl: `${Icons}#icon-tools-zoom`,
active: false,
},
{
command: 'Wwwc',
type: 'tool',
text: 'Levels',
svgUrl: `${Icons}#icon-tools-levels`,
active: true,
},
{
command: 'Pan',
type: 'tool',
text: 'Pan',
svgUrl: `${Icons}#icon-tools-pan`,
active: false,
},
{
command: 'Length',
type: 'tool',
text: 'Length',
svgUrl: `${Icons}#icon-tools-measure-temp`,
active: false,
},
/*{
command: 'Annotate',
type: 'tool',
text: 'Annotate',
svgUrl: `${Icons}#icon-tools-measure-non-target`,
active: false
},*/
{
command: 'Angle',
type: 'tool',
text: 'Angle',
iconClasses: 'fa fa-angle-left',
active: false,
},
{
command: 'Bidirectional',
type: 'tool',
text: 'Bidirectional',
svgUrl: `${Icons}#icon-tools-measure-target`,
active: false,
},
{
command: 'Brush',
type: 'tool',
text: 'Brush',
iconClasses: 'fa fa-circle',
active: false,
},
{
command: 'FreehandMouse',
type: 'tool',
text: 'Freehand',
iconClasses: 'fa fa-star',
active: false,
},
{
command: 'reset',
type: 'command',
text: 'Reset',
svgUrl: `${Icons}#icon-tools-reset`,
active: false,
},
]
const buttonsAction = OHIF.redux.actions.setAvailableButtons(defaultButtons)
store.dispatch(buttonsAction)
const availableTools = [ const availableTools = [
{ name: 'Pan', mouseButtonMasks: [1, 4] }, { name: 'Pan', mouseButtonMasks: [1, 4] },
{ name: 'Zoom', mouseButtonMasks: [1, 2] }, { name: 'Zoom', mouseButtonMasks: [1, 2] },
@ -181,6 +97,13 @@ class App extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
//
const defaultButtons = getDefaultToolbarButtons(this.props.routerBasename)
const buttonsAction = OHIF.redux.actions.setAvailableButtons(defaultButtons)
store.dispatch(buttonsAction)
//
this.userManager = getUserManagerForOpenIdConnectClient( this.userManager = getUserManagerForOpenIdConnectClient(
store, store,
this.props.oidc this.props.oidc

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react'
import './OHIFLogo.css'; import './OHIFLogo.css'
const Icons = 'icons.svg'; const Icons = `${window.config.routerBasename}/icons.svg`
function OHIFLogo() { function OHIFLogo() {
return ( return (
@ -16,7 +16,7 @@ function OHIFLogo() {
</svg> </svg>
<div className="header-logo-text">Open Health Imaging Foundation</div> <div className="header-logo-text">Open Health Imaging Foundation</div>
</a> </a>
); )
} }
export default OHIFLogo; export default OHIFLogo

View File

@ -1,42 +1,42 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux'
import PluginSwitch from './PluginSwitch.js'; import PluginSwitch from './PluginSwitch.js'
import OHIF from 'ohif-core'; import OHIF from 'ohif-core'
const { setLayout } = OHIF.redux.actions; const { setLayout } = OHIF.redux.actions
const mapStateToProps = state => { const mapStateToProps = state => {
const { activeViewportIndex, layout } = state.viewports; const { activeViewportIndex, layout } = state.viewports
return { return {
activeViewportIndex, activeViewportIndex,
layout layout,
}; }
}; }
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
setLayout: data => { setLayout: data => {
dispatch(setLayout(data)); dispatch(setLayout(data))
} },
}; }
}; }
function setSingleLayoutData(originalArray, viewportIndex, data) { function setSingleLayoutData(originalArray, viewportIndex, data) {
const viewports = originalArray.slice(); const viewports = originalArray.slice()
const layoutData = Object.assign({}, viewports[viewportIndex], data); const layoutData = Object.assign({}, viewports[viewportIndex], data)
viewports[viewportIndex] = layoutData; viewports[viewportIndex] = layoutData
return viewports; return viewports
} }
const mergeProps = (propsFromState, propsFromDispatch, ownProps) => { const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
const { activeViewportIndex, layout } = propsFromState; const { activeViewportIndex, layout } = propsFromState
const { setLayout } = propsFromDispatch; const { setLayout } = propsFromDispatch
// TODO: Do not display certain options if the current display set // TODO: Do not display certain options if the current display set
// cannot be displayed using these view types // cannot be displayed using these view types
const Icons = 'icons.svg'; const Icons = `${window.config.routerBasename}/icons.svg`
const buttons = [ const buttons = [
{ {
text: 'Acquired', text: 'Acquired',
@ -44,16 +44,16 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
iconClasses: 'fa fa-bars', iconClasses: 'fa fa-bars',
active: false, active: false,
onClick: click => { onClick: click => {
console.warn('Original Acquisition'); console.warn('Original Acquisition')
const layoutData = setSingleLayoutData( const layoutData = setSingleLayoutData(
layout.viewports, layout.viewports,
activeViewportIndex, activeViewportIndex,
{ plugin: 'cornerstone' } { plugin: 'cornerstone' }
); )
setLayout({ viewports: layoutData }); setLayout({ viewports: layoutData })
} },
}, },
{ {
text: 'Axial', text: 'Axial',
@ -61,46 +61,46 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
svgClasses: 'icon-rotate-120', svgClasses: 'icon-rotate-120',
active: false, active: false,
onClick: click => { onClick: click => {
console.warn('Axial'); console.warn('Axial')
const data = { const data = {
plugin: 'vtk', plugin: 'vtk',
vtk: { vtk: {
mode: 'mpr', mode: 'mpr',
sliceNormal: [0, 0, 1] sliceNormal: [0, 0, 1],
} },
}; }
const layoutData = setSingleLayoutData( const layoutData = setSingleLayoutData(
layout.viewports, layout.viewports,
activeViewportIndex, activeViewportIndex,
data data
); )
setLayout({ viewports: layoutData }); setLayout({ viewports: layoutData })
} },
}, },
{ {
text: 'Sagittal', text: 'Sagittal',
svgUrl: `${Icons}#cube`, svgUrl: `${Icons}#cube`,
active: false, active: false,
onClick: click => { onClick: click => {
console.warn('Sagittal'); console.warn('Sagittal')
const data = { const data = {
plugin: 'vtk', plugin: 'vtk',
vtk: { vtk: {
mode: 'mpr', mode: 'mpr',
sliceNormal: [1, 0, 0] sliceNormal: [1, 0, 0],
} },
}; }
const layoutData = setSingleLayoutData( const layoutData = setSingleLayoutData(
layout.viewports, layout.viewports,
activeViewportIndex, activeViewportIndex,
data data
); )
setLayout({ viewports: layoutData }); setLayout({ viewports: layoutData })
} },
}, },
{ {
text: 'Coronal', text: 'Coronal',
@ -108,24 +108,24 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
svgClasses: 'fa-rotate-90 fa-flip-horizontal', svgClasses: 'fa-rotate-90 fa-flip-horizontal',
active: false, active: false,
onClick: click => { onClick: click => {
console.warn('Coronal'); console.warn('Coronal')
const data = { const data = {
plugin: 'vtk', plugin: 'vtk',
vtk: { vtk: {
mode: 'mpr', mode: 'mpr',
sliceNormal: [0, 1, 0] sliceNormal: [0, 1, 0],
} },
}; }
const layoutData = setSingleLayoutData( const layoutData = setSingleLayoutData(
layout.viewports, layout.viewports,
activeViewportIndex, activeViewportIndex,
data data
); )
setLayout({ viewports: layoutData }); setLayout({ viewports: layoutData })
} },
} },
/*{ /*{
text: '3D', text: '3D',
svgUrl: `${Icons}#cube`, svgUrl: `${Icons}#cube`,
@ -143,17 +143,17 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
setLayout({ viewports: layoutData }); setLayout({ viewports: layoutData });
} }
}*/ }*/
]; ]
return { return {
buttons buttons,
}; }
}; }
const ConnectedPluginSwitch = connect( const ConnectedPluginSwitch = connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps, mapDispatchToProps,
mergeProps mergeProps
)(PluginSwitch); )(PluginSwitch)
export default ConnectedPluginSwitch; export default ConnectedPluginSwitch

View File

@ -1,12 +1,12 @@
import React, { Component } from 'react'; import React, { Component } from 'react'
import PropTypes from 'prop-types'; import PropTypes from 'prop-types'
import OHIF from 'ohif-core'; import OHIF from 'ohif-core'
import { RoundedButtonGroup } from 'react-viewerbase'; import { RoundedButtonGroup } from 'react-viewerbase'
import ConnectedLayoutButton from './ConnectedLayoutButton'; import ConnectedLayoutButton from './ConnectedLayoutButton'
import ConnectedPluginSwitch from './ConnectedPluginSwitch.js'; import ConnectedPluginSwitch from './ConnectedPluginSwitch.js'
import './ToolbarRow.css'; import './ToolbarRow.css'
const Icons = 'icons.svg'; const Icons = `${window.config.routerBasename}/icons.svg`
class ToolbarRow extends Component { class ToolbarRow extends Component {
static propTypes = { static propTypes = {
@ -14,21 +14,21 @@ class ToolbarRow extends Component {
rightSidebarOpen: PropTypes.bool.isRequired, rightSidebarOpen: PropTypes.bool.isRequired,
setLeftSidebarOpen: PropTypes.func, setLeftSidebarOpen: PropTypes.func,
setRightSidebarOpen: PropTypes.func, setRightSidebarOpen: PropTypes.func,
pluginId: PropTypes.string pluginId: PropTypes.string,
}; }
static defaultProps = { static defaultProps = {
leftSidebarOpen: false, leftSidebarOpen: false,
rightSidebarOpen: false rightSidebarOpen: false,
}; }
onLeftSidebarValueChanged = value => { onLeftSidebarValueChanged = value => {
this.props.setLeftSidebarOpen(!!value); this.props.setLeftSidebarOpen(!!value)
}; }
onRightSidebarValueChanged = value => { onRightSidebarValueChanged = value => {
this.props.setRightSidebarOpen(!!value); this.props.setRightSidebarOpen(!!value)
}; }
render() { render() {
const leftSidebarToggle = [ const leftSidebarToggle = [
@ -37,9 +37,9 @@ class ToolbarRow extends Component {
svgLink: `${Icons}#icon-studies`, svgLink: `${Icons}#icon-studies`,
svgWidth: 15, svgWidth: 15,
svgHeight: 13, svgHeight: 13,
bottomLabel: 'Series' bottomLabel: 'Series',
} },
]; ]
const rightSidebarToggle = [ const rightSidebarToggle = [
{ {
@ -47,32 +47,30 @@ class ToolbarRow extends Component {
svgLink: `${Icons}#icon-measurements-lesions`, svgLink: `${Icons}#icon-measurements-lesions`,
svgWidth: 15, svgWidth: 15,
svgHeight: 13, svgHeight: 13,
bottomLabel: 'Measurements' bottomLabel: 'Measurements',
} },
]; ]
const leftSidebarValue = this.props.leftSidebarOpen const leftSidebarValue = this.props.leftSidebarOpen
? leftSidebarToggle[0].value ? leftSidebarToggle[0].value
: null; : null
const rightSidebarValue = this.props.rightSidebarOpen const rightSidebarValue = this.props.rightSidebarOpen
? rightSidebarToggle[0].value ? rightSidebarToggle[0].value
: null; : null
const currentPluginId = this.props.pluginId; const currentPluginId = this.props.pluginId
const { PLUGIN_TYPES, availablePlugins } = OHIF.plugins; const { PLUGIN_TYPES, availablePlugins } = OHIF.plugins
const plugin = availablePlugins.find(entry => { const plugin = availablePlugins.find(entry => {
return ( return entry.type === PLUGIN_TYPES.TOOLBAR && entry.id === currentPluginId
entry.type === PLUGIN_TYPES.TOOLBAR && entry.id === currentPluginId })
);
});
let pluginComp; let pluginComp
if (plugin) { if (plugin) {
const PluginComponent = plugin.component; const PluginComponent = plugin.component
pluginComp = <PluginComponent />; pluginComp = <PluginComponent />
} }
return ( return (
@ -95,8 +93,8 @@ class ToolbarRow extends Component {
/> />
</div> </div>
</div> </div>
); )
} }
} }
export default ToolbarRow; export default ToolbarRow

View File

@ -0,0 +1,92 @@
/**
*
* @param {String} [baseDirectory='/']
*/
export default function(baseDirectory = '/') {
const iconsFileName = 'icons.svg'
const sanitizedBaseDirectory =
baseDirectory[baseDirectory.length - 1] === '/'
? baseDirectory
: `${baseDirectory}/`
const relativePathToIcons = `${sanitizedBaseDirectory}${iconsFileName}`
return [
{
command: 'StackScroll',
type: 'tool',
text: 'Stack Scroll',
svgUrl: `${relativePathToIcons}#icon-tools-stack-scroll`,
active: false,
},
{
command: 'Zoom',
type: 'tool',
text: 'Zoom',
svgUrl: `${relativePathToIcons}#icon-tools-zoom`,
active: false,
},
{
command: 'Wwwc',
type: 'tool',
text: 'Levels',
svgUrl: `${relativePathToIcons}#icon-tools-levels`,
active: true,
},
{
command: 'Pan',
type: 'tool',
text: 'Pan',
svgUrl: `${relativePathToIcons}#icon-tools-pan`,
active: false,
},
{
command: 'Length',
type: 'tool',
text: 'Length',
svgUrl: `${relativePathToIcons}#icon-tools-measure-temp`,
active: false,
},
/*{
command: 'Annotate',
type: 'tool',
text: 'Annotate',
svgUrl: `${Icons}#icon-tools-measure-non-target`,
active: false
},*/
{
command: 'Angle',
type: 'tool',
text: 'Angle',
iconClasses: 'fa fa-angle-left',
active: false,
},
{
command: 'Bidirectional',
type: 'tool',
text: 'Bidirectional',
svgUrl: `${relativePathToIcons}#icon-tools-measure-target`,
active: false,
},
{
command: 'Brush',
type: 'tool',
text: 'Brush',
iconClasses: 'fa fa-circle',
active: false,
},
{
command: 'FreehandMouse',
type: 'tool',
text: 'Freehand',
iconClasses: 'fa fa-star',
active: false,
},
{
command: 'reset',
type: 'command',
text: 'Reset',
svgUrl: `${relativePathToIcons}#icon-tools-reset`,
active: false,
},
]
}

View File

@ -0,0 +1,26 @@
import getDefaultToolbarButtons from './getDefaultToolbarButtons.js'
describe('getDefaultToolbarButtons.js', () => {
it('returns a non-empty array', () => {
const basePath = '/'
const buttons = getDefaultToolbarButtons(basePath)
expect(buttons.length).toBeGreaterThan(0)
})
it('uses the provided basePath in buttons with an svgUrl property', () => {
const basePath = '/demo/'
const buttons = getDefaultToolbarButtons(basePath)
const hasOneOrMoreButtonsWithSvgUrlProperty = buttons.some(btn =>
btn.hasOwnProperty('svgUrl')
)
const usesBasePathInButtonSvgUrls = buttons.every(
btn => !btn.hasOwnProperty('svgUrl') || btn.svgUrl.includes(basePath)
)
expect(hasOneOrMoreButtonsWithSvgUrlProperty).toBeTruthy()
expect(usesBasePathInButtonSvgUrls).toBeTruthy()
})
})

View File

@ -1,4 +1,9 @@
import getDefaultToolbarButtons from './getDefaultToolbarButtons.js'
import getUserManagerForOpenIdConnectClient from './getUserManagerForOpenIdConnectClient.js' import getUserManagerForOpenIdConnectClient from './getUserManagerForOpenIdConnectClient.js'
import initWebWorkers from './initWebWorkers.js' import initWebWorkers from './initWebWorkers.js'
export { getUserManagerForOpenIdConnectClient, initWebWorkers } export {
getDefaultToolbarButtons,
getUserManagerForOpenIdConnectClient,
initWebWorkers,
}

View File

@ -5,7 +5,11 @@ describe('utils', () => {
const utilExports = Object.keys(utils).sort() const utilExports = Object.keys(utils).sort()
expect(utilExports).toEqual( expect(utilExports).toEqual(
['getUserManagerForOpenIdConnectClient', 'initWebWorkers'].sort() [
'getDefaultToolbarButtons',
'getUserManagerForOpenIdConnectClient',
'initWebWorkers',
].sort()
) )
}) })
}) })