fix(admin): scope remembered list state to the signed-in admin and recover from bad restored queries
- Store list queries under summer-admin.list:<admin id>:<controller>; me() and setCurrentUser set the owner, which removes other admins' keys and the unscoped keys of older builds; nothing is read or written without one - clearUser removes every stored query, so logout, session expiry and an unrecoverable 401 (expireSession, now used by main.ts) all clear them - A list request built from a restored query that fails for any reason (422, 500, network) forgets the query and loads the plain list once - A failing URL query keeps the error and offers a reset button (backend::lang.list.reset_list, en and pl) - Document remembered list state in docs/backend/lists-and-filters.md - Rebuild modules/boardwalk/dist
This commit is contained in:
@@ -167,6 +167,14 @@ The badge texts are list messages. Override them per list in the `messages` bloc
|
||||
|
||||
A list that shows soft-deleted records includes them in its scope, as `withTrashed()` does in WinterCMS: return `db.Unscoped()` (narrowed as needed) from `pact.ListExtendQuery` and `pact.FormExtendQuery`. Such a record can then be shown, updated and targeted by bulk and record actions, and it stays soft-deleted through an update. Code that writes to it, such as an action's `Run`, must use an unscoped handle too (`tx.Unscoped()`), or GORM adds its `deleted_at IS NULL` condition and the write matches nothing. Deleting it through the admin soft-deletes again, which changes nothing; a controller that wants the delete to be permanent removes the row in `pact.FormAfterDelete`.
|
||||
|
||||
## Remembered list state
|
||||
|
||||
The admin keeps a list's search, sort, filters, page and page size in the URL, so a filtered list can be bookmarked or shared. It also remembers the last of these per list in the browser's local storage. When an administrator opens a list without any of these parameters in the URL (from the navigation, a breadcrumb or a form's back, save or delete), the admin restores the remembered query. A URL that carries list parameters wins and replaces the remembered query.
|
||||
|
||||
Search terms can contain personal data, so remembered queries belong to one administrator and one session. They are stored under the signed-in administrator's id. Signing in as another administrator on the same browser removes every other administrator's queries, and the remembered queries of older builds, which were not stored per administrator. Every session end removes all of them: logging out, an expired session, and a 401 that the session refresh cannot recover. Only these list parameters are stored, never a token or record data.
|
||||
|
||||
A restored query never leaves a list unusable. If the list request built from a restored query fails for any reason (a 422 for a column or filter that no longer exists, a server error, or no connection), the admin forgets the query and loads the plain list once instead. A query that came from the URL keeps the error on screen, because the administrator chose it. A 422 still removes it from storage, and a button next to the error clears search, filters and sorting and loads the plain list.
|
||||
|
||||
## Scoping every list
|
||||
|
||||
To restrict which records an administrator sees at all, implement `pact.ListExtendQuery` on the controller. It receives the list query before search, filters and pagination are applied, so the restriction holds for every request. See [Admin controllers](admin-controllers.md) for the other hooks.
|
||||
|
||||
Reference in New Issue
Block a user