mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-13 13:19:42 -06:00
Feat: Migrate Hardcoded Strings
This commit is contained in:
@@ -28,6 +28,7 @@ import {
|
||||
} from "../../../Utils/timeUtils";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { buildErrors, hasValidationErrors } from "../../../Validation/error";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const getDurationAndUnit = (durationInMs) => {
|
||||
if (durationInMs % MS_PER_DAY === 0) {
|
||||
@@ -113,6 +114,7 @@ const CreateMaintenance = () => {
|
||||
const { maintenanceWindowId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const { user } = useSelector((state) => state.auth);
|
||||
const [monitors, setMonitors] = useState([]);
|
||||
const [search, setSearch] = useState("");
|
||||
@@ -293,7 +295,7 @@ const CreateMaintenance = () => {
|
||||
component="span"
|
||||
fontSize="inherit"
|
||||
>
|
||||
{`${maintenanceWindowId === undefined ? "Create a" : "Edit"}`}{" "}
|
||||
{`${maintenanceWindowId === undefined ? t("createA") : t("edit")}`}{" "}
|
||||
</Typography>
|
||||
<Typography
|
||||
component="span"
|
||||
@@ -301,13 +303,13 @@ const CreateMaintenance = () => {
|
||||
fontSize="inherit"
|
||||
fontWeight="inherit"
|
||||
>
|
||||
maintenance{" "}
|
||||
{t("maintenance")}{" "}
|
||||
</Typography>
|
||||
<Typography
|
||||
component="span"
|
||||
fontSize="inherit"
|
||||
>
|
||||
window
|
||||
{t("window")}
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography
|
||||
@@ -315,7 +317,7 @@ const CreateMaintenance = () => {
|
||||
variant="body2"
|
||||
fontSize={14}
|
||||
>
|
||||
Your pings won't be sent during this time frame
|
||||
{t("maintenanceWindowDescription")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<ConfigBox>
|
||||
@@ -324,14 +326,14 @@ const CreateMaintenance = () => {
|
||||
component="h2"
|
||||
variant="h2"
|
||||
>
|
||||
General Settings
|
||||
{t("settingsGeneralSettings")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(15)}>
|
||||
<TextInput
|
||||
id="name"
|
||||
label="Friendly name"
|
||||
placeholder="Maintenance at __ : __ for ___ minutes"
|
||||
label={t("friendlyNameInput")}
|
||||
placeholder={t("friendlyNamePlaceholder")}
|
||||
value={form.name}
|
||||
onChange={(event) => {
|
||||
handleFormChange("name", event.target.value);
|
||||
@@ -342,7 +344,7 @@ const CreateMaintenance = () => {
|
||||
<Select
|
||||
id="repeat"
|
||||
name="maintenance-repeat"
|
||||
label="Maintenance Repeat"
|
||||
label={t("maintenanceRepeat")}
|
||||
value={getIdByValue(repeatConfig, form.repeat)}
|
||||
onChange={(event) => {
|
||||
handleFormChange(
|
||||
@@ -437,15 +439,15 @@ const CreateMaintenance = () => {
|
||||
component="h2"
|
||||
variant="h2"
|
||||
>
|
||||
Start time
|
||||
{t("startTime")}
|
||||
</Typography>
|
||||
<Typography>All dates and times are in GMT+0 time zone.</Typography>
|
||||
<Typography>{t("timeZoneInfo")}</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(15)}>
|
||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||
<MobileTimePicker
|
||||
id="startTime"
|
||||
label="Start time"
|
||||
label={t("startTime")}
|
||||
value={form.startTime}
|
||||
onChange={(newTime) => {
|
||||
handleTimeChange("startTime", newTime);
|
||||
@@ -486,7 +488,7 @@ const CreateMaintenance = () => {
|
||||
<TextInput
|
||||
type="number"
|
||||
id="duration"
|
||||
label="Duration"
|
||||
label={t("duration")}
|
||||
value={form.duration}
|
||||
onChange={(event) => {
|
||||
handleFormChange("duration", event.target.value);
|
||||
@@ -516,13 +518,13 @@ const CreateMaintenance = () => {
|
||||
component="h2"
|
||||
variant="h2"
|
||||
>
|
||||
Monitors to apply maintenance window to
|
||||
{t("monitorsToApply")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(15)}>
|
||||
<Search
|
||||
id={"monitors"}
|
||||
label="Add monitors"
|
||||
label={t("addMonitors")}
|
||||
multiple={true}
|
||||
isAdorned={false}
|
||||
options={monitors ? monitors : []}
|
||||
@@ -547,7 +549,7 @@ const CreateMaintenance = () => {
|
||||
onClick={() => navigate("/maintenance")}
|
||||
sx={{ mr: theme.spacing(6) }}
|
||||
>
|
||||
Cancel
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
loading={isLoading}
|
||||
@@ -558,8 +560,8 @@ const CreateMaintenance = () => {
|
||||
>
|
||||
{`${
|
||||
maintenanceWindowId === undefined
|
||||
? "Create maintenance"
|
||||
: "Edit maintenance"
|
||||
? t("createMaintenance")
|
||||
: t("editMaintenance")
|
||||
}`}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
@@ -8,6 +8,7 @@ import Settings from "../../../../assets/icons/settings-bold.svg?react";
|
||||
import PropTypes from "prop-types";
|
||||
import { networkService } from "../../../../main";
|
||||
import { createToast } from "../../../../Utils/toastUtils";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import Dialog from "../../../../Components/Dialog";
|
||||
|
||||
@@ -18,6 +19,7 @@ const ActionsMenu = ({ /* isAdmin, */ maintenanceWindow, updateCallback }) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleRemove = async (event) => {
|
||||
event.preventDefault();
|
||||
@@ -124,7 +126,7 @@ const ActionsMenu = ({ /* isAdmin, */ maintenanceWindow, updateCallback }) => {
|
||||
handleEdit();
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
{t("edit")}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={(e) => {
|
||||
@@ -142,7 +144,7 @@ const ActionsMenu = ({ /* isAdmin, */ maintenanceWindow, updateCallback }) => {
|
||||
openRemove(e);
|
||||
}}
|
||||
>
|
||||
Remove
|
||||
{t("remove")}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Dialog
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useDispatch, useSelector } from "react-redux";
|
||||
import { formatDurationRounded } from "../../../Utils/timeUtils";
|
||||
import { StatusLabel } from "../../../Components/Label";
|
||||
import { setRowsPerPage } from "../../../Features/UI/uiSlice";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import dayjs from "dayjs";
|
||||
/**
|
||||
* Component for pagination actions (first, previous, next, last).
|
||||
@@ -49,13 +50,15 @@ const MaintenanceTable = ({
|
||||
);
|
||||
setPage(0);
|
||||
};
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const headers = [
|
||||
{
|
||||
id: "name",
|
||||
content: (
|
||||
<Box onClick={() => handleSort("name")}>
|
||||
Maintenance Window Name
|
||||
{t("maintenanceWindowName")}
|
||||
<span
|
||||
style={{
|
||||
visibility: sort.field === "name" ? "visible" : "hidden",
|
||||
@@ -76,7 +79,7 @@ const MaintenanceTable = ({
|
||||
content: (
|
||||
<Box onClick={() => handleSort("status")}>
|
||||
{" "}
|
||||
Status
|
||||
{t("status")}
|
||||
<span
|
||||
style={{
|
||||
visibility: sort.field === "active" ? "visible" : "hidden",
|
||||
@@ -105,21 +108,21 @@ const MaintenanceTable = ({
|
||||
},
|
||||
{
|
||||
id: "nextWindow",
|
||||
content: "Next window",
|
||||
content: t("nextWindow"),
|
||||
render: (row) => {
|
||||
return getTimeToNextWindow(row.start, row.end, row.repeat);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "repeat",
|
||||
content: "Repeat",
|
||||
content: t("repeat"),
|
||||
render: (row) => {
|
||||
return row.repeat === 0 ? "N/A" : formatDurationRounded(row.repeat);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
content: "Actions",
|
||||
content: t("actions"),
|
||||
render: (row) => (
|
||||
<ActionsMenu
|
||||
maintenanceWindow={row}
|
||||
|
||||
@@ -9,9 +9,11 @@ import { networkService } from "../../main";
|
||||
import Breadcrumbs from "../../Components/Breadcrumbs";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useIsAdmin } from "../../Hooks/useIsAdmin";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Maintenance = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { rowsPerPage } = useSelector((state) => state.ui.maintenance);
|
||||
const isAdmin = useIsAdmin();
|
||||
@@ -74,7 +76,7 @@ const Maintenance = () => {
|
||||
}}
|
||||
sx={{ fontWeight: 500 }}
|
||||
>
|
||||
Create maintenance window
|
||||
{t("createMaintenanceWindow")}
|
||||
</Button>
|
||||
</Stack>
|
||||
<MaintenanceTable
|
||||
|
||||
@@ -4,6 +4,7 @@ import NotFoundSvg from "../../../src/assets/Images/sushi_404.svg";
|
||||
import { Button, Stack, Typography } from "@mui/material";
|
||||
import { useNavigate } from "react-router";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
/**
|
||||
* Support for defaultProps will be removed from function components in a future major release
|
||||
@@ -33,6 +34,7 @@ const DefaultValue = {
|
||||
const NotFound = ({ title = DefaultValue.title, desc = DefaultValue.desc }) => {
|
||||
const navigate = useNavigate();
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Stack
|
||||
@@ -62,7 +64,7 @@ const NotFound = ({ title = DefaultValue.title, desc = DefaultValue.desc }) => {
|
||||
sx={{ mt: theme.spacing(10) }}
|
||||
onClick={() => navigate("/")}
|
||||
>
|
||||
Go to the main dashboard
|
||||
{t("notFoundButton")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import { monitorValidation } from "../../../Validation/validation";
|
||||
import { createToast } from "../../../Utils/toastUtils";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ConfigBox from "../../../Components/ConfigBox";
|
||||
import TextInput from "../../../Components/Inputs/TextInput";
|
||||
import Select from "../../../Components/Inputs/Select";
|
||||
@@ -28,6 +29,7 @@ import Dialog from "../../../Components/Dialog";
|
||||
|
||||
const PageSpeedConfigure = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const MS_PER_MINUTE = 60000;
|
||||
@@ -256,7 +258,7 @@ const PageSpeedConfigure = () => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
Editing...
|
||||
{t("editing")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Box>
|
||||
@@ -284,12 +286,12 @@ const PageSpeedConfigure = () => {
|
||||
{monitor?.isActive ? (
|
||||
<>
|
||||
<PauseCircleOutlineIcon />
|
||||
Pause
|
||||
{t("pause")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<PlayCircleOutlineRoundedIcon />
|
||||
Resume
|
||||
{t("resume")}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
@@ -302,16 +304,15 @@ const PageSpeedConfigure = () => {
|
||||
ml: theme.spacing(6),
|
||||
}}
|
||||
>
|
||||
Remove
|
||||
{t("remove")}
|
||||
</Button>
|
||||
</Box>
|
||||
</Stack>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<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 type of
|
||||
monitor.
|
||||
{t("pageSpeedConfigureSettingsDescription")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack
|
||||
@@ -325,7 +326,7 @@ const PageSpeedConfigure = () => {
|
||||
<TextInput
|
||||
type="url"
|
||||
id="monitor-url"
|
||||
label="URL"
|
||||
label={t("url")}
|
||||
placeholder="random.website.com"
|
||||
value={monitor?.url || ""}
|
||||
onChange={handleChange}
|
||||
@@ -336,7 +337,7 @@ const PageSpeedConfigure = () => {
|
||||
<TextInput
|
||||
type="text"
|
||||
id="monitor-name"
|
||||
label="Monitor display name"
|
||||
label={t("monitorDisplayName")}
|
||||
placeholder="Example monitor"
|
||||
isOptional={true}
|
||||
value={monitor?.name || ""}
|
||||
@@ -348,16 +349,16 @@ const PageSpeedConfigure = () => {
|
||||
</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)}>
|
||||
<Typography component="p">When there is a new incident,</Typography>
|
||||
<Typography component="p">{t("whenNewIncident")}</Typography>
|
||||
<Checkbox
|
||||
id="notify-sms"
|
||||
label="Notify via SMS (coming soon)"
|
||||
label={t("notifySMS")}
|
||||
isChecked={false}
|
||||
value=""
|
||||
onChange={() => logger.warn("disabled")}
|
||||
@@ -376,7 +377,7 @@ const PageSpeedConfigure = () => {
|
||||
/>
|
||||
<Checkbox
|
||||
id="notify-email"
|
||||
label="Also notify via email to multiple addresses (coming soon)"
|
||||
label={t("notifyEmails")}
|
||||
isChecked={false}
|
||||
value=""
|
||||
onChange={() => logger.warn("disabled")}
|
||||
@@ -394,7 +395,7 @@ const PageSpeedConfigure = () => {
|
||||
onChange={() => logger.warn("disabled")}
|
||||
/>
|
||||
<Typography mt={theme.spacing(4)}>
|
||||
You can separate multiple emails with a comma
|
||||
{t("seperateEmails")}
|
||||
</Typography>
|
||||
</Box>
|
||||
) : (
|
||||
@@ -404,12 +405,12 @@ const PageSpeedConfigure = () => {
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<Typography component="h2">Advanced settings</Typography>
|
||||
<Typography component="h2">{t("distributedUptimeCreateAdvancedSettings")}</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(20)}>
|
||||
<Select
|
||||
id="monitor-frequency"
|
||||
label="Check frequency"
|
||||
label={t("checkFrequency")}
|
||||
items={frequencies}
|
||||
value={monitor?.interval / MS_PER_MINUTE || 3}
|
||||
onChange={(event) => handleChange(event, "interval")}
|
||||
@@ -429,7 +430,7 @@ const PageSpeedConfigure = () => {
|
||||
onClick={handleSave}
|
||||
sx={{ px: theme.spacing(12) }}
|
||||
>
|
||||
Save
|
||||
{t("settingsSave")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
@@ -438,8 +439,8 @@ const PageSpeedConfigure = () => {
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
theme={theme}
|
||||
title={"Do you really want to delete this monitor?"}
|
||||
description={"Once deleted, this monitor cannot be retrieved."}
|
||||
title={t("deleteDialogTitle")}
|
||||
description={t("deleteDialogDescription")}
|
||||
onCancel={() => setIsOpen(false)}
|
||||
confirmationButtonLabel={"Delete"}
|
||||
onConfirm={handleRemove}
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
checkEndpointResolution,
|
||||
} from "../../../Features/PageSpeedMonitor/pageSpeedMonitorSlice";
|
||||
import { parseDomainName } from "../../../Utils/monitorUtils";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
// MUI
|
||||
import { useTheme } from "@emotion/react";
|
||||
@@ -173,6 +174,8 @@ const CreatePageSpeed = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Box
|
||||
className="create-monitor"
|
||||
@@ -200,7 +203,7 @@ const CreatePageSpeed = () => {
|
||||
component="span"
|
||||
fontSize="inherit"
|
||||
>
|
||||
Create your{" "}
|
||||
{t("createYour")}{" "}
|
||||
</Typography>
|
||||
<Typography
|
||||
component="span"
|
||||
@@ -208,14 +211,14 @@ const CreatePageSpeed = () => {
|
||||
fontWeight="inherit"
|
||||
color={theme.palette.primary.contrastTextSecondary}
|
||||
>
|
||||
PageSpeed monitor
|
||||
{t("pageSpeedMonitor")}
|
||||
</Typography>
|
||||
</Typography>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<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 type of monitor.
|
||||
{t("distributedUptimeCreateSelectURL")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(15)}>
|
||||
@@ -248,9 +251,9 @@ const CreatePageSpeed = () => {
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<Typography component="h2">Checks to perform</Typography>
|
||||
<Typography component="h2">{t("distributedUptimeCreateChecks")}</Typography>
|
||||
<Typography component="p">
|
||||
You can always add or remove checks after adding your site.
|
||||
{t("distributedUptimeCreateChecksDescription")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(12)}>
|
||||
@@ -269,14 +272,14 @@ const CreatePageSpeed = () => {
|
||||
filled={https.toString()}
|
||||
onClick={() => setHttps(true)}
|
||||
>
|
||||
HTTPS
|
||||
{t("https")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="group" // Why does this work?
|
||||
filled={(!https).toString()} // There's nothing in the docs about this either
|
||||
onClick={() => setHttps(false)}
|
||||
>
|
||||
HTTP
|
||||
{t("http")}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</Stack>
|
||||
@@ -297,13 +300,13 @@ const CreatePageSpeed = () => {
|
||||
</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)}>
|
||||
<Typography component="p">When there is a new incident,</Typography>
|
||||
<Typography component="p">{t("whenNewIncident")}</Typography>
|
||||
<Checkbox
|
||||
id="notify-email-default"
|
||||
label={`Notify via email (to ${user.email})`}
|
||||
@@ -317,7 +320,7 @@ const CreatePageSpeed = () => {
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<Typography component="h2">Advanced settings</Typography>
|
||||
<Typography component="h2">{t("distributedUptimeCreateAdvancedSettings")}</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(12)}>
|
||||
<Select
|
||||
@@ -341,7 +344,7 @@ const CreatePageSpeed = () => {
|
||||
disabled={!Object.values(errors).every((value) => value === undefined)}
|
||||
loading={isLoading}
|
||||
>
|
||||
Create monitor
|
||||
{t("createMonitor")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -2,11 +2,12 @@ import { Box, Typography, Divider } from "@mui/material";
|
||||
import Checkbox from "../../../../../Components/Inputs/Checkbox";
|
||||
import MetricsIcon from "../../../../../assets/icons/ruler-icon.svg?react";
|
||||
import LegendBox from "../../../../../Components/Charts/LegendBox";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
const AreaChartLegend = ({ metrics, handleMetrics }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<LegendBox
|
||||
icon={<MetricsIcon />}
|
||||
@@ -17,7 +18,7 @@ const AreaChartLegend = ({ metrics, handleMetrics }) => {
|
||||
fontSize={11}
|
||||
fontWeight={500}
|
||||
>
|
||||
Shown
|
||||
{t("shown")}
|
||||
</Typography>
|
||||
<Divider sx={{ mt: theme.spacing(2) }} />
|
||||
</Box>
|
||||
|
||||
@@ -2,6 +2,7 @@ import StatusBoxes from "../../../../../Components/StatusBoxes";
|
||||
import StatBox from "../../../../../Components/StatBox";
|
||||
import { Typography } from "@mui/material";
|
||||
import { getHumanReadableDuration } from "../../../../../Utils/timeUtils";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const PageSpeedStatusBoxes = ({ shouldRender, monitor }) => {
|
||||
const { time: uptimeDuration, units: uptimeUnits } = getHumanReadableDuration(
|
||||
@@ -12,6 +13,8 @@ const PageSpeedStatusBoxes = ({ shouldRender, monitor }) => {
|
||||
monitor?.lastChecked
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<StatusBoxes shouldRender={shouldRender}>
|
||||
<StatBox
|
||||
@@ -20,7 +23,7 @@ const PageSpeedStatusBoxes = ({ shouldRender, monitor }) => {
|
||||
<>
|
||||
{uptimeDuration}
|
||||
<Typography component="span">{uptimeUnits}</Typography>
|
||||
<Typography component="span">ago</Typography>
|
||||
<Typography component="span">{t("ago")}</Typography>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
@@ -30,7 +33,7 @@ const PageSpeedStatusBoxes = ({ shouldRender, monitor }) => {
|
||||
<>
|
||||
{lastCheckTime}
|
||||
<Typography component="span">{lastCheckUnits}</Typography>
|
||||
<Typography component="span">ago</Typography>
|
||||
<Typography component="span">{t("ago")}</Typography>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -5,10 +5,12 @@ import { Typography } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import PieChartLegend from "../Charts/PieChartLegend";
|
||||
import SkeletonLayout from "./skeleton";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const PerformanceReport = ({ shouldRender, audits }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!shouldRender) {
|
||||
return <SkeletonLayout />;
|
||||
}
|
||||
@@ -25,7 +27,7 @@ const PerformanceReport = ({ shouldRender, audits }) => {
|
||||
variant="body1"
|
||||
mt="auto"
|
||||
>
|
||||
Values are estimated and may vary.{" "}
|
||||
{t("pageSpeedDetailsPerformanceReport")}{" "}
|
||||
<Typography
|
||||
component="span"
|
||||
fontSize="inherit"
|
||||
@@ -41,7 +43,7 @@ const PerformanceReport = ({ shouldRender, audits }) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
See calculator
|
||||
{t("pageSpeedDetailsPerformanceReportCalculator")}
|
||||
</Typography>
|
||||
</Typography>
|
||||
</ChartBox>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { useParams } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useMonitorFetch } from "./Hooks/useMonitorFetch";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
// Constants
|
||||
const BREADCRUMBS = [
|
||||
{ name: "pagespeed", path: "/pagespeed" },
|
||||
@@ -23,6 +24,7 @@ const BREADCRUMBS = [
|
||||
|
||||
const PageSpeedDetails = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const isAdmin = useIsAdmin();
|
||||
const { monitorId } = useParams();
|
||||
|
||||
@@ -50,9 +52,9 @@ const PageSpeedDetails = () => {
|
||||
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>
|
||||
);
|
||||
}
|
||||
@@ -68,7 +70,7 @@ const PageSpeedDetails = () => {
|
||||
monitor={monitor}
|
||||
/>
|
||||
<GenericFallback>
|
||||
<Typography>There is no check history for this monitor yet.</Typography>
|
||||
<Typography>{t("distributedUptimeDetailsNoMonitorHistory")}</Typography>
|
||||
</GenericFallback>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useSelector } from "react-redux";
|
||||
import { formatDateWithTz, formatDurationSplit } from "../../../../../Utils/timeUtils";
|
||||
import useUtils from "../../../../Uptime/Monitors/Hooks/useUtils";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import IconBox from "../../../../../Components/IconBox";
|
||||
/**
|
||||
* CustomToolTip displays a tooltip with formatted date and score information.
|
||||
@@ -207,6 +208,7 @@ PagespeedAreaChart.propTypes = {
|
||||
const Card = ({ monitor }) => {
|
||||
const { determineState, pagespeedStatusMsg } = useUtils();
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const monitorState = determineState(monitor);
|
||||
|
||||
@@ -297,7 +299,7 @@ const Card = ({ monitor }) => {
|
||||
fontSize={11}
|
||||
color={theme.palette.primary.contrastTextSecondary}
|
||||
>
|
||||
Checking every{" "}
|
||||
{t("checkingEvery")}{" "}
|
||||
{(() => {
|
||||
const { time, format } = formatDurationSplit(monitor?.interval);
|
||||
return (
|
||||
|
||||
@@ -12,12 +12,13 @@ import { useSelector } from "react-redux";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
import useMonitorsFetch from "./Hooks/useMonitorsFetch";
|
||||
import GenericFallback from "../../../Components/GenericFallback";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
// Constants
|
||||
const BREADCRUMBS = [{ name: `pagespeed`, path: "/pagespeed" }];
|
||||
|
||||
const PageSpeed = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const isAdmin = useIsAdmin();
|
||||
const { user } = useSelector((state) => state.auth);
|
||||
|
||||
@@ -33,9 +34,9 @@ const PageSpeed = () => {
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Button, Box } from "@mui/material";
|
||||
import ProgressUpload from "../../../../../Components/ProgressBars";
|
||||
import ImageIcon from "@mui/icons-material/Image";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { formatBytes } from "../../../../../Utils/fileUtils";
|
||||
const Progress = ({ isLoading, progressValue, logo, logoType, removeLogo, errors }) => {
|
||||
const { t } = useTranslation();
|
||||
if (isLoading) {
|
||||
return (
|
||||
<ProgressUpload
|
||||
@@ -27,7 +28,7 @@ const Progress = ({ isLoading, progressValue, logo, logoType, removeLogo, errors
|
||||
color="secondary"
|
||||
onClick={removeLogo}
|
||||
>
|
||||
Remove Logo
|
||||
{t("removeLogo")}
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import Checkbox from "../../../../../Components/Inputs/Checkbox";
|
||||
// Utils
|
||||
import { useState } from "react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ConfigStack from "./ConfigStack";
|
||||
const Content = ({
|
||||
tabValue,
|
||||
@@ -30,13 +31,14 @@ const Content = ({
|
||||
|
||||
// Utils
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<TabPanel value={tabValue}>
|
||||
<Stack gap={theme.spacing(10)}>
|
||||
<ConfigStack
|
||||
title="Status page servers"
|
||||
description="You can add any number of servers that you monitor to your status page. You can also reorder them for the best viewing experience."
|
||||
title={t("statusPageCreateTabsContent")}
|
||||
description={t("statusPageCreateTabsContentDescription")}
|
||||
>
|
||||
<Stack>
|
||||
<Stack
|
||||
@@ -70,21 +72,21 @@ const Content = ({
|
||||
</Stack>
|
||||
</ConfigStack>
|
||||
<ConfigStack
|
||||
title="Features"
|
||||
description="Show more details on the status page"
|
||||
title={t("features")}
|
||||
description={t("statusPageCreateTabsContentFeaturesDescription")}
|
||||
>
|
||||
<Stack>
|
||||
<Checkbox
|
||||
id="showCharts"
|
||||
name="showCharts"
|
||||
label={`Show charts`}
|
||||
label={t("showCharts")}
|
||||
isChecked={form.showCharts}
|
||||
onChange={handleFormChange}
|
||||
/>
|
||||
<Checkbox
|
||||
id="showUptimePercentage"
|
||||
name="showUptimePercentage"
|
||||
label={`Show uptime percentage`}
|
||||
label={t("showUptimePercentage")}
|
||||
isChecked={form.showUptimePercentage}
|
||||
onChange={handleFormChange}
|
||||
/>
|
||||
|
||||
@@ -13,6 +13,7 @@ import Progress from "../Progress";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import timezones from "../../../../../Utils/timezones.json";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const TabSettings = ({
|
||||
isCreate,
|
||||
@@ -26,22 +27,23 @@ const TabSettings = ({
|
||||
}) => {
|
||||
// Utils
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<TabPanel value={tabValue}>
|
||||
<Stack gap={theme.spacing(10)}>
|
||||
<ConfigBox>
|
||||
<Stack>
|
||||
<Typography component="h2">Access</Typography>
|
||||
<Typography component="h2">{t("access")}</Typography>
|
||||
<Typography component="p">
|
||||
If your status page is ready, you can mark it as published.
|
||||
{t("statusPageCreateSettings")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack gap={theme.spacing(18)}>
|
||||
<Checkbox
|
||||
id="publish"
|
||||
name="isPublished"
|
||||
label={`Published and visible to the public`}
|
||||
label={t("statusPageCreateSettingsCheckboxLabel")}
|
||||
isChecked={form.isPublished}
|
||||
onChange={handleFormChange}
|
||||
/>
|
||||
@@ -49,9 +51,9 @@ const TabSettings = ({
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Stack gap={theme.spacing(6)}>
|
||||
<Typography component="h2">Basic Information</Typography>
|
||||
<Typography component="h2">{t("basicInformation")}</Typography>
|
||||
<Typography component="p">
|
||||
Define company name and the subdomain that your status page points to.
|
||||
{t("statusPageCreateBasicInfoDescription")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack gap={theme.spacing(18)}>
|
||||
@@ -59,7 +61,7 @@ const TabSettings = ({
|
||||
id="companyName"
|
||||
name="companyName"
|
||||
type="text"
|
||||
label="Company name"
|
||||
label={t("companyName")}
|
||||
value={form.companyName}
|
||||
onChange={handleFormChange}
|
||||
helperText={errors["companyName"]}
|
||||
@@ -70,7 +72,7 @@ const TabSettings = ({
|
||||
name="url"
|
||||
type="url"
|
||||
disabled={!isCreate}
|
||||
label="Your status page address"
|
||||
label={t("statusPageCreateBasicInfoStatusPageAddress")}
|
||||
value={form.url}
|
||||
onChange={handleFormChange}
|
||||
helperText={errors["url"]}
|
||||
@@ -80,16 +82,16 @@ const TabSettings = ({
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Stack gap={theme.spacing(6)}>
|
||||
<Typography component="h2">Timezone</Typography>
|
||||
<Typography component="h2">{t("timezone")}</Typography>
|
||||
<Typography component="p">
|
||||
Select the timezone that your status page will be displayed in.
|
||||
{t("statusPageCreateSelectTimeZoneDescription")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack gap={theme.spacing(6)}>
|
||||
<Select
|
||||
id="timezone"
|
||||
name="timezone"
|
||||
label="Display timezone"
|
||||
label={t("settingsDisplayTimezone")}
|
||||
items={timezones}
|
||||
value={form.timezone}
|
||||
onChange={handleFormChange}
|
||||
@@ -98,9 +100,9 @@ const TabSettings = ({
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Stack gap={theme.spacing(6)}>
|
||||
<Typography component="h2">Appearance</Typography>
|
||||
<Typography component="h2">{t("settingsAppearance")}</Typography>
|
||||
<Typography component="p">
|
||||
Define the default look and feel of your public status page.
|
||||
{t("statusPageCreateAppearanceDescription")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack gap={theme.spacing(6)}>
|
||||
|
||||
@@ -14,7 +14,7 @@ import { createToast } from "../../../Utils/toastUtils";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useStatusPageFetch } from "../Status/Hooks/useStatusPageFetch";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
//Constants
|
||||
const TAB_LIST = ["General settings", "Contents"];
|
||||
|
||||
@@ -54,6 +54,7 @@ const CreateStatusPage = () => {
|
||||
const [createStatusPage, createStatusIsLoading, createStatusPageNetworkError] =
|
||||
useCreateStatusPage(isCreate);
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [statusPage, statusPageMonitors, statusPageIsLoading, statusPageNetworkError] =
|
||||
useStatusPageFetch(isCreate, url);
|
||||
@@ -205,9 +206,9 @@ const CreateStatusPage = () => {
|
||||
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>
|
||||
);
|
||||
}
|
||||
@@ -241,7 +242,7 @@ const CreateStatusPage = () => {
|
||||
color="accent"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Save
|
||||
{t("settingsSave")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -4,9 +4,11 @@ import { Box, Typography } from "@mui/material";
|
||||
// Utils
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const AdminLink = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
@@ -16,7 +18,7 @@ const AdminLink = () => {
|
||||
display="inline-block"
|
||||
color={theme.palette.primary.contrastText}
|
||||
>
|
||||
Administrator?
|
||||
{t("administrator")}
|
||||
</Typography>
|
||||
<Typography
|
||||
component="span"
|
||||
@@ -25,7 +27,7 @@ const AdminLink = () => {
|
||||
sx={{ cursor: "pointer" }}
|
||||
onClick={() => navigate("/login")}
|
||||
>
|
||||
Login here
|
||||
{t("loginHere")}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -8,9 +8,11 @@ import { useTheme } from "@mui/material/styles";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Controls = ({ isDeleteOpen, setIsDeleteOpen, isDeleting, url, type }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const currentPath = location.pathname;
|
||||
const navigate = useNavigate();
|
||||
@@ -35,7 +37,7 @@ const Controls = ({ isDeleteOpen, setIsDeleteOpen, isDeleting, url, type }) => {
|
||||
onClick={() => setIsDeleteOpen(!isDeleteOpen)}
|
||||
loading={isDeleting}
|
||||
>
|
||||
Delete
|
||||
{t("delete")}
|
||||
</Button>
|
||||
</Box>
|
||||
<Box>
|
||||
@@ -59,7 +61,7 @@ const Controls = ({ isDeleteOpen, setIsDeleteOpen, isDeleting, url, type }) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<SettingsIcon /> Configure
|
||||
<SettingsIcon /> {t("configure")}
|
||||
</Button>
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
@@ -17,6 +17,7 @@ import { useStatusPageDelete } from "./Hooks/useStatusPageDelete";
|
||||
import { useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
const PublicStatus = () => {
|
||||
const { url } = useParams();
|
||||
|
||||
@@ -24,6 +25,7 @@ const PublicStatus = () => {
|
||||
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
|
||||
// Utils
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -59,9 +61,9 @@ const PublicStatus = () => {
|
||||
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>
|
||||
);
|
||||
}
|
||||
@@ -76,9 +78,9 @@ const PublicStatus = () => {
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
A public status page is not set up.
|
||||
{t("statusPageStatus")}
|
||||
</Typography>
|
||||
<Typography>Please contact to your administrator</Typography>
|
||||
<Typography>{t("statusPageStatusContactAdmin")}</Typography>
|
||||
</GenericFallback>
|
||||
</Stack>
|
||||
);
|
||||
@@ -94,9 +96,9 @@ const PublicStatus = () => {
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
This status page is not public.
|
||||
{t("statusPageStatusNotPublic")}
|
||||
</Typography>
|
||||
<Typography>Please contact to your administrator</Typography>
|
||||
<Typography>{t("statusPageStatusContactAdmin")}</Typography>
|
||||
</GenericFallback>
|
||||
</Stack>
|
||||
);
|
||||
@@ -111,9 +113,9 @@ const PublicStatus = () => {
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
There's no status page here.
|
||||
{t("statusPageStatusNoPage")}
|
||||
</Typography>
|
||||
<Typography>Please contact to your administrator</Typography>
|
||||
<Typography>{t("statusPageStatusContactAdmin")}</Typography>
|
||||
</GenericFallback>
|
||||
);
|
||||
}
|
||||
@@ -131,12 +133,12 @@ const PublicStatus = () => {
|
||||
setIsDeleteOpen={setIsDeleteOpen}
|
||||
url={url}
|
||||
/>
|
||||
<Typography variant="h2">Service status</Typography>
|
||||
<Typography variant="h2">{t("statusPageStatusServiceStatus")}</Typography>
|
||||
<StatusBar monitors={monitors} />
|
||||
<MonitorsList monitors={monitors} />
|
||||
{link}
|
||||
<Dialog
|
||||
title="Do you want to delete this status page?"
|
||||
title={t("deleteStatusPage")}
|
||||
onConfirm={() => {
|
||||
deleteStatusPage();
|
||||
setIsDeleteOpen(false);
|
||||
@@ -146,8 +148,8 @@ const PublicStatus = () => {
|
||||
setIsDeleteOpen(false);
|
||||
}}
|
||||
open={isDeleteOpen}
|
||||
confirmationButtonLabel="Yes, delete status page"
|
||||
description="Once deleted, your status page cannot be retrieved."
|
||||
confirmationButtonLabel={t("deleteStatusPageConfirm")}
|
||||
description={t("deleteStatusPageDescription")}
|
||||
isLoading={isDeleting || isLoading}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -4,20 +4,22 @@ import { useNavigate } from "react-router-dom";
|
||||
import { StatusLabel } from "../../../../../Components/Label";
|
||||
import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import { useTranslation } from "react-i18next";
|
||||
const StatusPagesTable = ({ data }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const headers = [
|
||||
{
|
||||
id: "name",
|
||||
content: "Status page name",
|
||||
content: t("statusPageName"),
|
||||
render: (row) => {
|
||||
return row.companyName;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "url",
|
||||
content: "Public URL",
|
||||
content: t("publicURL"),
|
||||
onClick: (e, row) => {
|
||||
if (row.isPublished) {
|
||||
e.stopPropagation();
|
||||
@@ -57,14 +59,14 @@ const StatusPagesTable = ({ data }) => {
|
||||
},
|
||||
{
|
||||
id: "type",
|
||||
content: "Type",
|
||||
content: t("type"),
|
||||
render: (row) => {
|
||||
return row.type;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "status",
|
||||
content: "Status",
|
||||
content: t("status"),
|
||||
render: (row) => {
|
||||
const status = row.isPublished ? "published" : "unpublished";
|
||||
return (
|
||||
|
||||
@@ -8,6 +8,7 @@ import StatusPagesTable from "./Components/StatusPagesTable";
|
||||
import SkeletonLayout from "../../../Components/Skeletons/FullPage";
|
||||
// Utils
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useStatusPagesFetch } from "./Hooks/useStatusPagesFetch";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
const BREADCRUMBS = [{ name: `Status Pages`, path: "" }];
|
||||
@@ -15,6 +16,7 @@ const BREADCRUMBS = [{ name: `Status Pages`, path: "" }];
|
||||
const StatusPages = () => {
|
||||
// Utils
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const isAdmin = useIsAdmin();
|
||||
const [isLoading, networkError, statusPages] = useStatusPagesFetch();
|
||||
|
||||
@@ -30,9 +32,9 @@ const StatusPages = () => {
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Box, Stack, Tooltip, Typography, Button } from "@mui/material";
|
||||
import { monitorValidation } from "../../../Validation/validation";
|
||||
import { createToast } from "../../../Utils/toastUtils";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ConfigBox from "../../../Components/ConfigBox";
|
||||
import {
|
||||
updateUptimeMonitor,
|
||||
@@ -207,6 +208,8 @@ const Configure = () => {
|
||||
undefined: "Pending...",
|
||||
};
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Stack
|
||||
className="configure-monitor"
|
||||
@@ -293,7 +296,7 @@ const Configure = () => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
Editing...
|
||||
{t("editing")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Box>
|
||||
@@ -326,12 +329,12 @@ const Configure = () => {
|
||||
{monitor?.isActive ? (
|
||||
<>
|
||||
<PauseIcon />
|
||||
Pause
|
||||
{t("pause")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ResumeIcon />
|
||||
Resume
|
||||
{t("resume")}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
@@ -342,16 +345,15 @@ const Configure = () => {
|
||||
sx={{ px: theme.spacing(8) }}
|
||||
onClick={() => setIsOpen(true)}
|
||||
>
|
||||
Remove
|
||||
{t("remove")}
|
||||
</Button>
|
||||
</Box>
|
||||
</Stack>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<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 type of
|
||||
monitor.
|
||||
{t("distributedUptimeCreateSelectURL")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(20)}>
|
||||
@@ -364,7 +366,7 @@ const Configure = () => {
|
||||
)
|
||||
}
|
||||
id="monitor-url"
|
||||
label="URL to monitor"
|
||||
label={t("urlMonitor")}
|
||||
placeholder="google.com"
|
||||
value={parsedUrl?.host || monitor?.url || ""}
|
||||
disabled={true}
|
||||
@@ -372,7 +374,7 @@ const Configure = () => {
|
||||
<TextInput
|
||||
type="text"
|
||||
id="monitor-name"
|
||||
label="Display name"
|
||||
label={t("displayName")}
|
||||
isOptional={true}
|
||||
placeholder="Google"
|
||||
value={monitor?.name || ""}
|
||||
@@ -384,13 +386,13 @@ const Configure = () => {
|
||||
</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)}>
|
||||
<Typography component="p">When there is a new incident,</Typography>
|
||||
<Typography component="p">{t("whenNewIncident")}</Typography>
|
||||
{/* {Leaving components commented for future funtionality implimentation} */}
|
||||
{/* <Checkbox
|
||||
id="notify-sms"
|
||||
@@ -441,12 +443,12 @@ const Configure = () => {
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<Typography component="h2">Advanced settings</Typography>
|
||||
<Typography component="h2">{t("distributedUptimeCreateAdvancedSettings")}</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(20)}>
|
||||
<Select
|
||||
id="monitor-interval-configure"
|
||||
label="Check frequency"
|
||||
label={t("checkFrequency")}
|
||||
value={monitor?.interval / MS_PER_MINUTE || 1}
|
||||
onChange={(event) => handleChange(event, "interval")}
|
||||
items={frequencies}
|
||||
@@ -455,7 +457,7 @@ const Configure = () => {
|
||||
<>
|
||||
<Select
|
||||
id="match-method"
|
||||
label="Match Method"
|
||||
label={t("matchMethod")}
|
||||
value={monitor.matchMethod || "equal"}
|
||||
onChange={(event) => handleChange(event, "matchMethod")}
|
||||
items={matchMethodOptions}
|
||||
@@ -464,7 +466,7 @@ const Configure = () => {
|
||||
<TextInput
|
||||
type="text"
|
||||
id="expected-value"
|
||||
label="Expected value"
|
||||
label={t("expectedValue")}
|
||||
isOptional={true}
|
||||
placeholder={
|
||||
expectedValuePlaceholders[monitor.matchMethod || "equal"]
|
||||
@@ -479,8 +481,7 @@ const Configure = () => {
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
opacity={0.8}
|
||||
>
|
||||
The expected value is used to match against response result, and
|
||||
the match determines the status.
|
||||
{t("uptimeCreate")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
@@ -500,9 +501,7 @@ const Configure = () => {
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
opacity={0.8}
|
||||
>
|
||||
This expression will be evaluated against the reponse JSON data
|
||||
and the result will be used to match against the expected value.
|
||||
See
|
||||
{t("uptimeCreateJsonPath")}
|
||||
<Typography
|
||||
component="a"
|
||||
href="https://jmespath.org/"
|
||||
@@ -511,7 +510,7 @@ const Configure = () => {
|
||||
>
|
||||
jmespath.org
|
||||
</Typography>
|
||||
for query language documentation.
|
||||
{t("uptimeCreateJsonPathQuery")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</>
|
||||
@@ -530,7 +529,7 @@ const Configure = () => {
|
||||
sx={{ px: theme.spacing(12) }}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Save
|
||||
{t("settingsSave")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -10,7 +10,7 @@ import { checkEndpointResolution } from "../../../Features/UptimeMonitors/uptime
|
||||
import { monitorValidation } from "../../../Validation/validation";
|
||||
import { getUptimeMonitorById } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
|
||||
import { createUptimeMonitor } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
// MUI
|
||||
import { Box, Stack, Typography, Button, ButtonGroup } from "@mui/material";
|
||||
|
||||
@@ -240,6 +240,8 @@ const CreateMonitor = () => {
|
||||
fetchMonitor();
|
||||
}, [monitorId, dispatch, navigate]);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Box className="create-monitor">
|
||||
<Breadcrumbs list={crumbs} />
|
||||
@@ -257,7 +259,7 @@ const CreateMonitor = () => {
|
||||
component="span"
|
||||
fontSize="inherit"
|
||||
>
|
||||
Create your{" "}
|
||||
{t("createYour")}{" "}
|
||||
</Typography>
|
||||
<Typography
|
||||
component="span"
|
||||
@@ -265,22 +267,22 @@ const CreateMonitor = () => {
|
||||
fontSize="inherit"
|
||||
fontWeight="inherit"
|
||||
>
|
||||
monitor
|
||||
{t("monitor")}
|
||||
</Typography>
|
||||
</Typography>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<Typography component="h2">Checks to perform</Typography>
|
||||
<Typography component="h2">{t("distributedUptimeCreateChecks")}</Typography>
|
||||
<Typography component="p">
|
||||
You can always add or remove checks after adding your site.
|
||||
{t("distributedUptimeCreateChecksDescription")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(12)}>
|
||||
<Stack gap={theme.spacing(6)}>
|
||||
<Radio
|
||||
id="monitor-checks-http"
|
||||
title="Website monitoring"
|
||||
desc="Use HTTP(s) to monitor your website or API endpoint."
|
||||
title={t("websiteMonitoring")}
|
||||
desc={t("websiteMonitoringDescription")}
|
||||
size="small"
|
||||
value="http"
|
||||
checked={monitor.type === "http"}
|
||||
@@ -293,14 +295,14 @@ const CreateMonitor = () => {
|
||||
filled={https.toString()}
|
||||
onClick={() => setHttps(true)}
|
||||
>
|
||||
HTTPS
|
||||
{t("https")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="group"
|
||||
filled={(!https).toString()}
|
||||
onClick={() => setHttps(false)}
|
||||
>
|
||||
HTTP
|
||||
{t("http")}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
) : (
|
||||
@@ -309,8 +311,8 @@ const CreateMonitor = () => {
|
||||
</Stack>
|
||||
<Radio
|
||||
id="monitor-checks-ping"
|
||||
title="Ping monitoring"
|
||||
desc="Check whether your server is available or not."
|
||||
title={t("pingMonitoring")}
|
||||
desc={t("pingMonitoringDescription")}
|
||||
size="small"
|
||||
value="ping"
|
||||
checked={monitor.type === "ping"}
|
||||
@@ -318,8 +320,8 @@ const CreateMonitor = () => {
|
||||
/>
|
||||
<Radio
|
||||
id="monitor-checks-docker"
|
||||
title="Docker container monitoring"
|
||||
desc="Check whether your container is running or not."
|
||||
title={t("dockerContainerMonitoring")}
|
||||
desc={t("dockerContainerMonitoringDescription")}
|
||||
size="small"
|
||||
value="docker"
|
||||
checked={monitor.type === "docker"}
|
||||
@@ -327,8 +329,8 @@ const CreateMonitor = () => {
|
||||
/>
|
||||
<Radio
|
||||
id="monitor-checks-port"
|
||||
title="Port monitoring"
|
||||
desc="Check whether your port is open or not."
|
||||
title={t("portMonitoring")}
|
||||
desc={t("portMonitoringDescription")}
|
||||
size="small"
|
||||
value="port"
|
||||
checked={monitor.type === "port"}
|
||||
@@ -351,9 +353,9 @@ const CreateMonitor = () => {
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<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 type of monitor.
|
||||
{t("distributedUptimeCreateSelectURL")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(15)}>
|
||||
@@ -374,7 +376,7 @@ const CreateMonitor = () => {
|
||||
<TextInput
|
||||
type="number"
|
||||
id="monitor-port"
|
||||
label="Port to monitor"
|
||||
label={t("portToMonitor")}
|
||||
placeholder="5173"
|
||||
value={monitor.port}
|
||||
onChange={(event) => handleChange(event, "port")}
|
||||
@@ -385,7 +387,7 @@ const CreateMonitor = () => {
|
||||
<TextInput
|
||||
type="text"
|
||||
id="monitor-name"
|
||||
label="Display name"
|
||||
label={t("displayName")}
|
||||
isOptional={true}
|
||||
placeholder={monitorTypeMaps[monitor.type].namePlaceholder || ""}
|
||||
value={monitor.name}
|
||||
@@ -397,9 +399,9 @@ const CreateMonitor = () => {
|
||||
</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)}>
|
||||
@@ -427,7 +429,7 @@ const CreateMonitor = () => {
|
||||
</ConfigBox>
|
||||
<ConfigBox>
|
||||
<Box>
|
||||
<Typography component="h2">Advanced settings</Typography>
|
||||
<Typography component="h2">{t("distributedUptimeCreateAdvancedSettings")}</Typography>
|
||||
</Box>
|
||||
<Stack gap={theme.spacing(12)}>
|
||||
<Select
|
||||
@@ -465,8 +467,7 @@ const CreateMonitor = () => {
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
opacity={0.8}
|
||||
>
|
||||
The expected value is used to match against response result, and the
|
||||
match determines the status.
|
||||
{t("uptimeCreate")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
@@ -486,8 +487,7 @@ const CreateMonitor = () => {
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
opacity={0.8}
|
||||
>
|
||||
This expression will be evaluated against the reponse JSON data and
|
||||
the result will be used to match against the expected value. See
|
||||
{t("uptimeCreateJsonPath")}
|
||||
<Typography
|
||||
component="a"
|
||||
href="https://jmespath.org/"
|
||||
@@ -496,7 +496,7 @@ const CreateMonitor = () => {
|
||||
>
|
||||
jmespath.org
|
||||
</Typography>
|
||||
for query language documentation.
|
||||
{t("uptimeCreateJsonPathQuery")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</>
|
||||
@@ -514,7 +514,7 @@ const CreateMonitor = () => {
|
||||
disabled={!Object.values(errors).every((value) => value === undefined)}
|
||||
loading={isLoading}
|
||||
>
|
||||
Create monitor
|
||||
{t("createMonitor")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { useTheme } from "@mui/material";
|
||||
import { ResponsiveContainer, RadialBarChart, RadialBar, Cell } from "recharts";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const ResponseGaugeChart = ({ avgResponseTime }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { t } = useTranslation();
|
||||
let max = 1000; // max ms
|
||||
|
||||
const data = [
|
||||
@@ -61,7 +62,7 @@ const ResponseGaugeChart = ({ avgResponseTime }) => {
|
||||
textAnchor="start"
|
||||
fontSize={11}
|
||||
>
|
||||
low
|
||||
{t("low")}
|
||||
</text>
|
||||
<text
|
||||
x="100%"
|
||||
@@ -71,7 +72,7 @@ const ResponseGaugeChart = ({ avgResponseTime }) => {
|
||||
textAnchor="end"
|
||||
fontSize={11}
|
||||
>
|
||||
high
|
||||
{t("high")}
|
||||
</text>
|
||||
<text
|
||||
x="50%"
|
||||
|
||||
@@ -4,6 +4,7 @@ import HistoryIcon from "../../../../../assets/icons/history-icon.svg?react";
|
||||
import Table from "../../../../../Components/Table";
|
||||
import TablePagination from "../../../../../Components/Table/TablePagination";
|
||||
import { StatusLabel } from "../../../../../Components/Label";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { formatDateWithTz } from "../../../../../Utils/timeUtils";
|
||||
import SkeletonLayout from "./skeleton";
|
||||
const ResponseTable = ({
|
||||
@@ -16,6 +17,7 @@ const ResponseTable = ({
|
||||
rowsPerPage,
|
||||
setRowsPerPage,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
if (!shouldRender) {
|
||||
return <SkeletonLayout />;
|
||||
}
|
||||
@@ -23,7 +25,7 @@ const ResponseTable = ({
|
||||
const headers = [
|
||||
{
|
||||
id: "status",
|
||||
content: "Status",
|
||||
content: t("status"),
|
||||
render: (row) => {
|
||||
const status = row.status === true ? "up" : "down";
|
||||
|
||||
@@ -38,18 +40,18 @@ const ResponseTable = ({
|
||||
},
|
||||
{
|
||||
id: "date",
|
||||
content: "Date & Time",
|
||||
content: t("date&Time"),
|
||||
render: (row) =>
|
||||
formatDateWithTz(row.createdAt, "ddd, MMMM D, YYYY, HH:mm A", uiTimezone),
|
||||
},
|
||||
{
|
||||
id: "statusCode",
|
||||
content: "Status code",
|
||||
content: t("statusCode"),
|
||||
render: (row) => (row.statusCode ? row.statusCode : "N/A"),
|
||||
},
|
||||
{
|
||||
id: "message",
|
||||
content: "Message",
|
||||
content: t("message"),
|
||||
render: (row) => row.message,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -19,6 +19,7 @@ import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
import useMonitorFetch from "./Hooks/useMonitorFetch";
|
||||
import useCertificateFetch from "./Hooks/useCertificateFetch";
|
||||
import useChecksFetch from "./Hooks/useChecksFetch";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
// Constants
|
||||
const BREADCRUMBS = [
|
||||
@@ -46,6 +47,7 @@ const UptimeDetails = () => {
|
||||
const { monitorId } = useParams();
|
||||
const theme = useTheme();
|
||||
const isAdmin = useIsAdmin();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [monitor, monitorIsLoading, monitorNetworkError] = useMonitorFetch({
|
||||
monitorId,
|
||||
@@ -86,9 +88,9 @@ const UptimeDetails = () => {
|
||||
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>
|
||||
);
|
||||
}
|
||||
@@ -105,7 +107,7 @@ const UptimeDetails = () => {
|
||||
monitor={monitor}
|
||||
/>
|
||||
<GenericFallback>
|
||||
<Typography>There is no check history for this monitor yet.</Typography>
|
||||
<Typography>{t("distributedUptimeDetailsNoMonitorHistory")}</Typography>
|
||||
</GenericFallback>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -16,6 +16,7 @@ import { useTheme } from "@emotion/react";
|
||||
import useUtils from "../../Hooks/useUtils";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
/**
|
||||
* UptimeDataTable displays a table of uptime monitors with sorting, searching, and action capabilities
|
||||
@@ -59,6 +60,7 @@ const UptimeDataTable = ({
|
||||
const navigate = useNavigate();
|
||||
const { determineState } = useUtils();
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
// Local state
|
||||
// Handlers
|
||||
@@ -82,7 +84,7 @@ const UptimeDataTable = ({
|
||||
direction="row"
|
||||
onClick={() => handleSort("name")}
|
||||
>
|
||||
Host
|
||||
{t("host")}
|
||||
<Stack
|
||||
justifyContent="center"
|
||||
style={{
|
||||
@@ -118,7 +120,7 @@ const UptimeDataTable = ({
|
||||
onClick={() => handleSort("status")}
|
||||
>
|
||||
{" "}
|
||||
Status
|
||||
{t("status")}
|
||||
<Stack
|
||||
justifyContent="center"
|
||||
style={{
|
||||
@@ -146,12 +148,12 @@ const UptimeDataTable = ({
|
||||
},
|
||||
{
|
||||
id: "responseTime",
|
||||
content: "Response Time",
|
||||
content: t("responseTime"),
|
||||
render: (row) => <BarChart checks={row.monitor.checks.slice().reverse()} />,
|
||||
},
|
||||
{
|
||||
id: "type",
|
||||
content: "Type",
|
||||
content: t("type"),
|
||||
render: (row) => (
|
||||
<span style={{ textTransform: "uppercase" }}>
|
||||
{row.monitor.type === "http" ? "HTTP(s)" : row.monitor.type}
|
||||
@@ -160,7 +162,7 @@ const UptimeDataTable = ({
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
content: "Actions",
|
||||
content: t("actions"),
|
||||
render: (row) => (
|
||||
<ActionsMenu
|
||||
monitor={row.monitor}
|
||||
|
||||
@@ -30,6 +30,7 @@ import { setRowsPerPage } from "../../../Features/UI/uiSlice";
|
||||
import PropTypes from "prop-types";
|
||||
import useFetchMonitorsWithSummary from "../../../Hooks/useFetchMonitorsWithSummary";
|
||||
import useFetchMonitorsWithChecks from "../../../Hooks/useFetchMonitorsWithChecks";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const BREADCRUMBS = [{ name: `Uptime`, path: "/uptime" }];
|
||||
const TYPES = ["http", "ping", "docker", "port"];
|
||||
@@ -75,6 +76,7 @@ const UptimeMonitors = () => {
|
||||
const theme = useTheme();
|
||||
const isAdmin = useIsAdmin();
|
||||
const dispatch = useDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
// Handlers
|
||||
const handleChangePage = (event, newPage) => {
|
||||
@@ -130,9 +132,9 @@ const UptimeMonitors = () => {
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -107,6 +107,29 @@
|
||||
"aboutus": "About Us",
|
||||
"signUP": "Sign Up",
|
||||
"now": "Now",
|
||||
"createYour": "Create your",
|
||||
"createMonitor": "Create monitor",
|
||||
"actions": "Actions",
|
||||
"pause": "Pause",
|
||||
"resume": "Resume",
|
||||
"editing": "Editing...",
|
||||
"url": "URL",
|
||||
"access": "Access",
|
||||
"timezone": "Timezone",
|
||||
"features": "Features",
|
||||
"administrator": "Administrator?",
|
||||
"loginHere": "Login here",
|
||||
"displayName": "Display name",
|
||||
"urlMonitor": "URL to monitor",
|
||||
"portToMonitor": "Port to monitor",
|
||||
"websiteMonitoring": "Website monitoring",
|
||||
"websiteMonitoringDescription": "Use HTTP(s) to monitor your website or API endpoint.",
|
||||
"pingMonitoring": "Ping monitoring",
|
||||
"pingMonitoringDescription": "Check whether your server is available or not.",
|
||||
"dockerContainerMonitoring": "Docker container monitoring",
|
||||
"dockerContainerMonitoringDescription": "Check whether your Docker container is running or not.",
|
||||
"portMonitoring": "Port monitoring",
|
||||
"portMonitoringDescription": "Check whether your port is open or not.",
|
||||
"delete": "Delete",
|
||||
"configure": "Configure",
|
||||
"networkError": "Network error",
|
||||
@@ -143,6 +166,80 @@
|
||||
"distributedUptimeDetailsMonitorHeader": "Distributed Uptime Monitoring powered by DePIN",
|
||||
"distributedUptimeDetailsStatusHeaderUptime": "Uptime:",
|
||||
"distributedUptimeDetailsStatusHeaderLastUpdate": "Last updated",
|
||||
"createMaintenanceWindow": "Create maintenance window",
|
||||
"createMaintenance": "Create maintenance",
|
||||
"editMaintenance": "Edit maintenance",
|
||||
"maintenanceWindowName": "Maintenance Window Name",
|
||||
"friendlyNameInput": "Friendly name",
|
||||
"friendlyNamePlaceholder": "Maintenance at __ : __ for ___ minutes",
|
||||
"maintenanceRepeat": "Maintenance Repeat",
|
||||
"maintenance": "maintenance",
|
||||
"duration": "Duration",
|
||||
"addMonitors": "Add monitors",
|
||||
"window": "window",
|
||||
"cancel": "Cancel",
|
||||
"status": "Status",
|
||||
"message": "Message",
|
||||
"low": "low",
|
||||
"high": "high",
|
||||
"host": "Host",
|
||||
"statusCode": "Status code",
|
||||
"date&Time": "Date & Time",
|
||||
"type": "Type",
|
||||
"statusPageName": "Status page name",
|
||||
"publicURL": "Public URL",
|
||||
"repeat": "Repeat",
|
||||
"edit": "Edit",
|
||||
"createA": "Create a",
|
||||
"remove": "Remove",
|
||||
"maintenanceWindowDescription": "Your pings won't be sent during this time frame",
|
||||
"startTime": "Start time",
|
||||
"timeZoneInfo": "All dates and times are in GMT+0 time zone.",
|
||||
"monitorsToApply": "Monitors to apply maintenance window to",
|
||||
"nextWindow": "Next window",
|
||||
"notFoundButton": "Go to the main dashboard",
|
||||
"pageSpeedConfigureSettingsDescription": "Here you can select the URL of the host, together with the type of monitor.",
|
||||
"monitorDisplayName": "Monitor display name",
|
||||
"whenNewIncident,": "When there is a new incident,",
|
||||
"notifySMS": "Notify via SMS (coming soon)",
|
||||
"notifyEmails": "Also notify via email to multiple addresses (coming soon)",
|
||||
"seperateEmails": "You can separate multiple emails with a comma",
|
||||
"checkFrequency": "Check frequency",
|
||||
"matchMethod": "Match Method",
|
||||
"expectedValue": "Expected value",
|
||||
"deleteDialogTitle": "Do you really want to delete this monitor?",
|
||||
"deleteDialogDescription": "Once deleted, this monitor cannot be retrieved.",
|
||||
"pageSpeedMonitor": "PageSpeed monitor",
|
||||
"shown": "Shown",
|
||||
"ago": "ago",
|
||||
"companyName": "Company name",
|
||||
"pageSpeedDetailsPerformanceReport": "Values are estimated and may vary.",
|
||||
"pageSpeedDetailsPerformanceReportCalculator": "See calculator",
|
||||
"checkingEvery": "Checking every",
|
||||
"statusPageCreateSettings": "If your status page is ready, you can mark it as published.",
|
||||
"basicInformation": "Basic Information",
|
||||
"statusPageCreateBasicInfoDescription": "Define company name and the subdomain that your status page points to.",
|
||||
"statusPageCreateSelectTimeZoneDescription": "Select the timezone that your status page will be displayed in.",
|
||||
"statusPageCreateAppearanceDescription": "Define the default look and feel of your public status page.",
|
||||
"statusPageCreateSettingsCheckboxLabel": "Published and visible to the public",
|
||||
"statusPageCreateBasicInfoStatusPageAddress": "Your status page address",
|
||||
"statusPageCreateTabsContent": "Status page servers",
|
||||
"statusPageCreateTabsContentDescription": "You can add any number of servers that you monitor to your status page. You can also reorder them for the best viewing experience.",
|
||||
"statusPageCreateTabsContentFeaturesDescription": "Show more details on the status page",
|
||||
"showCharts": "Show charts",
|
||||
"showUptimePercentage": "Show uptime percentage",
|
||||
"removeLogo": "Remove Logo",
|
||||
"statusPageStatus": "A public status page is not set up.",
|
||||
"statusPageStatusContactAdmin": "Please contact to your administrator",
|
||||
"statusPageStatusNotPublic": "This status page is not public.",
|
||||
"statusPageStatusNoPage": "There's no status page here.",
|
||||
"statusPageStatusServiceStatus": "Service status",
|
||||
"deleteStatusPage": "Do you want to delete this status page?",
|
||||
"deleteStatusPageConfirm": "Yes, delete status page",
|
||||
"deleteStatusPageDescription": "Once deleted, your status page cannot be retrieved.",
|
||||
"uptimeCreate": "The expected value is used to match against response result, and the match determines the status.",
|
||||
"uptimeCreateJsonPath": "This expression will be evaluated against the reponse JSON data and the result will be used to match against the expected value. See",
|
||||
"uptimeCreateJsonPathQuery": "for query language documentation.",
|
||||
"notifications": {
|
||||
"enableNotifications": "Enable {{platform}} notifications",
|
||||
"testNotification": "Test notification",
|
||||
|
||||
Reference in New Issue
Block a user