FEATURE: Add group_list parameter type (#283)

This allows admins to select multiple groups from a dropdown list and
filter results using that parameter.
This commit is contained in:
Penar Musaraj 2024-03-12 12:06:01 -04:00 committed by GitHub
parent 0e301bef74
commit 2f1044820c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 65 additions and 5 deletions

View File

@ -46,6 +46,16 @@
/>
<span class="param-name">{{@info.identifier}}</span>
{{else if (eq this.type "group_list")}}
<GroupChooser
@content={{this.allGroups}}
@value={{this.value}}
@labelProperty="name"
@valueProperty="name"
@onChange={{this.updateGroupValue}}
/>
<span class="param-name">{{@info.identifier}}</span>
{{else if (eq this.type "user_list")}}
<EmailGroupUserChooser
@value={{this.value}}

View File

@ -25,6 +25,7 @@ const layoutMap = {
int_list: "generic",
string_list: "generic",
user_list: "user_list",
group_list: "group_list",
};
export default class ParamInput extends Component {
@ -158,6 +159,10 @@ export default class ParamInput extends Component {
return true;
}
get allGroups() {
return this.site.get("groups");
}
dasherizeCategoryId(value) {
const isPositiveInt = /^\d+$/.test(value);
if (!isPositiveInt && value !== dasherize(value)) {
@ -196,6 +201,12 @@ export default class ParamInput extends Component {
this.nullableBoolValue = input;
this.args.updateParams(this.args.info.identifier, this.nullableBoolValue);
}
@action
updateGroupValue(input) {
this.value = input;
this.args.updateParams(this.args.info.identifier, this.value.join(","));
}
}
function allowsInputTypeTime() {

View File

@ -42,6 +42,8 @@ export default class Query extends RestModel {
newParams[name] = null;
} else if (pinfo["type"] === "user_list") {
newParams[name] = null;
} else if (pinfo["type"] === "group_list") {
newParams[name] = null;
} else {
newParams[name] = "";
}

View File

@ -60,6 +60,7 @@ module ::DiscourseDataExplorer
:int_list,
:string_list,
:user_list,
:group_list,
)
end
@ -241,6 +242,9 @@ module ::DiscourseDataExplorer
when :user_list
value = string.split(",").map { |s| User.find_by_username_or_email(s).id }
invalid_format string, "can't be empty" if value.length == 0
when :group_list
value = string.split(",").map { |s| Group.where(name: s).first.name }
invalid_format string, "The group with id #{string} was not found" if value.length == 0
else
raise TypeError.new("unknown parameter type??? should not get here")
end

View File

@ -1,11 +1,14 @@
# frozen_string_literal: true
RSpec.describe "Explorer", type: :system, js: true do
fab!(:current_user) { Fabricate(:admin) }
fab!(:admin)
fab!(:group) { Fabricate(:group, name: "group") }
fab!(:group_user) { Fabricate(:group_user, user: current_user, group: group) }
fab!(:group_user) { Fabricate(:group_user, user: admin, group: group) }
before { SiteSetting.data_explorer_enabled = true }
before do
SiteSetting.data_explorer_enabled = true
sign_in admin
end
context "with a query using a default param" do
fab!(:query_1) do
@ -14,16 +17,46 @@ RSpec.describe "Explorer", type: :system, js: true do
name: "My default param query",
description: "Test default param query",
sql: "-- [params]\n-- string :limit = 42\n\nSELECT * FROM users LIMIT :limit",
user: current_user,
user: admin,
)
end
fab!(:query_group_1) { Fabricate(:query_group, query: query_1, group: group) }
it "pre-fills the field with the default param" do
sign_in(current_user)
visit("/g/group/reports/#{query_1.id}")
expect(page).to have_field("limit", with: 42)
end
end
context "with a group_list param" do
fab!(:q2) do
Fabricate(
:query,
name: "My query with group_list",
description: "Test group_list query",
sql:
"-- [params]\n-- group_list :groups\n\nSELECT g.id,g.name FROM groups g WHERE g.name IN(:groups) ORDER BY g.name ASC",
user: admin,
)
end
it "supports setting a group_list param" do
visit(
"/admin/plugins/explorer?id=#{q2.id}&params=%7B\"groups\"%3A\"admins%2Ctrust_level_1\"%7D",
)
find(".query-run .btn-primary").click
expect(page).to have_css(".query-results .result-header")
expect(page).to have_css(
".query-results tbody tr:nth-child(1) td:nth-child(2)",
text: "admins",
)
expect(page).to have_css(
".query-results tbody tr:nth-child(2) td:nth-child(2)",
text: "trust_level_1",
)
end
end
end