diff --git a/.jscsrc b/.jscsrc
index 6003e1d85..8c63714bf 100644
--- a/.jscsrc
+++ b/.jscsrc
@@ -11,7 +11,6 @@
"disallowKeywordsOnNewLine": ["else"],
"disallowNewlineBeforeBlockStatements": true,
"requirePaddingNewLinesAfterUseStrict": true,
- "requirePaddingNewLinesInObjects": true,
"requirePaddingNewLinesAfterBlocks": {
"allExcept": ["inCallExpressions", "inArrayExpressions", "inProperties"]
},
diff --git a/Packages/ohif-core/client/components/base/template.js b/Packages/ohif-core/client/components/base/template.js
index 979e9189a..1b56db365 100644
--- a/Packages/ohif-core/client/components/base/template.js
+++ b/Packages/ohif-core/client/components/base/template.js
@@ -1,5 +1,7 @@
-import { OHIF } from 'meteor/ohif:core';
+import { Template } from 'meteor/templating';
+import { Blaze } from 'meteor/blaze';
import { _ } from 'meteor/underscore';
+import { OHIF } from 'meteor/ohif:core';
// Create a new custom template for the base component
Template.baseComponent = new Template('baseComponent', () => {});
@@ -30,9 +32,6 @@ Template.baseComponent.constructView = function(contentFunc, elseFunc) {
// Extract the render function from the base template
template.renderFunction = baseTemplate.renderFunction;
- // Check for the mixins. If it's not informed set the lowest level mixin
- const mixins = data.mixins || 'component';
-
// Init the data manipulation mixins
OHIF.Mixin.initData(data);
diff --git a/Packages/ohif-core/client/components/base/templates/form.html b/Packages/ohif-core/client/components/base/templates/form.html
index e5a4e0e4a..ca7c66c00 100644
--- a/Packages/ohif-core/client/components/base/templates/form.html
+++ b/Packages/ohif-core/client/components/base/templates/form.html
@@ -11,7 +11,7 @@
target="{{this.target}}"
{{this.tagAttributes}}
>
- {{#if validationErrors}}
+ {{#if (and validationErrors (not this.hideValidationBox))}}
{{#each error in validationErrors}}
{{error.message}}
diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/form.html b/Packages/ohif-core/client/components/bootstrap/dialog/form.html
new file mode 100644
index 000000000..235eec6e5
--- /dev/null
+++ b/Packages/ohif-core/client/components/bootstrap/dialog/form.html
@@ -0,0 +1,19 @@
+
+
+
+ {{#form class='modal-content' schema=this.schema hideValidationBox=true api=instance.api}}
+
+
+ {{>UI.contentBlock}}
+
+
+ {{/form}}
+
+
+
diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/form.js b/Packages/ohif-core/client/components/bootstrap/dialog/form.js
new file mode 100644
index 000000000..3975bed41
--- /dev/null
+++ b/Packages/ohif-core/client/components/bootstrap/dialog/form.js
@@ -0,0 +1,45 @@
+import { Template } from 'meteor/templating';
+import { _ } from 'meteor/underscore';
+
+Template.dialogForm.onCreated(() => {
+ const instance = Template.instance();
+
+ instance.api = {
+ confirm() {
+ // Check if the form has valid data
+ const form = instance.$('form').data('component');
+ if (!form.validate()) {
+ return;
+ }
+
+ // Get the form value and call the confirm callback or resolve the promise
+ const formData = form.value();
+ if (_.isFunction(instance.data.confirmCallback)) {
+ instance.data.confirmCallback(formData, instance.data.promiseResolve);
+ } else {
+ instance.data.promiseResolve(formData);
+ }
+ },
+ cancel() {
+ // Call the cancel callback or resolve the promise
+ if (_.isFunction(instance.data.cancelCallback)) {
+ instance.data.cancelCallback(instance.data.promiseReject);
+ } else {
+ instance.data.promiseReject();
+ }
+ }
+ };
+});
+
+Template.dialogForm.onRendered(() => {
+ const instance = Template.instance();
+
+ // Create the bootstrap modal
+ const $modal = instance.$('.modal');
+ $modal.modal();
+
+ // Remove the created modal backdrop from DOM after promise is done
+ const $backdrop = $modal.next('.modal-backdrop');
+ const dismissDialogBackdrop = () => $backdrop.remove();
+ instance.data.promise.then(dismissDialogBackdrop).catch(dismissDialogBackdrop);
+});
diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/login.html b/Packages/ohif-core/client/components/bootstrap/dialog/login.html
new file mode 100644
index 000000000..bc719273d
--- /dev/null
+++ b/Packages/ohif-core/client/components/bootstrap/dialog/login.html
@@ -0,0 +1,6 @@
+
+ {{#dialogForm (extend this dialogClass='modal-sm' schema=(choose this.schema instance.schema))}}
+ {{>inputText labelClass='form-group' key='username'}}
+ {{>inputPassword labelClass='form-group' key='password'}}
+ {{/dialogForm}}
+
diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/login.js b/Packages/ohif-core/client/components/bootstrap/dialog/login.js
new file mode 100644
index 000000000..8ad40f073
--- /dev/null
+++ b/Packages/ohif-core/client/components/bootstrap/dialog/login.js
@@ -0,0 +1,17 @@
+import { Template } from 'meteor/templating';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+
+Template.dialogLogin.onCreated(() => {
+ const instance = Template.instance();
+
+ instance.schema = new SimpleSchema({
+ username: {
+ type: String,
+ label: 'Username'
+ },
+ password: {
+ type: String,
+ label: 'Password'
+ }
+ });
+});
diff --git a/Packages/ohif-core/client/components/bootstrap/index.js b/Packages/ohif-core/client/components/bootstrap/index.js
index 0fbf070a6..03dcfc14c 100644
--- a/Packages/ohif-core/client/components/bootstrap/index.js
+++ b/Packages/ohif-core/client/components/bootstrap/index.js
@@ -1,3 +1,8 @@
+import './dialog/form.html';
+import './dialog/form.js';
+import './dialog/login.html';
+import './dialog/login.js';
+
import './form/button.html';
import './form/form.html';
import './form/group.html';
@@ -5,6 +10,7 @@ import './form/group.html';
import './input/checkbox.html';
import './input/hidden.html';
import './input/groupRadio.html';
+import './input/password.html';
import './input/radio.html';
import './input/range.html';
import './input/select.html';
diff --git a/Packages/ohif-core/client/components/bootstrap/input/password.html b/Packages/ohif-core/client/components/bootstrap/input/password.html
new file mode 100644
index 000000000..caf51a343
--- /dev/null
+++ b/Packages/ohif-core/client/components/bootstrap/input/password.html
@@ -0,0 +1,7 @@
+
+ {{#inputText (extend this
+ type='password'
+ )}}
+ {{>UI.contentBlock}}
+ {{/inputText}}
+
diff --git a/Packages/ohif-core/client/ui/bounded/bounded.js b/Packages/ohif-core/client/ui/bounded/bounded.js
index 2d4d1ecd3..482931628 100644
--- a/Packages/ohif-core/client/ui/bounded/bounded.js
+++ b/Packages/ohif-core/client/ui/bounded/bounded.js
@@ -158,4 +158,4 @@ class Bounded {
}
-OHIF.Bounded = Bounded;
+OHIF.ui.Bounded = Bounded;
diff --git a/Packages/ohif-core/client/ui/dialog/form.js b/Packages/ohif-core/client/ui/dialog/form.js
new file mode 100644
index 000000000..9b72e0a57
--- /dev/null
+++ b/Packages/ohif-core/client/ui/dialog/form.js
@@ -0,0 +1,38 @@
+import { Template } from 'meteor/templating';
+import { Blaze } from 'meteor/blaze';
+import { _ } from 'meteor/underscore';
+import { OHIF } from 'meteor/ohif:core';
+
+OHIF.ui.showFormDialog = (templateName, dialogData) => {
+ // Check if the given template exists
+ const template = Template[templateName];
+ if (!template) {
+ throw {
+ name: 'TEMPLATE_NOT_FOUND',
+ message: `Template ${templateName} not found.`
+ };
+ }
+
+ // Create a new promise to control the modal and store its resolve and reject callbacks
+ let promiseResolve;
+ let promiseReject;
+ const promise = new Promise((resolve, reject) => {
+ promiseResolve = resolve;
+ promiseReject = reject;
+ });
+
+ // Render the dialog with the given template passing the promise object and callbacks
+ const templateData = _.extend({}, dialogData, {
+ promise,
+ promiseResolve,
+ promiseReject
+ });
+ const view = Blaze.renderWithData(template, templateData, document.body);
+
+ // Destroy the created dialog view when the promise is either resolved or rejected
+ const dismissModal = () => Blaze.remove(view);
+ promise.then(dismissModal).catch(dismissModal);
+
+ // Return the promise to allow callbacks stacking from outside
+ return promise;
+};
diff --git a/Packages/ohif-core/client/ui/draggable/draggable.js b/Packages/ohif-core/client/ui/draggable/draggable.js
index b21e79da9..323638036 100644
--- a/Packages/ohif-core/client/ui/draggable/draggable.js
+++ b/Packages/ohif-core/client/ui/draggable/draggable.js
@@ -1,6 +1,8 @@
+import { OHIF } from 'meteor/ohif:core';
+
// Allow attaching to jQuery selectors
-$.fn.draggable = function(options) {
- makeDraggable(this, options);
+$.fn.draggable = function() {
+ OHIF.ui.makeDraggable(this);
return this;
};
@@ -11,7 +13,7 @@ $.fn.draggable = function(options) {
*
* @param element
*/
-makeDraggable = function(element, options) {
+OHIF.ui.makeDraggable = function(element) {
var container = $(window);
var diffX,
diffY,
diff --git a/Packages/ohif-core/client/ui/index.js b/Packages/ohif-core/client/ui/index.js
index 2b2c872b5..7978c5073 100644
--- a/Packages/ohif-core/client/ui/index.js
+++ b/Packages/ohif-core/client/ui/index.js
@@ -1,3 +1,4 @@
import './bounded/bounded.js';
+import './dialog/form.js';
import './draggable/draggable.js';
import './resizable/resizable.js';
diff --git a/Packages/ohif-core/client/ui/resizable/resizable.js b/Packages/ohif-core/client/ui/resizable/resizable.js
index edde14ab0..d4eaeee3b 100644
--- a/Packages/ohif-core/client/ui/resizable/resizable.js
+++ b/Packages/ohif-core/client/ui/resizable/resizable.js
@@ -1,3 +1,5 @@
+import { OHIF } from 'meteor/ohif:core';
+
// Allow attaching to jQuery selectors
$.fn.resizable = function(options) {
_.each(this, element => {
@@ -174,3 +176,5 @@ class Resizable {
}
}
+
+OHIF.ui.Resizable = Resizable;
diff --git a/Packages/ohif-core/main.js b/Packages/ohif-core/main.js
index f47c51db6..ec18952f1 100644
--- a/Packages/ohif-core/main.js
+++ b/Packages/ohif-core/main.js
@@ -1,9 +1,12 @@
+import { Meteor } from 'meteor/meteor';
+
/*
* Defines the base OHIF object
*/
const OHIF = {
log: {},
+ ui: {},
viewer: {},
measurements: {}
};
diff --git a/Packages/ohif-cornerstone/main.js b/Packages/ohif-cornerstone/main.js
deleted file mode 100644
index 3b8d95406..000000000
--- a/Packages/ohif-cornerstone/main.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// TODO: stop exposing the libraries below and start using imports
-
-import { cornerstone } from './client/cornerstone.js';
-import { dicomParser } from './client/dicomParser.js';
-import { cornerstoneMath } from './client/cornerstoneMath.js';
-import { cornerstoneTools } from './client/cornerstoneTools.js';
-import { cornerstoneWADOImageLoader } from './client/cornerstoneWADOImageLoader.js';
-
-// Expose the cornerstone objects to the client if it is on development mode
-if (Meteor.isDevelopment) {
- window.cornerstone = cornerstone;
- window.cornerstoneMath = cornerstoneMath;
- window.cornerstoneTools = cornerstoneTools;
- window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
- window.dicomParser = dicomParser;
-}
-
-export {
- cornerstone,
- cornerstoneMath,
- cornerstoneTools,
- cornerstoneWADOImageLoader,
- dicomParser
-};