Skip to content

Fix pat-structure folder contents sort order [5.6.x]#1611

Open
petschki wants to merge 1 commit into
5.6.xfrom
fix-structure-sorting-race
Open

Fix pat-structure folder contents sort order [5.6.x]#1611
petschki wants to merge 1 commit into
5.6.xfrom
fix-structure-sorting-race

Conversation

@petschki

@petschki petschki commented Jul 1, 2026

Copy link
Copy Markdown
Member

Problem

In pat-structure (folder_contents) the listing is sorted incorrectly once a folder contains more than a few items. The server response (@@getVocabulary) is correctly ordered — only the rendered table is scrambled.

Root cause

The table row rendering in src/pat/structure/js/views/table.js iterates the collection with an async callback that appends each row only after await view.render(). Since collection.each does not await and row rendering is async (icon resolution, action menu), rows get appended in the order their render promises resolve rather than in collection order. With few rows this is invisible; with more rows the race scrambles the DOM order, and DataTables (order: []) does not re-sort it.

Why it only appeared in 5.6.0+

The race has existed since 5.4.x but was masked: DataTables was initialized with order: [0, "asc"], which re-sorted rows by the hidden _sort (server order) column on every draw. #1552 changed this to order: [] — correct in intent, but it removed the safety net that had been hiding the race, so the bug became visible in 5.6.0. Not reproducible in Plone 6.1 / mockup 5.4.x.

Fix

Build the row views in collection order, render them in parallel via Promise.all, then append them in order — so the DOM order always matches the collection order, independent of any DataTables ordering setting. The now-obsolete table_row_rendering_finished event mechanism is removed.

The table row rendering iterated the collection with an async callback
(`collection.each(async ...)`) that appended each row only after awaiting
`view.render()`. Row rendering is async (it awaits icon resolution), so
rows were appended in the arbitrary order their render promises resolved
rather than in collection order, corrupting the sort order of the folder
contents.

This stayed hidden until 5.6.0: DataTables was initialized with
`order: [0, "asc"]`, which re-sorted the rows by the hidden `_sort`
column (the server order index) on every draw and thus masked the race.
Commit 57cd7dd ("Fix ordering logic.") changed this to `order: []`,
removing the safety net and exposing the underlying bug.

Fix the root cause: build the row views in collection order, render them
all in parallel via `Promise.all`, then append them in order. This
guarantees the DOM order matches the collection order regardless of the
DataTables ordering settings. The now-obsolete
`table_row_rendering_finished` event dance and its `events` import are
removed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@petschki petschki requested review from pbauer and thet July 1, 2026 10:31
@petschki

petschki commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

/run-coredev-robottests

@pbauer pbauer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants