Skip to content

[OP-20570] Rebuild a pending render on collapse - #26290

Closed
myabc wants to merge 1 commit into
devfrom
bug/op-20570-collapse-pending-redraw
Closed

myabc wants to merge 1 commit into
devfrom
bug/op-20570-collapse-pending-redraw

Conversation

@myabc

@myabc myabc commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Ticket

https://community.openproject.org/wp/OP-20570

What are you trying to accomplish?

Fixes a collapse that is undone when a table redraw is pending. WorkPackageTable builds a render pass and commits it on the next animation frame. A group or hierarchy toggle that lands between the build and the commit updates the current rows and the collapse service, and then the commit replaces those rows with rows built before the toggle. The children reappear and the expander reverts, while the collapse service still treats the group or parent as collapsed.

The race was found during the review of DREAM-885 (#26288) and reproduces on dev in the Vitest harness and in the browser: with hierarchies and the Gantt shown, calling redrawTableAndTimeline() and toggling a parent in the same task leaves the child row and timeline cell visible.

What approach did you choose and why?

setHidden is the shared entry point for both toggle paths (GroupedRowsBuilder.refreshExpansionState and HierarchyTransformer.renderHierarchyState). When a render is pending, it now rebuilds that render from the current collapse state, which supersedes the stale frame callback the same way a second redraw does, and keeps a timeline-promoted pass promoted. Both paths update their service state before calling setHidden, so the rebuilt pass reads the new state. The cost is one extra buildRows when a toggle lands inside the pending window, which is the same as a second redrawTable().

Fixing the two call sites instead was the alternative; setHidden is narrower and is where #26288 already applies the same rebuild to keyboard-enabled tables. When #26288 is rebased onto this, its gated rebuildPendingRenderForSemantics() becomes this call, and its two capability-off "race unchanged" control tests need inverting or removing.

Not covered: a programmatic hierarchy change before the table's first publication never reaches setHidden, because the transformer filters on tableRendered.hasValue(). No UI path reaches it. Separately, any timeline redraw (raced or not) drops __hierarchy-root-collapsed from a collapsed parent's timeline cell, because only HierarchyTransformer sets that class and TimelineRenderPass does not derive it from hierarchy state. That predates this change and is left for its own ticket.

The table harness gains holdFrames() and atNextPublication(). The new regressions cover group collapse and expand, hierarchy collapse, and a timeline-promoted render. Each one asserts inside the tableRendered publication and on the final markup.

AI involvement

Directed – I specified the requirements and AI implemented most of it; I validated via testing rather than a full line-by-line review.

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

Rebuilds a queued render when a group or hierarchy toggle reaches
setHidden before the render's frame commit, so the committed rows
carry the current collapse state instead of the state the draft was
built with. The stale frame callback is superseded the same way a
second redraw supersedes it, and a timeline pass stays promoted.

Adds holdFrames and atNextPublication to the table harness, and
deferred-frame regressions for group collapse and expand, hierarchy
collapse, and a timeline-promoted render.

https://community.openproject.org/wp/OP-20570
@github-actions github-actions Bot added the ai: Directed 🪄 A human specified the requirements and AI implemented most of it; They validated via testing. label Oct 24, 2026
@myabc
myabc marked this pull request as ready for review October 24, 2026 04:56
@myabc myabc added needs review bugfix javascript Pull requests that update Javascript code labels Oct 24, 2026
@myabc myabc added this to the 18.0.x milestone Oct 24, 2026
@lwassermann
lwassermann self-requested a review October 26, 2026 09:20
@lwassermann

Copy link
Copy Markdown
Contributor

Did you run an AI code review?

Claude Opus 5 high finds several issues, such as "performRenderPass resets the edit status of all cells", "please use the existing definition of next render and test-harness frame holding" or "let's do it after the guard clause, since all tests stay green". I'm lacking context though, even with the explanation. And it feels odd to be the meat puppet.

Also, I've been told not to trigger AI code reviews without consent. Would that be ok for you in general, to invite Copilot to a PR?

@myabc myabc closed this Oct 26, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ai: Directed 🪄 A human specified the requirements and AI implemented most of it; They validated via testing. bugfix DO NOT MERGE javascript Pull requests that update Javascript code

Development

Successfully merging this pull request may close these issues.

2 participants