mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-22 01:29:57 -06:00
Merge branch 'develop' into feature/pagespeed-api-warning-2022
This commit is contained in:
@@ -18,11 +18,11 @@
|
||||
"@mui/x-charts": "^7.5.1",
|
||||
"@mui/x-data-grid": "7.28.3",
|
||||
"@mui/x-date-pickers": "7.28.3",
|
||||
"@mui/icons-material": "6.4.10",
|
||||
"@mui/icons-material": "6.4.11",
|
||||
"@mui/lab": "6.0.0-dev.240424162023-9968b4889d",
|
||||
"@mui/material": "6.4.10",
|
||||
"@mui/material": "6.4.11",
|
||||
"@reduxjs/toolkit": "2.6.1",
|
||||
"@solana/wallet-adapter-base": "0.9.23",
|
||||
"@solana/wallet-adapter-base": "0.9.24",
|
||||
"@solana/wallet-adapter-material-ui": "0.16.35",
|
||||
"@solana/wallet-adapter-react": "0.15.36",
|
||||
"@solana/wallet-adapter-react-ui": "0.9.36",
|
||||
|
||||
@@ -25,10 +25,14 @@ function App() {
|
||||
if (authToken) {
|
||||
dispatch(getAppSettings({ authToken })).then((action) => {
|
||||
if (action.payload && action.payload.success) {
|
||||
const { language } = action.payload.data;
|
||||
if (language) {
|
||||
const { language } = action.payload.data;
|
||||
const availableLanguages = Object.keys(i18n.options.resources || {});
|
||||
if (language && availableLanguages.includes(language)) {
|
||||
dispatch(setLanguage(language));
|
||||
i18n.changeLanguage(language);
|
||||
} else {
|
||||
dispatch(setLanguage(availableLanguages[0]));
|
||||
i18n.changeLanguage(availableLanguages[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ const ChartBox = ({
|
||||
flex={1}
|
||||
direction="row"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.tertiary.main,
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
|
||||
border: 1,
|
||||
borderStyle: "solid",
|
||||
|
||||
@@ -47,11 +47,25 @@ const FilterHeader = ({ header, options, value, onChange, multiple = true }) =>
|
||||
.filter(Boolean)
|
||||
.join(", ");
|
||||
}}
|
||||
MenuProps={{
|
||||
anchorOrigin: {
|
||||
vertical: "bottom",
|
||||
horizontal: "left",
|
||||
},
|
||||
transformOrigin: {
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{options.map((option) => (
|
||||
<MenuItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
sx={{
|
||||
height: theme.spacing(17),
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
<Checkbox
|
||||
checked={controlledValue.includes(option.value)}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { Stack } from "@mui/material";
|
||||
import { Heading } from "../Heading";
|
||||
import CircularCount from "../CircularCount";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import SkeletonLayout from "./skeleton";
|
||||
@@ -8,22 +6,36 @@ import SkeletonLayout from "./skeleton";
|
||||
const MonitorCountHeader = ({
|
||||
shouldRender = true,
|
||||
monitorCount,
|
||||
heading,
|
||||
heading = "monitors",
|
||||
sx,
|
||||
children,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
if (!shouldRender) return <SkeletonLayout />;
|
||||
|
||||
if (monitorCount === 1) {
|
||||
heading = "monitor";
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
display="flex"
|
||||
width="fit-content"
|
||||
height={theme.spacing(18)}
|
||||
gap={theme.spacing(2)}
|
||||
sx={{ ...sx }}
|
||||
mt={theme.spacing(2)}
|
||||
px={theme.spacing(4)}
|
||||
pt={theme.spacing(2)}
|
||||
pb={theme.spacing(3)}
|
||||
borderRadius={theme.spacing(1)}
|
||||
sx={{
|
||||
...sx,
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
}}
|
||||
>
|
||||
<Heading component="h2">{heading}</Heading>
|
||||
<CircularCount count={monitorCount} />
|
||||
{monitorCount} <Typography component="h2">{heading}</Typography>
|
||||
{children}
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -79,6 +79,17 @@ aside .MuiListSubheader-root {
|
||||
transition: padding 200ms ease;
|
||||
}
|
||||
|
||||
.sidebar-delay-fade {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
aside.expanded.sidebar-ready .sidebar-delay-fade {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import {
|
||||
Box,
|
||||
Collapse,
|
||||
@@ -127,6 +127,21 @@ function Sidebar() {
|
||||
const distributedUptimeEnabled = useSelector(
|
||||
(state) => state.ui.distributedUptimeEnabled
|
||||
);
|
||||
const sidebarRef = useRef(null);
|
||||
const [sidebarReady, setSidebarReady] = useState(false);
|
||||
const TRANSITION_DURATION = 200;
|
||||
|
||||
useEffect(() => {
|
||||
if (!collapsed) {
|
||||
setSidebarReady(false);
|
||||
const timeout = setTimeout(() => {
|
||||
setSidebarReady(true);
|
||||
}, TRANSITION_DURATION);
|
||||
return () => clearTimeout(timeout);
|
||||
} else {
|
||||
setSidebarReady(false);
|
||||
}
|
||||
}, [collapsed]);
|
||||
|
||||
const renderAccountMenuItems = () => {
|
||||
let filteredAccountMenuItems = [...accountMenuItems];
|
||||
@@ -148,7 +163,10 @@ function Sidebar() {
|
||||
return filteredAccountMenuItems.map((item) => (
|
||||
<MenuItem
|
||||
key={item.name}
|
||||
onClick={() => navigate(item.path)}
|
||||
onClick={() => {
|
||||
closePopup()
|
||||
navigate(item.path)
|
||||
}}
|
||||
sx={{
|
||||
gap: theme.spacing(2),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
@@ -191,12 +209,14 @@ function Sidebar() {
|
||||
}, [location]);
|
||||
|
||||
const iconColor = theme.palette.primary.contrastTextTertiary;
|
||||
const sidebarClassName = `${collapsed ? "collapsed" : "expanded"} ${sidebarReady ? "sidebar-ready" : ""}`;
|
||||
|
||||
/* TODO refactor this, there are a some ternaries and comments in the return */
|
||||
return (
|
||||
<Stack
|
||||
component="aside"
|
||||
className={collapsed ? "collapsed" : "expanded"}
|
||||
ref={sidebarRef}
|
||||
className={sidebarClassName}
|
||||
/* TODO general padding should be here */
|
||||
py={theme.spacing(6)}
|
||||
gap={theme.spacing(6)}
|
||||
@@ -342,21 +362,6 @@ function Sidebar() {
|
||||
component="nav"
|
||||
aria-labelledby="nested-menu-subheader"
|
||||
disablePadding
|
||||
subheader={
|
||||
<ListSubheader
|
||||
component="div"
|
||||
id="nested-menu-subheader"
|
||||
sx={{
|
||||
py: theme.spacing(4),
|
||||
/* TODO px should be centralized in container */
|
||||
px: collapsed ? theme.spacing(2) : theme.spacing(4),
|
||||
backgroundColor: "transparent",
|
||||
position: "static",
|
||||
}}
|
||||
>
|
||||
Menu
|
||||
</ListSubheader>
|
||||
}
|
||||
sx={{
|
||||
px: theme.spacing(6),
|
||||
height: "100%",
|
||||
@@ -725,6 +730,7 @@ function Sidebar() {
|
||||
</Typography>
|
||||
</Box>
|
||||
<Stack
|
||||
className="sidebar-delay-fade"
|
||||
flexDirection={"row"}
|
||||
marginLeft={"auto"}
|
||||
columnGap={theme.spacing(2)}
|
||||
|
||||
36
src/Components/Tab/index.jsx
Normal file
36
src/Components/Tab/index.jsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Box, useTheme } from "@mui/material";
|
||||
import { TabList } from "@mui/lab";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
/**
|
||||
* CustomTabList component
|
||||
* @param {string} value - The currently selected tab's value.
|
||||
* @param {function} onChange - Callback when a different tab is selected.
|
||||
* @param {React.ReactNode} children - Tab components to render inside the TabList.
|
||||
* @param {object} props - Additional props passed to the TabList component.
|
||||
*/
|
||||
|
||||
const CustomTabList = ({ value, onChange, children, ...props }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
borderBottom: `1px solid ${theme.palette.primary.lowContrast}`,
|
||||
"& .MuiTabs-root": { height: "fit-content", minHeight: "0" },
|
||||
}}
|
||||
>
|
||||
<TabList value={value} onChange={onChange} {...props}>
|
||||
{children}
|
||||
</TabList>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
CustomTabList.propTypes = {
|
||||
value: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default CustomTabList;
|
||||
@@ -65,7 +65,7 @@ const DataTable = ({
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
color: theme.palette.secondary.contrastText,
|
||||
fontWeight: 600,
|
||||
fontSize: "12px",
|
||||
fontSize: "13px",
|
||||
},
|
||||
"& :is(td)": {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
|
||||
@@ -3,8 +3,8 @@ import PropTypes from "prop-types";
|
||||
import { useNavigate } from "react-router";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Box, Tab, useTheme } from "@mui/material";
|
||||
import CustomTabList from "../../Components/Tab";
|
||||
import TabContext from "@mui/lab/TabContext";
|
||||
import TabList from "@mui/lab/TabList";
|
||||
import ProfilePanel from "../../Components/TabPanels/Account/ProfilePanel";
|
||||
import PasswordPanel from "../../Components/TabPanels/Account/PasswordPanel";
|
||||
import TeamPanel from "../../Components/TabPanels/Account/TeamPanel";
|
||||
@@ -59,29 +59,18 @@ const Account = ({ open = "profile" }) => {
|
||||
py={theme.spacing(12)}
|
||||
>
|
||||
<TabContext value={tab}>
|
||||
<Box
|
||||
sx={{
|
||||
borderBottom: 1,
|
||||
borderColor: theme.palette.primary.lowContrast,
|
||||
"& .MuiTabs-root": { height: "fit-content", minHeight: "0" },
|
||||
}}
|
||||
>
|
||||
<TabList
|
||||
onChange={handleTabChange}
|
||||
aria-label="account tabs"
|
||||
>
|
||||
{tabList.map((label, index) => (
|
||||
<Tab
|
||||
label={label}
|
||||
key={index}
|
||||
value={label.toLowerCase()}
|
||||
onKeyDown={handleKeyDown}
|
||||
onFocus={() => handleFocus(label.toLowerCase())}
|
||||
tabIndex={index}
|
||||
/>
|
||||
))}
|
||||
</TabList>
|
||||
</Box>
|
||||
<CustomTabList value={tab} onChange={handleTabChange} aria-label="account tabs">
|
||||
{tabList.map((label, index) => (
|
||||
<Tab
|
||||
label={label}
|
||||
key={index}
|
||||
value={label.toLowerCase()}
|
||||
onKeyDown={handleKeyDown}
|
||||
onFocus={() => handleFocus(label.toLowerCase())}
|
||||
tabIndex={index}
|
||||
/>
|
||||
))}
|
||||
</CustomTabList>
|
||||
<ProfilePanel />
|
||||
{user.role.includes("superadmin") && <PasswordPanel />}
|
||||
{!hideTeams && <TeamPanel />}
|
||||
|
||||
@@ -68,7 +68,7 @@ const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete
|
||||
),
|
||||
},
|
||||
{ id: "cpu", content: t("cpu"), render: (row) => <CustomGauge progress={row.cpu} /> },
|
||||
{ id: "mem", content: t("mem"), render: (row) => <CustomGauge progress={row.mem} /> },
|
||||
{ id: "memory", content: t("memory"), render: (row) => <CustomGauge progress={row.mem} /> },
|
||||
{ id: "disk", content: t("disk"), render: (row) => <CustomGauge progress={row.disk} /> },
|
||||
{
|
||||
id: "actions",
|
||||
|
||||
@@ -87,7 +87,6 @@ const InfrastructureMonitors = () => {
|
||||
/>
|
||||
<MonitorCountHeader
|
||||
shouldRender={!isLoading}
|
||||
heading="Infrastructure monitors"
|
||||
monitorCount={summary?.totalMonitors ?? 0}
|
||||
/>
|
||||
<MonitorsTable
|
||||
|
||||
@@ -67,7 +67,6 @@ const PageSpeed = () => {
|
||||
<MonitorCountHeader
|
||||
shouldRender={!isLoading}
|
||||
monitorCount={summary?.totalMonitors}
|
||||
heading="PageSpeed monitors"
|
||||
sx={{ mb: theme.spacing(8) }}
|
||||
/>
|
||||
<MonitorGrid
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Components
|
||||
import { TabContext, TabList } from "@mui/lab";
|
||||
import { Box, Tab, useTheme } from "@mui/material";
|
||||
import { TabContext } from "@mui/lab";
|
||||
import { Tab, useTheme } from "@mui/material";
|
||||
import Settings from "./Settings";
|
||||
import Content from "./Content";
|
||||
|
||||
// Utils
|
||||
import PropTypes from "prop-types";
|
||||
import CustomTabList from "../../../../../Components/Tab";
|
||||
|
||||
const Tabs = ({
|
||||
isCreate,
|
||||
@@ -26,28 +27,20 @@ const Tabs = ({
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<TabContext value={TAB_LIST[tab]}>
|
||||
<Box
|
||||
sx={{
|
||||
borderBottom: `1px solid ${theme.palette.primary.lowContrast}`,
|
||||
"& .MuiTabs-root": { height: "fit-content", minHeight: "0" },
|
||||
<CustomTabList
|
||||
onChange={(_, selected) => {
|
||||
setTab(TAB_LIST.indexOf(selected));
|
||||
}}
|
||||
aria-label="status page tabs"
|
||||
>
|
||||
<TabList
|
||||
onChange={(_, tab) => {
|
||||
setTab(TAB_LIST.indexOf(tab));
|
||||
}}
|
||||
>
|
||||
{TAB_LIST.map((tab, idx) => {
|
||||
return (
|
||||
<Tab
|
||||
key={tab}
|
||||
label={TAB_LIST[idx]}
|
||||
value={TAB_LIST[idx]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</TabList>
|
||||
</Box>
|
||||
{TAB_LIST.map((tabLabel, idx) => (
|
||||
<Tab
|
||||
key={tabLabel}
|
||||
label={tabLabel}
|
||||
value={tabLabel}
|
||||
/>
|
||||
))}
|
||||
</CustomTabList>
|
||||
{tab === 0 ? (
|
||||
<Settings
|
||||
tabValue={TAB_LIST[0]}
|
||||
|
||||
@@ -120,7 +120,7 @@ const UptimeMonitors = () => {
|
||||
|
||||
const filterLookup = new Map([
|
||||
[toFilterStatus, "status"],
|
||||
[toFilterActive, "isActive"]
|
||||
[toFilterActive, "isActive"],
|
||||
]);
|
||||
|
||||
const activeFilter = [...filterLookup].find(([key]) => key !== undefined);
|
||||
@@ -202,7 +202,6 @@ const UptimeMonitors = () => {
|
||||
<MonitorCountHeader
|
||||
shouldRender={monitors?.length > 0 && !monitorsWithSummaryIsLoading}
|
||||
monitorCount={monitorsSummary?.totalMonitors}
|
||||
heading={"Uptime monitors"}
|
||||
></MonitorCountHeader>
|
||||
<Filter
|
||||
selectedTypes={selectedTypes}
|
||||
|
||||
@@ -368,7 +368,6 @@ const baseTheme = (palette) => ({
|
||||
root: ({ theme }) => ({
|
||||
fontSize: theme.typography.fontSize - 1,
|
||||
color: theme.palette.tertiary.contrastText,
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
height: '34px',
|
||||
minHeight: '34px',
|
||||
borderRadius: 0,
|
||||
@@ -376,21 +375,13 @@ const baseTheme = (palette) => ({
|
||||
minWidth: "fit-content",
|
||||
padding: `${theme.spacing(6)}px ${theme.spacing(4)}px`,
|
||||
fontWeight: 400,
|
||||
borderBottom: `${theme.shape.borderThick}px solid transparent`,
|
||||
borderRight: `${theme.shape.borderRadius / 2}px solid ${theme.palette.primary.lowContrast}`,
|
||||
"&:first-of-type": { borderTopLeftRadius: theme.shape.borderRadius * 4 },
|
||||
"&:last-child": { borderTopRightRadius: theme.shape.borderRadius * 4, 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,
|
||||
borderRadius: 0,
|
||||
},
|
||||
"&:hover": {
|
||||
borderColor: theme.palette.primary.lowContrast,
|
||||
@@ -442,11 +433,7 @@ const baseTheme = (palette) => ({
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
display: 'inline-flex',
|
||||
borderTop: '1px solid',
|
||||
borderLeft: '1px solid',
|
||||
borderRight: '1px solid',
|
||||
borderColor: theme.palette.primary.lowContrast,
|
||||
borderRadius: `${theme.shape.borderRadius}px ${theme.shape.borderRadius}px 0 0`,
|
||||
borderRadius: 0,
|
||||
"& .MuiTabs-indicator": {
|
||||
backgroundColor: theme.palette.tertiary.contrastText,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user