fennec-fe/src/commits/commit-list.tsx

120 lines
3.6 KiB
TypeScript
Raw Normal View History

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>
);
};