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

@@ -3776,6 +3776,8 @@
"selectedCount": "Выбрано: {{count}}",
"selectAll": "Выбрать всех",
"deselectAll": "Снять выделение",
"selectUser": "Выбрать пользователя {{name}}",
"deselectUser": "Снять выбор пользователя {{name}}",
"noResults": "Пользователи не найдены",
"actions": {
"extend": "Продлить подписку",
@@ -3784,7 +3786,8 @@
"changeTariff": "Сменить тариф",
"addTraffic": "Начислить трафик",
"addBalance": "Начислить баланс",
"assignPromoGroup": "Назначить промогруппу"
"assignPromoGroup": "Назначить промогруппу",
"grantSubscription": "Выдать подписку"
},
"params": {
"days": "Количество дней",
@@ -3794,12 +3797,28 @@
"promoGroup": "Промогруппа",
"removePromoGroup": "Убрать промогруппу"
},
"grantSubscription": {
"warning": "Пользователи, у которых уже есть подписка на выбранный тариф, будут пропущены"
},
"confirm": "Применить",
"cancel": "Отмена",
"executing": "Выполнение...",
"complete": "Выполнено",
"successCount": "Успешно: {{count}}",
"errorCount": "Ошибок: {{count}}",
"progress": {
"processed": "Обработано: {{current}} / {{total}}",
"succeeded": "успешно",
"failed": "ошибок",
"ok": "ОК",
"errorGeneric": "Ошибка",
"doNotClose": "Не закрывайте это окно, пока операция выполняется",
"summarySuccess": "{{count}} успешно",
"summaryErrors": "{{count}} ошибок"
},
"errors": {
"title": "{{count}} ошибок — показать детали"
},
"filters": {
"search": "Поиск по ID, нику, email",
"status": "Статус подписки",