mirror of
https://github.com/coder/coder.git
synced 2025-07-08 11:39:50 +00:00
Summary: This adds the client-side implementation to match the types introduced in #879 and #844 as well as a card in the Workspaces page to present workspace the data. Details: * Added a convenient line break in the example schedule.Weekly * Added missing `json:""` annotations in codersdk/workspaces.go * Installed cronstrue for displaying human-friendly cron strings * Adjusted/Added client-side types to match codersdk/workspaces.go * Added new component WorkspaceSchedule.tsx Next Steps: The WorkspaceSchedule.tsx card only presents data (on purpose). In order to make it PUT/modify data, a few changes will be made: - a form for updating workspace schedule will be created - the form will wrapped in a dialog or modal - the WorkspaceSchedule card will have a way of opening the modal which will likely be generalized up to WorkspaceSection.tsx Impact: This is user-facing This does not fully resolve either #274 or #275 (I may further decompose that work to reflect reality and keep things in small deliverable increments), but adds significant progress towards both.
68 lines
1.9 KiB
Go
68 lines
1.9 KiB
Go
// package schedule provides utilities for parsing and deserializing
|
|
// cron-style expressions.
|
|
package schedule
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/robfig/cron/v3"
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
// For the purposes of this library, we only need minute, hour, and
|
|
// day-of-week.
|
|
const parserFormatWeekly = cron.Minute | cron.Hour | cron.Dow
|
|
|
|
var defaultParser = cron.NewParser(parserFormatWeekly)
|
|
|
|
// Weekly parses a Schedule from spec scoped to a recurring weekly event.
|
|
// Spec consists of the following space-delimited fields, in the following order:
|
|
// - timezone e.g. CRON_TZ=US/Central (optional)
|
|
// - minutes of hour e.g. 30 (required)
|
|
// - hour of day e.g. 9 (required)
|
|
// - day of week e.g. 1 (required)
|
|
//
|
|
// Example Usage:
|
|
// local_sched, _ := schedule.Weekly("59 23 *")
|
|
// fmt.Println(sched.Next(time.Now().Format(time.RFC3339)))
|
|
// // Output: 2022-04-04T23:59:00Z
|
|
//
|
|
// us_sched, _ := schedule.Weekly("CRON_TZ=US/Central 30 9 1-5")
|
|
// fmt.Println(sched.Next(time.Now()).Format(time.RFC3339))
|
|
// // Output: 2022-04-04T14:30:00Z
|
|
func Weekly(spec string) (*Schedule, error) {
|
|
specSched, err := defaultParser.Parse(spec)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("parse schedule: %w", err)
|
|
}
|
|
|
|
schedule, ok := specSched.(*cron.SpecSchedule)
|
|
if !ok {
|
|
return nil, xerrors.Errorf("expected *cron.SpecSchedule but got %T", specSched)
|
|
}
|
|
|
|
cronSched := &Schedule{
|
|
sched: schedule,
|
|
spec: spec,
|
|
}
|
|
return cronSched, nil
|
|
}
|
|
|
|
// Schedule represents a cron schedule.
|
|
// It's essentially a thin wrapper for robfig/cron/v3 that implements Stringer.
|
|
type Schedule struct {
|
|
sched *cron.SpecSchedule
|
|
// XXX: there isn't any nice way for robfig/cron to serialize
|
|
spec string
|
|
}
|
|
|
|
// String serializes the schedule to its original human-friendly format.
|
|
func (s Schedule) String() string {
|
|
return s.spec
|
|
}
|
|
|
|
// Next returns the next time in the schedule relative to t.
|
|
func (s Schedule) Next(t time.Time) time.Time {
|
|
return s.sched.Next(t)
|
|
}
|