Touch is a panel setting, and the rail grows with it
Docs / docs (push) Successful in 22s
Playwright Tests / test-playwright (1, 2) (push) Failing after 1m9s
Playwright Tests / test-playwright (2, 2) (push) Failing after 11s
pre-commit / pre-commit (push) Failing after 1m59s
Test Backend / test-backend (push) Failing after 2m28s
Compose Smoke Test / test-compose (push) Failing after 11s
Playwright Tests / merge-reports (push) Failing after 2m19s
Docs / docs (push) Successful in 22s
Playwright Tests / test-playwright (1, 2) (push) Failing after 1m9s
Playwright Tests / test-playwright (2, 2) (push) Failing after 11s
pre-commit / pre-commit (push) Failing after 1m59s
Test Backend / test-backend (push) Failing after 2m28s
Compose Smoke Test / test-compose (push) Failing after 11s
Playwright Tests / merge-reports (push) Failing after 2m19s
It described the wrong object. A dashboard is a document that may hang on a
hallway tablet and in a desk browser at the same time, and only one of those
has fingers on it — so the flag moves off `DashboardDef.settings` and onto
`PanelDef` as a plain bool, ticked in the Panels dialog. `useCanvasRoot` takes
it as an argument rather than reading the document, and `/panel/{id}` is the
only surface with a panel to ask.
Dropping the message binding with it is deliberate: nothing drove it, and a
flow deciding whether a screen has fingers on it was never the point. A stored
`settings.touch` is inert rather than migrated, which `_check_settings`
skipping unknown names already guaranteed.
The rail was the other half. It had no touch behaviour at all and its 40px
buttons met neither branch of the 44/32 rule. `[data-touch] .dui-rail{-item}`
in `ui/core/core.css` spends the padding and the gap on the buttons instead,
so they reach the 44px target and the rail comes out taller at exactly the
same width — `RAIL_INSET` never moves, and the arrangement under it does not
either.
Also closes the panels-dialog icon gap: `DashboardSummary` carries the `icon`
now, so the dialog draws each assigned dashboard's rail glyph beside its
checkbox. `initials()` went from three identical copies in the looks to one in
`Dashboard/icons.ts`, so the dialog and the rail fall back the same way.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Va7ExQDtuwKN7kNpHhWWNQ
This commit is contained in:
@@ -143,8 +143,6 @@ SETTING_DTYPES: dict[str, str] = {
|
||||
# An image drawn under the widgets, by URL. A flow publishing to it is what
|
||||
# a wallpaper that changes looks like here.
|
||||
"background": "str",
|
||||
# Bigger controls and no hover states, for a panel that is touched.
|
||||
"touch": "bool",
|
||||
}
|
||||
|
||||
|
||||
@@ -525,6 +523,9 @@ class DashboardSummary(BaseModel):
|
||||
|
||||
name: str
|
||||
title: str = ""
|
||||
#: The glyph this dashboard draws on a panel's rail, so a list can show it
|
||||
#: without reading every document.
|
||||
icon: str = ""
|
||||
widget_count: int = 0
|
||||
has_draft: bool = False
|
||||
#: Of the working copy, so publishing from a list needs no second read.
|
||||
@@ -586,6 +587,7 @@ class DashboardStore:
|
||||
DashboardSummary(
|
||||
name=defn.name,
|
||||
title=defn.title,
|
||||
icon=defn.icon,
|
||||
widget_count=len(defn.widgets),
|
||||
has_draft=defn.has_draft,
|
||||
version=defn.version,
|
||||
|
||||
@@ -31,6 +31,11 @@ class PanelDef(BaseModel):
|
||||
#: rail follows this order. A name that no longer resolves is simply a
|
||||
#: dashboard someone deleted; the panel skips it.
|
||||
dashboards: list[str] = Field(default_factory=list)
|
||||
#: Bigger controls, a bigger rail and no hover states, for a screen that is
|
||||
#: touched rather than pointed at. It belongs to the device rather than to
|
||||
#: any dashboard: the same dashboard may hang on a hallway tablet and on a
|
||||
#: desk browser, and only one of them has fingers on it.
|
||||
touch: bool = False
|
||||
#: Which generation of credential this panel honours. A token names the
|
||||
#: nonce it was minted at, so bumping this refuses the screen currently
|
||||
#: hanging here and leaves the panel, its dashboards and their arrangement
|
||||
|
||||
@@ -86,6 +86,38 @@ def test_assign_and_read_back(
|
||||
)
|
||||
|
||||
|
||||
def test_touch_belongs_to_the_panel(
|
||||
client: TestClient, superuser_token_headers: dict[str, str]
|
||||
) -> None:
|
||||
"""Whether a screen is touched is a fact about the screen, not the document.
|
||||
|
||||
The same dashboard may hang on a hallway tablet and on a desk browser, so
|
||||
the flag rides on the panel and each one answers for itself.
|
||||
"""
|
||||
client.post(f"{DASHBOARDS}/shared", headers=superuser_token_headers)
|
||||
_panels(
|
||||
client,
|
||||
superuser_token_headers,
|
||||
{
|
||||
"panels": [
|
||||
{"id": "wall", "dashboards": ["shared"], "touch": True},
|
||||
{"id": "desk", "dashboards": ["shared"]},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
by_id = {
|
||||
panel["id"]: panel
|
||||
for panel in client.get(f"{PREFIX}/", headers=superuser_token_headers).json()[
|
||||
"panels"
|
||||
]
|
||||
}
|
||||
assert by_id["wall"]["touch"] is True
|
||||
# Absent is pointed at, which is what a panels file written before this
|
||||
# field existed comes back as.
|
||||
assert by_id["desk"]["touch"] is False
|
||||
|
||||
|
||||
def test_duplicate_panel_is_refused(
|
||||
client: TestClient, superuser_token_headers: dict[str, str]
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user