frontend/app/mainpage.tsx (199 lines of code) (raw):

import React, { useEffect, useState } from "react"; import { RouteComponentProps } from "react-router"; import axios from "axios"; import { Button, Chip, Grid, makeStyles, Link, Typography, } from "@material-ui/core"; import Generalinfocell from "./buildsinfocell"; import DeploymentStatusIcon from "./deploymentstatusicon"; import DockerImageName from "./dockerimagename"; import { SystemNotification, SystemNotifcationKind, } from "@guardian/pluto-headers"; import { Cached, ChevronRight } from "@material-ui/icons"; import { Link as RouterLink } from "react-router-dom"; const useStyles = makeStyles((theme) => ({ infoGrid: { marginLeft: "auto", marginRight: "auto", maxWidth: "90%", minWidth: "20%", width: "fit-content", }, gridRow: { width: "fit-content", borderColor: theme.palette.common.white, borderWidth: "2px", borderRadius: "10px", borderStyle: "solid", marginBottom: "0.2em", padding: "0.6em", }, infoCell: { width: "400px", borderWidth: "2px", borderRightStyle: "solid", }, deployedVersionCell: { width: "400px", overflowWrap: "break-word", paddingLeft: "0.6em", paddingRight: "0.6em", borderWidth: "2px", borderRightStyle: "solid", }, buildsInfoCell: { width: "400px", overflowWrap: "break-word", paddingLeft: "0.6em", paddingRight: "0.6em", }, inlineText: { display: "inline", marginRight: "1em", }, deploymentLabel: { marginRight: "1em", marginTop: "1em", }, cellTitle: { fontWeight: "bold", fontSize: "1.3em", textAlign: "center", }, })); const MainPage: React.FC<RouteComponentProps> = (props) => { const [deployments, setDeployments] = useState<DeployedImageInfo[]>([]); const classes = useStyles(); const refresh = async () => { try { const response = await axios.get<DeployedImageInfo[]>( "/api/known_deployments" ); switch (response.status) { case 200: setDeployments( response.data.filter( (info) => info.labels.hasOwnProperty("gitlab-project-id") || (info.labels.hasOwnProperty("github-project-name") && info.labels.hasOwnProperty("github-org")) ) ); break; default: console.error(`server returned ${response.status}`); SystemNotification.open( SystemNotifcationKind.Error, `Could not load deployments from cluster: server returned ${response.status}` ); break; } } catch (e) { console.error("Could not load deployments: ", e); SystemNotification.open( SystemNotifcationKind.Error, `Could not load deployments from cluster: ${e}` ); } }; useEffect(() => { refresh(); }, []); /** * when an update is performed, then refresh the view after 1 second */ const onUpdateInitiated = () => { console.log("update was initiated, scheduling refresh"); window.setTimeout(() => refresh(), 1000); }; return ( <> <Grid container justify="space-between" alignItems="center" style={{ marginRight: "1em" }} > <Grid item> <Typography variant="h2">Pluto Versions Manager</Typography> </Grid> <Grid item> <Button variant="outlined" startIcon={<Cached />} onClick={refresh}> Refresh </Button> </Grid> </Grid> <Grid container className={classes.infoGrid} direction="column"> {deployments.map((info, idx) => ( <Grid item container direction="row" key={idx} className={classes.gridRow} > <Grid item className={classes.infoCell}> <Typography variant="h4" className={classes.inlineText}> {info.deploymentName} </Typography> <Typography className={classes.inlineText}> {info.namespace} </Typography> <br /> <Typography> {info.readyReplicas} ready and {info.notReadyReplicas} not ready {info.readyReplicas && info.notReadyReplicas ? ( <DeploymentStatusIcon availableReplicas={info.readyReplicas} notAvailableReplicas={info.notReadyReplicas} /> ) : null} </Typography> {Object.keys(info.labels).map((labelName) => ( <Chip key={labelName} label={`${labelName}: ${info.labels[labelName]}`} className={classes.deploymentLabel} /> ))} </Grid> <Grid item className={classes.deployedVersionCell}> <Typography className={classes.cellTitle}> Currently running </Typography> <ul> {info.deployedImages.map((imageInfo, idx) => ( <li key={idx}> <DockerImageName image={imageInfo} /> </li> ))} </ul> </Grid> <Grid item className={classes.buildsInfoCell}> <Generalinfocell deploymentInfo={info} onUpdateInitiated={onUpdateInitiated} /> <Button component={RouterLink} to={`/${info.deploymentName}/branches`} variant="outlined" endIcon={<ChevronRight />} style={{ display: "flex", marginLeft: "auto", marginRight: "auto", marginTop: "1em", }} > Other branches </Button> </Grid> </Grid> ))} </Grid> </> ); }; export { useStyles }; export default MainPage;