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"); + }); +});