mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-23 22:11:09 +03:00
Merge pull request #3225 from jaswilli/issue-3160-2
Turn on update notifications for Ember admin
This commit is contained in:
commit
6186ecb590
@ -1,6 +1,31 @@
|
||||
var NotificationComponent = Ember.Component.extend({
|
||||
classNames: ['js-bb-notification'],
|
||||
|
||||
typeClass: function () {
|
||||
var classes = '',
|
||||
message = this.get('message'),
|
||||
type,
|
||||
dismissible;
|
||||
|
||||
// Check to see if we're working with a DS.Model or a plain JS object
|
||||
if (typeof message.toJSON === 'function') {
|
||||
type = message.get('type');
|
||||
dismissible = message.get('dismissible');
|
||||
}
|
||||
else {
|
||||
type = message.type;
|
||||
dismissible = message.dismissible;
|
||||
}
|
||||
|
||||
classes += 'notification-' + type;
|
||||
|
||||
if (type === 'success' && dismissible !== false) {
|
||||
classes += ' notification-passive';
|
||||
}
|
||||
|
||||
return classes;
|
||||
}.property(),
|
||||
|
||||
didInsertElement: function () {
|
||||
var self = this;
|
||||
|
||||
|
@ -1,7 +1,20 @@
|
||||
var NotificationsComponent = Ember.Component.extend({
|
||||
tagName: 'aside',
|
||||
classNames: 'notifications',
|
||||
messages: Ember.computed.alias('notifications')
|
||||
classNameBindings: ['location'],
|
||||
|
||||
messages: Ember.computed.filter('notifications', function (notification) {
|
||||
// If this instance of the notifications component has no location affinity
|
||||
// then it gets all notifications
|
||||
if (!this.get('location')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var displayLocation = (typeof notification.toJSON === 'function') ?
|
||||
notification.get('location') : notification.location;
|
||||
|
||||
return this.get('location') === displayLocation;
|
||||
})
|
||||
});
|
||||
|
||||
export default NotificationsComponent;
|
@ -3,11 +3,7 @@ var Notification = DS.Model.extend({
|
||||
location: DS.attr('string'),
|
||||
status: DS.attr('string'),
|
||||
type: DS.attr('string'),
|
||||
message: DS.attr('string'),
|
||||
|
||||
typeClass: function () {
|
||||
return 'notification-' + this.get('type');
|
||||
}.property('type')
|
||||
message: DS.attr('string')
|
||||
});
|
||||
|
||||
export default Notification;
|
||||
|
@ -3,7 +3,8 @@
|
||||
{{/unless}}
|
||||
|
||||
<main role="main" id="main">
|
||||
{{gh-notifications}}
|
||||
{{gh-notifications location="top"}}
|
||||
{{gh-notifications location="bottom"}}
|
||||
|
||||
{{outlet}}
|
||||
</main>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<section {{bind-attr class=":js-notification message.typeClass"}}>
|
||||
<section {{bind-attr class=":js-notification typeClass"}}>
|
||||
<span class="notification-message">
|
||||
{{{message.message}}}
|
||||
</span>
|
||||
|
@ -6,11 +6,23 @@ var Notifications = Ember.ArrayProxy.extend({
|
||||
timeout: 3000,
|
||||
|
||||
pushObject: function (object) {
|
||||
object.typeClass = 'notification-' + object.type;
|
||||
// This should be somewhere else.
|
||||
if (object.type === 'success') {
|
||||
object.typeClass = object.typeClass + ' notification-passive';
|
||||
// object can be either a DS.Model or a plain JS object, so when working with
|
||||
// it, we need to handle both cases.
|
||||
|
||||
// make sure notifications have all the necessary properties set.
|
||||
if (typeof object.toJSON === 'function') {
|
||||
// working with a DS.Model
|
||||
|
||||
if (object.get('location') === '') {
|
||||
object.set('location', 'bottom');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!object.location) {
|
||||
object.location = 'bottom';
|
||||
}
|
||||
}
|
||||
|
||||
this._super(object);
|
||||
},
|
||||
handleNotification: function (message, delayed) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
var config = require('../config'),
|
||||
path = require('path'),
|
||||
_ = require('lodash'),
|
||||
when = require('when'),
|
||||
api = require('../api'),
|
||||
errors = require('../errors'),
|
||||
storage = require('../storage'),
|
||||
updateCheck = require('../update-check'),
|
||||
@ -26,11 +28,29 @@ adminControllers = {
|
||||
});
|
||||
}
|
||||
|
||||
when.join(
|
||||
updateCheck(res),
|
||||
when(renderIndex())
|
||||
// an error here should just get logged
|
||||
).otherwise(errors.logError);
|
||||
updateCheck().then(function () {
|
||||
return updateCheck.showUpdateNotification();
|
||||
}).then(function (updateAvailable) {
|
||||
if (!updateAvailable) {
|
||||
return when.resolve();
|
||||
}
|
||||
|
||||
var notification = {
|
||||
type: 'success',
|
||||
location: 'top',
|
||||
dismissible: false,
|
||||
status: 'persistent',
|
||||
message: 'A new version of Ghost is available! Hot Damn. <a href="https://ghost.org/download">Upgrade now</a>'
|
||||
};
|
||||
|
||||
return api.notifications.browse().then(function (results) {
|
||||
if (!_.some(results.notifications, { message: notification.message })) {
|
||||
return api.notifications.add({ notifications: [notification] });
|
||||
}
|
||||
});
|
||||
}).finally(function () {
|
||||
renderIndex();
|
||||
}).catch(errors.logError);
|
||||
},
|
||||
// Route: upload
|
||||
// Path: /ghost/upload/
|
||||
|
@ -11,7 +11,6 @@ var downsize = require('downsize'),
|
||||
filters = require('../filters'),
|
||||
template = require('./template'),
|
||||
schema = require('../data/schema').checks,
|
||||
updateCheck = require('../update-check'),
|
||||
|
||||
assetTemplate = _.template('<%= source %>?v=<%= version %>'),
|
||||
linkTemplate = _.template('<a href="<%= url %>"><%= text %></a>'),
|
||||
@ -700,28 +699,6 @@ coreHelpers.admin_url = function (options) {
|
||||
return config.urlFor(context, absolute);
|
||||
};
|
||||
|
||||
coreHelpers.update_notification = function (options) {
|
||||
var output = '';
|
||||
|
||||
if (config().updateCheck === false || !this.currentUser) {
|
||||
return when(output);
|
||||
}
|
||||
|
||||
return updateCheck.showUpdateNotification().then(function (result) {
|
||||
if (result) {
|
||||
if (options && options.hash && options.hash.classOnly) {
|
||||
output = ' update-available';
|
||||
} else {
|
||||
output = '<div class="notification-success">' +
|
||||
'A new version of Ghost is available! Hot damn. ' +
|
||||
'<a href="http://ghost.org/download">Upgrade now</a></div>';
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
});
|
||||
};
|
||||
|
||||
// Register an async handlebars helper for a given handlebars instance
|
||||
function registerAsyncHelper(hbs, name, fn) {
|
||||
hbs.registerAsyncHelper(name, function (options, cb) {
|
||||
@ -750,12 +727,6 @@ function registerAdminHelper(name, fn) {
|
||||
coreHelpers.adminHbs.registerHelper(name, fn);
|
||||
}
|
||||
|
||||
// Register an async handlebars helper for admin
|
||||
function registerAsyncAdminHelper(name, fn) {
|
||||
registerAsyncHelper(coreHelpers.adminHbs, name, fn);
|
||||
}
|
||||
|
||||
|
||||
registerHelpers = function (adminHbs, assetHash) {
|
||||
|
||||
// Expose hbs instance for admin
|
||||
@ -811,10 +782,6 @@ registerHelpers = function (adminHbs, assetHash) {
|
||||
registerAdminHelper('ghost_script_tags', coreHelpers.ghost_script_tags);
|
||||
|
||||
registerAdminHelper('asset', coreHelpers.asset);
|
||||
|
||||
// TODO: Make sure this works #3160
|
||||
// we probably don't need this code for it, but it needs to work still
|
||||
registerAsyncAdminHelper('update_notification', coreHelpers.update_notification);
|
||||
};
|
||||
|
||||
module.exports = coreHelpers;
|
||||
|
@ -32,7 +32,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:400,300,700" />
|
||||
<link rel="stylesheet" href="{{asset "css/ghost-ui.min.css" ghost="true"}}" />
|
||||
</head>
|
||||
<body class="{{bodyClass}}{{update_notification classOnly="true"}}">
|
||||
<body class="{{bodyClass}}">
|
||||
|
||||
{{{ghost_script_tags}}}
|
||||
|
||||
|
@ -1498,81 +1498,6 @@ describe('Core Helpers', function () {
|
||||
rendered.should.equal('http://testurl.com/blog/');
|
||||
});
|
||||
});
|
||||
describe('updateNotification', function () {
|
||||
it('outputs a correctly formatted notification when db version is higher than pkg version', function (done) {
|
||||
var defaultOutput = '<div class="notification-success">' +
|
||||
'A new version of Ghost is available! Hot damn. ' +
|
||||
'<a href="http://ghost.org/download">Upgrade now</a></div>',
|
||||
classOutput = ' update-available';
|
||||
|
||||
apiStub.restore();
|
||||
apiStub = sandbox.stub(api.settings, 'read', function () {
|
||||
var futureversion = packageInfo.version.split('.');
|
||||
futureversion[futureversion.length - 1] = parseInt(futureversion[futureversion.length - 1], 10) + 1;
|
||||
return when({
|
||||
settings: [{value: futureversion.join('.')}]
|
||||
});
|
||||
});
|
||||
|
||||
helpers.update_notification.call({currentUser: {name: 'bob'}}).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
|
||||
rendered.should.equal(defaultOutput);
|
||||
|
||||
// Test classOnly option
|
||||
return helpers.update_notification.call({currentUser: {name: 'bob'}}, {'hash': {'classOnly': 'true'}});
|
||||
}).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
|
||||
rendered.should.equal(classOutput);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does NOT output a correctly formatted notification when db version equals pkg version', function (done) {
|
||||
apiStub.restore();
|
||||
apiStub = sandbox.stub(api.settings, 'read', function () {
|
||||
return when({ settings: [{value: packageInfo.version}] });
|
||||
});
|
||||
|
||||
helpers.update_notification.call({currentUser: {name: 'bob'}}).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.should.equal('');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does NOT output a notification if updateCheck is false', function (done) {
|
||||
helpers.__set__('config', function () { return { updateCheck: false}; });
|
||||
|
||||
apiStub.restore();
|
||||
apiStub = sandbox.stub(api.settings, 'read', function () {
|
||||
return when({ settings: [{value: 'true'}] });
|
||||
});
|
||||
|
||||
helpers.update_notification.call({currentUser: {name: 'bob'}}).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.should.equal('');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does NOT output a notification if the user is not logged in', function (done) {
|
||||
apiStub.restore();
|
||||
apiStub = sandbox.stub(api.settings, 'read', function () {
|
||||
var futureversion = packageInfo.version.split('.');
|
||||
futureversion[futureversion.length-1] = parseInt(futureversion[futureversion.length-1], 10) + 1;
|
||||
return when({ settings: [{value: futureversion.join('.')}] });
|
||||
});
|
||||
|
||||
helpers.update_notification.call().then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.should.equal('');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('file storage helper', function () {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user