0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

Notifications on front end

Should close #37. There are persistent and passive notifications.

Persistent ones:
* are stored on `ghost.notifications`.
* have an api made to add / remove them with client side ajax logic (probably not the most elegant, but works)
* uses a modified `flashes.hbs` template
* will only disappear if user closes the bar
* stack

Passive
* added with backbone view / collection combo
* stack
* disappears on navigation and when user closes it
This commit is contained in:
Gabor Javorszky 2013-06-27 04:52:56 +01:00 committed by ErisDS
parent dec4b23374
commit 6086f9e6f0
2 changed files with 144 additions and 12 deletions

View file

@ -38,10 +38,50 @@
$(window).one('centered', fadeInAndFocus);
// Allow notifications to be dismissed
$(document).on('click', '.js-notification .close', function () {
$(document).on('click', '.js-notification.notification-passive .close', function () {
$(this).parent().fadeOut(200, function () { $(this).remove(); });
});
$(document).on('click', '.js-notification.notification-persistent .close', function () {
var self = this;
$.ajax({
type: "DELETE",
url: '/api/v0.1/notifications/' + $(this).data('id')
}).done(function (result) {
if ($(self).parent().parent().hasClass('js-bb-notification')) {
$(self).parent().parent().fadeOut(200, function () { $(self).remove(); });
} else {
$(self).parent().fadeOut(200, function () { $(self).remove(); });
}
});
});
/**
* Example of how to add a persistent notification.
*/
// $(document).on('click', '.add-persistent-notification', function (event) {
// event.preventDefault();
// var msg = {
// type: 'error',
// message: 'This is an error',
// status: 'persistent',
// id: 'per-' + $('.notification-persistent').length + 1
// };
// $.ajax({
// type: "POST",
// url: '/api/v0.1/notifications/',
// data: msg
// }).done(function (result) {
// var fcv;
// fcv = new Ghost.Views.FlashCollectionView({
// model: [msg]
// });
// console.log(fcv);
// });
// });
$(document).ready(function () {
// ## Set interactions for all menus
@ -79,4 +119,4 @@
});
}());
}());

View file

@ -1,6 +1,6 @@
// # Article Editor
/*global window, document, $, _, Backbone, Ghost, Showdown, CodeMirror, shortcut, Countable */
/*global window, document, $, _, Backbone, Ghost, Showdown, CodeMirror, shortcut, Countable, JST */
(function () {
"use strict";
@ -93,26 +93,55 @@
this.savePost({
status: keys[newIndex]
}).then(function () {
window.alert('Your post: ' + model.get('title') + ' has been ' + keys[newIndex]);
this.addSubview(new Ghost.Views.FlashCollectionView({
model: [{
type: 'success',
message: 'Your post: ' + model.get('title') + ' has been ' + keys[newIndex],
status: 'passive'
}]
}));
// window.alert('Your post: ' + model.get('title') + ' has been ' + keys[newIndex]);
});
},
handleStatus: function (e) {
e.preventDefault();
var status = $(e.currentTarget).attr('data-set-status'),
model = this.model;
model = this.model,
self = this;
if (status === 'publish-on') {
return window.alert('Scheduled publishing not supported yet.');
this.addSubview(new Ghost.Views.FlashCollectionView({
model: [{
type: 'alert',
message: 'Scheduled publishing not supported yet.',
status: 'passive'
}]
}));
// return window.alert('Scheduled publishing not supported yet.');
}
if (status === 'queue') {
return window.alert('Scheduled publishing not supported yet.');
this.addSubview(new Ghost.Views.FlashCollectionView({
model: [{
type: 'alert',
message: 'Scheduled publishing not supported yet.',
status: 'passive'
}]
}));
// return window.alert('Scheduled publishing not supported yet.');
}
this.savePost({
status: status
}).then(function () {
window.alert('Your post: ' + model.get('title') + ' has been ' + status);
self.addSubview(new Ghost.Views.FlashCollectionView({
model: [{
type: 'success',
message: 'Your post: ' + model.get('title') + ' has been ' + status,
status: 'passive'
}]
}));
// window.alert('Your post: ' + model.get('title') + ' has been ' + status);
});
},
@ -120,11 +149,26 @@
if (e) {
e.preventDefault();
}
var model = this.model;
var model = this.model,
self = this;
this.savePost().then(function () {
window.alert('Your post was saved as ' + model.get('status'));
self.addSubview(new Ghost.Views.FlashCollectionView({
model: [{
type: 'success',
message: 'Your post was saved as ' + model.get('status'),
status: 'passive'
}]
}));
// window.alert('Your post was saved as ' + model.get('status'));
}, function () {
window.alert(model.validationError);
self.addSubview(new Ghost.Views.FlashCollectionView({
model: [{
type: 'error',
message: model.validationError,
status: 'passive'
}]
}));
// window.alert(model.validationError);
});
},
@ -254,4 +298,52 @@
}
});
}());
/**
* This is the view to generate the markup for the individual
* notification. Will be included into #flashbar.
*
* States can be
* - persistent
* - passive
*
* Types can be
* - error
* - success
* - alert
* - (empty)
*
*/
Ghost.Views.FlashView = Ghost.View.extend({
templateName: 'notification',
className: 'js-bb-notification',
template: function (data) {
return JST[this.templateName](data);
},
render: function() {
var html = this.template(this.model);
this.$el.html(html);
return this;
}
});
/**
* This handles Notification groups
*/
Ghost.Views.FlashCollectionView = Ghost.View.extend({
el: '#flashbar',
initialize: function() {
this.render();
},
render: function() {
_.each(this.model, function (item) {
this.renderItem(item);
}, this);
},
renderItem: function (item) {
var itemView = new Ghost.Views.FlashView({ model: item });
this.$el.prepend(itemView.render().el);
}
});
}());