diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 38ca4eeb2..ce12f6711 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -240,7 +240,7 @@ docker rm uptime_database_mongo **Need more help?** -- Check the [full documentation](https://docs.checkmate.so) +- Check the [full documentation](https://checkmate.so/docs) - Ask on [Discord](https://discord.com/invite/NAb6H3UTjK) ### Start contributing code? @@ -316,7 +316,7 @@ If one or more of these are missing, we may ask you to update your pull request - `master` is used for stable releases. - Use descriptive branch names, like `fix/login-error` or `feat/add-alerts`. - Make sure that you are using the latest version. -- Make sure you run the code locally. The Checkmate [documentation](https://docs.checkmate.so) covers it. +- Make sure you run the code locally. The Checkmate [documentation](https://checkmate.so/docs) covers it. - Find out if the functionality is already covered, maybe by an individual configuration. - Perform a [search](/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. - Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. diff --git a/README.es.md b/README.es.md index e57efc2e4..92237ea3c 100644 --- a/README.es.md +++ b/README.es.md @@ -49,11 +49,11 @@ Puedes ver la última versión de [Checkmate](https://checkmate-demo.bluewavelab ## Guía del usuario -Las instrucciones de uso se pueden encontrar [aquí](https://docs.checkmate.so/checkmate-2.1). Todavía está en desarrollo y parte de la información puede estar desactualizada ya que continuamente añadimos funciones cada semana. ¡Ten por seguro que estamos haciendo lo mejor posible! :) +Las instrucciones de uso se pueden encontrar [aquí](https://checkmate.so/docs). Todavía está en desarrollo y parte de la información puede estar desactualizada ya que continuamente añadimos funciones cada semana. ¡Ten por seguro que estamos haciendo lo mejor posible! :) ## Instalación -Consulta las instrucciones de instalación en el [portal de documentación de Checkmate](https://docs.checkmate.so/checkmate-2.1/users-guide/quickstart). +Consulta las instrucciones de instalación en el [portal de documentación de Checkmate](https://checkmate.so/docs/getting-started/installation). Alternativamente, también puedes usar [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md) o [Pikapods](https://www.pikapods.com/) para desplegar rápidamente una instancia de Checkmate. Si deseas monitorear tu infraestructura de servidores, necesitarás el agente [Capture](https://github.com/bluewave-labs/capture). El repositorio de Capture también contiene las instrucciones de instalación. @@ -147,7 +147,7 @@ Cómo contribuir: 0. Dale una estrella al repositorio :) 1. Revisa la [guía para contribuidores](https://github.com/bluewave-labs/Checkmate/blob/develop/CONTRIBUTING.md). Se anima a los nuevos a revisar las etiquetas `good-first-issue`. -2. Consulta la [estructura del proyecto](https://docs.checkmate.so/checkmate-2.1/developers-guide/general-project-structure) y la [visión general](https://bluewavelabs.gitbook.io/checkmate/developers-guide/high-level-overview). +2. Consulta la [estructura del proyecto](https://deepwiki.com/bluewave-labs/Checkmate#system-architecture) y la [visión general](https://deepwiki.com/bluewave-labs/Checkmate#overview). 3. Lee una estructura detallada de [Checkmate](https://deepwiki.com/bluewave-labs/Checkmate) si deseas profundizar en la arquitectura. 4. Abre un issue si crees que has encontrado un error. 5. Revisa los issues con la etiqueta `good-first-issue` si eres nuevo. diff --git a/client/NOTICE b/client/NOTICE new file mode 100644 index 000000000..a72e9c36f --- /dev/null +++ b/client/NOTICE @@ -0,0 +1,18 @@ +Checkmate +Copyright (c) BlueWave Labs + +This product includes assets developed by third parties. + +---------------------------------------------------------------------- + +King chess-piece silhouette used in the Checkmate logo +(client/src/assets/icons/checkmate-icon.svg and + client/public/checkmate_favicon.svg) +is adapted from "Chess klt45.svg" by Cburnett, available at: + https://commons.wikimedia.org/wiki/File:Chess_klt45.svg +Licensed under Creative Commons Attribution-ShareAlike 3.0 Unported +(CC BY-SA 3.0): https://creativecommons.org/licenses/by-sa/3.0/ + +The original artwork has been recolored from the white-with-black-stroke +chess piece to the Checkmate brand green (#13715B) for use as a logo. +Modifications: stroke color change only; geometry unchanged. diff --git a/client/package-lock.json b/client/package-lock.json index 7462d95d7..850a2b149 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "client", - "version": "0.0.0", + "version": "3.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "client", - "version": "0.0.0", + "version": "3.6.1", "dependencies": { "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", @@ -20,7 +20,6 @@ "@types/maplibre-gl": "^1.13.2", "axios": "^1.7.4", "dayjs": "1.11.13", - "flag-icons": "7.3.2", "html2canvas": "^1.4.1", "human-interval": "2.0.1", "i18next": "25.4.2", @@ -3891,10 +3890,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flag-icons": { - "version": "7.3.2", - "license": "MIT" - }, "node_modules/flat-cache": { "version": "3.2.0", "dev": true, diff --git a/client/package.json b/client/package.json index 2e6b5cfcb..a09e89c4c 100644 --- a/client/package.json +++ b/client/package.json @@ -1,7 +1,7 @@ { "name": "client", "private": true, - "version": "0.0.0", + "version": "3.6.1", "type": "module", "scripts": { "dev": "vite", @@ -28,7 +28,6 @@ "@types/maplibre-gl": "^1.13.2", "axios": "^1.7.4", "dayjs": "1.11.13", - "flag-icons": "7.3.2", "html2canvas": "^1.4.1", "human-interval": "2.0.1", "i18next": "25.4.2", diff --git a/client/public/checkmate_favicon.svg b/client/public/checkmate_favicon.svg index e0e6bf6f4..e1701573a 100644 --- a/client/public/checkmate_favicon.svg +++ b/client/public/checkmate_favicon.svg @@ -1,49 +1,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Checkmate + King silhouette adapted from Cburnett's chess set (Wikimedia Commons, CC BY-SA 3.0). + + + + + + diff --git a/client/src/App.tsx b/client/src/App.tsx index 15c94dbb5..5a1a36455 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -33,6 +33,14 @@ function App() { body: { backgroundColor: theme.palette.background.default, }, + ".Toastify__progress-bar": { + height: 2, + bottom: 0, + top: "auto", + }, + ".Toastify__progress-bar--bg": { + display: "none", + }, }} /> @@ -41,12 +49,23 @@ function App() { diff --git a/client/src/Components/design-elements/BaseChart.tsx b/client/src/Components/design-elements/BaseChart.tsx index de87395eb..c6d8298a7 100644 --- a/client/src/Components/design-elements/BaseChart.tsx +++ b/client/src/Components/design-elements/BaseChart.tsx @@ -8,7 +8,7 @@ import type { ResponsiveStyleValue } from "@mui/system"; import { useTheme } from "@mui/material/styles"; type BaseChartProps = React.PropsWithChildren<{ - icon: React.ReactNode; + icon?: React.ReactNode; title: string; width?: number | string; maxWidth?: number | string; @@ -17,7 +17,6 @@ type BaseChartProps = React.PropsWithChildren<{ export const BaseChart = ({ children, - icon, title, width = "100%", maxWidth = "100%", @@ -38,34 +37,12 @@ export const BaseChart = ({ gap={theme.spacing(LAYOUT.MD)} flex={1} > - - {icon && ( - - {icon} - - )} - {title} - + {title} + {children} diff --git a/client/src/Components/design-elements/BasePage.tsx b/client/src/Components/design-elements/BasePage.tsx index 691e770dc..7522fa175 100644 --- a/client/src/Components/design-elements/BasePage.tsx +++ b/client/src/Components/design-elements/BasePage.tsx @@ -1,52 +1,84 @@ import Logo from "@/assets/icons/checkmate-icon.svg?react"; import Stack from "@mui/material/Stack"; import Box from "@mui/material/Box"; -import Alert from "@mui/material/Alert"; import Link from "@mui/material/Link"; -import { LAYOUT, SPACING } from "@/Utils/Theme/constants"; +import { LAYOUT } from "@/Utils/Theme/constants"; import { ErrorFallback, EmptyFallback, EmptyMonitorFallback, - BaseFallback, } from "@/Components/design-elements/Fallback"; +import { EmptyState } from "@/Components/design-elements/EmptyState"; import { Breadcrumb } from "@/Components/design-elements/Breadcrumb"; +import { PageHeader } from "@/Components/design-elements/PageHeader"; import CircularProgress from "@mui/material/CircularProgress"; -import { HeaderAuthControls } from "@/Pages/Auth/components/HeaderAuthControls"; +import { LanguageSelector, SwitchTheme } from "@/Components/inputs"; import type { StackProps } from "@mui/material/Stack"; -import { useTheme } from "@mui/material/styles"; +import { useTheme, alpha } from "@mui/material/styles"; import { Trans, useTranslation } from "react-i18next"; import { Link as RouterLink } from "react-router-dom"; import { Typography } from "@mui/material"; export const PageSpeedKeyPriorityFallback = () => { + const theme = useTheme(); + const { t } = useTranslation(); + const alertBg = alpha(theme.palette.warning.main, 0.08); + const alertBorder = alpha(theme.palette.warning.main, 0.45); + const alertIcon = theme.palette.warning.main; return ( - - - - - ), + + - - - + > + ⚠ + + + + ), + }} + /> + + + } + /> ); }; @@ -55,6 +87,9 @@ interface BasePageProps extends StackProps { error?: boolean; children: React.ReactNode; breadcrumbOverride?: string[]; + headerKey?: string; + backTo?: string; + backLabel?: string; } export const BasePage = ({ @@ -62,9 +97,13 @@ export const BasePage = ({ error, children, breadcrumbOverride, + headerKey, + backTo, + backLabel, ...props }: BasePageProps) => { const theme = useTheme(); + const { t } = useTranslation(); if (loading) { return ( @@ -95,7 +134,16 @@ export const BasePage = ({ spacing={theme.spacing(LAYOUT.LG)} {...props} > - + {headerKey ? ( + + ) : ( + + )} {children} ); @@ -105,11 +153,12 @@ interface BasePageWithStatesProps extends StackProps { loading: boolean; error: any; totalCount: number; - bullets: string[] | unknown; + description?: string; page: string; actionButtonText: string; actionLink: string; children: React.ReactNode; + headerKey?: string; } export const BasePageWithStates = ({ @@ -117,10 +166,11 @@ export const BasePageWithStates = ({ error, totalCount, page, - bullets, + description, actionButtonText, actionLink, children, + headerKey, ...props }: BasePageWithStatesProps) => { const showLoading = loading && totalCount === 0; @@ -128,7 +178,7 @@ export const BasePageWithStates = ({ if (!loading && totalCount === 0) { return ( {children} @@ -155,6 +206,7 @@ interface MonitorBasePageWithStatesProps extends StackProps { actionLink?: string; children: React.ReactNode; priorityFallback?: React.ReactNode; + headerKey?: string; } export const MonitorBasePageWithStates = ({ @@ -165,6 +217,7 @@ export const MonitorBasePageWithStates = ({ actionLink, children, priorityFallback, + headerKey, ...props }: MonitorBasePageWithStatesProps) => { const { t } = useTranslation(); @@ -172,15 +225,7 @@ export const MonitorBasePageWithStates = ({ const showLoading = loading && totalCount === 0; if (priorityFallback) { - return ( - - {priorityFallback} - - ); + return <>{priorityFallback}; } if (!loading && totalCount === 0) { @@ -188,7 +233,7 @@ export const MonitorBasePageWithStates = ({ @@ -199,6 +244,7 @@ export const MonitorBasePageWithStates = ({ {children} @@ -215,51 +261,163 @@ export const BaseAuthPage = ({ title, subtitle, children, - ...props + component, + onSubmit, }: BaseAuthPageProps) => { const theme = useTheme(); + const { t } = useTranslation(); return ( - - - - - - - + - {title} - - {subtitle} + + + + + + + + + + {t("common.appName")} + + + + + {title} + + + {subtitle} + + + {children} + - {children} +
+ + + {t("pages.auth.brandPanel.eyebrow")} + + + {t("pages.auth.brandPanel.tagline")} + + + {t("pages.auth.brandPanel.description")} + + + + v{__APP_VERSION__} + - + ); }; diff --git a/client/src/Components/design-elements/EmptyState.tsx b/client/src/Components/design-elements/EmptyState.tsx new file mode 100644 index 000000000..a8850d516 --- /dev/null +++ b/client/src/Components/design-elements/EmptyState.tsx @@ -0,0 +1,158 @@ +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import { useTheme } from "@mui/material/styles"; +import { Link as RouterLink } from "react-router-dom"; +import { Button } from "@/Components/inputs"; +import { LAYOUT } from "@/Utils/Theme/constants"; +import { EmptyStateIllustration } from "./EmptyStateIllustration"; + +import type { ReactNode } from "react"; + +interface EmptyStateProps { + title: string; + description?: ReactNode; + actionText?: string; + actionTo?: string; + onAction?: () => void; + secondaryText?: string; + secondaryHref?: string; + compact?: boolean; + fullscreen?: boolean; + alert?: ReactNode; + children?: ReactNode; +} + +export const EmptyState = ({ + title, + description, + actionText, + actionTo, + onAction, + secondaryText, + secondaryHref, + compact = false, + fullscreen = false, + alert, + children, +}: EmptyStateProps) => { + const theme = useTheme(); + + if (compact) { + return ( + + + + + {title} + + {description && ( + + {description} + + )} + + + ); + } + + return ( + + + + {title} + + {description && ( + + {description} + + )} + {alert && ( + + {alert} + + )} + {(actionText || secondaryText) && ( + + {actionText && (actionTo || onAction) && ( + + )} + {secondaryText && secondaryHref && ( + + {secondaryText} → + + )} + + )} + {children} + + ); +}; diff --git a/client/src/Components/design-elements/EmptyStateIllustration.tsx b/client/src/Components/design-elements/EmptyStateIllustration.tsx new file mode 100644 index 000000000..d4557bc9a --- /dev/null +++ b/client/src/Components/design-elements/EmptyStateIllustration.tsx @@ -0,0 +1,197 @@ +import { useTheme } from "@mui/material/styles"; + +interface EmptyStateIllustrationProps { + width?: number | string; + height?: number | string; +} + +const PALETTE = { + light: { + grid: "#CBD5E1", + backFill: "#F5F7FA", + backStroke: "#D5DBE3", + backInner: "#B6C2CF", + frontFill: "#EAF5F0", + frontStroke: "#7DBFAA", + frontInner: "#4DAF94", + }, + dark: { + grid: "#3A4452", + backFill: "#475569", + backStroke: "#64748B", + backInner: "#CBD5E1", + frontFill: "#0F5D4A", + frontStroke: "#4DAF94", + frontInner: "#B5E2D2", + }, +}; + +export const EmptyStateIllustration = ({ + width = 160, + height = 120, +}: EmptyStateIllustrationProps) => { + const theme = useTheme(); + const p = theme.palette.mode === "dark" ? PALETTE.dark : PALETTE.light; + return ( + + ); +}; diff --git a/client/src/Components/design-elements/Fallback.tsx b/client/src/Components/design-elements/Fallback.tsx index 003bda647..989c2bed4 100644 --- a/client/src/Components/design-elements/Fallback.tsx +++ b/client/src/Components/design-elements/Fallback.tsx @@ -1,12 +1,8 @@ import Stack from "@mui/material/Stack"; -import Typography from "@mui/material/Typography"; -import { BulletPointCheck, SkeletonCard } from "@/Components/design-elements"; -import { Button } from "@/Components/inputs"; -import { SPACING, LAYOUT } from "@/Utils/Theme/constants"; - -import { useNavigate } from "react-router"; -import useMediaQuery from "@mui/material/useMediaQuery"; import { useTheme } from "@mui/material/styles"; +import { LAYOUT } from "@/Utils/Theme/constants"; +import { EmptyState } from "./EmptyState"; + import type { StackProps } from "@mui/material/Stack"; interface BaseFallbackProps extends StackProps { @@ -15,30 +11,13 @@ interface BaseFallbackProps extends StackProps { export const BaseFallback = ({ children, ...props }: BaseFallbackProps) => { const theme = useTheme(); - const isSmall = useMediaQuery(theme.breakpoints.down("md")); - return ( - {children} ); @@ -51,126 +30,56 @@ export const ErrorFallback = ({ title: string; subtitle: string; }) => { - const theme = useTheme(); return ( - - - {title} - - {subtitle} - + ); }; export const EmptyFallback = ({ title, - bullets, + description, actionButtonText, actionLink, }: { title: string; - bullets: any; + description?: string; actionButtonText: string; actionLink: string; }) => { - const theme = useTheme(); - const navigate = useNavigate(); return ( - - - {title} - - {Array.isArray(bullets) && - bullets?.map((bullet: string) => ( - - ))} - - - - - - + ); }; export const EmptyMonitorFallback = ({ - page, title, - bullets, + description, actionButtonText, actionLink, }: { page: string; title: string; - bullets: any; + description?: string; actionButtonText: string; actionLink: string; }) => { - const theme = useTheme(); - const navigate = useNavigate(); return ( - - - - {title} - - - {Array.isArray(bullets) && - bullets?.map((bullet: string, index: number) => ( - - ))} - - - - - - + ); }; diff --git a/client/src/Components/design-elements/Gauge.tsx b/client/src/Components/design-elements/Gauge.tsx index fda42df3c..a377a5925 100644 --- a/client/src/Components/design-elements/Gauge.tsx +++ b/client/src/Components/design-elements/Gauge.tsx @@ -114,6 +114,7 @@ export const DetailGauge = ({ upperValue, lowerLabel, lowerValue, + maxWidth = 225, }: { title: string; progress: number; @@ -121,13 +122,14 @@ export const DetailGauge = ({ upperValue?: string | number; lowerLabel?: string; lowerValue?: string | number; + maxWidth?: number; }) => { const theme = useTheme(); return ( { { + const theme = useTheme(); + const { t } = useTranslation(); + + const linkItems: { key: keyof typeof EXTERNAL_LINKS; icon: ReactNode }[] = [ + { + key: "support", + icon: ( + + ), + }, + { + key: "docs", + icon: ( + + ), + }, + { + key: "changelog", + icon: ( + + ), + }, + ]; + + return ( + + + {backTo && backLabel && ( + + + {backLabel} + + )} + + {title} + + {description && ( + + {description} + + )} + + + {linkItems.map((item, idx) => ( + + + {item.icon} + + + ))} + + + ); +}; diff --git a/client/src/Components/design-elements/SplitBox.tsx b/client/src/Components/design-elements/SplitBox.tsx index 08f245178..4154ed010 100644 --- a/client/src/Components/design-elements/SplitBox.tsx +++ b/client/src/Components/design-elements/SplitBox.tsx @@ -63,9 +63,9 @@ export const ConfigBox = ({ left={ {title} diff --git a/client/src/Components/design-elements/StatBox.tsx b/client/src/Components/design-elements/StatBox.tsx index 01a8e9835..954120fe5 100644 --- a/client/src/Components/design-elements/StatBox.tsx +++ b/client/src/Components/design-elements/StatBox.tsx @@ -69,7 +69,12 @@ export const StatBox = ({ > - {title} + + {title} + {tooltip && ( { overflow: "hidden", position: "relative", flex: 1, - padding: theme.spacing(4), + padding: theme.spacing(6), ...sx, }} > @@ -65,9 +65,13 @@ const StatusBox = ({ {label} diff --git a/client/src/Components/design-elements/Table.tsx b/client/src/Components/design-elements/Table.tsx index 505f79fea..91bb69615 100644 --- a/client/src/Components/design-elements/Table.tsx +++ b/client/src/Components/design-elements/Table.tsx @@ -18,10 +18,9 @@ import { ChevronsRight, ChevronLeft, ChevronRight, - Coffee, Ellipsis, - PartyPopper, } from "lucide-react"; +import { EmptyState } from "./EmptyState"; import TablePagination from "@mui/material/TablePagination"; import type { TablePaginationOwnProps } from "@mui/material/TablePagination"; @@ -163,14 +162,19 @@ export function DataTable< }, "& .MuiTableHead-root .MuiTableRow-root": { height: "28px", + borderBottom: `1px solid ${theme.palette.divider}`, + }, + "& .MuiTableHead-root .MuiTableCell-root": { + borderBottom: "none", }, "& :is(th)": { backgroundColor: theme.palette.background.paper, color: theme.palette.text.secondary, fontWeight: 500, textTransform: "uppercase", + letterSpacing: "0.08em", padding: `${theme.spacing(SPACING.LG)} ${theme.spacing(LAYOUT.MD)}`, - fontSize: theme.typography.fontSize, + fontSize: 11, }, "& :is(td)": { backgroundColor: theme.palette.background.paper, @@ -548,49 +552,18 @@ export const Pagination = ({ ...props }: PaginationProps) => { ); }; -const EmptyView = ({ text, positive }: { text?: string; positive?: boolean }) => { - const theme = useTheme(); +const EmptyView = ({ text }: { text?: string; positive?: boolean }) => { const { t } = useTranslation(); - const Icon = positive ? PartyPopper : Coffee; + const theme = useTheme(); return ( - - - - - - {text ?? t("common.table.empty")} - - + + ); }; diff --git a/client/src/Components/design-elements/Tooltip.tsx b/client/src/Components/design-elements/Tooltip.tsx index f83b1331c..f9bbbb92b 100644 --- a/client/src/Components/design-elements/Tooltip.tsx +++ b/client/src/Components/design-elements/Tooltip.tsx @@ -16,16 +16,15 @@ export const Tooltip = ({ placement = "top", ...props }: StyledTooltipProps) => slotProps={{ tooltip: { sx: { - background: + backgroundColor: theme.palette.mode === "dark" - ? "linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)" - : "linear-gradient(135deg, #2c3e50 0%, #1a252f 100%)", - backgroundColor: "transparent", - color: "#ffffff", + ? theme.palette.grey[900] + : theme.palette.grey[800], + color: theme.palette.common.white, fontSize: "13px", padding: `${theme.spacing(4)} ${theme.spacing(5)}`, borderRadius: `${theme.shape.borderRadius}px`, - boxShadow: "0 8px 24px rgba(0, 0, 0, 0.4)", + boxShadow: theme.shadows[6], }, }, }} diff --git a/client/src/Components/design-elements/index.tsx b/client/src/Components/design-elements/index.tsx index ed6a885f6..efc85dbb0 100644 --- a/client/src/Components/design-elements/index.tsx +++ b/client/src/Components/design-elements/index.tsx @@ -1,5 +1,8 @@ export * from "./Breadcrumb"; +export * from "./PageHeader"; export * from "./BasePage"; +export * from "./EmptyState"; +export * from "./EmptyStateIllustration"; export * from "./Fallback"; export * from "./SkeletonCard"; export * from "./BulletPointCheck"; diff --git a/client/src/Components/inputs/Dialog.tsx b/client/src/Components/inputs/Dialog.tsx index b0c924f55..2b8084f85 100644 --- a/client/src/Components/inputs/Dialog.tsx +++ b/client/src/Components/inputs/Dialog.tsx @@ -46,6 +46,9 @@ export const DialogInput = ({ open={open} maxWidth={maxWidth} fullWidth={fullWidth} + onClose={(_event, reason) => { + if (reason !== "backdropClick" && onCancel) onCancel(undefined); + }} > {title && {title}} diff --git a/client/src/Components/inputs/ImageUpload.tsx b/client/src/Components/inputs/ImageUpload.tsx index 0d0b77b40..940e5f758 100644 --- a/client/src/Components/inputs/ImageUpload.tsx +++ b/client/src/Components/inputs/ImageUpload.tsx @@ -126,7 +126,12 @@ export const ImageUpload = ({ onChange={(e) => handleFile(e.target.files?.[0])} style={{ position: "absolute", inset: 0, opacity: 0, cursor: "pointer" }} /> - + = { - cs: "cz", - ja: "jp", - uk: "ua", - vi: "vn", +export const languageNames: Record = { + en: "English", + de: "Deutsch", + es: "Español", + fr: "Français", + "pt-BR": "Português (BR)", + cs: "Čeština", + fi: "Suomi", + tr: "Türkçe", + ru: "Русский", + uk: "Українська", + ar: "العربية", + th: "ไทย", + vi: "Tiếng Việt", + ja: "日本語", + "zh-CN": "简体中文", + "zh-TW": "繁體中文", }; export const LanguageSelector = () => { const { i18n } = useTranslation(); - const theme = useTheme(); const { language = "en" } = useSelector((state: RootState) => state.ui); const dispatch = useDispatch(); const handleChange = (event: any) => { @@ -35,64 +42,15 @@ export const LanguageSelector = () => { value={language} onChange={handleChange} size="small" - // sx={{ - // minWidth: 80, - // "& .MuiSelect-select": { - // display: "flex", - // alignItems: "center", - // justifyContent: "center", - // }, - // "& .MuiSelect-icon": { - // alignSelf: "center", - // }, - // }} > - {languages.map((lang) => { - let parsedLang = lang === "en" ? "gb" : lang; - - if (parsedLang.includes("-")) { - parsedLang = parsedLang.split("-")[1].toLowerCase(); - } - - parsedLang = langMap[parsedLang] || parsedLang; - - const flag = parsedLang ? `fi fi-${parsedLang}` : null; - - return ( - - - - {flag && } - - - {lang} - - - - ); - })} + {languages.map((lang) => ( + + {languageNames[lang] ?? lang} + + ))} ); }; diff --git a/client/src/Components/inputs/Radio.tsx b/client/src/Components/inputs/Radio.tsx index ad8dc3374..01e968188 100644 --- a/client/src/Components/inputs/Radio.tsx +++ b/client/src/Components/inputs/Radio.tsx @@ -1,52 +1,13 @@ import Radio from "@mui/material/Radio"; import type { RadioProps } from "@mui/material/Radio"; import { useTheme } from "@mui/material/styles"; -import { Circle, CircleDot } from "lucide-react"; import FormControlLabel from "@mui/material/FormControlLabel"; import Typography from "@mui/material/Typography"; interface RadioInputProps extends RadioProps {} export const RadioInput = ({ ...props }: RadioInputProps) => { - const theme = useTheme(); - return ( - - } - checkedIcon={ - - } - sx={{ - padding: 0, - mt: theme.spacing(0.5), - color: theme.palette.text.secondary, - "&.Mui-checked": { - color: theme.palette.primary.main, - "& svg circle": { - fill: theme.palette.primary.main, - }, - }, - "& .MuiSvgIcon-root": { - fontSize: 16, - }, - "& svg": { - stroke: "currentColor", - }, - "& svg path, & svg line, & svg polyline, & svg rect, & svg circle": { - stroke: "currentColor", - fill: "none", - }, - }} - /> - ); + return ; }; export const RadioWithDescription = ({ @@ -79,7 +40,6 @@ export const RadioWithDescription = ({ backgroundColor: theme.palette.background.paper, }, "& .MuiButtonBase-root": { - p: 0, mr: theme.spacing(6), }, }} diff --git a/client/src/Components/inputs/Select.tsx b/client/src/Components/inputs/Select.tsx index 190307ec3..92a57860a 100644 --- a/client/src/Components/inputs/Select.tsx +++ b/client/src/Components/inputs/Select.tsx @@ -11,15 +11,14 @@ interface SelectInputProps extends Omit, "label"> { fieldLabel?: string; required?: boolean; placeholder?: string; - placeholderColor?: string; } const SelectInputInner = ( - { fieldLabel, required, placeholder, placeholderColor, ...props }: SelectInputProps, + { fieldLabel, required, placeholder, ...props }: SelectInputProps, ref: React.ForwardedRef ) => { const theme = useTheme(); - const emptyPlaceholderColor = placeholderColor || theme.palette.text.disabled; + const emptyPlaceholderColor = theme.palette.text.secondary; const renderValue = (selected: unknown) => { const isMultiple = Boolean((props as { multiple?: boolean }).multiple); diff --git a/client/src/Components/inputs/Switch.tsx b/client/src/Components/inputs/Switch.tsx index 05be73a24..06ed5bc5f 100644 --- a/client/src/Components/inputs/Switch.tsx +++ b/client/src/Components/inputs/Switch.tsx @@ -21,24 +21,16 @@ export const SwitchComponent = forwardRef diff --git a/client/src/Components/inputs/TextInput.tsx b/client/src/Components/inputs/TextInput.tsx index 718b60327..bfcbfa181 100644 --- a/client/src/Components/inputs/TextInput.tsx +++ b/client/src/Components/inputs/TextInput.tsx @@ -26,6 +26,7 @@ export const TextInput = forwardRef(function T borderRadius: theme.shape.borderRadius, height: 34, fontSize: typographyLevels.base, + overflow: "hidden", }, "& .MuiOutlinedInput-notchedOutline": { borderColor: theme.palette.divider, @@ -38,6 +39,13 @@ export const TextInput = forwardRef(function T marginRight: 0, marginTop: theme.spacing(1), }, + "& input:-webkit-autofill, & input:-webkit-autofill:hover, & input:-webkit-autofill:focus, & input:-webkit-autofill:active": + { + WebkitBoxShadow: `0 0 0 100px ${theme.palette.background.default} inset !important`, + WebkitTextFillColor: `${theme.palette.text.primary} !important`, + caretColor: theme.palette.text.primary, + transition: "background-color 5000s ease-in-out 0s", + }, }} /> ); diff --git a/client/src/Components/inputs/ToggleButton.tsx b/client/src/Components/inputs/ToggleButton.tsx index 40b4309b8..a2b392357 100644 --- a/client/src/Components/inputs/ToggleButton.tsx +++ b/client/src/Components/inputs/ToggleButton.tsx @@ -3,8 +3,17 @@ import ToggleButtonGroup from "@mui/material/ToggleButtonGroup"; import type { ToggleButtonProps } from "@mui/material/ToggleButton"; import type { ToggleButtonGroupProps } from "@mui/material/ToggleButtonGroup"; import { useTheme } from "@mui/material/styles"; +import { alpha } from "@mui/material/styles"; export const ToggleButtonInput = ({ sx, ...props }: ToggleButtonProps) => { + const theme = useTheme(); + const isDark = theme.palette.mode === "dark"; + const selectedBg = isDark + ? alpha(theme.palette.primary.main, 0.22) + : alpha(theme.palette.primary.main, 0.06); + const selectedHoverBg = isDark + ? alpha(theme.palette.primary.main, 0.3) + : alpha(theme.palette.primary.main, 0.1); return ( { textOverflow: "ellipsis", overflow: "hidden", boxShadow: "none", + color: theme.palette.text.secondary, "&:hover": { boxShadow: "none", + backgroundColor: theme.palette.action.hover, + }, + "&.Mui-selected": { + backgroundColor: selectedBg, + color: theme.palette.text.primary, + fontWeight: 500, + "&:hover": { + backgroundColor: selectedHoverBg, + }, }, ...sx, }} @@ -34,7 +53,6 @@ export const ToggleButtonGroupInput = ({ sx, ...props }: ToggleButtonGroupProps) sx={{ "& .MuiToggleButtonGroup-grouped": { borderColor: theme.palette.divider, - borderRadius: 0, "&:first-of-type": { borderTopLeftRadius: 2, diff --git a/client/src/Components/monitors/charts/RadialAvgResponse.tsx b/client/src/Components/monitors/charts/RadialAvgResponse.tsx index fcfaa426b..9a88fb42c 100644 --- a/client/src/Components/monitors/charts/RadialAvgResponse.tsx +++ b/client/src/Components/monitors/charts/RadialAvgResponse.tsx @@ -52,7 +52,7 @@ export const RadialAvgResponse = ({ avg, max }: { avg: number; max: number }) => > @@ -75,13 +75,14 @@ export const RadialAvgResponse = ({ avg, max }: { avg: number; max: number }) => }} > {msg[palette]} {`${avg?.toFixed()}ms`} diff --git a/client/src/Components/sidebar/Authfooter.tsx b/client/src/Components/sidebar/Authfooter.tsx index 49df78270..34f76d7ce 100644 --- a/client/src/Components/sidebar/Authfooter.tsx +++ b/client/src/Components/sidebar/Authfooter.tsx @@ -68,7 +68,12 @@ export const AuthFooter = ({ collapsed, accountMenuItems }: AuthFooterProps) => gap: theme.spacing(LAYOUT.MD), borderRadius: theme.shape.borderRadius, pl: theme.spacing(LAYOUT.XS), - "& svg": { stroke: theme.palette.text.secondary }, + "& svg": { + height: 16, + width: 16, + opacity: 0.81, + stroke: theme.palette.text.secondary, + }, }; return ( diff --git a/client/src/Components/sidebar/Logo.tsx b/client/src/Components/sidebar/Logo.tsx index d7ab2c751..1bb25bd0a 100644 --- a/client/src/Components/sidebar/Logo.tsx +++ b/client/src/Components/sidebar/Logo.tsx @@ -6,6 +6,7 @@ import { toggleSidebar } from "@/Features/UI/uiSlice.js"; import { useDispatch } from "react-redux"; import { useTranslation } from "react-i18next"; import useSidebar from "@/Hooks/useSidebar"; +import KingIcon from "@/assets/icons/checkmate-icon.svg?react"; export const Logo = (props: StackProps) => { const { t } = useTranslation(); @@ -23,19 +24,21 @@ export const Logo = (props: StackProps) => { sx={{ cursor: "pointer" }} {...props} > - - C - + + { { name: t("components.sidebar.menu.logs"), path: "logs", - icon: , + icon: , }, { name: t("components.sidebar.menu.settings"), diff --git a/client/src/Components/sidebar/NavItem.tsx b/client/src/Components/sidebar/NavItem.tsx index 756b10d60..24f2c5778 100644 --- a/client/src/Components/sidebar/NavItem.tsx +++ b/client/src/Components/sidebar/NavItem.tsx @@ -22,7 +22,9 @@ export const NavItem = ({ }) => { const { collapsed } = useSidebar(); const theme = useTheme(); - const iconStroke = selected ? theme.palette.primary.main : theme.palette.text.secondary; + const iconStroke = selected + ? theme.palette.sidebar.accent + : theme.palette.text.secondary; const buttonBgColor = selected ? theme.palette.action.selected : "transparent"; const buttonBgHoverColor = selected @@ -79,7 +81,7 @@ export const NavItem = ({ }, ".MuiListItemButton-root:hover &": { "& svg path, & svg line, & svg polyline, & svg rect, & svg circle": { - stroke: theme.palette.primary.main, + stroke: theme.palette.sidebar.accent, }, }, }} diff --git a/client/src/Components/sidebar/index.tsx b/client/src/Components/sidebar/index.tsx index f4c6527eb..d2d759c6b 100644 --- a/client/src/Components/sidebar/index.tsx +++ b/client/src/Components/sidebar/index.tsx @@ -6,7 +6,7 @@ import Divider from "@mui/material/Divider"; import { LAYOUT } from "@/Utils/Theme/constants"; import { useSidebar } from "@/Hooks/useSidebar.js"; import { Logo } from "@/Components/sidebar/Logo"; -import { getMenu, getBottomMenu, getAccountMenu } from "@/Components/sidebar/Menu"; +import { getMenu, getAccountMenu } from "@/Components/sidebar/Menu"; import { NavItem } from "@/Components/sidebar/NavItem"; import { StarPrompt } from "@/Components/sidebar/StarPrompt"; import { AuthFooter } from "@/Components/sidebar/Authfooter"; @@ -20,7 +20,7 @@ import { setCollapsed } from "@/Features/UI/uiSlice"; const URL_MAP: Record = { support: "https://discord.com/invite/NAb6H3UTjK", discussions: "https://github.com/bluewave-labs/checkmate/discussions", - docs: "https://bluewavelabs.gitbook.io/checkmate", + docs: "https://checkmate.so/docs", changelog: "https://github.com/bluewave-labs/checkmate/releases", }; @@ -33,7 +33,6 @@ export const Sidebar = () => { const theme = useTheme(); const isSmall = useMediaQuery(theme.breakpoints.down("md")); const menu = getMenu(t); - const bottomMenu = getBottomMenu(t); const accountMenu = getAccountMenu(t); useEffect(() => { @@ -103,23 +102,6 @@ export const Sidebar = () => { })} - - {bottomMenu.map((item) => { - const selected = location.pathname.startsWith(`/${item.path}`); - return ( - handleNavClick(item.path)} - /> - ); - })} - () => { ...config?.headers, }, }); - toastSuccess(res.data?.msg || "Operation successful"); + if (res.data?.success === false) { + toastError(res.data?.msg || "Operation failed"); + } else { + toastSuccess(res.data?.msg || "Operation successful"); + } return res.data; } catch (err: any) { diff --git a/client/src/Hooks/UseToast.ts b/client/src/Hooks/UseToast.ts index 8823aa675..72e7b18c9 100644 --- a/client/src/Hooks/UseToast.ts +++ b/client/src/Hooks/UseToast.ts @@ -4,8 +4,9 @@ export const useToast = () => { const showToast = (message: string, options?: ToastOptions) => { toast.dismiss(); const baseStyle: React.CSSProperties = { - whiteSpace: "pre-line", - wordBreak: "break-word", + whiteSpace: "nowrap", + overflow: "hidden", + textOverflow: "ellipsis", }; toast(message, { ...options, diff --git a/client/src/Hooks/useClientPagination.ts b/client/src/Hooks/useClientPagination.ts new file mode 100644 index 000000000..93bb5256a --- /dev/null +++ b/client/src/Hooks/useClientPagination.ts @@ -0,0 +1,37 @@ +import { useState } from "react"; + +export const useClientPagination = (rows: T[], initialRowsPerPage = 10) => { + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(initialRowsPerPage); + + const handlePageChange = ( + _e: React.MouseEvent | null, + newPage: number + ) => { + setPage(newPage); + }; + + const handleRowsPerPageChange = ( + e: React.ChangeEvent + ) => { + setPage(0); + setRowsPerPage(Number(e.target.value)); + }; + + const pagedRows = rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage); + + return { + page, + rowsPerPage, + pagedRows, + paginationProps: { + component: "div" as const, + count: rows.length, + page, + rowsPerPage, + onPageChange: handlePageChange, + onRowsPerPageChange: handleRowsPerPageChange, + itemsOnPage: pagedRows.length, + }, + }; +}; diff --git a/client/src/Hooks/useStatusPageForm.ts b/client/src/Hooks/useStatusPageForm.ts index 0011ea761..2c1adf301 100644 --- a/client/src/Hooks/useStatusPageForm.ts +++ b/client/src/Hooks/useStatusPageForm.ts @@ -28,7 +28,7 @@ export const useStatusPageForm = ({ url: data?.url || generateDefaultUrl(), timezone: data?.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone, type: data?.type || ["uptime"], - color: data?.color || "#4169E1", + color: data?.color || "#13715B", monitors: data?.monitors || [], isPublished: data?.isPublished ?? false, showCharts: data?.showCharts ?? true, diff --git a/client/src/Pages/Account/TabTeam.tsx b/client/src/Pages/Account/TabTeam.tsx index 4eb2f8a97..ac82ab703 100644 --- a/client/src/Pages/Account/TabTeam.tsx +++ b/client/src/Pages/Account/TabTeam.tsx @@ -1,15 +1,18 @@ import { Stack } from "@mui/material"; import { useTheme } from "@mui/material"; import { useState, useMemo } from "react"; +import { useTranslation } from "react-i18next"; import { HeaderTeamControls } from "./components/HeaderTeamControls"; import { TeamTable } from "./components/TeamTable"; import { InviteTeamMemberDialog } from "./components/InviteTeamMemberDialog"; import { AddTeamMemberDialog } from "./components/AddTeamMemberDialog"; +import { EmptyState } from "@/Components/design-elements"; import { useGet } from "@/Hooks/UseApi"; import type { User, UserRole } from "@/Types/User"; export const TabTeam = () => { const theme = useTheme(); + const { t } = useTranslation(); const [filter, setFilter] = useState(""); const [inviteDialogOpen, setInviteDialogOpen] = useState(false); const [addMemberDialogOpen, setAddMemberDialogOpen] = useState(false); @@ -33,6 +36,9 @@ export const TabTeam = () => { refetch(); }; + const totalUsers = users?.length ?? 0; + const noUsers = users !== undefined && totalUsers === 0; + return ( { onInviteClick={handleOpenInviteDialog} onAddMemberClick={handleOpenAddMemberDialog} /> - + {noUsers ? ( + + ) : ( + + )} { const { t } = useTranslation(); const navigate = useNavigate(); const isAdmin = useIsAdmin(); + const { pagedRows, paginationProps } = useClientPagination(users); const headers: Header[] = [ { @@ -51,10 +54,13 @@ export const TeamTable = ({ users }: TeamTableProps) => { }; return ( - + <> +
+ {users.length > 0 && } + ); }; diff --git a/client/src/Pages/Account/index.tsx b/client/src/Pages/Account/index.tsx index fbe8db64b..ac05cd519 100644 --- a/client/src/Pages/Account/index.tsx +++ b/client/src/Pages/Account/index.tsx @@ -25,7 +25,7 @@ const Account = ({ open = "profile" }: AccountProps) => { }, [open]); return ( - + setActiveTab(newValue)} diff --git a/client/src/Pages/Auth/Register/index.tsx b/client/src/Pages/Auth/Register/index.tsx index 71603058f..92c712bda 100644 --- a/client/src/Pages/Auth/Register/index.tsx +++ b/client/src/Pages/Auth/Register/index.tsx @@ -95,7 +95,23 @@ const RegisterPage = () => { title={t("pages.auth.register.title")} subtitle={t("pages.auth.register.subtitle")} > - {!token && {t("pages.auth.register.setupNotice")}} + {!token && ( + ({ + fontSize: 13, + lineHeight: 1.55, + color: theme.palette.text.secondary, + backgroundColor: theme.palette.action.hover, + border: `1px solid ${theme.palette.divider}`, + borderRadius: 1, + "& .MuiAlert-message": { padding: 0 }, + })} + > + {t("pages.auth.register.setupNotice")} + + )} { const downChecks = summaryResponse?.downChecks || 0; const upChecks = totalChecks - (summaryResponse?.downChecks || 0); + const noMonitors = !isLoadingMonitors && (monitorsResponse?.length ?? 0) === 0; + if (noMonitors) { + return ( + + ); + } + return ( - + { refetchSummary(); }; + const trulyEmpty = summaryData !== undefined && (summaryData?.total ?? 0) === 0; + + if (trulyEmpty) { + return ( + + ); + } + return ( - + { setSelectedResolutionType={setFilter} onClearFilters={handleClearFilters} /> - {activeIncidentsCount > 0 ? ( + {activeIncidentsCount > 0 && ( <> { /> - ) : ( - - {t("pages.incidents.summaryCard.activeIncidents.active_zero")} - )} { return [ - { - id: 1, - label: t("pages.common.monitors.actions.openSite"), - action: () => { - window.open(monitor.url, "_blank", "noreferrer"); - }, - closeMenu: true, - }, { id: 2, label: t("pages.common.monitors.actions.details"), diff --git a/client/src/Pages/Infrastructure/Monitors/index.tsx b/client/src/Pages/Infrastructure/Monitors/index.tsx index bdf477613..ff63ee51e 100644 --- a/client/src/Pages/Infrastructure/Monitors/index.tsx +++ b/client/src/Pages/Infrastructure/Monitors/index.tsx @@ -122,6 +122,7 @@ const InfrastructureMonitors = () => { return ( { const theme = useTheme(); + const { t } = useTranslation(); const { data: diagnostics, isLoading: _isLoading, @@ -16,9 +19,35 @@ export const TabDiagnostics = () => { } = useGet("/diagnostic/system", {}, { refreshInterval: 5000 }); return ( - - - + + + + + {t("pages.logs.diagnostics.sections.runtimeStats.title")} + + + {t("pages.logs.diagnostics.sections.runtimeStats.description")} + + + + + + + + {t("pages.logs.diagnostics.sections.memoryCpu.title")} + + + {t("pages.logs.diagnostics.sections.memoryCpu.description")} + + + + ); }; diff --git a/client/src/Pages/Logs/TabLogs.tsx b/client/src/Pages/Logs/TabLogs.tsx index a05726b42..4bf59e149 100644 --- a/client/src/Pages/Logs/TabLogs.tsx +++ b/client/src/Pages/Logs/TabLogs.tsx @@ -4,6 +4,7 @@ import Typography from "@mui/material/Typography"; import { useSelector } from "react-redux"; import { Select } from "@/Components/inputs"; import { TableLogs } from "@/Pages/Logs/components/TableLogs"; +import { EmptyState } from "@/Components/design-elements"; import { useTheme } from "@mui/material"; import { useGet } from "@/Hooks/UseApi"; @@ -15,7 +16,7 @@ import type { RootState } from "@/Types/state"; export const TabLogs = () => { const theme = useTheme(); - const { data: logs } = useGet("/logs"); + const { data: logs, isLoading } = useGet("/logs"); const [selectedLogLevel, setSelectedLogLevel] = useState("all"); const [page, setPage] = useState(0); const rowsPerPage = useSelector( @@ -33,6 +34,16 @@ export const TabLogs = () => { const paginatedLogs = filteredLogs?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) ?? []; + if (!isLoading && (logs?.length ?? 0) === 0) { + return ( + + ); + } + return (
({ ...(row.lockedAt && { - "& td": { backgroundColor: theme.palette.success.light }, + "& td": { backgroundColor: runningBg }, }), })} /> @@ -106,6 +121,7 @@ interface TableFailedJobsProps { } export const TableFailedJobs = ({ metrics }: TableFailedJobsProps) => { const { t } = useTranslation(); + const theme = useTheme(); if (!metrics) { return null; } @@ -122,7 +138,11 @@ export const TableFailedJobs = ({ metrics }: TableFailedJobsProps) => { id: "monitorId", content: t("common.table.headers.monitorId"), render: (row) => { - return {row.monitorId}; + return ( + + {row.monitorId} + + ); }, }, { diff --git a/client/src/Pages/Logs/components/TableLogs.tsx b/client/src/Pages/Logs/components/TableLogs.tsx index 144d6056c..1244a65aa 100644 --- a/client/src/Pages/Logs/components/TableLogs.tsx +++ b/client/src/Pages/Logs/components/TableLogs.tsx @@ -45,6 +45,7 @@ const LevelBadge = ({ level }: { level: LogLevel }) => { export const TableLogs = ({ logs, logCount, page, setPage }: TableLogsProps) => { const { t } = useTranslation(); + const theme = useTheme(); const dispatch = useDispatch(); const rowsPerPage = useSelector( (state: RootState) => state?.ui?.logs?.rowsPerPage ?? 15 @@ -55,7 +56,7 @@ export const TableLogs = ({ logs, logCount, page, setPage }: TableLogsProps) => id: "timestamp", content: t("pages.logs.table.headers.timestamp"), render: (row) => ( - + {formatTimestamp(row.timestamp)} ), @@ -74,7 +75,9 @@ export const TableLogs = ({ logs, logCount, page, setPage }: TableLogsProps) => id: "method", content: t("pages.logs.table.headers.method"), render: (row) => ( - {row.method || "-"} + + {row.method || "-"} + ), }, { diff --git a/client/src/Pages/Logs/index.tsx b/client/src/Pages/Logs/index.tsx index 467e2f3a7..9d71e3253 100644 --- a/client/src/Pages/Logs/index.tsx +++ b/client/src/Pages/Logs/index.tsx @@ -10,7 +10,7 @@ const LogsPage = () => { const { t } = useTranslation(); const [activeTab, setActiveTab] = useState(1); return ( - + setActiveTab(newValue)} diff --git a/client/src/Pages/Maintenance/index.tsx b/client/src/Pages/Maintenance/index.tsx index 6a9c6f12b..abdfb4392 100644 --- a/client/src/Pages/Maintenance/index.tsx +++ b/client/src/Pages/Maintenance/index.tsx @@ -32,11 +32,10 @@ const MaintenanceWindowPage = () => { return ( { return [ @@ -68,7 +72,23 @@ export const NotificationsTable = ({ id: "destination", content: t("pages.notifications.table.headers.destination"), render: (row) => { - return {row?.address}; + return ( + + + {row?.address} + + + ); }, }, { @@ -82,15 +102,16 @@ export const NotificationsTable = ({ return headers; }; - const headers = getHeaders(); - return ( -
{ - navigate(`/notifications/configure/${row.id}`); - }} - /> + <> +
{ + navigate(`/notifications/configure/${row.id}`); + }} + /> + {notifications.length > 0 && } + ); }; diff --git a/client/src/Pages/Notifications/index.tsx b/client/src/Pages/Notifications/index.tsx index 1e4091461..3287cf0d3 100644 --- a/client/src/Pages/Notifications/index.tsx +++ b/client/src/Pages/Notifications/index.tsx @@ -39,10 +39,9 @@ const NotificationsPage = () => { return ( { return ( { return ( @@ -326,7 +328,7 @@ export const SettingsPage = () => { key={lang} value={lang} > - {lang.toUpperCase()} + {languageNames[lang] ?? lang} ))} @@ -578,11 +580,11 @@ export const SettingsPage = () => { @@ -974,19 +976,13 @@ export const SettingsPage = () => { loading={isDeletingAllMonitors} /> - {/* Sticky Save Button */} diff --git a/client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable.tsx b/client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable.tsx index 8f72931d6..9c9938c04 100644 --- a/client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable.tsx +++ b/client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable.tsx @@ -2,7 +2,9 @@ import Box from "@mui/material/Box"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; import { Table, type Header, ValueLabel } from "@/Components/design-elements"; +import { Pagination } from "@/Components/design-elements/Table"; import { ActionsMenu, type ActionMenuItem } from "@/Components/actions-menu"; +import { useClientPagination } from "@/Hooks/useClientPagination"; import { ExternalLink } from "lucide-react"; import { useTranslation } from "react-i18next"; @@ -23,6 +25,7 @@ export const StatusPagesTable = ({ const { t } = useTranslation(); const theme = useTheme(); const navigate = useNavigate(); + const { pagedRows, paginationProps } = useClientPagination(data); const getActions = (row: StatusPage): ActionMenuItem[] => { return [ @@ -133,10 +136,11 @@ export const StatusPagesTable = ({
+ {data.length > 0 && } ); }; diff --git a/client/src/Pages/StatusPage/StatusPages/index.tsx b/client/src/Pages/StatusPage/StatusPages/index.tsx index 9468b7e12..d5ae42766 100644 --- a/client/src/Pages/StatusPage/StatusPages/index.tsx +++ b/client/src/Pages/StatusPage/StatusPages/index.tsx @@ -37,11 +37,10 @@ const StatusPages = () => { return ( { + if (monitor.type !== "http" && monitor.type !== "pagespeed") return false; + return /^https?:\/\//i.test(monitor.url ?? ""); + }; + const getActions = (monitor: Monitor): ActionMenuItem[] => { - return [ - { + const actions: ActionMenuItem[] = []; + if (isBrowserOpenable(monitor)) { + actions.push({ id: 1, label: t("pages.common.monitors.actions.openSite"), action: () => { window.open(monitor.url, "_blank", "noreferrer"); }, closeMenu: true, - }, + }); + } + actions.push( { id: 2, label: t("pages.common.monitors.actions.details"), @@ -130,8 +138,9 @@ export const MonitorTable = ({ ), action: () => setSelectedMonitor(monitor), closeMenu: true, - }, - ]; + } + ); + return actions; }; const getHeaders = (chartType: string) => { diff --git a/client/src/Pages/Uptime/Monitors/index.tsx b/client/src/Pages/Uptime/Monitors/index.tsx index 792e0fd78..bfe244746 100644 --- a/client/src/Pages/Uptime/Monitors/index.tsx +++ b/client/src/Pages/Uptime/Monitors/index.tsx @@ -140,6 +140,7 @@ const UptimeMonitorsPage = () => { return ( mid (warning) // 300–600ms: interpolate mid (warning) -> end (error) // >600ms: solid end (error) + // MUI default success/warning/error.main values, used only when the caller + // fails to pass theme colors (defensive — keeps the gradient meaningful). const safe = { ...colors }; - if (!safe.start) safe.start = "#4caf50"; // fallback green - if (!safe.mid) safe.mid = "#ff9800"; // fallback orange - if (!safe.end) safe.end = "#f44336"; // fallback red + if (!safe.start) safe.start = "#4caf50"; + if (!safe.mid) safe.mid = "#ff9800"; + if (!safe.end) safe.end = "#f44336"; const toHex = (c: number) => c.toString(16).padStart(2, "0"); const clamp = (n: number) => Math.min(255, Math.max(0, Math.round(n))); diff --git a/client/src/Utils/Theme/Palette.ts b/client/src/Utils/Theme/Palette.ts index 9c19f0cbf..0fe08583a 100644 --- a/client/src/Utils/Theme/Palette.ts +++ b/client/src/Utils/Theme/Palette.ts @@ -14,21 +14,25 @@ export const colors = { gray700: "#313131", gray900: "#151518", gray850: "#1c1c21", - blueBlueWave: "#1570EF", + brandGreen: "#13715B", + brandGreenLight: "#4DAF94", }; export const lightPalette = { primary: { - main: colors.blueBlueWave, + main: colors.brandGreen, }, secondary: { main: colors.gray200, }, + sidebar: { + accent: colors.brandGreen, + }, }; export const darkPalette = { primary: { - main: colors.blueBlueWave, + main: colors.brandGreen, }, secondary: { main: colors.gray700, @@ -37,4 +41,7 @@ export const darkPalette = { default: colors.gray900, paper: colors.gray850, }, + sidebar: { + accent: colors.brandGreenLight, + }, }; diff --git a/client/src/Utils/Theme/Theme.ts b/client/src/Utils/Theme/Theme.ts index 49c1636ec..19f864c6f 100644 --- a/client/src/Utils/Theme/Theme.ts +++ b/client/src/Utils/Theme/Theme.ts @@ -2,12 +2,38 @@ import { createTheme } from "@mui/material"; import { lightPalette, darkPalette, typographyLevels } from "@/Utils/Theme/Palette"; import type { Theme } from "@mui/material/styles"; +import type {} from "@mui/material/styles"; + +declare module "@mui/material/styles" { + interface TypographyVariants { + eyebrow: React.CSSProperties; + fontFamilyMonospace: string; + } + interface TypographyVariantsOptions { + eyebrow?: React.CSSProperties; + fontFamilyMonospace?: string; + } + interface Palette { + sidebar: { accent: string }; + } + interface PaletteOptions { + sidebar?: { accent: string }; + } +} + +declare module "@mui/material/Typography" { + interface TypographyPropsVariantOverrides { + eyebrow: true; + } +} export type PaletteKey = { [K in keyof Theme["palette"]]: Theme["palette"][K] extends { main: any } ? K : never; }[keyof Theme["palette"]]; const fontFamilyPrimary = "system-ui, sans-serif"; +const fontFamilyMonospace = + 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace'; const shadow = "0px 4px 24px -4px rgba(16, 24, 40, 0.08), 0px 3px 3px -3px rgba(16, 24, 40, 0.03)"; @@ -29,6 +55,7 @@ export const theme = (mode: string, palette: any) => }, typography: { fontFamily: fontFamilyPrimary, + fontFamilyMonospace, fontSize: typographyLevels.base, h1: { fontSize: typographyLevels.xl, @@ -46,6 +73,13 @@ export const theme = (mode: string, palette: any) => fontSize: typographyLevels.s, fontWeight: 400, }, + eyebrow: { + fontSize: 13, + fontWeight: 500, + textTransform: "uppercase", + letterSpacing: "0.08em", + lineHeight: 1.4, + }, }, components: { @@ -120,11 +154,17 @@ export const theme = (mode: string, palette: any) => MuiOutlinedInput: { styleOverrides: { - root: { + root: ({ theme }) => ({ + "&:hover .MuiOutlinedInput-notchedOutline": { + borderColor: + theme.palette.mode === "dark" + ? "rgba(255, 255, 255, 0.23)" + : theme.palette.text.primary, + }, "&.Mui-focused .MuiOutlinedInput-notchedOutline": { borderColor: palette.primary.main, }, - }, + }), }, }, @@ -145,6 +185,113 @@ export const theme = (mode: string, palette: any) => }, }, }, + + MuiSwitch: { + defaultProps: { disableRipple: true }, + styleOverrides: { + root: { + width: 36, + height: 20, + padding: "0 6px 0 0", + boxSizing: "content-box", + overflow: "visible", + }, + switchBase: ({ theme }) => ({ + padding: 2, + "&.Mui-checked": { + transform: "translateX(16px)", + color: "#fff", + "& + .MuiSwitch-track": { + backgroundColor: theme.palette.primary.main, + opacity: 1, + border: 0, + }, + }, + }), + thumb: { + width: 16, + height: 16, + boxShadow: "0 1px 2px rgba(16, 24, 40, 0.1)", + }, + track: ({ theme }) => ({ + borderRadius: 999, + backgroundColor: + theme.palette.mode === "dark" + ? "rgba(255,255,255,0.16)" + : theme.palette.action.disabledBackground, + opacity: 1, + }), + }, + }, + + MuiRadio: { + defaultProps: { disableRipple: true }, + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(2), + color: theme.palette.divider, + "& .MuiSvgIcon-root": { + fontSize: 20, + transition: "none", + }, + "&.Mui-checked": { + color: theme.palette.primary.main, + }, + "&.Mui-checked .MuiSvgIcon-root:last-of-type": { + transform: "scale(0.6)", + }, + }), + }, + }, + + MuiSlider: { + styleOverrides: { + root: ({ theme }) => ({ + height: 4, + padding: "13px 0", + color: theme.palette.primary.main, + }), + rail: ({ theme }) => ({ + height: 4, + borderRadius: 999, + opacity: 1, + backgroundColor: + theme.palette.mode === "dark" + ? "rgba(255,255,255,0.16)" + : theme.palette.action.disabledBackground, + }), + track: { + height: 4, + borderRadius: 999, + border: "none", + }, + thumb: ({ theme }) => ({ + width: 18, + height: 18, + backgroundColor: theme.palette.background.paper, + border: `2px solid ${theme.palette.primary.main}`, + boxShadow: "0 1px 2px rgba(16, 24, 40, 0.1)", + "&:hover, &.Mui-focusVisible": { + boxShadow: `0 0 0 6px ${theme.palette.primary.main}1f`, + }, + "&.Mui-active": { + boxShadow: `0 0 0 8px ${theme.palette.primary.main}29`, + }, + "&::before": { display: "none" }, + }), + mark: ({ theme }) => ({ + width: 2, + height: 2, + borderRadius: 999, + backgroundColor: theme.palette.text.disabled, + opacity: 0.5, + }), + markActive: ({ theme }) => ({ + backgroundColor: theme.palette.primary.main, + opacity: 0.5, + }), + }, + }, }, shape: { borderRadius: 2, diff --git a/client/src/assets/icons/checkmate-icon.svg b/client/src/assets/icons/checkmate-icon.svg index e0e6bf6f4..e1701573a 100644 --- a/client/src/assets/icons/checkmate-icon.svg +++ b/client/src/assets/icons/checkmate-icon.svg @@ -1,49 +1,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Checkmate + King silhouette adapted from Cburnett's chess set (Wikimedia Commons, CC BY-SA 3.0). + + + + + + diff --git a/client/src/locales/ar.json b/client/src/locales/ar.json index 28624c469..1b70f7fa8 100644 --- a/client/src/locales/ar.json +++ b/client/src/locales/ar.json @@ -13,7 +13,7 @@ "content": "تحذير: لم تقم بإضافة مفتاح Google PageSpeed API بعد. قم بزيارة الإعدادات لإضافته. بدونه، لن تعمل مراقبة PageSpeed." } }, - "appName": "", + "appName": "Checkmate", "breadcrumbs": { "details": "التفاصيل", "home": "الرئيسية" @@ -35,11 +35,11 @@ "sendInvite": "إرسال دعوة", "test": "اختبار", "testNotifications": "اختبار الإشعارات", - "toggleTheme": "", + "toggleTheme": "تبديل الوضع الفاتح والداكن", "flushQueue": "تفريغ قائمة الانتظار", "notFound": "الانتقال إلى لوحة التحكم الرئيسية", - "resetPassword": "", - "reset": "", + "resetPassword": "إعادة تعيين كلمة المرور", + "reset": "إعادة تعيين", "clear": "مسح", "addDemo": "إضافة مراقبات تجريبية", "removeMonitors": "إزالة المراقبات", @@ -53,8 +53,8 @@ "labels": { "averageResponseTime": "متوسط وقت الاستجابة", "downtime": "وقت التوقف", - "high": "", - "low": "", + "high": "مرتفع", + "low": "منخفض", "uptime": "وقت التشغيل" }, "histogram": { @@ -86,12 +86,12 @@ "name": { "option": { "firstName": { - "label": "", - "placeholder": "" + "label": "الاسم الأول", + "placeholder": "أدخل اسمك الأول" }, "lastName": { - "label": "", - "placeholder": "" + "label": "اسم العائلة", + "placeholder": "أدخل اسم عائلتك" } } }, @@ -107,14 +107,14 @@ "table": { "empty": "لا يوجد شيء هنا", "headers": { - "actions": "", + "actions": "إجراءات", "dateTime": "التاريخ والوقت", "message": "الرسالة", "monitor": "المراقب", "monitorId": "معرّف المراقب", "name": "الاسم", "status": "الحالة", - "type": "", + "type": "النوع", "url": "الرابط", "interval": "الفاصل الزمني", "active": "نشط", @@ -125,17 +125,17 @@ "components": { "imageUpload": { "clickToUpload": "انقر للرفع", - "dragAndDrop": "", - "supportedFormats": "", - "maxSize": "", + "dragAndDrop": "أو اسحب وأسقط", + "supportedFormats": "الصيغ المدعومة", + "maxSize": "الحجم الأقصى", "orDragAndDrop": "أو اسحب وأفلت", "errors": { - "invalidFileSize": "", - "invalidFileFormat": "" + "invalidFileSize": "حجم الملف كبير جدًا!", + "invalidFileFormat": "تنسيق الملف غير مدعوم!" } }, "headerStatusPageControls": { - "publicLink": "" + "publicLink": "رابط عام" }, "headerTimeRange": { "labels": { @@ -155,26 +155,26 @@ "serverUnreachable": "تعذر الوصول إلى الخادم", "retry": "إعادة المحاولة", "retrying": "جارٍ إعادة المحاولة...", - "reconnected": "" + "reconnected": "تمت استعادة الاتصال" }, "sidebar": { "menu": { - "uptime": "", - "pagespeed": "", - "infrastructure": "", - "notifications": "", + "uptime": "وقت التشغيل", + "pagespeed": "Pagespeed", + "infrastructure": "البنية التحتية", + "notifications": "الإشعارات", "checks": "الفحوصات", - "incidents": "", - "statusPages": "", - "maintenance": "", - "logs": "", - "settings": "" + "incidents": "الحوادث", + "statusPages": "صفحات الحالة", + "maintenance": "الصيانة", + "logs": "السجلات", + "settings": "الإعدادات" }, "bottomMenu": { - "support": "", - "discussions": "", - "docs": "", - "changelog": "" + "support": "الدعم", + "discussions": "المناقشات", + "docs": "الوثائق", + "changelog": "سجل التغييرات" }, "accountMenu": { "profile": "الملف الشخصي", @@ -186,19 +186,27 @@ "description": "اطلع على أحدث الإصدارات وساعد في تنمية المجتمع على GitHub" }, "authFooter": { - "navControls": "", - "logOut": "", + "navControls": "عناصر التحكم", + "logOut": "تسجيل الخروج", "roles": { "superAdmin": "مسؤول أعلى", "admin": "مسؤول", "user": "مستخدم", - "demoUser": "" + "demoUser": "مستخدم تجريبي" } } }, "starPrompt": { "title": "أضف نجمة لـ Checkmate", "description": "اطلع على أحدث الإصدارات وساعد في تنمية المجتمع على GitHub" + }, + "pageHeader": { + "links": { + "support": "الدعم", + "discussions": "المناقشات", + "docs": "التوثيق", + "changelog": "سجل التغييرات" + } } }, "pages": { @@ -251,15 +259,15 @@ "team": { "filter": { "placeholder": "تصفية حسب الدور", - "all": "", + "all": "كل الأدوار", "admin": "مسؤول", - "member": "" + "member": "عضو" }, "table": { "headers": { "email": "البريد الإلكتروني", "role": "الدور", - "created": "" + "created": "تم الإنشاء في" } }, "addMember": { @@ -278,10 +286,23 @@ "placeholder": "اختر دوراً" }, "linkLabel": "رابط الدعوة" + }, + "fallback": { + "title": "لا يوجد بعد أعضاء فريق", + "description": "ادعُ زملاءك عبر البريد الإلكتروني أو أضفهم مباشرة. بمجرد انضمامهم، سيظهرون هنا مع دورهم." } + }, + "header": { + "title": "الحساب", + "description": "إدارة ملفك الشخصي وكلمة المرور والفريق وتفضيلات مساحة العمل." } }, "auth": { + "brandPanel": { + "eyebrow": "المراقبة المفتوحة المصدر للبنية التحتية", + "tagline": "راقب كل خطوة تقوم بها خوادمك.", + "description": "تتبع حالة التشغيل وأوقات الاستجابة والحوادث في الوقت الفعلي - ذاتية الاستضافة وتبقى لك." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "مرحباً بعودتك إلى Checkmate!", "subtitle": "سجّل للبدء", - "submit": "تسجيل" + "submit": "تسجيل", + "setupNotice": "هذه الصفحة متاحة فقط أثناء الإعداد الأولي. بمجرد تسجيل المسؤول الأعلى، يمكن دعوة مستخدمين إضافيين من إعدادات الفريق." }, "forgotPassword": { "title": "نسيت كلمة المرور؟", @@ -378,6 +400,14 @@ "statusCode": "رمز الحالة", "location": "الموقع" } + }, + "fallback": { + "title": "لا توجد فحوصات بعد", + "description": "بمجرد إنشاء جهاز مراقبة، ستظهر هنا كل عملية فحص حالة ووقت استجابة كفحص." + }, + "header": { + "title": "الفحوصات", + "description": "كل فحص يجريه Checkmate على مراقبيك يظهر هنا برمز الحالة ووقت الاستجابة." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "نشط منذ", "certificateExpiry": "انتهاء الشهادة", "lastCheck": "آخر فحص", - "lastResponseTime": "آخر وقت استجابة" + "lastResponseTime": "آخر وقت استجابة", + "serviceIsDown": "الخدمة معطلة" }, "status": { "down": "متوقف", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "لا حوادث — جميع الأنظمة سليمة", + "description": "عندما يتعطل جهاز مراقبة أو يتعافى، سيظهر الحادث هنا مع الأوقات وتفاصيل الجهاز وسجل الحل." + }, "dialog": { "resolveIncident": { "title": "حل الحادثة", @@ -720,6 +755,10 @@ "active": "نشط", "resolved": "تم الحل" } + }, + "header": { + "title": "الحوادث", + "description": "عندما يتعطل جهاز مراقبة أو يتعافى، تظهر الحوادث هنا مع الأوقات وتفاصيل الجهاز وسجل الحل." } }, "infrastructure": { @@ -774,21 +813,31 @@ }, "fallback": { "actionButton": "أنشئ مراقباً!", - "checks": "تتبع أداء خوادمك,تحديد الاختناقات وتحسين الاستخدام,ضمان الموثوقية من خلال المراقبة في الوقت الفعلي", - "title": "يُستخدم مراقب البنية التحتية من أجل:" + "title": "لا توجد بعد أجهزة مراقبة للبنية التحتية", + "description": "تتبّع أداء الخوادم وحدد الاختناقات واضمن الموثوقية مع مراقبة البنية التحتية في الوقت الفعلي." + }, + "header": { + "title": "مراقبات البنية التحتية", + "description": "تتبّع أداء الخوادم وحدد الاختناقات واضمن الموثوقية مع مراقبة البنية التحتية في الوقت الفعلي." } }, "logs": { + "fallback": { + "title": "لا توجد سجلات بعد", + "description": "ستظهر هنا نشاط الخادم والتحذيرات والأخطاء أثناء تشغيل Checkmate." + }, "tabs": { - "diagnostics": "", - "logs": "", - "queue": "" + "diagnostics": "التشخيص", + "logs": "السجلات", + "queue": "قائمة المهام" }, "logLevelSelect": { "label": "مستوى السجل" }, "jobQueue": "قائمة المهام", + "jobQueueExplainer": "الصفوف المميزة هي المهام التي تتم معالجتها حالياً بواسطة عامل.", "failedJobs": "المهام الفاشلة", + "failedJobsExplainer": "حالات الفشل الأخيرة حسب المراقب — وقت آخر فشل، وعدد مرات الفشل، والسبب.", "noLogs": "لم يتم العثور على سجلات", "metrics": { "jobs": "المهام", @@ -815,6 +864,16 @@ "usedSPercentage": "% من 1 ثانية مستخدمة بواسطة CPU", "total": "الإجمالي", "used": "مستخدم" + }, + "sections": { + "runtimeStats": { + "title": "إحصائيات التشغيل", + "description": "لقطة لعملية Node.js والجهاز المضيف. يتم التحديث كل 5 ثوانٍ." + }, + "memoryCpu": { + "title": "الذاكرة والمعالج", + "description": "كيف تستخدم العملية الذاكرة المخصصة لها ومعالج الجهاز المضيف." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "آخر فشل في", "failReason": "سبب الفشل" } + }, + "queueFallback": { + "title": "لا توجد مهام في قائمة الانتظار", + "description": "ستظهر هنا فحوصات أجهزة المراقبة المجدولة أو قيد التشغيل. قائمة الانتظار الفارغة تعني أن كل شيء محدّث." + }, + "header": { + "title": "السجلات وقائمة الانتظار", + "description": "افحص سجلات الخادم وقائمة انتظار مهام المراقبة وتشخيصات وقت التشغيل في مكان واحد." } }, "maintenanceWindow": { "fallback": { "actionButton": "أنشئ نافذة صيانة!", - "checks": "تحديد فترات الصيانة,التخلص من أي سوء فهم,إيقاف إرسال التنبيهات أثناء نوافذ الصيانة", - "title": "تُستخدم نافذة الصيانة من أجل:" + "title": "لا توجد نوافذ صيانة مجدولة", + "description": "حدد مواعيد التوقف المخطط لها لإيقاف التنبيهات وإعلام فريقك ومستخدميك بما يتوقعونه." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "نوافذ الصيانة", + "description": "حدد مواعيد التوقف المخطط لها لإيقاف التنبيهات وإعلام فريقك ومستخدميك بما يتوقعونه." } }, "notifications": { "fallback": { "actionButton": "إنشاء قناة", - "checks": "تنبيه الفرق حول التوقف أو مشكلات الأداء,إعلام المهندسين عند حدوث الحوادث,إبقاء المسؤولين على اطلاع بتغييرات النظام", - "title": "تُستخدم قنوات الإشعارات من أجل:" + "title": "لا توجد بعد قنوات إشعار", + "description": "اربط Slack وDiscord والبريد الإلكتروني وWebhooks والمزيد ليعلم الأشخاص المناسبون بالحوادث فور حدوثها." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "معرّف المحادثة", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "إعدادات Pushover", + "description": "أدخل رمز التطبيق ومفتاح المستخدم في Pushover.", + "optionAppToken": "رمز التطبيق", + "placeholderAppToken": "أدخل رمز التطبيق", + "optionUserKey": "مفتاح المستخدم", + "placeholderUserKey": "أدخل مفتاح المستخدم" + }, + "twilio": { + "title": "إعدادات Twilio", + "description": "أدخل بيانات اعتماد حساب Twilio لإرسال الرسائل النصية.", + "optionAccountSid": "معرف الحساب (SID)", + "placeholderAccountSid": "أدخل معرف الحساب", + "optionAuthToken": "رمز المصادقة", + "placeholderAuthToken": "أدخل رمز المصادقة", + "optionFromNumber": "من الرقم", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "إلى الرقم", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "الوجهة" } + }, + "header": { + "title": "الإشعارات", + "description": "اربط Slack وDiscord والبريد الإلكتروني وWebhooks والمزيد ليعلم الأشخاص المناسبون بالحوادث فور حدوثها." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "أنشئ مراقباً!", - "checks": "تقديم تقرير عن تجربة المستخدم للصفحة,المساعدة في تحليل سرعة الصفحة,تقديم اقتراحات لتحسين الصفحة", - "title": "يُستخدم مراقب PageSpeed من أجل:" + "title": "لا توجد بعد أجهزة مراقبة PageSpeed", + "description": "تابع Core Web Vitals ودرجات Lighthouse عبر الزمن لاكتشاف التراجع قبل أن يلاحظه المستخدمون." + }, + "header": { + "title": "مراقبات PageSpeed", + "description": "تابع Core Web Vitals ودرجات Lighthouse عبر الزمن لاكتشاف التراجع قبل أن يلاحظه المستخدمون." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "يرجى إصلاح أخطاء التحقق التالية:" } + }, + "header": { + "title": "الإعدادات", + "description": "تكوين SMTP والتكاملات والاحتفاظ والسلوك العام للتطبيق." } }, "statusPages": { "deleteSuccess": "تم حذف صفحة الحالة بنجاح", "fallback": { - "title": "تُستخدم صفحة الحالة من أجل:", - "checks": "إيصال حالة النظام للمستخدمين وأصحاب المصلحة,عرض معلومات وقت التشغيل في الوقت الفعلي للعامة,بناء الثقة من خلال مراقبة الخدمة الشفافة,تقليل طلبات الدعم أثناء الحوادث", - "actionButton": "أنشئ صفحة حالة!" + "title": "لا توجد بعد صفحات حالة", + "actionButton": "أنشئ صفحة حالة!", + "description": "انشر صفحة عامة تُظهر للعملاء وأصحاب المصلحة وقت التشغيل الفعلي وتاريخ الحوادث." }, "monitorsList": { "chartTypeHeatmap": "خريطة حرارية", @@ -1190,7 +1293,18 @@ "allDown": "جميع الأنظمة متوقفة", "allUp": "جميع الأنظمة تعمل بشكل طبيعي", "degraded": "بعض الأنظمة تواجه مشكلات", - "unknown": "تعذر تحديد حالة النظام" + "unknown": "تعذر تحديد حالة النظام", + "allBreached": "تجاوزت جميع الأنظمة الحدود", + "allMaintenance": "جميع الأنظمة قيد الصيانة", + "allPaused": "جميع الأنظمة متوقفة مؤقتًا", + "allInitializing": "جميع الأنظمة قيد التهيئة", + "breachedAndDown": "تجاوزت بعض الأنظمة الحدود وهي معطلة", + "breached": "تجاوزت بعض الأنظمة الحدود", + "maintenanceAndDown": "بعض الأنظمة معطلة أثناء الصيانة", + "maintenance": "بعض الأنظمة قيد الصيانة", + "partiallyPaused": "بعض الأنظمة متوقفة مؤقتًا", + "initializing": "بعض الأنظمة قيد التهيئة", + "noMonitors": "لم يتم تكوين أي شاشة" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "صفحات الحالة", + "description": "انشر صفحات عامة تُظهر للعملاء وأصحاب المصلحة وقت التشغيل الفعلي وتاريخ الحوادث." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "أنشئ مراقباً!", - "checks": "التحقق مما إذا كانت المواقع أو الخوادم متصلة ومتجاوبة,تنبيه الفرق حول التوقف أو مشكلات الأداء,مراقبة نقاط نهاية HTTP والـ Ping والحاويات والمنافذ,تتبع اتجاهات وقت التشغيل والموثوقية التاريخية", - "title": "يُستخدم مراقب وقت التشغيل من أجل:" + "title": "لا توجد بعد أجهزة مراقبة وقت التشغيل", + "description": "راقب نقاط نهاية HTTP وعمليات Ping والحاويات والمنافذ — احصل على تنبيه فور حدوث عطل." + }, + "header": { + "title": "مراقبات وقت التشغيل", + "description": "راقب نقاط نهاية HTTP وعمليات Ping والحاويات والمنافذ — احصل على تنبيه فور حدوث عطل." } } } diff --git a/client/src/locales/cs.json b/client/src/locales/cs.json index 780a7a723..81d9cffe6 100644 --- a/client/src/locales/cs.json +++ b/client/src/locales/cs.json @@ -39,7 +39,7 @@ "flushQueue": "Vyprázdnit frontu", "notFound": "Přejít na hlavní přehled", "resetPassword": "Obnovit heslo", - "reset": "", + "reset": "Resetovat", "clear": "Vymazat", "addDemo": "Přidat ukázkové monitory", "removeMonitors": "Odebrat monitory", @@ -53,8 +53,8 @@ "labels": { "averageResponseTime": "Průměrná doba odezvy", "downtime": "Výpadek", - "high": "", - "low": "", + "high": "Vysoké", + "low": "Nízké", "uptime": "Dostupnost" }, "histogram": { @@ -107,14 +107,14 @@ "table": { "empty": "Zde nic není", "headers": { - "actions": "", + "actions": "Akce", "dateTime": "Datum a čas", "message": "Zpráva", "monitor": "Monitor", "monitorId": "ID monitoru", "name": "Název", "status": "Stav", - "type": "", + "type": "Typ", "url": "URL", "interval": "Interval", "active": "Aktivní", @@ -125,17 +125,17 @@ "components": { "imageUpload": { "clickToUpload": "Klikněte pro nahrání", - "dragAndDrop": "", - "supportedFormats": "", - "maxSize": "", + "dragAndDrop": "nebo přetáhněte", + "supportedFormats": "Podporované formáty", + "maxSize": "Max. velikost", "orDragAndDrop": "nebo přetáhněte soubor", "errors": { - "invalidFileSize": "", - "invalidFileFormat": "" + "invalidFileSize": "Soubor je příliš velký!", + "invalidFileFormat": "Nepodporovaný formát souboru!" } }, "headerStatusPageControls": { - "publicLink": "" + "publicLink": "Veřejný odkaz" }, "headerTimeRange": { "labels": { @@ -159,22 +159,22 @@ }, "sidebar": { "menu": { - "uptime": "", - "pagespeed": "", - "infrastructure": "", - "notifications": "", + "uptime": "Dostupnost", + "pagespeed": "Pagespeed", + "infrastructure": "Infrastruktura", + "notifications": "Oznámení", "checks": "Kontroly", - "incidents": "", - "statusPages": "", - "maintenance": "", - "logs": "", - "settings": "" + "incidents": "Incidenty", + "statusPages": "Stavové stránky", + "maintenance": "Údržba", + "logs": "Záznamy", + "settings": "Nastavení" }, "bottomMenu": { - "support": "", - "discussions": "", - "docs": "", - "changelog": "" + "support": "Podpora", + "discussions": "Diskuze", + "docs": "Dokumentace", + "changelog": "Záznam změn" }, "accountMenu": { "profile": "Profil", @@ -186,19 +186,27 @@ "description": "Sledujte nejnovější vydání a pomozte rozšířit komunitu na GitHubu" }, "authFooter": { - "navControls": "", - "logOut": "", + "navControls": "Ovládací prvky", + "logOut": "Odhlásit se", "roles": { "superAdmin": "Superadministrátor", "admin": "Administrátor", "user": "Uživatel", - "demoUser": "" + "demoUser": "Demo uživatel" } } }, "starPrompt": { "title": "Ohodnoťte Checkmate", "description": "Sledujte nejnovější vydání a pomozte rozšířit komunitu na GitHubu" + }, + "pageHeader": { + "links": { + "support": "Podpora", + "discussions": "Diskuze", + "docs": "Dokumentace", + "changelog": "Seznam změn" + } } }, "pages": { @@ -251,15 +259,15 @@ "team": { "filter": { "placeholder": "Filtrovat podle role", - "all": "", + "all": "Všechny role", "admin": "Administrátor", - "member": "" + "member": "Člen" }, "table": { "headers": { "email": "Email", "role": "Role", - "created": "" + "created": "Vytvořeno" } }, "addMember": { @@ -278,10 +286,23 @@ "placeholder": "Vyberte roli" }, "linkLabel": "Odkaz pro pozvánku" + }, + "fallback": { + "title": "Zatím žádní členové týmu", + "description": "Pozvěte kolegy e-mailem nebo je přidejte přímo. Jakmile se připojí, objeví se zde se svou rolí." } + }, + "header": { + "title": "Účet", + "description": "Spravujte profil, heslo, tým a předvolby pracovního prostoru." } }, "auth": { + "brandPanel": { + "eyebrow": "Open-source monitoring infrastruktury", + "tagline": "Sledujte každý krok vašich serverů.", + "description": "Monitorování dostupnosti, doby odezvy a incidentů v reálném čase - self-hosted a vaše." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Vítejte v Checkmate!", "subtitle": "Zaregistrujte se a začněte", - "submit": "Registrovat" + "submit": "Registrovat", + "setupNotice": "Tato stránka je k dispozici pouze během počátečního nastavení. Po zaregistrování super administrátora lze pozvat další uživatele z nastavení týmu." }, "forgotPassword": { "title": "Zapomněli jste heslo?", @@ -378,6 +400,14 @@ "statusCode": "Stavový kód", "location": "Umístění" } + }, + "fallback": { + "title": "Zatím žádné kontroly", + "description": "Jakmile vytvoříte monitor, každá kontrola stavu a doba odezvy se zde zobrazí jako kontrola." + }, + "header": { + "title": "Kontroly", + "description": "Každá sonda, kterou Checkmate spustí proti vašim monitorům, se zde objeví se stavovým kódem a dobou odezvy." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Aktivní po dobu", "certificateExpiry": "Expirace certifikátu", "lastCheck": "Poslední kontrola", - "lastResponseTime": "Poslední doba odezvy" + "lastResponseTime": "Poslední doba odezvy", + "serviceIsDown": "Služba je nedostupná" }, "status": { "down": "nedostupný", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Žádné incidenty — všechny systémy v pořádku", + "description": "Když monitor vypadne nebo se zotaví, incident se zobrazí zde spolu s časem, detaily monitoru a historií řešení." + }, "dialog": { "resolveIncident": { "title": "Vyřešit incident", @@ -720,6 +755,10 @@ "active": "Aktivní", "resolved": "Vyřešeno" } + }, + "header": { + "title": "Incidenty", + "description": "Když monitor vypadne nebo se zotaví, incidenty se zobrazí zde spolu s časem, detaily monitoru a historií řešení." } }, "infrastructure": { @@ -774,21 +813,31 @@ }, "fallback": { "actionButton": "Vytvořte monitor!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Monitor infrastruktury slouží k:" + "title": "Zatím žádné monitory infrastruktury", + "description": "Sledujte výkon serverů, identifikujte úzká místa a zajistěte spolehlivost pomocí monitoringu infrastruktury v reálném čase." + }, + "header": { + "title": "Monitory infrastruktury", + "description": "Sledujte výkon serverů, identifikujte úzká místa a zajistěte spolehlivost pomocí monitoringu infrastruktury v reálném čase." } }, "logs": { + "fallback": { + "title": "Zatím žádné protokoly", + "description": "Aktivita serveru, varování a chyby se zobrazí zde, jak Checkmate běží." + }, "tabs": { - "diagnostics": "", - "logs": "", - "queue": "" + "diagnostics": "Diagnostika", + "logs": "Záznamy", + "queue": "Fronta úloh" }, "logLevelSelect": { "label": "Úroveň logování" }, "jobQueue": "Fronta úloh", + "jobQueueExplainer": "Zvýrazněné řádky jsou úlohy, které právě zpracovává worker.", "failedJobs": "Neúspěšné úlohy", + "failedJobsExplainer": "Nedávná selhání podle monitoru — čas posledního selhání, počet selhání a důvod.", "noLogs": "Žádné logy nebyly nalezeny", "metrics": { "jobs": "Úlohy", @@ -815,6 +864,16 @@ "usedSPercentage": "% z 1s využito CPU", "total": "Celkem", "used": "Použité" + }, + "sections": { + "runtimeStats": { + "title": "Statistiky běhu", + "description": "Snímek procesu Node.js a hostitelského počítače. Aktualizuje se každých 5 sekund." + }, + "memoryCpu": { + "title": "Paměť a CPU", + "description": "Jak proces využívá přidělenou paměť a CPU hostitele." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Poslední selhání", "failReason": "Důvod selhání" } + }, + "queueFallback": { + "title": "Žádné úlohy ve frontě", + "description": "Naplánované nebo běžící kontroly monitorů se objeví zde. Prázdná fronta znamená, že je vše aktuální." + }, + "header": { + "title": "Protokoly a fronta", + "description": "Zkontrolujte serverové protokoly, frontu úloh monitoru a diagnostiku v jednom místě." } }, "maintenanceWindow": { "fallback": { "actionButton": "Vytvořte okno údržby!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Okno údržby slouží k:" + "title": "Žádná naplánovaná okna údržby", + "description": "Naplánujte plánované odstávky, aby byly výstrahy potlačeny a váš tým i uživatelé věděli, co očekávat." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Okna údržby", + "description": "Naplánujte plánované odstávky, aby byly výstrahy potlačeny a váš tým i uživatelé věděli, co očekávat." } }, "notifications": { "fallback": { "actionButton": "Vytvořit kanál", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Kanály oznámení slouží k:" + "title": "Zatím žádné notifikační kanály", + "description": "Připojte Slack, Discord, e-mail, webhooky a další, aby se ti správní lidé dozvěděli o incidentech v okamžiku, kdy nastanou." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "ID chatu", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Konfigurace Pushover", + "description": "Zadejte token aplikace a uživatelský klíč Pushover.", + "optionAppToken": "Token aplikace", + "placeholderAppToken": "Zadejte token aplikace", + "optionUserKey": "Uživatelský klíč", + "placeholderUserKey": "Zadejte uživatelský klíč" + }, + "twilio": { + "title": "Konfigurace Twilio", + "description": "Zadejte přihlašovací údaje účtu Twilio pro odesílání SMS.", + "optionAccountSid": "SID účtu", + "placeholderAccountSid": "Zadejte SID účtu", + "optionAuthToken": "Autentizační token", + "placeholderAuthToken": "Zadejte autentizační token", + "optionFromNumber": "Z čísla", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Na číslo", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Cíl" } + }, + "header": { + "title": "Notifikace", + "description": "Připojte Slack, Discord, e-mail, webhooky a další, aby se ti správní lidé dozvěděli o incidentech v okamžiku, kdy nastanou." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Vytvořte monitor!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "Monitor PageSpeed slouží k:" + "title": "Zatím žádné PageSpeed monitory", + "description": "Sledujte Core Web Vitals a skóre Lighthouse v čase a zachyťte regrese dříve než vaši uživatelé." + }, + "header": { + "title": "Monitory PageSpeed", + "description": "Sledujte Core Web Vitals a skóre Lighthouse v čase a zachyťte regrese dříve než vaši uživatelé." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Opravte prosím následující chyby validace:" } + }, + "header": { + "title": "Nastavení", + "description": "Nakonfigurujte SMTP, integrace, uchovávání a globální chování aplikace." } }, "statusPages": { "deleteSuccess": "Stavová stránka byla úspěšně smazána", "fallback": { - "title": "Stavová stránka slouží k:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "Vytvořte stavovou stránku!" + "title": "Zatím žádné stavové stránky", + "actionButton": "Vytvořte stavovou stránku!", + "description": "Publikujte veřejnou stránku, která zákazníkům a zúčastněným stranám zobrazuje dostupnost v reálném čase a historii incidentů." }, "monitorsList": { "chartTypeHeatmap": "Heatmapa", @@ -1190,7 +1293,18 @@ "allDown": "Všechny systémy jsou nedostupné", "allUp": "Všechny systémy fungují", "degraded": "Některé systémy mají problémy", - "unknown": "Nelze určit stav systému" + "unknown": "Nelze určit stav systému", + "allBreached": "Všechny systémy překročily prahové hodnoty", + "allMaintenance": "Všechny systémy jsou v údržbě", + "allPaused": "Všechny systémy jsou pozastavené", + "allInitializing": "Všechny systémy se inicializují", + "breachedAndDown": "Některé systémy překročily prahové hodnoty a jsou nedostupné", + "breached": "Některé systémy překročily prahové hodnoty", + "maintenanceAndDown": "Některé systémy jsou nedostupné během údržby", + "maintenance": "Některé systémy jsou v údržbě", + "partiallyPaused": "Některé systémy jsou pozastavené", + "initializing": "Některé systémy se inicializují", + "noMonitors": "Nebyly nakonfigurovány žádné monitory" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Stavové stránky", + "description": "Publikujte veřejné stránky, které zákazníkům a zúčastněným stranám zobrazují dostupnost v reálném čase a historii incidentů." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Vytvořte monitor!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Monitor dostupnosti slouží k:" + "title": "Zatím žádné monitory dostupnosti", + "description": "Sledujte HTTP koncové body, pingy, kontejnery a porty — buďte upozorněni v okamžiku, kdy něco vypadne." + }, + "header": { + "title": "Monitory dostupnosti", + "description": "Sledujte HTTP koncové body, pingy, kontejnery a porty — buďte upozorněni v okamžiku, kdy něco vypadne." } } } diff --git a/client/src/locales/de.json b/client/src/locales/de.json index 34755aaba..6fb1f6a4f 100644 --- a/client/src/locales/de.json +++ b/client/src/locales/de.json @@ -199,6 +199,14 @@ "starPrompt": { "title": "Checkmate bewerten", "description": "Entdecken Sie die neuesten Versionen und helfen Sie der Community auf GitHub" + }, + "pageHeader": { + "links": { + "support": "Support", + "discussions": "Diskussionen", + "docs": "Dokumentation", + "changelog": "Änderungsverlauf" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "Rolle auswählen" }, "linkLabel": "Einladungslink" + }, + "fallback": { + "title": "Noch keine Teammitglieder", + "description": "Laden Sie Teammitglieder per E-Mail ein oder fügen Sie sie direkt hinzu. Sobald sie beitreten, erscheinen sie hier mit ihrer Rolle." } + }, + "header": { + "title": "Konto", + "description": "Verwalten Sie Profil, Passwort, Team und Workspace-Einstellungen." } }, "auth": { + "brandPanel": { + "eyebrow": "Open-Source-Infrastruktur-Monitoring", + "tagline": "Beobachten Sie jeden Zug Ihrer Server.", + "description": "Echtzeit-Überwachung von Verfügbarkeit, Antwortzeiten und Vorfällen - selbst gehostet und in Ihrer Hand." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Willkommen bei Checkmate!", "subtitle": "Registrieren Sie sich, um loszulegen", - "submit": "Registrieren" + "submit": "Registrieren", + "setupNotice": "Diese Seite ist nur während der Ersteinrichtung verfügbar. Sobald ein Super-Admin registriert ist, können weitere Benutzer in den Team-Einstellungen eingeladen werden." }, "forgotPassword": { "title": "Passwort vergessen?", @@ -378,6 +400,14 @@ "statusCode": "Statuscode", "location": "Standort" } + }, + "fallback": { + "title": "Noch keine Prüfungen", + "description": "Sobald Sie einen Monitor erstellen, erscheinen jede Statusprüfung und Antwortzeit hier als Prüfung." + }, + "header": { + "title": "Prüfungen", + "description": "Jede Sondierung, die Checkmate gegen Ihre Monitore ausführt, erscheint hier mit Statuscode und Antwortzeit." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Aktiv seit", "certificateExpiry": "Zertifikatablauf", "lastCheck": "Letzter Check", - "lastResponseTime": "Letzte Antwortzeit" + "lastResponseTime": "Letzte Antwortzeit", + "serviceIsDown": "Dienst ist nicht erreichbar" }, "status": { "down": "ausgefallen", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Keine Vorfälle — alle Systeme funktionieren", + "description": "Wenn ein Monitor ausfällt oder wiederhergestellt wird, erscheint der Vorfall hier mit Zeitangaben, Monitordetails und Lösungsverlauf." + }, "dialog": { "resolveIncident": { "title": "Vorfall lösen", @@ -720,6 +755,10 @@ "active": "Aktiv", "resolved": "Gelöst" } + }, + "header": { + "title": "Vorfälle", + "description": "Wenn ein Monitor ausfällt oder wiederhergestellt wird, erscheinen Vorfälle hier mit Zeitangaben, Monitordetails und Lösungsverlauf." } }, "infrastructure": { @@ -774,11 +813,19 @@ }, "fallback": { "actionButton": "Monitor erstellen!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Ein Infrastruktur-Monitor wird verwendet, um:" + "title": "Noch keine Infrastruktur-Monitore", + "description": "Verfolgen Sie die Serverleistung, identifizieren Sie Engpässe und gewährleisten Sie Zuverlässigkeit mit Echtzeit-Infrastrukturüberwachung." + }, + "header": { + "title": "Infrastruktur-Monitore", + "description": "Verfolgen Sie die Serverleistung, identifizieren Sie Engpässe und gewährleisten Sie Zuverlässigkeit mit Echtzeit-Infrastrukturüberwachung." } }, "logs": { + "fallback": { + "title": "Noch keine Protokolle", + "description": "Serveraktivitäten, Warnungen und Fehler werden hier angezeigt, während Checkmate läuft." + }, "tabs": { "diagnostics": "Diagnose", "logs": "Server logs", @@ -788,7 +835,9 @@ "label": "Log-Level" }, "jobQueue": "Job-Warteschlange", + "jobQueueExplainer": "Hervorgehobene Zeilen sind Jobs, die derzeit von einem Worker verarbeitet werden.", "failedJobs": "Fehlgeschlagene Jobs", + "failedJobsExplainer": "Aktuelle Fehler nach Monitor — Zeit des letzten Fehlers, Fehleranzahl und Grund.", "noLogs": "Keine Protokolle gefunden", "metrics": { "jobs": "Jobs", @@ -815,6 +864,16 @@ "usedSPercentage": "% von 1s durch CPU genutzt", "total": "Gesamt", "used": "Belegt" + }, + "sections": { + "runtimeStats": { + "title": "Laufzeitstatistiken", + "description": "Snapshot des Node.js-Prozesses und Host-Rechners. Wird alle 5 Sekunden aktualisiert." + }, + "memoryCpu": { + "title": "Speicher & CPU", + "description": "Wie der Prozess seinen zugewiesenen Speicher und die Host-CPU nutzt." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Letzter Fehler am", "failReason": "Fehlergrund" } + }, + "queueFallback": { + "title": "Keine Aufträge in der Warteschlange", + "description": "Geplante oder laufende Monitorprüfungen erscheinen hier. Eine leere Warteschlange bedeutet, dass alles aktuell ist." + }, + "header": { + "title": "Protokolle & Warteschlange", + "description": "Serverprotokolle, Monitor-Warteschlange und Laufzeitdiagnosen an einem Ort." } }, "maintenanceWindow": { "fallback": { "actionButton": "Wartungsfenster erstellen!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Ein Wartungsfenster wird verwendet, um:" + "title": "Keine Wartungsfenster geplant", + "description": "Planen Sie Wartungsausfälle, damit Warnungen unterdrückt werden und Team und Nutzer wissen, was sie erwartet." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Wartungsfenster", + "description": "Planen Sie Wartungsausfälle, damit Warnungen unterdrückt werden und Team und Nutzer wissen, was sie erwartet." } }, "notifications": { "fallback": { "actionButton": "Kanal erstellen", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Benachrichtigungskanäle werden verwendet, um:" + "title": "Noch keine Benachrichtigungskanäle", + "description": "Verbinden Sie Slack, Discord, E-Mail, Webhooks und mehr, damit die richtigen Personen sofort von Vorfällen erfahren." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "Chat-ID", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Pushover-Konfiguration", + "description": "Geben Sie Ihr Anwendungstoken und Ihren Benutzerschlüssel von Pushover ein.", + "optionAppToken": "Anwendungstoken", + "placeholderAppToken": "Anwendungstoken eingeben", + "optionUserKey": "Benutzerschlüssel", + "placeholderUserKey": "Benutzerschlüssel eingeben" + }, + "twilio": { + "title": "Twilio-Konfiguration", + "description": "Geben Sie Ihre Twilio-Kontoanmeldeinformationen ein, um SMS zu senden.", + "optionAccountSid": "Account-SID", + "placeholderAccountSid": "Account-SID eingeben", + "optionAuthToken": "Auth-Token", + "placeholderAuthToken": "Auth-Token eingeben", + "optionFromNumber": "Absendernummer", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Empfängernummer", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Ziel" } + }, + "header": { + "title": "Benachrichtigungen", + "description": "Verbinden Sie Slack, Discord, E-Mail, Webhooks und mehr, damit die richtigen Personen sofort von Vorfällen erfahren." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Monitor erstellen!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "Ein PageSpeed-Monitor wird verwendet, um:" + "title": "Noch keine PageSpeed-Monitore", + "description": "Verfolgen Sie Core Web Vitals und Lighthouse-Werte im Zeitverlauf, um Regressionen zu erkennen, bevor Nutzer es tun." + }, + "header": { + "title": "PageSpeed-Monitore", + "description": "Verfolgen Sie Core Web Vitals und Lighthouse-Werte im Zeitverlauf, um Regressionen zu erkennen, bevor Nutzer es tun." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Bitte beheben Sie die folgenden Validierungsfehler:" } + }, + "header": { + "title": "Einstellungen", + "description": "Konfigurieren Sie SMTP, Integrationen, Aufbewahrung und globales App-Verhalten." } }, "statusPages": { "deleteSuccess": "Statusseite erfolgreich gelöscht", "fallback": { - "title": "Eine Statusseite wird verwendet, um:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "Statusseite erstellen!" + "title": "Noch keine Statusseiten", + "actionButton": "Statusseite erstellen!", + "description": "Veröffentlichen Sie eine öffentliche Seite, die Kunden und Stakeholdern Echtzeit-Verfügbarkeit und Vorfallsverlauf zeigt." }, "monitorsList": { "chartTypeHeatmap": "Heatmap", @@ -1190,7 +1293,18 @@ "allDown": "Alle Systeme sind ausgefallen", "allUp": "Alle Systeme funktionsfähig", "degraded": "Einige Systeme haben Probleme", - "unknown": "Systemstatus kann nicht ermittelt werden" + "unknown": "Systemstatus kann nicht ermittelt werden", + "allBreached": "Alle Systeme haben Schwellenwerte überschritten", + "allMaintenance": "Alle Systeme befinden sich in Wartung", + "allPaused": "Alle Systeme sind pausiert", + "allInitializing": "Alle Systeme werden initialisiert", + "breachedAndDown": "Einige Systeme haben Schwellenwerte überschritten und sind ausgefallen", + "breached": "Einige Systeme haben Schwellenwerte überschritten", + "maintenanceAndDown": "Einige Systeme sind während der Wartung ausgefallen", + "maintenance": "Einige Systeme befinden sich in Wartung", + "partiallyPaused": "Einige Systeme sind pausiert", + "initializing": "Einige Systeme werden initialisiert", + "noMonitors": "Es wurden keine Monitore konfiguriert" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Statusseiten", + "description": "Veröffentlichen Sie öffentliche Seiten, die Kunden und Stakeholdern Echtzeit-Verfügbarkeit und Vorfallsverlauf zeigen." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Monitor erstellen!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Ein Verfügbarkeitsmonitor wird verwendet, um:" + "title": "Noch keine Uptime-Monitore", + "description": "Überwachen Sie HTTP-Endpunkte, Pings, Container und Ports und werden Sie sofort benachrichtigt, wenn etwas ausfällt." + }, + "header": { + "title": "Uptime-Monitore", + "description": "Überwachen Sie HTTP-Endpunkte, Pings, Container und Ports und werden Sie sofort benachrichtigt, wenn etwas ausfällt." } } } diff --git a/client/src/locales/en.json b/client/src/locales/en.json index eb9a34339..b6201728e 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -105,7 +105,7 @@ } }, "table": { - "empty": "Nothing here", + "empty": "Nothing to show yet", "headers": { "actions": "Actions", "dateTime": "Date & time", @@ -123,6 +123,14 @@ } }, "components": { + "pageHeader": { + "links": { + "support": "Support", + "discussions": "Discussions", + "docs": "Documentation", + "changelog": "Changelog" + } + }, "imageUpload": { "clickToUpload": "Click to upload", "dragAndDrop": "or drag and drop", @@ -249,6 +257,10 @@ } }, "team": { + "fallback": { + "title": "No team members yet", + "description": "Invite teammates by email or add them directly. Once they join, they'll appear here with their role." + }, "filter": { "placeholder": "Filter by role", "all": "All roles", @@ -279,9 +291,18 @@ }, "linkLabel": "Invite link" } + }, + "header": { + "title": "Account", + "description": "Manage your profile, password, team, and workspace preferences." } }, "auth": { + "brandPanel": { + "eyebrow": "Open-source infrastructure monitoring", + "tagline": "Watch every move your servers make.", + "description": "Real-time uptime, response time and incident tracking - self-hosted and yours to keep." + }, "common": { "passwordRules": { "length": { @@ -363,6 +384,10 @@ } }, "checks": { + "fallback": { + "title": "No checks yet", + "description": "Once you create a monitor, every status probe and response time will appear here as a check." + }, "selects": { "monitor": { "all": "All monitors" @@ -379,6 +404,10 @@ "statusCode": "Status code", "location": "Location" } + }, + "header": { + "title": "Checks", + "description": "Every probe Checkmate runs against your monitors lands here, with status code and response time." } }, "common": { @@ -642,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "No incidents — all systems healthy", + "description": "When a monitor goes down or recovers, the incident will appear here with timing, monitor details, and resolution history." + }, "dialog": { "resolveIncident": { "title": "Resolve incident", @@ -722,6 +755,10 @@ "active": "Active", "resolved": "Resolved" } + }, + "header": { + "title": "Incidents", + "description": "When monitors go down or recover, incidents appear here with timing, monitor details and resolution history." } }, "infrastructure": { @@ -775,16 +812,24 @@ } }, "fallback": { - "actionButton": "Create a monitor!", - "checks": [ - "Track the performance of your servers", - "Identify bottlenecks and optimize usage", - "Ensure reliability with real-time monitoring" - ], - "title": "An infrastructure monitor is used to:" + "actionButton": "Create a monitor", + "description": "Track server performance, identify bottlenecks, and ensure reliability with real-time infrastructure monitoring.", + "title": "No infrastructure monitors yet" + }, + "header": { + "title": "Infrastructure monitors", + "description": "Track server performance, identify bottlenecks, and ensure reliability with real-time infrastructure monitoring." } }, "logs": { + "fallback": { + "title": "No logs yet", + "description": "Server activity, warnings, and errors will appear here as Checkmate runs." + }, + "queueFallback": { + "title": "No jobs in the queue", + "description": "Monitor checks that are scheduled or running will appear here. An empty queue means everything is up to date." + }, "tabs": { "diagnostics": "Diagnostics", "logs": "Logs", @@ -794,7 +839,9 @@ "label": "Log level" }, "jobQueue": "Job queue", + "jobQueueExplainer": "Highlighted rows are jobs currently being processed by a worker.", "failedJobs": "Failed jobs", + "failedJobsExplainer": "Recent failures by monitor — last failure time, fail count, and the reason.", "noLogs": "No logs found", "metrics": { "jobs": "Jobs", @@ -804,6 +851,16 @@ "totalFailures": "Total failures" }, "diagnostics": { + "sections": { + "runtimeStats": { + "title": "Runtime stats", + "description": "Snapshot of the Node.js process and host machine. Updates every 5 seconds." + }, + "memoryCpu": { + "title": "Memory & CPU", + "description": "How the process is using its allocated memory and host CPU." + } + }, "stats": { "eventLoopDelay": "Event loop delay", "uptime": "Uptime", @@ -812,7 +869,7 @@ "osMemoryLimit": "OS memory limit" }, "gauges": { - "heapAllocation": "Heap allocaton", + "heapAllocation": "Heap allocation", "heapUsage": "Heap usage", "heapUtilization": "Heap utilization", "instantCpuUsage": "Instant CPU usage", @@ -831,25 +888,25 @@ "method": "Method", "monitorId": "Monitor ID", "runCount": "Run count", - "failCount": "Fail count", + "failCount": "Count", "lastRunAt": "Last run at", "lockedAt": "Locked at", "lastFinishedAt": "Last finished at", "lastRunTook": "Last run took", - "lastFailedAt": "Last failed at", + "lastFailedAt": "Last failed", "failReason": "Fail reason" } + }, + "header": { + "title": "Logs & queue", + "description": "Inspect server logs, the monitor job queue, and runtime diagnostics in one place." } }, "maintenanceWindow": { "fallback": { - "actionButton": "Create a maintenance window!", - "checks": [ - "Mark your maintenance periods", - "Eliminate any misunderstandings", - "Stop sending alerts in maintenance windows" - ], - "title": "A maintenance window is used to:" + "actionButton": "Create a maintenance window", + "description": "Schedule planned downtime so alerts are suppressed and your team and users know what to expect.", + "title": "No maintenance windows scheduled" }, "table": { "headers": { @@ -901,17 +958,17 @@ } } } + }, + "header": { + "title": "Maintenance windows", + "description": "Schedule planned downtime so alerts are suppressed and your team and users know what to expect." } }, "notifications": { "fallback": { "actionButton": "Create a channel", - "checks": [ - "Alert teams about downtime or performance issues", - "Let engineers know when incidents happen", - "Keep administrators informed of system changes" - ], - "title": "Notification channles are used to:" + "description": "Connect Slack, Discord, email, webhooks and more so the right people hear about incidents the moment they happen.", + "title": "No notification channels yet" }, "form": { "accessToken": { @@ -987,6 +1044,10 @@ "headers": { "destination": "Destination" } + }, + "header": { + "title": "Notifications", + "description": "Connect Slack, Discord, email, webhooks and more so the right people hear about incidents the moment they happen." } }, "pageSpeed": { @@ -1012,13 +1073,13 @@ } }, "fallback": { - "actionButton": "Create a monitor!", - "checks": [ - "Report on the user experience of a page", - "Help analyze webpage speed", - "Give suggestions on how the page can be improved" - ], - "title": "A PageSpeed monitor is used to:" + "actionButton": "Create a monitor", + "description": "Track Core Web Vitals and Lighthouse scores over time so you can spot regressions before users do.", + "title": "No PageSpeed monitors yet" + }, + "header": { + "title": "PageSpeed monitors", + "description": "Track Core Web Vitals and Lighthouse scores over time so you can spot regressions before users do." } }, "settings": { @@ -1196,19 +1257,18 @@ "validation": { "errorMessage": "Please fix the following validation errors:" } + }, + "header": { + "title": "Settings", + "description": "Configure SMTP, integrations, retention, and global app behavior." } }, "statusPages": { "deleteSuccess": "Status page deleted successfully", "fallback": { - "title": "A status page is used to:", - "checks": [ - "Communicate system status to users and stakeholders", - "Display real-time uptime information publicly", - "Build trust with transparent service monitoring", - "Reduce support requests during incidents" - ], - "actionButton": "Create a status page!" + "title": "No status pages yet", + "description": "Publish a public page that shows real-time uptime and incident history to your customers and stakeholders.", + "actionButton": "Create a status page" }, "monitorsList": { "chartTypeHeatmap": "Heatmap", @@ -1336,6 +1396,10 @@ } } } + }, + "header": { + "title": "Status pages", + "description": "Publish public pages that show real-time uptime and incident history to your customers and stakeholders." } }, "uptime": { @@ -1350,14 +1414,13 @@ } }, "fallback": { - "actionButton": "Create a monitor!", - "checks": [ - "Check if websites or servers are online & responsive", - "Alert teams about downtime or performance issues", - "Monitor HTTP endpoints, pings, containers & ports", - "Track historical uptime and reliability trends" - ], - "title": "An uptime monitor is used to:" + "actionButton": "Create a monitor", + "description": "Watch HTTP endpoints, pings, containers, and ports — and get alerted the moment something goes down.", + "title": "No uptime monitors yet" + }, + "header": { + "title": "Uptime monitors", + "description": "Watch HTTP endpoints, pings, containers, and ports — and get alerted the moment something goes down." } } } diff --git a/client/src/locales/es.json b/client/src/locales/es.json index 2006e1cea..61e7b557e 100644 --- a/client/src/locales/es.json +++ b/client/src/locales/es.json @@ -13,7 +13,7 @@ "content": "Advertencia: Aún no ha agregado una clave de API de Google PageSpeed. Visite Configuración para agregar una. Sin ella, el monitor de PageSpeed no funcionará." } }, - "appName": "", + "appName": "Checkmate", "breadcrumbs": { "details": "Detalles", "home": "Inicio" @@ -35,11 +35,11 @@ "sendInvite": "Enviar invitación", "test": "Probar", "testNotifications": "Probar notificaciones", - "toggleTheme": "", + "toggleTheme": "Cambiar tema claro / oscuro", "flushQueue": "Vaciar cola", "notFound": "Ir al panel principal", - "resetPassword": "", - "reset": "", + "resetPassword": "Restablecer contraseña", + "reset": "Restablecer", "clear": "Limpiar", "addDemo": "Agregar monitores de demostración", "removeMonitors": "Eliminar monitores", @@ -47,7 +47,14 @@ "exportToJSON": "Exportar a JSON", "importFromJSON": "Importar desde JSON", "clearFilters": "Limpiar filtros", - "removeUser": "Eliminar usuario" + "removeUser": "Eliminar usuario", + "testNotification": "Probar notificación", + "invite": "Invitar", + "copyLink": "Copiar enlace", + "regenerateToken": "Regenerar token", + "copyToken": "Copiar token", + "exportLogs": "Exportar registros", + "refresh": "Actualizar" }, "charts": { "labels": { @@ -86,12 +93,12 @@ "name": { "option": { "firstName": { - "label": "", - "placeholder": "" + "label": "Nombre", + "placeholder": "Introduce tu nombre" }, "lastName": { - "label": "", - "placeholder": "" + "label": "Apellidos", + "placeholder": "Introduce tus apellidos" } } }, @@ -99,7 +106,7 @@ "option": { "email": { "label": "Correo electrónico", - "placeholder": "you@example.com" + "placeholder": "tu@ejemplo.com" } } } @@ -107,14 +114,14 @@ "table": { "empty": "No hay nada aquí", "headers": { - "actions": "", + "actions": "Acciones", "dateTime": "Fecha y hora", "message": "Mensaje", "monitor": "Monitor", "monitorId": "ID de monitor", "name": "Nombre", "status": "Estado", - "type": "", + "type": "Tipo", "url": "URL", "interval": "Intervalo", "active": "Activo", @@ -125,17 +132,17 @@ "components": { "imageUpload": { "clickToUpload": "Haga clic para subir", - "dragAndDrop": "", - "supportedFormats": "", - "maxSize": "", + "dragAndDrop": "o arrastra y suelta", + "supportedFormats": "Formatos admitidos", + "maxSize": "Tamaño máximo", "orDragAndDrop": "o arrastre y suelte", "errors": { - "invalidFileSize": "", - "invalidFileFormat": "" + "invalidFileSize": "¡El archivo es demasiado grande!", + "invalidFileFormat": "¡Formato de archivo no admitido!" } }, "headerStatusPageControls": { - "publicLink": "" + "publicLink": "Enlace público" }, "headerTimeRange": { "labels": { @@ -155,26 +162,26 @@ "serverUnreachable": "No se puede conectar al servidor", "retry": "Reintentar", "retrying": "Reintentando...", - "reconnected": "" + "reconnected": "Conexión restablecida" }, "sidebar": { "menu": { - "uptime": "", - "pagespeed": "", - "infrastructure": "", - "notifications": "", + "uptime": "Disponibilidad", + "pagespeed": "Pagespeed", + "infrastructure": "Infraestructura", + "notifications": "Notificaciones", "checks": "Verificaciones", - "incidents": "", - "statusPages": "", - "maintenance": "", - "logs": "", - "settings": "" + "incidents": "Incidentes", + "statusPages": "Páginas de estado", + "maintenance": "Mantenimiento", + "logs": "Registros", + "settings": "Configuración" }, "bottomMenu": { - "support": "", - "discussions": "", - "docs": "", - "changelog": "" + "support": "Soporte", + "discussions": "Discusiones", + "docs": "Documentación", + "changelog": "Registro de cambios" }, "accountMenu": { "profile": "Perfil", @@ -186,19 +193,27 @@ "description": "Vea las últimas versiones y ayude a crecer la comunidad en GitHub" }, "authFooter": { - "navControls": "", - "logOut": "", + "navControls": "Controles", + "logOut": "Cerrar sesión", "roles": { "superAdmin": "Superadministrador", "admin": "Administrador", "user": "Usuario", - "demoUser": "" + "demoUser": "Usuario demo" } } }, "starPrompt": { "title": "Dale estrella a Checkmate", "description": "Vea las últimas versiones y ayude a crecer la comunidad en GitHub" + }, + "pageHeader": { + "links": { + "support": "Soporte", + "discussions": "Discusiones", + "docs": "Documentación", + "changelog": "Registro de cambios" + } } }, "pages": { @@ -251,15 +266,15 @@ "team": { "filter": { "placeholder": "Filtrar por rol", - "all": "", + "all": "Todos los roles", "admin": "Administrador", - "member": "" + "member": "Miembro" }, "table": { "headers": { "email": "Correo electrónico", "role": "Rol", - "created": "" + "created": "Creado el" } }, "addMember": { @@ -278,42 +293,55 @@ "placeholder": "Seleccione un rol" }, "linkLabel": "Enlace de invitación" + }, + "fallback": { + "title": "Aún no hay miembros del equipo", + "description": "Invita a tus compañeros por correo o añádelos directamente. Una vez que se unan, aparecerán aquí con su rol." } + }, + "header": { + "title": "Cuenta", + "description": "Administra tu perfil, contraseña, equipo y preferencias del espacio de trabajo." } }, "auth": { + "brandPanel": { + "eyebrow": "Monitorización de infraestructura de código abierto", + "tagline": "Vigila cada movimiento de tus servidores.", + "description": "Monitorización en tiempo real de disponibilidad, tiempo de respuesta e incidentes - autoalojada y tuya." + }, "common": { "passwordRules": { "length": { - "beginning": "", - "highlighted": "" + "beginning": "Debe tener al menos", + "highlighted": "8 caracteres" }, "lowercase": { - "beginning": "", - "highlighted": "" + "beginning": "Debe contener al menos", + "highlighted": "una letra minúscula" }, "match": { - "beginning": "", - "highlighted": "" + "beginning": "Las contraseñas", + "highlighted": "deben coincidir" }, "number": { - "beginning": "", - "highlighted": "" + "beginning": "Debe contener al menos", + "highlighted": "un número" }, "special": { - "beginning": "", - "highlighted": "" + "beginning": "Debe contener al menos", + "highlighted": "un carácter especial (!?@#$%^&*()-_=+[]{}|;:'\",./\\~`)" }, "uppercase": { - "beginning": "", - "highlighted": "" + "beginning": "Debe contener al menos", + "highlighted": "una letra mayúscula" } }, "form": { "option": { "email": { "label": "Correo electrónico", - "placeholder": "me@example.com" + "placeholder": "yo@ejemplo.com" }, "password": { "label": "Contraseña", @@ -343,7 +371,8 @@ "register": { "title": "¡Bienvenido de nuevo a Checkmate!", "subtitle": "Regístrese para comenzar", - "submit": "Registrarse" + "submit": "Registrarse", + "setupNotice": "Esta página solo está disponible durante la configuración inicial. Una vez que se haya registrado un super administrador, se podrá invitar a usuarios adicionales desde la configuración del equipo." }, "forgotPassword": { "title": "¿Olvidó su contraseña?", @@ -378,6 +407,14 @@ "statusCode": "Código de estado", "location": "Ubicación" } + }, + "fallback": { + "title": "Aún no hay comprobaciones", + "description": "Una vez que crees un monitor, cada sonda de estado y tiempo de respuesta aparecerá aquí como una comprobación." + }, + "header": { + "title": "Comprobaciones", + "description": "Cada sonda que Checkmate ejecuta contra tus monitores aparece aquí con código de estado y tiempo de respuesta." } }, "common": { @@ -397,7 +434,8 @@ "activeFor": "Activo desde hace", "certificateExpiry": "Vencimiento del certificado", "lastCheck": "Última verificación", - "lastResponseTime": "Último tiempo de respuesta" + "lastResponseTime": "Último tiempo de respuesta", + "serviceIsDown": "El servicio está caído" }, "status": { "down": "caído", @@ -438,9 +476,9 @@ }, "matchMethod": { "label": "Método de coincidencia", - "equal": "", - "include": "", - "regex": "" + "equal": "Igual", + "include": "Contiene", + "regex": "Regex" } }, "title": "Configuración avanzada" @@ -452,15 +490,15 @@ "label": "Frecuencia de verificación", "value": { "fifteenMinutes": "15 minutos", - "fifteenSeconds": "", + "fifteenSeconds": "15 segundos", "fiveMinutes": "5 minutos", - "fourMinutes": "", - "oneMinute": "", + "fourMinutes": "4 minutos", + "oneMinute": "1 minuto", "tenMinutes": "10 minutos", "thirtyMinutes": "30 minutos", - "thirtySeconds": "", - "threeMinutes": "", - "twoMinutes": "" + "thirtySeconds": "30 segundos", + "threeMinutes": "3 minutos", + "twoMinutes": "2 minutos" } } }, @@ -489,8 +527,8 @@ "placeholder": "https://www.google.com" }, "game": { - "label": "", - "placeholder": "" + "label": "Elige el juego", + "placeholder": "Selecciona un juego" }, "port": { "label": "Puerto a monitorear", @@ -508,10 +546,10 @@ "title": "Configuración general", "description": { "http": "Ingrese la URL o IP a monitorear (p. ej., https://example.com/ o 192.168.1.100) y agregue un nombre para mostrar que aparecerá en el panel.", - "ping": "", - "port": "", - "docker": "", - "game": "", + "ping": "Introduce la dirección IP o el nombre de host para hacer ping (p. ej., 192.168.1.100 o ejemplo.com) y un nombre descriptivo que aparecerá en el panel.", + "port": "Introduce la URL o IP del servidor, el número de puerto y un nombre descriptivo que aparecerá en el panel.", + "docker": "Introduce el nombre o ID del contenedor de Docker. Puedes usar el nombre del contenedor (p. ej., my-app) o su ID.", + "game": "Introduce la dirección IP o el nombre de host y el número de puerto para hacer ping (p. ej., 192.168.1.100 o ejemplo.com) y un nombre descriptivo que aparecerá en el panel.", "pagespeed": "Rastree el rendimiento de carga de página, Core Web Vitals y puntuaciones de optimización de su sitio web.", "grpc": "Ingrese el nombre de host y puerto del servidor gRPC, opcionalmente especifique un nombre de servicio para la verificación de salud, y agregue un nombre para mostrar.", "websocket": "Ingrese la URL de WebSocket a monitorear (p. ej., wss://example.com/socket) y agregue un nombre para mostrar.", @@ -640,6 +678,10 @@ } }, "incidents": { + "fallback": { + "title": "Sin incidentes — todos los sistemas saludables", + "description": "Cuando un monitor falla o se recupera, el incidente aparecerá aquí con los tiempos, los detalles del monitor y el historial de resolución." + }, "dialog": { "resolveIncident": { "title": "Resolver incidente", @@ -712,7 +754,7 @@ "headers": { "endTime": "Hora de fin", "resolutionType": "Tipo de resolución", - "startTime": "", + "startTime": "Hora de inicio", "statusCode": "Código de estado" }, "resolvedIncidents": "Incidentes resueltos", @@ -720,6 +762,10 @@ "active": "Activo", "resolved": "Resuelto" } + }, + "header": { + "title": "Incidentes", + "description": "Cuando un monitor falla o se recupera, los incidentes aparecen aquí con los tiempos, los detalles del monitor y el historial de resolución." } }, "infrastructure": { @@ -751,10 +797,10 @@ } }, "statBoxes": { - "avgCpuTemperature": "", - "cpuFrequency": "", - "cpuLogical": "", - "cpuPhysical": "", + "avgCpuTemperature": "Temperatura media de la CPU", + "cpuFrequency": "Frecuencia de la CPU", + "cpuLogical": "CPU (lógicas)", + "cpuPhysical": "CPU (físicas)", "disk": "Disco", "memory": "Memoria", "os": "SO" @@ -768,27 +814,37 @@ }, "tabs": { "labels": { - "network": "", + "network": "Red", "overview": "Resumen" } }, "fallback": { "actionButton": "¡Cree un monitor!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Un monitor de infraestructura se usa para:" + "title": "Aún no hay monitores de infraestructura", + "description": "Rastrea el rendimiento de los servidores, identifica cuellos de botella y garantiza la fiabilidad con monitoreo en tiempo real." + }, + "header": { + "title": "Monitores de infraestructura", + "description": "Rastrea el rendimiento de los servidores, identifica cuellos de botella y garantiza la fiabilidad con monitoreo en tiempo real." } }, "logs": { + "fallback": { + "title": "Aún no hay registros", + "description": "La actividad del servidor, advertencias y errores aparecerán aquí mientras Checkmate se ejecuta." + }, "tabs": { - "diagnostics": "", - "logs": "", - "queue": "" + "diagnostics": "Diagnóstico", + "logs": "Registros", + "queue": "Cola de trabajos" }, "logLevelSelect": { "label": "Nivel de registro" }, "jobQueue": "Cola de trabajos", + "jobQueueExplainer": "Las filas resaltadas son los trabajos que un worker está procesando actualmente.", "failedJobs": "Trabajos fallidos", + "failedJobsExplainer": "Fallos recientes por monitor — hora del último fallo, número de fallos y motivo.", "noLogs": "No se encontraron registros", "metrics": { "jobs": "Trabajos", @@ -815,6 +871,16 @@ "usedSPercentage": "% de 1s usado por CPU", "total": "Total", "used": "Usado" + }, + "sections": { + "runtimeStats": { + "title": "Estadísticas de tiempo de ejecución", + "description": "Instantánea del proceso Node.js y la máquina anfitriona. Se actualiza cada 5 segundos." + }, + "memoryCpu": { + "title": "Memoria y CPU", + "description": "Cómo el proceso utiliza la memoria asignada y la CPU del host." + } } }, "table": { @@ -833,18 +899,26 @@ "lastFailedAt": "Última falla", "failReason": "Razón de falla" } + }, + "queueFallback": { + "title": "No hay trabajos en la cola", + "description": "Las comprobaciones de monitores programadas o en ejecución aparecerán aquí. Una cola vacía significa que todo está al día." + }, + "header": { + "title": "Registros y cola", + "description": "Inspecciona registros del servidor, la cola de trabajos del monitor y los diagnósticos de runtime en un solo lugar." } }, "maintenanceWindow": { "fallback": { "actionButton": "¡Cree una ventana de mantenimiento!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Una ventana de mantenimiento se usa para:" + "title": "No hay ventanas de mantenimiento programadas", + "description": "Programa interrupciones planificadas para silenciar las alertas y que tu equipo y usuarios sepan qué esperar." }, "table": { "headers": { - "nextWindow": "", - "repeat": "" + "nextWindow": "Próxima ventana", + "repeat": "Repetición" } }, "form": { @@ -891,13 +965,17 @@ } } } + }, + "header": { + "title": "Ventanas de mantenimiento", + "description": "Programa interrupciones planificadas para silenciar las alertas y que tu equipo y usuarios sepan qué esperar." } }, "notifications": { "fallback": { "actionButton": "Crear un canal", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Los canales de notificación se usan para:" + "title": "Aún no hay canales de notificación", + "description": "Conecta Slack, Discord, correo electrónico, webhooks y más para que las personas adecuadas se enteren de los incidentes en cuanto ocurran." }, "form": { "accessToken": { @@ -947,12 +1025,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "ID de chat", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Configuración de Pushover", + "description": "Introduce tu token de aplicación y la clave de usuario de Pushover.", + "optionAppToken": "Token de aplicación", + "placeholderAppToken": "Introduce el token de aplicación", + "optionUserKey": "Clave de usuario", + "placeholderUserKey": "Introduce la clave de usuario" + }, + "twilio": { + "title": "Configuración de Twilio", + "description": "Introduce las credenciales de tu cuenta de Twilio para enviar SMS.", + "optionAccountSid": "SID de la cuenta", + "placeholderAccountSid": "Introduce el SID de la cuenta", + "optionAuthToken": "Token de autenticación", + "placeholderAuthToken": "Introduce el token de autenticación", + "optionFromNumber": "Número de origen", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Número de destino", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Destino" } + }, + "header": { + "title": "Notificaciones", + "description": "Conecta Slack, Discord, correo electrónico, webhooks y más para que las personas adecuadas se enteren de los incidentes en cuanto ocurran." } }, "pageSpeed": { @@ -979,8 +1081,12 @@ }, "fallback": { "actionButton": "¡Cree un monitor!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "Un monitor de PageSpeed se usa para:" + "title": "Aún no hay monitores de PageSpeed", + "description": "Sigue las Core Web Vitals y las puntuaciones de Lighthouse a lo largo del tiempo para detectar regresiones antes que tus usuarios." + }, + "header": { + "title": "Monitores de PageSpeed", + "description": "Sigue las Core Web Vitals y las puntuaciones de Lighthouse a lo largo del tiempo para detectar regresiones antes que tus usuarios." } }, "settings": { @@ -1083,7 +1189,7 @@ "email": { "title": "Configuración de correo electrónico", "description": "Configure los ajustes de correo electrónico de su sistema. Se usa para enviar notificaciones y alertas.", - "descriptionTransport": "", + "descriptionTransport": "Esto crea un transporte SMTP para NodeMailer", "descriptionTransportLink": "Ver especificaciones aquí", "option": { "host": { @@ -1158,14 +1264,18 @@ "validation": { "errorMessage": "Corrija los siguientes errores de validación:" } + }, + "header": { + "title": "Configuración", + "description": "Configura SMTP, integraciones, retención y comportamiento global de la app." } }, "statusPages": { "deleteSuccess": "Página de estado eliminada exitosamente", "fallback": { - "title": "Una página de estado se usa para:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "¡Cree una página de estado!" + "title": "Aún no hay páginas de estado", + "actionButton": "¡Cree una página de estado!", + "description": "Publica una página pública que muestre a tus clientes y partes interesadas la disponibilidad en tiempo real y el historial de incidentes." }, "monitorsList": { "chartTypeHeatmap": "Mapa de calor", @@ -1190,7 +1300,18 @@ "allDown": "Todos los sistemas están caídos", "allUp": "Todos los sistemas operativos", "degraded": "Algunos sistemas están experimentando problemas", - "unknown": "No se puede determinar el estado del sistema" + "unknown": "No se puede determinar el estado del sistema", + "allBreached": "Todos los sistemas han superado los umbrales", + "allMaintenance": "Todos los sistemas están en mantenimiento", + "allPaused": "Todos los sistemas están en pausa", + "allInitializing": "Todos los sistemas se están inicializando", + "breachedAndDown": "Algunos sistemas han superado los umbrales y están caídos", + "breached": "Algunos sistemas han superado los umbrales", + "maintenanceAndDown": "Algunos sistemas están caídos durante el mantenimiento", + "maintenance": "Algunos sistemas están en mantenimiento", + "partiallyPaused": "Algunos sistemas están en pausa", + "initializing": "Algunos sistemas se están inicializando", + "noMonitors": "No se ha configurado ningún monitor" }, "table": { "headers": { @@ -1282,6 +1403,17 @@ } } } + }, + "header": { + "title": "Páginas de estado", + "description": "Publica páginas públicas que muestren a tus clientes y partes interesadas la disponibilidad en tiempo real y el historial de incidentes." + }, + "publicPage": { + "maintenance": { + "upcoming": "Mantenimiento programado", + "inProgress": "Mantenimiento en curso", + "completed": "Mantenimiento completado" + } } }, "uptime": { @@ -1297,8 +1429,12 @@ }, "fallback": { "actionButton": "¡Cree un monitor!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Un monitor de tiempo de actividad se usa para:" + "title": "Aún no hay monitores de uptime", + "description": "Observa endpoints HTTP, pings, contenedores y puertos — recibe alertas en el momento en que algo falla." + }, + "header": { + "title": "Monitores de uptime", + "description": "Observa endpoints HTTP, pings, contenedores y puertos — recibe alertas en el momento en que algo falla." } } } diff --git a/client/src/locales/fi.json b/client/src/locales/fi.json index d56cb5bda..67e91c480 100644 --- a/client/src/locales/fi.json +++ b/client/src/locales/fi.json @@ -13,7 +13,7 @@ "content": "Varoitus: Et ole vielä lisännyt Google PageSpeed API -avainta. Siirry Asetuksiin lisätäksesi sellainen. Ilman sitä PageSpeed-monitorointi ei toimi." } }, - "appName": "", + "appName": "Checkmate", "breadcrumbs": { "details": "Tiedot", "home": "Etusivu" @@ -35,10 +35,10 @@ "sendInvite": "Lähetä kutsu", "test": "Testaa", "testNotifications": "Testaa ilmoitukset", - "toggleTheme": "", + "toggleTheme": "Vaihda vaalea / tumma", "flushQueue": "Tyhjennä jono", "notFound": "Siirry pääsivulle", - "resetPassword": "", + "resetPassword": "Nollaa salasana", "reset": "Palauta", "clear": "Tyhjennä", "addDemo": "Lisää demomonitorit", @@ -53,8 +53,8 @@ "labels": { "averageResponseTime": "Keskimääräinen vasteaika", "downtime": "Käyttökatko", - "high": "", - "low": "", + "high": "Korkea", + "low": "Matala", "uptime": "Käytettävyys" }, "histogram": { @@ -86,12 +86,12 @@ "name": { "option": { "firstName": { - "label": "", - "placeholder": "" + "label": "Etunimi", + "placeholder": "Anna etunimesi" }, "lastName": { - "label": "", - "placeholder": "" + "label": "Sukunimi", + "placeholder": "Anna sukunimesi" } } }, @@ -107,14 +107,14 @@ "table": { "empty": "Täällä ei ole mitään", "headers": { - "actions": "", + "actions": "Toiminnot", "dateTime": "Päivämäärä ja aika", "message": "Viesti", "monitor": "Monitori", "monitorId": "Monitorin tunnus", "name": "Nimi", "status": "Tila", - "type": "", + "type": "Tyyppi", "url": "Osoite", "interval": "Aikaväli", "active": "Aktiivinen", @@ -131,7 +131,7 @@ "orDragAndDrop": "tai vedä ja pudota", "errors": { "invalidFileSize": "Tiedoston koko on liian suuri!", - "invalidFileFormat": "" + "invalidFileFormat": "Tiedostomuotoa ei tueta!" } }, "headerStatusPageControls": { @@ -155,19 +155,19 @@ "serverUnreachable": "Palvelimeen ei saada yhteyttä", "retry": "Yritä uudelleen", "retrying": "Yritetään uudelleen...", - "reconnected": "" + "reconnected": "Yhteys palautettu" }, "sidebar": { "menu": { - "uptime": "", - "pagespeed": "", + "uptime": "Käytettävyys", + "pagespeed": "Pagespeed", "infrastructure": "Infrastruktuuri", - "notifications": "", + "notifications": "Ilmoitukset", "checks": "Tarkistukset", - "incidents": "", + "incidents": "Häiriöt", "statusPages": "Tilasivut", "maintenance": "Huolto", - "logs": "", + "logs": "Lokit", "settings": "Asetukset" }, "bottomMenu": { @@ -199,6 +199,14 @@ "starPrompt": { "title": "Lisää Checkmate suosikkeihin", "description": "Katso uusimmat julkaisut ja auta kasvattamaan yhteisöä GitHubissa" + }, + "pageHeader": { + "links": { + "support": "Tuki", + "discussions": "Keskustelut", + "docs": "Dokumentaatio", + "changelog": "Muutosloki" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "Valitse rooli" }, "linkLabel": "Kutsulinkki" + }, + "fallback": { + "title": "Ei vielä tiimin jäseniä", + "description": "Kutsu tiimin jäsenet sähköpostitse tai lisää heidät suoraan. Kun he liittyvät, he näkyvät tässä roolinsa kanssa." } + }, + "header": { + "title": "Tili", + "description": "Hallitse profiilia, salasanaa, tiimiä ja työtilan asetuksia." } }, "auth": { + "brandPanel": { + "eyebrow": "Avoimen lähdekoodin infrastruktuurin valvonta", + "tagline": "Seuraa palvelimiesi jokaista liikettä.", + "description": "Reaaliaikainen käytettävyyden, vasteajan ja häiriöiden valvonta - itse isännöity ja sinun." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Tervetuloa takaisin Checkmateen!", "subtitle": "Rekisteröidy aloittaaksesi", - "submit": "Rekisteröidy" + "submit": "Rekisteröidy", + "setupNotice": "Tämä sivu on käytettävissä vain alkuasennuksen aikana. Kun super-admin on rekisteröity, lisäkäyttäjiä voi kutsua tiimiasetuksista." }, "forgotPassword": { "title": "Unohditko salasanasi?", @@ -378,6 +400,14 @@ "statusCode": "Tilakoodi", "location": "Sijainti" } + }, + "fallback": { + "title": "Ei vielä tarkistuksia", + "description": "Kun luot monitorin, jokainen tilatarkistus ja vasteaika näkyy täällä tarkistuksena." + }, + "header": { + "title": "Tarkistukset", + "description": "Jokainen tarkistus, jonka Checkmate suorittaa monitoreitasi vastaan, näkyy täällä tilakoodin ja vasteajan kanssa." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Aktiivinen", "certificateExpiry": "Varmenteen vanheneminen", "lastCheck": "Viimeisin tarkistus", - "lastResponseTime": "Viimeisin vasteaika" + "lastResponseTime": "Viimeisin vasteaika", + "serviceIsDown": "Palvelu ei ole käytettävissä" }, "status": { "down": "alhaalla", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Ei tapauksia — kaikki järjestelmät ovat kunnossa", + "description": "Kun monitori kaatuu tai palautuu, tapaus tulee näkyviin ajoituksen, monitorin tietojen ja ratkaisuhistorian kanssa." + }, "dialog": { "resolveIncident": { "title": "Ratkaise häiriö", @@ -720,6 +755,10 @@ "active": "Aktiivinen", "resolved": "Ratkaistu" } + }, + "header": { + "title": "Tapaukset", + "description": "Kun monitori kaatuu tai palautuu, tapaukset näkyvät täällä ajoituksen, monitorin tietojen ja ratkaisuhistorian kanssa." } }, "infrastructure": { @@ -774,21 +813,31 @@ }, "fallback": { "actionButton": "Luo monitori!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Infrastruktuurimonitorilla voit:" + "title": "Ei vielä infrastruktuurimonitoreita", + "description": "Seuraa palvelinten suorituskykyä, tunnista pullonkauloja ja varmista luotettavuus reaaliaikaisella valvonnalla." + }, + "header": { + "title": "Infrastruktuurimonitorit", + "description": "Seuraa palvelinten suorituskykyä, tunnista pullonkauloja ja varmista luotettavuus reaaliaikaisella valvonnalla." } }, "logs": { + "fallback": { + "title": "Ei vielä lokeja", + "description": "Palvelimen toiminta, varoitukset ja virheet näkyvät täällä Checkmaten toimiessa." + }, "tabs": { - "diagnostics": "", - "logs": "", - "queue": "" + "diagnostics": "Diagnostiikka", + "logs": "Lokit", + "queue": "Työjono" }, "logLevelSelect": { "label": "Lokitaso" }, "jobQueue": "Työnojono", + "jobQueueExplainer": "Korostetut rivit ovat työt, joita työntekijä käsittelee parhaillaan.", "failedJobs": "Epäonnistuneet työt", + "failedJobsExplainer": "Viimeisimmät epäonnistumiset valvojan mukaan — viimeisin epäonnistumisaika, epäonnistumismäärä ja syy.", "noLogs": "Lokeja ei löytynyt", "metrics": { "jobs": "Työt", @@ -815,6 +864,16 @@ "usedSPercentage": "% sekunnista CPU:n käytössä", "total": "Yhteensä", "used": "Käytetty" + }, + "sections": { + "runtimeStats": { + "title": "Suoritusajan tilastot", + "description": "Node.js-prosessin ja isäntäkoneen tilannekuva. Päivittyy 5 sekunnin välein." + }, + "memoryCpu": { + "title": "Muisti ja CPU", + "description": "Miten prosessi käyttää sille varattua muistia ja isännän CPU:ta." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Viimeisin epäonnistuminen", "failReason": "Epäonnistumisen syy" } + }, + "queueFallback": { + "title": "Jonossa ei ole töitä", + "description": "Aikataulutetut tai käynnissä olevat monitoritarkistukset näkyvät täällä. Tyhjä jono tarkoittaa, että kaikki on ajan tasalla." + }, + "header": { + "title": "Lokit ja jono", + "description": "Tarkasta palvelinlokit, monitorin työjono ja ajonaikaiset diagnostiikat yhdestä paikasta." } }, "maintenanceWindow": { "fallback": { "actionButton": "Luo huoltoikkuna!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Huoltoikkunalla voit:" + "title": "Ei suunniteltuja huoltokatkoja", + "description": "Aikatauluta suunnitellut katkot, jotta hälytykset vaimennetaan ja tiimisi sekä käyttäjät tietävät mitä odottaa." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Huoltoikkunat", + "description": "Aikatauluta suunnitellut katkot, jotta hälytykset vaimennetaan ja tiimisi sekä käyttäjät tietävät mitä odottaa." } }, "notifications": { "fallback": { "actionButton": "Luo kanava", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Ilmoituskanavia käytetään:" + "title": "Ei vielä ilmoituskanavia", + "description": "Yhdistä Slack, Discord, sähköposti, webhookit ja muut, jotta oikeat ihmiset kuulevat tapauksista heti." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "Chat-tunnus", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Pushover-määritys", + "description": "Anna Pushover-sovellustunnus ja käyttäjäavain.", + "optionAppToken": "Sovellustunnus", + "placeholderAppToken": "Anna sovellustunnus", + "optionUserKey": "Käyttäjäavain", + "placeholderUserKey": "Anna käyttäjäavain" + }, + "twilio": { + "title": "Twilio-määritys", + "description": "Anna Twilio-tilin tunnistetiedot tekstiviestien lähettämistä varten.", + "optionAccountSid": "Tilin SID", + "placeholderAccountSid": "Anna tilin SID", + "optionAuthToken": "Todennustunnus", + "placeholderAuthToken": "Anna todennustunnus", + "optionFromNumber": "Lähettäjän numero", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Vastaanottajan numero", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Kohde" } + }, + "header": { + "title": "Ilmoitukset", + "description": "Yhdistä Slack, Discord, sähköposti, webhookit ja muut, jotta oikeat ihmiset kuulevat tapauksista heti." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Luo monitori!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "PageSpeed-monitorilla voit:" + "title": "Ei vielä PageSpeed-monitoreita", + "description": "Seuraa Core Web Vitals -mittareita ja Lighthouse-pisteitä ajan mittaan ja huomaa heikennykset ennen käyttäjiä." + }, + "header": { + "title": "PageSpeed-monitorit", + "description": "Seuraa Core Web Vitals -mittareita ja Lighthouse-pisteitä ajan mittaan ja huomaa heikennykset ennen käyttäjiä." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Korjaa seuraavat vahvistusvirheet:" } + }, + "header": { + "title": "Asetukset", + "description": "Määritä SMTP, integraatiot, säilytys ja sovelluksen yleinen käyttäytyminen." } }, "statusPages": { "deleteSuccess": "Tilasivu poistettu onnistuneesti", "fallback": { - "title": "Tilasivulla voit:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "Luo tilasivu!" + "title": "Ei vielä tilasivuja", + "actionButton": "Luo tilasivu!", + "description": "Julkaise julkinen sivu, joka näyttää asiakkaille ja sidosryhmille reaaliaikaisen käytettävyyden ja tapaushistorian." }, "monitorsList": { "chartTypeHeatmap": "Lämpökartta", @@ -1190,7 +1293,18 @@ "allDown": "Kaikki järjestelmät ovat alhaalla", "allUp": "Kaikki järjestelmät toiminnassa", "degraded": "Joissakin järjestelmissä on ongelmia", - "unknown": "Järjestelmän tilaa ei voida määrittää" + "unknown": "Järjestelmän tilaa ei voida määrittää", + "allBreached": "Kaikki järjestelmät ovat ylittäneet kynnysarvot", + "allMaintenance": "Kaikki järjestelmät ovat huollossa", + "allPaused": "Kaikki järjestelmät on keskeytetty", + "allInitializing": "Kaikki järjestelmät alustuvat", + "breachedAndDown": "Jotkin järjestelmät ovat ylittäneet kynnysarvot ja ovat alhaalla", + "breached": "Jotkin järjestelmät ovat ylittäneet kynnysarvot", + "maintenanceAndDown": "Jotkin järjestelmät ovat alhaalla huollon aikana", + "maintenance": "Jotkin järjestelmät ovat huollossa", + "partiallyPaused": "Jotkin järjestelmät on keskeytetty", + "initializing": "Jotkin järjestelmät alustuvat", + "noMonitors": "Yhtään monitoria ei ole määritetty" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Tilasivut", + "description": "Julkaise julkisia sivuja, jotka näyttävät asiakkaille ja sidosryhmille reaaliaikaisen käytettävyyden ja tapaushistorian." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Luo monitori!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Käytettävyysmonitorilla voit:" + "title": "Ei vielä käytettävyysmonitoreita", + "description": "Tarkkaile HTTP-päätepisteitä, pingejä, kontteja ja portteja — saat hälytyksen heti, kun jokin kaatuu." + }, + "header": { + "title": "Käytettävyysmonitorit", + "description": "Tarkkaile HTTP-päätepisteitä, pingejä, kontteja ja portteja — saat hälytyksen heti, kun jokin kaatuu." } } } diff --git a/client/src/locales/fr.json b/client/src/locales/fr.json index 9b7ec03f9..a2f8142bf 100644 --- a/client/src/locales/fr.json +++ b/client/src/locales/fr.json @@ -199,6 +199,14 @@ "starPrompt": { "title": "Star Checkmate", "description": "Consultez les dernières versions et aidez la communauté à grandir sur GitHub" + }, + "pageHeader": { + "links": { + "support": "Assistance", + "discussions": "Discussions", + "docs": "Documentation", + "changelog": "Journal des modifications" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "Sélectionnez un rôle" }, "linkLabel": "Lien d'invitation" + }, + "fallback": { + "title": "Aucun membre d'équipe pour le moment", + "description": "Invitez vos coéquipiers par e-mail ou ajoutez-les directement. Une fois qu'ils auront rejoint, ils apparaîtront ici avec leur rôle." } + }, + "header": { + "title": "Compte", + "description": "Gérez votre profil, mot de passe, équipe et préférences d'espace de travail." } }, "auth": { + "brandPanel": { + "eyebrow": "Surveillance d'infrastructure open source", + "tagline": "Surveillez chaque mouvement de vos serveurs.", + "description": "Suivi en temps réel de la disponibilité, du temps de réponse et des incidents - auto-hébergé et à vous." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Bienvenue sur Checkmate !", "subtitle": "Inscrivez-vous pour commencer", - "submit": "S'inscrire" + "submit": "S'inscrire", + "setupNotice": "Cette page n'est disponible que lors de la configuration initiale. Une fois qu'un super administrateur est enregistré, des utilisateurs supplémentaires peuvent être invités depuis les paramètres de l'équipe." }, "forgotPassword": { "title": "Mot de passe oublié ?", @@ -378,6 +400,14 @@ "statusCode": "Code de statut", "location": "Emplacement" } + }, + "fallback": { + "title": "Aucune vérification pour le moment", + "description": "Une fois que vous aurez créé un moniteur, chaque sonde d'état et temps de réponse apparaîtra ici sous forme de vérification." + }, + "header": { + "title": "Vérifications", + "description": "Chaque sonde que Checkmate exécute contre vos moniteurs apparaît ici avec le code d'état et le temps de réponse." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Actif depuis", "certificateExpiry": "Expiration du certificat", "lastCheck": "Dernière vérification", - "lastResponseTime": "Dernier temps de réponse" + "lastResponseTime": "Dernier temps de réponse", + "serviceIsDown": "Le service est indisponible" }, "status": { "down": "hors ligne", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Aucun incident — tous les systèmes sont sains", + "description": "Lorsqu'un moniteur tombe en panne ou se rétablit, l'incident apparaîtra ici avec l'horodatage, les détails du moniteur et l'historique de résolution." + }, "dialog": { "resolveIncident": { "title": "Résoudre l'incident", @@ -720,6 +755,10 @@ "active": "Actif", "resolved": "Résolu" } + }, + "header": { + "title": "Incidents", + "description": "Lorsqu'un moniteur tombe en panne ou se rétablit, les incidents apparaissent ici avec l'horodatage, les détails du moniteur et l'historique de résolution." } }, "infrastructure": { @@ -774,11 +813,19 @@ }, "fallback": { "actionButton": "Créer un moniteur !", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Un moniteur d'infrastructure sert à :" + "title": "Aucun moniteur d'infrastructure", + "description": "Suivez les performances des serveurs, identifiez les goulots d'étranglement et garantissez la fiabilité avec une surveillance en temps réel." + }, + "header": { + "title": "Moniteurs d'infrastructure", + "description": "Suivez les performances des serveurs, identifiez les goulots d'étranglement et garantissez la fiabilité avec une surveillance en temps réel." } }, "logs": { + "fallback": { + "title": "Aucun journal pour le moment", + "description": "L'activité du serveur, les avertissements et les erreurs apparaîtront ici pendant l'exécution de Checkmate." + }, "tabs": { "diagnostics": "Diagnostic", "logs": "Journaux des serveurs", @@ -788,7 +835,9 @@ "label": "Niveau de log" }, "jobQueue": "File d'attente des tâches", + "jobQueueExplainer": "Les lignes mises en évidence sont les tâches actuellement traitées par un worker.", "failedJobs": "Tâches échouées", + "failedJobsExplainer": "Échecs récents par moniteur — heure du dernier échec, nombre d'échecs et raison.", "noLogs": "Aucun log trouvé", "metrics": { "jobs": "Tâches", @@ -815,6 +864,16 @@ "usedSPercentage": "% de 1s utilisé par le CPU", "total": "Total", "used": "Utilisé" + }, + "sections": { + "runtimeStats": { + "title": "Statistiques d'exécution", + "description": "Aperçu du processus Node.js et de la machine hôte. Mis à jour toutes les 5 secondes." + }, + "memoryCpu": { + "title": "Mémoire et CPU", + "description": "Comment le processus utilise sa mémoire allouée et le CPU de l'hôte." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Dernier échec", "failReason": "Raison de l'échec" } + }, + "queueFallback": { + "title": "Aucun travail dans la file", + "description": "Les vérifications de moniteurs planifiées ou en cours apparaîtront ici. Une file vide signifie que tout est à jour." + }, + "header": { + "title": "Journaux et file", + "description": "Inspectez les journaux serveur, la file des tâches de moniteur et les diagnostics d'exécution au même endroit." } }, "maintenanceWindow": { "fallback": { "actionButton": "Créer une fenêtre de maintenance !", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Une fenêtre de maintenance sert à :" + "title": "Aucune fenêtre de maintenance planifiée", + "description": "Planifiez les interruptions afin que les alertes soient supprimées et que votre équipe et vos utilisateurs sachent à quoi s'attendre." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Fenêtres de maintenance", + "description": "Planifiez les interruptions afin que les alertes soient supprimées et que votre équipe et vos utilisateurs sachent à quoi s'attendre." } }, "notifications": { "fallback": { "actionButton": "Créer un canal", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Les canaux de notification servent à :" + "title": "Aucun canal de notification", + "description": "Connectez Slack, Discord, e-mail, webhooks et plus encore pour que les bonnes personnes soient prévenues dès qu'un incident survient." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "ID du chat", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Configuration Pushover", + "description": "Entrez votre jeton d'application et votre clé utilisateur Pushover.", + "optionAppToken": "Jeton d'application", + "placeholderAppToken": "Entrez le jeton d'application", + "optionUserKey": "Clé utilisateur", + "placeholderUserKey": "Entrez la clé utilisateur" + }, + "twilio": { + "title": "Configuration Twilio", + "description": "Entrez les identifiants de votre compte Twilio pour envoyer des SMS.", + "optionAccountSid": "SID du compte", + "placeholderAccountSid": "Entrez le SID du compte", + "optionAuthToken": "Jeton d'authentification", + "placeholderAuthToken": "Entrez le jeton d'authentification", + "optionFromNumber": "Numéro d'origine", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Numéro de destination", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Destination" } + }, + "header": { + "title": "Notifications", + "description": "Connectez Slack, Discord, e-mail, webhooks et plus encore pour que les bonnes personnes soient prévenues dès qu'un incident survient." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Créer un moniteur !", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "Un moniteur PageSpeed sert à :" + "title": "Aucun moniteur PageSpeed", + "description": "Suivez les Core Web Vitals et les scores Lighthouse au fil du temps pour détecter les régressions avant vos utilisateurs." + }, + "header": { + "title": "Moniteurs PageSpeed", + "description": "Suivez les Core Web Vitals et les scores Lighthouse au fil du temps pour détecter les régressions avant vos utilisateurs." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Veuillez corriger les erreurs de validation suivantes :" } + }, + "header": { + "title": "Paramètres", + "description": "Configurez SMTP, intégrations, rétention et comportement global de l'application." } }, "statusPages": { "deleteSuccess": "Page de statut supprimée avec succès", "fallback": { - "title": "Une page de statut sert à :", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "Créer une page de statut !" + "title": "Aucune page de statut", + "actionButton": "Créer une page de statut !", + "description": "Publiez une page publique qui montre à vos clients et parties prenantes la disponibilité en temps réel et l'historique des incidents." }, "monitorsList": { "chartTypeHeatmap": "Carte thermique", @@ -1190,7 +1293,18 @@ "allDown": "Tous les systèmes sont hors service", "allUp": "Tous les systèmes sont opérationnels", "degraded": "Certains systèmes rencontrent des problèmes", - "unknown": "Impossible de déterminer le statut du système" + "unknown": "Impossible de déterminer le statut du système", + "allBreached": "Tous les systèmes ont dépassé les seuils", + "allMaintenance": "Tous les systèmes sont en maintenance", + "allPaused": "Tous les systèmes sont en pause", + "allInitializing": "Tous les systèmes sont en cours d'initialisation", + "breachedAndDown": "Certains systèmes ont dépassé les seuils et sont hors ligne", + "breached": "Certains systèmes ont dépassé les seuils", + "maintenanceAndDown": "Certains systèmes sont hors ligne pendant la maintenance", + "maintenance": "Certains systèmes sont en maintenance", + "partiallyPaused": "Certains systèmes sont en pause", + "initializing": "Certains systèmes sont en cours d'initialisation", + "noMonitors": "Aucun moniteur n'a été configuré" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Pages de statut", + "description": "Publiez des pages publiques montrant à vos clients et parties prenantes la disponibilité en temps réel et l'historique des incidents." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Créer un moniteur !", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Un moniteur de disponibilité sert à :" + "title": "Aucun moniteur de disponibilité", + "description": "Surveillez les points de terminaison HTTP, les pings, les conteneurs et les ports — soyez alerté dès qu'une panne survient." + }, + "header": { + "title": "Moniteurs de disponibilité", + "description": "Surveillez les points de terminaison HTTP, les pings, les conteneurs et les ports — soyez alerté dès qu'une panne survient." } } } diff --git a/client/src/locales/ja.json b/client/src/locales/ja.json index 7dae6c9e0..0d39c9418 100644 --- a/client/src/locales/ja.json +++ b/client/src/locales/ja.json @@ -199,6 +199,14 @@ "starPrompt": { "title": "Checkmateにスターを付ける", "description": "GitHubで最新リリースを確認し、コミュニティの成長に貢献しましょう" + }, + "pageHeader": { + "links": { + "support": "サポート", + "discussions": "ディスカッション", + "docs": "ドキュメント", + "changelog": "変更履歴" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "ロールを選択" }, "linkLabel": "招待リンク" + }, + "fallback": { + "title": "チームメンバーがまだいません", + "description": "メールでチームメイトを招待するか、直接追加してください。参加すると、役割とともにここに表示されます。" } + }, + "header": { + "title": "アカウント", + "description": "プロファイル、パスワード、チーム、ワークスペースの設定を管理します。" } }, "auth": { + "brandPanel": { + "eyebrow": "オープンソースのインフラ監視", + "tagline": "サーバーのすべての動きを見守ろう。", + "description": "稼働状況、応答時間、インシデントをリアルタイムで追跡 - セルフホスト型で完全にあなたのもの。" + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Checkmateへようこそ!", "subtitle": "サインアップして始めましょう", - "submit": "登録" + "submit": "登録", + "setupNotice": "このページは初期セットアップ中のみ利用できます。スーパー管理者が登録されると、追加のユーザーはチーム設定から招待できます。" }, "forgotPassword": { "title": "パスワードをお忘れですか?", @@ -378,6 +400,14 @@ "statusCode": "ステータスコード", "location": "ロケーション" } + }, + "fallback": { + "title": "チェックがまだありません", + "description": "モニターを作成すると、すべてのステータスプローブと応答時間がここにチェックとして表示されます。" + }, + "header": { + "title": "チェック", + "description": "Checkmateがモニターに対して実行するすべてのプローブが、ステータスコードと応答時間とともにここに表示されます。" } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "稼働期間", "certificateExpiry": "証明書の有効期限", "lastCheck": "最終チェック", - "lastResponseTime": "最終応答時間" + "lastResponseTime": "最終応答時間", + "serviceIsDown": "サービスがダウンしています" }, "status": { "down": "ダウン", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "インシデントなし — すべてのシステムが正常です", + "description": "モニターがダウンまたは復旧すると、タイミング、モニターの詳細、解決履歴とともにここに表示されます。" + }, "dialog": { "resolveIncident": { "title": "インシデントを解決", @@ -720,6 +755,10 @@ "active": "アクティブ", "resolved": "解決済み" } + }, + "header": { + "title": "インシデント", + "description": "モニターがダウンまたは復旧すると、インシデントがタイミング、モニターの詳細、解決履歴とともにここに表示されます。" } }, "infrastructure": { @@ -774,11 +813,19 @@ }, "fallback": { "actionButton": "モニターを作成!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "インフラストラクチャモニターの用途:" + "title": "インフラモニターがまだありません", + "description": "サーバーのパフォーマンスを追跡し、ボトルネックを特定し、リアルタイムのインフラ監視で信頼性を確保します。" + }, + "header": { + "title": "インフラ監視", + "description": "サーバーのパフォーマンスを追跡し、ボトルネックを特定し、リアルタイムのインフラ監視で信頼性を確保します。" } }, "logs": { + "fallback": { + "title": "ログがまだありません", + "description": "サーバーのアクティビティ、警告、エラーがCheckmateの実行中にここに表示されます。" + }, "tabs": { "diagnostics": "診断", "logs": "サーバーログ", @@ -788,7 +835,9 @@ "label": "ログレベル" }, "jobQueue": "ジョブキュー", + "jobQueueExplainer": "ハイライトされた行は、現在ワーカーによって処理中のジョブです。", "failedJobs": "失敗したジョブ", + "failedJobsExplainer": "モニター別の最近の失敗 — 最終失敗時刻、失敗回数、および理由。", "noLogs": "ログが見つかりません", "metrics": { "jobs": "ジョブ", @@ -815,6 +864,16 @@ "usedSPercentage": "CPUによる1秒あたりの使用%", "total": "合計", "used": "使用済み" + }, + "sections": { + "runtimeStats": { + "title": "ランタイム統計", + "description": "Node.jsプロセスとホストマシンのスナップショット。5秒ごとに更新されます。" + }, + "memoryCpu": { + "title": "メモリとCPU", + "description": "プロセスが割り当てられたメモリとホストCPUをどのように使用しているか。" + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "最終失敗日時", "failReason": "失敗理由" } + }, + "queueFallback": { + "title": "キューにジョブがありません", + "description": "スケジュールされたモニターチェックや実行中のチェックがここに表示されます。空のキューはすべてが最新であることを意味します。" + }, + "header": { + "title": "ログとキュー", + "description": "サーバーログ、モニタージョブキュー、ランタイム診断を一か所で確認できます。" } }, "maintenanceWindow": { "fallback": { "actionButton": "メンテナンスウィンドウを作成!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "メンテナンスウィンドウの用途:" + "title": "予定されているメンテナンスウィンドウはありません", + "description": "計画されたダウンタイムをスケジュールしてアラートを抑制し、チームとユーザーに事前に知らせます。" }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "メンテナンスウィンドウ", + "description": "計画されたダウンタイムをスケジュールしてアラートを抑制し、チームとユーザーに事前に知らせます。" } }, "notifications": { "fallback": { "actionButton": "チャンネルを作成", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "通知チャンネルの用途:" + "title": "通知チャンネルがまだありません", + "description": "Slack、Discord、メール、Webhookなどを接続して、インシデント発生時に適切な担当者に通知します。" }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "チャットID", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Pushover の設定", + "description": "Pushover のアプリケーショントークンとユーザーキーを入力してください。", + "optionAppToken": "アプリトークン", + "placeholderAppToken": "アプリトークンを入力", + "optionUserKey": "ユーザーキー", + "placeholderUserKey": "ユーザーキーを入力" + }, + "twilio": { + "title": "Twilio の設定", + "description": "SMS を送信するための Twilio アカウント認証情報を入力してください。", + "optionAccountSid": "アカウント SID", + "placeholderAccountSid": "アカウント SID を入力", + "optionAuthToken": "認証トークン", + "placeholderAuthToken": "認証トークンを入力", + "optionFromNumber": "送信元番号", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "送信先番号", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "送信先" } + }, + "header": { + "title": "通知", + "description": "Slack、Discord、メール、Webhookなどを接続して、インシデント発生時に適切な担当者に通知します。" } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "モニターを作成!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "PageSpeedモニターの用途:" + "title": "PageSpeedモニターがまだありません", + "description": "Core Web VitalsとLighthouseスコアを継続的に追跡し、ユーザーが気付く前に劣化を発見します。" + }, + "header": { + "title": "PageSpeed監視", + "description": "Core Web VitalsとLighthouseスコアを継続的に追跡し、ユーザーが気付く前に劣化を発見します。" } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "以下のバリデーションエラーを修正してください:" } + }, + "header": { + "title": "設定", + "description": "SMTP、統合、保持、グローバルアプリの動作を設定します。" } }, "statusPages": { "deleteSuccess": "ステータスページが正常に削除されました", "fallback": { - "title": "ステータスページの用途:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "ステータスページを作成!" + "title": "ステータスページがまだありません", + "actionButton": "ステータスページを作成!", + "description": "顧客と関係者にリアルタイムの稼働状況とインシデント履歴を表示する公開ページを公開します。" }, "monitorsList": { "chartTypeHeatmap": "ヒートマップ", @@ -1190,7 +1293,18 @@ "allDown": "すべてのシステムがダウンしています", "allUp": "すべてのシステムが正常に稼働しています", "degraded": "一部のシステムに問題が発生しています", - "unknown": "システムステータスを判定できません" + "unknown": "システムステータスを判定できません", + "allBreached": "すべてのシステムがしきい値を超えました", + "allMaintenance": "すべてのシステムがメンテナンス中です", + "allPaused": "すべてのシステムが一時停止中です", + "allInitializing": "すべてのシステムが初期化中です", + "breachedAndDown": "一部のシステムがしきい値を超えてダウンしています", + "breached": "一部のシステムがしきい値を超えています", + "maintenanceAndDown": "一部のシステムがメンテナンス中にダウンしています", + "maintenance": "一部のシステムがメンテナンス中です", + "partiallyPaused": "一部のシステムが一時停止中です", + "initializing": "一部のシステムが初期化中です", + "noMonitors": "モニターが設定されていません" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "ステータスページ", + "description": "顧客と関係者にリアルタイムの稼働状況とインシデント履歴を表示する公開ページを公開します。" } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "モニターを作成!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "稼働時間モニターの用途:" + "title": "アップタイムモニターがまだありません", + "description": "HTTPエンドポイント、Ping、コンテナ、ポートを監視し、ダウンした瞬間に通知を受け取ります。" + }, + "header": { + "title": "稼働監視", + "description": "HTTPエンドポイント、Ping、コンテナ、ポートを監視し、ダウンした瞬間に通知を受け取ります。" } } } diff --git a/client/src/locales/pt-BR.json b/client/src/locales/pt-BR.json index 9b292dd68..9c9d33e4c 100644 --- a/client/src/locales/pt-BR.json +++ b/client/src/locales/pt-BR.json @@ -199,6 +199,14 @@ "starPrompt": { "title": "Avalie o Checkmate", "description": "Veja os últimos lançamentos e ajude a comunidade a crescer no GitHub" + }, + "pageHeader": { + "links": { + "support": "Suporte", + "discussions": "Discussões", + "docs": "Documentação", + "changelog": "Notas de versão" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "Selecione uma função" }, "linkLabel": "Link de convite" + }, + "fallback": { + "title": "Ainda não há membros na equipe", + "description": "Convide colegas por e-mail ou adicione-os diretamente. Assim que entrarem, aparecerão aqui com sua função." } + }, + "header": { + "title": "Conta", + "description": "Gerencie seu perfil, senha, equipe e preferências de workspace." } }, "auth": { + "brandPanel": { + "eyebrow": "Monitoramento de infraestrutura open-source", + "tagline": "Acompanhe cada passo dos seus servidores.", + "description": "Monitoramento em tempo real de disponibilidade, tempo de resposta e incidentes - auto-hospedado e seu." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Bem-vindo ao Checkmate!", "subtitle": "Cadastre-se para começar", - "submit": "Cadastrar" + "submit": "Cadastrar", + "setupNotice": "Esta página está disponível apenas durante a configuração inicial. Após o registro de um super administrador, usuários adicionais podem ser convidados a partir das configurações da equipe." }, "forgotPassword": { "title": "Esqueceu sua senha?", @@ -378,6 +400,14 @@ "statusCode": "Código de status", "location": "Localização" } + }, + "fallback": { + "title": "Ainda não há verificações", + "description": "Assim que você criar um monitor, cada sondagem de status e tempo de resposta aparecerá aqui como uma verificação." + }, + "header": { + "title": "Verificações", + "description": "Cada sonda que o Checkmate executa contra seus monitores aparece aqui com código de status e tempo de resposta." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Ativo há", "certificateExpiry": "Validade do certificado", "lastCheck": "Última verificação", - "lastResponseTime": "Último tempo de resposta" + "lastResponseTime": "Último tempo de resposta", + "serviceIsDown": "O serviço está fora do ar" }, "status": { "down": "fora do ar", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Sem incidentes — todos os sistemas saudáveis", + "description": "Quando um monitor falha ou se recupera, o incidente aparecerá aqui com horários, detalhes do monitor e histórico de resolução." + }, "dialog": { "resolveIncident": { "title": "Resolver incidente", @@ -720,6 +755,10 @@ "active": "Ativo", "resolved": "Resolvido" } + }, + "header": { + "title": "Incidentes", + "description": "Quando um monitor falha ou se recupera, os incidentes aparecem aqui com horários, detalhes do monitor e histórico de resolução." } }, "infrastructure": { @@ -774,11 +813,19 @@ }, "fallback": { "actionButton": "Criar um monitor!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Um monitor de infraestrutura é usado para:" + "title": "Ainda não há monitores de infraestrutura", + "description": "Acompanhe o desempenho dos servidores, identifique gargalos e garanta confiabilidade com monitoramento em tempo real." + }, + "header": { + "title": "Monitores de infraestrutura", + "description": "Acompanhe o desempenho dos servidores, identifique gargalos e garanta confiabilidade com monitoramento em tempo real." } }, "logs": { + "fallback": { + "title": "Ainda não há logs", + "description": "Atividade do servidor, avisos e erros aparecerão aqui enquanto o Checkmate roda." + }, "tabs": { "diagnostics": "Diagnóstico", "logs": "Logs do servidor", @@ -788,7 +835,9 @@ "label": "Nível de log" }, "jobQueue": "Fila de tarefas", + "jobQueueExplainer": "As linhas destacadas são as tarefas que estão sendo processadas atualmente por um worker.", "failedJobs": "Tarefas com falha", + "failedJobsExplainer": "Falhas recentes por monitor — horário da última falha, contagem de falhas e o motivo.", "noLogs": "Nenhum log encontrado", "metrics": { "jobs": "Tarefas", @@ -815,6 +864,16 @@ "usedSPercentage": "% de 1s usado pela CPU", "total": "Total", "used": "Usado" + }, + "sections": { + "runtimeStats": { + "title": "Estatísticas de execução", + "description": "Snapshot do processo Node.js e da máquina host. Atualiza a cada 5 segundos." + }, + "memoryCpu": { + "title": "Memória e CPU", + "description": "Como o processo está usando a memória alocada e a CPU do host." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Última falha em", "failReason": "Motivo da falha" } + }, + "queueFallback": { + "title": "Sem tarefas na fila", + "description": "Verificações de monitores agendadas ou em execução aparecerão aqui. Uma fila vazia significa que tudo está em dia." + }, + "header": { + "title": "Logs e fila", + "description": "Inspecione logs do servidor, fila de tarefas de monitor e diagnósticos de runtime em um só lugar." } }, "maintenanceWindow": { "fallback": { "actionButton": "Criar uma janela de manutenção!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Uma janela de manutenção é usada para:" + "title": "Nenhuma janela de manutenção agendada", + "description": "Programe paradas planejadas para que os alertas sejam suprimidos e sua equipe e usuários saibam o que esperar." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Janelas de manutenção", + "description": "Programe paradas planejadas para que os alertas sejam suprimidos e sua equipe e usuários saibam o que esperar." } }, "notifications": { "fallback": { "actionButton": "Criar um canal", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Canais de notificação são usados para:" + "title": "Ainda não há canais de notificação", + "description": "Conecte Slack, Discord, e-mail, webhooks e outros para que as pessoas certas saibam dos incidentes assim que acontecerem." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "ID do chat", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Configuração do Pushover", + "description": "Insira o token de aplicação e a chave de usuário do Pushover.", + "optionAppToken": "Token de aplicação", + "placeholderAppToken": "Insira o token de aplicação", + "optionUserKey": "Chave de usuário", + "placeholderUserKey": "Insira a chave de usuário" + }, + "twilio": { + "title": "Configuração do Twilio", + "description": "Insira as credenciais da conta Twilio para enviar SMS.", + "optionAccountSid": "SID da conta", + "placeholderAccountSid": "Insira o SID da conta", + "optionAuthToken": "Token de autenticação", + "placeholderAuthToken": "Insira o token de autenticação", + "optionFromNumber": "Número de origem", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Número de destino", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Destino" } + }, + "header": { + "title": "Notificações", + "description": "Conecte Slack, Discord, e-mail, webhooks e outros para que as pessoas certas saibam dos incidentes assim que acontecerem." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Criar um monitor!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "Um monitor PageSpeed é usado para:" + "title": "Ainda não há monitores PageSpeed", + "description": "Acompanhe Core Web Vitals e pontuações do Lighthouse ao longo do tempo para detectar regressões antes dos seus usuários." + }, + "header": { + "title": "Monitores PageSpeed", + "description": "Acompanhe Core Web Vitals e pontuações do Lighthouse ao longo do tempo para detectar regressões antes dos seus usuários." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Por favor, corrija os seguintes erros de validação:" } + }, + "header": { + "title": "Configurações", + "description": "Configure SMTP, integrações, retenção e comportamento global do app." } }, "statusPages": { "deleteSuccess": "Página de status excluída com sucesso", "fallback": { - "title": "Uma página de status é usada para:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "Criar uma página de status!" + "title": "Ainda não há páginas de status", + "actionButton": "Criar uma página de status!", + "description": "Publique uma página pública que mostre aos seus clientes e partes interessadas o tempo de atividade em tempo real e o histórico de incidentes." }, "monitorsList": { "chartTypeHeatmap": "Mapa de calor", @@ -1190,7 +1293,18 @@ "allDown": "Todos os sistemas estão fora do ar", "allUp": "Todos os sistemas operacionais", "degraded": "Alguns sistemas estão com problemas", - "unknown": "Não foi possível determinar o status do sistema" + "unknown": "Não foi possível determinar o status do sistema", + "allBreached": "Todos os sistemas excederam os limites", + "allMaintenance": "Todos os sistemas estão em manutenção", + "allPaused": "Todos os sistemas estão pausados", + "allInitializing": "Todos os sistemas estão inicializando", + "breachedAndDown": "Alguns sistemas excederam os limites e estão fora do ar", + "breached": "Alguns sistemas excederam os limites", + "maintenanceAndDown": "Alguns sistemas estão fora do ar durante a manutenção", + "maintenance": "Alguns sistemas estão em manutenção", + "partiallyPaused": "Alguns sistemas estão pausados", + "initializing": "Alguns sistemas estão inicializando", + "noMonitors": "Nenhum monitor foi configurado" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Páginas de status", + "description": "Publique páginas públicas que mostram aos seus clientes e partes interessadas o tempo de atividade em tempo real e o histórico de incidentes." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Criar um monitor!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Um monitor de uptime é usado para:" + "title": "Ainda não há monitores de uptime", + "description": "Acompanhe endpoints HTTP, pings, contêineres e portas — receba alertas no momento em que algo falhar." + }, + "header": { + "title": "Monitores de uptime", + "description": "Acompanhe endpoints HTTP, pings, contêineres e portas — receba alertas no momento em que algo falhar." } } } diff --git a/client/src/locales/ru.json b/client/src/locales/ru.json index 461187454..d1666fa56 100644 --- a/client/src/locales/ru.json +++ b/client/src/locales/ru.json @@ -199,6 +199,14 @@ "starPrompt": { "title": "Star Checkmate", "description": "Следите за последними релизами и помогайте развивать сообщество на GitHub" + }, + "pageHeader": { + "links": { + "support": "Поддержка", + "discussions": "Обсуждения", + "docs": "Документация", + "changelog": "Журнал изменений" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "Выберите роль" }, "linkLabel": "Ссылка-приглашение" + }, + "fallback": { + "title": "Пока нет участников команды", + "description": "Пригласите коллег по электронной почте или добавьте их напрямую. Как только они присоединятся, они появятся здесь со своей ролью." } + }, + "header": { + "title": "Учётная запись", + "description": "Управляйте профилем, паролем, командой и настройками рабочего пространства." } }, "auth": { + "brandPanel": { + "eyebrow": "Мониторинг инфраструктуры с открытым исходным кодом", + "tagline": "Следите за каждым шагом ваших серверов.", + "description": "Мониторинг доступности, времени отклика и инцидентов в реальном времени - self-hosted и принадлежит вам." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "С возвращением в Checkmate!", "subtitle": "Зарегистрируйтесь, чтобы начать", - "submit": "Регистрация" + "submit": "Регистрация", + "setupNotice": "Эта страница доступна только во время первоначальной настройки. После регистрации суперадминистратора дополнительных пользователей можно пригласить из настроек команды." }, "forgotPassword": { "title": "Забыли пароль?", @@ -378,6 +400,14 @@ "statusCode": "Код статуса", "location": "Расположение" } + }, + "fallback": { + "title": "Пока нет проверок", + "description": "Как только вы создадите монитор, каждая проверка состояния и время отклика появятся здесь." + }, + "header": { + "title": "Проверки", + "description": "Каждый зонд, который Checkmate выполняет к вашим мониторам, появится здесь с кодом состояния и временем отклика." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Активен", "certificateExpiry": "Истечение сертификата", "lastCheck": "Последняя проверка", - "lastResponseTime": "Последнее время ответа" + "lastResponseTime": "Последнее время ответа", + "serviceIsDown": "Сервис недоступен" }, "status": { "down": "недоступен", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Инцидентов нет — все системы исправны", + "description": "Когда монитор перестаёт работать или восстанавливается, инцидент появится здесь со временем, деталями монитора и историей решения." + }, "dialog": { "resolveIncident": { "title": "Решить инцидент", @@ -720,6 +755,10 @@ "active": "Активный", "resolved": "Решён" } + }, + "header": { + "title": "Инциденты", + "description": "Когда монитор перестаёт работать или восстанавливается, инцидент появляется здесь со временем, деталями монитора и историей решения." } }, "infrastructure": { @@ -774,11 +813,19 @@ }, "fallback": { "actionButton": "Создать монитор!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Монитор инфраструктуры используется для:" + "title": "Пока нет инфраструктурных мониторов", + "description": "Отслеживайте производительность серверов, выявляйте узкие места и обеспечивайте надёжность с мониторингом в реальном времени." + }, + "header": { + "title": "Инфраструктурные мониторы", + "description": "Отслеживайте производительность серверов, выявляйте узкие места и обеспечивайте надёжность с мониторингом в реальном времени." } }, "logs": { + "fallback": { + "title": "Пока нет журналов", + "description": "Активность сервера, предупреждения и ошибки появятся здесь во время работы Checkmate." + }, "tabs": { "diagnostics": "Диагностика", "logs": "Серверные логи", @@ -788,7 +835,9 @@ "label": "Уровень логов" }, "jobQueue": "Очередь заданий", + "jobQueueExplainer": "Выделенные строки — это задания, которые в данный момент обрабатываются воркером.", "failedJobs": "Неудачные задания", + "failedJobsExplainer": "Недавние сбои по мониторам — время последнего сбоя, количество сбоев и причина.", "noLogs": "Логи не найдены", "metrics": { "jobs": "Задания", @@ -815,6 +864,16 @@ "usedSPercentage": "% 1с использовано CPU", "total": "Всего", "used": "Использовано" + }, + "sections": { + "runtimeStats": { + "title": "Статистика выполнения", + "description": "Снимок процесса Node.js и хост-машины. Обновляется каждые 5 секунд." + }, + "memoryCpu": { + "title": "Память и ЦП", + "description": "Как процесс использует выделенную память и ЦП хоста." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Последняя ошибка", "failReason": "Причина ошибки" } + }, + "queueFallback": { + "title": "В очереди нет заданий", + "description": "Запланированные или выполняемые проверки мониторов будут отображаться здесь. Пустая очередь означает, что всё актуально." + }, + "header": { + "title": "Журналы и очередь", + "description": "Изучайте журналы сервера, очередь заданий мониторов и диагностику в одном месте." } }, "maintenanceWindow": { "fallback": { "actionButton": "Создать окно обслуживания!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Окно обслуживания используется для:" + "title": "Нет запланированных окон обслуживания", + "description": "Планируйте плановые простои, чтобы оповещения были подавлены, а команда и пользователи знали, чего ожидать." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Окна обслуживания", + "description": "Планируйте плановые простои, чтобы оповещения были подавлены, а команда и пользователи знали, чего ожидать." } }, "notifications": { "fallback": { "actionButton": "Создать канал", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Каналы уведомлений используются для:" + "title": "Пока нет каналов уведомлений", + "description": "Подключите Slack, Discord, email, вебхуки и другое, чтобы нужные люди узнавали об инцидентах сразу же." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "ID чата", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Настройка Pushover", + "description": "Введите токен приложения и ключ пользователя Pushover.", + "optionAppToken": "Токен приложения", + "placeholderAppToken": "Введите токен приложения", + "optionUserKey": "Ключ пользователя", + "placeholderUserKey": "Введите ключ пользователя" + }, + "twilio": { + "title": "Настройка Twilio", + "description": "Введите учётные данные аккаунта Twilio для отправки SMS.", + "optionAccountSid": "SID аккаунта", + "placeholderAccountSid": "Введите SID аккаунта", + "optionAuthToken": "Токен аутентификации", + "placeholderAuthToken": "Введите токен аутентификации", + "optionFromNumber": "Номер отправителя", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Номер получателя", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Назначение" } + }, + "header": { + "title": "Уведомления", + "description": "Подключите Slack, Discord, email, вебхуки и другое, чтобы нужные люди узнавали об инцидентах сразу же." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Создать монитор!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "Монитор PageSpeed используется для:" + "title": "Пока нет мониторов PageSpeed", + "description": "Отслеживайте Core Web Vitals и оценки Lighthouse во времени, чтобы заметить регрессии раньше пользователей." + }, + "header": { + "title": "Мониторы PageSpeed", + "description": "Отслеживайте Core Web Vitals и оценки Lighthouse во времени, чтобы заметить регрессии раньше пользователей." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Пожалуйста, исправьте следующие ошибки валидации:" } + }, + "header": { + "title": "Настройки", + "description": "Настройте SMTP, интеграции, сроки хранения и общее поведение приложения." } }, "statusPages": { "deleteSuccess": "Страница статуса успешно удалена", "fallback": { - "title": "Страница статуса используется для:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "Создать страницу статуса!" + "title": "Пока нет страниц состояния", + "actionButton": "Создать страницу статуса!", + "description": "Опубликуйте публичную страницу, показывающую клиентам и заинтересованным сторонам реальное время работы и историю инцидентов." }, "monitorsList": { "chartTypeHeatmap": "Тепловая карта", @@ -1190,7 +1293,18 @@ "allDown": "Все системы недоступны", "allUp": "Все системы работают", "degraded": "Некоторые системы испытывают проблемы", - "unknown": "Не удаётся определить статус системы" + "unknown": "Не удаётся определить статус системы", + "allBreached": "Все системы превысили пороговые значения", + "allMaintenance": "Все системы на техническом обслуживании", + "allPaused": "Все системы приостановлены", + "allInitializing": "Все системы инициализируются", + "breachedAndDown": "Некоторые системы превысили пороги и недоступны", + "breached": "Некоторые системы превысили пороги", + "maintenanceAndDown": "Некоторые системы недоступны во время техобслуживания", + "maintenance": "Некоторые системы на техобслуживании", + "partiallyPaused": "Некоторые системы приостановлены", + "initializing": "Некоторые системы инициализируются", + "noMonitors": "Мониторы не настроены" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Страницы состояния", + "description": "Публикуйте публичные страницы со временем работы и историей инцидентов для клиентов и заинтересованных сторон." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Создать монитор!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Монитор аптайма используется для:" + "title": "Пока нет мониторов работоспособности", + "description": "Наблюдайте за HTTP-конечными точками, пингами, контейнерами и портами — получайте уведомления в момент отказа." + }, + "header": { + "title": "Мониторы работоспособности", + "description": "Наблюдайте за HTTP-конечными точками, пингами, контейнерами и портами — получайте уведомления в момент отказа." } } } diff --git a/client/src/locales/th.json b/client/src/locales/th.json index cf92d999f..0b5fb7526 100644 --- a/client/src/locales/th.json +++ b/client/src/locales/th.json @@ -199,6 +199,14 @@ "starPrompt": { "title": "ให้ดาว Checkmate", "description": "ดูรุ่นล่าสุดและช่วยเติบโตชุมชนบน GitHub" + }, + "pageHeader": { + "links": { + "support": "ฝ่ายสนับสนุน", + "discussions": "การสนทนา", + "docs": "เอกสาร", + "changelog": "บันทึกการเปลี่ยนแปลง" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "เลือกบทบาท" }, "linkLabel": "ลิงก์เชิญ" + }, + "fallback": { + "title": "ยังไม่มีสมาชิกทีม", + "description": "เชิญเพื่อนร่วมทีมทางอีเมลหรือเพิ่มพวกเขาโดยตรง เมื่อพวกเขาเข้าร่วม พวกเขาจะปรากฏที่นี่พร้อมบทบาทของพวกเขา" } + }, + "header": { + "title": "บัญชี", + "description": "จัดการโปรไฟล์ รหัสผ่าน ทีม และการตั้งค่าพื้นที่ทำงานของคุณ" } }, "auth": { + "brandPanel": { + "eyebrow": "การมอนิเตอร์โครงสร้างพื้นฐานโอเพนซอร์ส", + "tagline": "คอยจับตาดูทุกการเคลื่อนไหวของเซิร์ฟเวอร์ของคุณ", + "description": "ติดตามสถานะ เวลาตอบสนอง และเหตุการณ์ผิดปกติแบบเรียลไทม์ - โฮสต์เองและเป็นของคุณ" + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "ยินดีต้อนรับกลับสู่ Checkmate!", "subtitle": "สมัครสมาชิกเพื่อเริ่มต้น", - "submit": "ลงทะเบียน" + "submit": "ลงทะเบียน", + "setupNotice": "หน้านี้พร้อมใช้งานเฉพาะระหว่างการตั้งค่าเริ่มต้นเท่านั้น เมื่อลงทะเบียนผู้ดูแลระบบสูงสุดแล้ว สามารถเชิญผู้ใช้เพิ่มเติมได้จากการตั้งค่าทีม" }, "forgotPassword": { "title": "ลืมรหัสผ่านใช่ไหม?", @@ -378,6 +400,14 @@ "statusCode": "รหัสสถานะ", "location": "ตำแหน่ง" } + }, + "fallback": { + "title": "ยังไม่มีการตรวจสอบ", + "description": "เมื่อคุณสร้างตัวตรวจสอบ การตรวจสอบสถานะและเวลาตอบสนองทุกครั้งจะปรากฏที่นี่เป็นการตรวจสอบ" + }, + "header": { + "title": "การตรวจสอบ", + "description": "การตรวจสอบทุกครั้งที่ Checkmate ทำกับตัวตรวจสอบของคุณจะปรากฏที่นี่พร้อมรหัสสถานะและเวลาตอบสนอง" } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "ทำงานมาแล้ว", "certificateExpiry": "วันหมดอายุใบรับรอง", "lastCheck": "ตรวจสอบล่าสุด", - "lastResponseTime": "เวลาตอบสนองล่าสุด" + "lastResponseTime": "เวลาตอบสนองล่าสุด", + "serviceIsDown": "บริการขัดข้อง" }, "status": { "down": "ล่ม", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "ไม่มีเหตุการณ์ — ระบบทั้งหมดทำงานปกติ", + "description": "เมื่อตัวตรวจสอบล่มหรือฟื้นตัว เหตุการณ์จะปรากฏที่นี่พร้อมเวลา รายละเอียดตัวตรวจสอบ และประวัติการแก้ไข" + }, "dialog": { "resolveIncident": { "title": "แก้ไขเหตุการณ์", @@ -720,6 +755,10 @@ "active": "ใช้งานอยู่", "resolved": "แก้ไขแล้ว" } + }, + "header": { + "title": "เหตุการณ์", + "description": "เมื่อตัวตรวจสอบล่มหรือฟื้นตัว เหตุการณ์จะปรากฏที่นี่พร้อมเวลา รายละเอียดตัวตรวจสอบ และประวัติการแก้ไข" } }, "infrastructure": { @@ -774,11 +813,19 @@ }, "fallback": { "actionButton": "สร้างมอนิเตอร์!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "มอนิเตอร์โครงสร้างพื้นฐานใช้เพื่อ:" + "title": "ยังไม่มีตัวตรวจสอบโครงสร้างพื้นฐาน", + "description": "ติดตามประสิทธิภาพเซิร์ฟเวอร์ ระบุคอขวด และมั่นใจในความน่าเชื่อถือด้วยการตรวจสอบโครงสร้างพื้นฐานแบบเรียลไทม์" + }, + "header": { + "title": "ตัวตรวจสอบโครงสร้างพื้นฐาน", + "description": "ติดตามประสิทธิภาพเซิร์ฟเวอร์ ระบุคอขวด และมั่นใจในความน่าเชื่อถือด้วยการตรวจสอบโครงสร้างพื้นฐานแบบเรียลไทม์" } }, "logs": { + "fallback": { + "title": "ยังไม่มีบันทึก", + "description": "กิจกรรมเซิร์ฟเวอร์ คำเตือน และข้อผิดพลาดจะปรากฏที่นี่ในขณะที่ Checkmate ทำงาน" + }, "tabs": { "diagnostics": "วินิจฉัย", "logs": "Logs เซิร์ฟเวอร์", @@ -788,7 +835,9 @@ "label": "ระดับบันทึก" }, "jobQueue": "คิวงาน", + "jobQueueExplainer": "แถวที่ไฮไลต์ คืองานที่กำลังถูกประมวลผลโดยเวิร์กเกอร์อยู่ในขณะนี้", "failedJobs": "งานที่ล้มเหลว", + "failedJobsExplainer": "ความล้มเหลวล่าสุดตามมอนิเตอร์ — เวลาที่ล้มเหลวล่าสุด จำนวนครั้งที่ล้มเหลว และเหตุผล", "noLogs": "ไม่พบบันทึก", "metrics": { "jobs": "งาน", @@ -815,6 +864,16 @@ "usedSPercentage": "% ของ 1 วินาทีที่ CPU ใช้", "total": "ทั้งหมด", "used": "ใช้แล้ว" + }, + "sections": { + "runtimeStats": { + "title": "สถิติรันไทม์", + "description": "ภาพรวมของโปรเซส Node.js และเครื่องโฮสต์ อัปเดตทุก 5 วินาที" + }, + "memoryCpu": { + "title": "หน่วยความจำและ CPU", + "description": "กระบวนการใช้หน่วยความจำที่จัดสรรและ CPU ของโฮสต์อย่างไร" + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "ล้มเหลวล่าสุดเมื่อ", "failReason": "สาเหตุที่ล้มเหลว" } + }, + "queueFallback": { + "title": "ไม่มีงานในคิว", + "description": "การตรวจสอบตัวตรวจสอบที่กำหนดเวลาหรือกำลังทำงานจะปรากฏที่นี่ คิวที่ว่างหมายความว่าทุกอย่างเป็นปัจจุบัน" + }, + "header": { + "title": "บันทึกและคิว", + "description": "ตรวจสอบบันทึกเซิร์ฟเวอร์ คิวงานตัวตรวจสอบ และการวินิจฉัยรันไทม์ในที่เดียว" } }, "maintenanceWindow": { "fallback": { "actionButton": "สร้างช่วงเวลาบำรุงรักษา!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "ช่วงเวลาบำรุงรักษาใช้เพื่อ:" + "title": "ไม่มีช่วงเวลาบำรุงรักษาที่กำหนด", + "description": "กำหนดเวลาหยุดทำงานเพื่อระงับการแจ้งเตือน และให้ทีมและผู้ใช้รู้ถึงสิ่งที่จะเกิดขึ้น" }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "ช่วงเวลาบำรุงรักษา", + "description": "กำหนดเวลาหยุดทำงานเพื่อระงับการแจ้งเตือน และให้ทีมและผู้ใช้รู้ถึงสิ่งที่จะเกิดขึ้น" } }, "notifications": { "fallback": { "actionButton": "สร้างช่องทาง", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "ช่องทางการแจ้งเตือนใช้เพื่อ:" + "title": "ยังไม่มีช่องทางการแจ้งเตือน", + "description": "เชื่อมต่อ Slack, Discord, อีเมล, webhooks และอื่น ๆ เพื่อให้คนที่ถูกต้องรู้เกี่ยวกับเหตุการณ์ทันทีที่เกิดขึ้น" }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "Chat ID", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "การตั้งค่า Pushover", + "description": "ป้อนโทเค็นแอปและคีย์ผู้ใช้ Pushover ของคุณ", + "optionAppToken": "โทเค็นแอป", + "placeholderAppToken": "ป้อนโทเค็นแอป", + "optionUserKey": "คีย์ผู้ใช้", + "placeholderUserKey": "ป้อนคีย์ผู้ใช้" + }, + "twilio": { + "title": "การตั้งค่า Twilio", + "description": "ป้อนข้อมูลรับรองบัญชี Twilio เพื่อส่ง SMS", + "optionAccountSid": "SID บัญชี", + "placeholderAccountSid": "ป้อน SID บัญชี", + "optionAuthToken": "โทเค็นการรับรอง", + "placeholderAuthToken": "ป้อนโทเค็นการรับรอง", + "optionFromNumber": "หมายเลขผู้ส่ง", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "หมายเลขผู้รับ", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "ปลายทาง" } + }, + "header": { + "title": "การแจ้งเตือน", + "description": "เชื่อมต่อ Slack, Discord, อีเมล, webhooks และอื่น ๆ เพื่อให้คนที่ถูกต้องรู้เกี่ยวกับเหตุการณ์ทันทีที่เกิดขึ้น" } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "สร้างมอนิเตอร์!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "มอนิเตอร์ PageSpeed ใช้เพื่อ:" + "title": "ยังไม่มีตัวตรวจสอบ PageSpeed", + "description": "ติดตาม Core Web Vitals และคะแนน Lighthouse เพื่อจับความถดถอยก่อนที่ผู้ใช้จะสังเกตเห็น" + }, + "header": { + "title": "ตัวตรวจสอบ PageSpeed", + "description": "ติดตาม Core Web Vitals และคะแนน Lighthouse เพื่อจับความถดถอยก่อนที่ผู้ใช้จะสังเกตเห็น" } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "กรุณาแก้ไขข้อผิดพลาดการตรวจสอบต่อไปนี้:" } + }, + "header": { + "title": "การตั้งค่า", + "description": "กำหนดค่า SMTP, การผสานรวม, การเก็บรักษา และพฤติกรรมแอปทั่วโลก" } }, "statusPages": { "deleteSuccess": "ลบหน้าสถานะสำเร็จ", "fallback": { - "title": "หน้าสถานะใช้เพื่อ:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "สร้างหน้าสถานะ!" + "title": "ยังไม่มีหน้าสถานะ", + "actionButton": "สร้างหน้าสถานะ!", + "description": "เผยแพร่หน้าสาธารณะที่แสดง uptime แบบเรียลไทม์และประวัติเหตุการณ์ให้กับลูกค้าและผู้มีส่วนได้ส่วนเสีย" }, "monitorsList": { "chartTypeHeatmap": "แผนที่ความร้อน", @@ -1190,7 +1293,18 @@ "allDown": "ระบบทั้งหมดล่ม", "allUp": "ระบบทั้งหมดทำงานปกติ", "degraded": "บางระบบกำลังประสบปัญหา", - "unknown": "ไม่สามารถระบุสถานะระบบได้" + "unknown": "ไม่สามารถระบุสถานะระบบได้", + "allBreached": "ทุกระบบเกินขีดจำกัด", + "allMaintenance": "ทุกระบบอยู่ระหว่างการบำรุงรักษา", + "allPaused": "ทุกระบบถูกหยุดชั่วคราว", + "allInitializing": "ทุกระบบกำลังเริ่มต้น", + "breachedAndDown": "บางระบบเกินขีดจำกัดและขัดข้อง", + "breached": "บางระบบเกินขีดจำกัด", + "maintenanceAndDown": "บางระบบขัดข้องระหว่างการบำรุงรักษา", + "maintenance": "บางระบบอยู่ระหว่างการบำรุงรักษา", + "partiallyPaused": "บางระบบถูกหยุดชั่วคราว", + "initializing": "บางระบบกำลังเริ่มต้น", + "noMonitors": "ยังไม่มีการกำหนดค่ามอนิเตอร์" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "หน้าสถานะ", + "description": "เผยแพร่หน้าสาธารณะที่แสดง uptime แบบเรียลไทม์และประวัติเหตุการณ์ให้กับลูกค้าและผู้มีส่วนได้ส่วนเสีย" } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "สร้างมอนิเตอร์!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "มอนิเตอร์อัปไทม์ใช้เพื่อ:" + "title": "ยังไม่มีตัวตรวจสอบ uptime", + "description": "ติดตาม HTTP endpoints, ping, คอนเทนเนอร์ และพอร์ต — รับการแจ้งเตือนทันทีที่บางอย่างล่ม" + }, + "header": { + "title": "ตัวตรวจสอบ uptime", + "description": "ติดตาม HTTP endpoints, ping, คอนเทนเนอร์ และพอร์ต — รับการแจ้งเตือนทันทีที่บางอย่างล่ม" } } } diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json index 43f0a8041..d501d4f19 100644 --- a/client/src/locales/tr.json +++ b/client/src/locales/tr.json @@ -35,7 +35,7 @@ "sendInvite": "Davet gönder", "test": "Test", "testNotifications": "Bildirimleri test et", - "toggleTheme": "", + "toggleTheme": "Açık / koyu temayı değiştir", "flushQueue": "Kuyruğu temizle", "notFound": "Ana panele git", "resetPassword": "Parolayı sıfırla", @@ -86,7 +86,7 @@ "name": { "option": { "firstName": { - "label": "", + "label": "Ad", "placeholder": "Jordan" }, "lastName": { @@ -155,13 +155,13 @@ "serverUnreachable": "Sunucuya ulaşılamıyor", "retry": "Tekrar dene", "retrying": "Yeniden deneniyor...", - "reconnected": "" + "reconnected": "Bağlantı yeniden kuruldu" }, "sidebar": { "menu": { - "uptime": "", + "uptime": "Çalışma süresi", "pagespeed": "Sayfa hızı", - "infrastructure": "", + "infrastructure": "Altyapı", "notifications": "Bildirimler", "checks": "Kontroller", "incidents": "Olaylar", @@ -199,6 +199,14 @@ "starPrompt": { "title": "Checkmate'e yıldız verin", "description": "En son sürümleri görün ve GitHub'da topluluğun büyümesine katkıda bulunun" + }, + "pageHeader": { + "links": { + "support": "Destek", + "discussions": "Tartışmalar", + "docs": "Dokümantasyon", + "changelog": "Değişiklik günlüğü" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "Bir rol seçin" }, "linkLabel": "Davet bağlantısı" + }, + "fallback": { + "title": "Henüz takım üyesi yok", + "description": "Ekip arkadaşlarınızı e-posta ile davet edin veya doğrudan ekleyin. Katıldıklarında, rolleriyle birlikte burada görünecekler." } + }, + "header": { + "title": "Hesap", + "description": "Profilinizi, parolanızı, ekibinizi ve çalışma alanı tercihlerinizi yönetin." } }, "auth": { + "brandPanel": { + "eyebrow": "Açık kaynaklı altyapı izleme", + "tagline": "Sunucularınızın her hareketini izleyin.", + "description": "Sistemlerinizin çalışma süresini, yanıt hızını ve yaşanan kesintileri tek bir panelden anlık takip edin. Kendi sunucunuzda çalışır, verileriniz sizde kalır." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Checkmate'e tekrar hoş geldiniz!", "subtitle": "Başlamak için kaydolun", - "submit": "Kaydol" + "submit": "Kaydol", + "setupNotice": "Bu sayfa yalnızca ilk kurulum sırasında kullanılabilir. Süper yönetici kaydedildikten sonra, ek kullanıcılar takım ayarlarından davet edilebilir." }, "forgotPassword": { "title": "Parolanızı mı unuttunuz?", @@ -378,6 +400,14 @@ "statusCode": "Durum kodu", "location": "Konum" } + }, + "fallback": { + "title": "Henüz kontrol yok", + "description": "Bir izleyici oluşturduğunuzda, her durum kontrolü ve yanıt süresi burada bir kontrol olarak görünecek." + }, + "header": { + "title": "Kontroller", + "description": "Checkmate'in izleyicilerinize karşı çalıştırdığı her sondaj, durum kodu ve yanıt süresiyle birlikte burada görünür." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Aktif süresi", "certificateExpiry": "Sertifika bitiş tarihi", "lastCheck": "Son kontrol", - "lastResponseTime": "Son yanıt süresi" + "lastResponseTime": "Son yanıt süresi", + "serviceIsDown": "Servis çalışmıyor" }, "status": { "down": "çevrimdışı", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Olay yok — tüm sistemler sağlıklı", + "description": "Bir izleyici devre dışı kaldığında veya kurtarıldığında, olay zamanlama, izleyici detayları ve çözüm geçmişiyle birlikte burada görünecek." + }, "dialog": { "resolveIncident": { "title": "Olayı çöz", @@ -720,6 +755,10 @@ "active": "Aktif", "resolved": "Çözüldü" } + }, + "header": { + "title": "Olaylar", + "description": "Bir izleyici devre dışı kaldığında veya kurtarıldığında, olaylar zamanlama, izleyici detayları ve çözüm geçmişiyle birlikte burada görünür." } }, "infrastructure": { @@ -774,11 +813,19 @@ }, "fallback": { "actionButton": "Monitör oluşturun!", - "checks": "Sunucularınızın performansını takip edin,Darboğazları belirleyin ve kullanımı optimize edin,Gerçek zamanlı izleme ile güvenilirliği sağlayın", - "title": "Bir altyapı monitörü şunlar için kullanılır:" + "title": "Henüz altyapı izleyicisi yok", + "description": "Sunucu performansını izleyin, darboğazları belirleyin ve gerçek zamanlı altyapı izleme ile güvenilirliği sağlayın." + }, + "header": { + "title": "Altyapı izleyicileri", + "description": "Sunucu performansını izleyin, darboğazları belirleyin ve gerçek zamanlı altyapı izleme ile güvenilirliği sağlayın." } }, "logs": { + "fallback": { + "title": "Henüz günlük yok", + "description": "Sunucu etkinliği, uyarılar ve hatalar Checkmate çalıştıkça burada görünecek." + }, "tabs": { "diagnostics": "Teşhis", "logs": "Sunucu günlükleri", @@ -788,7 +835,9 @@ "label": "Günlük seviyesi" }, "jobQueue": "İş kuyruğu", + "jobQueueExplainer": "Vurgulanan satırlar şu anda bir işçi tarafından işlenmekte olan işlerdir.", "failedJobs": "Başarısız işler", + "failedJobsExplainer": "Monitöre göre son başarısızlıklar — son başarısızlık zamanı, başarısızlık sayısı ve nedeni.", "noLogs": "Günlük bulunamadı", "metrics": { "jobs": "İşler", @@ -815,6 +864,16 @@ "usedSPercentage": "% CPU tarafından kullanılan (1s)", "total": "Toplam", "used": "Kullanılan" + }, + "sections": { + "runtimeStats": { + "title": "Çalışma istatistikleri", + "description": "Node.js süreci ve ana makinenin anlık görüntüsü. 5 saniyede bir güncellenir." + }, + "memoryCpu": { + "title": "Bellek ve CPU", + "description": "Sürecin ayrılmış belleğini ve ana makinenin CPU'sunu nasıl kullandığı." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Son başarısızlık zamanı", "failReason": "Başarısızlık nedeni" } + }, + "queueFallback": { + "title": "Kuyrukta iş yok", + "description": "Zamanlanmış veya çalışan izleyici kontrolleri burada görünür. Boş bir kuyruk her şeyin güncel olduğu anlamına gelir." + }, + "header": { + "title": "Günlükler ve kuyruk", + "description": "Sunucu günlüklerini, izleyici iş kuyruğunu ve çalışma zamanı tanılarını tek bir yerde inceleyin." } }, "maintenanceWindow": { "fallback": { "actionButton": "Bakım penceresi oluşturun!", - "checks": "Bakım dönemlerinizi işaretleyin,Yanlış anlamaları ortadan kaldırın,Bakım pencerelerinde uyarı göndermeyi durdurun", - "title": "Bakım penceresi şunlar için kullanılır:" + "title": "Planlanmış bakım penceresi yok", + "description": "Planlı kesintileri zamanlayın; uyarılar bastırılsın, ekibiniz ve kullanıcılarınız ne bekleyeceklerini bilsin." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Bakım pencereleri", + "description": "Planlı kesintileri zamanlayın; uyarılar bastırılsın, ekibiniz ve kullanıcılarınız ne bekleyeceklerini bilsin." } }, "notifications": { "fallback": { "actionButton": "Kanal oluştur", - "checks": "Kesinti veya performans sorunları hakkında ekipleri uyarın,Olaylar meydana geldiğinde mühendisleri bilgilendirin,Yöneticileri sistem değişiklikleri hakkında haberdar edin", - "title": "Bildirim kanalları şunlar için kullanılır:" + "title": "Henüz bildirim kanalı yok", + "description": "Slack, Discord, e-posta, webhook ve daha fazlasını bağlayın — olaylar olur olmaz doğru kişilere haber verilir." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "Sohbet ID", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Pushover yapılandırması", + "description": "Pushover uygulama belirtecinizi ve kullanıcı anahtarınızı girin.", + "optionAppToken": "Uygulama belirteci", + "placeholderAppToken": "Uygulama belirtecini girin", + "optionUserKey": "Kullanıcı anahtarı", + "placeholderUserKey": "Kullanıcı anahtarını girin" + }, + "twilio": { + "title": "Twilio yapılandırması", + "description": "SMS göndermek için Twilio hesap kimlik bilgilerinizi girin.", + "optionAccountSid": "Hesap SID", + "placeholderAccountSid": "Hesap SID girin", + "optionAuthToken": "Kimlik doğrulama belirteci", + "placeholderAuthToken": "Kimlik doğrulama belirtecini girin", + "optionFromNumber": "Gönderen numara", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Alıcı numara", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Hedef" } + }, + "header": { + "title": "Bildirimler", + "description": "Slack, Discord, e-posta, webhook ve daha fazlasını bağlayın — olaylar olur olmaz doğru kişilere haber verilir." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Monitör oluşturun!", - "checks": "Bir sayfanın kullanıcı deneyimini raporlayın,Web sayfası hızını analiz etmeye yardımcı olun,Sayfanın nasıl iyileştirilebileceğine dair öneriler sunun", - "title": "Bir PageSpeed monitörü şunlar için kullanılır:" + "title": "Henüz PageSpeed izleyicisi yok", + "description": "Core Web Vitals ve Lighthouse puanlarını zaman içinde izleyerek kullanıcılarınız fark etmeden gerilemeleri yakalayın." + }, + "header": { + "title": "PageSpeed izleyicileri", + "description": "Core Web Vitals ve Lighthouse puanlarını zaman içinde izleyerek kullanıcılarınız fark etmeden gerilemeleri yakalayın." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Lütfen aşağıdaki doğrulama hatalarını düzeltin:" } + }, + "header": { + "title": "Ayarlar", + "description": "SMTP, entegrasyonlar, saklama ve genel uygulama davranışını yapılandırın." } }, "statusPages": { "deleteSuccess": "Durum sayfası başarıyla silindi", "fallback": { - "title": "Bir durum sayfası şunlar için kullanılır:", - "checks": "Kullanıcılara ve paydaşlara sistem durumunu iletin,Gerçek zamanlı çalışma süresi bilgilerini herkese açık olarak görüntüleyin,Şeffaf hizmet izleme ile güven oluşturun,Olaylar sırasında destek taleplerini azaltın", - "actionButton": "Durum sayfası oluşturun!" + "title": "Henüz durum sayfası yok", + "actionButton": "Durum sayfası oluşturun!", + "description": "Müşterilerinize ve paydaşlarınıza gerçek zamanlı çalışma süresi ve olay geçmişini gösteren herkese açık bir sayfa yayınlayın." }, "monitorsList": { "chartTypeHeatmap": "Isı haritası", @@ -1190,7 +1293,18 @@ "allDown": "Tüm sistemler çevrimdışı", "allUp": "Tüm sistemler çalışıyor", "degraded": "Bazı sistemlerde sorun yaşanıyor", - "unknown": "Sistem durumu belirlenemiyor" + "unknown": "Sistem durumu belirlenemiyor", + "allBreached": "Tüm sistemler eşik değerlerini aştı", + "allMaintenance": "Tüm sistemler bakımda", + "allPaused": "Tüm sistemler duraklatıldı", + "allInitializing": "Tüm sistemler başlatılıyor", + "breachedAndDown": "Bazı sistemler eşik değerlerini aştı ve çalışmıyor", + "breached": "Bazı sistemler eşik değerlerini aştı", + "maintenanceAndDown": "Bazı sistemler bakım sırasında çalışmıyor", + "maintenance": "Bazı sistemler bakımda", + "partiallyPaused": "Bazı sistemler duraklatıldı", + "initializing": "Bazı sistemler başlatılıyor", + "noMonitors": "Hiç monitör yapılandırılmadı" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Durum sayfaları", + "description": "Müşterilerinize ve paydaşlarınıza gerçek zamanlı çalışma süresi ve olay geçmişini gösteren herkese açık sayfalar yayınlayın." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Monitör oluşturun!", - "checks": "Web sitelerinin veya sunucuların çevrimiçi ve yanıt verip vermediğini kontrol edin,Kesinti veya performans sorunları hakkında ekipleri uyarın,HTTP uç noktalarını, ping'leri, container'ları ve portları izleyin,Geçmiş çalışma süresi ve güvenilirlik trendlerini takip edin", - "title": "Bir çalışma süresi monitörü şunlar için kullanılır:" + "title": "Henüz çalışma süresi izleyicisi yok", + "description": "HTTP uç noktalarını, ping'leri, konteynerleri ve portları izleyin — bir şey kapandığında anında uyarı alın." + }, + "header": { + "title": "Çalışma süresi izleyicileri", + "description": "HTTP uç noktalarını, ping'leri, konteynerleri ve portları izleyin — bir şey kapandığında anında uyarı alın." } } } diff --git a/client/src/locales/uk.json b/client/src/locales/uk.json index 3872638aa..aede28a55 100644 --- a/client/src/locales/uk.json +++ b/client/src/locales/uk.json @@ -13,7 +13,7 @@ "content": "Увага: Ви ще не додали ключ API Google PageSpeed. Перейдіть у Налаштування, щоб додати його. Без нього моніторинг PageSpeed не працюватиме." } }, - "appName": "", + "appName": "Checkmate", "breadcrumbs": { "details": "Деталі", "home": "Головна" @@ -31,15 +31,15 @@ "inviteMember": "Запросити учасника", "pause": "Призупинити", "resume": "Відновити", - "save": "", + "save": "Зберегти", "sendInvite": "Надіслати запрошення", "test": "Тест", "testNotifications": "Тестові сповіщення", - "toggleTheme": "", + "toggleTheme": "Перемкнути світлу / темну", "flushQueue": "Очистити чергу", "notFound": "Перейти на головну панель", - "resetPassword": "", - "reset": "", + "resetPassword": "Скинути пароль", + "reset": "Скинути", "clear": "Очистити", "addDemo": "Додати демо-монітори", "removeMonitors": "Видалити монітори", @@ -53,8 +53,8 @@ "labels": { "averageResponseTime": "Середній час відповіді", "downtime": "Час простою", - "high": "", - "low": "", + "high": "Високий", + "low": "Низький", "uptime": "Час роботи" }, "histogram": { @@ -86,12 +86,12 @@ "name": { "option": { "firstName": { - "label": "", - "placeholder": "" + "label": "Ім'я", + "placeholder": "Введіть ім'я" }, "lastName": { - "label": "", - "placeholder": "" + "label": "Прізвище", + "placeholder": "Введіть прізвище" } } }, @@ -107,14 +107,14 @@ "table": { "empty": "Тут нічого немає", "headers": { - "actions": "", + "actions": "Дії", "dateTime": "Дата і час", "message": "Повідомлення", "monitor": "Монітор", "monitorId": "ID монітора", "name": "Ім'я", "status": "Статус", - "type": "", + "type": "Тип", "url": "URL", "interval": "Інтервал", "active": "Активний", @@ -125,17 +125,17 @@ "components": { "imageUpload": { "clickToUpload": "Натисніть, щоб завантажити", - "dragAndDrop": "", - "supportedFormats": "", - "maxSize": "", + "dragAndDrop": "або перетягніть", + "supportedFormats": "Підтримувані формати", + "maxSize": "Макс. розмір", "orDragAndDrop": "або перетягніть файл", "errors": { - "invalidFileSize": "", - "invalidFileFormat": "" + "invalidFileSize": "Розмір файлу занадто великий!", + "invalidFileFormat": "Непідтримуваний формат файлу!" } }, "headerStatusPageControls": { - "publicLink": "" + "publicLink": "Публічне посилання" }, "headerTimeRange": { "labels": { @@ -155,26 +155,26 @@ "serverUnreachable": "Не вдається з'єднатися з сервером", "retry": "Повторити", "retrying": "Повторна спроба...", - "reconnected": "" + "reconnected": "З'єднання відновлено" }, "sidebar": { "menu": { - "uptime": "", - "pagespeed": "", - "infrastructure": "", - "notifications": "", + "uptime": "Доступність", + "pagespeed": "Pagespeed", + "infrastructure": "Інфраструктура", + "notifications": "Сповіщення", "checks": "Перевірки", - "incidents": "", - "statusPages": "", - "maintenance": "", - "logs": "", - "settings": "" + "incidents": "Інциденти", + "statusPages": "Сторінки статусу", + "maintenance": "Обслуговування", + "logs": "Журнали", + "settings": "Налаштування" }, "bottomMenu": { - "support": "", - "discussions": "", - "docs": "", - "changelog": "" + "support": "Підтримка", + "discussions": "Обговорення", + "docs": "Документація", + "changelog": "Журнал змін" }, "accountMenu": { "profile": "Профіль", @@ -186,19 +186,27 @@ "description": "Переглядайте останні оновлення та допомагайте розвивати спільноту на GitHub" }, "authFooter": { - "navControls": "", - "logOut": "", + "navControls": "Керування", + "logOut": "Вийти", "roles": { "superAdmin": "Суперадміністратор", "admin": "Адміністратор", "user": "Користувач", - "demoUser": "" + "demoUser": "Демо-користувач" } } }, "starPrompt": { "title": "Оцінити Checkmate", "description": "Переглядайте останні оновлення та допомагайте розвивати спільноту на GitHub" + }, + "pageHeader": { + "links": { + "support": "Підтримка", + "discussions": "Обговорення", + "docs": "Документація", + "changelog": "Журнал змін" + } } }, "pages": { @@ -251,15 +259,15 @@ "team": { "filter": { "placeholder": "Фільтрувати за роллю", - "all": "", + "all": "Усі ролі", "admin": "Адміністратор", - "member": "" + "member": "Учасник" }, "table": { "headers": { "email": "Електронна пошта", - "role": "", - "created": "" + "role": "Роль", + "created": "Створено" } }, "addMember": { @@ -278,10 +286,23 @@ "placeholder": "Оберіть роль" }, "linkLabel": "Посилання для запрошення" + }, + "fallback": { + "title": "Поки що немає учасників команди", + "description": "Запросіть колег електронною поштою або додайте їх безпосередньо. Як тільки вони приєднаються, вони з'являться тут зі своєю роллю." } + }, + "header": { + "title": "Обліковий запис", + "description": "Керуйте профілем, паролем, командою та налаштуваннями робочого простору." } }, "auth": { + "brandPanel": { + "eyebrow": "Моніторинг інфраструктури з відкритим кодом", + "tagline": "Слідкуйте за кожним кроком ваших серверів.", + "description": "Моніторинг доступності, часу відгуку та інцидентів у реальному часі - self-hosted і належить вам." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Ласкаво просимо до Checkmate!", "subtitle": "Зареєструйтесь, щоб розпочати", - "submit": "Зареєструватися" + "submit": "Зареєструватися", + "setupNotice": "Ця сторінка доступна лише під час початкового налаштування. Після реєстрації суперадміністратора додаткових користувачів можна запросити з налаштувань команди." }, "forgotPassword": { "title": "Забули пароль?", @@ -378,6 +400,14 @@ "statusCode": "Код статусу", "location": "Розташування" } + }, + "fallback": { + "title": "Перевірок ще немає", + "description": "Як тільки ви створите монітор, кожна перевірка статусу та час відповіді з’являться тут." + }, + "header": { + "title": "Перевірки", + "description": "Кожне зондування, яке Checkmate виконує проти ваших моніторів, з'явиться тут з кодом статусу та часом відповіді." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Активний протягом", "certificateExpiry": "Закінчення сертифіката", "lastCheck": "Остання перевірка", - "lastResponseTime": "Останній час відповіді" + "lastResponseTime": "Останній час відповіді", + "serviceIsDown": "Сервіс недоступний" }, "status": { "down": "недоступний", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Інцидентів немає — усі системи справні", + "description": "Коли монітор виходить з ладу або відновлюється, інцидент з’явиться тут з часом, деталями монітора та історією вирішення." + }, "dialog": { "resolveIncident": { "title": "Вирішити інцидент", @@ -720,6 +755,10 @@ "active": "Активний", "resolved": "Вирішено" } + }, + "header": { + "title": "Інциденти", + "description": "Коли монітор виходить з ладу або відновлюється, інциденти з'являються тут з часом, деталями монітора та історією вирішення." } }, "infrastructure": { @@ -774,21 +813,31 @@ }, "fallback": { "actionButton": "Створити монітор!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Монітор інфраструктури використовується для:" + "title": "Ще немає моніторів інфраструктури", + "description": "Відстежуйте продуктивність серверів, виявляйте вузькі місця та забезпечуйте надійність з моніторингом у реальному часі." + }, + "header": { + "title": "Монітори інфраструктури", + "description": "Відстежуйте продуктивність серверів, виявляйте вузькі місця та забезпечуйте надійність з моніторингом у реальному часі." } }, "logs": { + "fallback": { + "title": "Поки що немає журналів", + "description": "Активність сервера, попередження та помилки з’являться тут під час роботи Checkmate." + }, "tabs": { "diagnostics": "Діагностика", - "logs": "", - "queue": "" + "logs": "Журнали", + "queue": "Черга завдань" }, "logLevelSelect": { "label": "Рівень логів" }, "jobQueue": "Черга завдань", + "jobQueueExplainer": "Виділені рядки — це завдання, які наразі обробляються воркером.", "failedJobs": "Невдалі завдання", + "failedJobsExplainer": "Останні збої за моніторами — час останнього збою, кількість збоїв і причина.", "noLogs": "Логи не знайдено", "metrics": { "jobs": "Завдання", @@ -815,6 +864,16 @@ "usedSPercentage": "% від 1с використано CPU", "total": "Усього", "used": "Використано" + }, + "sections": { + "runtimeStats": { + "title": "Статистика виконання", + "description": "Знімок процесу Node.js і хост-машини. Оновлюється кожні 5 секунд." + }, + "memoryCpu": { + "title": "Пам'ять і ЦП", + "description": "Як процес використовує виділену пам'ять і ЦП хоста." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Остання помилка", "failReason": "Причина помилки" } + }, + "queueFallback": { + "title": "У черзі немає завдань", + "description": "Заплановані або виконувані перевірки моніторів з’являться тут. Порожня черга означає, що все актуально." + }, + "header": { + "title": "Журнали та черга", + "description": "Перевіряйте серверні журнали, чергу завдань моніторів і діагностику в одному місці." } }, "maintenanceWindow": { "fallback": { "actionButton": "Створити вікно обслуговування!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Вікно обслуговування використовується для:" + "title": "Немає запланованих вікон обслуговування", + "description": "Плануйте планові простої, щоб сповіщення було пригнічено, а команда та користувачі знали, чого очікувати." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Вікна обслуговування", + "description": "Плануйте планові простої, щоб сповіщення було пригнічено, а команда та користувачі знали, чого очікувати." } }, "notifications": { "fallback": { "actionButton": "Створити канал", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Канали сповіщень використовуються для:" + "title": "Ще немає каналів сповіщень", + "description": "Підключіть Slack, Discord, електронну пошту, вебхуки та інше, щоб потрібні люди дізнавалися про інциденти одразу." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "ID чату", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Налаштування Pushover", + "description": "Введіть токен застосунку та ключ користувача Pushover.", + "optionAppToken": "Токен застосунку", + "placeholderAppToken": "Введіть токен застосунку", + "optionUserKey": "Ключ користувача", + "placeholderUserKey": "Введіть ключ користувача" + }, + "twilio": { + "title": "Налаштування Twilio", + "description": "Введіть облікові дані Twilio для надсилання SMS.", + "optionAccountSid": "SID акаунта", + "placeholderAccountSid": "Введіть SID акаунта", + "optionAuthToken": "Токен автентифікації", + "placeholderAuthToken": "Введіть токен автентифікації", + "optionFromNumber": "Номер відправника", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Номер отримувача", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Призначення" } + }, + "header": { + "title": "Сповіщення", + "description": "Підключіть Slack, Discord, електронну пошту, вебхуки та інше, щоб потрібні люди дізнавалися про інциденти одразу." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Створити монітор!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "Монітор PageSpeed використовується для:" + "title": "Ще немає моніторів PageSpeed", + "description": "Відстежуйте Core Web Vitals і оцінки Lighthouse у часі, щоб помітити регресії раніше за користувачів." + }, + "header": { + "title": "Монітори PageSpeed", + "description": "Відстежуйте Core Web Vitals і оцінки Lighthouse у часі, щоб помітити регресії раніше за користувачів." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Будь ласка, виправте такі помилки валідації:" } + }, + "header": { + "title": "Налаштування", + "description": "Налаштуйте SMTP, інтеграції, зберігання та загальну поведінку додатку." } }, "statusPages": { "deleteSuccess": "Сторінку статусу успішно видалено", "fallback": { - "title": "Сторінка статусу використовується для:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "Створити сторінку статусу!" + "title": "Ще немає сторінок статусу", + "actionButton": "Створити сторінку статусу!", + "description": "Опублікуйте публічну сторінку, що показує клієнтам і зацікавленим сторонам час роботи в реальному часі та історію інцидентів." }, "monitorsList": { "chartTypeHeatmap": "Теплова карта", @@ -1190,7 +1293,18 @@ "allDown": "Усі системи недоступні", "allUp": "Усі системи працюють", "degraded": "Деякі системи мають проблеми", - "unknown": "Неможливо визначити стан системи" + "unknown": "Неможливо визначити стан системи", + "allBreached": "Усі системи перевищили порогові значення", + "allMaintenance": "Усі системи на технічному обслуговуванні", + "allPaused": "Усі системи призупинено", + "allInitializing": "Усі системи ініціалізуються", + "breachedAndDown": "Деякі системи перевищили пороги та недоступні", + "breached": "Деякі системи перевищили пороги", + "maintenanceAndDown": "Деякі системи недоступні під час техобслуговування", + "maintenance": "Деякі системи на техобслуговуванні", + "partiallyPaused": "Деякі системи призупинено", + "initializing": "Деякі системи ініціалізуються", + "noMonitors": "Не налаштовано жодного монітора" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Сторінки статусу", + "description": "Публікуйте публічні сторінки з часом роботи в реальному часі та історією інцидентів для клієнтів і зацікавлених сторін." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Створити монітор!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Монітор доступності використовується для:" + "title": "Ще немає моніторів працездатності", + "description": "Спостерігайте за HTTP-кінцевими точками, пінгами, контейнерами та портами — отримуйте сповіщення в момент відмови." + }, + "header": { + "title": "Монітори працездатності", + "description": "Спостерігайте за HTTP-кінцевими точками, пінгами, контейнерами та портами — отримуйте сповіщення в момент відмови." } } } diff --git a/client/src/locales/vi.json b/client/src/locales/vi.json index f9963958b..a9f5cfbbc 100644 --- a/client/src/locales/vi.json +++ b/client/src/locales/vi.json @@ -13,7 +13,7 @@ "content": "Cảnh báo: Bạn chưa thêm khóa API Google PageSpeed. Truy cập Cài đặt để thêm. Nếu không có khóa này, trình giám sát PageSpeed sẽ không hoạt động." } }, - "appName": "", + "appName": "Checkmate", "breadcrumbs": { "details": "Chi tiết", "home": "Trang chủ" @@ -31,15 +31,15 @@ "inviteMember": "Mời thành viên", "pause": "Tạm dừng", "resume": "Tiếp tục", - "save": "", + "save": "Lưu", "sendInvite": "Gửi lời mời", "test": "Kiểm tra", "testNotifications": "Kiểm tra thông báo", - "toggleTheme": "", + "toggleTheme": "Chuyển sáng / tối", "flushQueue": "Xóa hàng đợi", "notFound": "Về bảng điều khiển chính", - "resetPassword": "", - "reset": "", + "resetPassword": "Đặt lại mật khẩu", + "reset": "Đặt lại", "clear": "Xóa", "addDemo": "Thêm trình giám sát mẫu", "removeMonitors": "Xóa trình giám sát", @@ -53,8 +53,8 @@ "labels": { "averageResponseTime": "Thời gian phản hồi trung bình", "downtime": "Thời gian ngừng hoạt động", - "high": "", - "low": "", + "high": "Cao", + "low": "Thấp", "uptime": "Thời gian hoạt động" }, "histogram": { @@ -86,12 +86,12 @@ "name": { "option": { "firstName": { - "label": "", - "placeholder": "" + "label": "Tên", + "placeholder": "Nhập tên của bạn" }, "lastName": { - "label": "", - "placeholder": "" + "label": "Họ", + "placeholder": "Nhập họ của bạn" } } }, @@ -107,14 +107,14 @@ "table": { "empty": "Không có dữ liệu", "headers": { - "actions": "", + "actions": "Hành động", "dateTime": "Ngày & giờ", "message": "Tin nhắn", "monitor": "Trình giám sát", "monitorId": "ID trình giám sát", "name": "Tên", "status": "Trạng thái", - "type": "", + "type": "Loại", "url": "Url", "interval": "Khoảng thời gian", "active": "Đang hoạt động", @@ -125,17 +125,17 @@ "components": { "imageUpload": { "clickToUpload": "Nhấn để tải lên", - "dragAndDrop": "", - "supportedFormats": "", - "maxSize": "", + "dragAndDrop": "hoặc kéo và thả", + "supportedFormats": "Định dạng hỗ trợ", + "maxSize": "Kích thước tối đa", "orDragAndDrop": "hoặc kéo và thả", "errors": { - "invalidFileSize": "", - "invalidFileFormat": "" + "invalidFileSize": "Tệp quá lớn!", + "invalidFileFormat": "Định dạng tệp không được hỗ trợ!" } }, "headerStatusPageControls": { - "publicLink": "" + "publicLink": "Liên kết công khai" }, "headerTimeRange": { "labels": { @@ -155,26 +155,26 @@ "serverUnreachable": "Không thể kết nối đến máy chủ", "retry": "Thử lại", "retrying": "Đang thử lại...", - "reconnected": "" + "reconnected": "Đã khôi phục kết nối" }, "sidebar": { "menu": { - "uptime": "", - "pagespeed": "", - "infrastructure": "", - "notifications": "", + "uptime": "Thời gian hoạt động", + "pagespeed": "Pagespeed", + "infrastructure": "Hạ tầng", + "notifications": "Thông báo", "checks": "Kiểm tra", - "incidents": "", - "statusPages": "", - "maintenance": "", - "logs": "", - "settings": "" + "incidents": "Sự cố", + "statusPages": "Trang trạng thái", + "maintenance": "Bảo trì", + "logs": "Nhật ký", + "settings": "Cài đặt" }, "bottomMenu": { - "support": "", - "discussions": "", - "docs": "", - "changelog": "" + "support": "Hỗ trợ", + "discussions": "Thảo luận", + "docs": "Tài liệu", + "changelog": "Nhật ký thay đổi" }, "accountMenu": { "profile": "Hồ sơ", @@ -186,19 +186,27 @@ "description": "Xem các bản phát hành mới nhất và giúp phát triển cộng đồng trên GitHub" }, "authFooter": { - "navControls": "", - "logOut": "", + "navControls": "Điều khiển", + "logOut": "Đăng xuất", "roles": { "superAdmin": "Quản trị viên cấp cao", "admin": "Quản trị viên", "user": "Người dùng", - "demoUser": "" + "demoUser": "Người dùng demo" } } }, "starPrompt": { "title": "Gắn sao Checkmate", "description": "Xem các bản phát hành mới nhất và giúp phát triển cộng đồng trên GitHub" + }, + "pageHeader": { + "links": { + "support": "Hỗ trợ", + "discussions": "Thảo luận", + "docs": "Tài liệu", + "changelog": "Nhật ký thay đổi" + } } }, "pages": { @@ -251,15 +259,15 @@ "team": { "filter": { "placeholder": "Lọc theo vai trò", - "all": "", + "all": "Tất cả vai trò", "admin": "Quản trị viên", - "member": "" + "member": "Thành viên" }, "table": { "headers": { "email": "Email", - "role": "", - "created": "" + "role": "Vai trò", + "created": "Đã tạo" } }, "addMember": { @@ -278,10 +286,23 @@ "placeholder": "Chọn vai trò" }, "linkLabel": "Liên kết mời" + }, + "fallback": { + "title": "Chưa có thành viên nhóm", + "description": "Mời đồng đội qua email hoặc thêm họ trực tiếp. Khi họ tham gia, họ sẽ xuất hiện tại đây với vai trò của họ." } + }, + "header": { + "title": "Tài khoản", + "description": "Quản lý hồ sơ, mật khẩu, đội ngũ và tùy chọn không gian làm việc." } }, "auth": { + "brandPanel": { + "eyebrow": "Giám sát hạ tầng mã nguồn mở", + "tagline": "Theo dõi mọi chuyển động của các máy chủ của bạn.", + "description": "Theo dõi thời gian hoạt động, thời gian phản hồi và sự cố theo thời gian thực - tự lưu trữ và thuộc về bạn." + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "Chào mừng bạn trở lại Checkmate!", "subtitle": "Đăng ký để bắt đầu", - "submit": "Đăng ký" + "submit": "Đăng ký", + "setupNotice": "Trang này chỉ khả dụng trong quá trình thiết lập ban đầu. Sau khi siêu quản trị viên được đăng ký, có thể mời thêm người dùng từ cài đặt nhóm." }, "forgotPassword": { "title": "Quên mật khẩu?", @@ -378,6 +400,14 @@ "statusCode": "Mã trạng thái", "location": "Vị trí" } + }, + "fallback": { + "title": "Chưa có kiểm tra nào", + "description": "Khi bạn tạo một trình giám sát, mỗi lần thăm dò trạng thái và thời gian phản hồi sẽ xuất hiện tại đây như một kiểm tra." + }, + "header": { + "title": "Kiểm tra", + "description": "Mỗi lần thăm dò mà Checkmate chạy trên trình giám sát của bạn sẽ xuất hiện tại đây với mã trạng thái và thời gian phản hồi." } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "Hoạt động từ", "certificateExpiry": "Hạn chứng chỉ", "lastCheck": "Lần kiểm tra cuối", - "lastResponseTime": "Thời gian phản hồi cuối" + "lastResponseTime": "Thời gian phản hồi cuối", + "serviceIsDown": "Dịch vụ đang ngừng hoạt động" }, "status": { "down": "ngừng hoạt động", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "Không có sự cố — tất cả hệ thống đều khỏe mạnh", + "description": "Khi một trình giám sát ngừng hoạt động hoặc phục hồi, sự cố sẽ xuất hiện tại đây kèm thời gian, chi tiết trình giám sát và lịch sử giải quyết." + }, "dialog": { "resolveIncident": { "title": "Giải quyết sự cố", @@ -720,6 +755,10 @@ "active": "Đang hoạt động", "resolved": "Đã giải quyết" } + }, + "header": { + "title": "Sự cố", + "description": "Khi một trình giám sát ngừng hoạt động hoặc phục hồi, sự cố sẽ xuất hiện tại đây kèm thời gian, chi tiết trình giám sát và lịch sử giải quyết." } }, "infrastructure": { @@ -774,21 +813,31 @@ }, "fallback": { "actionButton": "Tạo trình giám sát!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "Trình giám sát hạ tầng dùng để:" + "title": "Chưa có trình giám sát hạ tầng", + "description": "Theo dõi hiệu suất máy chủ, xác định nút thắt cổ chai và đảm bảo độ tin cậy với giám sát hạ tầng theo thời gian thực." + }, + "header": { + "title": "Trình giám sát hạ tầng", + "description": "Theo dõi hiệu suất máy chủ, xác định nút thắt cổ chai và đảm bảo độ tin cậy với giám sát hạ tầng theo thời gian thực." } }, "logs": { + "fallback": { + "title": "Chưa có nhật ký", + "description": "Hoạt động máy chủ, cảnh báo và lỗi sẽ xuất hiện tại đây khi Checkmate đang chạy." + }, "tabs": { "diagnostics": "Chẩn đoán", - "logs": "", - "queue": "" + "logs": "Nhật ký", + "queue": "Hàng đợi tác vụ" }, "logLevelSelect": { "label": "Mức nhật ký" }, "jobQueue": "Hàng đợi công việc", + "jobQueueExplainer": "Các hàng được làm nổi bật là các công việc hiện đang được worker xử lý.", "failedJobs": "Công việc thất bại", + "failedJobsExplainer": "Các lần thất bại gần đây theo trình giám sát — thời gian thất bại gần nhất, số lần thất bại và lý do.", "noLogs": "Không tìm thấy nhật ký", "metrics": { "jobs": "Công việc", @@ -815,6 +864,16 @@ "usedSPercentage": "% của 1 giây CPU sử dụng", "total": "Tổng", "used": "Đã dùng" + }, + "sections": { + "runtimeStats": { + "title": "Thống kê thời gian chạy", + "description": "Ảnh chụp nhanh tiến trình Node.js và máy chủ. Cập nhật mỗi 5 giây." + }, + "memoryCpu": { + "title": "Bộ nhớ & CPU", + "description": "Cách tiến trình sử dụng bộ nhớ được cấp phát và CPU của máy chủ." + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "Lỗi lần cuối lúc", "failReason": "Lý do lỗi" } + }, + "queueFallback": { + "title": "Hàng đợi không có công việc", + "description": "Các kiểm tra trình giám sát đã lên lịch hoặc đang chạy sẽ xuất hiện tại đây. Một hàng đợi trống có nghĩa là mọi thứ đều cập nhật." + }, + "header": { + "title": "Nhật ký & hàng đợi", + "description": "Kiểm tra nhật ký máy chủ, hàng đợi công việc giám sát và chẩn đoán runtime tại một nơi." } }, "maintenanceWindow": { "fallback": { "actionButton": "Tạo cửa sổ bảo trì!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "Cửa sổ bảo trì dùng để:" + "title": "Chưa có cửa sổ bảo trì nào được lên lịch", + "description": "Lên lịch thời gian chết để các cảnh báo được tạm dừng và đội ngũ cũng như người dùng biết điều cần mong đợi." }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "Cửa sổ bảo trì", + "description": "Lên lịch thời gian chết để các cảnh báo được tạm dừng và đội ngũ cũng như người dùng biết điều cần mong đợi." } }, "notifications": { "fallback": { "actionButton": "Tạo kênh", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "Kênh thông báo dùng để:" + "title": "Chưa có kênh thông báo", + "description": "Kết nối Slack, Discord, email, webhook và nhiều hơn để đúng người nhận được thông báo ngay khi có sự cố." }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "ID cuộc trò chuyện", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Cấu hình Pushover", + "description": "Nhập mã thông báo ứng dụng và khóa người dùng Pushover của bạn.", + "optionAppToken": "Mã thông báo ứng dụng", + "placeholderAppToken": "Nhập mã thông báo ứng dụng", + "optionUserKey": "Khóa người dùng", + "placeholderUserKey": "Nhập khóa người dùng" + }, + "twilio": { + "title": "Cấu hình Twilio", + "description": "Nhập thông tin xác thực tài khoản Twilio để gửi SMS.", + "optionAccountSid": "SID tài khoản", + "placeholderAccountSid": "Nhập SID tài khoản", + "optionAuthToken": "Mã thông báo xác thực", + "placeholderAuthToken": "Nhập mã thông báo xác thực", + "optionFromNumber": "Số gửi", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "Số nhận", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "Đích đến" } + }, + "header": { + "title": "Thông báo", + "description": "Kết nối Slack, Discord, email, webhook và nhiều hơn để đúng người nhận được thông báo ngay khi có sự cố." } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "Tạo trình giám sát!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "Trình giám sát PageSpeed dùng để:" + "title": "Chưa có trình giám sát PageSpeed", + "description": "Theo dõi Core Web Vitals và điểm Lighthouse theo thời gian để phát hiện sự suy giảm trước khi người dùng nhận ra." + }, + "header": { + "title": "Trình giám sát PageSpeed", + "description": "Theo dõi Core Web Vitals và điểm Lighthouse theo thời gian để phát hiện sự suy giảm trước khi người dùng nhận ra." } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "Vui lòng sửa các lỗi xác thực sau:" } + }, + "header": { + "title": "Cài đặt", + "description": "Cấu hình SMTP, tích hợp, lưu trữ và hành vi ứng dụng toàn cục." } }, "statusPages": { "deleteSuccess": "Đã xóa trang trạng thái thành công", "fallback": { - "title": "Trang trạng thái dùng để:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "Tạo trang trạng thái!" + "title": "Chưa có trang trạng thái", + "actionButton": "Tạo trang trạng thái!", + "description": "Công bố một trang công khai cho khách hàng và các bên liên quan thấy thời gian hoạt động theo thời gian thực và lịch sử sự cố." }, "monitorsList": { "chartTypeHeatmap": "Bản đồ nhiệt", @@ -1190,7 +1293,18 @@ "allDown": "Tất cả hệ thống đều ngừng hoạt động", "allUp": "Tất cả hệ thống đang hoạt động", "degraded": "Một số hệ thống đang gặp sự cố", - "unknown": "Không thể xác định trạng thái hệ thống" + "unknown": "Không thể xác định trạng thái hệ thống", + "allBreached": "Tất cả hệ thống đã vượt ngưỡng", + "allMaintenance": "Tất cả hệ thống đang bảo trì", + "allPaused": "Tất cả hệ thống đã tạm dừng", + "allInitializing": "Tất cả hệ thống đang khởi tạo", + "breachedAndDown": "Một số hệ thống đã vượt ngưỡng và đang ngừng hoạt động", + "breached": "Một số hệ thống đã vượt ngưỡng", + "maintenanceAndDown": "Một số hệ thống ngừng hoạt động trong quá trình bảo trì", + "maintenance": "Một số hệ thống đang bảo trì", + "partiallyPaused": "Một số hệ thống đã tạm dừng", + "initializing": "Một số hệ thống đang khởi tạo", + "noMonitors": "Chưa cấu hình màn hình giám sát nào" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "Trang trạng thái", + "description": "Công bố các trang công khai cho khách hàng và các bên liên quan thấy thời gian hoạt động theo thời gian thực và lịch sử sự cố." } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "Tạo trình giám sát!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "Trình giám sát hoạt động dùng để:" + "title": "Chưa có trình giám sát uptime", + "description": "Theo dõi các endpoint HTTP, ping, container và cổng — nhận cảnh báo ngay khi có sự cố." + }, + "header": { + "title": "Trình giám sát uptime", + "description": "Theo dõi các endpoint HTTP, ping, container và cổng — nhận cảnh báo ngay khi có sự cố." } } } diff --git a/client/src/locales/zh-CN.json b/client/src/locales/zh-CN.json index d6580e851..d305e660e 100644 --- a/client/src/locales/zh-CN.json +++ b/client/src/locales/zh-CN.json @@ -199,6 +199,14 @@ "starPrompt": { "title": "Star Checkmate", "description": "查看最新版本并在 GitHub 上帮助发展社区" + }, + "pageHeader": { + "links": { + "support": "支持", + "discussions": "讨论", + "docs": "文档", + "changelog": "更新日志" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "选择角色" }, "linkLabel": "邀请链接" + }, + "fallback": { + "title": "暂无团队成员", + "description": "通过电子邮件邀请队友或直接添加他们。一旦加入,他们将与角色一起显示在这里。" } + }, + "header": { + "title": "账户", + "description": "管理个人资料、密码、团队和工作区设置。" } }, "auth": { + "brandPanel": { + "eyebrow": "开源基础设施监控", + "tagline": "关注您服务器的每一步动作。", + "description": "实时跟踪运行状态、响应时间和事件 - 自托管,完全属于您。" + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "欢迎回到 Checkmate!", "subtitle": "注册以开始使用", - "submit": "注册" + "submit": "注册", + "setupNotice": "此页面仅在初始设置期间可用。注册超级管理员后,可以从团队设置中邀请更多用户。" }, "forgotPassword": { "title": "忘记密码了?", @@ -378,6 +400,14 @@ "statusCode": "状态码", "location": "位置" } + }, + "fallback": { + "title": "暂无检查", + "description": "创建监控器后,每次状态探测和响应时间都会以一次检查的形式显示在这里。" + }, + "header": { + "title": "检查", + "description": "Checkmate 对监控器执行的每次探测都会在此显示,包含状态码和响应时间。" } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "已活跃", "certificateExpiry": "证书到期", "lastCheck": "上次检查", - "lastResponseTime": "上次响应时间" + "lastResponseTime": "上次响应时间", + "serviceIsDown": "服务已停止" }, "status": { "down": "宕机", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "无事件 — 所有系统正常", + "description": "当监控器宕机或恢复时,事件将连同时间、监控器详情和解决记录一起显示在这里。" + }, "dialog": { "resolveIncident": { "title": "解决事件", @@ -720,6 +755,10 @@ "active": "活跃", "resolved": "已解决" } + }, + "header": { + "title": "事件", + "description": "当监控器宕机或恢复时,事件将连同时间、监控器详情和解决记录一起显示在这里。" } }, "infrastructure": { @@ -774,11 +813,19 @@ }, "fallback": { "actionButton": "创建监控!", - "checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring", - "title": "基础设施监控用于:" + "title": "暂无基础设施监控器", + "description": "跟踪服务器性能、识别瓶颈,通过实时基础设施监控确保可靠性。" + }, + "header": { + "title": "基础设施监控器", + "description": "跟踪服务器性能、识别瓶颈,通过实时基础设施监控确保可靠性。" } }, "logs": { + "fallback": { + "title": "暂无日志", + "description": "Checkmate 运行时的服务器活动、警告和错误将显示在这里。" + }, "tabs": { "diagnostics": "诊断", "logs": "服务器日志", @@ -788,7 +835,9 @@ "label": "日志级别" }, "jobQueue": "作业队列", + "jobQueueExplainer": "高亮的行是当前正在被工作进程处理的作业。", "failedJobs": "失败作业", + "failedJobsExplainer": "按监控的最近失败 — 最近失败时间、失败次数及原因。", "noLogs": "未找到日志", "metrics": { "jobs": "作业", @@ -815,6 +864,16 @@ "usedSPercentage": "CPU 1 秒使用百分比", "total": "总计", "used": "已使用" + }, + "sections": { + "runtimeStats": { + "title": "运行时统计", + "description": "Node.js 进程和主机的快照。每 5 秒更新一次。" + }, + "memoryCpu": { + "title": "内存与 CPU", + "description": "进程如何使用其分配的内存和主机 CPU。" + } } }, "table": { @@ -833,13 +892,21 @@ "lastFailedAt": "上次失败于", "failReason": "失败原因" } + }, + "queueFallback": { + "title": "队列中没有任务", + "description": "已安排或正在运行的监控检查将显示在这里。空队列意味着一切都是最新的。" + }, + "header": { + "title": "日志与队列", + "description": "在一处查看服务器日志、监控器作业队列和运行时诊断。" } }, "maintenanceWindow": { "fallback": { "actionButton": "创建维护窗口!", - "checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows", - "title": "维护窗口用于:" + "title": "暂无计划维护窗口", + "description": "安排计划停机时间以抑制告警,让团队和用户知晓预期。" }, "table": { "headers": { @@ -891,13 +958,17 @@ } } } + }, + "header": { + "title": "维护窗口", + "description": "安排计划停机时间以抑制告警,让团队和用户知晓预期。" } }, "notifications": { "fallback": { "actionButton": "创建渠道", - "checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes", - "title": "通知渠道用于:" + "title": "暂无通知渠道", + "description": "连接 Slack、Discord、邮件、Webhook 等,让事件发生时正确的人立即收到通知。" }, "form": { "accessToken": { @@ -947,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "聊天 ID", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Pushover 配置", + "description": "输入您的 Pushover 应用令牌和用户密钥。", + "optionAppToken": "应用令牌", + "placeholderAppToken": "输入应用令牌", + "optionUserKey": "用户密钥", + "placeholderUserKey": "输入用户密钥" + }, + "twilio": { + "title": "Twilio 配置", + "description": "输入 Twilio 帐户凭据以发送短信。", + "optionAccountSid": "帐户 SID", + "placeholderAccountSid": "输入帐户 SID", + "optionAuthToken": "认证令牌", + "placeholderAuthToken": "输入认证令牌", + "optionFromNumber": "发送号码", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "接收号码", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "目标" } + }, + "header": { + "title": "通知", + "description": "连接 Slack、Discord、邮件、Webhook 等,让事件发生时正确的人立即收到通知。" } }, "pageSpeed": { @@ -979,8 +1074,12 @@ }, "fallback": { "actionButton": "创建监控!", - "checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved", - "title": "PageSpeed 监控用于:" + "title": "暂无 PageSpeed 监控器", + "description": "持续追踪 Core Web Vitals 和 Lighthouse 评分,在用户察觉之前发现性能回退。" + }, + "header": { + "title": "PageSpeed 监控器", + "description": "持续追踪 Core Web Vitals 和 Lighthouse 评分,在用户察觉之前发现性能回退。" } }, "settings": { @@ -1158,14 +1257,18 @@ "validation": { "errorMessage": "请修复以下验证错误:" } + }, + "header": { + "title": "设置", + "description": "配置 SMTP、集成、保留和全局应用行为。" } }, "statusPages": { "deleteSuccess": "状态页已成功删除", "fallback": { - "title": "状态页用于:", - "checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents", - "actionButton": "创建状态页!" + "title": "暂无状态页面", + "actionButton": "创建状态页!", + "description": "发布一个公开页面,向客户和利益相关者展示实时运行情况和事件历史。" }, "monitorsList": { "chartTypeHeatmap": "热力图", @@ -1190,7 +1293,18 @@ "allDown": "所有系统已宕机", "allUp": "所有系统运行正常", "degraded": "部分系统正在出现问题", - "unknown": "无法确定系统状态" + "unknown": "无法确定系统状态", + "allBreached": "所有系统已超过阈值", + "allMaintenance": "所有系统正在维护中", + "allPaused": "所有系统已暂停", + "allInitializing": "所有系统正在初始化", + "breachedAndDown": "部分系统超过阈值且已停止", + "breached": "部分系统超过阈值", + "maintenanceAndDown": "部分系统在维护期间停止", + "maintenance": "部分系统正在维护", + "partiallyPaused": "部分系统已暂停", + "initializing": "部分系统正在初始化", + "noMonitors": "尚未配置任何监控器" }, "table": { "headers": { @@ -1282,6 +1396,10 @@ } } } + }, + "header": { + "title": "状态页面", + "description": "发布公开页面,向客户和利益相关者展示实时运行情况和事件历史。" } }, "uptime": { @@ -1297,8 +1415,12 @@ }, "fallback": { "actionButton": "创建监控!", - "checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends", - "title": "正常运行时间监控用于:" + "title": "暂无运行时间监控器", + "description": "监控 HTTP 端点、Ping、容器和端口 — 一旦故障即刻收到提醒。" + }, + "header": { + "title": "运行时间监控器", + "description": "监控 HTTP 端点、Ping、容器和端口 — 一旦故障即刻收到提醒。" } } } diff --git a/client/src/locales/zh-TW.json b/client/src/locales/zh-TW.json index 16aca7ed8..17516d71f 100644 --- a/client/src/locales/zh-TW.json +++ b/client/src/locales/zh-TW.json @@ -199,6 +199,14 @@ "starPrompt": { "title": "為 Checkmate 加星", "description": "查看最新版本並在 GitHub 上幫助社群成長" + }, + "pageHeader": { + "links": { + "support": "支援", + "discussions": "討論", + "docs": "文件", + "changelog": "更新日誌" + } } }, "pages": { @@ -278,10 +286,23 @@ "placeholder": "選擇角色" }, "linkLabel": "邀請連結" + }, + "fallback": { + "title": "尚無團隊成員", + "description": "透過電子郵件邀請隊友或直接新增他們。一旦加入,他們將與角色一起顯示在此。" } + }, + "header": { + "title": "帳號", + "description": "管理個人資料、密碼、團隊和工作區設定。" } }, "auth": { + "brandPanel": { + "eyebrow": "開源基礎設施監控", + "tagline": "關注您伺服器的每一步動作。", + "description": "即時追蹤運行狀態、回應時間和事件 - 自主託管,完全屬於您。" + }, "common": { "passwordRules": { "length": { @@ -343,7 +364,8 @@ "register": { "title": "歡迎回到 Checkmate!", "subtitle": "註冊以開始使用", - "submit": "註冊" + "submit": "註冊", + "setupNotice": "此頁面僅在初始設定期間可用。註冊超級管理員後,可以從團隊設定中邀請更多使用者。" }, "forgotPassword": { "title": "忘記密碼了嗎?", @@ -378,6 +400,14 @@ "statusCode": "狀態碼", "location": "位置" } + }, + "fallback": { + "title": "尚無檢查", + "description": "建立監視器後,每次狀態探測與回應時間都會以一次檢查的形式顯示在此。" + }, + "header": { + "title": "檢查", + "description": "Checkmate 對您的監視器執行的每次探測都會在此顯示,包含狀態碼與回應時間。" } }, "common": { @@ -397,7 +427,8 @@ "activeFor": "已啟用", "certificateExpiry": "憑證到期", "lastCheck": "最後檢查", - "lastResponseTime": "最後回應時間" + "lastResponseTime": "最後回應時間", + "serviceIsDown": "服務已停止" }, "status": { "down": "離線", @@ -640,6 +671,10 @@ } }, "incidents": { + "fallback": { + "title": "無事件 — 所有系統健康", + "description": "當監視器宕機或恢復時,事件將連同時間、監視器詳情與解決紀錄一起顯示在此。" + }, "dialog": { "resolveIncident": { "title": "解決事件", @@ -720,6 +755,10 @@ "active": "啟用中", "resolved": "已解決" } + }, + "header": { + "title": "事件", + "description": "當監視器宕機或恢復時,事件將連同時間、監視器詳情與解決紀錄一起顯示在此。" } }, "infrastructure": { @@ -774,15 +813,19 @@ }, "fallback": { "actionButton": "建立監控!", - "checks": [ - "追蹤您伺服器的效能", - "找出瓶頸並最佳化使用", - "透過即時監控確保可靠性" - ], - "title": "基礎架構監控用於:" + "title": "尚無基礎設施監視器", + "description": "追蹤伺服器效能、找出瓶頸,透過即時基礎設施監控確保可靠性。" + }, + "header": { + "title": "基礎設施監視器", + "description": "追蹤伺服器效能、找出瓶頸,透過即時基礎設施監控確保可靠性。" } }, "logs": { + "fallback": { + "title": "尚無日誌", + "description": "Checkmate 運行時的伺服器活動、警告與錯誤將顯示在此。" + }, "tabs": { "diagnostics": "診斷", "logs": "日誌", @@ -792,7 +835,9 @@ "label": "日誌等級" }, "jobQueue": "工作佇列", + "jobQueueExplainer": "反白的列是目前正由工作程序處理的工作。", "failedJobs": "失敗的工作", + "failedJobsExplainer": "依監控的最近失敗 — 最近失敗時間、失敗次數及原因。", "noLogs": "找不到日誌", "metrics": { "jobs": "工作", @@ -819,6 +864,16 @@ "usedSPercentage": "CPU 使用 1 秒百分比", "total": "總計", "used": "已使用" + }, + "sections": { + "runtimeStats": { + "title": "執行階段統計", + "description": "Node.js 程序和主機的快照。每 5 秒更新一次。" + }, + "memoryCpu": { + "title": "記憶體與 CPU", + "description": "程序如何使用其分配的記憶體和主機 CPU。" + } } }, "table": { @@ -837,13 +892,21 @@ "lastFailedAt": "最後失敗於", "failReason": "失敗原因" } + }, + "queueFallback": { + "title": "佇列中沒有任務", + "description": "已排定或正在執行的監視器檢查將顯示在此。空佇列代表一切都是最新狀態。" + }, + "header": { + "title": "日誌與佇列", + "description": "在一處查看伺服器日誌、監視器作業佇列和執行時診斷。" } }, "maintenanceWindow": { "fallback": { "actionButton": "建立維護時段!", - "checks": ["標記您的維護期間", "消除任何誤解", "在維護時段停止發送警報"], - "title": "維護時段用於:" + "title": "尚無排定的維護時段", + "description": "安排計畫性停機,抑制警報,並讓團隊和使用者知曉預期狀況。" }, "table": { "headers": { @@ -895,17 +958,17 @@ } } } + }, + "header": { + "title": "維護時段", + "description": "安排計畫性停機,抑制警報,並讓團隊和使用者知曉預期狀況。" } }, "notifications": { "fallback": { "actionButton": "建立頻道", - "checks": [ - "針對停機或效能問題通知團隊", - "在事件發生時通知工程師", - "讓管理員隨時了解系統變更" - ], - "title": "通知頻道用於:" + "title": "尚無通知頻道", + "description": "連接 Slack、Discord、電子郵件、Webhook 等,讓事件發生時正確的人立即收到通知。" }, "form": { "accessToken": { @@ -955,12 +1018,36 @@ "placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", "optionChatId": "聊天室 ID", "placeholderChatId": "-1001234567890" + }, + "pushover": { + "title": "Pushover 設定", + "description": "輸入您的 Pushover 應用程式權杖和使用者金鑰。", + "optionAppToken": "應用程式權杖", + "placeholderAppToken": "輸入應用程式權杖", + "optionUserKey": "使用者金鑰", + "placeholderUserKey": "輸入使用者金鑰" + }, + "twilio": { + "title": "Twilio 設定", + "description": "輸入 Twilio 帳戶憑證以傳送簡訊。", + "optionAccountSid": "帳戶 SID", + "placeholderAccountSid": "輸入帳戶 SID", + "optionAuthToken": "驗證權杖", + "placeholderAuthToken": "輸入驗證權杖", + "optionFromNumber": "發送號碼", + "placeholderFromNumber": "+1234567890", + "optionToNumber": "接收號碼", + "placeholderToNumber": "+1234567890" } }, "table": { "headers": { "destination": "目的地" } + }, + "header": { + "title": "通知", + "description": "連接 Slack、Discord、電子郵件、Webhook 等,讓事件發生時正確的人立即收到通知。" } }, "pageSpeed": { @@ -987,8 +1074,12 @@ }, "fallback": { "actionButton": "建立監控!", - "checks": ["報告頁面的使用者體驗", "協助分析網頁速度", "提供頁面改善建議"], - "title": "PageSpeed 監控用於:" + "title": "尚無 PageSpeed 監視器", + "description": "持續追蹤 Core Web Vitals 與 Lighthouse 評分,在使用者察覺前發現效能退化。" + }, + "header": { + "title": "PageSpeed 監視器", + "description": "持續追蹤 Core Web Vitals 與 Lighthouse 評分,在使用者察覺前發現效能退化。" } }, "settings": { @@ -1166,19 +1257,18 @@ "validation": { "errorMessage": "請修正以下驗證錯誤:" } + }, + "header": { + "title": "設定", + "description": "設定 SMTP、整合、保留與全域應用程式行為。" } }, "statusPages": { "deleteSuccess": "狀態頁面已成功刪除", "fallback": { - "title": "狀態頁面用於:", - "checks": [ - "向使用者和利害關係人傳達系統狀態", - "公開顯示即時正常運行時間資訊", - "透過透明的服務監控建立信任", - "在事件期間減少支援請求" - ], - "actionButton": "建立狀態頁面!" + "title": "尚無狀態頁面", + "actionButton": "建立狀態頁面!", + "description": "發佈一個公開頁面,向客戶和利害關係人顯示即時的運行狀態與事件歷史。" }, "monitorsList": { "chartTypeHeatmap": "熱力圖", @@ -1203,7 +1293,18 @@ "allDown": "所有系統已停機", "allUp": "所有系統運作正常", "degraded": "部分系統正在發生問題", - "unknown": "無法判斷系統狀態" + "unknown": "無法判斷系統狀態", + "allBreached": "所有系統已超過閾值", + "allMaintenance": "所有系統正在維護中", + "allPaused": "所有系統已暫停", + "allInitializing": "所有系統正在初始化", + "breachedAndDown": "部分系統超過閾值且已停止", + "breached": "部分系統超過閾值", + "maintenanceAndDown": "部分系統在維護期間停止", + "maintenance": "部分系統正在維護", + "partiallyPaused": "部分系統已暫停", + "initializing": "部分系統正在初始化", + "noMonitors": "尚未設定任何監視器" }, "table": { "headers": { @@ -1295,6 +1396,10 @@ } } } + }, + "header": { + "title": "狀態頁面", + "description": "發佈公開頁面,向客戶和利害關係人顯示即時的運行狀態與事件歷史。" } }, "uptime": { @@ -1310,13 +1415,12 @@ }, "fallback": { "actionButton": "建立監控!", - "checks": [ - "檢查網站或伺服器是否上線並回應", - "針對停機或效能問題通知團隊", - "監控 HTTP 端點、Ping、容器和連接埠", - "追蹤歷史正常運行時間和可靠性趨勢" - ], - "title": "正常運行時間監控用於:" + "title": "尚無運行時間監視器", + "description": "監控 HTTP 端點、Ping、容器和連接埠 — 一旦發生故障即刻收到提醒。" + }, + "header": { + "title": "運行時間監視器", + "description": "監控 HTTP 端點、Ping、容器和連接埠 — 一旦發生故障即刻收到提醒。" } } } diff --git a/client/vite.config.ts b/client/vite.config.ts index 075bc7a0b..f04ef8c45 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -3,17 +3,28 @@ import react from "@vitejs/plugin-react"; import svgr from "vite-plugin-svgr"; import path from "path"; import { fileURLToPath } from "url"; +import { readFileSync } from "fs"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export default defineConfig(({}) => { - let version = "3.6.1"; + const pkg = JSON.parse(readFileSync(path.resolve(__dirname, "package.json"), "utf-8")); + const version = pkg.version; + + const allowedHosts = process.env.VITE_ALLOWED_HOSTS + ? process.env.VITE_ALLOWED_HOSTS.split(",").map((h) => h.trim()) + : true; return { base: "/", plugins: [svgr(), react()], server: { host: true, + allowedHosts, + }, + preview: { + host: true, + allowedHosts, }, resolve: { alias: { diff --git a/docs/README.md b/docs/README.md index dc245e21e..b8904d1f9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -35,4 +35,4 @@ If you find issues or want to improve the documentation: - [GitHub Discussions](https://github.com/bluewave-labs/checkmate/discussions) - [Discord Channel](https://discord.gg/NAb6H3UTjK) -- [Documentation Portal](https://docs.checkmate.so/) +- [Documentation Portal](https://checkmate.so/docs) diff --git a/docs/infrastructure-disk-selection.md b/docs/infrastructure-disk-selection.md index 500e3be1e..bcfca165b 100644 --- a/docs/infrastructure-disk-selection.md +++ b/docs/infrastructure-disk-selection.md @@ -70,5 +70,5 @@ When you select specific disks, the following elements are filtered: ## Related Documentation -- [Infrastructure Monitoring Setup](https://docs.checkmate.so/checkmate-2.1) +- [Infrastructure Monitoring Setup](https://checkmate.so/docs) - [Capture Agent Installation](https://github.com/bluewave-labs/capture) \ No newline at end of file diff --git a/server/openapi.json b/server/openapi.json index de0103a38..cfb1c5aa4 100644 --- a/server/openapi.json +++ b/server/openapi.json @@ -597,8 +597,79 @@ "schema": { "type": "integer", "minimum": 1, - "maximum": 50, - "default": 10 + "maximum": 100 + } + }, + { + "name": "page", + "in": "query", + "description": "Zero-based page index for pagination", + "schema": { + "type": "integer", + "minimum": 0 + } + }, + { + "name": "rowsPerPage", + "in": "query", + "description": "Number of monitors per page", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100 + } + }, + { + "name": "filter", + "in": "query", + "description": "Search filter value", + "schema": { + "type": "string" + } + }, + { + "name": "field", + "in": "query", + "description": "Field to sort by", + "schema": { + "type": "string" + } + }, + { + "name": "order", + "in": "query", + "description": "Sort order", + "schema": { + "type": "string", + "enum": ["asc", "desc"] + } + }, + { + "name": "type", + "in": "query", + "description": "Filter by monitor type", + "schema": { + "oneOf": [ + { + "type": "string", + "enum": ["http", "ping", "pagespeed", "docker", "hardware", "port", "game", "grpc", "websocket"] + }, + { + "type": "array", + "items": { + "type": "string", + "enum": ["http", "ping", "pagespeed", "docker", "hardware", "port", "game", "grpc", "websocket"] + } + } + ] + } + }, + { + "name": "explain", + "in": "query", + "description": "Include MongoDB query explain output (debug)", + "schema": { + "type": "boolean" } } ], diff --git a/server/src/controllers/notificationController.ts b/server/src/controllers/notificationController.ts index 0a49cbdb1..301c15446 100644 --- a/server/src/controllers/notificationController.ts +++ b/server/src/controllers/notificationController.ts @@ -37,13 +37,9 @@ class NotificationController implements INotificationController { const notification = testNotificationBodyValidation.parse(req.body); const success = await this.notificationsService.sendTestNotification(notification); - if (!success) { - throw new AppError({ message: "Sending notification failed", status: 500 }); - } - return res.status(200).json({ - success: true, - msg: "Notification sent successfully", + success, + msg: success ? "Notification sent successfully" : "Notification could not be sent — check the destination details.", details: { service: SERVICE_NAME }, }); } catch (error) { diff --git a/server/src/db/models/Check.ts b/server/src/db/models/Check.ts index 541abb4d9..964936af9 100644 --- a/server/src/db/models/Check.ts +++ b/server/src/db/models/Check.ts @@ -271,6 +271,7 @@ const CheckSchema = new Schema( { timestamps: true, strict: false, + suppressReservedKeysWarning: true, timeseries: { timeField: "createdAt", metaField: "metadata",