LT-275: Creating measure flow component common section
This commit is contained in:
1 parent
9a8eaff560
commit
bbb7dad905
60 files changed
+391
-156
No files matched your search
@@ -0,0 +1,8 @@
|
||||
<template name="form">
|
||||
{{#baseComponent (extend this
|
||||
base='baseForm'
|
||||
mixins=(concat 'form ' this.mixins)
|
||||
)}}
|
||||
{{>UI.contentBlock}}
|
||||
{{/baseComponent}}
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template name="group">
|
||||
{{#baseComponent (extend this
|
||||
class=(concat 'component-group ' this.class)
|
||||
base='baseDiv'
|
||||
mixins=(concat 'group ' this.mixins)
|
||||
)}}
|
||||
{{>UI.contentBlock}}
|
||||
{{/baseComponent}}
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
import './form/form.html';
|
||||
import './form/group.html';
|
||||
|
||||
import './input/groupRadio.html';
|
||||
import './input/radio.html';
|
||||
import './input/select.html';
|
||||
import './input/text.html';
|
||||
import './input/selectTree.html';
|
||||
import './input/selectTree.js';
|
||||
@@ -0,0 +1,21 @@
|
||||
<template name="groupRadio">
|
||||
{{#group (extend this
|
||||
class=(concat 'group-radio ' this.class)
|
||||
mixins=(concat 'groupRadio ' this.mixins)
|
||||
wrappers=(concat ''
|
||||
(valueIf reactive this.label 'wrapperTitle ' '')
|
||||
this.wrappers
|
||||
)
|
||||
)}}
|
||||
{{>UI.contentBlock}}
|
||||
{{#each item in (reactive this.items)}}
|
||||
{{>inputRadio
|
||||
class=this.radioClass
|
||||
name=this.key
|
||||
value=item.value
|
||||
label=item.label
|
||||
checked=(eq item.value (reactive this.value))
|
||||
}}
|
||||
{{/each}}
|
||||
{{/group}}
|
||||
</template>
|
||||
@@ -0,0 +1,15 @@
|
||||
<template name="inputRadio">
|
||||
{{#baseComponent (extend this
|
||||
base='baseInput'
|
||||
type='radio'
|
||||
mixins=(concat 'input ' this.mixins)
|
||||
labelAfter=(valueIf (isUndefined this.labelAfter) true this.labelAfter)
|
||||
labelClass=(concat 'checkboxLabel ' this.labelClass)
|
||||
wrappers=(concat ''
|
||||
(valueIf reactive this.label 'wrapperLabel ' '')
|
||||
this.wrappers
|
||||
)
|
||||
)}}
|
||||
{{>UI.contentBlock}}
|
||||
{{/baseComponent}}
|
||||
</template>
|
||||
@@ -0,0 +1,18 @@
|
||||
<template name="inputSelect">
|
||||
{{#baseComponent (extend this
|
||||
base='baseSelect'
|
||||
mixins=(concat 'select2 ' this.mixins)
|
||||
wrappers=(concat ''
|
||||
(valueIf reactive this.label 'wrapperLabel ' '')
|
||||
this.wrappers
|
||||
)
|
||||
options=(clone this.options
|
||||
multiple=(valueIf this.multiple true false)
|
||||
minimumResultsForSearch=(valueIf this.hideSearch
|
||||
-1 this.minimumResultsForSearch
|
||||
)
|
||||
)
|
||||
)}}
|
||||
{{>UI.contentBlock}}
|
||||
{{/baseComponent}}
|
||||
</template>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template name="selectTree">
|
||||
{{#group (extend this
|
||||
class=(concat
|
||||
'select-tree '
|
||||
(valueIf this.root '' 'select-tree-root ')
|
||||
this.class
|
||||
)
|
||||
mixins=(concat 'selectTree ' this.mixins)
|
||||
)}}
|
||||
{{>UI.contentBlock}}
|
||||
<div class="tree-content">
|
||||
{{#let currentNode=this.currentNode.get}}
|
||||
{{#if (and (not this.root) (ne this.search false))}}
|
||||
{{>inputText
|
||||
label=this.label
|
||||
labelClass='tree-search'
|
||||
placeholder=(choose this.searchPlaceholder 'Search')
|
||||
}}
|
||||
{{/if}}
|
||||
<div class="tree-options {{#if currentNode}}collapsed{{/if}}">
|
||||
{{#if this.root}}
|
||||
{{>selectTreeBreadcrumb component=this.component}}
|
||||
{{/if}}
|
||||
<div class="tree-inputs">
|
||||
{{#each item in (reactive this.items)}}
|
||||
{{>inputRadio
|
||||
class=this.radioClass
|
||||
name=this.key
|
||||
value=item.value
|
||||
label=item.label
|
||||
labelClass=(valueIf (isArray item.items) 'tree-node' 'tree-leaf')
|
||||
checked=(eq item.value (reactive this.value))
|
||||
}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{#if (and currentNode (isArray currentNode.items))}}
|
||||
{{>selectTree (clone this
|
||||
items=currentNode.items
|
||||
root=(choose this.root this.component)
|
||||
class='select-tree-node'
|
||||
)}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/let}}
|
||||
</div>
|
||||
{{#unless this.root}}
|
||||
{{>selectTreeCommon this}}
|
||||
{{/unless}}
|
||||
{{/group}}
|
||||
</template>
|
||||
|
||||
<template name="selectTreeCommon">
|
||||
<div class="select-tree-common">
|
||||
<div class="content">
|
||||
<h5 class="title">Common</h5>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="selectTreeBreadcrumb">
|
||||
<div class="tree-breadcrumb clearfix">
|
||||
{{>selectTreeBreadcrumbParent
|
||||
component=this.component.parent
|
||||
index=1
|
||||
}}
|
||||
{{#let currentNode=this.component.parent.templateInstance.data.currentNode.get}}
|
||||
<span class="tree-current-node">{{currentNode.label}}</span>
|
||||
{{/let}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="selectTreeBreadcrumbParent">
|
||||
{{#let parent=this.component.parent}}
|
||||
{{#let parentNode=(reactive parent.templateInstance.data.currentNode)}}
|
||||
{{#if parentNode}}
|
||||
{{>selectTreeBreadcrumbParent
|
||||
component=parent
|
||||
index=(sum this.index 1)
|
||||
}}
|
||||
{{/if}}
|
||||
<span class="path-link">
|
||||
<a href="#" class="tree-back" data-index="{{this.index}}">
|
||||
{{#if parentNode}}
|
||||
<span>{{parentNode.label}}</span>
|
||||
{{else}}
|
||||
<i class="fa fa-fast-backward"></i>
|
||||
{{/if}}
|
||||
</a>
|
||||
{{#if parentNode}}<span>/</span>{{/if}}
|
||||
</span>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
</template>
|
||||
@@ -0,0 +1,145 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Template } from 'meteor/templating';
|
||||
import { _ } from 'meteor/underscore';
|
||||
import { $ } from 'meteor/jquery';
|
||||
|
||||
// TODO: use npm dependency
|
||||
import transition from 'meteor/ohif:core/client/lib/third-party/transition-to-from-auto';
|
||||
|
||||
Template.selectTree.onRendered(() => {
|
||||
const instance = Template.instance();
|
||||
const component = instance.$('.select-tree:first').data('component');
|
||||
const rootComponent = instance.data.root || component;
|
||||
const rootInstance = rootComponent.templateInstance;
|
||||
const $treeRoot = rootInstance.$('.select-tree-root:first').first();
|
||||
|
||||
instance.component = component;
|
||||
|
||||
// Start the component transitions
|
||||
$treeRoot.addClass('started');
|
||||
|
||||
// Update the component's viewport height
|
||||
instance.updateHeight = () => {
|
||||
const height = rootInstance.$('.tree-options:last').data('height');
|
||||
rootInstance.$('.tree-options:first').height(height);
|
||||
};
|
||||
|
||||
// Update the opened node
|
||||
instance.updateOpen = () => {
|
||||
rootInstance.$('.select-tree').removeClass('open');
|
||||
rootInstance.$('.select-tree:last').addClass('open');
|
||||
};
|
||||
|
||||
// Put the component in selected state
|
||||
instance.setSelected = (flag) => {
|
||||
if (flag) {
|
||||
$treeRoot.addClass('selected');
|
||||
} else {
|
||||
$treeRoot.removeClass('selected');
|
||||
}
|
||||
};
|
||||
|
||||
// Store the element's initial height
|
||||
const $treeOptions = instance.$('.tree-options:first').first();
|
||||
const height = $treeOptions.height();
|
||||
$treeOptions.data('height', height);
|
||||
|
||||
instance.autorun(() => {
|
||||
// Run this computation everytime the current node is changed
|
||||
instance.data.currentNode.dep.depend();
|
||||
|
||||
// Update the viewport height
|
||||
Tracker.afterFlush(() => {
|
||||
instance.updateHeight();
|
||||
instance.updateOpen();
|
||||
});
|
||||
});
|
||||
|
||||
const selector = '.select-tree:first>.tree-content>.tree-options>.tree-breadcrumb .path-link';
|
||||
instance.$(selector).css('width', 0).each((index, element) => {
|
||||
transition({
|
||||
element: element,
|
||||
prop: 'width',
|
||||
style: 'width 0.3s ease',
|
||||
val: 'auto'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Template.selectTree.events({
|
||||
'click .select-tree-root'(event, instance) {
|
||||
// Detect the first interaction with the component and do the animation
|
||||
$(event.currentTarget).addClass('interacted');
|
||||
},
|
||||
|
||||
'change .select-tree:first>.tree-content>.tree-options>.tree-inputs>label>input'(event, instance) {
|
||||
const component = instance.component;
|
||||
const $target = $(event.target);
|
||||
const $label = $target.closest('label');
|
||||
const eventComponent = $target.data('component');
|
||||
const rootComponent = instance.data.root || component;
|
||||
const rootInstance = rootComponent.templateInstance;
|
||||
|
||||
// Change the component's value
|
||||
component.value(eventComponent.value());
|
||||
|
||||
// Unset the active leaf
|
||||
rootInstance.$('label').removeClass('active');
|
||||
|
||||
// Unset the selected state
|
||||
instance.setSelected(false);
|
||||
|
||||
// Check if the clicked element is a node or a leaf
|
||||
const isLeaf = $label.hasClass('tree-leaf');
|
||||
if (isLeaf) {
|
||||
// Change the active item
|
||||
$label.addClass('active');
|
||||
|
||||
// Mark the component as selected
|
||||
instance.setSelected(true);
|
||||
} else {
|
||||
// Get the position of the clicked element
|
||||
const position = $label.position();
|
||||
|
||||
Meteor.defer(() => {
|
||||
const $treeNode = $label.parent().siblings('.select-tree');
|
||||
|
||||
// Do the transition from the clicked position to top
|
||||
$treeNode.css(position);
|
||||
setTimeout(() => $treeNode.css('top', 0));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
'click .select-tree:first>.tree-content>.tree-options>.tree-breadcrumb .tree-back'(event, instance) {
|
||||
const rootComponent = instance.data.root || instance.component;
|
||||
const rootInstance = rootComponent.templateInstance;
|
||||
|
||||
// Prevent the default element action
|
||||
event.preventDefault();
|
||||
|
||||
// Reset the checked inputs to unchecked state
|
||||
rootInstance.$('input').removeAttr('checked');
|
||||
|
||||
// Unset the selected state
|
||||
instance.setSelected(false);
|
||||
|
||||
// Get the index of the breadcrumb's clicked option
|
||||
const index = $(event.currentTarget).attr('data-index') | 0;
|
||||
|
||||
// Set the current instance
|
||||
let currentInstance = instance.component.parent.templateInstance;
|
||||
|
||||
// Iterate over all parents until gets into the clicked node
|
||||
for (let i = 1; i <= index; i++) {
|
||||
// Unset the selected node
|
||||
currentInstance.data.currentNode.set(null);
|
||||
|
||||
// Check if it's not the root node
|
||||
if (i < index) {
|
||||
// Change the current instance
|
||||
currentInstance = currentInstance.component.parent.templateInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
<template name="inputText">
|
||||
{{#baseComponent (extend this
|
||||
base='baseInput'
|
||||
class=(concat 'form-control ' this.class)
|
||||
mixins=(concat 'input ' this.mixins)
|
||||
wrappers=(concat ''
|
||||
(valueIf reactive this.label 'wrapperLabel ' '')
|
||||
this.wrappers
|
||||
)
|
||||
)}}
|
||||
{{>UI.contentBlock}}
|
||||
{{/baseComponent}}
|
||||
</template>
|
||||
Reference in new issue
Block a user