diff --git a/app/assets/javascripts/discourse/components/queued-post.js.es6 b/app/assets/javascripts/discourse/components/queued-post.js.es6
index 9629724b438..bd1e3292d14 100644
--- a/app/assets/javascripts/discourse/components/queued-post.js.es6
+++ b/app/assets/javascripts/discourse/components/queued-post.js.es6
@@ -17,10 +17,42 @@ function updateState(state, opts) {
};
}
-export default Ember.Component.extend(bufferedProperty('post'), {
+export default Ember.Component.extend(bufferedProperty('editables'), {
editing: propertyEqual('post', 'currentlyEditing'),
+ editables: {},
_confirmDelete: updateState('rejected', {deleteUser: true}),
+ _initEditables: function() {
+ const post = this.get('post');
+ const postOptions = post.get('post_options');
+
+ this.set('editables.raw', post.get('raw'));
+ this.set('editables.category', post.get('category'));
+ this.set('editables.category_id', post.get('category.id'));
+ this.set('editables.title', postOptions.title);
+ this.set('editables.tags', postOptions.tags);
+ }.on('init'),
+
+ _categoryChanged: function() {
+ this.set('buffered.category', Discourse.Category.findById(this.get('buffered.category_id')));
+ }.observes('buffered.category_id'),
+
+ editTitleAndCategory: function() {
+ return this.get('editing') && !this.get('post.topic');
+ }.property('editing'),
+
+ tags: function() {
+ return this.get('editables.tags') || this.get('post.topic.tags') || [];
+ }.property('editables.tags'),
+
+ showTags: function() {
+ return this.siteSettings.tagging_enabled && !this.get('editing') && this.get('tags').length > 0;
+ }.property('editing', 'tags'),
+
+ editTags: function() {
+ return this.siteSettings.tagging_enabled && this.get('editing') && !this.get('post.topic');
+ }.property('editing'),
+
actions: {
approve: updateState('approved'),
reject: updateState('rejected'),
@@ -38,7 +70,14 @@ export default Ember.Component.extend(bufferedProperty('post'), {
},
confirmEdit() {
- this.get('post').update({ raw: this.get('buffered.raw') }).then(() => {
+ const buffered = this.get('buffered');
+
+ this.get('post').update(buffered.getProperties(
+ 'raw',
+ 'title',
+ 'tags',
+ 'category_id'
+ )).then(() => {
this.commitBuffer();
this.set('currentlyEditing', null);
});
diff --git a/app/assets/javascripts/discourse/templates/components/queued-post.hbs b/app/assets/javascripts/discourse/templates/components/queued-post.hbs
index 78a7723ab6b..e0bbe42ac7f 100644
--- a/app/assets/javascripts/discourse/templates/components/queued-post.hbs
+++ b/app/assets/javascripts/discourse/templates/components/queued-post.hbs
@@ -20,24 +20,41 @@
-
- {{i18n "queue.topic"}}
- {{#if post.topic}}
- {{topic-link post.topic}}
- {{else}}
- {{post.post_options.title}}
- {{/if}}
- {{category-badge post.category}}
-
+ {{#if editTitleAndCategory}}
+
+ {{text-field value=buffered.title maxlength=siteSettings.max_topic_title_length}}
+
+ {{category-chooser value=buffered.category_id}}
+ {{else}}
+
+ {{i18n "queue.topic"}}
+ {{#if post.topic}}
+ {{topic-link post.topic}}
+ {{else}}
+ {{editables.title}}
+ {{/if}}
+ {{category-badge editables.category}}
+
+ {{/if}}
{{#if editing}}
{{d-editor value=buffered.raw}}
{{else}}
- {{cook-text post.raw}}
+ {{cook-text editables.raw}}
{{/if}}
+ {{#if showTags}}
+
+ {{#each tags as |t|}}
+ {{discourse-tag t}}
+ {{/each}}
+
+ {{else if editTags}}
+ {{tag-chooser tags=buffered.tags categoryId=buffered.category_id width='100%'}}
+ {{/if}}
+
{{#if editing}}
{{d-button action="confirmEdit"
diff --git a/app/controllers/queued_posts_controller.rb b/app/controllers/queued_posts_controller.rb
index 888ef0ddc2a..55a086f5c6c 100644
--- a/app/controllers/queued_posts_controller.rb
+++ b/app/controllers/queued_posts_controller.rb
@@ -20,10 +20,17 @@ class QueuedPostsController < ApplicationController
def update
qp = QueuedPost.where(id: params[:id]).first
- if params[:queued_post][:raw].present?
- qp.update_column(:raw, params[:queued_post][:raw])
+ update_params = params[:queued_post]
+
+ qp.raw = update_params[:raw] if update_params[:raw].present?
+ unless qp.topic_id
+ qp.post_options['title'] = update_params[:title] if update_params[:title].present?
+ qp.post_options['category'] = update_params[:category_id].to_i if update_params[:category_id].present?
+ qp.post_options['tags'] = update_params[:tags] if update_params[:tags].present?
end
+ qp.save(validate: false)
+
state = params[:queued_post][:state]
begin
if state == 'approved'
diff --git a/spec/controllers/queued_posts_controller_spec.rb b/spec/controllers/queued_posts_controller_spec.rb
index ed4782ebdac..590e988a010 100644
--- a/spec/controllers/queued_posts_controller_spec.rb
+++ b/spec/controllers/queued_posts_controller_spec.rb
@@ -27,7 +27,7 @@ describe QueuedPostsController do
end
end
- context 'update' do
+ describe '#update' do
let!(:user) { log_in(:moderator) }
let(:qp) { Fabricate(:queued_post) }
@@ -43,7 +43,7 @@ describe QueuedPostsController do
end
context 'rejected' do
- it 'updates the post to approved' do
+ it 'updates the post to rejected' do
xhr :put, :update, id: qp.id, queued_post: { state: 'rejected' }
expect(response).to be_success
@@ -53,5 +53,66 @@ describe QueuedPostsController do
end
end
+ context 'editing content' do
+ let(:changes) do
+ {
+ raw: 'new raw',
+ title: 'new title',
+ category_id: 10,
+ tags: ['new_tag']
+ }
+ end
+
+ context 'when it is a topic' do
+ let(:queued_topic) { Fabricate(:queued_topic) }
+
+ before do
+ xhr :put, :update, id: queued_topic.id, queued_post: changes
+ expect(response).to be_success
+ end
+
+ it 'updates raw' do
+ expect(queued_topic.reload.raw).to eq(changes[:raw])
+ end
+
+ it 'updates the title' do
+ expect(queued_topic.reload.post_options['title']).to eq(changes[:title])
+ end
+
+ it 'updates the category' do
+ expect(queued_topic.reload.post_options['category']).to eq(changes[:category_id])
+ end
+
+ it 'updates the tags' do
+ expect(queued_topic.reload.post_options['tags']).to eq(changes[:tags])
+ end
+ end
+
+ context 'when it is a reply' do
+ let(:queued_reply) { Fabricate(:queued_post) }
+
+ before do
+ xhr :put, :update, id: queued_reply.id, queued_post: changes
+ expect(response).to be_success
+ end
+
+ it 'updates raw' do
+ expect(queued_reply.reload.raw).to eq(changes[:raw])
+ end
+
+ it 'does not update the title' do
+ expect(queued_reply.reload.post_options['title']).to be_nil
+ end
+
+ it 'does not update the category' do
+ original_category = queued_reply.post_options['category']
+ expect(queued_reply.reload.post_options['category']).to eq(original_category)
+ end
+
+ it 'does not update the tags' do
+ expect(queued_reply.reload.post_options['tags']).to be_nil
+ end
+ end
+ end
end
end
diff --git a/spec/fabricators/queued_post_fabricator.rb b/spec/fabricators/queued_post_fabricator.rb
index acfea91792d..b61680a8b1d 100644
--- a/spec/fabricators/queued_post_fabricator.rb
+++ b/spec/fabricators/queued_post_fabricator.rb
@@ -15,3 +15,12 @@ Fabricator(:queued_post) do
image_sizes: { "http://foo.bar/image.png" => { "width" => 0, "height" => 222 } } }
end
end
+
+Fabricator(:queued_topic, from: :queued_post) do
+ topic nil
+ raw 'This post should be queued up, and more importantly, this is a new topic'
+ post_options do
+ { category: 1,
+ title: 'This is a new topic' }
+ end
+end
diff --git a/test/javascripts/acceptance/queued-posts-test.js.es6 b/test/javascripts/acceptance/queued-posts-test.js.es6
new file mode 100644
index 00000000000..1dcffd1a5ef
--- /dev/null
+++ b/test/javascripts/acceptance/queued-posts-test.js.es6
@@ -0,0 +1,47 @@
+import { acceptance } from "helpers/qunit-helpers";
+
+acceptance("Queued Posts", {
+ loggedIn: true,
+ settings: { tagging_enabled: true }
+});
+
+QUnit.test("For topics: body of post, title, category and tags are all editbale", assert => {
+ server.get("/queued_posts", () => { //eslint-disable-line no-undef
+ return [
+ 200,
+ {"Content-Type": "application/json"},
+ {"users":[{"id":3,"username":"test_user","avatar_template":"/letter_avatar_proxy/v2/letter/t/eada6e/{size}.png","active":true,"admin":false,"moderator":false,"last_seen_at":"2017-08-11T20:48:05.405Z","last_emailed_at":null,"created_at":"2017-08-07T02:23:33.309Z","last_seen_age":"1d","last_emailed_age":null,"created_at_age":"6d","username_lower":"test_user","trust_level":0,"trust_level_locked":false,"flag_level":0,"title":null,"suspended_at":null,"suspended_till":null,"suspended":null,"blocked":false,"time_read":"19m","staged":false,"days_visited":4,"posts_read_count":12,"topics_entered":6,"post_count":2}],"queued_posts":[{"id":22,"queue":"default","user_id":3,"state":1,"topic_id":null,"approved_by_id":null,"rejected_by_id":null,"raw":"some content","post_options":{"archetype":"regular","category":"1","typing_duration_msecs":"3200","composer_open_duration_msecs":"19007","visible":true,"is_warning":false,"title":"a new topic that needs to be reviewed","ip_address":"172.17.0.1","first_post_checks":true,"is_poll":true},"created_at":"2017-08-11T20:43:41.115Z","category_id":1,"can_delete_user":true}],"__rest_serializer":"1","refresh_queued_posts":"/queued_posts?status=new"}
+ ];
+ });
+
+ visit("/queued-posts");
+ click(".queued-posts .queued-post button.edit");
+
+ andThen(() => {
+ assert.ok(exists(".d-editor-container"), "the body should be editable");
+ assert.ok(exists(".edit-title .ember-text-field"), "the title should be editable");
+ assert.ok(exists(".category-combobox"), "category should be editbale");
+ assert.ok(exists(".tag-chooser"), "tags should be editable");
+ });
+});
+
+
+QUnit.test("For replies: only the body of post is editbale", assert => {
+ server.get("/queued_posts", () => { //eslint-disable-line no-undef
+ return [
+ 200,
+ {"Content-Type": "application/json"},
+ {"users":[{"id":3,"username":"test_user","avatar_template":"/letter_avatar_proxy/v2/letter/t/eada6e/{size}.png","active":true,"admin":false,"moderator":false,"last_seen_at":"2017-08-11T20:48:05.405Z","last_emailed_at":null,"created_at":"2017-08-07T02:23:33.309Z","last_seen_age":"1d","last_emailed_age":null,"created_at_age":"6d","username_lower":"test_user","trust_level":0,"trust_level_locked":false,"flag_level":0,"title":null,"suspended_at":null,"suspended_till":null,"suspended":null,"blocked":false,"time_read":"19m","staged":false,"days_visited":4,"posts_read_count":12,"topics_entered":6,"post_count":2}],"topics":[{"id":11,"title":"This is a topic","fancy_title":"This is a topic","slug":"this-is-a-topic","posts_count":2}],"queued_posts":[{"id":4,"queue":"default","user_id":3,"state":1,"topic_id":11,"approved_by_id":null,"rejected_by_id":null,"raw":"edited haahaasdfasdfasdfasdf","post_options":{"archetype":"regular","category":"3","reply_to_post_number":"2","typing_duration_msecs":"1900","composer_open_duration_msecs":"12096","visible":true,"is_warning":false,"featured_link":"","ip_address":"172.17.0.1","first_post_checks":true,"is_poll":true},"created_at":"2017-08-07T19:11:52.018Z","category_id":3,"can_delete_user":true}],"__rest_serializer":"1","refresh_queued_posts":"/queued_posts?status=new"}
+ ];
+ });
+
+ visit("/queued-posts");
+ click(".queued-posts .queued-post button.edit");
+
+ andThen(() => {
+ assert.ok(exists(".d-editor-container"), "the body should be editable");
+ assert.notOk(exists(".edit-title .ember-text-field"), "title should not be editbale");
+ assert.notOk(exists(".category-combobox"), "category should not be editable");
+ assert.notOk(exists("div.tag-chooser"), "tags should not be editable");
+ });
+});