chore(locales): Update translations for multiple languages and add new status messages

feat(links): Correct URL formatting in invitation and verification email links
refactor(notification): Simplify notification utility imports
chore(docs): Update Discord link and API reference URLs in documentation
style(buttons): Change button variant for better UI consistency
chore(scripts): Implement script to sort translation keys in locale files
This commit is contained in:
Raj Nandan Sharma
2026-02-23 09:57:22 +05:30
parent 78bad84f0e
commit 3363e90007
38 changed files with 483 additions and 80 deletions
+15
View File
@@ -21,6 +21,15 @@ const TRANSLATION_CALL_REGEX = /\$t\s*\(\s*(["'`])([\s\S]*?)\1\s*(?:,|\))/g;
const COMMENT_PATTERNS = [/\/\*[\s\S]*?\*\//g, /\/\/[^\n\r]*/g, /<!--[\s\S]*?-->/g];
const WHITELISTED_DYNAMIC_KEYS = new Set([
"All Systems Operational",
"Degraded Performance",
"Partial Degraded Performance",
"Partial System Outage",
"Major System Outage",
"No Status Available",
]);
function decodeQuotedContent(value) {
return value
.replace(/\\\\/g, "\\")
@@ -86,6 +95,10 @@ function getUsedTranslationKeys() {
}
}
for (const key of WHITELISTED_DYNAMIC_KEYS) {
usedKeys.add(key);
}
return {
usedKeys,
skippedDynamicCalls,
@@ -171,6 +184,8 @@ function main() {
scannedSourceDir: "src",
usedLiteralKeysCount: sortedUsedKeys.length,
usedLiteralKeys: sortedUsedKeys,
whitelistedDynamicKeysCount: WHITELISTED_DYNAMIC_KEYS.size,
whitelistedDynamicKeys: [...WHITELISTED_DYNAMIC_KEYS].sort((a, b) => a.localeCompare(b)),
localeFilesCount: localeFiles.length,
locales: localesReport,
skippedDynamicCallsCount: skippedDynamicCalls.length,
+10 -1
View File
@@ -9,6 +9,15 @@ const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, "..");
const localesDir = path.join(projectRoot, "src", "lib", "locales");
const WHITELISTED_DYNAMIC_KEYS = new Set([
"All Systems Operational",
"Degraded Performance",
"Partial Degraded Performance",
"Partial System Outage",
"Major System Outage",
"No Status Available",
]);
function fail(message) {
throw new Error(message);
}
@@ -191,7 +200,7 @@ function cleanTranslations(report) {
const localePath = path.join(localesDir, localeFileName);
const localeData = loadLocaleJson(localePath, localeFileName);
const unusedKeys = getUnusedKeysForLocale(report, localeFileName);
const unusedSet = new Set(unusedKeys);
const unusedSet = new Set(unusedKeys.filter((key) => !WHITELISTED_DYNAMIC_KEYS.has(key)));
const currentMappings = localeData.mappings;
const cleanedMappings = {};
+113
View File
@@ -0,0 +1,113 @@
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { globSync } from "glob";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, "..");
const localesDir = path.join(projectRoot, "src", "lib", "locales");
function fail(message) {
throw new Error(message);
}
function isPlainObject(value) {
return value !== null && typeof value === "object" && !Array.isArray(value);
}
function sortObjectKeysAscending(input) {
const keys = Object.keys(input).sort((a, b) => a.localeCompare(b));
const result = {};
for (const key of keys) {
result[key] = input[key];
}
return result;
}
function replaceMappingsPreserveTopLevelOrder(localeData, sortedMappings) {
const next = {};
let sawMappings = false;
for (const key of Object.keys(localeData)) {
if (key === "mappings") {
next[key] = sortedMappings;
sawMappings = true;
} else {
next[key] = localeData[key];
}
}
if (!sawMappings) {
next.mappings = sortedMappings;
}
return next;
}
function loadLocaleJson(localePath, localeFileName) {
const raw = fs.readFileSync(localePath, "utf8");
let parsed;
try {
parsed = JSON.parse(raw);
} catch (error) {
fail(`Invalid JSON in ${localeFileName}: ${error instanceof Error ? error.message : String(error)}`);
}
if (!isPlainObject(parsed)) {
fail(`Invalid locale file ${localeFileName}: expected a top-level object.`);
}
if (!isPlainObject(parsed.mappings)) {
fail(`Invalid locale file ${localeFileName}: expected "mappings" to be an object.`);
}
return parsed;
}
function sortTranslations() {
if (!fs.existsSync(localesDir)) {
fail(`Locales directory not found: ${localesDir}`);
}
const localeFiles = globSync("*.json", {
cwd: localesDir,
nodir: true,
}).sort((a, b) => a.localeCompare(b));
if (localeFiles.length === 0) {
fail(`No locale files found in ${localesDir}`);
}
let changedFilesCount = 0;
for (const localeFileName of localeFiles) {
const localePath = path.join(localesDir, localeFileName);
const localeData = loadLocaleJson(localePath, localeFileName);
const sortedMappings = sortObjectKeysAscending(localeData.mappings);
const nextLocaleData = replaceMappingsPreserveTopLevelOrder(localeData, sortedMappings);
const nextContent = `${JSON.stringify(nextLocaleData, null, 2)}\n`;
const currentContent = fs.readFileSync(localePath, "utf8");
if (nextContent !== currentContent) {
fs.writeFileSync(localePath, nextContent, "utf8");
changedFilesCount += 1;
console.log(`${localeFileName}: sorted mappings in ascending key order`);
} else {
console.log(`${localeFileName}: already sorted`);
}
}
console.log(`Done. Updated ${changedFilesCount} file${changedFilesCount === 1 ? "" : "s"}.`);
}
try {
sortTranslations();
} catch (error) {
console.error("Failed to sort translations.");
console.error(error instanceof Error ? error.message : String(error));
process.exitCode = 1;
}
@@ -28,9 +28,15 @@
});
</script>
<div class=" px-4">
<div class="w-full">
<Drawer.Root bind:open={isOpen} direction="bottom">
<Drawer.Trigger class={buttonVariants({ variant: "outline", size: "sm", class: "rounded-btn text-xs" })}>
<Drawer.Trigger
class={buttonVariants({
variant: "ghost",
size: "sm",
class: "rounded-btn bg-secondary w-full text-xs"
})}
>
{@render children()}
</Drawer.Trigger>
<Drawer.Content class="max-h-[80vh]">
+12 -12
View File
@@ -144,18 +144,18 @@
</p>
</div>
</div>
{#if showGroupPopover}
<div class="flex justify-center gap-2">
<GroupMonitorPopover
tags={groupChildTags}
days={days as number}
endOfDayTodayAtTz={endOfDayTodayAtTz as number}
>
{$t("Included Monitors")} ({groupChildTags.length})
<ICONS.ARROW_UP class="size-3" />
</GroupMonitorPopover>
</div>
{/if}
{/if}
{#if showGroupPopover}
<div class="mt-2 flex justify-center gap-2 px-4">
<GroupMonitorPopover
tags={groupChildTags}
days={days as number}
endOfDayTodayAtTz={endOfDayTodayAtTz as number}
>
{groupChildTags.length}
{$t("Included Monitors")}
</GroupMonitorPopover>
</div>
{/if}
{/if}
</div>
+3 -3
View File
@@ -257,15 +257,15 @@
<div class="mb-3 flex justify-between gap-4">
<div class="flex flex-col items-start gap-1">
<p class="text-lg font-semibold">{displayMinLatency}</p>
<p class="text-muted-foreground text-xs">{$t("Min Latency")}</p>
<p class="text-muted-foreground text-xs">{$t("Minimum Latency")}</p>
</div>
<div class="flex flex-col items-center gap-1">
<p class="text-lg font-semibold">{displayAvgLatency}</p>
<p class="text-muted-foreground text-xs">{$t("Avg Latency")}</p>
<p class="text-muted-foreground text-xs">{$t("Average Latency")}</p>
</div>
<div class="flex flex-col items-end gap-1">
<p class="text-lg font-semibold">{displayMaxLatency}</p>
<p class="text-muted-foreground text-xs">{$t("Max Latency")}</p>
<p class="text-muted-foreground text-xs">{$t("Maximum Latency")}</p>
</div>
</div>
-7
View File
@@ -74,10 +74,3 @@ export default {
MAX_IMAGE_DIMENSION: 4096,
MAX_INPUT_PIXELS: 4096 * 4096,
} as const;
const AnalyticsProviders = {
GA: "https://unpkg.com/@analytics/google-analytics@1.0.7/dist/@analytics/google-analytics.min.js",
AMPLITUDE: "https://unpkg.com/@analytics/amplitude@0.1.3/dist/@analytics/amplitude.min.js",
MIXPANEL: "https://unpkg.com/@analytics/mixpanel@0.4.0/dist/@analytics/mixpanel.min.js",
};
export { AnalyticsProviders };
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latence",
"Affected Monitors (%count)": "Zasažené monitory (%count)",
"All Systems Operational": "Všechny systémy jsou v provozu",
"Average Latency": "Průměrná latence",
"Avg Latency": "Prům. latence",
"Back": "Zpět",
@@ -13,6 +14,7 @@
"Day": "Den",
"Day Uptime": "Denní dostupnost",
"Days": "Dny",
"Degraded Performance": "Zhoršený výkon",
"Didn't receive the code? Resend": "Nepřišel vám kód? Odeslat znovu",
"Duration": "Trvání",
"Email address": "E-mailová adresa",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Načítám vaše nastavení...",
"Maintenance Updates": "Aktualizace údržby",
"Maintenances": "Údržby",
"Major System Outage": "Závažný výpadek systému",
"Manage your notification preferences.": "Spravujte svá nastavení oznámení.",
"Max Latency": "Max. latence",
"Maximum Latency": "Max. latence",
"Min Latency": "Min. latence",
"Minimum Latency": "Min. latence",
"Minute-by-minute status data for this day": "Minutová data stavu pro tento den",
"Network error. Please try again.": "Chyba sítě. Zkuste to prosím znovu.",
"No Events in %currentMonth": "V měsíci %currentMonth nejsou žádné události",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Žádné probíhající údržby",
"No past maintenances": "Žádné minulé údržby",
"No Status Available": "Stav není k dispozici",
"No upcoming maintenances": "Žádné nadcházející údržby",
"No Updates": "No Updates",
"No updates yet": "Zatím bez aktualizací",
"Notifications": "Notifications",
"One-time": "Jednorázově",
"Ongoing": "Probíhající",
"Partial Degraded Performance": "Částečně zhoršený výkon",
"Partial System Outage": "Částečný výpadek systému",
"Past": "Minulé",
"Per-Minute Status": "Stav po minutách",
"Pinging": "Pingování",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric Latenz",
"Affected Monitors (%count)": "Betroffene Monitore (%count)",
"All Systems Operational": "Alle Systeme betriebsbereit",
"Average Latency": "Durchschnittliche Latenz",
"Avg Latency": "Durchschnittliche Latenz",
"Back": "Zurück",
@@ -13,6 +14,7 @@
"Day": "Tag",
"Day Uptime": "Tagesverfügbarkeit",
"Days": "Tage",
"Degraded Performance": "Beeinträchtigte Leistung",
"Didn't receive the code? Resend": "Sie haben den Code nicht erhalten? ",
"Duration": "Dauer",
"Email address": "E-Mail-Adresse",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Deine Einstellungen werden geladen...",
"Maintenance Updates": "Wartungsaktualisierungen",
"Maintenances": "Wartungen",
"Major System Outage": "Schwerwiegender Systemausfall",
"Manage your notification preferences.": "Verwalten Sie Ihre Benachrichtigungseinstellungen.",
"Max Latency": "Maximale Latenz",
"Maximum Latency": "Maximale Latenz",
"Min Latency": "Min. Latenz",
"Minimum Latency": "Min. Latenz",
"Minute-by-minute status data for this day": "Minutenweise Statusdaten für diesen Tag",
"Network error. Please try again.": "Netzwerkfehler. ",
"No Events in %currentMonth": "Keine Ereignisse in %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Keine laufenden Wartungsarbeiten",
"No past maintenances": "Keine früheren Wartungsarbeiten",
"No Status Available": "Kein Status verfügbar",
"No upcoming maintenances": "Keine bevorstehenden Wartungsarbeiten",
"No Updates": "No Updates",
"No updates yet": "Noch keine Updates",
"Notifications": "Notifications",
"One-time": "Einmalig",
"Ongoing": "Laufend",
"Partial Degraded Performance": "Teilweise beeinträchtigte Leistung",
"Partial System Outage": "Teilweiser Systemausfall",
"Past": "Vergangenheit",
"Per-Minute Status": "Status pro Minute",
"Pinging": "Ping",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric forsinkelse",
"Affected Monitors (%count)": "Berørte skærme (%count)",
"All Systems Operational": "Alle systemer er i drift",
"Average Latency": "Gennemsnitlig latenstid",
"Avg Latency": "Gns. latens",
"Back": "Tilbage",
@@ -13,6 +14,7 @@
"Day": "Dag",
"Day Uptime": "Dag oppetid",
"Days": "dage",
"Degraded Performance": "Nedsat ydeevne",
"Didn't receive the code? Resend": "Modtog du ikke koden? ",
"Duration": "Varighed",
"Email address": "E-mailadresse",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Indlæser dine præferencer...",
"Maintenance Updates": "Vedligeholdelsesopdateringer",
"Maintenances": "Vedligeholdelse",
"Major System Outage": "Større systemnedbrud",
"Manage your notification preferences.": "Administrer dine meddelelsespræferencer.",
"Max Latency": "Max latens",
"Maximum Latency": "Max latens",
"Min Latency": "Min latens",
"Minimum Latency": "Min latens",
"Minute-by-minute status data for this day": "Minut for minut statusdata for denne dag",
"Network error. Please try again.": "Netværksfejl. ",
"No Events in %currentMonth": "Ingen begivenheder i %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Ingen løbende vedligeholdelse",
"No past maintenances": "Ingen tidligere vedligeholdelse",
"No Status Available": "Ingen status tilgængelig",
"No upcoming maintenances": "Ingen kommende vedligeholdelse",
"No Updates": "No Updates",
"No updates yet": "Ingen opdateringer endnu",
"Notifications": "Notifications",
"One-time": "Engangs",
"Ongoing": "Løbende",
"Partial Degraded Performance": "Delvist nedsat ydeevne",
"Partial System Outage": "Delvist systemnedbrud",
"Past": "Forbi",
"Per-Minute Status": "Status pr. minut",
"Pinging": "Pinger",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latency",
"Affected Monitors (%count)": "Affected Monitors (%count)",
"All Systems Operational": "All Systems Operational",
"Average Latency": "Average Latency",
"Avg Latency": "Avg Latency",
"Back": "Back",
@@ -13,6 +14,7 @@
"Day": "Day",
"Day Uptime": "Day Uptime",
"Days": "Days",
"Degraded Performance": "Degraded Performance",
"Didn't receive the code? Resend": "Didn't receive the code? Resend",
"Duration": "Duration",
"Email address": "Email address",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Loading your preferences...",
"Maintenance Updates": "Maintenance Updates",
"Maintenances": "Maintenances",
"Major System Outage": "Major System Outage",
"Manage your notification preferences.": "Manage your notification preferences.",
"Max Latency": "Max Latency",
"Maximum Latency": "Max Latency",
"Min Latency": "Min Latency",
"Minimum Latency": "Min Latency",
"Minute-by-minute status data for this day": "Minute-by-minute status data for this day",
"Network error. Please try again.": "Network error. Please try again.",
"No Events in %currentMonth": "No Events in %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "No ongoing maintenances",
"No past maintenances": "No past maintenances",
"No Status Available": "No Status Available",
"No upcoming maintenances": "No upcoming maintenances",
"No Updates": "No Updates",
"No updates yet": "No updates yet",
"Notifications": "Notifications",
"One-time": "One-time",
"Ongoing": "Ongoing",
"Partial Degraded Performance": "Partial Degraded Performance",
"Partial System Outage": "Partial System Outage",
"Past": "Past",
"Per-Minute Status": "Per-Minute Status",
"Pinging": "Pinging",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latencia",
"Affected Monitors (%count)": "Monitores afectados (%count)",
"All Systems Operational": "Todos los sistemas en funcionamiento",
"Average Latency": "Latencia promedio",
"Avg Latency": "Latencia promedio",
"Back": "Atrás",
@@ -13,6 +14,7 @@
"Day": "Día",
"Day Uptime": "Tiempo de actividad del día",
"Days": "Días",
"Degraded Performance": "Rendimiento degradado",
"Didn't receive the code? Resend": "¿No recibiste el código? ",
"Duration": "Duración",
"Email address": "Dirección de correo electrónico",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Cargando tus preferencias...",
"Maintenance Updates": "Actualizaciones de mantenimiento",
"Maintenances": "Mantenimientos",
"Major System Outage": "Interrupción importante del sistema",
"Manage your notification preferences.": "Administre sus preferencias de notificación.",
"Max Latency": "Latencia máxima",
"Maximum Latency": "Latencia máxima",
"Min Latency": "Latencia mínima",
"Minimum Latency": "Latencia mínima",
"Minute-by-minute status data for this day": "Datos del estado minuto a minuto de este día",
"Network error. Please try again.": "Error de red. ",
"No Events in %currentMonth": "No hay eventos en %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Sin mantenimientos continuos",
"No past maintenances": "Sin mantenimientos pasados",
"No Status Available": "Estado no disponible",
"No upcoming maintenances": "No hay mantenimientos próximos",
"No Updates": "No Updates",
"No updates yet": "Aún no hay actualizaciones",
"Notifications": "Notifications",
"One-time": "una sola vez",
"Ongoing": "En curso",
"Partial Degraded Performance": "Rendimiento parcialmente degradado",
"Partial System Outage": "Interrupción parcial del sistema",
"Past": "Pasado",
"Per-Minute Status": "Estado por minuto",
"Pinging": "haciendo ping",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "تأخیر %latency %metric",
"Affected Monitors (%count)": "مانیتورهای تحت تأثیر (%count)",
"All Systems Operational": "تمام سیستم‌ها عملیاتی هستند",
"Average Latency": "تأخیر متوسط",
"Avg Latency": "تأخیر متوسط",
"Back": "برگشت",
@@ -13,6 +14,7 @@
"Day": "روز",
"Day Uptime": "تایم روز",
"Days": "روزها",
"Degraded Performance": "عملکرد کاهش‌یافته",
"Didn't receive the code? Resend": "کد را دریافت نکردید؟ ",
"Duration": "مدت",
"Email address": "آدرس ایمیل",
@@ -47,9 +49,12 @@
"Loading your preferences...": "در حال بارگیری تنظیمات برگزیده شما...",
"Maintenance Updates": "به روز رسانی های تعمیر و نگهداری",
"Maintenances": "تعمیر و نگهداری",
"Major System Outage": "قطعی عمده سیستم",
"Manage your notification preferences.": "تنظیمات برگزیده اعلان خود را مدیریت کنید.",
"Max Latency": "حداکثر تاخیر",
"Maximum Latency": "حداکثر تاخیر",
"Min Latency": "حداقل تاخیر",
"Minimum Latency": "حداقل تاخیر",
"Minute-by-minute status data for this day": "داده های وضعیت دقیقه به دقیقه برای این روز",
"Network error. Please try again.": "خطای شبکه ",
"No Events in %currentMonth": "هیچ رویدادی در %currentMonth وجود ندارد",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "بدون تعمیر و نگهداری مداوم",
"No past maintenances": "بدون تعمیر و نگهداری قبلی",
"No Status Available": "وضعیتی در دسترس نیست",
"No upcoming maintenances": "بدون تعمیر و نگهداری آینده",
"No Updates": "No Updates",
"No updates yet": "هنوز به روز رسانی نشده است",
"Notifications": "Notifications",
"One-time": "یک بار",
"Ongoing": "در حال انجام است",
"Partial Degraded Performance": "کاهش عملکرد جزئی",
"Partial System Outage": "قطعی جزئی سیستم",
"Past": "گذشته",
"Per-Minute Status": "وضعیت در دقیقه",
"Pinging": "پینگ زدن",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latence",
"Affected Monitors (%count)": "Moniteurs concernés (%count)",
"All Systems Operational": "Tous les systèmes opérationnels",
"Average Latency": "Latence moyenne",
"Avg Latency": "Latence moyenne",
"Back": "Dos",
@@ -13,6 +14,7 @@
"Day": "Jour",
"Day Uptime": "Disponibilité journalière",
"Days": "Jours",
"Degraded Performance": "Performance dégradée",
"Didn't receive the code? Resend": "Vous n'avez pas reçu le code ? ",
"Duration": "Durée",
"Email address": "Adresse email",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Chargement de vos préférences...",
"Maintenance Updates": "Mises à jour de maintenance",
"Maintenances": "Entretiens",
"Major System Outage": "Panne majeure du système",
"Manage your notification preferences.": "Gérez vos préférences de notification.",
"Max Latency": "Latence maximale",
"Maximum Latency": "Latence maximale",
"Min Latency": "Latence minimale",
"Minimum Latency": "Latence minimale",
"Minute-by-minute status data for this day": "Données d'état minute par minute pour cette journée",
"Network error. Please try again.": "Erreur réseau. ",
"No Events in %currentMonth": "Aucun événement dans %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Aucune maintenance en cours",
"No past maintenances": "Aucune maintenance passée",
"No Status Available": "Aucun statut disponible",
"No upcoming maintenances": "Aucune maintenance à venir",
"No Updates": "No Updates",
"No updates yet": "Aucune mise à jour pour l'instant",
"Notifications": "Notifications",
"One-time": "Une fois",
"Ongoing": "En cours",
"Partial Degraded Performance": "Performance partiellement dégradée",
"Partial System Outage": "Panne partielle du système",
"Past": "Passé",
"Per-Minute Status": "Statut par minute",
"Pinging": "Ping",
+10 -2
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latency",
"Affected Monitors (%count)": "प्रभावित मॉनिटर (%count)",
"All Systems Operational": "सभी सिस्टम सुचारू रूप से चल रहे हैं",
"Average Latency": "औसत लेटेंसी",
"Avg Latency": "औसत लेटेंसी",
"Back": "वापस",
@@ -10,9 +11,10 @@
"Continue": "जारी रखें",
"Copied": "कॉपी किया गया",
"Dark": "डार्क",
"Day": "Day",
"Day": "दिन",
"Day Uptime": "दिन का अपटाइम",
"Days": "Days",
"Days": "दिन",
"Degraded Performance": "प्रदर्शन में गिरावट",
"Didn't receive the code? Resend": "कोड नहीं मिला? फिर से भेजें",
"Duration": "अवधि",
"Email address": "ईमेल पता",
@@ -47,9 +49,12 @@
"Loading your preferences...": "आपकी प्राथमिकताएँ लोड हो रही हैं...",
"Maintenance Updates": "रखरखाव अपडेट",
"Maintenances": "रखरखाव",
"Major System Outage": "सिस्टम का बड़ा आउटेज",
"Manage your notification preferences.": "अपनी सूचना प्राथमिकताएँ प्रबंधित करें।",
"Max Latency": "Max Latency",
"Maximum Latency": "Max Latency",
"Min Latency": "Min Latency",
"Minimum Latency": "Min Latency",
"Minute-by-minute status data for this day": "इस दिन के लिए मिनट-दर-मिनट स्थिति डेटा",
"Network error. Please try again.": "नेटवर्क त्रुटि। कृपया पुनः प्रयास करें।",
"No Events in %currentMonth": "%currentMonth में कोई घटना नहीं",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "कोई चल रहा रखरखाव नहीं",
"No past maintenances": "कोई बीता हुआ रखरखाव नहीं",
"No Status Available": "स्थिति उपलब्ध नहीं है",
"No upcoming maintenances": "कोई आने वाला रखरखाव नहीं",
"No Updates": "No Updates",
"No updates yet": "अभी तक कोई अपडेट नहीं",
"Notifications": "Notifications",
"One-time": "एक बार",
"Ongoing": "चल रहा है",
"Partial Degraded Performance": "आंशिक प्रदर्शन गिरावट",
"Partial System Outage": "सिस्टम का आंशिक आउटेज.",
"Past": "बीता हुआ",
"Per-Minute Status": "प्रति मिनट स्थिति",
"Pinging": "पिंग हो रहा है",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latenza",
"Affected Monitors (%count)": "Monitor interessati (%count)",
"All Systems Operational": "Tutti i sistemi sono operativi",
"Average Latency": "Latenza media",
"Avg Latency": "Latenza media",
"Back": "Indietro",
@@ -13,6 +14,7 @@
"Day": "Giorno",
"Day Uptime": "Tempo di attività giornaliero",
"Days": "Giorni",
"Degraded Performance": "Prestazioni degradate",
"Didn't receive the code? Resend": "Non hai ricevuto il codice? ",
"Duration": "Durata",
"Email address": "Indirizzo e-mail",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Caricamento delle tue preferenze...",
"Maintenance Updates": "Aggiornamenti sulla manutenzione",
"Maintenances": "Manutenzioni",
"Major System Outage": "Interruzione grave del sistema",
"Manage your notification preferences.": "Gestisci le tue preferenze di notifica.",
"Max Latency": "Latenza massima",
"Maximum Latency": "Latenza massima",
"Min Latency": "Latenza minima",
"Minimum Latency": "Latenza minima",
"Minute-by-minute status data for this day": "Dati sullo stato minuto per minuto per questo giorno",
"Network error. Please try again.": "Errore di rete. ",
"No Events in %currentMonth": "Nessun evento in %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Nessuna manutenzione continua",
"No past maintenances": "Nessuna manutenzione passata",
"No Status Available": "Nessuno stato disponibile",
"No upcoming maintenances": "Nessuna manutenzione imminente",
"No Updates": "No Updates",
"No updates yet": "Nessun aggiornamento ancora",
"Notifications": "Notifications",
"One-time": "Una volta",
"Ongoing": "In corso",
"Partial Degraded Performance": "Prestazioni parzialmente degradate",
"Partial System Outage": "Interruzione parziale del sistema",
"Past": "Passato",
"Per-Minute Status": "Stato al minuto",
"Pinging": "Ping",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric レイテンシー",
"Affected Monitors (%count)": "影響を受けるモニター (%count)",
"All Systems Operational": "すべてのシステムは正常に稼働しています",
"Average Latency": "平均レイテンシ",
"Avg Latency": "平均レイテンシー",
"Back": "戻る",
@@ -13,6 +14,7 @@
"Day": "日",
"Day Uptime": "一日の稼働時間",
"Days": "日数",
"Degraded Performance": "パフォーマンスの低下",
"Didn't receive the code? Resend": "コードを受け取っていませんか?",
"Duration": "間隔",
"Email address": "電子メールアドレス",
@@ -47,9 +49,12 @@
"Loading your preferences...": "設定を読み込んでいます...",
"Maintenance Updates": "メンテナンスアップデート",
"Maintenances": "メンテナンス",
"Major System Outage": "大規模なシステム障害",
"Manage your notification preferences.": "通知設定を管理します。",
"Max Latency": "最大レイテンシー",
"Maximum Latency": "最大レイテンシー",
"Min Latency": "最小レイテンシ",
"Minimum Latency": "最小レイテンシ",
"Minute-by-minute status data for this day": "この日の分単位のステータスデータ",
"Network error. Please try again.": "ネットワークエラー。",
"No Events in %currentMonth": "%currentMonth にはイベントがありません",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "継続的なメンテナンスはありません",
"No past maintenances": "過去のメンテナンスはありません",
"No Status Available": "ステータス情報はありません",
"No upcoming maintenances": "今後のメンテナンスはありません",
"No Updates": "No Updates",
"No updates yet": "まだ更新はありません",
"Notifications": "Notifications",
"One-time": "一度",
"Ongoing": "進行中",
"Partial Degraded Performance": "部分的なパフォーマンス低下",
"Partial System Outage": "部分的なシステム障害。",
"Past": "過去",
"Per-Minute Status": "1分ごとのステータス",
"Pinging": "ピンピング",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric 대기 시간",
"Affected Monitors (%count)": "영향을 받는 모니터(%count)",
"All Systems Operational": "모든 시스템 정상 운영 중",
"Average Latency": "평균 지연 시간",
"Avg Latency": "평균 지연 시간",
"Back": "뒤쪽에",
@@ -13,6 +14,7 @@
"Day": "낮",
"Day Uptime": "일일 가동 시간",
"Days": "날",
"Degraded Performance": "성능 저하",
"Didn't receive the code? Resend": "코드를 받지 못하셨나요? 재전송",
"Duration": "지속",
"Email address": "이메일 주소",
@@ -47,9 +49,12 @@
"Loading your preferences...": "환경설정 로드 중...",
"Maintenance Updates": "유지보수 업데이트",
"Maintenances": "유지보수",
"Major System Outage": "대규모 시스템 장애",
"Manage your notification preferences.": "알림 기본 설정을 관리하세요.",
"Max Latency": "최대 대기 시간",
"Maximum Latency": "최대 대기 시간",
"Min Latency": "최소 지연 시간",
"Minimum Latency": "최소 지연 시간",
"Minute-by-minute status data for this day": "오늘의 분별 상태 데이터",
"Network error. Please try again.": "네트워크 오류입니다. 다시 시도해 주세요.",
"No Events in %currentMonth": "%currentMonth에 이벤트가 없습니다.",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "지속적인 유지 관리가 필요하지 않습니다.",
"No past maintenances": "과거 유지보수 없음",
"No Status Available": "사용 가능한 상태 정보 없음",
"No upcoming maintenances": "예정된 유지 관리가 없습니다.",
"No Updates": "No Updates",
"No updates yet": "아직 업데이트가 없습니다",
"Notifications": "Notifications",
"One-time": "일회성",
"Ongoing": "전진",
"Partial Degraded Performance": "부분적 성능 저하",
"Partial System Outage": "부분적 시스템 장애.",
"Past": "과거",
"Per-Minute Status": "분당 현황",
"Pinging": "핑잉",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric forsinkelse",
"Affected Monitors (%count)": "Berørte skjermer (%count)",
"All Systems Operational": "Alle systemer er operative",
"Average Latency": "Gjennomsnittlig ventetid",
"Avg Latency": "Gj.sn. ventetid",
"Back": "Tilbake",
@@ -13,6 +14,7 @@
"Day": "Dag",
"Day Uptime": "Dag oppetid",
"Days": "Dager",
"Degraded Performance": "Redusert ytelse",
"Didn't receive the code? Resend": "Fikk du ikke koden? Send på nytt",
"Duration": "Varighet",
"Email address": "E-postadresse",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Laster inn innstillingene dine ...",
"Maintenance Updates": "Vedlikeholdsoppdateringer",
"Maintenances": "Vedlikehold",
"Major System Outage": "Større systemutfall",
"Manage your notification preferences.": "Administrer varslingspreferansene dine.",
"Max Latency": "Maks ventetid",
"Maximum Latency": "Maks ventetid",
"Min Latency": "Min latens",
"Minimum Latency": "Min latens",
"Minute-by-minute status data for this day": "Statusdata fra minutt for minutt for denne dagen",
"Network error. Please try again.": "Nettverksfeil. Vennligst prøv igjen.",
"No Events in %currentMonth": "Ingen hendelser i %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Ingen løpende vedlikehold",
"No past maintenances": "Ingen tidligere vedlikehold",
"No Status Available": "Ingen status tilgjengelig",
"No upcoming maintenances": "Ingen kommende vedlikehold",
"No Updates": "No Updates",
"No updates yet": "Ingen oppdateringer ennå",
"Notifications": "Notifications",
"One-time": "En gang",
"Ongoing": "Pågående",
"Partial Degraded Performance": "Delvis redusert ytelse",
"Partial System Outage": "Delvis systemutfall",
"Past": "Forbi",
"Per-Minute Status": "Status per minutt",
"Pinging": "Pinger",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latentie",
"Affected Monitors (%count)": "Betrokken monitoren (%count)",
"All Systems Operational": "Alle systemen operationeel",
"Average Latency": "Gemiddelde latentie",
"Avg Latency": "Gem. latentie",
"Back": "Rug",
@@ -13,6 +14,7 @@
"Day": "Dag",
"Day Uptime": "Dag uptime",
"Days": "Dagen",
"Degraded Performance": "Verminderde prestaties",
"Didn't receive the code? Resend": "Heb je de code niet ontvangen? ",
"Duration": "Duur",
"Email address": "E-mailadres",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Uw voorkeuren laden...",
"Maintenance Updates": "Onderhoudsupdates",
"Maintenances": "Onderhouden",
"Major System Outage": "Grote systeemstoring",
"Manage your notification preferences.": "Beheer uw meldingsvoorkeuren.",
"Max Latency": "Maximale latentie",
"Maximum Latency": "Maximale latentie",
"Min Latency": "Minimale latentie",
"Minimum Latency": "Minimale latentie",
"Minute-by-minute status data for this day": "Statusgegevens van minuut tot minuut voor deze dag",
"Network error. Please try again.": "Netwerkfout. ",
"No Events in %currentMonth": "Geen evenementen in %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Geen doorlopend onderhoud",
"No past maintenances": "Geen onderhoudsbeurten uit het verleden",
"No Status Available": "Geen status beschikbaar",
"No upcoming maintenances": "Geen aankomend onderhoud",
"No Updates": "No Updates",
"No updates yet": "Nog geen updates",
"Notifications": "Notifications",
"One-time": "Eenmalig",
"Ongoing": "Lopend",
"Partial Degraded Performance": "Gedeeltelijk verminderde prestaties",
"Partial System Outage": "Gedeeltelijke systeemstoring",
"Past": "Verleden",
"Per-Minute Status": "Status per minuut",
"Pinging": "Pingen",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric opóźnienie",
"Affected Monitors (%count)": "Monitory, których dotyczy problem (%count)",
"All Systems Operational": "Wszystkie systemy działają",
"Average Latency": "Średnie opóźnienie",
"Avg Latency": "Średnie opóźnienie",
"Back": "Z powrotem",
@@ -13,6 +14,7 @@
"Day": "Dzień",
"Day Uptime": "Dzień sprawności",
"Days": "Dni",
"Degraded Performance": "Obniżona wydajność",
"Didn't receive the code? Resend": "Nie otrzymałeś kodu? ",
"Duration": "Czas trwania",
"Email address": "Adres e-mail",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Ładowanie Twoich preferencji...",
"Maintenance Updates": "Aktualizacje konserwacyjne",
"Maintenances": "Konserwacje",
"Major System Outage": "Poważna awaria systemu",
"Manage your notification preferences.": "Zarządzaj preferencjami powiadomień.",
"Max Latency": "Maksymalne opóźnienie",
"Maximum Latency": "Maksymalne opóźnienie",
"Min Latency": "Minimalne opóźnienie",
"Minimum Latency": "Minimalne opóźnienie",
"Minute-by-minute status data for this day": "Dane o stanie minuta po minucie na ten dzień",
"Network error. Please try again.": "Błąd sieci. ",
"No Events in %currentMonth": "Brak wydarzeń w %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Brak bieżących konserwacji",
"No past maintenances": "Brak wcześniejszych konserwacji",
"No Status Available": "Brak dostępnego statusu",
"No upcoming maintenances": "Brak nadchodzących prac konserwacyjnych",
"No Updates": "No Updates",
"No updates yet": "Nie ma jeszcze żadnych aktualizacji",
"Notifications": "Notifications",
"One-time": "Jednorazowy",
"Ongoing": "Bieżący",
"Partial Degraded Performance": "Częściowo obniżona wydajność",
"Partial System Outage": "Częściowa awaria systemu",
"Past": "Przeszłość",
"Per-Minute Status": "Stan na minutę",
"Pinging": "Pingowanie",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latência",
"Affected Monitors (%count)": "Monitores afetados (%count)",
"All Systems Operational": "Todos os sistemas operando",
"Average Latency": "Latência Média",
"Avg Latency": "Latência Média",
"Back": "Voltar",
@@ -13,6 +14,7 @@
"Day": "Dia",
"Day Uptime": "Tempo de atividade diurno",
"Days": "Dias",
"Degraded Performance": "Desempenho degradado",
"Didn't receive the code? Resend": "Não recebeu o código? ",
"Duration": "Duração",
"Email address": "Endereço de email",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Carregando suas preferências...",
"Maintenance Updates": "Atualizações de manutenção",
"Maintenances": "Manutenção",
"Major System Outage": "Indisponibilidade grave do sistema",
"Manage your notification preferences.": "Gerencie suas preferências de notificação.",
"Max Latency": "Latência máxima",
"Maximum Latency": "Latência máxima",
"Min Latency": "Latência mínima",
"Minimum Latency": "Latência mínima",
"Minute-by-minute status data for this day": "Dados de status minuto a minuto para este dia",
"Network error. Please try again.": "Erro de rede. ",
"No Events in %currentMonth": "Nenhum evento em %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Sem manutenções contínuas",
"No past maintenances": "Sem manutenções anteriores",
"No Status Available": "Nenhum status disponível",
"No upcoming maintenances": "Sem manutenções futuras",
"No Updates": "No Updates",
"No updates yet": "Ainda não há atualizações",
"Notifications": "Notifications",
"One-time": "Único",
"Ongoing": "Em andamento",
"Partial Degraded Performance": "Desempenho parcialmente degradado",
"Partial System Outage": "Indisponibilidade parcial do sistema",
"Past": "Passado",
"Per-Minute Status": "Status por minuto",
"Pinging": "Pingando",
+8
View File
@@ -4,6 +4,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latency",
"Affected Monitors (%count)": "Затронутые мониторы (%count)",
"All Systems Operational": "Все системы работают",
"Average Latency": "Средняя задержка",
"Avg Latency": "Средняя задержка",
"Back": "Назад",
@@ -14,6 +15,7 @@
"Day": "Day",
"Day Uptime": "Время работы за день",
"Days": "Days",
"Degraded Performance": "Снижение производительности",
"Didn't receive the code? Resend": "Не получили код? Отправить повторно",
"Duration": "Продолжительность",
"Email address": "Адрес электронной почты",
@@ -48,9 +50,12 @@
"Loading your preferences...": "Загрузка настроек...",
"Maintenance Updates": "Обновления обслуживания",
"Maintenances": "Обслуживание",
"Major System Outage": "Крупный сбой системы",
"Manage your notification preferences.": "Управляйте настройками уведомлений.",
"Max Latency": "Max Latency",
"Maximum Latency": "Max Latency",
"Min Latency": "Min Latency",
"Minimum Latency": "Min Latency",
"Minute-by-minute status data for this day": "Поминутные данные о статусе за этот день",
"Network error. Please try again.": "Ошибка сети. Пожалуйста, попробуйте снова.",
"No Events in %currentMonth": "Нет событий в %currentMonth",
@@ -62,12 +67,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Нет текущих обслуживаний",
"No past maintenances": "Нет прошедших обслуживаний",
"No Status Available": "Статус недоступен",
"No upcoming maintenances": "Нет предстоящих обслуживаний",
"No Updates": "No Updates",
"No updates yet": "Обновлений пока нет",
"Notifications": "Notifications",
"One-time": "Одноразовое",
"Ongoing": "Текущие",
"Partial Degraded Performance": "Частичное снижение производительности",
"Partial System Outage": "Частичный сбой системы",
"Past": "Прошедшие",
"Per-Minute Status": "Статус по минутам",
"Pinging": "Проверка связи",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric latencia",
"Affected Monitors (%count)": "Ovplyvnené monitory (%count)",
"All Systems Operational": "Všetky systémy sú funkčné",
"Average Latency": "Priemerná latencia",
"Avg Latency": "Priem. latencia",
"Back": "Späť",
@@ -13,6 +14,7 @@
"Day": "deň",
"Day Uptime": "Day Uptime",
"Days": "dní",
"Degraded Performance": "Znížený výkon",
"Didn't receive the code? Resend": "Nedostali ste kód? ",
"Duration": "Trvanie",
"Email address": "E-mailová adresa",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Načítavajú sa vaše preferencie...",
"Maintenance Updates": "Aktualizácie údržby",
"Maintenances": "Údržba",
"Major System Outage": "Veľký výpadok systému",
"Manage your notification preferences.": "Spravujte svoje predvoľby upozornení.",
"Max Latency": "Maximálna latencia",
"Maximum Latency": "Maximálna latencia",
"Min Latency": "Minimálna latencia",
"Minimum Latency": "Minimálna latencia",
"Minute-by-minute status data for this day": "Údaje o stave z minúty na minútu pre tento deň",
"Network error. Please try again.": "Chyba siete. ",
"No Events in %currentMonth": "Žiadne udalosti v %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Žiadna priebežná údržba",
"No past maintenances": "Žiadna minulá údržba",
"No Status Available": "Stav nie je k dispozícii",
"No upcoming maintenances": "Žiadna nadchádzajúca údržba",
"No Updates": "No Updates",
"No updates yet": "Zatiaľ žiadne aktualizácie",
"Notifications": "Notifications",
"One-time": "Jednorazovo",
"Ongoing": "Prebieha",
"Partial Degraded Performance": "Čiastočne znížený výkon",
"Partial System Outage": "Čiastočný výpadok systému",
"Past": "Minulosť",
"Per-Minute Status": "Stav za minútu",
"Pinging": "Ping",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric gecikme",
"Affected Monitors (%count)": "Etkilenen Monitörler (%count)",
"All Systems Operational": "Tüm sistemler çalışıyor",
"Average Latency": "Ortalama Gecikme",
"Avg Latency": "Ortalama Gecikme",
"Back": "Geri",
@@ -13,6 +14,7 @@
"Day": "Gün",
"Day Uptime": "Gün Çalışma Süresi",
"Days": "Günler",
"Degraded Performance": "Düşük performans",
"Didn't receive the code? Resend": "Kodu almadınız mı? ",
"Duration": "Süre",
"Email address": "E-posta adresi",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Tercihleriniz yükleniyor...",
"Maintenance Updates": "Bakım Güncellemeleri",
"Maintenances": "Bakımlar",
"Major System Outage": "Büyük sistem kesintisi",
"Manage your notification preferences.": "Bildirim tercihlerinizi yönetin.",
"Max Latency": "Maksimum Gecikme",
"Maximum Latency": "Maksimum Gecikme",
"Min Latency": "Minimum Gecikme",
"Minimum Latency": "Minimum Gecikme",
"Minute-by-minute status data for this day": "Bu günün dakika dakika durum verileri",
"Network error. Please try again.": "Ağ hatası. ",
"No Events in %currentMonth": "%currentMonth Bölgesinde Etkinlik Yok",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Devam eden bakım yok",
"No past maintenances": "Geçmiş bakım yok",
"No Status Available": "Durum bilgisi yok",
"No upcoming maintenances": "Yaklaşan bakım yok",
"No Updates": "No Updates",
"No updates yet": "Henüz güncelleme yok",
"Notifications": "Notifications",
"One-time": "Bir kerelik",
"Ongoing": "devam ediyor",
"Partial Degraded Performance": "Kısmi düşük performans",
"Partial System Outage": "Kısmi sistem kesintisi",
"Past": "Geçmiş",
"Per-Minute Status": "Dakika Başına Durum",
"Pinging": "Ping atılıyor",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric độ trễ",
"Affected Monitors (%count)": "Màn hình bị ảnh hưởng (%count)",
"All Systems Operational": "Tất cả hệ thống đang hoạt động",
"Average Latency": "Độ trễ trung bình",
"Avg Latency": "Độ trễ trung bình",
"Back": "Mặt sau",
@@ -13,6 +14,7 @@
"Day": "Ngày",
"Day Uptime": "Thời gian hoạt động trong ngày",
"Days": "Ngày",
"Degraded Performance": "Hiệu suất suy giảm",
"Didn't receive the code? Resend": "Không nhận được mã? ",
"Duration": "Khoảng thời gian",
"Email address": "Địa chỉ email",
@@ -47,9 +49,12 @@
"Loading your preferences...": "Đang tải tùy chọn của bạn...",
"Maintenance Updates": "Cập nhật bảo trì",
"Maintenances": "Bảo trì",
"Major System Outage": "Sự cố hệ thống nghiêm trọng",
"Manage your notification preferences.": "Quản lý tùy chọn thông báo của bạn.",
"Max Latency": "Độ trễ tối đa",
"Maximum Latency": "Độ trễ tối đa",
"Min Latency": "Độ trễ tối thiểu",
"Minimum Latency": "Độ trễ tối thiểu",
"Minute-by-minute status data for this day": "Dữ liệu trạng thái từng phút cho ngày này",
"Network error. Please try again.": "Lỗi mạng. ",
"No Events in %currentMonth": "Không có sự kiện nào trong %currentMonth",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "Không có bảo trì liên tục",
"No past maintenances": "Không có bảo trì trước đây",
"No Status Available": "Không có trạng thái khả dụng",
"No upcoming maintenances": "Không có bảo trì sắp tới",
"No Updates": "No Updates",
"No updates yet": "Chưa có cập nhật nào",
"Notifications": "Notifications",
"One-time": "Một lần",
"Ongoing": "Đang thực hiện",
"Partial Degraded Performance": "Hiệu suất suy giảm một phần",
"Partial System Outage": "Sự cố hệ thống một phần",
"Past": "Quá khứ",
"Per-Minute Status": "Trạng thái mỗi phút",
"Pinging": "Ping",
+8
View File
@@ -3,6 +3,7 @@
"mappings": {
"%latency %metric latency": "%latency %metric 延迟",
"Affected Monitors (%count)": "受影响的监视器 (%count)",
"All Systems Operational": "所有系统运行正常",
"Average Latency": "平均延迟",
"Avg Latency": "平均延迟",
"Back": "后退",
@@ -13,6 +14,7 @@
"Day": "天",
"Day Uptime": "日间正常运行时间",
"Days": "天",
"Degraded Performance": "性能下降",
"Didn't receive the code? Resend": "没有收到代码?",
"Duration": "期间",
"Email address": "电子邮件",
@@ -47,9 +49,12 @@
"Loading your preferences...": "正在加载您的偏好设置...",
"Maintenance Updates": "维护更新",
"Maintenances": "维护保养",
"Major System Outage": "重大系统故障",
"Manage your notification preferences.": "管理您的通知首选项。",
"Max Latency": "最大延迟",
"Maximum Latency": "最大延迟",
"Min Latency": "最短延迟",
"Minimum Latency": "最短延迟",
"Minute-by-minute status data for this day": "当日每分钟的状态数据",
"Network error. Please try again.": "网络错误。",
"No Events in %currentMonth": "%currentMonth 没有活动",
@@ -61,12 +66,15 @@
"No monitors available.": "No monitors available.",
"No ongoing maintenances": "无需持续维护",
"No past maintenances": "过去没有维护过",
"No Status Available": "无可用状态",
"No upcoming maintenances": "没有即将进行的维护",
"No Updates": "No Updates",
"No updates yet": "还没有更新",
"Notifications": "Notifications",
"One-time": "一度",
"Ongoing": "进行中",
"Partial Degraded Performance": "部分性能下降",
"Partial System Outage": "部分系统故障.",
"Past": "过去的",
"Per-Minute Status": "每分钟状态",
"Pinging": "pinging",
+3 -3
View File
@@ -315,7 +315,7 @@ export const SendInvitationEmail = async (email: string, role: string, name: str
const siteData = await GetAllSiteData();
const siteVars = siteDataToVariables(siteData);
const siteUrl = siteVars.site_url || "";
let link = `${siteUrl}/account/invitation?view=confirm_token&token=${token}`;
let link = `${siteUrl}account/invitation?view=confirm_token&token=${token}`;
const emailVars = {
...siteVars,
@@ -363,7 +363,7 @@ export const ResendInvitationEmail = async (email: string, currentUserRole: stri
const siteData = await GetAllSiteData();
const siteVars = siteDataToVariables(siteData);
const siteUrl = siteVars.site_url || "";
let link = `${siteUrl}/account/invitation?view=confirm_token&token=${token}`;
let link = `${siteUrl}account/invitation?view=confirm_token&token=${token}`;
const emailVars = {
...siteVars,
@@ -412,7 +412,7 @@ export const SendVerificationEmail = async (toUserId: number, currentUser: { id:
const siteData = await GetAllSiteData();
const siteVars = siteDataToVariables(siteData);
const siteUrl = siteVars.site_url || "";
const verificationLink = `${siteUrl}/account/verify?view=confirm_token&token=${token}`;
const verificationLink = `${siteUrl}account/verify?view=confirm_token&token=${token}`;
const emailVars = {
...siteVars,
@@ -1,12 +1,5 @@
import type { MaintenanceEventRecordDetailed, MonitorAlertConfigRecord, MonitorAlertV2Record } from "../types/db";
import type {
AlertVariableMap,
ResendAPIConfiguration,
SiteDataForNotification,
SMTPConfiguration,
SubscriptionVariableMap,
TemplateVariableMap,
} from "./types.js";
import type { AlertVariableMap, SiteDataForNotification, SubscriptionVariableMap } from "./types.js";
import GC from "../../global-constants.js";
import type { SiteDataTransformed } from "../controllers/siteDataController.js";
import { format } from "date-fns";
@@ -29,7 +29,7 @@ export const POST: RequestHandler = async ({ request }) => {
const siteData = await GetAllSiteData();
const siteVars = siteDataToVariables(siteData);
const siteUrl = siteVars.site_url || "";
let link = `${siteUrl}/account/forgot?view=confirm_token&token=${token}`;
let link = `${siteUrl}account/forgot?view=confirm_token&token=${token}`;
const template = await GetGeneralEmailTemplateById("forgot_password");
if (!template) {
+5 -1
View File
@@ -209,6 +209,10 @@
{
"title": "Pages",
"content": "v4/pages"
},
{
"title": "Internationalization",
"content": "v4/internationalization"
}
]
}
@@ -255,7 +259,7 @@
},
{
"name": "Discord",
"url": "https://discord.gg/kener"
"url": "https://discord.gg/uSTpnuK9XR"
}
]
}
+24 -27
View File
@@ -74,60 +74,60 @@
return findFirstSlug(["quickstart", "introduction"]) ?? data.config.sidebar[0]?.pages[0]?.slug;
}
function getApiReferenceSlug(): string {
return findFirstSlug(["api-reference"]) ?? "api-reference";
}
const coreFeatures: FeatureCard[] = [
{
icon: Zap,
title: "Powerful Monitoring",
description: "Track API, Ping, TCP, DNS, SSL, SQL, Heartbeat, and GameDig monitors with flexible checks.",
href: "/docs/monitors"
href: "/docs/monitors/overview"
},
{
icon: Shield,
title: "Incident Management",
description: "Create transparent incident timelines with updates, acknowledgements, and clear communication.",
href: "/docs/incidents"
href: "/docs/incidents/overview"
},
{
icon: Bell,
title: "Smart Notifications",
description: "Notify subscribers via email, webhooks, Slack, and Discord with trigger-based workflows.",
href: "/docs/notifications"
href: "/docs/alerting/overview"
},
{
icon: Wrench,
title: "Maintenance Scheduling",
description: "Plan recurring maintenance windows and keep customers informed before, during, and after.",
href: "/docs/maintenances"
href: "/docs/maintenances/overview"
},
{
icon: Users,
title: "Multi-user Collaboration",
description: "Invite your team with role-based access to monitors, incidents, and configuration workflows."
description: "Invite your team with role-based access to monitors, incidents, and configuration workflows.",
href: "/docs/user-management"
},
{
icon: Database,
title: "Multiple Status Pages",
description: "Manage multiple branded status pages from one Kener instance for different products or teams."
description: "Manage multiple branded status pages from one Kener instance for different products or teams.",
href: "/docs/pages"
},
{
icon: Code,
title: "Complete API Access",
description: "Automate incidents, monitor operations, and reporting with the full REST API.",
href: "/docs/api-reference"
href: "/docs/spec/v4/"
},
{
icon: Globe,
title: "Global Reach",
description: "Use localization, timezone-aware display, and SEO-friendly pages for global audiences."
description: "Use localization, timezone-aware display, and SEO-friendly pages for global audiences.",
href: "/docs/internationalization"
},
{
icon: Palette,
title: "Customization & Branding",
description: "Customize logo, colors, CSS, and theme behavior to match your product identity."
description: "Customize logo, colors, CSS, and theme behavior to match your product identity.",
href: "/docs/setup/customizations"
},
{
icon: Moon,
@@ -137,7 +137,8 @@
{
icon: Book,
title: "Embeddable Widgets & Badges",
description: "Embed status cards and badges into your website, app, or support portal."
description: "Embed status cards and badges into your website, app, or support portal.",
href: "/docs/sharing"
},
{
icon: Activity,
@@ -193,17 +194,11 @@
}
function getMetrics(): Array<{ label: string; value: string }> {
return [
{ label: "Open Source", value: "MIT" },
{ label: "Docs Sections", value: `${data.config.sidebar.length}+` },
{ label: "Theme", value: "Light / Dark" },
{ label: "APIs", value: "REST" }
];
return [];
}
function getCtaButtons(): CtaButton[] {
const quickStartSlug = getQuickStartSlug();
const apiReferenceSlug = getApiReferenceSlug();
return [
{
@@ -213,12 +208,7 @@
},
{
title: "API Reference",
href: `/docs/${apiReferenceSlug}`,
primary: false
},
{
title: "View Introduction",
href: "/docs/introduction",
href: "/docs/spec/v4/",
primary: false
}
];
@@ -229,6 +219,10 @@
return `${base}${path}`;
}
if (path.startsWith("/docs/spec/")) {
return `${base}${path}`;
}
const suffix = path.replace(/^\/docs\/?/, "");
if (suffix.startsWith(`${data.config.activeVersion}/`)) {
@@ -246,6 +240,7 @@
<svelte:head>
<title>Documentation - {data.config.name}</title>
<meta name="description" content="Documentation and guides for {data.config.name}" />
<link rel="icon" href={data.config.favicon} />
</svelte:head>
<div class="bg-background text-foreground min-h-screen">
@@ -309,6 +304,7 @@
{#each getCtaButtons() as button (button.title)}
<a
href={getHref(button.href)}
rel="external"
class={[
"inline-flex items-center gap-2 rounded px-6 py-3 text-sm font-semibold no-underline transition-all duration-200 md:px-7 md:py-3.5 md:text-base",
button.primary
@@ -357,6 +353,7 @@
</div>
{#if feature.href}
<a
rel="external"
href={getHref(feature.href)}
class="text-muted-foreground hover:text-foreground text-xs font-medium no-underline transition-colors"
>
@@ -0,0 +1,119 @@
---
title: Internationalization
description: Configure language localization and timezone behavior for your Kener status page.
---
Kener internationalization has two parts:
1. **Localization** (translated UI text)
2. **Timezone handling** (how date/time values are displayed)
Use this page to configure both from the admin UI and keep translations complete.
## Quick setup {#quick-setup}
1. Open **Manage → Internationalization**.
2. In **Languages**:
- select available locales,
- pick a default locale,
- click **Save Languages**.
3. In **Timezone Settings**:
- enable or disable **Allow users to switch timezones**,
- click **Save Timezone**.
## Localization {#localization}
### How it works {#localization-how-it-works}
- Locale files are JSON files in `src/lib/locales/`.
- Each locale file stores translations under `mappings`.
- Admin settings store:
- selected locales,
- default locale.
Only selected locales are exposed to users in the language selector.
### Add or update translations {#localization-add-update}
1. Edit the locale file(s) in `src/lib/locales/`.
2. Add missing keys under `mappings`.
3. Run translation checks.
Example locale shape:
```json
{
"name": "English",
"mappings": {
"Status": "Status",
"All Systems Operational": "All Systems Operational"
}
}
```
### Validate localization {#localization-validate}
Run these from project root:
```bash
node scripts/check-translations.js
node scripts/sort-translations.js
```
- `check-translations` reports missing/unused keys.
- `sort-translations` normalizes key order in locale files.
## Timezone handling {#timezone}
### How it works {#timezone-how-it-works}
- Kener stores timestamps in UTC (Unix seconds).
- On the client, Kener detects browser timezone automatically.
- If timezone switching is enabled, users can change timezone manually from the public page controls.
### Admin toggle {#timezone-admin-toggle}
In **Manage → Internationalization**, the timezone switch controls whether manual timezone selection is shown to users:
- **ON**: users can switch timezones.
- **OFF**: users see auto-detected timezone behavior only.
### Server timezone variable {#timezone-server-variable}
Server-side timezone behavior is also affected by `TZ`.
For setup details, see: [/docs/v4/setup/environment-variables#timezone](/docs/v4/setup/environment-variables#timezone)
## Stored settings reference {#stored-settings}
Kener saves internationalization settings in site data with keys like:
| Key | Purpose |
| -------------------- | ------------------------------------------------------------------------------------ |
| `i18n.defaultLocale` | Default locale shown on first visit (unless user already has a language preference). |
| `i18n.locales[]` | List of available locales and whether each one is selected. |
| `tzToggle` | Enables/disables manual timezone switching in the public UI. |
## Verification checklist {#verification}
- Language selector shows only selected locales.
- Default language is used for first-time visits.
- `translation-report.json` has no unexpected missing keys.
- Time values render correctly for your locale/timezone.
- Timezone selector visibility matches your `tzToggle` setting.
## Troubleshooting {#troubleshooting}
- **Missing translation keys in report**
- Add keys to all required locale files under `mappings`.
- Re-run `node scripts/check-translations.js`.
- **Language not appearing in selector**
- Make sure it is selected in **Manage → Internationalization**.
- Save language settings.
- **Timezone selector not visible**
- Enable **Allow users to switch timezones** and save.
- **Unexpected server-side time behavior**
- Verify `TZ` is set as documented in [/docs/v4/setup/environment-variables#timezone](/docs/v4/setup/environment-variables#timezone).
+2 -2
View File
@@ -850,9 +850,9 @@ async function uploadImage(data: ImageUploadData): Promise<{ id: string; url: st
finalMimeType = "image/png";
}
// Generate ID with prefix, nanoid, and extension
// Generate ID with nanoid and extension
const fileExtension = finalMimeType === "image/jpeg" ? "jpg" : "png";
const id = `${prefix}${nanoid(16)}.${fileExtension}`;
const id = `${nanoid(16)}.${fileExtension}`;
// Convert processed image back to base64
const processedBase64 = processedBuffer.toString("base64");
@@ -620,7 +620,7 @@
<p class="text-muted-foreground mt-4 text-sm">
Want to upload and use custom fonts? Read more about it in the
<a
href="https://kener.ing/docs/custom-fonts/"
href="https//kener.ing/docs/v4/guides/custom-fonts"
target="_blank"
class="text-foreground underline underline-offset-4"
>
@@ -785,7 +785,7 @@
Add custom CSS to further customize the appearance of your status page. Do not include &lt;style&gt; tags.
Learn more in the
<a
href="https://kener.ing/docs/custom-js-css-guide"
href="https//kener.ing/docs/v4/guides/custom-js-css-guide"
target="_blank"
class="text-foreground underline underline-offset-4"
>
@@ -124,12 +124,7 @@
</Table.Cell>
<Table.Cell class="text-right">
<Button
variant="outline"
target="_blank"
size="sm"
href={clientResolver(resolve, `/${page.page_path}`)}
>
<Button variant="ghost" target="_blank" size="sm" href={clientResolver(resolve, `/${page.page_path}`)}>
View
</Button>
<Button
@@ -137,7 +132,6 @@
size="sm"
onclick={() => goto(clientResolver(resolve, `/manage/app/pages/${page.id}`))}
>
<SettingsIcon class="mr-1 size-4" />
Edit
</Button>
</Table.Cell>
@@ -299,7 +299,7 @@
<p>
Please visit the email set up documentation <a
class="underline"
href={clientResolver(resolve, "/docs/setup/email-setup")}>here</a
href={clientResolver(resolve, "https://kener.ing/docs/v4/setup/email-setup")}>here</a
>.
</p>
</Alert.Description>
@@ -451,7 +451,7 @@
<p>
Please visit the email set up documentation <a
class="underline"
href={clientResolver(resolve, "/docs/setup/email-setup")}>here</a
href={clientResolver(resolve, "https://kener.ing/docs/v4/setup/email-setup")}>here</a
>.
</p>
</Alert.Description>