diff --git a/app/assets/javascripts/discourse/components/shared-draft-controls.js.es6 b/app/assets/javascripts/discourse/components/shared-draft-controls.js.es6
index a2b11f460b2..a9f35cb8ab2 100644
--- a/app/assets/javascripts/discourse/components/shared-draft-controls.js.es6
+++ b/app/assets/javascripts/discourse/components/shared-draft-controls.js.es6
@@ -1,4 +1,5 @@
import computed from 'ember-addons/ember-computed-decorators';
+import { ajax } from 'discourse/lib/ajax';
export default Ember.Component.extend({
tagName: '',
@@ -11,8 +12,14 @@ export default Ember.Component.extend({
},
actions: {
- publish() {
+ updateDestinationCategory(category) {
+ ajax(`/t/${this.get('topic.id')}/shared-draft`, {
+ method: 'PUT',
+ data: { category_id: category.get('id') }
+ });
+ },
+ publish() {
bootbox.confirm(I18n.t('shared_drafts.confirm_publish'), result => {
if (result) {
this.set('publishing', true);
diff --git a/app/assets/javascripts/discourse/templates/components/shared-draft-controls.hbs b/app/assets/javascripts/discourse/templates/components/shared-draft-controls.hbs
index 056d9d5af54..feeed4be439 100644
--- a/app/assets/javascripts/discourse/templates/components/shared-draft-controls.hbs
+++ b/app/assets/javascripts/discourse/templates/components/shared-draft-controls.hbs
@@ -6,7 +6,9 @@
- {{category-chooser value=topic.destination_category_id}}
+ {{category-chooser
+ value=topic.destination_category_id
+ onChooseCategory=(action "updateDestinationCategory")}}
diff --git a/app/assets/javascripts/select-kit/components/category-chooser.js.es6 b/app/assets/javascripts/select-kit/components/category-chooser.js.es6
index 069ba1a3299..b1e4fedc73a 100644
--- a/app/assets/javascripts/select-kit/components/category-chooser.js.es6
+++ b/app/assets/javascripts/select-kit/components/category-chooser.js.es6
@@ -98,6 +98,12 @@ export default ComboBoxComponent.extend({
this.appEvents.off("composer:resized");
},
+ didSelect(computedContentItem) {
+ if (this.attrs.onChooseCategory) {
+ this.attrs.onChooseCategory(computedContentItem.originalContent);
+ }
+ },
+
computeContent() {
const categories = Discourse.SiteSettings.fixed_category_positions_on_create ?
Category.list() :
diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb
index 457dcaf7220..af3f12c5483 100644
--- a/app/controllers/topics_controller.rb
+++ b/app/controllers/topics_controller.rb
@@ -11,6 +11,7 @@ class TopicsController < ApplicationController
:timings,
:destroy_timings,
:update,
+ :update_shared_draft,
:destroy,
:recover,
:status,
@@ -236,6 +237,17 @@ class TopicsController < ApplicationController
render body: nil
end
+ def update_shared_draft
+ topic = Topic.find_by(id: params[:id])
+ guardian.ensure_can_edit!(topic)
+ guardian.ensure_can_create_shared_draft!
+ raise Discourse::NotFound unless topic.shared_draft.present?
+
+ SharedDraft.where(topic_id: topic.id).update_all(category_id: params[:category_id].to_i)
+
+ render json: success_json
+ end
+
def update
topic = Topic.find_by(id: params[:topic_id])
guardian.ensure_can_edit!(topic)
diff --git a/config/routes.rb b/config/routes.rb
index 587e93ab7d9..a5249b598db 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -599,6 +599,7 @@ Discourse::Application.routes.draw do
put "t/:id/move-to-inbox" => "topics#move_to_inbox"
put "t/:id/convert-topic/:type" => "topics#convert_topic"
put "t/:id/publish" => "topics#publish"
+ put "t/:id/shared-draft" => "topics#update_shared_draft"
put "topics/bulk"
put "topics/reset-new" => 'topics#reset_new'
post "topics/timings"
diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb
index 646a926e3af..b70c38aeed8 100644
--- a/spec/requests/topics_controller_spec.rb
+++ b/spec/requests/topics_controller_spec.rb
@@ -464,6 +464,36 @@ RSpec.describe TopicsController do
SiteSetting.shared_drafts_category = shared_drafts_category.id
end
+ describe "#update_shared_draft" do
+ let(:category) { Fabricate(:category) }
+ let(:other_cat) { Fabricate(:category) }
+ let(:topic) { Fabricate(:topic, category: shared_drafts_category, visible: false) }
+ let!(:shared_draft) { Fabricate(:shared_draft, topic: topic, category: category) }
+ let(:moderator) { Fabricate(:moderator) }
+
+ context "anonymous" do
+ it "doesn't allow staff to update the shared draft" do
+ put "/t/#{topic.id}/shared-draft.json", params: { category_id: other_cat.id }
+ expect(response.code.to_i).to eq(403)
+ topic.reload
+ expect(topic.shared_draft.category_id).to eq(category.id)
+ end
+ end
+
+ context "as a moderator" do
+ before do
+ sign_in(moderator)
+ end
+
+ it "allows staff to update the category id" do
+ put "/t/#{topic.id}/shared-draft.json", params: { category_id: other_cat.id }
+ expect(response).to be_success
+ topic.reload
+ expect(topic.shared_draft.category_id).to eq(other_cat.id)
+ end
+ end
+ end
+
describe "#publish" do
let(:category) { Fabricate(:category) }
let(:topic) { Fabricate(:topic, category: shared_drafts_category, visible: false) }