Merge pull request #1914 from Br0wnHammer/feat/migrate/hardcoded-strings

Feat: Migrate Hardcoded Strings
This commit is contained in:
Alexander Holliday
2025-03-12 09:34:46 -07:00
committed by GitHub
15 changed files with 232 additions and 118 deletions
@@ -20,11 +20,13 @@ import { createToast } from "../../../Utils/toastUtils";
import { useNavigate } from "react-router-dom";
import { useMonitorsFetch } from "../../StatusPage/Create/Hooks/useMonitorsFetch";
import { useDUStatusPageFetchByUrl } from "../Status/Hooks/useDUStatusPageFetchByUrl";
import { useTranslation } from "react-i18next";
const CreateStatus = () => {
const theme = useTheme();
const { monitorId, url } = useParams();
const navigate = useNavigate();
const { t } = useTranslation();
const isCreate = typeof url === "undefined";
const [createStatusPage, isLoading, networkError] = useCreateStatusPage(isCreate);
@@ -176,7 +178,7 @@ const CreateStatus = () => {
component="span"
fontSize="inherit"
>
{isCreate ? "Create your" : "Edit your"}{" "}
{isCreate ? t("distributedUptimeStatusCreateYour") : t("distributedUptimeStatusEditYour")}{" "}
</Typography>
<Typography
component="span"
@@ -184,21 +186,21 @@ const CreateStatus = () => {
fontSize="inherit"
fontWeight="inherit"
>
status page
{t("distributedUptimeStatusCreateStatusPage")}
</Typography>
</Typography>
<ConfigBox>
<Stack>
<Typography component="h2">Access</Typography>
<Typography component="h2">{t("distributedUptimeStatusCreateStatusPageAccess")}</Typography>
<Typography component="p">
If your status page is ready, you can mark it as published.
{t("distributedUptimeStatusCreateStatusPageReady")}
</Typography>
</Stack>
<Stack gap={theme.spacing(18)}>
<Checkbox
id="publish"
name="isPublished"
label={`Published and visible to the public`}
label={t("distributedUptimeStatusPublishedLabel")}
isChecked={form.isPublished}
onChange={handleFormChange}
/>
@@ -206,9 +208,9 @@ const CreateStatus = () => {
</ConfigBox>
<ConfigBox>
<Stack gap={theme.spacing(6)}>
<Typography component="h2">Basic Information</Typography>
<Typography component="h2">{t("distributedUptimeStatusBasicInfoHeader")}</Typography>
<Typography component="p">
Define company name and the subdomain that your status page points to.
{t("distributedUptimeStatusBasicInfoDescription")}
</Typography>
</Stack>
<Stack gap={theme.spacing(18)}>
@@ -216,7 +218,7 @@ const CreateStatus = () => {
id="companyName"
name="companyName"
type="text"
label="Company name"
label={t("distributedUptimeStatusCompanyNameLabel")}
placeholder="Company name"
value={form.companyName}
onChange={handleFormChange}
@@ -227,7 +229,7 @@ const CreateStatus = () => {
id="url"
name="url"
type="url"
label="Your status page address"
label={t("distributedUptimeStatusPageAddressLabel")}
disabled={!isCreate}
value={form.url}
onChange={handleFormChange}
@@ -238,8 +240,8 @@ const CreateStatus = () => {
</ConfigBox>
<ConfigBox>
<Stack gap={theme.spacing(6)}>
<Typography component="h2">Logo</Typography>
<Typography component="p">Upload a logo for your status page </Typography>
<Typography component="h2">{t("distributedUptimeStatusLogoHeader")}</Typography>
<Typography component="p">{t("distributedUptimeStatusLogoDescription")} </Typography>
</Stack>
<Stack
gap={theme.spacing(18)}
@@ -262,7 +264,7 @@ const CreateStatus = () => {
color="accent"
tabIndex={-1}
>
Upload logo
{t("distributedUptimeStatusLogoUploadButton")}
<VisuallyHiddenInput onChange={handleImageUpload} />
</Button>
</Box>
@@ -270,9 +272,9 @@ const CreateStatus = () => {
</ConfigBox>
<ConfigBox>
<Stack>
<Typography component="h2">Standard Monitors</Typography>
<Typography component="h2">{t("distributedUptimeStatusStandardMonitorsHeader")}</Typography>
<Typography component="p">
Attach standard monitors to your status page.
{t("distributedUptimeStatusStandardMonitorsDescription")}
</Typography>
</Stack>
<Stack gap={theme.spacing(18)}>
@@ -301,7 +303,7 @@ const CreateStatus = () => {
color="accent"
onClick={handleSubmit}
>
Save
{t("settingsSave")}
</Button>
</Stack>
</Stack>
@@ -1,8 +1,10 @@
import { Stack, Button, ButtonGroup } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
const TimeFrameHeader = ({ timeFrame, setTimeFrame, sx, ...props }) => {
const theme = useTheme();
const { t } = useTranslation();
return (
<Stack
direction="row"
@@ -16,21 +18,21 @@ const TimeFrameHeader = ({ timeFrame, setTimeFrame, sx, ...props }) => {
filled={(timeFrame === 30).toString()}
onClick={() => setTimeFrame(30)}
>
30 days
{t("distributedUptimeStatus30Days")}
</Button>
<Button
variant="group"
filled={(timeFrame === 60).toString()}
onClick={() => setTimeFrame(60)}
>
60 days
{t("distributedUptimeStatus60Days")}
</Button>
<Button
variant="group"
filled={(timeFrame === 90).toString()}
onClick={() => setTimeFrame(90)}
>
90 days
{t("distributedUptimeStatus90Days")}
</Button>
</ButtonGroup>
</Stack>
@@ -124,9 +124,9 @@ const DistributedUptimeStatus = () => {
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
A status page is not set up.
{t("distributedUptimeStatusPageNotSetUp")}
</Typography>
<Typography>Please contact your administrator</Typography>
<Typography>{t("distributedUptimeStatusContactAdmin")}</Typography>
</GenericFallback>
</Stack>
);
@@ -137,7 +137,7 @@ const DistributedUptimeStatus = () => {
return (
<Stack sx={sx}>
<GenericFallback>
<Typography>This status page is not public.</Typography>
<Typography>{t("distributedUptimeStatusPageNotPublic")}</Typography>
</GenericFallback>
</Stack>
);
@@ -155,9 +155,9 @@ const DistributedUptimeStatus = () => {
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
Network error
{t("networkError")}
</Typography>
<Typography>Please check your connection</Typography>
<Typography>{t("checkConnection")}</Typography>
</GenericFallback>
);
}
@@ -171,7 +171,7 @@ const DistributedUptimeStatus = () => {
<Stack gap={theme.spacing(10)}>
<Breadcrumbs list={BREADCRUMBS} />
<GenericFallback>
<Typography>There is no check history for this monitor yet.</Typography>
<Typography>{t("distributedUptimeDetailsNoMonitorHistory")}</Typography>
</GenericFallback>
</Stack>
);
@@ -246,17 +246,17 @@ const DistributedUptimeStatus = () => {
gap={theme.spacing(8)}
>
<InfoBox
heading="Devices"
heading={t("distributedUptimeStatusDevices")}
subHeading={monitor?.totalChecks ?? 0}
icon={PeopleAltOutlinedIcon}
alt="Upt Logo"
sx={{ width: "50%" }}
/>
<InfoBox
heading={isSmallScreen ? "UPT" : "UPT Burned"}
heading={isSmallScreen ? t("distributedUptimeStatusUpt") : t("distributedUptimeStatusUptBurned")}
subHeading={safelyParseFloat(monitor?.uptBurnt).toFixed(4)}
img={UptLogo}
alt="Upt Logo"
alt={t("distributedUptimeStatusUptLogo")}
sx={{ width: "50%" }}
/>
</Stack>
@@ -295,7 +295,7 @@ const DistributedUptimeStatus = () => {
<Footer />
<Dialog
// open={isOpen.deleteStats}
title="Do you want to delete this status page?"
title={t("distributedUptimeStatusPageDeleteDialog")}
onConfirm={() => {
deleteStatusPage();
setIsDeleteOpen(false);
@@ -304,8 +304,8 @@ const DistributedUptimeStatus = () => {
setIsDeleteOpen(false);
}}
open={isDeleteOpen}
confirmationButtonLabel="Yes, delete status page"
description="Once deleted, your status page cannot be retrieved."
confirmationButtonLabel={t("distributedUptimeStatusPageDeleteConfirm")}
description={t("distributedUptimeStatusPageDeleteDescription")}
isLoading={isDeleting || isLoading}
/>
</Stack>
@@ -13,6 +13,7 @@ import { useSelector } from "react-redux";
import { useState } from "react";
import useChecksFetch from "../../Hooks/useChecksFetch";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
const IncidentTable = ({
shouldRender,
@@ -38,6 +39,8 @@ const IncidentTable = ({
rowsPerPage,
});
const { t } = useTranslation();
//Handlers
const handleChangePage = (_, newPage) => {
setPage(newPage);
@@ -50,12 +53,12 @@ const IncidentTable = ({
const headers = [
{
id: "monitorName",
content: "Monitor Name",
content: t("incidentsTableMonitorName"),
render: (row) => monitors[row.monitorId]?.name ?? "N/A",
},
{
id: "status",
content: "Status",
content: t("incidentsTableStatus"),
render: (row) => {
const status = row.status === true ? "up" : "down";
return (
@@ -69,7 +72,7 @@ const IncidentTable = ({
},
{
id: "dateTime",
content: "Date & Time",
content: t("incidentsTableDateTime"),
render: (row) => {
const formattedDate = formatDateWithTz(
row.createdAt,
@@ -81,10 +84,10 @@ const IncidentTable = ({
},
{
id: "statusCode",
content: "Status Code",
content: t("incidentsTableStatusCode"),
render: (row) => <HttpStatusLabel status={row.statusCode} />,
},
{ id: "message", content: "Message", render: (row) => row.message },
{ id: "message", content: t("incidentsTableMessage"), render: (row) => row.message },
];
if (!shouldRender || isLoading) return <TableSkeleton />;
@@ -98,7 +101,7 @@ const IncidentTable = ({
}
if (!isLoading && typeof checksCount === "undefined") {
return <GenericFallback>No incidents recorded</GenericFallback>;
return <GenericFallback>{t("incidentsTableNoIncidents")}</GenericFallback>;
}
return (
@@ -108,7 +111,7 @@ const IncidentTable = ({
data={checks}
/>
<Pagination
paginationLabel="incidents"
paginationLabel={t("incidentsTablePaginationLabel")}
itemCount={checksCount}
page={page}
rowsPerPage={rowsPerPage}
@@ -6,6 +6,7 @@ import PropTypes from "prop-types";
//Utils
import { useTheme } from "@emotion/react";
import SkeletonLayout from "./skeleton";
import { useTranslation } from "react-i18next";
const OptionsHeader = ({
shouldRender,
@@ -18,6 +19,7 @@ const OptionsHeader = ({
setDateRange,
}) => {
const theme = useTheme();
const { t } = useTranslation();
const monitorNames = typeof monitors !== "undefined" ? Object.values(monitors) : [];
// The stacks below which are three in number have the same style so
@@ -40,11 +42,11 @@ const OptionsHeader = ({
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
Incidents for:
{t("incidentsOptionsHeader")}
</Typography>
<Select
id="incidents-select-monitor"
placeholder="All servers"
placeholder={t("incidentsOptionsPlaceholderAllServers")}
value={selectedMonitor}
onChange={(e) => setSelectedMonitor(e.target.value)}
items={monitorNames}
@@ -61,7 +63,7 @@ const OptionsHeader = ({
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
Filter by:
{t("incidentsOptionsHeaderFilterBy")}
</Typography>
<ButtonGroup>
<Button
@@ -69,21 +71,21 @@ const OptionsHeader = ({
filled={(filter === "all").toString()}
onClick={() => setFilter("all")}
>
All
{t("incidentsOptionsHeaderFilterAll")}
</Button>
<Button
variant="group"
filled={(filter === "down").toString()}
onClick={() => setFilter("down")}
>
Down
{t("incidentsOptionsHeaderFilterDown")}
</Button>
<Button
variant="group"
filled={(filter === "resolve").toString()}
onClick={() => setFilter("resolve")}
>
Cannot resolve
{t("incidentsOptionsHeaderFilterCannotResolve")}
</Button>
</ButtonGroup>
</Stack>
@@ -93,7 +95,7 @@ const OptionsHeader = ({
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
Show:
{t("incidentsOptionsHeaderShow")}
</Typography>
<ButtonGroup>
<Button
@@ -101,28 +103,28 @@ const OptionsHeader = ({
filled={(dateRange === "hour").toString()}
onClick={() => setDateRange("hour")}
>
Last hour
{t("incidentsOptionsHeaderLastHour")}
</Button>
<Button
variant="group"
filled={(dateRange === "day").toString()}
onClick={() => setDateRange("day")}
>
Last day
{t("incidentsOptionsHeaderLastDay")}
</Button>
<Button
variant="group"
filled={(dateRange === "week").toString()}
onClick={() => setDateRange("week")}
>
Last week
{t("incidentsOptionsHeaderLastWeek")}
</Button>
<Button
variant="group"
filled={(dateRange === "all").toString()}
onClick={() => setDateRange("all")}
>
All
{t("incidentsOptionsHeaderFilterAll")}
</Button>
</ButtonGroup>
</Stack>
+19 -19
View File
@@ -8,6 +8,7 @@ import { useSelector, useDispatch } from "react-redux";
import { infrastructureMonitorValidation } from "../../../Validation/validation";
import { createInfrastructureMonitor } from "../../../Features/InfrastructureMonitors/infrastructureMonitorsSlice";
import { capitalizeFirstLetter } from "../../../Utils/stringUtils";
import { useTranslation } from "react-i18next";
// MUI
import { Box, Stack, Typography, Button, ButtonGroup } from "@mui/material";
@@ -52,6 +53,7 @@ const CreateInfrastructureMonitor = () => {
const monitorState = useSelector((state) => state.infrastructureMonitor);
const dispatch = useDispatch();
const navigate = useNavigate();
const { t } = useTranslation();
// State
const [errors, setErrors] = useState({});
@@ -233,7 +235,7 @@ const CreateInfrastructureMonitor = () => {
component="span"
fontSize="inherit"
>
Create your{" "}
{t("infrastructureCreateYour")}{" "}
</Typography>
<Typography
component="span"
@@ -241,18 +243,17 @@ const CreateInfrastructureMonitor = () => {
fontSize="inherit"
fontWeight="inherit"
>
monitor
{t("monitor")}
</Typography>
</Typography>
<ConfigBox>
<Stack gap={theme.spacing(6)}>
<Typography component="h2">General settings</Typography>
<Typography component="h2">{t("settingsGeneralSettings")}</Typography>
<Typography component="p">
Here you can select the URL of the host, together with the friendly name and
authorization secret to connect to the server agent.
{t("infrastructureCreateGeneralSettingsDescription")}
</Typography>
<Typography component="p">
The server you are monitoring must be running the{" "}
{t("infrastructureServerRequirement")}{" "}
<Link
level="primary"
url="https://github.com/bluewave-labs/checkmate-agent"
@@ -267,7 +268,7 @@ const CreateInfrastructureMonitor = () => {
name="url"
startAdornment={<HttpAdornment https={https} />}
placeholder={"localhost:59232/api/v1/metrics"}
label="Server URL"
label={t("infrastructureServerUrlLabel")}
https={https}
value={infrastructureMonitor.url}
onChange={handleChange}
@@ -275,21 +276,21 @@ const CreateInfrastructureMonitor = () => {
helperText={errors["url"]}
/>
<Box>
<Typography component="p">Protocol</Typography>
<Typography component="p">{t("infrastructureProtocol")}</Typography>
<ButtonGroup>
<Button
variant="group"
filled={https.toString()}
onClick={() => setHttps(true)}
>
HTTPS
{t("https")}
</Button>
<Button
variant="group"
filled={(!https).toString()}
onClick={() => setHttps(false)}
>
HTTP
{t("http")}
</Button>
</ButtonGroup>
</Box>
@@ -297,7 +298,7 @@ const CreateInfrastructureMonitor = () => {
type="text"
id="name"
name="name"
label="Display name"
label={t("infrastructureDisplayNameLabel")}
placeholder="Google"
isOptional={true}
value={infrastructureMonitor.name}
@@ -308,7 +309,7 @@ const CreateInfrastructureMonitor = () => {
type="text"
id="secret"
name="secret"
label="Authorization secret"
label={t("infrastructureAuthorizationSecretLabel")}
value={infrastructureMonitor.secret}
onChange={handleChange}
error={errors["secret"] ? true : false}
@@ -318,9 +319,9 @@ const CreateInfrastructureMonitor = () => {
</ConfigBox>
<ConfigBox>
<Box>
<Typography component="h2">Incident notifications</Typography>
<Typography component="h2">{t("distributedUptimeCreateIncidentNotification")}</Typography>
<Typography component="p">
When there is an incident, notify users.
{t("distributedUptimeCreateIncidentDescription")}
</Typography>
</Box>
<Stack gap={theme.spacing(6)}>
@@ -337,10 +338,9 @@ const CreateInfrastructureMonitor = () => {
</ConfigBox>
<ConfigBox>
<Box>
<Typography component="h2">Customize alerts</Typography>
<Typography component="h2">{t("infrastructureCustomizeAlerts")}</Typography>
<Typography component="p">
Send a notification to user(s) when thresholds exceed a specified
percentage.
{t("infrastructureAlertNotificationDescription")}
</Typography>
</Box>
<Stack gap={theme.spacing(6)}>
@@ -385,7 +385,7 @@ const CreateInfrastructureMonitor = () => {
</ConfigBox>
<ConfigBox>
<Box>
<Typography component="h2">Advanced settings</Typography>
<Typography component="h2">{t("distributedUptimeCreateAdvancedSettings")}</Typography>
</Box>
<Stack gap={theme.spacing(12)}>
<Select
@@ -408,7 +408,7 @@ const CreateInfrastructureMonitor = () => {
onClick={handleCreateInfrastructureMonitor}
loading={monitorState?.isLoading}
>
Create infrastructure monitor
{t("infrastructureCreateMonitor")}
</Button>
</Stack>
</Stack>
@@ -12,8 +12,10 @@ import {
} from "../../../../../Components/Charts/Utils/chartUtils";
import { useTheme } from "@emotion/react";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
import { useTranslation } from "react-i18next";
const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
const theme = useTheme();
const { t } = useTranslation();
const { buildTemps } = useHardwareUtils();
if (!shouldRender) {
@@ -31,10 +33,10 @@ const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
type: "memory",
data: checks,
dataKeys: ["avgMemoryUsage"],
heading: "Memory usage",
heading: t("memoryUsage"),
strokeColor: theme.palette.accent.main, // CAIO_REVIEW
gradientStartColor: theme.palette.accent.main, // CAIO_REVIEW
yLabel: "Memory usage",
yLabel: t("memoryUsage"),
yDomain: [0, 1],
yTick: <PercentTick />,
xTick: <TzTick dateRange={dateRange} />,
@@ -51,10 +53,10 @@ const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
type: "cpu",
data: checks,
dataKeys: ["avgCpuUsage"],
heading: "CPU usage",
heading: t("cpuUsage"),
strokeColor: theme.palette.success.main,
gradientStartColor: theme.palette.success.main,
yLabel: "CPU usage",
yLabel: t("cpuUsage"),
yDomain: [0, 1],
yTick: <PercentTick />,
xTick: <TzTick dateRange={dateRange} />,
@@ -73,7 +75,7 @@ const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
dataKeys: tempKeys,
strokeColor: theme.palette.error.main,
gradientStartColor: theme.palette.error.main,
heading: "CPU Temperature",
heading: t("cpuTemperature"),
yLabel: "Temperature",
xTick: <TzTick dateRange={dateRange} />,
yDomain: [
@@ -96,7 +98,7 @@ const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
heading: `Disk${idx} usage`,
strokeColor: theme.palette.warning.main,
gradientStartColor: theme.palette.warning.main,
yLabel: "Disk Usage",
yLabel: t("diskUsage"),
yDomain: [0, 1],
yTick: <PercentTick />,
xTick: <TzTick dateRange={dateRange} />,
@@ -6,10 +6,12 @@ import SkeletonLayout from "./skeleton";
// Utils
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
const Gauges = ({ shouldRender, monitor }) => {
const { decimalToPercentage, formatBytes } = useHardwareUtils();
const theme = useTheme();
const { t } = useTranslation();
if (!shouldRender) {
return <SkeletonLayout />;
@@ -28,19 +30,19 @@ const Gauges = ({ shouldRender, monitor }) => {
{
type: "memory",
value: decimalToPercentage(memoryUsagePercent),
heading: "Memory usage",
metricOne: "Used",
heading: t("memoryUsage"),
metricOne: t("used"),
valueOne: formatBytes(memoryUsedBytes, true),
metricTwo: "Total",
metricTwo: t("total"),
valueTwo: formatBytes(memoryTotalBytes, true),
},
{
type: "cpu",
value: decimalToPercentage(cpuUsagePercent),
heading: "CPU usage",
metricOne: "Cores",
heading: t("cpuUsage"),
metricOne: t("cores"),
valueOne: cpuPhysicalCores ?? 0,
metricTwo: "Frequency",
metricTwo: t("frequency"),
valueTwo: `${(cpuFrequency / 1000).toFixed(2)} Ghz`,
},
...(latestCheck?.disk ?? []).map((disk, idx) => ({
@@ -48,9 +50,9 @@ const Gauges = ({ shouldRender, monitor }) => {
diskIndex: idx,
value: decimalToPercentage(disk.usage_percent),
heading: `Disk${idx} usage`,
metricOne: "Used",
metricOne: t("used"),
valueOne: formatBytes(disk.total_bytes - disk.free_bytes, true),
metricTwo: "Total",
metricTwo: t("total"),
valueTwo: formatBytes(disk.total_bytes, true),
})),
];
@@ -6,11 +6,13 @@ import StatBox from "../../../../../Components/StatBox";
//Utils
import useUtils from "../../../../../Pages/Uptime/Monitors/Hooks/useUtils";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
import { useTranslation } from "react-i18next";
const InfraStatBoxes = ({ shouldRender, monitor }) => {
// Utils
const { formatBytes } = useHardwareUtils();
const { statusStyles, determineState } = useUtils();
const { t } = useTranslation();
const { stats, uptimePercentage } = monitor ?? {};
const latestCheck = stats?.aggregateData?.latestCheck;
@@ -40,11 +42,11 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
>
<StatBox
sx={statusStyles[determineState(monitor)]}
heading="Status"
heading={t("status")}
subHeading={determineState(monitor)}
/>
<StatBox
heading="CPU (Physical)"
heading={t("cpuPhysical")}
subHeading={
<>
{physicalCores}
@@ -54,7 +56,7 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
/>
<StatBox
key={2}
heading="CPU (Logical)"
heading={t("cpuLogical")}
subHeading={
<>
{logicalCores}
@@ -63,7 +65,7 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
}
/>
<StatBox
heading="CPU Frequency"
heading={t("cpuFrequency")}
subHeading={
<>
{(cpuFrequency / 1000).toFixed(2)}
@@ -72,7 +74,7 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
}
/>
<StatBox
heading="Average CPU Temperature"
heading={t("avgCpuTemperature")}
subHeading={
<>
{cpuTemperature.toFixed(2)}
@@ -81,15 +83,15 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
}
/>
<StatBox
heading="Memory"
heading={t("memory")}
subHeading={formatBytes(memoryTotalBytes)}
/>
<StatBox
heading="Disk"
heading={t("disk")}
subHeading={formatBytes(diskTotalBytes)}
/>
<StatBox
heading="Uptime"
heading={t("uptime")}
subHeading={
<>
{(uptimePercentage * 100).toFixed(2)}
@@ -99,7 +101,7 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
/>
<StatBox
key={8}
heading="OS"
heading={t("os")}
subHeading={osPlatform}
/>
</StatusBoxes>
@@ -1,5 +1,6 @@
import { Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
// Constants
const BASE_BOX_PADDING_VERTICAL = 4;
@@ -9,6 +10,7 @@ const CHART_CONTAINER_HEIGHT = 300;
const useHardwareUtils = () => {
const theme = useTheme();
const { t } = useTranslation();
const getDimensions = () => {
const totalTypographyPadding = parseInt(theme.spacing(TYPOGRAPHY_PADDING), 10) * 2;
@@ -29,7 +31,7 @@ const useHardwareUtils = () => {
<>
{0}
{space ? " " : ""}
<Typography component="span">GB</Typography>
<Typography component="span">{t("gb")}</Typography>
</>
);
if (typeof bytes !== "number")
@@ -37,7 +39,7 @@ const useHardwareUtils = () => {
<>
{0}
{space ? " " : ""}
<Typography component="span">GB</Typography>
<Typography component="span">{t("gb")}</Typography>
</>
);
if (bytes === 0)
@@ -45,7 +47,7 @@ const useHardwareUtils = () => {
<>
{0}
{space ? " " : ""}
<Typography component="span">GB</Typography>
<Typography component="span">{t("gb")}</Typography>
</>
);
@@ -57,7 +59,7 @@ const useHardwareUtils = () => {
<>
{Number(GB.toFixed(0))}
{space ? " " : ""}
<Typography component="span">GB</Typography>
<Typography component="span">{t("gb")}</Typography>
</>
);
} else {
@@ -65,7 +67,7 @@ const useHardwareUtils = () => {
<>
{Number(MB.toFixed(0))}
{space ? " " : ""}
<Typography component="span">MB</Typography>
<Typography component="span">{t("mb")}</Typography>
</>
);
}
+5 -3
View File
@@ -13,6 +13,7 @@ import { useTheme } from "@emotion/react";
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
import { useHardwareMonitorsFetch } from "./Hooks/useHardwareMonitorsFetch";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
// Constants
@@ -29,6 +30,7 @@ const InfrastructureDetails = () => {
// Utils
const theme = useTheme();
const { monitorId } = useParams();
const { t } = useTranslation();
const { isLoading, networkError, monitor } = useHardwareMonitorsFetch({
monitorId,
@@ -43,9 +45,9 @@ const InfrastructureDetails = () => {
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
Network error
{t("networkError")}
</Typography>
<Typography>Please check your connection</Typography>
<Typography>{t("checkConnection")}</Typography>
</GenericFallback>
);
}
@@ -61,7 +63,7 @@ const InfrastructureDetails = () => {
monitor={monitor}
/>
<GenericFallback>
<Typography>No check history for this monitor yet.</Typography>
<Typography>{t("distributedUptimeDetailsNoMonitorHistory")}</Typography>
</GenericFallback>
</Stack>
);
@@ -13,10 +13,12 @@ import { useTheme } from "@emotion/react";
import useUtils from "../../../../Uptime/Monitors/Hooks/useUtils";
import { useNavigate } from "react-router-dom";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete }) => {
// Utils
const theme = useTheme();
const { t } = useTranslation();
const { determineState } = useUtils();
const navigate = useNavigate();
@@ -27,7 +29,7 @@ const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete
const headers = [
{
id: "host",
content: "Host",
content: t("host"),
render: (row) => (
<Host
title={row.name}
@@ -39,7 +41,7 @@ const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete
},
{
id: "status",
content: "Status",
content: t("incidentsTableStatus"),
render: (row) => (
<StatusLabel
status={row.status}
@@ -49,7 +51,7 @@ const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete
},
{
id: "frequency",
content: "Frequency",
content: t("frequency"),
render: (row) => (
<Stack
direction={"row"}
@@ -65,12 +67,12 @@ const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete
</Stack>
),
},
{ id: "cpu", content: "CPU", render: (row) => <CustomGauge progress={row.cpu} /> },
{ id: "mem", content: "Mem", render: (row) => <CustomGauge progress={row.mem} /> },
{ id: "disk", content: "Disk", render: (row) => <CustomGauge progress={row.disk} /> },
{ id: "cpu", content: t("cpu"), render: (row) => <CustomGauge progress={row.cpu} /> },
{ id: "mem", content: t("mem"), render: (row) => <CustomGauge progress={row.mem} /> },
{ id: "disk", content: t("disk"), render: (row) => <CustomGauge progress={row.disk} /> },
{
id: "actions",
content: "Actions",
content: t("actions"),
render: (row) => (
<InfrastructureMenu
monitor={row}
+5 -3
View File
@@ -12,6 +12,7 @@ import { useTheme } from "@emotion/react";
import { useMonitorFetch } from "./Hooks/useMonitorFetch";
import { useState } from "react";
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
import { useTranslation } from "react-i18next";
// Constants
const BREADCRUMBS = [{ name: `infrastructure`, path: "/infrastructure" }];
@@ -24,6 +25,7 @@ const InfrastructureMonitors = () => {
// Utils
const theme = useTheme();
const isAdmin = useIsAdmin();
const { t } = useTranslation();
// Handlers
const handleActionMenuDelete = () => {
@@ -52,9 +54,9 @@ const InfrastructureMonitors = () => {
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
Network error
{t("networkError")}
</Typography>
<Typography>Please check your connection</Typography>
<Typography>{t("checkConnection")}</Typography>
</GenericFallback>
);
}
@@ -96,7 +98,7 @@ const InfrastructureMonitors = () => {
/>
<Pagination
itemCount={summary?.totalMonitors}
paginationLabel="monitors"
paginationLabel={t("monitors")}
page={page}
rowsPerPage={rowsPerPage}
handleChangePage={handleChangePage}
+12 -9
View File
@@ -4,6 +4,7 @@ import { useTheme } from "@emotion/react";
import Discord from "../../assets/icons/discord-icon.svg?react";
import Slack from "../../assets/icons/slack-icon.svg?react";
import Zapier from "../../assets/icons/zapier-icon.svg?react";
import { useTranslation } from "react-i18next";
import "./index.css";
@@ -18,6 +19,7 @@ import "./index.css";
*/
const IntegrationsComponent = ({ icon, header, info, onClick }) => {
const theme = useTheme();
const { t } = useTranslation();
return (
<Grid
@@ -59,7 +61,7 @@ const IntegrationsComponent = ({ icon, header, info, onClick }) => {
sx={{ alignSelf: "center" }}
disabled={true}
>
Add
{t("add")}
</Button>
</Stack>
</Grid>
@@ -81,6 +83,7 @@ IntegrationsComponent.propTypes = {
const Integrations = () => {
const theme = useTheme();
const { t } = useTranslation();
const integrations = [
{
@@ -90,8 +93,8 @@ const Integrations = () => {
style={{ width: "45px", height: "45px", alignSelf: "center" }}
/>
),
header: "Slack",
info: "Connect with Slack and see incidents in a channel",
header: t("integrationsSlack"),
info: t("integrationsSlackInfo"),
onClick: () => {},
},
{
@@ -101,8 +104,8 @@ const Integrations = () => {
style={{ width: "42px", height: "42px", alignSelf: "center" }}
/>
),
header: "Discord",
info: "Connect with Discord and view incidents directly in a channel",
header: t("integrationsDiscord"),
info: t("integrationsDiscordInfo"),
onClick: () => {},
},
{
@@ -112,8 +115,8 @@ const Integrations = () => {
style={{ width: "42px", height: "42px", alignSelf: "center" }}
/>
),
header: "Zapier",
info: "Send all incidents to Zapier, and then see them everywhere",
header: t("integrationsZapier"),
info: t("integrationsZapierInfo"),
onClick: () => {},
},
// Add more integrations as needed
@@ -130,9 +133,9 @@ const Integrations = () => {
},
}}
>
<Typography component="h1">Integrations</Typography>
<Typography component="h1">{t("integrations")}</Typography>
<Typography mb={theme.spacing(12)}>
Connect Prism to your favorite service.
{t("integrationsPrism")}
</Typography>
<Grid
container
+89 -1
View File
@@ -2,7 +2,9 @@
"dontHaveAccount": "Don't have account",
"https": "HTTPS",
"http": "HTTP",
"add": "Add",
"monitor": "monitor",
"monitors": "monitors",
"aboutus": "About Us",
"email": "E-mail",
"forgotPassword": "Forgot Password",
@@ -100,7 +102,93 @@
"distributedUptimeDetailsMonitorHeader": "Distributed Uptime Monitoring powered by DePIN",
"distributedUptimeDetailsStatusHeaderUptime": "Uptime:",
"distributedUptimeDetailsStatusHeaderLastUpdate": "Last updated",
"distributedUptimeStatusCreateStatusPage": "status page",
"distributedUptimeStatusCreateStatusPageAccess": "Access",
"distributedUptimeStatusCreateStatusPageReady": "If your status page is ready, you can mark it as published.",
"distributedUptimeStatusBasicInfoHeader": "Basic Information",
"distributedUptimeStatusBasicInfoDescription": "Define company name and the subdomain that your status page points to.",
"distributedUptimeStatusLogoHeader": "Logo",
"distributedUptimeStatusLogoDescription": "Upload a logo for your status page",
"distributedUptimeStatusLogoUploadButton": "Upload logo",
"distributedUptimeStatusStandardMonitorsHeader": "Standard Monitors",
"distributedUptimeStatusStandardMonitorsDescription": "Attach standard monitors to your status page.",
"distributedUptimeStatusCreateYour": "Create your",
"distributedUptimeStatusEditYour": "Edit your",
"distributedUptimeStatusPublishedLabel": "Published and visible to the public",
"distributedUptimeStatusCompanyNameLabel": "Company name",
"distributedUptimeStatusPageAddressLabel": "Your status page address",
"distributedUptimeStatus30Days": "30 days",
"distributedUptimeStatus60Days": "60 days",
"distributedUptimeStatus90Days": "90 days",
"distributedUptimeStatusPageNotSetUp": "A status page is not set up.",
"distributedUptimeStatusContactAdmin": "Please contact your administrator",
"distributedUptimeStatusPageNotPublic": "This status page is not public.",
"distributedUptimeStatusPageDeleteDialog": "Do you want to delete this status page?",
"distributedUptimeStatusPageDeleteConfirm": "Yes, delete status page",
"distributedUptimeStatusPageDeleteDescription": "Once deleted, your status page cannot be retrieved.",
"distributedUptimeStatusDevices": "Devices",
"distributedUptimeStatusUpt": "UPT",
"distributedUptimeStatusUptBurned": "UPT Burned",
"distributedUptimeStatusUptLogo": "Upt Logo",
"incidentsTableNoIncidents": "No incidents recorded",
"incidentsTablePaginationLabel": "incidents",
"incidentsTableMonitorName": "Monitor Name",
"incidentsTableStatus": "Status",
"incidentsTableDateTime": "Date & Time",
"incidentsTableStatusCode": "Status Code",
"incidentsTableMessage": "Message",
"incidentsOptionsHeader": "Incidents for:",
"incidentsOptionsHeaderFilterBy": "Filter by:",
"incidentsOptionsHeaderFilterAll": "All",
"incidentsOptionsHeaderFilterDown": "Down",
"incidentsOptionsHeaderFilterCannotResolve": "Cannot resolve",
"incidentsOptionsHeaderShow": "Show:",
"incidentsOptionsHeaderLastHour": "Last hour",
"incidentsOptionsHeaderLastDay": "Last day",
"incidentsOptionsHeaderLastWeek": "Last week",
"incidentsOptionsPlaceholderAllServers": "All servers",
"infrastructureCreateYour": "Create your",
"infrastructureCreateGeneralSettingsDescription": "Here you can select the URL of the host, together with the friendly name and authorization secret to connect to the server agent.",
"infrastructureServerRequirement": "The server you are monitoring must be running the",
"infrastructureCustomizeAlerts": "Customize alerts",
"infrastructureAlertNotificationDescription": "Send a notification to user(s) when thresholds exceed a specified percentage.",
"infrastructureCreateMonitor": "Create Infrastructure Monitor",
"infrastructureProtocol": "Protocol",
"infrastructureServerUrlLabel": "Server URL",
"infrastructureDisplayNameLabel": "Display name",
"infrastructureAuthorizationSecretLabel": "Authorization secret",
"gb": "GB",
"mb": "MB",
"mem": "Mem",
"memoryUsage": "Memory usage",
"cpu": "CPU",
"cpuUsage": "CPU usage",
"cpuTemperature": "CPU Temperature",
"diskUsage": "Disk Usage",
"used": "Used",
"total": "Total",
"cores": "Cores",
"frequency": "Frequency",
"status": "Status",
"cpuPhysical": "CPU (Physical)",
"cpuLogical": "CPU (Logical)",
"cpuFrequency": "CPU Frequency",
"avgCpuTemperature": "Average CPU Temperature",
"memory": "Memory",
"disk": "Disk",
"uptime": "Uptime",
"os": "OS",
"host": "Host",
"actions": "Actions",
"integrations": "Integrations",
"integrationsPrism": "Connect Prism to your favorite service.",
"integrationsSlack": "Slack",
"integrationsSlackInfo": "Connect with Slack and see incidents in a channel",
"integrationsDiscord": "Discord",
"integrationsDiscordInfo": "Connect with Discord and view incidents directly in a channel",
"integrationsZapier": "Zapier",
"integrationsZapierInfo": "Send all incidents to Zapier, and then see them everywhere",
"settingsGeneralSettings": "General settings",
"settingsDisplayTimezone": "Display timezone",
"settingsDisplayTimezoneDescription": "The timezone of the dashboard you publicly display.",