mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Use Ember.inject instead of needs and initializers
No Issue - Switches to the newer style of dependency injection. - Instead of injection Controllers via "needs," use Ember.inject.controller(). - Get rid of initializers that were only injecting objects into various factories. Converts these objects into Ember.Service objects and declaratively inject them where needed via Ember.inject.service(). The added benefit to this is that it's no longer a mystery where these properties/methods come from and it's straightforward to inject them where needed.
This commit is contained in:
parent
3ece83f68d
commit
c3ad1ae9e2
61 changed files with 377 additions and 483 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -60,6 +60,7 @@ CHANGELOG.md
|
|||
|
||||
config.js
|
||||
/core/client/config.js
|
||||
!/core/client/app/services/config.js
|
||||
|
||||
# Built asset files
|
||||
/core/built
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
var AlertComponent = Ember.Component.extend({
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'article',
|
||||
classNames: ['gh-alert', 'gh-alert-blue'],
|
||||
classNameBindings: ['typeClass'],
|
||||
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
typeClass: Ember.computed(function () {
|
||||
var classes = '',
|
||||
message = this.get('message'),
|
||||
|
@ -31,10 +33,7 @@ var AlertComponent = Ember.Component.extend({
|
|||
|
||||
actions: {
|
||||
closeNotification: function () {
|
||||
var self = this;
|
||||
self.notifications.closeNotification(self.get('message'));
|
||||
this.get('notifications').closeNotification(this.get('message'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default AlertComponent;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
var blogUrl = Ember.Component.extend({
|
||||
tagName: ''
|
||||
tagName: '',
|
||||
config: Ember.inject.service()
|
||||
});
|
||||
|
||||
export default blogUrl;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
import DropdownMixin from 'ghost/mixins/dropdown-mixin';
|
||||
|
||||
var DropdownButton = Ember.Component.extend(DropdownMixin, {
|
||||
export default Ember.Component.extend(DropdownMixin, {
|
||||
tagName: 'button',
|
||||
attributeBindings: 'role',
|
||||
role: 'button',
|
||||
|
@ -9,11 +9,11 @@ var DropdownButton = Ember.Component.extend(DropdownMixin, {
|
|||
// matches with the dropdown this button toggles
|
||||
dropdownName: null,
|
||||
|
||||
dropdown: Ember.inject.service(),
|
||||
|
||||
// Notify dropdown service this dropdown should be toggled
|
||||
click: function (event) {
|
||||
this._super(event);
|
||||
this.get('dropdown').toggleDropdown(this.get('dropdownName'), this);
|
||||
}
|
||||
});
|
||||
|
||||
export default DropdownButton;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import Ember from 'ember';
|
||||
import DropdownMixin from 'ghost/mixins/dropdown-mixin';
|
||||
|
||||
var GhostDropdown = Ember.Component.extend(DropdownMixin, {
|
||||
export default Ember.Component.extend(DropdownMixin, {
|
||||
classNames: 'ghost-dropdown',
|
||||
classNameBindings: ['fadeIn:fade-in-scale:fade-out', 'isOpen:open:closed'],
|
||||
|
||||
name: null,
|
||||
closeOnClick: false,
|
||||
|
||||
|
@ -17,7 +19,7 @@ var GhostDropdown = Ember.Component.extend(DropdownMixin, {
|
|||
return this.get('isOpen') && !this.get('closing');
|
||||
}),
|
||||
|
||||
classNameBindings: ['fadeIn:fade-in-scale:fade-out', 'isOpen:open:closed'],
|
||||
dropdown: Ember.inject.service(),
|
||||
|
||||
open: function () {
|
||||
this.set('isOpen', true);
|
||||
|
@ -88,5 +90,3 @@ var GhostDropdown = Ember.Component.extend(DropdownMixin, {
|
|||
dropdownService.off('toggle', this, this.toggle);
|
||||
}
|
||||
});
|
||||
|
||||
export default GhostDropdown;
|
||||
|
|
|
@ -2,6 +2,8 @@ import Ember from 'ember';
|
|||
import uploader from 'ghost/assets/lib/uploader';
|
||||
|
||||
var Preview = Ember.Component.extend({
|
||||
config: Ember.inject.service(),
|
||||
|
||||
didInsertElement: function () {
|
||||
this.set('scrollWrapper', this.$().closest('.entry-preview-content'));
|
||||
Ember.run.scheduleOnce('afterRender', this, this.dropzoneHandler);
|
||||
|
|
|
@ -5,6 +5,8 @@ export default Ember.Component.extend({
|
|||
classNames: ['gh-nav'],
|
||||
classNameBindings: ['open'],
|
||||
|
||||
config: Ember.inject.service(),
|
||||
|
||||
open: false,
|
||||
|
||||
autoNav: null,
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
var NotificationComponent = Ember.Component.extend({
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'article',
|
||||
classNames: ['gh-notification', 'gh-notification-green'],
|
||||
classNameBindings: ['typeClass'],
|
||||
|
||||
message: null,
|
||||
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
typeClass: Ember.computed(function () {
|
||||
var classes = '',
|
||||
message = this.get('message'),
|
||||
|
@ -34,17 +38,14 @@ var NotificationComponent = Ember.Component.extend({
|
|||
|
||||
self.$().on('animationend webkitAnimationEnd oanimationend MSAnimationEnd', function (event) {
|
||||
if (event.originalEvent.animationName === 'fade-out') {
|
||||
self.notifications.removeObject(self.get('message'));
|
||||
self.get('notifications').removeObject(self.get('message'));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
closeNotification: function () {
|
||||
var self = this;
|
||||
self.notifications.closeNotification(self.get('message'));
|
||||
this.get('notifications').closeNotification(this.get('message'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default NotificationComponent;
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import Ember from 'ember';
|
||||
var NotificationsComponent = Ember.Component.extend({
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'aside',
|
||||
classNames: 'gh-notifications',
|
||||
|
||||
messages: Ember.computed.filter('notifications', function (notification) {
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
messages: Ember.computed.filter('notifications.content', function (notification) {
|
||||
var displayStatus = (typeof notification.toJSON === 'function') ?
|
||||
notification.get('status') : notification.status;
|
||||
|
||||
return displayStatus === 'passive';
|
||||
})
|
||||
});
|
||||
|
||||
export default NotificationsComponent;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import Ember from 'ember';
|
||||
import DropdownButton from 'ghost/components/gh-dropdown-button';
|
||||
|
||||
var PopoverButton = DropdownButton.extend({
|
||||
click: Ember.K, // We don't want clicks on popovers, but dropdowns have them. So `K`ill them here.
|
||||
export default DropdownButton.extend({
|
||||
dropdown: Ember.inject.service(),
|
||||
|
||||
click: Ember.K,
|
||||
|
||||
mouseEnter: function (event) {
|
||||
this._super(event);
|
||||
|
@ -14,5 +16,3 @@ var PopoverButton = DropdownButton.extend({
|
|||
this.get('dropdown').toggleDropdown(this.get('popoverName'), this);
|
||||
}
|
||||
});
|
||||
|
||||
export default PopoverButton;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
import GhostDropdown from 'ghost/components/gh-dropdown';
|
||||
|
||||
var GhostPopover = GhostDropdown.extend({
|
||||
classNames: 'ghost-popover'
|
||||
export default GhostDropdown.extend({
|
||||
classNames: 'ghost-popover',
|
||||
dropdown: Ember.inject.service()
|
||||
});
|
||||
|
||||
export default GhostPopover;
|
||||
|
|
|
@ -6,6 +6,8 @@ import cajaSanitizers from 'ghost/utils/caja-sanitizers';
|
|||
var UploadModal = ModalDialog.extend({
|
||||
layoutName: 'components/gh-modal-dialog',
|
||||
|
||||
config: Ember.inject.service(),
|
||||
|
||||
didInsertElement: function () {
|
||||
this._super();
|
||||
upload.call(this.$('.js-drop-zone'), {fileStorage: this.get('config.fileStorage')});
|
||||
|
|
|
@ -4,6 +4,8 @@ import uploader from 'ghost/assets/lib/uploader';
|
|||
var PostImageUploader = Ember.Component.extend({
|
||||
classNames: ['image-uploader', 'js-post-image-upload'],
|
||||
|
||||
config: Ember.inject.service(),
|
||||
|
||||
imageSource: Ember.computed('image', function () {
|
||||
return this.get('image') || '';
|
||||
}),
|
||||
|
|
|
@ -8,9 +8,11 @@ var urlPreview = Ember.Component.extend({
|
|||
prefix: null,
|
||||
slug: null,
|
||||
|
||||
config: Ember.inject.service(),
|
||||
|
||||
url: Ember.computed('slug', function () {
|
||||
// Get the blog URL and strip the scheme
|
||||
var blogUrl = this.get('config').blogUrl,
|
||||
var blogUrl = this.get('config.blogUrl'),
|
||||
noSchemeBlogUrl = blogUrl.substr(blogUrl.indexOf('://') + 3), // Remove `http[s]://`
|
||||
|
||||
// Get the prefix and slug values
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
dropdown: Ember.inject.service(),
|
||||
|
||||
// jscs: disable
|
||||
signedOut: Ember.computed.match('currentPath', /(signin|signup|setup|reset)/),
|
||||
// jscs: enable
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import Ember from 'ember';
|
||||
var CopyHTMLController = Ember.Controller.extend({
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
generatedHTML: Ember.computed.alias('model.generatedHTML')
|
||||
|
||||
});
|
||||
|
||||
export default CopyHTMLController;
|
||||
|
|
|
@ -2,6 +2,9 @@ import Ember from 'ember';
|
|||
import {request as ajax} from 'ic-ajax';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
actions: {
|
||||
confirmAccept: function () {
|
||||
var self = this;
|
||||
|
@ -9,11 +12,11 @@ export default Ember.Controller.extend({
|
|||
ajax(this.get('ghostPaths.url').api('db'), {
|
||||
type: 'DELETE'
|
||||
}).then(function () {
|
||||
self.notifications.showSuccess('All content deleted from database.');
|
||||
self.get('notifications').showSuccess('All content deleted from database.');
|
||||
self.store.unloadAll('post');
|
||||
self.store.unloadAll('tag');
|
||||
}).catch(function (response) {
|
||||
self.notifications.showErrors(response);
|
||||
self.get('notifications').showErrors(response);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import Ember from 'ember';
|
||||
var DeletePostController = Ember.Controller.extend({
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
dropdown: Ember.inject.service(),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
actions: {
|
||||
confirmAccept: function () {
|
||||
var self = this,
|
||||
|
@ -11,9 +15,9 @@ var DeletePostController = Ember.Controller.extend({
|
|||
model.destroyRecord().then(function () {
|
||||
self.get('dropdown').closeDropdowns();
|
||||
self.transitionToRoute('posts.index');
|
||||
self.notifications.showSuccess('Your post has been deleted.', {delayed: true});
|
||||
self.get('notifications').showSuccess('Your post has been deleted.', {delayed: true});
|
||||
}, function () {
|
||||
self.notifications.showError('Your post could not be deleted. Please try again.');
|
||||
self.get('notifications').showError('Your post could not be deleted. Please try again.');
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -33,5 +37,3 @@ var DeletePostController = Ember.Controller.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default DeletePostController;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import Ember from 'ember';
|
||||
var DeleteTagController = Ember.Controller.extend({
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
postInflection: Ember.computed('model.post_count', function () {
|
||||
return this.get('model.post_count') > 1 ? 'posts' : 'post';
|
||||
}),
|
||||
|
@ -13,9 +16,9 @@ var DeleteTagController = Ember.Controller.extend({
|
|||
this.send('closeSettingsMenu');
|
||||
|
||||
tag.destroyRecord().then(function () {
|
||||
self.notifications.showSuccess('Deleted ' + name);
|
||||
self.get('notifications').showSuccess('Deleted ' + name);
|
||||
}).catch(function (error) {
|
||||
self.notifications.showAPIError(error);
|
||||
self.get('notifications').showAPIError(error);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -35,5 +38,3 @@ var DeleteTagController = Ember.Controller.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default DeleteTagController;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import Ember from 'ember';
|
||||
var DeleteUserController = Ember.Controller.extend({
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
userPostCount: Ember.computed('model.id', function () {
|
||||
var promise,
|
||||
query = {
|
||||
|
@ -28,9 +31,9 @@ var DeleteUserController = Ember.Controller.extend({
|
|||
user.destroyRecord().then(function () {
|
||||
self.store.unloadAll('post');
|
||||
self.transitionToRoute('settings.users');
|
||||
self.notifications.showSuccess('The user has been deleted.', {delayed: true});
|
||||
self.get('notifications').showSuccess('The user has been deleted.', {delayed: true});
|
||||
}, function () {
|
||||
self.notifications.showError('The user could not be deleted. Please try again.');
|
||||
self.get('notifications').showError('The user could not be deleted. Please try again.');
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -50,5 +53,3 @@ var DeleteUserController = Ember.Controller.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default DeleteUserController;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import Ember from 'ember';
|
||||
var InviteNewUserController = Ember.Controller.extend({
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
// Used to set the initial value for the dropdown
|
||||
authorRole: Ember.computed(function () {
|
||||
var self = this;
|
||||
|
@ -45,9 +48,9 @@ var InviteNewUserController = Ember.Controller.extend({
|
|||
|
||||
if (invitedUser) {
|
||||
if (invitedUser.get('status') === 'invited' || invitedUser.get('status') === 'invited-pending') {
|
||||
self.notifications.showWarn('A user with that email address was already invited.');
|
||||
self.get('notifications').showWarn('A user with that email address was already invited.');
|
||||
} else {
|
||||
self.notifications.showWarn('A user with that email address already exists.');
|
||||
self.get('notifications').showWarn('A user with that email address already exists.');
|
||||
}
|
||||
} else {
|
||||
newUser = self.store.createRecord('user', {
|
||||
|
@ -62,13 +65,13 @@ var InviteNewUserController = Ember.Controller.extend({
|
|||
// If sending the invitation email fails, the API will still return a status of 201
|
||||
// but the user's status in the response object will be 'invited-pending'.
|
||||
if (newUser.get('status') === 'invited-pending') {
|
||||
self.notifications.showWarn('Invitation email was not sent. Please try resending.');
|
||||
self.get('notifications').showWarn('Invitation email was not sent. Please try resending.');
|
||||
} else {
|
||||
self.notifications.showSuccess(notificationText);
|
||||
self.get('notifications').showSuccess(notificationText);
|
||||
}
|
||||
}).catch(function (errors) {
|
||||
newUser.deleteRecord();
|
||||
self.notifications.showErrors(errors);
|
||||
self.get('notifications').showErrors(errors);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -79,5 +82,3 @@ var InviteNewUserController = Ember.Controller.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default InviteNewUserController;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import Ember from 'ember';
|
||||
var LeaveEditorController = Ember.Controller.extend({
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
args: Ember.computed.alias('model'),
|
||||
|
||||
actions: {
|
||||
|
@ -16,7 +19,7 @@ var LeaveEditorController = Ember.Controller.extend({
|
|||
}
|
||||
|
||||
if (!transition || !editorController) {
|
||||
this.notifications.showError('Sorry, there was an error in the application. Please let the Ghost team know what happened.');
|
||||
this.get('notifications').showError('Sorry, there was an error in the application. Please let the Ghost team know what happened.');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -56,5 +59,3 @@ var LeaveEditorController = Ember.Controller.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default LeaveEditorController;
|
||||
|
|
|
@ -2,17 +2,18 @@ import Ember from 'ember';
|
|||
import ValidationEngine from 'ghost/mixins/validation-engine';
|
||||
|
||||
export default Ember.Controller.extend(ValidationEngine, {
|
||||
needs: 'application',
|
||||
|
||||
validationType: 'signin',
|
||||
|
||||
application: Ember.inject.controller(),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
identification: Ember.computed('session.user.email', function () {
|
||||
return this.get('session.user.email');
|
||||
}),
|
||||
|
||||
actions: {
|
||||
authenticate: function () {
|
||||
var appController = this.get('controllers.application'),
|
||||
var appController = this.get('application'),
|
||||
authStrategy = 'simple-auth-authenticator:oauth2-password-grant',
|
||||
data = this.getProperties('identification', 'password'),
|
||||
self = this;
|
||||
|
@ -21,7 +22,7 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
|
||||
this.get('session').authenticate(authStrategy, data).then(function () {
|
||||
self.send('closeModal');
|
||||
self.notifications.showSuccess('Login successful.');
|
||||
self.get('notifications').showSuccess('Login successful.');
|
||||
self.set('password', '');
|
||||
}).catch(function () {
|
||||
// if authentication fails a rejected promise will be returned.
|
||||
|
@ -40,10 +41,10 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
$('#login').find('input').trigger('change');
|
||||
|
||||
this.validate({format: false}).then(function () {
|
||||
self.notifications.closePassive();
|
||||
self.get('notifications').closePassive();
|
||||
self.send('authenticate');
|
||||
}).catch(function (errors) {
|
||||
self.notifications.showErrors(errors);
|
||||
self.get('notifications').showErrors(errors);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@ import Ember from 'ember';
|
|||
import {request as ajax} from 'ic-ajax';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
dropdown: Ember.inject.service(),
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
actions: {
|
||||
confirmAccept: function () {
|
||||
var user = this.get('model'),
|
||||
|
@ -29,9 +33,9 @@ export default Ember.Controller.extend({
|
|||
});
|
||||
}
|
||||
|
||||
self.notifications.showSuccess('Ownership successfully transferred to ' + user.get('name'));
|
||||
self.get('notifications').showSuccess('Ownership successfully transferred to ' + user.get('name'));
|
||||
}).catch(function (error) {
|
||||
self.notifications.showAPIError(error);
|
||||
self.get('notifications').showAPIError(error);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
var UploadController = Ember.Controller.extend({
|
||||
export default Ember.Controller.extend({
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
acceptEncoding: 'image/*',
|
||||
|
||||
actions: {
|
||||
confirmAccept: function () {
|
||||
var self = this;
|
||||
var notifications = this.get('notifications');
|
||||
|
||||
this.get('model').save().then(function (model) {
|
||||
self.notifications.showSuccess('Saved');
|
||||
notifications.showSuccess('Saved');
|
||||
|
||||
return model;
|
||||
}).catch(function (err) {
|
||||
self.notifications.showErrors(err);
|
||||
notifications.showErrors(err);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -19,5 +23,3 @@ var UploadController = Ember.Controller.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default UploadController;
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
import Ember from 'ember';
|
||||
/* global moment */
|
||||
|
||||
import Ember from 'ember';
|
||||
import {parseDateString, formatDate} from 'ghost/utils/date-formatting';
|
||||
import SettingsMenuMixin from 'ghost/mixins/settings-menu-controller';
|
||||
import SlugGenerator from 'ghost/models/slug-generator';
|
||||
import boundOneWay from 'ghost/utils/bound-one-way';
|
||||
import isNumber from 'ghost/utils/isNumber';
|
||||
|
||||
var PostSettingsMenuController = Ember.Controller.extend(SettingsMenuMixin, {
|
||||
export default Ember.Controller.extend(SettingsMenuMixin, {
|
||||
debounceId: null,
|
||||
lastPromise: null,
|
||||
selectedAuthor: null,
|
||||
uploaderReference: null,
|
||||
|
||||
application: Ember.inject.controller(),
|
||||
config: Ember.inject.service(),
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
initializeSelectedAuthor: function () {
|
||||
var self = this;
|
||||
|
@ -212,11 +216,11 @@ var PostSettingsMenuController = Ember.Controller.extend(SettingsMenuMixin, {
|
|||
|
||||
showErrors: function (errors) {
|
||||
errors = Ember.isArray(errors) ? errors : [errors];
|
||||
this.notifications.showErrors(errors);
|
||||
this.get('notifications').showErrors(errors);
|
||||
},
|
||||
|
||||
showSuccess: function (message) {
|
||||
this.notifications.showSuccess(message);
|
||||
this.get('notifications').showSuccess(message);
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
@ -465,5 +469,3 @@ var PostSettingsMenuController = Ember.Controller.extend(SettingsMenuMixin, {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default PostSettingsMenuController;
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
import Ember from 'ember';
|
||||
var PostController = Ember.Controller.extend({
|
||||
isPublished: Ember.computed.equal('model.status', 'published'),
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
classNameBindings: ['model.featured'],
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
isPublished: Ember.computed.equal('model.status', 'published'),
|
||||
|
||||
authorName: Ember.computed('model.author.name', 'model.author.email', function () {
|
||||
return this.get('model.author.name') || this.get('model.author.email');
|
||||
}),
|
||||
|
@ -17,17 +22,16 @@ var PostController = Ember.Controller.extend({
|
|||
|
||||
actions: {
|
||||
toggleFeatured: function () {
|
||||
var self = this;
|
||||
var notifications = this.get('notifications');
|
||||
|
||||
this.toggleProperty('model.featured');
|
||||
this.get('model').save().catch(function (errors) {
|
||||
self.notifications.showErrors(errors);
|
||||
notifications.showErrors(errors);
|
||||
});
|
||||
},
|
||||
|
||||
showPostContent: function () {
|
||||
this.transitionToRoute('posts.post', this.get('model'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default PostController;
|
||||
|
|
|
@ -10,6 +10,9 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
|
||||
validationType: 'reset',
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
email: Ember.computed('token', function () {
|
||||
// The token base64 encodes the email (and some other stuff),
|
||||
// each section is divided by a '|'. Email comes second.
|
||||
|
@ -40,18 +43,18 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
}
|
||||
}).then(function (resp) {
|
||||
self.toggleProperty('submitting');
|
||||
self.notifications.showSuccess(resp.passwordreset[0].message, true);
|
||||
self.get('notifications').showSuccess(resp.passwordreset[0].message, true);
|
||||
self.get('session').authenticate('simple-auth-authenticator:oauth2-password-grant', {
|
||||
identification: self.get('email'),
|
||||
password: credentials.newPassword
|
||||
});
|
||||
}).catch(function (response) {
|
||||
self.notifications.showAPIError(response);
|
||||
self.get('notifications').showAPIError(response);
|
||||
self.toggleProperty('submitting');
|
||||
});
|
||||
}).catch(function (error) {
|
||||
self.toggleProperty('submitting');
|
||||
self.notifications.showErrors(error);
|
||||
self.get('notifications').showErrors(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
import Ember from 'ember';
|
||||
var SettingsCodeInjectionController = Ember.Controller.extend({
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
actions: {
|
||||
save: function () {
|
||||
var self = this;
|
||||
var notifications = this.get('notifications');
|
||||
|
||||
return this.get('model').save().then(function (model) {
|
||||
self.notifications.closePassive();
|
||||
self.notifications.showSuccess('Settings successfully saved.');
|
||||
notifications.closePassive();
|
||||
notifications.showSuccess('Settings successfully saved.');
|
||||
|
||||
return model;
|
||||
}).catch(function (errors) {
|
||||
self.notifications.closePassive();
|
||||
self.notifications.showErrors(errors);
|
||||
notifications.closePassive();
|
||||
notifications.showErrors(errors);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default SettingsCodeInjectionController;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import Ember from 'ember';
|
||||
import randomPassword from 'ghost/utils/random-password';
|
||||
|
||||
var SettingsGeneralController = Ember.Controller.extend({
|
||||
export default Ember.Controller.extend({
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
selectedTheme: null,
|
||||
|
||||
logoImageSource: Ember.computed('model.logo', function () {
|
||||
|
@ -47,14 +49,14 @@ var SettingsGeneralController = Ember.Controller.extend({
|
|||
|
||||
actions: {
|
||||
save: function () {
|
||||
var self = this;
|
||||
var notifications = this.get('notifications');
|
||||
|
||||
return this.get('model').save().then(function (model) {
|
||||
self.notifications.showSuccess('Settings successfully saved.');
|
||||
notifications.showSuccess('Settings successfully saved.');
|
||||
|
||||
return model;
|
||||
}).catch(function (errors) {
|
||||
self.notifications.showErrors(errors);
|
||||
notifications.showErrors(errors);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -67,5 +69,3 @@ var SettingsGeneralController = Ember.Controller.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default SettingsGeneralController;
|
||||
|
|
|
@ -2,10 +2,12 @@ import Ember from 'ember';
|
|||
import {request as ajax} from 'ic-ajax';
|
||||
|
||||
export default Ember.Controller.extend(Ember.Evented, {
|
||||
needs: ['feature'],
|
||||
|
||||
uploadButtonText: 'Import',
|
||||
importErrors: '',
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
labsJSON: Ember.computed('model.labs', function () {
|
||||
return JSON.parse(this.get('model.labs') || {});
|
||||
}),
|
||||
|
@ -28,11 +30,12 @@ export default Ember.Controller.extend(Ember.Evented, {
|
|||
actions: {
|
||||
onUpload: function (file) {
|
||||
var self = this,
|
||||
formData = new FormData();
|
||||
formData = new FormData(),
|
||||
notifications = this.get('notifications');
|
||||
|
||||
this.set('uploadButtonText', 'Importing');
|
||||
this.set('importErrors', '');
|
||||
this.notifications.closePassive();
|
||||
notifications.closePassive();
|
||||
|
||||
formData.append('importfile', file);
|
||||
|
||||
|
@ -51,13 +54,13 @@ export default Ember.Controller.extend(Ember.Evented, {
|
|||
self.store.unloadAll('role');
|
||||
self.store.unloadAll('setting');
|
||||
self.store.unloadAll('notification');
|
||||
self.notifications.showSuccess('Import successful.');
|
||||
notifications.showSuccess('Import successful.');
|
||||
}).catch(function (response) {
|
||||
if (response && response.jqXHR && response.jqXHR.responseJSON && response.jqXHR.responseJSON.errors) {
|
||||
self.set('importErrors', response.jqXHR.responseJSON.errors);
|
||||
}
|
||||
|
||||
self.notifications.showError('Import Failed');
|
||||
notifications.showError('Import Failed');
|
||||
}).finally(function () {
|
||||
self.set('uploadButtonText', 'Import');
|
||||
self.trigger('reset');
|
||||
|
@ -77,17 +80,17 @@ export default Ember.Controller.extend(Ember.Evented, {
|
|||
},
|
||||
|
||||
sendTestEmail: function () {
|
||||
var self = this;
|
||||
var notifications = this.get('notifications');
|
||||
|
||||
ajax(this.get('ghostPaths.url').api('mail', 'test'), {
|
||||
type: 'POST'
|
||||
}).then(function () {
|
||||
self.notifications.showSuccess('Check your email for the test message.');
|
||||
notifications.showSuccess('Check your email for the test message.');
|
||||
}).catch(function (error) {
|
||||
if (typeof error.jqXHR !== 'undefined') {
|
||||
self.notifications.showAPIError(error);
|
||||
notifications.showAPIError(error);
|
||||
} else {
|
||||
self.notifications.showErrors(error);
|
||||
notifications.showErrors(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import Ember from 'ember';
|
||||
var NavigationController,
|
||||
NavItem;
|
||||
|
||||
NavItem = Ember.Object.extend({
|
||||
var NavItem = Ember.Object.extend({
|
||||
label: '',
|
||||
url: '',
|
||||
last: false,
|
||||
|
@ -12,7 +10,10 @@ NavItem = Ember.Object.extend({
|
|||
})
|
||||
});
|
||||
|
||||
NavigationController = Ember.Controller.extend({
|
||||
export default Ember.Controller.extend({
|
||||
config: Ember.inject.service(),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
blogUrl: Ember.computed('config.blogUrl', function () {
|
||||
var url = this.get('config.blogUrl');
|
||||
|
||||
|
@ -96,18 +97,18 @@ NavigationController = Ember.Controller.extend({
|
|||
},
|
||||
|
||||
save: function () {
|
||||
var self = this,
|
||||
navSetting,
|
||||
var navSetting,
|
||||
blogUrl = this.get('config').blogUrl,
|
||||
blogUrlRegex = new RegExp('^' + blogUrl + '(.*)', 'i'),
|
||||
navItems = this.get('navigationItems'),
|
||||
message = 'One of your navigation items has an empty label. ' +
|
||||
'<br /> Please enter a new label or delete the item before saving.',
|
||||
match;
|
||||
match,
|
||||
notifications = this.get('notifications');
|
||||
|
||||
// Don't save if there's a blank label.
|
||||
if (navItems.find(function (item) { return !item.get('isComplete') && !item.get('last');})) {
|
||||
self.notifications.showErrors([message.htmlSafe()]);
|
||||
if (navItems.find(function (item) {return !item.get('isComplete') && !item.get('last');})) {
|
||||
notifications.showErrors([message.htmlSafe()]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -147,15 +148,13 @@ NavigationController = Ember.Controller.extend({
|
|||
// we need to have navigationItems recomputed.
|
||||
this.get('model').notifyPropertyChange('navigation');
|
||||
|
||||
this.notifications.closePassive();
|
||||
notifications.closePassive();
|
||||
|
||||
this.get('model').save().then(function () {
|
||||
self.notifications.showSuccess('Navigation items saved.');
|
||||
notifications.showSuccess('Navigation items saved.');
|
||||
}).catch(function (err) {
|
||||
self.notifications.showErrors(err);
|
||||
notifications.showErrors(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default NavigationController;
|
||||
|
|
|
@ -3,7 +3,7 @@ import PaginationMixin from 'ghost/mixins/pagination-controller';
|
|||
import SettingsMenuMixin from 'ghost/mixins/settings-menu-controller';
|
||||
import boundOneWay from 'ghost/utils/bound-one-way';
|
||||
|
||||
var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuMixin, {
|
||||
export default Ember.ArrayController.extend(PaginationMixin, SettingsMenuMixin, {
|
||||
tags: Ember.computed.alias('model'),
|
||||
|
||||
activeTag: null,
|
||||
|
@ -20,10 +20,12 @@ var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuM
|
|||
},
|
||||
|
||||
application: Ember.inject.controller(),
|
||||
config: Ember.inject.service(),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
showErrors: function (errors) {
|
||||
errors = Ember.isArray(errors) ? errors : [errors];
|
||||
this.notifications.showErrors(errors);
|
||||
this.get('notifications').showErrors(errors);
|
||||
},
|
||||
|
||||
saveActiveTagProperty: function (propKey, newValue) {
|
||||
|
@ -40,7 +42,7 @@ var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuM
|
|||
|
||||
activeTag.set(propKey, newValue);
|
||||
|
||||
this.notifications.closePassive();
|
||||
this.get('notifications').closePassive();
|
||||
|
||||
activeTag.save().catch(function (errors) {
|
||||
self.showErrors(errors);
|
||||
|
@ -62,7 +64,7 @@ var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuM
|
|||
}),
|
||||
|
||||
seoURL: Ember.computed('activeTagSlugScratch', function () {
|
||||
var blogUrl = this.get('config').blogUrl,
|
||||
var blogUrl = this.get('config.blogUrl'),
|
||||
seoSlug = this.get('activeTagSlugScratch') ? this.get('activeTagSlugScratch') : '',
|
||||
seoURL = blogUrl + '/tag/' + seoSlug;
|
||||
|
||||
|
@ -137,5 +139,3 @@ var TagsController = Ember.ArrayController.extend(PaginationMixin, SettingsMenuM
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default TagsController;
|
||||
|
|
|
@ -3,7 +3,9 @@ import SlugGenerator from 'ghost/models/slug-generator';
|
|||
import isNumber from 'ghost/utils/isNumber';
|
||||
import boundOneWay from 'ghost/utils/bound-one-way';
|
||||
|
||||
var SettingsUserController = Ember.Controller.extend({
|
||||
export default Ember.Controller.extend({
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
user: Ember.computed.alias('model'),
|
||||
|
||||
|
@ -16,8 +18,10 @@ var SettingsUserController = Ember.Controller.extend({
|
|||
coverDefault: Ember.computed('ghostPaths', function () {
|
||||
return this.get('ghostPaths.url').asset('/shared/img/user-cover.png');
|
||||
}),
|
||||
|
||||
coverImageBackground: Ember.computed('user.cover', 'coverDefault', function () {
|
||||
var url = this.get('user.cover') || this.get('coverDefault');
|
||||
|
||||
return `background-image: url(${url})`.htmlSafe();
|
||||
}),
|
||||
|
||||
|
@ -28,8 +32,10 @@ var SettingsUserController = Ember.Controller.extend({
|
|||
userDefault: Ember.computed('ghostPaths', function () {
|
||||
return this.get('ghostPaths.url').asset('/shared/img/user-image.png');
|
||||
}),
|
||||
|
||||
userImageBackground: Ember.computed('user.image', 'userDefault', function () {
|
||||
var url = this.get('user.image') || this.get('userDefault');
|
||||
|
||||
return `background-image: url(${url})`.htmlSafe();
|
||||
}),
|
||||
|
||||
|
@ -68,14 +74,15 @@ var SettingsUserController = Ember.Controller.extend({
|
|||
if (model.get('invited')) {
|
||||
model.destroyRecord().then(function () {
|
||||
var notificationText = 'Invitation revoked. (' + email + ')';
|
||||
self.notifications.showSuccess(notificationText, false);
|
||||
|
||||
self.get('notifications').showSuccess(notificationText, false);
|
||||
}).catch(function (error) {
|
||||
self.notifications.showAPIError(error);
|
||||
self.get('notifications').showAPIError(error);
|
||||
});
|
||||
} else {
|
||||
// if the user is no longer marked as "invited", then show a warning and reload the route
|
||||
self.get('target').send('reload');
|
||||
self.notifications.showError('This user has already accepted the invitation.', {delayed: 500});
|
||||
self.get('notifications').showError('This user has already accepted the invitation.', {delayed: 500});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -88,13 +95,13 @@ var SettingsUserController = Ember.Controller.extend({
|
|||
// If sending the invitation email fails, the API will still return a status of 201
|
||||
// but the user's status in the response object will be 'invited-pending'.
|
||||
if (result.users[0].status === 'invited-pending') {
|
||||
self.notifications.showWarn('Invitation email was not sent. Please try resending.');
|
||||
self.get('notifications').showWarn('Invitation email was not sent. Please try resending.');
|
||||
} else {
|
||||
self.get('model').set('status', result.users[0].status);
|
||||
self.notifications.showSuccess(notificationText);
|
||||
self.get('notifications').showSuccess(notificationText);
|
||||
}
|
||||
}).catch(function (error) {
|
||||
self.notifications.showAPIError(error);
|
||||
self.get('notifications').showAPIError(error);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -117,7 +124,7 @@ var SettingsUserController = Ember.Controller.extend({
|
|||
var currentPath,
|
||||
newPath;
|
||||
|
||||
self.notifications.showSuccess('Settings successfully saved.');
|
||||
self.get('notifications').showSuccess('Settings successfully saved.');
|
||||
|
||||
// If the user's slug has changed, change the URL and replace
|
||||
// the history so refresh and back button still work
|
||||
|
@ -133,7 +140,7 @@ var SettingsUserController = Ember.Controller.extend({
|
|||
|
||||
return model;
|
||||
}).catch(function (errors) {
|
||||
self.notifications.showErrors(errors);
|
||||
self.get('notifications').showErrors(errors);
|
||||
});
|
||||
|
||||
this.set('lastPromise', promise);
|
||||
|
@ -152,14 +159,14 @@ var SettingsUserController = Ember.Controller.extend({
|
|||
ne2Password: ''
|
||||
});
|
||||
|
||||
self.notifications.showSuccess('Password updated.');
|
||||
self.get('notifications').showSuccess('Password updated.');
|
||||
|
||||
return model;
|
||||
}).catch(function (errors) {
|
||||
self.notifications.showAPIError(errors);
|
||||
self.get('notifications').showAPIError(errors);
|
||||
});
|
||||
} else {
|
||||
self.notifications.showErrors(user.get('passwordValidationErrors'));
|
||||
self.get('notifications').showErrors(user.get('passwordValidationErrors'));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -217,5 +224,3 @@ var SettingsUserController = Ember.Controller.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default SettingsUserController;
|
||||
|
|
|
@ -12,12 +12,16 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
// ValidationEngine settings
|
||||
validationType: 'setup',
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
actions: {
|
||||
setup: function () {
|
||||
var self = this,
|
||||
data = self.getProperties('blogTitle', 'name', 'email', 'password');
|
||||
data = self.getProperties('blogTitle', 'name', 'email', 'password'),
|
||||
notifications = this.get('notifications');
|
||||
|
||||
self.notifications.closePassive();
|
||||
notifications.closePassive();
|
||||
|
||||
this.toggleProperty('submitting');
|
||||
this.validate({format: false}).then(function () {
|
||||
|
@ -39,11 +43,11 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
});
|
||||
}).catch(function (resp) {
|
||||
self.toggleProperty('submitting');
|
||||
self.notifications.showAPIError(resp);
|
||||
notifications.showAPIError(resp);
|
||||
});
|
||||
}).catch(function (errors) {
|
||||
self.toggleProperty('submitting');
|
||||
self.notifications.showErrors(errors);
|
||||
notifications.showErrors(errors);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
|
||||
submitting: false,
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
actions: {
|
||||
authenticate: function () {
|
||||
var model = this.get('model'),
|
||||
|
@ -28,10 +31,10 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
$('#login').find('input').trigger('change');
|
||||
|
||||
this.validate({format: false}).then(function () {
|
||||
self.notifications.closePassive();
|
||||
self.get('notifications').closePassive();
|
||||
self.send('authenticate');
|
||||
}).catch(function (errors) {
|
||||
self.notifications.showErrors(errors);
|
||||
self.get('notifications').showErrors(errors);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -55,10 +58,10 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
}
|
||||
}).then(function () {
|
||||
self.set('submitting', false);
|
||||
self.notifications.showSuccess('Please check your email for instructions.');
|
||||
self.get('notifications').showSuccess('Please check your email for instructions.');
|
||||
}).catch(function (resp) {
|
||||
self.set('submitting', false);
|
||||
self.notifications.showAPIError(resp, {defaultErrorText: 'There was a problem with the reset, please try again.'});
|
||||
self.get('notifications').showAPIError(resp, {defaultErrorText: 'There was a problem with the reset, please try again.'});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,18 +3,22 @@ import {request as ajax} from 'ic-ajax';
|
|||
import ValidationEngine from 'ghost/mixins/validation-engine';
|
||||
|
||||
export default Ember.Controller.extend(ValidationEngine, {
|
||||
submitting: false,
|
||||
|
||||
// ValidationEngine settings
|
||||
validationType: 'signup',
|
||||
|
||||
submitting: false,
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
actions: {
|
||||
signup: function () {
|
||||
var self = this,
|
||||
model = this.get('model'),
|
||||
data = model.getProperties('name', 'email', 'password', 'token');
|
||||
data = model.getProperties('name', 'email', 'password', 'token'),
|
||||
notifications = this.get('notifications');
|
||||
|
||||
self.notifications.closePassive();
|
||||
notifications.closePassive();
|
||||
|
||||
this.toggleProperty('submitting');
|
||||
this.validate({format: false}).then(function () {
|
||||
|
@ -37,11 +41,11 @@ export default Ember.Controller.extend(ValidationEngine, {
|
|||
});
|
||||
}, function (resp) {
|
||||
self.toggleProperty('submitting');
|
||||
self.notifications.showAPIError(resp);
|
||||
notifications.showAPIError(resp);
|
||||
});
|
||||
}, function (errors) {
|
||||
self.toggleProperty('submitting');
|
||||
self.notifications.showErrors(errors);
|
||||
notifications.showErrors(errors);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
import DropdownService from 'ghost/utils/dropdown-service';
|
||||
|
||||
var dropdownInitializer = {
|
||||
name: 'dropdown',
|
||||
|
||||
initialize: function (container, application) {
|
||||
application.register('dropdown:service', DropdownService);
|
||||
|
||||
// Inject dropdowns
|
||||
application.inject('component:gh-dropdown', 'dropdown', 'dropdown:service');
|
||||
application.inject('component:gh-dropdown-button', 'dropdown', 'dropdown:service');
|
||||
application.inject('controller:application', 'dropdown', 'dropdown:service');
|
||||
application.inject('controller:modals.delete-post', 'dropdown', 'dropdown:service');
|
||||
application.inject('controller:modals.transfer-owner', 'dropdown', 'dropdown:service');
|
||||
application.inject('route:application', 'dropdown', 'dropdown:service');
|
||||
|
||||
// Inject popovers
|
||||
application.inject('component:gh-popover', 'dropdown', 'dropdown:service');
|
||||
application.inject('component:gh-popover-button', 'dropdown', 'dropdown:service');
|
||||
application.inject('route:application', 'dropdown', 'dropdown:service');
|
||||
}
|
||||
};
|
||||
|
||||
export default dropdownInitializer;
|
|
@ -1,17 +0,0 @@
|
|||
import getConfig from 'ghost/utils/config-parser';
|
||||
|
||||
var ConfigInitializer = {
|
||||
name: 'config',
|
||||
|
||||
initialize: function (container, application) {
|
||||
var config = getConfig();
|
||||
application.register('ghost:config', config, {instantiate: false});
|
||||
|
||||
application.inject('route', 'config', 'ghost:config');
|
||||
application.inject('model:post', 'config', 'ghost:config');
|
||||
application.inject('controller', 'config', 'ghost:config');
|
||||
application.inject('component', 'config', 'ghost:config');
|
||||
}
|
||||
};
|
||||
|
||||
export default ConfigInitializer;
|
|
@ -1,16 +0,0 @@
|
|||
import ghostPaths from 'ghost/utils/ghost-paths';
|
||||
|
||||
var ghostPathsInitializer = {
|
||||
name: 'ghost-paths',
|
||||
after: 'store',
|
||||
|
||||
initialize: function (container, application) {
|
||||
application.register('ghost:paths', ghostPaths(), {instantiate: false});
|
||||
|
||||
application.inject('route', 'ghostPaths', 'ghost:paths');
|
||||
application.inject('model', 'ghostPaths', 'ghost:paths');
|
||||
application.inject('controller', 'ghostPaths', 'ghost:paths');
|
||||
}
|
||||
};
|
||||
|
||||
export default ghostPathsInitializer;
|
|
@ -1,17 +0,0 @@
|
|||
import Notifications from 'ghost/utils/notifications';
|
||||
|
||||
var injectNotificationsInitializer = {
|
||||
name: 'injectNotifications',
|
||||
before: 'authentication',
|
||||
|
||||
initialize: function (container, application) {
|
||||
application.register('notifications:main', Notifications);
|
||||
|
||||
application.inject('controller', 'notifications', 'notifications:main');
|
||||
application.inject('component', 'notifications', 'notifications:main');
|
||||
application.inject('router', 'notifications', 'notifications:main');
|
||||
application.inject('route', 'notifications', 'notifications:main');
|
||||
}
|
||||
};
|
||||
|
||||
export default injectNotificationsInitializer;
|
|
@ -5,24 +5,24 @@ import PostModel from 'ghost/models/post';
|
|||
import boundOneWay from 'ghost/utils/bound-one-way';
|
||||
import imageManager from 'ghost/utils/ed-image-manager';
|
||||
|
||||
var watchedProps,
|
||||
EditorControllerMixin;
|
||||
|
||||
// this array will hold properties we need to watch
|
||||
// to know if the model has been changed (`controller.isDirty`)
|
||||
watchedProps = ['model.scratch', 'model.titleScratch', 'model.isDirty', 'model.tags.[]'];
|
||||
var watchedProps = ['model.scratch', 'model.titleScratch', 'model.isDirty', 'model.tags.[]'];
|
||||
|
||||
PostModel.eachAttribute(function (name) {
|
||||
watchedProps.push('model.' + name);
|
||||
});
|
||||
|
||||
EditorControllerMixin = Ember.Mixin.create({
|
||||
needs: ['post-tags-input', 'post-settings-menu'],
|
||||
export default Ember.Mixin.create({
|
||||
postTagsInputController: Ember.inject.controller('post-tags-input'),
|
||||
postSettingsMenuController: Ember.inject.controller('post-settings-menu'),
|
||||
|
||||
autoSaveId: null,
|
||||
timedSaveId: null,
|
||||
editor: null,
|
||||
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
init: function () {
|
||||
var self = this;
|
||||
|
||||
|
@ -32,6 +32,7 @@ EditorControllerMixin = Ember.Mixin.create({
|
|||
return self.get('isDirty') ? self.unloadDirtyMessage() : null;
|
||||
};
|
||||
},
|
||||
|
||||
autoSave: function () {
|
||||
// Don't save just because we swapped out models
|
||||
if (this.get('model.isDraft') && !this.get('model.isNew')) {
|
||||
|
@ -213,21 +214,24 @@ EditorControllerMixin = Ember.Mixin.create({
|
|||
showSaveNotification: function (prevStatus, status, delay) {
|
||||
var message = this.messageMap.success.post[prevStatus][status],
|
||||
path = this.get('model.absoluteUrl'),
|
||||
type = this.get('postOrPage');
|
||||
type = this.get('postOrPage'),
|
||||
notifications = this.get('notifications');
|
||||
|
||||
if (status === 'published') {
|
||||
message += ` <a href="${path}">View ${type}</a>`;
|
||||
}
|
||||
this.notifications.showSuccess(message.htmlSafe(), {delayed: delay});
|
||||
|
||||
notifications.showSuccess(message.htmlSafe(), {delayed: delay});
|
||||
},
|
||||
|
||||
showErrorNotification: function (prevStatus, status, errors, delay) {
|
||||
var message = this.messageMap.errors.post[prevStatus][status],
|
||||
error = (errors && errors[0] && errors[0].message) || 'Unknown Error';
|
||||
error = (errors && errors[0] && errors[0].message) || 'Unknown Error',
|
||||
notifications = this.get('notifications');
|
||||
|
||||
message += '<br />' + error;
|
||||
|
||||
this.notifications.showError(message.htmlSafe(), {delayed: delay});
|
||||
notifications.showError(message.htmlSafe(), {delayed: delay});
|
||||
},
|
||||
|
||||
shouldFocusTitle: Ember.computed.alias('model.isNew'),
|
||||
|
@ -241,8 +245,9 @@ EditorControllerMixin = Ember.Mixin.create({
|
|||
autoSaveId = this.get('autoSaveId'),
|
||||
timedSaveId = this.get('timedSaveId'),
|
||||
self = this,
|
||||
psmController = this.get('controllers.post-settings-menu'),
|
||||
promise;
|
||||
psmController = this.get('postSettingsMenuController'),
|
||||
promise,
|
||||
notifications = this.get('notifications');
|
||||
|
||||
options = options || {};
|
||||
|
||||
|
@ -263,10 +268,10 @@ EditorControllerMixin = Ember.Mixin.create({
|
|||
this.set('timedSaveId', null);
|
||||
}
|
||||
|
||||
self.notifications.closePassive();
|
||||
notifications.closePassive();
|
||||
|
||||
// ensure an incomplete tag is finalised before save
|
||||
this.get('controllers.post-tags-input').send('addNewTag');
|
||||
this.get('postTagsInputController').send('addNewTag');
|
||||
|
||||
// Set the properties that are indirected
|
||||
// set markdown equal to what's in the editor, minus the image markers.
|
||||
|
@ -367,5 +372,3 @@ EditorControllerMixin = Ember.Mixin.create({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default EditorControllerMixin;
|
||||
|
|
|
@ -2,6 +2,8 @@ import Ember from 'ember';
|
|||
import getRequestErrorMessage from 'ghost/utils/ajax';
|
||||
|
||||
export default Ember.Mixin.create({
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
// set from PaginationRouteMixin
|
||||
paginationSettings: null,
|
||||
|
||||
|
@ -23,7 +25,7 @@ export default Ember.Mixin.create({
|
|||
message += '.';
|
||||
}
|
||||
|
||||
this.notifications.showError(message);
|
||||
this.get('notifications').showError(message);
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
import Ember from 'ember';
|
||||
// SelectiveSaveMixin adds a saveOnly method to a DS.Model.
|
||||
//
|
||||
// saveOnly provides a way to save one or more properties of a model while
|
||||
// preserving outstanding changes to other properties.
|
||||
var SelectiveSaveMixin = Ember.Mixin.create({
|
||||
saveOnly: function () {
|
||||
if (arguments.length === 0) {
|
||||
return Ember.RSVP.resolve();
|
||||
}
|
||||
|
||||
if (arguments.length === 1 && Ember.isArray(arguments[0])) {
|
||||
return this.saveOnly.apply(this, Array.prototype.slice.call(arguments[0]));
|
||||
}
|
||||
|
||||
var propertiesToSave = Array.prototype.slice.call(arguments),
|
||||
changed,
|
||||
hasMany = {},
|
||||
belongsTo = {},
|
||||
self = this;
|
||||
|
||||
changed = this.changedAttributes();
|
||||
|
||||
// disable observers so we can make changes to the model but not have
|
||||
// them reflected by the UI
|
||||
this.beginPropertyChanges();
|
||||
|
||||
// make a copy of any relations the model may have so they can
|
||||
// be reapplied later
|
||||
this.eachRelationship(function (name, meta) {
|
||||
if (meta.kind === 'hasMany') {
|
||||
hasMany[name] = self.get(name).slice();
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta.kind === 'belongsTo') {
|
||||
belongsTo[name] = self.get(name);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
// roll back all changes to the model and then reapply only those that
|
||||
// are part of the saveOnly
|
||||
|
||||
self.rollback();
|
||||
|
||||
propertiesToSave.forEach(function (name) {
|
||||
if (hasMany.hasOwnProperty(name)) {
|
||||
self.get(name).clear();
|
||||
|
||||
hasMany[name].forEach(function (relatedType) {
|
||||
self.get(name).pushObject(relatedType);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (belongsTo.hasOwnProperty(name)) {
|
||||
return self.updateBelongsTo(name, belongsTo[name]);
|
||||
}
|
||||
|
||||
if (changed.hasOwnProperty(name)) {
|
||||
return self.set(name, changed[name][1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
// if we were not able to get the model into the correct state
|
||||
// put it back the way we found it and return a rejected promise
|
||||
|
||||
Ember.keys(changed).forEach(function (name) {
|
||||
self.set(name, changed[name][1]);
|
||||
});
|
||||
|
||||
Ember.keys(hasMany).forEach(function (name) {
|
||||
self.updateHasMany(name, hasMany[name]);
|
||||
});
|
||||
|
||||
Ember.keys(belongsTo).forEach(function (name) {
|
||||
self.updateBelongsTo(name, belongsTo[name]);
|
||||
});
|
||||
|
||||
self.endPropertyChanges();
|
||||
|
||||
return Ember.RSVP.reject(new Error(err.message || 'Error during saveOnly. Changes NOT saved.'));
|
||||
}
|
||||
|
||||
return this.save().finally(function () {
|
||||
// reapply any changes that were not part of the save
|
||||
|
||||
Ember.keys(changed).forEach(function (name) {
|
||||
if (propertiesToSave.hasOwnProperty(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.set(name, changed[name][1]);
|
||||
});
|
||||
|
||||
Ember.keys(hasMany).forEach(function (name) {
|
||||
if (propertiesToSave.hasOwnProperty(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.updateHasMany(name, hasMany[name]);
|
||||
});
|
||||
|
||||
Ember.keys(belongsTo).forEach(function (name) {
|
||||
if (propertiesToSave.hasOwnProperty(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.updateBelongsTo(name, belongsTo[name]);
|
||||
});
|
||||
|
||||
// signal that we're finished and normal model observation may continue
|
||||
self.endPropertyChanges();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default SelectiveSaveMixin;
|
|
@ -1,10 +1,11 @@
|
|||
import Ember from 'ember';
|
||||
var SettingsMenuControllerMixin = Ember.Mixin.create({
|
||||
needs: 'application',
|
||||
|
||||
isViewingSubview: Ember.computed('controllers.application.showSettingsMenu', function (key, value) {
|
||||
export default Ember.Mixin.create({
|
||||
application: Ember.inject.controller(),
|
||||
|
||||
isViewingSubview: Ember.computed('application.showSettingsMenu', function (key, value) {
|
||||
// Not viewing a subview if we can't even see the PSM
|
||||
if (!this.get('controllers.application.showSettingsMenu')) {
|
||||
if (!this.get('application.showSettingsMenu')) {
|
||||
return false;
|
||||
}
|
||||
if (arguments.length > 1) {
|
||||
|
@ -24,5 +25,3 @@ var SettingsMenuControllerMixin = Ember.Mixin.create({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default SettingsMenuControllerMixin;
|
||||
|
|
|
@ -2,7 +2,7 @@ import Ember from 'ember';
|
|||
import DS from 'ember-data';
|
||||
import ValidationEngine from 'ghost/mixins/validation-engine';
|
||||
|
||||
var Post = DS.Model.extend(ValidationEngine, {
|
||||
export default DS.Model.extend(ValidationEngine, {
|
||||
validationType: 'post',
|
||||
|
||||
uuid: DS.attr('string'),
|
||||
|
@ -28,6 +28,9 @@ var Post = DS.Model.extend(ValidationEngine, {
|
|||
tags: DS.hasMany('tag', {embedded: 'always'}),
|
||||
url: DS.attr('string'),
|
||||
|
||||
config: Ember.inject.service(),
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
|
||||
absoluteUrl: Ember.computed('url', 'ghostPaths.url', 'config.blogUrl', function () {
|
||||
var blogUrl = this.get('config.blogUrl'),
|
||||
postUrl = this.get('url');
|
||||
|
@ -69,5 +72,3 @@ var Post = DS.Model.extend(ValidationEngine, {
|
|||
}
|
||||
|
||||
});
|
||||
|
||||
export default Post;
|
||||
|
|
|
@ -2,10 +2,11 @@ import Ember from 'ember';
|
|||
import {request as ajax} from 'ic-ajax';
|
||||
|
||||
export default Ember.Object.extend({
|
||||
ghostPaths: null,
|
||||
slugType: null,
|
||||
value: null,
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
|
||||
toString: function () {
|
||||
return this.get('value');
|
||||
},
|
||||
|
|
|
@ -2,9 +2,8 @@ import Ember from 'ember';
|
|||
import DS from 'ember-data';
|
||||
import {request as ajax} from 'ic-ajax';
|
||||
import ValidationEngine from 'ghost/mixins/validation-engine';
|
||||
import SelectiveSaveMixin from 'ghost/mixins/selective-save';
|
||||
|
||||
export default DS.Model.extend(SelectiveSaveMixin, ValidationEngine, {
|
||||
export default DS.Model.extend(ValidationEngine, {
|
||||
validationType: 'user',
|
||||
|
||||
uuid: DS.attr('string'),
|
||||
|
@ -28,6 +27,8 @@ export default DS.Model.extend(SelectiveSaveMixin, ValidationEngine, {
|
|||
updated_by: DS.attr('number'),
|
||||
roles: DS.hasMany('role', {embedded: 'always'}),
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
|
||||
role: Ember.computed('roles', function (name, value) {
|
||||
if (arguments.length > 1) {
|
||||
// Only one role per user, so remove any old data.
|
||||
|
@ -93,13 +94,13 @@ export default DS.Model.extend(SelectiveSaveMixin, ValidationEngine, {
|
|||
|
||||
isPasswordValid: Ember.computed.empty('passwordValidationErrors.[]'),
|
||||
|
||||
active: function () {
|
||||
active: Ember.computed('status', function () {
|
||||
return ['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked'].indexOf(this.get('status')) > -1;
|
||||
}.property('status'),
|
||||
}),
|
||||
|
||||
invited: function () {
|
||||
invited: Ember.computed('status', function () {
|
||||
return ['invited', 'invited-pending'].indexOf(this.get('status')) > -1;
|
||||
}.property('status'),
|
||||
}),
|
||||
|
||||
pending: Ember.computed.equal('status', 'invited-pending').property('status')
|
||||
});
|
||||
|
|
|
@ -6,9 +6,13 @@ var Router = Ember.Router.extend({
|
|||
location: 'trailing-history', // use HTML5 History API instead of hash-tag based URLs
|
||||
rootURL: ghostPaths().adminRoot, // admin interface lives under sub-directory /ghost
|
||||
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
clearNotifications: Ember.on('didTransition', function () {
|
||||
this.notifications.closePassive();
|
||||
this.notifications.displayDelayed();
|
||||
var notifications = this.get('notifications');
|
||||
|
||||
notifications.closePassive();
|
||||
notifications.displayDelayed();
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Ember from 'ember';
|
||||
import {request as ajax} from 'ic-ajax';
|
||||
import AuthenticatedRoute from 'ghost/routes/authenticated';
|
||||
import styleBody from 'ghost/mixins/style-body';
|
||||
|
@ -7,6 +8,8 @@ export default AuthenticatedRoute.extend(styleBody, {
|
|||
|
||||
classNames: ['view-about'],
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
|
||||
cachedConfig: false,
|
||||
|
||||
model: function () {
|
||||
|
|
|
@ -6,16 +6,19 @@ import Configuration from 'simple-auth/configuration';
|
|||
import ShortcutsRoute from 'ghost/mixins/shortcuts-route';
|
||||
import ctrlOrCmd from 'ghost/utils/ctrl-or-cmd';
|
||||
|
||||
var ApplicationRoute,
|
||||
shortcuts = {};
|
||||
var shortcuts = {};
|
||||
|
||||
shortcuts.esc = {action: 'closePopups', scope: 'all'};
|
||||
shortcuts.enter = {action: 'confirmModal', scope: 'modal'};
|
||||
shortcuts[ctrlOrCmd + '+s'] = {action: 'save', scope: 'all'};
|
||||
|
||||
ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
|
||||
export default Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
|
||||
shortcuts: shortcuts,
|
||||
|
||||
config: Ember.inject.service(),
|
||||
dropdown: Ember.inject.service(),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
afterModel: function (model, transition) {
|
||||
if (this.get('session').isAuthenticated) {
|
||||
transition.send('loadServerNotifications');
|
||||
|
@ -68,10 +71,10 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
|
|||
err.message = err.message.htmlSafe();
|
||||
});
|
||||
|
||||
this.notifications.showErrors(error.errors);
|
||||
this.get('notifications').showErrors(error.errors);
|
||||
} else {
|
||||
// connection errors don't return proper status message, only req.body
|
||||
this.notifications.showError('There was a problem on the server.');
|
||||
this.get('notifications').showError('There was a problem on the server.');
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -96,7 +99,7 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
|
|||
},
|
||||
|
||||
sessionInvalidationFailed: function (error) {
|
||||
this.notifications.showError(error.message);
|
||||
this.get('notifications').showError(error.message);
|
||||
},
|
||||
|
||||
openModal: function (modalName, model, type) {
|
||||
|
@ -149,7 +152,7 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
|
|||
if (!user.get('isAuthor') && !user.get('isEditor')) {
|
||||
self.store.findAll('notification').then(function (serverNotifications) {
|
||||
serverNotifications.forEach(function (notification) {
|
||||
self.notifications.handleNotification(notification, isDelayed);
|
||||
self.get('notifications').handleNotification(notification, isDelayed);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -158,11 +161,11 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
|
|||
},
|
||||
|
||||
handleErrors: function (errors) {
|
||||
var self = this;
|
||||
var notifications = this.get('notifications');
|
||||
|
||||
this.notifications.clear();
|
||||
notifications.clear();
|
||||
errors.forEach(function (errorObj) {
|
||||
self.notifications.showError(errorObj.message || errorObj);
|
||||
notifications.showError(errorObj.message || errorObj);
|
||||
|
||||
if (errorObj.hasOwnProperty('el')) {
|
||||
errorObj.el.addClass('input-error');
|
||||
|
@ -174,5 +177,3 @@ ApplicationRoute = Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
|
|||
save: Ember.K
|
||||
}
|
||||
});
|
||||
|
||||
export default ApplicationRoute;
|
||||
|
|
|
@ -2,12 +2,14 @@ import Ember from 'ember';
|
|||
import Configuration from 'simple-auth/configuration';
|
||||
import styleBody from 'ghost/mixins/style-body';
|
||||
|
||||
var ResetRoute = Ember.Route.extend(styleBody, {
|
||||
export default Ember.Route.extend(styleBody, {
|
||||
classNames: ['ghost-reset'],
|
||||
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
beforeModel: function () {
|
||||
if (this.get('session').isAuthenticated) {
|
||||
this.notifications.showWarn('You can\'t reset your password while you\'re signed in.', {delayed: true});
|
||||
this.get('notifications').showWarn('You can\'t reset your password while you\'re signed in.', {delayed: true});
|
||||
this.transitionTo(Configuration.routeAfterAuthentication);
|
||||
}
|
||||
},
|
||||
|
@ -22,5 +24,3 @@ var ResetRoute = Ember.Route.extend(styleBody, {
|
|||
this.controller.clearData();
|
||||
}
|
||||
});
|
||||
|
||||
export default ResetRoute;
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import Ember from 'ember';
|
||||
import AuthenticatedRoute from 'ghost/routes/authenticated';
|
||||
import CurrentUserSettings from 'ghost/mixins/current-user-settings';
|
||||
import styleBody from 'ghost/mixins/style-body';
|
||||
|
||||
var AppsRoute = AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
|
||||
export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
|
||||
titleToken: 'Apps',
|
||||
|
||||
classNames: ['settings-view-apps'],
|
||||
|
||||
config: Ember.inject.service(),
|
||||
|
||||
beforeModel: function () {
|
||||
if (!this.get('config.apps')) {
|
||||
return this.transitionTo('settings.general');
|
||||
|
@ -21,5 +24,3 @@ var AppsRoute = AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
|
|||
return this.store.find('app');
|
||||
}
|
||||
});
|
||||
|
||||
export default AppsRoute;
|
||||
|
|
|
@ -8,9 +8,10 @@ export default Ember.Route.extend(styleBody, {
|
|||
|
||||
classNames: ['ghost-setup'],
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
|
||||
// use the beforeModel hook to check to see whether or not setup has been
|
||||
// previously completed. If it has, stop the transition into the setup page.
|
||||
|
||||
beforeModel: function () {
|
||||
var self = this;
|
||||
|
||||
|
|
|
@ -2,13 +2,15 @@ import Ember from 'ember';
|
|||
import AuthenticatedRoute from 'ghost/routes/authenticated';
|
||||
import styleBody from 'ghost/mixins/style-body';
|
||||
|
||||
var SignoutRoute = AuthenticatedRoute.extend(styleBody, {
|
||||
export default AuthenticatedRoute.extend(styleBody, {
|
||||
titleToken: 'Sign Out',
|
||||
|
||||
classNames: ['ghost-signout'],
|
||||
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
afterModel: function (model, transition) {
|
||||
this.notifications.clear();
|
||||
this.get('notifications').closeAll();
|
||||
if (Ember.canInvoke(transition, 'send')) {
|
||||
transition.send('invalidateSession');
|
||||
transition.abort();
|
||||
|
@ -17,5 +19,3 @@ var SignoutRoute = AuthenticatedRoute.extend(styleBody, {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default SignoutRoute;
|
||||
|
|
|
@ -6,9 +6,12 @@ import styleBody from 'ghost/mixins/style-body';
|
|||
export default Ember.Route.extend(styleBody, {
|
||||
classNames: ['ghost-signup'],
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
beforeModel: function () {
|
||||
if (this.get('session').isAuthenticated) {
|
||||
this.notifications.showWarn('You need to sign out to register as a new user.', {delayed: true});
|
||||
this.get('notifications').showWarn('You need to sign out to register as a new user.', {delayed: true});
|
||||
this.transitionTo(Configuration.routeAfterAuthentication);
|
||||
}
|
||||
},
|
||||
|
@ -22,7 +25,7 @@ export default Ember.Route.extend(styleBody, {
|
|||
|
||||
return new Ember.RSVP.Promise(function (resolve) {
|
||||
if (!re.test(params.token)) {
|
||||
self.notifications.showError('Invalid token.', {delayed: true});
|
||||
self.get('notifications').showError('Invalid token.', {delayed: true});
|
||||
|
||||
return resolve(self.transitionTo('signin'));
|
||||
}
|
||||
|
@ -42,7 +45,7 @@ export default Ember.Route.extend(styleBody, {
|
|||
}
|
||||
}).then(function (response) {
|
||||
if (response && response.invitation && response.invitation[0].valid === false) {
|
||||
self.notifications.showError('The invitation does not exist or is no longer valid.', {delayed: true});
|
||||
self.get('notifications').showError('The invitation does not exist or is no longer valid.', {delayed: true});
|
||||
|
||||
return resolve(self.transitionTo('signin'));
|
||||
}
|
||||
|
|
43
core/client/app/services/config.js
Normal file
43
core/client/app/services/config.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
function isNumeric(num) {
|
||||
return !isNaN(num);
|
||||
}
|
||||
|
||||
function _mapType(val) {
|
||||
if (val === '') {
|
||||
return null;
|
||||
} else if (val === 'true') {
|
||||
return true;
|
||||
} else if (val === 'false') {
|
||||
return false;
|
||||
} else if (isNumeric(val)) {
|
||||
return +val;
|
||||
} else if (val.indexOf('{') === 0) {
|
||||
try {
|
||||
return JSON.parse(val);
|
||||
} catch (e) {
|
||||
/*jshint unused:false */
|
||||
return val;
|
||||
}
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
export default Ember.Service.extend(Ember._ProxyMixin, {
|
||||
content: Ember.computed(function () {
|
||||
var metaConfigTags = Ember.$('meta[name^="env-"]'),
|
||||
config = {};
|
||||
|
||||
metaConfigTags.each(function (i, el) {
|
||||
var key = el.name,
|
||||
value = el.content,
|
||||
propertyName = key.substring(4);
|
||||
|
||||
config[propertyName] = _mapType(value);
|
||||
});
|
||||
|
||||
return config;
|
||||
})
|
||||
});
|
|
@ -2,17 +2,17 @@ import Ember from 'ember';
|
|||
// This is used by the dropdown initializer (and subsequently popovers) to manage closing & toggling
|
||||
import BodyEventListener from 'ghost/mixins/body-event-listener';
|
||||
|
||||
var DropdownService = Ember.Object.extend(Ember.Evented, BodyEventListener, {
|
||||
export default Ember.Service.extend(Ember.Evented, BodyEventListener, {
|
||||
bodyClick: function (event) {
|
||||
/*jshint unused:false */
|
||||
this.closeDropdowns();
|
||||
},
|
||||
|
||||
closeDropdowns: function () {
|
||||
this.trigger('close');
|
||||
},
|
||||
|
||||
toggleDropdown: function (dropdownName, dropdownButton) {
|
||||
this.trigger('toggle', {target: dropdownName, button: dropdownButton});
|
||||
}
|
||||
});
|
||||
|
||||
export default DropdownService;
|
6
core/client/app/services/ghost-paths.js
Normal file
6
core/client/app/services/ghost-paths.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
import Ember from 'ember';
|
||||
import ghostPaths from 'ghost/utils/ghost-paths';
|
||||
|
||||
export default Ember.Service.extend(Ember._ProxyMixin, {
|
||||
content: ghostPaths()
|
||||
});
|
|
@ -1,8 +1,8 @@
|
|||
import Ember from 'ember';
|
||||
import Notification from 'ghost/models/notification';
|
||||
|
||||
var Notifications = Ember.ArrayProxy.extend({
|
||||
delayedNotifications: [],
|
||||
export default Ember.Service.extend({
|
||||
delayedNotifications: Ember.A(),
|
||||
content: Ember.A(),
|
||||
timeout: 3000,
|
||||
|
||||
|
@ -25,6 +25,7 @@ var Notifications = Ember.ArrayProxy.extend({
|
|||
|
||||
this._super(object);
|
||||
},
|
||||
|
||||
handleNotification: function (message, delayed) {
|
||||
if (typeof message.toJSON === 'function') {
|
||||
// If this is a persistent message from the server, treat it as html safe
|
||||
|
@ -42,11 +43,12 @@ var Notifications = Ember.ArrayProxy.extend({
|
|||
}
|
||||
|
||||
if (!delayed) {
|
||||
this.pushObject(message);
|
||||
this.get('content').pushObject(message);
|
||||
} else {
|
||||
this.delayedNotifications.push(message);
|
||||
this.delayedNotifications.pushObject(message);
|
||||
}
|
||||
},
|
||||
|
||||
showError: function (message, options) {
|
||||
options = options || {};
|
||||
|
||||
|
@ -59,6 +61,7 @@ var Notifications = Ember.ArrayProxy.extend({
|
|||
message: message
|
||||
}, options.delayed);
|
||||
},
|
||||
|
||||
showErrors: function (errors, options) {
|
||||
options = options || {};
|
||||
|
||||
|
@ -70,6 +73,7 @@ var Notifications = Ember.ArrayProxy.extend({
|
|||
this.showError(errors[i].message || errors[i], {doNotClosePassive: true});
|
||||
}
|
||||
},
|
||||
|
||||
showAPIError: function (resp, options) {
|
||||
options = options || {};
|
||||
|
||||
|
@ -89,6 +93,7 @@ var Notifications = Ember.ArrayProxy.extend({
|
|||
this.showError(options.defaultErrorText, {doNotClosePassive: true});
|
||||
}
|
||||
},
|
||||
|
||||
showInfo: function (message, options) {
|
||||
options = options || {};
|
||||
|
||||
|
@ -101,6 +106,7 @@ var Notifications = Ember.ArrayProxy.extend({
|
|||
message: message
|
||||
}, options.delayed);
|
||||
},
|
||||
|
||||
showSuccess: function (message, options) {
|
||||
options = options || {};
|
||||
|
||||
|
@ -113,6 +119,7 @@ var Notifications = Ember.ArrayProxy.extend({
|
|||
message: message
|
||||
}, options.delayed);
|
||||
},
|
||||
|
||||
showWarn: function (message, options) {
|
||||
options = options || {};
|
||||
|
||||
|
@ -125,35 +132,38 @@ var Notifications = Ember.ArrayProxy.extend({
|
|||
message: message
|
||||
}, options.delayed);
|
||||
},
|
||||
|
||||
displayDelayed: function () {
|
||||
var self = this;
|
||||
|
||||
self.delayedNotifications.forEach(function (message) {
|
||||
self.pushObject(message);
|
||||
self.get('content').pushObject(message);
|
||||
});
|
||||
self.delayedNotifications = [];
|
||||
},
|
||||
|
||||
closeNotification: function (notification) {
|
||||
var self = this;
|
||||
var content = this.get('content');
|
||||
|
||||
if (notification instanceof Notification) {
|
||||
notification.deleteRecord();
|
||||
notification.save().finally(function () {
|
||||
self.removeObject(notification);
|
||||
content.removeObject(notification);
|
||||
});
|
||||
} else {
|
||||
this.removeObject(notification);
|
||||
content.removeObject(notification);
|
||||
}
|
||||
},
|
||||
|
||||
closePassive: function () {
|
||||
this.set('content', this.rejectBy('status', 'passive'));
|
||||
this.set('content', this.get('content').rejectBy('status', 'passive'));
|
||||
},
|
||||
|
||||
closePersistent: function () {
|
||||
this.set('content', this.rejectBy('status', 'persistent'));
|
||||
this.set('content', this.get('content').rejectBy('status', 'persistent'));
|
||||
},
|
||||
|
||||
closeAll: function () {
|
||||
this.clear();
|
||||
this.get('content').clear();
|
||||
}
|
||||
});
|
||||
|
||||
export default Notifications;
|
|
@ -1,43 +0,0 @@
|
|||
var isNumeric = function (num) {
|
||||
return !isNaN(num);
|
||||
},
|
||||
|
||||
_mapType = function (val) {
|
||||
if (val === '') {
|
||||
return null;
|
||||
} else if (val === 'true') {
|
||||
return true;
|
||||
} else if (val === 'false') {
|
||||
return false;
|
||||
} else if (isNumeric(val)) {
|
||||
return +val;
|
||||
} else if (val.indexOf('{') === 0) {
|
||||
try {
|
||||
return JSON.parse(val);
|
||||
} catch (e) {
|
||||
/*jshint unused:false */
|
||||
return val;
|
||||
}
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
},
|
||||
|
||||
parseConfiguration = function () {
|
||||
var metaConfigTags = $('meta[name^="env-"]'),
|
||||
propertyName,
|
||||
config = {},
|
||||
value,
|
||||
key,
|
||||
i;
|
||||
|
||||
for (i = 0; i < metaConfigTags.length; i += 1) {
|
||||
key = $(metaConfigTags[i]).prop('name');
|
||||
value = $(metaConfigTags[i]).prop('content');
|
||||
propertyName = key.substring(4); // produce config name ignoring the initial 'env-'.
|
||||
config[propertyName] = _mapType(value); // map string values to types if possible
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
export default parseConfiguration;
|
Loading…
Reference in a new issue