mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 10:52:22 +00:00
i18n: complete Slovak Monitor and CLI messages
This commit is contained in:
@@ -2,6 +2,12 @@
|
||||
* API Configuration for ProxMenux Monitor
|
||||
* Handles API URL generation with automatic proxy detection
|
||||
*/
|
||||
// Resolve wording only for a generic transport failure. Normal responses and
|
||||
// backend error payloads keep the transport free of locale-loading work.
|
||||
async function apiFailure(...args: Parameters<typeof import("./api-errors").apiFailure>): Promise<string> {
|
||||
const messages = await import("./api-errors")
|
||||
return messages.apiFailure(...args)
|
||||
}
|
||||
|
||||
/**
|
||||
* API Server Port Configuration
|
||||
@@ -114,7 +120,7 @@ export async function fetchApi<T>(endpoint: string, options?: RequestInit): Prom
|
||||
hadToken = true
|
||||
}
|
||||
if (!hadToken) {
|
||||
throw new Error(`Unauthorized: ${endpoint}`)
|
||||
throw new Error(await apiFailure("unauthorized", { endpoint }))
|
||||
}
|
||||
try {
|
||||
localStorage.removeItem("proxmenux-auth-token")
|
||||
@@ -131,7 +137,7 @@ export async function fetchApi<T>(endpoint: string, options?: RequestInit): Prom
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
throw new Error(`Unauthorized: ${endpoint}`)
|
||||
throw new Error(await apiFailure("unauthorized", { endpoint }))
|
||||
}
|
||||
// Try to surface the backend's JSON error payload instead of a
|
||||
// bare `500 INTERNAL SERVER ERROR`. The Flask routes consistently
|
||||
@@ -168,7 +174,7 @@ export async function fetchApi<T>(endpoint: string, options?: RequestInit): Prom
|
||||
throw parseErr
|
||||
}
|
||||
}
|
||||
throw new Error(`API request failed: ${response.status} ${response.statusText}`)
|
||||
throw new Error(await apiFailure("http", { status: response.status, statusText: response.statusText }))
|
||||
}
|
||||
|
||||
// Check content type to ensure we're getting JSON
|
||||
@@ -176,13 +182,13 @@ export async function fetchApi<T>(endpoint: string, options?: RequestInit): Prom
|
||||
if (!contentType || !contentType.includes("application/json")) {
|
||||
const text = await response.text()
|
||||
console.error("fetchApi: Expected JSON but got:", contentType, "- Body preview:", text.substring(0, 200))
|
||||
throw new Error(`Expected JSON response but got ${contentType || "unknown content type"}`)
|
||||
throw new Error(await apiFailure("unexpectedContentType", { contentType: contentType || await apiFailure("unknownContentType") }))
|
||||
}
|
||||
|
||||
try {
|
||||
return await response.json()
|
||||
} catch (jsonError) {
|
||||
console.error("fetchApi: JSON parse error for", endpoint, "-", jsonError)
|
||||
throw new Error(`Invalid JSON response from ${endpoint}`)
|
||||
throw new Error(await apiFailure("invalidJson", { endpoint }))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import enMessages from "../messages/en/common.json"
|
||||
import skMessages from "../messages/sk/common.json"
|
||||
import { detectBrowserLanguage, LANGUAGE_STORAGE_KEY } from "./i18n/languages"
|
||||
|
||||
type Failure = keyof typeof enMessages.apiErrors
|
||||
|
||||
// fetchApi also runs outside React hooks. Read the provider's current document
|
||||
// language, with its stored/browser preference as a fallback.
|
||||
export function apiFailure(key: Failure, params: Record<string, string | number> = {}): string {
|
||||
let language = typeof document === "undefined" ? "" : document.documentElement?.lang
|
||||
if (!language && typeof window !== "undefined") {
|
||||
try { language = window.localStorage.getItem(LANGUAGE_STORAGE_KEY) || "" } catch { /* private browsing */ }
|
||||
}
|
||||
language ||= detectBrowserLanguage()
|
||||
const messages = language === "sk" ? skMessages.apiErrors : enMessages.apiErrors
|
||||
return messages[key].replace(/\{(\w+)\}/g, (match, name) => params[name] === undefined ? match : String(params[name]))
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import enMessages from "../messages/en/common.json"
|
||||
|
||||
type Translate = (key: string, params?: Record<string, string | number>) => string
|
||||
|
||||
// Descriptions are live server metadata. Translate only exact known wording;
|
||||
// a newer script description must remain visible rather than become stale text.
|
||||
export function optimizationDescription(description: string, t: Translate): string {
|
||||
const entries = Object.entries(enMessages.settings.optimizations.toolDescriptions)
|
||||
const match = entries.find(([, english]) => english === description)
|
||||
return match ? t(`settings.optimizations.toolDescriptions.${match[0]}`) : description
|
||||
}
|
||||
|
||||
// Unknown tools retain the server's name until their key is translated.
|
||||
export function optimizationToolName(tool: string, fallback: string, t: Translate): string {
|
||||
return Object.prototype.hasOwnProperty.call(enMessages.settings.optimizations.toolNames, tool)
|
||||
? t(`settings.optimizations.toolNames.${tool}`)
|
||||
: fallback
|
||||
}
|
||||
Reference in New Issue
Block a user