Replacing studyListContextMenu for dropdown
This commit is contained in:
parent
4daf7d8bf8
commit
485f82f64c
@ -15,7 +15,7 @@ Template.app.onCreated(() => {
|
||||
|
||||
ViewerData = Session.get('ViewerData') || {};
|
||||
|
||||
OHIF.header.setDropdownItems([{
|
||||
OHIF.header.dropdown.setItems([{
|
||||
action: OHIF.user.audit,
|
||||
text: 'View Audit Log',
|
||||
iconClasses: 'log',
|
||||
|
||||
@ -20,11 +20,12 @@ OHIF.mixins.action = new OHIF.Mixin({
|
||||
event.preventDefault();
|
||||
const component = instance.component;
|
||||
|
||||
// Extract action, params and disabled state
|
||||
const { action, params, disabled } = instance.data;
|
||||
// Extract action, disabled state and params
|
||||
const { action } = instance.data;
|
||||
const params = instance.data.params ? instance.data.params : event;
|
||||
|
||||
// Stop here if the component is disabled
|
||||
if (disabled) return;
|
||||
if (component.$element.hasClass('disabled')) return;
|
||||
|
||||
// Get the current component's API
|
||||
const api = component.getApi();
|
||||
|
||||
@ -42,7 +42,8 @@ OHIF.mixins.dropdown = new OHIF.Mixin({
|
||||
// Close the dropdown resolving or rejecting the promise
|
||||
instance.close = (isResolve, result) => {
|
||||
const method = instance.data[isResolve ? 'promiseResolve' : 'promiseReject'];
|
||||
method(result);
|
||||
const param = result instanceof Promise ? null : result;
|
||||
method(param);
|
||||
};
|
||||
|
||||
// Stop here and destroy the view if no items was given
|
||||
@ -52,7 +53,7 @@ OHIF.mixins.dropdown = new OHIF.Mixin({
|
||||
|
||||
dropdown.oncontextmenu = () => false;
|
||||
|
||||
const cssBefore = { 'z-index': 10000 };
|
||||
const cssBefore = {};
|
||||
if (event) {
|
||||
cssBefore.position = 'fixed';
|
||||
$dropdownMenu.bounded();
|
||||
|
||||
@ -6,9 +6,13 @@
|
||||
|
||||
ul.dropdown-menu
|
||||
display: block
|
||||
z-index: 1000
|
||||
transform(scale(0))
|
||||
transition(transform 0.3s ease)
|
||||
|
||||
&.dropdown-menu-left
|
||||
transform-origin(0% 0%)
|
||||
|
||||
&.dropdown-menu-right
|
||||
transform-origin(100% 0%)
|
||||
|
||||
|
||||
38
Packages/ohif-core/client/ui/dropdown/class.js
Normal file
38
Packages/ohif-core/client/ui/dropdown/class.js
Normal file
@ -0,0 +1,38 @@
|
||||
import { Tracker } from 'meteor/tracker';
|
||||
import { _ } from 'meteor/underscore';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
class Dropdown {
|
||||
constructor() {
|
||||
this.observer = new Tracker.Dependency();
|
||||
this._items = [];
|
||||
this.observer.changed();
|
||||
}
|
||||
|
||||
clearItems() {
|
||||
this._items = [];
|
||||
this.observer.changed();
|
||||
}
|
||||
|
||||
setItems(items) {
|
||||
this._items = items;
|
||||
this.observer.changed();
|
||||
}
|
||||
|
||||
addItem(item) {
|
||||
this._items.push(item);
|
||||
this.observer.changed();
|
||||
}
|
||||
|
||||
removeItem(item) {
|
||||
this._items = _.without(this._items, item);
|
||||
this.observer.changed();
|
||||
}
|
||||
|
||||
getItems() {
|
||||
this.observer.depend();
|
||||
return this._items;
|
||||
}
|
||||
}
|
||||
|
||||
OHIF.ui.Dropdown = Dropdown;
|
||||
@ -1,29 +0,0 @@
|
||||
import { Template } from 'meteor/templating';
|
||||
import { Blaze } from 'meteor/blaze';
|
||||
import { _ } from 'meteor/underscore';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
OHIF.ui.showFormDropdown = (templateName, dropdownData) => {
|
||||
// Check if the given template exists
|
||||
const template = Template[templateName];
|
||||
if (!template) {
|
||||
throw {
|
||||
name: 'TEMPLATE_NOT_FOUND',
|
||||
message: `Template ${templateName} not found.`
|
||||
};
|
||||
}
|
||||
|
||||
// Prepare the method to destroy the view
|
||||
let view;
|
||||
const destroyView = () => Blaze.remove(view);
|
||||
const templateData = _.extend({}, dropdownData, {
|
||||
destroyView
|
||||
});
|
||||
|
||||
// Render the dialog with the given template and data
|
||||
view = Blaze.renderWithData(template, templateData, document.body);
|
||||
|
||||
// Return the dropdown element to enable position manipulation
|
||||
const dropdown = view.firstNode();
|
||||
return dropdown;
|
||||
};
|
||||
@ -4,7 +4,7 @@ import './dialog/display.js';
|
||||
import './dialog/spatial.js';
|
||||
import './dialog/unsavedChangesDialog.js';
|
||||
import './draggable/draggable.js';
|
||||
import './dropdown/dropdown.js';
|
||||
import './dropdown/form.js';
|
||||
import './dropdown/class.js';
|
||||
import './dropdown/display.js';
|
||||
import './resizable/resizable.js';
|
||||
import './unsavedChanges/unsavedChanges.js';
|
||||
|
||||
@ -7,8 +7,8 @@ Template.header.onCreated(() => {
|
||||
|
||||
instance.dropdownItems = [];
|
||||
instance.autorun(() => {
|
||||
OHIF.header.dropdownObserver.depend();
|
||||
instance.dropdownItems = OHIF.header.getDropdownItems();
|
||||
OHIF.header.dropdown.observer.depend();
|
||||
instance.dropdownItems = OHIF.header.dropdown.getItems();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
import { Tracker } from 'meteor/tracker';
|
||||
import { _ } from 'meteor/underscore';
|
||||
|
||||
export class Header {
|
||||
constructor() {
|
||||
this.dropdownObserver = new Tracker.Dependency();
|
||||
this._dropdownItems = [];
|
||||
this.dropdownObserver.changed();
|
||||
}
|
||||
|
||||
clearDropDownItems() {
|
||||
this._dropdownItems = [];
|
||||
this.dropdownObserver.changed();
|
||||
}
|
||||
|
||||
setDropdownItems(items) {
|
||||
this._dropdownItems = items;
|
||||
this.dropdownObserver.changed();
|
||||
}
|
||||
|
||||
addDropdownItem(item) {
|
||||
this._dropdownItems.push(item);
|
||||
this.dropdownObserver.changed();
|
||||
}
|
||||
|
||||
removeDropdownItem(item) {
|
||||
this._dropdownItems = _.without(this._dropdownItems, item);
|
||||
this.dropdownObserver.changed();
|
||||
}
|
||||
|
||||
getDropdownItems() {
|
||||
this.dropdownObserver.depend();
|
||||
return this._dropdownItems;
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
import { Header } from './client/lib/header';
|
||||
|
||||
/*
|
||||
* Defines the base OHIF header object
|
||||
*/
|
||||
const header = new Header();
|
||||
const dropdown = new OHIF.ui.Dropdown();
|
||||
const header = { dropdown };
|
||||
|
||||
OHIF.header = header;
|
||||
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
import { Template } from 'meteor/templating';
|
||||
import { Random } from 'meteor/random';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
// Use Aldeed's meteor-template-extension package to replace the
|
||||
// default StudyListStudy template.
|
||||
// See https://github.com/aldeed/meteor-template-extension
|
||||
const defaultTemplate = 'studyContextMenu';
|
||||
|
||||
function getAssociationAssessment() {
|
||||
/**
|
||||
* Loads multiple unassociated studies in the Viewer
|
||||
*/
|
||||
const getAssociationAssessment = () => {
|
||||
// default result value
|
||||
const assessment = {
|
||||
selected: 0,
|
||||
@ -33,49 +30,40 @@ function getAssociationAssessment() {
|
||||
}
|
||||
|
||||
return assessment;
|
||||
}
|
||||
};
|
||||
|
||||
Template.longitudinalStudyListContextMenu.helpers({
|
||||
/**
|
||||
* Loads multiple unassociated studies in the Viewer
|
||||
*/
|
||||
const viewStudies = () => {
|
||||
OHIF.log.info('viewStudies');
|
||||
const selectedStudies = OHIF.studylist.getSelectedStudies();
|
||||
|
||||
getAssociationClasses() {
|
||||
const disabledClass = 'disabled';
|
||||
let classList = '';
|
||||
|
||||
const assessment = getAssociationAssessment();
|
||||
// if (assessment.selected < 1 || assessment.associated > 0) {
|
||||
// TODO: REMOVE - Temporary for RSNA
|
||||
if (assessment.selected < 1) {
|
||||
classList += disabledClass;
|
||||
}
|
||||
|
||||
return classList;
|
||||
},
|
||||
|
||||
getRemoveAssociationClasses() {
|
||||
const disabledClass = 'disabled';
|
||||
let classList = '';
|
||||
|
||||
const assessment = getAssociationAssessment();
|
||||
if (assessment.selected < 1 || assessment.selected !== assessment.associated) {
|
||||
classList += disabledClass;
|
||||
}
|
||||
|
||||
return classList;
|
||||
if (!selectedStudies || !selectedStudies.length) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
Template.longitudinalStudyListContextMenu.replaces(defaultTemplate);
|
||||
Template[defaultTemplate].inheritsHelpersFrom('longitudinalStudyListContextMenu');
|
||||
const title = selectedStudies[0].patientName;
|
||||
const studyInstanceUids = selectedStudies.map(study => study.studyInstanceUid);
|
||||
const contentId = 'viewerTab';
|
||||
|
||||
StudyList.functions.launchStudyAssociation = () => OHIF.ui.showDialog('dialogStudyAssociation');
|
||||
StudyList.functions.removeTimepointAssociations = removeTimepointAssociations;
|
||||
StudyList.functions.exportSelectedStudies = exportSelectedStudies;
|
||||
StudyList.functions.viewStudies = viewStudies;
|
||||
ViewerData = window.ViewerData || ViewerData;
|
||||
|
||||
// Update the ViewerData global object
|
||||
ViewerData[contentId] = {
|
||||
title: title,
|
||||
contentId: contentId,
|
||||
studyInstanceUids: studyInstanceUids
|
||||
};
|
||||
|
||||
// Switch to the new tab
|
||||
switchToTab(contentId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes all present study / timepoint associations from the Clinical Trial
|
||||
*/
|
||||
function removeTimepointAssociations($study, event) {
|
||||
const removeTimepointAssociations = event => {
|
||||
const dialogSettings = {
|
||||
title: 'Remove Association',
|
||||
message: 'Measurements related to this Study and Timepoint will be erased. Do you really want to delete this association?',
|
||||
@ -105,47 +93,44 @@ function removeTimepointAssociations($study, event) {
|
||||
timepointApi.disassociateStudy(timepointIds, studyInstanceUid);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// ---------- TODO: Remove these duplicated functions below -------------
|
||||
|
||||
/**
|
||||
* Exports all selected studies on the studylist
|
||||
*/
|
||||
function exportSelectedStudies() {
|
||||
const selectedStudies = OHIF.studylist.getSelectedStudies();
|
||||
|
||||
if (!selectedStudies || !selectedStudies.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
OHIF.studylist.exportStudies(selectedStudies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads multiple unassociated studies in the Viewer
|
||||
*/
|
||||
function viewStudies() {
|
||||
OHIF.log.info('viewStudies');
|
||||
const selectedStudies = OHIF.studylist.getSelectedStudies();
|
||||
|
||||
if (!selectedStudies || !selectedStudies.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const title = selectedStudies[0].patientName;
|
||||
const studyInstanceUids = selectedStudies.map(study => study.studyInstanceUid);
|
||||
const contentId = 'viewerTab';
|
||||
|
||||
ViewerData = window.ViewerData || ViewerData;
|
||||
|
||||
// Update the ViewerData global object
|
||||
ViewerData[contentId] = {
|
||||
title: title,
|
||||
contentId: contentId,
|
||||
studyInstanceUids: studyInstanceUids
|
||||
};
|
||||
|
||||
// Switch to the new tab
|
||||
switchToTab(contentId);
|
||||
}
|
||||
Meteor.startup(() => {
|
||||
OHIF.studylist.dropdown.setItems([{
|
||||
action: viewStudies,
|
||||
text: 'View',
|
||||
separatorAfter: true
|
||||
}, {
|
||||
action: () => OHIF.ui.showDialog('dialogStudyAssociation'),
|
||||
text: 'Associate',
|
||||
disabled: () => {
|
||||
const assessment = getAssociationAssessment();
|
||||
return assessment.selected < 1;
|
||||
}
|
||||
}, {
|
||||
action: removeTimepointAssociations,
|
||||
text: 'Remove Association',
|
||||
separatorAfter: true,
|
||||
disabled: () => {
|
||||
const assessment = getAssociationAssessment();
|
||||
return assessment.selected < 1 || assessment.selected !== assessment.associated;
|
||||
}
|
||||
}, {
|
||||
action: OHIF.studylist.viewSeriesDetails,
|
||||
text: 'View Series Details'
|
||||
}, {
|
||||
text: 'Anonymize',
|
||||
disabled: true
|
||||
}, {
|
||||
text: 'Send',
|
||||
disabled: true,
|
||||
separatorAfter: true
|
||||
}, {
|
||||
action: OHIF.studylist.exportSelectedStudies,
|
||||
text: 'Export',
|
||||
title: 'Export Selected Studies'
|
||||
}, {
|
||||
text: 'Delete',
|
||||
disabled: true
|
||||
}]);
|
||||
});
|
||||
@ -3,8 +3,7 @@ import './longitudinalStudyListStudy/longitudinalStudyListStudy.html';
|
||||
import './longitudinalStudyListStudy/longitudinalStudyListStudy.styl';
|
||||
import './longitudinalStudyListStudy/longitudinalStudyListStudy.js';
|
||||
|
||||
import './longitudinalStudyListContextMenu/longitudinalStudyListContextMenu.html';
|
||||
import './longitudinalStudyListContextMenu/longitudinalStudyListContextMenu.js';
|
||||
|
||||
import './longitudinalViewportOverlay/longitudinalViewportOverlay.html';
|
||||
import './longitudinalViewportOverlay/longitudinalViewportOverlay.js';
|
||||
|
||||
import './dropdown.js';
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
<template name="longitudinalStudyListContextMenu">
|
||||
{{#dropdownForm}}
|
||||
<li><a id="viewStudies" type="button" title="View Studies">View</a></li>
|
||||
<li class="divider" role="separator"></li>
|
||||
|
||||
{{#let classes=getAssociationClasses}}
|
||||
<li class="{{classes}}">
|
||||
<a id="launchStudyAssociation" class="{{classes}}"
|
||||
title="Launch Study Association">Associate</a>
|
||||
</li>
|
||||
{{/let}}
|
||||
|
||||
{{#let classes=getRemoveAssociationClasses}}
|
||||
<li class="{{classes}}">
|
||||
<a id="removeTimepointAssociations" type="button" class="{{classes}}"
|
||||
title="Remove Timepoint Association">Remove Association</a>
|
||||
</li>
|
||||
{{/let}}
|
||||
|
||||
<li class="divider" role="separator"></li>
|
||||
<li>
|
||||
<a id="viewSeriesDetails" type="button"
|
||||
title="View Series Details">View Series Details</a>
|
||||
</li>
|
||||
<li class="disabled"><a class="disabled">Anonymize</a></li>
|
||||
<li class="disabled"><a class="disabled">Send</a></li>
|
||||
<li class="divider" role="separator"></li>
|
||||
<li><a id="exportSelectedStudies" title="Export Selected Studies">Export</a></li>
|
||||
<li class="disabled"><a class="disabled">Delete</a></li>
|
||||
{{/dropdownForm}}
|
||||
</template>
|
||||
@ -1,5 +1,4 @@
|
||||
import './seriesDetailsModal';
|
||||
import './serverInformation';
|
||||
import './studyContextMenu';
|
||||
import './studylist';
|
||||
import './themeSelector';
|
||||
|
||||
@ -1,89 +1,23 @@
|
||||
import { Template } from 'meteor/templating';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
import { $ } from 'meteor/jquery';
|
||||
|
||||
/**
|
||||
* This function is used inside the StudyList package to define a right click callback
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
openStudyContextMenu = event => {
|
||||
if (!OHIF.uiSettings.studyListFunctionsEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
StudyList.functions.exportSelectedStudies = exportSelectedStudies;
|
||||
StudyList.functions.viewSeriesDetails = viewSeriesDetails;
|
||||
|
||||
Template.studyContextMenu.$study = $(event.currentTarget);
|
||||
|
||||
const dropdown = OHIF.ui.showFormDropdown('studyContextMenu');
|
||||
const $dropdown = $(dropdown);
|
||||
const $dropdownMenu = $dropdown.children('.dropdown-menu');
|
||||
|
||||
dropdown.oncontextmenu = () => false;
|
||||
|
||||
$dropdownMenu.css({
|
||||
visibility: 'hidden',
|
||||
position: 'fixed',
|
||||
'z-index': 10000,
|
||||
}).bounded().focus();
|
||||
|
||||
// Postpone position change to allow boundaries restriction
|
||||
Meteor.defer(() => {
|
||||
$dropdownMenu.css({
|
||||
visibility: 'visible',
|
||||
left: `${event.clientX}px`,
|
||||
top: `${event.clientY}px`
|
||||
}).trigger('spatialChanged');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Exports all selected studies on the studylist
|
||||
*/
|
||||
function exportSelectedStudies($study, event) {
|
||||
const selectedStudies = OHIF.studylist.getSelectedStudies();
|
||||
const studiesCount = selectedStudies.length;
|
||||
const studyText = studiesCount > 1 ? 'Studies' : 'Study';
|
||||
|
||||
OHIF.ui.showDialog('dialogConfirm', {
|
||||
element: event.element,
|
||||
title: `Export ${studyText}`,
|
||||
message: `Would you like to export ${studiesCount} ${studyText.toLowerCase()}?`
|
||||
}).then(() => {
|
||||
OHIF.studylist.exportStudies(selectedStudies);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display series details of study in modal
|
||||
*/
|
||||
function viewSeriesDetails() {
|
||||
const selectedStudies = OHIF.studylist.getSelectedStudies();
|
||||
|
||||
if (!selectedStudies) {
|
||||
return;
|
||||
}
|
||||
|
||||
OHIF.ui.showDialog('seriesDetailsModal', { selectedStudies });
|
||||
}
|
||||
|
||||
Template.studyContextMenu.events({
|
||||
'click a'(event, instance) {
|
||||
const $target = $(event.currentTarget);
|
||||
|
||||
if ($target.hasClass('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const id = $target.attr('id');
|
||||
if (id in StudyList.functions) {
|
||||
const fn = StudyList.functions[id];
|
||||
if (typeof fn === 'function') {
|
||||
fn(Template.studyContextMenu.$study, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
Meteor.startup(() => {
|
||||
OHIF.studylist.dropdown.setItems([{
|
||||
action: OHIF.studylist.viewSeriesDetails,
|
||||
text: 'View Series Details'
|
||||
}, {
|
||||
text: 'Anonymize',
|
||||
disabled: true
|
||||
}, {
|
||||
text: 'Send',
|
||||
disabled: true,
|
||||
separatorAfter: true
|
||||
}, {
|
||||
text: 'Delete',
|
||||
disabled: true
|
||||
}, {
|
||||
action: OHIF.studylist.exportSelectedStudies,
|
||||
text: 'Export',
|
||||
title: 'Export Selected Studies'
|
||||
}]);
|
||||
});
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Template } from 'meteor/templating';
|
||||
import { Blaze } from 'meteor/blaze';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
// Maybe we should use regular StudyList collection?
|
||||
@ -45,7 +48,7 @@ function doUnselectRow(studyRow, data) {
|
||||
studyRow.removeClass('active');
|
||||
}
|
||||
|
||||
function handleShiftClick(studyRow, data) {
|
||||
function handleShiftClick($studyRow, data) {
|
||||
//OHIF.log.info('shiftKey');
|
||||
|
||||
let study, previous = StudyList.previouslySelected ? $(StudyList.previouslySelected) : null;
|
||||
@ -59,49 +62,49 @@ function handleShiftClick(studyRow, data) {
|
||||
|
||||
// Select all rows in between these two rows
|
||||
if (previous) {
|
||||
let rowsInBetween;
|
||||
if (previous.index() < studyRow.index()) {
|
||||
let $rowsInBetween;
|
||||
if (previous.index() < $studyRow.index()) {
|
||||
// The previously selected row is above (lower index) the
|
||||
// currently selected row.
|
||||
|
||||
// Fill in the rows upwards from the previously selected row
|
||||
rowsInBetween = previous.nextAll('tr');
|
||||
} else if (previous.index() > studyRow.index()) {
|
||||
$rowsInBetween = previous.nextAll('tr');
|
||||
} else if (previous.index() > $studyRow.index()) {
|
||||
// The previously selected row is below the currently
|
||||
// selected row.
|
||||
|
||||
// Fill in the rows upwards from the previously selected row
|
||||
rowsInBetween = previous.prevAll('tr');
|
||||
$rowsInBetween = previous.prevAll('tr');
|
||||
} else {
|
||||
// nothing to do since previous.index() === studyRow.index()
|
||||
// nothing to do since previous.index() === $studyRow.index()
|
||||
// the user is shift-clicking the same row...
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through the rows in between current and previous selected studies
|
||||
rowsInBetween.each(function() {
|
||||
let row = $(this);
|
||||
$rowsInBetween.forEach(row => {
|
||||
const $row = $(row);
|
||||
|
||||
if (row.hasClass('active')) {
|
||||
if ($row.hasClass('active')) {
|
||||
// If we find one that is already selected, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the relevant studyInstanceUid
|
||||
let studyInstanceUid = row.attr('studyInstanceUid');
|
||||
let studyInstanceUid = $row.attr('studyInstanceUid');
|
||||
|
||||
// Retrieve the data context through Blaze
|
||||
let data = Blaze.getData(this);
|
||||
|
||||
// Set the current study as selected
|
||||
doSelectRow(row, data);
|
||||
doSelectRow($row, data);
|
||||
|
||||
// When we reach the currently clicked-on row, stop the loop
|
||||
return !row.is(studyRow);
|
||||
// When we reach the currently clicked-on $row, stop the loop
|
||||
return !$row.is($studyRow);
|
||||
});
|
||||
} else {
|
||||
// Set the current study as selected
|
||||
doSelectSingleRow(studyRow, data);
|
||||
doSelectSingleRow($studyRow, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,59 +142,58 @@ Template.studylistStudy.onRendered(function() {
|
||||
});
|
||||
|
||||
Template.studylistStudy.events({
|
||||
'click tr.studylistStudy': function(e) {
|
||||
var studyRow = $(e.currentTarget);
|
||||
var data = this;
|
||||
'click tr.studylistStudy'(event, instance) {
|
||||
const $studyRow = $(event.currentTarget);
|
||||
const data = instance.data;
|
||||
|
||||
// Remove the ID so we can directly insert this into our client-side collection
|
||||
delete data._id;
|
||||
|
||||
if (e.shiftKey) {
|
||||
handleShiftClick(studyRow, data);
|
||||
} else if (e.ctrlKey || e.metaKey) {
|
||||
handleCtrlClick(studyRow, data);
|
||||
if (event.shiftKey) {
|
||||
handleShiftClick($studyRow, data);
|
||||
} else if (event.ctrlKey || event.metaKey) {
|
||||
handleCtrlClick($studyRow, data);
|
||||
} else {
|
||||
doSelectSingleRow(studyRow, data);
|
||||
doSelectSingleRow($studyRow, data);
|
||||
}
|
||||
},
|
||||
'mousedown tr.studylistStudy': function(e) {
|
||||
|
||||
'mousedown tr.studylistStudy'(event, instance) {
|
||||
// This event handler is meant to handle middle-click on a study
|
||||
if (e.which !== 2) {
|
||||
if (event.which !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = this;
|
||||
var middleClickOnStudy = StudyList.callbacks.middleClickOnStudy;
|
||||
const middleClickOnStudy = StudyList.callbacks.middleClickOnStudy;
|
||||
if (middleClickOnStudy && typeof middleClickOnStudy === 'function') {
|
||||
middleClickOnStudy(data);
|
||||
middleClickOnStudy(instance.data);
|
||||
}
|
||||
},
|
||||
'dblclick tr.studylistStudy, doubletap tr.studylistStudy': function(e) {
|
||||
if (e.which !== undefined && e.which !== 1) {
|
||||
|
||||
'dblclick tr.studylistStudy, doubletap tr.studylistStudy'(event, instance) {
|
||||
if (event.which !== undefined && event.which !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = this;
|
||||
var dblClickOnStudy = StudyList.callbacks.dblClickOnStudy;
|
||||
const dblClickOnStudy = StudyList.callbacks.dblClickOnStudy;
|
||||
|
||||
if (dblClickOnStudy && typeof dblClickOnStudy === 'function') {
|
||||
dblClickOnStudy(data);
|
||||
dblClickOnStudy(instance.data);
|
||||
}
|
||||
},
|
||||
'contextmenu tr.studylistStudy, press tr.studylistStudy': function(e, template) {
|
||||
|
||||
var studyRow = $(e.currentTarget),
|
||||
data = this;
|
||||
'contextmenu tr.studylistStudy, press tr.studylistStudy'(event, instance) {
|
||||
const $studyRow = $(event.currentTarget);
|
||||
|
||||
if (!isStudySelected(data)) {
|
||||
doSelectSingleRow(studyRow, data);
|
||||
if (!isStudySelected(instance.data)) {
|
||||
doSelectSingleRow($studyRow, instance.data);
|
||||
}
|
||||
|
||||
if (typeof openStudyContextMenu === 'function') {
|
||||
e.preventDefault();
|
||||
openStudyContextMenu(e, template);
|
||||
return false;
|
||||
}
|
||||
event.preventDefault();
|
||||
OHIF.ui.showDropdown(OHIF.studylist.dropdown.getItems(), {
|
||||
event,
|
||||
menuClasses: 'dropdown-menu-left'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
25
Packages/ohif-study-list/client/dropdown.js
Normal file
25
Packages/ohif-study-list/client/dropdown.js
Normal file
@ -0,0 +1,25 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
Meteor.startup(() => {
|
||||
OHIF.studylist.dropdown = new OHIF.ui.Dropdown();
|
||||
|
||||
OHIF.studylist.dropdown.setItems([{
|
||||
action: OHIF.studylist.viewSeriesDetails,
|
||||
text: 'View Series Details'
|
||||
}, {
|
||||
text: 'Anonymize',
|
||||
disabled: true
|
||||
}, {
|
||||
text: 'Send',
|
||||
disabled: true,
|
||||
separatorAfter: true
|
||||
}, {
|
||||
text: 'Delete',
|
||||
disabled: true
|
||||
}, {
|
||||
action: OHIF.studylist.exportSelectedStudies,
|
||||
text: 'Export',
|
||||
title: 'Export Selected Studies'
|
||||
}]);
|
||||
});
|
||||
@ -1,3 +1,4 @@
|
||||
import './collections';
|
||||
import './lib';
|
||||
import './components';
|
||||
import './dropdown';
|
||||
|
||||
19
Packages/ohif-study-list/client/lib/exportSelectedStudies.js
Normal file
19
Packages/ohif-study-list/client/lib/exportSelectedStudies.js
Normal file
@ -0,0 +1,19 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
/**
|
||||
* Exports all selected studies on the studylist
|
||||
* @param event Event that triggered the export
|
||||
*/
|
||||
OHIF.studylist.exportSelectedStudies = event => {
|
||||
const selectedStudies = OHIF.studylist.getSelectedStudies();
|
||||
const studiesCount = selectedStudies.length;
|
||||
const studyText = studiesCount > 1 ? 'Studies' : 'Study';
|
||||
|
||||
OHIF.ui.showDialog('dialogConfirm', {
|
||||
element: event.element,
|
||||
title: `Export ${studyText}`,
|
||||
message: `Would you like to export ${studiesCount} ${studyText.toLowerCase()}?`
|
||||
}).then(() => {
|
||||
OHIF.studylist.exportStudies(selectedStudies);
|
||||
});
|
||||
};
|
||||
@ -1,5 +1,6 @@
|
||||
import './third-party/jquery.twbsPagination.min.js';
|
||||
|
||||
import './exportSelectedStudies.js';
|
||||
import './exportStudies.js';
|
||||
import './getSelectedStudies.js';
|
||||
import './getStudyMetadata.js';
|
||||
@ -10,3 +11,4 @@ import './queryStudies.js';
|
||||
import './retrieveStudyMetadata.js';
|
||||
import './studylist.js';
|
||||
import './switchToTab.js';
|
||||
import './viewSeriesDetails.js';
|
||||
|
||||
10
Packages/ohif-study-list/client/lib/viewSeriesDetails.js
Normal file
10
Packages/ohif-study-list/client/lib/viewSeriesDetails.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
/**
|
||||
* Display series details of study in a modal
|
||||
*/
|
||||
OHIF.studylist.viewSeriesDetails = () => {
|
||||
const selectedStudies = OHIF.studylist.getSelectedStudies();
|
||||
if (!selectedStudies) return;
|
||||
OHIF.ui.showDialog('seriesDetailsModal', { selectedStudies });
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user