-
Notifications
You must be signed in to change notification settings - Fork 894
feat: Redesign build logs #4734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
41b79d0
7e97461
24ccec4
6dc9cd2
19eb0cb
ef080c3
a9a7baf
6cd9659
b947be1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import Avatar from "@material-ui/core/Avatar" | ||
import Badge from "@material-ui/core/Badge" | ||
import { Theme, useTheme, withStyles } from "@material-ui/core/styles" | ||
import { FC } from "react" | ||
import PlayArrowOutlined from "@material-ui/icons/PlayArrowOutlined" | ||
import PauseOutlined from "@material-ui/icons/PauseOutlined" | ||
import DeleteOutlined from "@material-ui/icons/DeleteOutlined" | ||
import { WorkspaceBuild, WorkspaceTransition } from "api/typesGenerated" | ||
import { getDisplayWorkspaceBuildStatus } from "util/workspace" | ||
import { PaletteIndex } from "theme/palettes" | ||
|
||
interface StylesBadgeProps { | ||
type: PaletteIndex | ||
} | ||
|
||
const StyledBadge = withStyles((theme) => ({ | ||
badge: { | ||
backgroundColor: ({ type }: StylesBadgeProps) => theme.palette[type].light, | ||
borderRadius: "100%", | ||
width: 8, | ||
minWidth: 8, | ||
height: 8, | ||
display: "block", | ||
padding: 0, | ||
}, | ||
}))(Badge) | ||
|
||
const StyledAvatar = withStyles((theme) => ({ | ||
root: { | ||
background: theme.palette.background.paperLight, | ||
color: theme.palette.text.primary, | ||
border: `2px solid ${theme.palette.divider}`, | ||
|
||
"& svg": { | ||
width: 24, | ||
height: 24, | ||
}, | ||
}, | ||
}))(Avatar) | ||
|
||
export type BuildAvatarProps = { | ||
build: WorkspaceBuild | ||
} | ||
|
||
const iconByTransition: Record<WorkspaceTransition, JSX.Element> = { | ||
start: <PlayArrowOutlined />, | ||
stop: <PauseOutlined />, | ||
delete: <DeleteOutlined />, | ||
} | ||
|
||
export const BuildAvatar: FC<BuildAvatarProps> = ({ build }) => { | ||
const theme = useTheme<Theme>() | ||
const displayBuildStatus = getDisplayWorkspaceBuildStatus(theme, build) | ||
|
||
return ( | ||
<StyledBadge | ||
role="status" | ||
type={displayBuildStatus.type} | ||
arial-label={displayBuildStatus.status} | ||
title={displayBuildStatus.status} | ||
overlap="circular" | ||
anchorOrigin={{ | ||
vertical: "bottom", | ||
horizontal: "right", | ||
}} | ||
badgeContent={<div></div>} | ||
> | ||
<StyledAvatar>{iconByTransition[build.transition]}</StyledAvatar> | ||
</StyledBadge> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { makeStyles } from "@material-ui/core/styles" | ||
import TableCell from "@material-ui/core/TableCell" | ||
import TableRow from "@material-ui/core/TableRow" | ||
import formatRelative from "date-fns/formatRelative" | ||
|
||
export interface BuildDateRow { | ||
date: Date | ||
} | ||
|
||
export const BuildDateRow: React.FC<BuildDateRow> = ({ date }) => { | ||
BrunoQuaresma marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const styles = useStyles() | ||
// We only want the message related to the date since the time is displayed | ||
// inside of the build row | ||
const displayDate = formatRelative(date, new Date()).split("at")[0] | ||
|
||
return ( | ||
<TableRow className={styles.buildDateRow}> | ||
<TableCell | ||
className={styles.buildDateCell} | ||
title={date.toLocaleDateString()} | ||
> | ||
{displayDate} | ||
</TableCell> | ||
</TableRow> | ||
) | ||
} | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
buildDateRow: { | ||
background: theme.palette.background.paper, | ||
|
||
"&:not(:first-child) td": { | ||
borderTop: `1px solid ${theme.palette.divider}`, | ||
}, | ||
}, | ||
|
||
buildDateCell: { | ||
padding: `${theme.spacing(1, 4)} !important`, | ||
background: `${theme.palette.background.paperLight} !important`, | ||
fontSize: 12, | ||
position: "relative", | ||
color: theme.palette.text.secondary, | ||
textTransform: "capitalize", | ||
}, | ||
})) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import { makeStyles } from "@material-ui/core/styles" | ||
import TableCell from "@material-ui/core/TableCell" | ||
import TableRow from "@material-ui/core/TableRow" | ||
import { WorkspaceBuild } from "api/typesGenerated" | ||
import { Stack } from "components/Stack/Stack" | ||
import { useTranslation } from "react-i18next" | ||
import { MONOSPACE_FONT_FAMILY } from "theme/constants" | ||
import { | ||
displayWorkspaceBuildDuration, | ||
getDisplayWorkspaceBuildInitiatedBy, | ||
} from "util/workspace" | ||
import { BuildAvatar } from "./BuildAvatar" | ||
|
||
export interface BuildRowProps { | ||
build: WorkspaceBuild | ||
} | ||
|
||
export const BuildRow: React.FC<BuildRowProps> = ({ build }) => { | ||
const styles = useStyles() | ||
const { t } = useTranslation("workspacePage") | ||
const initiatedBy = getDisplayWorkspaceBuildInitiatedBy(build) | ||
|
||
return ( | ||
<TableRow | ||
hover | ||
key={build.id} | ||
data-testid={`build-${build.id}`} | ||
className={styles.buildRow} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is such a nice, tabbable table! I would love to be able to hit 'enter' and navigate to the log page without having to touch my mouse. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was watching TV when I "remembered" that I forgot to add the link 😆 I'm glad you found it as well, really good review 🌮 |
||
> | ||
<TableCell className={styles.buildCell}> | ||
<Stack | ||
direction="row" | ||
alignItems="center" | ||
className={styles.buildRow} | ||
tabIndex={0} | ||
> | ||
<Stack | ||
direction="row" | ||
alignItems="center" | ||
justifyContent="space-between" | ||
className={styles.buildRowMain} | ||
> | ||
<Stack direction="row" alignItems="center"> | ||
<BuildAvatar build={build} /> | ||
<div> | ||
<Stack | ||
className={styles.buildResume} | ||
direction="row" | ||
alignItems="center" | ||
spacing={1} | ||
> | ||
<span> | ||
<strong>{initiatedBy}</strong>{" "} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can add translations with formatting by using a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found it hard to use |
||
{build.reason !== "initiator" ? "automatically " : " "} | ||
<strong> | ||
{t(`buildTransitionMessage.${build.transition}`)} | ||
</strong>{" "} | ||
the workspace | ||
</span> | ||
|
||
<span className={styles.buildTime}> | ||
{new Date(build.created_at).toLocaleTimeString()} | ||
</span> | ||
</Stack> | ||
|
||
<Stack direction="row" spacing={1}> | ||
<span className={styles.buildInfo}> | ||
Reason: <strong>{build.reason}</strong> | ||
BrunoQuaresma marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</span> | ||
|
||
<span className={styles.buildInfo}> | ||
Duration:{" "} | ||
<strong>{displayWorkspaceBuildDuration(build)}</strong> | ||
</span> | ||
</Stack> | ||
</div> | ||
</Stack> | ||
</Stack> | ||
</Stack> | ||
</TableCell> | ||
</TableRow> | ||
) | ||
} | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
buildRow: { | ||
padding: theme.spacing(2, 4), | ||
cursor: "pointer", | ||
|
||
"&:not(:last-child) td:before": { | ||
position: "absolute", | ||
top: 20, | ||
left: 50, | ||
display: "block", | ||
content: "''", | ||
height: "100%", | ||
width: 2, | ||
background: theme.palette.divider, | ||
}, | ||
}, | ||
|
||
buildCell: { | ||
padding: "0 !important", | ||
position: "relative", | ||
borderBottom: 0, | ||
}, | ||
|
||
buildRowMain: { | ||
flex: 1, | ||
}, | ||
|
||
buildResume: { | ||
...theme.typography.body1, | ||
fontFamily: "inherit", | ||
}, | ||
|
||
buildInfo: { | ||
...theme.typography.body2, | ||
fontSize: 12, | ||
fontFamily: "inherit", | ||
color: theme.palette.text.secondary, | ||
display: "block", | ||
}, | ||
|
||
buildTime: { | ||
color: theme.palette.text.secondary, | ||
fontSize: 12, | ||
}, | ||
|
||
buildRight: { | ||
width: "auto", | ||
}, | ||
|
||
buildExtraInfo: { | ||
...theme.typography.body2, | ||
fontFamily: MONOSPACE_FONT_FAMILY, | ||
color: theme.palette.text.secondary, | ||
whiteSpace: "nowrap", | ||
}, | ||
})) |
Uh oh!
There was an error while loading. Please reload this page.