Skip to content

Commit 41b79d0

Browse files
committed
feat: Redesign build logs
1 parent c41bdc2 commit 41b79d0

File tree

7 files changed

+310
-108
lines changed

7 files changed

+310
-108
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import Avatar from "@material-ui/core/Avatar"
2+
import Badge from "@material-ui/core/Badge"
3+
import { Theme, useTheme, withStyles } from "@material-ui/core/styles"
4+
import { FC } from "react"
5+
import PlayArrowOutlined from "@material-ui/icons/PlayArrowOutlined"
6+
import PauseOutlined from "@material-ui/icons/PauseOutlined"
7+
import DeleteOutlined from "@material-ui/icons/DeleteOutlined"
8+
import { WorkspaceBuild, WorkspaceTransition } from "api/typesGenerated"
9+
import { getDisplayWorkspaceBuildStatus } from "util/workspace"
10+
import { PaletteIndex } from "theme/palettes"
11+
12+
interface StylesBadgeProps {
13+
type: PaletteIndex
14+
}
15+
16+
const StyledBadge = withStyles((theme) => ({
17+
badge: {
18+
backgroundColor: ({ type }: StylesBadgeProps) => theme.palette[type].light,
19+
borderRadius: "100%",
20+
width: 8,
21+
minWidth: 8,
22+
height: 8,
23+
display: "block",
24+
padding: 0,
25+
},
26+
}))(Badge)
27+
28+
const StyledAvatar = withStyles((theme) => ({
29+
root: {
30+
background: theme.palette.background.paperLight,
31+
color: theme.palette.text.primary,
32+
border: `2px solid ${theme.palette.divider}`,
33+
34+
"& svg": {
35+
width: 24,
36+
height: 24,
37+
},
38+
},
39+
}))(Avatar)
40+
41+
export type BuildAvatarProps = {
42+
build: WorkspaceBuild
43+
}
44+
45+
const iconByTransition: Record<WorkspaceTransition, JSX.Element> = {
46+
start: <PlayArrowOutlined />,
47+
stop: <PauseOutlined />,
48+
delete: <DeleteOutlined />,
49+
}
50+
51+
export const BuildAvatar: FC<BuildAvatarProps> = ({ build }) => {
52+
const theme = useTheme<Theme>()
53+
const displayBuildStatus = getDisplayWorkspaceBuildStatus(theme, build)
54+
55+
return (
56+
<StyledBadge
57+
role="status"
58+
type={displayBuildStatus.type}
59+
arial-label={displayBuildStatus.status}
60+
title={displayBuildStatus.status}
61+
overlap="circular"
62+
anchorOrigin={{
63+
vertical: "bottom",
64+
horizontal: "right",
65+
}}
66+
badgeContent={<div></div>}
67+
>
68+
<StyledAvatar>{iconByTransition[build.transition]}</StyledAvatar>
69+
</StyledBadge>
70+
)
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { makeStyles } from "@material-ui/core/styles"
2+
import TableCell from "@material-ui/core/TableCell"
3+
import TableRow from "@material-ui/core/TableRow"
4+
import formatRelative from "date-fns/formatRelative"
5+
6+
export interface BuildDateRow {
7+
date: Date
8+
}
9+
10+
export const BuildDateRow: React.FC<BuildDateRow> = ({ date }) => {
11+
const styles = useStyles()
12+
// We only want the message related to the date since the time is displayed
13+
// inside of the build row
14+
const displayDate = formatRelative(date, new Date()).split("at")[0]
15+
16+
return (
17+
<TableRow className={styles.buildDateRow}>
18+
<TableCell
19+
className={styles.buildDateCell}
20+
title={date.toLocaleDateString()}
21+
>
22+
{displayDate}
23+
</TableCell>
24+
</TableRow>
25+
)
26+
}
27+
28+
const useStyles = makeStyles((theme) => ({
29+
buildDateRow: {
30+
background: theme.palette.background.paper,
31+
32+
"&:not(:first-child) td": {
33+
borderTop: `1px solid ${theme.palette.divider}`,
34+
},
35+
},
36+
37+
buildDateCell: {
38+
padding: `${theme.spacing(1, 4)} !important`,
39+
background: `${theme.palette.background.paperLight} !important`,
40+
fontSize: 12,
41+
position: "relative",
42+
color: theme.palette.text.secondary,
43+
textTransform: "capitalize",
44+
},
45+
}))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { makeStyles } from "@material-ui/core/styles"
2+
import TableCell from "@material-ui/core/TableCell"
3+
import TableRow from "@material-ui/core/TableRow"
4+
import { WorkspaceBuild } from "api/typesGenerated"
5+
import { Stack } from "components/Stack/Stack"
6+
import { useTranslation } from "react-i18next"
7+
import { MONOSPACE_FONT_FAMILY } from "theme/constants"
8+
import {
9+
displayWorkspaceBuildDuration,
10+
getDisplayWorkspaceBuildInitiatedBy,
11+
} from "util/workspace"
12+
import { BuildAvatar } from "./BuildAvatar"
13+
14+
export interface BuildRowProps {
15+
build: WorkspaceBuild
16+
}
17+
18+
export const BuildRow: React.FC<BuildRowProps> = ({ build }) => {
19+
const styles = useStyles()
20+
const { t } = useTranslation("workspacePage")
21+
const initiatedBy = getDisplayWorkspaceBuildInitiatedBy(build)
22+
23+
return (
24+
<TableRow
25+
hover
26+
key={build.id}
27+
data-testid={`build-${build.id}`}
28+
className={styles.buildRow}
29+
>
30+
<TableCell className={styles.buildCell}>
31+
<Stack
32+
direction="row"
33+
alignItems="center"
34+
className={styles.buildRow}
35+
tabIndex={0}
36+
>
37+
<Stack
38+
direction="row"
39+
alignItems="center"
40+
justifyContent="space-between"
41+
className={styles.buildRowMain}
42+
>
43+
<Stack direction="row" alignItems="center">
44+
<BuildAvatar build={build} />
45+
<div>
46+
<Stack
47+
className={styles.buildResume}
48+
direction="row"
49+
alignItems="center"
50+
spacing={1}
51+
>
52+
<span>
53+
<strong>{initiatedBy}</strong>{" "}
54+
{build.reason !== "initiator" ? "automatically " : " "}
55+
<strong>
56+
{t(`buildTransitionMessage.${build.transition}`)}
57+
</strong>{" "}
58+
the workspace
59+
</span>
60+
61+
<span className={styles.buildTime}>
62+
{new Date(build.created_at).toLocaleTimeString()}
63+
</span>
64+
</Stack>
65+
66+
<Stack direction="row" spacing={1}>
67+
<span className={styles.buildInfo}>
68+
Reason: <strong>{build.reason}</strong>
69+
</span>
70+
71+
<span className={styles.buildInfo}>
72+
Duration:{" "}
73+
<strong>{displayWorkspaceBuildDuration(build)}</strong>
74+
</span>
75+
</Stack>
76+
</div>
77+
</Stack>
78+
</Stack>
79+
</Stack>
80+
</TableCell>
81+
</TableRow>
82+
)
83+
}
84+
85+
const useStyles = makeStyles((theme) => ({
86+
buildRow: {
87+
padding: theme.spacing(2, 4),
88+
cursor: "pointer",
89+
90+
"&:not(:last-child) td:before": {
91+
position: "absolute",
92+
top: 20,
93+
left: 50,
94+
display: "block",
95+
content: "''",
96+
height: "100%",
97+
width: 2,
98+
background: theme.palette.divider,
99+
},
100+
},
101+
102+
buildCell: {
103+
padding: "0 !important",
104+
position: "relative",
105+
borderBottom: 0,
106+
},
107+
108+
buildRowMain: {
109+
flex: 1,
110+
},
111+
112+
buildResume: {
113+
...theme.typography.body1,
114+
fontFamily: "inherit",
115+
},
116+
117+
buildInfo: {
118+
...theme.typography.body2,
119+
fontSize: 12,
120+
fontFamily: "inherit",
121+
color: theme.palette.text.secondary,
122+
display: "block",
123+
},
124+
125+
buildTime: {
126+
color: theme.palette.text.secondary,
127+
fontSize: 12,
128+
},
129+
130+
buildRight: {
131+
width: "auto",
132+
},
133+
134+
buildExtraInfo: {
135+
...theme.typography.body2,
136+
fontFamily: MONOSPACE_FONT_FAMILY,
137+
color: theme.palette.text.secondary,
138+
whiteSpace: "nowrap",
139+
},
140+
}))

0 commit comments

Comments
 (0)