fix: check for a new view version on a view display's "refresh now" - #657
Conversation
"refresh now" only marked the view's query result as outdated, so a view whose definition had just been superseded kept rendering as the old version. The definition was never re-checked on either path: the memo in View.get is only re-resolved once a minute in the background, and a display built from get-view-displays holds an exact version that is never re-checked client-side at all. View.refreshLatestVersion goes back to the API instead: it drops every memoized resolution leading to the shown version — not just the one keyed by it, since a built-in view is looked up by a hard-coded id — along with the lookups behind them, and re-resolves synchronously. When a newer version is found, the menu escalates from the in-place rebuild to a structure refresh plus a page re-render, the route the page-level "refresh now" takes: the version in use comes from the page's structure, and a new version can change the query, columns, actions and width, which is more than the piece on screen can be patched into. An unchanged view takes the in-place path as before. Closes #654 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A query-form view renders a QueryFormPanel, which is not a QueryResult, so findParent(QueryResult.class) came back null, nothing could be rebuilt, and the handler fell into its "no Ajax, nothing to rebuild" fallback: a full page re-render. That is the one display type this happened to — every other kind builds a QueryResult that can be swapped in place — and it is what made these views flicker on every refresh. There is nothing on screen to bring up to date for them: the form collects parameters and the results live on the page it submits to. The query has been marked outdated for that next submit and the view definition has been re-checked, so the refresh is done; repainting the page on top of that changes nothing visible. Measured on a live space page with two query-form views and two regular ones: before, the query-form views navigated to a fresh page render on the click; after, no navigation, while the regular views keep refreshing in place as before. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Folded in a second fix: a query-form view's "refresh now" re-rendered the whole page (66e35d9).
For a query-form view there is nothing on screen to bring up to date: the form collects parameters and the results live on the page it submits to. The query is marked outdated for that next submit and the view definition is re-checked, so the refresh is complete; repainting the page on top of that changes nothing visible. Measured on a live space page carrying two query-form views (🔍 Basic Search, 🧪 Test Search With Actions) and two regular ones (📢 Status Updates, 🗄 Archive URLs), driving the menu click headlessly and watching for a main-frame navigation:
Full suite still green: 1215 tests, 0 failures. |
Closes #654.
The problem
"refresh now" on a view display only marked the view's query result as outdated. The view definition was never re-checked, on either of the two paths it can arrive by:
View.get(id)'s memo (latestResolvedViews) is only re-resolved once a minute, in the background;get-view-displaysquery holds an exact version (View.get(latestViewIri, false)), which is never re-checked client-side at all.So a view whose definition had just been superseded kept rendering as the old version until the page's structure happened to be refreshed.
The change
View.refreshLatestVersion(String id)— goes back to the API instead of trusting what is memoized:QueryApiAccess.forgetLatestVersion+ApiCache.clearCacheonget-latest-version-of-np, or onget-latest-governed-versionfor a space-governed view;QueryApiAccess.forgetLatestVersion— drops the up-to-a-minute-old memo inlatestVersionMap.ViewDisplayMenu— "refresh now" calls it. An unchanged view takes the existing in-place rebuild path, untouched. A newer version escalates toresource.forceRefresh(0)plus a page re-render, the same route the page-level "refresh now" takes: the version in use comes from the page's structure, and a new version can change the query, columns, actions and width — more thanQueryResult.rebuildcan patch, since it reuses the oldviewDisplay/queryRefand has nonpIdto rebuild query params from.Also folds the twice-duplicated view-id → nanopub-id regex into
View.toNanopubId.Testing
mvn test: 1215 tests, 0 failures. Two new tests inViewTest— a superseding version is picked up, and memos reaching the view by another id are dropped — against three header-view TriG fixtures (header views are the one display type without a query, so loading one pulls in nothing else).Not verified end to end: the escalation branch only fires when a view is genuinely superseded, which would mean publishing a new view nanopub.
Left open
A header view still has no "refresh now" at all (
queryRef == nullhides the entry). Now that the entry also refreshes the definition, a header view does have something to refresh — but that is a menu-visibility change beyond this issue.🤖 Generated with Claude Code