-
Notifications
You must be signed in to change notification settings - Fork 889
feat: Workspace StatusBar #1362
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
Conversation
It's so big, but collapsing start and stop made it hard to distinguish retry from toggle
Codecov Report
@@ Coverage Diff @@
## main #1362 +/- ##
==========================================
- Coverage 67.10% 67.07% -0.03%
==========================================
Files 291 293 +2
Lines 19527 19631 +104
Branches 258 274 +16
==========================================
+ Hits 13104 13168 +64
- Misses 5073 5111 +38
- Partials 1350 1352 +2
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
delete: "deleted", | ||
} | ||
|
||
export const selectWorkspaceStatus = (state: State<WorkspaceContext, WorkspaceEvent>): WorkspaceStatus => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BrunoQuaresma this is how I'm translating workspace build and job info into the user-facing workspace status.
deleted: "Deleted", | ||
// "Canceling" would be misleading because it refers to a build, not the workspace. | ||
// So just stall. When it is canceled it will appear as the error workspaceStatus. | ||
canceling: "Loading Status", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BrunoQuaresma and these show how I translate that workspace status into the actual language.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nicely handled. Pulled the code, ran it and tested it including deleting the workspace from the CLI and monitoring the network and UI.
The state machine looks great to me.
All comments are either informational or minor, not meant to block.
site/src/api/api.ts
Outdated
@@ -132,6 +132,21 @@ export const getWorkspaceResources = async (workspaceBuildID: string): Promise<T | |||
return response.data | |||
} | |||
|
|||
const postWorkspaceBuild = | |||
(transition: string) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion(if-minor): Could this be:
(transition: WorkspaceBuildTransition) =>
@@ -1,8 +1,57 @@ | |||
/* eslint-disable @typescript-eslint/no-floating-promises */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question(minor): Would you find it useful for this to be disabled in all test.tsx
files? We can certainly make that override at the configuration-level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think that's what we intended to do
)} | ||
|
||
{/* Workspace will not update while another job is in progress so hide the button until it's usable */} | ||
{workspace.outdated && ["started", "stopped", "deleted", "error"].includes(workspaceStatus) && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion(if-minor): This is the type of logic I like to break out as it says something about our model, something like:
const isTerminalWorkspaceStatus = (workspaceStatus) => boolean
We get cheap unit tests, reuse and refined concepts (I don't have to read the code + comment to understand the model, the function name is self-descriptive).
I don't have a satisfying answer yet as to where to put these kinds of model functions. They technically enrich the api
package.
Can we discuss at a FE V and skip for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of hiding the button, should we just be disabling it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Kira-Pilot my thinking was that if you see a disabled Update button you might think there's something you should do to enable it (like how a disabled Submit button means fill out your form better), but it's only possible when the template is updated, which you may or may not be able to do. But if you have a different perspective I'm happy to hear it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I can totally see that. I was thinking it might be confusing to have the button disappearing and reappearing but I'm honestly not sure which is preferable. If there are no strong opinions from elsewhere, I suggest we just leave it and see what feedback we get, if any.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vapurrmaid I extracted the function and left it in the file for now, adding the "where" question to FE V
pollingWorkspace: { | ||
initial: "refreshingWorkspace", | ||
states: { | ||
refreshingWorkspace: { | ||
entry: "clearRefreshWorkspaceError", | ||
invoke: { | ||
id: "refreshWorkspace", | ||
src: "refreshWorkspace", | ||
onDone: { target: "waiting", actions: "assignWorkspace" }, | ||
onError: { target: "waiting", actions: "assignRefreshWorkspaceError" }, | ||
}, | ||
}, | ||
waiting: { | ||
after: { | ||
1000: "refreshingWorkspace", | ||
}, | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment(informing):
@f0ssel - we both understand the implications of the web client polling on the workspaces page, w.r.t scale and monitoring of network traffic.
I wanted to:
- Inform you of this (TL:DR a workspace page (via workspace id) will continuously poll on a 1-second interval). The response is always 200, even for a deleted or stopped workspace.
- Get your thoughts about this design and the 1-second interval, and if there's any other concerns you have
I am making this comment without any intent of blocking this PR, but just to understand the implications and inquire about http vs wss here.
State machine diagram associated to this code:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was initially going to use a 1 sec interval for polling while building, and 5 seconds for just updating status, but I ended up using the same code for both so I went with 1 second. But let me know what you think! If we put statuses on the workspace list page, there will be more polling.
I added @f0ssel as a reviewer specifically for #1362 (comment) but want to emphasize this is more for informing and breaking out a separate discussion, than something that is required now for merge. |
Co-authored-by: G r e y <grey@coder.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job!! I really appreciated the workspaces writeup you made last week; that really helped me understand this better.
* Move component and prep * Make WorkspaceSection more reusable * Lay out elements * Layout tweaks * Add outdated to Workspace type * Fill out status bar component * Format * Add transition to types * Add api handlers for build toggle * Format * Parallelize machine * Lay out basics of build submachine * Pipe start and stop events through - needs status * Attempt at a machine It's so big, but collapsing start and stop made it hard to distinguish retry from toggle * Update mock * Render status and buttons * Fix type error on template page * Move Settings * Format * Keep refreshed workspace * Make it switch workspaces * Lint * Fix relative api path * Test * Fix polling * Add loading workspace state * Format * Add stub settings page * Format * Lint * Get rid of let * Add update * Make start use version id Important for update * Fix imports * Add polling for outdated * Rely on context instead of finite state for status * Handle canceling * Fix tests * Format * Display errors so users know when button presses didn't work * Fix api typo, remove logging * Lint * Simplify type Co-authored-by: G r e y <grey@coder.com> * Add type, extract helper Co-authored-by: G r e y <grey@coder.com>
Adds a status bar to the workspace page with:
Closes #1032