Overviews: icon toolbar, dashboard drafts, publish all
Both overviews carried the same toolbar twice, left-aligned, with a search
field permanently taking a row of width. One `OverviewToolbar` now serves
them: the search folds into an icon and expands again on click (Escape puts
it away and hands focus back), create is a `+`, and everything sits right of
the page. Each page keeps its own create dialog — the toolbar only renders
the trigger — so the testids the runtime spec and the capture script drive
stayed where they were.
Dashboards get the flow store's draft/publish split. The editor autosaves
`dashboard.draft.json` beside `dashboard.json`; `/view/{name}`, `bindings_for`
and `history_requirements` keep reading the published file, so a wall panel
sees an edit only once someone publishes it. `POST /dashboards/{name}/publish`
and `/discard` mirror the flow routes down to the version precondition and the
409, `GET /dashboards/{name}?draft=true` is what the editor asks for, and the
dock grows the same Publish button — which flushes a queued save first, so an
autosave in flight is not published around. Creating a dashboard still writes
the published file directly: an empty document on a panel is harmless, and it
keeps the store free of a never-published case.
"Publish all" is a checkmark in the toolbar, live only when something actually
has `has_draft`. A summary carries no version and publish needs the one it is
based on, so each document's detail is read immediately before its publish —
honest against a stale list, and no version-less backend path to maintain.
Failures are counted rather than swallowed: three of five fails says so and
names the three.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XC2jX6Hdj7pxGGKzBTrbqB
This commit is contained in:
@@ -59,6 +59,34 @@ def test_a_save_based_on_a_version_someone_moved_past_is_refused(
|
||||
store.write(first, first.version)
|
||||
|
||||
|
||||
def test_an_edit_reaches_a_panel_only_once_it_is_published(store: DashboardStore):
|
||||
"""A wall panel reads the published file; the editor writes beside it."""
|
||||
published = store.write(default_dashboard("house"))
|
||||
|
||||
draft = store.write_draft(
|
||||
published.model_copy(update={"title": "Kitchen"}), published.version
|
||||
)
|
||||
|
||||
assert store.has_draft("house")
|
||||
assert store.read("house").title == published.title
|
||||
assert store.read("house", draft=True).title == "Kitchen"
|
||||
|
||||
store.publish("house", draft.version)
|
||||
|
||||
assert store.read("house").title == "Kitchen"
|
||||
assert not store.has_draft("house")
|
||||
|
||||
|
||||
def test_discarding_leaves_what_is_published(store: DashboardStore):
|
||||
published = store.write(default_dashboard("house"))
|
||||
store.write_draft(
|
||||
published.model_copy(update={"title": "Kitchen"}), published.version
|
||||
)
|
||||
|
||||
assert store.discard_draft("house").title == published.title
|
||||
assert not store.has_draft("house")
|
||||
|
||||
|
||||
def test_deleting_and_renaming(store: DashboardStore):
|
||||
store.write(default_dashboard("house"))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user