import { type ReactNode } from "react"; export type Weekday = "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun"; export type IntervalUnit = "minutes" | "hours" | "days"; /** * When something runs. Times are wall-clock "HH:MM" in the schedule's time * zone, which travels next to the rule (see `CadenceValue`). */ export type CadenceRule = { frequency: "hourly"; } | { frequency: "daily"; time: string; } | { frequency: "weekdays"; time: string; } | { frequency: "weekly"; days: Weekday[]; time: string; } | { frequency: "monthly"; dayOfMonth: number; time: string; } | { frequency: "interval"; every: number; unit: IntervalUnit; /** Day intervals only: the time of day of the first run. */ time?: string | undefined; /** A stored anchor from the API. New rules leave it empty. */ startAt?: string | undefined; } /** One run on a local date ("2026-10-02") and time. */ | { frequency: "once"; date: string; time: string; } /** One run at an exact instant (ISO), as stored by older clients. */ | { frequency: "once"; at: string; }; export type CadenceFrequency = CadenceRule["frequency"]; export interface CadenceValue { rule: CadenceRule; /** IANA time zone, for example "Europe/Oslo". */ timeZone: string; } export type ApiWeekday = "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY"; /** * The API schedule spec (`ScheduledTaskScheduleSpec` in @opengeni/contracts), * plus `daysOfMonth` on calendar rules. True monthly schedules need that small * contract addition (Temporal supports `dayOfMonth` natively); until it lands, * the API rejects a monthly spec instead of silently drifting. */ export type CadenceScheduleSpec = { type: "once"; runAt: string; timeZone: string; } | { type: "interval"; everySeconds: number; startAt?: string; } | { type: "calendar"; timeZone: string; hour: number; minute: number; daysOfWeek?: ApiWeekday[] | undefined; daysOfMonth?: number[] | undefined; }; export declare const WEEKDAYS: readonly Weekday[]; export declare const DEFAULT_CADENCE_TIME = "09:00"; export interface LocalDate { year: number; /** 1-12. */ month: number; day: number; } interface ZonedParts extends LocalDate { hour: number; minute: number; second: number; } /** The wall-clock date and time of an instant in a time zone. */ export declare function zonedParts(date: Date, timeZone: string): ZonedParts; /** The instant a wall-clock date and time happens in a time zone. */ export declare function zonedTimeToUtc(date: LocalDate, time: { hour: number; minute: number; }, timeZone: string): Date; export declare function formatLocalDate(date: LocalDate): string; export declare function parseLocalDate(value: string): LocalDate | null; /** Human labels for an IANA zone: "Oslo time" and "Oslo". */ export declare function timeZoneLabels(timeZone: string): { label: string; shortLabel: string; }; /** Strict "HH:MM" (24 hour). */ export declare function parseTime(value: string): { hour: number; minute: number; } | null; /** * Lenient time entry, normalised to "HH:MM": "8" -> "08:00", "830" -> "08:30", * "8.30" -> "08:30", "8pm" -> "20:00". Returns null for times that don't exist. */ export declare function normalizeTime(input: string): string | null; /** Steps a "HH:MM" time by minutes, wrapping around midnight. */ export declare function stepTime(value: string, minutes: number): string; export interface RunFormatOptions { timeZone: string; now: Date; } /** "Today, 14:00", "Tomorrow, 08:00", "Mon 28 Sep, 08:00" or "Mon 4 Jan 2027, 08:00". */ export declare function formatRunTime(date: Date, { timeZone, now }: RunFormatOptions): string; /** * The next runs as one line: "Mon 28 Sep, 08:00, then Tue 29 Sep and Wed 30 Sep". * Later runs drop what repeats: the time when it matches the first run, the * date when they fall on the same day as the run before. */ export declare function describeNextRuns(runs: readonly Date[], options: RunFormatOptions): string; export interface CadenceDescribeOptions { timeZone: string; /** "Oslo time". Derived from the zone when omitted. */ timeZoneLabel?: string | undefined; /** "Oslo". Derived from the zone when omitted. */ timeZoneShortLabel?: string | undefined; /** Used to decide whether a one-time date needs its year. */ now?: Date | undefined; } export interface CadenceDescription { /** "Runs every weekday at 08:00 Oslo time" - for sentences and sheets. */ sentence: string; /** "Every weekday at 08:00 ยท Oslo" - for list rows. Same words, zone as a suffix. */ short: string; } /** The rule in words, as a sentence and as a short row label. */ export declare function describeCadence(rule: CadenceRule, options: CadenceDescribeOptions): CadenceDescription; /** A one-time rule as a local date and time, converting stored instants. */ export declare function normalizeCadenceRule(rule: CadenceRule, timeZone: string): CadenceRule; export type CadenceField = "time" | "days" | "dayOfMonth" | "every" | "date"; export interface CadenceIssue { field: CadenceField; message: string; } /** What's wrong with a rule, in words, or null when it can run. */ export declare function validateCadence(rule: CadenceRule, { timeZone, now }: RunFormatOptions): CadenceIssue | null; export interface NextRunOptions extends RunFormatOptions { /** How many runs to return. Default 3. */ count?: number | undefined; } /** The next runs strictly after `now`, in order. Empty when the rule is invalid. */ export declare function nextRuns(rule: CadenceRule, options: NextRunOptions): Date[]; /** The API schedule spec for a rule. Call only for valid rules. */ export declare function toScheduleSpec(rule: CadenceRule, { timeZone, now }: RunFormatOptions): CadenceScheduleSpec; /** * A stored API spec as a rule the picker can edit. Fixes the classic * "43200 minutes" edit: whole hours and days come back as hours and days. */ export declare function cadenceFromScheduleSpec(spec: CadenceScheduleSpec, fallbackTimeZone: string): CadenceValue; export type CadenceParseResult = { ok: true; rule: CadenceRule; } | { ok: false; message: string; }; /** * Reads a typed cadence: "every weekday at 8", "mondays and thursdays at 9:30", * "1st of every month at 9", "every 30 minutes", "tomorrow at 15:00". * Missing times default to 09:00. */ export declare function parseCadence(input: string, { timeZone, now }: RunFormatOptions): CadenceParseResult; export type CadencePickerVariant = "sentence" | "presets" | "text"; export interface CadenceTimeZoneOption { /** IANA id, "Europe/Oslo". */ id: string; /** "Oslo time". */ label: string; /** "Oslo". */ shortLabel?: string | undefined; /** "UTC+2". */ offsetLabel?: string | undefined; } export interface CadencePickerProps { value: CadenceValue; /** Called with every valid change. The text variant only reports rules it could read. */ onChange: (value: CadenceValue) => void; /** * "sentence" (default): [Every weekday] at [08:00] [Oslo time]. * "presets": labelled preset chips and fields. * "text": type the cadence in words. */ variant?: CadencePickerVariant | undefined; /** Suggested zones, listed first. Search also covers every zone the browser knows. */ timeZones?: readonly CadenceTimeZoneOption[] | undefined; /** Limit the frequencies, for example for knowledge source sync. */ frequencies?: readonly CadenceFrequency[] | undefined; /** The clock for previews. Defaults to the time of the first render. */ now?: Date | undefined; /** When it differs from the schedule's zone, the preview adds the viewer's local time. */ viewerTimeZone?: string | undefined; /** How many upcoming runs the preview lists. Default 3. */ previewCount?: number | undefined; disabled?: boolean | undefined; /** Shown under the picker while it is disabled: who can change it. */ disabledReason?: ReactNode | undefined; /** The surrounding field label ("When"). */ "aria-labelledby"?: string | undefined; className?: string | undefined; } /** Switching frequency keeps what still applies: the time, the days. */ export declare function switchFrequency(rule: CadenceRule, frequency: CadenceFrequency, { timeZone, now }: RunFormatOptions): CadenceRule; /** The typed form of a rule, without "Runs" or the zone: "every weekday at 08:00". */ export declare function cadencePhrase(rule: CadenceRule, timeZone: string, now?: Date): string; /** A 24-hour time input. Type "8", "830" or "8pm"; arrow keys step 15 minutes. */ export declare function TimeField({ value, onChange, label, disabled, id, className, }: { value: string; onChange: (value: string) => void; label?: string | undefined; disabled?: boolean | undefined; id?: string | undefined; className?: string | undefined; }): import("react").JSX.Element; /** * The searchable list inside the time zone picker. Exported so a sheet or the * kit can show it inline; the picker renders it in a popover. */ export declare function TimeZoneSearch({ value, onSelect, timeZones, now, initialQuery, autoFocus, preview, className, }: { value: string; onSelect: (timeZone: string) => void; timeZones?: readonly CadenceTimeZoneOption[] | undefined; now?: Date | undefined; initialQuery?: string | undefined; autoFocus?: boolean | undefined; /** A static, inert copy for previews and docs (like ComboboxPanelPreview). */ preview?: boolean | undefined; className?: string | undefined; }): import("react").JSX.Element; /** "Oslo time" with a search popover. */ export declare function TimeZonePicker({ value, onChange, timeZones, now, disabled, className, variant, }: { value: string; onChange: (timeZone: string) => void; timeZones?: readonly CadenceTimeZoneOption[] | undefined; now?: Date | undefined; disabled?: boolean | undefined; className?: string | undefined; /** "field" is a bordered control; "ghost" sits inside another field. */ variant?: "field" | "ghost" | undefined; }): import("react").JSX.Element; /** * The live summary under a cadence: the rule as a sentence, the next runs, * or what to fix. Exported for read-only places such as a schedule sheet. */ export declare function CadencePreview({ value, now, timeZones, viewerTimeZone, count, issue, id, className, }: { value: CadenceValue; now: Date; timeZones?: readonly CadenceTimeZoneOption[] | undefined; viewerTimeZone?: string | undefined; count?: number | undefined; /** Overrides the rule's own validation, for example a parse error. */ issue?: string | null | undefined; id?: string | undefined; className?: string | undefined; }): import("react").JSX.Element; /** * Say when something runs. Emits a `CadenceValue` (rule + time zone); map it * to the API with `toScheduleSpec` and describe it with `describeCadence`. */ export declare function CadencePicker({ value, onChange, variant, timeZones, frequencies, now: nowProp, viewerTimeZone, previewCount, disabled, disabledReason, "aria-labelledby": labelledBy, className, }: CadencePickerProps): import("react").JSX.Element; export {};