diff --git a/app/assets/javascripts/discourse/controllers/convert-to-public-topic.js.es6 b/app/assets/javascripts/discourse/controllers/convert-to-public-topic.js.es6
new file mode 100644
index 00000000000..58ccfbcf88a
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/convert-to-public-topic.js.es6
@@ -0,0 +1,26 @@
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import ModalFunctionality from "discourse/mixins/modal-functionality";
+
+export default Ember.Controller.extend(ModalFunctionality, {
+ publicCategoryId: null,
+ saving: true,
+
+ onShow() {
+ this.setProperties({ publicCategoryId: null, saving: false });
+ },
+
+ actions: {
+ makePublic() {
+ let topic = this.model;
+ topic
+ .convertTopic("public", { categoryId: this.publicCategoryId })
+ .then(() => {
+ topic.set("archetype", "regular");
+ topic.set("category_id", this.publicCategoryId);
+ this.appEvents.trigger("header:show-topic", topic);
+ this.send("closeModal");
+ })
+ .catch(popupAjaxError);
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6
index 1e86063b0d7..d4ef29adc9d 100644
--- a/app/assets/javascripts/discourse/controllers/topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/topic.js.es6
@@ -1073,11 +1073,17 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
},
convertToPublicTopic() {
- this.model.convertTopic("public");
+ showModal("convert-to-public-topic", {
+ model: this.model,
+ modalClass: "convert-to-public-topic"
+ });
},
convertToPrivateMessage() {
- this.model.convertTopic("private");
+ this.model
+ .convertTopic("private")
+ .then(() => window.location.reload())
+ .catch(popupAjaxError);
},
removeFeaturedLink() {
diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6
index 4d3056b3bf0..ca2c4350b71 100644
--- a/app/assets/javascripts/discourse/models/topic.js.es6
+++ b/app/assets/javascripts/discourse/models/topic.js.es6
@@ -599,10 +599,12 @@ const Topic = RestModel.extend({
});
},
- convertTopic(type) {
- return ajax(`/t/${this.id}/convert-topic/${type}`, { type: "PUT" })
- .then(() => window.location.reload())
- .catch(popupAjaxError);
+ convertTopic(type, opts) {
+ let args = { type: "PUT" };
+ if (opts && opts.categoryId) {
+ args.data = { category_id: opts.categoryId };
+ }
+ return ajax(`/t/${this.id}/convert-topic/${type}`, args);
},
resetBumpDate() {
diff --git a/app/assets/javascripts/discourse/templates/modal/convert-to-public-topic.hbs b/app/assets/javascripts/discourse/templates/modal/convert-to-public-topic.hbs
new file mode 100644
index 00000000000..b13804bb0b4
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/modal/convert-to-public-topic.hbs
@@ -0,0 +1,13 @@
+{{#d-modal-body title="topic.make_public.title"}}
+
+
+ {{i18n "topic.make_public.choose_category"}}
+
+ {{category-chooser value=publicCategoryId}}
+
+{{/d-modal-body}}
+
+
diff --git a/app/assets/stylesheets/common/components/convert-to-public-topic-modal.scss b/app/assets/stylesheets/common/components/convert-to-public-topic-modal.scss
new file mode 100644
index 00000000000..50a32a81314
--- /dev/null
+++ b/app/assets/stylesheets/common/components/convert-to-public-topic-modal.scss
@@ -0,0 +1,5 @@
+.convert-to-public-topic .modal-body {
+ .instructions {
+ margin-bottom: 1em;
+ }
+}
diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb
index 74789f51d88..8116dfb19e5 100644
--- a/app/controllers/topics_controller.rb
+++ b/app/controllers/topics_controller.rb
@@ -821,7 +821,7 @@ class TopicsController < ApplicationController
guardian.ensure_can_convert_topic!(topic)
if params[:type] == "public"
- converted_topic = topic.convert_to_public_topic(current_user)
+ converted_topic = topic.convert_to_public_topic(current_user, category_id: params[:category_id])
else
converted_topic = topic.convert_to_private_message(current_user)
end
diff --git a/app/models/topic.rb b/app/models/topic.rb
index 648da51a741..cb125080a59 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -1307,8 +1307,8 @@ class Topic < ActiveRecord::Base
builder.query_single.first.to_i
end
- def convert_to_public_topic(user)
- public_topic = TopicConverter.new(self, user).convert_to_public_topic
+ def convert_to_public_topic(user, category_id: nil)
+ public_topic = TopicConverter.new(self, user).convert_to_public_topic(category_id)
add_small_action(user, "public_topic") if public_topic
public_topic
end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index ce1738906e5..c092fd6768d 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -2171,6 +2171,9 @@ en:
title: "Flag"
help: "privately flag this topic for attention or send a private notification about it"
success_message: "You successfully flagged this topic."
+ make_public:
+ title: "Convert to Public Topic"
+ choose_category: "Please choose a category for the public topic:"
feature_topic:
title: "Feature this topic"
diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb
index ad718e80f30..a5440b1e78e 100644
--- a/spec/requests/topics_controller_spec.rb
+++ b/spec/requests/topics_controller_spec.rb
@@ -2230,12 +2230,15 @@ RSpec.describe TopicsController do
end
context "success" do
+ fab!(:category) { Fabricate(:category) }
+
it "returns success" do
sign_in(admin)
- put "/t/#{topic.id}/convert-topic/public.json"
+ put "/t/#{topic.id}/convert-topic/public.json?category_id=#{category.id}"
topic.reload
expect(topic.archetype).to eq(Archetype.default)
+ expect(topic.category_id).to eq(category.id)
expect(response.status).to eq(200)
result = ::JSON.parse(response.body)
diff --git a/test/javascripts/acceptance/topic-test.js.es6 b/test/javascripts/acceptance/topic-test.js.es6
index 0e9c235000c..3a3b6de1fa6 100644
--- a/test/javascripts/acceptance/topic-test.js.es6
+++ b/test/javascripts/acceptance/topic-test.js.es6
@@ -213,6 +213,20 @@ QUnit.test("remove featured link", async assert => {
// assert.ok(!exists('.title-wrapper .topic-featured-link'), 'link is gone');
});
+QUnit.test("Converting to a public topic", async assert => {
+ await visit("/t/test-pm/34");
+ assert.ok(exists(".private_message"));
+ await click(".toggle-admin-menu");
+ await click(".topic-admin-convert button");
+
+ let categoryChooser = selectKit(".convert-to-public-topic .category-chooser");
+ await categoryChooser.expand();
+ await categoryChooser.selectRowByValue(21);
+
+ await click(".convert-to-public-topic .btn-primary");
+ assert.ok(!exists(".private_message"));
+});
+
QUnit.test("Unpinning unlisted topic", async assert => {
await visit("/t/internationalization-localization/280");
diff --git a/test/javascripts/helpers/create-pretender.js.es6 b/test/javascripts/helpers/create-pretender.js.es6
index 64a70ccdb92..781cdb919ce 100644
--- a/test/javascripts/helpers/create-pretender.js.es6
+++ b/test/javascripts/helpers/create-pretender.js.es6
@@ -150,6 +150,10 @@ export default function() {
});
});
+ this.put("/t/34/convert-topic/public", () => {
+ return response({});
+ });
+
this.put("/t/280/make-banner", () => {
return response({});
});