Skip to content

Commit

Permalink
FEATURE: Allow excluding groups from leaderboards (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
xfalcox committed Jun 23, 2022
1 parent 48b2dec commit ac393c7
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def update
to_date: params[:to_date],
from_date: params[:from_date],
included_groups_ids: params[:included_groups_ids] || [],
excluded_groups_ids: params[:excluded_groups_ids] || [],
visible_to_groups_ids: params[:visible_to_groups_ids] || [],
)

Expand Down
4 changes: 3 additions & 1 deletion app/models/gamification_leaderboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ def self.scores_for(leaderboard_id, page: 0, for_user_id: false)
sum_sql = "SUM(COALESCE(gamification_scores.score, 0)) as total_score"

users = User.joins(:primary_email).real.where.not("user_emails.email LIKE '%@anonymized.invalid%'").where(staged: false).joins(join_sql)
users = users.joins(:groups).where(groups: { id: leaderboard.included_groups_ids }) if leaderboard.included_groups_ids.present?
users = users.where("EXISTS (SELECT 1 FROM group_users AS gu WHERE group_id IN (?) and gu.user_id = users.id)", leaderboard.included_groups_ids) if leaderboard.included_groups_ids.present?
users = users.where("NOT EXISTS (SELECT 1 FROM group_users AS gu WHERE group_id IN (?) and gu.user_id = users.id)", leaderboard.excluded_groups_ids) if leaderboard.excluded_groups_ids.present?
users = users.where("gamification_scores.date BETWEEN ? AND ?", leaderboard.from_date, leaderboard.to_date) if leaderboard.from_date.present?
# calculate scores up to to_date if just to_date is present
users = users.where("gamification_scores.date <= ?", leaderboard.to_date) if leaderboard.to_date != Date.today && !leaderboard.from_date.present?
users = users.select("users.id, users.username, users.uploaded_avatar_id, #{sum_sql}").group("users.id").order(total_score: :desc, id: :asc)

if for_user_id
user = users.find_by(id: for_user_id)
index = users.index(user)
Expand Down
1 change: 1 addition & 0 deletions app/serializers/leaderboard_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ class LeaderboardSerializer < ApplicationSerializer
:to_date,
:visible_to_groups_ids,
:included_groups_ids,
:excluded_groups_ids,
:updated_at
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default Controller.extend({
fromDate: "",
visibleGroupIds: [],
includedGroupIds: [],
excludedGroupIds: [],

@discourseComputed("model.leaderboards.@each.updated_at")
sortedLeaderboards(leaderboards) {
Expand Down Expand Up @@ -45,6 +46,10 @@ export default Controller.extend({
"includedGroupIds",
this.filterGroupsById(leaderboard.included_groups_ids)
);
this.set(
"excludedGroupIds",
this.filterGroupsById(leaderboard.excluded_groups_ids)
);
},

filterGroupsById(groupIds) {
Expand Down Expand Up @@ -103,6 +108,7 @@ export default Controller.extend({
fromDate: "",
visibleGroupIds: [],
includedGroupIds: [],
excludedGroupIds: [],
});
},

Expand Down Expand Up @@ -140,6 +146,7 @@ export default Controller.extend({
from_date: this.fromDate,
visible_to_groups_ids: this.visibleGroupIds,
included_groups_ids: this.includedGroupIds,
excluded_groups_ids: this.excludedGroupIds,
};

return ajax(
Expand All @@ -163,13 +170,20 @@ export default Controller.extend({
this.includedGroupIds
);
}
if (this.excludedGroupIds) {
this.selectedLeaderboard.set(
"excluded_groups_ids",
this.excludedGroupIds
);
}
this.setProperties({
loading: false,
selectedLeaderboardId: null,
toDate: "",
fromDate: "",
visibleGroupIds: [],
includedGroupIds: [],
excludedGroupIds: [],
});
})
.catch(popupAjaxError);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@
}}
<div>{{i18n "gamification.leaderboard.included_groups_help"}}</div>
</div>
<div class="control-group">
<label class="control-label">
{{i18n "gamification.leaderboard.excluded_groups"}}
</label>
{{group-chooser
content=model.groups
value=excludedGroupIds
labelProperty="name"
onChange=(action (mut excludedGroupIds))
}}
<div>{{i18n "gamification.leaderboard.excluded_groups_help"}}</div>
</div>
<div class="control-group">
<label class="control-label">
{{i18n "gamification.leaderboard.visible_to_groups"}}
Expand Down
2 changes: 2 additions & 0 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ en:
visible_to_groups_help: "The groups that can view the the leaderboard."
included_groups: "Included groups"
included_groups_help: "The groups that will be included in the leaderboard."
excluded_groups: "Excluded groups"
excluded_groups_help: "The groups that will not be included in the leaderboard."
create: "Create"
cancel: "Cancel"
delete: "Delete"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true
class AddExcludedGroupsToLeaderboards < ActiveRecord::Migration[7.0]
def change
add_column :gamification_leaderboards, :excluded_groups_ids, :integer, array: true, null: false, default: []
end
end

0 comments on commit ac393c7

Please sign in to comment.