Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add notifications when a badge is awarded #3442

Merged
merged 32 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8462f34
Init commit for badge notifications
Nov 15, 2024
0abc604
Merge main into branch
Nov 15, 2024
8a16a65
Fixed linting error from previous merge
Nov 15, 2024
24a3519
Fixed confetti file
Nov 20, 2024
eaa5b22
Working fix for permissions bug
Nov 26, 2024
e17bd9c
Implemented initial popup component
Nov 27, 2024
40b2ca8
Addressed review comments
Nov 29, 2024
4970971
Changed badge image import in teams, fixed test cases
Nov 29, 2024
bbd2a50
Addressed review comments
Nov 29, 2024
4ff5f1c
Refactored badge notification sender
Nov 29, 2024
70c6724
Addressed review comments
Dec 2, 2024
224148e
Addressed review comments
Dec 2, 2024
37dd168
Added category to notification
Dec 2, 2024
ed2e37e
Added discard functionality for popup
Dec 3, 2024
27cd4e1
Merge main into branch
Dec 3, 2024
7d258e6
Added CSS and code fixes
Dec 4, 2024
af296bc
Fixed failing test case
Dec 4, 2024
c5f544c
Fixed tooltip styling on translate view
Dec 4, 2024
6f7f919
Fixed translate confetti animation
Dec 4, 2024
8f488e6
Changed confetti colors in translate view
Dec 5, 2024
e398823
Small fixes
Dec 5, 2024
2b696be
Fixed review count bug
Dec 5, 2024
d6778ae
Fixed linting error
Dec 5, 2024
26db4e6
Added counting bug fix for approvals
Dec 5, 2024
a39fc0f
Changed query structure
Dec 6, 2024
2f0b7ef
Created new variable for Review thresholds
Dec 9, 2024
4a76e47
Fixed confetti css bug
Dec 9, 2024
5f2e821
Addressed review comments
Dec 9, 2024
90f789f
Added Review Master notification for auto-rejections
Dec 10, 2024
2cb0f62
Added explicit action field to ActionLog model
Dec 10, 2024
f9d79d0
Changed explicit action to implicit
Dec 10, 2024
076e825
Typo fixes
Dec 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export default [
jQuery: 'readonly',
Clipboard: 'readonly',
Chart: 'readonly',
confetti: 'readonly',
NProgress: 'readonly',
diff_match_patch: 'readonly',
Highcharts: 'readonly',
Expand Down
30 changes: 30 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 23 additions & 33 deletions pontoon/base/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@
from django import forms
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils import timezone

from pontoon.base import utils
from pontoon.base.models import (
Locale,
PermissionChangelog,
ProjectLocale,
User,
UserProfile,
)
from pontoon.sync.formats import are_compatible_files
from pontoon.teams.utils import log_group_members
from pontoon.translations.views import _send_badge_notification


class HtmlField(forms.CharField):
Expand Down Expand Up @@ -91,6 +90,8 @@ class UserPermissionLogFormMixin:
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
super().__init__(*args, **kwargs)
# Track if user reached new level for Community Builder Badge
self.community_builder_level_reached = 0

def assign_users_to_groups(self, group_name, users):
"""
Expand All @@ -102,42 +103,11 @@ def assign_users_to_groups(self, group_name, users):

group.user_set.clear()

before_count = self.user.badges_promotion_count
now = timezone.now()

if users:
group.user_set.add(*users)

log_group_members(self.user, group, (add_users, remove_users))

after_count = self.user.badges_promotion_count

# TODO:
# This code is the only consumer of the PermissionChangelog
# model, so we should refactor in the future to simplify
# how promotions are retrieved. (see #2195)

# Check if user was demoted from Manager to Translator
# In this case, it doesn't count as a promotion
if group_name == "managers":
removal = PermissionChangelog.objects.filter(
performed_by=self.user,
action_type=PermissionChangelog.ActionType.REMOVED,
created_at__gte=now,
)
if removal:
for item in removal:
if "managers" in item.group.name:
after_count -= 1

# Award Community Builder badge
if (
after_count > before_count
and after_count in settings.BADGES_PROMOTION_THRESHOLDS
):
# TODO: Send a notification to the user
pass


class LocalePermsForm(UserPermissionLogFormMixin, forms.ModelForm):
translators = forms.ModelMultipleChoiceField(
Expand All @@ -158,9 +128,29 @@ def save(self, *args, **kwargs):
translators = self.cleaned_data.get("translators", User.objects.none())
managers = self.cleaned_data.get("managers", User.objects.none())

before_count = self.user.badges_promotion_count

self.assign_users_to_groups("translators", translators)
self.assign_users_to_groups("managers", managers)

after_count = self.user.badges_promotion_count

# Award Community Builder badge
if (
after_count > before_count
and after_count in settings.BADGES_PROMOTION_THRESHOLDS
):
self.community_builder_level_reached = (
settings.BADGES_PROMOTION_THRESHOLDS.index(after_count) + 1
)
_send_badge_notification(
self.user,
"Community Builder Badge",
self.community_builder_level_reached,
)

return self.community_builder_level_reached

harmitgoswami marked this conversation as resolved.
Show resolved Hide resolved

class ProjectLocalePermsForm(UserPermissionLogFormMixin, forms.ModelForm):
translators = forms.ModelMultipleChoiceField(
Expand Down
23 changes: 21 additions & 2 deletions pontoon/base/models/user.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import timedelta
from hashlib import md5
from urllib.parse import quote, urlencode

Expand All @@ -7,7 +8,7 @@
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.db.models import Count, Q
from django.db.models import Count, Exists, OuterRef, Q
from django.urls import reverse
from django.utils import timezone

Expand Down Expand Up @@ -243,9 +244,27 @@ def badges_review_count(self):
@property
def badges_promotion_count(self):
"""Role promotions performed by user that count towards their badges"""
return self.changed_permissions_log.filter(
added_entries = self.changed_permissions_log.filter(
action_type="added",
created_at__gte=settings.BADGES_START_DATE,
)

# Check if user was demoted from Manager to Translator.
# In this case, it doesn't count as a promotion.
#
# TODO:
# This code is the only consumer of the PermissionChangelog model, so we should
# refactor to simplify how promotions are retrieved. (see #2195)
return added_entries.exclude(
Exists(
self.changed_permissions_log.filter(
performed_by=OuterRef("performed_by"),
performed_on=OuterRef("performed_on"),
action_type="removed",
created_at__gt=OuterRef("created_at"),
created_at__lte=OuterRef("created_at") + timedelta(milliseconds=10),
)
)
).count()
harmitgoswami marked this conversation as resolved.
Show resolved Hide resolved


Expand Down
Loading
Loading