Skip to content

Commit

Permalink
fix: Optimistically update the UI when a workspace action is triggered (
Browse files Browse the repository at this point in the history
  • Loading branch information
BrunoQuaresma committed Nov 8, 2022
1 parent bf4a6fb commit e7bd049
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 24 deletions.
3 changes: 1 addition & 2 deletions site/src/components/DropdownButton/ActionCtas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ const useStyles = makeStyles((theme) => ({
// this is all custom to work with our button wrapper
loadingButton: {
border: "none",
borderLeft: "1px solid #333740", // MUI disabled button
borderRadius: "3px 0px 0px 3px",
borderRadius: `${theme.shape.borderRadius} 0px 0px ${theme.shape.borderRadius}`,
},
}))
2 changes: 1 addition & 1 deletion site/src/components/DropdownButton/DropdownButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const useStyles = makeStyles((theme) => ({
borderLeft: `1px solid ${theme.palette.divider}`,
borderRadius: `0px ${theme.shape.borderRadius}px ${theme.shape.borderRadius}px 0px`,
minWidth: "unset",
width: "63px", // matching cancel button so button grouping doesn't grow in size
width: "64px", // matching cancel button so button grouping doesn't grow in size
"& .MuiButton-label": {
marginRight: "8px",
},
Expand Down
4 changes: 2 additions & 2 deletions site/src/components/LoadingButton/LoadingButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const LoadingButton: FC<React.PropsWithChildren<LoadingButtonProps>> = ({
<span style={hidden}>{children}</span>
{loading && (
<div className={styles.loader}>
<CircularProgress size={18} className={styles.spinner} />
<CircularProgress size={16} className={styles.spinner} />
</div>
)}
{Boolean(loadingLabel) && loadingLabel}
Expand Down Expand Up @@ -63,7 +63,7 @@ const useStyles = makeStyles<Theme, StyleProps>((theme) => ({
top: "50%",
left: "50%",
height: 22, // centering loading icon
width: 18,
width: 16,
},
spinner: {
color: theme.palette.text.disabled,
Expand Down
2 changes: 1 addition & 1 deletion site/src/components/WorkspaceActions/WorkspaceActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
<DisabledButton label={t("disabledButton.deleted")} />
),
[ButtonTypesEnum.pending]: (
<DisabledButton label={t("disabledButton.pending")} />
<ActionLoadingButton label={t("disabledButton.pending")} />
),
}

Expand Down
24 changes: 13 additions & 11 deletions site/src/pages/WorkspacePage/WorkspacePage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,6 @@ afterAll(() => {
})

describe("WorkspacePage", () => {
it("requests a stop job when the user presses Stop", async () => {
const stopWorkspaceMock = jest
.spyOn(api, "stopWorkspace")
.mockResolvedValueOnce(MockWorkspaceBuild)
testButton(
t("actionButton.stop", { ns: "workspacePage" }),
stopWorkspaceMock,
)
})

it("requests a delete job when the user presses Delete and confirms", async () => {
const user = userEvent.setup()
const deleteWorkspaceMock = jest
Expand Down Expand Up @@ -140,11 +130,23 @@ describe("WorkspacePage", () => {
const startWorkspaceMock = jest
.spyOn(api, "startWorkspace")
.mockImplementation(() => Promise.resolve(MockWorkspaceBuild))
testButton(
await testButton(
t("actionButton.start", { ns: "workspacePage" }),
startWorkspaceMock,
)
})

it("requests a stop job when the user presses Stop", async () => {
const stopWorkspaceMock = jest
.spyOn(api, "stopWorkspace")
.mockResolvedValueOnce(MockWorkspaceBuild)

await testButton(
t("actionButton.stop", { ns: "workspacePage" }),
stopWorkspaceMock,
)
})

it("requests cancellation when the user presses Cancel", async () => {
server.use(
rest.get(
Expand Down
34 changes: 27 additions & 7 deletions site/src/xServices/workspace/workspaceXService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ export const workspaceMachine = createMachine(
},
},
requestingStart: {
entry: "clearBuildError",
entry: ["clearBuildError", "updateStatusToPending"],
invoke: {
src: "startWorkspace",
id: "startWorkspace",
Expand All @@ -344,7 +344,7 @@ export const workspaceMachine = createMachine(
},
},
requestingStop: {
entry: "clearBuildError",
entry: ["clearBuildError", "updateStatusToPending"],
invoke: {
src: "stopWorkspace",
id: "stopWorkspace",
Expand All @@ -363,7 +363,7 @@ export const workspaceMachine = createMachine(
},
},
requestingDelete: {
entry: "clearBuildError",
entry: ["clearBuildError", "updateStatusToPending"],
invoke: {
src: "deleteWorkspace",
id: "deleteWorkspace",
Expand All @@ -382,7 +382,11 @@ export const workspaceMachine = createMachine(
},
},
requestingCancel: {
entry: ["clearCancellationMessage", "clearCancellationError"],
entry: [
"clearCancellationMessage",
"clearCancellationError",
"updateStatusToPending",
],
invoke: {
src: "cancelWorkspace",
id: "cancelWorkspace",
Expand Down Expand Up @@ -430,9 +434,7 @@ export const workspaceMachine = createMachine(
on: {
REFRESH_TIMELINE: {
target: "#workspaceState.ready.timeline.gettingBuilds",
cond: {
type: "moreBuildsAvailable",
},
cond: "moreBuildsAvailable",
},
},
},
Expand Down Expand Up @@ -599,6 +601,24 @@ export const workspaceMachine = createMachine(
}),
{ to: "scheduleBannerMachine" },
),
// Optimistically update. So when the user clicks on stop, we can show
// the "pending" state right away without having to wait 0.5s ~ 2s to
// display the visual feedback to the user.
updateStatusToPending: assign({
workspace: ({ workspace }) => {
if (!workspace) {
throw new Error("Workspace not defined")
}

return {
...workspace,
latest_build: {
...workspace.latest_build,
status: "pending" as TypesGen.WorkspaceStatus,
},
}
},
}),
},
guards: {
moreBuildsAvailable,
Expand Down

0 comments on commit e7bd049

Please sign in to comment.