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({}); });