2021-05-09 15:29:11 +08:00
|
|
|
import { useQuery } from '@apollo/client';
|
2021-05-09 16:42:19 +08:00
|
|
|
import { Link, useResponse } from '@curi/react-dom';
|
2021-05-09 15:29:11 +08:00
|
|
|
import { faPlayCircle, faVial } from '@fortawesome/free-solid-svg-icons';
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
|
|
import { CircularProgress, Collapse, IconButton, LinearProgress, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, makeStyles, useTheme } from '@material-ui/core';
|
|
|
|
import { Cancel, CheckCircle, CloudDownload, ShoppingCart, Timer } from '@material-ui/icons';
|
|
|
|
import { format } from 'date-fns';
|
|
|
|
import React, { FC, Fragment, ReactNode, useState } from 'react';
|
|
|
|
import { Commit, Pipeline, PipelineTask, TaskStatuses } from '../generated/graphql';
|
|
|
|
import { COMMITS } from './queries';
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
pipeline: Pipeline;
|
|
|
|
}
|
|
|
|
|
|
|
|
const useStyles = makeStyles((theme) => ({
|
|
|
|
root: {
|
|
|
|
flex: "1 1 100%",
|
|
|
|
},
|
|
|
|
nested: {
|
|
|
|
paddingLeft: theme.spacing(4),
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
|
|
|
export const CommitList: FC<Props> = ({pipeline}) => {
|
|
|
|
const { data, loading } = useQuery<{ commits: Commit[] }>(COMMITS, {
|
|
|
|
variables: {
|
|
|
|
pipelineId: pipeline.id,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
const classes = useStyles();
|
|
|
|
|
|
|
|
return (
|
|
|
|
<section className={classes.root}>
|
|
|
|
{(() => {
|
|
|
|
if (loading) {
|
|
|
|
return <LinearProgress color="secondary" />;
|
|
|
|
}
|
|
|
|
|
2021-05-09 16:42:19 +08:00
|
|
|
return (
|
|
|
|
<List>
|
|
|
|
{data?.commits.map((commit) => (
|
|
|
|
<Item key={commit.hash} commit={commit} />
|
|
|
|
))}
|
|
|
|
</List>
|
|
|
|
);
|
2021-05-09 15:29:11 +08:00
|
|
|
})()}
|
|
|
|
</section>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const Item: FC<{commit: Commit}> = ({commit}) => {
|
|
|
|
const [isOpen, setOpen] = useState(() => false);
|
|
|
|
const classes = useStyles();
|
2021-05-09 16:42:19 +08:00
|
|
|
|
|
|
|
const {response} = useResponse();
|
2021-05-09 15:29:11 +08:00
|
|
|
return (
|
|
|
|
<Fragment>
|
|
|
|
<ListItem button onClick={() => setOpen(!isOpen)}>
|
|
|
|
<ListItemText
|
|
|
|
primary={commit.message}
|
|
|
|
secondary={format(commit.date, "yyyy-MM-dd HH:mm:ss")}
|
|
|
|
/>
|
|
|
|
<ListItemSecondaryAction>
|
|
|
|
<IconButton edge="end" aria-label="delete">
|
|
|
|
<ShoppingCart />
|
|
|
|
</IconButton>
|
|
|
|
<IconButton edge="end" aria-label="delete">
|
|
|
|
<CloudDownload />
|
|
|
|
</IconButton>
|
|
|
|
<IconButton edge="end" aria-label="delete">
|
|
|
|
<FontAwesomeIcon icon={faVial} />
|
|
|
|
</IconButton>
|
|
|
|
<IconButton edge="end" aria-label="delete">
|
|
|
|
<FontAwesomeIcon icon={faPlayCircle} />
|
|
|
|
</IconButton>
|
|
|
|
</ListItemSecondaryAction>
|
|
|
|
</ListItem>
|
|
|
|
<Collapse in={isOpen} timeout="auto" unmountOnExit>
|
|
|
|
<List component="div" disablePadding>
|
2021-05-09 16:42:19 +08:00
|
|
|
{commit.tasks.map((task) => (
|
|
|
|
<Link
|
|
|
|
key={task.id}
|
|
|
|
name="pipeline-task-detail"
|
|
|
|
params={{ ...response.params, taskId: task.id }}
|
|
|
|
>
|
|
|
|
<TaskItem task={task} />
|
|
|
|
</Link>
|
|
|
|
))}
|
2021-05-09 15:29:11 +08:00
|
|
|
</List>
|
|
|
|
</Collapse>
|
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TaskItem: FC<{task: PipelineTask}> = ({task}) => {
|
|
|
|
const classes = useStyles();
|
|
|
|
const theme = useTheme();
|
|
|
|
const statusIcon: ReactNode = (() => {
|
|
|
|
switch (task.status) {
|
|
|
|
case TaskStatuses.Pending:
|
|
|
|
return <Timer style={{ color: theme.palette.info.main }} />;
|
|
|
|
case TaskStatuses.Success:
|
|
|
|
return <CheckCircle style={{ color: theme.palette.success.main }} />;
|
|
|
|
case TaskStatuses.Failed:
|
|
|
|
return <Cancel style={{ color: theme.palette.error.main }} />;
|
|
|
|
case TaskStatuses.Working:
|
|
|
|
return <CircularProgress style={{ color: theme.palette.secondary.main }} />;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)()
|
|
|
|
return (
|
|
|
|
<ListItem button className={classes.nested}>
|
|
|
|
<ListItemIcon>{statusIcon}</ListItemIcon>
|
|
|
|
<ListItemText primary={format(task.startedAt, "yyyy-MM-dd HH:mm:ss")} />
|
|
|
|
</ListItem>
|
|
|
|
);
|
|
|
|
};
|