From 657a35e948aafae880dfbfb9e0ca66e0be6afcfe Mon Sep 17 00:00:00 2001 From: harsh-aghara Date: Sat, 2 May 2026 14:28:15 +0530 Subject: [PATCH] feat(i18n): implement strict pluralization for bulk action notifications Removes generic '(s)' syntax from backend responses. Adds proper _one and _other pluralization keys to all 16 locales with native grammar translations, resolving 0-count edge cases. Fixes #3602 --- client/src/Hooks/useBulkMonitorActions.ts | 60 ++++++++++++++------- client/src/locales/ar.json | 17 ++++-- client/src/locales/cs.json | 15 +++++- client/src/locales/de.json | 15 +++++- client/src/locales/en.json | 13 ++++- client/src/locales/es.json | 15 +++++- client/src/locales/fi.json | 17 ++++-- client/src/locales/fr.json | 15 +++++- client/src/locales/ja.json | 15 +++++- client/src/locales/pt-BR.json | 15 +++++- client/src/locales/ru.json | 15 +++++- client/src/locales/th.json | 17 ++++-- client/src/locales/tr.json | 15 +++++- client/src/locales/uk.json | 15 +++++- client/src/locales/vi.json | 17 ++++-- client/src/locales/zh-CN.json | 17 ++++-- client/src/locales/zh-TW.json | 17 ++++-- server/src/controllers/monitorController.ts | 3 +- 18 files changed, 256 insertions(+), 57 deletions(-) diff --git a/client/src/Hooks/useBulkMonitorActions.ts b/client/src/Hooks/useBulkMonitorActions.ts index 3bb520aa1..ddf96fedb 100644 --- a/client/src/Hooks/useBulkMonitorActions.ts +++ b/client/src/Hooks/useBulkMonitorActions.ts @@ -1,9 +1,14 @@ import { useState, useEffect } from "react"; -import { usePost } from "@/Hooks/UseApi"; +import { post } from "@/Utils/ApiClient"; +import { useToast } from "@/Hooks/UseToast"; +import { useTranslation } from "react-i18next"; +import { logger } from "@/Utils/logger"; +import type { Monitor } from "@/Types/Monitor"; -interface BulkPauseBody { - monitorIds: string[]; - pause: boolean; +interface ApiResponse { + success: boolean; + msg: string; + data: Monitor[]; } interface UseBulkMonitorActionsReturn { @@ -19,33 +24,50 @@ export const useBulkMonitorActions = ( page?: number ): UseBulkMonitorActionsReturn => { const [selectedRows, setSelectedRows] = useState([]); - const { post: bulkPost } = usePost(); + const { toastSuccess, toastError, toastInfo } = useToast(); + const { t } = useTranslation(); // Clear selection when page changes useEffect(() => { setSelectedRows([]); }, [page]); - const handleBulkPause = async () => { - const result = await bulkPost("/monitors/bulk/pause", { - monitorIds: selectedRows, - pause: true, - }); - if (result) { + const executeBulkAction = async (pause: boolean) => { + try { + const res = await post("/monitors/bulk/pause", { + monitorIds: selectedRows, + pause, + }); + + const affectedCount = res.data?.data?.length ?? 0; + + if (affectedCount === 0) { + const key = pause + ? "pages.common.monitors.bulkPause.alreadyPaused" + : "pages.common.monitors.bulkPause.alreadyRunning"; + toastInfo(t(key, { count: selectedRows.length })); + } else { + const key = pause + ? "pages.common.monitors.bulkPause.paused" + : "pages.common.monitors.bulkPause.resumed"; + toastSuccess(t(key, { count: affectedCount })); + } + setSelectedRows([]); refetch(); + } catch (err: any) { + const errMsg = err?.response?.data?.msg || err.message || "An error occurred"; + logger.error("Bulk pause/resume failed", err, { pause }); + toastError(errMsg); } }; + const handleBulkPause = async () => { + await executeBulkAction(true); + }; + const handleBulkResume = async () => { - const result = await bulkPost("/monitors/bulk/pause", { - monitorIds: selectedRows, - pause: false, - }); - if (result) { - setSelectedRows([]); - refetch(); - } + await executeBulkAction(false); }; const handleCancelSelection = () => { diff --git a/client/src/locales/ar.json b/client/src/locales/ar.json index 70509feed..5b21acd8e 100644 --- a/client/src/locales/ar.json +++ b/client/src/locales/ar.json @@ -422,9 +422,10 @@ "openSite": "فتح الموقع", "pause": "إيقاف مؤقت", "resume": "استئناف", - "bulkSelected": "تم تحديد {{count}} جهاز(أجهزة) مراقبة", - "selectAll": "تحديد جميع أجهزة المراقبة", - "selectMonitor": "تحديد {{name}}" + "selectAll": "تحديد جميع الشاشات", + "selectMonitor": "تحديد {{name}}", + "bulkSelected_one": "{{count}} شاشة محددة", + "bulkSelected_other": "{{count}} شاشات محددة" }, "statBoxes": { "activeFor": "نشط منذ", @@ -452,6 +453,16 @@ "optionHardware": "البنية التحتية", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "تم إيقاف {{count}} شاشة مؤقتاً", + "paused_other": "تم إيقاف {{count}} شاشات مؤقتاً", + "resumed_one": "تم استئناف {{count}} شاشة", + "resumed_other": "تم استئناف {{count}} شاشات", + "alreadyPaused_one": "الشاشة المحددة متوقفة مؤقتاً بالفعل", + "alreadyPaused_other": "جميع الشاشات المحددة متوقفة مؤقتاً بالفعل", + "alreadyRunning_one": "الشاشة المحددة قيد التشغيل بالفعل", + "alreadyRunning_other": "جميع الشاشات المحددة قيد التشغيل بالفعل" } } }, diff --git a/client/src/locales/cs.json b/client/src/locales/cs.json index e86677c29..e440b3b12 100644 --- a/client/src/locales/cs.json +++ b/client/src/locales/cs.json @@ -422,9 +422,10 @@ "openSite": "Otevřít stránku", "pause": "Pozastavit", "resume": "Obnovit", - "bulkSelected": "{{count}} monitor(ů) vybráno", "selectAll": "Vybrat všechny monitory", - "selectMonitor": "Vybrat {{name}}" + "selectMonitor": "Vybrat {{name}}", + "bulkSelected_one": "Vybrán {{count}} monitor", + "bulkSelected_other": "Vybráno {{count}} monitorů" }, "statBoxes": { "activeFor": "Aktivní po dobu", @@ -452,6 +453,16 @@ "optionHardware": "Infrastruktura", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} monitor pozastaven", + "paused_other": "{{count}} monitorů pozastaveno", + "resumed_one": "{{count}} monitor obnoven", + "resumed_other": "{{count}} monitorů obnoveno", + "alreadyPaused_one": "Vybraný monitor je již pozastaven", + "alreadyPaused_other": "Všechny vybrané monitory jsou již pozastaveny", + "alreadyRunning_one": "Vybraný monitor již běží", + "alreadyRunning_other": "Všechny vybrané monitory již běží" } } }, diff --git a/client/src/locales/de.json b/client/src/locales/de.json index cd93c4810..c3bc35011 100644 --- a/client/src/locales/de.json +++ b/client/src/locales/de.json @@ -422,9 +422,10 @@ "openSite": "Seite öffnen", "pause": "Pausieren", "resume": "Fortsetzen", - "bulkSelected": "{{count}} Monitor(e) ausgewählt", "selectAll": "Alle Monitore auswählen", - "selectMonitor": "{{name}} auswählen" + "selectMonitor": "{{name}} auswählen", + "bulkSelected_one": "{{count}} Monitor ausgewählt", + "bulkSelected_other": "{{count}} Monitore ausgewählt" }, "statBoxes": { "activeFor": "Aktiv seit", @@ -452,6 +453,16 @@ "optionHardware": "Infrastruktur", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} Monitor pausiert", + "paused_other": "{{count}} Monitore pausiert", + "resumed_one": "{{count}} Monitor fortgesetzt", + "resumed_other": "{{count}} Monitore fortgesetzt", + "alreadyPaused_one": "Der ausgewählte Monitor ist bereits pausiert", + "alreadyPaused_other": "Alle ausgewählten Monitore sind bereits pausiert", + "alreadyRunning_one": "Der ausgewählte Monitor wird bereits ausgeführt", + "alreadyRunning_other": "Alle ausgewählten Monitore werden bereits ausgeführt" } } }, diff --git a/client/src/locales/en.json b/client/src/locales/en.json index 2e22baa07..c505d0213 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -422,10 +422,21 @@ "openSite": "Open site", "pause": "Pause", "resume": "Resume", - "bulkSelected": "{{count}} Monitor(s) selected", + "bulkSelected_one": "{{count}} monitor selected", + "bulkSelected_other": "{{count}} monitors selected", "selectAll": "Select all monitors", "selectMonitor": "Select {{name}}" }, + "bulkPause": { + "alreadyPaused_one": "The selected monitor is already paused", + "alreadyPaused_other": "All selected monitors are already paused", + "alreadyRunning_one": "The selected monitor is already running", + "alreadyRunning_other": "All selected monitors are already running", + "paused_one": "{{count}} monitor paused", + "paused_other": "{{count}} monitors paused", + "resumed_one": "{{count}} monitor resumed", + "resumed_other": "{{count}} monitors resumed" + }, "statBoxes": { "activeFor": "Active for", "certificateExpiry": "Certificate expiry", diff --git a/client/src/locales/es.json b/client/src/locales/es.json index 04f447e40..f7c719f53 100644 --- a/client/src/locales/es.json +++ b/client/src/locales/es.json @@ -429,9 +429,10 @@ "openSite": "Abrir sitio", "pause": "Pausar", "resume": "Reanudar", - "bulkSelected": "{{count}} monitor(es) seleccionado(s)", "selectAll": "Seleccionar todos los monitores", - "selectMonitor": "Seleccionar {{name}}" + "selectMonitor": "Seleccionar {{name}}", + "bulkSelected_one": "{{count}} monitor seleccionado", + "bulkSelected_other": "{{count}} monitores seleccionados" }, "statBoxes": { "activeFor": "Activo desde hace", @@ -459,6 +460,16 @@ "optionHardware": "Infraestructura", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} monitor pausado", + "paused_other": "{{count}} monitores pausados", + "resumed_one": "{{count}} monitor reanudado", + "resumed_other": "{{count}} monitores reanudados", + "alreadyPaused_one": "El monitor seleccionado ya está pausado", + "alreadyPaused_other": "Todos los monitores seleccionados ya están pausados", + "alreadyRunning_one": "El monitor seleccionado ya se está ejecutando", + "alreadyRunning_other": "Todos los monitores seleccionados ya se están ejecutando" } } }, diff --git a/client/src/locales/fi.json b/client/src/locales/fi.json index 74afedd84..f74e9f58f 100644 --- a/client/src/locales/fi.json +++ b/client/src/locales/fi.json @@ -422,9 +422,10 @@ "openSite": "Avaa sivusto", "pause": "Keskeytä", "resume": "Jatka", - "bulkSelected": "{{count}} monitori(a) valittu", - "selectAll": "Valitse kaikki monitorit", - "selectMonitor": "Valitse {{name}}" + "selectAll": "Valitse kaikki näytöt", + "selectMonitor": "Valitse {{name}}", + "bulkSelected_one": "{{count}} näyttö valittu", + "bulkSelected_other": "{{count}} näyttöä valittu" }, "statBoxes": { "activeFor": "Aktiivinen", @@ -452,6 +453,16 @@ "optionHardware": "Infrastruktuuri", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} näyttö keskeytetty", + "paused_other": "{{count}} näyttöä keskeytetty", + "resumed_one": "{{count}} näyttö jatkettu", + "resumed_other": "{{count}} näyttöä jatkettu", + "alreadyPaused_one": "Valittu näyttö on jo keskeytetty", + "alreadyPaused_other": "Kaikki valitut näytöt on jo keskeytetty", + "alreadyRunning_one": "Valittu näyttö on jo käynnissä", + "alreadyRunning_other": "Kaikki valitut näytöt ovat jo käynnissä" } } }, diff --git a/client/src/locales/fr.json b/client/src/locales/fr.json index 8e3c78b85..003f64118 100644 --- a/client/src/locales/fr.json +++ b/client/src/locales/fr.json @@ -422,9 +422,10 @@ "openSite": "Ouvrir le site", "pause": "Pause", "resume": "Reprendre", - "bulkSelected": "{{count}} moniteur(s) sélectionné(s)", "selectAll": "Sélectionner tous les moniteurs", - "selectMonitor": "Sélectionner {{name}}" + "selectMonitor": "Sélectionner {{name}}", + "bulkSelected_one": "{{count}} moniteur sélectionné", + "bulkSelected_other": "{{count}} moniteurs sélectionnés" }, "statBoxes": { "activeFor": "Actif depuis", @@ -452,6 +453,16 @@ "optionHardware": "Infrastructure", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} moniteur en pause", + "paused_other": "{{count}} moniteurs en pause", + "resumed_one": "{{count}} moniteur repris", + "resumed_other": "{{count}} moniteurs repris", + "alreadyPaused_one": "Le moniteur sélectionné est déjà en pause", + "alreadyPaused_other": "Tous les moniteurs sélectionnés sont déjà en pause", + "alreadyRunning_one": "Le moniteur sélectionné est déjà en cours d'exécution", + "alreadyRunning_other": "Tous les moniteurs sélectionnés sont déjà en cours d'exécution" } } }, diff --git a/client/src/locales/ja.json b/client/src/locales/ja.json index 09db6971f..1cf614379 100644 --- a/client/src/locales/ja.json +++ b/client/src/locales/ja.json @@ -422,9 +422,10 @@ "openSite": "サイトを開く", "pause": "一時停止", "resume": "再開", - "bulkSelected": "{{count}} 件のモニターを選択中", "selectAll": "すべてのモニターを選択", - "selectMonitor": "{{name}} を選択" + "selectMonitor": "{{name}} を選択", + "bulkSelected_one": "{{count}} 個のモニターが選択されました", + "bulkSelected_other": "{{count}} 個のモニターが選択されました" }, "statBoxes": { "activeFor": "稼働期間", @@ -452,6 +453,16 @@ "optionHardware": "インフラストラクチャ", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} 個のモニターを一時停止しました", + "paused_other": "{{count}} 個のモニターを一時停止しました", + "resumed_one": "{{count}} 個のモニターを再開しました", + "resumed_other": "{{count}} 個のモニターを再開しました", + "alreadyPaused_one": "選択したモニターはすでに一時停止されています", + "alreadyPaused_other": "選択したすべてのモニターはすでに一時停止されています", + "alreadyRunning_one": "選択したモニターはすでに実行中です", + "alreadyRunning_other": "選択したすべてのモニターはすでに実行中です" } } }, diff --git a/client/src/locales/pt-BR.json b/client/src/locales/pt-BR.json index 6c97a9869..6cc241777 100644 --- a/client/src/locales/pt-BR.json +++ b/client/src/locales/pt-BR.json @@ -422,9 +422,10 @@ "openSite": "Abrir site", "pause": "Pausar", "resume": "Retomar", - "bulkSelected": "{{count}} monitor(es) selecionado(s)", "selectAll": "Selecionar todos os monitores", - "selectMonitor": "Selecionar {{name}}" + "selectMonitor": "Selecionar {{name}}", + "bulkSelected_one": "{{count}} monitor selecionado", + "bulkSelected_other": "{{count}} monitores selecionados" }, "statBoxes": { "activeFor": "Ativo há", @@ -452,6 +453,16 @@ "optionHardware": "Infraestrutura", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} monitor pausado", + "paused_other": "{{count}} monitores pausados", + "resumed_one": "{{count}} monitor retomado", + "resumed_other": "{{count}} monitores retomados", + "alreadyPaused_one": "O monitor selecionado já está pausado", + "alreadyPaused_other": "Todos os monitores selecionados já estão pausados", + "alreadyRunning_one": "O monitor selecionado já está em execução", + "alreadyRunning_other": "Todos os monitores selecionados já estão em execução" } } }, diff --git a/client/src/locales/ru.json b/client/src/locales/ru.json index 778d481f9..171a596dd 100644 --- a/client/src/locales/ru.json +++ b/client/src/locales/ru.json @@ -422,9 +422,10 @@ "openSite": "Открыть сайт", "pause": "Пауза", "resume": "Продолжить", - "bulkSelected": "Выбрано мониторов: {{count}}", "selectAll": "Выбрать все мониторы", - "selectMonitor": "Выбрать {{name}}" + "selectMonitor": "Выбрать {{name}}", + "bulkSelected_one": "Выбран {{count}} монитор", + "bulkSelected_other": "Выбрано {{count}} мониторов" }, "statBoxes": { "activeFor": "Активен", @@ -452,6 +453,16 @@ "optionHardware": "Инфраструктура", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} монитор приостановлен", + "paused_other": "{{count}} мониторов приостановлено", + "resumed_one": "{{count}} монитор возобновлен", + "resumed_other": "{{count}} мониторов возобновлено", + "alreadyPaused_one": "Выбранный монитор уже приостановлен", + "alreadyPaused_other": "Все выбранные мониторы уже приостановлены", + "alreadyRunning_one": "Выбранный монитор уже запущен", + "alreadyRunning_other": "Все выбранные мониторы уже запущены" } } }, diff --git a/client/src/locales/th.json b/client/src/locales/th.json index aab97dc93..d39a20a6f 100644 --- a/client/src/locales/th.json +++ b/client/src/locales/th.json @@ -422,9 +422,10 @@ "openSite": "เปิดเว็บไซต์", "pause": "หยุดชั่วคราว", "resume": "ดำเนินการต่อ", - "bulkSelected": "เลือก {{count}} มอนิเตอร์แล้ว", - "selectAll": "เลือกมอนิเตอร์ทั้งหมด", - "selectMonitor": "เลือก {{name}}" + "selectAll": "เลือกจอภาพทั้งหมด", + "selectMonitor": "เลือก {{name}}", + "bulkSelected_one": "เลือกแล้ว {{count}} จอภาพ", + "bulkSelected_other": "เลือกแล้ว {{count}} จอภาพ" }, "statBoxes": { "activeFor": "ทำงานมาแล้ว", @@ -452,6 +453,16 @@ "optionHardware": "โครงสร้างพื้นฐาน", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "หยุดจอภาพชั่วคราว {{count}} จอ", + "paused_other": "หยุดจอภาพชั่วคราว {{count}} จอ", + "resumed_one": "กลับมาทำงานต่อ {{count}} จอ", + "resumed_other": "กลับมาทำงานต่อ {{count}} จอ", + "alreadyPaused_one": "จอภาพที่เลือกถูกหยุดชั่วคราวแล้ว", + "alreadyPaused_other": "จอภาพที่เลือกทั้งหมดถูกหยุดชั่วคราวแล้ว", + "alreadyRunning_one": "จอภาพที่เลือกกำลังทำงานอยู่แล้ว", + "alreadyRunning_other": "จอภาพที่เลือกทั้งหมดกำลังทำงานอยู่แล้ว" } } }, diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json index 6e6aaf365..dd5fcfa80 100644 --- a/client/src/locales/tr.json +++ b/client/src/locales/tr.json @@ -422,9 +422,10 @@ "openSite": "Siteyi aç", "pause": "Duraklat", "resume": "Devam et", - "bulkSelected": "{{count}} monitör seçildi", "selectAll": "Tüm monitörleri seç", - "selectMonitor": "{{name}} seç" + "selectMonitor": "{{name}}'i seç", + "bulkSelected_one": "{{count}} monitör seçildi", + "bulkSelected_other": "{{count}} monitör seçildi" }, "statBoxes": { "activeFor": "Aktif süresi", @@ -452,6 +453,16 @@ "optionHardware": "Altyapı", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} monitör duraklatıldı", + "paused_other": "{{count}} monitör duraklatıldı", + "resumed_one": "{{count}} monitör sürdürüldü", + "resumed_other": "{{count}} monitör sürdürüldü", + "alreadyPaused_one": "Seçili monitör zaten duraklatıldı", + "alreadyPaused_other": "Seçili tüm monitörler zaten duraklatıldı", + "alreadyRunning_one": "Seçili monitör zaten çalışıyor", + "alreadyRunning_other": "Seçili tüm monitörler zaten çalışıyor" } } }, diff --git a/client/src/locales/uk.json b/client/src/locales/uk.json index f7ff24647..9b893d56a 100644 --- a/client/src/locales/uk.json +++ b/client/src/locales/uk.json @@ -422,9 +422,10 @@ "openSite": "Відкрити сайт", "pause": "Призупинити", "resume": "Відновити", - "bulkSelected": "Вибрано моніторів: {{count}}", "selectAll": "Вибрати всі монітори", - "selectMonitor": "Вибрати {{name}}" + "selectMonitor": "Вибрати {{name}}", + "bulkSelected_one": "Вибрано {{count}} монітор", + "bulkSelected_other": "Вибрано {{count}} моніторів" }, "statBoxes": { "activeFor": "Активний протягом", @@ -452,6 +453,16 @@ "optionHardware": "Інфраструктура", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "{{count}} монітор призупинено", + "paused_other": "{{count}} моніторів призупинено", + "resumed_one": "{{count}} монітор відновлено", + "resumed_other": "{{count}} моніторів відновлено", + "alreadyPaused_one": "Вибраний монітор уже призупинено", + "alreadyPaused_other": "Всі вибрані монітори уже призупинено", + "alreadyRunning_one": "Вибраний монітор уже запущено", + "alreadyRunning_other": "Всі вибрані монітори уже запущено" } } }, diff --git a/client/src/locales/vi.json b/client/src/locales/vi.json index 90d8afd04..a7363cea5 100644 --- a/client/src/locales/vi.json +++ b/client/src/locales/vi.json @@ -422,9 +422,10 @@ "openSite": "Mở trang web", "pause": "Tạm dừng", "resume": "Tiếp tục", - "bulkSelected": "Đã chọn {{count}} monitor", - "selectAll": "Chọn tất cả monitor", - "selectMonitor": "Chọn {{name}}" + "selectAll": "Chọn tất cả màn hình", + "selectMonitor": "Chọn {{name}}", + "bulkSelected_one": "Đã chọn {{count}} màn hình", + "bulkSelected_other": "Đã chọn {{count}} màn hình" }, "statBoxes": { "activeFor": "Hoạt động từ", @@ -452,6 +453,16 @@ "optionHardware": "Hạ tầng", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "Đã tạm dừng {{count}} màn hình", + "paused_other": "Đã tạm dừng {{count}} màn hình", + "resumed_one": "Đã tiếp tục {{count}} màn hình", + "resumed_other": "Đã tiếp tục {{count}} màn hình", + "alreadyPaused_one": "Màn hình đã chọn đã được tạm dừng", + "alreadyPaused_other": "Tất cả các màn hình đã chọn đã được tạm dừng", + "alreadyRunning_one": "Màn hình đã chọn đã đang chạy", + "alreadyRunning_other": "Tất cả các màn hình đã chọn đã đang chạy" } } }, diff --git a/client/src/locales/zh-CN.json b/client/src/locales/zh-CN.json index 73a4ce166..861f0dd8b 100644 --- a/client/src/locales/zh-CN.json +++ b/client/src/locales/zh-CN.json @@ -422,9 +422,10 @@ "openSite": "打开站点", "pause": "暂停", "resume": "恢复", - "bulkSelected": "已选择 {{count}} 个监控", - "selectAll": "选择所有监控", - "selectMonitor": "选择 {{name}}" + "selectAll": "选择所有监视器", + "selectMonitor": "选择 {{name}}", + "bulkSelected_one": "已选择 {{count}} 个监视器", + "bulkSelected_other": "已选择 {{count}} 个监视器" }, "statBoxes": { "activeFor": "已活跃", @@ -452,6 +453,16 @@ "optionHardware": "基础设施", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "已暂停 {{count}} 个监视器", + "paused_other": "已暂停 {{count}} 个监视器", + "resumed_one": "已恢复 {{count}} 个监视器", + "resumed_other": "已恢复 {{count}} 个监视器", + "alreadyPaused_one": "所选监视器已暂停", + "alreadyPaused_other": "所有选定的监视器均已暂停", + "alreadyRunning_one": "所选监视器已经在运行", + "alreadyRunning_other": "所有选定的监视器均已在运行" } } }, diff --git a/client/src/locales/zh-TW.json b/client/src/locales/zh-TW.json index 91fc7766e..c5992e2b4 100644 --- a/client/src/locales/zh-TW.json +++ b/client/src/locales/zh-TW.json @@ -422,9 +422,10 @@ "openSite": "開啟網站", "pause": "暫停", "resume": "恢復", - "bulkSelected": "已選擇 {{count}} 個監控", - "selectAll": "選擇所有監控", - "selectMonitor": "選擇 {{name}}" + "selectAll": "選擇所有監視器", + "selectMonitor": "選擇 {{name}}", + "bulkSelected_one": "已選擇 {{count}} 個監視器", + "bulkSelected_other": "已選擇 {{count}} 個監視器" }, "statBoxes": { "activeFor": "已啟用", @@ -452,6 +453,16 @@ "optionHardware": "基礎架構", "optionGrpc": "gRPC", "optionWebSocket": "WebSocket" + }, + "bulkPause": { + "paused_one": "已暫停 {{count}} 個監視器", + "paused_other": "已暫停 {{count}} 個監視器", + "resumed_one": "已恢復 {{count}} 個監視器", + "resumed_other": "已恢復 {{count}} 個監視器", + "alreadyPaused_one": "所選監視器已暫停", + "alreadyPaused_other": "所有選定的監視器均已暫停", + "alreadyRunning_one": "所選監視器已經在運行", + "alreadyRunning_other": "所有選定的監視器均已在運行" } } }, diff --git a/server/src/controllers/monitorController.ts b/server/src/controllers/monitorController.ts index 4529f972d..7422d5abb 100644 --- a/server/src/controllers/monitorController.ts +++ b/server/src/controllers/monitorController.ts @@ -318,10 +318,11 @@ class MonitorController implements IMonitorController { const monitors = await this.monitorService.bulkPauseMonitors({ teamId, monitorIds, pause }); const action = pause ? "paused" : "resumed"; + const monitorStr = monitors.length === 1 ? "monitor" : "monitors"; return res.status(200).json({ success: true, - msg: `${monitors.length} monitor(s) ${action} successfully`, + msg: `${monitors.length} ${monitorStr} ${action} successfully`, data: monitors, }); } catch (error) {