LT-275: Making the measure flow respect the window bounds and fixing scrolling when selecting by common section
This commit is contained in:
parent
033eca0dbd
commit
3827fb0e7b
@ -12,6 +12,9 @@
|
|||||||
<meta name="HandheldFriendly" content="True">
|
<meta name="HandheldFriendly" content="True">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
|
||||||
|
<!-- Make SVG work on IE -->
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
<link href='http://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
<link href='http://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
||||||
<link href='http://fonts.googleapis.com/css?family=Sanchez:400,700&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
<link href='http://fonts.googleapis.com/css?family=Sanchez:400,700&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@ -13,8 +13,8 @@ $gray6 = #303030
|
|||||||
.tree-content
|
.tree-content
|
||||||
background-color: white
|
background-color: white
|
||||||
position: relative
|
position: relative
|
||||||
|
transition(transform 0.3s ease\, background-color 0.3s ease\, border-color 0.3s ease\, border-radius 0.3s ease)
|
||||||
|
|
||||||
&
|
|
||||||
.tree-search
|
.tree-search
|
||||||
a.tree-back
|
a.tree-back
|
||||||
.tree-breadcrumb span
|
.tree-breadcrumb span
|
||||||
@ -146,6 +146,7 @@ $gray6 = #303030
|
|||||||
|
|
||||||
&.active
|
&.active
|
||||||
box-shadow: 0 0 0 200px white, inset 0 0 0 200px white
|
box-shadow: 0 0 0 200px white, inset 0 0 0 200px white
|
||||||
|
position: fixed
|
||||||
transition(box-shadow 0.3s ease)
|
transition(box-shadow 0.3s ease)
|
||||||
z-index: 0
|
z-index: 0
|
||||||
|
|
||||||
@ -192,7 +193,6 @@ $gray6 = #303030
|
|||||||
&>.tree-content
|
&>.tree-content
|
||||||
transform(scale(0))
|
transform(scale(0))
|
||||||
transform-origin(100% 50%)
|
transform-origin(100% 50%)
|
||||||
transition(all 0.3s ease)
|
|
||||||
|
|
||||||
.select-tree-common
|
.select-tree-common
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
|||||||
@ -1,12 +1,5 @@
|
|||||||
<template name="measureFlow">
|
<template name="measureFlow">
|
||||||
<div class="measure-flow">
|
<div class="measure-flow {{instance.state.get}}" style="position:fixed; top:200px; left:400px">
|
||||||
<button>Add label</button>
|
<button class="btn-add">Add label</button>
|
||||||
{{>selectTree
|
|
||||||
key='label'
|
|
||||||
items=instance.items
|
|
||||||
label='Assign label'
|
|
||||||
searchPlaceholder='Search labels'
|
|
||||||
storageKey='measureLabelCommon'
|
|
||||||
}}
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,6 +1,15 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Blaze } from 'meteor/blaze';
|
||||||
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { $ } from 'meteor/jquery';
|
||||||
|
|
||||||
Template.measureFlow.onCreated(() => {
|
Template.measureFlow.onCreated(() => {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
instance.state = new ReactiveVar('closed');
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
'Adrenal',
|
'Adrenal',
|
||||||
'Bladder',
|
'Bladder',
|
||||||
@ -40,11 +49,46 @@ Template.measureFlow.onCreated(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.measureFlow.events({
|
Template.measureFlow.events({
|
||||||
|
'click .measure-flow .btn-add'(event, instance) {
|
||||||
|
// Set the open state for the component
|
||||||
|
instance.state.set('open');
|
||||||
|
|
||||||
|
// Wait template rerender before rendering the selectTree
|
||||||
|
Tracker.afterFlush(() => {
|
||||||
|
// Get the click position
|
||||||
|
const position = {
|
||||||
|
left: event.clientX,
|
||||||
|
top: event.clientY,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define the data for selectTreeComponent
|
||||||
|
const data = {
|
||||||
|
key: 'label',
|
||||||
|
items: instance.items,
|
||||||
|
label: 'Assign label',
|
||||||
|
searchPlaceholder: 'Search labels',
|
||||||
|
storageKey: 'measureLabelCommon',
|
||||||
|
position
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define in which element the selectTree will be rendered in
|
||||||
|
const parentElement = instance.$('.measure-flow')[0];
|
||||||
|
|
||||||
|
// Render the selectTree element
|
||||||
|
Blaze.renderWithData(Template.selectTree, data, parentElement);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'click .select-tree-common label'(event, instance) {
|
||||||
|
instance.commonClicked = true;
|
||||||
|
},
|
||||||
'click .tree-leaf input'(event, instance) {
|
'click .tree-leaf input'(event, instance) {
|
||||||
console.warn('>>>>event', event);
|
|
||||||
const $label = $(event.currentTarget).closest('label');
|
const $label = $(event.currentTarget).closest('label');
|
||||||
const $container = $label.closest('.select-tree-root').find('.tree-options:first');
|
const $container = $label.closest('.select-tree-root').find('.tree-options:first');
|
||||||
const top = $label.position().top;
|
if (instance.commonClicked) {
|
||||||
$container.scrollTop(top);
|
const labelTop = $label.position().top;
|
||||||
|
const containerCenter = Math.round($container.height() / 2);
|
||||||
|
const labelCenter = Math.round($label.height() / 2);
|
||||||
|
$container.scrollTop(labelTop - containerCenter + labelCenter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,23 @@
|
|||||||
|
@import "{design}/app"
|
||||||
|
|
||||||
.measure-flow
|
.measure-flow
|
||||||
|
|
||||||
|
&.open
|
||||||
|
|
||||||
|
.btn-add
|
||||||
|
display: none
|
||||||
|
|
||||||
|
.btn-add
|
||||||
|
background-color: $activeColor
|
||||||
|
border: 2px solid $uiBorderColor
|
||||||
|
border-radius: 14px
|
||||||
|
color: $textColorActive
|
||||||
|
cursor: pointer
|
||||||
|
font-weight: bold
|
||||||
|
height: 24px
|
||||||
|
line-height: 24px
|
||||||
|
padding: 0 14px
|
||||||
|
|
||||||
.select-tree-root>.tree-content>.tree-options
|
.select-tree-root>.tree-content>.tree-options
|
||||||
margin-right: -20px
|
margin-right: -20px
|
||||||
max-height: 250px
|
max-height: 250px
|
||||||
|
|||||||
@ -27,8 +27,26 @@ Template.selectTree.onRendered(() => {
|
|||||||
// Set the margin to display the common section
|
// Set the margin to display the common section
|
||||||
$treeRoot.children('.tree-content').css('margin-right', $treeRoot.width());
|
$treeRoot.children('.tree-content').css('margin-right', $treeRoot.width());
|
||||||
|
|
||||||
|
// Make the component respect the window boundaries
|
||||||
|
$treeRoot.bounded();
|
||||||
|
|
||||||
|
// Check if the component will be rendered on a specific position
|
||||||
|
const position = instance.data.position;
|
||||||
|
if (position) {
|
||||||
|
// Get the dimensions and move it with the given position as its center
|
||||||
|
const width = $treeRoot.outerWidth();
|
||||||
|
const height = $treeRoot.outerHeight();
|
||||||
|
position.left -= Math.round(width / 2);
|
||||||
|
position.top -= Math.round(height / 2);
|
||||||
|
|
||||||
|
// Change the component's position and trigger the bounded event
|
||||||
|
$treeRoot.css(_.extend({}, position, {
|
||||||
|
position: 'fixed'
|
||||||
|
})).trigger('spatialChanged');
|
||||||
|
}
|
||||||
|
|
||||||
// Start the component transitions
|
// Start the component transitions
|
||||||
$treeRoot.addClass('started');
|
Meteor.defer(() => $treeRoot.addClass('started'));
|
||||||
|
|
||||||
// Update the component's viewport height
|
// Update the component's viewport height
|
||||||
instance.updateHeight = searchTerm => {
|
instance.updateHeight = searchTerm => {
|
||||||
@ -126,7 +144,7 @@ Template.selectTree.events({
|
|||||||
component.value(eventComponent.value());
|
component.value(eventComponent.value());
|
||||||
|
|
||||||
// Unset the active leaf
|
// Unset the active leaf
|
||||||
rootInstance.$('label').removeClass('active');
|
rootInstance.$('label').removeClass('active').css('width', '');
|
||||||
|
|
||||||
// Unset the selected state
|
// Unset the selected state
|
||||||
instance.setSelected(false);
|
instance.setSelected(false);
|
||||||
@ -135,7 +153,7 @@ Template.selectTree.events({
|
|||||||
const isLeaf = $label.hasClass('tree-leaf');
|
const isLeaf = $label.hasClass('tree-leaf');
|
||||||
if (isLeaf) {
|
if (isLeaf) {
|
||||||
// Change the active item
|
// Change the active item
|
||||||
$label.addClass('active');
|
$label.css('width', $label.outerWidth()).addClass('active');
|
||||||
|
|
||||||
// Ckeck if there's a storageKey defined
|
// Ckeck if there's a storageKey defined
|
||||||
const storageKey = instance.data.storageKey;
|
const storageKey = instance.data.storageKey;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import './base';
|
import './base';
|
||||||
import './bootstrap';
|
import './bootstrap';
|
||||||
import './playground/playground.html';
|
import './playground/playground.html';
|
||||||
|
import './playground/playground.styl';
|
||||||
import './playground/playground.js';
|
import './playground/playground.js';
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
<template name="componentPlayground">
|
<template name="componentPlayground">
|
||||||
<!--
|
<div class="component-playground">
|
||||||
|
{{>measureFlow}}
|
||||||
|
<!--
|
||||||
<div class="p-a-3">
|
<div class="p-a-3">
|
||||||
{{>selectTree
|
{{>selectTree
|
||||||
key='label'
|
key='label'
|
||||||
@ -9,6 +11,6 @@
|
|||||||
storageKey='measureLabelCommon'
|
storageKey='measureLabelCommon'
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
{{>measureFlow}}
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -0,0 +1,2 @@
|
|||||||
|
.component-playground
|
||||||
|
height: 100vh
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
// Allow attaching to jQuery selectors
|
// Allow attaching to jQuery selectors
|
||||||
$.fn.bounded = function(options) {
|
$.fn.bounded = function(options) {
|
||||||
_.each(this, element => {
|
_.each(this, element => {
|
||||||
@ -63,7 +65,7 @@ class Bounded {
|
|||||||
this.$element.removeClass('bounded');
|
this.$element.removeClass('bounded');
|
||||||
}
|
}
|
||||||
|
|
||||||
spatialInfo(element) {
|
static spatialInfo(element) {
|
||||||
// Create the result object
|
// Create the result object
|
||||||
const result = {};
|
const result = {};
|
||||||
|
|
||||||
@ -105,8 +107,8 @@ class Bounded {
|
|||||||
defineEventHandlers() {
|
defineEventHandlers() {
|
||||||
this.spatialChangedHandler = event => {
|
this.spatialChangedHandler = event => {
|
||||||
// Get the spatial information for element and its bounding element
|
// Get the spatial information for element and its bounding element
|
||||||
const elementInfo = this.spatialInfo(this.element);
|
const elementInfo = Bounded.spatialInfo(this.element);
|
||||||
const boundingInfo = this.spatialInfo(this.boundingElement);
|
const boundingInfo = Bounded.spatialInfo(this.boundingElement);
|
||||||
|
|
||||||
// Fix element's x positioning and width
|
// Fix element's x positioning and width
|
||||||
if (this.allowResizing && elementInfo.width > boundingInfo.width) {
|
if (this.allowResizing && elementInfo.width > boundingInfo.width) {
|
||||||
@ -143,3 +145,5 @@ class Bounded {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OHIF.Bounded = Bounded;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user