Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Merged
merged 29 commits into from
May 26, 2022
Merged

Conversation

greyscaled
Copy link
Contributor

@greyscaled greyscaled commented May 24, 2022

Resolves: #1455
Resolves: #1456

Summary

Adds a page (accessible from Workspace Schedule section on a workspace) to edit a schedule.

State Machine

WorkspaceSchedule 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

edit-schedule

@greyscaled greyscaled requested a review from johnstcn May 24, 2022 06:05
Copy link
Member

@johnstcn johnstcn left a 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.

Copy link
Member

@kylecarbs kylecarbs left a 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!

@greyscaled
Copy link
Contributor Author

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:

  • we don't yet have the settings page or a design or really any thoughts of how it will look
  • the schedule form is complex and is represented as a full-page form for that reason right now

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.

@kylecarbs
Copy link
Member

Makes complete sense to me! Appreciate hearing the thought process 💡

@ammario
Copy link
Member

ammario commented May 24, 2022

@vapurrmaid could you share what it looks like please?

@johnstcn
Copy link
Member

@ammario you can check the Storybook UI review

@greyscaled greyscaled self-assigned this May 24, 2022
@greyscaled greyscaled mentioned this pull request May 24, 2022
2 tasks
@ammario
Copy link
Member

ammario commented May 25, 2022

@johnstcn thanks for sharing the Storybook.

  1. Why did we omit the timezone field?
  2. Why was "runtime" selected instead of "TTL"?
  3. Why is runtime in minutes instead of hours?

@greyscaled
Copy link
Contributor Author

@johnstcn thanks for sharing the Storybook.

  1. Why did we omit the timezone field?
  2. Why was "runtime" selected instead of "TTL"?
  3. Why is runtime in minutes instead of hours?

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

@ammario
Copy link
Member

ammario commented May 25, 2022

Sounds good @vapurrmaid. I think the UI is clean and professional and I'm excited to give it a swing!

Copy link
Contributor Author

@greyscaled greyscaled left a 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>
}
/>
Copy link
Contributor Author

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>
Copy link
Contributor Author

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"),
Copy link
Contributor Author

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 }}
Copy link
Contributor Author

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 },
]
Copy link
Contributor Author

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

Comment on lines +94 to +107
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
}
}),
Copy link
Contributor Author

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
Copy link
Contributor Author

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.

Comment on lines +1 to +4
/**
* @fileoverview workspaceSchedule is an xstate machine backing a form to CRUD
* an individual workspace's schedule.
*/
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:

Here's a GIF of me stepping through the machine states/possibilities. Please LMK if there are any questions.

To attempt and get ahead, I added a final state submitSuccess that's essentially a dupe of the idle state, but the page is using it to know to navigate.

edit-schedule-model

Copy link
Member

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]
Copy link
Contributor Author

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
}
Copy link
Contributor Author

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
}
Copy link
Contributor Author

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.

Copy link
Member

@johnstcn johnstcn left a 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]>
Copy link
Member

@kylecarbs kylecarbs left a 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!

@Kira-Pilot
Copy link
Member

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.

@greyscaled
Copy link
Contributor Author

keyboard shortcut my way through the form until I get to the Days of Week checklist; then I must use a mouse.

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!!!!

@greyscaled greyscaled merged commit 7c59ec4 into main May 26, 2022
@greyscaled greyscaled deleted the vapurrmaid/gh-1455/part-3/page branch May 26, 2022 16:11
kylecarbs pushed a commit that referenced this pull request Jun 10, 2022
Resolves: #1455 
Resolves: #1456

Summary:

Adds a page (accessible from Workspace Schedule section on a workspace) to edit a schedule.

Impact:

General parity with CLI for autostart/autostop: that is you can update your schedule from the UI
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Set Auto-off in the UI Set Auto-on in the UI
5 participants