Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit37aff0c

Browse files
authored
fix: FE parsing of schedule with day strings (#2006)
Resolves:#1901Summary:We had a homegrown parser that only understood numbers, not strings likeMON or TUES. We replace the homegrown parser with cron-parser.Details:This was nearly a straight drop-in.Impact:Much less code/maintenance burden :DWhat I learned:Don't trust the README, sometimes you just gotta read the code or importit and try it out. The `fields` representation of the parsed expressionwas missing from their docs. I might open an issue or PR to update them!
1 parent7e89d91 commit37aff0c

File tree

5 files changed

+28
-105
lines changed

5 files changed

+28
-105
lines changed

‎site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"@xstate/react":"3.0.0",
3737
"axios":"0.26.1",
3838
"can-ndjson-stream":"1.0.2",
39+
"cron-parser":"4.4.0",
3940
"cronstrue":"2.5.0",
4041
"dayjs":"1.11.2",
4142
"formik":"2.2.9",

‎site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import{useMachine}from"@xstate/react"
2+
import*ascronParserfrom"cron-parser"
23
importdayjsfrom"dayjs"
34
importtimezonefrom"dayjs/plugin/timezone"
45
importutcfrom"dayjs/plugin/utc"
@@ -12,7 +13,7 @@ import {
1213
WorkspaceScheduleFormValues,
1314
}from"../../components/WorkspaceScheduleForm/WorkspaceScheduleForm"
1415
import{firstOrItem}from"../../util/array"
15-
import{dowToWeeklyFlag,extractTimezone,stripTimezone}from"../../util/schedule"
16+
import{extractTimezone,stripTimezone}from"../../util/schedule"
1617
import{workspaceSchedule}from"../../xServices/workspaceSchedule/workspaceScheduleXService"
1718

1819
// REMARK: timezone plugin depends on UTC
@@ -93,7 +94,7 @@ export const formValuesToTTLRequest = (values: WorkspaceScheduleFormValues): Typ
9394

9495
exportconstworkspaceToInitialValues=(workspace:TypesGen.Workspace):WorkspaceScheduleFormValues=>{
9596
constschedule=workspace.autostart_schedule
96-
constttl=workspace.ttl_ms ?workspace.ttl_ms/(1000*60*60) :0
97+
constttlHours=workspace.ttl_ms ?Math.round(workspace.ttl_ms/(1000*60*60)) :0
9798

9899
if(!schedule){
99100
return{
@@ -106,22 +107,22 @@ export const workspaceToInitialValues = (workspace: TypesGen.Workspace): Workspa
106107
saturday:false,
107108
startTime:"",
108109
timezone:"",
109-
ttl,
110+
ttl:ttlHours,
110111
}
111112
}
112113

113114
consttimezone=extractTimezone(schedule,dayjs.tz.guess())
114-
constcronString=stripTimezone(schedule)
115115

116-
// parts has the following format: "mm HH * * dow"
117-
constparts=cronString.split(" ")
116+
constexpression=cronParser.parseExpression(stripTimezone(schedule))
118117

119-
// -> we skip month and day-of-month
120-
constmm=parts[0]
121-
constHH=parts[1]
122-
constdow=parts[4]
118+
constHH=expression.fields.hour.join("").padStart(2,"0")
119+
constmm=expression.fields.minute.join("").padStart(2,"0")
123120

124-
constweeklyFlags=dowToWeeklyFlag(dow)
121+
constweeklyFlags=[false,false,false,false,false,false,false]
122+
123+
for(constdayofexpression.fields.dayOfWeek){
124+
weeklyFlags[day%7]=true
125+
}
125126

126127
return{
127128
sunday:weeklyFlags[0],
@@ -131,9 +132,9 @@ export const workspaceToInitialValues = (workspace: TypesGen.Workspace): Workspa
131132
thursday:weeklyFlags[4],
132133
friday:weeklyFlags[5],
133134
saturday:weeklyFlags[6],
134-
startTime:`${HH.padStart(2,"0")}:${mm.padStart(2,"0")}`,
135+
startTime:`${HH}:${mm}`,
135136
timezone,
136-
ttl,
137+
ttl:ttlHours,
137138
}
138139
}
139140

‎site/src/util/schedule.test.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import{dowToWeeklyFlag,extractTimezone,stripTimezone,WeeklyFlag}from"./schedule"
1+
import{extractTimezone,stripTimezone}from"./schedule"
22

33
describe("util/schedule",()=>{
44
describe("stripTimezone",()=>{
@@ -20,26 +20,4 @@ describe("util/schedule", () => {
2020
expect(extractTimezone(input)).toBe(expected)
2121
})
2222
})
23-
24-
describe("dowToWeeklyFlag",()=>{
25-
it.each<[string,WeeklyFlag]>([
26-
// All days
27-
["*",[true,true,true,true,true,true,true]],
28-
["0-6",[true,true,true,true,true,true,true]],
29-
["1-7",[true,true,true,true,true,true,true]],
30-
31-
// Single number modulo 7
32-
["3",[false,false,false,true,false,false,false]],
33-
["0",[true,false,false,false,false,false,false]],
34-
["7",[true,false,false,false,false,false,false]],
35-
["8",[false,true,false,false,false,false,false]],
36-
37-
// Comma-separated Numbers, Ranges and Mixes
38-
["1,3,5",[false,true,false,true,false,true,false]],
39-
["1-2,4-5",[false,true,true,false,true,true,false]],
40-
["1,3-4,6",[false,true,false,true,true,false,true]],
41-
])(`dowToWeeklyFlag(%p) returns %p`,(dow,weeklyFlag)=>{
42-
expect(dowToWeeklyFlag(dow)).toEqual(weeklyFlag)
43-
})
44-
})
4523
})

‎site/src/util/schedule.ts

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -30,72 +30,3 @@ export const extractTimezone = (raw: string, defaultTZ = DEFAULT_TIMEZONE): stri
3030
returndefaultTZ
3131
}
3232
}
33-
34-
/**
35-
* WeeklyFlag is an array representing which days of the week are set or flagged
36-
*
37-
*@remarks
38-
*
39-
* A WeeklyFlag has an array size of 7 and should never have its size modified.
40-
* The 0th index is Sunday
41-
* The 6th index is Saturday
42-
*/
43-
exporttypeWeeklyFlag=[boolean,boolean,boolean,boolean,boolean,boolean,boolean]
44-
45-
/**
46-
* dowToWeeklyFlag converts a dow cron string to a WeeklyFlag array.
47-
*
48-
*@example
49-
*
50-
* dowToWeeklyFlag("1") // [false, true, false, false, false, false, false]
51-
* dowToWeeklyFlag("1-5") // [false, true, true, true, true, true, false]
52-
* dowToWeeklyFlag("1,3-4,6") // [false, true, false, true, true, false, true]
53-
*/
54-
exportconstdowToWeeklyFlag=(dow:string):WeeklyFlag=>{
55-
if(dow==="*"){
56-
return[true,true,true,true,true,true,true]
57-
}
58-
59-
constresults:WeeklyFlag=[false,false,false,false,false,false,false]
60-
61-
constcommaSeparatedRangeOrNum=dow.split(",")
62-
63-
for(constrangeOrNumofcommaSeparatedRangeOrNum){
64-
constflags=processRangeOrNum(rangeOrNum)
65-
66-
flags.forEach((value,idx)=>{
67-
if(value){
68-
results[idx]=true
69-
}
70-
})
71-
}
72-
73-
returnresults
74-
}
75-
76-
/**
77-
* processRangeOrNum is a helper for dowToWeeklyFlag. It processes a range or
78-
* number (modulo 7) into a Weeklyflag boolean array.
79-
*
80-
*@example
81-
*
82-
* processRangeOrNum("1") // [false, true, false, false, false, false, false]
83-
* processRangeOrNum("1-5") // [false, true, true, true, true, true, false]
84-
*/
85-
constprocessRangeOrNum=(rangeOrNum:string):WeeklyFlag=>{
86-
constresult:WeeklyFlag=[false,false,false,false,false,false,false]
87-
88-
constisRange=/^[0-9]-[0-9]$/.test(rangeOrNum)
89-
90-
if(isRange){
91-
const[first,last]=rangeOrNum.split("-")
92-
93-
for(leti=Number(first);i<=Number(last);i++){
94-
result[i%7]=true
95-
}
96-
}else{
97-
result[Number(rangeOrNum)%7]=true
98-
}
99-
100-
returnresult
101-
}

‎site/yarn.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5372,6 +5372,13 @@ create-require@^1.1.0:
53725372
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
53735373
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
53745374

5375+
cron-parser@4.4.0:
5376+
version "4.4.0"
5377+
resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-4.4.0.tgz#829d67f9e68eb52fa051e62de0418909f05db983"
5378+
integrity sha512-TrE5Un4rtJaKgmzPewh67yrER5uKM0qI9hGLDBfWb8GGRe9pn/SDkhVrdHa4z7h0SeyeNxnQnogws/H+AQANQA==
5379+
dependencies:
5380+
luxon "^1.28.0"
5381+
53755382
cronstrue@2.5.0:
53765383
version "2.5.0"
53775384
resolved "https://registry.yarnpkg.com/cronstrue/-/cronstrue-2.5.0.tgz#1d69bd53520ce536789fb666d9fd562065b491c6"
@@ -9280,6 +9287,11 @@ lru-cache@^6.0.0:
92809287
dependencies:
92819288
yallist "^4.0.0"
92829289

9290+
luxon@^1.28.0:
9291+
version "1.28.0"
9292+
resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf"
9293+
integrity sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==
9294+
92839295
lz-string@^1.4.4:
92849296
version "1.4.4"
92859297
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp