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,
|
topicId,
|
||||||
categoryId,
|
categoryId,
|
||||||
includeGroups,
|
includeGroups,
|
||||||
|
customGroupsScope,
|
||||||
includeMentionableGroups,
|
includeMentionableGroups,
|
||||||
includeMessageableGroups,
|
includeMessageableGroups,
|
||||||
allowedUsers,
|
allowedUsers,
|
||||||
|
@ -56,6 +57,7 @@ function performSearch(
|
||||||
topic_id: topicId,
|
topic_id: topicId,
|
||||||
category_id: categoryId,
|
category_id: categoryId,
|
||||||
include_groups: includeGroups,
|
include_groups: includeGroups,
|
||||||
|
custom_groups_scope: customGroupsScope,
|
||||||
include_mentionable_groups: includeMentionableGroups,
|
include_mentionable_groups: includeMentionableGroups,
|
||||||
include_messageable_groups: includeMessageableGroups,
|
include_messageable_groups: includeMessageableGroups,
|
||||||
groups: groupMembersOf,
|
groups: groupMembersOf,
|
||||||
|
@ -100,6 +102,7 @@ let debouncedSearch = function (
|
||||||
topicId,
|
topicId,
|
||||||
categoryId,
|
categoryId,
|
||||||
includeGroups,
|
includeGroups,
|
||||||
|
customGroupsScope,
|
||||||
includeMentionableGroups,
|
includeMentionableGroups,
|
||||||
includeMessageableGroups,
|
includeMessageableGroups,
|
||||||
allowedUsers,
|
allowedUsers,
|
||||||
|
@ -116,6 +119,7 @@ let debouncedSearch = function (
|
||||||
topicId,
|
topicId,
|
||||||
categoryId,
|
categoryId,
|
||||||
includeGroups,
|
includeGroups,
|
||||||
|
customGroupsScope,
|
||||||
includeMentionableGroups,
|
includeMentionableGroups,
|
||||||
includeMessageableGroups,
|
includeMessageableGroups,
|
||||||
allowedUsers,
|
allowedUsers,
|
||||||
|
@ -207,6 +211,7 @@ export default function userSearch(options) {
|
||||||
|
|
||||||
let term = options.term || "",
|
let term = options.term || "",
|
||||||
includeGroups = options.includeGroups,
|
includeGroups = options.includeGroups,
|
||||||
|
customGroupsScope = options.customGroupsScope,
|
||||||
includeMentionableGroups = options.includeMentionableGroups,
|
includeMentionableGroups = options.includeMentionableGroups,
|
||||||
includeMessageableGroups = options.includeMessageableGroups,
|
includeMessageableGroups = options.includeMessageableGroups,
|
||||||
allowedUsers = options.allowedUsers,
|
allowedUsers = options.allowedUsers,
|
||||||
|
@ -248,6 +253,7 @@ export default function userSearch(options) {
|
||||||
topicId,
|
topicId,
|
||||||
categoryId,
|
categoryId,
|
||||||
includeGroups,
|
includeGroups,
|
||||||
|
customGroupsScope,
|
||||||
includeMentionableGroups,
|
includeMentionableGroups,
|
||||||
includeMessageableGroups,
|
includeMessageableGroups,
|
||||||
allowedUsers,
|
allowedUsers,
|
||||||
|
|
|
@ -104,3 +104,5 @@
|
||||||
onChange=(action (mut model.default_notification_level))
|
onChange=(action (mut model.default_notification_level))
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{plugin-outlet name="groups-interaction-custom-options" args=(hash model=model)}}
|
||||||
|
|
|
@ -70,6 +70,7 @@ export default MultiSelectComponent.extend({
|
||||||
categoryId: options.categoryId,
|
categoryId: options.categoryId,
|
||||||
exclude: this.excludedUsers,
|
exclude: this.excludedUsers,
|
||||||
includeGroups: options.includeGroups,
|
includeGroups: options.includeGroups,
|
||||||
|
customGroupsScope: options.customGroupsScope,
|
||||||
allowedUsers: options.allowedUsers,
|
allowedUsers: options.allowedUsers,
|
||||||
includeMentionableGroups: options.includeMentionableGroups,
|
includeMentionableGroups: options.includeMentionableGroups,
|
||||||
includeMessageableGroups: options.includeMessageableGroups,
|
includeMessageableGroups: options.includeMessageableGroups,
|
||||||
|
|
|
@ -180,6 +180,8 @@ class Admin::GroupsController < Admin::AdminController
|
||||||
custom_fields = DiscoursePluginRegistry.editable_group_custom_fields
|
custom_fields = DiscoursePluginRegistry.editable_group_custom_fields
|
||||||
permitted << { custom_fields: custom_fields } unless custom_fields.blank?
|
permitted << { custom_fields: custom_fields } unless custom_fields.blank?
|
||||||
|
|
||||||
|
permitted = permitted | DiscoursePluginRegistry.group_params
|
||||||
|
|
||||||
params.require(:group).permit(permitted)
|
params.require(:group).permit(permitted)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -736,6 +736,8 @@ class GroupsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
permitted_params = permitted_params | DiscoursePluginRegistry.group_params
|
||||||
|
|
||||||
params.require(:group).permit(*permitted_params)
|
params.require(:group).permit(*permitted_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1123,7 +1123,12 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
if groups
|
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')
|
groups = groups.order('groups.name asc')
|
||||||
|
|
||||||
to_render[:groups] = groups.map do |m|
|
to_render[:groups] = groups.map do |m|
|
||||||
|
|
|
@ -557,8 +557,14 @@ class Group < ActiveRecord::Base
|
||||||
lookup_group(name) || refresh_automatic_group!(name)
|
lookup_group(name) || refresh_automatic_group!(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.search_groups(name, groups: nil)
|
def self.search_groups(name, groups: nil, custom_scope: {})
|
||||||
(groups || Group).where(
|
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}%"
|
"name ILIKE :term_like OR full_name ILIKE :term_like", term_like: "%#{name}%"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -76,6 +76,8 @@ class DiscoursePluginRegistry
|
||||||
define_filtered_register :staff_editable_user_custom_fields
|
define_filtered_register :staff_editable_user_custom_fields
|
||||||
|
|
||||||
define_filtered_register :editable_group_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
|
define_filtered_register :topic_thumbnail_sizes
|
||||||
|
|
||||||
|
|
|
@ -369,6 +369,17 @@ class Plugin::Instance
|
||||||
end
|
end
|
||||||
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
|
# Add validation method but check that the plugin is enabled
|
||||||
def validate(klass, name, &block)
|
def validate(klass, name, &block)
|
||||||
klass = klass.to_s.classify.constantize
|
klass = klass.to_s.classify.constantize
|
||||||
|
|
|
@ -920,6 +920,7 @@ describe Group do
|
||||||
|
|
||||||
describe '.search_groups' do
|
describe '.search_groups' do
|
||||||
fab!(:group) { Fabricate(:group, name: 'tEsT_more_things', full_name: 'Abc something awesome') }
|
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
|
it 'should return the right groups' do
|
||||||
group
|
group
|
||||||
|
@ -934,6 +935,18 @@ describe Group do
|
||||||
expect(Group.search_groups('sOmEthi')).to eq([group])
|
expect(Group.search_groups('sOmEthi')).to eq([group])
|
||||||
expect(Group.search_groups('test2')).to eq([])
|
expect(Group.search_groups('test2')).to eq([])
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe '#bulk_add' do
|
describe '#bulk_add' do
|
||||||
|
|
|
@ -76,6 +76,31 @@ RSpec.describe Admin::GroupsController do
|
||||||
expect(group.custom_fields['test2']).to be_blank
|
expect(group.custom_fields['test2']).to be_blank
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
describe '#add_owners' do
|
describe '#add_owners' do
|
||||||
|
|
Loading…
Reference in New Issue