Skip to content

improvement(tables): migrate inputs to emcn chip components and clean up tables feature#4995

Open
waleedlatif1 wants to merge 1 commit into
stagingfrom
worktree-tables-emcn-input-migration
Open

improvement(tables): migrate inputs to emcn chip components and clean up tables feature#4995
waleedlatif1 wants to merge 1 commit into
stagingfrom
worktree-tables-emcn-input-migration

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • migrate all form-style inputs in the tables feature to the emcn chip family: column name (column-config + workflow sidebars), enrichment output names, enrichments search (with icon={Search}), table find, and filter value now use ChipInput; filter column/operator pickers now use ChipDropdown instead of hand-rolled 28px pills
  • drive error states through the error prop instead of className border overrides; fix ChipCombobox error misuse where the message replaced the options list (workflow picker, enrichment input mapping)
  • fix undefined --text-danger CSS var (rendered in currentColor, not red) and wrong text-destructive token in field errors — both now --text-error
  • hoist duplicated RequiredLabel/FieldError into shared sidebar-fields, extract ActionIconButton in the table action bar (4x duplicated chrome string), align enrichments-sidebar close buttons with sibling sidebars, swap lucide X/ChevronDown for the emcn icons
  • cleanup pass over the tables feature: keyed ExpandedCellEditor so an in-progress cell draft survives SSE/refetch row updates; memoize filter/aside props feeding the memoized Resource.Header/Resource.Options; derive uploading from uploadProgress; drop unstable mutation object from handleCreateTable deps; delete dead useTableRows hook

Type of Change

  • Improvement

Testing

bun run check:api-validation passes, tables unit tests pass (28/28), typecheck clean. 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

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 12, 2026 7:02am

Request Review

@cursor

cursor Bot commented Jun 12, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Mostly presentational component swaps and shared UI helpers; the expanded-cell editor change is localized UX/state behavior with no auth or data-model changes.

Overview
Standardizes tables UI on emcn chip controls (ChipInput, ChipDropdown) for column names, enrichment search/output names, find-in-table, and filter value entry; filter column/operator pickers move off hand-rolled dropdowns to ChipDropdown.

Validation and styling: field errors use the error prop on chip inputs instead of border class overrides; workflow/enrichment comboboxes stop passing error strings into ChipCombobox (which broke the options UI) and show separate messages; shared RequiredLabel / FieldError live in sidebar-fields with --text-error / text-caption tokens.

UX and perf fixes: expanded cell editing is split into a keyed ExpandedCellEditor so drafts survive row refetches while the popover stays open; memoized filter / aside props for Resource.Options / Resource.Header; CSV list upload derives uploading from uploadProgress; dead useTableRows hook removed. Minor refactors: ActionIconButton in the action bar, emcn close icons/buttons on enrichments sidebar.

Reviewed by Cursor Bugbot for commit 5bbc574. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5bbc574. Configure here.

align='start'
matchTriggerWidth={false}
className='min-w-[100px]'
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Filter hides missing column label

Low Severity

Replacing the column picker with ChipDropdown drops the previous fallback when rule.column is set but no longer appears in options (for example after a column was removed). The trigger shows the placeholder Column even though a column id is still selected, so the active rule looks unset while the filter logic may still use the stale id.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5bbc574. Configure here.

@greptile-apps

greptile-apps Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR migrates all form-style inputs across the tables feature to the emcn chip component family (ChipInput, ChipDropdown, ChipCombobox) and performs a focused cleanup pass — fixing broken CSS variable references, extracting shared RequiredLabel/FieldError components, deduplicating ActionIconButton, and removing the dead useTableRows hook.

  • UI migration: InputChipInput (with error boolean prop replacing className border overrides), hand-rolled dropdown pills → ChipDropdown, --text-danger/text-destructive--text-error/text-caption throughout sidebars and filter rows.
  • ExpandedCellEditor refactor: Extracted as a keyed child component so the textarea draft survives SSE/polling row refetches without being reset; memoization of filterConfig and handleToggleFilter prevents defeating React.memo on Resource.Options.
  • Correctness fix: ChipCombobox's error string prop (which replaced the options list with the error message rather than styling the trigger) removed in workflow-sidebar and enrichment-config; errors now render as a separate FieldError element below the combobox.

Confidence Score: 4/5

Safe to merge; all changes are additive UI migrations and correctness fixes with no data-path or API-contract changes.

The ChipCombobox error-misuse fix, CSS variable correction, and ExpandedCellEditor keying are all improvements over the previous state. The only open question is the inline error paragraph in enrichment-config.tsx lacking the pl-0.5 spacing that FieldError provides, leaving a minor visual inconsistency. No regressions identified in the core table data or mutation paths.

