DEV: Allow `freeze_original` argument in topics controller & JS transformer (#30120)
PostMover has a new option called freeze_original implemented in this commit. It was previously unexposed in the controller. This PR permits the param in the controller, and passes it into PostMover. Also, this applies a value transformer for move/merge payload options. In addition a plugin outlet in the move post modal. This allows plugins to add content to the modal, which can modify the payload (and use the freeze_original argument for example)
This commit is contained in:
parent
555ca4da55
commit
68e57190df
|
@ -131,6 +131,8 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<PluginOutlet @name="move-to-topic-after-radio-buttons" />
|
||||||
|
|
||||||
{{#if this.existingTopic}}
|
{{#if this.existingTopic}}
|
||||||
<p>
|
<p>
|
||||||
{{html-safe
|
{{html-safe
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { tracked } from "@glimmer/tracking";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { service } from "@ember/service";
|
import { service } from "@ember/service";
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
|
import { applyValueTransformer } from "discourse/lib/transformer";
|
||||||
import DiscourseURL from "discourse/lib/url";
|
import DiscourseURL from "discourse/lib/url";
|
||||||
import { mergeTopic, movePosts } from "discourse/models/topic";
|
import { mergeTopic, movePosts } from "discourse/models/topic";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
@ -145,6 +146,15 @@ export default class MoveToTopic extends Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mergeOptions = applyValueTransformer(
|
||||||
|
"move-to-topic-merge-options",
|
||||||
|
mergeOptions
|
||||||
|
);
|
||||||
|
moveOptions = applyValueTransformer(
|
||||||
|
"move-to-topic-move-options",
|
||||||
|
moveOptions
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let result;
|
let result;
|
||||||
if (this.args.model.selectedAllPosts) {
|
if (this.args.model.selectedAllPosts) {
|
||||||
|
|
|
@ -13,6 +13,8 @@ export const VALUE_TRANSFORMERS = Object.freeze([
|
||||||
"invite-simple-mode-topic",
|
"invite-simple-mode-topic",
|
||||||
"mentions-class",
|
"mentions-class",
|
||||||
"more-topics-tabs",
|
"more-topics-tabs",
|
||||||
|
"move-to-topic-merge-options",
|
||||||
|
"move-to-topic-move-options",
|
||||||
"parent-category-row-class-mobile",
|
"parent-category-row-class-mobile",
|
||||||
"parent-category-row-class",
|
"parent-category-row-class",
|
||||||
"post-menu-buttons",
|
"post-menu-buttons",
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { click, fillIn, visit } from "@ember/test-helpers";
|
||||||
|
import { test } from "qunit";
|
||||||
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
|
import pretender, {
|
||||||
|
parsePostData,
|
||||||
|
response,
|
||||||
|
} from "discourse/tests/helpers/create-pretender";
|
||||||
|
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
|
||||||
|
acceptance("Modal - move-to-topic", function (needs) {
|
||||||
|
needs.user({ admin: true });
|
||||||
|
|
||||||
|
test("Transformer can modify merge/move options sent in request", async function (assert) {
|
||||||
|
withPluginApi("1.24.0", (api) => {
|
||||||
|
["move-to-topic-merge-options", "move-to-topic-move-options"].forEach(
|
||||||
|
(transformerName) => {
|
||||||
|
api.registerValueTransformer(transformerName, (transformer) => {
|
||||||
|
transformer.value.sillyVal = true;
|
||||||
|
return transformer.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await visit("/t/internationalization-localization/280");
|
||||||
|
|
||||||
|
// Open admin menu, select a post, and open move to topic modal
|
||||||
|
await click(".topic-admin-menu-trigger");
|
||||||
|
await click(".topic-admin-menu-content .topic-admin-multi-select button");
|
||||||
|
await click(".select-posts .select-post");
|
||||||
|
await click(".selected-posts .move-to-topic");
|
||||||
|
|
||||||
|
// Choose existing topic, and pick the first topic.
|
||||||
|
await click("input#move-to-existing-topic");
|
||||||
|
await fillIn("input#choose-topic-title", 1);
|
||||||
|
await click(".choose-topic-list .existing-topic input");
|
||||||
|
|
||||||
|
pretender.post("/t/280/move-posts", (request) => {
|
||||||
|
assert.step("request");
|
||||||
|
const data = parsePostData(request.requestBody);
|
||||||
|
assert.strictEqual(data.sillyVal, "true");
|
||||||
|
return response({ success: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Submit!
|
||||||
|
await click(".d-modal__footer .btn-primary");
|
||||||
|
assert.verifySteps(["request"]);
|
||||||
|
});
|
||||||
|
});
|
|
@ -857,6 +857,7 @@ class TopicsController < ApplicationController
|
||||||
params.permit(:participants)
|
params.permit(:participants)
|
||||||
params.permit(:chronological_order)
|
params.permit(:chronological_order)
|
||||||
params.permit(:archetype)
|
params.permit(:archetype)
|
||||||
|
params.permit(:freeze_original)
|
||||||
|
|
||||||
raise Discourse::InvalidAccess if params[:archetype] == "private_message" && !guardian.is_staff?
|
raise Discourse::InvalidAccess if params[:archetype] == "private_message" && !guardian.is_staff?
|
||||||
|
|
||||||
|
@ -869,6 +870,7 @@ class TopicsController < ApplicationController
|
||||||
args = {}
|
args = {}
|
||||||
args[:destination_topic_id] = destination_topic_id.to_i
|
args[:destination_topic_id] = destination_topic_id.to_i
|
||||||
args[:chronological_order] = params[:chronological_order] == "true"
|
args[:chronological_order] = params[:chronological_order] == "true"
|
||||||
|
args[:freeze_original] = params[:freeze_original] == "true"
|
||||||
|
|
||||||
if params[:archetype].present?
|
if params[:archetype].present?
|
||||||
args[:archetype] = params[:archetype]
|
args[:archetype] = params[:archetype]
|
||||||
|
@ -891,6 +893,7 @@ class TopicsController < ApplicationController
|
||||||
params.permit(:participants)
|
params.permit(:participants)
|
||||||
params.permit(:chronological_order)
|
params.permit(:chronological_order)
|
||||||
params.permit(:archetype)
|
params.permit(:archetype)
|
||||||
|
params.permit(:freeze_original)
|
||||||
|
|
||||||
topic = Topic.with_deleted.find_by(id: topic_id)
|
topic = Topic.with_deleted.find_by(id: topic_id)
|
||||||
guardian.ensure_can_move_posts!(topic)
|
guardian.ensure_can_move_posts!(topic)
|
||||||
|
@ -1399,6 +1402,7 @@ class TopicsController < ApplicationController
|
||||||
].present?
|
].present?
|
||||||
args[:tags] = params[:tags] if params[:tags].present?
|
args[:tags] = params[:tags] if params[:tags].present?
|
||||||
args[:chronological_order] = params[:chronological_order] == "true"
|
args[:chronological_order] = params[:chronological_order] == "true"
|
||||||
|
args[:freeze_original] = true if params[:freeze_original] == "true"
|
||||||
|
|
||||||
if params[:archetype].present?
|
if params[:archetype].present?
|
||||||
args[:archetype] = params[:archetype]
|
args[:archetype] = params[:archetype]
|
||||||
|
|
|
@ -1298,6 +1298,9 @@ class Topic < ActiveRecord::Base
|
||||||
moved_by,
|
moved_by,
|
||||||
post_ids,
|
post_ids,
|
||||||
move_to_pm: opts[:archetype].present? && opts[:archetype] == "private_message",
|
move_to_pm: opts[:archetype].present? && opts[:archetype] == "private_message",
|
||||||
|
options: {
|
||||||
|
freeze_original: opts[:freeze_original],
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if opts[:destination_topic_id]
|
if opts[:destination_topic_id]
|
||||||
|
|
|
@ -166,6 +166,21 @@ RSpec.describe TopicsController do
|
||||||
expect(Tag.all.pluck(:name)).to include("foo", "bar")
|
expect(Tag.all.pluck(:name)).to include("foo", "bar")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "with freeze_original param" do
|
||||||
|
it "duplicates post to new topic and keeps original post in place" do
|
||||||
|
expect do
|
||||||
|
post "/t/#{topic.id}/move-posts.json",
|
||||||
|
params: {
|
||||||
|
title: "Logan is a good movie",
|
||||||
|
post_ids: [p2.id],
|
||||||
|
freeze_original: true,
|
||||||
|
}
|
||||||
|
end.to change { Topic.count }.by(1)
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(topic.post_ids).to include(p2.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "when topic has been deleted" do
|
describe "when topic has been deleted" do
|
||||||
it "should still be able to move posts" do
|
it "should still be able to move posts" do
|
||||||
PostDestroyer.new(admin, topic.first_post).destroy
|
PostDestroyer.new(admin, topic.first_post).destroy
|
||||||
|
@ -308,6 +323,22 @@ RSpec.describe TopicsController do
|
||||||
expect(result["url"]).to be_present
|
expect(result["url"]).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "with freeze_original param" do
|
||||||
|
it "duplicates post to topic and keeps original post in place" do
|
||||||
|
expect do
|
||||||
|
post "/t/#{topic.id}/move-posts.json",
|
||||||
|
params: {
|
||||||
|
post_ids: [p2.id],
|
||||||
|
destination_topic_id: dest_topic.id,
|
||||||
|
freeze_original: true,
|
||||||
|
}
|
||||||
|
end.to change { dest_topic.posts.count }.by(1)
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(topic.post_ids).to include(p2.id)
|
||||||
|
expect(dest_topic.posts.find_by(raw: p2.raw)).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "triggers an event on merge" do
|
it "triggers an event on merge" do
|
||||||
begin
|
begin
|
||||||
called = false
|
called = false
|
||||||
|
|
Loading…
Reference in New Issue