LT-67: Migrating the main form and its inputs to components

This commit is contained in:
Bruno Alves de Faria 2016-08-29 16:51:02 -03:00
parent eb63e88581
commit 6cbfc1c180
16 changed files with 145 additions and 39 deletions

View File

@ -8,13 +8,13 @@ npm-bcrypt@0.8.7
meteor-base@1.0.4 # Packages every Meteor app needs to have
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
blaze-html-templates@1.0.4 # Compile .html files into Meteor Blaze views
session@1.1.6 # Client-side reactive dictionary for your app
jquery@1.11.9 # Helpful client-side library
jquery@1.11.9 # Helpful client-side library
tracker@1.1.0 # Meteor's client-side reactive programming library
es5-shim@4.6.13 # ECMAScript 5 compatibility for older browsers.
es5-shim@4.6.13 # ECMAScript 5 compatibility for older browsers.
ecmascript@0.5.7 # Enable ECMAScript2015+ syntax in app code
clinical:router
@ -26,6 +26,8 @@ clinical:fonts
clinical:hipaa-audit-log
clinical:hipaa-logger
aldeed:simple-schema # Third party package to deal with schemas
design
ohif:core

View File

@ -26,6 +26,7 @@ spacebars@1.0.12
check@1.2.3
cornerstone
dicomweb
aldeed:simple-schema # Third party package to deal with schemas
design
ohif:core
ecmascript@0.5.7

View File

@ -4,10 +4,27 @@ html body
font-family: 'Roboto', 'OpenSans', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif
// Try to fix LT-273, need a monitor to test on though.
//text-rendering: optimizeLegibility
html hr
border-top: 1px solid $uiBorderColor
label.form-group
width: 100%
&>span.select2
display: block
width: 100% !important
span.select2-selection
min-height: 34px
span.select2-selection__rendered
height: 34px
line-height: 34px
span.select2-selection__arrow
height: 34px
.center-table
display: table
margin-left: auto
@ -38,4 +55,3 @@ html hr
.modal-header, .modal-footer
border-color: $uiBorderColor

View File

