Adjusting Standalone Viewer to the new structure

This commit is contained in:
Bruno Alves de Faria 2017-03-20 17:13:41 -03:00
parent 718fd30feb
commit bb9d04d569
21 changed files with 129 additions and 175 deletions

View File

@ -5,9 +5,7 @@
{{>section 'brand'}}
</a>
{{>section 'headerAfterBrand'}}
<a href='#' class="header-menu pull-right">
{{>section 'headerMenu'}}
</a>
<a href='#' class="header-menu pull-right">{{>section 'headerMenu'}}</a>
</div>
{{>UI.contentBlock}}
</div>

View File

@ -18,6 +18,9 @@ body>.header
text-decoration: none
theme('color', '$defaultColor')
&:empty
display: none
&.header-big
height: $topBarExpandedHeight
background-color: rgba(21, 25, 30, 0.7)

View File

@ -20,6 +20,7 @@ shell-server@0.2.1 # Server-side component of the `meteor shell` comm
# OHIF Packages
ohif:core
ohif:header
ohif:design
ohif:cornerstone
ohif:viewerbase
@ -34,6 +35,7 @@ aldeed:simple-schema@1.5.3
stylus@2.513.8
iron:router
session@1.1.7
u2622:persistent-session@0.4.4
practicalmeteor:loglevel
reactive-dict@1.1.8
twbs:bootstrap

View File

@ -6,6 +6,7 @@ aldeed:schema-index@1.1.1
aldeed:simple-schema@1.5.3
aldeed:template-extension@4.0.0
allow-deny@1.0.5
amplify@1.0.0
autoupdate@1.3.12
babel-compiler@6.13.0
babel-runtime@1.0.1
@ -76,9 +77,12 @@ ohif:cornerstone@0.0.1
ohif:design@0.0.1
ohif:dicom-services@0.0.1
ohif:hanging-protocols@0.0.1
ohif:header@0.0.1
ohif:log@0.0.1
ohif:metadata@0.0.1
ohif:study-list@0.0.1
ohif:themes@0.0.1
ohif:themes-common@0.0.1
ohif:viewerbase@0.0.1
ohif:wadoproxy@0.0.1
ordered-dict@1.0.9
@ -110,6 +114,7 @@ templating-runtime@1.2.15
templating-tools@1.0.5
tracker@1.1.1
twbs:bootstrap@3.3.6
u2622:persistent-session@0.4.4
ui@1.0.12
underscore@1.0.10
url@1.0.11

View File

@ -1,10 +1,10 @@
<template name="flexboxLayout">
<div class="viewerSection">
<div class="sidebarMenu sidebar-left {{#if leftSidebarOpen}}sidebar-open{{/if}}">
{{> studyBrowser (clone this)}}
{{>studyBrowser (clone this)}}
</div>
<div class="mainContent {{#if leftSidebarOpen}}sidebar-left-open{{/if}}">
{{> standaloneViewerMain (clone this)}}
{{>standaloneViewerMain (clone this)}}
</div>
</div>
</template>

View File

