Skip to content

Commit

Permalink
Routable tags
Browse files Browse the repository at this point in the history
refs #5845
- Updates tag settings screen to match content screen behaviour. Each now tag has it's own route that is link-able from other areas of the app
- Updates a number of places where jQuery event handler code was not wrapped in Ember's run loop
  • Loading branch information
kevinansfield committed Oct 27, 2015
1 parent 049df95 commit bc346d2
Show file tree
Hide file tree
Showing 28 changed files with 1,399 additions and 424 deletions.
2 changes: 1 addition & 1 deletion core/client/app/adapters/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ export default EmbeddedRelationAdapter.extend({
return false;
}

});
});
19 changes: 8 additions & 11 deletions core/client/app/components/gh-cm-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,17 @@ export default Ember.Component.extend({

didInsertElement: function () {
var options = this.getProperties('lineNumbers', 'indentUnit', 'mode', 'theme'),
self = this,
editor;
editor = new CodeMirror(this.get('element'), options);
editor = new CodeMirror(this.get('element'), options);

editor.getDoc().setValue(this.get('value'));

// events
editor.on('focus', function () {
self.set('isFocused', true);
});
editor.on('blur', function () {
self.set('isFocused', false);
});
editor.on('change', function () {
self.set('value', editor.getDoc().getValue());
editor.on('focus', Ember.run.bind(this, 'set', 'isFocused', true));
editor.on('blur', Ember.run.bind(this, 'set', 'isFocused', false));
editor.on('change', () => {
Ember.run(this, function () {
this.set('value', editor.getDoc().getValue());
});
});

this.set('editor', editor);
Expand Down
10 changes: 6 additions & 4 deletions core/client/app/components/gh-dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ export default Ember.Component.extend(DropdownMixin, {
}
this.$().on('animationend webkitAnimationEnd oanimationend MSAnimationEnd', function (event) {
if (event.originalEvent.animationName === 'fade-out') {
if (self.get('closing')) {
self.set('isOpen', false);
self.set('closing', false);
}
Ember.run(self, function () {
if (this.get('closing')) {
this.set('isOpen', false);
this.set('closing', false);
}
});
}
});
},
Expand Down
127 changes: 127 additions & 0 deletions core/client/app/components/gh-tag-settings-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/* global key */
import Ember from 'ember';
import boundOneWay from 'ghost/utils/bound-one-way';

const {get} = Ember;

export default Ember.Component.extend({

tag: null,

scratchName: boundOneWay('tag.name'),
scratchSlug: boundOneWay('tag.slug'),
scratchDescription: boundOneWay('tag.description'),
scratchMetaTitle: boundOneWay('tag.meta_title'),
scratchMetaDescription: boundOneWay('tag.meta_description'),

isViewingSubview: false,

config: Ember.inject.service(),

title: Ember.computed('tag.isNew', function () {
if (this.get('tag.isNew')) {
return 'New Tag';
} else {
return 'Tag Settings';
}
}),

seoTitle: Ember.computed('scratchName', 'scratchMetaTitle', function () {
let metaTitle = this.get('scratchMetaTitle') || '';

metaTitle = metaTitle.length > 0 ? metaTitle : this.get('scratchName');

if (metaTitle && metaTitle.length > 70) {
metaTitle = metaTitle.substring(0, 70).trim();
metaTitle = Ember.Handlebars.Utils.escapeExpression(metaTitle);
metaTitle = Ember.String.htmlSafe(metaTitle + '…');
}

return metaTitle;
}),

seoURL: Ember.computed('scratchSlug', function () {
const blogUrl = this.get('config.blogUrl'),
seoSlug = this.get('scratchSlug') || '';

let seoURL = blogUrl + '/tag/' + seoSlug;

// only append a slash to the URL if the slug exists
if (seoSlug) {
seoURL += '/';
}

if (seoURL.length > 70) {
seoURL = seoURL.substring(0, 70).trim();
seoURL = Ember.String.htmlSafe(seoURL + '…');
}

return seoURL;
}),

seoDescription: Ember.computed('scratchDescription', 'scratchMetaDescription', function () {
let metaDescription = this.get('scratchMetaDescription') || '';

metaDescription = metaDescription.length > 0 ? metaDescription : this.get('scratchDescription');

if (metaDescription && metaDescription.length > 156) {
metaDescription = metaDescription.substring(0, 156).trim();
metaDescription = Ember.Handlebars.Utils.escapeExpression(metaDescription);
metaDescription = Ember.String.htmlSafe(metaDescription + '…');
}

return metaDescription;
}),

didReceiveAttrs: function (attrs) {
if (get(attrs, 'newAttrs.tag.value.id') !== get(attrs, 'oldAttrs.tag.value.id')) {
this.reset();
}
},

reset: function () {
this.set('isViewingSubview', false);
if (this.$()) {
this.$('.settings-menu-pane').scrollTop(0);
}
},

focusIn: function () {
key.setScope('tag-settings-form');
},

focusOut: function () {
key.setScope('default');
},

actions: {
setProperty: function (property, value) {
this.attrs.setProperty(property, value);
},

setCoverImage: function (image) {
this.attrs.setProperty('image', image);
},

clearCoverImage: function () {
this.attrs.setProperty('image', '');
},

setUploaderReference: function () {
// noop
},

openMeta: function () {
this.set('isViewingSubview', true);
},

closeMeta: function () {
this.set('isViewingSubview', false);
},

deleteTag: function () {
this.sendAction('openModal', 'delete-tag', this.get('tag'));
}
}

});
53 changes: 13 additions & 40 deletions core/client/app/components/gh-uploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,6 @@ export default Ember.Component.extend({
return this.get('image') || '';
}),

/**
* Sets up the uploader on render
*/
setup: function () {
var $this = this.$(),
self = this;

// this.set('uploaderReference', uploader.call($this, {
// editor: true,
// fileStorage: this.get('config.fileStorage')
// }));

$this.on('uploadsuccess', function (event, result) {
if (result && result !== '' && result !== 'http://') {
self.sendAction('uploaded', result);
}
});

$this.on('imagecleared', function () {
self.sendAction('canceled');
});
},

// removes event listeners from the uploader
removeListeners: function () {
var $this = this.$();
Expand All @@ -41,17 +18,6 @@ export default Ember.Component.extend({
$this.find('.js-cancel').off();
},

// didInsertElement: function () {
// Ember.run.scheduleOnce('afterRender', this, this.setup());
// },
didInsertElement: function () {
this.send('initUploader');
},

willDestroyElement: function () {
this.removeListeners();
},

// NOTE: because the uploader is sometimes in the same place in the DOM
// between transitions Glimmer will re-use the existing elements including
// those that arealready decorated by jQuery. The following works around
Expand All @@ -77,27 +43,34 @@ export default Ember.Component.extend({
}
},

didInsertElement: function () {
this.send('initUploader');
},

willDestroyElement: function () {
this.removeListeners();
},

actions: {
initUploader: function () {
var ref,
el,
el = this.$(),
self = this;

el = this.$();
ref = uploader.call(el, {
editor: true,
fileStorage: this.get('config.fileStorage')
});

el.on('uploadsuccess', function (event, result) {
if (result && result !== '' && result !== 'http://') {
self.sendAction('uploaded', result);
Ember.run(self, function () {
this.sendAction('uploaded', result);
});
}
});

el.on('imagecleared', function () {
self.sendAction('canceled');
});
el.on('imagecleared', Ember.run.bind(self, 'sendAction', 'canceled'));

this.sendAction('initUploader', ref);
}
Expand Down
14 changes: 10 additions & 4 deletions core/client/app/controllers/modals/delete-tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ import Ember from 'ember';

export default Ember.Controller.extend({
notifications: Ember.inject.service(),
application: Ember.inject.controller(),

postInflection: Ember.computed('model.post_count', function () {
return this.get('model.post_count') > 1 ? 'posts' : 'post';
}),

actions: {
confirmAccept: function () {
var tag = this.get('model'),
self = this;
var tag = this.get('model');

this.send('closeMenus');

tag.destroyRecord().catch(function (error) {
self.get('notifications').showAPIError(error, {key: 'tag.delete'});
tag.destroyRecord().then(() => {
let currentRoute = this.get('application.currentRouteName') || '';

if (currentRoute.match(/^settings\.tags/)) {
this.transitionToRoute('settings.tags.index');
}
}).catch((error) => {
this.get('notifications').showAPIError(error, {key: 'tag.delete'});
});
},

Expand Down
Loading

0 comments on commit bc346d2

Please sign in to comment.