Merge branch 'develop' into fix/incidents

This commit is contained in:
Alex Holliday
2026-01-20 19:08:03 +00:00
12 changed files with 95 additions and 55 deletions
@@ -14,15 +14,7 @@
}
} */
/* .home-layout aside {
position: sticky;
top: 0;
left: 0;
height: 100vh;
max-width: var(--env-var-side-bar-width);
} */
.home-layout > div {
.home-layout > .home-content-wrapper {
min-height: calc(100vh - var(--env-var-spacing-2) * 2);
flex: 1;
}
@@ -1,17 +1,27 @@
import Sidebar from "../../Sidebar/index.jsx";
import { Outlet } from "react-router";
import { Stack } from "@mui/material";
import { Box, Stack } from "@mui/material";
import { useSidebar } from "@/Hooks/useSidebar.js";
import "./index.css";
const HomeLayout = () => {
const { width, transition } = useSidebar();
return (
<Stack
className="home-layout"
flexDirection="row"
gap={14}
>
<Sidebar />
{/* Spacer for fixed sidebar */}
<Box
sx={{
width,
flexShrink: 0,
transition,
}}
/>
<Stack className="home-content-wrapper">
<Outlet />
</Stack>
+9 -11
View File
@@ -12,9 +12,9 @@ import Icon from "../Icon";
// Utils
import { useTheme } from "@mui/material/styles";
import { useSelector } from "react-redux";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router";
import { useSidebar } from "@/Hooks/useSidebar.js";
const URL_MAP = {
support: "https://discord.com/invite/NAb6H3UTjK",
@@ -65,8 +65,7 @@ const Sidebar = () => {
const theme = useTheme();
const { t } = useTranslation();
const navigate = useNavigate();
// Redux state
const collapsed = useSelector((state) => state.ui.sidebar?.collapsed ?? false);
const { collapsed, width, transition } = useSidebar();
const menu = getMenu(t);
const otherMenuItems = getOtherMenuItems(t);
@@ -75,20 +74,19 @@ const Sidebar = () => {
return (
<Stack
height="100vh"
width={
collapsed
? "var(--env-var-side-bar-collapsed-width)"
: "var(--env-var-side-bar-width)"
}
width={width}
component="aside"
position="sticky"
position="fixed"
top={0}
borderRight={`1px solid ${theme.palette.primary.lowContrast}`}
left={0}
paddingTop={theme.spacing(6)}
paddingBottom={theme.spacing(6)}
gap={theme.spacing(6)}
sx={{
transition: "width 650ms cubic-bezier(0.36, -0.01, 0, 0.77)",
transition,
backgroundColor: "#000000",
borderRight: "1px solid #344054",
zIndex: 1000,
}}
>
<CollapseButton collapsed={collapsed} />
+29
View File
@@ -0,0 +1,29 @@
import { useSelector } from "react-redux";
// CSS variable names for sidebar widths
const SIDEBAR_WIDTH_VAR = "var(--env-var-side-bar-width)";
const SIDEBAR_COLLAPSED_WIDTH_VAR = "var(--env-var-side-bar-collapsed-width)";
// Transition timing for sidebar width changes
const SIDEBAR_TRANSITION = "width 650ms cubic-bezier(0.36, -0.01, 0, 0.77)";
/**
* Hook to get sidebar state and computed width
* Centralizes sidebar width logic to avoid duplication between Sidebar and HomeLayout
*
* @returns {Object} Sidebar state and styles
* @returns {boolean} collapsed - Whether the sidebar is collapsed
* @returns {string} width - CSS width value based on collapsed state
* @returns {string} transition - CSS transition for width changes
*/
export const useSidebar = () => {
const collapsed = useSelector((state) => state.ui.sidebar?.collapsed ?? false);
return {
collapsed,
width: collapsed ? SIDEBAR_COLLAPSED_WIDTH_VAR : SIDEBAR_WIDTH_VAR,
transition: SIDEBAR_TRANSITION,
};
};
export default useSidebar;
@@ -129,7 +129,9 @@ const CreateInfrastructureMonitor = () => {
const onSubmit = async (event) => {
event.preventDefault();
const form = buildForm(infrastructureMonitor, https);
const error = validateForm(form);
// When editing, exclude URL from validation since it's disabled and can't be changed
const formToValidate = isCreate ? form : { ...form, url: monitor.url };
const error = validateForm(formToValidate);
if (error) {
return;
}
@@ -205,14 +207,14 @@ const CreateInfrastructureMonitor = () => {
<></>
)}
</Typography>
{!isCreate && (
{!isCreate && monitor && (
<MonitorStatusHeader
monitor={monitor}
infrastructureMonitor={infrastructureMonitor}
/>
)}
</Box>
{!isCreate && (
{!isCreate && monitor && (
<MonitorActionButtons
monitor={monitor}
isBusy={isBusy}
@@ -14,7 +14,7 @@ import { useTheme } from "@emotion/react";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils.jsx";
import PropTypes from "prop-types";
const BaseContainer = ({ children, sx = {} }) => {
const BaseContainer = ({ children, sx = {}, shouldExpand = false }) => {
const theme = useTheme();
const { getDimensions } = useHardwareUtils();
return (
@@ -22,7 +22,7 @@ const BaseContainer = ({ children, sx = {} }) => {
sx={{
padding: `${theme.spacing(getDimensions().baseBoxPaddingVertical)} ${theme.spacing(getDimensions().baseBoxPaddingHorizontal)}`,
minWidth: 200,
width: 225,
width: shouldExpand ? "100%" : 225,
backgroundColor: theme.palette.primary.main,
border: 1,
borderStyle: "solid",
@@ -38,6 +38,7 @@ const BaseContainer = ({ children, sx = {} }) => {
BaseContainer.propTypes = {
children: PropTypes.node.isRequired,
sx: PropTypes.object,
shouldExpand: PropTypes.bool,
};
export default BaseContainer;
@@ -17,21 +17,26 @@ const Gauge = ({
valueThree,
metricFour,
valueFour,
shouldExpand = false,
}) => {
const theme = useTheme();
const valueStyle = {
borderRadius: theme.spacing(2),
backgroundColor: theme.palette.tertiary.main,
width: "40%",
minWidth: "40%",
maxWidth: "60%",
mb: theme.spacing(2),
mt: theme.spacing(2),
pr: theme.spacing(2),
textAlign: "right",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
};
return (
<BaseContainer>
<BaseContainer shouldExpand={shouldExpand}>
<Stack
direction="column"
gap={theme.spacing(2)}
@@ -116,6 +121,7 @@ Gauge.propTypes = {
valueThree: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
metricFour: PropTypes.string,
valueFour: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
shouldExpand: PropTypes.bool,
};
export default Gauge;
@@ -1,5 +1,5 @@
// Components
import { Stack } from "@mui/material";
import { Box } from "@mui/material";
import Gauge from "./Gauge.jsx";
import SkeletonLayout from "./skeleton.jsx";
import PropTypes from "prop-types";
@@ -65,16 +65,23 @@ const Gauges = ({ isLoading = false, monitor }) => {
valueTwo: formatBytes(disk.total_bytes, true),
metricThree: t("device"),
valueThree: formatDeviceName(disk.device),
metricFour: t("mountpoint"),
metricFour: t("mountedOn"),
valueFour: formatMountpoint(disk.mountpoint),
})),
];
// Only expand gauges to fill row when there are 4 or more
const shouldExpand = gauges.length >= 4;
return (
<Stack
direction="row"
flexWrap="wrap"
gap={theme.spacing(8)}
<Box
sx={{
display: "grid",
gridTemplateColumns: shouldExpand
? "repeat(auto-fill, minmax(200px, 1fr))"
: "repeat(auto-fill, 225px)",
gap: theme.spacing(4),
}}
>
{gauges.map((gauge) => {
return (
@@ -90,10 +97,11 @@ const Gauges = ({ isLoading = false, monitor }) => {
valueThree={gauge.valueThree}
metricFour={gauge.metricFour}
valueFour={gauge.valueFour}
shouldExpand={shouldExpand}
/>
);
})}
</Stack>
</Box>
);
};
@@ -123,14 +123,7 @@ const useHardwareUtils = () => {
const formatDeviceName = (device) => {
const deviceStr = String(device || "");
// Extract the last part of the path (after last '/')
const parts = deviceStr.split("/");
const lastPart = parts[parts.length - 1];
// If there's more than one part, show with "..." prefix
const displayText = parts.length > 1 ? `.../${lastPart}` : deviceStr;
// Always show tooltip with full device path
// Show full device path
return (
<Tooltip
title={deviceStr}
@@ -149,7 +142,7 @@ const useHardwareUtils = () => {
maxWidth: "100%",
}}
>
{displayText}
{deviceStr}
</Typography>
</Tooltip>
);
@@ -181,14 +174,7 @@ const useHardwareUtils = () => {
);
}
// Extract the last part of the path (after last '/')
const parts = mountpointStr.split("/");
const lastPart = parts[parts.length - 1];
// If there's more than one part, show with "..." prefix
const displayText = parts.length > 1 ? `.../${lastPart}` : mountpointStr;
// Always show tooltip with full mountpoint path
// Show full mountpoint path
return (
<Tooltip
title={mountpointStr}
@@ -207,7 +193,7 @@ const useHardwareUtils = () => {
maxWidth: "100%",
}}
>
{displayText}
{mountpointStr}
</Typography>
</Tooltip>
);
+6
View File
@@ -4,6 +4,12 @@
box-sizing: border-box;
}
html,
body {
background-color: #000000;
overscroll-behavior: none;
}
html {
scroll-behavior: smooth;
}
+2
View File
@@ -193,6 +193,8 @@
"total": "Total",
"cores": "Cores",
"frequency": "Frequency",
"device": "Device",
"mountedOn": "Mounted on",
"status": "Status",
"cpuPhysical": "CPU (Physical)",
"cpuLogical": "CPU (Logical)",