Skip to content

feat(tables): freeze columns#4770

Open
waleedlatif1 wants to merge 6 commits into
stagingfrom
fix/frozen
Open

feat(tables): freeze columns#4770
waleedlatif1 wants to merge 6 commits into
stagingfrom
fix/frozen

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Add column freezing (pin to left) for the Tables grid — inspired by Clay/Airtable
  • Frozen columns use position: sticky with computed left offsets stacked after the checkbox column
  • Workflow output columns freeze/unfreeze as a group
  • Visual separator (box-shadow) on the rightmost frozen column in both header and data rows
  • Freeze state persists to TableMetadata via updateMetadataMutation; seeded from metadata on load
  • Added frozenColumns?: string[] to TableMetadata type and tableMetadataSchema

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped May 28, 2026 6:26pm

Request Review

@cursor
Copy link
Copy Markdown

cursor Bot commented May 28, 2026

PR Summary

Medium Risk
Touches core table grid layout, column order/metadata persistence, and undo paths; no auth or data-model changes, but incorrect sticky/offset logic could affect editing and scrolling UX.

Overview
Adds column freezing to the workspace table grid: users can pin columns (or whole workflow output groups) to the left via Freeze / Unfreeze column in the column options menu.

Frozen columns use position: sticky with computed left offsets (after the checkbox gutter), a separator on the rightmost frozen column, and state persisted in TableMetadata.frozenColumns (schema + load/rename/delete/reorder paths). Freezing also moves frozen columns to the front of columnOrder; drag-reorder re-sorts so frozen columns stay left. Horizontal scroll-to-reveal now accounts for the full frozen zone instead of only the row-number column. Undo for column delete restores prior frozen metadata; DataRow memoization keys off frozen offset maps with a width fingerprint to limit re-renders on non-frozen resizes.

Also removes in-header change column type wiring (onChangeType / handleChangeType) and switches the header chevron to emcn icons.

Reviewed by Cursor Bugbot for commit b37a049. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 28, 2026

Greptile Summary

This PR adds a "freeze column" (pin-to-left) feature to the Tables grid, persisting state to TableMetadata via frozenColumns?: string[]. Frozen columns use position: sticky with computed left offsets stacked after the checkbox gutter, and workflow-output columns freeze/unfreeze as a group.

  • handleFreezeToggle reorders frozen columns to the front of columnOrder on freeze and updates metadata; frozenOffsets, lastFrozenColKey, and frozenStickyLeftEdge are derived via useMemo and flow down to ColumnHeaderMenu, WorkflowGroupMetaCell, and DataRow.
  • The undo hook is extended with getFrozenColumns / onFrozenColumnsChange so delete-column redo correctly strips the deleted column from current (not snapshot) frozen state — fixing the stale-snapshot bug from the prior review cycle.
  • onChangeType / handleChangeType are removed from the header menu path; the ColumnOptionsMenu docstring confirms type changes were already relocated to the column config sidebar.

Confidence Score: 5/5

Safe to merge — the freeze feature is well-contained, no data mutation paths are affected, and the previously identified undo/redo stale-snapshot bug has been addressed.

All changes are UI-preference state (sticky offsets, column ordering) with no write path to row data. The undo/redo extension for delete-column correctly reads live frozen state via a getter ref, matching the pattern already used for column widths. The onChangeType removal is intentional per the component docstring. No regressions found in the freeze toggle logic, metadata seeding, or scroll-to-reveal update.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/table-grid.tsx Core implementation of freeze-column feature: adds frozenColumns state, handleFreezeToggle, frozenOffsets/lastFrozenColKey/frozenStickyLeftEdge derived values, and wires sticky props into ColumnHeaderMenu, WorkflowGroupMetaCell, and DataRow. The drag-drop handler re-enforces frozen-at-front ordering. Scroll-to-reveal updated with frozenStickyLeftEdge. handleChangeType/onChangeType removed (intentional — type changes now live in the column sidebar).
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/column-header-menu.tsx Adds isFrozen, onFreezeToggle, stickyLeft, and isLastFrozen props; applies sticky positioning and separator shadow on the frozen column header; passes freeze props to ColumnOptionsMenu. Removes onChangeType (intentional — type changes moved to sidebar).
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/workflow-group-meta-cell.tsx Adds freeze props to both WorkflowGroupMetaCell and ColumnOptionsMenu; renders freeze/unfreeze menu item; applies sticky positioning to the meta header cell. useCallback wrappers removed from event handlers (pre-existing regression already flagged in prior review).
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/data-row.tsx Adds frozenOffsets and lastFrozenColKey props; applies position:sticky + z-index + bg to frozen cells and separator shadow on the last frozen column. Equality comparator updated to include both new props.
apps/sim/hooks/use-table-undo.ts Adds onFrozenColumnsChange / getFrozenColumns callbacks; undo restores previousFrozenColumns; redo reads current frozen state via getFrozenColumnsRef and strips the deleted column, fixing the stale-snapshot bug from the prior review.
apps/sim/lib/api/contracts/tables.ts Adds frozenColumns as an optional string array to tableMetadataSchema — a minimal, safe schema extension.
apps/sim/lib/table/types.ts Adds frozenColumns?: string[] to TableMetadata interface with a descriptive JSDoc comment.
apps/sim/stores/table/types.ts Adds previousFrozenColumns: string[]

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User clicks Freeze/Unfreeze in column menu] --> B{Column has workflowGroupId?}
    B -- Yes --> C[Collect all sibling column names in group]
    B -- No --> D[Use single column name]
    C --> E{Currently frozen?}
    D --> E
    E -- Unfreeze --> F[Filter siblings out of frozenColumns]
    E -- Freeze --> G[Append siblings to frozenColumns]
    G --> H[Re-enforce frozen-at-front in columnOrder]
    H --> I[setColumnOrder + columnOrderRef]
    F --> J[setFrozenColumns + frozenColumnsRef]
    I --> J
    J --> K[updateMetadata with frozenColumns + columnOrder]
    K --> L[Server persists to TableMetadata]
    J --> M[frozenColumnSet useMemo]
    M --> N[frozenOffsets useMemo key to sticky left px]
    M --> O[lastFrozenColKey useMemo]
    N --> P[frozenStickyLeftEdge useMemo]
    N --> Q[ColumnHeaderMenu stickyLeft + isLastFrozen]
    N --> R[WorkflowGroupMetaCell stickyLeft + isLastFrozen]
    N --> S[DataRow frozenOffsets + lastFrozenColKey]
    P --> T[Scroll-to-reveal inset]
Loading

Reviews (5): Last reviewed commit: "fix(tables): use current frozenColumns o..." | Re-trigger Greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ 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 6d19730. Configure here.

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/hooks/use-table-undo.ts
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ 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 6526129. Configure here.

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

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.

1 participant