diff --git a/.gitignore b/.gitignore
index 2299e795a..f6e292bc9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@
.VSCodeCounter
*.sh
mongo
-node_modules/
\ No newline at end of file
+node_modules/
+docs/architecture
\ No newline at end of file
diff --git a/client/package-lock.json b/client/package-lock.json
index 84fc4c3a6..038814543 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -2472,11 +2472,13 @@
}
},
"node_modules/axios": {
- "version": "1.13.4",
+ "version": "1.13.5",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
+ "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
"license": "MIT",
"dependencies": {
- "follow-redirects": "^1.15.6",
- "form-data": "^4.0.4",
+ "follow-redirects": "^1.15.11",
+ "form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 0a6b364f8..a8a25669e 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -1,4 +1,4 @@
-import { useEffect, type CSSProperties } from "react";
+import { type CSSProperties } from "react";
import { useSelector } from "react-redux";
import "react-toastify/dist/ReactToastify.css";
import { ToastContainer } from "react-toastify";
@@ -6,7 +6,6 @@ import { ThemeProvider } from "@emotion/react";
import lightTheme from "./Utils/Theme/lightTheme";
import darkTheme from "./Utils/Theme/darkTheme";
import { CssBaseline, GlobalStyles } from "@mui/material";
-import { logger } from "./Utils/Logger"; // Import the logger
import { Routes } from "./Routes";
import AppLayout from "@/Components/v2/layout/AppLayout";
import type { RootState } from "@/Types/state";
@@ -14,13 +13,6 @@ import type { RootState } from "@/Types/state";
function App() {
const mode = useSelector((state: RootState) => state.ui.mode);
- // Cleanup
- useEffect(() => {
- return () => {
- logger.cleanup();
- };
- }, []);
-
const theme = mode === "light" ? lightTheme : darkTheme;
return (
diff --git a/client/src/Components/v2/design-elements/StatusBox.tsx b/client/src/Components/v2/design-elements/StatusBox.tsx
index a83ebcf5d..1be76988b 100644
--- a/client/src/Components/v2/design-elements/StatusBox.tsx
+++ b/client/src/Components/v2/design-elements/StatusBox.tsx
@@ -2,7 +2,6 @@ import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
import { BaseBox } from "@/Components/v2/design-elements";
-import Background from "@/assets/Images/background-grid.svg?react";
import { useTranslation } from "react-i18next";
import type { SxProps } from "@mui/material";
@@ -18,6 +17,7 @@ export const BGBox = ({ children, sx }: StatusBoxProps) => {
return (
{
>
-
-
+ top={0}
+ left={0}
+ right={0}
+ bottom={0}
+ sx={{
+ pointerEvents: "none",
+ backgroundImage: `
+ linear-gradient(${theme.palette.divider} 1px, transparent 1px),
+ linear-gradient(90deg, ${theme.palette.divider} 1px, transparent 1px)
+ `,
+ backgroundSize: "24px 24px",
+ maskImage:
+ "linear-gradient(135deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 30%, rgba(0,0,0,0.4) 100%)",
+ WebkitMaskImage:
+ "linear-gradient(135deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 30%, rgba(0,0,0,0.4) 100%)",
+ }}
+ />
{children}
);
diff --git a/client/src/Components/v1/I18nLoader/index.jsx b/client/src/Components/v2/i18nLoader/index.tsx
similarity index 63%
rename from client/src/Components/v1/I18nLoader/index.jsx
rename to client/src/Components/v2/i18nLoader/index.tsx
index 676e63d7b..f0555afed 100644
--- a/client/src/Components/v1/I18nLoader/index.jsx
+++ b/client/src/Components/v2/i18nLoader/index.tsx
@@ -1,8 +1,9 @@
-import i18n from "../../../Utils/i18n.js";
+import i18n from "@/Utils/i18n.js";
import { useSelector } from "react-redux";
import { useEffect } from "react";
+import type { RootState } from "@/store";
const I18nLoader = () => {
- const language = useSelector((state) => state.ui.language ?? "en");
+ const language = useSelector((state: RootState) => state.ui.language ?? "en");
useEffect(() => {
if (language && i18n.language !== language) {
diff --git a/client/src/Components/v2/inputs/ImageUpload.tsx b/client/src/Components/v2/inputs/ImageUpload.tsx
index 6c9fc1783..0d0b77b40 100644
--- a/client/src/Components/v2/inputs/ImageUpload.tsx
+++ b/client/src/Components/v2/inputs/ImageUpload.tsx
@@ -38,11 +38,11 @@ export const ImageUpload = ({
const isValidType = accept.some((type) => file.type.includes(type));
const isValidSize = file.size <= maxSize;
if (!isValidType) {
- setLocalError(t("common.errors.invalidFileFormat"));
+ setLocalError(t("components.imageUpload.errors.invalidFileFormat"));
return;
}
if (!isValidSize) {
- setLocalError(t("common.errors.invalidFileSize"));
+ setLocalError(t("components.imageUpload.errors.invalidFileSize"));
return;
}
setLocalError(null);
@@ -137,15 +137,15 @@ export const ImageUpload = ({
color="primary"
fontWeight={500}
>
- {t("common.imageUpload.clickToUpload")}
+ {t("components.imageUpload.clickToUpload")}
{" "}
- {t("common.imageUpload.orDragAndDrop")}
+ {t("components.imageUpload.orDragAndDrop")}
- {accept.join(", ").toUpperCase()} • {t("common.imageUpload.maxSize")}{" "}
+ {accept.join(", ").toUpperCase()} • {t("components.imageUpload.maxSize")}{" "}
{Math.round(maxSize / 1024 / 1024)}MB
diff --git a/client/src/Components/v2/inputs/Slider.tsx b/client/src/Components/v2/inputs/Slider.tsx
index 97a16ac2c..83037ab54 100644
--- a/client/src/Components/v2/inputs/Slider.tsx
+++ b/client/src/Components/v2/inputs/Slider.tsx
@@ -41,7 +41,10 @@ export const SliderInput = forwardRef(
"& .MuiSlider-thumb": {
backgroundColor: "#fff",
"&:hover, &.Mui-focusVisible": {
- boxShadow: `0 0 0 8px ${theme.palette.primary.main}20`,
+ boxShadow: "none",
+ },
+ "&:active": {
+ boxShadow: "none",
},
},
"& .MuiSlider-valueLabel": {
diff --git a/client/src/Components/v2/monitors/charts/HistogramStatus.tsx b/client/src/Components/v2/monitors/charts/HistogramStatus.tsx
index 1c25c339e..d3aa62a69 100644
--- a/client/src/Components/v2/monitors/charts/HistogramStatus.tsx
+++ b/client/src/Components/v2/monitors/charts/HistogramStatus.tsx
@@ -3,7 +3,7 @@ import Typography from "@mui/material/Typography";
import { BaseChart } from "@/Components/v2/design-elements";
import { useTheme } from "@mui/material/styles";
import { useSelector } from "react-redux";
-import { formatDateWithTz } from "@/Utils/timeUtilsLegacy";
+import { formatDateWithTz } from "@/Utils/TimeUtils";
import { useTranslation } from "react-i18next";
import { ResponsiveContainer, BarChart, XAxis, Bar, Cell, Tooltip } from "recharts";
import { getResponseTimeColor } from "@/Utils/MonitorUtils";
diff --git a/client/src/Features/UI/uiSlice.ts b/client/src/Features/UI/uiSlice.ts
index 0675784b9..84e8248db 100644
--- a/client/src/Features/UI/uiSlice.ts
+++ b/client/src/Features/UI/uiSlice.ts
@@ -12,11 +12,6 @@ interface SidebarState {
collapsed: boolean;
}
-interface GreetingState {
- index: number;
- lastUpdate: string | null;
-}
-
interface UIState {
monitors: TableState;
team: TableState;
@@ -26,7 +21,6 @@ interface UIState {
sidebar: SidebarState;
mode: ThemeMode;
showURL: boolean;
- greeting: GreetingState;
timezone: string;
distributedUptimeEnabled: boolean;
language: string;
@@ -60,7 +54,6 @@ const initialState: UIState = {
},
mode: initialMode,
showURL: false,
- greeting: { index: 0, lastUpdate: null },
timezone: "America/Toronto",
distributedUptimeEnabled: false,
language: "en",
@@ -94,13 +87,7 @@ const uiSlice = createSlice({
setShowURL: (state, action: PayloadAction) => {
state.showURL = action.payload;
},
- setGreeting: (
- state,
- action: PayloadAction<{ index: number; lastUpdate: string | null }>
- ) => {
- state.greeting.index = action.payload.index;
- state.greeting.lastUpdate = action.payload.lastUpdate;
- },
+
setTimezone: (state, action: PayloadAction<{ timezone: string }>) => {
state.timezone = action.payload.timezone;
},
@@ -124,7 +111,6 @@ export const {
setCollapsed,
setMode,
setShowURL,
- setGreeting,
setTimezone,
setDistributedUptimeEnabled,
setLanguage,
diff --git a/client/src/Pages/Auth/SetNewPassword/index.tsx b/client/src/Pages/Auth/SetNewPassword/index.tsx
index 09bd565f1..2e99be254 100644
--- a/client/src/Pages/Auth/SetNewPassword/index.tsx
+++ b/client/src/Pages/Auth/SetNewPassword/index.tsx
@@ -97,27 +97,27 @@ const SetNewPasswordPage = () => {
/>
@@ -127,7 +127,7 @@ const SetNewPasswordPage = () => {
fullWidth
loading={loading}
>
- {t("auth.forgotPassword.buttons.resetPassword")}
+ {t("common.buttons.resetPassword")}
{
render={({ field, fieldState }) => (
field.onChange(Number(e.target.value) || 0)}
+ value={field.value === 0 ? "" : field.value}
+ onChange={(e) => {
+ const val = e.target.value;
+ field.onChange(val === "" ? 0 : Number(val));
+ }}
type="number"
- fieldLabel={t("portToMonitor")}
- placeholder="5173"
+ fieldLabel={t("pages.createMonitor.form.general.option.port.label")}
+ placeholder={t(
+ "pages.createMonitor.form.general.option.port.placeholder"
+ )}
fullWidth
error={!!fieldState.error}
helperText={fieldState.error?.message ?? ""}
@@ -351,10 +356,12 @@ const CreateMonitorPage = () => {
)}
/>
}
/>
+ {/* Alert Thresholds - only for hardware type */}
+ {generalSettingsConfig.showSecret && (
+
+ (
+ `${value}%`}
+ />
+ )}
+ />
+ (
+ `${value}%`}
+ />
+ )}
+ />
+ (
+ `${value}%`}
+ />
+ )}
+ />
+ (
+ `${value}°C`}
+ />
+ )}
+ />
+
+ }
+ />
+ )}
+
{
"pages.createMonitor.form.advanced.option.matchMethod.label"
)}
>
- {t("matchMethodOptions.equal")}
-
- {t("matchMethodOptions.include")}
+
+ {t(
+ "pages.createMonitor.form.advanced.option.matchMethod.equal"
+ )}
+
+
+ {t(
+ "pages.createMonitor.form.advanced.option.matchMethod.include"
+ )}
+
+
+ {t(
+ "pages.createMonitor.form.advanced.option.matchMethod.regex"
+ )}
- {t("matchMethodOptions.regex")}
)}
/>
diff --git a/client/src/Pages/Incidents/Components/DialogResolution.tsx b/client/src/Pages/Incidents/Components/DialogResolution.tsx
index 648af52a9..a102b1de3 100644
--- a/client/src/Pages/Incidents/Components/DialogResolution.tsx
+++ b/client/src/Pages/Incidents/Components/DialogResolution.tsx
@@ -46,10 +46,9 @@ export const DialogResolution = ({
return (