Skip to content

Commit

Permalink
Initial commit for counting batch actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Harmit Goswami committed Dec 18, 2024
1 parent 1ea8f48 commit 34e0a5e
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 4 deletions.
54 changes: 54 additions & 0 deletions pontoon/batch/actions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.conf import settings
from django.utils import timezone

from pontoon.actionlog.models import ActionLog
Expand All @@ -6,6 +7,14 @@
TranslationMemoryEntry,
)
from pontoon.batch import utils
from pontoon.messaging.notifications import send_badge_notification


def _get_badge_level(thresholds, action_count):
for level in range(len(thresholds) - 1):
if thresholds[level] <= action_count < thresholds[level + 1]:
return level + 1
return 0


def batch_action_template(form, user, translations, locale):
Expand Down Expand Up @@ -69,6 +78,10 @@ def approve_translations(form, user, translations, locale):
locale,
)

before_level = _get_badge_level(
settings.BADGES_REVIEW_THRESHOLDS, user.badges_review_count
)

# Log approving actions
actions_to_log = [
ActionLog(
Expand All @@ -80,6 +93,16 @@ def approve_translations(form, user, translations, locale):
]
ActionLog.objects.bulk_create(actions_to_log)

# Send Review Master Badge notification information
after_level = _get_badge_level(
settings.BADGES_REVIEW_THRESHOLDS, user.badges_review_count
)
badge_update = {}
if after_level > before_level:
badge_update["level"] = after_level
badge_update["name"] = "Review Master Badge"
send_badge_notification(user, badge_update["name"], badge_update["level"])

# Approve translations.
translations.update(
approved=True,
Expand All @@ -99,6 +122,7 @@ def approve_translations(form, user, translations, locale):
"latest_translation_pk": latest_translation_pk,
"changed_translation_pks": changed_translation_pks,
"invalid_translation_pks": invalid_translation_pks,
"badge_update": badge_update,
}


Expand All @@ -124,6 +148,10 @@ def reject_translations(form, user, translations, locale):
)
TranslationMemoryEntry.objects.filter(translation__in=suggestions).delete()

before_level = _get_badge_level(
settings.BADGES_REVIEW_THRESHOLDS, user.badges_review_count
)

# Log rejecting actions
actions_to_log = [
ActionLog(
Expand All @@ -135,6 +163,16 @@ def reject_translations(form, user, translations, locale):
]
ActionLog.objects.bulk_create(actions_to_log)

# Send Review Master Badge notification information
after_level = _get_badge_level(
settings.BADGES_REVIEW_THRESHOLDS, user.badges_review_count
)
badge_update = {}
if after_level > before_level:
badge_update["level"] = after_level
badge_update["name"] = "Review Master Badge"
send_badge_notification(user, badge_update["name"], badge_update["level"])

# Reject translations.
suggestions.update(
active=False,
Expand All @@ -155,6 +193,7 @@ def reject_translations(form, user, translations, locale):
"latest_translation_pk": None,
"changed_translation_pks": [],
"invalid_translation_pks": [],
"badge_update": badge_update,
}


Expand Down Expand Up @@ -216,6 +255,10 @@ def replace_translations(form, user, translations, locale):
translations_to_create,
)

before_level = _get_badge_level(
settings.BADGES_TRANSLATION_THRESHOLDS, user.badges_translation_count
)

# Log creating actions
actions_to_log = [
ActionLog(
Expand All @@ -227,6 +270,16 @@ def replace_translations(form, user, translations, locale):
]
ActionLog.objects.bulk_create(actions_to_log)

# Send Translation Champion Badge notification information
after_level = _get_badge_level(
settings.BADGES_TRANSLATION_THRESHOLDS, user.badges_translation_count
)
badge_update = {}
if after_level > before_level:
badge_update["level"] = after_level
badge_update["name"] = "Translation Champion Badge"
send_badge_notification(user, badge_update["name"], badge_update["level"])

changed_translation_pks = [c.pk for c in changed_translations]

if changed_translation_pks:
Expand All @@ -239,6 +292,7 @@ def replace_translations(form, user, translations, locale):
"latest_translation_pk": latest_translation_pk,
"changed_translation_pks": changed_translation_pks,
"invalid_translation_pks": invalid_translation_pks,
"badge_update": badge_update,
}


