Creating a notification mechanism
This commit is contained in:
parent
06fe7f0da7
commit
820b2efd88
@ -32,4 +32,6 @@ import './input/range.html';
|
||||
import './input/select.html';
|
||||
import './input/text.html';
|
||||
|
||||
import './notification';
|
||||
|
||||
import './popover/form.html';
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
import './notificationArea.html';
|
||||
import './notificationArea.styl';
|
||||
import './notificationNote.html';
|
||||
import './notificationNote.js';
|
||||
@ -0,0 +1,3 @@
|
||||
<template name="notificationArea">
|
||||
<div id="notificationArea" class="notification-area"></div>
|
||||
</template>
|
||||
@ -0,0 +1,62 @@
|
||||
@require '{ohif:design}/app'
|
||||
|
||||
.notification-area
|
||||
position: fixed
|
||||
right: 0
|
||||
top: 50px
|
||||
max-width: 320px
|
||||
z-index: 10000
|
||||
|
||||
.notification-note
|
||||
opacity: 0
|
||||
position: relative
|
||||
transition(opacity 0.5s linear\, max-height 0.5s linear)
|
||||
width: 300px
|
||||
z-index: 2
|
||||
|
||||
.note-container
|
||||
padding: 10px
|
||||
transform(translateY(0))
|
||||
transition(transform 0.5s linear)
|
||||
|
||||
.note-body
|
||||
margin: 0
|
||||
padding: 10px
|
||||
position: relative
|
||||
|
||||
&:not(.hide-dismiss)
|
||||
padding-right: 40px
|
||||
|
||||
.note-dismiss
|
||||
display: block
|
||||
|
||||
.note-dismiss
|
||||
bottom: 0
|
||||
cursor: pointer
|
||||
display: none
|
||||
position: absolute
|
||||
right: 0
|
||||
top: 0
|
||||
width: 40px
|
||||
|
||||
i
|
||||
display: block
|
||||
font-size: 20px
|
||||
left: 0
|
||||
position: absolute
|
||||
text-align: center
|
||||
top: 50%
|
||||
transform(translateY(-50%))
|
||||
width: 100%
|
||||
|
||||
&.in
|
||||
max-height: auto
|
||||
opacity: 1
|
||||
|
||||
&.out
|
||||
max-height: 0 !important
|
||||
opacity: 0
|
||||
z-index: 1
|
||||
|
||||
.note-container
|
||||
transform(translateY(-100%))
|
||||
@ -0,0 +1,12 @@
|
||||
<template name="notificationNote">
|
||||
<div class="notification-note {{this.class}}">
|
||||
<div class="note-container">
|
||||
<div class="note-body alert alert-{{choose this.style 'info'}} {{#if hideDismiss}}hide-dismiss{{/if}}">
|
||||
<div class="note-text">{{this.text}}</div>
|
||||
<div class="note-dismiss">
|
||||
<i class="fa fa-times"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,21 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Template } from 'meteor/templating';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
Template.notificationNote.onRendered(() => {
|
||||
const instance = Template.instance();
|
||||
Meteor.setTimeout(() => {
|
||||
const $note = instance.$('.notification-note');
|
||||
$note.css('max-height', $note.outerHeight()).addClass('in');
|
||||
}, 100);
|
||||
});
|
||||
|
||||
Template.notificationNote.events({
|
||||
'click .note-dismiss'(event, instance) {
|
||||
if (instance.data.promiseResolve) {
|
||||
instance.data.promiseResolve();
|
||||
} else {
|
||||
OHIF.ui.notifications.dismiss(instance.data.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -6,6 +6,7 @@ import './dialog/unsavedChangesDialog.js';
|
||||
import './draggable/draggable.js';
|
||||
import './dropdown/class.js';
|
||||
import './dropdown/display.js';
|
||||
import './notifications/notifications.js';
|
||||
import './popover/display.js';
|
||||
import './resizable/resizable.js';
|
||||
import './unsavedChanges/unsavedChanges.js';
|
||||
|
||||
105
Packages/ohif-core/client/ui/notifications/notifications.js
Normal file
105
Packages/ohif-core/client/ui/notifications/notifications.js
Normal file
@ -0,0 +1,105 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Template } from 'meteor/templating';
|
||||
import { ReactiveDict } from 'meteor/reactive-dict';
|
||||
import { Tracker } from 'meteor/tracker';
|
||||
import { $ } from 'meteor/jquery';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
const Notifications = {
|
||||
currentId: 0,
|
||||
views: new Map()
|
||||
};
|
||||
|
||||
// Remove the view object from DOM and from views Map
|
||||
const removeView = (id, view) => {
|
||||
Notifications.views.delete(id);
|
||||
Blaze.remove(view);
|
||||
};
|
||||
|
||||
// Dismiss a single notification note by its id
|
||||
Notifications.dismiss = id => {
|
||||
const view = Notifications.views.get(id);
|
||||
if (!view || view.isDestroyed) {
|
||||
return Notifications.views.delete(id);
|
||||
}
|
||||
|
||||
const node = view.firstNode();
|
||||
const $note = node && $(node);
|
||||
|
||||
if ($note.length) {
|
||||
$note.addClass('out').one('transitionend', () => removeView(id, view));
|
||||
} else {
|
||||
removeView(id, view)
|
||||
}
|
||||
};
|
||||
|
||||
// Dismiss all notification notes
|
||||
Notifications.clear = () => Array.from(Notifications.views.keys()).forEach(Notifications.dismiss);
|
||||
|
||||
// Display a notification note
|
||||
Notifications.show = ({ template, promise, text, style, timeout=5000 }) => {
|
||||
// Check if the given template exists
|
||||
const templateObject = Template[template];
|
||||
if (template && !templateObject) {
|
||||
throw new Meteor.Error('TEMPLATE_NOT_FOUND', `Template ${template} not found.`);
|
||||
}
|
||||
|
||||
// Check if there is a notification area container
|
||||
const $area = $('#notificationArea');
|
||||
if (!$area.length) {
|
||||
throw new Meteor.Error('NOTIFICATION_AREA_NOT_FOUND', `Notification area not found.`);
|
||||
}
|
||||
|
||||
let notificationPromise;
|
||||
let templateData = {
|
||||
text,
|
||||
style,
|
||||
timeout,
|
||||
id: Notifications.currentId++
|
||||
};
|
||||
|
||||
if (promise instanceof Promise) {
|
||||
// Use the given promise to control the notification
|
||||
notificationPromise = templateData.promise = promise;
|
||||
} else {
|
||||
// Create a new promise to control the modal and store its resolve and reject callbacks
|
||||
let promiseResolve;
|
||||
let promiseReject;
|
||||
notificationPromise = new Promise((resolve, reject) => {
|
||||
promiseResolve = resolve;
|
||||
promiseReject = reject;
|
||||
});
|
||||
|
||||
// Render the notification passing the promise object and callbacks
|
||||
_.extend({}, templateData, {
|
||||
promise: notificationPromise,
|
||||
promiseResolve,
|
||||
promiseReject
|
||||
});
|
||||
}
|
||||
|
||||
const view = Blaze.renderWithData(Template.notificationNote, templateData, $area[0]);
|
||||
const dismissNotification = () => Notifications.dismiss(templateData.id);
|
||||
|
||||
// Add the current view to the list of views to allow clearing all notifications
|
||||
Notifications.views.set(templateData.id, view);
|
||||
|
||||
// Destroy the created notification view when the promise is either resolved or rejected
|
||||
notificationPromise.then(dismissNotification).catch(dismissNotification);
|
||||
|
||||
// Destroy the created notification view if the given timeout time has passed
|
||||
if (timeout > 0) {
|
||||
Meteor.setTimeout(() => {
|
||||
if (templateData.promiseResolve) {
|
||||
templateData.promiseResolve();
|
||||
} else {
|
||||
dismissNotification();
|
||||
}
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
// Return the promise to allow callbacks stacking from outside
|
||||
return notificationPromise;
|
||||
};
|
||||
|
||||
OHIF.ui.notifications = Notifications;
|
||||
@ -15,7 +15,7 @@
|
||||
<div class="form-buttons clearfix">
|
||||
{{#button class='btn btn-danger pull-left' action='resetDefaults'}}Reset to Defaults{{/button}}
|
||||
{{#button class='btn btn-primary pull-right' action='save'}}Save{{/button}}
|
||||
{{#button class='btn btn-default pull-right m-r-1' tagAttributes=(extend '' data-dismiss='modal')}}Cancel{{/button}}
|
||||
{{#button class='btn btn-default pull-right m-r-1' tagAttributes=(extend '' data-dismiss='modal')}}Close{{/button}}
|
||||
</div>
|
||||
{{/form}}
|
||||
</template>
|
||||
|
||||
@ -11,7 +11,12 @@ Template.hotkeysForm.onCreated(() => {
|
||||
const { contextName } = instance.data;
|
||||
const form = instance.$('form').first().data('component');
|
||||
const definitions = form.value();
|
||||
return OHIF.hotkeys.store(contextName, definitions);
|
||||
const promise = OHIF.hotkeys.store(contextName, definitions);
|
||||
promise.then(() => OHIF.ui.notifications.show({
|
||||
text: 'The keyboard shortcut preferences were successfully saved.',
|
||||
style: 'success'
|
||||
}));
|
||||
return promise;
|
||||
},
|
||||
|
||||
resetDefaults() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user