/** * Schedules dashboard card. * * The list view is compact, paginated, refreshable, and read-only except for * per-row detail entry. The detail view exposes pause/resume, execution-position * switching, and back actions. Run-now remains outside this card because it is * a one-shot side effect rather than a reversible state change. * * Pause/resume callbacks block on Route B and return a rebuilt card on success. * Pause can be rendered from the pre-POST snapshot plus `enabled:false`; resume * refetches because scheduler-owned nextRunAt calculation must remain * authoritative. Failures return toast-only and leave the card unchanged. * * Security: * - `invokerOpenId` pins callbacks to the admin who opened the card. * - sender union_id never lands on `action.value`. * - command entry and callbacks both enforce the dashboard admin gate. * - row ids are routing keys only; Route B still enforces row ownership. * - write actions re-run the model availability matrix before POSTing. */ import type { ScheduleCardTaskInput, ScheduleDetailDto } from '../../dashboard/schedule-card-model.js'; import type { DaemonClient } from '../../dashboard/daemon-internal-client.js'; import { type Locale } from '../../i18n/index.js'; import type { CardActionData } from './card-handler.js'; export declare const SCHEDULES_ACTION_REFRESH: "dash_schedules_refresh"; export declare const SCHEDULES_ACTION_PAGE: "dash_schedules_page"; export declare const SCHEDULES_ACTION_DETAIL: "dash_schedules_detail"; export declare const SCHEDULES_ACTION_PAUSE: "dash_schedules_pause"; export declare const SCHEDULES_ACTION_RESUME: "dash_schedules_resume"; export declare const SCHEDULES_ACTION_DELIVERY: "dash_schedules_delivery"; export declare const SCHEDULES_ACTION_BACK_TO_LIST: "dash_schedules_back_to_list"; export interface BuildSchedulesCardOpts { invokerOpenId: string; locale: Locale; /** 1-based page index. Caller clamps; this just renders what's given. */ page: number; /** Page size override, threaded through every button value. */ pageSize?: number; /** Navigation origin. `'overview'` β†’ footer renders "πŸ”™ θΏ”ε›žζ€»θ§ˆ" and every * button.value carries `origin=overview`. Undefined β†’ standalone card. */ origin?: 'overview'; /** Dashboard scope. `'global'` shows schedules from every bot and threads * `?scope=global` through reads/writes so row-owner routing is preserved. */ scope?: 'global'; } /** Build the schedules list card JSON. Pure (sorts + paginates + renders). */ export declare function buildSchedulesCard(tasks: ReadonlyArray, opts: BuildSchedulesCardOpts, nowMs: number): string; /** Options for the detail card. `invokerOpenId` plumbs the lock onto every callback button. */ export interface BuildSchedulesDetailCardOpts { invokerOpenId: string; locale: Locale; /** Overview drilldown nav state β€” threaded into action buttons so * the list rebuilt by BACK_TO_LIST is still drilldown-shaped (5/page + * return-to-overview). Detail itself does NOT render return-to-overview. */ origin?: 'overview'; pageSize?: number; /** Source list page. Detail buttons round-trip this so BACK_TO_LIST restores * the page that opened the detail card. */ sourcePage?: number; /** Global-scope flag threaded into action buttons and rebuilt cards. */ scope?: 'global'; } /** * Build the schedule detail card: task metadata, next-run preview, reversible * state controls, execution-position switching, and back action. * * Pause and resume are mutually exclusive per the model matrix: * enabled === true β†’ pause clickable, resume disabled (alreadyEnabled) * enabled === false β†’ pause disabled (alreadyPaused), resume clickable * * The disabled button is rendered with `disabled:true` and a small reason * note next to it via `mapPauseDisabledReason` / `mapResumeDisabledReason`. */ export declare function buildSchedulesDetailCard(detail: ScheduleDetailDto, opts: BuildSchedulesDetailCardOpts): string; /** ─── Handler ─────────────────────────────────────────────────────────── */ export interface SchedulesCardHandlerDeps { getOwnerOpenId?: (larkAppId: string) => string | undefined; getDashboardAdminOpenIds?: (larkAppId: string) => ReadonlyArray | undefined; createClient: (larkAppId: string) => DaemonClient; locale?: Locale; /** Override `Date.now()` so tests are deterministic. */ nowMs?: () => number; } export interface SchedulesCardHandlerResult { toast?: { type: 'info' | 'success' | 'error'; content: string; }; card?: { type: 'raw'; data: Record; }; } /** Dispatch a `dash_schedules_*` action callback. Mirrors sessions-card. */ export declare function handleSchedulesCardAction(data: CardActionData, larkAppId: string, deps: SchedulesCardHandlerDeps): Promise; //# sourceMappingURL=schedules-card.d.ts.map