}
@@ -223,7 +223,9 @@ function AlertContent({ data }: { data: AlertData }) {
{t("alerts.for")} {min}{" "}
- {min > 1 ? t("alerts.minutes") : t("alerts.minute")}
+ {t("minutes", {
+ count: min,
+ }).replace(String(min), "")}
{Object.entries(chartTimeData).map(([value, { label }]) => (
-
- {label}
+
+ {label()}
))}
diff --git a/beszel/site/src/components/routes/home.tsx b/beszel/site/src/components/routes/home.tsx
index f716259..29aab6e 100644
--- a/beszel/site/src/components/routes/home.tsx
+++ b/beszel/site/src/components/routes/home.tsx
@@ -82,7 +82,9 @@ export default function () {
{t("home.active_des", {
value: alert.value,
unit: info.unit,
- minutes: alert.min,
+ })}
+ {t("minutes", {
+ count: alert.min,
})}
{Object.entries(chartTimeData).map(([value, { label }]) => (
-
- {label}
+
+ {label()}
))}
diff --git a/beszel/site/src/lib/utils.ts b/beszel/site/src/lib/utils.ts
index e20fe67..44a53d3 100644
--- a/beszel/site/src/lib/utils.ts
+++ b/beszel/site/src/lib/utils.ts
@@ -10,6 +10,7 @@ import { useEffect, useState } from "react"
import { CpuIcon, HardDriveIcon, MemoryStickIcon, ServerIcon } from "lucide-react"
import { EthernetIcon, ThermometerIcon } from "@/components/ui/icons"
import { t } from "i18next"
+
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
@@ -153,7 +154,7 @@ export const chartTimeData: ChartTimeData = {
"1h": {
type: "1m",
expectedInterval: 60_000,
- label: "1 hour",
+ label: () => t("hours", { count: 1 }),
// ticks: 12,
format: (timestamp: string) => hourWithMinutes(timestamp),
getOffset: (endTime: Date) => timeHour.offset(endTime, -1),
@@ -161,7 +162,7 @@ export const chartTimeData: ChartTimeData = {
"12h": {
type: "10m",
expectedInterval: 60_000 * 10,
- label: "12 hours",
+ label: () => t("hours", { count: 12 }),
ticks: 12,
format: (timestamp: string) => hourWithMinutes(timestamp),
getOffset: (endTime: Date) => timeHour.offset(endTime, -12),
@@ -169,14 +170,14 @@ export const chartTimeData: ChartTimeData = {
"24h": {
type: "20m",
expectedInterval: 60_000 * 20,
- label: "24 hours",
+ label: () => t("hours", { count: 24 }),
format: (timestamp: string) => hourWithMinutes(timestamp),
getOffset: (endTime: Date) => timeHour.offset(endTime, -24),
},
"1w": {
type: "120m",
expectedInterval: 60_000 * 120,
- label: "1 week",
+ label: () => t("weeks", { count: 1 }),
ticks: 7,
format: (timestamp: string) => formatDay(timestamp),
getOffset: (endTime: Date) => timeDay.offset(endTime, -7),
@@ -184,7 +185,7 @@ export const chartTimeData: ChartTimeData = {
"30d": {
type: "480m",
expectedInterval: 60_000 * 480,
- label: "30 days",
+ label: () => t("days_other", { count: 30 }),
ticks: 30,
format: (timestamp: string) => formatDay(timestamp),
getOffset: (endTime: Date) => timeDay.offset(endTime, -30),
diff --git a/beszel/site/src/locales/ar/translation.json b/beszel/site/src/locales/ar/translation.json
index 26d3ff1..1cbb887 100644
--- a/beszel/site/src/locales/ar/translation.json
+++ b/beszel/site/src/locales/ar/translation.json
@@ -8,9 +8,15 @@
"systems": "الأنظمة",
"cancel": "إلغاء",
"continue": "متابعة",
+ "minutes_one": "{{count}} دقيقة",
+ "minutes_other": "{{count}} دقائق",
+ "hours_one": "{{count}} ساعة",
+ "hours_other": "{{count}} ساعات",
+ "days_other": "{{count}} أيام",
+ "weeks_one": "{{count}} أسبوع",
"home": {
"active_alerts": "التنبيهات النشطة",
- "active_des": "يتجاوز متوسط {{value}}{{unit}} في آخر {{minutes}} دقيقة",
+ "active_des": "يتجاوز {{value}}{{unit}} في آخر ",
"subtitle": "يتم التحديث في الوقت الفعلي. انقر على نظام لعرض المعلومات."
},
"systems_table": {
@@ -49,9 +55,7 @@
"bandwidth_des": "يتم التشغيل عندما يتجاوز استخدام الشبكة الحد."
},
"average_exceeds": "المتوسط يتجاوز",
- "for": "لمدة",
- "minute": "دقيقة",
- "minutes": "دقائق"
+ "for": "لمدة"
},
"settings": {
"settings": "الإعدادات",
@@ -86,7 +90,7 @@
"to_ensure_alerts_are_delivered": "لضمان تسليم التنبيهات.",
"to_email_s": "إلى البريد الإلكتروني",
"enter_email_address": "أدخل عنوان البريد الإلكتروني...",
- "des": "احفظ العنوان باستخدام مفتاح الإدخال أو الفاصلة. اتركه فارغاً لتعطيل إشعارات البريد الإلكتروني."
+ "des": "احفظ العنوان باستخدام مفتاح الإدخال أو الفاصلة. اتركه فا��غاً لتعطيل إشعارات البريد الإلكتروني."
},
"webhook_push": {
"title": "إشعارات Webhook / Push",
diff --git a/beszel/site/src/locales/de/translation.json b/beszel/site/src/locales/de/translation.json
index 68680bb..ad8ab33 100644
--- a/beszel/site/src/locales/de/translation.json
+++ b/beszel/site/src/locales/de/translation.json
@@ -8,9 +8,15 @@
"systems": "Systeme",
"cancel": "Abbrechen",
"continue": "Fortsetzen",
+ "minutes_one": "{{count}} Minute",
+ "minutes_other": "{{count}} Minuten",
+ "hours_one": "{{count}} Stunde",
+ "hours_other": "{{count}} Stunden",
+ "days_other": "{{count}} Tage",
+ "weeks_one": "{{count}} Woche",
"home": {
"active_alerts": "Aktive Warnungen",
- "active_des": "Überschreitet {{value}}{{unit}} Durchschnitt in den letzten {{minutes}} Minuten",
+ "active_des": "Überschreitet {{value}}{{unit}} in den letzten ",
"subtitle": "Wird in Echtzeit aktualisiert. Klicken Sie auf ein System, um Informationen anzuzeigen."
},
"systems_table": {
@@ -51,9 +57,7 @@
"temperature_des": "Löst aus, wenn ein Sensor einen Schwellenwert überschreitet."
},
"average_exceeds": "Durchschnitt überschreitet",
- "for": "Für",
- "minute": "Minute",
- "minutes": "Minuten"
+ "for": "Für"
},
"settings": {
"settings": "Einstellungen",
diff --git a/beszel/site/src/locales/en/translation.json b/beszel/site/src/locales/en/translation.json
index bae7747..dcb1ae6 100644
--- a/beszel/site/src/locales/en/translation.json
+++ b/beszel/site/src/locales/en/translation.json
@@ -8,9 +8,15 @@
"systems": "Systems",
"cancel": "Cancel",
"continue": "Continue",
+ "minutes_one": "{{count}} minute",
+ "minutes_other": "{{count}} minutes",
+ "hours_one": "{{count}} hour",
+ "hours_other": "{{count}} hours",
+ "days_other": "{{count}} days",
+ "weeks_one": "{{count}} week",
"home": {
"active_alerts": "Active Alerts",
- "active_des": "Exceeds {{value}}{{unit}} average in last {{minutes}} min",
+ "active_des": "Exceeds {{value}}{{unit}} in last ",
"subtitle": "Updated in real time. Click on a system to view information."
},
"systems_table": {
@@ -51,9 +57,7 @@
"temperature_des": "Triggers when any sensor exceeds a threshold."
},
"average_exceeds": "Average exceeds",
- "for": "For",
- "minute": "minute",
- "minutes": "minutes"
+ "for": "For"
},
"settings": {
"settings": "Settings",
diff --git a/beszel/site/src/locales/es/translation.json b/beszel/site/src/locales/es/translation.json
index 7c49224..0be6ae6 100644
--- a/beszel/site/src/locales/es/translation.json
+++ b/beszel/site/src/locales/es/translation.json
@@ -8,9 +8,15 @@
"systems": "Sistemas",
"cancel": "Cancelar",
"continue": "Continuar",
+ "minutes_one": "{{count}} minuto",
+ "minutes_other": "{{count}} minutos",
+ "hours_one": "{{count}} hora",
+ "hours_other": "{{count}} horas",
+ "days_other": "{{count}} días",
+ "weeks_one": "{{count}} semana",
"home": {
"active_alerts": "Alertas activas",
- "active_des": "Excede el promedio de {{value}}{{unit}} en los últimos {{minutes}} minutos",
+ "active_des": "Excede {{value}}{{unit}} en los últimos ",
"subtitle": "Actualizado en tiempo real. Haga clic en un sistema para ver información."
},
"systems_table": {
@@ -51,9 +57,7 @@
"temperature_des": "Se activa cuando cualquier sensor supera un umbral."
},
"average_exceeds": "Promedio excede",
- "for": "Por",
- "minute": "minuto",
- "minutes": "minutos"
+ "for": "Por"
},
"settings": {
"settings": "Configuraciones",
diff --git a/beszel/site/src/locales/fr/translation.json b/beszel/site/src/locales/fr/translation.json
index 2ed857e..598bfff 100644
--- a/beszel/site/src/locales/fr/translation.json
+++ b/beszel/site/src/locales/fr/translation.json
@@ -8,9 +8,15 @@
"systems": "Systèmes",
"cancel": "Annuler",
"continue": "Continuer",
+ "minutes_one": "{{count}} minute",
+ "minutes_other": "{{count}} minutes",
+ "hours_one": "{{count}} heure",
+ "hours_other": "{{count}} heures",
+ "days_other": "{{count}} jours",
+ "weeks_one": "{{count}} semaine",
"home": {
"active_alerts": "Alertes actives",
- "active_des": "Dépasse {{value}}{{unit}} en moyenne au cours des {{minutes}} dernières minutes",
+ "active_des": "Dépasse {{value}}{{unit}} dans les derniers ",
"subtitle": "Mis à jour en temps réel. Cliquez sur un système pour voir les informations.",
"subtitle_1": "Mis à jour en temps réel. Appuyez sur",
"subtitle_2": "pour ouvrir la palette de commandes."
@@ -53,9 +59,7 @@
"temperature_des": "Déclenchement lorsque n'importe quel capteur dépasse un seuil."
},
"average_exceeds": "La moyenne dépasse",
- "for": "Pour",
- "minute": "minute",
- "minutes": "minutes"
+ "for": "Pour"
},
"settings": {
"settings": "Paramètres",
diff --git a/beszel/site/src/locales/ja/translation.json b/beszel/site/src/locales/ja/translation.json
index db843a3..ccc256c 100644
--- a/beszel/site/src/locales/ja/translation.json
+++ b/beszel/site/src/locales/ja/translation.json
@@ -8,9 +8,16 @@
"systems": "システム一覧",
"cancel": "キャンセル",
"continue": "続行",
+ "minutes_one": "{{count}}分",
+ "minutes_other": "{{count}}分",
+ "hours_one": "{{count}}時間",
+ "hours_other": "{{count}}時間",
+ "days_other": "{{count}}日",
+ "weeks_one": "{{count}}週間",
+ "weeks_other": "{{count}}週間",
"home": {
"active_alerts": "アクティブなアラート",
- "active_des": "過去{{minutes}}分間の平均が{{value}}{{unit}}を超過",
+ "active_des": "過去{{value}}{{unit}}を超過",
"subtitle": "リアルタイムで更新されます。システムをクリックして情報を表示します。"
},
"systems_table": {
@@ -51,9 +58,7 @@
"temperature_des": "いずれかのセンサーが閾値を超えた時にトリガー。"
},
"average_exceeds": "平均値が超過",
- "for": "期間",
- "minute": "分",
- "minutes": "分"
+ "for": "期間"
},
"settings": {
"settings": "設定",
diff --git a/beszel/site/src/locales/ko/translation.json b/beszel/site/src/locales/ko/translation.json
index f961905..4f45ac4 100644
--- a/beszel/site/src/locales/ko/translation.json
+++ b/beszel/site/src/locales/ko/translation.json
@@ -8,9 +8,16 @@
"systems": "시스템",
"cancel": "취소",
"continue": "계속",
+ "minutes_one": "{{count}}분",
+ "minutes_other": "{{count}}분",
+ "hours_one": "{{count}}시간",
+ "hours_other": "{{count}}시간",
+ "days_other": "{{count}}일",
+ "weeks_one": "{{count}}주",
+ "weeks_other": "{{count}}주",
"home": {
"active_alerts": "활성 경고",
- "active_des": "지난 {{minutes}}분 동안 평균 {{value}}{{unit}} 초과",
+ "active_des": "{{value}}{{unit}} 초과 지난",
"subtitle": "실시간으로 업데이트됩니다. 시스템을 클릭하여 정보를 확인하세요."
},
"systems_table": {
@@ -51,9 +58,7 @@
"temperature_des": "센서가 임계값을 초과할 때 트리거됩니다."
},
"average_exceeds": "평균 초과",
- "for": "동안",
- "minute": "분",
- "minutes": "분"
+ "for": "동안"
},
"settings": {
"settings": "설정",
diff --git a/beszel/site/src/locales/pt/translation.json b/beszel/site/src/locales/pt/translation.json
index 34e0c5d..fa124c6 100644
--- a/beszel/site/src/locales/pt/translation.json
+++ b/beszel/site/src/locales/pt/translation.json
@@ -8,9 +8,15 @@
"systems": "Sistemas",
"cancel": "Cancelar",
"continue": "Continuar",
+ "minutes_one": "{{count}} minuto",
+ "minutes_other": "{{count}} minutos",
+ "hours_one": "{{count}} hora",
+ "hours_other": "{{count}} horas",
+ "days_other": "{{count}} dias",
+ "weeks_one": "{{count}} semana",
"home": {
"active_alerts": "Alertas Ativos",
- "active_des": "Excede {{value}}{{unit}} em média nos últimos {{minutes}} minutos",
+ "active_des": "Excede {{value}}{{unit}} nos últimos ",
"subtitle": "Atualizado em tempo real. Clique em um sistema para ver informações."
},
"systems_table": {
@@ -51,9 +57,7 @@
"temperature_des": "Dispara quando qualquer sensor excede um limite."
},
"average_exceeds": "Média excede",
- "for": "Por",
- "minute": "minuto",
- "minutes": "minutos"
+ "for": "Por"
},
"settings": {
"settings": "Configurações",
diff --git a/beszel/site/src/locales/ru/translation.json b/beszel/site/src/locales/ru/translation.json
index 8397c2c..5a7ba6b 100644
--- a/beszel/site/src/locales/ru/translation.json
+++ b/beszel/site/src/locales/ru/translation.json
@@ -8,9 +8,17 @@
"systems": "Системы",
"cancel": "Отмена",
"continue": "Продолжить",
+ "minutes_one": "{{count}} минута",
+ "minutes_other": "{{count}} минут",
+ "hours_one": "{{count}} час",
+ "hours_few": "{{count}} часа",
+ "hours_many": "{{count}} часов",
+ "hours_other": "{{count}} часов",
+ "days_other": "{{count}} дней",
+ "weeks_one": "{{count}} неделя",
"home": {
"active_alerts": "Активные предупреждения",
- "active_des": "Превышает {{value}}{{unit}} в среднем за последние {{minutes}} минут",
+ "active_des": "Превышает {{value}}{{unit}} за последние ",
"subtitle": "Обновляется в реальном времени. Нажмите на систему для просмотра информации."
},
"systems_table": {
@@ -51,9 +59,7 @@
"temperature_des": "Срабатывает, когда любой датчик превышает порог."
},
"average_exceeds": "Среднее превышает",
- "for": "За",
- "minute": "минуту",
- "minutes": "минут"
+ "for": "За"
},
"settings": {
"settings": "Настройки",
diff --git a/beszel/site/src/locales/vi/translation.json b/beszel/site/src/locales/vi/translation.json
index 1e9a91a..f8b15dd 100644
--- a/beszel/site/src/locales/vi/translation.json
+++ b/beszel/site/src/locales/vi/translation.json
@@ -8,9 +8,16 @@
"systems": "Các hệ thống",
"cancel": "Hủy",
"continue": "Tiếp tục",
+ "minutes_one": "{{count}} phút",
+ "minutes_other": "{{count}} phút",
+ "hours_one": "{{count}} giờ",
+ "hours_other": "{{count}} giờ",
+ "days_other": "{{count}} ngày",
+ "weeks_one": "{{count}} tuần",
+ "weeks_other": "{{count}} tuần",
"home": {
"active_alerts": "Cảnh báo đang hoạt động",
- "active_des": "Vượt quá {{value}}{{unit}} trung bình trong {{minutes}} phút cuối",
+ "active_des": "Vượt quá {{value}}{{unit}} trong ",
"subtitle": "Cập nhật theo thời gian thực. Nhấp vào hệ thống để xem thông tin."
},
"systems_table": {
@@ -51,9 +58,7 @@
"temperature_des": "Kích hoạt khi bất kỳ cảm biến nào vượt quá ngưỡng."
},
"average_exceeds": "Trung bình vượt quá",
- "for": "Trong",
- "minute": "phút",
- "minutes": "phút"
+ "for": "Trong"
},
"settings": {
"settings": "Cài đặt",
diff --git a/beszel/site/src/locales/zh-CN/translation.json b/beszel/site/src/locales/zh-CN/translation.json
index 37fda2b..e24bfb6 100644
--- a/beszel/site/src/locales/zh-CN/translation.json
+++ b/beszel/site/src/locales/zh-CN/translation.json
@@ -8,9 +8,16 @@
"systems": "服务器",
"cancel": "取消",
"continue": "继续",
+ "minutes_one": "{{count}} 分钟",
+ "minutes_other": "{{count}} 分钟",
+ "hours_one": "{{count}} 小时",
+ "hours_other": "{{count}} 小时",
+ "days_other": "{{count}} 天",
+ "weeks_one": "{{count}} 周",
+ "weeks_other": "{{count}} 周",
"home": {
"active_alerts": "活动警报",
- "active_des": "在过去 {{minutes}} 分钟内超过 {{value}}{{unit}} 平均值",
+ "active_des": "超过 {{value}}{{unit}} 在过去 ",
"subtitle": "实时更新。点击系统以查看信息。"
},
"systems_table": {
@@ -51,9 +58,7 @@
"temperature_des": "当任何传感器超过阈值时触发。"
},
"average_exceeds": "平均值超过",
- "for": "持续",
- "minute": "分钟",
- "minutes": "分钟"
+ "for": "持续"
},
"settings": {
"settings": "设置",
diff --git a/beszel/site/src/locales/zh-HK/translation.json b/beszel/site/src/locales/zh-HK/translation.json
index 406290a..9ed3f9c 100644
--- a/beszel/site/src/locales/zh-HK/translation.json
+++ b/beszel/site/src/locales/zh-HK/translation.json
@@ -8,9 +8,15 @@
"systems": "伺服器",
"cancel": "取消",
"continue": "繼續",
+ "minutes_one": "{{count}} 分鐘",
+ "minutes_other": "{{count}} 分鐘",
+ "hours_one": "{{count}} 小時",
+ "hours_other": "{{count}} 小時",
+ "days_other": "{{count}} 天",
+ "weeks_one": "{{count}} 週",
"home": {
"active_alerts": "活動警報",
- "active_des": "在過去 {{minutes}} 分鐘內超過 {{value}}{{unit}} 平均值",
+ "active_des": "超過 {{value}}{{unit}} 在過去 ",
"subtitle": "即時更新。點擊系統以查看資訊。"
},
"systems_table": {
@@ -51,9 +57,7 @@
"temperature_des": "當任何感應器超過閾值時觸發。"
},
"average_exceeds": "平均值超過",
- "for": "持續",
- "minute": "分鐘",
- "minutes": "分鐘"
+ "for": "持續"
},
"settings": {
"settings": "設定",
diff --git a/beszel/site/src/types.d.ts b/beszel/site/src/types.d.ts
index 54feff7..a183b6f 100644
--- a/beszel/site/src/types.d.ts
+++ b/beszel/site/src/types.d.ts
@@ -138,7 +138,7 @@ export interface ChartTimeData {
[key: string]: {
type: "1m" | "10m" | "20m" | "120m" | "480m"
expectedInterval: number
- label: string
+ label: () => string
ticks?: number
format: (timestamp: string) => string
getOffset: (endTime: Date) => Date