Support for custom messages and redirects when creating posts (#8434)

* Support for custom messages and redirects when creating posts

When a post/topic is created Discourse serializes a `NewPostResult`
object. Normally this contains a status like `created_post` or
errors describing why the post could not be created.

There are times when a plugin might want to take the inputted post
and do something in the background. In this case, the plugin
can return a custom `message` and `route_to` attribute in the
`NewPostResult`.

If present, the message will be displayed in an alert, and when "Ok" is
clicked the user will be routed to the new URL.

* Destroy the draft in parallel
This commit is contained in:
Robin Ward 2019-11-29 09:30:54 -05:00 committed by GitHub
parent 1e0c2235a3
commit 7fee3c61de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 1 deletions

View File

@ -709,6 +709,17 @@ export default Controller.extend({
if (result.responseJson.action === "create_post") {
this.appEvents.trigger("post:highlight", result.payload.post_number);
}
if (result.responseJson.route_to) {
this.destroyDraft();
if (result.responseJson.message) {
return bootbox.alert(result.responseJson.message, () => {
DiscourseURL.routeTo(result.responseJson.route_to);
});
}
return DiscourseURL.routeTo(result.responseJson.route_to);
}
this.close();
const currentUser = this.currentUser;

View File

@ -6,7 +6,9 @@ class NewPostResultSerializer < ApplicationSerializer
:errors,
:success,
:pending_count,
:reason
:reason,
:message,
:route_to
has_one :pending_post, serializer: TopicPendingPostSerializer, root: false, embed: :objects
@ -64,4 +66,20 @@ class NewPostResultSerializer < ApplicationSerializer
pending_count.present?
end
def route_to
object.route_to
end
def include_route_to?
object.route_to.present?
end
def message
object.message
end
def include_message?
object.message.present?
end
end

View File

@ -9,6 +9,8 @@ class NewPostResult
attr_accessor :post
attr_accessor :reviewable
attr_accessor :pending_count
attr_accessor :route_to
attr_accessor :message
def initialize(action, success = false)
@action = action

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
require 'rails_helper'
describe NewPostResultSerializer do
it "includes the message and route_to if present" do
result = NewPostResult.new(:custom, true)
result.message = 'hello :)'
result.route_to = "/cool-route"
serializer = described_class.new(result)
expect(serializer.success).to eq(true)
expect(serializer.message).to eq('hello :)')
expect(serializer.route_to).to eq('/cool-route')
end
end

View File

@ -234,6 +234,26 @@ QUnit.test("Create an enqueued Topic", async assert => {
assert.ok(invisible(".d-modal"), "the modal can be dismissed");
});
QUnit.test("Can display a message and route to a URL", async assert => {
await visit("/");
await click("#create-topic");
await fillIn("#reply-title", "This title doesn't matter");
await fillIn(".d-editor-input", "custom message");
await click("#reply-control button.create");
assert.equal(
find(".bootbox .modal-body").text(),
"This is a custom response"
);
assert.equal(currentURL(), "/", "it doesn't change routes");
await click(".bootbox .btn-primary");
assert.equal(
currentURL(),
"/faq",
"can navigate to a `route_to` destination"
);
});
QUnit.test("Create a Reply", async assert => {
await visit("/t/internationalization-localization/280");

View File

@ -497,6 +497,15 @@ export default function() {
});
}
if (data.raw === "custom message") {
return response(200, {
success: true,
action: "custom",
message: "This is a custom response",
route_to: "/faq"
});
}
return response(200, {
success: true,
action: "create_post",