Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
yosefmih committed Apr 24, 2024
1 parent 729f1cb commit 90cf429
Show file tree
Hide file tree
Showing 5 changed files with 407 additions and 55 deletions.
2 changes: 1 addition & 1 deletion dashboard/src/main/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export default class Main extends Component<PropsType, StateType> {
}}
/>
<Route
path={`/:status/:projectId?/:clusterId?`}
path={`/status`}
render={() => {
if (!this.state.isLoggedIn) {
return <Redirect to="/login" />;
Expand Down
181 changes: 181 additions & 0 deletions dashboard/src/main/status/ClusterStatusSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import React, { useContext, useEffect, useState } from "react";

import { ProjectListType, ClusterType } from "shared/types";

import styled from "styled-components";
import Container from "components/porter/Container";
import Expandable from "components/porter/Expandable";
import Image from "components/porter/Image";
import Spacer from "components/porter/Spacer";
import logo from "assets/logo.png";

import Back from "components/porter/Back";
import Text from "components/porter/Text";
import { Context } from "shared/Context";

import midnight from "shared/themes/midnight";
import gradient from "assets/gradient.png";

import api from "shared/api";

import {StatusData, DailyHealthStatus} from "shared/types";

type Props = { cluster: ClusterType, projectId: number};

const ClusterStatusSection: React.FC<Props> = ({ cluster, projectId }) => {
const [statusData, setStatusData] = useState<StatusData>({} as StatusData);

useEffect(() => {
if (!projectId || !cluster) {
return;
}

api
.systemStatusHistory(
"<token>",
{},
{
projectId,
clusterId: cluster.id,
}
)
.then(({ data }) => {
console.log(data);
setStatusData({
cluster_health_histories: data.cluster_status_histories,
service_health_histories_grouped: {},
});
})
.catch((err) => {
console.error(err);
});
}, [projectId, cluster]);
return (
<>
<Expandable
key={cluster.id}
alt
header={
<Container row>
<Text size={16}> {cluster.name} </Text>
<Spacer x={1} inline />
<Text color="#01a05d">Operational</Text>
</Container>
}
>
{
statusData?.cluster_health_histories &&
Object.keys(statusData?.cluster_health_histories).map((key) => {
return (
<React.Fragment key={key}>
<Text color="helper">{key}</Text>
<Spacer y={0.25} />
<StatusBars>
{Array.from({ length: 90 }).map((_, i) => {
const status =
statusData?.cluster_health_histories[key][89 - i] ? "failure" : "healthy";
return (
<Bar
key={i}
isFirst={i === 0}
isLast={i === 89}
status={status}
/>
);
})}
</StatusBars>
<Spacer y={0.25} />
</React.Fragment>
);
})}
</Expandable>
</>
);
}


export default ClusterStatusSection;

const getBackgroundGradient = (status: string): string => {
switch (status) {
case "healthy":
return "linear-gradient(#01a05d, #0f2527)";
case "failure":
return "linear-gradient(#E1322E, #25100f)";
case "partial_failure":
return "linear-gradient(#E49621, #25270f)";
default:
return "linear-gradient(#76767644, #76767622)"; // Default or unknown status
}
}

const Badge = styled.div`
background: ${(props) => props.theme.clickable.bg};
padding: 5px 10px;
border: 1px solid ${(props) => props.theme.border};
border-radius: 5px;
font-size: 13px;
`;

const Letter = styled.div`
height: 100%;
width: 100%;
position: absolute;
padding-bottom: 2px;
font-weight: 500;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
`;

const ProjectImage = styled.img`
width: 100%;
height: 100%;
`;

const ProjectIcon = styled.div`
width: 26px;
min-width: 26px;
height: 26px;
border-radius: 3px;
overflow: hidden;
position: relative;
margin-right: 10px;
font-weight: 400;
`;

const Bar = styled.div<{ isFirst: boolean; isLast: boolean; status: string }>`
height: 20px;
display: flex;
flex: 1;
border-top-left-radius: ${(props) => (props.isFirst ? "5px" : "0")};
border-bottom-left-radius: ${(props) => (props.isFirst ? "5px" : "0")};
border-top-right-radius: ${(props) => (props.isLast ? "5px" : "0")};
border-bottom-right-radius: ${(props) => (props.isLast ? "5px" : "0")};
background: ${(props) => getBackgroundGradient(props.status)};
`;

const StatusBars = styled.div`
width: 100%;
display: flex;
justify-content: space-between;
gap: 2px;
`;

const StyledStatusPage = styled.div`
width: 100vw;
height: 100vh;
overflow: auto;
padding-top: 50px;
display: flex;
align-items: center;
flex-direction: column;
`;

const StatusSection = styled.div`
width: calc(100% - 40px);
padding-bottom: 50px;
max-width: 1000px;
`;
154 changes: 154 additions & 0 deletions dashboard/src/main/status/ProjectStatusSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import React, { useContext, useEffect, useState } from "react";

import { ProjectListType, ClusterType } from "shared/types";

import styled from "styled-components";
import Container from "components/porter/Container";
import Expandable from "components/porter/Expandable";
import Image from "components/porter/Image";
import Spacer from "components/porter/Spacer";
import logo from "assets/logo.png";

import Back from "components/porter/Back";
import Text from "components/porter/Text";
import { Context } from "shared/Context";

import midnight from "shared/themes/midnight";
import gradient from "assets/gradient.png";

import api from "shared/api";

import ClusterStatusSection from "./ClusterStatusSection";

type Props = { project: ProjectListType };

const ProjectStatusSection: React.FC<Props> = ({ project }) => {
const [clusters, setClusters] = useState<ClusterType[]>([]);

useEffect(() => {
if (!project || !project.id) {
console.log("project undefined")
return;
}
api.
getClusters(
"<token>",
{},
{ id: project.id },
)
.then((res) => res.data as ClusterType[])
.then((clustersList) => {
console.log(clustersList);
setClusters(clustersList);
})
.catch((err) => {
console.log(err);
});
}, [project]);

return (
<>
<Expandable
key={project.id}
alt
header={
<Container row>
<Text size={16}> {project.name} </Text>
<Spacer x={1} inline />
<Text color="#01a05d">Operational</Text>
</Container>
}
>
{clusters.map((cluster, _) => (
<>
<Spacer y={0.25} />
<Container row spaced>
<Text color="helper">{cluster.name}</Text>
<Text color="#01a05d">Operational</Text>
</Container>
<Spacer y={0.25} />
<StatusBars>
{Array.from({ length: 90 }).map((_, i) => (
<Bar key={i} isFirst={i === 0} isLast={i === 89} />
))}
</StatusBars>
<Spacer y={0.5} />
</>
))}
</Expandable>
</>
);
}

export default ProjectStatusSection;

const Badge = styled.div`
background: ${(props) => props.theme.clickable.bg};
padding: 5px 10px;
border: 1px solid ${(props) => props.theme.border};
border-radius: 5px;
font-size: 13px;
`;

const Letter = styled.div`
height: 100%;
width: 100%;
position: absolute;
padding-bottom: 2px;
font-weight: 500;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
`;

const ProjectImage = styled.img`
width: 100%;
height: 100%;
`;

const ProjectIcon = styled.div`
width: 26px;
min-width: 26px;
height: 26px;
border-radius: 3px;
overflow: hidden;
position: relative;
margin-right: 10px;
font-weight: 400;
`;

const Bar = styled.div<{ isFirst: boolean; isLast: boolean }>`
height: 20px;
display: flex;
flex: 1;
border-top-left-radius: ${(props) => (props.isFirst ? "5px" : "0")};
border-bottom-left-radius: ${(props) => (props.isFirst ? "5px" : "0")};
border-top-right-radius: ${(props) => (props.isLast ? "5px" : "0")};
border-bottom-right-radius: ${(props) => (props.isLast ? "5px" : "0")};
background: linear-gradient(#01a05d, #0f2527);
`;

const StatusBars = styled.div`
width: 100%;
display: flex;
justify-content: space-between;
gap: 2px;
`;

const StyledStatusPage = styled.div`
width: 100vw;
height: 100vh;
overflow: auto;
padding-top: 50px;
display: flex;
align-items: center;
flex-direction: column;
`;

const StatusSection = styled.div`
width: calc(100% - 40px);
padding-bottom: 50px;
max-width: 1000px;
`;
Loading

0 comments on commit 90cf429

Please sign in to comment.