Skip to content

Commit 9a670b9

Browse files
authored
chore: refactor frontend to use workspace status directly (coder#4361)
* Add/update copy * Update mocks * Handle disabled button labels separately * Use workspace status directly, use i18n * Update stories and tests * Fix optimistic update in xservice to use status, pending * Rename started to running in story * Fix deletion banner conditional * Send label to disabled button * Refactor workspace actions
1 parent 2a66395 commit 9a670b9

File tree

18 files changed

+263
-373
lines changed

18 files changed

+263
-373
lines changed

site/src/components/DropdownButton/ActionCtas.tsx

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,72 +7,63 @@ import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"
77
import PlayCircleOutlineIcon from "@material-ui/icons/PlayCircleOutline"
88
import { LoadingButton } from "components/LoadingButton/LoadingButton"
99
import { FC } from "react"
10+
import { useTranslation } from "react-i18next"
1011
import { combineClasses } from "util/combineClasses"
11-
import { WorkspaceStateEnum } from "util/workspace"
1212
import { WorkspaceActionButton } from "../WorkspaceActionButton/WorkspaceActionButton"
1313

14-
export const Language = {
15-
start: "Start",
16-
stop: "Stop",
17-
delete: "Delete",
18-
cancel: "Cancel",
19-
update: "Update",
20-
updating: "Updating",
21-
// these labels are used in WorkspaceActions.tsx
22-
starting: "Starting...",
23-
stopping: "Stopping...",
24-
deleting: "Deleting...",
25-
}
26-
2714
interface WorkspaceAction {
2815
handleAction: () => void
2916
}
3017

3118
export const UpdateButton: FC<React.PropsWithChildren<WorkspaceAction>> = ({ handleAction }) => {
3219
const styles = useStyles()
20+
const { t } = useTranslation("workspacePage")
3321

3422
return (
3523
<Button className={styles.actionButton} startIcon={<CloudQueueIcon />} onClick={handleAction}>
36-
{Language.update}
24+
{t("actionButton.update")}
3725
</Button>
3826
)
3927
}
4028

4129
export const StartButton: FC<React.PropsWithChildren<WorkspaceAction>> = ({ handleAction }) => {
4230
const styles = useStyles()
31+
const { t } = useTranslation("workspacePage")
4332

4433
return (
4534
<WorkspaceActionButton
4635
className={styles.actionButton}
4736
icon={<PlayCircleOutlineIcon />}
4837
onClick={handleAction}
49-
label={Language.start}
38+
label={t("actionButton.start")}
5039
/>
5140
)
5241
}
5342

5443
export const StopButton: FC<React.PropsWithChildren<WorkspaceAction>> = ({ handleAction }) => {
5544
const styles = useStyles()
45+
const { t } = useTranslation("workspacePage")
5646

5747
return (
5848
<WorkspaceActionButton
5949
className={styles.actionButton}
6050
icon={<CropSquareIcon />}
6151
onClick={handleAction}
62-
label={Language.stop}
52+
label={t("actionButton.stop")}
6353
/>
6454
)
6555
}
6656

6757
export const DeleteButton: FC<React.PropsWithChildren<WorkspaceAction>> = ({ handleAction }) => {
6858
const styles = useStyles()
59+
const { t } = useTranslation("workspacePage")
6960

7061
return (
7162
<WorkspaceActionButton
7263
className={styles.actionButton}
7364
icon={<DeleteOutlineIcon />}
7465
onClick={handleAction}
75-
label={Language.delete}
66+
label={t("actionButton.delete")}
7667
/>
7768
)
7869
}
@@ -92,15 +83,15 @@ export const CancelButton: FC<React.PropsWithChildren<WorkspaceAction>> = ({ han
9283
}
9384

9485
interface DisabledProps {
95-
workspaceState: WorkspaceStateEnum
86+
label: string
9687
}
9788

98-
export const DisabledButton: FC<React.PropsWithChildren<DisabledProps>> = ({ workspaceState }) => {
89+
export const DisabledButton: FC<React.PropsWithChildren<DisabledProps>> = ({ label }) => {
9990
const styles = useStyles()
10091

10192
return (
10293
<Button disabled className={styles.actionButton}>
103-
{workspaceState}
94+
{label}
10495
</Button>
10596
)
10697
}

site/src/components/DropdownButton/DropdownButton.stories.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { action } from "@storybook/addon-actions"
22
import { Story } from "@storybook/react"
3-
import { WorkspaceStateEnum } from "util/workspace"
43
import { DeleteButton, DisabledButton, StartButton, UpdateButton } from "./ActionCtas"
54
import { DropdownButton, DropdownButtonProps } from "./DropdownButton"
65

@@ -23,7 +22,7 @@ WithDropdown.args = {
2322

2423
export const WithCancel = Template.bind({})
2524
WithCancel.args = {
26-
primaryAction: <DisabledButton workspaceState={WorkspaceStateEnum.deleting} />,
25+
primaryAction: <DisabledButton workspaceStatus="deleting" />,
2726
secondaryActions: [],
2827
canCancel: true,
2928
handleCancel: action("cancel"),

site/src/components/Workspace/Workspace.stories.tsx

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export default {
1313

1414
const Template: Story<WorkspaceProps> = (args) => <Workspace {...args} />
1515

16-
export const Started = Template.bind({})
17-
Started.args = {
16+
export const Running = Template.bind({})
17+
Running.args = {
1818
bannerProps: {
1919
isLoading: false,
2020
onExtend: action("extend"),
@@ -53,42 +53,32 @@ Started.args = {
5353

5454
export const WithoutUpdateAccess = Template.bind({})
5555
WithoutUpdateAccess.args = {
56-
...Started.args,
56+
...Running.args,
5757
canUpdateWorkspace: false,
5858
}
5959

6060
export const Starting = Template.bind({})
6161
Starting.args = {
62-
...Started.args,
62+
...Running.args,
6363
workspace: Mocks.MockStartingWorkspace,
6464
}
6565

6666
export const Stopped = Template.bind({})
6767
Stopped.args = {
68-
...Started.args,
68+
...Running.args,
6969
workspace: Mocks.MockStoppedWorkspace,
7070
}
7171

7272
export const Stopping = Template.bind({})
7373
Stopping.args = {
74-
...Started.args,
74+
...Running.args,
7575
workspace: Mocks.MockStoppingWorkspace,
7676
}
7777

78-
export const Error = Template.bind({})
79-
Error.args = {
80-
...Started.args,
81-
workspace: {
82-
...Mocks.MockFailedWorkspace,
83-
latest_build: {
84-
...Mocks.MockWorkspaceBuild,
85-
job: {
86-
...Mocks.MockProvisionerJob,
87-
status: "failed",
88-
},
89-
transition: "start",
90-
},
91-
},
78+
export const Failed = Template.bind({})
79+
Failed.args = {
80+
...Running.args,
81+
workspace: Mocks.MockFailedWorkspace,
9282
workspaceErrors: {
9383
[WorkspaceErrors.BUILD_ERROR]: Mocks.makeMockApiError({
9484
message: "A workspace build is already active.",
@@ -98,37 +88,37 @@ Error.args = {
9888

9989
export const Deleting = Template.bind({})
10090
Deleting.args = {
101-
...Started.args,
91+
...Running.args,
10292
workspace: Mocks.MockDeletingWorkspace,
10393
}
10494

10595
export const Deleted = Template.bind({})
10696
Deleted.args = {
107-
...Started.args,
97+
...Running.args,
10898
workspace: Mocks.MockDeletedWorkspace,
10999
}
110100

111101
export const Canceling = Template.bind({})
112102
Canceling.args = {
113-
...Started.args,
103+
...Running.args,
114104
workspace: Mocks.MockCancelingWorkspace,
115105
}
116106

117107
export const Canceled = Template.bind({})
118108
Canceled.args = {
119-
...Started.args,
109+
...Running.args,
120110
workspace: Mocks.MockCanceledWorkspace,
121111
}
122112

123113
export const Outdated = Template.bind({})
124114
Outdated.args = {
125-
...Started.args,
115+
...Running.args,
126116
workspace: Mocks.MockOutdatedWorkspace,
127117
}
128118

129119
export const GetBuildsError = Template.bind({})
130120
GetBuildsError.args = {
131-
...Started.args,
121+
...Running.args,
132122
workspaceErrors: {
133123
[WorkspaceErrors.GET_BUILDS_ERROR]: Mocks.makeMockApiError({
134124
message: "There is a problem fetching builds.",
@@ -138,7 +128,7 @@ GetBuildsError.args = {
138128

139129
export const GetResourcesError = Template.bind({})
140130
GetResourcesError.args = {
141-
...Started.args,
131+
...Running.args,
142132
workspaceErrors: {
143133
[WorkspaceErrors.GET_RESOURCES_ERROR]: Mocks.makeMockApiError({
144134
message: "There is a problem fetching workspace resources.",
@@ -148,7 +138,7 @@ GetResourcesError.args = {
148138

149139
export const CancellationError = Template.bind({})
150140
CancellationError.args = {
151-
...Error.args,
141+
...Failed.args,
152142
workspaceErrors: {
153143
[WorkspaceErrors.CANCELLATION_ERROR]: Mocks.makeMockApiError({
154144
message: "Job could not be canceled.",

site/src/components/Workspace/Workspace.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
100100
canUpdateWorkspace={canUpdateWorkspace}
101101
/>
102102
<WorkspaceActions
103-
workspace={workspace}
103+
workspaceStatus={workspace.latest_build.status}
104+
isOutdated={workspace.outdated}
104105
handleStart={handleStart}
105106
handleStop={handleStop}
106107
handleDelete={handleDelete}

site/src/components/WorkspaceActions/WorkspaceActions.stories.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,72 +16,74 @@ const defaultArgs = {
1616
handleDelete: action("delete"),
1717
handleUpdate: action("update"),
1818
handleCancel: action("cancel"),
19+
isOutdated: false,
1920
isUpdating: false,
2021
}
2122

2223
export const Starting = Template.bind({})
2324
Starting.args = {
2425
...defaultArgs,
25-
workspace: Mocks.MockStartingWorkspace,
26+
workspaceStatus: Mocks.MockStartingWorkspace.latest_build.status,
2627
}
2728

28-
export const Started = Template.bind({})
29-
Started.args = {
29+
export const Running = Template.bind({})
30+
Running.args = {
3031
...defaultArgs,
31-
workspace: Mocks.MockWorkspace,
32+
workspaceStatus: Mocks.MockWorkspace.latest_build.status,
3233
}
3334

3435
export const Stopping = Template.bind({})
3536
Stopping.args = {
3637
...defaultArgs,
37-
workspace: Mocks.MockStoppingWorkspace,
38+
workspaceStatus: Mocks.MockStoppingWorkspace.latest_build.status,
3839
}
3940

4041
export const Stopped = Template.bind({})
4142
Stopped.args = {
4243
...defaultArgs,
43-
workspace: Mocks.MockStoppedWorkspace,
44+
workspaceStatus: Mocks.MockStoppedWorkspace.latest_build.status,
4445
}
4546

4647
export const Canceling = Template.bind({})
4748
Canceling.args = {
4849
...defaultArgs,
49-
workspace: Mocks.MockCancelingWorkspace,
50+
workspaceStatus: Mocks.MockCancelingWorkspace.latest_build.status,
5051
}
5152

5253
export const Canceled = Template.bind({})
5354
Canceled.args = {
5455
...defaultArgs,
55-
workspace: Mocks.MockCanceledWorkspace,
56+
workspaceStatus: Mocks.MockCanceledWorkspace.latest_build.status,
5657
}
5758

5859
export const Deleting = Template.bind({})
5960
Deleting.args = {
6061
...defaultArgs,
61-
workspace: Mocks.MockDeletingWorkspace,
62+
workspaceStatus: Mocks.MockDeletingWorkspace.latest_build.status,
6263
}
6364

6465
export const Deleted = Template.bind({})
6566
Deleted.args = {
6667
...defaultArgs,
67-
workspace: Mocks.MockDeletedWorkspace,
68+
workspaceStatus: Mocks.MockDeletedWorkspace.latest_build.status,
6869
}
6970

7071
export const Outdated = Template.bind({})
7172
Outdated.args = {
7273
...defaultArgs,
73-
workspace: Mocks.MockOutdatedWorkspace,
74+
isOutdated: true,
75+
workspaceStatus: Mocks.MockOutdatedWorkspace.latest_build.status,
7476
}
7577

76-
export const Errored = Template.bind({})
77-
Errored.args = {
78+
export const Failed = Template.bind({})
79+
Failed.args = {
7880
...defaultArgs,
79-
workspace: Mocks.MockFailedWorkspace,
81+
workspaceStatus: Mocks.MockFailedWorkspace.latest_build.status,
8082
}
8183

8284
export const Updating = Template.bind({})
8385
Updating.args = {
8486
...defaultArgs,
8587
isUpdating: true,
86-
workspace: Mocks.MockOutdatedWorkspace,
88+
workspaceStatus: Mocks.MockOutdatedWorkspace.latest_build.status,
8789
}

0 commit comments

Comments
 (0)