From 9c21d71c4491474f5e14b388104612249eeed3c9 Mon Sep 17 00:00:00 2001 From: gorkem-bwl Date: Tue, 28 Apr 2026 23:54:39 -0400 Subject: [PATCH 1/8] refactor(inputs): softer button hover, sx-forwarding TextInput, themed FieldLabel - Button.tsx: contained variant's hover now uses HOVER.DARKEN=0.06 instead of MUI's default 16%, which was visibly heavy on the green primary buttons across the app. Also fixes a subtle bug where the earlier hover sx merge order silently dropped the boxShadow:'none' reset. Added a HOVER token group to constants.ts so the darken value has a single source of truth. - TextInput.tsx: forward the caller's sx to the wrapper Stack when a fieldLabel is present (previously it was applied to the inner TextField, so flex:1 etc. didn't propagate to the visible width). Inner sx now also explicitly width:100% so wrapped inputs don't collapse to content width when their parent is a flex row. - FieldLabel.tsx: drop the hardcoded fontSize:'14px' and use variant=body1 (=13px from theme) to match the rest of the app's body typography. --- client/src/Components/inputs/Button.tsx | 40 ++++++++++--- client/src/Components/inputs/FieldLabel.tsx | 2 +- client/src/Components/inputs/TextInput.tsx | 62 +++++++++++---------- client/src/Utils/Theme/constants.ts | 4 ++ 4 files changed, 70 insertions(+), 38 deletions(-) diff --git a/client/src/Components/inputs/Button.tsx b/client/src/Components/inputs/Button.tsx index 54f776075..4eae654b2 100644 --- a/client/src/Components/inputs/Button.tsx +++ b/client/src/Components/inputs/Button.tsx @@ -1,19 +1,43 @@ import Button from "@mui/material/Button"; import type { ButtonProps } from "@mui/material/Button"; -import { useTheme } from "@mui/material/styles"; +import { useTheme, darken } from "@mui/material/styles"; +import { HOVER } from "@/Utils/Theme/constants"; + +const PALETTE_COLORS = [ + "primary", + "secondary", + "error", + "warning", + "info", + "success", +] as const; +type PaletteColor = (typeof PALETTE_COLORS)[number]; export const ButtonInput = ({ sx, ...props }: ButtonProps) => { const theme = useTheme(); - const outlinedSx = + + const hoverOverrides: Record = { boxShadow: "none" }; + + if (props.variant === "outlined") { + hoverOverrides.borderColor = theme.palette.text.secondary; + } + + if (props.variant === "contained") { + const colorKey = (props.color ?? "primary") as PaletteColor; + const palette = theme.palette[colorKey]; + if (palette && typeof palette === "object" && "main" in palette) { + hoverOverrides.backgroundColor = darken(palette.main, HOVER.DARKEN); + } + } + + const variantSx = props.variant === "outlined" ? { color: theme.palette.text.primary, borderColor: theme.palette.divider, - "&:hover": { - borderColor: theme.palette.text.secondary, - }, } : {}; + return ( } > - + Date: Tue, 28 Apr 2026 23:56:10 -0400 Subject: [PATCH 3/8] feat(incidents): consistent typography, icons, and layout across the page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - All uppercase headers (Active Incidents, Latest Incidents, Incident Statistics, Resolved Incidents, summary card titles, details card sections) now use the existing 'eyebrow' typography variant. That's the same style used on the Logs page and lives in Theme.ts so future tweaks land in one place. - Latest Incidents and Incident Statistics rows now share a minHeight so both cards line up vertically; Latest Incidents items dropped their extra dividers and Box wrappers. - Body text in the summary cards (and the details dialog) uses variant=body1 (13px) consistently — previously a mix of body1/body2 and unspecified Typography. - All lucide icons in CardSummary go through the design-system wrapper so they share the project's strokeWidth=1.5 default rather than lucide's default 2. - ControlsIncidentFilter: replaced the missing pages.incidents.filters.clearFilters key (which was rendering as raw text) with the existing common.buttons.clearFilters. - CardDetails: extracted local SectionHeading and Cell helpers; switched the cards' bare cells to variant=body1 + variant=eyebrow for headings; dropped redundant title-dividers (eyebrow style already separates visually). --- .../Incidents/Components/CardDetails.tsx | 100 +++++++++--------- .../Incidents/Components/CardSummary.tsx | 63 +++++------ .../Components/ControlsIncidentFilter.tsx | 2 +- client/src/Pages/Incidents/index.tsx | 11 +- 4 files changed, 85 insertions(+), 91 deletions(-) diff --git a/client/src/Pages/Incidents/Components/CardDetails.tsx b/client/src/Pages/Incidents/Components/CardDetails.tsx index 448ba2e69..c4ae3a83d 100644 --- a/client/src/Pages/Incidents/Components/CardDetails.tsx +++ b/client/src/Pages/Incidents/Components/CardDetails.tsx @@ -20,6 +20,20 @@ interface CardDetailsProps { sx?: object; } +const SectionHeading = ({ children }: { children: React.ReactNode }) => ( + + {children} + +); + +const Cell = ({ children }: { children: React.ReactNode }) => ( + {children} +); + export const CardDetails = ({ incident, monitor, sx }: CardDetailsProps) => { const { t } = useTranslation(); const theme = useTheme(); @@ -33,22 +47,18 @@ export const CardDetails = ({ incident, monitor, sx }: CardDetailsProps) => { gap={theme.spacing(LAYOUT.MD)} sx={sx} > - - {t("pages.incidents.dialog.details.title")} - + {t("pages.incidents.dialog.details.title")} - - {t("pages.incidents.dialog.details.overview")} - - - + {t("pages.incidents.dialog.details.overview")} - {t("pages.incidents.dialog.details.status")} + + {t("pages.incidents.dialog.details.status")} + { {monitor && ( <> - {t("pages.incidents.dialog.details.monitor")} + + {t("pages.incidents.dialog.details.monitor")} + - {monitor.name ?? "N/A"} + {monitor.name ?? "N/A"} - {t("pages.incidents.dialog.details.url")} + {t("pages.incidents.dialog.details.url")} - {monitor.url ?? "N/A"} + {monitor.url ?? "N/A"} )} @@ -78,51 +90,48 @@ export const CardDetails = ({ incident, monitor, sx }: CardDetailsProps) => { - - {t("pages.incidents.dialog.details.analysis")} - - + {t("pages.incidents.dialog.details.analysis")} - {t("pages.incidents.dialog.details.timeline")} + {t("pages.incidents.dialog.details.timeline")} - {t("pages.incidents.dialog.details.detailsLabel")} + {t("pages.incidents.dialog.details.detailsLabel")} - + - + - {t("pages.incidents.dialog.details.startedAt")} + {t("pages.incidents.dialog.details.startedAt")} - + {formatDateWithTz(incident.startTime, "D MMM YYYY, h:mm A", uiTimezone)} - + - {t("pages.incidents.dialog.details.statusCode")} + {t("pages.incidents.dialog.details.statusCode")} - {incident.statusCode ?? "N/A"} + {incident.statusCode ?? "N/A"} - {t("pages.incidents.dialog.details.downtime")} + {t("pages.incidents.dialog.details.downtime")} - {getIncidentsDuration(incident)} + {getIncidentsDuration(incident)} - {t("pages.incidents.dialog.details.message")} + {t("pages.incidents.dialog.details.message")} - {incident.message ?? "N/A"} + {incident.message ?? "N/A"} @@ -130,60 +139,53 @@ export const CardDetails = ({ incident, monitor, sx }: CardDetailsProps) => { {!incident.status && ( - + {t("pages.incidents.dialog.details.resolutionDetails")} - - + - {t("pages.incidents.dialog.details.resolvedAt")} + {t("pages.incidents.dialog.details.resolvedAt")} - + {incident.endTime ? formatDateWithTz(incident.endTime, "D MMM YYYY, h:mm A", uiTimezone) : "N/A"} - + - - {t("pages.incidents.dialog.details.resolutionType")} - + {t("pages.incidents.dialog.details.resolutionType")} - + {incident.resolutionType ? t( `pages.incidents.dialog.details.resolutionTypes.${incident.resolutionType}` ) : "N/A"} - + {incident.resolvedBy && ( <> - - {t("pages.incidents.dialog.details.resolvedBy")} - + {t("pages.incidents.dialog.details.resolvedBy")} - - {incident.resolvedByEmail ?? incident.resolvedBy} - + {incident.resolvedByEmail ?? incident.resolvedBy} )} {incident.comment && ( <> - {t("pages.incidents.dialog.details.comment")} + {t("pages.incidents.dialog.details.comment")} - {incident.comment} + {incident.comment} )} diff --git a/client/src/Pages/Incidents/Components/CardSummary.tsx b/client/src/Pages/Incidents/Components/CardSummary.tsx index 938455808..ae75f5f37 100644 --- a/client/src/Pages/Incidents/Components/CardSummary.tsx +++ b/client/src/Pages/Incidents/Components/CardSummary.tsx @@ -1,8 +1,7 @@ import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; -import Divider from "@mui/material/Divider"; import Grid from "@mui/material/Grid"; -import { BaseBox, ValueLabel } from "@/Components/design-elements"; +import { BaseBox, Icon, ValueLabel } from "@/Components/design-elements"; import { CircleCheck, TriangleAlert, Bell, Wrench, Globe } from "lucide-react"; import Box from "@mui/material/Box"; @@ -25,6 +24,7 @@ const SummaryItem = ({ icon, label, value }: SummaryItemProps) => { alignItems="center" justifyContent="space-between" gap={theme.spacing(2)} + minHeight={32} > { gap={theme.spacing(2)} > {icon} - {label} + {label} {value} @@ -67,15 +67,11 @@ export const SummaryCard = ({ > {title} - {children} @@ -97,10 +93,13 @@ export const SummaryCardActiveIncidents = ({ const activeCount = summary.totalActive; const hasActive = activeCount > 0; const color = hasActive ? theme.palette.error.main : theme.palette.success.main; - const icon = hasActive ? ( - - ) : ( - + const icon = ( + + + ); const msg = t("pages.incidents.summaryCard.activeIncidents.active", { count: activeCount, @@ -133,10 +132,7 @@ const SummaryIncidentItem = ({ incident }: { incident: IncidentSummaryItem }) => container alignItems="center" spacing={2} - sx={{ - width: "100%", - py: theme.spacing(0.5), - }} + sx={{ width: "100%", minHeight: 32 }} > gap: theme.spacing(2), }} > - + size={{ xs: 12, md: 6, lg: 4 }} sx={{ textAlign: { xs: "left", md: "right" }, - fontWeight: 500, + fontWeight: 600, }} > {duration} @@ -190,22 +184,17 @@ export const SummaryCardLatestIncidents = ({ summary, }: SummaryCardLatestIncidentsProps) => { const { t } = useTranslation(); - const theme = useTheme(); const latestIncidents = summary?.latestIncidents ?? []; return ( - - {latestIncidents.slice(0, 3).map((incident, index) => ( - - - {index < latestIncidents.length - 1 && ( - - )} - - ))} - + {latestIncidents.slice(0, 3).map((incident) => ( + + ))} ); }; @@ -224,17 +213,17 @@ export const SummaryCardStats = ({ summary }: SummaryCardStatsProps) => { return ( } + icon={} label={t("pages.incidents.summaryCard.incidentStats.totalIncidents")} value={summary?.total || 0} /> } + icon={} label={t("pages.incidents.summaryCard.incidentStats.mostAffectedMonitor")} value={mostAffected} /> } + icon={} label={t("pages.incidents.summaryCard.incidentStats.avgResolutionTime")} value={ summary.total > 0 diff --git a/client/src/Pages/Incidents/Components/ControlsIncidentFilter.tsx b/client/src/Pages/Incidents/Components/ControlsIncidentFilter.tsx index a0f4eb15a..af7cba105 100644 --- a/client/src/Pages/Incidents/Components/ControlsIncidentFilter.tsx +++ b/client/src/Pages/Incidents/Components/ControlsIncidentFilter.tsx @@ -75,7 +75,7 @@ export const ControlsIncidentFilter = ({ variant="contained" onClick={onClearFilters} > - {t("pages.incidents.filters.clearFilters")} + {t("common.buttons.clearFilters")} )} diff --git a/client/src/Pages/Incidents/index.tsx b/client/src/Pages/Incidents/index.tsx index 84c414b26..a0a7e04d8 100644 --- a/client/src/Pages/Incidents/index.tsx +++ b/client/src/Pages/Incidents/index.tsx @@ -15,6 +15,7 @@ import { HeaderTimeRange } from "@/Components/common"; import { ControlsIncidentFilter } from "@/Pages/Incidents/Components/ControlsIncidentFilter"; import { useGet } from "@/Hooks/UseApi"; +import { LAYOUT } from "@/Utils/Theme/constants"; import { useState, useEffect, useMemo } from "react"; import { useParams } from "react-router-dom"; import type { Incident, IncidentsResponse, IncidentSummary } from "@/Types/Incident"; @@ -186,8 +187,9 @@ const IncidentsPage = () => { {activeIncidentsCount > 0 && ( <> {t("pages.incidents.table.activeIncidents")} @@ -208,8 +210,9 @@ const IncidentsPage = () => { )} {t("pages.incidents.table.resolvedIncidents")} From c89dbebe98bff24e1e9d61a20a3f4275db2d9217 Mon Sep 17 00:00:00 2001 From: gorkem-bwl Date: Tue, 28 Apr 2026 23:57:14 -0400 Subject: [PATCH 4/8] feat(infrastructure): show notice when network charts have zero traffic When Capture runs inside a container (typical for Docker Desktop), the only visible interfaces are loopback, so every bytes_sent/bytes_recv counter is zero and the charts render as flat lines without any explanation. Users couldn't tell whether Capture was unreachable, the monitor was broken, or there was just genuinely no traffic. Detect the case where checks exist (chart configs were built) but every interface across every check reports zero bytesSentPerSecond and deltaBytesRecv, and render a NoticeBanner above the chart grid explaining it and suggesting Capture be run on the host. Adds pages.infrastructure.charts.labels.netNoTraffic to all 16 locales. --- .../Details/Components/ChartsNetwork.tsx | 72 +++++++++++-------- client/src/locales/ar.json | 3 +- client/src/locales/cs.json | 5 +- client/src/locales/de.json | 3 +- client/src/locales/en.json | 1 + client/src/locales/es.json | 5 +- client/src/locales/fi.json | 3 +- client/src/locales/fr.json | 5 +- client/src/locales/ja.json | 1 + client/src/locales/pt-BR.json | 5 +- client/src/locales/ru.json | 3 +- client/src/locales/th.json | 3 +- client/src/locales/tr.json | 5 +- client/src/locales/uk.json | 3 +- client/src/locales/vi.json | 3 +- client/src/locales/zh-CN.json | 3 +- client/src/locales/zh-TW.json | 5 +- 17 files changed, 80 insertions(+), 48 deletions(-) diff --git a/client/src/Pages/Infrastructure/Details/Components/ChartsNetwork.tsx b/client/src/Pages/Infrastructure/Details/Components/ChartsNetwork.tsx index 54e3cc1ed..c7ebac5be 100644 --- a/client/src/Pages/Infrastructure/Details/Components/ChartsNetwork.tsx +++ b/client/src/Pages/Infrastructure/Details/Components/ChartsNetwork.tsx @@ -1,4 +1,6 @@ import Grid from "@mui/material/Grid"; +import Stack from "@mui/material/Stack"; +import { NoticeBanner } from "@/Components/design-elements"; import { HistogramInfrastructure } from "@/Components/monitors"; import { useTranslation } from "react-i18next"; @@ -6,6 +8,7 @@ import type { HardwareCheckStats } from "@/Types/Monitor"; import { useMemo } from "react"; import { useTheme } from "@mui/material/styles"; import useMediaQuery from "@mui/material/useMediaQuery"; +import { LAYOUT } from "@/Utils/Theme/constants"; const formatBytesToMB = (value: number) => `${(value / (1024 * 1024)).toFixed(2)} MB`; @@ -60,6 +63,11 @@ const getChartConfigs = ( return configs; }; +const hasAnyNetworkTraffic = (checks: HardwareCheckStats[]): boolean => + checks.some((c) => + c.net?.some((iface) => iface.bytesSentPerSecond > 0 || iface.deltaBytesRecv > 0) + ); + export const InfraNetworkCharts = ({ checks, dateRange, @@ -74,35 +82,43 @@ export const InfraNetworkCharts = ({ () => getChartConfigs(theme, checks, t), [theme, checks, t] ); + const showNoTrafficNotice = chartConfigs.length > 0 && !hasAnyNetworkTraffic(checks); return ( - - {chartConfigs.map((config) => { - return ( - - - - ); - })} - + + {showNoTrafficNotice && ( + + {t("pages.infrastructure.charts.labels.netNoTraffic")} + + )} + + {chartConfigs.map((config) => { + return ( + + + + ); + })} + + ); }; diff --git a/client/src/locales/ar.json b/client/src/locales/ar.json index e4782a345..eb8476d87 100644 --- a/client/src/locales/ar.json +++ b/client/src/locales/ar.json @@ -769,6 +769,7 @@ "memory": "استخدام الذاكرة", "netBytesRecv": "{{name}} - البايتات المستلمة", "netBytesSent": "{{name}} - البايتات المرسلة", + "netNoTraffic": "Capture يبلغ عن عدم وجود حركة بيانات على أي واجهة. هذا أمر طبيعي عندما يعمل Capture داخل حاوية لا ترى سوى واجهات الاسترجاع — قم بتشغيل Capture مباشرة على المضيف لرؤية نشاط الشبكة الحقيقي.", "temp": "الحرارة" } }, @@ -1236,7 +1237,7 @@ "description": "إضافة مراقبات نموذجية لأغراض العرض التوضيحي." }, "removeMonitors": { - "title": "إعادة تعيين النظام", + "title": "إعادة ضبط النظام", "description": "إزالة جميع المراقبات من نظامك.", "dialog": { "title": "إزالة جميع المراقبات؟", diff --git a/client/src/locales/cs.json b/client/src/locales/cs.json index 57225bdda..2c99e485a 100644 --- a/client/src/locales/cs.json +++ b/client/src/locales/cs.json @@ -769,6 +769,7 @@ "memory": "Využití paměti", "netBytesRecv": "{{name}} - přijaté bajty", "netBytesSent": "{{name}} - odeslané bajty", + "netNoTraffic": "Capture hlásí nulový provoz na všech rozhraních. To je normální, když Capture běží uvnitř kontejneru, který vidí pouze loopback rozhraní — spusťte Capture přímo na hostiteli, abyste viděli skutečnou síťovou aktivitu.", "temp": "Teplota" } }, @@ -1236,8 +1237,8 @@ "description": "Přidejte ukázkové monitory pro demonstrační účely." }, "removeMonitors": { - "title": "Obnovení systému", - "description": "Odeberte všechny monitory z vašeho systému.", + "title": "Reset systému", + "description": "Odstranit všechny monitory ze systému.", "dialog": { "title": "Odebrat všechny monitory?", "description": "Tuto akci nelze vrátit zpět." diff --git a/client/src/locales/de.json b/client/src/locales/de.json index 2f85d2f38..e01243670 100644 --- a/client/src/locales/de.json +++ b/client/src/locales/de.json @@ -769,6 +769,7 @@ "memory": "Arbeitsspeicherauslastung", "netBytesRecv": "{{name}} - Empfangene Bytes", "netBytesSent": "{{name}} - Gesendete Bytes", + "netNoTraffic": "Capture meldet null Datenverkehr auf allen Schnittstellen. Das ist normal, wenn Capture in einem Container läuft, der nur Loopback-Schnittstellen sieht — führe Capture direkt auf dem Host aus, um echten Netzwerkverkehr zu sehen.", "temp": "Temp." } }, @@ -1237,7 +1238,7 @@ }, "removeMonitors": { "title": "System zurücksetzen", - "description": "Alle Monitore aus Ihrem System entfernen.", + "description": "Alle Monitore aus dem System entfernen.", "dialog": { "title": "Alle Monitore entfernen?", "description": "Dies kann nicht rückgängig gemacht werden." diff --git a/client/src/locales/en.json b/client/src/locales/en.json index dd9b66c1e..5aada5776 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -769,6 +769,7 @@ "memory": "Memory usage", "netBytesRecv": "{{name}} - Bytes Received", "netBytesSent": "{{name}} - Bytes Sent", + "netNoTraffic": "Capture is reporting zero traffic on every interface. This is normal when Capture runs inside a container that can only see loopback interfaces — run Capture directly on the host to see real network activity.", "temp": "Temp" } }, diff --git a/client/src/locales/es.json b/client/src/locales/es.json index 77786176a..27a99da8a 100644 --- a/client/src/locales/es.json +++ b/client/src/locales/es.json @@ -776,6 +776,7 @@ "memory": "Uso de memoria", "netBytesRecv": "{{name}} - Bytes recibidos", "netBytesSent": "{{name}} - Bytes enviados", + "netNoTraffic": "Capture no informa tráfico en ninguna interfaz. Esto es normal cuando Capture se ejecuta dentro de un contenedor que solo ve interfaces de loopback — ejecuta Capture directamente en el host para ver actividad de red real.", "temp": "Temp" } }, @@ -1243,8 +1244,8 @@ "description": "Agregue monitores de ejemplo con fines demostrativos." }, "removeMonitors": { - "title": "Reinicio del sistema", - "description": "Elimine todos los monitores de su sistema.", + "title": "Reiniciar sistema", + "description": "Eliminar todos los monitores del sistema.", "dialog": { "title": "¿Eliminar todos los monitores?", "description": "Esto no se puede deshacer." diff --git a/client/src/locales/fi.json b/client/src/locales/fi.json index 77b591eba..a8c5780a6 100644 --- a/client/src/locales/fi.json +++ b/client/src/locales/fi.json @@ -769,6 +769,7 @@ "memory": "Muistin käyttö", "netBytesRecv": "{{name}} - tavua vastaanotettu", "netBytesSent": "{{name}} - tavua lähetetty", + "netNoTraffic": "Capture ilmoittaa nollaliikennettä kaikilla rajapinnoilla. Tämä on normaalia, kun Capture käynnistetään säiliössä, joka näkee vain loopback-rajapinnat — suorita Capture suoraan isännällä nähdäksesi todellisen verkkoaktiviteetin.", "temp": "Lämpö" } }, @@ -1236,7 +1237,7 @@ "description": "Lisää esimerkkimonitoreja esittelytarkoituksiin." }, "removeMonitors": { - "title": "Järjestelmän nollaus", + "title": "Järjestelmän palautus", "description": "Poista kaikki monitorit järjestelmästäsi.", "dialog": { "title": "Poistetaanko kaikki monitorit?", diff --git a/client/src/locales/fr.json b/client/src/locales/fr.json index 9a92cd677..8d1ac57b1 100644 --- a/client/src/locales/fr.json +++ b/client/src/locales/fr.json @@ -769,6 +769,7 @@ "memory": "Utilisation mémoire", "netBytesRecv": "{{name}} - Octets reçus", "netBytesSent": "{{name}} - Octets envoyés", + "netNoTraffic": "Capture ne signale aucun trafic sur toutes les interfaces. C'est normal lorsque Capture s'exécute dans un conteneur qui ne voit que les interfaces de loopback — exécutez Capture directement sur l'hôte pour voir l'activité réseau réelle.", "temp": "Temp." } }, @@ -1236,8 +1237,8 @@ "description": "Ajoutez des moniteurs d'exemple à des fins de démonstration." }, "removeMonitors": { - "title": "Réinitialisation du système", - "description": "Supprimez tous les moniteurs de votre système.", + "title": "Réinitialiser le système", + "description": "Supprimer tous les moniteurs de votre système.", "dialog": { "title": "Supprimer tous les moniteurs ?", "description": "Cette action est irréversible." diff --git a/client/src/locales/ja.json b/client/src/locales/ja.json index 485d896e5..f9766228e 100644 --- a/client/src/locales/ja.json +++ b/client/src/locales/ja.json @@ -769,6 +769,7 @@ "memory": "メモリ使用率", "netBytesRecv": "{{name}} - 受信バイト数", "netBytesSent": "{{name}} - 送信バイト数", + "netNoTraffic": "Capture はすべてのインターフェイスでゼロのトラフィックを報告しています。これは Capture がループバックインターフェイスのみを認識できるコンテナ内で実行されている場合に正常です — 実際のネットワークアクティビティを表示するには、ホスト上で Capture を直接実行してください。", "temp": "温度" } }, diff --git a/client/src/locales/pt-BR.json b/client/src/locales/pt-BR.json index be0bda185..f2a389db6 100644 --- a/client/src/locales/pt-BR.json +++ b/client/src/locales/pt-BR.json @@ -769,6 +769,7 @@ "memory": "Uso de memória", "netBytesRecv": "{{name}} - Bytes recebidos", "netBytesSent": "{{name}} - Bytes enviados", + "netNoTraffic": "Capture está reportando zero tráfego em todas as interfaces. Isso é normal quando Capture é executado dentro de um container que só consegue ver interfaces de loopback — execute Capture diretamente no host para ver a atividade real da rede.", "temp": "Temp" } }, @@ -1236,8 +1237,8 @@ "description": "Adicione monitores de exemplo para fins de demonstração." }, "removeMonitors": { - "title": "Redefinição do sistema", - "description": "Remova todos os monitores do seu sistema.", + "title": "Redefinir sistema", + "description": "Remover todos os monitores do seu sistema.", "dialog": { "title": "Remover todos os monitores?", "description": "Isso não pode ser desfeito." diff --git a/client/src/locales/ru.json b/client/src/locales/ru.json index c185cce22..44fd8d2a4 100644 --- a/client/src/locales/ru.json +++ b/client/src/locales/ru.json @@ -769,6 +769,7 @@ "memory": "Использование памяти", "netBytesRecv": "{{name}} - байт получено", "netBytesSent": "{{name}} - байт отправлено", + "netNoTraffic": "Capture сообщает о нулевом трафике на всех интерфейсах. Это нормально, когда Capture работает внутри контейнера, который видит только loopback-интерфейсы — запустите Capture непосредственно на хосте, чтобы увидеть реальную сетевую активность.", "temp": "Температура" } }, @@ -1237,7 +1238,7 @@ }, "removeMonitors": { "title": "Сброс системы", - "description": "Удалить все мониторы из Вашей системы.", + "description": "Удалить все мониторы из вашей системы.", "dialog": { "title": "Удалить все мониторы?", "description": "Это действие нельзя отменить." diff --git a/client/src/locales/th.json b/client/src/locales/th.json index 0204702de..e66dbbc86 100644 --- a/client/src/locales/th.json +++ b/client/src/locales/th.json @@ -769,6 +769,7 @@ "memory": "การใช้งานหน่วยความจำ", "netBytesRecv": "{{name}} - ไบต์ที่รับ", "netBytesSent": "{{name}} - ไบต์ที่ส่ง", + "netNoTraffic": "Capture รายงานว่าไม่มีการรับส่งข้อมูลบนอินเทอร์เฟซใดๆ เลย ซึ่งเป็นเรื่องปกติเมื่อ Capture ทำงานอยู่ในคอนเทนเนอร์ที่มองเห็นเพียงอินเทอร์เฟซ loopback เท่านั้น — รัน Capture บนโฮสต์โดยตรงเพื่อดูกิจกรรมเครือข่ายจริง", "temp": "อุณหภูมิ" } }, @@ -1237,7 +1238,7 @@ }, "removeMonitors": { "title": "รีเซ็ตระบบ", - "description": "ลบมอนิเตอร์ทั้งหมดออกจากระบบ", + "description": "ลบมอนิเตอร์ทั้งหมดจากระบบของคุณ", "dialog": { "title": "ลบมอนิเตอร์ทั้งหมด?", "description": "ไม่สามารถย้อนกลับได้" diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json index 1b07562e9..a75572117 100644 --- a/client/src/locales/tr.json +++ b/client/src/locales/tr.json @@ -769,6 +769,7 @@ "memory": "Bellek kullanımı", "netBytesRecv": "{{name}} - Alınan bayt", "netBytesSent": "{{name}} - Gönderilen bayt", + "netNoTraffic": "Capture tüm arabirimlerde sıfır trafik raporluyor. Bu, Capture yalnızca loopback arabirimlerini görebilen bir konteyner içinde çalışırken normaldir — gerçek ağ etkinliğini görmek için Capture'ı doğrudan host üzerinde çalıştırın.", "temp": "Sıcaklık" } }, @@ -1236,8 +1237,8 @@ "description": "Gösterim amaçlı örnek monitörler ekleyin." }, "removeMonitors": { - "title": "Sistem sıfırlama", - "description": "Sisteminizdeki tüm monitörleri kaldırın.", + "title": "Sistemi sıfırla", + "description": "Sistemdeki tüm monitörleri kaldır.", "dialog": { "title": "Tüm monitörler kaldırılsın mı?", "description": "Bu işlem geri alınamaz." diff --git a/client/src/locales/uk.json b/client/src/locales/uk.json index ae66971a7..ca5b33dc4 100644 --- a/client/src/locales/uk.json +++ b/client/src/locales/uk.json @@ -769,6 +769,7 @@ "memory": "Використання пам'яті", "netBytesRecv": "{{name}} - Отримано байтів", "netBytesSent": "{{name}} - Надіслано байтів", + "netNoTraffic": "Capture повідомляє про нульовий трафік на всіх інтерфейсах. Це нормально, коли Capture працює всередині контейнера, який бачить лише loopback-інтерфейси — запустіть Capture безпосередньо на хості, щоб побачити реальну мережеву активність.", "temp": "Темп." } }, @@ -1237,7 +1238,7 @@ }, "removeMonitors": { "title": "Скидання системи", - "description": "Видалити всі монітори з Вашої системи.", + "description": "Видалити всі монітори з вашої системи.", "dialog": { "title": "Видалити всі монітори?", "description": "Це не можна скасувати." diff --git a/client/src/locales/vi.json b/client/src/locales/vi.json index c4d1ed02e..61427389d 100644 --- a/client/src/locales/vi.json +++ b/client/src/locales/vi.json @@ -769,6 +769,7 @@ "memory": "Sử dụng bộ nhớ", "netBytesRecv": "{{name}} - Byte nhận", "netBytesSent": "{{name}} - Byte gửi", + "netNoTraffic": "Capture đang báo cáo lưu lượng bằng không trên mọi giao diện. Điều này là bình thường khi Capture chạy bên trong một container chỉ có thể thấy các giao diện loopback — hãy chạy Capture trực tiếp trên máy chủ để xem hoạt động mạng thực tế.", "temp": "Nhiệt độ" } }, @@ -1237,7 +1238,7 @@ }, "removeMonitors": { "title": "Đặt lại hệ thống", - "description": "Xóa tất cả trình giám sát khỏi hệ thống.", + "description": "Xóa tất cả các monitor khỏi hệ thống của bạn.", "dialog": { "title": "Xóa tất cả trình giám sát?", "description": "Không thể hoàn tác." diff --git a/client/src/locales/zh-CN.json b/client/src/locales/zh-CN.json index 8dee3dcb2..fe66cfcca 100644 --- a/client/src/locales/zh-CN.json +++ b/client/src/locales/zh-CN.json @@ -769,6 +769,7 @@ "memory": "内存使用率", "netBytesRecv": "{{name}} - 接收字节", "netBytesSent": "{{name}} - 发送字节", + "netNoTraffic": "Capture 报告所有接口的流量均为零。当 Capture 在只能看到回环接口的容器内运行时,这属于正常情况——请直接在主机上运行 Capture 才能看到真实的网络活动。", "temp": "温度" } }, @@ -1237,7 +1238,7 @@ }, "removeMonitors": { "title": "系统重置", - "description": "从系统中移除所有监控。", + "description": "从系统中移除所有监视器。", "dialog": { "title": "移除所有监控?", "description": "此操作无法撤销。" diff --git a/client/src/locales/zh-TW.json b/client/src/locales/zh-TW.json index cdcf2d079..388ad4789 100644 --- a/client/src/locales/zh-TW.json +++ b/client/src/locales/zh-TW.json @@ -769,6 +769,7 @@ "memory": "記憶體使用率", "netBytesRecv": "{{name}} - 接收位元組", "netBytesSent": "{{name}} - 發送位元組", + "netNoTraffic": "Capture 回報所有介面的流量皆為零。當 Capture 在只能看到回環介面的容器中執行時,這是正常情況——請直接在主機上執行 Capture 才能看到實際的網路活動。", "temp": "溫度" } }, @@ -1236,8 +1237,8 @@ "description": "新增範例監控以供示範用途。" }, "removeMonitors": { - "title": "系統重設", - "description": "從系統中移除所有監控。", + "title": "系統重置", + "description": "從系統中移除所有監視器。", "dialog": { "title": "移除所有監控?", "description": "此操作無法復原。" From 5792ca624e3e0eea67b4bb5fdd13ca43dac9dad4 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 29 Apr 2026 09:37:37 -0700 Subject: [PATCH 5/8] normalize NoticeBanner --- .../design-elements/MonitorStatus.tsx | 2 +- .../design-elements/NoticeBanner.tsx | 31 +++++++++---------- client/src/Utils/Theme/Palette.ts | 13 ++++---- client/src/Utils/Theme/Theme.ts | 2 +- client/src/Utils/Theme/constants.ts | 1 + 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/client/src/Components/design-elements/MonitorStatus.tsx b/client/src/Components/design-elements/MonitorStatus.tsx index dbeb5fa84..14f33d934 100644 --- a/client/src/Components/design-elements/MonitorStatus.tsx +++ b/client/src/Components/design-elements/MonitorStatus.tsx @@ -17,7 +17,7 @@ export const MonitorStatus = ({ monitor }: { monitor: Monitor }) => { return ( = { info: "ⓘ", @@ -25,29 +27,26 @@ export const NoticeBanner = ({ severity = "info", children }: NoticeBannerProps) direction="row" alignItems="flex-start" gap={theme.spacing(LAYOUT.SM)} - sx={{ - width: "100%", - p: theme.spacing(LAYOUT.MD), - borderRadius: 1, - border: `1px solid ${alpha(tone, 0.45)}`, - backgroundColor: alpha(tone, 0.08), - textAlign: "left", - }} + width={"100%"} + p={theme.spacing(LAYOUT.MD)} + borderRadius={theme.shape.borderRadius} + border={`1px solid ${alpha(tone, 0.45)}`} + bgcolor={alpha(tone, 0.08)} + textAlign={"left"} > {SEVERITY_GLYPH[severity]} {children} diff --git a/client/src/Utils/Theme/Palette.ts b/client/src/Utils/Theme/Palette.ts index 0fe08583a..92c08cd2f 100644 --- a/client/src/Utils/Theme/Palette.ts +++ b/client/src/Utils/Theme/Palette.ts @@ -1,12 +1,13 @@ const typographyBase = 13; export const typographyLevels = { - base: typographyBase, - xs: `${(typographyBase - 4) / 16}rem`, - s: `${(typographyBase - 2) / 16}rem`, - m: `${typographyBase / 16}rem`, - l: `${(typographyBase + 2) / 16}rem`, - xl: `${(typographyBase + 10) / 16}rem`, + base: typographyBase, // 13px + xs: `${(typographyBase - 4) / 16}rem`, // 9px + s: `${(typographyBase - 2) / 16}rem`, // 11px + m: `${typographyBase / 16}rem`, // 13px + l: `${(typographyBase + 2) / 16}rem`, // 15px + xl: `${(typographyBase + 5) / 16}rem`, // 18px + xxl: `${(typographyBase + 10) / 16}rem`, // 23px }; export const colors = { diff --git a/client/src/Utils/Theme/Theme.ts b/client/src/Utils/Theme/Theme.ts index 19f864c6f..7c712d66d 100644 --- a/client/src/Utils/Theme/Theme.ts +++ b/client/src/Utils/Theme/Theme.ts @@ -58,7 +58,7 @@ export const theme = (mode: string, palette: any) => fontFamilyMonospace, fontSize: typographyLevels.base, h1: { - fontSize: typographyLevels.xl, + fontSize: typographyLevels.xxl, fontWeight: 500, }, h2: { diff --git a/client/src/Utils/Theme/constants.ts b/client/src/Utils/Theme/constants.ts index 8b045f9f6..e0d74815e 100644 --- a/client/src/Utils/Theme/constants.ts +++ b/client/src/Utils/Theme/constants.ts @@ -8,6 +8,7 @@ export const SPACING = { } as const; export const LAYOUT = { + XXS: 2, XS: 4, SM: 6, MD: 8, From 2dd921891045af89f13db243074d2a2a2b166982 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 29 Apr 2026 09:42:49 -0700 Subject: [PATCH 6/8] normailze dialog and basepage --- .../Components/design-elements/BasePage.tsx | 4 ++-- client/src/Components/inputs/Dialog.tsx | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/client/src/Components/design-elements/BasePage.tsx b/client/src/Components/design-elements/BasePage.tsx index 845d20a4c..c955fb6b7 100644 --- a/client/src/Components/design-elements/BasePage.tsx +++ b/client/src/Components/design-elements/BasePage.tsx @@ -38,9 +38,9 @@ export const PageSpeedKeyPriorityFallback = () => { diff --git a/client/src/Components/inputs/Dialog.tsx b/client/src/Components/inputs/Dialog.tsx index 38b858bd6..02d164abd 100644 --- a/client/src/Components/inputs/Dialog.tsx +++ b/client/src/Components/inputs/Dialog.tsx @@ -53,24 +53,24 @@ export const DialogInput = ({ > {title && ( {title} {content && ( {content} @@ -79,7 +79,7 @@ export const DialogInput = ({ )} {children && ( - {children} + {children} )} Date: Wed, 29 Apr 2026 09:47:11 -0700 Subject: [PATCH 7/8] normalize --- client/src/Components/inputs/TextInput.tsx | 3 ++- client/src/Utils/Theme/constants.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/Components/inputs/TextInput.tsx b/client/src/Components/inputs/TextInput.tsx index 8b7092d0b..13277be72 100644 --- a/client/src/Components/inputs/TextInput.tsx +++ b/client/src/Components/inputs/TextInput.tsx @@ -5,6 +5,7 @@ import { typographyLevels } from "@/Utils/Theme/Palette"; import { useTheme } from "@mui/material/styles"; import Stack from "@mui/material/Stack"; import { FieldLabel } from "./FieldLabel"; +import { LAYOUT } from "@/Utils/Theme/constants"; interface TextInputProps extends Omit { fieldLabel?: string; @@ -56,7 +57,7 @@ export const TextInput = forwardRef(function T if (fieldLabel) { return ( {fieldLabel} diff --git a/client/src/Utils/Theme/constants.ts b/client/src/Utils/Theme/constants.ts index 4b2e04be6..d718d61dc 100644 --- a/client/src/Utils/Theme/constants.ts +++ b/client/src/Utils/Theme/constants.ts @@ -18,5 +18,5 @@ export const LAYOUT = { } as const; export const HOVER = { - DARKEN: 0.06, + DARKEN: 0.06, // This is a coefficient for darkening function } as const; From 301942d0eb5f863b334de0136c326a0cbc4c710d Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 29 Apr 2026 09:56:01 -0700 Subject: [PATCH 8/8] normalize --- .../Incidents/Components/CardDetails.tsx | 23 +++++++++++-------- .../Incidents/Components/CardSummary.tsx | 2 +- client/src/Pages/Incidents/index.tsx | 8 +++---- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/client/src/Pages/Incidents/Components/CardDetails.tsx b/client/src/Pages/Incidents/Components/CardDetails.tsx index c4ae3a83d..82ececaa8 100644 --- a/client/src/Pages/Incidents/Components/CardDetails.tsx +++ b/client/src/Pages/Incidents/Components/CardDetails.tsx @@ -13,6 +13,7 @@ import { useSelector } from "react-redux"; import type { RootState } from "@/Types/state"; import { formatDateWithTz } from "@/Utils/TimeUtils"; import { getIncidentsDuration } from "@/Pages/Incidents/utils"; +import { theme } from "@/Utils/Theme/Theme"; interface CardDetailsProps { incident: Incident | null; @@ -20,15 +21,19 @@ interface CardDetailsProps { sx?: object; } -const SectionHeading = ({ children }: { children: React.ReactNode }) => ( - - {children} - -); +const SectionHeading = ({ children }: { children: React.ReactNode }) => { + const theme = useTheme(); + + return ( + + {children} + + ); +}; const Cell = ({ children }: { children: React.ReactNode }) => ( {children} diff --git a/client/src/Pages/Incidents/Components/CardSummary.tsx b/client/src/Pages/Incidents/Components/CardSummary.tsx index ae75f5f37..60dadaa74 100644 --- a/client/src/Pages/Incidents/Components/CardSummary.tsx +++ b/client/src/Pages/Incidents/Components/CardSummary.tsx @@ -68,7 +68,7 @@ export const SummaryCard = ({ {title} diff --git a/client/src/Pages/Incidents/index.tsx b/client/src/Pages/Incidents/index.tsx index a0a7e04d8..63cd18889 100644 --- a/client/src/Pages/Incidents/index.tsx +++ b/client/src/Pages/Incidents/index.tsx @@ -188,8 +188,8 @@ const IncidentsPage = () => { <> {t("pages.incidents.table.activeIncidents")} @@ -211,8 +211,8 @@ const IncidentsPage = () => { {t("pages.incidents.table.resolvedIncidents")}