Skip to content
Snippets Groups Projects
Commit 7427dc4e authored by John Sparger's avatar John Sparger
Browse files

Deployment details gives live feedback. IOC Deploy button redirects to deployment page

parent 36c3ae02
No related branches found
No related tags found
2 merge requests!25IOCListView now has tabs to prefilter on all or currentUsers IOCs. The currentUser is hardcoded,!18Merge current UI state
Pipeline #67355 failed
......@@ -160,6 +160,16 @@ export function useDeployment(id) {
return useAsync({ fcn: method.bind(null, { deploymentId: id }) });
}
export function unpackDeploymentJob(job) {
return {...job};
}
export function useDeploymentJob(awxJobId) {
const api = useContext(apiContext);
const method = callAndUnpack(api.apis.Deployments.fetchDeploymentJobDetails, unpackDeploymentJob)
return useAsync({ fcn: method.bind(null, { awxJobId: awxJobId }) });
}
export function useCreateDeployment() {
const api = useContext(apiContext);
const method = callAndUnpack(
......
import { Box, Button, Container, Fab, IconButton, useTheme } from "@material-ui/core";
import { DirectionsBoat, Edit } from "@material-ui/icons";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { useGlobalAppBar } from "../../components/navigation/GlobalAppBar/GlobalAppBar";
import { IOCDetails } from "../../components/IOC/IOCDetails";
import { CreateIOC } from "../../components/IOC/CreateIOC";
......@@ -13,7 +13,7 @@ export function IOCConfiguration({ ioc, getIOC }) {
const [iocFormOpen, setIOCFormOpen] = useState(false);
const [deployment, createDeployment] = useCreateDeployment();
const theme = useTheme();
// const history = useHistory()
const history = useHistory()
console.log(deployment);
useGlobalAppBar(
......@@ -29,6 +29,10 @@ export function IOCConfiguration({ ioc, getIOC }) {
// history.push(window.location.pathname);
}
useEffect(() => {
if (deployment) history.push(`/deployments/${deployment[0].id}`);
}, [deployment]);
let content = <></>;
if (ioc) {
const getSubset = ({ name, description, host, active, status }) => ({ name, description, host, active, status });
......
import React from "react";
import { SimpleAccordion } from "../common/Accordion/StandardAccordion";
import { SimpleAccordion } from "../common/Accordion/SimpleAccordion";
import { KeyValueTable } from "../common/KeyValueTable/KeyValueTable";
import { IOCBadge } from "./IOCBadge";
......
import React from 'react';
import { TextField, Grid, Typography, Box, Button, Card, CardContent, CardActions} from '@material-ui/core';
import React, { useEffect } from 'react';
import { TextField, Grid, Typography, Box, Button, Card, CardContent, CardActions } from '@material-ui/core';
import { makeStyles, createMuiTheme } from '@material-ui/core/styles';
import {deploymentStatusColors} from "./DeploymentsTable"
import {DeploymentStepper} from "./DeploymentStepper"
import { deploymentStatusColors } from "./DeploymentsTable"
import { DeploymentStepper } from "./DeploymentStepper"
import { KeyValueTable } from "../common/KeyValueTable/KeyValueTable";
import { SimpleAccordion } from "../common/Accordion/StandardAccordion";
import { SimpleAccordion } from "../common/Accordion/SimpleAccordion";
import { useDeploymentJob } from '../../api/SwaggerApi';
import { DeploymentBadge } from './DeploymentBadge';
const useStyles = makeStyles({
root: {
......@@ -16,74 +18,62 @@ const useStyles = makeStyles({
});
export function DeploymentDetails({ deployment, onDeploymentStart, startButtonDisabled }) {
const jobDetails = {...deployment.jobDetails};
deployment = {...deployment.deployment};
const [deploymentJob, getDeploymentJob] = useDeploymentJob(deployment.awxJobId);
deployment.status = deploymentJob?.job.status ?? deployment.status;
console.log(deployment.status);
console.log(deploymentJob);
useEffect(() => {
if (deploymentJob && !(["successful", "failed"].includes(deploymentJob.job.status))) {
console.log(deploymentJob.job.status);
setTimeout(getDeploymentJob, 5000);
}
}, [deploymentJob]);
const deploymentDetails = {
version: deployment.version.sourceVersion,
host: deployment.host.host,
repository: deployment.version.sourceUrl,
startTime: deployment.startDate.toLocaleString(),
duration: deployment.duration + ' s',
};
version: deployment.version.sourceVersion,
host: deployment.host.host,
repository: deployment.version.sourceUrl,
startTime: deploymentJob?.job.started,
duration: (new Date(deploymentJob?.job.finished ?? Date()) - new Date(deploymentJob?.job.started ?? Date())) / 1000 + " s"
}
const theme = createMuiTheme();
const classes = useStyles(theme);
return (
<Grid container spacing={1}>
<Grid item xs={12} md={12}>
<SimpleAccordion summary={
<Grid container spacing={1}>
<Grid item xs={12} md={10}>
<Typography variant="h4" component="h3" color="textPrimary" gutterBottom>
{deployment.iocName}
</Typography>
</Grid>
{ deployment.status !== "initialized" &&
<Grid item xs={6} md={2}>
<Box bgcolor={deploymentStatusColors[deployment.status]}
color="primary.contrastText" p={2} borderRadius={10}>
<Grid container justify="center">
<Typography variant="body2" component="p">
{deployment.status.toUpperCase()}
</Typography>
</Grid>
</Box>
</Grid>
}
</Grid>
}>
<KeyValueTable obj={deploymentDetails} variant="overline" />
</SimpleAccordion>
</Grid>
<Grid item xs={12} md={12}>
<Card className={classes.root}>
<CardContent>
<div className={classes.stepperContainer}>
<DeploymentStepper activeStep={deployment.activeStep} deploymentStatus={deployment.status}/>
</div>
</CardContent>
{ deployment.manual &&
<Grid container spacing={1}>
<Grid item xs={12} md={12}>
<SimpleAccordion defaultExpanded summary={<DeploymentBadge deployment={deployment} />}>
<KeyValueTable obj={deploymentDetails} variant="overline" />
</SimpleAccordion>
</Grid>
<Grid item xs={12} md={12}>
<Card className={classes.root}>
<CardContent>
<div className={classes.stepperContainer}>
<DeploymentStepper activeStep={["created", "scheduled", "running", "successful"].indexOf(deploymentJob?.job.status)} deploymentStatus={deploymentJob?.job.status} />
</div>
</CardContent>
{deployment.manual &&
<CardActions className={classes.actions}>
<Button variant="contained" color="primary" onClick={onDeploymentStart} disabled={startButtonDisabled}>
Start deployment
</Button>
</CardActions>
}
</Card>
</Grid>
<Grid item xs={12} md={12}>
<SimpleAccordion summary="Deployment steps" defaultExpanded>
{/* <TextField style={{ marginTop: "20px", width: "100%" }}
id="outlined-multiline-static"
multiline
disabled
rows={10}
value={deployment.output.replaceAll(";", "\n")}
// variant="outlined"
/> */}
</SimpleAccordion>
</Grid>
}
</Card>
</Grid>
<Grid item xs={12} md={12}>
<SimpleAccordion summary="Deployment steps" defaultExpanded>
<DeploymentJobStdOut deploymentJob={deploymentJob} />
</SimpleAccordion>
</Grid>
</Grid>
);
}
export function DeploymentJobStdOut({ deploymentJob }) {
return deploymentJob ? <iframe srcDoc={deploymentJob.stdout} width="100%" height="500px" /> : "Fetching job details";
}
......@@ -6,18 +6,25 @@ export function DeploymentStatusIcon({ deployment }) {
const deploymentStatusIcons = {
"success": <CheckCircleOutline />,
"successful": <CheckCircleOutline />,
"failed": <ErrorOutline />,
"running": <RotateRightOutlined />,
"scheduled": <ScheduleOutlined />,
"created": <ScheduleOutlined />,
"pending": <ScheduleOutlined />,
}
const deploymentStatusColors = {
"success": theme.palette.status.ok,
"successful": theme.palette.status.ok,
"failed": theme.palette.status.fail,
"running": theme.palette.status.progress,
"scheduled": theme.palette.status.neutral,
"pending": theme.palette.status.neutral,
"created": theme.palette.status.neutral,
}
console.log(deployment);
const iconStyle = { fill: deploymentStatusColors[deployment.status] };
const icon = React.cloneElement(deploymentStatusIcons[deployment.status], { style: iconStyle });
......
......@@ -40,7 +40,7 @@ const useColorlibStepIconStyles = makeStyles({
},
});
const steps = ['Checking user permissions', 'Checking target host', 'Starting Ansible playbook', 'Deployment completed'];
const steps = ['Creating Deployment', 'Deployment Queued ', 'Running Deployment', 'Deployment Completed'];
const ColorlibConnectorHorizontal = withStyles({
alternativeLabel: {
......@@ -128,7 +128,7 @@ ColorlibStepIcon.propTypes = {
export function DeploymentStepper(props) {
const classes = useStyles(theme);
const {activeStep, deploymentStatus} = props;
let {activeStep, deploymentStatus} = props;
const isStepFailed = (step) => {
if (deploymentStatus === "failed") {
return step === activeStep;
......@@ -136,6 +136,10 @@ export function DeploymentStepper(props) {
return false;
};
console.log(activeStep);
activeStep = activeStep<1 ? 1 : activeStep;
activeStep = activeStep===3 ? 4 : activeStep;
return (
<>
<Hidden smUp>
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment