Skip to content

Commit cbb9cf4

Browse files
committed
fix(tables): harden inline column renaming
1 parent b549180 commit cbb9cf4

5 files changed

Lines changed: 21 additions & 15 deletions

File tree

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/column-header-menu.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,12 @@ describe('ColumnHeaderMenu interactions', () => {
132132
const headerButton = renderHeader({ onColumnSelect, onRenameColumn })
133133

134134
act(() => {
135-
headerButton.click()
136-
headerButton.click()
135+
headerButton.dispatchEvent(new MouseEvent('click', { bubbles: true, detail: 1 }))
136+
headerButton.dispatchEvent(new MouseEvent('click', { bubbles: true, detail: 2 }))
137137
headerButton.dispatchEvent(new MouseEvent('dblclick', { bubbles: true }))
138138
})
139139

140-
expect(onColumnSelect).toHaveBeenCalledTimes(2)
140+
expect(onColumnSelect).toHaveBeenCalledTimes(1)
141141
expect(onRenameColumn).toHaveBeenCalledWith('col-name')
142142
})
143143

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ export const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({
234234
return
235235
}
236236
if (isRenaming) return
237+
if (e.detail > 1) return
237238
onColumnSelect(colIndex, e.shiftKey)
238239
}
239240

@@ -293,7 +294,7 @@ export const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({
293294
<div className='flex h-full w-full min-w-0 items-center px-2 py-[7px]'>
294295
<ColumnTypeIcon
295296
type={column.type}
296-
isWorkflowColumn={!!column.workflowGroupId && ownGroup?.type !== 'enrichment'}
297+
isWorkflowColumn={isWorkflowOutput}
297298
blockIconInfo={sourceInfo?.blockIconInfo}
298299
blockMissing={blockMissing}
299300
/>
@@ -318,7 +319,7 @@ export const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({
318319
<div className='flex h-full w-full min-w-0 items-center px-2 py-[7px]'>
319320
<ColumnTypeIcon
320321
type={column.type}
321-
isWorkflowColumn={!!column.workflowGroupId && ownGroup?.type !== 'enrichment'}
322+
isWorkflowColumn={isWorkflowOutput}
322323
blockIconInfo={sourceInfo?.blockIconInfo}
323324
blockMissing={blockMissing}
324325
/>
@@ -338,7 +339,7 @@ export const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({
338339
>
339340
<ColumnTypeIcon
340341
type={column.type}
341-
isWorkflowColumn={!!column.workflowGroupId && ownGroup?.type !== 'enrichment'}
342+
isWorkflowColumn={isWorkflowOutput}
342343
blockIconInfo={sourceInfo?.blockIconInfo}
343344
blockMissing={blockMissing}
344345
/>

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@ export function TableGrid({
15041504
const handleFindCloseRef = useRef(handleFindClose)
15051505
handleFindCloseRef.current = handleFindClose
15061506

1507-
const [renameError, setRenameError] = useState(false)
1507+
const [renameErrorColumnId, setRenameErrorColumnId] = useState<string | null>(null)
15081508

15091509
const columnRename = useInlineRename({
15101510
// `columnName` is the column id; record the prior display name + id so undo
@@ -1519,7 +1519,7 @@ export function TableGrid({
15191519
if (isValidationError(error)) {
15201520
toast.error(extractValidationIssues(error)[0]?.message ?? getErrorMessage(error))
15211521
}
1522-
setRenameError(true)
1522+
setRenameErrorColumnId(columnName)
15231523
throw error
15241524
})
15251525
},
@@ -1528,7 +1528,7 @@ export function TableGrid({
15281528
columnRenameRef.current = columnRename
15291529

15301530
const handleRenameValueChange = useCallback((value: string) => {
1531-
setRenameError(false)
1531+
setRenameErrorColumnId(null)
15321532
columnRenameRef.current.setEditValue(value)
15331533
}, [])
15341534

@@ -1537,7 +1537,7 @@ export function TableGrid({
15371537
const { editingId, editValue, submitRename } = columnRenameRef.current
15381538
const trimmedName = editValue.trim()
15391539
const currentColumn = columnsRef.current.find((column) => column.key === editingId)
1540-
if (trimmedName && currentColumn && trimmedName !== currentColumn.name) {
1540+
if (currentColumn && trimmedName !== currentColumn.name) {
15411541
const issue = columnNameIssue(
15421542
trimmedName,
15431543
schemaColumnsRef.current
@@ -1546,16 +1546,16 @@ export function TableGrid({
15461546
)
15471547
if (issue) {
15481548
toast.error(issue)
1549-
setRenameError(true)
1549+
setRenameErrorColumnId(editingId)
15501550
return
15511551
}
15521552
}
1553-
setRenameError(false)
1553+
setRenameErrorColumnId(null)
15541554
void submitRename()
15551555
}, [])
15561556

15571557
const handleRenameCancel = useCallback(() => {
1558-
setRenameError(false)
1558+
setRenameErrorColumnId(null)
15591559
columnRenameRef.current.cancelRename()
15601560
}, [])
15611561

@@ -4035,7 +4035,7 @@ export function TableGrid({
40354035

40364036
const handleRenameColumn = useCallback(
40374037
(columnName: string) => {
4038-
setRenameError(false)
4038+
setRenameErrorColumnId(null)
40394039
const column = columnsRef.current.find((candidate) => candidate.key === columnName)
40404040
columnRename.startRename(columnName, column?.name ?? columnName)
40414041
},
@@ -4932,7 +4932,7 @@ export function TableGrid({
49324932
renameValue={
49334933
columnRename.editingId === column.key ? columnRename.editValue : ''
49344934
}
4935-
renameError={renameError && columnRename.editingId === column.key}
4935+
renameError={renameErrorColumnId === column.key}
49364936
onRenameValueChange={handleRenameValueChange}
49374937
onRenameSubmit={handleRenameSubmit}
49384938
onRenameCancel={handleRenameCancel}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ describe('columnNameIssue', () => {
204204
expect(columnNameIssue('email_address', ['name', 'status'])).toBeNull()
205205
})
206206

207+
it('requires a name', () => {
208+
expect(columnNameIssue('', [])).toBe('Column name is required')
209+
})
210+
207211
it('refuses invalid patterns and names that begin with a digit', () => {
208212
expect(columnNameIssue('New Text', [])).toMatch(/letter or underscore/)
209213
expect(columnNameIssue('1st', [])).toMatch(/letter or underscore/)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ export function canWriteRowsWithChip(opts: {
494494
* @param takenNames Names of every other column in the table.
495495
*/
496496
export function columnNameIssue(name: string, takenNames: Iterable<string>): string | null {
497+
if (!name) return 'Column name is required'
497498
if (name.length > TABLE_LIMITS.MAX_COLUMN_NAME_LENGTH) {
498499
return `Column names must be ${TABLE_LIMITS.MAX_COLUMN_NAME_LENGTH} characters or less`
499500
}

0 commit comments

Comments
 (0)