mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-15 11:34:24 +03:00
d0c151be70
closes #5336 - creates gh-form-group component to handle form group status - refactors current validation methods to work on a per-property basis - adds gh-error-message component to render error message - removes (comments out) tests that pertain to the old notifications until the new inline validation is added
204 lines
7.2 KiB
JavaScript
204 lines
7.2 KiB
JavaScript
import Ember from 'ember';
|
|
import SlugGenerator from 'ghost/models/slug-generator';
|
|
import isNumber from 'ghost/utils/isNumber';
|
|
import boundOneWay from 'ghost/utils/bound-one-way';
|
|
|
|
export default Ember.Controller.extend({
|
|
ghostPaths: Ember.inject.service('ghost-paths'),
|
|
notifications: Ember.inject.service(),
|
|
|
|
currentUser: Ember.computed.alias('session.user'),
|
|
|
|
isNotOwnProfile: Ember.computed('user.id', 'currentUser.id', function () {
|
|
return this.get('user.id') !== this.get('currentUser.id');
|
|
}),
|
|
|
|
isNotOwnersProfile: Ember.computed.not('user.isOwner'),
|
|
|
|
canAssignRoles: Ember.computed.or('currentUser.isAdmin', 'currentUser.isOwner'),
|
|
|
|
canMakeOwner: Ember.computed.and('currentUser.isOwner', 'isNotOwnProfile', 'user.isAdmin'),
|
|
|
|
rolesDropdownIsVisible: Ember.computed.and('isNotOwnProfile', 'canAssignRoles', 'isNotOwnersProfile'),
|
|
|
|
deleteUserActionIsVisible: Ember.computed('currentUser', 'canAssignRoles', 'user', function () {
|
|
if ((this.get('canAssignRoles') && this.get('isNotOwnProfile') && !this.get('user.isOwner')) ||
|
|
(this.get('currentUser.isEditor') && (this.get('isNotOwnProfile') ||
|
|
this.get('user.isAuthor')))) {
|
|
return true;
|
|
}
|
|
}),
|
|
|
|
userActionsAreVisible: Ember.computed.or('deleteUserActionIsVisible', 'canMakeOwner'),
|
|
|
|
user: Ember.computed.alias('model'),
|
|
|
|
email: Ember.computed.readOnly('model.email'),
|
|
|
|
slugValue: boundOneWay('model.slug'),
|
|
|
|
lastPromise: null,
|
|
|
|
// duplicated in gh-user-active -- find a better home and consolidate?
|
|
|
|
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();
|
|
}),
|
|
|
|
// end duplicated
|
|
|
|
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();
|
|
}),
|
|
|
|
coverTitle: Ember.computed('user.name', function () {
|
|
return this.get('user.name') + '\'s Cover Image';
|
|
}),
|
|
|
|
// Lazy load the slug generator for slugPlaceholder
|
|
slugGenerator: Ember.computed(function () {
|
|
return SlugGenerator.create({
|
|
ghostPaths: this.get('ghostPaths'),
|
|
slugType: 'user'
|
|
});
|
|
}),
|
|
|
|
actions: {
|
|
changeRole: function (newRole) {
|
|
this.set('model.role', newRole);
|
|
},
|
|
|
|
save: function () {
|
|
var user = this.get('user'),
|
|
slugValue = this.get('slugValue'),
|
|
afterUpdateSlug = this.get('lastPromise'),
|
|
promise,
|
|
slugChanged,
|
|
self = this;
|
|
|
|
if (user.get('slug') !== slugValue) {
|
|
slugChanged = true;
|
|
user.set('slug', slugValue);
|
|
}
|
|
|
|
promise = Ember.RSVP.resolve(afterUpdateSlug).then(function () {
|
|
return user.save({format: false});
|
|
}).then(function (model) {
|
|
var currentPath,
|
|
newPath;
|
|
|
|
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
|
|
if (slugChanged) {
|
|
currentPath = window.history.state.path;
|
|
|
|
newPath = currentPath.split('/');
|
|
newPath[newPath.length - 2] = model.get('slug');
|
|
newPath = newPath.join('/');
|
|
|
|
window.history.replaceState({path: newPath}, '', newPath);
|
|
}
|
|
|
|
return model;
|
|
}).catch(function (errors) {
|
|
if (errors) {
|
|
self.get('notifications').showErrors(errors);
|
|
}
|
|
});
|
|
|
|
this.set('lastPromise', promise);
|
|
},
|
|
|
|
password: function () {
|
|
var user = this.get('user'),
|
|
self = this;
|
|
|
|
if (user.get('isPasswordValid')) {
|
|
user.saveNewPassword().then(function (model) {
|
|
// Clear properties from view
|
|
user.setProperties({
|
|
password: '',
|
|
newPassword: '',
|
|
ne2Password: ''
|
|
});
|
|
|
|
self.get('notifications').showSuccess('Password updated.');
|
|
|
|
return model;
|
|
}).catch(function (errors) {
|
|
self.get('notifications').showAPIError(errors);
|
|
});
|
|
} else {
|
|
self.get('notifications').showErrors(user.get('passwordValidationErrors'));
|
|
}
|
|
},
|
|
|
|
updateSlug: function (newSlug) {
|
|
var self = this,
|
|
afterSave = this.get('lastPromise'),
|
|
promise;
|
|
|
|
promise = Ember.RSVP.resolve(afterSave).then(function () {
|
|
var slug = self.get('model.slug');
|
|
|
|
newSlug = newSlug || slug;
|
|
|
|
newSlug = newSlug.trim();
|
|
|
|
// Ignore unchanged slugs or candidate slugs that are empty
|
|
if (!newSlug || slug === newSlug) {
|
|
self.set('slugValue', slug);
|
|
|
|
return;
|
|
}
|
|
|
|
return self.get('slugGenerator').generateSlug(newSlug).then(function (serverSlug) {
|
|
// If after getting the sanitized and unique slug back from the API
|
|
// we end up with a slug that matches the existing slug, abort the change
|
|
if (serverSlug === slug) {
|
|
return;
|
|
}
|
|
|
|
// Because the server transforms the candidate slug by stripping
|
|
// certain characters and appending a number onto the end of slugs
|
|
// to enforce uniqueness, there are cases where we can get back a
|
|
// candidate slug that is a duplicate of the original except for
|
|
// the trailing incrementor (e.g., this-is-a-slug and this-is-a-slug-2)
|
|
|
|
// get the last token out of the slug candidate and see if it's a number
|
|
var slugTokens = serverSlug.split('-'),
|
|
check = Number(slugTokens.pop());
|
|
|
|
// if the candidate slug is the same as the existing slug except
|
|
// for the incrementor then the existing slug should be used
|
|
if (isNumber(check) && check > 0) {
|
|
if (slug === slugTokens.join('-') && serverSlug !== newSlug) {
|
|
self.set('slugValue', slug);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
self.set('slugValue', serverSlug);
|
|
});
|
|
});
|
|
|
|
this.set('lastPromise', promise);
|
|
}
|
|
}
|
|
});
|