fix(resources): sort folders and resources as one list so pinned items reach the top - #6213
Conversation
Folders and their sibling resources were sorted as two lists and concatenated folders-first, so a pinned file, table, or knowledge base could never rank above an unpinned folder — pinning only reordered within each partition. Sort them as one list instead: pinned -> sort key -> name, in a shared `sortResources` comparator. Rows with no value for the active column (a folder has no row count or token count) sort last in both directions, and the name tiebreak is never inverted by `desc`. Also aligns the surfaces that browse the same resources: the mothership resource trees, the collapsed sidebar flyout (whose nested levels partitioned folders-first while its own root interleaved), the sidebar file tree, and the recently-deleted tiebreak. Files' sort params were nullable only to encode "folders name/asc, files updated/desc"; with one list that state is gone, so they default to updated/desc like Tables and Knowledge.
…urce lists Files, Tables, and Knowledge already prefetched their items and folders, but not the two lists a complete row needs. Pinned ids are the list's primary sort key now, so a page that painted before they arrived rendered the whole list in the wrong order and then visibly re-sorted. Members back the Owner column, which painted empty and filled in after. Both now hydrate alongside the lists via `prefetchResourceListChrome`. Pinned keys move to `hooks/queries/utils/pinned-item-keys` so the server prefetch can address them without pulling the contracts barrel and the optimistic-mutation machinery into the route.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Files drops nullable URL sort params and uses the same default Prefetch for Files, Tables, and Knowledge now also hydrates pinned ids (resource + folder pin namespaces) and workspace members so the first paint matches final order and Owner cells don’t flash empty. Browse and sidebar surfaces are aligned with the pages: mothership Removes legacy knowledge card grid pieces ( Reviewed by Cursor Bugbot for commit 3e494e2. Configure here. |
Greptile SummaryThe PR unifies folders and sibling resources under shared ordering so pinned resources can rank above unpinned folders.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| apps/sim/app/workspace/[workspaceId]/components/folders/resource-sort.ts | Introduces the shared comparator with deterministic pin, null-key, direction, and name-tiebreak behavior. |
| apps/sim/app/workspace/[workspaceId]/files/files.tsx | Merges visible folders and filtered files into one decorated and sorted row sequence. |
| apps/sim/app/workspace/[workspaceId]/tables/tables.tsx | Applies the shared merged ordering to tables and folders while preserving filtering and rendering behavior. |
| apps/sim/app/workspace/[workspaceId]/knowledge/knowledge.tsx | Applies merged resource ordering to knowledge bases and removes reliance on the former separate sort utility. |
| apps/sim/app/workspace/[workspaceId]/lib/prefetch-resource-list-chrome.ts | Prefetches resource and folder pin state plus workspace members under keys matching the client hooks. |
| apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/add-resource-dropdown/resource-folder-tree.ts | Interleaves folders and items deterministically at every tree level by name or explicit sort order. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Lists[Folders and resources] --> Decorate[Compute pin state, active key, and name]
Pins[Pinned IDs] --> Decorate
Members[Workspace members] --> Decorate
Decorate --> Sort[Sort pinned first, then active key, then name]
Sort --> Rows[Render one interleaved resource list]
Reviews (3): Last reviewed commit: "chore(knowledge): delete the dead base-c..." | Re-trigger Greptile
`sortKnowledgeBases` was a second, complete ordering for knowledge bases (name/createdAt/updatedAt/docCount) left over from the old sort dropdown, with no consumers since the shared Resource sort menu replaced it — the kind of duplicate that silently diverges from the page it shadows. Its `SortOption`/`SortOrder` types and the `SORT_OPTIONS` list that fed it were dead with it. `utils/sort.ts` now holds only a filter, so it is renamed to `utils/filter.ts`.
… menu An owner id that resolves to no workspace member renders an empty cell, but its sort key was `''`, so those rows floated to the TOP of an ascending Owner sort while every other valueless cell sorted last. They now key `null` and follow the same nulls-last rule on all three pages. The Knowledge sort menu also listed Owner after Last Updated while its column order — and Tables' menu — put Owner before it.
|
@cursor review |
`BaseCard`/`BaseCardSkeleton`/`BaseCardSkeletonGrid` were the pre-redesign grid-card knowledge base view, kept alive only by the barrel re-export — no call sites since the Resource list replaced it. Removing it orphans `components/constants.ts` entirely (its sort types went with the dead sort; its three class-name constants had no consumers left), so that goes too.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 3e494e2. Configure here.
Summary
sortResourcescomparator:pinned → sort key → namedescsortOrder), the sidebar file tree, and the recently-deleted tiebreakupdated/desclike Tables and KnowledgeType of Change
Testing
Unit tests for the comparator (interleaving, pinned floats over unpinned folders in both directions, nulls last, direction-independent name tiebreak) and for the browse-tree ordering and the new prefetch keys. Verified each test goes red when the behavior is reverted.
tsc,bun run lint,check:client-boundary,check:react-query,check:api-validationall pass. Not yet verified in a running browser.Checklist