From 0600ac2f77818618c80dc853fe4e763c0cd449fc Mon Sep 17 00:00:00 2001 From: Austin Pickett Date: Fri, 24 Jul 2026 14:22:43 -0400 Subject: [PATCH] feat(desktop): add Cron Blueprints to the GUI (#70066) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(desktop): add Cron Blueprints to the GUI The desktop app had a Cron jobs panel but no Blueprints tab, so the parameterized automation templates the dashboard offers were unreachable there (parity matrix: Dashboard=Y, GUI=N). Adds a Jobs/Blueprints segmented toggle to the cron panel. The Blueprints tab renders the catalog from the existing GET /api/cron/blueprints endpoint, one card per template with a typed form (time/enum/weekdays/text slots). Submitting POSTs to /api/cron/blueprints/instantiate, which fills the slots and creates a real cron job via the same create_job path as a hand-written one. The new job is merged into the shared atom so the Jobs tab and sidebar reflect it immediately. Backend already served both endpoints; this is desktop frontend only. Strings added to all four locales. * fix(desktop): stop cron blueprint cards clipping and tabs overlapping close X Blueprint cards were wrapped in PanelBlock (a max-h-48 overflow-auto
for monospace code), which capped each card and forced an inner scroll,
clipping the copy. Use a plain auto-height card div so rows grow with their
content and the gallery scrolls as one.

PanelHeader actions sat under the overlay's absolutely-positioned close X
(no layout space reserved). Reserve pr-8 clearance when actions are present.

* refactor(desktop): narrow blueprint card i18n dep, document intentional scoping

Address review nits on the Cron Blueprints PR:
- BlueprintCard's submit useCallback depended on the whole t.cron object; it
  only uses the blueprints slice. Bind const b = c.blueprints and use it (plus
  narrow the dep) throughout the card.
- Document the intentional GET-vs-POST profile asymmetry on the blueprint
  endpoints (global catalog vs per-profile instantiate) — the prior comment
  claimed both were profile-scoped.
- Note why the blueprints tab collapses 'all' scope to 'default' (a blueprint
  creates a real per-profile job; 'all' is not a writable target).

* fix(desktop): default blueprint delivery to This desktop, not origin

The blueprint catalog is shared with the dashboard, so its deliver slot
defaults to 'origin' (the chat/home-channel a dashboard or gateway job was
created from). Desktop has no origin chat and no home-channel picker, so the
seeded 'origin' rendered unlabeled and, at delivery, fell through the
home-channel fallback to nowhere when no gateway was configured.

Seed the deliver slot to 'local' (This desktop) when the backend default is
'origin' or empty, drop the origin option from the desktop dropdown, and label
the remaining options with the desktop's own delivery labels — matching the
manual cron editor (local/telegram/discord/slack/email). Also skip the
backend's origin-centric deliver help, which contradicts desktop semantics.

* refactor(desktop): align blueprint cards with the Panel/settings idiom

Address PR review (UI consistency with neighboring surfaces):
- Card container: drop the standalone-card look (bg-foreground/5) for the
  shared in-panel grouping token bg-(--ui-bg-quinary), matching the cron
  editor's in-surface groupings so blueprints sit in the Panel family.
- Form fields: replace the bespoke