Skip to content

Commit 634eef7

Browse files
committed
refactor(tables): inject the cell editor instead of importing it
Completes the presentational/editing split at the row level. `DataRow` took an `InlineEditor` import and constructed the editor itself, which would have carried the whole write path — and its authenticated `useTimezone` — into the moved view layer. It now takes a `renderCellEditor` callback and renders whatever the host returns. `TableGrid` supplies it, which is where it belongs: the closure needs the pending-update state and the save/cancel handlers that own the mutation. A surface with no write path passes nothing and renders no editor. `DataRow.workspaceId` also becomes optional, matching `CellContent` — the two together are the seam a share-scope surface needs. Note the failure mode this deliberately avoids: making the prop optional means `tsc` stays green whether or not the shell wires it, so the callsite and the memo comparator were both updated in this change rather than left to a later one.
1 parent d8b10aa commit 634eef7

2 files changed

Lines changed: 41 additions & 21 deletions

File tree

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/data-row.tsx

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
'use client'
22

3-
import React from 'react'
3+
import React, { type ReactNode } from 'react'
44
import { Button, Checkbox, cn, handleKeyboardActivation } from '@sim/emcn'
55
import { PlayOutline, Square } from '@sim/emcn/icons'
66
import type { ActiveDispatch } from '@/lib/api/contracts/tables'
77
import type { TableRow as TableRowType, WorkflowGroup } from '@/lib/table'
88
import { getUnmetGroupDeps } from '@/lib/table/deps'
99
import type { SaveReason } from '../../types'
10-
import { CellContent, InlineEditor } from './cells'
10+
import { CellContent } from './cells'
1111
import {
1212
CELL,
1313
CELL_CHECKBOX,
@@ -21,9 +21,17 @@ import { type NormalizedSelection, resolveCellExec } from './utils'
2121
export interface DataRowProps {
2222
row: TableRowType
2323
columns: DisplayColumn[]
24-
/** Current workspace id — forwarded to cells so in-workspace resource URLs
25-
* render as tagged-resource chips. */
26-
workspaceId: string
24+
/**
25+
* Current workspace id — forwarded to cells so in-workspace resource URLs render
26+
* as tagged-resource chips. Optional: a surface with no workspace identity (an
27+
* anonymous share) omits it and those chips are never emitted.
28+
*/
29+
workspaceId?: string
30+
/**
31+
* Builds the inline editing surface for a cell. Supplied by the host that owns
32+
* the write path, so a read-only surface renders — and bundles — no editor.
33+
*/
34+
renderCellEditor?: (cell: { row: TableRowType; column: DisplayColumn }) => ReactNode
2735
rowIndex: number
2836
isFirstRow: boolean
2937
editingColumnName: string | null
@@ -111,6 +119,7 @@ function dataRowPropsAreEqual(prev: DataRowProps, next: DataRowProps): boolean {
111119
prev.pendingCellValue !== next.pendingCellValue ||
112120
prev.onClick !== next.onClick ||
113121
prev.onDoubleClick !== next.onDoubleClick ||
122+
prev.renderCellEditor !== next.renderCellEditor ||
114123
prev.onSave !== next.onSave ||
115124
prev.onCancel !== next.onCancel ||
116125
prev.onContextMenu !== next.onContextMenu ||
@@ -156,6 +165,7 @@ export const DataRow = React.memo(function DataRow({
156165
editingColumnName,
157166
initialCharacter,
158167
pendingCellValue,
168+
renderCellEditor,
159169
normalizedSelection,
160170
isRowChecked,
161171
onClick,
@@ -376,21 +386,7 @@ export const DataRow = React.memo(function DataRow({
376386
)}
377387
column={column}
378388
isEditing={isEditing}
379-
editor={
380-
isEditing ? (
381-
<InlineEditor
382-
value={
383-
pendingCellValue && column.key in pendingCellValue
384-
? pendingCellValue[column.key]
385-
: row.data[column.key]
386-
}
387-
column={column}
388-
initialCharacter={initialCharacter ?? undefined}
389-
onSave={(value, reason) => onSave(row.id, column.key, value, reason)}
390-
onCancel={onCancel}
391-
/>
392-
) : undefined
393-
}
389+
editor={isEditing ? renderCellEditor?.({ row, column }) : undefined}
394390
waitingOnLabels={
395391
column.workflowGroupId
396392
? (waitingByGroupId?.get(column.workflowGroupId) ?? undefined)

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/table-grid.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import type { ColumnConfig } from '../column-config-sidebar'
5050
import { ContextMenu } from '../context-menu'
5151
import { NewColumnDropdown } from '../new-column-dropdown'
5252
import type { WorkflowConfig } from '../workflow-sidebar'
53-
import { ExpandedCellPopover } from './cells'
53+
import { ExpandedCellPopover, InlineEditor } from './cells'
5454
import { ADD_COL_WIDTH, COL_WIDTH, SELECTION_TINT_BG } from './constants'
5555
import { DataRow } from './data-row'
5656
import { ColumnHeaderMenu, WorkflowGroupMetaCell } from './headers'
@@ -3683,6 +3683,29 @@ export function TableGrid({
36833683

36843684
const pendingUpdate = updateRowMutation.isPending ? updateRowMutation.variables : null
36853685

3686+
/**
3687+
* The inline editing surface for a cell. Built here rather than inside `DataRow`
3688+
* because it is the write path: it closes over the pending-update state and the
3689+
* save/cancel handlers that own the mutation. A read-only surface passes no
3690+
* `renderCellEditor` at all and therefore renders — and bundles — no editor.
3691+
*/
3692+
const renderCellEditor = useCallback(
3693+
({ row, column }: { row: TableRowType; column: DisplayColumn }) => (
3694+
<InlineEditor
3695+
value={
3696+
pendingUpdate && pendingUpdate.rowId === row.id && column.key in pendingUpdate.data
3697+
? pendingUpdate.data[column.key]
3698+
: row.data[column.key]
3699+
}
3700+
column={column}
3701+
initialCharacter={initialCharacter ?? undefined}
3702+
onSave={(value, reason) => handleInlineSave(row.id, column.key, value, reason)}
3703+
onCancel={handleInlineCancel}
3704+
/>
3705+
),
3706+
[pendingUpdate, initialCharacter, handleInlineSave, handleInlineCancel]
3707+
)
3708+
36863709
/**
36873710
* Row ids for the current multi-row selection. Drives "Run N selected rows"
36883711
* in the workflow-group run menu — `null` when there's no multi-selection so
@@ -4287,6 +4310,7 @@ export function TableGrid({
42874310
onDoubleClick={handleCellDoubleClick}
42884311
onSave={handleInlineSave}
42894312
onCancel={handleInlineCancel}
4313+
renderCellEditor={renderCellEditor}
42904314
onContextMenu={handleRowContextMenu}
42914315
onCellMouseDown={handleCellMouseDown}
42924316
onCellMouseEnter={handleCellMouseEnter}

0 commit comments

Comments
 (0)