Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/UI.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,17 +234,17 @@ Logs a warning on degraded/failure. Auth-gated; unauthenticated requests redirec
- *Rep Fields* — `x-data="repFieldsEditor()"` wrapper; HTMX-loaded `sortableChips` suggestions (`hx-trigger="load"`); `<textarea name="rep_fields">` with `PATCH /dashboard/info-items/{id}/rep-fields` inline save; flash target `#rep-fields-flash`.
- *Replication Specs* — `data-table` of active `info_item_rep_specs` assignments; assign form (`filter-card`, `rep_spec_id` field); HTMX delete per row.

**GET `/dashboard/info-items/{id}/watcher-status`** — HTMX partial (`info_items/_watcher_status.html`). Calls Watcher `get_watched_item`; renders ok/error/unknown/not_watching/not_configured/degraded. Used by `hx-trigger="load"` on the health strip and re-renders after check-now, begin-watching, resync-watcher.
**GET `/dashboard/info-items/{id}/watcher-status`** — HTMX partial (`info_items/_watcher_status.html`). Calls Watcher `get_watched_item`; renders ok/error/unknown/not_watching/not_configured/degraded. Used by `hx-trigger="load"` on the health strip and re-renders after check-now, begin-watching, resync-watcher. **Self-heal on 404:** a `WatcherNotFound` (the WatchedItem was permanently deleted in Watcher) NULLs the stale `watcher_item_id` (commits) and renders `not_watching` so "Begin Watching" reappears — only a confirmed 404 clears the link; transient failures (network/5xx) still render `degraded` and retain it (CannObserv/archiver#63).

**GET `/dashboard/info-items/{id}/watcher-section`** — HTMX partial (`info_items/_watcher_section.html`). Calls Watcher `get_watched_item`; renders not_configured/not_watching/degraded/watching. The watching state shows health badge, timestamps, cadence, and action buttons (no URL or spec — those live in the Information Sources section). Loaded on page init via `hx-trigger="load"` and re-fetched on the `watcherUpdated` body event. The Watcher deeplink lives on the section's `<h2>` header (rendered by the detail page, not this partial).
**GET `/dashboard/info-items/{id}/watcher-section`** — HTMX partial (`info_items/_watcher_section.html`). Calls Watcher `get_watched_item`; renders not_configured/not_watching/degraded/watching. The watching state shows health badge, timestamps, cadence, and action buttons (no URL or spec — those live in the Information Sources section). Loaded on page init via `hx-trigger="load"` and re-fetched on the `watcherUpdated` body event. The Watcher deeplink lives on the section's `<h2>` header (rendered by the detail page, not this partial). Same 404 self-heal as `/watcher-status` (CannObserv/archiver#63).

**POST `/dashboard/info-items/{id}/check-now`** — proxies to Watcher `check-now`; re-renders `_watcher_status.html`; also sets `HX-Trigger: {"watcherUpdated":{}}` so Section 3 (`#watcher-section`) auto-refreshes. If `check_now` fails, re-fetches via `get_watched_item` (shows degraded only if that also fails) **and** adds a `showFlash` error to the `HX-Trigger` so the failure is surfaced rather than swallowed *(#60)*. A `WatcherConflict` (409 — check-now on a paused item) flashes "resume it first"; any other failure flashes "Watcher is unavailable".
**POST `/dashboard/info-items/{id}/check-now`** — proxies to Watcher `check-now`; re-renders `_watcher_status.html`; also sets `HX-Trigger: {"watcherUpdated":{}}` so Section 3 (`#watcher-section`) auto-refreshes. If `check_now` fails, re-fetches via `get_watched_item` (shows degraded only if that also fails) **and** adds a `showFlash` error to the `HX-Trigger` so the failure is surfaced rather than swallowed *(#60)*. A `WatcherConflict` (409 — check-now on a paused item) flashes "resume it first"; a `WatcherNotFound` (404 — the WatchedItem was deleted in Watcher) clears the stale `watcher_item_id` and flashes "no longer watched — it was removed in Watcher" so the re-render falls back to `not_watching` (CannObserv/archiver#63); any other failure flashes "Watcher is unavailable".

**POST `/dashboard/info-items/{id}/begin-watching`** — provisions a WatchedItem on demand (for InfoItems without `watcher_item_id`); calls `provision_on_create`; re-renders `_watcher_status.html`; sets `HX-Trigger: {"watcherUpdated":{}}` so Section 3 auto-refreshes. `provision_on_create` returns a `WatcherSyncOutcome`; on `FAILED` (provisioning attempted but Watcher unavailable) the response adds a `showFlash` error so the failure is surfaced rather than swallowed. When the item has no active primary source to watch, flashes "No primary source to watch — bind one first." A `SKIPPED` outcome (no Watcher configured) flashes nothing *(#61)*.

**POST `/dashboard/info-items/{id}/resync-watcher`** — PATCHes the WatchedItem with the current primary URL and specs via `sync_on_source_swap`; re-renders `_watcher_status.html`; also sets `HX-Trigger: {"watcherUpdated":{}}` so Section 3 auto-refreshes. `sync_on_source_swap` returns a `WatcherSyncOutcome`; on `FAILED` the response adds a `showFlash` error ("Couldn't re-sync with Watcher — it's unavailable"). When the watched item has no active primary source, flashes "No primary source to re-sync — bind one first." *(#61)*
**POST `/dashboard/info-items/{id}/resync-watcher`** — PATCHes the WatchedItem with the current primary URL and specs via `sync_on_source_swap`; re-renders `_watcher_status.html`; also sets `HX-Trigger: {"watcherUpdated":{}}` so Section 3 auto-refreshes. `sync_on_source_swap` returns a `WatcherSyncOutcome`; on `FAILED` the response adds a `showFlash` error ("Couldn't re-sync with Watcher — it's unavailable"). When the watched item has no active primary source, flashes "No primary source to re-sync — bind one first." *(#61)* **404 self-heal:** a deleted WatchedItem 404s inside `sync_on_source_swap` (swallowed to `FAILED`), but the trailing `_watcher_status.html` re-render re-fetches via `get_watched_item`, 404s, clears the stale `watcher_item_id`, and reconciles to `not_watching` — so a deleted item recovers even though the flash stays the generic "unavailable" (the 404 is opaque to the shared core helper; CannObserv/archiver#63).

**POST `/dashboard/info-items/{id}/toggle-watch-active`** *(#60)* — pauses or resumes the WatchedItem via `patch_watched_item(is_active=…)`. Form field `active` is the desired target state ("true" → resume, anything else → pause); the button submits the opposite of the current state. Re-renders `_watcher_status.html` and sets `HX-Trigger: {"watcherUpdated":{}}` so Section 3 auto-refreshes. On failure the response adds a `showFlash` error to the `HX-Trigger`: a Watcher 409 (`WatcherConflict`, e.g. pause/resume on an archived item) flashes "the item may be archived"; any other failure flashes "Watcher is unavailable". The partial still re-renders rather than 500ing. No-op (no patch) when the InfoItem has no `watcher_item_id`.
**POST `/dashboard/info-items/{id}/toggle-watch-active`** *(#60)* — pauses or resumes the WatchedItem via `patch_watched_item(is_active=…)`. Form field `active` is the desired target state ("true" → resume, anything else → pause); the button submits the opposite of the current state. Re-renders `_watcher_status.html` and sets `HX-Trigger: {"watcherUpdated":{}}` so Section 3 auto-refreshes. On failure the response adds a `showFlash` error to the `HX-Trigger`: a Watcher 409 (`WatcherConflict`, e.g. pause/resume on an archived item) flashes "the item may be archived"; a `WatcherNotFound` (404 — the WatchedItem was deleted in Watcher) clears the stale `watcher_item_id` and flashes "no longer watched — it was removed in Watcher" so the re-render falls back to `not_watching` (CannObserv/archiver#63); any other failure flashes "Watcher is unavailable". The partial still re-renders rather than 500ing. No-op (no patch) when the InfoItem has no `watcher_item_id`.

**POST `/dashboard/info-items/{id}/swap-primary-source`** — inline primary-source swap: creates a new InfoSource (form fields: `url`, `source_specs` JSON array), deactivates the old active binding, binds the new source, best-effort `patch_watched_item` post-commit. Returns 204 + `HX-Redirect` to detail on success; returns 422 with an `<div id="swap-error">` fragment on validation error (targeted by `hx-target-422="#swap-error"` on the form). Template: `info_items/_swap_primary.html`.

Expand Down
2 changes: 1 addition & 1 deletion skills-vendor/obra-superpowers
Submodule obra-superpowers updated 127 files
Loading
Loading