diff --git a/LesionTracker/.meteor/packages b/LesionTracker/.meteor/packages index 063656cd3..1326f3bf7 100644 --- a/LesionTracker/.meteor/packages +++ b/LesionTracker/.meteor/packages @@ -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 diff --git a/OHIFViewer/.meteor/packages b/OHIFViewer/.meteor/packages index af7747e20..4108a86e1 100755 --- a/OHIFViewer/.meteor/packages +++ b/OHIFViewer/.meteor/packages @@ -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 diff --git a/Packages/design/styles/common/global.styl b/Packages/design/styles/common/global.styl index ac25bb23a..ccaf049ef 100644 --- a/Packages/design/styles/common/global.styl +++ b/Packages/design/styles/common/global.styl @@ -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 - diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html index 435b795a4..03b89862e 100644 --- a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html +++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html @@ -1,33 +1,19 @@ - - + {{#form class='server-information-form' schema=instance.currentSchema}} + {{>inputHidden key='_id'}} - - - Server Name - - - + {{>inputText labelClass='form-group' key='name'}} - - - Server Type - - Select - DICOM Web - DIMSE - - - + {{>inputSelect labelClass='form-group' key='type' hideSearch=true}} - {{#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 @@ {{/if}} - + {{/form}} diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.js b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.js index 69a8c1465..4f2a36d69 100644 --- a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.js +++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.js @@ -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) { diff --git a/Packages/ohif-core/both/index.js b/Packages/ohif-core/both/index.js new file mode 100644 index 000000000..94b130b86 --- /dev/null +++ b/Packages/ohif-core/both/index.js @@ -0,0 +1 @@ +import './schema.js'; diff --git a/Packages/ohif-core/both/schema.js b/Packages/ohif-core/both/schema.js new file mode 100644 index 000000000..516330e6a --- /dev/null +++ b/Packages/ohif-core/both/schema.js @@ -0,0 +1,6 @@ +import { SimpleSchema } from 'meteor/aldeed:simple-schema'; + +SimpleSchema.extendOptions({ + valuesLabels: Match.Optional([String]), + emptyOption: Match.Optional(Boolean) +}); diff --git a/Packages/ohif-core/client/components/base/mixins/form.js b/Packages/ohif-core/client/components/base/mixins/form.js index 2e04a6f50..345c0891a 100644 --- a/Packages/ohif-core/client/components/base/mixins/form.js +++ b/Packages/ohif-core/client/components/base/mixins/form.js @@ -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 = () => { diff --git a/Packages/ohif-core/client/components/base/mixins/schemaData.js b/Packages/ohif-core/client/components/base/mixins/schemaData.js index bb6cacc5b..6bddc2012 100644 --- a/Packages/ohif-core/client/components/base/mixins/schemaData.js +++ b/Packages/ohif-core/client/components/base/mixins/schemaData.js @@ -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 diff --git a/Packages/ohif-core/client/components/base/mixins/select.js b/Packages/ohif-core/client/components/base/mixins/select.js index 17fe6d95f..966eaaf6e 100644 --- a/Packages/ohif-core/client/components/base/mixins/select.js +++ b/Packages/ohif-core/client/components/base/mixins/select.js @@ -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'); } + } }); diff --git a/Packages/ohif-core/client/components/base/templates/input.html b/Packages/ohif-core/client/components/base/templates/input.html index 847826cef..2df32a319 100644 --- a/Packages/ohif-core/client/components/base/templates/input.html +++ b/Packages/ohif-core/client/components/base/templates/input.html @@ -6,6 +6,7 @@ name="{{this.name}}" value="{{reactive this.value}}" placeholder="{{this.placeholder}}" + data-key="{{this.key}}" {{this.tagAttributes}} > {{>UI.contentBlock}} diff --git a/Packages/ohif-core/client/components/base/templates/select.html b/Packages/ohif-core/client/components/base/templates/select.html index 99536a06a..fa1535a33 100644 --- a/Packages/ohif-core/client/components/base/templates/select.html +++ b/Packages/ohif-core/client/components/base/templates/select.html @@ -4,6 +4,7 @@ class="{{this.class}}" name="{{this.name}}" multiple="{{#if this.multiple}}multiple{{/if}}" + data-key="{{this.key}}" {{this.tagAttributes}} > {{>UI.contentBlock}} diff --git a/Packages/ohif-core/client/components/bootstrap/index.js b/Packages/ohif-core/client/components/bootstrap/index.js index 6bc4a245e..b8aa81556 100644 --- a/Packages/ohif-core/client/components/bootstrap/index.js +++ b/Packages/ohif-core/client/components/bootstrap/index.js @@ -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'; diff --git a/Packages/ohif-core/client/components/bootstrap/input/hidden.html b/Packages/ohif-core/client/components/bootstrap/input/hidden.html new file mode 100644 index 000000000..01ec712ea --- /dev/null +++ b/Packages/ohif-core/client/components/bootstrap/input/hidden.html @@ -0,0 +1,7 @@ + + {{>baseComponent (extend this + base='baseInput' + type='hidden' + mixins=(concat 'input ' this.mixins) + )}} + diff --git a/Packages/ohif-core/package.js b/Packages/ohif-core/package.js index 2f08ef057..9969718ed 100644 --- a/Packages/ohif-core/package.js +++ b/Packages/ohif-core/package.js @@ -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']); + }); diff --git a/Packages/worklist/both/schema.js b/Packages/worklist/both/schema.js index 57bb71405..c64e4da0c 100644 --- a/Packages/worklist/both/schema.js +++ b/Packages/worklist/both/schema.js @@ -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',