mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-03 06:59:32 -05:00
Merge remote-tracking branch 'upstream/develop' into feat/monitor-details-revamp
This commit is contained in:
@@ -31,7 +31,7 @@ const icons = {
|
||||
|
||||
const Alert = ({ variant, title, body, isToast, hasIcon = true, onClick }) => {
|
||||
const theme = useTheme();
|
||||
const { text, light, border } = theme.palette[variant];
|
||||
const { text, bg, border } = theme.palette[variant];
|
||||
const icon = icons[variant];
|
||||
|
||||
return (
|
||||
@@ -45,7 +45,7 @@ const Alert = ({ variant, title, body, isToast, hasIcon = true, onClick }) => {
|
||||
padding: hasIcon
|
||||
? theme.spacing(8)
|
||||
: `${theme.spacing(4)} ${theme.spacing(8)}`,
|
||||
backgroundColor: light,
|
||||
backgroundColor: bg,
|
||||
border: `solid 1px ${border}`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
}}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Stack } from "@mui/material";
|
||||
import { BarChart, Bar, ResponsiveContainer, Cell } from "recharts";
|
||||
import "./index.css";
|
||||
|
||||
const ResponseTimeChart = ({ checks = [] }) => {
|
||||
return (
|
||||
<Stack
|
||||
flexDirection="row"
|
||||
justifyContent="space-around"
|
||||
alignItems="flex-end"
|
||||
height="50px"
|
||||
width="300px"
|
||||
>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart
|
||||
width={150}
|
||||
height={40}
|
||||
data={checks}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<Bar maxBarSize={10} dataKey="responseTime">
|
||||
{checks.map((check, index) => (
|
||||
<Cell
|
||||
key={`cell-${index}`}
|
||||
fill={
|
||||
check.status === true
|
||||
? "var(--success-color)"
|
||||
: "var(--error-color)"
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
ResponseTimeChart.propTypes = {
|
||||
checks: PropTypes.array,
|
||||
};
|
||||
export default ResponseTimeChart;
|
||||
@@ -0,0 +1,116 @@
|
||||
import { Autocomplete, TextField } from "@mui/material";
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
/**
|
||||
* @example
|
||||
*
|
||||
* const options = [
|
||||
* { _id: "66d6119ef959cbc681e034f0", name: "Googler" },
|
||||
* { _id: "66d6119ef959cbc681e034f0", name: "CNN" },
|
||||
* { _id: "66d61a1bf959cbc681e0353f", name: "X Corp." },
|
||||
* ];
|
||||
*
|
||||
* <AutoCompleteField options={options} />
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* AutoCompleteField component.
|
||||
*
|
||||
* @component
|
||||
* @param {Object} props - The component props.
|
||||
* @param {string} props.id - The ID of the autocomplete field.
|
||||
* @param {string} props.type - The type of the input field (text or number).
|
||||
* @param {Array} props.options - The options for the autocomplete field.
|
||||
* @param {string} props.placeholder - The placeholder text for the input field.
|
||||
* @param {boolean} props.disabled - Indicates if the field is disabled.
|
||||
* @returns {JSX.Element} The AutoCompleteField component.
|
||||
*/
|
||||
|
||||
const AutoCompleteField = ({
|
||||
id,
|
||||
type,
|
||||
options,
|
||||
placeholder = "Type to search",
|
||||
disabled,
|
||||
}) => {
|
||||
const [value, setValue] = React.useState();
|
||||
const [inputValue, setInputValue] = React.useState("");
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Autocomplete
|
||||
freeSolo
|
||||
className="auto-complete-field"
|
||||
id={id}
|
||||
value={value}
|
||||
onChange={(event, newValue) => {
|
||||
setValue(newValue);
|
||||
}}
|
||||
inputValue={inputValue}
|
||||
onInputChange={(event, newInputValue) => {
|
||||
setInputValue(newInputValue);
|
||||
}}
|
||||
options={options}
|
||||
getOptionLabel={(option) => option.name}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
type={type}
|
||||
placeholder={placeholder}
|
||||
disabled={disabled}
|
||||
InputProps={{
|
||||
...params.InputProps,
|
||||
sx: {
|
||||
width: 360,
|
||||
height: 34,
|
||||
fontSize: 13,
|
||||
p: 0,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
"& input": {
|
||||
p: 0,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
renderOption={(props, option) => {
|
||||
const { key, ...optionProps } = props;
|
||||
return (
|
||||
<li key={option._id} {...optionProps}>
|
||||
<div>{<span>{option.name}</span>}</div>
|
||||
</li>
|
||||
);
|
||||
}}
|
||||
slotProps={{
|
||||
popper: {
|
||||
sx: {
|
||||
"& ul": { p: 0 },
|
||||
"& li": { borderRadius: theme.shape.borderRadius },
|
||||
},
|
||||
},
|
||||
paper: {
|
||||
sx: {
|
||||
p: 2,
|
||||
fontSize: 13,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
AutoCompleteField.displayName = "AutoCompleteField";
|
||||
|
||||
AutoCompleteField.propTypes = {
|
||||
id: PropTypes.string,
|
||||
type: PropTypes.oneOf(["text", "number"]),
|
||||
options: PropTypes.array,
|
||||
placeholder: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
setWidth: PropTypes.string,
|
||||
};
|
||||
|
||||
export default AutoCompleteField;
|
||||
@@ -53,7 +53,8 @@ Host.propTypes = {
|
||||
params: PropTypes.shape({
|
||||
title: PropTypes.string,
|
||||
percentageColor: PropTypes.string,
|
||||
percentage: PropTypes.number,
|
||||
percentage: PropTypes.string,
|
||||
url: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
|
||||
@@ -27,30 +27,52 @@ const data = {
|
||||
rows: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds table data for a list of monitors.
|
||||
*
|
||||
* @param {Array} monitors - An array of monitor objects containing information about each monitor.
|
||||
* @param {boolean} isAdmin - Flag indicating if the current user is an admin.
|
||||
* @param {Function} navigate - A function to navigate to the monitor detail page.
|
||||
* @returns {Object} The data structure containing columns and rows for the table.
|
||||
*/
|
||||
export const buildData = (monitors, isAdmin, navigate) => {
|
||||
const theme = useTheme();
|
||||
|
||||
data.rows = monitors.map((monitor, idx) => {
|
||||
let uptimePercentage = "";
|
||||
let percentageColor = theme.palette.percentage.uptimeExcellent;
|
||||
|
||||
// Determine uptime percentage and color based on the monitor's uptimePercentage value
|
||||
if (monitor.uptimePercentage !== undefined) {
|
||||
uptimePercentage =
|
||||
monitor.uptimePercentage === 0
|
||||
? "0"
|
||||
: (monitor.uptimePercentage * 100).toFixed(2);
|
||||
? "0"
|
||||
: (monitor.uptimePercentage * 100).toFixed(2);
|
||||
|
||||
percentageColor =
|
||||
monitor.uptimePercentage < 0.25
|
||||
? theme.palette.percentage.uptimePoor
|
||||
: monitor.uptimePercentage < 0.5
|
||||
? theme.palette.percentage.uptimeFair
|
||||
: monitor.uptimePercentage < 0.75
|
||||
? theme.palette.percentage.uptimeGood
|
||||
: theme.palette.percentage.uptimeExcellent;
|
||||
}
|
||||
|
||||
const params = {
|
||||
url: monitor.url,
|
||||
title: monitor.name,
|
||||
percentage: uptimePercentage,
|
||||
percentageColor:
|
||||
monitor.status === true
|
||||
? theme.palette.success.main
|
||||
: theme.palette.error.text,
|
||||
status: monitor.status === true ? "up" : "down",
|
||||
percentageColor,
|
||||
status:
|
||||
monitor.status === undefined
|
||||
? "unknown"
|
||||
: monitor.status === true
|
||||
? "up"
|
||||
: "down",
|
||||
};
|
||||
|
||||
// Reverse checks so latest check is on the right
|
||||
// Reverse checks so the latest check is on the right
|
||||
const reversedChecks = monitor.checks.slice().reverse();
|
||||
|
||||
return {
|
||||
@@ -86,6 +108,3 @@ export const buildData = (monitors, isAdmin, navigate) => {
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ class NetworkService {
|
||||
* @param {string} [sortOrder] - The order in which to sort the retrieved statistics.
|
||||
* @param {number} [limit] - The maximum number of statistics to retrieve.
|
||||
* @param {string} [dateRange] - The date range for which to retrieve statistics.
|
||||
* @param {number} [numToDisplay] - The number of statistics to display.
|
||||
* @param {number} [numToDisplay] - The number of checks to display.
|
||||
* @param {boolean} [normalize] - Whether to normalize the retrieved statistics.
|
||||
* @returns {Promise<AxiosResponse>} The response from the axios GET request.
|
||||
*/
|
||||
|
||||
@@ -57,6 +57,12 @@ const darkTheme = createTheme({
|
||||
bg: "#624711",
|
||||
border: "#e88c30",
|
||||
},
|
||||
percentage: {
|
||||
uptimePoor: "#d32f2f",
|
||||
uptimeFair: "#e88c30",
|
||||
uptimeGood: "#ffd600",
|
||||
uptimeExcellent: "#079455",
|
||||
},
|
||||
unresolved: { main: "#4e5ba6", light: "#e2eaf7", bg: "#f2f4f7" },
|
||||
divider: border.light,
|
||||
other: {
|
||||
|
||||
@@ -54,6 +54,12 @@ const lightTheme = createTheme({
|
||||
bg: "#ffecbc",
|
||||
border: "#fec84b",
|
||||
},
|
||||
percentage: {
|
||||
uptimePoor: "#d32f2f",
|
||||
uptimeFair: "#ec8013",
|
||||
uptimeGood: "#ffb800",
|
||||
uptimeExcellent: "#079455",
|
||||
},
|
||||
unresolved: { main: "#4e5ba6", light: "#e2eaf7", bg: "#f2f4f7" },
|
||||
divider: border.light,
|
||||
other: {
|
||||
|
||||
Reference in New Issue
Block a user