feat: bulk actions — live progress, grant subscription, error details

- Real-time progress: SSE streaming with animated progress bar,
  live success/error counters, scrollable log of last 10 results
  with auto-scroll, percentage display
- New action "Выдать подписку": tariff selector + days input,
  warning about users with existing subscriptions being skipped
- Error details: collapsible section with per-user error list,
  colored summary line (green successes / red errors)
- Fix: modal cannot be closed during loading (backdrop + Escape)
- Fix: row checkbox aria-labels now user-specific
- i18n: full progress/grant/error translations (ru + en)
This commit is contained in:
Fringg
2026-04-24 04:40:53 +03:00
parent ebe9d9be48
commit 312e0b4927
4 changed files with 535 additions and 59 deletions

View File

@@ -2028,6 +2028,8 @@
"selectedCount": "Selected: {{count}}",
"selectAll": "Select all",
"deselectAll": "Deselect all",
"selectUser": "Select user {{name}}",
"deselectUser": "Deselect user {{name}}",
"noResults": "No users found",
"actions": {
"extend": "Extend subscription",
@@ -2036,7 +2038,8 @@
"changeTariff": "Change tariff",
"addTraffic": "Add traffic",
"addBalance": "Add balance",
"assignPromoGroup": "Assign promo group"
"assignPromoGroup": "Assign promo group",
"grantSubscription": "Grant subscription"
},
"params": {
"days": "Number of days",
@@ -2046,12 +2049,28 @@
"promoGroup": "Promo group",
"removePromoGroup": "Remove promo group"
},
"grantSubscription": {
"warning": "Users who already have a subscription on the selected tariff will be skipped"
},
"confirm": "Apply",
"cancel": "Cancel",
"executing": "Executing...",
"complete": "Complete",
"successCount": "Succeeded: {{count}}",
"errorCount": "Errors: {{count}}",
"progress": {
"processed": "Processed: {{current}} / {{total}}",
"succeeded": "succeeded",
"failed": "failed",
"ok": "OK",
"errorGeneric": "Error",
"doNotClose": "Please do not close this window while the operation is in progress",
"summarySuccess": "{{count}} succeeded",
"summaryErrors": "{{count}} errors"
},
"errors": {
"title": "{{count}} errors — show details"
},
"filters": {
"search": "Search by ID, username, email",
"status": "Subscription status",