Begin switching study browser use react-viewerbase
This commit is contained in:
parent
83a7271cd1
commit
c3565cd687
@ -1,13 +0,0 @@
|
|||||||
<template name="flexboxLayout">
|
|
||||||
<div class="viewerSection">
|
|
||||||
<div class="sidebarMenu sidebar-left {{#if leftSidebarOpen}}sidebar-open{{/if}}">
|
|
||||||
{{> studyBrowser (clone this)}}
|
|
||||||
</div>
|
|
||||||
<div class="mainContent {{#if leftSidebarOpen}}sidebar-left-open{{/if}} {{#if rightSidebarOpen}}sidebar-right-open{{/if}}">
|
|
||||||
{{> React component=ViewerMain studies=this.studies}}
|
|
||||||
</div>
|
|
||||||
<div class="sidebarMenu sidebar-right {{#if rightSidebarOpen}}sidebar-open{{/if}}">
|
|
||||||
{{> measurementLightTable (clone this)}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1,15 +1,176 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { Viewerbase } from 'meteor/ohif:viewerbase';
|
import { Viewerbase } from 'meteor/ohif:viewerbase';
|
||||||
|
import { StudyBrowser } from 'react-viewerbase';
|
||||||
|
|
||||||
Template.flexboxLayout.helpers({
|
/**
|
||||||
leftSidebarOpen() {
|
* Asynchronous wrapper around Cornerstone's renderToCanvas method.
|
||||||
return Template.instance().data.state.get('leftSidebar');
|
*
|
||||||
},
|
* @param {HTMLElement} canvasElement An HTML <canvas> element
|
||||||
|
* @param {Image} image A Cornerstone Image
|
||||||
|
*
|
||||||
|
* @return {Promise} A promise tracking the progress of the rendering. Resolves empty.
|
||||||
|
*/
|
||||||
|
function renderAsync(canvasElement, image) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
cornerstone.renderToCanvas(canvasElement, image);
|
||||||
|
resolve();
|
||||||
|
} catch(error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
rightSidebarOpen() {
|
// Define a handler for success on image load
|
||||||
return Template.instance().data.state.get('rightSidebar');
|
const loadSuccess = function(image, studyInstanceUid, displaySetInstanceUid) {
|
||||||
},
|
// This is an off-screen canvas. It's used to get dataURL images by using
|
||||||
|
// cornerstone.renderToCanvas function.
|
||||||
|
const canvasElement = document.createElement('canvas');
|
||||||
|
canvasElement.width = 193;
|
||||||
|
canvasElement.height = 123;
|
||||||
|
|
||||||
ViewerMain() {
|
console.warn(this.state);
|
||||||
return Viewerbase.components.viewer.ViewerMain;
|
|
||||||
|
// Render the image to canvas to be able to get its dataURL
|
||||||
|
renderAsync(canvasElement, image).then(() => {
|
||||||
|
const studies = this.state.studiesForBrowser;
|
||||||
|
const study = studies.find(study => study.studyInstanceUid === studyInstanceUid);
|
||||||
|
const thumbnail = study.thumbnails.find(t => t.displaySetInstanceUid === displaySetInstanceUid);
|
||||||
|
|
||||||
|
thumbnail.imageSrc = canvasElement.toDataURL('image/jpeg', 1);
|
||||||
|
|
||||||
|
console.warn(this.state);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
studiesForBrowser: studies
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define a handler for error on image load
|
||||||
|
const loadError = function(error, studyInstanceUid, displaySetInstanceUid) {
|
||||||
|
const studies = this.state.studiesForBrowser;
|
||||||
|
const study = studies.find(study => study.studyInstanceUid === studyInstanceUid);
|
||||||
|
const thumbnail = study.thumbnails.find(t => t.displaySetInstanceUid === displaySetInstanceUid);
|
||||||
|
|
||||||
|
thumbnail.error = error;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
studiesForBrowser: studies
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const ViewerMain = Viewerbase.components.viewer.ViewerMain;
|
||||||
|
|
||||||
|
class FlexboxLayout extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
leftSidebarOpen: true,
|
||||||
|
rightSidebarOpen: false,
|
||||||
|
studiesForBrowser: this.getStudiesForBrowser(),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getStudiesForBrowser = this.getStudiesForBrowser.bind(this);
|
||||||
|
this.getThumbnailsFromImageIds = this.getThumbnailsFromImageIds.bind(this);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.getThumbnailsFromImageIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
getThumbnailsFromImageIds() {
|
||||||
|
const studyThumbnails = this.state.studiesForBrowser.forEach(function (study) {
|
||||||
|
const { studyInstanceUid } = study;
|
||||||
|
|
||||||
|
study.thumbnails.forEach(function (displaySet) {
|
||||||
|
const imageId = displaySet.imageId;
|
||||||
|
const {displaySetInstanceUid, seriesDescription, seriesNumber, instanceNumber, numImageFrames} = displaySet;
|
||||||
|
|
||||||
|
cornerstone.loadAndCacheImage(imageId).then((image) => {
|
||||||
|
loadSuccess.call(this, image, studyInstanceUid, displaySetInstanceUid);
|
||||||
|
}, error => {
|
||||||
|
loadError.call(this, error, studyInstanceUid, displaySetInstanceUid);
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getStudiesForBrowser() {
|
||||||
|
// @TypeSafeStudies
|
||||||
|
const studies = OHIF.viewer.Studies.findAllBy({
|
||||||
|
selected: true
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// TODO[react]:
|
||||||
|
// - Add sorting of display sets
|
||||||
|
// - Pass in which display set is active from Redux
|
||||||
|
// - Pass in errors and stack loading progress from Redux
|
||||||
|
// - Add useMiddleSeriesInstanceAsThumbnail
|
||||||
|
// - Add showStackLoadingProgressBar option
|
||||||
|
return studies.map((study) => {
|
||||||
|
const { studyInstanceUid } = study;
|
||||||
|
|
||||||
|
const thumbnails = study.displaySets.map((displaySet) => {
|
||||||
|
const active = false;
|
||||||
|
const stackPercentComplete = 0;
|
||||||
|
const { displaySetInstanceUid, seriesDescription, seriesNumber, instanceNumber, numImageFrames } = displaySet;
|
||||||
|
const imageId = displaySet.images[0].getImageId();
|
||||||
|
return {
|
||||||
|
imageSrc: '',
|
||||||
|
imageId,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
seriesDescription,
|
||||||
|
seriesNumber,
|
||||||
|
instanceNumber,
|
||||||
|
numImageFrames,
|
||||||
|
active,
|
||||||
|
stackPercentComplete
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
studyInstanceUid,
|
||||||
|
thumbnails
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let mainContentClassName = "mainContent"
|
||||||
|
if (this.state.leftSidebarOpen) {
|
||||||
|
mainContentClassName += ' sidebar-left-open';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.state.rightSidebarOpen) {
|
||||||
|
mainContentClassName += ' sidebar-right-open';
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO[react]: Add measurementLightTable
|
||||||
|
return (
|
||||||
|
<div className="viewerSection">
|
||||||
|
<div className={this.state.leftSidebarOpen ? "sidebarMenu sidebar-left sidebar-open" : "sidebarMenu sidebar-left"}>
|
||||||
|
<StudyBrowser studies={this.state.studiesForBrowser}/>
|
||||||
|
</div>
|
||||||
|
<div className={mainContentClassName}>
|
||||||
|
<ViewerMain studies={this.props.studies}/>
|
||||||
|
</div>
|
||||||
|
<div className={this.state.rightSidebarOpen ? "sidebarMenu sidebar-right sidebar-open" : "sidebarMenu sidebar-right"}>
|
||||||
|
{/*{{> measurementLightTable (clone this)}}*/}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlexboxLayout.propTypes = {
|
||||||
|
studies: PropTypes.array.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FlexboxLayout;
|
||||||
|
|||||||
@ -1,13 +1,19 @@
|
|||||||
<template name="viewer">
|
<template name="viewer">
|
||||||
{{#if and Template.subscriptionsReady}}
|
{{#if and Template.subscriptionsReady}}
|
||||||
|
<div class="viewerDialogs-react">
|
||||||
|
{{> React component=CineDialog}}
|
||||||
|
</div>
|
||||||
<div class="viewerDialogs">
|
<div class="viewerDialogs">
|
||||||
{{>cineDialog}}
|
|
||||||
{{>layoutChooser}}
|
{{>layoutChooser}}
|
||||||
{{>annotationDialogs}}
|
{{>annotationDialogs}}
|
||||||
</div>
|
</div>
|
||||||
<div id="viewer">
|
<div id="viewer">
|
||||||
{{>toolbarSection (clone this state=state)}}
|
<div>
|
||||||
{{>flexboxLayout (clone this state=state)}}
|
{{>toolbarSection (clone this state=state)}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{> React component=FlexboxLayout studies=this.studies}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{>loadingText}}
|
{{>loadingText}}
|
||||||
|
|||||||
@ -6,6 +6,9 @@ import { Tracker } from 'meteor/tracker';
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
import { MeasurementTable } from 'meteor/ohif:measurement-table';
|
import { MeasurementTable } from 'meteor/ohif:measurement-table';
|
||||||
|
|
||||||
|
import { CineDialog } from 'react-viewerbase';
|
||||||
|
import FlexboxLayout from '../flexboxLayout/flexboxLayout.js';
|
||||||
|
|
||||||
import 'meteor/ohif:cornerstone';
|
import 'meteor/ohif:cornerstone';
|
||||||
import 'meteor/ohif:viewerbase';
|
import 'meteor/ohif:viewerbase';
|
||||||
import 'meteor/ohif:metadata';
|
import 'meteor/ohif:metadata';
|
||||||
@ -180,5 +183,13 @@ Template.viewer.onDestroyed(function() {
|
|||||||
Template.viewer.helpers({
|
Template.viewer.helpers({
|
||||||
state() {
|
state() {
|
||||||
return Template.instance().state;
|
return Template.instance().state;
|
||||||
|
},
|
||||||
|
|
||||||
|
CineDialog() {
|
||||||
|
return CineDialog
|
||||||
|
},
|
||||||
|
|
||||||
|
FlexboxLayout() {
|
||||||
|
return FlexboxLayout
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
12
OHIFViewer/package-lock.json
generated
12
OHIFViewer/package-lock.json
generated
@ -49,6 +49,11 @@
|
|||||||
"integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==",
|
"integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"classnames": {
|
||||||
|
"version": "2.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
||||||
|
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
|
||||||
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
@ -413,6 +418,13 @@
|
|||||||
"warning": "^4.0.1"
|
"warning": "^4.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-viewerbase": {
|
||||||
|
"version": "git://github.com/OHIF/react-viewerbase.git#af26417b7c1da75b713f70b38c9dc3ce29e5c359",
|
||||||
|
"from": "git://github.com/OHIF/react-viewerbase.git",
|
||||||
|
"requires": {
|
||||||
|
"classnames": "^2.2.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "2.3.6",
|
"version": "2.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||||
|
|||||||
@ -12,7 +12,8 @@
|
|||||||
"react": "^16.6.3",
|
"react": "^16.6.3",
|
||||||
"react-dom": "^16.6.3",
|
"react-dom": "^16.6.3",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^4.3.1",
|
||||||
"redux": "^4.0.1"
|
"redux": "^4.0.1",
|
||||||
|
"react-viewerbase": "git://github.com:OHIF/react-viewerbase.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"puppeteer": "^1.5.0"
|
"puppeteer": "^1.5.0"
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
<template name="studyBrowser">
|
|
||||||
<div class="studyBrowser">
|
|
||||||
<div class="scrollableStudyThumbnails">
|
|
||||||
{{#each study in studies}}
|
|
||||||
{{#each thumbnail in (sort (studyThumbnails study) thumbnailSortBy thumbnailSortType)}}
|
|
||||||
{{>thumbnailEntry thumbnail=thumbnail}}
|
|
||||||
{{/each}}
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { Template } from 'meteor/templating';
|
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
|
||||||
|
|
||||||
Template.studyBrowser.helpers({
|
|
||||||
studies() {
|
|
||||||
// @TypeSafeStudies
|
|
||||||
return OHIF.viewer.Studies.findAllBy({
|
|
||||||
selected: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
.studyBrowser
|
|
||||||
float: left
|
|
||||||
height: 100%
|
|
||||||
width: 100%
|
|
||||||
overflow: hidden
|
|
||||||
background-color: black
|
|
||||||
padding-bottom: 20px
|
|
||||||
|
|
||||||
.scrollableStudyThumbnails
|
|
||||||
height: 100%
|
|
||||||
overflow-y: auto
|
|
||||||
overflow-x: hidden
|
|
||||||
padding-bottom: 50px
|
|
||||||
padding-right: 16px
|
|
||||||
padding-left: 4px
|
|
||||||
margin-right: -16px
|
|
||||||
|
|
||||||
&::-webkit-scrollbar
|
|
||||||
display: none
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
<template name="thumbnailEntry">
|
|
||||||
{{#let stack=this.thumbnail.stack}}
|
|
||||||
<div class="thumbnailEntry noselect m-t-1 m-b-2 {{draggableClass}} {{#if isDisplaySetActive stack.displaySetInstanceUid viewportIndex}}active{{/if}}">
|
|
||||||
<div class="p-x-1">
|
|
||||||
{{>imageThumbnail thumbnail=thumbnail currentStudy=currentStudy}}
|
|
||||||
</div>
|
|
||||||
<div class="seriesDetails flex-h m-x-1 {{#unless stack.seriesDescription}}info-only{{/unless}}">
|
|
||||||
<div class="seriesDescription flex-grow">
|
|
||||||
{{stack.seriesDescription}}
|
|
||||||
</div>
|
|
||||||
<div class="seriesInformation">
|
|
||||||
<div class="item item-series clearfix">
|
|
||||||
<div class="icon">S:</div>
|
|
||||||
<div class="value">{{stack.seriesNumber}}</div>
|
|
||||||
</div>
|
|
||||||
{{#unless isUndefined instanceNumber}}
|
|
||||||
<div class="item item-series clearfix">
|
|
||||||
<div class="icon">I:</div>
|
|
||||||
<div class="value">{{instanceNumber}}</div>
|
|
||||||
</div>
|
|
||||||
{{/unless}}
|
|
||||||
<div class="item item-frames clearfix">
|
|
||||||
<div class="icon"><div></div></div>
|
|
||||||
<div class="value">{{stack.numImageFrames}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/let}}
|
|
||||||
</template>
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
import { Template } from 'meteor/templating';
|
|
||||||
import { _ } from 'meteor/underscore';
|
|
||||||
import { Session } from 'meteor/session';
|
|
||||||
|
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
|
||||||
import { thumbnailDragHandlers } from '../../../lib/thumbnailDragHandlers';
|
|
||||||
|
|
||||||
Template.thumbnailEntry.onCreated(() => {
|
|
||||||
const instance = Template.instance();
|
|
||||||
|
|
||||||
// Check if the thumbnails will be draggable or clickable
|
|
||||||
const isIndexUndefined = _.isUndefined(instance.data.viewportIndex);
|
|
||||||
instance.isDragAndDrop = isIndexUndefined && OHIF.uiSettings.leftSidebarDragAndDrop !== false;
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.thumbnailEntry.events({
|
|
||||||
// Event handlers for drag and drop
|
|
||||||
'mousedown .thumbnailEntry'(event, instance) {
|
|
||||||
const data = instance.data.thumbnail.stack;
|
|
||||||
if (!instance.isDragAndDrop || event.button !== 0) return;
|
|
||||||
thumbnailDragHandlers.thumbnailDragStartHandler(event, data);
|
|
||||||
},
|
|
||||||
|
|
||||||
'touchstart .thumbnailEntry'(event, instance) {
|
|
||||||
const data = instance.data.thumbnail.stack;
|
|
||||||
if (!instance.isDragAndDrop) return;
|
|
||||||
thumbnailDragHandlers.thumbnailDragStartHandler(event, data);
|
|
||||||
},
|
|
||||||
|
|
||||||
'touchmove .thumbnailEntry'(event, instance) {
|
|
||||||
if (!instance.isDragAndDrop) return;
|
|
||||||
thumbnailDragHandlers.thumbnailDragHandler(event);
|
|
||||||
},
|
|
||||||
|
|
||||||
'touchend .thumbnailEntry'(event, instance) {
|
|
||||||
const data = instance.data.thumbnail.stack;
|
|
||||||
if (!instance.isDragAndDrop) return;
|
|
||||||
thumbnailDragHandlers.thumbnailDragEndHandler(event, data);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Event handlers for click (quick switch)
|
|
||||||
'click .thumbnailEntry'(event, instance) {
|
|
||||||
if (instance.isDragAndDrop) return;
|
|
||||||
|
|
||||||
// Get the thumbnail stack data
|
|
||||||
const data = instance.data.thumbnail.stack;
|
|
||||||
|
|
||||||
// Get the viewport index
|
|
||||||
let { viewportIndex } = instance.data;
|
|
||||||
if (_.isUndefined(viewportIndex)) {
|
|
||||||
viewportIndex = window.store.getState().viewports.activeViewport || 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rerender the viewport using the clicked thumbnail data
|
|
||||||
OHIF.viewerbase.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, data);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Event handlers for double click
|
|
||||||
'dblclick .thumbnailEntry'(event, instance) {
|
|
||||||
if (!instance.isDragAndDrop) return;
|
|
||||||
|
|
||||||
// Get the active viewport index and total number of viewports...
|
|
||||||
const viewportCount = OHIF.viewerbase.layoutManager.getNumberOfViewports();
|
|
||||||
let viewportIndex = window.store.getState().viewports.activeViewport || 0;
|
|
||||||
if (viewportIndex >= viewportCount) {
|
|
||||||
viewportIndex = viewportCount > 0 ? viewportCount - 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the thumbnail stack data
|
|
||||||
const data = instance.data.thumbnail.stack;
|
|
||||||
|
|
||||||
// Rerender the viewport using the clicked thumbnail data
|
|
||||||
OHIF.viewerbase.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.thumbnailEntry.helpers({
|
|
||||||
draggableClass() {
|
|
||||||
return Template.instance().isDragAndDrop ? 'draggable' : '';
|
|
||||||
},
|
|
||||||
|
|
||||||
instanceNumber() {
|
|
||||||
const thumbnail = Template.instance().data.thumbnail;
|
|
||||||
if (!thumbnail) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stack = thumbnail.stack;
|
|
||||||
if (!stack) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No need to show instance number for single-frame images
|
|
||||||
if (!stack.isMultiFrame) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstImage = stack.images[0];
|
|
||||||
if (!firstImage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return firstImage.instanceNumber;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
@import "{ohif:design}/app"
|
|
||||||
|
|
||||||
$seriesCountBackgroundColor = #678696
|
|
||||||
|
|
||||||
.thumbnailEntry
|
|
||||||
cursor: pointer
|
|
||||||
display: table
|
|
||||||
margin: 0 auto
|
|
||||||
|
|
||||||
&.draggable
|
|
||||||
cursor: copy
|
|
||||||
cursor: -webkit-grab
|
|
||||||
cursor: -moz-grab
|
|
||||||
|
|
||||||
.seriesDetails
|
|
||||||
theme('color', '$textPrimaryColor')
|
|
||||||
font-size: 14px
|
|
||||||
line-height: 1.3em
|
|
||||||
margin-top: 5px
|
|
||||||
max-width: 217px
|
|
||||||
min-height: 36px
|
|
||||||
position: relative
|
|
||||||
word-wrap: break-word
|
|
||||||
|
|
||||||
&.info-only
|
|
||||||
|
|
||||||
.seriesDescription
|
|
||||||
display: none
|
|
||||||
|
|
||||||
.seriesInformation
|
|
||||||
display: flex
|
|
||||||
flex-grow: 1
|
|
||||||
float: none
|
|
||||||
max-width: none
|
|
||||||
padding-right: 0
|
|
||||||
|
|
||||||
.item
|
|
||||||
flex: 1
|
|
||||||
text-align: center
|
|
||||||
|
|
||||||
.icon, .value
|
|
||||||
display: inline
|
|
||||||
float: none
|
|
||||||
line-height: 25px
|
|
||||||
|
|
||||||
.value
|
|
||||||
margin-left: 0
|
|
||||||
width: auto
|
|
||||||
|
|
||||||
.seriesInformation
|
|
||||||
padding-right: 4px
|
|
||||||
max-width: 50px
|
|
||||||
|
|
||||||
.item-frames .icon
|
|
||||||
height: 18px
|
|
||||||
|
|
||||||
.value
|
|
||||||
theme('color', '$textSecondaryColor')
|
|
||||||
display: inline-block
|
|
||||||
float: right
|
|
||||||
font-size: 12px
|
|
||||||
margin-left: 4px
|
|
||||||
overflow: hidden
|
|
||||||
text-overflow: ellipsis
|
|
||||||
white-space: nowrap
|
|
||||||
width: calc(100% - 15px)
|
|
||||||
|
|
||||||
.icon
|
|
||||||
theme('color', '$activeColor')
|
|
||||||
display: inline-block
|
|
||||||
float: left
|
|
||||||
font-size: 10px
|
|
||||||
font-weight: 900
|
|
||||||
text-align: right
|
|
||||||
width: 11px
|
|
||||||
|
|
||||||
div
|
|
||||||
background-color: $seriesCountBackgroundColor
|
|
||||||
margin-top: 6px
|
|
||||||
position: relative
|
|
||||||
|
|
||||||
&:after
|
|
||||||
theme('background-color', '$activeColor')
|
|
||||||
box-shadow: 1px 1px rgba(0, 0, 0, .115)
|
|
||||||
left: -5px
|
|
||||||
position: absolute
|
|
||||||
top: -5px
|
|
||||||
|
|
||||||
&
|
|
||||||
&:after
|
|
||||||
theme('border', '1px solid $primaryBackgroundColor')
|
|
||||||
content: ''
|
|
||||||
display: inline-block
|
|
||||||
height: 11px
|
|
||||||
width: 11px
|
|
||||||
@ -6,6 +6,7 @@ Package.describe({
|
|||||||
|
|
||||||
Npm.depends({
|
Npm.depends({
|
||||||
'react-cornerstone-viewport': 'git://github.com:cornerstonejs/react-cornerstone-viewport.git',
|
'react-cornerstone-viewport': 'git://github.com:cornerstonejs/react-cornerstone-viewport.git',
|
||||||
|
'react-viewerbase': 'git://github.com:OHIF/react-viewerbase.git',
|
||||||
hammerjs: '2.0.8',
|
hammerjs: '2.0.8',
|
||||||
'cornerstone-core': '2.2.8',
|
'cornerstone-core': '2.2.8',
|
||||||
'cornerstone-tools': '3.0.0-b.1471',
|
'cornerstone-tools': '3.0.0-b.1471',
|
||||||
@ -118,19 +119,6 @@ Package.onUse(function(api) {
|
|||||||
api.addFiles('client/components/basic/aboutModal/aboutModal.js', 'client');
|
api.addFiles('client/components/basic/aboutModal/aboutModal.js', 'client');
|
||||||
api.addFiles('client/components/basic/aboutModal/aboutModal.styl', 'client');
|
api.addFiles('client/components/basic/aboutModal/aboutModal.styl', 'client');
|
||||||
|
|
||||||
// Study Browser components
|
|
||||||
api.addFiles('client/components/studyBrowser/studyBrowser/studyBrowser.html', 'client');
|
|
||||||
api.addFiles('client/components/studyBrowser/studyBrowser/studyBrowser.js', 'client');
|
|
||||||
api.addFiles('client/components/studyBrowser/studyBrowser/studyBrowser.styl', 'client');
|
|
||||||
|
|
||||||
api.addFiles('client/components/studyBrowser/thumbnailEntry/thumbnailEntry.html', 'client');
|
|
||||||
api.addFiles('client/components/studyBrowser/thumbnailEntry/thumbnailEntry.js', 'client');
|
|
||||||
api.addFiles('client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl', 'client');
|
|
||||||
|
|
||||||
api.addFiles('client/components/studyBrowser/imageThumbnail/imageThumbnail.html', 'client');
|
|
||||||
api.addFiles('client/components/studyBrowser/imageThumbnail/imageThumbnail.js', 'client');
|
|
||||||
api.addFiles('client/components/studyBrowser/imageThumbnail/imageThumbnail.styl', 'client');
|
|
||||||
|
|
||||||
// Viewer components
|
// Viewer components
|
||||||
api.addFiles('client/components/viewer/annotationDialogs/annotationDialogs.html', 'client');
|
api.addFiles('client/components/viewer/annotationDialogs/annotationDialogs.html', 'client');
|
||||||
api.addFiles('client/components/viewer/annotationDialogs/annotationDialogs.js', 'client');
|
api.addFiles('client/components/viewer/annotationDialogs/annotationDialogs.js', 'client');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user