Expand Down
4 changes: 4 additions & 0 deletions pontoon/batch/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def test_batch_approve_valid_translations(
assert response.json() == {
"count": 1,
"invalid_translation_count": 0,
"badge_update": {},
}

translation_dtd_unapproved.refresh_from_db()
Expand All @@ -170,6 +171,7 @@ def test_batch_approve_invalid_translations(
assert response.json() == {
"count": 0,
"invalid_translation_count": 1,
"badge_update": {},
}

translation_dtd_invalid_unapproved.refresh_from_db()
Expand All @@ -195,6 +197,7 @@ def test_batch_find_and_replace_valid_translations(
assert response.json() == {
"count": 1,
"invalid_translation_count": 0,
"badge_update": {},
}

translation = translation_dtd_unapproved.entity.translation_set.last()
Expand Down Expand Up @@ -224,6 +227,7 @@ def test_batch_find_and_replace_invalid_translations(
assert response.json() == {
"count": 0,
"invalid_translation_count": 1,
"badge_update": {},
}

translation = translation_dtd_unapproved.entity.translation_set.last()
Expand Down
7 changes: 6 additions & 1 deletion pontoon/batch/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ def batch_edit_translations(request):
invalid_translation_count = len(action_status.get("invalid_translation_pks", []))
if action_status["count"] == 0:
return JsonResponse(
{"count": 0, "invalid_translation_count": invalid_translation_count}
{
"count": 0,
"invalid_translation_count": invalid_translation_count,
"badge_update": action_status["badge_update"],
}
)

tr_pks = [tr.pk for tr in action_status["translated_resources"]]
Expand Down Expand Up @@ -145,5 +149,6 @@ def batch_edit_translations(request):
{
"count": action_status["count"],
"invalid_translation_count": invalid_translation_count,
"badge_update": action_status["badge_update"],
}
)
7 changes: 6 additions & 1 deletion translate/src/api/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
EntityTranslation,
HistoryTranslation,
} from './translation';
import type { BatchBadgeUpdate } from '../modules/batchactions/actions';

/**
* String that needs to be translated, along with its current metadata,
Expand Down Expand Up @@ -42,7 +43,11 @@ export type EntitySiblings = {
};

type BatchEditResponse =
| { count: number; invalid_translation_count?: number }
| {
count: number;
invalid_translation_count?: number;
badge_update?: BatchBadgeUpdate;
}
| { error: true };

export async function batchEditEntities(
Expand Down
22 changes: 22 additions & 0 deletions translate/src/modules/batchactions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ export const RESET_BATCHACTIONS_RESPONSE = 'batchactions/RESET_RESPONSE';
export const TOGGLE_BATCHACTIONS = 'batchactions/TOGGLE';
export const UNCHECK_BATCHACTIONS = 'batchactions/UNCHECK';

export type BatchBadgeUpdate = {
name: string | null;
level: number | null;
};

export type ResponseType = {
action: string;
changedCount: number | null | undefined;
invalidCount: number | null | undefined;
badgeUpdate: BatchBadgeUpdate | null | undefined;
error: boolean | null | undefined;
};

Expand Down Expand Up @@ -117,6 +123,10 @@ export const performAction =
location: Location,
action: 'approve' | 'reject' | 'replace',
entityIds: number[],
showBadgeTooltip: (tooltip: {
badgeName: string | null;
badgeLevel: number | null;
}) => void,
find?: string,
replace?: string,
) =>
Expand All @@ -134,13 +144,25 @@ export const performAction =
const response: ResponseType = {
changedCount: 0,
invalidCount: 0,
badgeUpdate: {
name: '',
level: 0,
},
error: false,
action,
};

if ('count' in data) {
response.changedCount = data.count;
response.invalidCount = data.invalid_translation_count;
response.badgeUpdate = data.badge_update;

if (response.badgeUpdate?.level && response.badgeUpdate?.level > 0) {
showBadgeTooltip({
badgeName: response.badgeUpdate.name,
badgeLevel: response.badgeUpdate.level,
});
}

if (data.count > 0) {
dispatch(updateUI(location, entityIds));
Expand Down
21 changes: 19 additions & 2 deletions translate/src/modules/batchactions/components/BatchActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Localized } from '@fluent/react';
import React, { useCallback, useContext, useEffect, useRef } from 'react';

import { Location } from '~/context/Location';
import { ShowBadgeTooltip } from '~/context/BadgeTooltip';
import { useAppDispatch, useAppSelector } from '~/hooks';

import { performAction, resetSelection, selectAll } from '../actions';
Expand All @@ -18,6 +19,7 @@ import { ReplaceAll } from './ReplaceAll';
export function BatchActions(): React.ReactElement<'div'> {
const batchactions = useAppSelector((state) => state[BATCHACTIONS]);
const location = useContext(Location);
const showBadgeTooltip = useContext(ShowBadgeTooltip);
const dispatch = useAppDispatch();

const find = useRef<HTMLInputElement>(null);
Expand All @@ -43,13 +45,27 @@ export function BatchActions(): React.ReactElement<'div'> {

const approveAll = useCallback(() => {
if (!batchactions.requestInProgress) {
dispatch(performAction(location, 'approve', batchactions.entities));
dispatch(
performAction(
location,
'approve',
batchactions.entities,
showBadgeTooltip,
),
);
}
}, [location, batchactions]);

const rejectAll = useCallback(() => {
if (!batchactions.requestInProgress) {
dispatch(performAction(location, 'reject', batchactions.entities));
dispatch(
performAction(
location,
'reject',
batchactions.entities,
showBadgeTooltip,
),
);
}
}, [location, batchactions]);

Expand All @@ -67,6 +83,7 @@ export function BatchActions(): React.ReactElement<'div'> {
location,
'replace',
batchactions.entities,
showBadgeTooltip,
encodeURIComponent(fv),
encodeURIComponent(rv),
),
Expand Down

0 comments on commit 34e0a5e

Please sign in to comment.