Arrange should put the dashboard itself into an editing mode, and Settings → Dashboard should go #201

Closed
opened 2026-09-13 08:29:39 +00:00 by tiagoagueda · 0 comments
Owner

The change

Pressing Arrange on the dashboard puts the dashboard itself into an editing mode:
the widgets stay where they are, on the page they live on, and grow the controls to move,
remove and add them. Settings → Dashboard — the separate page that does this today —
should not exist.

What happens today

Every arranging control on the dashboard is a link away from it. core/dashboard.html:48
(Arrange), :24 (arrange your dashboard, in the "Not shown yet" banner) and :93
(Arrange it, on the empty dashboard) all go to settings:dashboard. That page —
DashboardView in accounts/settings_views.py:150, templates/settings/dashboard.html
(176 lines), section dashboard in core/settings_sections.py:45, route
settings_urls.py:10 — lists the widgets as rows, each with four move buttons (up and
down move a row, left and right a place), a Remove, and below it the widgets not shown
with Add and Dismiss, plus Reset. Every action is a POST to that page, and the
redirect carries a fragment so focus lands on the widget that moved. Dragging a row into
place is a script-added addition (app.js:1168 onwards, tests/e2e/test_widget_drag.py).

So a person arranging their dashboard is arranging a list of names on another page and
switching back to see what it did. The mode this asks for shows the effect where it
happens.

What carries over unchanged, and should

