Skip to content

Commit b0bab3e

Browse files
authored
feat: show last build initiator for workspaces (#2921)
1 parent e172a40 commit b0bab3e

File tree

4 files changed

+58
-7
lines changed

4 files changed

+58
-7
lines changed

site/src/components/WorkspaceStats/WorkspaceStats.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Link as RouterLink } from "react-router-dom"
66
import { Workspace } from "../../api/typesGenerated"
77
import { CardRadius, MONOSPACE_FONT_FAMILY } from "../../theme/constants"
88
import { combineClasses } from "../../util/combineClasses"
9-
import { getDisplayStatus } from "../../util/workspace"
9+
import { getDisplayStatus, getDisplayWorkspaceBuildInitiatedBy } from "../../util/workspace"
1010
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
1111

1212
const Language = {
@@ -17,6 +17,7 @@ const Language = {
1717
lastBuiltLabel: "Last Built",
1818
outdated: "Outdated",
1919
upToDate: "Up to date",
20+
byLabel: "Last Built by",
2021
}
2122

2223
export interface WorkspaceStatsProps {
@@ -27,6 +28,7 @@ export const WorkspaceStats: FC<WorkspaceStatsProps> = ({ workspace }) => {
2728
const styles = useStyles()
2829
const theme = useTheme()
2930
const status = getDisplayStatus(theme, workspace.latest_build)
31+
const initiatedBy = getDisplayWorkspaceBuildInitiatedBy(theme, workspace.latest_build)
3032

3133
return (
3234
<WorkspaceSection title={Language.workspaceDetails} contentsProps={{ className: styles.stats }}>
@@ -59,6 +61,13 @@ export const WorkspaceStats: FC<WorkspaceStatsProps> = ({ workspace }) => {
5961
</span>
6062
</div>
6163
<div className={styles.statsDivider} />
64+
<div className={styles.statItem}>
65+
<span className={styles.statsLabel}>{Language.byLabel}</span>
66+
<span className={styles.statsValue}>
67+
<span style={{ color: initiatedBy.color }}>{initiatedBy.initiatedBy}</span>
68+
</span>
69+
</div>
70+
<div className={styles.statsDivider} />
6271
<div className={styles.statItem}>
6372
<span className={styles.statsLabel}>{Language.statusLabel}</span>
6473
<span className={styles.statsValue}>
@@ -88,7 +97,7 @@ const useStyles = makeStyles((theme) => ({
8897
},
8998

9099
statItem: {
91-
minWidth: "20%",
100+
minWidth: "16%",
92101
padding: theme.spacing(2),
93102
paddingTop: theme.spacing(1.75),
94103
},

site/src/components/WorkspacesTable/WorkspacesRow.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import dayjs from "dayjs"
77
import relativeTime from "dayjs/plugin/relativeTime"
88
import { FC } from "react"
99
import { useNavigate } from "react-router-dom"
10-
import { getDisplayStatus } from "../../util/workspace"
10+
import { getDisplayStatus, getDisplayWorkspaceBuildInitiatedBy } from "../../util/workspace"
1111
import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService"
1212
import { AvatarData } from "../AvatarData/AvatarData"
1313
import { TableCellLink } from "../TableCellLink/TableCellLink"
@@ -27,6 +27,7 @@ export const WorkspacesRow: FC<{ workspaceRef: WorkspaceItemMachineRef }> = ({ w
2727
const [workspaceState, send] = useActor(workspaceRef)
2828
const { data: workspace } = workspaceState.context
2929
const status = getDisplayStatus(theme, workspace.latest_build)
30+
const initiatedBy = getDisplayWorkspaceBuildInitiatedBy(theme, workspace.latest_build)
3031
const workspacePageLink = `/@${workspace.owner_name}/${workspace.name}`
3132

3233
return (
@@ -64,6 +65,9 @@ export const WorkspacesRow: FC<{ workspaceRef: WorkspaceItemMachineRef }> = ({ w
6465
{dayjs().to(dayjs(workspace.latest_build.created_at))}
6566
</span>
6667
</TableCellLink>
68+
<TableCellLink to={workspacePageLink}>
69+
<span style={{ color: initiatedBy.color }}>{initiatedBy.initiatedBy}</span>
70+
</TableCellLink>
6771
<TableCellLink to={workspacePageLink}>
6872
<span style={{ color: status.color }}>{status.status}</span>
6973
</TableCellLink>

site/src/components/WorkspacesTable/WorkspacesTable.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const Language = {
1313
version: "Version",
1414
lastBuilt: "Last Built",
1515
status: "Status",
16+
lastBuiltBy: "By",
1617
}
1718

1819
export interface WorkspacesTableProps {
@@ -26,10 +27,11 @@ export const WorkspacesTable: FC<WorkspacesTableProps> = ({ isLoading, workspace
2627
<Table>
2728
<TableHead>
2829
<TableRow>
29-
<TableCell width="35%">{Language.name}</TableCell>
30+
<TableCell width="30%">{Language.name}</TableCell>
3031
<TableCell width="15%">{Language.template}</TableCell>
31-
<TableCell width="15%">{Language.version}</TableCell>
32-
<TableCell width="20%">{Language.lastBuilt}</TableCell>
32+
<TableCell width="10%">{Language.version}</TableCell>
33+
<TableCell width="15%">{Language.lastBuilt}</TableCell>
34+
<TableCell width="15%">{Language.lastBuiltBy}</TableCell>
3335
<TableCell width="15%">{Language.status}</TableCell>
3436
<TableCell width="1%"></TableCell>
3537
</TableRow>

site/src/util/workspace.test.ts

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import dayjs from "dayjs"
22
import * as TypesGen from "../api/typesGenerated"
33
import * as Mocks from "../testHelpers/entities"
4-
import { defaultWorkspaceExtension, isWorkspaceDeleted, isWorkspaceOn } from "./workspace"
4+
import { dark } from "../theme/theme"
5+
import {
6+
defaultWorkspaceExtension,
7+
getDisplayWorkspaceBuildInitiatedBy,
8+
isWorkspaceDeleted,
9+
isWorkspaceOn,
10+
} from "./workspace"
511

612
describe("util > workspace", () => {
713
describe("isWorkspaceOn", () => {
@@ -101,4 +107,34 @@ describe("util > workspace", () => {
101107
expect(defaultWorkspaceExtension(dayjs(startTime))).toEqual(request)
102108
})
103109
})
110+
111+
describe("getDisplayWorkspaceBuildInitiatedBy", () => {
112+
it.each<[TypesGen.WorkspaceBuild, string, string]>([
113+
[Mocks.MockWorkspaceBuild, "#C1C1C1", "TestUser"],
114+
[
115+
{
116+
...Mocks.MockWorkspaceBuild,
117+
reason: "autostart",
118+
},
119+
"#7057FF",
120+
"system/autostart",
121+
],
122+
[
123+
{
124+
...Mocks.MockWorkspaceBuild,
125+
reason: "autostop",
126+
},
127+
"#7057FF",
128+
"system/autostop",
129+
],
130+
])(
131+
`getDisplayWorkspaceBuildInitiatedBy(%p) returns color: %p, initiatedBy: %p`,
132+
(build, color, initiatedBy) => {
133+
expect(getDisplayWorkspaceBuildInitiatedBy(dark, build)).toEqual({
134+
color: color,
135+
initiatedBy: initiatedBy,
136+
})
137+
},
138+
)
139+
})
104140
})

0 commit comments

Comments
 (0)