Skip to content

Commit 1da718f

Browse files
committed
improvement(tables): react-doctor safe performance pass
Apply high-confidence, behavior-preserving perf fixes surfaced by react-doctor on the tables module: - Lazy-init the import-status ref so it stops allocating and discarding a fresh Map on every render (rerender-lazy-ref-init). - expandToDisplayColumns: build an outputs-by-column-name Map once per workflow group instead of Array.find() per column (js-index-maps). - Sort the tables list with toSorted() instead of [...list].sort() (js-tosorted-immutable; ES2023 lib is enabled for apps/sim). - Hoist the static TITLE_BY_MODE map and the pure editor wheel handler to module scope so they are not rebuilt each render. Left the effect/selection refactors (state-synced-to-prop, effect chains) untouched: those effects react to async-loaded rows and are not the copy-a-prop-into-state anti-pattern; refactoring them needs live grid verification. Barrel-import findings are false positives against the repo's mandated barrel-import convention.
1 parent 42e3a03 commit 1da718f

5 files changed

Lines changed: 27 additions & 20 deletions

File tree

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ interface InlineEditorProps {
1919
onCancel: () => void
2020
}
2121

22+
/** Redirect wheel gestures over an inline editor to the surrounding table scroll container. */
23+
function handleEditorWheel(e: React.WheelEvent<HTMLInputElement>) {
24+
e.preventDefault()
25+
const container = e.currentTarget.closest('[data-table-scroll]') as HTMLElement | null
26+
if (container) {
27+
container.scrollBy(e.deltaX, e.deltaY)
28+
}
29+
}
30+
2231
/** Inline editor for `date` columns — text input + popover calendar. */
2332
function InlineDateEditor({
2433
value,
@@ -152,14 +161,6 @@ function InlineTextEditor({
152161
}
153162
}, [])
154163

155-
const handleWheel = (e: React.WheelEvent<HTMLInputElement>) => {
156-
e.preventDefault()
157-
const container = e.currentTarget.closest('[data-table-scroll]') as HTMLElement | null
158-
if (container) {
159-
container.scrollBy(e.deltaX, e.deltaY)
160-
}
161-
}
162-
163164
const doSave = (reason: SaveReason) => {
164165
if (doneRef.current) return
165166
doneRef.current = true
@@ -194,7 +195,7 @@ function InlineTextEditor({
194195
value={draft ?? ''}
195196
onChange={(e) => setDraft(e.target.value)}
196197
onKeyDown={handleKeyDown}
197-
onWheel={handleWheel}
198+
onWheel={handleEditorWheel}
198199
onBlur={() => doSave('blur')}
199200
className='w-full min-w-0 select-text border-none bg-transparent p-0 text-[var(--text-primary)] text-small outline-none'
200201
/>

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,13 @@ export function expandToDisplayColumns(
116116
size++
117117
}
118118
const group = groupById.get(gid)
119+
const outputByColumnName = group
120+
? new Map(group.outputs.map((o) => [o.columnName, o]))
121+
: undefined
119122
const startIdx = out.length
120123
for (let k = 0; k < size; k++) {
121124
const child = columns[i + k]
122-
const output = group?.outputs.find((o) => o.columnName === getColumnId(child))
125+
const output = outputByColumnName?.get(getColumnId(child))
123126
out.push({
124127
...child,
125128
key: getColumnId(child),

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ interface WorkflowSidebarProps {
121121

122122
const OUTPUT_VALUE_SEPARATOR = '::'
123123

124+
const TITLE_BY_MODE = {
125+
create: 'Add workflow',
126+
'edit-group': 'Configure workflow',
127+
'edit-output': 'Configure output column',
128+
} as const
129+
124130
const encodeOutputValue = (blockId: string, path: string) =>
125131
`${blockId}${OUTPUT_VALUE_SEPARATOR}${path}`
126132

@@ -772,15 +778,10 @@ export function WorkflowSidebarBody({
772778
updateWorkflowGroup.isPending ||
773779
updateColumn.isPending ||
774780
!depsValid
775-
const titleByMode = {
776-
create: 'Add workflow',
777-
'edit-group': 'Configure workflow',
778-
'edit-output': 'Configure output column',
779-
} as const
780781
const title =
781782
config.mode === 'create' && config.kind === 'enrichment' && config.enrichmentName
782783
? config.enrichmentName
783-
: titleByMode[config.mode]
784+
: TITLE_BY_MODE[config.mode]
784785
const showBackButton = isEnrichment && Boolean(onBack)
785786

786787
// edit-output mode is single-select on the output picker; everywhere else

apps/sim/app/workspace/[workspaceId]/tables/components/import-progress-menu/use-workspace-imports.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,14 @@ export function useWorkspaceImports(
5151
// jobs), so the tray reads them from their dedicated workspace listing.
5252
const { data: exportJobs } = useWorkspaceExportJobs(workspaceId)
5353

54-
const prevStatus = useRef<Map<string, string>>(new Map())
54+
const prevStatusRef = useRef<Map<string, string> | null>(null)
55+
prevStatusRef.current ??= new Map()
5556
useEffect(() => {
5657
if (!tables) return
58+
const prevStatus = prevStatusRef.current ?? new Map<string, string>()
5759
const store = useImportTrayStore.getState()
5860
for (const table of tables) {
59-
const before = prevStatus.current.get(table.id)
61+
const before = prevStatus.get(table.id)
6062
const now = table.jobStatus ?? 'none'
6163
if (before === 'running' && now === 'ready') {
6264
// Success toast only for imports — deletes reflect instantly in the grid and backfills
@@ -80,7 +82,7 @@ export function useWorkspaceImports(
8082
if (table.jobType === 'import') store.notify(table.id)
8183
}
8284
if (now !== 'running' && store.isCanceled(table.id)) store.consumeCanceled(table.id)
83-
prevStatus.current.set(table.id, now)
85+
prevStatus.set(table.id, now)
8486
}
8587
}, [tables])
8688

apps/sim/app/workspace/[workspaceId]/tables/tables.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export function Tables() {
185185
}
186186
const col = activeSort?.column ?? 'updated'
187187
const dir = activeSort?.direction ?? 'desc'
188-
return [...result].sort((a, b) => {
188+
return result.toSorted((a, b) => {
189189
let cmp = 0
190190
switch (col) {
191191
case 'name':

0 commit comments

Comments
 (0)