@ -1,33 +1,19 @@
<template name="serverInformationForm">
<form class="server-information-form">
<input type="hidden" name="_id">
{{#form class='server-information-form' schema=instance.currentSchema}}
{{>inputHidden key='_id'}}
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label class="wrapper">
<strong>Server Name</strong>
<input type="text" name="name" class="form-control">
</label>
</div>
{{>inputText labelClass='form-group' key='name'}}
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="wrapper">
<strong>Server Type</strong>
<select name="type" class="form-control js-server-type">
<option>Select</option>
<option value="dicomWeb">DICOM Web</option>
<option value="dimse">DIMSE</option>
</select>
</label>
</div>
{{>inputSelect labelClass='form-group' key='type' hideSearch=true}}
</div>
</div>
<hr>
{{#if eq this.serverType.get "dicomWeb"}}
{{#if eq this.serverType.get 'dicomWeb'}}
{{>serverInformationDicomWeb this}}
{{/if}}
{{#if eq this.serverType.get "dimse"}}
{{#if eq this.serverType.get 'dimse'}}
{{>serverInformationDimse this}}
{{/if}}
{{#if this.serverType.get}}
@ -35,5 +21,5 @@
<input type="submit" class="btn btn-primary" value="Save">
</div>
{{/if}}
</form>
{{/form}}
</template>

View File

@ -1,9 +1,27 @@
Template.serverInformationForm.onRendered(function() {
var instance = Template.instance();
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { DICOMWebServer as dicomSchema } from 'meteor/worklist/both/schema';
import { DIMSEServer as dimseSchema } from 'meteor/worklist/both/schema';
Template.serverInformationForm.onCreated(() => {
const instance = Template.instance();
instance.currentSchema = new ReactiveVar(dicomSchema);
});
Template.serverInformationForm.onRendered(() => {
const instance = Template.instance();
instance.data.$form = instance.$('form');
instance.autorun(function() {
var mode = instance.data.mode.get();
instance.autorun(() => {
const typeComponent = instance.$('[data-key=type]').data('component');
typeComponent.changeObserver.depend();
instance.data.serverType.set(typeComponent.value());
});
instance.autorun(() => {
const mode = instance.data.mode.get();
if (mode === 'edit') {
var data = instance.data.currentItem.get();
FormUtils.setFormData(instance.data.$form, data);
@ -12,11 +30,7 @@ Template.serverInformationForm.onRendered(function() {
});
Template.serverInformationForm.events({
'change .js-server-type': function(event, instance) {
var value = $(event.currentTarget).val();
instance.data.serverType.set(value);
},
submit: function(event, instance) {
submit(event, instance) {
event.preventDefault();
var formData = FormUtils.getFormData(instance.data.$form);
Meteor.call('serverSave', formData, function(error) {

View File

@ -0,0 +1 @@
import './schema.js';

View File

@ -0,0 +1,6 @@
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
SimpleSchema.extendOptions({
valuesLabels: Match.Optional([String]),
emptyOption: Match.Optional(Boolean)
});

View File

@ -1,5 +1,6 @@
import { OHIF } from 'meteor/ohif:core';
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
/*
* form: controls a form and its registered inputs
@ -11,9 +12,19 @@ OHIF.mixins.form = new OHIF.Mixin({
const instance = Template.instance();
const component = instance.component;
// Define the form's data schema
const schema = instance.data.schema;
component.schema = schema && schema.newContext();
// Run this computation every time the schema property is changed
instance.autorun(() => {
let schema;
// Check if the schema is reactive
if (instance.data.schema instanceof ReactiveVar) {
// Register a dependency on schema property
schema = instance.data.schema.get();
}
// Set the form's data schema
component.schema = schema && schema.newContext();
});
// Check if the form data is valid in its schema
component.validate = () => {

View File

@ -17,6 +17,11 @@ const getCurrentSchema = (parentComponent, key) => {
// Get the current schema data using component's key
const currentSchema = _.clone(schema._schema[key]);
// Stop here if no schema was found for the given key
if (!currentSchema) {
return;
}
// Merge the sub-schema properties if it's an array
if (Array.isArray(currentSchema.type())) {
_.extend(currentSchema, schema._schema[key + '.$']);
@ -53,6 +58,11 @@ OHIF.mixins.schemaData = new OHIF.Mixin({
data.label = new ReactiveVar(currentSchema.label);
}
// Set the emptyOption data attribute if given on schema
if (currentSchema.emptyOption) {
data.emptyOption = currentSchema.emptyOption;
}
// Fill the items if it's an array schema
if (!data.items && Array.isArray(currentSchema.allowedValues)) {
// Initialize the items array

View File

@ -7,6 +7,43 @@ import { Template } from 'meteor/templating';
OHIF.mixins.select = new OHIF.Mixin({
dependencies: 'formItem',
composition: {
onCreated() {
const instance = Template.instance();
// Check if this select will include an empty option
if (instance.data.emptyOption) {
// Get the option items
let items = instance.data.items;
// Check if the items are reactive and get them if true
const isReactive = items instanceof ReactiveVar;
if (isReactive) {
items = items.get();
}
// Check if there is already an empty option on items list
const query = {
value: ''
};
if (!_.findWhere(items, query)) {
// Clone the current items
const newItems = _.clone(items);
newItems.unshift({
label: 'Select',
value: ''
});
// Set the new items list including the empty option
if (isReactive) {
instance.data.items.set(newItems);
} else {
instance.data.items = newItems;
}
}
}
},
onRendered() {
const instance = Template.instance();
const component = instance.component;
@ -14,5 +51,6 @@ OHIF.mixins.select = new OHIF.Mixin({
// Set the element to be controlled
component.$element = instance.$('select:first');
}
}
});

View File

@ -6,6 +6,7 @@
name="{{this.name}}"
value="{{reactive this.value}}"
placeholder="{{this.placeholder}}"
data-key="{{this.key}}"
{{this.tagAttributes}}
>
{{>UI.contentBlock}}

View File

@ -4,6 +4,7 @@
class="{{this.class}}"
name="{{this.name}}"
multiple="{{#if this.multiple}}multiple{{/if}}"
data-key="{{this.key}}"
{{this.tagAttributes}}
>
{{>UI.contentBlock}}

View File

@ -1,6 +1,7 @@
import './form/form.html';
import './form/group.html';
import './input/hidden.html';
import './input/groupRadio.html';
import './input/radio.html';
import './input/select.html';

View File

@ -0,0 +1,7 @@
<template name="inputHidden">
{{>baseComponent (extend this
base='baseInput'
type='hidden'
mixins=(concat 'input ' this.mixins)
)}}
</template>

View File

@ -34,4 +34,7 @@ Package.onUse(function(api) {
// Server imports and methods
api.addFiles('server/index.js', 'server');
// Client and server imports
api.addFiles('both/index.js', ['client', 'server']);
});

View File

@ -26,9 +26,17 @@ export const DICOMWebRequestOptions = new SimpleSchema({
export const DICOMWebServer = new SimpleSchema({
name: {
type: String,
label: 'Name',
label: 'Server Name',
max: 100
},
type: {
type: String,
label: 'Server Type',
allowedValues: ['dicomWeb', 'dimse'],
valuesLabels: ['DICOM Web', 'DIMSE'],
optional: true,
emptyOption: true
},
wadoUriRoot: {
type: String,
label: 'WADO URI root',