Chore/kill yalc with fire (#629)
* init * more shifting * Move @babel dependencies up to workspace root * Begin updating dependent libraries to use sync'd webpack builds w/ watches * Commit changes before a long weekend * Split packages into platform and extensions * Consolidate how/where we specify file/module type entrypoints * Make it possible to pass in extensions as App props * Resolve viewer's modules * Target for UMD bundle * Add Webpack Stylus loader * Provide WebPack build options for microscopy, vtk, and ui * Better entrypoint for extensions * Push changes up to switch PCs * Fix ESM symlink build for Viewers * Shift docs to root * Specify additional lerna config props * Begin providing basic readme info * Rename example extension folder * Shift links to bottom of doc * First attempt at a netlify deploy preview * Attempt to fix deploy preview build * push workspace enabled to initial command; remove second yarn install; use npx to call gitbook cli commands * Try to use global gitbook-cli * Export node_modules path * More agressive with modifying PATH * Follow deploy log output advice * try again to set bin path * Try swapping bash with a new shell * Try bash -l instead of exec bash * Annd let's try again * and again * We may have figured it out johnny, boy * We need to pull cornerstone-wado-image-loader files from hoisted node_modules * Attempt to fix ticks/escapes * Change copy syntax; try running tests on viewers from root for circleci * Lower version to match circleci image * Try alternative jest-canvas-mock location and version file syntax * Run version command instead of calling node directly * Try alternative jest transform * Set path and enable workspaces * Add codecov flags * Use cpx so our copying finishes? * Get all platform unit tests to run * Run and report individually and in parallel * Try once relying on codecov yaml to split w/ flags * Add projects to split by flags * Generate separate reports * Trigger codecov after everything has finished running; these may not support flags * Use recommended flags from issue comments for codecov * Fix typo * Remove clear flag * Shift back to calling codecov from root * Generate example for codecov issue * Try fixing paths * Simplify * Try using codecov orb * Bump circleci version * Upload core and viewer * Use full string paths * Remove individual codecov calls * Fix dir * Combine files before upload * Escape anchors * tryfix syntax * Escape string literal * Combine lines to reduce path * long paths * Use home alias * Fix filename * Try to see the contents of our cat'd file * Also upload `core` * Try running with aliased folder * Fix path; split PR and Merge unit tests into separate jobs * Set default threshold * Fix typo * Changing to scoped package names * Adding note * Catch more updates * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.0 - @ohif/extension-dicom-html@0.0.4-alpha.0 - @ohif/extension-dicom-microscopy@0.0.9-alpha.0 - @ohif/extension-dicom-pdf@0.0.8-alpha.0 - @ohif/extension-vtk@0.1.4-alpha.0 - @ohif/core@0.11.1-alpha.0 - @ohif/i18n@0.2.3-alpha.0 - @ohif/ui@0.2.18-alpha.0 - @ohif/viewer@0.0.22-alpha.0 * Clean up primary readme * Support for dev and dev:* commands * Shift build command; satisfy default PWA build * Remove old scripts * Clean up UI to set webpack scripts * Tidy up project links * Clean duplicate code in UI project * Update UI project's docs * Clean up ui and i18n config * Reduce duplicate code in `@ohif/core` * Fix @ohif/ui versions * bump @ohif/core versions * Redux testkit dep * Remove unused/duplicate config files for projects/packages * ohif-core --> @ohif/core * Safer publish command * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.1 - @ohif/extension-dicom-html@0.0.4-alpha.1 - @ohif/extension-dicom-microscopy@0.0.9-alpha.1 - @ohif/extension-dicom-pdf@0.0.8-alpha.1 - @ohif/extension-vtk@0.1.4-alpha.1 - @ohif/core@0.11.1-alpha.1 - @ohif/i18n@0.2.3-alpha.1 - @ohif/ui@0.2.18-alpha.1 - @ohif/viewer@0.0.22-alpha.1 * test version bump * Add global prettier config * chore(release): publish %s [skip ci] - @ohif/viewer@0.0.22-alpha.2 * test lerna publish * Update package.jsons * Fix build scripts * catch changes * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.2 - @ohif/extension-dicom-html@0.0.4-alpha.2 - @ohif/extension-dicom-microscopy@0.0.9-alpha.2 - @ohif/extension-dicom-pdf@0.0.8-alpha.2 - @ohif/extension-vtk@0.1.4-alpha.2 - @ohif/core@0.11.1-alpha.2 - @ohif/i18n@0.2.3-alpha.2 - @ohif/ui@0.2.18-alpha.2 - @ohif/viewer@0.0.22-alpha.3 * fix eslint issues caused by eslint 6 and our react-app config * Publish with canary tag * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.3 - @ohif/extension-dicom-html@0.0.4-alpha.3 - @ohif/extension-dicom-microscopy@0.0.9-alpha.3 - @ohif/extension-dicom-pdf@0.0.8-alpha.3 - @ohif/extension-vtk@0.1.4-alpha.3 - @ohif/core@0.11.1-alpha.3 - @ohif/i18n@0.2.3-alpha.3 - @ohif/ui@0.2.18-alpha.3 - @ohif/viewer@0.0.22-alpha.4 * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.4 - @ohif/extension-dicom-html@0.0.4-alpha.4 - @ohif/extension-dicom-microscopy@0.0.9-alpha.4 - @ohif/extension-dicom-pdf@0.0.8-alpha.4 - @ohif/extension-vtk@0.1.4-alpha.4 - @ohif/core@0.11.1-alpha.4 - @ohif/i18n@0.2.3-alpha.4 - @ohif/ui@0.2.18-alpha.4 - @ohif/viewer@0.0.22-alpha.5 * Simplify build * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.5 - @ohif/extension-dicom-html@0.0.4-alpha.5 - @ohif/extension-dicom-microscopy@0.0.9-alpha.5 - @ohif/extension-dicom-pdf@0.0.8-alpha.5 - @ohif/extension-vtk@0.1.4-alpha.5 - @ohif/core@0.11.1-alpha.5 - @ohif/i18n@0.2.3-alpha.5 - @ohif/ui@0.2.18-alpha.5 - @ohif/viewer@0.0.22-alpha.6 * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.6 - @ohif/extension-dicom-html@0.0.4-alpha.6 - @ohif/extension-dicom-microscopy@0.0.9-alpha.6 - @ohif/extension-dicom-pdf@0.0.8-alpha.6 - @ohif/extension-vtk@0.1.4-alpha.6 - @ohif/core@0.11.1-alpha.6 - @ohif/i18n@0.2.3-alpha.6 - @ohif/ui@0.2.18-alpha.6 - @ohif/viewer@0.0.22-alpha.7 * Split version and publish * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.7 - @ohif/extension-dicom-html@0.0.4-alpha.7 - @ohif/extension-dicom-microscopy@0.0.9-alpha.7 - @ohif/extension-dicom-pdf@0.0.8-alpha.7 - @ohif/extension-vtk@0.1.4-alpha.7 - @ohif/core@0.11.1-alpha.7 - @ohif/i18n@0.2.3-alpha.7 - @ohif/ui@0.2.18-alpha.7 - @ohif/viewer@0.0.22-alpha.8 * Try simplify netlify build * react-viewerbase --> @ohif/ui * add test for stylus loader * Try new way to specify publish path * Use an output folder that won't be ignored * Try move command * fiddle with paths * Dig for some information * Make sure we're in root for our commands * Remove discovery * Setup script-tag example * Fix typo * Move config folder * Update cornerstone extension to use shared/root webpack configs * capture changes * Update extension webpack configs * Don't check in docz output * Fix babel runtime resolution issue * Simplify ui build steps * Push in progress * Shift directories * Get viewer dev path to work * Fix viewer commonjs build * Fix build pwa config for viewers * Make sure our package specific command can be called from root * Update notes * Fix imports and misc. merge notes * Bump wado-image-loader version * Switch up commands to remove webworkers copy * Fix CI config * Fix more broken package references * Add react-dropzone * Persist so e2e test can use * Fix lockfile * Use cypress orb to simplify CI * Fix config * Try again * Install yarn latest for orb * Install yarn a different way * Wait on correct port * Run tests in viewer project * Fix cypress config * Make Cypress happier - use default location * Simplify e2e testing * Capture UI changes since fork * Catch core up * Grab latest deps after merge * Fix broken import * Make sure cornerstone-wado-image-loader resolves to 3+ * Note regarding orbs * Fix refresh on 404 routes * Fix odd error for cornerstone-wado-image-loader * Different target for UMD * Simplify dev script * Try to get fancy with netlify output * Let's do it again * Try to fix measurementTools issue * See if we can get our lerna magic to work on merge to monorepo branch
This commit is contained in:
1 parent
cac911f08e
commit
08ff214ea6
919 files changed
+45652
-52097
No files matched your search
@@ -0,0 +1,153 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { StudiesList } from './StudiesList.js';
|
||||
import { ScrollableArea } from './../../ScrollableArea/ScrollableArea.js';
|
||||
import { SeriesList } from './SeriesList.js';
|
||||
|
||||
import './QuickSwitch.styl';
|
||||
|
||||
export class QuickSwitch extends Component {
|
||||
static propTypes = {
|
||||
side: PropTypes.string,
|
||||
studyListData: PropTypes.array.isRequired,
|
||||
onSeriesSelected: PropTypes.func.isRequired,
|
||||
seriesListData: PropTypes.array,
|
||||
onStudySelected: PropTypes.func,
|
||||
activeStudyInstanceUid: PropTypes.string,
|
||||
activeDisplaySetInstanceUid: PropTypes.string,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
seriesQuickSwitchOpen: false,
|
||||
sideClass: this.props.side || '',
|
||||
activeStudyInstanceUid: this.props.activeStudyInstanceUid,
|
||||
activeDisplaySetInstanceUid: this.props.activeDisplaySetInstanceUid,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const props = this.props;
|
||||
|
||||
if (props.activeStudyInstanceUid !== prevProps.activeStudyInstanceUid) {
|
||||
this.setState({
|
||||
activeStudyInstanceUid: props.activeStudyInstanceUid,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
props.activeDisplaySetInstanceUid !==
|
||||
prevProps.activeDisplaySetInstanceUid
|
||||
) {
|
||||
this.setState({
|
||||
activeDisplaySetInstanceUid: props.activeDisplaySetInstanceUid,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const quickSwitchClass = this.state.seriesQuickSwitchOpen
|
||||
? 'series-triggered'
|
||||
: '';
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`series-quick-switch clearfix noselect ${
|
||||
this.state.sideClass
|
||||
} ${quickSwitchClass}`}
|
||||
onMouseLeave={this.hideSeriesSwitch}
|
||||
>
|
||||
<div className="series-switch" onMouseEnter={this.showSeriesSwitch}>
|
||||
<div className="title-label">Series</div>
|
||||
<div className="series-box">
|
||||
{this.getSmallListItems()}
|
||||
<ScrollableArea scrollStep={201} class="series-browser">
|
||||
<SeriesList
|
||||
seriesItems={this.getSeriesItems()}
|
||||
onClick={this.onSeriesClick}
|
||||
activeDisplaySetInstanceUid={
|
||||
this.state.activeDisplaySetInstanceUid
|
||||
}
|
||||
/>
|
||||
</ScrollableArea>
|
||||
</div>
|
||||
</div>
|
||||
<div className="study-switch">
|
||||
<div className="title-label">Study</div>
|
||||
<div className="study-box">
|
||||
<ScrollableArea scrollStep={91} class="study-browser">
|
||||
<StudiesList
|
||||
studyListData={this.props.studyListData}
|
||||
onClick={this.onStudyClick}
|
||||
activeStudyInstanceUid={this.state.activeStudyInstanceUid}
|
||||
/>
|
||||
</ScrollableArea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getSeriesItems = () => {
|
||||
let seriesListData;
|
||||
|
||||
if (this.props.seriesListData) {
|
||||
seriesListData = this.props.seriesListData;
|
||||
} else if (this.state.activeStudyInstanceUid) {
|
||||
const study = this.props.studyListData.find(
|
||||
study => study.studyInstanceUid === this.state.activeStudyInstanceUid
|
||||
);
|
||||
|
||||
seriesListData = study.thumbnails;
|
||||
} else {
|
||||
seriesListData = this.props.studyListData[0].thumbnails;
|
||||
}
|
||||
|
||||
return seriesListData || [];
|
||||
};
|
||||
|
||||
getSmallListItems = () => {
|
||||
const seriesItems = this.getSeriesItems() || [];
|
||||
return seriesItems.map((seriesData, index) => {
|
||||
const active =
|
||||
seriesData.displaySetInstanceUid ===
|
||||
this.state.activeDisplaySetInstanceUid;
|
||||
return (
|
||||
<div key={index} className={`series-item ${active ? 'active' : ''}`} />
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
onStudyClick = studyDataSelected => {
|
||||
if (this.props.onStudySelected) {
|
||||
this.props.onStudySelected(studyDataSelected);
|
||||
}
|
||||
this.setState({
|
||||
activeStudyInstanceUid: studyDataSelected.studyInstanceUid,
|
||||
seriesQuickSwitchOpen: true,
|
||||
});
|
||||
};
|
||||
|
||||
onSeriesClick = seriesDataSelected => {
|
||||
this.setState({
|
||||
activeDisplaySetInstanceUid: seriesDataSelected.displaySetInstanceUid,
|
||||
});
|
||||
|
||||
this.props.onSeriesSelected(seriesDataSelected);
|
||||
};
|
||||
|
||||
showSeriesSwitch = () => {
|
||||
this.setState({
|
||||
seriesQuickSwitchOpen: true,
|
||||
});
|
||||
};
|
||||
|
||||
hideSeriesSwitch = () => {
|
||||
this.setState({
|
||||
seriesQuickSwitchOpen: false,
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
.series-quick-switch
|
||||
position: relative;
|
||||
|
||||
&:before
|
||||
box-shadow: 0 0 0 5000px rgba(0, 0, 0, 0.8)
|
||||
transition: opacity 0.3s ease
|
||||
opacity: 0
|
||||
content: ''
|
||||
|
||||
&:hover
|
||||
z-index: 50
|
||||
|
||||
&:before
|
||||
display: table;
|
||||
opacity: 1
|
||||
content: ''
|
||||
|
||||
&:not(.left):not(.right)
|
||||
left: 50%
|
||||
transform: translateX(-50%)
|
||||
|
||||
&.left
|
||||
border-right: 1px solid var(--ui-border-color)
|
||||
right: 0
|
||||
|
||||
&.right
|
||||
left: 0
|
||||
|
||||
.series-switch
|
||||
float: right
|
||||
|
||||
.study-switch
|
||||
float: left
|
||||
|
||||
.study-browser
|
||||
left: auto
|
||||
right: 0
|
||||
transform-origin: calc(100% - 1em) calc(1em + 17px)
|
||||
|
||||
.series-browser
|
||||
left: 0
|
||||
right: auto
|
||||
transform-origin: 1em calc(1em + 15px)
|
||||
|
||||
.thumbnails-wrapper
|
||||
transform-origin: 0% 0%
|
||||
|
||||
.ThumbnailEntry
|
||||
float: left
|
||||
|
||||
.series-item
|
||||
float: left
|
||||
|
||||
.title-label
|
||||
color: var(--text-secondary-color)
|
||||
font-size: 12px
|
||||
font-weight: 500
|
||||
line-height: 12px
|
||||
opacity: 1
|
||||
padding-bottom: 3px
|
||||
text-align: center
|
||||
transition: opacity 0.3s ease
|
||||
|
||||
.series-switch
|
||||
padding-right: 10px;
|
||||
|
||||
.series-switch,
|
||||
.study-switch
|
||||
float: left
|
||||
position: relative
|
||||
|
||||
.study-switch:hover:after
|
||||
content: ''
|
||||
display: block
|
||||
height: 100px
|
||||
left: 0
|
||||
position: absolute
|
||||
top: 0
|
||||
width: 300px
|
||||
|
||||
.study-browser
|
||||
left: 0
|
||||
padding-top: 60px;
|
||||
max-height: calc(100vh - 60px);
|
||||
transform-origin: 1em calc(1em + 17px)
|
||||
width: 300px
|
||||
|
||||
.study-browser-list
|
||||
padding: 0 10px
|
||||
|
||||
.series-browser
|
||||
max-height: 100vh
|
||||
max-width: 720px
|
||||
right: 0
|
||||
transform-origin: calc(100% - 1em) calc(1em + 15px)
|
||||
|
||||
.thumbnails-wrapper
|
||||
transition: transform 0.3s ease
|
||||
transform-origin: 100% 0%
|
||||
|
||||
.ThumbnailEntry
|
||||
float: right
|
||||
|
||||
.series-details
|
||||
opacity: 0
|
||||
transform: translateY(-100%)
|
||||
transition: transform 0.3s ease, opacity 0.3s ease
|
||||
|
||||
.scrollable
|
||||
padding-top: 15px
|
||||
transition: padding-bottom 0.3s ease
|
||||
|
||||
.study-browser-series {
|
||||
overflow hidden
|
||||
}
|
||||
|
||||
.series-browser,
|
||||
.study-browser
|
||||
min-height: 120px
|
||||
opacity: 0
|
||||
position: absolute
|
||||
top: 0
|
||||
transform: scale(0)
|
||||
transition: transform 0.3s ease , opacity 0.3s ease
|
||||
z-index: 3
|
||||
|
||||
.series-box,
|
||||
.study-box
|
||||
height: 57px
|
||||
width: 57px
|
||||
|
||||
.study-box
|
||||
background-color: var(--ui-gray-dark)
|
||||
border: solid 2px var(--ui-border-color-dark)
|
||||
border-radius: 11px
|
||||
|
||||
.series-item
|
||||
background-color: var(--box-background-color)
|
||||
border-radius: 3px
|
||||
float: right
|
||||
height: 15px
|
||||
margin: 2px
|
||||
transition: opacity 0.3s ease
|
||||
width: 15px
|
||||
|
||||
&.count
|
||||
color: var(--text-primary-color)
|
||||
background-color: transparent
|
||||
font-size: 12px
|
||||
font-weight: 500
|
||||
line-height: 17px
|
||||
text-align: center
|
||||
|
||||
&.active
|
||||
background-color: var(--active-color)
|
||||
|
||||
&.series-triggered .series-browser,
|
||||
.series-switch:hover .series-browser,
|
||||
.study-switch:hover .study-browser
|
||||
opacity: 1
|
||||
transform: scale(1)
|
||||
|
||||
&.series-triggered .series-item,
|
||||
.series-switch:hover .title-label
|
||||
opacity: 0
|
||||
|
||||
&.series-triggered
|
||||
.thumbnails-wrapper
|
||||
transform: scale(0.9) translateY(80px)
|
||||
|
||||
.series-browser:not(:hover)
|
||||
&>.scrollable
|
||||
padding-bottom: 80px
|
||||
|
||||
&>.scrollNav
|
||||
opacity: 0
|
||||
|
||||
.series-switch:hover .series-browser
|
||||
.thumbnails-wrapper
|
||||
transform: scale(1) translateY(0)
|
||||
|
||||
.ThumbnailEntry .series-details
|
||||
opacity: 1
|
||||
transform: translateY(0)
|
||||
transition-delay: 0.3s
|
||||
|
||||
.study-browser-item.active .study-item-box
|
||||
box-shadow: inset 0 0 0 3px var(--active-color)
|
||||
|
||||
@media screen and (max-width: 1599px)
|
||||
.series-quick-switch
|
||||
|
||||
.series-box,
|
||||
.study-box
|
||||
width: 36px
|
||||
height: 36px
|
||||
|
||||
.study-box
|
||||
border-radius: 7px
|
||||
|
||||
.series-item
|
||||
height: 10px
|
||||
margin: 1px
|
||||
width: 10px
|
||||
|
||||
&.count
|
||||
font-size: 10px
|
||||
font-weight: 300
|
||||
line-height: 10px
|
||||
@@ -0,0 +1,40 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { ThumbnailEntry } from './../studyBrowser';
|
||||
import './SeriesList.styl';
|
||||
|
||||
export class SeriesList extends Component {
|
||||
static propTypes = {
|
||||
seriesItems: PropTypes.array.isRequired,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
activeDisplaySetInstanceUid: PropTypes.string,
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="study-browser-series clearfix thumbnails-wrapper">
|
||||
<div className="study-series-container">{this.getSeriesItems()}</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
getSeriesItems = () => {
|
||||
return this.props.seriesItems.map((seriesData, index) => {
|
||||
return (
|
||||
<ThumbnailEntry
|
||||
key={seriesData.displaySetInstanceUid}
|
||||
id={`series_thumb_${index}`}
|
||||
{...seriesData}
|
||||
active={
|
||||
seriesData.displaySetInstanceUid ===
|
||||
this.props.activeDisplaySetInstanceUid
|
||||
}
|
||||
onClick={() => this.props.onClick(seriesData)}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,60 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './StudiesItem.styl';
|
||||
|
||||
export class StudiesItem extends Component {
|
||||
static propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
studyData: PropTypes.object.isRequired,
|
||||
active: PropTypes.bool,
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
studyDate,
|
||||
studyDescription,
|
||||
modalities,
|
||||
studyAvailable,
|
||||
} = this.props.studyData;
|
||||
const activeClass = this.props.active ? ' active' : '';
|
||||
const hasDescriptionAndDate = studyDate && studyDescription;
|
||||
return (
|
||||
<div
|
||||
className={`studyBrowseItem${activeClass}`}
|
||||
onClick={this.props.onClick}
|
||||
>
|
||||
<div className="studyItemBox">
|
||||
<div className="studyModality">
|
||||
<div
|
||||
className="studyModalityText"
|
||||
style={this.getModalitiesStyle()}
|
||||
>
|
||||
{modalities}
|
||||
</div>
|
||||
</div>
|
||||
<div className="studyText">
|
||||
{hasDescriptionAndDate ? (
|
||||
<React.Fragment>
|
||||
<div className="studyDate">{studyDate}</div>
|
||||
<div className="studyDescription">{studyDescription}</div>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<div className="studyAvailability">
|
||||
{studyAvailable ? (
|
||||
<React.Fragment>N/A</React.Fragment>
|
||||
) : (
|
||||
<React.Fragment>Click to load</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getModalitiesStyle = () => {
|
||||
return {};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
$boxHoverBackgroundColor = #14191E
|
||||
$boxHoverBorderColor = #2d4660
|
||||
$boxActiveBorderColor = #131D29
|
||||
$boxWidth = 50px
|
||||
$borderThickness = 2px
|
||||
$boxBorderRadius = 8px
|
||||
$nestingMargin = 6px
|
||||
$spacerX = 7px
|
||||
$spacerY = 12px
|
||||
|
||||
.studyBrowseItem
|
||||
margin-bottom: 10px;
|
||||
position: relative
|
||||
// required transformation to make inner fixed elements relative to this one
|
||||
transform: scale(1)
|
||||
|
||||
&.active
|
||||
.studyItemBox
|
||||
border-color: var(--active-color)
|
||||
|
||||
.studyModality
|
||||
color: var(--primary-background-color)
|
||||
&
|
||||
&:before
|
||||
&:after
|
||||
background-color: var(--active-color)
|
||||
border-color: $boxActiveBorderColor
|
||||
|
||||
&:not(.active) .studyBrowserSeries
|
||||
max-height: 0 !important
|
||||
|
||||
.studySeriesContainer
|
||||
opacity: 0
|
||||
transform: translateY(-100%)
|
||||
|
||||
.studyBrowserSeries
|
||||
overflow: hidden
|
||||
transition: max-height 0.3s ease
|
||||
|
||||
.studySeriesContainer
|
||||
opacity: 1
|
||||
transition: opacity 0.3s ease, transform 0.3s ease
|
||||
transform: translateY(0)
|
||||
transform-origin: 50% 0%
|
||||
|
||||
.studyItemBox
|
||||
border: 3px solid var(--ui-border-color-dark)
|
||||
border-radius: 12px
|
||||
cursor: pointer
|
||||
padding: $spacerY $spacerX ($spacerY - 1)
|
||||
position: relative
|
||||
transition: $sidebarTransition
|
||||
background-color: $boxHoverBackgroundColor
|
||||
z-index: 0
|
||||
|
||||
&:hover
|
||||
border-color: var(--active-color)
|
||||
|
||||
&.additional
|
||||
color: var(--text-secondary-color)
|
||||
|
||||
.studyModality
|
||||
color: var(--primary-background-color)
|
||||
&
|
||||
&:before
|
||||
&:after
|
||||
background-color: var(--active-color)
|
||||
|
||||
&.additional
|
||||
color: var(--text-primary-color)
|
||||
font-size: 16px
|
||||
font-weight: normal
|
||||
height: 91px
|
||||
line-height: 91px
|
||||
padding: 0
|
||||
text-align: center
|
||||
|
||||
.studyText
|
||||
font-size: 13px
|
||||
left: ($spacerX * 3) + $boxWidth + ($nestingMargin * 3)
|
||||
line-height: 14px
|
||||
position: absolute
|
||||
right: $spacerX
|
||||
top: $spacerY
|
||||
.studyDate
|
||||
margin-top: 8px
|
||||
color: var(--text-secondary-color)
|
||||
.studyDescription
|
||||
margin-top: 8px
|
||||
color: var(--text-primary-color)
|
||||
.studyAvailability
|
||||
margin-top: 24px
|
||||
color: var(--text-primary-color)
|
||||
|
||||
.studyModality
|
||||
color: var(--text-secondary-color)
|
||||
font-size: 20px
|
||||
line-height: $boxWidth
|
||||
margin-left: $nestingMargin * 2
|
||||
margin-top: $nestingMargin * 2
|
||||
position: relative
|
||||
|
||||
.studyModalityText
|
||||
height: 100%
|
||||
overflow: hidden
|
||||
text-align: center
|
||||
text-transform: uppercase
|
||||
|
||||
&
|
||||
&:before
|
||||
&:after
|
||||
border: $borderThickness solid var(--primary-background-color)
|
||||
background-color: var(--box-background-color)
|
||||
border-radius: $boxBorderRadius
|
||||
height: $boxWidth + ($borderThickness * 2)
|
||||
transition($sidebarTransition)
|
||||
width: $boxWidth + ($borderThickness * 2)
|
||||
|
||||
&:before
|
||||
&:after
|
||||
display: block
|
||||
content: ''
|
||||
position: absolute
|
||||
|
||||
&:before
|
||||
top: -($borderThickness + $nestingMargin)
|
||||
left: -($borderThickness + $nestingMargin)
|
||||
z-index: -1
|
||||
|
||||
&:after
|
||||
top: -($borderThickness + ($nestingMargin * 2))
|
||||
left: -($borderThickness + ($nestingMargin * 2))
|
||||
z-index: -2
|
||||
@@ -0,0 +1,37 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { StudiesItem } from './StudiesItem.js';
|
||||
import './StudiesList.styl';
|
||||
|
||||
export class StudiesList extends Component {
|
||||
static propTypes = {
|
||||
class: PropTypes.string,
|
||||
studyListData: PropTypes.array.isRequired,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
activeStudyInstanceUid: PropTypes.string,
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={`studiesList ${this.props.class}`}>
|
||||
{this.getBrowserItems()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getBrowserItems = () => {
|
||||
return this.props.studyListData.map((studyData, index) => {
|
||||
return (
|
||||
<StudiesItem
|
||||
key={index}
|
||||
studyData={studyData}
|
||||
active={
|
||||
studyData.studyInstanceUid === this.props.activeStudyInstanceUid
|
||||
}
|
||||
onClick={event => this.props.onClick(studyData)}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,61 @@
|
||||
---
|
||||
name: Quick Switch
|
||||
menu: Components
|
||||
route: /components/quick-switch
|
||||
---
|
||||
|
||||
import { Playground, Props } from 'docz'
|
||||
import { State } from 'react-powerplug'
|
||||
import { QuickSwitch } from './../index.js'
|
||||
//
|
||||
import studies from './studies.js'
|
||||
|
||||
# Quick Switch
|
||||
|
||||
## Basic usage
|
||||
|
||||
<Playground>
|
||||
<State initial={{
|
||||
studyListData: studies,
|
||||
}}>
|
||||
{({ state, setState }) => (
|
||||
<QuickSwitch
|
||||
studyListData={state.studyListData}
|
||||
// If this is always activeStudy's thumbnails,
|
||||
// Why do we need to specify this?
|
||||
seriesListData={
|
||||
state.studyListData.find((study) => {
|
||||
return !!study.active;
|
||||
}).thumbnails}
|
||||
onSeriesSelected={(selectedSeries) => {
|
||||
const { studyListData } = state;
|
||||
const selectedId = selectedSeries.displaySetInstanceUid;
|
||||
|
||||
studyListData.forEach(study => {
|
||||
study.thumbnails.forEach(series => {
|
||||
series.active = series.displaySetInstanceUid === selectedId;
|
||||
})
|
||||
});
|
||||
|
||||
setState({ studyListData });
|
||||
}}
|
||||
onStudySelected={(selectedStudy) => {
|
||||
const { studyListData } = state;
|
||||
const selectedId = selectedStudy.studyInstanceUid;
|
||||
|
||||
studyListData.forEach(study => {
|
||||
study.active = study.studyInstanceUid === selectedId;
|
||||
});
|
||||
|
||||
setState({ studyListData });
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
</State>
|
||||
|
||||
</Playground>
|
||||
|
||||
## API
|
||||
|
||||
<Props of={QuickSwitch} />
|
||||
@@ -0,0 +1,76 @@
|
||||
export default [
|
||||
{
|
||||
studyInstanceUid: '10001',
|
||||
studyDescription: 'Anti-PD-1',
|
||||
modalities: 'CT',
|
||||
studyDate: '18-nov-2018',
|
||||
active: false,
|
||||
thumbnails: [
|
||||
{
|
||||
imageSrc:
|
||||
'https://raw.githubusercontent.com/crowds-cure/cancer/master/public/screenshots/Anti-PD-1_Lung.jpg',
|
||||
seriesDescription: 'Anti-PD-1_Lung',
|
||||
seriesNumber: '2',
|
||||
numImageFrames: 512,
|
||||
displaySetInstanceUid: '10001-1',
|
||||
stackPercentComplete: 30,
|
||||
},
|
||||
{
|
||||
imageSrc:
|
||||
'https://raw.githubusercontent.com/crowds-cure/cancer/master/public/screenshots/Anti-PD-1_MELANOMA.jpg',
|
||||
seriesDescription: 'Anti-PD-1_MELANOMA',
|
||||
seriesNumber: '2',
|
||||
instanceNumber: '1',
|
||||
numImageFrames: 256,
|
||||
displaySetInstanceUid: '10001-2',
|
||||
stackPercentComplete: 70,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
studyInstanceUid: '10002',
|
||||
studyDescription: 'CPTAC',
|
||||
modalities: 'CT',
|
||||
studyDate: '16-aug-2017',
|
||||
active: true,
|
||||
thumbnails: [
|
||||
{
|
||||
imageSrc:
|
||||
'https://raw.githubusercontent.com/crowds-cure/cancer/master/public/screenshots/CPTAC-GBM.jpg',
|
||||
seriesDescription: 'CPTAC-GBM',
|
||||
active: true,
|
||||
seriesNumber: '2',
|
||||
numImageFrames: 512,
|
||||
displaySetInstanceUid: '10002-1',
|
||||
stackPercentComplete: 100,
|
||||
},
|
||||
{
|
||||
imageSrc:
|
||||
'https://raw.githubusercontent.com/crowds-cure/cancer/master/public/screenshots/CPTAC-CM.jpg',
|
||||
seriesDescription: 'CPTAC-CM',
|
||||
seriesNumber: '2',
|
||||
instanceNumber: '1',
|
||||
displaySetInstanceUid: '10002-2',
|
||||
numImageFrames: 256,
|
||||
},
|
||||
{
|
||||
imageSrc:
|
||||
'https://raw.githubusercontent.com/crowds-cure/cancer/master/public/screenshots/CPTAC-HNSCC.jpg',
|
||||
seriesDescription: 'CPTAC-HNSCC',
|
||||
seriesNumber: '2',
|
||||
instanceNumber: '1',
|
||||
displaySetInstanceUid: '10002-3',
|
||||
numImageFrames: 256,
|
||||
},
|
||||
{
|
||||
imageSrc:
|
||||
'https://raw.githubusercontent.com/crowds-cure/cancer/master/public/screenshots/CPTAC-LSCC.jpg',
|
||||
seriesDescription: 'CPTAC-LSCC',
|
||||
seriesNumber: '2',
|
||||
instanceNumber: '1',
|
||||
displaySetInstanceUid: '10002-4',
|
||||
numImageFrames: 256,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
export { QuickSwitch } from './QuickSwitch.js';
|
||||
Reference in new issue
Block a user