enrichment-config.tsx — the input-mapping validation error paragraph should use FieldError for consistent padding.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/expanded-cell-popover.tsx Extracts ExpandedCellEditor into a keyed child component so the textarea draft survives SSE/polling row refetches; focus and ref wiring are correct
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-filter/table-filter.tsx Replaces hand-rolled dropdown pills and raw input with ChipDropdown/ChipInput; OPERATOR_LABELS constant correctly removed as ChipDropdown handles label lookup internally
apps/sim/app/workspace/[workspaceId]/tables/tables.tsx Derives uploading from uploadProgress.total, memoizes filterConfig and headerAside to stabilize props into memoized Resource sub-components; drops createTable from handleCreateTable deps with appropriate eslint-disable
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/sidebar-fields/sidebar-fields.tsx New shared component exporting RequiredLabel and FieldError; fixes text-destructive → text-[var(--text-error)] token; well-structured extraction
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx Migrates Input → ChipInput with error prop, fixes ChipCombobox error-string misuse (which replaced the options list) by using a separate FieldError below the combobox
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichment-config.tsx Migrates Input → ChipInput, fixes ChipCombobox error misuse; inline error paragraph for input mappings lacks pl-0.5 padding that FieldError provides
apps/sim/hooks/queries/tables.ts Removes dead useTableRows hook (superseded by useInfiniteTableRows), fixes misplaced JSDoc comment, updates cache shape comment to reflect single-hook reality
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/table.tsx Memoizes filterConfig and handleToggleFilter to avoid defeating the memoized Resource.Options on every render
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-action-bar/table-action-bar.tsx Extracts ActionIconButton to eliminate four copies of the Tooltip+Button chrome string; correct and clean refactor
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/table-find.tsx Migrates Input → ChipInput, removes explicit h-8 height class; ChevronDown/Up still import from lucide-react but those were not in scope for this PR
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/run-settings-section.tsx Fixes --text-danger → --text-error CSS variable and text-xs → text-caption token for error paragraph
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichments-sidebar.tsx Migrates search Input → ChipInput with icon prop, replaces hand-rolled close buttons with Button component to align with sibling sidebars
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-config-sidebar/column-config-sidebar.tsx Migrates Input → ChipInput with error boolean prop, pulls RequiredLabel/FieldError from shared sidebar-fields, removes local duplicates
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/index.ts Re-exports new sidebar-fields module from the feature barrel
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/sidebar-fields/index.ts Barrel file for sidebar-fields; clean export

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph "New shared: sidebar-fields"
        RF[RequiredLabel]
        FE[FieldError]
    end

    subgraph "column-config-sidebar"
        CC[ColumnConfigBody] -->|imports| RF
        CC -->|imports| FE
        CC -->|ChipInput error=Boolean| CI1[ChipInput]
    end

    subgraph "workflow-sidebar"
        WS[WorkflowSidebarBody] -->|imports| RF
        WS -->|imports| FE
        WS -->|ChipInput error=Boolean| CI2[ChipInput]
        WS -->|error prop removed| CCB1[ChipCombobox]
        WS -->|renders below| FE
    end

    subgraph "enrichment-config"
        EC[EnrichmentConfig] -->|ChipInput error=Boolean| CI3[ChipInput]
        EC -->|error prop removed| CCB2[ChipCombobox]
        EC -->|inline p.text-error| ERR[error paragraph]
    end

    subgraph "table-filter"
        TF[FilterRuleRow] -->|was hand-rolled pill| CD1[ChipDropdown column]
        TF -->|was hand-rolled pill| CD2[ChipDropdown operator]
        TF -->|was raw input| CI4[ChipInput value]
    end

    subgraph "expanded-cell-popover"
        ECP[ExpandedCellPopover] -->|key=rowId:colKey| ECE[ExpandedCellEditor]
        ECE -->|useState initialValue| DV[draftValue preserved on SSE refetch]
    end

    subgraph "tables.tsx"
        T[Tables] -->|derived| UP[uploading = uploadProgress.total > 0]
        T -->|useMemo| FC[filterConfig stable ref]
        T -->|useMemo| HA[headerAside stable ref]
    end
Loading

Comments Outside Diff (1)

  1. apps/sim/app/workspace/[workspaceId]/tables/tables.tsx, line 513-517 (link)

    P2 The createTable mutation object is closed over in handleCreateTable but omitted from its useCallback deps. In TanStack Query v5, mutateAsync is stable, so the lint suppression is valid for that access. However, createTable.isPending is read in the headerActions useMemo at line 546 and correctly listed in that memo's dep array via createTable.isPending. The only risk here is if a future change accesses additional createTable properties inside this callback — the eslint-disable would silently hide the missing dep. A slightly safer pattern is to destructure only mutateAsync at the call site so the suppress comment is scoped to exactly what's stable.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "improvement(tables): migrate inputs to e..." | Re-trigger Greptile

Comment on lines +146 to +154
<ExpandedCellEditor
key={`${expandedCell.rowId}:${expandedCell.columnKey ?? expandedCell.columnName}`}
initialValue={formatValueForInput(target.value, target.column.type)}
column={target.column}
rowId={target.row.id}
onSave={onSave}
onClose={onClose}
textareaRef={textareaRef}
/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 textareaRef focus during key-driven remount

When expandedCell changes, the useLayoutEffect (line 72) and the key on ExpandedCellEditor both react simultaneously. React unmounts the old editor, mounts the new one, attaches the ref, then runs layout effects — so textareaRef.current is set to the new textarea by the time the effect fires and the requestAnimationFrame fires a frame later. This is correct as written. Worth noting for future maintainers: if the focus logic ever moves outside useLayoutEffect into a regular useEffect, there could be a one-frame window where the ref is null between the old unmount and the new commit.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +283 to +285
{showValidation && input.required && !inputMappings[input.id] && (
<p className='text-[var(--text-error)] text-caption'>Required</p>
)}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 The inline error paragraph for input mapping validation is missing the pl-0.5 left-padding that the shared FieldError component applies. Using FieldError here would keep spacing consistent across all sidebar field errors.

Suggested change
{showValidation && input.required && !inputMappings[input.id] && (
<p className='text-[var(--text-error)] text-caption'>Required</p>
)}
{showValidation && input.required && !inputMappings[input.id] && (
<FieldError message='Required' />
)}

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