Merge pull request #1556 from bluewave-labs/fix/colors-general

Fix/colors general
This commit is contained in:
Alexander Holliday authored and GitHub committed 2025-01-21 13:26:13 -08:00
commit c4d223aee5
108 files changed
+1479 -1129

No files matched your search

+1
View File
@@ -40,6 +40,7 @@ function App() {
return {
body: {
backgroundImage: `radial-gradient(circle, ${palette.gradient.color1}, ${palette.gradient.color2}, ${palette.gradient.color3}, ${palette.gradient.color4}, ${palette.gradient.color5})`,
color: palette.primary.contrastText,
},
};
}}
+6 -3
View File
@@ -32,9 +32,12 @@ const icons = {
const Alert = ({ variant, title, body, isToast, hasIcon = true, onClick }) => {
const theme = useTheme();
/* TODO
This needs fixing. text bg and border not necessarilly exist. Probably text becomes contrastText. border becomes contrastText. bg becomes dark.
Check possible variants, see implementation in light and dark theme, and adjust */
const { text, bg, border } = theme.palette[variant];
Do we need other variants for alert?
*/
const text = theme.palette.secondary.contrastText;
const bg = theme.palette.secondary.main;
const border = theme.palette.secondary.contrastText;
const icon = icons[variant];
return (
+8 -2
View File
@@ -1,5 +1,6 @@
import PropTypes from "prop-types";
import { Box, Stack } from "@mui/material";
import { Box, Stack, useTheme } from "@mui/material";
// import useUtils from "../../Pages/Uptime/utils";
/**
* A component that renders a pulsating dot with a specified color.
@@ -15,6 +16,11 @@ import { Box, Stack } from "@mui/material";
*/
const PulseDot = ({ color }) => {
const theme = useTheme();
// const { statusToTheme } = useUtils();
/* TODO refactor so it gets status and gets theme color. Then uses theme.palette.[themeColor].lowContrast */
/* const themeColor = statusToTheme[status]; */
return (
<Stack
width="26px"
@@ -44,7 +50,7 @@ const PulseDot = ({ color }) => {
width: "7px",
height: "7px",
borderRadius: "50%",
backgroundColor: "white",
backgroundColor: theme.palette.accent.contrastText,
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
+6 -3
View File
@@ -32,13 +32,16 @@ const Avatar = ({ src, small, sx }) => {
return (
<MuiAvatar
alt={`${user?.firstName} ${user?.lastName}`}
/* TODO What is the /static/images/avatar/2.jpg ?*/
src={src ? src : user?.avatarImage ? image : "/static/images/avatar/2.jpg"}
sx={{
fontSize: small ? "16px" : "22px",
color: "white",
fontWeight: 400,
backgroundColor: theme.palette.primary.main, // Same BG color as checkmate BG in sidebar
color: theme.palette.accent.contrastText,
backgroundColor: theme.palette.accent.main, // Same BG color as checkmate BG in sidebar
display: "inline-flex",
/*
TODO not sure what this is for*/
"&::before": {
content: `""`,
position: "absolute",
@@ -54,7 +57,7 @@ const Avatar = ({ src, small, sx }) => {
}}
>
{user.firstName?.charAt(0)}
{user.lastName?.charAt(0) || ''}
{user.lastName?.charAt(0) || ""}
</MuiAvatar>
);
};
+360
View File
@@ -0,0 +1,360 @@
/* TODO
Should we delete this?
*/
import PropTypes from "prop-types";
import { useState, useEffect } from "react";
import { useTheme } from "@emotion/react";
import {
TableContainer,
Paper,
Table,
TableHead,
TableRow,
TableCell,
TableBody,
TablePagination,
Box,
Typography,
Stack,
Button,
} from "@mui/material";
import { useDispatch, useSelector } from "react-redux";
import { setRowsPerPage } from "../../Features/UI/uiSlice";
import LeftArrowDouble from "../../assets/icons/left-arrow-double.svg?react";
import RightArrowDouble from "../../assets/icons/right-arrow-double.svg?react";
import LeftArrow from "../../assets/icons/left-arrow.svg?react";
import RightArrow from "../../assets/icons/right-arrow.svg?react";
import SelectorVertical from "../../assets/icons/selector-vertical.svg?react";
import "./index.css";
/**
* Component for pagination actions (first, previous, next, last).
*
* @component
* @param {Object} props
* @param {number} props.count - Total number of items.
* @param {number} props.page - Current page number.
* @param {number} props.rowsPerPage - Number of rows per page.
* @param {function} props.onPageChange - Callback function to handle page change.
*
* @returns {JSX.Element} Pagination actions component.
*/
const TablePaginationActions = (props) => {
const { count, page, rowsPerPage, onPageChange } = props;
const handleFirstPageButtonClick = (event) => {
onPageChange(event, 0);
};
const handleBackButtonClick = (event) => {
onPageChange(event, page - 1);
};
const handleNextButtonClick = (event) => {
onPageChange(event, page + 1);
};
const handleLastPageButtonClick = (event) => {
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
};
return (
<Box sx={{ flexShrink: 0, ml: "24px" }}>
<Button
variant="group"
onClick={handleFirstPageButtonClick}
disabled={page === 0}
aria-label="first page"
>
<LeftArrowDouble />
</Button>
<Button
variant="group"
onClick={handleBackButtonClick}
disabled={page === 0}
aria-label="previous page"
>
<LeftArrow />
</Button>
<Button
variant="group"
onClick={handleNextButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="next page"
>
<RightArrow />
</Button>
<Button
variant="group"
onClick={handleLastPageButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="last page"
>
<RightArrowDouble />
</Button>
</Box>
);
};
TablePaginationActions.propTypes = {
count: PropTypes.number.isRequired,
page: PropTypes.number.isRequired,
rowsPerPage: PropTypes.number.isRequired,
onPageChange: PropTypes.func.isRequired,
};
/**
* BasicTable Component
* Renders a table with optional pagination.
*
* @component
* @param {Object} props - Component props.
* @param {Object} props.data - Data for the table including columns and rows.
* @param {Array} props.data.cols - Array of objects for column headers.
* @param {number} props.data.cols[].id - Unique identifier for the column.
* @param {string} props.data.cols[].name - Name of the column to display as header.
* @param {Array} props.data.rows - Array of row objects.
* @param {number} props.data.rows[].id - Unique identifier for the row.
* @param {Array} props.data.rows[].data - Array of cell data objects for the row.
* @param {number} props.data.rows[].data[].id - Unique identifier for the cell.
* @param {JSX.Element} props.data.rows[].data[].data - The content to display in the cell.
* @param {function} props.data.rows.data.handleClick - Function to call when the row is clicked.
* @param {boolean} [props.paginated=false] - Flag to enable pagination.
* @param {boolean} [props.reversed=false] - Flag to enable reverse order.
* @param {number} props.rowsPerPage- Number of rows per page (table).
* @param {string} props.emptyMessage - Message to display when there is no data.
* @example
* const data = {
* cols: [
* { id: 1, name: "First Col" },
* { id: 2, name: "Second Col" },
* { id: 3, name: "Third Col" },
* { id: 4, name: "Fourth Col" },
* ],
* rows: [
* {
* id: 1,
* data: [
* { id: 1, data: <div>Data for Row 1 Col 1</div> },
* { id: 2, data: <div>Data for Row 1 Col 2</div> },
* { id: 3, data: <div>Data for Row 1 Col 3</div> },
* { id: 4, data: <div>Data for Row 1 Col 4</div> },
* ],
* },
* {
* id: 2,
* data: [
* { id: 5, data: <div>Data for Row 2 Col 1</div> },
* { id: 6, data: <div>Data for Row 2 Col 2</div> },
* { id: 7, data: <div>Data for Row 2 Col 3</div> },
* { id: 8, data: <div>Data for Row 2 Col 4</div> },
* ],
* },
* ],
* };
*
* <BasicTable data={data} rows={rows} paginated={true} />
*/
const BasicTable = ({ data, paginated, reversed, table, emptyMessage = "No data" }) => {
const DEFAULT_ROWS_PER_PAGE = 5;
const theme = useTheme();
const dispatch = useDispatch();
const uiState = useSelector((state) => state.ui);
let rowsPerPage = uiState?.[table]?.rowsPerPage ?? DEFAULT_ROWS_PER_PAGE;
const [page, setPage] = useState(0);
useEffect(() => {
setPage(0);
}, [data]);
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
dispatch(
setRowsPerPage({
value: parseInt(event.target.value, 10),
table: table,
})
);
setPage(0);
};
let displayData = [];
if (data && data.rows) {
let rows = reversed ? [...data.rows].reverse() : data.rows;
displayData = paginated
? rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
: rows;
}
if (!data || !data.cols || !data.rows) {
return <div>No data</div>;
}
/**
* Helper function to calculate the range of displayed rows.
* @returns {string}
*/
const getRange = () => {
let start = page * rowsPerPage + 1;
let end = Math.min(page * rowsPerPage + rowsPerPage, data.rows.length);
return `${start} - ${end}`;
};
return (
<>
<TableContainer component={Paper}>
<Table
sx={{
"&.MuiTable-root :is(.MuiTableHead-root, .MuiTableBody-root) :is(th, td)": {
paddingLeft: theme.spacing(12),
},
"& th": {
backgroundColor: theme.palette.secondary.main,
color: theme.palette.secondary.contrastText,
/*
TODO all general styling for th should live here
*/
},
"& td": {
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastTextSecondary,
/*
TODO all general styling for td should live here
*/
},
}}
>
<TableHead>
<TableRow>
{data.cols.map((col) => (
<TableCell key={col.id}>{col.name}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{displayData.map((row) => {
return (
<TableRow
sx={{
cursor: row.handleClick ? "pointer" : "default",
"&:hover": {
filter: "brightness(.75)",
opacity: 0.75,
transition: "filter 0.3s ease, opacity 0.3s ease",
},
}}
key={row.id}
onClick={row.handleClick ? row.handleClick : null}
>
{row.data.map((cell) => {
return <TableCell key={cell.id}>{cell.data}</TableCell>;
})}
</TableRow>
);
})}
{displayData.length === 0 && (
<TableRow>
<TableCell
sx={{ textAlign: "center" }}
colSpan={data.cols.length}
>
{emptyMessage}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
{paginated && (
<Stack
direction="row"
alignItems="center"
justifyContent="space-between"
px={theme.spacing(4)}
sx={{
"& p": {
color: theme.palette.primary.contrastTextTertiary,
},
}}
>
<Typography
px={theme.spacing(2)}
fontSize={12}
sx={{ opacity: 0.7 }}
>
Showing {getRange()} of {data.rows.length} monitor(s)
</Typography>
<TablePagination
component="div"
count={data.rows.length}
page={page}
onPageChange={handleChangePage}
rowsPerPage={rowsPerPage}
rowsPerPageOptions={[5, 10, 15, 25]}
onRowsPerPageChange={handleChangeRowsPerPage}
ActionsComponent={TablePaginationActions}
labelRowsPerPage="Rows per page"
labelDisplayedRows={({ page, count }) =>
`Page ${page + 1} of ${Math.max(0, Math.ceil(count / rowsPerPage))}`
}
slotProps={{
select: {
MenuProps: {
keepMounted: true,
PaperProps: {
className: "pagination-dropdown",
sx: {
mt: 0,
mb: theme.spacing(2),
},
},
transformOrigin: { vertical: "bottom", horizontal: "left" },
anchorOrigin: { vertical: "top", horizontal: "left" },
sx: { mt: theme.spacing(-2) },
},
inputProps: { id: "pagination-dropdown" },
IconComponent: SelectorVertical,
sx: {
ml: theme.spacing(4),
mr: theme.spacing(12),
minWidth: theme.spacing(20),
textAlign: "left",
"&.Mui-focused > div": {
backgroundColor: theme.palette.primary.main,
},
},
},
}}
sx={{
mt: theme.spacing(6),
color: theme.palette.primary.contrastTextSecondary,
"& svg path": {
stroke: theme.palette.primary.contrastTextTertiary,
strokeWidth: 1.3,
},
"& .MuiSelect-select": {
border: 1,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
},
}}
/>
</Stack>
)}
</>
);
};
BasicTable.propTypes = {
data: PropTypes.object.isRequired,
paginated: PropTypes.bool,
reversed: PropTypes.bool,
rowPerPage: PropTypes.number,
table: PropTypes.string,
emptyMessage: PropTypes.string,
};
export default BasicTable;
+2 -2
View File
@@ -1,9 +1,9 @@
.MuiBreadcrumbs-root {
height: 34px;
min-height: 34px;
}
.MuiBreadcrumbs-root svg {
width: 16px;
height: 16px;
min-height: 16px;
}
.MuiBreadcrumbs-root .MuiBreadcrumbs-li a {
font-size: var(--env-var-font-size-medium);
+7 -4
View File
@@ -28,13 +28,16 @@ const Breadcrumbs = ({ list }) => {
px={theme.spacing(2)}
py={theme.spacing(3.5)}
width="fit-content"
backgroundColor={theme.palette.background.fill}
backgroundColor={theme.palette.secondary.main}
borderRadius={theme.shape.borderRadius}
lineHeight="18px"
sx={{
"& .MuiBreadcrumbs-li a": {
transition: "background-color 0.2s ease-in-out, color 0.2s ease-in-out",
},
"& .MuiBreadcrumbs-li:not(:last-of-type):hover a": {
backgroundColor: theme.palette.other.fill,
opacity: 1,
backgroundColor: theme.palette.secondary.contrastText,
color: theme.palette.secondary.main,
},
}}
>
@@ -52,7 +55,7 @@ const Breadcrumbs = ({ list }) => {
opacity: 0.8,
textTransform: "capitalize",
"&, &:hover": {
color: theme.palette.text.tertiary,
color: theme.palette.secondary.contrastText,
},
}}
>
@@ -149,7 +149,7 @@ const CustomAreaChart = ({
/>
<CartesianGrid
stroke={theme.palette.border.light}
stroke={theme.palette.primary.lowContrast}
strokeWidth={1}
strokeOpacity={1}
fill="transparent"
@@ -180,7 +180,7 @@ const CustomAreaChart = ({
})}
{customTooltip ? (
<Tooltip
cursor={{ stroke: theme.palette.border.light }}
cursor={{ stroke: theme.palette.primary.lowContrast }}
content={customTooltip}
wrapperStyle={{ pointerEvents: "none" }}
/>
+19 -14
View File
@@ -39,12 +39,15 @@ const BarChart = ({ checks = [] }) => {
>
{checks.map((check, index) =>
check === "placeholder" ? (
/* TODO what is the purpose of this box? */
// CAIO_REVIEW the purpose of this box is to make sure there are always at least 25 bars
// even if there are less than 25 checks
<Box
key={`${check}-${index}`}
position="relative"
width={theme.spacing(4.5)}
height="100%"
backgroundColor={theme.palette.border.light}
backgroundColor={theme.palette.primary.lowContrast}
sx={{
borderRadius: theme.spacing(1.5),
}}
@@ -67,8 +70,8 @@ const BarChart = ({ checks = [] }) => {
height={theme.spacing(4)}
backgroundColor={
check.status
? theme.palette.success.main
: theme.palette.error.contrastText
? theme.palette.success.lowContrast
: theme.palette.error.lowContrast
}
sx={{ borderRadius: "50%" }}
/>
@@ -116,20 +119,22 @@ const BarChart = ({ checks = [] }) => {
"& .MuiTooltip-tooltip": {
backgroundColor: theme.palette.secondary.main,
border: 1,
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
boxShadow: theme.shape.boxShadow,
px: theme.spacing(4),
py: theme.spacing(2),
py: theme.spacing(3),
},
"& .MuiTooltip-tooltip p": {
/* TODO Font size should point to theme */
fontSize: 12,
color: theme.palette.text.tertiary,
color: theme.palette.secondary.contrastText,
fontWeight: 500,
},
"& .MuiTooltip-tooltip span": {
/* TODO Font size should point to theme */
fontSize: 11,
color: theme.palette.text.tertiary,
color: theme.palette.secondary.contrastText,
fontWeight: 600,
},
},
@@ -140,16 +145,14 @@ const BarChart = ({ checks = [] }) => {
position="relative"
width="9px"
height="100%"
backgroundColor={
check.status
? theme.palette.success.contrastText
: theme.palette.error.dark
}
backgroundColor={theme.palette.primary.lowContrast} // CAIO_REVIEW
sx={{
borderRadius: theme.spacing(1.5),
/*
TODO this doesn't seem to be used
"&:hover > .MuiBox-root": {
filter: "brightness(0.8)",
},
}, */
}}
>
<Box
@@ -158,7 +161,9 @@ const BarChart = ({ checks = [] }) => {
width="100%"
height={`${animate ? check.responseTime : 0}%`}
backgroundColor={
check.status ? theme.palette.success.main : theme.palette.error.main
check.status
? theme.palette.success.lowContrast
: theme.palette.error.lowContrast
}
sx={{
borderRadius: theme.spacing(1.5),
@@ -54,8 +54,8 @@ const CustomGauge = ({ progress = 0, radius = 70, strokeWidth = 15, threshold =
const fillColor =
progressWithinRange > threshold
? theme.palette.percentage.uptimePoor
: theme.palette.primary.main;
? theme.palette.error.lowContrast // CAIO_REVIEW
: theme.palette.accent.main; // CAIO_REVIEW
return (
<Box
@@ -70,7 +70,7 @@ const CustomGauge = ({ progress = 0, radius = 70, strokeWidth = 15, threshold =
>
<circle
className="radial-chart-base"
stroke={theme.palette.background.fill}
stroke={theme.palette.primary.lowContrast} // CAIO_REVIEW
strokeWidth={strokeWidth}
fill="none"
cx={totalSize / 2} // Center the circle
@@ -1,111 +0,0 @@
import { RadialBarChart, RadialBar, ResponsiveContainer } from "recharts";
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
/* TODO delete component */
const MINIMUM_VALUE = 0;
const MAXIMUM_VALUE = 100;
const CHART_MAXIMUM_DATA = {
value: MAXIMUM_VALUE,
fill: "transparent",
};
const PROGRESS_THRESHOLD = 50;
const DEFAULT_WIDTH = 60;
const RADIUS_SIZE = "90%";
const START_ANGLE = 90;
const CHART_RANGE = 360;
const RADIAL_BAR_CHART_PROPS = {
innerRadius: RADIUS_SIZE,
outerRadius: RADIUS_SIZE,
barSize: 6,
startAngle: START_ANGLE,
endAngle: START_ANGLE - CHART_RANGE,
margin: { top: 0, right: 0, bottom: 0, left: 0 },
};
const RADIAL_BAR_PROPS = {
dataKey: "value",
cornerRadius: 8,
};
Gauge.propTypes = {
progressValue: PropTypes.number.isRequired,
width: PropTypes.number,
};
/**
* A circular gauge component that displays a progress value and text.
* The gauge fills based on the progress value and changes color at a 50% threshold.
*
* @component
* @param {Object} props - Component props
* @param {number} props.progressValue - The value to display in the gauge (0-100)
* @param {number} props.width - Width of the gauge container in pixels
* @returns {JSX.Element} A circular gauge chart with progress value and text
*
* @example
* <Gauge
* progressValue={75}
* width={200}
* />
*/
function Gauge({ progressValue, width = DEFAULT_WIDTH }) {
const theme = useTheme();
const myProgressValue = Math.max(MINIMUM_VALUE, Math.min(progressValue, MAXIMUM_VALUE));
const chartColor =
progressValue > PROGRESS_THRESHOLD
? theme.palette.primary.main
: theme.palette.percentage.uptimePoor;
const chartData = [
CHART_MAXIMUM_DATA,
{
value: myProgressValue,
fill: chartColor,
},
];
return (
<ResponsiveContainer
aspect={1}
width={width}
style={{ marginInline: "auto" }}
>
<RadialBarChart
{...RADIAL_BAR_CHART_PROPS}
data={chartData}
>
<RadialBar
{...RADIAL_BAR_PROPS}
fill={
progressValue > PROGRESS_THRESHOLD
? theme.palette.primary.main
: theme.palette.percentage.uptimePoor
}
background={{ fill: theme.palette.background.fill }}
label={{
position: "center",
content: () => (
<text
x="50%"
y="50%"
textAnchor="middle"
dominantBaseline="middle"
style={{
...theme.typography.body2,
fill: theme.typography.body2.color,
}}
>
{`${myProgressValue}%`}
</text>
),
}}
/>
</RadialBarChart>
</ResponsiveContainer>
);
}
export { Gauge };
@@ -31,9 +31,9 @@ const CustomToolTip = ({ active, payload, label, dateRange }) => {
<Box
className="area-tooltip"
sx={{
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
border: 1,
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
py: theme.spacing(2),
px: theme.spacing(4),
@@ -41,7 +41,7 @@ const CustomToolTip = ({ active, payload, label, dateRange }) => {
>
<Typography
sx={{
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 12,
fontWeight: 500,
}}
@@ -63,7 +63,7 @@ const CustomToolTip = ({ active, payload, label, dateRange }) => {
ml={theme.spacing(3)}
sx={{
"& span": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 11,
fontWeight: 500,
},
@@ -109,7 +109,7 @@ CustomToolTip.propTypes = {
label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
dateRange: PropTypes.string,
};
const CustomTick = ({ x, y, payload, index, dateRange }) => {
const CustomTick = ({ x, y, payload, dateRange }) => {
const format = tickDateFormatLookup(dateRange);
const theme = useTheme();
const uiTimezone = useSelector((state) => state.ui.timezone);
@@ -118,7 +118,7 @@ const CustomTick = ({ x, y, payload, index, dateRange }) => {
x={x}
y={y + 10}
textAnchor="middle"
fill={theme.palette.text.tertiary}
fill={theme.palette.primary.contrastTextTertiary}
fontSize={11}
fontWeight={400}
>
@@ -139,7 +139,6 @@ const MonitorDetailsAreaChart = ({ checks, dateRange }) => {
const theme = useTheme();
const memoizedChecks = useMemo(() => checks, [checks[0]]);
const [isHovered, setIsHovered] = useState(false);
return (
<ResponsiveContainer
width="100%"
@@ -160,7 +159,7 @@ const MonitorDetailsAreaChart = ({ checks, dateRange }) => {
onMouseLeave={() => setIsHovered(false)}
>
<CartesianGrid
stroke={theme.palette.border.light}
stroke={theme.palette.primary.lowContrast}
strokeWidth={1}
strokeOpacity={1}
fill="transparent"
@@ -176,18 +175,18 @@ const MonitorDetailsAreaChart = ({ checks, dateRange }) => {
>
<stop
offset="0%"
stopColor={theme.palette.primary.main}
stopColor={theme.palette.accent.main}
stopOpacity={0.8}
/>
<stop
offset="100%"
stopColor={theme.palette.primary.light}
stopColor={theme.palette.accent.light}
stopOpacity={0}
/>
</linearGradient>
</defs>
<XAxis
stroke={theme.palette.border.dark}
stroke={theme.palette.primary.lowContrast}
dataKey="_id"
tick={<CustomTick dateRange={dateRange} />}
axisLine={false}
@@ -195,17 +194,17 @@ const MonitorDetailsAreaChart = ({ checks, dateRange }) => {
height={20}
/>
<Tooltip
cursor={{ stroke: theme.palette.border.light }}
cursor={{ stroke: theme.palette.primary.lowContrast }}
content={<CustomToolTip dateRange={dateRange} />}
wrapperStyle={{ pointerEvents: "none" }}
/>
<Area
type="monotone"
dataKey="avgResponseTime"
stroke={theme.palette.primary.main}
stroke={theme.palette.accent.main} // CAIO_REVIEW
fill="url(#colorUv)"
strokeWidth={isHovered ? 2.5 : 1.5}
activeDot={{ stroke: theme.palette.background.main, r: 5 }}
activeDot={{ stroke: theme.palette.accent.main, r: 5 }} // CAIO_REVIEW
/>
</AreaChart>
</ResponsiveContainer>
@@ -24,7 +24,7 @@ export const TzTick = ({ x, y, payload, index, dateRange }) => {
x={x}
y={y + 10}
textAnchor="middle"
fill={theme.palette.text.tertiary}
fill={theme.palette.primary.contrastTextTertiary}
fontSize={11}
fontWeight={400}
>
@@ -59,7 +59,7 @@ export const PercentTick = ({ x, y, payload, index }) => {
x={x - 20}
y={y}
textAnchor="middle"
fill={theme.palette.text.tertiary}
fill={theme.palette.primary.contrastTextTertiary}
fontSize={11}
fontWeight={400}
>
@@ -123,9 +123,9 @@ export const InfrastructureTooltip = ({
<Box
className="area-tooltip"
sx={{
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
border: 1,
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
py: theme.spacing(2),
px: theme.spacing(4),
@@ -133,7 +133,7 @@ export const InfrastructureTooltip = ({
>
<Typography
sx={{
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 12,
fontWeight: 500,
}}
@@ -155,7 +155,7 @@ export const InfrastructureTooltip = ({
ml={theme.spacing(3)}
sx={{
"& span": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 11,
fontWeight: 500,
},
@@ -212,9 +212,9 @@ export const TemperatureTooltip = ({
<Box
className="area-tooltip"
sx={{
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
border: 1,
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
py: theme.spacing(2),
px: theme.spacing(4),
@@ -222,7 +222,7 @@ export const TemperatureTooltip = ({
>
<Typography
sx={{
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 12,
fontWeight: 500,
}}
@@ -241,7 +241,7 @@ export const TemperatureTooltip = ({
ml={theme.spacing(3)}
sx={{
"& span": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 11,
fontWeight: 500,
},
+4 -1
View File
@@ -49,7 +49,10 @@ const Check = ({ text, noHighlightText, variant = "info", outlined = false }) =>
<Typography
component="span"
sx={{
color: variant === "info" ? theme.palette.text.tertiary : colors[variant],
color:
variant === "info"
? theme.palette.primary.contrastTextTertiary
: colors[variant],
opacity: 0.8,
}}
>
+5 -5
View File
@@ -5,10 +5,10 @@ const ConfigBox = styled(Stack)(({ theme }) => ({
flexDirection: "row",
justifyContent: "space-between",
gap: theme.spacing(20),
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.spacing(2),
"& > *": {
paddingTop: theme.spacing(12),
@@ -18,7 +18,7 @@ const ConfigBox = styled(Stack)(({ theme }) => ({
flex: 0.7,
borderRight: 1,
borderRightStyle: "solid",
borderRightColor: theme.palette.border.light,
borderRightColor: theme.palette.primary.lowContrast,
paddingRight: theme.spacing(15),
paddingLeft: theme.spacing(15),
},
@@ -28,10 +28,10 @@ const ConfigBox = styled(Stack)(({ theme }) => ({
paddingLeft: theme.spacing(18),
},
"& h1, & h2": {
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
},
"& p": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
},
}));
@@ -22,9 +22,9 @@ const GenericDialog = ({ title, description, open, onClose, theme, children }) =
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: theme.palette.background.main,
bgcolor: theme.palette.primary.main,
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
boxShadow: 24,
p: theme.spacing(15),
@@ -37,7 +37,7 @@ const GenericDialog = ({ title, description, open, onClose, theme, children }) =
id={titleId}
component="h2"
fontSize={16}
color={theme.palette.text.primary}
color={theme.palette.primary.contrastText}
fontWeight={600}
>
{title}
@@ -45,7 +45,7 @@ const GenericDialog = ({ title, description, open, onClose, theme, children }) =
{description && (
<Typography
id={descriptionId}
color={theme.palette.text.tertiary}
color={theme.palette.primary.contrastTextTertiary}
>
{description}
</Typography>
+1 -1
View File
@@ -12,7 +12,7 @@
width: max-content;
}
[class*="fallback__"] button.MuiButtonBase-root {
height: 34px;
min-height: 34px;
}
[class*="fallback__"] .check span.MuiTypography-root,
[class*="fallback__"] button.MuiButtonBase-root {
+3 -3
View File
@@ -40,7 +40,7 @@ const Fallback = ({ title, checks, link = "/", isAdmin, vowelStart = false }) =>
className="background-pattern-svg"
sx={{
"& svg g g:last-of-type path": {
stroke: theme.palette.border.light,
stroke: theme.palette.primary.lowContrast,
},
}}
>
@@ -54,7 +54,7 @@ const Fallback = ({ title, checks, link = "/", isAdmin, vowelStart = false }) =>
<Typography
component="h1"
marginY={theme.spacing(4)}
color={theme.palette.text.tertiary}
color={theme.palette.primary.contrastTextTertiary}
>
{vowelStart ? "An" : "A"} {title} is used to:
</Typography>
@@ -70,7 +70,7 @@ const Fallback = ({ title, checks, link = "/", isAdmin, vowelStart = false }) =>
{isAdmin && (
<Button
variant="contained"
color="primary"
color="accent"
sx={{ alignSelf: "center" }}
onClick={() => navigate(link)}
>
+4 -1
View File
@@ -6,16 +6,18 @@ import PropTypes from "prop-types";
*
* @param {Object} props - The properties passed to the Heading component.
* @param {('h1'|'h2'|'h3')} props.component - The heading level for the component.
* @param {Object} props.style - Custom styles to apply to the heading.
* @param {string} props.children - The content to display inside the heading.
* @returns {JSX.Element} The Typography component with specified heading properties.
*/
function Heading({ component, children }) {
function Heading({ component, style, children }) {
return (
<Typography
component={component}
variant="h2"
fontWeight={600}
style={style}
>
{children}
</Typography>
@@ -24,6 +26,7 @@ function Heading({ component, children }) {
Heading.propTypes = {
component: PropTypes.oneOf(["h1", "h2", "h3"]).isRequired,
style: PropTypes.object,
children: PropTypes.string.isRequired,
};
export { Heading };
@@ -30,32 +30,28 @@ const HttpStatusLabel = ({ status, customStyles }) => {
const theme = useTheme();
const colors = {
400: {
dotColor: theme.palette.warning.main,
bgColor: theme.palette.warning.dark,
borderColor: theme.palette.warning.light,
color: theme.palette.warning.main,
borderColor: theme.palette.warning.lowContrast,
},
500: {
dotColor: theme.palette.error.main,
bgColor: theme.palette.error.dark,
borderColor: theme.palette.error.light,
color: theme.palette.error.main,
borderColor: theme.palette.error.lowContrast,
},
default: {
dotColor: theme.palette.unresolved.main,
bgColor: theme.palette.unresolved.bg,
borderColor: theme.palette.unresolved.light,
color: theme.palette.primary.contrastText,
borderColor: theme.palette.primary.contrastText,
},
};
const statusCode = handleStatusCode(status);
const { borderColor, bgColor, dotColor } =
const { borderColor, color } =
colors[getRoundedStatusCode(statusCode)] || colors.default;
return (
<BaseLabel
label={String(statusCode)}
styles={{
color: dotColor,
backgroundColor: bgColor,
color: color,
borderColor: borderColor,
...customStyles,
}}
+3 -3
View File
@@ -48,9 +48,9 @@ const IconBox = styled(Box)(
position: "relative",
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: borderRadius,
backgroundColor: theme.palette.background.accent,
backgroundColor: theme.palette.tertiary.main,
"& svg": {
position: "absolute",
top: "50%",
@@ -59,7 +59,7 @@ const IconBox = styled(Box)(
width: svgWidth,
height: svgHeight,
"& path": {
stroke: theme.palette.text.tertiary,
stroke: theme.palette.primary.contrastTextTertiary,
},
},
})
@@ -90,14 +90,14 @@ const Checkbox = ({
mr: theme.spacing(6),
},
"&:not(:has(.Mui-disabled)):hover": {
backgroundColor: theme.palette.background.accent,
backgroundColor: theme.palette.tertiary.main,
},
"& span.MuiTypography-root": {
fontSize: 13,
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
},
".MuiFormControlLabel-label.Mui-disabled": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
opacity: 0.25,
},
}}
+5 -5
View File
@@ -39,7 +39,7 @@ const ImageField = ({ id, src, loading, onChange }) => {
borderRadius: theme.shape.borderRadius,
borderColor: isDragging
? theme.palette.primary.main
: theme.palette.border.light,
: theme.palette.primary.lowContrast,
borderWidth: "2px",
transition: "0.2s",
"&:hover": {
@@ -86,7 +86,7 @@ const ImageField = ({ id, src, loading, onChange }) => {
sx={{
pointerEvents: "none",
borderRadius: theme.shape.borderRadius,
border: `solid ${theme.shape.borderThick}px ${theme.palette.border.light}`,
border: `solid ${theme.shape.borderThick}px ${theme.palette.primary.lowContrast}`,
boxShadow: theme.shape.boxShadow,
}}
>
@@ -94,7 +94,7 @@ const ImageField = ({ id, src, loading, onChange }) => {
</IconButton>
<Typography
component="h2"
color={theme.palette.text.tertiary}
color={theme.palette.primary.contrastTextTertiary}
>
<Typography
component="span"
@@ -108,7 +108,7 @@ const ImageField = ({ id, src, loading, onChange }) => {
</Typography>
<Typography
component="p"
color={theme.palette.text.tertiary}
color={theme.palette.primary.contrastTextTertiary}
sx={{ opacity: 0.6 }}
>
(maximum size: 3MB)
@@ -117,7 +117,7 @@ const ImageField = ({ id, src, loading, onChange }) => {
</Box>
<Typography
component="p"
color={theme.palette.text.tertiary}
color={theme.palette.primary.contrastTextTertiary}
sx={{ opacity: 0.6 }}
>
Supported formats: JPG, PNG
+3 -3
View File
@@ -43,7 +43,7 @@ const Radio = (props) => {
height: 16,
boxShadow: `inset 0 0 0 1px ${theme.palette.secondary.main}`,
"&:not(.Mui-checked)": {
boxShadow: `inset 0 0 0 1px ${theme.palette.text.primary}70`, // Use theme text color for the outline
boxShadow: `inset 0 0 0 1px ${theme.palette.primary.contrastText}70`, // Use theme text color for the outline
},
mt: theme.spacing(0.5),
}}
@@ -56,7 +56,7 @@ const Radio = (props) => {
<Typography
component="h6"
mt={theme.spacing(1)}
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
>
{props.desc}
</Typography>
@@ -69,7 +69,7 @@ const Radio = (props) => {
m: theme.spacing(-2.5),
borderRadius: theme.shape.borderRadius,
"&:hover": {
backgroundColor: theme.palette.background.accent,
backgroundColor: theme.palette.tertiary.main,
},
"& .MuiButtonBase-root": {
p: 0,
+13 -8
View File
@@ -27,7 +27,7 @@ const SearchAdornment = () => {
width: 16,
height: 16,
"& path": {
stroke: theme.palette.text.tertiary,
stroke: theme.palette.primary.contrastTextTertiary,
strokeWidth: 1.2,
},
},
@@ -79,7 +79,7 @@ const Search = ({
<Typography
component="h3"
fontSize={"var(--env-var-font-size-medium)"}
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
fontWeight={500}
>
{label}
@@ -94,12 +94,12 @@ const Search = ({
}}
sx={{
"& fieldset": {
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
},
"& .MuiOutlinedInput-root:hover:not(:has(input:focus)):not(:has(textarea:focus)) fieldset":
{
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
},
"& .MuiOutlinedInput-root": {
paddingY: 0,
@@ -142,7 +142,7 @@ const Search = ({
option.noOptions
? {
pointerEvents: "none",
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
}
: {}
}
@@ -155,16 +155,21 @@ const Search = ({
popper: {
keepMounted: true,
sx: {
"& ul": { p: 2 },
"& ul": { p: 2, backgroundColor: theme.palette.primary.main },
"& li.MuiAutocomplete-option": {
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
px: 4,
borderRadius: theme.shape.borderRadius,
},
"& .MuiAutocomplete-listbox .MuiAutocomplete-option[aria-selected='true'], & .MuiAutocomplete-listbox .MuiAutocomplete-option[aria-selected='true'].Mui-focused, & .MuiAutocomplete-listbox .MuiAutocomplete-option[aria-selected='true']:hover":
{
backgroundColor: theme.palette.background.fill,
backgroundColor: theme.palette.primary.lowContrast,
},
"& li.MuiAutocomplete-option:hover:not([aria-selected='true'])": {
color: theme.palette.primary.main,
backgroundColor: theme.palette.primary.contrastTextSecondary,
},
"& .MuiAutocomplete-noOptions": {
px: theme.spacing(6),
py: theme.spacing(5),
@@ -1,6 +1,6 @@
.select-wrapper .select-component > .MuiSelect-select {
padding: 0 10px;
height: 34px;
min-height: 34px;
display: flex;
align-items: center;
line-height: 1;
@@ -54,11 +54,11 @@ const Select = ({
const theme = useTheme();
const itemStyles = {
fontSize: "var(--env-var-font-size-medium)",
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
borderRadius: theme.shape.borderRadius,
margin: theme.spacing(2),
};
return (
<Stack
gap={theme.spacing(labelControlSpacing)}
@@ -67,7 +67,7 @@ const Select = ({
{label && (
<Typography
component="h3"
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
fontWeight={500}
fontSize={13}
>
@@ -89,13 +89,13 @@ const Select = ({
minWidth: "125px",
"& fieldset": {
borderRadius: theme.shape.borderRadius,
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
},
"&:not(.Mui-focused):hover fieldset": {
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
},
"& svg path": {
fill: theme.palette.other.icon,
fill: theme.palette.primary.contrastTextTertiary,
},
...sx,
}}
@@ -12,15 +12,15 @@ export const HttpAdornment = ({ https }) => {
alignItems="center"
height="100%"
sx={{
borderRight: `solid 1px ${theme.palette.border.dark}`,
backgroundColor: theme.palette.background.accent,
borderRight: `solid 1px ${theme.palette.primary.lowContrast}`,
backgroundColor: theme.palette.tertiary.main,
pl: theme.spacing(6),
}}
>
<Typography
component="h5"
paddingRight={"var(--env-var-spacing-1-minus)"}
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
sx={{ lineHeight: 1, opacity: 0.8 }}
>
{https ? "https" : "http"}://
@@ -41,7 +41,7 @@ export const PasswordEndAdornment = ({ fieldType, setFieldType }) => {
aria-label="toggle password visibility"
onClick={() => setFieldType(fieldType === "password" ? "text" : "password")}
sx={{
color: theme.palette.border.dark,
color: theme.palette.primary.lowContrast,
padding: theme.spacing(1),
"&:focus-visible": {
outline: `2px solid ${theme.palette.primary.main}`,
@@ -6,6 +6,19 @@ import PropTypes from "prop-types";
const getSx = (theme, type, maxWidth) => {
const sx = {
maxWidth: maxWidth,
"& .MuiOutlinedInput-root ": {
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.primary.contrastText, // Adjust hover border color
},
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.accent.main, // Adjust focus border color
},
"&.Mui-disabled .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.primary.contrastText, // CAIO_REVIEW
opacity: 0.5,
},
},
"& .MuiFormHelperText-root": {
position: "absolute",
bottom: `-${theme.spacing(24)}`,
@@ -101,7 +114,7 @@ const TextInput = forwardRef(
<Typography
component="h3"
fontSize={"var(--env-var-font-size-medium)"}
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
fontWeight={500}
>
{label}
+16 -37
View File
@@ -24,15 +24,15 @@ const BaseLabel = ({ label, styles, children }) => {
// Grab the default borderRadius from the theme to match button style
const { borderRadius } = theme.shape;
// Calculate padding for the label to mimic button. Appears to scale correctly, not 100% sure though.
const padding = theme.spacing(1 * 0.75, 2);
const padding = theme.spacing(3, 5);
return (
<Box
className="label"
sx={{
borderRadius: borderRadius,
border: `1px solid ${theme.palette.text.tertiary}`,
color: theme.palette.text.tertiary,
border: `1px solid ${theme.palette.primary.lowContrast}`,
color: theme.palette.primary.contrastText,
padding: padding,
...styles,
}}
@@ -87,7 +87,7 @@ const ColoredLabel = ({ label, color }) => {
const theme = useTheme();
// If an invalid color is passed, default to the labelGray color
if (typeof color !== "string" || !/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(color)) {
color = theme.palette.border.light;
color = theme.palette.primary.lowContrast;
}
// Calculate lighter shades for border and bg
@@ -122,53 +122,32 @@ ColoredLabel.propTypes = {
* <StatusLabel status="up" text="Active" />
*/
const statusToTheme = {
up: "success",
down: "error",
paused: "warning",
pending: "warning",
"cannot resolve": "error",
};
const StatusLabel = ({ status, text, customStyles }) => {
const theme = useTheme();
const colors = {
up: {
dotColor: theme.palette.success.main,
bgColor: theme.palette.success.contrastText /* dark */,
borderColor: theme.palette.success.main /* light */,
},
down: {
dotColor: theme.palette.error.main,
bgColor: theme.palette.error.dark,
borderColor: theme.palette.error.light,
},
paused: {
dotColor: theme.palette.warning.main,
bgColor: theme.palette.warning.dark,
borderColor: theme.palette.warning.light,
},
pending: {
dotColor: theme.palette.text.secondary,
bgColor: theme.palette.background.main,
borderColor: theme.palette.border.dark,
},
"cannot resolve": {
dotColor: theme.palette.unresolved.main,
bgColor: theme.palette.unresolved.bg,
borderColor: theme.palette.unresolved.light,
},
};
// Look up the color for the status
const { borderColor, bgColor, dotColor } = colors[status];
const themeColor = statusToTheme[status];
return (
<BaseLabel
label={text}
styles={{
color: dotColor,
backgroundColor: bgColor,
borderColor: borderColor,
color: theme.palette[themeColor].main,
borderColor: theme.palette[themeColor].lowContrast,
...customStyles,
}}
>
<Box
width={7}
height={7}
bgcolor={dotColor}
bgcolor={theme.palette[themeColor].lowContrast}
borderRadius="50%"
marginRight="5px"
/>
+5 -5
View File
@@ -16,24 +16,24 @@ const Link = ({ level, label, url }) => {
const levelConfig = {
primary: {},
secondary: {
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
sx: {
":hover": {
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
},
},
},
tertiary: {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
sx: {
textDecoration: "underline",
textDecorationStyle: "dashed",
textDecorationColor: theme.palette.primary.main,
textUnderlineOffset: "1px",
":hover": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
textDecorationColor: theme.palette.primary.main,
backgroundColor: theme.palette.background.fill,
backgroundColor: theme.palette.primary.lowContrast,
},
},
},
+8 -9
View File
@@ -1,4 +1,3 @@
import React from "react";
import { useTheme } from "@emotion/react";
import PropTypes from "prop-types";
import { Box, IconButton, LinearProgress, Stack, Typography } from "@mui/material";
@@ -30,11 +29,11 @@ const ProgressUpload = ({ icon, label, size, progress = 0, onClick, error }) =>
height: "fit-content",
borderRadius: theme.shape.borderRadius,
border: 1,
borderColor: theme.palette.border.light,
backgroundColor: theme.palette.background.fill,
borderColor: theme.palette.primary.lowContrast,
backgroundColor: theme.palette.primary.lowContrast,
"&:has(.input-error)": {
borderColor: theme.palette.error.main,
backgroundColor: theme.palette.error.dark,
backgroundColor: theme.palette.error.lowContrast,
py: theme.spacing(4),
px: theme.spacing(8),
"& > .MuiStack-root > svg": {
@@ -60,9 +59,9 @@ const ProgressUpload = ({ icon, label, size, progress = 0, onClick, error }) =>
height: 30,
minWidth: 30,
border: 1,
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: 2,
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
"& svg": {
position: "absolute",
top: "50%",
@@ -71,7 +70,7 @@ const ProgressUpload = ({ icon, label, size, progress = 0, onClick, error }) =>
width: 23,
height: 23,
"& path": {
fill: theme.palette.other.icon,
fill: theme.palette.primary.contrastTextTertiary,
},
},
}}
@@ -90,7 +89,7 @@ const ProgressUpload = ({ icon, label, size, progress = 0, onClick, error }) =>
{error}
</Typography>
) : (
<Box color={theme.palette.text.tertiary}>
<Box color={theme.palette.primary.contrastTextTertiary}>
<Typography
component="h2"
mb={theme.spacing(1.5)}
@@ -148,7 +147,7 @@ const ProgressUpload = ({ icon, label, size, progress = 0, onClick, error }) =>
height: "10px",
borderRadius: theme.shape.borderRadius,
maxWidth: "500px",
backgroundColor: theme.palette.border.light,
backgroundColor: theme.palette.primary.lowContrast,
}}
/>
</Box>
@@ -7,9 +7,9 @@ import PropTypes from "prop-types";
const CustomStepIcon = (props) => {
const { completed, active } = props;
return completed ? (
<CheckCircle color="primary" />
<CheckCircle color="accent" />
) : (
<RadioButtonCheckedIcon color={active ? "primary" : "disabled"} />
<RadioButtonCheckedIcon color={active ? "accent" : "disabled"} />
);
};
+1
View File
@@ -1,3 +1,4 @@
/* TODO */
aside .MuiList-root svg {
width: 20px;
height: 20px;
+105 -57
View File
@@ -156,35 +156,105 @@ function Sidebar() {
}
}, [location]);
/* TODO refactor this, there are a some ternaries and comments in the return */
const iconColor = theme.palette.primary.contrastTextTertiary;
/* TODO refactor this, there are a some ternaries and comments in the return */
return (
<Stack
component="aside"
className={collapsed ? "collapsed" : "expanded"}
/* TODO general padding should be here */
py={theme.spacing(6)}
gap={theme.spacing(6)}
/* TODO set all style in this sx if possible (when general)
This is the top lever for styles
*/
sx={{
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
backgroundColor: theme.palette.background.main,
"& .selected-path, & .MuiListItemButton-root:hover": {
backgroundColor: theme.palette.background.accent,
"& :is(p, span, .MuiListSubheader-root)": {
/*
Text color for unselected menu items and menu headings
Secondary contrast text against main background
*/
color: theme.palette.primary.contrastTextSecondary,
},
"& .MuiList-root svg path": {
stroke: theme.palette.text.tertiary,
/* Menu Icons */
stroke: iconColor,
},
"& p, & span, & .MuiListSubheader-root": {
color: theme.palette.text.secondary,
"& .selected-path": {
/* Selected menu item */
backgroundColor: theme.palette.secondary.main,
"&:hover": {
backgroundColor: theme.palette.secondary.main,
},
"& .MuiListItemIcon-root svg path": {
/* Selected menu item icon */
stroke: theme.palette.secondary.contrastText,
},
"& .MuiListItemText-root :is(p, span)": {
/* Selected menu item text */
color: theme.palette.secondary.contrastText,
},
},
"& .MuiListItemButton-root:not(.selected-path)": {
transition: "background-color .3s",
" &:hover": {
/* Hovered menu item bg color */
backgroundColor: theme.palette.tertiary.main,
"& :is(p, span)": {
/* Hovered menu item text color */
color: theme.palette.tertiary.contrastText,
},
},
},
}}
>
<IconButton
sx={{
position: "absolute",
/* TODO 60 is a magic number. if logo chnges size this might break */
top: 60,
right: 0,
transform: `translate(50%, 0)`,
backgroundColor: theme.palette.tertiary.main,
border: 1,
borderColor: theme.palette.primary.lowContrast,
p: theme.spacing(2.5),
"& svg": {
width: theme.spacing(8),
height: theme.spacing(8),
"& path": {
/* TODO this should be set at the top level if possible */
stroke: theme.palette.primary.contrastTextSecondary,
},
},
"&:focus": { outline: "none" },
"&:hover": {
backgroundColor: theme.palette.primary.lowContrast,
borderColor: theme.palette.primary.lowContrast,
},
}}
onClick={() => {
setOpen((prev) =>
Object.fromEntries(Object.keys(prev).map((key) => [key, false]))
);
dispatch(toggleSidebar());
}}
>
{collapsed ? <ArrowRight /> : <ArrowLeft />}
</IconButton>
{/* TODO Alignment done using padding. Use single source of truth to that*/}
<Stack
pt={theme.spacing(6)}
pb={theme.spacing(12)}
pl={theme.spacing(8)}
>
{/* TODO Abstract logo into component */}
{/* TODO Turn logo into a link */}
<Stack
direction="row"
alignItems="center"
@@ -199,10 +269,11 @@ function Sidebar() {
minHeight={theme.spacing(16)}
pl="1px"
fontSize={18}
color="white"
color={theme.palette.accent.contrastText}
sx={{
position: "relative",
backgroundColor: theme.palette.primary.main,
backgroundColor: theme.palette.accent.main,
color: theme.palette.accent.contrastText,
borderRadius: theme.shape.borderRadius,
userSelect: "none",
}}
@@ -217,40 +288,7 @@ function Sidebar() {
Checkmate
</Typography>
</Stack>
<IconButton
sx={{
position: "absolute",
top: 60,
right: 0,
transform: `translate(50%, 0)`,
backgroundColor: theme.palette.background.fill,
border: 1,
borderColor: theme.palette.border.light,
p: theme.spacing(2.5),
"& svg": {
width: theme.spacing(8),
height: theme.spacing(8),
"& path": {
stroke: theme.palette.text.secondary,
},
},
"&:focus": { outline: "none" },
"&:hover": {
backgroundColor: theme.palette.border.light,
borderColor: theme.palette.border.light,
},
}}
onClick={() => {
setOpen((prev) =>
Object.fromEntries(Object.keys(prev).map((key) => [key, false]))
);
dispatch(toggleSidebar());
}}
>
{collapsed ? <ArrowRight /> : <ArrowLeft />}
</IconButton>
</Stack>
{/* menu */}
<List
component="nav"
aria-labelledby="nested-menu-subheader"
@@ -260,7 +298,8 @@ function Sidebar() {
component="div"
id="nested-menu-subheader"
sx={{
pt: theme.spacing(4),
py: theme.spacing(4),
/* TODO px should be centralized in container */
px: collapsed ? theme.spacing(2) : theme.spacing(4),
backgroundColor: "transparent",
}}
@@ -271,11 +310,12 @@ function Sidebar() {
sx={{
px: theme.spacing(6),
height: "100%",
overflow: "hidden",
/* overflow: "hidden", */
}}
>
{menu.map((item) =>
item.path ? (
/* If item has a path */
<Tooltip
key={item.path}
placement="right"
@@ -298,10 +338,12 @@ function Sidebar() {
className={location.pathname.includes(item.path) ? "selected-path" : ""}
onClick={() => navigate(`/${item.path}`)}
sx={{
height: "37px",
/*
TODO we do not need this height
minHeight: "37px", */
p: theme.spacing(5),
gap: theme.spacing(4),
borderRadius: theme.shape.borderRadius,
px: theme.spacing(4),
}}
>
<ListItemIcon sx={{ minWidth: 0 }}>{item.icon}</ListItemIcon>
@@ -309,7 +351,7 @@ function Sidebar() {
</ListItemButton>
</Tooltip>
) : collapsed ? (
/* TODO Do we ever get here? */
/* TODO Do we ever get here? If item does not have a path and collapsed state is true */
<React.Fragment key={item.name}>
<Tooltip
placement="right"
@@ -365,8 +407,9 @@ function Sidebar() {
MenuListProps={{ sx: { px: 1, py: 2 } }}
sx={{
ml: theme.spacing(8),
/* TODO what is this selection? */
"& .selected-path": {
backgroundColor: theme.palette.background.accent,
backgroundColor: theme.palette.tertiary.main,
},
}}
>
@@ -397,9 +440,10 @@ function Sidebar() {
sx={{
gap: theme.spacing(4),
opacity: 0.9,
/* TODO this has no effect? */
"& svg": {
"& path": {
stroke: theme.palette.other.icon,
stroke: theme.palette.primary.contrastTextTertiary,
strokeWidth: 1.1,
},
},
@@ -413,6 +457,7 @@ function Sidebar() {
</Menu>
</React.Fragment>
) : (
/* TODO Do we ever get here? If item does not have a path and collapsed state is false */
<React.Fragment key={item.name}>
<ListItemButton
onClick={() =>
@@ -474,7 +519,7 @@ function Sidebar() {
left: "-7px",
height: "100%",
borderLeft: 1,
borderLeftColor: theme.palette.other.line,
borderLeftColor: theme.palette.primary.lowContrast,
},
"&:last-child::before": {
height: "50%",
@@ -487,10 +532,11 @@ function Sidebar() {
height: "3px",
width: "3px",
borderRadius: "50%",
backgroundColor: theme.palette.other.line,
backgroundColor: theme.palette.primary.lowContrast,
},
"&.selected-path::after": {
backgroundColor: theme.palette.text.tertiary,
/* TODO what is this selector doing? */
backgroundColor: theme.palette.primary.contrastTextTertiary,
transform: "scale(1.2)",
},
}}
@@ -562,7 +608,7 @@ function Sidebar() {
marginLeft={"auto"}
columnGap={theme.spacing(2)}
>
<ThemeSwitch />
<ThemeSwitch color={iconColor} />
<Tooltip
title="Controls"
disableInteractive
@@ -573,14 +619,15 @@ function Sidebar() {
mr: "-8px",
"&:focus": { outline: "none" },
alignSelf: "center",
padding: '10px',
padding: "10px",
"& svg": {
width: "22px",
height: "22px",
},
"& svg path": {
stroke: theme.palette.other.icon,
/* Vertical three dots */
stroke: iconColor,
},
}}
onClick={(event) => openPopup(event, "logout")}
@@ -638,6 +685,7 @@ function Sidebar() {
</Box>
</MenuItem>
)}
{/* TODO Do we need two dividers? */}
{collapsed && <Divider />}
<Divider />
<MenuItem
@@ -647,7 +695,7 @@ function Sidebar() {
borderRadius: theme.shape.borderRadius,
pl: theme.spacing(4),
"& svg path": {
stroke: theme.palette.other.icon,
stroke: iconColor,
},
}}
>
+49 -11
View File
@@ -1,6 +1,7 @@
import { Box, Typography } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import PropTypes from "prop-types";
import useUtils from "../../Pages/Uptime/utils";
/**
* StatBox Component
@@ -12,6 +13,8 @@ import PropTypes from "prop-types";
* @param {Object} props - The component props
* @param {string} props.heading - The primary heading/title of the statistic
* @param {string|React.ReactNode} props.subHeading - The value or description of the statistic
* @param {boolean} [props.gradient=false] - Determines if the box should have a gradient background
* @param {string} [props.status] - The status of the statistic
* @param {Object} [props.sx] - Additional custom styling to be applied to the box
*
* @example
@@ -26,35 +29,68 @@ import PropTypes from "prop-types";
* @returns {React.ReactElement} A styled box containing the statistic
*/
const StatBox = ({ heading, subHeading, sx }) => {
const StatBox = ({ heading, subHeading, gradient = false, status = "", sx }) => {
const theme = useTheme();
const { statusToTheme } = useUtils();
const themeColor = statusToTheme[status];
const statusBoxStyles = gradient
? {
background: `linear-gradient(to bottom right, ${theme.palette[themeColor].main} 30%, ${theme.palette[themeColor].lowContrast} 70%)`,
borderColor: theme.palette[themeColor].lowContrast,
}
: {
background: `linear-gradient(340deg, ${theme.palette.tertiary.main} 20%, ${theme.palette.primary.main} 45%)`,
borderColor: theme.palette.primary.lowContrast,
};
const headingStyles = gradient
? {
color: theme.palette[themeColor].contrastText,
}
: {
color: theme.palette.primary.contrastTextSecondary,
};
const spanFixedStyles = { marginLeft: theme.spacing(2), fontSize: 15 };
const detailTextStyles = gradient
? {
color: theme.palette[themeColor].contrastText,
"& span": {
color: theme.palette[themeColor].contrastText,
...spanFixedStyles,
},
}
: {
color: theme.palette.primary.contrastText,
"& span": {
color: theme.palette.primary.contrastTextTertiary,
...spanFixedStyles,
},
};
return (
<Box
sx={{
padding: `${theme.spacing(4)} ${theme.spacing(8)}`,
/* TODO why are we using width and min width here? */
minWidth: 200,
width: 225,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
borderRadius: 4,
backgroundColor: theme.palette.background.main,
background: `linear-gradient(340deg, ${theme.palette.background.accent} 20%, ${theme.palette.background.main} 45%)`,
...statusBoxStyles,
"& h2": {
/* TODO font size should come from theme */
fontSize: 13,
fontWeight: 500,
color: theme.palette.text.secondary,
textTransform: "uppercase",
...headingStyles,
},
"& p": {
fontSize: 18,
color: theme.palette.text.primary,
marginTop: theme.spacing(2),
"& span": {
color: theme.palette.text.tertiary,
marginLeft: theme.spacing(2),
fontSize: 15,
},
...detailTextStyles,
},
...sx,
}}
@@ -68,6 +104,8 @@ const StatBox = ({ heading, subHeading, sx }) => {
StatBox.propTypes = {
heading: PropTypes.string.isRequired,
subHeading: PropTypes.node.isRequired,
gradient: PropTypes.bool,
status: PropTypes.string,
sx: PropTypes.object,
};
@@ -28,8 +28,7 @@ const PasswordPanel = () => {
const theme = useTheme();
const dispatch = useDispatch();
const SPACING_GAP = theme.spacing(12);
const SPACING_GAP = theme.spacing(12);
//redux state
const { authToken, isLoading } = useSelector((state) => state.auth);
@@ -116,7 +115,7 @@ const PasswordPanel = () => {
value="password"
sx={{
"& h1, & input": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
},
}}
>
@@ -126,8 +125,7 @@ const PasswordPanel = () => {
noValidate
spellCheck="false"
gap={theme.spacing(26)}
maxWidth={"80ch"} // Keep maxWidth
maxWidth={"80ch"} // Keep maxWidth
>
<TextInput
type="text"
@@ -142,7 +140,7 @@ const PasswordPanel = () => {
direction="row"
justifyContent={"flex-start"}
alignItems={"center"}
gap={SPACING_GAP}
gap={SPACING_GAP}
flexWrap={"wrap"}
>
<Typography
@@ -167,7 +165,7 @@ const PasswordPanel = () => {
<Stack
direction="row"
alignItems={"flex-start"}
gap={SPACING_GAP}
gap={SPACING_GAP}
flexWrap={"wrap"}
>
<Typography
@@ -193,7 +191,7 @@ const PasswordPanel = () => {
<Stack
direction="row"
alignItems={"flex-start"}
gap={SPACING_GAP}
gap={SPACING_GAP}
flexWrap={"wrap"}
>
<Typography
@@ -230,7 +228,7 @@ const PasswordPanel = () => {
>
<LoadingButton
variant="contained"
color="primary"
color="accent"
type="submit"
loading={isLoading}
loadingIndicator="Saving..."
@@ -255,4 +253,4 @@ PasswordPanel.propTypes = {
// No props are being passed to this component, hence no specific PropTypes are defined.
};
export default PasswordPanel;
export default PasswordPanel;
@@ -29,7 +29,7 @@ import Dialog from "../../Dialog";
const ProfilePanel = () => {
const theme = useTheme();
const dispatch = useDispatch();
const SPACING_GAP = theme.spacing(12);
//redux state
@@ -216,7 +216,7 @@ const ProfilePanel = () => {
value="profile"
sx={{
"& h1, & p, & input": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
},
}}
>
@@ -225,9 +225,13 @@ const ProfilePanel = () => {
className="edit-profile-form"
noValidate
spellCheck="false"
gap={SPACING_GAP}
gap={SPACING_GAP}
>
<Stack direction="row" gap={SPACING_GAP}>
<Stack
direction="row"
gap={SPACING_GAP}
>
{/* This 0.9 is a bit magic numbering, refactor */}
<Box flex={0.9}>
<Typography component="h1">First name</Typography>
</Box>
@@ -242,7 +246,10 @@ const ProfilePanel = () => {
flex={1}
/>
</Stack>
<Stack direction="row" gap={SPACING_GAP}>
<Stack
direction="row"
gap={SPACING_GAP}
>
<Box flex={0.9}>
<Typography component="h1">Last name</Typography>
</Box>
@@ -257,7 +264,10 @@ const ProfilePanel = () => {
flex={1}
/>
</Stack>
<Stack direction="row" gap={SPACING_GAP}>
<Stack
direction="row"
gap={SPACING_GAP}
>
<Stack flex={0.9}>
<Typography component="h1">Email</Typography>
<Typography
@@ -277,7 +287,10 @@ const ProfilePanel = () => {
flex={1}
/>
</Stack>
<Stack direction="row" gap={SPACING_GAP}>
<Stack
direction="row"
gap={SPACING_GAP}
>
<Stack flex={0.9}>
<Typography component="h1">Your photo</Typography>
<Typography
@@ -291,6 +304,7 @@ const ProfilePanel = () => {
direction="row"
alignItems="center"
flex={1}
gap={"8px"}
>
<Avatar
src={
@@ -300,18 +314,18 @@ const ProfilePanel = () => {
? localData.file
: ""
}
sx={{ mr: "8px" }}
sx={{ marginRight: "8px" }}
/>
<Button
variant="text"
color="info"
variant="contained" // CAIO_REIVEW
color="error"
onClick={handleDeletePicture}
>
Delete
</Button>
<Button
variant="text"
color="primary"
variant="contained" // CAIO_REVIEW
color="accent"
onClick={openPictureModal}
>
Update
@@ -332,7 +346,7 @@ const ProfilePanel = () => {
<Box width="fit-content">
<LoadingButton
variant="contained"
color="primary"
color="accent"
onClick={handleSaveProfile}
loading={isLoading}
loadingIndicator="Saving..."
@@ -348,7 +362,7 @@ const ProfilePanel = () => {
aria-hidden="true"
sx={{
marginY: theme.spacing(20),
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
}}
/>
{!user.role.includes("demo") && (
@@ -438,7 +452,7 @@ const ProfilePanel = () => {
</Button>
<Button
variant="contained"
color="primary"
color="accent"
onClick={handleUpdatePicture}
disabled={
(Object.keys(errors).length !== 0 && errors?.picture) ||
@@ -43,7 +43,7 @@ const TeamPanel = () => {
render: (row) => {
return (
<Stack>
<Typography color={theme.palette.text.secondary}>
<Typography color={theme.palette.primary.contrastTextSecondary}>
{row.firstName + " " + row.lastName}
</Typography>
<Typography>
@@ -180,11 +180,11 @@ const TeamPanel = () => {
value="team"
sx={{
"& h1": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
},
"& .MuiTable-root .MuiTableBody-root .MuiTableCell-root, & .MuiTable-root p + p":
{
color: theme.palette.text.accent,
color: theme.palette.primary.contrastTextSecondary,
},
}}
>
@@ -232,7 +232,7 @@ const TeamPanel = () => {
<LoadingButton
loading={isSendingInvite}
variant="contained"
color="primary"
color="accent"
onClick={() => setIsOpen(true)}
>
Invite a team member
@@ -289,15 +289,15 @@ const TeamPanel = () => {
>
<LoadingButton
loading={isSendingInvite}
variant="text"
color="info"
variant="contained" // CAIO_REVIEW
color="error"
onClick={closeInviteModal}
>
Cancel
</LoadingButton>
<LoadingButton
variant="contained"
color="primary"
color="accent"
onClick={handleInviteMember}
loading={isSendingInvite}
disabled={isDisabled}
@@ -92,7 +92,7 @@ function Pagination({
minWidth: theme.spacing(20),
textAlign: "left",
"&.Mui-focused > div": {
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
},
"& .MuiSelect-icon": {
// Add this style override
@@ -105,14 +105,14 @@ function Pagination({
},
}}
sx={{
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
"& svg path": {
stroke: theme.palette.text.tertiary,
stroke: theme.palette.primary.contrastTextTertiary,
strokeWidth: 1.3,
},
"& .MuiSelect-select": {
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
},
}}
+19 -5
View File
@@ -40,16 +40,30 @@ const DataTable = ({ headers, data, config = { emptyView: "No data" } }) => {
return (
<TableContainer component={Paper}>
<Table stickyHeader>
<TableHead sx={{ backgroundColor: theme.palette.background.accent }}>
<Table
stickyHeader
sx={{
"&.MuiTable-root :is(.MuiTableHead-root, .MuiTableBody-root) :is(th, td)": {
paddingLeft: theme.spacing(8),
},
"& :is(th)": {
backgroundColor: theme.palette.secondary.main,
color: theme.palette.secondary.contrastText,
fontWeight: 600,
fontSize: "12px",
},
"& :is(td)": {
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastTextSecondary,
},
}}
>
<TableHead>
<TableRow>
{headers.map((header, index) => (
<TableCell
key={header.id}
align={index === 0 ? "left" : "center"}
sx={{
backgroundColor: theme.palette.background.accent,
}}
>
{header.content}
</TableCell>
@@ -35,12 +35,12 @@ const SunAndMoonIcon = () => {
cx="12"
cy="12"
r="6"
fill={theme.palette.text.secondary}
fill={theme.palette.primary.contrastTextSecondary}
mask="url(#moon-mask)"
/>
<g
className="sun-beams"
stroke={theme.palette.text.secondary}
stroke={theme.palette.primary.contrastTextSecondary}
>
<line
x1="12"
+5 -1
View File
@@ -15,7 +15,7 @@ import { useDispatch, useSelector } from "react-redux";
import { setMode } from "../../Features/UI/uiSlice";
import "./index.css";
const ThemeSwitch = ({ width = 48, height = 48 }) => {
const ThemeSwitch = ({ width = 48, height = 48, color }) => {
const mode = useSelector((state) => state.ui.mode);
const dispatch = useDispatch();
@@ -37,6 +37,10 @@ const ThemeSwitch = ({ width = 48, height = 48 }) => {
display: "flex",
alignItems: "center",
justifyContent: "center",
"& svg >:is(circle, g)": {
fill: color,
stroke: color,
},
}}
>
<SunAndMoonIcon />
+1 -1
View File
@@ -14,7 +14,7 @@
margin-top: 50px;
}
.account button:not(.MuiIconButton-root) {
height: 34px;
min-height: 34px;
}
.account .field {
flex: 1;
+25 -12
View File
@@ -57,22 +57,27 @@ const Account = ({ open = "profile" }) => {
className="account"
px={theme.spacing(20)}
py={theme.spacing(12)}
backgroundColor={theme.palette.primary.main}
border={1}
borderColor={theme.palette.border.light}
borderColor={theme.palette.primary.lowContrast}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
>
<TabContext value={tab}>
<Box
sx={{
borderBottom: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
"& .MuiTabs-root": { height: "fit-content", minHeight: "0" },
}}
>
<TabList
onChange={handleTabChange}
aria-label="account tabs"
sx={{
"& .MuiTabs-indicator": {
backgroundColor: theme.palette.tertiary.contrastText,
},
}}
>
{tabList.map((label, index) => (
<Tab
@@ -84,21 +89,29 @@ const Account = ({ open = "profile" }) => {
tabIndex={index}
sx={{
fontSize: 13,
color: theme.palette.text.tertiary,
color: theme.palette.tertiary.contrastText,
backgroundColor: theme.palette.tertiary.main,
textTransform: "none",
minWidth: "fit-content",
minHeight: 0,
paddingLeft: 0,
paddingY: theme.spacing(4),
paddingY: theme.spacing(6),
fontWeight: 400,
marginRight: theme.spacing(8),
borderBottom: "2px solid transparent",
"&:focus": {
borderBottom: `2px solid ${theme.palette.border.light}`,
borderRight: `1px solid ${theme.palette.primary.lowContrast}`,
"&:first-child": { borderTopLeftRadius: "8px" },
"&:last-child": { borderTopRightRadius: "8px", borderRight: 0 },
"&:focus-visible": {
color: theme.palette.primary.contrastText,
borderColor: theme.palette.tertiary.contrastText,
borderRightColor: theme.palette.primary.lowContrast,
},
"&.Mui-selected": {
backgroundColor: theme.palette.secondary.main,
color: theme.palette.secondary.contrastText,
borderColor: theme.palette.secondary.contrastText,
borderRightColor: theme.palette.primary.lowContrast,
},
"&:hover": {
borderBottom: `2px solid ${theme.palette.border.light}`,
borderColor: theme.palette.primary.lowContrast,
},
}}
/>
+6 -5
View File
@@ -94,7 +94,8 @@ const CheckEmail = () => {
fontWeight: 600,
fontSize: 22,
},
"& p": { color: theme.palette.text.accent, fontSize: 13.5 },
/* TODO font size from theme */
"& p": { color: theme.palette.primary.contrastTextSecondary, fontSize: 13.5 },
"& span": { fontSize: "inherit" },
}}
>
@@ -102,7 +103,7 @@ const CheckEmail = () => {
className="background-pattern-svg"
sx={{
"& svg g g:last-of-type path": {
stroke: theme.palette.border.light,
stroke: theme.palette.primary.lowContrast,
},
}}
>
@@ -129,8 +130,8 @@ const CheckEmail = () => {
"& > .MuiStack-root": {
border: 1,
borderRadius: theme.spacing(5),
borderColor: theme.palette.border.light,
backgroundColor: theme.palette.background.main,
borderColor: theme.palette.primary.lowContrast,
backgroundColor: theme.palette.primary.main,
padding: {
xs: theme.spacing(12),
sm: theme.spacing(20),
@@ -173,7 +174,7 @@ const CheckEmail = () => {
</Box>
<Button
variant="contained"
color="primary"
color="accent"
onClick={openMail}
sx={{
width: "100%",
+6 -5
View File
@@ -95,8 +95,9 @@ const ForgotPassword = () => {
fontSize: 21,
},
"& p": {
/* TODO font size from theme */
fontSize: 14,
color: theme.palette.text.accent,
color: theme.palette.primary.contrastTextSecondary,
},
}}
>
@@ -104,7 +105,7 @@ const ForgotPassword = () => {
className="background-pattern-svg"
sx={{
"& svg g g:last-of-type path": {
stroke: theme.palette.border.light,
stroke: theme.palette.primary.lowContrast,
},
}}
>
@@ -131,8 +132,8 @@ const ForgotPassword = () => {
"& > .MuiStack-root": {
border: 1,
borderRadius: theme.spacing(5),
borderColor: theme.palette.border.light,
backgroundColor: theme.palette.background.main,
borderColor: theme.palette.primary.lowContrast,
backgroundColor: theme.palette.primary.main,
padding: {
xs: theme.spacing(12),
sm: theme.spacing(20),
@@ -186,7 +187,7 @@ const ForgotPassword = () => {
/>
<LoadingButton
variant="contained"
color="primary"
color="accent"
loading={isLoading}
disabled={errors.email !== undefined}
onClick={handleSubmit}
@@ -65,7 +65,7 @@ const EmailStep = ({ form, errors, onSubmit, onChange }) => {
>
<Button
variant="contained"
color="primary"
color="accent"
type="submit"
disabled={errors.email && true}
sx={{
@@ -24,7 +24,7 @@ const ForgotPasswordLabel = ({ email, errorEmail }) => {
</Typography>
<Typography
component="span"
color={theme.palette.primary.main}
color={theme.palette.accent.main}
ml={theme.spacing(2)}
sx={{ userSelect: "none" }}
onClick={handleNavigate}
@@ -91,7 +91,7 @@ const PasswordStep = ({ form, errors, onSubmit, onChange, onBack }) => {
</Button>
<LoadingButton
variant="contained"
color="primary"
color="accent"
type="submit"
loading={authState.isLoading}
disabled={errors.password && true}
+5 -4
View File
@@ -145,7 +145,8 @@ const Login = () => {
fontWeight: 600,
fontSize: 28,
},
"& p": { fontSize: 14, color: theme.palette.text.accent },
/* TODO set font size from theme */
"& p": { fontSize: 14, color: theme.palette.primary.contrastTextSecondary },
"& span": { fontSize: "inherit" },
}}
>
@@ -153,7 +154,7 @@ const Login = () => {
className="background-pattern-svg"
sx={{
"& svg g g:last-of-type path": {
stroke: theme.palette.border.light,
stroke: theme.palette.primary.lowContrast,
},
}}
>
@@ -181,8 +182,8 @@ const Login = () => {
"& > .MuiStack-root": {
border: 1,
borderRadius: theme.spacing(5),
borderColor: theme.palette.border.light,
backgroundColor: theme.palette.background.main,
borderColor: theme.palette.primary.lowContrast,
backgroundColor: theme.palette.primary.main,
padding: {
xs: theme.spacing(12),
sm: theme.spacing(20),
@@ -31,14 +31,15 @@ const NewPasswordConfirmed = () => {
fontWeight: 600,
fontSize: 21,
},
"& p": { fontSize: 13.5, color: theme.palette.text.accent },
/* TODO font size from theme*/
"& p": { fontSize: 13.5, color: theme.palette.primary.contrastTextSecondary },
}}
>
<Box
className="background-pattern-svg"
sx={{
"& svg g g:last-of-type path": {
stroke: theme.palette.border.light,
stroke: theme.palette.primary.lowContrast,
},
}}
>
@@ -65,8 +66,8 @@ const NewPasswordConfirmed = () => {
"& > .MuiStack-root": {
border: 1,
borderRadius: theme.spacing(5),
borderColor: theme.palette.border.light,
backgroundColor: theme.palette.background.main,
borderColor: theme.palette.primary.lowContrast,
backgroundColor: theme.palette.primary.main,
padding: {
xs: theme.spacing(12),
sm: theme.spacing(20),
@@ -103,7 +104,6 @@ const NewPasswordConfirmed = () => {
</Box>
<Button
variant="contained"
color="primary"
onClick={() => navigate("/uptime")}
sx={{
width: "100%",
+8 -7
View File
@@ -50,7 +50,7 @@ const LandingPage = ({ isSuperAdmin, onSignup }) => {
"& svg": {
mr: theme.spacing(4),
"& path": {
stroke: theme.palette.other.icon,
stroke: theme.palette.primary.contrastTextTertiary,
},
},
"&:focus-visible": {
@@ -77,7 +77,7 @@ const LandingPage = ({ isSuperAdmin, onSignup }) => {
}}
sx={{
"&:hover": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
},
}}
>
@@ -95,7 +95,7 @@ const LandingPage = ({ isSuperAdmin, onSignup }) => {
}}
sx={{
"&:hover": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
},
}}
>
@@ -285,7 +285,8 @@ const Register = ({ isSuperAdmin }) => {
fontWeight: 600,
fontSize: 28,
},
"& p": { fontSize: 14, color: theme.palette.text.accent },
/* TODO set fontsize from theme */
"& p": { fontSize: 14, color: theme.palette.primary.contrastTextSecondary },
"& span": { fontSize: "inherit" },
}}
>
@@ -293,7 +294,7 @@ const Register = ({ isSuperAdmin }) => {
className="background-pattern-svg"
sx={{
"& svg g g:last-of-type path": {
stroke: theme.palette.border.light,
stroke: theme.palette.primary.lowContrast,
},
}}
>
@@ -320,8 +321,8 @@ const Register = ({ isSuperAdmin }) => {
"& > .MuiStack-root": {
border: 1,
borderRadius: theme.spacing(5),
borderColor: theme.palette.border.light,
backgroundColor: theme.palette.background.main,
borderColor: theme.palette.primary.lowContrast,
backgroundColor: theme.palette.primary.main,
padding: {
xs: theme.spacing(12),
sm: theme.spacing(20),
@@ -111,7 +111,7 @@ function StepOne({ form, errors, onSubmit, onChange, onBack }) {
</Button>
<Button
variant="contained"
color="primary"
color="accent"
type="submit"
disabled={(errors.firstName || errors.lastName) && true}
sx={{
@@ -134,7 +134,7 @@ function StepThree({ onSubmit, onBack }) {
mr: theme.spacing(3),
},
":focus-visible": {
outline: `2px solid ${theme.palette.primary.dark}`,
outline: `2px solid ${theme.palette.primary.lowContrast}`,
outlineOffset: "4px",
},
}}
@@ -145,7 +145,7 @@ function StepThree({ onSubmit, onBack }) {
<Button
type="submit"
variant="contained"
color="primary"
color="accent"
disabled={
form.password.length === 0 ||
form.confirm.length === 0 ||
@@ -93,7 +93,7 @@ function StepTwo({ form, errors, onSubmit, onChange, onBack }) {
</Button>
<Button
variant="contained"
color="primary"
color="accent"
onClick={onSubmit}
disabled={errors.email && true}
sx={{
+6 -5
View File
@@ -74,8 +74,9 @@ const SetNewPassword = () => {
fontSize: 24,
},
"& p": {
/* TODO font size from theme */
fontSize: 14,
color: theme.palette.text.accent,
color: theme.palette.primary.contrastTextSecondary,
},
}}
>
@@ -83,7 +84,7 @@ const SetNewPassword = () => {
className="background-pattern-svg"
sx={{
"& svg g g:last-of-type path": {
stroke: theme.palette.border.light,
stroke: theme.palette.primary.lowContrast,
},
}}
>
@@ -110,8 +111,8 @@ const SetNewPassword = () => {
"& > .MuiStack-root": {
border: 1,
borderRadius: theme.spacing(5),
borderColor: theme.palette.border.light,
backgroundColor: theme.palette.background.main,
borderColor: theme.palette.primary.lowContrast,
backgroundColor: theme.palette.primary.main,
padding: {
xs: theme.spacing(12),
sm: theme.spacing(20),
@@ -233,7 +234,7 @@ const SetNewPassword = () => {
</Box>
<LoadingButton
variant="contained"
color="primary"
color="accent"
loading={isLoading}
onClick={handleSubmit}
disabled={
@@ -16,7 +16,7 @@ const Empty = ({ styles, mode }) => {
</Box>
<Typography
textAlign="center"
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
>
No incidents recorded yet.
</Typography>
@@ -158,9 +158,9 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => {
let sharedStyles = {
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
p: theme.spacing(30),
};
@@ -187,7 +187,7 @@ const IncidentTable = ({ monitors, selectedMonitor, filter }) => {
</Box>
<Typography
textAlign="center"
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
>
The monitor you have selected has no recorded incidents yet.
</Typography>
+1 -1
View File
@@ -7,5 +7,5 @@
font-size: var(--env-var-font-size-medium);
}
.incidents button.MuiButtonBase-root {
height: 34px;
min-height: 34px;
}
+4 -3
View File
@@ -83,7 +83,7 @@ const Incidents = () => {
<Typography
display="inline-block"
component="h1"
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
>
Incidents for
</Typography>
@@ -94,14 +94,15 @@ const Incidents = () => {
onChange={handleSelect}
items={Object.values(monitors)}
sx={{
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastTextSecondary,
}}
/>
<ButtonGroup
sx={{
ml: "auto",
"& .MuiButtonBase-root, & .MuiButtonBase-root:hover": {
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
},
}}
>
@@ -407,7 +407,7 @@ const CreateInfrastructureMonitor = () => {
>
<LoadingButton
variant="contained"
color="primary"
color="accent"
onClick={handleCreateInfrastructureMonitor}
loading={monitorState?.isLoading}
>
@@ -19,7 +19,7 @@ const Empty = ({ styles }) => {
<Typography variant="h2">Your infrastructure dashboard will show here</Typography>
<Typography
textAlign="center"
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
>
Hang tight! Data is loading
</Typography>
@@ -108,10 +108,10 @@ const BaseBox = ({ children, sx = {} }) => {
padding: `${theme.spacing(BASE_BOX_PADDING_VERTICAL)} ${theme.spacing(BASE_BOX_PADDING_HORIZONTAL)}`,
minWidth: 200,
width: 225,
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
...sx,
}}
>
@@ -155,7 +155,7 @@ const GaugeBox = ({ value, heading, metricOne, valueOne, metricTwo, valueTwo })
<Box
sx={{
width: "100%",
borderTop: `1px solid ${theme.palette.border.light}`,
borderTop: `1px solid ${theme.palette.primary.lowContrast}`,
}}
>
<Stack
@@ -408,8 +408,8 @@ const InfrastructureDetails = () => {
data: checks,
dataKeys: ["avgMemoryUsage"],
heading: "Memory usage",
strokeColor: theme.palette.primary.main,
gradientStartColor: theme.palette.primary.main,
strokeColor: theme.palette.accent.main, // CAIO_REVIEW
gradientStartColor: theme.palette.accent.main, // CAIO_REVIEW
yLabel: "Memory usage",
yDomain: [0, 1],
yTick: <PercentTick />,
@@ -668,9 +668,9 @@ const InfrastructureDetails = () => {
<Empty
styles={{
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
p: theme.spacing(30),
}}
/>
@@ -83,7 +83,7 @@ const InfrastructureMenu = ({ monitor, isAdmin, updateCallback }) => {
outline: "none",
},
"& svg path": {
stroke: theme.palette.other.icon,
stroke: theme.palette.primary.contrastTextTertiary,
},
}}
ref={anchor}
+22 -20
View File
@@ -137,13 +137,7 @@ function Infrastructure() {
id: "actions",
content: "Actions",
render: (row) => (
<IconButton
sx={{
"& svg path": {
stroke: theme.palette.other.icon,
},
}}
>
<IconButton>
<InfrastructureMenu
monitor={row}
isAdmin={isAdmin}
@@ -166,12 +160,12 @@ function Infrastructure() {
.toString();
const percentageColor =
monitor.uptimePercentage < 0.25
? theme.palette.percentage.uptimePoor
? theme.palette.error.main
: monitor.uptimePercentage < 0.5
? theme.palette.percentage.uptimeFair
: monitor.uptimePercentage < 0.75
? theme.palette.percentage.uptimeGood
: theme.palette.percentage.uptimeExcellent;
: theme.palette.success.lowContrast;
return {
id: monitor._id,
name: monitor.name,
@@ -194,10 +188,10 @@ function Infrastructure() {
':has(> [class*="fallback__"])': {
position: "relative",
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
borderStyle: "dashed",
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
overflow: "hidden",
},
}}
@@ -217,7 +211,7 @@ function Infrastructure() {
{isAdmin && (
<Button
variant="contained"
color="primary"
color="accent"
onClick={navigateToCreate}
sx={{ fontWeight: 500, whiteSpace: "nowrap" }}
>
@@ -240,14 +234,19 @@ function Infrastructure() {
}}
>
<Heading component="h2">Infrastructure monitors</Heading>
{/* TODO Correct the class current-monitors-counter, there are some unnecessary things there */}
{/* TODO Same as the one in UptimaDataTable. Create component */}
<Box
component="span"
className="current-monitors-counter"
color={theme.palette.text.primary}
border={1}
borderColor={theme.palette.border.light}
backgroundColor={theme.palette.background.accent}
color={theme.palette.tertiary.contrastText}
border={2}
borderColor={theme.palette.accent.main}
backgroundColor={theme.palette.tertiary.main}
sx={{
padding: ".25em .75em",
borderRadius: "50%",
fontSize: "12px",
fontWeight: 500,
}}
>
{summary?.totalMonitors ?? 0}
</Box>
@@ -255,10 +254,12 @@ function Infrastructure() {
<DataTable
config={{
/* TODO this behavior seems to be repeated. Put it on the root table? */
rowSX: {
cursor: "pointer",
"&:hover": {
backgroundColor: theme.palette.background.accent,
"&:hover td": {
backgroundColor: theme.palette.tertiary.main,
transition: "background-color .3s ease",
},
},
onRowClick: (row) => openDetails(row.id),
@@ -266,6 +267,7 @@ function Infrastructure() {
headers={headers}
data={monitorsAsRows}
/>
<Pagination
monitorCount={summary?.totalMonitors ?? 0}
page={page}
+4 -4
View File
@@ -33,9 +33,9 @@ const IntegrationsComponent = ({ icon, header, info, onClick }) => {
pl={theme.spacing(12)}
height="100%"
border={1}
borderColor={theme.palette.border.light}
borderColor={theme.palette.primary.lowContrast}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
backgroundColor={theme.palette.primary.main}
>
{icon}
<Stack
@@ -54,7 +54,7 @@ const IntegrationsComponent = ({ icon, header, info, onClick }) => {
</Stack>
<Button
variant="contained"
color="primary"
color="accent"
onClick={onClick}
sx={{ alignSelf: "center" }}
disabled={true}
@@ -126,7 +126,7 @@ const Integrations = () => {
gap={theme.spacing(2)}
sx={{
"& h1, & p": {
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
},
}}
>
@@ -360,7 +360,6 @@ const CreateMaintenance = () => {
<DatePicker
id="startDate"
disablePast
label="Date"
disableHighlightToday
value={form.startDate}
slots={{ openPickerIcon: CalendarIcon }}
@@ -374,17 +373,17 @@ const CreateMaintenance = () => {
flexDirection: "row-reverse",
},
"& input": {
height: 34,
minHeight: 34,
p: 0,
pr: theme.spacing(5),
},
"& fieldset": {
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
},
"&:not(:has(.Mui-disabled)):not(:has(.Mui-error)) .MuiOutlinedInput-root:not(:has(input:focus)):hover fieldset":
{
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
},
},
},
@@ -394,12 +393,36 @@ const CreateMaintenance = () => {
py: 0,
mr: 0,
"& path": {
stroke: theme.palette.other.icon,
stroke: theme.palette.primary.contrastTextTertiary,
strokeWidth: 1.1,
},
"&:hover": { backgroundColor: "transparent" },
},
},
// CAIO_REVIEW, entire popper
popper: {
sx: {
"& .MuiPickersDay-root": {
color: theme.palette.primary.contrastText,
"&.Mui-selected": {
backgroundColor: theme.palette.accent.main, // Selected day background
color: theme.palette.primary.contrastText, // Selected day text color
},
"&:hover": {
backgroundColor: theme.palette.accent.light, // Hover background
},
"&.Mui-disabled": {
color: theme.palette.primary.lowContrast, // Disabled day color
},
},
"& .MuiDayCalendar-weekDayLabel": {
color: theme.palette.primary.contrastText,
},
"& .MuiPickersCalendarHeader-label": {
color: theme.palette.primary.contrastText,
},
},
},
}}
sx={{}}
onChange={(newDate) => {
@@ -439,17 +462,17 @@ const CreateMaintenance = () => {
flexDirection: "row-reverse",
},
"& input": {
height: 34,
minHeight: 34,
p: 0,
pl: theme.spacing(5),
},
"& fieldset": {
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
},
"&:not(:has(.Mui-disabled)):not(:has(.Mui-error)) .MuiOutlinedInput-root:not(:has(input:focus)):hover fieldset":
{
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
},
},
},
@@ -532,7 +555,7 @@ const CreateMaintenance = () => {
<LoadingButton
loading={isLoading}
variant="contained"
color="primary"
color="accent"
onClick={handleSubmit}
disabled={false}
>
@@ -95,7 +95,7 @@ const ActionsMenu = ({ /* isAdmin, */ maintenanceWindow, updateCallback }) => {
outline: "none",
},
"& svg path": {
stroke: theme.palette.other.icon,
stroke: theme.palette.primary.contrastTextTertiary,
},
}}
>
@@ -322,21 +322,21 @@ const MaintenanceTable = ({
minWidth: theme.spacing(20),
textAlign: "left",
"&.Mui-focused > div": {
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
},
},
},
}}
sx={{
mt: theme.spacing(6),
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
"& svg path": {
stroke: theme.palette.text.tertiary,
stroke: theme.palette.primary.contrastTextTertiary,
strokeWidth: 1.3,
},
"& .MuiSelect-select": {
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
},
}}
+3 -3
View File
@@ -51,10 +51,10 @@ const Maintenance = () => {
':has(> [class*="fallback__"])': {
position: "relative",
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
borderStyle: "dashed",
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
overflow: "hidden",
},
}}
@@ -70,7 +70,7 @@ const Maintenance = () => {
<Breadcrumbs list={[{ name: "maintenance", path: "/maintenance" }]} />
<Button
variant="contained"
color="primary"
color="accent"
onClick={() => {
navigate("/maintenance/create");
}}
+1 -1
View File
@@ -58,7 +58,7 @@ const NotFound = ({ title = DefaultValue.title, desc = DefaultValue.desc }) => {
<Typography variant="body1">{desc}</Typography>
<Button
variant="contained"
color="primary"
color="accent"
sx={{ mt: theme.spacing(10) }}
onClick={() => navigate("/")}
>
@@ -249,7 +249,7 @@ const PageSpeedConfigure = () => {
width: 4,
height: 4,
borderRadius: "50%",
backgroundColor: theme.palette.text.tertiary,
backgroundColor: theme.palette.primary.contrastTextTertiary,
opacity: 0.8,
left: -10,
top: "50%",
@@ -276,7 +276,7 @@ const PageSpeedConfigure = () => {
"& svg": {
mr: theme.spacing(2),
"& path": {
stroke: theme.palette.other.icon,
stroke: theme.palette.primary.contrastTextTertiary,
strokeWidth: 0.1,
},
},
@@ -319,7 +319,7 @@ const PageSpeedConfigure = () => {
gap={theme.spacing(20)}
sx={{
".MuiInputBase-root:has(> .Mui-disabled)": {
backgroundColor: theme.palette.background.accent,
backgroundColor: theme.palette.tertiary.main,
},
}}
>
@@ -426,7 +426,7 @@ const PageSpeedConfigure = () => {
loading={isLoading}
type="submit"
variant="contained"
color="primary"
color="accent"
onClick={handleSave}
sx={{ px: theme.spacing(12) }}
>
@@ -179,7 +179,7 @@ const CreatePageSpeed = () => {
className="create-monitor"
sx={{
"& h1": {
color: theme.palette.text.primary,
color: theme.palette.primary.contrastText,
},
}}
>
@@ -207,7 +207,7 @@ const CreatePageSpeed = () => {
component="span"
fontSize="inherit"
fontWeight="inherit"
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
>
PageSpeed monitor
</Typography>
@@ -337,7 +337,7 @@ const CreatePageSpeed = () => {
>
<LoadingButton
variant="contained"
color="primary"
color="accent"
onClick={handleCreateMonitor}
disabled={!Object.values(errors).every((value) => value === undefined)}
loading={isLoading}
@@ -18,7 +18,7 @@ const config = {
seo: {
id: "seo",
text: "SEO",
color: "unresolved",
color: "secondary",
},
performance: {
id: "performance",
@@ -33,7 +33,7 @@ const config = {
accessibility: {
id: "accessibility",
text: "accessibility",
color: "primary",
color: "accent",
},
};
@@ -54,9 +54,9 @@ const CustomToolTip = ({ active, payload, label, config }) => {
return (
<Box
sx={{
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
border: 1,
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
py: theme.spacing(2),
px: theme.spacing(4),
@@ -64,7 +64,7 @@ const CustomToolTip = ({ active, payload, label, config }) => {
>
<Typography
sx={{
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 12,
fontWeight: 500,
}}
@@ -86,7 +86,7 @@ const CustomToolTip = ({ active, payload, label, config }) => {
mt={theme.spacing(1)}
sx={{
"& span": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 11,
fontWeight: 500,
},
@@ -186,7 +186,7 @@ const CustomTick = ({ x, y, payload, index }) => {
x={x}
y={y + 8}
textAnchor="middle"
fill={theme.palette.text.tertiary}
fill={theme.palette.primary.contrastTextTertiary}
fontSize={11}
fontWeight={400}
>
@@ -238,14 +238,14 @@ const PagespeedDetailsAreaChart = ({ data, interval, metrics }) => {
onMouseLeave={() => setIsHovered(false)}
>
<CartesianGrid
stroke={theme.palette.border.light}
stroke={theme.palette.primary.lowContrast}
strokeWidth={1}
strokeOpacity={1}
fill="transparent"
vertical={false}
/>
<XAxis
stroke={theme.palette.border.dark}
stroke={theme.palette.primary.lowContrast}
dataKey="createdAt"
tick={<CustomTick />}
axisLine={false}
@@ -255,13 +255,14 @@ const PagespeedDetailsAreaChart = ({ data, interval, metrics }) => {
interval="equidistantPreserveStart"
/>
<Tooltip
cursor={{ stroke: theme.palette.border.light }}
cursor={{ stroke: theme.palette.primary.lowContrast }}
content={<CustomToolTip config={filteredConfig} />}
/>
<defs>
{Object.values(filteredConfig).map(({ id, color }) => {
/* TODO not working? */
const startColor = theme.palette[color].main;
const endColor = theme.palette[color].light;
const endColor = theme.palette[color].lowContrast;
return (
<linearGradient
@@ -289,7 +290,7 @@ const PagespeedDetailsAreaChart = ({ data, interval, metrics }) => {
{Object.keys(filteredConfig).map((key) => {
const { color } = filteredConfig[key];
const strokeColor = theme.palette[color].main;
const bgColor = theme.palette.background.main;
const bgColor = theme.palette.primary.main;
return (
<Area
@@ -126,29 +126,29 @@ const PieChart = ({ audits }) => {
if (value >= 90 && value <= 100)
return {
stroke: theme.palette.success.main,
strokeBg: theme.palette.success.light,
strokeBg: theme.palette.success.lowContrast,
text: theme.palette.success.contrastText,
bg: theme.palette.success.light,
bg: theme.palette.success.lowContrast,
};
else if (value >= 50 && value < 90)
return {
stroke: theme.palette.warning.main,
strokeBg: theme.palette.warning.light,
strokeBg: theme.palette.warning.lowContrast,
text: theme.palette.warning.contrastText,
bg: theme.palette.warning.dark,
bg: theme.palette.warning.lowContrast,
};
else if (value >= 0 && value < 50)
return {
stroke: theme.palette.error.contrastText,
strokeBg: theme.palette.error.light,
strokeBg: theme.palette.error.lowContrast,
text: theme.palette.error.contrastText,
bg: theme.palette.error.dark,
bg: theme.palette.error.lowContrast,
};
return {
stroke: theme.palette.unresolved.main,
strokeBg: theme.palette.unresolved.light,
text: theme.palette.unresolved.main,
bg: theme.palette.unresolved.bg,
stroke: theme.palette.tertiary.contrastText,
strokeBg: theme.palette.tertiary.contrastText,
text: theme.palette.tertiary.contrastText,
bg: theme.palette.tertiary.main,
};
};
+1 -1
View File
@@ -1,5 +1,5 @@
.page-speed-details button.MuiButtonBase-root {
height: 34px;
min-height: 34px;
}
.page-speed-details .MuiPieArcLabel-root {
+5 -5
View File
@@ -151,7 +151,7 @@ const PageSpeedDetails = () => {
width: 4,
height: 4,
borderRadius: "50%",
backgroundColor: theme.palette.text.tertiary,
backgroundColor: theme.palette.primary.contrastTextTertiary,
opacity: 0.8,
left: -9,
top: "50%",
@@ -175,7 +175,7 @@ const PageSpeedDetails = () => {
"& svg": {
mr: theme.spacing(3),
"& path": {
stroke: theme.palette.other.icon,
stroke: theme.palette.primary.contrastTextTertiary,
},
},
}}
@@ -372,7 +372,7 @@ const PageSpeedDetails = () => {
? theme.palette.warning.main
: score >= 0
? theme.palette.error.contrastText
: theme.palette.unresolved.main;
: theme.palette.tertiary.main;
// Find the position where the number ends and the unit begins
const match = audit.displayValue.match(/(\d+\.?\d*)\s*([a-zA-Z]+)/);
@@ -393,7 +393,7 @@ const PageSpeedDetails = () => {
gap={theme.spacing(4)}
p={theme.spacing(3)}
border={1}
borderColor={theme.palette.border.light}
borderColor={theme.palette.primary.lowContrast}
borderRadius={4}
>
<Box>
@@ -410,7 +410,7 @@ const PageSpeedDetails = () => {
component="span"
fontSize={14}
fontWeight={500}
color={theme.palette.text.primary}
color={theme.palette.primary.contrastText}
>
{value}
<Typography
@@ -6,17 +6,17 @@ export const ChartBox = styled(Stack)(({ theme }) => ({
minWidth: 250,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: 4,
borderTopRightRadius: 16,
borderBottomRightRadius: 16,
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
"& h2": {
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
fontSize: 15,
fontWeight: 500,
},
"& p": { color: theme.palette.text.tertiary },
"& p": { color: theme.palette.primary.contrastTextTertiary },
"& > :nth-of-type(1)": {
gridColumn: 1,
gridRow: 1,
@@ -31,10 +31,10 @@ export const ChartBox = styled(Stack)(({ theme }) => ({
padding: theme.spacing(8),
borderLeft: 1,
borderLeftStyle: "solid",
borderLeftColor: theme.palette.border.light,
borderLeftColor: theme.palette.primary.lowContrast,
borderRadius: 16,
backgroundColor: theme.palette.background.main,
background: `linear-gradient(325deg, ${theme.palette.background.accent} 20%, ${theme.palette.background.main} 45%)`,
backgroundColor: theme.palette.primary.main,
background: `linear-gradient(325deg, ${theme.palette.tertiary.main} 20%, ${theme.palette.primary.main} 45%)`,
},
"& path": {
transition: "stroke-width 400ms ease",
+24 -19
View File
@@ -23,9 +23,9 @@ const CustomToolTip = ({ payload }) => {
return (
<Box
sx={{
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
border: 1,
borderColor: theme.palette.border.dark,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
py: theme.spacing(2),
px: theme.spacing(4),
@@ -33,7 +33,7 @@ const CustomToolTip = ({ payload }) => {
>
<Typography
sx={{
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 12,
fontWeight: 500,
}}
@@ -52,7 +52,7 @@ const CustomToolTip = ({ payload }) => {
mt={theme.spacing(1)}
sx={{
"& span": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 11,
fontWeight: 500,
},
@@ -81,6 +81,7 @@ CustomToolTip.propTypes = {
payload: PropTypes.array,
};
/* TODO separate utils in folder*/
/**
* Processes the raw data to include a score for each entry.
* @param {Array<Object>} data - The raw data array.
@@ -104,6 +105,7 @@ const processData = (data) => {
return formattedData;
};
/* TODO separate component*/
/**
* Renders an area chart displaying page speed scores.
* @param {Object} props
@@ -114,7 +116,9 @@ const processData = (data) => {
const PagespeedAreaChart = ({ data, status }) => {
const theme = useTheme();
const [isHovered, setIsHovered] = useState(false);
const { pagespeedStyles } = useUtils();
const { statusToTheme } = useUtils();
const themeColor = statusToTheme[status];
const formattedData = processData(data);
@@ -134,14 +138,14 @@ const PagespeedAreaChart = ({ data, status }) => {
onMouseLeave={() => setIsHovered(false)}
>
<CartesianGrid
stroke={theme.palette.border.light}
stroke={theme.palette.primary.lowContrast}
strokeWidth={1}
strokeOpacity={1}
fill="transparent"
vertical={false}
/>
<Tooltip
cursor={{ stroke: theme.palette.border.light }}
cursor={{ stroke: theme.palette.primary.lowContrast }}
content={<CustomToolTip />}
/>
<defs>
@@ -154,24 +158,24 @@ const PagespeedAreaChart = ({ data, status }) => {
>
<stop
offset="0%"
stopColor={pagespeedStyles[status].stroke}
stopColor={theme.palette[themeColor].lowContrast}
stopOpacity={0.8}
/>
<stop
offset="100%"
stopColor={pagespeedStyles[status].light}
stopColor={theme.palette[themeColor].main}
stopOpacity={0}
/>
</linearGradient>
</defs>
<Area
dataKey="score"
stroke={pagespeedStyles[status].stroke}
stroke={theme.palette[themeColor].lowContrast}
strokeWidth={isHovered ? 2.5 : 1.5}
fill={`url(#pagespeed-chart-${status})`}
activeDot={{
stroke: pagespeedStyles[status].light,
fill: pagespeedStyles[status].stroke,
stroke: theme.palette[themeColor].main,
fill: theme.palette[themeColor].lowContrast,
r: 4.5,
}}
/>
@@ -192,6 +196,7 @@ PagespeedAreaChart.propTypes = {
status: PropTypes.string.isRequired,
};
/* TODO separate component */
/**
* Renders a card displaying monitor details and an area chart.
* @param {Object} props
@@ -215,9 +220,9 @@ const Card = ({ monitor }) => {
p={theme.spacing(8)}
onClick={() => navigate(`/pagespeed/${monitor._id}`)}
border={1}
borderColor={theme.palette.border.light}
borderColor={theme.palette.primary.lowContrast}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
backgroundColor={theme.palette.primary.main}
sx={{
display: "grid",
gridTemplateColumns: "34px 2fr 1fr",
@@ -225,7 +230,7 @@ const Card = ({ monitor }) => {
gridTemplateRows: "34px 1fr 3fr",
cursor: "pointer",
"&:hover": {
backgroundColor: theme.palette.background.accent,
backgroundColor: theme.palette.tertiary.main,
},
"& path": {
transition: "stroke-width 400ms ease",
@@ -278,8 +283,8 @@ const Card = ({ monitor }) => {
px={theme.spacing(4)}
borderTop={1}
borderRight={1}
borderColor={theme.palette.border.light}
backgroundColor={theme.palette.background.accent}
borderColor={theme.palette.primary.lowContrast}
backgroundColor={theme.palette.tertiary.main}
sx={{
pointerEvents: "none",
userSelect: "none",
@@ -289,7 +294,7 @@ const Card = ({ monitor }) => {
>
<Typography
fontSize={11}
color={theme.palette.text.accent}
color={theme.palette.primary.contrastTextSecondary}
>
Checking every{" "}
{(() => {
@@ -299,7 +304,7 @@ const Card = ({ monitor }) => {
<Typography
component="span"
fontSize={12}
color={theme.palette.text.primary}
color={theme.palette.primary.contrastText}
>
{time}{" "}
</Typography>
+1 -1
View File
@@ -4,5 +4,5 @@
font-size: var(--env-var-font-size-small);
}
.page-speed:not(:has([class*="fallback__"])) button {
height: 34px;
min-height: 34px;
}
+6 -6
View File
@@ -60,10 +60,10 @@ const PageSpeed = () => {
':has(> [class*="fallback__"])': {
position: "relative",
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
borderStyle: "dashed",
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
overflow: "hidden",
},
}}
@@ -83,7 +83,7 @@ const PageSpeed = () => {
{isAdmin && (
<Button
variant="contained"
color="primary"
color="accent"
onClick={() => navigate("/pagespeed/create")}
sx={{ fontWeight: 500, whiteSpace: "nowrap" }}
>
@@ -105,10 +105,10 @@ const PageSpeed = () => {
<Box
component="span"
className="current-monitors-counter"
color={theme.palette.text.primary}
color={theme.palette.primary.contrastText}
border={1}
borderColor={theme.palette.border.light}
backgroundColor={theme.palette.background.accent}
borderColor={theme.palette.primary.lowContrast}
backgroundColor={theme.palette.tertiary.main}
>
{summary?.totalMonitors ?? 0}
</Box>
+1 -1
View File
@@ -13,7 +13,7 @@
font-weight: 600;
}
.settings button {
height: 34px;
min-height: 34px;
}
.settings span.MuiTypography-root {
opacity: 0.6;
+2 -2
View File
@@ -287,7 +287,7 @@ const Settings = () => {
<Typography>Add demo monitors</Typography>
<LoadingButton
variant="contained"
color="primary"
color="accent"
loading={isLoading || authIsLoading || checksIsLoading}
onClick={handleInsertDemoMonitors}
sx={{ mt: theme.spacing(4) }}
@@ -346,7 +346,7 @@ const Settings = () => {
loading={isLoading || authIsLoading || checksIsLoading}
disabled={Object.keys(errors).length > 0}
variant="contained"
color="primary"
color="accent"
sx={{ px: theme.spacing(12), mt: theme.spacing(20) }}
onClick={handleSave}
>
+2 -2
View File
@@ -12,10 +12,10 @@ const Status = () => {
':has(> [class*="fallback__"])': {
position: "relative",
border: 1,
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
borderStyle: "dashed",
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
overflow: "hidden",
},
}}
+3 -3
View File
@@ -274,7 +274,7 @@ const Configure = () => {
width: 4,
height: 4,
borderRadius: "50%",
backgroundColor: theme.palette.text.tertiary,
backgroundColor: theme.palette.primary.contrastTextTertiary,
opacity: 0.8,
left: -10,
top: "50%",
@@ -305,7 +305,7 @@ const Configure = () => {
width: 22,
height: 22,
"& path": {
stroke: theme.palette.text.tertiary,
stroke: theme.palette.primary.contrastTextTertiary,
strokeWidth: 1.7,
},
},
@@ -445,7 +445,7 @@ const Configure = () => {
>
<LoadingButton
variant="contained"
color="primary"
color="accent"
loading={isLoading}
sx={{ px: theme.spacing(12) }}
onClick={handleSubmit}
@@ -402,7 +402,7 @@ const CreateMonitor = () => {
>
<LoadingButton
variant="contained"
color="primary"
color="accent"
onClick={handleCreateMonitor}
disabled={!Object.values(errors).every((value) => value === undefined)}
loading={isLoading}
@@ -31,7 +31,7 @@ const DownBarChart = memo(({ monitor, type, onBarHover }) => {
}}
>
<XAxis
stroke={theme.palette.border.dark}
stroke={theme.palette.primary.lowContrast}
height={15}
tick={false}
label={
@@ -53,26 +53,28 @@ const DownBarChart = memo(({ monitor, type, onBarHover }) => {
maxBarSize={7}
background={{ fill: "transparent" }}
>
{monitor.groupedDownChecks.map((entry, index) => (
<Cell
key={`cell-${entry.time}`}
fill={
hoveredBarIndex === index
? theme.palette.error.main
: chartHovered
? theme.palette.error.light
: theme.palette.error.main
}
onMouseEnter={() => {
setHoveredBarIndex(index);
onBarHover(entry);
}}
onMouseLeave={() => {
setHoveredBarIndex(null);
onBarHover({ time: null, totalChecks: 0 });
}}
/>
))}
{monitor.groupedDownChecks.map((entry, index) => {
return (
<Cell
key={`cell-${entry.time}`}
fill={
hoveredBarIndex === index
? theme.palette.error.main
: chartHovered
? theme.palette.error.light // CAIO_REVIEW
: theme.palette.error.main
}
onMouseEnter={() => {
setHoveredBarIndex(index);
onBarHover(entry);
}}
onMouseLeave={() => {
setHoveredBarIndex(null);
onBarHover({ time: null, totalChecks: 0 });
}}
/>
);
})}
</Bar>
</BarChart>
</ResponsiveContainer>
@@ -29,12 +29,12 @@ const ResponseGaugeChart = ({ avgResponseTime }) => {
? {
category: "Acceptable",
main: theme.palette.warning.main,
bg: theme.palette.warning.dark,
bg: theme.palette.warning.lowContrast,
}
: {
category: "Poor",
main: theme.palette.error.main,
bg: theme.palette.error.light,
bg: theme.palette.error.contrastText,
};
return (
@@ -4,19 +4,21 @@ import { ResponsiveContainer, BarChart, XAxis, Bar, Cell } from "recharts";
import PropTypes from "prop-types";
import CustomLabels from "./CustomLabels";
const getThemeColor = (responseTime) => {
if (responseTime < 200) {
return "success";
} else if (responseTime < 300) {
return "warning";
} else {
return "error";
}
};
const UpBarChart = memo(({ monitor, type, onBarHover }) => {
const theme = useTheme();
const [chartHovered, setChartHovered] = useState(false);
const [hoveredBarIndex, setHoveredBarIndex] = useState(null);
const getColorRange = (responseTime) => {
return responseTime < 200
? { main: theme.palette.success.main, light: theme.palette.success.light }
: responseTime < 300
? { main: theme.palette.warning.main, light: theme.palette.warning.light }
: { main: theme.palette.error.main, light: theme.palette.error.light };
};
return (
<ResponsiveContainer
width="100%"
@@ -38,7 +40,7 @@ const UpBarChart = memo(({ monitor, type, onBarHover }) => {
}}
>
<XAxis
stroke={theme.palette.border.dark}
stroke={theme.palette.primary.lowContrast}
height={15}
tick={false}
label={
@@ -59,11 +61,17 @@ const UpBarChart = memo(({ monitor, type, onBarHover }) => {
background={{ fill: "transparent" }}
>
{monitor.groupedUpChecks.map((entry, index) => {
let { main, light } = getColorRange(entry.avgResponseTime);
const themeColor = getThemeColor(entry.avgResponseTime);
return (
<Cell
key={`cell-${entry.time}`}
fill={hoveredBarIndex === index ? main : chartHovered ? light : main}
fill={
hoveredBarIndex === index
? theme.palette[themeColor].main
: chartHovered
? theme.palette[themeColor].light // CAIO_REVIEW
: theme.palette[themeColor].main
}
onMouseEnter={() => {
setHoveredBarIndex(index);
onBarHover(entry);
@@ -19,8 +19,9 @@ import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded";
import ArrowForwardRoundedIcon from "@mui/icons-material/ArrowForwardRounded";
import { logger } from "../../../../Utils/Logger";
import { formatDateWithTz } from "../../../../Utils/timeUtils";
import { useTheme } from "@emotion/react";
const PaginationTable = ({ monitorId, dateRange }) => {
const theme = useTheme();
const { authToken } = useSelector((state) => state.auth);
const [checks, setChecks] = useState([]);
const [checksCount, setChecksCount] = useState(0);
@@ -96,7 +97,23 @@ const PaginationTable = ({ monitorId, dateRange }) => {
return (
<>
<TableContainer component={Paper}>
<Table>
<Table
sx={{
"&.MuiTable-root :is(.MuiTableHead-root, .MuiTableBody-root) :is(th, td)": {
paddingLeft: theme.spacing(8),
},
"& :is(th)": {
backgroundColor: theme.palette.secondary.main,
color: theme.palette.secondary.contrastText,
fontWeight: 600,
fontSize: "12px",
},
"& :is(td)": {
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastTextSecondary,
},
}}
>
<TableHead>
<TableRow>
<TableCell>Status</TableCell>
+28 -8
View File
@@ -33,7 +33,7 @@ import ResponseGaugeChart from "./Charts/ResponseGaugeChart";
*/
const DetailsPage = () => {
const theme = useTheme();
const { statusColor, statusStyles, statusMsg, determineState } = useUtils();
const { statusColor, statusMsg, determineState } = useUtils();
const isAdmin = useIsAdmin();
const [monitor, setMonitor] = useState({});
const { monitorId } = useParams();
@@ -136,6 +136,7 @@ const DetailsPage = () => {
height="fit-content"
gap={theme.spacing(2)}
>
{/* TODO there is a tooltip at BarChart component. Wrap the Tooltip on our own component */}
<Tooltip
title={statusMsg[determineState(monitor)]}
disableInteractive
@@ -149,6 +150,21 @@ const DetailsPage = () => {
},
},
],
sx: {
"& .MuiTooltip-tooltip": {
backgroundColor: theme.palette.secondary.main,
color: theme.palette.secondary.contrastText,
px: theme.spacing(4),
py: theme.spacing(3),
border: 1,
borderColor: theme.palette.primary.lowContrast,
borderRadius: theme.shape.borderRadius,
boxShadow: theme.shape.boxShadow,
/* TODO Font size should point to theme */
fontSize: 12,
fontWeight: 500,
},
},
},
}}
>
@@ -174,7 +190,7 @@ const DetailsPage = () => {
width: 4,
height: 4,
borderRadius: "50%",
backgroundColor: theme.palette.text.tertiary,
backgroundColor: theme.palette.primary.contrastTextTertiary,
opacity: 0.8,
left: -9,
top: "50%",
@@ -204,7 +220,8 @@ const DetailsPage = () => {
"& svg": {
mr: theme.spacing(3),
"& path": {
stroke: theme.palette.text.tertiary,
/* Should always be contrastText for the button color */
stroke: theme.palette.secondary.contrastText,
},
},
}}
@@ -219,7 +236,10 @@ const DetailsPage = () => {
gap={theme.spacing(8)}
>
<StatBox
sx={statusStyles[determineState(monitor)]}
/* sx={getStatusStyles(determineState(monitor))} */
/* statusStyles[determineState(monitor)] */
gradient={true}
status={determineState(monitor)}
heading={"active for"}
subHeading={splitDuration(monitor?.uptimeStreak)}
/>
@@ -242,7 +262,7 @@ const DetailsPage = () => {
<Typography
component="span"
fontSize={13}
color={theme.palette.text.primary}
color={theme.palette.primary.contrastText}
>
{certificateExpiry}
</Typography>
@@ -318,7 +338,7 @@ const DetailsPage = () => {
position="absolute"
top="100%"
fontSize={11}
color={theme.palette.text.tertiary}
color={theme.palette.primary.contrastTextTertiary}
>
{formatDateWithTz(
hoveredUptimeData._id,
@@ -377,7 +397,7 @@ const DetailsPage = () => {
position="absolute"
top="100%"
fontSize={11}
color={theme.palette.text.tertiary}
color={theme.palette.primary.contrastTextTertiary}
>
{formatDateWithTz(
hoveredIncidentsData._id,
@@ -431,7 +451,7 @@ const DetailsPage = () => {
</IconBox>
<Typography
component="h2"
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
>
History
</Typography>
+6 -6
View File
@@ -8,20 +8,20 @@ export const ChartBox = styled(Stack)(({ theme }) => ({
padding: theme.spacing(8),
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
borderColor: theme.palette.primary.lowContrast,
borderRadius: 4,
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
"& h2": {
color: theme.palette.text.secondary,
color: theme.palette.primary.contrastTextSecondary,
fontSize: 15,
fontWeight: 500,
},
"& .MuiBox-root:not(.area-tooltip) p": {
color: theme.palette.text.tertiary,
color: theme.palette.primary.contrastTextTertiary,
fontSize: 13,
},
"& .MuiBox-root > span": {
color: theme.palette.text.primary,
color: theme.palette.primary.contrastText,
fontSize: 20,
"& span": {
opacity: 0.8,
@@ -37,7 +37,7 @@ export const ChartBox = styled(Stack)(({ theme }) => ({
alignItems: "center",
},
"& tspan, & text": {
fill: theme.palette.text.tertiary,
fill: theme.palette.primary.contrastTextTertiary,
},
"& path": {
transition: "fill 300ms ease, stroke-width 400ms ease",
+10 -15
View File
@@ -12,27 +12,27 @@ const StatusBox = ({ title, value }) => {
position: "absolute",
right: 8,
opacity: 0.5,
"& svg path": { stroke: theme.palette.other.icon },
"& svg path": { stroke: theme.palette.primary.contrastTextTertiary },
};
let color;
let icon;
if (title === "up") {
color = theme.palette.success.main;
color = theme.palette.success.lowContrast;
icon = (
<Box sx={{ ...sharedStyles, top: 8 }}>
<Arrow />
</Box>
);
} else if (title === "down") {
color = theme.palette.error.main;
color = theme.palette.error.lowContrast;
icon = (
<Box sx={{ ...sharedStyles, transform: "rotate(180deg)", top: 5 }}>
<Arrow />
</Box>
);
} else if (title === "paused") {
color = theme.palette.warning.main;
color = theme.palette.warning.lowContrast;
icon = (
<Box sx={{ ...sharedStyles, top: 12, right: 12 }}>
<ClockSnooze />
@@ -45,16 +45,11 @@ const StatusBox = ({ title, value }) => {
position="relative"
flex={1}
border={1}
borderColor={theme.palette.border.light}
backgroundColor={theme.palette.primary.main}
borderColor={theme.palette.primary.lowContrast}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
p={theme.spacing(8)}
overflow="hidden"
sx={{
"&:hover": {
backgroundColor: theme.palette.background.accent,
},
}}
>
<Box
sx={{
@@ -63,7 +58,7 @@ const StatusBox = ({ title, value }) => {
left: "5%",
pointerEvents: "none",
"& svg g g:last-of-type path": {
stroke: theme.palette.other.grid,
stroke: theme.palette.primary.contrastTextTertiary,
},
}}
>
@@ -73,9 +68,8 @@ const StatusBox = ({ title, value }) => {
textTransform="uppercase"
fontSize={15}
letterSpacing={0.5}
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextTertiary}
mb={theme.spacing(8)}
sx={{ opacity: 0.6 }}
>
{title}
</Box>
@@ -89,11 +83,12 @@ const StatusBox = ({ title, value }) => {
gap="2px"
>
{value}
<Typography
component="span"
fontSize={20}
fontWeight={300}
color={theme.palette.text.secondary}
color={theme.palette.primary.contrastTextSecondary}
sx={{ opacity: 0.3 }}
>
#
@@ -156,7 +156,7 @@ const UptimeDataTable = ({
direction="row"
gap={theme.spacing(4)}
alignItems="center"
width="max-content"
display={"inline-flex"}
onClick={() => handleSort("status")}
>
{" "}
@@ -168,9 +168,9 @@ const UptimeDataTable = ({
}}
>
{sort.order === "asc" ? (
<ArrowUpwardRoundedIcon />
<ArrowUpwardRoundedIcon fontSize="18px" />
) : (
<ArrowDownwardRoundedIcon />
<ArrowDownwardRoundedIcon fontSize="18px" />
)}
</Stack>
</Stack>
@@ -222,15 +222,22 @@ const UptimeDataTable = ({
direction="row"
alignItems="center"
mb={theme.spacing(8)}
gap={theme.spacing(2)}
>
<Heading component="h2">Uptime monitors</Heading>
{/* TODO Same as the one in Infrastructure. Create component */}
<Box
className="current-monitors-counter"
color={theme.palette.text.primary}
border={1}
borderColor={theme.palette.border.light}
backgroundColor={theme.palette.background.accent}
component="span"
color={theme.palette.tertiary.contrastText}
border={2}
borderColor={theme.palette.accent.main}
backgroundColor={theme.palette.tertiary.main}
sx={{
padding: ".25em .75em",
borderRadius: "50%",
fontSize: "12px",
fontWeight: 500,
}}
>
{monitorCount}
</Box>
@@ -250,7 +257,7 @@ const UptimeDataTable = ({
height="100%"
position="absolute"
sx={{
backgroundColor: theme.palette.background.main,
backgroundColor: theme.palette.primary.main,
opacity: 0.8,
zIndex: 100,
}}
@@ -267,7 +274,7 @@ const UptimeDataTable = ({
>
<CircularProgress
sx={{
color: theme.palette.other.icon,
color: theme.palette.accent.main,
}}
/>
</Box>
@@ -279,8 +286,9 @@ const UptimeDataTable = ({
config={{
rowSX: {
cursor: "pointer",
"&:hover": {
backgroundColor: theme.palette.background.accent,
"&:hover td": {
backgroundColor: theme.palette.tertiary.main,
transition: "background-color .3s ease",
},
},
onRowClick: (row) => {
+10 -4
View File
@@ -95,7 +95,7 @@ const ActionsMenu = ({
outline: "none",
},
"& svg path": {
stroke: theme.palette.other.icon,
stroke: theme.palette.primary.contrastTextTertiary,
},
}}
>
@@ -111,11 +111,16 @@ const ActionsMenu = ({
slotProps={{
paper: {
sx: {
"& ul": { p: theme.spacing(2.5) },
"& li": { m: 0 },
"& ul": {
p: theme.spacing(2.5),
backgroundColor: theme.palette.primary.main,
},
"& li": { m: 0, color: theme.palette.primary.contrastTextSecondary },
/*
This should not be set automatically on the last of type
"& li:last-of-type": {
color: theme.palette.error.main,
},
}, */
},
},
}}
@@ -189,6 +194,7 @@ const ActionsMenu = ({
e.stopPropagation();
openRemove(e);
}}
sx={{ "&.MuiButtonBase-root": { color: theme.palette.error.main } }}
>
Remove
</MenuItem>
+4 -4
View File
@@ -14,14 +14,14 @@ const Fallback = ({ isAdmin }) => {
return (
<Stack
alignItems="center"
backgroundColor={theme.palette.background.main}
backgroundColor={theme.palette.primary.main}
p={theme.spacing(30)}
pt={theme.spacing(25)}
gap={theme.spacing(2)}
border={1}
borderRadius={theme.shape.borderRadius}
borderColor={theme.palette.border.light}
color={theme.palette.text.secondary}
borderColor={theme.palette.primary.lowContrast}
color={theme.palette.primary.contrastTextSecondary}
>
<Box pb={theme.spacing(20)}>
{mode === "light" ? <PlaceholderLight /> : <PlaceholderDark />}
@@ -39,7 +39,7 @@ const Fallback = ({ isAdmin }) => {
{isAdmin && (
<Button
variant="contained"
color="primary"
color="accent"
onClick={() => {
navigate("/uptime/create");
}}
+1
View File
@@ -42,6 +42,7 @@ const Host = ({ url, title, percentageColor, percentage }) => {
sx={{
color: percentageColor,
fontWeight: 500,
/* TODO point font weight to theme */
ml: "15px",
}}
>
-14
View File
@@ -4,17 +4,3 @@
height: var(--env-var-height-2);
min-width: fit-content;
}
.current-monitors-counter {
display: flex;
justify-content: center;
align-items: center;
padding: 5px;
min-width: 25px;
min-height: 25px;
border-radius: 50%;
font-size: var(--env-var-font-size-medium);
font-weight: 500;
margin-left: 10px;
line-height: 0.8;
}
+26 -15
View File
@@ -41,6 +41,7 @@ const UptimeMonitors = () => {
const theme = useTheme();
const navigate = useNavigate();
const isAdmin = useIsAdmin();
const authState = useSelector((state) => state.auth);
const fetchParams = useMemo(
@@ -57,7 +58,7 @@ const UptimeMonitors = () => {
const getMonitorWithPercentage = useCallback((monitor, theme) => {
let uptimePercentage = "";
let percentageColor = theme.palette.percentage.uptimeExcellent;
let percentageColor = "";
if (monitor.uptimePercentage !== undefined) {
uptimePercentage =
@@ -67,12 +68,12 @@ const UptimeMonitors = () => {
percentageColor =
monitor.uptimePercentage < 0.25
? theme.palette.percentage.uptimePoor
? theme.palette.error.main
: monitor.uptimePercentage < 0.5
? theme.palette.percentage.uptimeFair
? theme.palette.warning.main
: monitor.uptimePercentage < 0.75
? theme.palette.percentage.uptimeGood
: theme.palette.percentage.uptimeExcellent;
? theme.palette.success.main
: theme.palette.success.main;
}
return {
@@ -158,16 +159,26 @@ const UptimeMonitors = () => {
gap={theme.spacing(6)}
>
{canAddMonitor && (
<Button
variant="contained"
color="primary"
onClick={() => {
navigate("/uptime/create");
}}
sx={{ fontWeight: 500, whiteSpace: "nowrap" }}
>
Create new
</Button>
<>
<Button
variant="contained"
color="accent"
onClick={() => {
navigate("/uptime/create");
}}
sx={{
fontWeight: 500,
whiteSpace: "nowrap",
/* TODO IMPORTANT this should be applied to all buttons */
"&:focus-visible": {
outline: `2px solid ${theme.palette.primary.contrastText}`,
outlineOffset: 4,
},
}}
>
Create new
</Button>
</>
)}
</Stack>
<Greeting type="uptime" />
Loaded 100 of 108 files, more files were not shown because too many files have changed in this diff. Show more