@ -1,5 +1,7 @@
import { Template } from 'meteor/templating';
Template.flexboxLayout.events({
'transitionend .sidebarMenu'(event) {
'transitionend .sidebarMenu'(event, instance) {
if (!event.target.classList.contains('sidebarMenu')) {
return;
}

View File

@ -1,17 +1,11 @@
<template name="standaloneViewer">
<div class="topBar noselect">
<div class="clearfix">
<a target='_blank'
class="brandSection pull-left"
href="http://ohif.org">
<svg class="logoImage">
<use xlink:href={{absoluteUrl "packages/ohif_viewerbase/assets/icons.svg#icon-ohif-logo"}}></use>
</svg>
<div class="logoText">
Open Health Imaging Foundation
</div>
</a>
</div>
</div>
{{> viewer }}
{{#header}}
{{#section 'brand'}}
<svg class="logo-image">
<use xlink:href={{absoluteUrl "packages/ohif_viewerbase/assets/icons.svg#icon-ohif-logo"}}></use>
</svg>
<div class="logo-text">Open Health Imaging Foundation</div>
{{/section}}
{{/header}}
{{>viewer}}
</template>

View File

@ -1,78 +1,24 @@
@import "{ohif:design}/app"
$expandedHeight = 160px
body>.header
.logoImage
display: inline-block
height: 100%
float: left
.topBar
height: $topBarHeight
padding: 10px 10px 0
theme('color', '$textPrimaryColor')
theme('background-color', '$primaryBackgroundColor')
transition(all 0.5s ease)
&>.clearfix
position: relative
.brandSection
.brand
height: 30px
display: inline-block
text-decoration: none
.logoImage
.logo-image
display: inline-block
fill: transparent
float: left
height: 100%
margin: 0 8px 0 0
width: 30px
.logoText
.logo-text
display: inline-block
font-family: $logoFontFamily
font-size: 14px
font-weight: $logoFontWeight
theme('color', '$textPrimaryColor')
line-height: 30px
.studyListLinkSection
theme('border-left', '%s solid $uiBorderColor' % $uiBorderThickness)
margin: 3px 0 0 10px
padding: 0 0 0 10px
.btn
theme('color', '$textSecondaryColor')
cursor: pointer
font-size: 13px
font-weight: 500
line-height: 26px
&:hover
theme('color', '$hoverColor')
&:active
theme('color', '$activeColor')
&.studyList
background-color: rgba(21, 25, 30, 0.7)
height: $expandedHeight
padding-left: $studyListPadding
padding-right: $studyListPadding
.brandSection
height: 100%
width: 80%
line-height: $expandedHeight - 10px
.logoImage
width: 50px
margin: 0 20px 0 0
.logoText
font-size: 30px
.studyListLinkSection
border: none
left: 0
margin: 0
padding: 0
position: absolute
top: 0

View File

@ -1,6 +1,5 @@
<template name="standaloneViewerMain">
<div class="viewerMain">
<div id='layoutManagerTarget'>
</div>
<div id='layoutManagerTarget'></div>
</div>
</template>
</template>

View File

@ -1,3 +1,5 @@
import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { OHIF } from 'meteor/ohif:core';
import 'meteor/ohif:viewerbase';

View File

@ -11,7 +11,7 @@
#imageViewerViewports
padding-right: 0 !important // Top remove odd borders from non-existant right Sidebar
.viewportContainer
theme('border', '%s solid $uiBorderColorDark' % $viewportBorderThickness)
float: left

View File

@ -4,8 +4,7 @@
<div class="pull-left m-t-1">
{{>roundedButtonGroup leftSidebarToggleButtonData}}
</div>
{{> toolbarSectionTools
toolbarButtons=toolbarButtons}}
{{>toolbarSectionTools toolbarButtons=toolbarButtons}}
</div>
</div>
</template>

View File

@ -1,3 +1,4 @@
import { Template } from 'meteor/templating';
import { OHIF } from 'meteor/ohif:core';
import 'meteor/ohif:viewerbase';
@ -85,7 +86,7 @@ Template.toolbarSection.helpers({
iconClasses: 'fa fa-trash'
});
var buttonData = [];
const buttonData = [];
buttonData.push({
id: 'zoom',
@ -220,7 +221,7 @@ Template.toolbarSection.onRendered(function() {
const disabledToolButtons = states.disabledToolButtons;
const allToolbarButtons = $('#toolbar').find('button');
if (disabledToolButtons && disabledToolButtons.length > 0) {
for (var i = 0; i < allToolbarButtons.length; i++) {
for (let i = 0; i < allToolbarButtons.length; i++) {
const toolbarButton = allToolbarButtons[i];
$(toolbarButton).prop('disabled', false);

View File

@ -1,15 +1,15 @@
<template name="viewer">
{{#if Template.subscriptionsReady}}
<div class="viewerDialogs">
{{> cineDialog}}
{{> layoutChooser }}
{{> annotationDialogs }}
</div>
<div id="viewer">
{{> toolbarSection (clone this)}}
{{> flexboxLayout (clone this)}}
</div>
<div class="viewerDialogs">
{{>cineDialog}}
{{>layoutChooser}}
{{>annotationDialogs}}
</div>
<div id="viewer">
{{>toolbarSection (clone this)}}
{{>flexboxLayout (clone this)}}
</div>
{{else}}
{{> loadingText}}
{{>loadingText}}
{{/if}}
</template>
</template>

View File

@ -69,6 +69,9 @@ Template.viewer.onCreated(() => {
OHIF.viewer.data.activeViewport = 0;
}
// Store the viewer data in session for further user
Session.setPersistent('ViewerData', OHIF.viewer.data);
Session.set('activeViewport', OHIF.viewer.data.activeViewport || 0);
// @TypeSafeStudies

View File

@ -3,15 +3,15 @@ import { OHIF } from 'meteor/ohif:core';
import { cornerstoneWADOImageLoader } from 'meteor/ohif:cornerstone';
Meteor.startup(function() {
const maxWebWorkers = Math.max(navigator.hardwareConcurrency - 1, 1);
const maxWebWorkers = Math.max(navigator.hardwareConcurrency - 1, 1);
const config = {
maxWebWorkers: maxWebWorkers,
startWebWorkersOnDemand: true,
webWorkerPath : OHIF.utils.absoluteUrl('packages/ohif_cornerstone/public/js/cornerstoneWADOImageLoaderWebWorker.es5.js'),
maxWebWorkers: maxWebWorkers,
startWebWorkersOnDemand: true,
webWorkerPath: OHIF.utils.absoluteUrl('packages/ohif_cornerstone/public/js/cornerstoneWADOImageLoaderWebWorker.es5.js'),
taskConfiguration: {
'decodeTask' : {
loadCodecsOnStartup : true,
initializeCodecsOnStartup: false,
decodeTask: {
loadCodecsOnStartup: true,
initializeCodecsOnStartup: false,
codecsPath: OHIF.utils.absoluteUrl('packages/ohif_cornerstone/public/js/cornerstoneWADOImageLoaderCodecs.es5.js'),
usePDFJS: false
}
@ -19,4 +19,4 @@ Meteor.startup(function() {
};
cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
});
});

View File

@ -161,4 +161,4 @@ cornerstoneWebImageLoader = {};
cornerstone.registerImageLoader('https', loadImage);
cornerstoneWebImageLoader.configure = configure;
return cornerstone;
}($, cornerstone, cornerstoneWebImageLoader));
}($, cornerstone, cornerstoneWebImageLoader));

View File

@ -8,4 +8,4 @@
<meta name="MobileOptimized" content="320">
<meta name="HandheldFriendly" content="True">
<meta name="apple-mobile-web-app-capable" content="yes">
</head>
</head>

View File

@ -1,3 +0,0 @@
// Create application logger using loglevel
// https://atmospherejs.com/spacejamio/loglevel
log = loglevel.createAppLogger('StandaloneViewer', defaultLevel = 'info');

View File

@ -1,6 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { Router } from 'meteor/iron:router';
import { OHIF } from 'meteor/ohif:core';
if (Meteor.isClient) {
// Disconnect from the Meteor Server since we don't need it
console.log('Disconnecting from the Meteor server');
OHIF.log.info('Disconnecting from the Meteor server');
Meteor.disconnect();
Router.configure({
@ -15,31 +19,31 @@ if (Meteor.isClient) {
let id = this.params.id;
if (!id) {
id = 'testId';
id = 'testId';
}
// Define a request to the server to retrieve the study data
// as JSON, given an ID that was in the Route
var oReq = new XMLHttpRequest();
const oReq = new XMLHttpRequest();
// Add event listeners for request failure
oReq.addEventListener("error", () => {
console.warn("An error occurred while retrieving the JSON data");
oReq.addEventListener('error', () => {
OHIF.log.warn('An error occurred while retrieving the JSON data');
});
const self = this;
// When the JSON has been returned, parse it into a JavaScript Object
// and render the OHIF Viewer with this data
oReq.addEventListener("load", function() {
oReq.addEventListener('load', function() {
// Parse the response content
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText
if (!this.responseText) {
console.warn('Response was undefined');
OHIF.log.warn('Response was undefined');
return;
}
console.log(JSON.stringify(this.responseText, null, 2));
OHIF.log.info(JSON.stringify(this.responseText, null, 2));
const parsed = JSON.parse(this.responseText);
@ -60,8 +64,8 @@ if (Meteor.isClient) {
// Open the Request to the server for the JSON data
// In this case we have a server-side route called /api/
// which responds to GET requests with the study data
console.log('Sending Request to: ' + "/api/" + id);
oReq.open("GET", "/api/" + id);
OHIF.log.info(`Sending Request to: /api/${id}`);
oReq.open('GET', `/api/${id}`);
// Fire the request the server
oReq.send();
@ -70,7 +74,6 @@ if (Meteor.isClient) {
});
}
// This is ONLY for demo purposes.
if (Meteor.isServer) {
// You can test this with:
@ -79,19 +82,19 @@ if (Meteor.isServer) {
// Or by going to:
// http://localhost:3000/api/testId
Router.route('/api/:id', {where: 'server'}).get(function () {
Router.route('/api/:id', { where: 'server' }).get(function() {
// "this" is the RouteController instance.
// "this.response" is the Connect response object
// "this.request" is the Connect request object
const id = this.params.id;
// Find the relevant study data from the Collection given the ID
var data = RequestStudies.findOne({transactionId: id});
const data = RequestStudies.findOne({ transactionId: id });
// Set the response headers to return JSON to any server
this.response.setHeader("Content-Type", "application/json");
this.response.setHeader("Access-Control-Allow-Origin", "*");
this.response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
this.response.setHeader('Content-Type', 'application/json');
this.response.setHeader('Access-Control-Allow-Origin', '*');
this.response.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
// Change the response text depending on the available study data
if (!data) {
@ -104,4 +107,4 @@ if (Meteor.isServer) {
// Finalize the response
this.response.end();
});
}
}

View File

@ -1,3 +1,5 @@
import { Meteor } from 'meteor/meteor';
// Create a Collection to store data
RequestStudies = new Meteor.Collection('requestStudies');
@ -6,32 +8,32 @@ RequestStudies.remove({});
// Insert our test data
RequestStudies.insert({
'transactionId': 'testId',
'studies': [{
'studyInstanceUid': '23.23.21.3.32',
'patientName': 'Patient Name',
'seriesList': [{
'seriesInstanceUid': '1.23.2.32.1.2.1.3.2',
'seriesDescription': 'Wikipedia Samples',
'instances': [
transactionId: 'testId',
studies: [{
studyInstanceUid: '23.23.21.3.32',
patientName: 'Patient Name',
seriesList: [{
seriesInstanceUid: '1.23.2.32.1.2.1.3.2',
seriesDescription: 'Wikipedia Samples',
instances: [
{
'sopInstanceUid': '1.2.3.2.32.18.8',
'rows': 1, // TODO: Remove all requirement for this
'url': 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg'
sopInstanceUid: '1.2.3.2.32.18.8',
rows: 1, // TODO: Remove all requirement for this
url: 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg'
}, {
'sopInstanceUid': '1.2.3.2.32.18.9',
'rows': 1,
'url': 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Sample_Floorplan.jpg/800px-Sample_Floorplan.jpg'
sopInstanceUid: '1.2.3.2.32.18.9',
rows: 1,
url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Sample_Floorplan.jpg/800px-Sample_Floorplan.jpg'
}
]
}, {
'seriesInstanceUid': '1.33.2.32.1.2.1.3.2',
'seriesDescription': 'JPS-sample',
'instances': [
seriesInstanceUid: '1.33.2.32.1.2.1.3.2',
seriesDescription: 'JPS-sample',
instances: [
{
'sopInstanceUid': '1.2.3.2.32.18.10',
'rows': 1,
'url': 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/JPS-sample.jpg/800px-JPS-sample.jpg'
sopInstanceUid: '1.2.3.2.32.18.10',
rows: 1,
url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/JPS-sample.jpg/800px-JPS-sample.jpg'
}
]
}]
@ -40,36 +42,34 @@ RequestStudies.insert({
// Insert our test data
RequestStudies.insert({
'transactionId': 'testDICOMs',
'studies': [{
'studyInstanceUid': '23.23.21.3.32',
'patientName': 'Patient Name',
'seriesList': [{
'seriesInstanceUid': '1.23.2.32.1.2.1.3.2',
'seriesDescription': 'T-1',
'instances': [
transactionId: 'testDICOMs',
studies: [{
studyInstanceUid: '23.23.21.3.32',
patientName: 'Patient Name',
seriesList: [{
seriesInstanceUid: '1.23.2.32.1.2.1.3.2',
seriesDescription: 'T-1',
instances: [
{
'sopInstanceUid': '1.2.3.2.32.18.8',
'rows': 1, // TODO: Remove all requirement for this
'url': 'dicomweb://cornerstonetech.org/images/ClearCanvas/MRStudy/1.2.840.113619.2.5.1762583153.215519.978957063.80.dcm'
sopInstanceUid: '1.2.3.2.32.18.8',
rows: 1, // TODO: Remove all requirement for this
url: 'dicomweb://cornerstonetech.org/images/ClearCanvas/MRStudy/1.2.840.113619.2.5.1762583153.215519.978957063.80.dcm'
}, {
'sopInstanceUid': '1.2.3.2.32.18.9',
'rows': 1,
'url': 'dicomweb://cornerstonetech.org/images/ClearCanvas/MRStudy/1.2.840.113619.2.5.1762583153.215519.978957063.81.dcm'
sopInstanceUid: '1.2.3.2.32.18.9',
rows: 1,
url: 'dicomweb://cornerstonetech.org/images/ClearCanvas/MRStudy/1.2.840.113619.2.5.1762583153.215519.978957063.81.dcm'
}
]
}, {
'seriesInstanceUid': '1.33.2.32.1.2.1.3.2',
'seriesDescription': 'COR T-1',
'instances': [
seriesInstanceUid: '1.33.2.32.1.2.1.3.2',
seriesDescription: 'COR T-1',
instances: [
{
'sopInstanceUid': '1.2.3.2.32.18.10',
'rows': 1,
'url': 'dicomweb://cornerstonetech.org/images/ClearCanvas/MRStudy/1.2.840.113619.2.5.1762583153.215519.978957063.136.dcm'
sopInstanceUid: '1.2.3.2.32.18.10',
rows: 1,
url: 'dicomweb://cornerstonetech.org/images/ClearCanvas/MRStudy/1.2.840.113619.2.5.1762583153.215519.978957063.136.dcm'
}
]
}]
}]
});