Close notifications on transition or user action.

closes #3012
- Inject notification object into router
- Listen to didTransition / observe currentPath to close notifications
- Close notifications on successful save actions
This commit is contained in:
Fabian Becker 2014-06-24 10:00:28 +00:00
parent 185fd0130f
commit 6aabb08660
8 changed files with 54 additions and 20 deletions

View File

@ -9,8 +9,8 @@ var DeletePostController = Ember.Controller.extend({
model.destroyRecord().then(function () { model.destroyRecord().then(function () {
self.get('popover').closePopovers(); self.get('popover').closePopovers();
self.notifications.showSuccess('Your post has been deleted.');
self.transitionToRoute('posts.index'); self.transitionToRoute('posts.index');
self.notifications.showSuccess('Your post has been deleted.', true);
}, function () { }, function () {
self.notifications.showError('Your post could not be deleted. Please try again.'); self.notifications.showError('Your post could not be deleted. Please try again.');
}); });

View File

@ -31,6 +31,9 @@ var SettingsGeneralController = Ember.ObjectController.extend({
var self = this; var self = this;
return this.get('model').save().then(function (model) { return this.get('model').save().then(function (model) {
// @TODO This should call closePassive() to only close passive notifications
self.notifications.closeAll();
self.notifications.showSuccess('Settings successfully saved.'); self.notifications.showSuccess('Settings successfully saved.');
return model; return model;
}).catch(this.notifications.showErrors); }).catch(this.notifications.showErrors);

View File

@ -21,10 +21,15 @@ var SettingsUserController = Ember.Controller.extend({
actions: { actions: {
save: function () { save: function () {
var self = this;
alert('@TODO: Saving user...'); alert('@TODO: Saving user...');
if (this.user.validate().get('isValid')) { if (this.user.validate().get('isValid')) {
this.user.save().then(function (response) { this.user.save().then(function (response) {
// @TODO This should call closePassive() to only close passive notifications
self.notifications.closeAll();
alert('Done saving' + JSON.stringify(response)); alert('Done saving' + JSON.stringify(response));
}, function () { }, function () {
alert('Error saving.'); alert('Error saving.');

View File

@ -8,6 +8,7 @@ var injectNotificationsInitializer = {
application.inject('controller', 'notifications', 'notifications:main'); application.inject('controller', 'notifications', 'notifications:main');
application.inject('component', 'notifications', 'notifications:main'); application.inject('component', 'notifications', 'notifications:main');
application.inject('router', 'notifications', 'notifications:main');
application.inject('route', 'notifications', 'notifications:main'); application.inject('route', 'notifications', 'notifications:main');
} }
}; };

View File

@ -118,11 +118,11 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
actions: { actions: {
save: function () { save: function () {
var status = this.get('willPublish') ? 'published' : 'draft', var status = this.get('willPublish') ? 'published' : 'draft',
isNew = this.get('isNew'),
self = this; self = this;
// set markdown equal to what's in the editor, minus the image markers. // set markdown equal to what's in the editor, minus the image markers.
this.set('markdown', this.getMarkdown().withoutMarkers); this.set('markdown', this.getMarkdown().withoutMarkers);
this.set('status', status); this.set('status', status);
return this.get('model').save().then(function (model) { return this.get('model').save().then(function (model) {
@ -131,8 +131,11 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
// for a saved model it would otherwise be false. // for a saved model it would otherwise be false.
self.set('isDirty', false); self.set('isDirty', false);
// @TODO This should call closePassive() to only close passive notifications
self.notifications.closeAll();
self.notifications.showSuccess('Post status saved as <strong>' + self.notifications.showSuccess('Post status saved as <strong>' +
model.get('status') + '</strong>.'); model.get('status') + '</strong>.', isNew ? true : false);
return model; return model;
}).catch(function (errors) { }).catch(function (errors) {
self.notifications.showErrors(errors); self.notifications.showErrors(errors);

View File

@ -6,7 +6,13 @@ var Router = Ember.Router.extend();
Router.reopen({ Router.reopen({
location: 'trailing-history', // use HTML5 History API instead of hash-tag based URLs location: 'trailing-history', // use HTML5 History API instead of hash-tag based URLs
rootURL: ghostPaths().subdir + '/ghost/ember/' // admin interface lives under sub-directory /ghost rootURL: ghostPaths().subdir + '/ghost/ember/', // admin interface lives under sub-directory /ghost
clearNotifications: function () {
// @TODO This should call closePassive() to only close passive notifications
this.notifications.closeAll();
this.notifications.displayDelayed();
}.on('didTransition')
}); });
Router.map(function () { Router.map(function () {

View File

@ -16,10 +16,10 @@ var SignoutRoute = AuthenticatedRoute.extend(styleBody, loadingIndicator, {
'X-CSRF-Token': this.get('csrf') 'X-CSRF-Token': this.get('csrf')
} }
}).then(function () { }).then(function () {
self.notifications.showSuccess('You were successfully signed out.');
self.transitionTo('signin'); self.transitionTo('signin');
self.notifications.showSuccess('You were successfully signed out.', true);
}, function (resp) { }, function (resp) {
self.notifications.showAPIError(resp, 'There was a problem logging out, please try again.'); self.notifications.showAPIError(resp, 'There was a problem logging out, please try again.', true);
self.transitionTo('posts'); self.transitionTo('posts');
}); });
} }

View File

@ -1,4 +1,5 @@
var Notifications = Ember.ArrayProxy.extend({ var Notifications = Ember.ArrayProxy.extend({
delayedNotifications: [],
content: Ember.A(), content: Ember.A(),
timeout: 3000, timeout: 3000,
pushObject: function (object) { pushObject: function (object) {
@ -9,43 +10,58 @@ var Notifications = Ember.ArrayProxy.extend({
} }
this._super(object); this._super(object);
}, },
showError: function (message) { handleNotification: function (message, delayed) {
this.pushObject({ if (!delayed) {
this.pushObject(message);
} else {
this.delayedNotifications.push(message);
}
},
showError: function (message, delayed) {
this.handleNotification({
type: 'error', type: 'error',
message: message message: message
}); }, delayed);
}, },
showErrors: function (errors) { showErrors: function (errors) {
for (var i = 0; i < errors.length; i += 1) { for (var i = 0; i < errors.length; i += 1) {
this.showError(errors[i].message || errors[i]); this.showError(errors[i].message || errors[i]);
} }
}, },
showAPIError: function (resp, defaultErrorText) { showAPIError: function (resp, defaultErrorText, delayed) {
defaultErrorText = defaultErrorText || 'There was a problem on the server, please try again.'; defaultErrorText = defaultErrorText || 'There was a problem on the server, please try again.';
if (resp && resp.jqXHR && resp.jqXHR.responseJSON && resp.jqXHR.responseJSON.error) { if (resp && resp.jqXHR && resp.jqXHR.responseJSON && resp.jqXHR.responseJSON.error) {
this.showError(resp.jqXHR.responseJSON.error); this.showError(resp.jqXHR.responseJSON.error, delayed);
} else { } else {
this.showError(defaultErrorText); this.showError(defaultErrorText, delayed);
} }
}, },
showInfo: function (message) { showInfo: function (message, delayed) {
this.pushObject({ this.handleNotification({
type: 'info', type: 'info',
message: message message: message
}); }, delayed);
}, },
showSuccess: function (message) { showSuccess: function (message, delayed) {
this.pushObject({ this.handleNotification({
type: 'success', type: 'success',
message: message message: message
}); }, delayed);
}, },
showWarn: function (message) { showWarn: function (message, delayed) {
this.pushObject({ this.handleNotification({
type: 'warn', type: 'warn',
message: message message: message
}, delayed);
},
displayDelayed: function () {
var self = this;
self.delayedNotifications.forEach(function (message) {
self.pushObject(message);
}); });
self.delayedNotifications = [];
}, },
closeAll: function () { closeAll: function () {
this.clear(); this.clear();