diff --git a/package.json b/package.json index 5f79d93a..5be489bb 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@types/node": "^20.11.30", "@types/qs": "^6.9.14", "@types/react": "^18.2.69", + "@types/react-big-calendar": "^1", "@types/react-color": "^3.0.12", "@types/react-dom": "^18.2.22", "@types/shelljs": "^0.8.15", @@ -78,6 +79,7 @@ "rc-dock": "^3.2.19", "rc-trigger": "^5.3.4", "react": "^18.2.0", + "react-big-calendar": "^1.12.0", "react-color": "^2.19.3", "react-dom": "^18.2.0", "resize-observer-polyfill": "^1.5.1", diff --git a/src/core/block/Event.ts b/src/core/block/Event.ts index 4947e62a..f314c6aa 100644 --- a/src/core/block/Event.ts +++ b/src/core/block/Event.ts @@ -11,11 +11,8 @@ export class Event { static get uid(): string { return Event._uid.current; } - loopId: string; - type: string; - - constructor(type: string) { + constructor(public readonly type: string) { this.type = type; this.loopId = Event.uid; } @@ -39,9 +36,10 @@ export class Event { } export class ErrorEvent extends Event { - detail: unknown; - - constructor(type: string, detail?: unknown) { + constructor( + type: string, + public readonly detail?: unknown + ) { super(type); this.detail = detail; } @@ -77,5 +75,15 @@ export class CompleteEvent extends Event { } } +export class ValueUpdateEvent extends Event { + constructor( + public readonly name: string, + public readonly value: unknown, + public readonly ts?: number + ) { + super('valueUpdate'); + } +} + export const WAIT = new WaitEvent(); export const NO_EMIT = new NoEmit(); diff --git a/src/core/functions/base/AutoUpdateFunction.ts b/src/core/functions/base/AutoUpdateFunction.ts new file mode 100644 index 00000000..980a920d --- /dev/null +++ b/src/core/functions/base/AutoUpdateFunction.ts @@ -0,0 +1,57 @@ +import {FunctionData, ImpureFunction} from '../../block/BlockFunction'; +import {ScheduleEvent, setSchedule} from '../../util/SetSchedule'; +import {Block} from '../../block/Block'; +import type {BlockConfig} from '../../block/BlockProperty'; + +export abstract class AutoUpdateFunction extends ImpureFunction { + #schedule: ScheduleEvent; + #onTimer = (time: number) => { + this.#schedule = null; + if (this._data instanceof Block) { + this._data._queueFunction(); + } + }; + + #autoUpdate: boolean; + #setAutoUpdate(v: boolean) { + if (v !== this.#autoUpdate && this._data instanceof Block) { + this.#autoUpdate = v; + if (!v && this.#schedule) { + this.#schedule.cancel(); + this.#schedule = null; + } + return true; + } + return false; + } + + addSchedule(nextCheck: number) { + if (this.#autoUpdate) { + if (nextCheck !== this.#schedule?.start) { + this.#schedule?.cancel(); + this.#schedule = setSchedule(this.#onTimer, nextCheck); + } + } + } + + constructor(data: FunctionData) { + super(data); + this.#autoUpdate = data instanceof Block; + } + + configChanged(config: BlockConfig, val: unknown): boolean { + if (config._name === 'mode') { + return this.#setAutoUpdate(config._value == null || config._value === 'auto'); + } + return false; + } + + cleanup() { + this.#schedule?.cancel(); + super.cleanup(); + } + destroy() { + this.#schedule?.cancel(); + super.destroy(); + } +} diff --git a/src/core/functions/date/GenerateRange.ts b/src/core/functions/date/GenerateRange.ts index 9ed38641..1fde9357 100644 --- a/src/core/functions/date/GenerateRange.ts +++ b/src/core/functions/date/GenerateRange.ts @@ -1,48 +1,12 @@ -import {FunctionData, ImpureFunction, PureFunction} from '../../block/BlockFunction'; import {Functions} from '../../block/Functions'; import {DateTime} from 'luxon'; import {invalidDate} from '../../util/DateTime'; -import type {BlockConfig} from '../../block/BlockProperty'; -import {Block} from '../../block/Block'; -import {ScheduleEvent, setSchedule} from '../../util/SetSchedule'; +import {AutoUpdateFunction} from '../base/AutoUpdateFunction'; const UNIT_OPTIONS = ['year', 'month', 'day', 'hour', 'minute', 'week'] as const; export type UNIT_TYPE = (typeof UNIT_OPTIONS)[number]; -export class GenerateDateFunction extends ImpureFunction { - #schedule: ScheduleEvent; - #onTimer = (time: number) => { - this.#schedule = null; - if (this._data instanceof Block) { - this._data._queueFunction(); - } - }; - - #autoUpdate: boolean; - #setAutoUpdate(v: boolean) { - if (v !== this.#autoUpdate && this._data instanceof Block) { - this.#autoUpdate = v; - if (!v && this.#schedule) { - this.#schedule.cancel(); - this.#schedule = null; - } - return true; - } - return false; - } - - constructor(data: FunctionData) { - super(data); - this.#autoUpdate = data instanceof Block; - } - - configChanged(config: BlockConfig, val: unknown): boolean { - if (config._name === 'mode') { - return this.#setAutoUpdate(config._value == null || config._value === 'auto'); - } - return false; - } - +export class GenerateDateFunction extends AutoUpdateFunction { run() { const count = Number(this._data.getValue('count') ?? 1); const unit = (this._data.getValue('unit') as UNIT_TYPE) ?? 'day'; @@ -77,12 +41,7 @@ export class GenerateDateFunction extends ImpureFunction { const result = [start.plus({[unit]: dStart}), start.plus({[unit]: dEnd}).endOf(unit)]; this._data.output(result); - if (this.#autoUpdate) { - if (nextCheck !== this.#schedule?.start) { - this.#schedule?.cancel(); - this.#schedule = setSchedule(this.#onTimer, nextCheck); - } - } + this.addSchedule(nextCheck); return; } catch (err) { @@ -91,21 +50,13 @@ export class GenerateDateFunction extends ImpureFunction { } this._data.output([invalidDate, invalidDate]); } - cleanup() { - this.#schedule?.cancel(); - super.cleanup(); - } - destroy() { - this.#schedule?.cancel(); - super.destroy(); - } } Functions.add( GenerateDateFunction, { name: 'generate-range', - icon: 'fas:clock', + icon: 'fas:calendar', priority: 0, properties: [ {name: 'mode', type: 'select', options: ['previous', 'next'], init: 'previous', pinned: true}, diff --git a/src/core/functions/date/Schedule/Schedule.ts b/src/core/functions/date/Schedule/Schedule.ts index 2743e6f5..bc846110 100644 --- a/src/core/functions/date/Schedule/Schedule.ts +++ b/src/core/functions/date/Schedule/Schedule.ts @@ -1,15 +1,139 @@ -import {BlockFunction} from '../../../block/BlockFunction'; import {Functions} from '../../../block/Functions'; +import {AutoUpdateFunction} from '../../base/AutoUpdateFunction'; +import {type EventOccur, ScheduleEvent} from './ScheduleEvent'; +import {BlockIO} from '../../../block/BlockProperty'; +import {ValueUpdateEvent} from '../../../block/Event'; -export class ScheduleFunction extends BlockFunction { - run(): unknown { - return undefined; +export class ScheduleValue { + occur: EventOccur; + constructor( + public readonly event: ScheduleEvent, + public value: unknown, + public index: number + ) {} + getOccur(ts: number, timezone: string): EventOccur { + this.occur = this.event.getOccur(ts, timezone); + return this.occur; + } + shouldReplace(current: ScheduleValue) { + if (!current) { + return true; + } + if (this.event.urgency === current.event.urgency) { + if (this.occur.start === current.occur.start) { + // when everything is same, lower index is more important + return this.index < current.index; + } + return this.occur.start > current.occur.start; + } + return this.event.urgency > current.event.urgency; + } + shouldReplaceNext(current: ScheduleValue, next: ScheduleValue) { + if (current) { + // not need to check anything happens after current + if (this.occur.start > current.occur.end) { + return false; + } + // this need have higher priority, otherwise it still happens after current + if (!this.shouldReplace(current)) { + return false; + } + } + if (next) { + if (this.occur.start === next.occur.start) { + return this.shouldReplace(next); + } + // we only care about the earliest event that happens next + return this.occur.start < next.occur.start; + } + return true; + } +} + +export class ScheduleFunction extends AutoUpdateFunction { + #cache = new WeakMap(); + #events: ScheduleValue[]; + + inputChanged(input: BlockIO, val: unknown): boolean { + if (input._name !== 'default') { + // re-generate events when input changes. + this.#events = null; + } + return true; + } + + run() { + const eventsData = this._data.getArray('', 1, ['config', 'value']) as {config: unknown; value: unknown}[]; + if (!this.#events) { + // generate events + this.#events = []; + const newCache = new WeakMap(); + for (let i = 0; i < eventsData.length; i++) { + let {config, value} = eventsData[i]; + let sv = this.#cache.get(config as object); + if (!sv) { + let event = ScheduleEvent.fromProperty(config); + if (!event) { + continue; + } + sv = new ScheduleValue(event, value, i); + } else { + sv.value = value; + sv.index = i; + } + newCache.set(config as object, sv); + this.#events.push(sv); + } + this.#cache = newCache; + } + let timezone = this._data.getValue('timezone') as string; + if (typeof timezone !== 'string') { + timezone = null; + } + const occurs: EventOccur[] = []; + let ts = new Date().getTime(); + let current: ScheduleValue; + let next: ScheduleValue; + // check the current + for (let sv of this.#events) { + const occur = sv.getOccur(ts, timezone); + if (occur.isValid()) { + if (occur.start <= ts) { + if (sv.shouldReplace(current)) { + current = sv; + } + } + } + } + // check the next + for (let sv of this.#events) { + const occur = sv.occur; + if (occur.isValid()) { + if (occur.start > ts) { + if (sv.shouldReplaceNext(current, next)) { + next = sv; + } + } + } + } + if (next) { + this.addSchedule(next.occur.start); + } else if (current) { + this.addSchedule(current.occur.end + 1); + } + + let outputValue = current ? current.value : this._data.getValue('default'); + this._data.output(outputValue); + + if (current) { + return new ValueUpdateEvent(current.event.name, current.value, current.occur.start); + } } } Functions.add(ScheduleFunction, { name: 'schedule', - icon: 'fas:calendar', + icon: 'fas:calendar-days', priority: 1, properties: [ { @@ -21,7 +145,7 @@ Functions.add(ScheduleFunction, { {name: 'value', type: 'any', pinned: true}, ], }, - {name: 'default', type: 'any'}, + {name: 'default', type: 'any', pinned: true}, {name: 'timezone', type: 'string', default: ''}, {name: '#output', type: 'any', readonly: true, pinned: true}, ], diff --git a/src/core/functions/date/Schedule/ScheduleEvent.ts b/src/core/functions/date/Schedule/ScheduleEvent.ts index 5559fdfd..ee6a76ea 100644 --- a/src/core/functions/date/Schedule/ScheduleEvent.ts +++ b/src/core/functions/date/Schedule/ScheduleEvent.ts @@ -20,8 +20,7 @@ interface ScheduleConfig { duration?: number; // duration in minutes after?: DateTime; before?: DateTime; - // when priority is 0, it overwrites the default value - priority?: number; + urgency?: number; days?: number[]; // array of [year, month, day] that the special event may occur, must be sorted special?: [number, number, number][]; @@ -33,7 +32,7 @@ const ConfigValidator = { duration: z.notNegative, after: z.nullable(z.datetime), before: z.nullable(z.datetime), - priority: z.nullable(z.notNegative), + urgency: z.nullable(Number.isFinite), // used in monthly and weekly days: (value: unknown, config: ScheduleConfig) => { switch (config.repeat) { @@ -49,14 +48,16 @@ const ConfigValidator = { config.repeat === 'special' ? z.array(value, [[z.int, z.num1n(12), z.num1n(31)]]) : value == null, }; -class EventOccur { +export class EventOccur { constructor( - public event: ScheduleEvent, public start: number, public end: number ) {} + isValid() { + return this.start < Infinity; + } } -const expired = new EventOccur(null, Infinity, Infinity); +const expired = new EventOccur(Infinity, Infinity); export class ScheduleEvent { constructor( public readonly repeat: RepeatMode, @@ -66,17 +67,17 @@ export class ScheduleEvent { public readonly after?: number, public readonly before?: number, // default 0 - public readonly priority?: number, + public readonly urgency?: number, public readonly days?: number[], // array of [year, month, day] that the special event may occur, must be sorted public readonly special?: [number, number, number][] ) {} - static fromProperty(config: ScheduleConfig): ScheduleEvent { + static fromProperty(config: unknown): ScheduleEvent { if (config) { if (z.check(config, ConfigValidator)) { - const {name, start, duration, after, before, priority, repeat, days, special} = config; + const {name, start, duration, after, before, urgency, repeat, days, special} = config as ScheduleConfig; return new ScheduleEvent( repeat, start, @@ -84,7 +85,7 @@ export class ScheduleEvent { duration * ONE_MINUTE - 1, after?.valueOf() ?? -Infinity, before?.valueOf() ?? Infinity, - priority ?? Infinity, + urgency ?? 0, days, special ); @@ -157,7 +158,7 @@ export class ScheduleEvent { } #current: EventOccur; - getEvent(ts: number, timezone?: string): EventOccur { + getOccur(ts: number, timezone?: string): EventOccur { if (this.#current && this.#current.end >= ts) { return this.#current; } @@ -184,7 +185,7 @@ export class ScheduleEvent { break; } } - current = new EventOccur(this, startTs, startTs + this.durationMs); + current = new EventOccur(startTs, startTs + this.durationMs); } } diff --git a/src/core/functions/date/Schedule/spec/ScheduleEvent.spec.ts b/src/core/functions/date/Schedule/spec/ScheduleEvent.spec.ts index c4e65e3c..9310d5be 100644 --- a/src/core/functions/date/Schedule/spec/ScheduleEvent.spec.ts +++ b/src/core/functions/date/Schedule/spec/ScheduleEvent.spec.ts @@ -29,29 +29,29 @@ describe('ScheduleEvent', function () { it('next event', function () { const event = ScheduleEvent.fromProperty({repeat: 'daily', start: [12, 20], duration: 60}); - const occur1 = event.getEvent(new Date('2024-01-01').getTime()); + const occur1 = event.getOccur(new Date('2024-01-01').getTime()); expect(occur1.start).toBe(new Date('2024-01-01T12:20').getTime()); - const occur2 = event.getEvent(new Date('2024-01-01T11:00').getTime()); + const occur2 = event.getOccur(new Date('2024-01-01T11:00').getTime()); expect(occur2).toBe(occur1); // not changed - const occur3 = event.getEvent(new Date('2024-01-01T12:30').getTime()); + const occur3 = event.getOccur(new Date('2024-01-01T12:30').getTime()); expect(occur3).toBe(occur1); // not changed // next - const occur4 = event.getEvent(new Date('2024-01-01T13:20').getTime()); + const occur4 = event.getOccur(new Date('2024-01-01T13:20').getTime()); expect(occur4.start).toBe(new Date('2024-01-02T12:20').getTime()); }); it('duration overflow', function () { const event = ScheduleEvent.fromProperty({repeat: 'hourly', start: [0, 0], duration: 120}); - const occur1 = event.getEvent(DateTime.fromISO('2024-01-01').valueOf()); + const occur1 = event.getOccur(DateTime.fromISO('2024-01-01').valueOf()); expect(occur1.start).toBe(DateTime.fromISO('2024-01-01T00:00').valueOf()); // when duration pass the next start, it should end before the next start expect(occur1.end - occur1.start).toBe(3600_000 - 1); - const occur2 = event.getEvent(new Date('2024-01-01T01:00').getTime()); + const occur2 = event.getOccur(new Date('2024-01-01T01:00').getTime()); expect(occur2.start).toBe(DateTime.fromISO('2024-01-01T01:00').valueOf()); }); @@ -62,10 +62,10 @@ describe('ScheduleEvent', function () { duration: 90, after: DateTime.fromISO('2024-01-05'), }); - const occur1 = event.getEvent(DateTime.fromISO('2024-01-01').valueOf()); + const occur1 = event.getOccur(DateTime.fromISO('2024-01-01').valueOf()); expect(occur1.start).toBe(DateTime.fromISO('2024-01-05T12:10').valueOf()); - const occur2 = event.getEvent(DateTime.fromISO('2024-01-07').valueOf()); + const occur2 = event.getOccur(DateTime.fromISO('2024-01-07').valueOf()); expect(occur2.start).toBe(DateTime.fromISO('2024-01-07T12:10').valueOf()); }); @@ -76,10 +76,10 @@ describe('ScheduleEvent', function () { duration: 90, before: DateTime.fromISO('2024-01-05'), }); - const occur1 = event.getEvent(DateTime.fromISO('2024-01-01').valueOf()); + const occur1 = event.getOccur(DateTime.fromISO('2024-01-01').valueOf()); expect(occur1.start).toBe(DateTime.fromISO('2024-01-01T12:10').valueOf()); - const occur2 = event.getEvent(DateTime.fromISO('2024-01-07').valueOf()); + const occur2 = event.getOccur(DateTime.fromISO('2024-01-07').valueOf()); expect(occur2.start).toBe(Infinity); }); }); diff --git a/src/core/functions/date/index.ts b/src/core/functions/date/index.ts index 60a1a145..ef7dd122 100644 --- a/src/core/functions/date/index.ts +++ b/src/core/functions/date/index.ts @@ -4,3 +4,5 @@ import './FormatDate'; import './ModifyDate'; import './GenerateRange'; + +import './Schedule/Schedule'; diff --git a/src/core/util/Validator.ts b/src/core/util/Validator.ts index b8db0eeb..04227158 100644 --- a/src/core/util/Validator.ts +++ b/src/core/util/Validator.ts @@ -23,7 +23,7 @@ function checkO( validator: {[key: string]: ValidatorAny}, root?: unknown ): value is object { - if (typeof value !== 'object' || value == null) { + if (typeof value !== 'object' || value === null) { return false; } for (const key of Object.keys(validator)) { diff --git a/yarn.lock b/yarn.lock index db67167f..83c30213 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1406,12 +1406,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.10.4, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.7, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.8.4": - version: 7.24.1 - resolution: "@babel/runtime@npm:7.24.1" +"@babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.10.4, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.16.7, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7": + version: 7.24.4 + resolution: "@babel/runtime@npm:7.24.4" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 500c6a99ddd84f37c7bc5dbc84777af47b1372b20e879941670451d55484faf18a673c5ebee9ca2b0f36208a729417873b35b1b92e76f811620f6adf7b8cb0f1 + checksum: 785aff96a3aa8ff97f90958e1e8a7b1d47f793b204b47c6455eaadc3f694f48c97cd5c0a921fe3596d818e71f18106610a164fb0f1c71fd68c622a58269d537c languageName: node linkType: hard @@ -2046,6 +2046,13 @@ __metadata: languageName: node linkType: hard +"@popperjs/core@npm:^2.11.6": + version: 2.11.8 + resolution: "@popperjs/core@npm:2.11.8" + checksum: 4681e682abc006d25eb380d0cf3efc7557043f53b6aea7a5057d0d1e7df849a00e281cd8ea79c902a35a414d7919621fc2ba293ecec05f413598e0b23d5a1e63 + languageName: node + linkType: hard + "@puppeteer/browsers@npm:1.4.6": version: 1.4.6 resolution: "@puppeteer/browsers@npm:1.4.6" @@ -2099,6 +2106,17 @@ __metadata: languageName: node linkType: hard +"@restart/hooks@npm:^0.4.7": + version: 0.4.16 + resolution: "@restart/hooks@npm:0.4.16" + dependencies: + dequal: "npm:^2.0.3" + peerDependencies: + react: ">=16.8.0" + checksum: b6a0f1db046cdec28737092ab5defdfb25fad498d37d218646f7f123aed02a5078b1c89ae631bda14d9ee35f7bb8c9e0f15379b1a45003144dc30cd15e8ba668 + languageName: node + linkType: hard + "@rollup/plugin-inject@npm:^5.0.5": version: 5.0.5 resolution: "@rollup/plugin-inject@npm:5.0.5" @@ -2347,6 +2365,13 @@ __metadata: languageName: node linkType: hard +"@types/date-arithmetic@npm:*": + version: 4.1.4 + resolution: "@types/date-arithmetic@npm:4.1.4" + checksum: 4ee68b5a422bd5f1cf08923d18a08db558e653bbdc597677e0465a330f1e807da0e79b06b72651b62b19b4b922a779470f84657cbd765805f84f33af518b408f + languageName: node + linkType: hard + "@types/dompurify@npm:^3.0.5": version: 3.0.5 resolution: "@types/dompurify@npm:3.0.5" @@ -2532,6 +2557,17 @@ __metadata: languageName: node linkType: hard +"@types/react-big-calendar@npm:^1": + version: 1.8.9 + resolution: "@types/react-big-calendar@npm:1.8.9" + dependencies: + "@types/date-arithmetic": "npm:*" + "@types/prop-types": "npm:*" + "@types/react": "npm:*" + checksum: 38fc1c3889ceffb2caf216f357966514e373e4faeb030315b8a712c73c0cd6056b51edd6b777c18059a41398b350b2b8f1f6c6d8d791bc3d95b676301cb00967 + languageName: node + linkType: hard + "@types/react-color@npm:^3.0.12": version: 3.0.12 resolution: "@types/react-color@npm:3.0.12" @@ -2562,6 +2598,16 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:>=16.9.11": + version: 18.2.79 + resolution: "@types/react@npm:18.2.79" + dependencies: + "@types/prop-types": "npm:*" + csstype: "npm:^3.0.2" + checksum: c8a8a005d8830a48cc1ef93c3510c4935a2a03e5557dbecaa8f1038450cbfcb18eb206fa7fba7077d54b8da21faeb25577e897a333392770a7797f625b62c78a + languageName: node + linkType: hard + "@types/reactcss@npm:*": version: 1.2.12 resolution: "@types/reactcss@npm:1.2.12" @@ -2630,6 +2676,13 @@ __metadata: languageName: node linkType: hard +"@types/warning@npm:^3.0.0": + version: 3.0.3 + resolution: "@types/warning@npm:3.0.3" + checksum: 82c1235bd05d7f6940f80012404844e225d589ad338aa4585b231a2c8deacc695b683f4168757c82c10047b81854cbeaaeefd60536dd67bb48f8a65e20410652 + languageName: node + linkType: hard + "@types/which@npm:^2.0.1": version: 2.0.2 resolution: "@types/which@npm:2.0.2" @@ -3959,6 +4012,13 @@ __metadata: languageName: node linkType: hard +"clsx@npm:^1.2.1": + version: 1.2.1 + resolution: "clsx@npm:1.2.1" + checksum: 34dead8bee24f5e96f6e7937d711978380647e936a22e76380290e35486afd8634966ce300fc4b74a32f3762c7d4c0303f442c3e259f4ce02374eb0c82834f27 + languageName: node + linkType: hard + "codemirror@npm:^6.0.0, codemirror@npm:^6.0.1": version: 6.0.1 resolution: "codemirror@npm:6.0.1" @@ -4311,6 +4371,13 @@ __metadata: languageName: node linkType: hard +"date-arithmetic@npm:^4.1.0": + version: 4.1.0 + resolution: "date-arithmetic@npm:4.1.0" + checksum: 697774a1a6a1b226004b5527326599c01a095bf715a0d43089e0493a565a91e7f4342b1b73b855c0e7b0caaf4bc947a61bc35ec60d162d52ef3c3c08eab26b6e + languageName: node + linkType: hard + "date-fns@npm:2.x": version: 2.30.0 resolution: "date-fns@npm:2.30.0" @@ -4320,7 +4387,7 @@ __metadata: languageName: node linkType: hard -"dayjs@npm:1.x": +"dayjs@npm:1.x, dayjs@npm:^1.11.7": version: 1.11.10 resolution: "dayjs@npm:1.11.10" checksum: 4de9af50639d47df87f2e15fa36bb07e0f9ed1e9c52c6caa1482788ee9a384d668f1dbd00c54f82aaab163db07d61d2899384b8254da3a9184fc6deca080e2fe @@ -4541,6 +4608,16 @@ __metadata: languageName: node linkType: hard +"dom-helpers@npm:^5.2.0, dom-helpers@npm:^5.2.1": + version: 5.2.1 + resolution: "dom-helpers@npm:5.2.1" + dependencies: + "@babel/runtime": "npm:^7.8.7" + csstype: "npm:^3.0.2" + checksum: f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c + languageName: node + linkType: hard + "domain-browser@npm:^4.22.0": version: 4.23.0 resolution: "domain-browser@npm:4.23.0" @@ -5463,6 +5540,13 @@ __metadata: languageName: node linkType: hard +"globalize@npm:^0.1.1": + version: 0.1.1 + resolution: "globalize@npm:0.1.1" + checksum: 6d4687e7c52a38e7f16f77339aef9b3364c34ce8cc1c8b8495b76418013252eaf5b2453fbc2d8bb9e6e56c739262665484dc7ac51b729501ff0a3b822730116b + languageName: node + linkType: hard + "globals@npm:^11.1.0": version: 11.12.0 resolution: "globals@npm:11.12.0" @@ -5801,6 +5885,15 @@ __metadata: languageName: node linkType: hard +"invariant@npm:^2.2.4": + version: 2.2.4 + resolution: "invariant@npm:2.2.4" + dependencies: + loose-envify: "npm:^1.0.0" + checksum: 5af133a917c0bcf65e84e7f23e779e7abc1cd49cb7fdc62d00d1de74b0d8c1b5ee74ac7766099fb3be1b05b26dfc67bab76a17030d2fe7ea2eef867434362dfc + languageName: node + linkType: hard + "ip-address@npm:^9.0.5": version: 9.0.5 resolution: "ip-address@npm:9.0.5" @@ -6437,7 +6530,7 @@ __metadata: languageName: node linkType: hard -"lodash-es@npm:^4.17.15": +"lodash-es@npm:^4.17.15, lodash-es@npm:^4.17.21": version: 4.17.21 resolution: "lodash-es@npm:4.17.21" checksum: fb407355f7e6cd523a9383e76e6b455321f0f153a6c9625e21a8827d10c54c2a2341bd2ae8d034358b60e07325e1330c14c224ff582d04612a46a4f0479ff2f2 @@ -6503,7 +6596,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -6562,7 +6655,7 @@ __metadata: languageName: node linkType: hard -"luxon@npm:^3.4.4": +"luxon@npm:^3.2.1, luxon@npm:^3.4.4": version: 3.4.4 resolution: "luxon@npm:3.4.4" checksum: 02e26a0b039c11fd5b75e1d734c8f0332c95510f6a514a9a0991023e43fb233884da02d7f966823ffb230632a733fc86d4a4b1e63c3fbe00058b8ee0f8c728af @@ -6677,6 +6770,13 @@ __metadata: languageName: node linkType: hard +"memoize-one@npm:^6.0.0": + version: 6.0.0 + resolution: "memoize-one@npm:6.0.0" + checksum: 45c88e064fd715166619af72e8cf8a7a17224d6edf61f7a8633d740ed8c8c0558a4373876c9b8ffc5518c2b65a960266adf403cc215cb1e90f7e262b58991f54 + languageName: node + linkType: hard + "merge-descriptors@npm:1.0.1": version: 1.0.1 resolution: "merge-descriptors@npm:1.0.1" @@ -6984,7 +7084,16 @@ __metadata: languageName: node linkType: hard -"moment@npm:^2.24.0, moment@npm:^2.29.2": +"moment-timezone@npm:^0.5.40": + version: 0.5.45 + resolution: "moment-timezone@npm:0.5.45" + dependencies: + moment: "npm:^2.29.4" + checksum: 7497f23c4b8c875dbf07c03f9a1253f79edaeedc29d5732e36bfd3c5577e25aed1924fbd84cbb713ce1920dbe822be0e21bd487851a7d13907226f289a5e568b + languageName: node + linkType: hard + +"moment@npm:^2.24.0, moment@npm:^2.29.2, moment@npm:^2.29.4": version: 2.30.1 resolution: "moment@npm:2.30.1" checksum: 865e4279418c6de666fca7786607705fd0189d8a7b7624e2e56be99290ac846f90878a6f602e34b4e0455c549b85385b1baf9966845962b313699e7cb847543a @@ -7722,7 +7831,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.5.10": +"prop-types@npm:^15.5.10, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -8542,6 +8651,33 @@ __metadata: languageName: node linkType: hard +"react-big-calendar@npm:^1.12.0": + version: 1.12.0 + resolution: "react-big-calendar@npm:1.12.0" + dependencies: + "@babel/runtime": "npm:^7.20.7" + clsx: "npm:^1.2.1" + date-arithmetic: "npm:^4.1.0" + dayjs: "npm:^1.11.7" + dom-helpers: "npm:^5.2.1" + globalize: "npm:^0.1.1" + invariant: "npm:^2.2.4" + lodash: "npm:^4.17.21" + lodash-es: "npm:^4.17.21" + luxon: "npm:^3.2.1" + memoize-one: "npm:^6.0.0" + moment: "npm:^2.29.4" + moment-timezone: "npm:^0.5.40" + prop-types: "npm:^15.8.1" + react-overlays: "npm:^5.2.1" + uncontrollable: "npm:^7.2.1" + peerDependencies: + react: ^16.14.0 || ^17 || ^18 + react-dom: ^16.14.0 || ^17 || ^18 + checksum: 56ef4a42ea7eb708782b089c175050eae8296be3ed7682409ca6aed3668db267ab9ec1795795a21d22a0c56f23985d6421021ce5b238db4e16b253d53e2f0dfb + languageName: node + linkType: hard + "react-color@npm:^2.19.3": version: 2.19.3 resolution: "react-color@npm:2.19.3" @@ -8585,6 +8721,32 @@ __metadata: languageName: node linkType: hard +"react-lifecycles-compat@npm:^3.0.4": + version: 3.0.4 + resolution: "react-lifecycles-compat@npm:3.0.4" + checksum: 1d0df3c85af79df720524780f00c064d53a9dd1899d785eddb7264b378026979acbddb58a4b7e06e7d0d12aa1494fd5754562ee55d32907b15601068dae82c27 + languageName: node + linkType: hard + +"react-overlays@npm:^5.2.1": + version: 5.2.1 + resolution: "react-overlays@npm:5.2.1" + dependencies: + "@babel/runtime": "npm:^7.13.8" + "@popperjs/core": "npm:^2.11.6" + "@restart/hooks": "npm:^0.4.7" + "@types/warning": "npm:^3.0.0" + dom-helpers: "npm:^5.2.0" + prop-types: "npm:^15.7.2" + uncontrollable: "npm:^7.2.1" + warning: "npm:^4.0.3" + peerDependencies: + react: ">=16.3.0" + react-dom: ">=16.3.0" + checksum: 61836490040cfcdebc792b6eddcfac47b7b7e159f99304165371e9eb389a6875f20ddba3433421413ccfb918e8da6042ab2829f9b1f6f5dd9f8476aa16ddcfbe + languageName: node + linkType: hard + "react-refresh@npm:^0.14.0": version: 0.14.0 resolution: "react-refresh@npm:0.14.0" @@ -9612,6 +9774,7 @@ __metadata: "@types/node": "npm:^20.11.30" "@types/qs": "npm:^6.9.14" "@types/react": "npm:^18.2.69" + "@types/react-big-calendar": "npm:^1" "@types/react-color": "npm:^3.0.12" "@types/react-dom": "npm:^18.2.22" "@types/shelljs": "npm:^0.8.15" @@ -9654,6 +9817,7 @@ __metadata: rc-dock: "npm:^3.2.19" rc-trigger: "npm:^5.3.4" react: "npm:^18.2.0" + react-big-calendar: "npm:^1.12.0" react-color: "npm:^2.19.3" react-dom: "npm:^18.2.0" resize-observer-polyfill: "npm:^1.5.1" @@ -9965,6 +10129,20 @@ __metadata: languageName: node linkType: hard +"uncontrollable@npm:^7.2.1": + version: 7.2.1 + resolution: "uncontrollable@npm:7.2.1" + dependencies: + "@babel/runtime": "npm:^7.6.3" + "@types/react": "npm:>=16.9.11" + invariant: "npm:^2.2.4" + react-lifecycles-compat: "npm:^3.0.4" + peerDependencies: + react: ">=15.0.0" + checksum: 81473e892027a99f1ead6b9afd16db65097651cd36c4b6db710728f206f1fc4b82ba9170ecb4a1127a23857e01ba51c0194d0a7cfeecfea61ba9418e0276cb56 + languageName: node + linkType: hard + "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5" @@ -10289,6 +10467,15 @@ __metadata: languageName: node linkType: hard +"warning@npm:^4.0.3": + version: 4.0.3 + resolution: "warning@npm:4.0.3" + dependencies: + loose-envify: "npm:^1.0.0" + checksum: aebab445129f3e104c271f1637fa38e55eb25f968593e3825bd2f7a12bd58dc3738bb70dc8ec85826621d80b4acfed5a29ebc9da17397c6125864d72301b937e + languageName: node + linkType: hard + "web-streams-polyfill@npm:^3.0.3": version: 3.3.3 resolution: "web-streams-polyfill@npm:3.3.3"