improvement(pinning): move pin into the context menu and make folders pinnable - #6039
Conversation
… pinnable - Replaces the hover-revealed inline pin button on Files, Knowledge, and Tables with a Pin/Unpin item in each row's right-click menu, labelled from current state - Deletes `PinButton` and the now-unused `ResourceCell.endAdornment` slot (plus the `group` class `DataRow` only carried for it) - Adds `folder` to `pinnedResourceTypeSchema` and `PINNED_RESOURCES` — no migration needed, `pinned_item.resource_type` is plain text — and wires Pin/Unpin into the Files folder rows, which sort pinned-first like every other list - Folder pins resolve against `workspace_file_folders`, not the generic `folder` table: file folders are still read and written there, and `folder`'s `resource_type = 'file'` rows are a one-time backfill new folders never reach
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Folders join the pinned-items contract ( Knowledge and Tables drop inline pins and call Reviewed by Cursor Bugbot for commit 6cdfd4d. Configure here. |
Greptile SummaryMoves pin/unpin from hover
Confidence Score: 5/5This PR appears safe to merge; pin moves to context menus and folder pins resolve against the live file-folder table with matching API/tests. Folder pins use workspaceFileFolder with deletedAt/workspace checks; file and folder pinned-first sorts remain; context-menu handlers pin the right-clicked row with stable mutation.mutate; no remaining PinButton consumers or blocking contract gaps.
|
| Filename | Overview |
|---|---|
| apps/sim/lib/pinned-items/resources.ts | Adds folder pin resolution to workspaceFileFolder with soft-delete and workspace scoping; intentional vs generic folder table. |
| apps/sim/app/workspace/[workspaceId]/files/files.tsx | Folder pin set, pinned-first folder sort, context-menu pin toggle for file vs folder resource types. |
| apps/sim/app/workspace/[workspaceId]/knowledge/knowledge.tsx | Removes row PinButton; wires pin toggle and pinned label on knowledge base context menu. |
| apps/sim/app/workspace/[workspaceId]/tables/tables.tsx | Removes row PinButton; wires pin toggle and pinned label on table context menu. |
| apps/sim/lib/api/contracts/pinned-items.ts | Extends pinnedResourceTypeSchema with folder. |
| apps/sim/components/pin-button.tsx | Deletes unused PinButton after context-menu migration. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
UI[Files / KB / Tables list]
CM[Context menu Pin / Unpin]
Hook[usePinItem / useUnpinItem]
API[POST/DELETE /api/pinned-items]
Res[PINNED_RESOURCES lookup]
FF[workspace_file_folders]
Other[workflow / files / KB / tables tables]
UI --> CM --> Hook --> API --> Res
Res -->|folder| FF
Res -->|other types| Other
Reviews (1): Last reviewed commit: "improvement(pinning): move pin into the ..." | Re-trigger Greptile
Summary
Pinning moved out of the hover-revealed inline button and into the right-click context menu, and folders became pinnable.
PinButtonis deleted (no consumers left), along with theResourceCell.endAdornmentslot it was the only user of and thegroupclassDataRowcarried solely so the button could reveal on hover.FileRowContextMenu,KnowledgeBaseContextMenu,TableContextMenu— using thePinicon from@sim/emcn/iconsand matching the neighbouring Rename / Copy ID / Delete items. The label reflects current state. On Files it is hidden in multi-select (like Rename), since a pin targets one row.'folder'added topinnedResourceTypeSchemaand toPINNED_RESOURCESin the same change, sofilterToActiveResourcesresolves folder pins rather than failing them closed. No migration —pinned_item.resource_typeis plaintext, not apgEnum. Wired into the Files folder rows only; KB and table folders don't exist yet and are being built in parallel PRs.One deviation worth reviewing
The brief specified backing
folderpins with the genericfoldertable. That would ship broken: #6025 moved only workflow folders onto it. File folders — the only pinnable folders today — are still read and written againstworkspace_file_folders, andfolder'sresource_type = 'file'rows are a one-time backfill from migration 0272 that no folder created afterwards ever reaches. Resolving againstfolderwould 404 every pin on a folder made since that migration.So
PINNED_RESOURCES.folderpoints atworkspaceFileFolder, documented in a TSDoc at the callsite. The 0272 backfill preserved folder ids, so when the file-folder cutover lands this entry repoints atfolder(scoped toresourceType = 'file') without invalidating a single existing pin.Type of Change
Testing
bunx tsc --noEmitclean inapps/simbun run lintandbun run check:api-validationpassbunx vitest run --root apps/sim lib/pinned-items app/api/pinned-items app/workspace— 98 files / 1221 tests greenresources.test.tsgains a case asserting folder pins resolve (regression guard for the contract/lookup-map pair — adding the enum member without thePINNED_RESOURCESentry would silently drop every folder pin), and the pre-existing "unknown resourceType fails closed" case was retargeted off'folder'since it is now a known type.app/api/pinned-items/route.test.tsgains a POST case coveringfolderend to end.Reviewers should focus on the
workspace_file_foldersvsfolderchoice above, and on the context-menu separator logic inTableContextMenu/KnowledgeBaseContextMenu— the new item joins the existing info group, so the surrounding separator conditions were widened to include it.Checklist