Merge branch 'develop' into settings-zod-schema
This commit is contained in:
commit
6195650dc1
19 files changed
+179
-464
No files matched your search
@@ -1,53 +0,0 @@
|
||||
.wallet-adapter-dropdown {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
.wallet-adapter-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: auto;
|
||||
height: var(--env-var-height-2) !important;
|
||||
font-size: var(--env-var-font-size-medium-plus) !important;
|
||||
font-weight: 500 !important;
|
||||
margin: 0;
|
||||
padding: calc(
|
||||
(var(--env-var-height-2) - var(--env-var-font-size-medium-plus) * 1.2) / 2
|
||||
)
|
||||
var(--env-var-spacing-1);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wallet-adapter-modal-title {
|
||||
font-size: var(--font-size-h5) !important;
|
||||
}
|
||||
|
||||
/* Separator styling */
|
||||
.wallet-adapter-modal-divider {
|
||||
background-color: var(--border-color) !important;
|
||||
margin: var(--spacing-md) 0 !important;
|
||||
}
|
||||
|
||||
/* Responsive fixes */
|
||||
@media (max-width: 1200px) {
|
||||
.wallet-adapter-button {
|
||||
font-size: var(--env-var-font-size-medium) !important;
|
||||
padding: calc((var(--env-var-height-2) - var(--env-var-font-size-medium) * 1.2) / 2)
|
||||
var(--env-var-spacing-1-minus) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.wallet-adapter-modal-wrapper {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.wallet-adapter-modal-divider {
|
||||
margin: var(--spacing-sm) 0 !important;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// import { useMemo } from "react";
|
||||
// import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
|
||||
// import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
|
||||
// import {
|
||||
// UnsafeBurnerWalletAdapter,
|
||||
// PhantomWalletAdapter,
|
||||
// } from "@solana/wallet-adapter-wallets";
|
||||
|
||||
// import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
|
||||
// import { clusterApiUrl } from "@solana/web3.js";
|
||||
// import PropTypes from "prop-types";
|
||||
// import "./index.css";
|
||||
|
||||
// // Default styles that can be overridden by your app
|
||||
// import "@solana/wallet-adapter-react-ui/styles.css";
|
||||
|
||||
// export const Wallet = ({ children }) => {
|
||||
// // The network can be set to 'devnet', 'testnet', or 'mainnet-beta'.
|
||||
// const network = WalletAdapterNetwork.Mainnet;
|
||||
|
||||
// // You can also provide a custom RPC endpoint.
|
||||
// const endpoint = useMemo(() => clusterApiUrl(network), [network]);
|
||||
|
||||
// const wallets = useMemo(
|
||||
// () => [new PhantomWalletAdapter()],
|
||||
// // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
// [network]
|
||||
// );
|
||||
|
||||
// return (
|
||||
// <ConnectionProvider endpoint={endpoint}>
|
||||
// <WalletProvider
|
||||
// wallets={wallets}
|
||||
// autoConnect
|
||||
// >
|
||||
// <WalletModalProvider>{children}</WalletModalProvider>
|
||||
// </WalletProvider>
|
||||
// </ConnectionProvider>
|
||||
// );
|
||||
// };
|
||||
|
||||
// Wallet.propTypes = {
|
||||
// children: PropTypes.node,
|
||||
// };
|
||||
|
||||
const Wallet = ({ children }) => {
|
||||
return children;
|
||||
};
|
||||
|
||||
export default Wallet;
|
||||
@@ -6,7 +6,6 @@
|
||||
min-height: 16px;
|
||||
}
|
||||
.MuiBreadcrumbs-root .MuiBreadcrumbs-li a {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 400;
|
||||
}
|
||||
.MuiBreadcrumbs-root .MuiBreadcrumbs-li:not(:last-child) {
|
||||
|
||||
@@ -64,7 +64,6 @@ const Select = ({
|
||||
const theme = useTheme();
|
||||
const getItemValue = (item) => item?._id ?? item?.id;
|
||||
const itemStyles = {
|
||||
fontSize: "var(--env-var-font-size-medium)",
|
||||
color: theme.palette.primary.contrastTextTertiary,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
margin: theme.spacing(2),
|
||||
|
||||
@@ -18,7 +18,6 @@ export const HttpAdornment = ({ https }) => {
|
||||
>
|
||||
<Typography
|
||||
component="h5"
|
||||
paddingRight={"var(--env-var-spacing-1-minus)"}
|
||||
color={theme.palette.primary.contrastTextSecondary}
|
||||
sx={{ lineHeight: 1, opacity: 0.8 }}
|
||||
>
|
||||
|
||||
@@ -23,7 +23,6 @@ export const MonitorStatus = ({ monitor }: { monitor: Monitor }) => {
|
||||
overflow={"hidden"}
|
||||
textOverflow={"ellipsis"}
|
||||
whiteSpace={"nowrap"}
|
||||
maxWidth={isSmall ? "100%" : "calc((100vw - var(--env-var-width-2)) / 2)"}
|
||||
>
|
||||
{monitor.name}
|
||||
</Typography>
|
||||
@@ -40,7 +39,6 @@ export const MonitorStatus = ({ monitor }: { monitor: Monitor }) => {
|
||||
overflow={"hidden"}
|
||||
textOverflow={"ellipsis"}
|
||||
whiteSpace={"nowrap"}
|
||||
maxWidth={isSmall ? "100%" : "calc((100vw - var(--env-var-width-2)) / 2)"}
|
||||
>
|
||||
{formatUrl(monitor?.url)}
|
||||
</Typography>
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
import { Box, Stack, useTheme } from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import { useTheme, keyframes } from "@mui/material";
|
||||
|
||||
const ripple = keyframes`
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: scale(0);
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: scale(2);
|
||||
}
|
||||
`;
|
||||
|
||||
interface PulseDotProps {
|
||||
color: string;
|
||||
@@ -28,7 +41,7 @@ export const PulseDot = ({ color }: PulseDotProps) => {
|
||||
height: "100%",
|
||||
backgroundColor: "inherit",
|
||||
borderRadius: "50%",
|
||||
animation: "ripple 1.8s ease-out infinite",
|
||||
animation: `${ripple} 1.8s ease-out infinite`,
|
||||
},
|
||||
"&::after": {
|
||||
content: `""`,
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialMode = window?.matchMedia?.("(prefers-color-scheme: dark)")?.matches
|
||||
? "dark"
|
||||
: "light";
|
||||
|
||||
const initialState = {
|
||||
monitors: {
|
||||
rowsPerPage: 10,
|
||||
},
|
||||
team: {
|
||||
rowsPerPage: 5,
|
||||
},
|
||||
maintenance: {
|
||||
rowsPerPage: 5,
|
||||
},
|
||||
infrastructure: {
|
||||
rowsPerPage: 5,
|
||||
},
|
||||
logs: {
|
||||
rowsPerPage: 15,
|
||||
},
|
||||
sidebar: {
|
||||
collapsed: false,
|
||||
},
|
||||
mode: initialMode,
|
||||
showURL: false,
|
||||
greeting: { index: 0, lastUpdate: null },
|
||||
timezone: "America/Toronto",
|
||||
distributedUptimeEnabled: false,
|
||||
language: "en",
|
||||
starPromptOpen: true,
|
||||
chartType: "histogram",
|
||||
};
|
||||
|
||||
const uiSlice = createSlice({
|
||||
name: "ui",
|
||||
initialState,
|
||||
reducers: {
|
||||
setDistributedUptimeEnabled: (state, action) => {
|
||||
state.distributedUptimeEnabled = action.payload;
|
||||
},
|
||||
setRowsPerPage: (state, action) => {
|
||||
const { table, value } = action.payload;
|
||||
if (!state[table]) {
|
||||
state[table] = {};
|
||||
}
|
||||
state[table].rowsPerPage = value;
|
||||
},
|
||||
toggleSidebar: (state) => {
|
||||
state.sidebar.collapsed = !state.sidebar.collapsed;
|
||||
},
|
||||
setCollapsed: (state, action) => {
|
||||
const { collapsed } = action.payload;
|
||||
state.sidebar.collapsed = collapsed;
|
||||
},
|
||||
setMode: (state, action) => {
|
||||
state.mode = action.payload;
|
||||
},
|
||||
setShowURL: (state, action) => {
|
||||
state.showURL = action.payload;
|
||||
},
|
||||
setGreeting(state, action) {
|
||||
if (!state.greeting) {
|
||||
state.greeting = { index: 0, lastUpdate: null };
|
||||
}
|
||||
state.greeting.index = action.payload.index;
|
||||
state.greeting.lastUpdate = action.payload.lastUpdate;
|
||||
},
|
||||
setTimezone(state, action) {
|
||||
state.timezone = action.payload.timezone;
|
||||
},
|
||||
setLanguage: (state, action) => {
|
||||
state.language = action.payload;
|
||||
},
|
||||
setStarPromptOpen: (state, action) => {
|
||||
state.starPromptOpen = action.payload;
|
||||
},
|
||||
setChartType: (state, action) => {
|
||||
state.chartType = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default uiSlice.reducer;
|
||||
export const {
|
||||
setRowsPerPage,
|
||||
toggleSidebar,
|
||||
setCollapsed,
|
||||
setMode,
|
||||
setShowURL,
|
||||
setGreeting,
|
||||
setTimezone,
|
||||
setDistributedUptimeEnabled,
|
||||
setLanguage,
|
||||
setStarPromptOpen,
|
||||
setChartType,
|
||||
} = uiSlice.actions;
|
||||
@@ -0,0 +1,133 @@
|
||||
import { createSlice, type PayloadAction } from "@reduxjs/toolkit";
|
||||
|
||||
type ThemeMode = "light" | "dark";
|
||||
type ChartType = "histogram" | "line";
|
||||
type TableName = "monitors" | "team" | "maintenance" | "infrastructure" | "logs";
|
||||
|
||||
interface TableState {
|
||||
rowsPerPage: number;
|
||||
}
|
||||
|
||||
interface SidebarState {
|
||||
collapsed: boolean;
|
||||
}
|
||||
|
||||
interface GreetingState {
|
||||
index: number;
|
||||
lastUpdate: string | null;
|
||||
}
|
||||
|
||||
interface UIState {
|
||||
monitors: TableState;
|
||||
team: TableState;
|
||||
maintenance: TableState;
|
||||
infrastructure: TableState;
|
||||
logs: TableState;
|
||||
sidebar: SidebarState;
|
||||
mode: ThemeMode;
|
||||
showURL: boolean;
|
||||
greeting: GreetingState;
|
||||
timezone: string;
|
||||
distributedUptimeEnabled: boolean;
|
||||
language: string;
|
||||
starPromptOpen: boolean;
|
||||
chartType: ChartType;
|
||||
}
|
||||
|
||||
const initialMode: ThemeMode = window?.matchMedia?.("(prefers-color-scheme: dark)")
|
||||
?.matches
|
||||
? "dark"
|
||||
: "light";
|
||||
|
||||
const initialState: UIState = {
|
||||
monitors: {
|
||||
rowsPerPage: 10,
|
||||
},
|
||||
team: {
|
||||
rowsPerPage: 5,
|
||||
},
|
||||
maintenance: {
|
||||
rowsPerPage: 5,
|
||||
},
|
||||
infrastructure: {
|
||||
rowsPerPage: 5,
|
||||
},
|
||||
logs: {
|
||||
rowsPerPage: 15,
|
||||
},
|
||||
sidebar: {
|
||||
collapsed: false,
|
||||
},
|
||||
mode: initialMode,
|
||||
showURL: false,
|
||||
greeting: { index: 0, lastUpdate: null },
|
||||
timezone: "America/Toronto",
|
||||
distributedUptimeEnabled: false,
|
||||
language: "en",
|
||||
starPromptOpen: true,
|
||||
chartType: "histogram",
|
||||
};
|
||||
|
||||
const uiSlice = createSlice({
|
||||
name: "ui",
|
||||
initialState,
|
||||
reducers: {
|
||||
setDistributedUptimeEnabled: (state, action: PayloadAction<boolean>) => {
|
||||
state.distributedUptimeEnabled = action.payload;
|
||||
},
|
||||
setRowsPerPage: (
|
||||
state,
|
||||
action: PayloadAction<{ table: TableName; value: number }>
|
||||
) => {
|
||||
const { table, value } = action.payload;
|
||||
state[table].rowsPerPage = value;
|
||||
},
|
||||
toggleSidebar: (state) => {
|
||||
state.sidebar.collapsed = !state.sidebar.collapsed;
|
||||
},
|
||||
setCollapsed: (state, action: PayloadAction<{ collapsed: boolean }>) => {
|
||||
state.sidebar.collapsed = action.payload.collapsed;
|
||||
},
|
||||
setMode: (state, action: PayloadAction<ThemeMode>) => {
|
||||
state.mode = action.payload;
|
||||
},
|
||||
setShowURL: (state, action: PayloadAction<boolean>) => {
|
||||
state.showURL = action.payload;
|
||||
},
|
||||
setGreeting: (
|
||||
state,
|
||||
action: PayloadAction<{ index: number; lastUpdate: string | null }>
|
||||
) => {
|
||||
state.greeting.index = action.payload.index;
|
||||
state.greeting.lastUpdate = action.payload.lastUpdate;
|
||||
},
|
||||
setTimezone: (state, action: PayloadAction<{ timezone: string }>) => {
|
||||
state.timezone = action.payload.timezone;
|
||||
},
|
||||
setLanguage: (state, action: PayloadAction<string>) => {
|
||||
state.language = action.payload;
|
||||
},
|
||||
setStarPromptOpen: (state, action: PayloadAction<boolean>) => {
|
||||
state.starPromptOpen = action.payload;
|
||||
},
|
||||
setChartType: (state, action: PayloadAction<ChartType>) => {
|
||||
state.chartType = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export type { UIState, ThemeMode, ChartType, TableName };
|
||||
export default uiSlice.reducer;
|
||||
export const {
|
||||
setRowsPerPage,
|
||||
toggleSidebar,
|
||||
setCollapsed,
|
||||
setMode,
|
||||
setShowURL,
|
||||
setGreeting,
|
||||
setTimezone,
|
||||
setDistributedUptimeEnabled,
|
||||
setLanguage,
|
||||
setStarPromptOpen,
|
||||
setChartType,
|
||||
} = uiSlice.actions;
|
||||
@@ -1,10 +0,0 @@
|
||||
.integrations h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
font-weight: 600;
|
||||
}
|
||||
.integrations p.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.integrations button {
|
||||
height: var(--env-var-height-2);
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Stack, Typography, Grid, Button } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import Discord from "../../../assets/icons/discord-icon.svg?react";
|
||||
import Slack from "../../../assets/icons/slack-icon.svg?react";
|
||||
import Zapier from "../../../assets/icons/zapier-icon.svg?react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
/**
|
||||
* Integrations component
|
||||
* @param {Object} props - Props for the IntegrationsComponent.
|
||||
* @param {string} props.icon - The icon for the integration image.
|
||||
* @param {string} props.header - The header for the integration.
|
||||
* @param {string} props.info - Information about the integration.
|
||||
* @param {Function} props.onClick - The onClick handler for the integration button.
|
||||
* @returns {JSX.Element} The JSX representation of the IntegrationsComponent.
|
||||
*/
|
||||
const IntegrationsComponent = ({ icon, header, info, onClick }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Grid
|
||||
item
|
||||
lg={6}
|
||||
flexGrow={1}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.spacing(12)}
|
||||
p={theme.spacing(8)}
|
||||
pl={theme.spacing(12)}
|
||||
height="100%"
|
||||
border={1}
|
||||
borderColor={theme.palette.primary.lowContrast}
|
||||
borderRadius={theme.shape.borderRadius}
|
||||
backgroundColor={theme.palette.primary.main}
|
||||
>
|
||||
{icon}
|
||||
<Stack
|
||||
gap={theme.spacing(2)}
|
||||
flex={1}
|
||||
>
|
||||
<Typography component="h1">{header}</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
maxWidth: "300px",
|
||||
wordWrap: "break-word",
|
||||
}}
|
||||
>
|
||||
{info}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="accent"
|
||||
onClick={onClick}
|
||||
sx={{ alignSelf: "center" }}
|
||||
disabled={true}
|
||||
>
|
||||
{t("add")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
// PropTypes for IntegrationsComponent
|
||||
IntegrationsComponent.propTypes = {
|
||||
icon: PropTypes.object.isRequired,
|
||||
header: PropTypes.string.isRequired,
|
||||
info: PropTypes.string.isRequired,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
/**
|
||||
* Integrations Page Component
|
||||
* @returns {JSX.Element} The JSX representation of the Integrations page.
|
||||
*/
|
||||
|
||||
const Integrations = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const integrations = [
|
||||
{
|
||||
icon: (
|
||||
<Slack
|
||||
alt="slack integration"
|
||||
style={{ width: "45px", height: "45px", alignSelf: "center" }}
|
||||
/>
|
||||
),
|
||||
header: t("integrationsSlack"),
|
||||
info: t("integrationsSlackInfo"),
|
||||
onClick: () => {},
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<Discord
|
||||
alt="discord integration"
|
||||
style={{ width: "42px", height: "42px", alignSelf: "center" }}
|
||||
/>
|
||||
),
|
||||
header: t("integrationsDiscord"),
|
||||
info: t("integrationsDiscordInfo"),
|
||||
onClick: () => {},
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<Zapier
|
||||
alt="zapier integration"
|
||||
style={{ width: "42px", height: "42px", alignSelf: "center" }}
|
||||
/>
|
||||
),
|
||||
header: t("integrationsZapier"),
|
||||
info: t("integrationsZapierInfo"),
|
||||
onClick: () => {},
|
||||
},
|
||||
// Add more integrations as needed
|
||||
];
|
||||
|
||||
return (
|
||||
<Stack
|
||||
className="integrations"
|
||||
pt={theme.spacing(20)}
|
||||
gap={theme.spacing(2)}
|
||||
sx={{
|
||||
"& h1, & p": {
|
||||
color: theme.palette.primary.contrastTextSecondary,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography component="h1">{t("integrations")}</Typography>
|
||||
<Typography mb={theme.spacing(12)}>{t("integrationsPrism")}</Typography>
|
||||
<Grid
|
||||
container
|
||||
spacing={theme.spacing(12)}
|
||||
>
|
||||
{integrations.map((integration, index) => (
|
||||
<IntegrationsComponent
|
||||
key={index}
|
||||
icon={integration.icon}
|
||||
header={integration.header}
|
||||
info={integration.info}
|
||||
onClick={integration.onClick}
|
||||
/>
|
||||
))}
|
||||
</Grid>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default Integrations;
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
import SettingsStats from "./SettingsStats.jsx";
|
||||
|
||||
import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
|
||||
import { useGet, usePost, useDelete, useLazyGet, usePut } from "@/Hooks/UseApi";
|
||||
import { useGet, usePost, useDelete, useLazyGet, usePatch } from "@/Hooks/UseApi";
|
||||
// Constants
|
||||
const BREADCRUMBS = [{ name: `Settings`, path: "/settings" }];
|
||||
|
||||
@@ -62,10 +62,10 @@ const Settings = () => {
|
||||
}
|
||||
}, [fetchedSettings]);
|
||||
|
||||
const { put: saveSettingsFn, loading: isSaving } = usePut();
|
||||
const { patch: saveSettingsFn, loading: isSaving } = usePatch();
|
||||
|
||||
const saveSettings = async (settings) => {
|
||||
const response = await saveSettingsFn("/settings", { settings });
|
||||
const response = await saveSettingsFn("/settings", settings);
|
||||
if (response?.data) {
|
||||
const data = response.data;
|
||||
setIsApiKeySet(data.pagespeedKeySet);
|
||||
|
||||
@@ -38,7 +38,6 @@ const baseTheme = (palette) => ({
|
||||
fontWeight: 400,
|
||||
},
|
||||
label: {
|
||||
fontSize: "var(--env-var-font-size-medium)",
|
||||
color: palette.primary.contrastTextSecondary,
|
||||
fontWeight: 500,
|
||||
},
|
||||
@@ -332,8 +331,6 @@ const baseTheme = (palette) => ({
|
||||
|
||||
"& .MuiInputBase-input": {
|
||||
padding: ".75em",
|
||||
minHeight: "var(--env-var-height-2)",
|
||||
fontSize: "var(--env-var-font-size-medium)",
|
||||
fontWeight: 400,
|
||||
color: palette.primary.contrastTextSecondary,
|
||||
"&.Mui-disabled": {
|
||||
@@ -368,13 +365,12 @@ const baseTheme = (palette) => ({
|
||||
"& .MuiFormHelperText-root": {
|
||||
color: palette.error.main,
|
||||
opacity: 0.8,
|
||||
fontSize: "var(--env-var-font-size-medium)",
|
||||
fontSize: "var()",
|
||||
marginLeft: 0,
|
||||
},
|
||||
|
||||
"& .MuiFormHelperText-root.Mui-error": {
|
||||
opacity: 0.8,
|
||||
fontSize: "var(--env-var-font-size-medium)",
|
||||
color: palette.error.main,
|
||||
whiteSpace: "nowrap",
|
||||
},
|
||||
@@ -762,7 +758,6 @@ const baseTheme = (palette) => ({
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
maxWidth: "calc((100vw - var(--env-var-width-2)) / 2)",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -775,7 +770,6 @@ const baseTheme = (palette) => ({
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
maxWidth: "calc((100vw - var(--env-var-width-2)) / 2)",
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -49,6 +49,13 @@ export const theme = (mode: string, palette: any) =>
|
||||
},
|
||||
|
||||
components: {
|
||||
MuiTouchRipple: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiButtonBase: {
|
||||
defaultProps: {
|
||||
disableRipple: true,
|
||||
|
||||
@@ -18,70 +18,4 @@ html {
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Generalized Stylings */
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-2: 360px;
|
||||
--env-var-width-4: 100px;
|
||||
|
||||
--env-var-height-2: 34px;
|
||||
|
||||
--env-var-nav-bar-height: 70px;
|
||||
--env-var-side-bar-width: 250px;
|
||||
--env-var-side-bar-collapsed-width: 64px;
|
||||
--env-var-side-bar-auth-footer-height: 50px;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-1-plus: 16px;
|
||||
--env-var-spacing-1-minus: 10px;
|
||||
--env-var-spacing-2: 24px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-small-plus: 12px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-large-plus: 22px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
}
|
||||
|
||||
.MuiInputBase-root.Mui-disabled input {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* .Toastify__toast-container {
|
||||
min-width: 300px;
|
||||
width: auto;
|
||||
}
|
||||
.Toastify__toast-body .alert {
|
||||
min-width: 150px;
|
||||
padding: 5px 10px;
|
||||
align-items: center;
|
||||
}
|
||||
.Toastify [class^="Toastify__toast"] {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.Toastify__toast {
|
||||
min-height: 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.Toastify [class*="Toastify__toast-theme"] {
|
||||
background-color: transparent;
|
||||
} */
|
||||
|
||||
.MuiTouchRipple-root {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: scale(0);
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: scale(2);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ import App from "./App.jsx";
|
||||
import "./index.css";
|
||||
import { BrowserRouter as Router } from "react-router-dom";
|
||||
import { Provider } from "react-redux";
|
||||
import { persistor, store } from "./store.js";
|
||||
import { persistor, store } from "@/store.js";
|
||||
import { PersistGate } from "redux-persist/integration/react";
|
||||
import I18nLoader from "./Components/v1/I18nLoader/index.jsx";
|
||||
import { initApiClient } from "./Utils/ApiClient.js";
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import { configureStore, combineReducers } from "@reduxjs/toolkit";
|
||||
|
||||
import authReducer from "./Features/Auth/authSlice";
|
||||
import uiReducer from "./Features/UI/uiSlice";
|
||||
import authReducer from "@/Features/Auth/authSlice";
|
||||
import uiReducer from "@/Features/UI/uiSlice";
|
||||
import storage from "redux-persist/lib/storage";
|
||||
import { persistReducer, persistStore, createTransform } from "redux-persist";
|
||||
import {
|
||||
persistReducer,
|
||||
persistStore,
|
||||
createTransform,
|
||||
PERSIST,
|
||||
REHYDRATE,
|
||||
} from "redux-persist";
|
||||
|
||||
const authTransform = createTransform(
|
||||
(inboundState) => {
|
||||
(inboundState: Record<string, unknown>) => {
|
||||
const { profileImage, ...rest } = inboundState;
|
||||
return rest;
|
||||
},
|
||||
// No transformation on rehydration
|
||||
null,
|
||||
// Only applies to auth
|
||||
undefined,
|
||||
{ whitelist: ["auth"] }
|
||||
);
|
||||
|
||||
@@ -28,6 +31,7 @@ const rootReducer = combineReducers({
|
||||
ui: uiReducer,
|
||||
});
|
||||
|
||||
// @ts-expect-error - redux-persist types don't align perfectly with redux-toolkit
|
||||
const persistedReducer = persistReducer(persistConfig, rootReducer);
|
||||
|
||||
export const store = configureStore({
|
||||
@@ -35,10 +39,13 @@ export const store = configureStore({
|
||||
middleware: (getDefaultMiddleware) =>
|
||||
getDefaultMiddleware({
|
||||
serializableCheck: {
|
||||
ignoredActions: ["persist/PERSIST", "persist/REHYDRATE", "persist/REGISTER"],
|
||||
ignoredActions: [PERSIST, REHYDRATE, "persist/REGISTER"],
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
export type RootState = ReturnType<typeof rootReducer>;
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
|
||||
export const persistor = persistStore(store);
|
||||
export default store;
|
||||
@@ -89,7 +89,6 @@ class SuperSimpleQueueHelper {
|
||||
|
||||
// Step 4 Add check to buffer
|
||||
this.buffer.addToBuffer({ check });
|
||||
|
||||
// Step 4. Update monitor status
|
||||
const statusChangeResult = await this.statusService.updateMonitorStatus(status, check);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import MonitorStats from "../../db/models/MonitorStats.js";
|
||||
import { CheckModel } from "@/db/models/index.js";
|
||||
import type {
|
||||
Monitor,
|
||||
MonitorStatus,
|
||||
MonitorStatusResponse,
|
||||
StatusChangeResult,
|
||||
Check,
|
||||
@@ -200,14 +201,13 @@ export class StatusService implements IStatusService {
|
||||
monitor.recentChecks.shift();
|
||||
}
|
||||
|
||||
monitor.status = status === true ? "up" : "down";
|
||||
|
||||
const prevStatus = monitor.status;
|
||||
let newStatus = monitor.status;
|
||||
let newStatus: MonitorStatus = status === true ? "up" : "down";
|
||||
let statusChanged = false;
|
||||
|
||||
// Return early if not enough data points
|
||||
if (monitor.statusWindow.length < monitor.statusWindowSize) {
|
||||
monitor.status = newStatus;
|
||||
const updated = await this.monitorsRepository.updateById(monitor.id, monitor.teamId, monitor);
|
||||
return {
|
||||
monitor: updated,
|
||||
|
||||
Reference in new issue
Block a user