-
Notifications
You must be signed in to change notification settings - Fork 881
feat: edit workspace schedule page #1701
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
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.
Looking good so far! Comments below.
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.
Code looks good to me, but skipping a thorough review until in a ready state 😄!
What do you think about Schedule being an option in the Settings pages? It could be helpful to the user for all editable options to be in one spot!
In the short term, I don't want to do that for the reasons of:
I do think it's the right call in the long(er) term, longer here is relative - could even be as early as next sprint (week). I don't want to pause getting it in here as our current workspace design has a sidebar that links out to the schedule page, and it fits in really nicely. If we decide we have cycles to design the settings page, I'd absolutely believe this could be a candidate. |
Makes complete sense to me! Appreciate hearing the thought process 💡 |
@vapurrmaid could you share what it looks like please? |
@ammario you can check the Storybook UI review |
@johnstcn thanks for sharing the Storybook.
|
There are no good reasons other than the initial draft, followed by iteration. I'll change from runtime to TTL. I'll change from minutes to hours. I'll add a timezone field |
Sounds good @vapurrmaid. I think the UI is clean and professional and I'm excited to give it a swing! |
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.
This PR is unfortunately large (though a lot of the code is test code, thankfully).
I am adding REVIEW comments to most diffs to add further explanation/context.
I'm happy to do a synchronous review in Discord if it's warranted.
Sorry that this one got large, I like to find smaller pieces, but this is just how things are as CE deadline approaches. Many thanks in advance 💖 .
Edit: Also, if you're newer to cron strings, https://crontab.guru/#30_09_*_*_1-5 is the way to go
Edit: If you're wondering why we don't use a cron library for some of our manipulation, it's because we have a custom implementation right now and do not want to expand it to full blast just yet.
Edit: This PR grew way larger than I had intended. I'm happy to address all comments, but my default response to things like refactors, improvements, nice-to-haves will be "iteration", as in follow-up efforts.
@johnstcn and I already have various follow-up efforts, like changing the ttl
from nanosecond precision. Some of the messy hours to nanosecond time conversion will get cleaned up then.
See also @ammario and I's awesome comment thread and a consensus here: #1701 (comment) that we want to give the user a diff-like preview in this form while editing it. That may not land in CE (I'll certainly try), as there are other priorities like notifications and extension that must come first.
<WorkspaceSchedulePage /> | ||
</RequireAuth> | ||
} | ||
/> |
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.
Review:
A route /workspaces/:workspace/schedule
was added to view the form
<Link className={styles.scheduleAction}>{Language.editScheduleLink}</Link> | ||
<Link className={styles.scheduleAction} component={RouterLink} to={`/workspaces/${workspace.id}/schedule`}> | ||
{Language.editScheduleLink} | ||
</Link> |
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.
Review: The dashboard link to edit a workspace schedule now works!
action("onSubmit") | ||
return Promise.resolve() | ||
}, | ||
onSubmit: () => action("onSubmit"), |
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.
Review:
You'll see this show up in the WorkspaceScheduleForm
component as well: I un-promisified onSubmit
. I did this because the model goes to a new state once the promises resolve and the API calls are success. We use that state to navigate away from the page.
In other words, there is a bit of a 'fire-n-forget' from Formik's point of view, but since we also pass in isLoading
to the form, which stems from the model, it still works out OK.
{form.errors.monday && <FormHelperText>{Language.errorNoDayOfWeek}</FormHelperText>} | ||
</FormControl> | ||
|
||
<TextField | ||
{...formHelpers("ttl", Language.ttlHelperText)} | ||
inputProps={{ min: 0, step: 30 }} | ||
disabled={form.isSubmitting || isLoading} | ||
inputProps={{ min: 0, step: 1 }} |
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.
Review:
We changed from minutes to hours
{ value: form.values.thursday, name: "thursday", label: Language.dayThursdayLabel }, | ||
{ value: form.values.friday, name: "friday", label: Language.dayFridayLabel }, | ||
{ value: form.values.saturday, name: "saturday", label: Language.daySaturdayLabel }, | ||
] |
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.
Review:
I refactored to use a map
startTime: Yup.string() | ||
.ensure() | ||
.test("is-time-string", Language.errorTime, (value) => { | ||
if (value === "") { | ||
return true | ||
} else if (!/^[0-9][0-9]:[0-9][0-9]$/.test(value)) { | ||
return false | ||
} else { | ||
const parts = value.split(":") | ||
const HH = Number(parts[0]) | ||
const mm = Number(parts[1]) | ||
return HH >= 0 && HH <= 23 && mm >= 0 && mm <= 59 | ||
} | ||
}), |
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.
Review:
We had no tests or validation on startTime
previously. See related tests in WorkspaceScheduleForm.test.tsx
.
@@ -45,6 +62,7 @@ export interface WorkspaceScheduleFormValues { | |||
saturday: boolean | |||
|
|||
startTime: string | |||
timezone: 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.
Review:
The form now has a new timezone
input, with validation and tests.
site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx
Outdated
Show resolved
Hide resolved
/** | ||
* @fileoverview workspaceSchedule is an xstate machine backing a form to CRUD | ||
* an individual workspace's schedule. | ||
*/ |
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.
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.
This was so helpful; thank you!
* The 0th index is Sunday | ||
* The 6th index is Saturday | ||
*/ | ||
export type WeeklyFlag = [boolean, boolean, boolean, boolean, boolean, boolean, boolean] |
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.
Review:
This type is very helpful and needed because we get some static analysis on the size of the arrays. The semantic meaning is like a bit mask where in the array, each index corresponds to a day and whether that day is "set" (true) or unset "false".
So in other words, it goes from Sunday -> Saturday.
This sort of thing is easier to understand than bit masks, and maps very cleanly to setting values for the checkbox group.
} | ||
|
||
return result | ||
} |
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.
Review:
This is a "private" method (only meant to be used in dowToWeeklyFlag
and thus is not exported.
I'd review this before I'd review dowToWeeklyFlag
.
The algorithm does the following:
- takes a number (ex: 1)
- or number range (ex: 1-5)
and returns the associated WeeklyFlag
array (see: https://github.com/coder/coder/pull/1701/files#r882360151).
I have a method that focuses just on number or range, because in the parent function dowToWeeklyFlag
, you can have comma-separated values like this:
1,3,5
1-2,4-5
So this function is called in a loop on each comma-separated group.
} | ||
|
||
return results | ||
} |
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.
Review:
Before reading this function, I'd read https://github.com/coder/coder/pull/1701/files#r882361592
This builds upon processRangeOrNum
by calling it in a loop after splitting the dow cron string by comma.
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.
Looking good!
Co-authored-by: Kira Pilot <[email protected]>
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 thorough comments and tests!
I noticed that I can blissfully keyboard shortcut my way through the form until I get to the Days of Week checklist; then I must use a mouse. Accessibility probably isn't a huge priority rn, but would be nice to revisit this at some time. Fantastic work! Also great job leaving comments/screenshots throughout the PR - that made it much easier to review. |
Interesting, I wonder why that is - I will look into this and see if I can figure it out. If I get stuck spinning my wheels, I'll log a ticket and move on. The code I was using was adapted from: https://v4.mui.com/components/checkboxes/#checkboxes-with-formgroup which means their example must not be accessible either (odd). Either way, thank you for finding this, that's a wonderful thing to test/review!!!! |
Resolves: #1455
Resolves: #1456
Summary
Adds a page (accessible from Workspace Schedule section on a workspace) to edit a schedule.
State Machine
Impact of Change
General parity with CLI for autostart/autostop: that is you can update your schedule from the UI
Demo of Change