Skip to content

fix: keep the default table sorting alive past the first grid state save - #1787

Merged
AStaroverov merged 1 commit into
mainfrom
fix/pl-data-table-default-sorting
Aug 19, 2026
Merged

fix: keep the default table sorting alive past the first grid state save#1787
AStaroverov merged 1 commit into
mainfrom
fix/pl-data-table-default-sorting

Conversation

@AStaroverov

@AStaroverov AStaroverov commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

The problem

The default sorting a block passes to createPlDataTableV3({ sorting }) applies on the first render and then silently disappears: the sorted column stays in the table, the rows just stop being sorted.

resolveSorting (sdk/model/.../createPlDataTableV3.ts) reads the persisted user sorting three ways:

  • null — the user never touched sorting → apply the block's default;
  • [] — the user explicitly cleared the sorting → suppress the default.

The grid state never produced that null. AG Grid omits sort from its state while nothing is sorted, and convertAgSortingToPTableSorting turned the absent state into []. onStateUpdated fires as the grid initialises, so the first entry written to stateCache already stamped sorting: [] and the block's default was gone from that moment on.

Before @platforma-sdk/model@1.80.0 resolveSorting used isEmpty instead of isNil, so [] still fell through to the default and the bug stayed hidden. Going back to isEmpty is not the fix — it breaks clearing the sorting by hand.

The change

  • convertAgSortingToPTableSorting returns null for an absent sort state, and [] only for a genuinely empty sortModel.
  • normalizeSort in PlAgDataTableV2.vue promotes the absent state to an explicit { sortModel: [] } only once the grid has reported an explicit sort model before — so clearing the sorting by hand still suppresses the default. This is the same treatment the neighbouring normalizeColumnVisibility already gives hidden columns; both are now applied through normalizeGridState.
  • stateForReloadCompare treats an empty sortModel as equivalent to an absent one, so the promoted { sortModel: [] } does not read as a state change and trigger a grid reload.

Compatibility

Existing projects recover on the next render without a state migration: their stored gridState.sort is absent, which now reads as "untouched".

Verification

  • pnpm --filter @platforma-sdk/ui-vue run types:check — no errors in the changed files (the 18 errors elsewhere reproduce on a clean tree).
  • formatter:check, linter:check — clean.
  • New unit test table-state-v2.test.ts covering the three converter states, plus the package's existing node suites — green. PlDatasetSelector.jsdomtest.ts fails on a clean tree too in this environment.

Greptile Summary

The PR preserves a block’s default table sorting until the user explicitly changes or clears sorting, while retaining the distinction between untouched and intentionally empty state.

  • Default sorting — the block-provided ordering used when no user sorting preference exists; it now survives initial grid-state persistence.
  • Grid sort state — AG Grid’s optional sort object; an omitted object now remains distinguishable from an explicit empty sortModel.
  • User sorting — persisted table ordering selected by the user; null means untouched, while [] means explicitly cleared.
  • normalizeSort — the new transition normalizer that promotes an omitted sort to an explicit empty model only after an explicit sorting state previously existed.
  • stateForReloadCompare — the reload comparison representation; it now treats absent and empty AG Grid sort models as operationally equivalent.
  • Adds converter tests for absent, empty, ascending, and descending sort representations.

Confidence Score: 4/5

The PR appears safe to merge, with the non-blocking concern that its central sort-state transition logic is not directly covered by tests.

The nullable converter matches the receiving schema and model fallback semantics, and AG Grid initialization ordering contradicts the suspected sort-erasure path; only focused regression coverage for normalizeSort remains advisable.

Files Needing Attention: sdk/ui-vue/src/components/PlAgDataTable/PlAgDataTableV2.vue; sdk/ui-vue/src/components/PlAgDataTable/sources/table-state-v2.test.ts

Important Files Changed

Filename Overview
sdk/ui-vue/src/components/PlAgDataTable/PlAgDataTableV2.vue Adds transition-aware sort normalization and reload-comparison normalization; the behavior is coherent but lacks direct transition tests.
sdk/ui-vue/src/components/PlAgDataTable/sources/table-state-v2.ts Converts absent AG Grid sort state to the nullable untouched representation expected by the table-state schema and model resolver.
sdk/ui-vue/src/components/PlAgDataTable/sources/table-state-v2.test.ts Covers all converter representations but not the new normalizeSort state machine.
.changeset/pl-data-table-default-sorting.md Accurately documents the absent-versus-empty sorting-state fix and compatibility behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[AG Grid state update] --> B{sort present?}
  B -- Yes --> C[Persist explicit sortModel]
  B -- No --> D{Previous sort present?}
  D -- No --> E[Keep sort absent]
  D -- Yes --> F[Persist empty sortModel]
  E --> G[Converter returns null]
  F --> H[Converter returns empty array]
  C --> I[Converter returns user sorting]
  G --> J[Use block default sorting]
  H --> K[Suppress block default]
  I --> L[Use user sorting]
Loading

Fix all with Greploop Fix All in Claude Code

Prompt To Fix All With AI
### Issue 1
sdk/ui-vue/src/components/PlAgDataTable/PlAgDataTableV2.vue:237-250
**Test sort-state transitions**

`normalizeSort` now carries the central three-state contract, but the added tests cover only the converter. Directly test that untouched sorting stays absent, explicit sorting is preserved, and clearing a previous sort produces an empty model; otherwise a regression can discard the block default or restore it after the user clears sorting without failing this test suite.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix: keep the default table sorting aliv..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Context used:

`resolveSorting` falls back to the block's default sorting only while the
persisted user sorting is `null`; `[]` means the user cleared the sorting and
deliberately suppresses the default. The grid state never produced that `null`:
AG Grid omits `sort` while nothing is sorted, and the converter turned the
absent state into `[]`. Since `onStateUpdated` fires as the grid initialises,
the first persisted state entry stamped `sorting: []` and the default was gone
from that moment on — the sorted column stayed in the table, just unsorted.

The absent sort state now converts to `null`, and `normalizeSort` promotes it
to an explicit empty sort model only after the grid has reported an explicit
one, so clearing the sorting by hand still suppresses the default. This mirrors
`normalizeColumnVisibility`, which already draws the same distinction for
hidden columns.

`stateForReloadCompare` treats an empty sort model as absent, so the promoted
`{ sortModel: [] }` does not read as a state change and trigger a grid reload.
Comment thread sdk/ui-vue/src/components/PlAgDataTable/PlAgDataTableV2.vue
@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.97%. Comparing base (c291fe2) to head (5070b32).
⚠️ Report is 20 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1787   +/-   ##
=======================================
  Coverage   52.97%   52.97%           
=======================================
  Files         412      412           
  Lines       21322    21322           
  Branches     4761     4761           
=======================================
  Hits        11296    11296           
  Misses       8665     8665           
  Partials     1361     1361           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mzueva
mzueva self-requested a review August 19, 2026 08:15
@AStaroverov
AStaroverov added this pull request to the merge queue Aug 19, 2026
Merged via the queue into main with commit 64195d9 Aug 19, 2026
19 of 20 checks passed
@AStaroverov
AStaroverov deleted the fix/pl-data-table-default-sorting branch August 19, 2026 08:18
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