Merge branch 'develop' into fix/email-case

This commit is contained in:
Alexander Holliday
2024-08-23 15:19:24 -07:00
committed by GitHub
13 changed files with 266 additions and 120 deletions
+2 -2
View File
@@ -23,8 +23,8 @@ const PulseDot = ({ color }) => {
justifyContent="center"
>
<Box
minWidth="16px"
minHeight="16px"
minWidth="18px"
minHeight="18px"
sx={{
position: "relative",
backgroundColor: color,
+4 -13
View File
@@ -1,22 +1,12 @@
.MuiTable-root .host a {
width: var(--env-var-img-width-2);
height: var(--env-var-img-width-2);
color: var(--env-var-color-5);
margin-right: 10px;
}
.MuiTable-root .host a svg {
width: var(--env-var-font-size-large);
height: var(--env-var-font-size-large);
}
.MuiTable-root .host div:nth-child(2) {
.MuiTable-root .host {
width: fit-content;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.MuiTable-root .host div:nth-child(2) span {
.MuiTable-root .host span {
font-size: var(--env-var-font-size-small);
margin-left: 10px;
margin-left: 8px;
}
.MuiTable-root .label {
@@ -128,6 +118,7 @@
.MuiTablePagination-root p {
color: var(--env-var-color-2);
font-weight: 500;
font-size: var(--env-var-font-size-small-plus);
}
.MuiTablePagination-root button,
.MuiTablePagination-root .MuiSelect-select {
@@ -0,0 +1,19 @@
.bar-tooltip .MuiTooltip-tooltip {
background-color: white;
border: solid 1px black;
box-shadow: var(--env-var-shadow-1);
border: solid 1px var(--env-var-color-6);
border-radius: var(--env-var-radius-1);
padding: 4px 8px;
}
.bar-tooltip .MuiTooltip-tooltip p {
font-size: var(--env-var-font-size-small-plus);
color: var(--env-var-color-2);
font-weight: 500;
}
.bar-tooltip .MuiTooltip-tooltip span {
font-size: var(--env-var-font-size-small);
color: var(--env-var-color-2);
font-weight: 600;
}
@@ -0,0 +1,142 @@
import { useTheme } from "@emotion/react";
import { Box, Stack, Tooltip, Typography } from "@mui/material";
import { formatDate } from "../../../Utils/timeUtils";
import { useEffect, useState } from "react";
import "./index.css";
const BarChart = ({ checks = [] }) => {
const theme = useTheme();
const [animate, setAnimate] = useState(false);
useEffect(() => {
setAnimate(true);
});
// set responseTime to average if there's only one check
if (checks.length === 1) {
checks[0] = { ...checks[0], responseTime: 50 };
}
if (checks.length !== 25) {
const placeholders = Array(25 - checks.length).fill("placeholder");
checks = [...checks, ...placeholders];
}
return (
<Stack
direction="row"
flexWrap="nowrap"
gap="3px"
height="50px"
width="fit-content"
onClick={(event) => event.stopPropagation()}
sx={{
cursor: "default",
}}
>
{checks.map((check, index) =>
check === "placeholder" ? (
<Box
key={`${check}-${index}`}
position="relative"
width="9px"
height="100%"
backgroundColor={theme.palette.otherColors.fillGray}
sx={{
borderRadius: "3px",
}}
/>
) : (
<Tooltip
title={
<>
<Typography>
{formatDate(new Date(check.createdAt), { year: undefined })}
</Typography>
<Box mt={theme.gap.xs}>
<Box
display="inline-block"
width={theme.gap.small}
height={theme.gap.small}
backgroundColor={
check.status
? theme.label.up.dotColor
: theme.label.down.dotColor
}
sx={{ borderRadius: "50%" }}
/>
<Stack
display="inline-flex"
direction="row"
justifyContent="space-between"
ml={theme.gap.xs}
gap={theme.gap.large}
>
<Typography component="span" sx={{ opacity: 0.8 }}>
Response Time
</Typography>
<Typography component="span">
{check.originalResponseTime}
<Typography component="span" sx={{ opacity: 0.8 }}>
{" "}
ms
</Typography>
</Typography>
</Stack>
</Box>
</>
}
placement="top"
key={`check-${check?._id}`}
slotProps={{
popper: {
className: "bar-tooltip",
modifiers: [
{
name: "offset",
options: {
offset: [0, -10],
},
},
],
},
}}
>
<Box
position="relative"
width="9px"
height="100%"
backgroundColor={
check.status ? theme.label.up.bgColor : theme.label.down.bgColor
}
sx={{
borderRadius: "3px",
"&:hover > .MuiBox-root": {
filter: "brightness(0.8)",
},
}}
>
<Box
position="absolute"
bottom={0}
width="100%"
height={`${animate ? check.responseTime : 0}%`}
backgroundColor={
check.status
? theme.label.up.dotColor
: theme.label.down.dotColor
}
sx={{
borderRadius: "3px",
transition: "height 600ms cubic-bezier(0.4, 0, 0.2, 1)",
}}
/>
</Box>
</Tooltip>
)
)}
</Stack>
);
};
export default BarChart;
+4 -4
View File
@@ -53,9 +53,9 @@ const menu = [
],
},
{ name: "Incidents", path: "incidents", icon: <Incidents /> },
{ name: "Status pages", path: "status", icon: <StatusPages /> },
// { name: "Status pages", path: "status", icon: <StatusPages /> },
{ name: "Maintenance", path: "maintenance", icon: <Maintenance /> },
{ name: "Integrations", path: "integrations", icon: <Integrations /> },
// { name: "Integrations", path: "integrations", icon: <Integrations /> },
{
name: "Account",
icon: <Account />,
@@ -310,7 +310,7 @@ function Sidebar() {
gap: theme.gap.small,
borderRadius: `${theme.shape.borderRadius}px`,
pl: theme.gap.small,
mb:"1px"
mb: "1px",
}}
>
{child.icon}
@@ -427,7 +427,7 @@ function Sidebar() {
onClick={() =>
item.path === "support"
? window.open(
"https://github.com/bluewave-labs/bluewave-uptime",
"https://github.com/bluewave-labs/bluewave-uptime/issues",
"_blank",
"noreferrer"
)
@@ -74,7 +74,8 @@ const TeamPanel = () => {
{ id: 1, name: "NAME" },
{ id: 2, name: "EMAIL" },
{ id: 3, name: "ROLE" },
{ id: 4, name: "ACTION" },
// FEATURE STILL TO BE IMPLEMENTED
// { id: 4, name: "ACTION" },
],
rows: team?.map((member, idx) => {
return {
@@ -101,22 +102,23 @@ const TeamPanel = () => {
id: idx + 2,
data: member.role.includes("admin") ? "Administrator" : "Member",
},
{
// TODO - Add delete onClick
id: idx + 3,
data: (
<IconButton
aria-label="remove member"
sx={{
"&:focus": {
outline: "none",
},
}}
>
<Remove />
</IconButton>
),
},
// FEATURE STILL TO BE IMPLEMENTED
// {
// // TODO - Add delete onClick
// id: idx + 3,
// data: (
// <IconButton
// aria-label="remove member"
// sx={{
// "&:focus": {
// outline: "none",
// },
// }}
// >
// <Remove />
// </IconButton>
// ),
// },
],
};
}),
@@ -197,7 +199,8 @@ const TeamPanel = () => {
return (
<TabPanel value="team">
<Stack component="form">
{/* FEATURE STILL TO BE IMPLEMENTED */}
{/* <Stack component="form">
<Box sx={{ alignSelf: "flex-start" }}>
<Typography component="h1">Organization name</Typography>
</Box>
@@ -242,7 +245,7 @@ const TeamPanel = () => {
/>
</Stack>
</Stack>
<Divider aria-hidden="true" sx={{ marginY: theme.spacing(4) }} />
<Divider aria-hidden="true" sx={{ marginY: theme.spacing(4) }} /> */}
<Stack
component="form"
noValidate
+7 -33
View File
@@ -10,11 +10,9 @@ import Button from "../../Components/Button";
import ServerStatus from "../../Components/Charts/Servers/ServerStatus";
import { useTheme } from "@emotion/react";
import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded";
import OpenInNewPage from "../../assets/icons/open-in-new-page.svg?react";
import BasicTable from "../../Components/BasicTable";
import { StatusLabel } from "../../Components/Label";
import { createToast } from "../../Utils/toastUtils";
import ResponseTimeChart from "../../Components/Charts/ResponseTimeChart";
import {
Box,
IconButton,
@@ -28,6 +26,7 @@ import {
import Settings from "../../assets/icons/settings-bold.svg?react";
import PropTypes from "prop-types";
import BarChart from "../../Components/Charts/BarChart";
const ActionsMenu = ({ monitor }) => {
const [anchorEl, setAnchorEl] = useState(null);
@@ -206,7 +205,6 @@ ActionsMenu.propTypes = {
*
* @component
* @param {Object} params - An object containing the following properties:
* @param {string} params.url - The URL of the host.
* @param {string} params.title - The name of the host.
* @param {string} params.percentageColor - The color of the percentage text.
* @param {number} params.percentage - The percentage to display.
@@ -214,40 +212,17 @@ ActionsMenu.propTypes = {
*/
const Host = ({ params }) => {
return (
<Stack direction="row" alignItems="center" className="host">
<IconButton
aria-label="monitor link"
onClick={(event) => {
event.stopPropagation();
window.open(params.url, "_blank", "noreferrer");
}}
sx={{
"&:focus": {
outline: "none",
},
mr: "5px",
}}
>
<OpenInNewPage
style={{
marginTop: "-1px",
marginRight: "-1px",
}}
/>
</IconButton>
<Box>
{params.title}
<Typography component="span" sx={{ color: params.percentageColor }}>
{params.percentage}%
</Typography>
</Box>
<Stack direction="row" alignItems="baseline" className="host">
{params.title}
<Typography component="span" sx={{ color: params.percentageColor }}>
{params.percentage}%
</Typography>
</Stack>
);
};
Host.propTypes = {
params: PropTypes.shape({
url: PropTypes.string,
title: PropTypes.string,
percentageColor: PropTypes.string,
percentage: PropTypes.number,
@@ -326,7 +301,6 @@ const Monitors = () => {
data.rows = monitorState.monitors.map((monitor, idx) => {
const params = {
url: monitor.url,
title: monitor.name,
percentage: 100,
percentageColor:
@@ -357,7 +331,7 @@ const Monitors = () => {
/>
),
},
{ id: idx + 2, data: <ResponseTimeChart checks={reversedChecks} /> },
{ id: idx + 2, data: <BarChart checks={reversedChecks} /> },
{
id: idx + 3,
data: (
+2 -1
View File
@@ -43,7 +43,7 @@ export const formatDurationRounded = (ms) => {
return time;
};
export const formatDate = (date) => {
export const formatDate = (date, customOptions) => {
const options = {
year: "numeric",
month: "long",
@@ -51,6 +51,7 @@ export const formatDate = (date) => {
hour: "numeric",
minute: "numeric",
hour12: true,
...customOptions
};
// Return the date using the specified options
+1 -1
View File
@@ -67,7 +67,7 @@
--env-var-width-2: 360px;
--env-var-height-1: 100vh;
--env-var-height-2: 36px;
--env-var-height-2: 34px;
--env-var-nav-bar-height: 70px;
--env-var-side-bar-width: 250px;
+1 -1
View File
@@ -16,7 +16,7 @@ RUN npm run build
FROM nginx:1.27.1-alpine
COPY ./Docker/nginx/default.conf /etc/nginx/conf.d/default.conf
# COPY ./Docker/nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
+11 -1
View File
@@ -1,11 +1,21 @@
version: "3"
services:
client:
image: uptime_client:latest
ports:
- "80:80"
- "443:443"
depends_on:
- server
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d/:ro
- ./certbot/www:/var/www/certbot/:ro
- ./certbot/conf/:/etc/nginx/ssl/:ro
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
server:
image: uptime_server:latest
ports:
+51
View File
@@ -0,0 +1,51 @@
server {
listen 80;
listen [::]:80;
server_name uptime-demo.bluewavelabs.ca;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server:5000/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;
server_name uptime-demo.bluewavelabs.ca;
ssl_certificate /etc/nginx/ssl/live/uptime-demo.bluewavelabs.ca/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/uptime-demo.bluewavelabs.ca/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server:5000/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
-45
View File
@@ -1,45 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}