Fix Viewer opening bugs in OHIF Viewer (OHIF-49)

This commit is contained in:
Erik Ziegler 2016-08-04 10:42:34 +02:00
parent 1a264f81e5
commit afeb0d82fb
21 changed files with 72 additions and 87 deletions

View File

@ -3,16 +3,6 @@ Session.setDefault('ViewerData', {});
// verifyEmail controls whether emailVerification template will be rendered or not // verifyEmail controls whether emailVerification template will be rendered or not
var verifyEmail = Meteor.settings && Meteor.settings.public && Meteor.settings.public.verifyEmail || false; var verifyEmail = Meteor.settings && Meteor.settings.public && Meteor.settings.public.verifyEmail || false;
// Re-add any tab data saved in the Session
Object.keys(ViewerData).forEach(function(contentId) {
var tabData = ViewerData[contentId];
var data = {
title: tabData.title,
contentid: tabData.contentid
};
WorklistTabs.insert(data);
});
Router.configure({ Router.configure({
layoutTemplate: 'layout', layoutTemplate: 'layout',
loadingTemplate: 'layout' loadingTemplate: 'layout'

View File

@ -2,6 +2,7 @@ Template.flexboxLayout.events({
'transitionend .sidebarMenu'() { 'transitionend .sidebarMenu'() {
handleResize(); handleResize();
}, },
'transitionend .sidebar-option'(event) { 'transitionend .sidebar-option'(event) {
// Prevent this event from bubbling // Prevent this event from bubbling
event.stopPropagation(); event.stopPropagation();

View File

@ -1,5 +1,7 @@
const worklistContentId = 'worklistTab'; const worklistContentId = 'worklistTab';
const viewerContentId = 'viewerTab'; let lastContentId;
// Test
// Define the ViewerData global object // Define the ViewerData global object
// If there is currently any Session data for this object, // If there is currently any Session data for this object,
@ -15,7 +17,7 @@ Template.ohifViewer.events({
if (contentId !== worklistContentId) { if (contentId !== worklistContentId) {
switchToTab(worklistContentId); switchToTab(worklistContentId);
} else { } else {
switchToTab(viewerContentId); switchToTab(lastContentId);
} }
} }
}); });
@ -23,6 +25,7 @@ Template.ohifViewer.events({
Template.ohifViewer.helpers({ Template.ohifViewer.helpers({
studyListToggleText() { studyListToggleText() {
const contentId = Session.get('activeContentId'); const contentId = Session.get('activeContentId');
Session.get('ViewerData');
// If the Viewer has not been opened yet, 'Back to viewer' should // If the Viewer has not been opened yet, 'Back to viewer' should
// not be displayed // not be displayed
@ -34,6 +37,7 @@ Template.ohifViewer.helpers({
if (contentId === worklistContentId) { if (contentId === worklistContentId) {
return 'Back to viewer'; return 'Back to viewer';
} else { } else {
lastContentId = contentId;
return 'Study list'; return 'Study list';
} }
}, },

View File

@ -1,5 +1,7 @@
import { OHIF } from 'meteor/ohif:core'; import { OHIF } from 'meteor/ohif:core';
//test2
OHIF.viewer = OHIF.viewer || {}; OHIF.viewer = OHIF.viewer || {};
OHIF.viewer.loadIndicatorDelay = 500; OHIF.viewer.loadIndicatorDelay = 500;
OHIF.viewer.defaultTool = 'wwwc'; OHIF.viewer.defaultTool = 'wwwc';
@ -35,9 +37,7 @@ Template.viewer.onCreated(() => {
if (ViewerData[contentId] && ViewerData[contentId].loadedSeriesData) { if (ViewerData[contentId] && ViewerData[contentId].loadedSeriesData) {
log.info('Reloading previous loadedSeriesData'); log.info('Reloading previous loadedSeriesData');
OHIF.viewer.loadedSeriesData = ViewerData[contentId].loadedSeriesData; OHIF.viewer.loadedSeriesData = ViewerData[contentId].loadedSeriesData;
} else { } else {
log.info('Setting default ViewerData'); log.info('Setting default ViewerData');
OHIF.viewer.loadedSeriesData = {}; OHIF.viewer.loadedSeriesData = {};
@ -48,7 +48,6 @@ Template.viewer.onCreated(() => {
ViewerData[contentId].viewportColumns = 1; ViewerData[contentId].viewportColumns = 1;
ViewerData[contentId].viewportRows = 1; ViewerData[contentId].viewportRows = 1;
ViewerData[contentId].activeViewport = 0; ViewerData[contentId].activeViewport = 0;
Session.set('ViewerData', ViewerData);
} }
Session.set('activeViewport', ViewerData[contentId].activeViewport || 0); Session.set('activeViewport', ViewerData[contentId].activeViewport || 0);
@ -56,10 +55,14 @@ Template.viewer.onCreated(() => {
// Update the ViewerStudies collection with the loaded studies // Update the ViewerStudies collection with the loaded studies
ViewerStudies.remove({}); ViewerStudies.remove({});
ViewerData[contentId].studyInstanceUids = [];
instance.data.studies.forEach(study => { instance.data.studies.forEach(study => {
study.selected = true; study.selected = true;
ViewerStudies.insert(study); ViewerStudies.insert(study);
ViewerData[contentId].studyInstanceUids.push(study.studyInstanceUid);
}); });
Session.set('ViewerData', ViewerData);
}); });
Template.viewer.events({ Template.viewer.events({

View File

@ -8,4 +8,9 @@
height: 100% height: 100%
width: 100% width: 100%
margin: 0 margin: 0
padding: 0 padding: 0
.loadingTextDiv
color: $textSecondaryColor
font-size: 30px
font-weight: 200

View File

@ -92,6 +92,7 @@ Template.protocolEditor.helpers({
// If no ProtocolEngine, protocol, or stage is defined, stop here // If no ProtocolEngine, protocol, or stage is defined, stop here
if (!ProtocolEngine || if (!ProtocolEngine ||
!ProtocolEngine.protocol || !ProtocolEngine.protocol ||
!ProtocolEngine.layoutManager ||
ProtocolEngine.stage === undefined) { ProtocolEngine.stage === undefined) {
return; return;
} }
@ -105,8 +106,8 @@ Template.protocolEditor.helpers({
// Update active Stage's layout template and properties based on the displayed // Update active Stage's layout template and properties based on the displayed
// layout properties. This is used to update the Stage Model when the user modifies // layout properties. This is used to update the Stage Model when the user modifies
// the layout in the viewer // the layout in the viewer
stage.viewportStructure.layoutTemplateName = layoutManager.layoutTemplateName; stage.viewportStructure.layoutTemplateName = ProtocolEngine.layoutManager.layoutTemplateName;
stage.viewportStructure.properties = layoutManager.layoutProps; stage.viewportStructure.properties = ProtocolEngine.layoutManager.layoutProps;
// If there is a discrepancy between the Stage's number of viewports and the // If there is a discrepancy between the Stage's number of viewports and the
// the number of required viewports given the properties above, rectify it // the number of required viewports given the properties above, rectify it

View File

@ -5,7 +5,7 @@ $height = 20px
#protocolEditor #protocolEditor
height: 100% height: 100%
width: 450px width: 450px
padding: 10px padding: 10px 0
position: absolute position: absolute
top: 0 top: 0
background: $primaryBackgroundColor background: $primaryBackgroundColor
@ -84,6 +84,8 @@ $height = 20px
position: absolute position: absolute
bottom: 0 bottom: 0
width: 100% width: 100%
margin-bottom: 0
background: $uiGrayDarker
p p
font-size: 8pt font-size: 8pt
@ -98,7 +100,7 @@ $height = 20px
padding-left: 20px padding-left: 20px
margin-right: -16px margin-right: -16px
width: 100% width: 100%
height: calc(100% - 120px) height: calc(100% - 50px)
&::-webkit-scrollbar &::-webkit-scrollbar
display: none display: none

View File

@ -1,6 +1,8 @@
@import "{design}/app.styl" @import "{design}/app.styl"
#stageSortingContainer #stageSortingContainer
padding: 0 20px
#stageSortable #stageSortable
.sortable-item .sortable-item
padding: 3px padding: 3px

View File

@ -45,9 +45,9 @@ Template.layoutChooser.events({
columns: columnIndex + 1 columns: columnIndex + 1
}; };
layoutManager.layoutTemplateName = 'gridLayout'; window.layoutManager.layoutTemplateName = 'gridLayout';
layoutManager.layoutProps = layoutProps; window.layoutManager.layoutProps = layoutProps;
layoutManager.updateViewports(); window.layoutManager.updateViewports();
const $dropdown = $('.layoutChooser'); const $dropdown = $('.layoutChooser');
toggleDialog($dropdown); toggleDialog($dropdown);

View File

@ -1,7 +1,7 @@
<template name="loadingIndicator"> <template name="loadingIndicator">
<div class="imageViewerLoadingIndicator loadingIndicator"> <div class="imageViewerLoadingIndicator loadingIndicator">
<div class="indicatorContents"> <div class="indicatorContents">
<p>Loading... {{percentComplete}}</p> <p>Loading... <i class="fa fa-spin fa-circle-o-notch fa-fw"></i> {{percentComplete}}</p>
</div> </div>
</div> </div>
<div class="imageViewerErrorLoadingIndicator loadingIndicator"> <div class="imageViewerErrorLoadingIndicator loadingIndicator">

View File

@ -30,4 +30,7 @@
position: absolute position: absolute
top: 40% top: 40%
width: 100% width: 100%
color: $textSecondaryColor
font-size: 30px
font-weight: 200
text-align: center text-align: center

View File

@ -10,7 +10,7 @@ Template.viewerMain.onRendered(() => {
const instance = Template.instance(); const instance = Template.instance();
const studies = instance.data.studies; const studies = instance.data.studies;
const parentElement = instance.$("#layoutManagerTarget").get(0); const parentElement = instance.$('#layoutManagerTarget').get(0);
window.layoutManager = new LayoutManager(parentElement, studies); window.layoutManager = new LayoutManager(parentElement, studies);
ProtocolEngine = new HP.ProtocolEngine(window.layoutManager, studies); ProtocolEngine = new HP.ProtocolEngine(window.layoutManager, studies);
@ -26,4 +26,7 @@ Template.viewerMain.onDestroyed(() => {
// Destroy the synchronizer used to update reference lines // Destroy the synchronizer used to update reference lines
OHIF.viewer.updateImageSynchronizer.destroy(); OHIF.viewer.updateImageSynchronizer.destroy();
});
delete window.layoutManager;
delete ProtocolEngine;
});

View File

@ -1,10 +0,0 @@
<template name="tabContent">
<div role="tabpanel" class="tab-pane {{active}}" id="{{contentid}}">
{{>loadingText}}
<div class="viewerContainer">
<!-- This extra viewerContainer div only exists to be destroyed when switching tabs.
It is a workaround because Meteor's onDestroyed and destruction handlers don't fire
when removing the actual template from the DOM.-->
</div>
</div>
</template>

View File

@ -1,11 +0,0 @@
@import "{design}/app"
.tab-pane
.loadingTextDiv
color: $textSecondaryColor
font-size: 30px
font-weight: 200
.viewerContainer
height: 100%
width: 100%

View File

@ -5,9 +5,11 @@
{{> worklistResult }} {{> worklistResult }}
</div> </div>
</div> </div>
{{#each worklistTabs }} <div role="tabpanel" class="tab-pane" id="viewerTab">
{{>tabContent }} <div class="viewerContainer">
{{/each }} </div>
</div>
{{>loadingText}}
</div> </div>
{{#each additionalTemplates}} {{#each additionalTemplates}}
{{> UI.dynamic template=this}} {{> UI.dynamic template=this}}

View File

@ -19,7 +19,6 @@ WorklistTabs._debugName = 'WorklistTabs';
WorklistStudies = new Meteor.Collection(null); WorklistStudies = new Meteor.Collection(null);
WorklistStudies._debugName = 'WorklistStudies'; WorklistStudies._debugName = 'WorklistStudies';
Session.setDefault('activeContentId', 'worklistTab'); Session.setDefault('activeContentId', 'worklistTab');
Template.worklist.onRendered(() => { Template.worklist.onRendered(() => {
@ -32,7 +31,7 @@ Template.worklist.onRendered(() => {
// switch to that now. // switch to that now.
console.log('worklist onRendered'); console.log('worklist onRendered');
const contentId = Session.get('activeContentId'); const contentId = Session.get('activeContentId');
if (contentId !== 'worklistTab') { if (contentId !== 'worklistTab' && ViewerData && ViewerData[contentId]) {
switchToTab(contentId); switchToTab(contentId);
} }
} }
@ -40,16 +39,6 @@ Template.worklist.onRendered(() => {
Meteor.subscribe('hangingprotocols'); Meteor.subscribe('hangingprotocols');
}); });
Template.worklist.helpers({
/**
* Returns the current set of Worklist Tabs
* @returns Meteor.Collection The current state of the WorklistTabs Collection
*/
worklistTabs() {
return WorklistTabs.find();
}
});
Template.worklist.events({ Template.worklist.events({
'click #tablist a[data-toggle="tab"]': function(e) { 'click #tablist a[data-toggle="tab"]': function(e) {
// If this tab is already active, do nothing // If this tab is already active, do nothing

View File

@ -1,15 +1,17 @@
@import "{design}/app"
body body
background-color: black background-color: $primaryBackgroundColor
#tblStudyList #tblStudyList
tr tr
height: 20px height: 20px
#worklistTab #worklistTab
background-color: black background-color: $primaryBackgroundColor
.worklistContainer .worklistContainer
background-color: black background-color: $primaryBackgroundColor
margin: 0 auto margin: 0 auto
color: white color: white
@ -17,6 +19,15 @@ body
width: 100% width: 100%
height: calc(100% - 91px) height: calc(100% - 91px)
.loadingTextDiv
color: $textSecondaryColor
font-size: 30px
font-weight: 200
.tab-pane .tab-pane
width: 100% width: 100%
height: 100% height: 100%
.viewerContainer
height: 100%
width: 100%

View File

@ -94,10 +94,10 @@
</table> </table>
{{#if session "showLoadingText"}} {{#if session "showLoadingText"}}
{{>loadingText}} {{>loadingText}}
{{ else }}
{{#unless numberOfStudies}}
<div class="notFound">No matching results</div>
{{/unless}}
{{/if}} {{/if}}
{{#unless numberOfStudies}}
<div class="notFound">No matching results</div>
{{/unless}}
</div> </div>
</template> </template>

View File

@ -13,14 +13,6 @@ openNewTab = function(studyInstanceUid, title) {
// then it will change after hot-reloading. // then it will change after hot-reloading.
var contentid = uuid.new(); var contentid = uuid.new();
// Create a new entry in the WorklistTabs Collection
WorklistTabs.insert({
title: title,
contentid: contentid,
studyInstanceUid: studyInstanceUid,
active: false
});
// Update the ViewerData global object // Update the ViewerData global object
ViewerData[contentid] = { ViewerData[contentid] = {
title: title, title: title,

View File

@ -15,7 +15,12 @@ switchToTab = function(contentId) {
$('.tabTitle a[data-target="#' + contentId + '"]').addClass('active'); $('.tabTitle a[data-target="#' + contentId + '"]').addClass('active');
$('.tab-content .tab-pane').removeClass('active'); $('.tab-content .tab-pane').removeClass('active');
$('.tab-content .tab-pane#' + contentId).addClass('active'); if (contentId !== 'worklistTab') {
$('.tab-content .tab-pane#viewerTab').addClass('active');
} else {
$('.tab-content .tab-pane#' + contentId).addClass('active');
}
// Remove any previous Viewers from the DOM // Remove any previous Viewers from the DOM
$('.viewerContainer').remove(); $('.viewerContainer').remove();
@ -97,11 +102,7 @@ function viewStudiesInTab(contentId, studies) {
// Get tab content container given the contentId string // Get tab content container given the contentId string
// If no such container exists, stop here because something is wrong // If no such container exists, stop here because something is wrong
var container = $('.tab-content').find('#' + contentId).get(0); var container = $('.tab-content').find('#viewerTab').get(0);
if (!container) {
log.warn('No container present with the contentId: ' + contentId);
return;
}
// Remove the loading text template that is inside the tab container by default // Remove the loading text template that is inside the tab container by default
var viewerContainer = document.createElement('div'); var viewerContainer = document.createElement('div');

View File

@ -46,9 +46,6 @@ Package.onUse(function (api) {
api.addFiles('client/components/tabTitle/tabTitle.js', 'client'); api.addFiles('client/components/tabTitle/tabTitle.js', 'client');
api.addFiles('client/components/tabTitle/tabTitle.styl', 'client'); api.addFiles('client/components/tabTitle/tabTitle.styl', 'client');
api.addFiles('client/components/tabContent/tabContent.html', 'client');
api.addFiles('client/components/tabContent/tabContent.styl', 'client');
api.addFiles('client/components/worklistStudy/worklistStudy.html', 'client'); api.addFiles('client/components/worklistStudy/worklistStudy.html', 'client');
api.addFiles('client/components/worklistStudy/worklistStudy.js', 'client'); api.addFiles('client/components/worklistStudy/worklistStudy.js', 'client');
api.addFiles('client/components/worklistStudy/worklistStudy.styl', 'client'); api.addFiles('client/components/worklistStudy/worklistStudy.styl', 'client');