DEV: APIs for plugin to add custom reviewable confirm modal (#12246)
This commit is contained in:
parent
4c1e02d412
commit
4adce0d844
|
@ -12,6 +12,14 @@ import showModal from "discourse/lib/show-modal";
|
|||
|
||||
let _components = {};
|
||||
|
||||
const pluginReviewableParams = {};
|
||||
|
||||
export function addPluginReviewableParam(reviewableType, param) {
|
||||
pluginReviewableParams[reviewableType]
|
||||
? pluginReviewableParams[reviewableType].push(param)
|
||||
: (pluginReviewableParams[reviewableType] = [param]);
|
||||
}
|
||||
|
||||
export default Component.extend({
|
||||
adminTools: optionalService(),
|
||||
tagName: "",
|
||||
|
@ -106,14 +114,23 @@ export default Component.extend({
|
|||
let performAction = () => {
|
||||
let version = reviewable.get("version");
|
||||
this.set("updating", true);
|
||||
|
||||
const data = {
|
||||
send_email: reviewable.sendEmail,
|
||||
reject_reason: reviewable.rejectReason,
|
||||
};
|
||||
|
||||
(pluginReviewableParams[reviewable.type] || []).forEach((param) => {
|
||||
if (reviewable[param]) {
|
||||
data[param] = reviewable[param];
|
||||
}
|
||||
});
|
||||
|
||||
return ajax(
|
||||
`/review/${reviewable.id}/perform/${action.id}?version=${version}`,
|
||||
{
|
||||
type: "PUT",
|
||||
data: {
|
||||
send_email: reviewable.sendEmail,
|
||||
reject_reason: reviewable.rejectReason,
|
||||
},
|
||||
data,
|
||||
}
|
||||
)
|
||||
.then((result) => {
|
||||
|
@ -227,6 +244,7 @@ export default Component.extend({
|
|||
|
||||
let msg = action.get("confirm_message");
|
||||
let requireRejectReason = action.get("require_reject_reason");
|
||||
let customModal = action.get("custom_modal");
|
||||
if (msg) {
|
||||
bootbox.confirm(msg, (answer) => {
|
||||
if (answer) {
|
||||
|
@ -241,6 +259,14 @@ export default Component.extend({
|
|||
performConfirmed: this._performConfirmed.bind(this),
|
||||
action,
|
||||
});
|
||||
} else if (customModal) {
|
||||
showModal(customModal, {
|
||||
title: `review.${customModal}.title`,
|
||||
model: this.reviewable,
|
||||
}).setProperties({
|
||||
performConfirmed: this._performConfirmed.bind(this),
|
||||
action,
|
||||
});
|
||||
} else {
|
||||
return this._performConfirmed(action);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import { addGTMPageChangedCallback } from "discourse/lib/page-tracker";
|
|||
import { addGlobalNotice } from "discourse/components/global-notice";
|
||||
import { addNavItem } from "discourse/models/nav-item";
|
||||
import { addPluginOutletDecorator } from "discourse/components/plugin-connector";
|
||||
import { addPluginReviewableParam } from "discourse/components/reviewable-item";
|
||||
import { addPopupMenuOptionsCallback } from "discourse/controllers/composer";
|
||||
import { addPostClassesCallback } from "discourse/widgets/post";
|
||||
import { addPostSmallActionIcon } from "discourse/widgets/post-small-action";
|
||||
|
@ -1222,6 +1223,9 @@ class PluginApi {
|
|||
addSaveableUserOptionField(fieldName) {
|
||||
addSaveableUserOptionField(fieldName);
|
||||
}
|
||||
addPluginReviewableParam(reviewableType, param) {
|
||||
addPluginReviewableParam(reviewableType, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the default category background and text colors in the
|
||||
|
|
|
@ -192,6 +192,11 @@ class ReviewablesController < ApplicationController
|
|||
|
||||
args.merge!(reject_reason: params[:reject_reason], send_email: params[:send_email] != "false") if reviewable.type == 'ReviewableUser'
|
||||
|
||||
plugin_params = DiscoursePluginRegistry.reviewable_params.select do |reviewable_param|
|
||||
reviewable.type == reviewable_param[:type].to_s.classify
|
||||
end
|
||||
args.merge!(params.slice(*plugin_params.map { |pp| pp[:param] }).permit!)
|
||||
|
||||
result = reviewable.perform(current_user, params[:action_id].to_sym, args)
|
||||
rescue Reviewable::InvalidAction => e
|
||||
# Consider InvalidAction an InvalidAccess
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReviewableActionSerializer < ApplicationSerializer
|
||||
attributes :id, :icon, :button_class, :label, :confirm_message, :description, :client_action, :require_reject_reason
|
||||
attributes :id, :icon, :button_class, :label, :confirm_message, :description, :client_action, :require_reject_reason, :custom_modal
|
||||
|
||||
def label
|
||||
I18n.t(object.label)
|
||||
|
@ -30,4 +30,8 @@ class ReviewableActionSerializer < ApplicationSerializer
|
|||
def include_require_reject_reason?
|
||||
object.require_reject_reason.present?
|
||||
end
|
||||
|
||||
def include_custom_modal?
|
||||
object.custom_modal.present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -84,6 +84,7 @@ class DiscoursePluginRegistry
|
|||
define_filtered_register :user_api_key_scope_mappings
|
||||
|
||||
define_filtered_register :permitted_bulk_action_parameters
|
||||
define_filtered_register :reviewable_params
|
||||
|
||||
def self.register_auth_provider(auth_provider)
|
||||
self.auth_providers << auth_provider
|
||||
|
|
|
@ -877,6 +877,13 @@ class Plugin::Instance
|
|||
DiscoursePluginRegistry.demon_processes << demon_class
|
||||
end
|
||||
|
||||
def add_permitted_reviewable_param(type, param)
|
||||
DiscoursePluginRegistry.register_reviewable_param({
|
||||
type: type,
|
||||
param: param
|
||||
}, self)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def self.js_path
|
||||
|
|
|
@ -33,7 +33,7 @@ class Reviewable < ActiveRecord::Base
|
|||
end
|
||||
|
||||
class Action < Item
|
||||
attr_accessor :icon, :button_class, :label, :description, :confirm_message, :client_action, :require_reject_reason
|
||||
attr_accessor :icon, :button_class, :label, :description, :confirm_message, :client_action, :require_reject_reason, :custom_modal
|
||||
|
||||
def initialize(id, icon = nil, button_class = nil, label = nil)
|
||||
super(id)
|
||||
|
|
|
@ -432,6 +432,48 @@ describe ReviewablesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "with reviewable params added via plugin API" do
|
||||
class ::ReviewablePhony < Reviewable
|
||||
def build_actions(actions, guardian, _args)
|
||||
return [] unless pending?
|
||||
|
||||
actions.add(:approve_phony) do |action|
|
||||
action.label = "js.phony.review.approve"
|
||||
end
|
||||
end
|
||||
|
||||
def perform_approve_phony(performed_by, args)
|
||||
puts args.inspect
|
||||
MessageBus.publish("/phony-reviewable-test", { args: args }, user_ids: [1])
|
||||
create_result(:success, :approved)
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
plugin = Plugin::Instance.new
|
||||
plugin.add_permitted_reviewable_param(:reviewable_phony, :fake_id)
|
||||
end
|
||||
|
||||
after do
|
||||
DiscoursePluginRegistry.reset!
|
||||
end
|
||||
|
||||
fab!(:reviewable_phony) { Fabricate(:reviewable, type: "ReviewablePhony") }
|
||||
|
||||
it "passes the added param into the reviewable class' perform method" do
|
||||
MessageBus.expects(:publish)
|
||||
.with("/phony-reviewable-test", { args: {
|
||||
version: reviewable_phony.version,
|
||||
"fake_id" => "2" }
|
||||
},
|
||||
{ user_ids: [1] })
|
||||
.once
|
||||
|
||||
put "/review/#{reviewable_phony.id}/perform/approve_phony.json?version=#{reviewable_phony.version}", params: { fake_id: 2 }
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
context "#topics" do
|
||||
fab!(:post0) { Fabricate(:post) }
|
||||
fab!(:post1) { Fabricate(:post, topic: post0.topic) }
|
||||
|
|
Loading…
Reference in New Issue