mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 15:48:43 -05:00
Refactor topic title/category saving to support easier changing of
attributes via plugins.
This commit is contained in:
parent
9523b26af2
commit
7182767349
8 changed files with 49 additions and 86 deletions
|
@ -1,7 +1,8 @@
|
|||
import ObjectController from 'discourse/controllers/object';
|
||||
import BufferedContent from 'discourse/mixins/buffered-content';
|
||||
import { spinnerHTML } from 'discourse/helpers/loading-spinner';
|
||||
|
||||
export default ObjectController.extend(Discourse.SelectedPostsCount, {
|
||||
export default ObjectController.extend(Discourse.SelectedPostsCount, BufferedContent, {
|
||||
multiSelect: false,
|
||||
needs: ['header', 'modal', 'composer', 'quote-button', 'search', 'topic-progress', 'application'],
|
||||
allPostsSelected: false,
|
||||
|
@ -235,11 +236,6 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, {
|
|||
this.set('allPostsSelected', false);
|
||||
},
|
||||
|
||||
/**
|
||||
Toggle a participant for filtering
|
||||
|
||||
@method toggleParticipant
|
||||
**/
|
||||
toggleParticipant: function(user) {
|
||||
this.get('postStream').toggleParticipant(Em.get(user, 'username'));
|
||||
},
|
||||
|
@ -247,17 +243,13 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, {
|
|||
editTopic: function() {
|
||||
if (!this.get('details.can_edit')) return false;
|
||||
|
||||
this.setProperties({
|
||||
editingTopic: true,
|
||||
newTitle: this.get('title'),
|
||||
newCategoryId: this.get('category_id')
|
||||
});
|
||||
this.set('editingTopic', true);
|
||||
return false;
|
||||
},
|
||||
|
||||
// close editing mode
|
||||
cancelEditingTopic: function() {
|
||||
this.set('editingTopic', false);
|
||||
this.rollbackBuffer();
|
||||
},
|
||||
|
||||
toggleMultiSelect: function() {
|
||||
|
@ -265,39 +257,25 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, {
|
|||
},
|
||||
|
||||
finishedEditingTopic: function() {
|
||||
if (this.get('editingTopic')) {
|
||||
if (!this.get('editingTopic')) { return; }
|
||||
|
||||
var topic = this.get('model');
|
||||
// save the modifications
|
||||
var self = this,
|
||||
props = this.get('buffered.buffer');
|
||||
|
||||
// Topic title hasn't been sanitized yet, so the template shouldn't trust it.
|
||||
this.set('topicSaving', true);
|
||||
|
||||
// manually update the titles & category
|
||||
var backup = topic.setPropertiesBackup({
|
||||
title: this.get('newTitle'),
|
||||
category_id: parseInt(this.get('newCategoryId'), 10),
|
||||
fancy_title: this.get('newTitle')
|
||||
});
|
||||
|
||||
// save the modifications
|
||||
var self = this;
|
||||
topic.save().then(function(result){
|
||||
// update the title if it has been changed (cleaned up) server-side
|
||||
topic.setProperties(Em.getProperties(result.basic_topic, 'title', 'fancy_title'));
|
||||
self.set('topicSaving', false);
|
||||
}, function(error) {
|
||||
self.setProperties({ editingTopic: true, topicSaving: false });
|
||||
topic.setProperties(backup);
|
||||
if (error && error.responseText) {
|
||||
bootbox.alert($.parseJSON(error.responseText).errors[0]);
|
||||
} else {
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
}
|
||||
});
|
||||
|
||||
// close editing mode
|
||||
Discourse.Topic.update(this.get('model'), props).then(function() {
|
||||
self.set('editingTopic', false);
|
||||
}
|
||||
}).catch(function(error) {
|
||||
if (error && error.responseText) {
|
||||
bootbox.alert($.parseJSON(error.responseText).errors[0]);
|
||||
} else {
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
}
|
||||
}).finally(function() {
|
||||
// Note we even roll back on success here because `update` saves
|
||||
// the properties to the topic.
|
||||
self.rollbackBuffer();
|
||||
});
|
||||
},
|
||||
|
||||
toggledSelectedPost: function(post) {
|
||||
|
|
|
@ -463,13 +463,10 @@ Discourse.Composer = Discourse.Model.extend({
|
|||
|
||||
// Update the title if we've changed it
|
||||
if (this.get('title') && post.get('post_number') === 1) {
|
||||
var topic = this.get('topic');
|
||||
topic.setProperties({
|
||||
Discourse.Topic.update(this.get('topic'), {
|
||||
title: this.get('title'),
|
||||
fancy_title: Handlebars.Utils.escapeExpression(this.get('title')),
|
||||
category_id: parseInt(this.get('categoryId'), 10)
|
||||
category_id: this.get('categoryId')
|
||||
});
|
||||
topic.save();
|
||||
}
|
||||
|
||||
post.setProperties({
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
Discourse.Model = Ember.Object.extend(Discourse.Presence, {
|
||||
// Like `setProperties` but returns the original values in case
|
||||
// we want to roll back
|
||||
setPropertiesBackup: function(obj) {
|
||||
var backup = this.getProperties(Ember.keys(obj));
|
||||
this.setProperties(obj);
|
||||
return backup;
|
||||
}
|
||||
});
|
||||
Discourse.Model = Ember.Object.extend(Discourse.Presence);
|
||||
|
||||
Discourse.Model.reopenClass({
|
||||
extractByKey: function(collection, klass) {
|
||||
|
|
|
@ -202,23 +202,6 @@ Discourse.Topic = Discourse.Model.extend({
|
|||
});
|
||||
},
|
||||
|
||||
// Save any changes we've made to the model
|
||||
save: function() {
|
||||
// Don't save unless we can
|
||||
if (!this.get('details.can_edit')) return;
|
||||
|
||||
var data = { title: this.get('title') };
|
||||
|
||||
if(this.get('category')){
|
||||
data.category_id = this.get('category.id');
|
||||
}
|
||||
|
||||
return Discourse.ajax(this.get('url'), {
|
||||
type: 'PUT',
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Invite a user to this topic
|
||||
|
||||
|
@ -373,6 +356,17 @@ Discourse.Topic.reopenClass({
|
|||
}
|
||||
},
|
||||
|
||||
update: function(topic, props) {
|
||||
return Discourse.ajax(topic.get('url'), { type: 'PUT', data: props }).then(function(result) {
|
||||
|
||||
// The title can be cleaned up server side
|
||||
props.title = result.basic_topic.title;
|
||||
props.fancy_title = result.basic_topic.fancy_title;
|
||||
|
||||
topic.setProperties(props);
|
||||
});
|
||||
},
|
||||
|
||||
create: function() {
|
||||
var result = this._super.apply(this, arguments);
|
||||
this.createActionSummary(result);
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
{{#if editingTopic}}
|
||||
{{#if isPrivateMessage}}
|
||||
<span class="private-message-glyph">{{fa-icon envelope}}</span>
|
||||
{{autofocus-text-field id='edit-title' value=newTitle maxLength=maxTitleLength}}
|
||||
{{autofocus-text-field id='edit-title' value=buffered.title maxLength=maxTitleLength}}
|
||||
{{else}}
|
||||
{{autofocus-text-field id='edit-title' value=newTitle maxLength=maxTitleLength}}
|
||||
{{autofocus-text-field id='edit-title' value=buffered.title maxLength=maxTitleLength}}
|
||||
</br>
|
||||
{{category-chooser valueAttribute="id" value=newCategoryId source=category_id}}
|
||||
{{category-chooser valueAttribute="id" value=buffered.category_id source=buffered.category_id}}
|
||||
{{/if}}
|
||||
|
||||
<button class='btn btn-primary btn-small no-text' {{action "finishedEditingTopic"}}>{{fa-icon check}}</button>
|
||||
|
@ -34,11 +34,7 @@
|
|||
{{#if details.loaded}}
|
||||
{{topic-status topic=model}}
|
||||
<a href='{{unbound url}}' {{action "jumpTop"}}>
|
||||
{{#if topicSaving}}
|
||||
{{fancy_title}}
|
||||
{{else}}
|
||||
{{{fancy_title}}}
|
||||
{{/if}}
|
||||
{{{fancy_title}}}
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ export default ComboboxView.extend({
|
|||
overrideWidths: true,
|
||||
dataAttributes: ['id', 'description_text'],
|
||||
valueBinding: Ember.Binding.oneWay('source'),
|
||||
castInteger: true,
|
||||
|
||||
content: function() {
|
||||
var scopedCategoryId = this.get('scopedCategoryId');
|
||||
|
|
|
@ -63,7 +63,7 @@ export default Discourse.View.extend({
|
|||
this.rerender();
|
||||
}.observes('content.@each'),
|
||||
|
||||
didInsertElement: function() {
|
||||
_initializeCombo: function() {
|
||||
var $elem = this.$(),
|
||||
self = this;
|
||||
|
||||
|
@ -75,10 +75,15 @@ export default Discourse.View.extend({
|
|||
|
||||
$elem.select2({formatResult: this.template, minimumResultsForSearch: 5, width: 'resolve'});
|
||||
|
||||
var castInteger = this.get('castInteger');
|
||||
$elem.on("change", function (e) {
|
||||
self.set('value', $(e.target).val());
|
||||
var val = $(e.target).val();
|
||||
if (val.length && castInteger) {
|
||||
val = parseInt(val, 10);
|
||||
}
|
||||
self.set('value', val);
|
||||
});
|
||||
},
|
||||
}.on('didInsertElement'),
|
||||
|
||||
willClearRender: function() {
|
||||
var elementId = "s2id_" + this.$().attr('id');
|
||||
|
|
|
@ -28,8 +28,8 @@ test("editingMode", function() {
|
|||
topicController.set('model.details.can_edit', true);
|
||||
topicController.send('editTopic');
|
||||
ok(topicController.get('editingTopic'), "calling editTopic enables editing if the user can edit");
|
||||
equal(topicController.get('newTitle'), topic.get('title'));
|
||||
equal(topicController.get('newCategoryId'), topic.get('category_id'));
|
||||
equal(topicController.get('buffered.title'), topic.get('title'));
|
||||
equal(topicController.get('buffered.category_id'), topic.get('category_id'));
|
||||
|
||||
topicController.send('cancelEditingTopic');
|
||||
ok(!topicController.get('editingTopic'), "cancelling edit mode reverts the property value");
|
||||
|
|
Loading…
Reference in a new issue