LT-275 Implementing search for measure labels

This commit is contained in:
Bruno Alves de Faria 2016-08-08 10:47:57 -03:00
parent f5a64574cc
commit 9d8c039ffc
6 changed files with 100 additions and 18 deletions

View File

@ -4,6 +4,8 @@
# 'meteor add' and 'meteor remove' will edit this file for you, # 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand. # but you can also edit it by hand.
npm-bcrypt@0.8.7
meteor-base@1.0.4 # Packages every Meteor app needs to have meteor-base@1.0.4 # Packages every Meteor app needs to have
mobile-experience@1.0.4 # Packages for a great mobile UX mobile-experience@1.0.4 # Packages for a great mobile UX
mongo@1.1.10 # The database Meteor supports right now mongo@1.1.10 # The database Meteor supports right now

View File

@ -158,7 +158,6 @@ $gray6 = #303030
.select-tree-common .select-tree-common
height: 100% height: 100%
overflow: hidden
padding-left: 6px padding-left: 6px
position: absolute position: absolute
right: -100% right: -100%
@ -191,22 +190,34 @@ $gray6 = #303030
transform-origin(100% 50%) transform-origin(100% 50%)
transition(all 0.3s ease) transition(all 0.3s ease)
.select-tree-common .content .select-tree-common
margin-left: calc(-100% - 6px) overflow: hidden
transition(all 0.3s ease 0.3s) z-index: -1
.content
margin-left: calc(-100% - 6px)
transition(all 0.3s ease 0.3s)
&.started &.started
&>.tree-content &>.tree-content
transform(scale(1)) transform(scale(1))
.select-tree-common .content .select-tree-common
margin-left: 0 animation-name: selectTreeCommonOverflow
animation-delay: 0.3s
animation-duration: 0.3s
animation-iteration-count: 1
animation-direction: alternate
animation-fill-mode: forwards
.content
margin-left: 0
&.interacted &.interacted
.select-tree-common .select-tree-common
overflow: visible z-index: 1
.content .content
animation-name: selectTreeCommonCloseLeft animation-name: selectTreeCommonCloseLeft
@ -216,6 +227,15 @@ $gray6 = #303030
animation-timing-function: ease-out animation-timing-function: ease-out
animation-fill-mode: forwards animation-fill-mode: forwards
@keyframes selectTreeCommonOverflow {
from {
overflow: hidden
}
to {
overflow: visible
}
}
@keyframes selectTreeCommonCloseLeft { @keyframes selectTreeCommonCloseLeft {
from { from {
height: 37px height: 37px

View File

@ -22,7 +22,7 @@
{{>selectTreeBreadcrumb component=this.component}} {{>selectTreeBreadcrumb component=this.component}}
{{/if}} {{/if}}
<div class="tree-inputs"> <div class="tree-inputs">
{{#each item in (reactive this.items)}} {{#each item in treeItems}}
{{>inputRadio {{>inputRadio
id=(concat this.storageKey '_' (encodeId item.value)) id=(concat this.storageKey '_' (encodeId item.value))
class=this.radioClass class=this.radioClass

View File

@ -1,12 +1,20 @@
import { OHIF } from 'meteor/ohif:core'; import { OHIF } from 'meteor/ohif:core';
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating'; import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { _ } from 'meteor/underscore'; import { _ } from 'meteor/underscore';
import { $ } from 'meteor/jquery'; import { $ } from 'meteor/jquery';
// TODO: use npm dependency // TODO: use npm dependency
import transition from 'meteor/ohif:core/client/lib/third-party/transition-to-from-auto'; import transition from 'meteor/ohif:core/client/lib/third-party/transition-to-from-auto';
Template.selectTree.onCreated(() => {
const instance = Template.instance();
// Create a reactive variable to control the search
instance.searchTerm = new ReactiveVar('');
});
Template.selectTree.onRendered(() => { Template.selectTree.onRendered(() => {
const instance = Template.instance(); const instance = Template.instance();
const component = instance.$('.select-tree:first').data('component'); const component = instance.$('.select-tree:first').data('component');
@ -20,8 +28,19 @@ Template.selectTree.onRendered(() => {
$treeRoot.addClass('started'); $treeRoot.addClass('started');
// Update the component's viewport height // Update the component's viewport height
instance.updateHeight = () => { instance.updateHeight = searchTerm => {
const height = rootInstance.$('.tree-options:last').data('height'); let height;
// Check if there's a search term
if (searchTerm) {
// Set the viewport height as same as listed options height
height = rootInstance.$('.tree-inputs').height();
} else {
// Set the viewport height as same as selected node's options height
height = rootInstance.$('.tree-options:last').data('height');
}
// Update the viewport's height
rootInstance.$('.tree-options:first').height(height); rootInstance.$('.tree-options:first').height(height);
}; };
@ -49,9 +68,17 @@ Template.selectTree.onRendered(() => {
// Run this computation everytime the current node is changed // Run this computation everytime the current node is changed
instance.data.currentNode.dep.depend(); instance.data.currentNode.dep.depend();
// Run this computation everytime the search term is changed
const searchTerm = instance.searchTerm.get();
// Clean the current node selection if the user started the search
if (searchTerm) {
rootInstance.data.currentNode.set(null);
}
// Update the viewport height // Update the viewport height
Tracker.afterFlush(() => { Tracker.afterFlush(() => {
instance.updateHeight(); instance.updateHeight(searchTerm);
instance.updateOpen(); instance.updateOpen();
}); });
}); });
@ -73,6 +100,11 @@ Template.selectTree.events({
$(event.currentTarget).parent().addClass('interacted'); $(event.currentTarget).parent().addClass('interacted');
}, },
'input .tree-search input'(event, instance) {
// Change the search term to update the tree items
instance.searchTerm.set($(event.currentTarget).val());
},
'change .select-tree:first>.tree-content>.tree-options>.tree-inputs>label>input'(event, instance) { 'change .select-tree:first>.tree-content>.tree-options>.tree-inputs>label>input'(event, instance) {
const component = instance.component; const component = instance.component;
const $target = $(event.target); const $target = $(event.target);
@ -96,10 +128,13 @@ Template.selectTree.events({
// Change the active item // Change the active item
$label.addClass('active'); $label.addClass('active');
// Ckeck if there's a storageKey defined
const storageKey = instance.data.storageKey; const storageKey = instance.data.storageKey;
if (storageKey) { if (storageKey) {
// Get the current stored data
const storedData = _.extend({}, OHIF.user.getData(storageKey)); const storedData = _.extend({}, OHIF.user.getData(storageKey));
// Increment or create a counter for the clicked leaf
const itemKey = OHIF.string.encodeId($target.val()); const itemKey = OHIF.string.encodeId($target.val());
if (storedData[itemKey]) { if (storedData[itemKey]) {
storedData[itemKey]++; storedData[itemKey]++;
@ -107,8 +142,7 @@ Template.selectTree.events({
storedData[itemKey] = 1; storedData[itemKey] = 1;
} }
console.warn('>>>>', storageKey, storedData, itemKey); // Updata the stored data with the new count
OHIF.user.setData(storageKey, storedData); OHIF.user.setData(storageKey, storedData);
} }
@ -160,3 +194,27 @@ Template.selectTree.events({
} }
} }
}); });
Template.selectTree.helpers({
treeItems() {
const instance = Template.instance();
// Run this computation everytime the search term is changed
const searchTerm = instance.searchTerm.get();
// Get all the items
let items = instance.data.items;
// Check if the search term was informed
if (searchTerm) {
// Search the items by the give search term
items = OHIF.string.search(items, searchTerm, 'label');
// Filter only the tree leaves
items = _.filter(items, item => !item.items);
}
// Return the tree items
return items;
}
});

View File

@ -22,9 +22,11 @@ OHIF.string.search = (object, query, property=null, result=[]) => {
if (_.isString(value) && pattern.test(value)) { if (_.isString(value) && pattern.test(value)) {
// Add the current item to the result // Add the current item to the result
result.push(item); result.push(item);
} else if (_.isObject(value)) { }
if (_.isObject(item)) {
// Search recursively the item if the current item is an object // Search recursively the item if the current item is an object
OHIF.string.search(value, query, property, result); OHIF.string.search(item, query, property, result);
} }
}); });

View File

@ -37,7 +37,7 @@ function filterToQIDOURL(server, filter) {
AccessionNumber: filter.accessionNumber, AccessionNumber: filter.accessionNumber,
StudyDescription: filter.studyDescription, StudyDescription: filter.studyDescription,
limit: filter.limit || 20, limit: filter.limit || 20,
includefield: server.qidoSupportsIncludeField ? commaSeparatedFields : 'all' includefield: server.qidoSupportsIncludeField ? 'all' : commaSeparatedFields
}; };
// build the StudyDate range parameter // build the StudyDate range parameter
@ -45,7 +45,7 @@ function filterToQIDOURL(server, filter) {
var date = "".concat(dateToString(new Date(filter.studyDateFrom)), "-", dateToString(new Date(filter.studyDateTo))); var date = "".concat(dateToString(new Date(filter.studyDateFrom)), "-", dateToString(new Date(filter.studyDateTo)));
parameters.StudyDate = date; parameters.StudyDate = date;
} }
return server.qidoRoot + '/studies?' + encodeQueryData(parameters); return server.qidoRoot + '/studies?' + encodeQueryData(parameters);
} }
@ -84,7 +84,7 @@ function resultDataToStudies(resultData) {
modalities: DICOMWeb.getString(DICOMWeb.getModalities(study['00080060'], study['00080061'])) modalities: DICOMWeb.getString(DICOMWeb.getModalities(study['00080060'], study['00080061']))
}); });
}); });
return studies; return studies;
} }