FEATURE: allow plugins to extend Groups (#14216)
* add_permitted_group_param API for plugins * add groups-interaction-custom-options outlet * custom search can use custom group scope
This commit is contained in:
parent
9873a942e3
commit
f859fd6bde
|
@ -25,6 +25,7 @@ function performSearch(
|
|||
topicId,
|
||||
categoryId,
|
||||
includeGroups,
|
||||
customGroupsScope,
|
||||
includeMentionableGroups,
|
||||
includeMessageableGroups,
|
||||
allowedUsers,
|
||||
|
@ -56,6 +57,7 @@ function performSearch(
|
|||
topic_id: topicId,
|
||||
category_id: categoryId,
|
||||
include_groups: includeGroups,
|
||||
custom_groups_scope: customGroupsScope,
|
||||
include_mentionable_groups: includeMentionableGroups,
|
||||
include_messageable_groups: includeMessageableGroups,
|
||||
groups: groupMembersOf,
|
||||
|
@ -100,6 +102,7 @@ let debouncedSearch = function (
|
|||
topicId,
|
||||
categoryId,
|
||||
includeGroups,
|
||||
customGroupsScope,
|
||||
includeMentionableGroups,
|
||||
includeMessageableGroups,
|
||||
allowedUsers,
|
||||
|
@ -116,6 +119,7 @@ let debouncedSearch = function (
|
|||
topicId,
|
||||
categoryId,
|
||||
includeGroups,
|
||||
customGroupsScope,
|
||||
includeMentionableGroups,
|
||||
includeMessageableGroups,
|
||||
allowedUsers,
|
||||
|
@ -207,6 +211,7 @@ export default function userSearch(options) {
|
|||
|
||||
let term = options.term || "",
|
||||
includeGroups = options.includeGroups,
|
||||
customGroupsScope = options.customGroupsScope,
|
||||
includeMentionableGroups = options.includeMentionableGroups,
|
||||
includeMessageableGroups = options.includeMessageableGroups,
|
||||
allowedUsers = options.allowedUsers,
|
||||
|
@ -248,6 +253,7 @@ export default function userSearch(options) {
|
|||
topicId,
|
||||
categoryId,
|
||||
includeGroups,
|
||||
customGroupsScope,
|
||||
includeMentionableGroups,
|
||||
includeMessageableGroups,
|
||||
allowedUsers,
|
||||
|
|
|
@ -104,3 +104,5 @@
|
|||
onChange=(action (mut model.default_notification_level))
|
||||
}}
|
||||
</div>
|
||||
|
||||
{{plugin-outlet name="groups-interaction-custom-options" args=(hash model=model)}}
|
||||
|
|
|
@ -70,6 +70,7 @@ export default MultiSelectComponent.extend({
|
|||
categoryId: options.categoryId,
|
||||
exclude: this.excludedUsers,
|
||||
includeGroups: options.includeGroups,
|
||||
customGroupsScope: options.customGroupsScope,
|
||||
allowedUsers: options.allowedUsers,
|
||||
includeMentionableGroups: options.includeMentionableGroups,
|
||||
includeMessageableGroups: options.includeMessageableGroups,
|
||||
|
|
|
@ -180,6 +180,8 @@ class Admin::GroupsController < Admin::AdminController
|
|||
custom_fields = DiscoursePluginRegistry.editable_group_custom_fields
|
||||
permitted << { custom_fields: custom_fields } unless custom_fields.blank?
|
||||
|
||||
permitted = permitted | DiscoursePluginRegistry.group_params
|
||||
|
||||
params.require(:group).permit(permitted)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -736,6 +736,8 @@ class GroupsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
permitted_params = permitted_params | DiscoursePluginRegistry.group_params
|
||||
|
||||
params.require(:group).permit(*permitted_params)
|
||||
end
|
||||
|
||||
|
|
|
@ -1123,7 +1123,12 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
if groups
|
||||
groups = Group.search_groups(term, groups: groups)
|
||||
groups = Group.search_groups(term,
|
||||
groups: groups,
|
||||
custom_scope: {
|
||||
name: params["custom_groups_scope"]&.to_sym,
|
||||
arguments: [current_user]
|
||||
})
|
||||
groups = groups.order('groups.name asc')
|
||||
|
||||
to_render[:groups] = groups.map do |m|
|
||||
|
|
|
@ -557,8 +557,14 @@ class Group < ActiveRecord::Base
|
|||
lookup_group(name) || refresh_automatic_group!(name)
|
||||
end
|
||||
|
||||
def self.search_groups(name, groups: nil)
|
||||
(groups || Group).where(
|
||||
def self.search_groups(name, groups: nil, custom_scope: {})
|
||||
groups ||= Group
|
||||
|
||||
if custom_scope.present? && DiscoursePluginRegistry.group_scope_for_search.include?(custom_scope[:name])
|
||||
groups = groups.send(custom_scope[:name], *custom_scope[:arguments])
|
||||
end
|
||||
|
||||
groups.where(
|
||||
"name ILIKE :term_like OR full_name ILIKE :term_like", term_like: "%#{name}%"
|
||||
)
|
||||
end
|
||||
|
|
|
@ -76,6 +76,8 @@ class DiscoursePluginRegistry
|
|||
define_filtered_register :staff_editable_user_custom_fields
|
||||
|
||||
define_filtered_register :editable_group_custom_fields
|
||||
define_filtered_register :group_params
|
||||
define_filtered_register :group_scope_for_search
|
||||
|
||||
define_filtered_register :topic_thumbnail_sizes
|
||||
|
||||
|
|
|
@ -369,6 +369,17 @@ class Plugin::Instance
|
|||
end
|
||||
end
|
||||
|
||||
# Add a permitted_param to Group, respecting if the plugin is enabled
|
||||
# Used in GroupsController#update and Admin::GroupsController#create
|
||||
def register_group_param(param)
|
||||
DiscoursePluginRegistry.register_group_param(param, self)
|
||||
end
|
||||
|
||||
# Add a custom scopes for search to Group, respecting if the plugin is enabled
|
||||
def register_group_scope_for_search(scope_name)
|
||||
DiscoursePluginRegistry.register_group_scope_for_search(scope_name, self)
|
||||
end
|
||||
|
||||
# Add validation method but check that the plugin is enabled
|
||||
def validate(klass, name, &block)
|
||||
klass = klass.to_s.classify.constantize
|
||||
|
|
|
@ -920,6 +920,7 @@ describe Group do
|
|||
|
||||
describe '.search_groups' do
|
||||
fab!(:group) { Fabricate(:group, name: 'tEsT_more_things', full_name: 'Abc something awesome') }
|
||||
let(:messageable_group) { Fabricate(:group, name: "MessageableGroup", messageable_level: Group::ALIAS_LEVELS[:everyone]) }
|
||||
|
||||
it 'should return the right groups' do
|
||||
group
|
||||
|
@ -934,6 +935,18 @@ describe Group do
|
|||
expect(Group.search_groups('sOmEthi')).to eq([group])
|
||||
expect(Group.search_groups('test2')).to eq([])
|
||||
end
|
||||
|
||||
it 'allows to filter with additional scope' do
|
||||
messageable_group
|
||||
|
||||
expect(Group.search_groups('es', custom_scope: { name: :messageable, arguments: [user] }).sort).to eq([messageable_group, group].sort)
|
||||
|
||||
plugin = Plugin::Instance.new
|
||||
plugin.register_group_scope_for_search(:messageable)
|
||||
expect(Group.search_groups('es', custom_scope: { name: :messageable, arguments: [user] }).sort).to eq([messageable_group].sort)
|
||||
|
||||
DiscoursePluginRegistry.reset!
|
||||
end
|
||||
end
|
||||
|
||||
describe '#bulk_add' do
|
||||
|
|
|
@ -76,6 +76,31 @@ RSpec.describe Admin::GroupsController do
|
|||
expect(group.custom_fields['test2']).to be_blank
|
||||
end
|
||||
end
|
||||
|
||||
context 'with Group.plugin_permitted_params' do
|
||||
after do
|
||||
DiscoursePluginRegistry.reset!
|
||||
end
|
||||
|
||||
it 'filter unpermitted params' do
|
||||
params = group_params
|
||||
params[:group].merge!(allow_unknown_sender_topic_replies: true)
|
||||
|
||||
post "/admin/groups.json", params: params
|
||||
expect(Group.last.allow_unknown_sender_topic_replies).to eq(false)
|
||||
end
|
||||
|
||||
it 'allows plugin to allow custom params' do
|
||||
params = group_params
|
||||
params[:group].merge!(allow_unknown_sender_topic_replies: true)
|
||||
|
||||
plugin = Plugin::Instance.new
|
||||
plugin.register_group_param :allow_unknown_sender_topic_replies
|
||||
|
||||
post "/admin/groups.json", params: params
|
||||
expect(Group.last.allow_unknown_sender_topic_replies).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#add_owners' do
|
||||
|
|
Loading…
Reference in New Issue