The view's docstring states two rules that hold whatever the page is, and both were
fought for (#124, #125):

  • Every action works with scripts off. Buttons, POSTs, a redirect with a fragment and
    a sentence saying where the widget landed. Dragging stays an addition to that, never a
    replacement — it does not fire on a touch screen and is not reachable from a keyboard.
  • One dimension, not two. Widgets have widths and fill rows in order, so there is no
    cell to name; left and right move one place, up and down a whole row, and on a
    narrow screen the two axes coincide. An editing mode on the grid itself makes this
    easier to see, not harder — the widget moves in front of you — but the four buttons
    stay the model.

The data does not change either: Profile.dashboard_widgets and dashboard_known, the
widgets module that reads and writes them, seed, and the export that carries them.

What a fix has to settle

  • How the mode is entered and left. A parameter on the dashboard's own address
    (/?arrange=1), so it survives a reload, works under the back button and can be left
    by a plain link Done; the POSTs go to the dashboard and redirect back into the mode
    with the fragment. A remembered "editing" state would be wrong: the mode is a moment,
    not a preference.
  • Where the controls sit. On each widget, in the mode: the four moves and Remove
    in the widget's header, with the same target-size care the settings rows had (#115).
    Widgets not shown — the Add / Dismiss offer, with each widget's sentence — need a
    place on the dashboard too, below the grid or in a panel the mode opens; the "Not shown
    yet" banner then opens the mode rather than leaving the page.
  • Dragging moves from list rows to grid cells: app.js's widget handler keys on
    data-widget-row and posts to data-widget-place; the dashboard's cells carry
    data-widget today (dashboard.html:82). One handler, on whichever markup remains.
  • The section goes. settings_sections.py:45, the route, the view, the template and
    its move_widget partial. Settings keeps Appearance, Language and time, Account,
    Connections, Plugins, and any plugin section. Nothing stored refers to the section by
    name, so no migration.
  • The tests move with it. tests/test_dashboard_grid.py, test_dashboard_ownership.py,
    test_widget_placement.py and test_widgets.py post to settings:dashboard;
    tests/e2e/test_widget_drag.py drags its rows; tests/e2e/test_accessibility.py and
    test_direction.py walk /settings/dashboard/ and test_page_coverage.py counts it.
    They point at the dashboard in its mode instead; the drag test's assertion that the
    menu stays is the one to keep word for word.
  • The wiki names the page four times — Getting-started.md:129 and Insights.md:3,
    :14-15, :100 — and says "press Arrange, or Settings → Dashboard". It says
    Arrange alone.

Not in this issue: what the widgets are, their widths, or the packing rule.

## The change Pressing **Arrange** on the dashboard puts *the dashboard itself* into an editing mode: the widgets stay where they are, on the page they live on, and grow the controls to move, remove and add them. *Settings → Dashboard* — the separate page that does this today — should not exist. ## What happens today Every arranging control on the dashboard is a link away from it. `core/dashboard.html:48` (*Arrange*), `:24` (*arrange your dashboard*, in the "Not shown yet" banner) and `:93` (*Arrange it*, on the empty dashboard) all go to `settings:dashboard`. That page — `DashboardView` in `accounts/settings_views.py:150`, `templates/settings/dashboard.html` (176 lines), section `dashboard` in `core/settings_sections.py:45`, route `settings_urls.py:10` — lists the widgets as rows, each with four move buttons (up and down move a row, left and right a place), a *Remove*, and below it the widgets not shown with *Add* and *Dismiss*, plus *Reset*. Every action is a POST to that page, and the redirect carries a fragment so focus lands on the widget that moved. Dragging a row into place is a script-added addition (`app.js:1168` onwards, `tests/e2e/test_widget_drag.py`). So a person arranging their dashboard is arranging a *list of names* on another page and switching back to see what it did. The mode this asks for shows the effect where it happens. ## What carries over unchanged, and should The view's docstring states two rules that hold whatever the page is, and both were fought for (#124, #125): - **Every action works with scripts off.** Buttons, POSTs, a redirect with a fragment and a sentence saying where the widget landed. Dragging stays an addition to that, never a replacement — it does not fire on a touch screen and is not reachable from a keyboard. - **One dimension, not two.** Widgets have widths and fill rows in order, so there is no cell to name; *left* and *right* move one place, *up* and *down* a whole row, and on a narrow screen the two axes coincide. An editing mode on the grid itself makes this easier to see, not harder — the widget moves in front of you — but the four buttons stay the model. The data does not change either: `Profile.dashboard_widgets` and `dashboard_known`, the `widgets` module that reads and writes them, `seed`, and the export that carries them. ## What a fix has to settle - **How the mode is entered and left.** A parameter on the dashboard's own address (`/?arrange=1`), so it survives a reload, works under the back button and can be left by a plain link *Done*; the POSTs go to the dashboard and redirect back into the mode with the fragment. A remembered "editing" state would be wrong: the mode is a moment, not a preference. - **Where the controls sit.** On each widget, in the mode: the four moves and *Remove* in the widget's header, with the same target-size care the settings rows had (#115). Widgets not shown — the *Add* / *Dismiss* offer, with each widget's sentence — need a place on the dashboard too, below the grid or in a panel the mode opens; the "Not shown yet" banner then opens the mode rather than leaving the page. - **Dragging** moves from list rows to grid cells: `app.js`'s widget handler keys on `data-widget-row` and posts to `data-widget-place`; the dashboard's cells carry `data-widget` today (`dashboard.html:82`). One handler, on whichever markup remains. - **The section goes.** `settings_sections.py:45`, the route, the view, the template and its `move_widget` partial. `Settings` keeps Appearance, Language and time, Account, Connections, Plugins, and any plugin section. Nothing stored refers to the section by name, so no migration. - **The tests move with it.** `tests/test_dashboard_grid.py`, `test_dashboard_ownership.py`, `test_widget_placement.py` and `test_widgets.py` post to `settings:dashboard`; `tests/e2e/test_widget_drag.py` drags its rows; `tests/e2e/test_accessibility.py` and `test_direction.py` walk `/settings/dashboard/` and `test_page_coverage.py` counts it. They point at the dashboard in its mode instead; the drag test's assertion that the menu stays is the one to keep word for word. - **The wiki names the page four times** — `Getting-started.md:129` and `Insights.md:3`, `:14-15`, `:100` — and says "press *Arrange*, or *Settings → Dashboard*". It says *Arrange* alone. Not in this issue: what the widgets are, their widths, or the packing rule.
tiagoagueda added this to the 0.3.0 milestone 2026-09-13 08:29:39 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Postulo/postulo#201
No description provided.