Skip to content

Commit c406724

Browse files
committed
fix(tables): harden inline column renaming
1 parent 1c3a779 commit c406724

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
@@ -1506,7 +1506,7 @@ export function TableGrid({
15061506
const handleFindCloseRef = useRef(handleFindClose)
15071507
handleFindCloseRef.current = handleFindClose
15081508

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

15111511
const columnRename = useInlineRename({
15121512
// `columnName` is the column id; record the prior display name + id so undo
@@ -1521,7 +1521,7 @@ export function TableGrid({
15211521
if (isValidationError(error)) {
15221522
toast.error(extractValidationIssues(error)[0]?.message ?? getErrorMessage(error))
15231523
}
1524-
setRenameError(true)
1524+
setRenameErrorColumnId(columnName)
15251525
throw error
15261526
})
15271527
},
@@ -1530,7 +1530,7 @@ export function TableGrid({
15301530
columnRenameRef.current = columnRename
15311531

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

@@ -1539,7 +1539,7 @@ export function TableGrid({
15391539
const { editingId, editValue, submitRename } = columnRenameRef.current
15401540
const trimmedName = editValue.trim()
15411541
const currentColumn = columnsRef.current.find((column) => column.key === editingId)
1542-
if (trimmedName && currentColumn && trimmedName !== currentColumn.name) {
1542+
if (currentColumn && trimmedName !== currentColumn.name) {
15431543
const issue = columnNameIssue(
15441544
trimmedName,
15451545
schemaColumnsRef.current
@@ -1548,16 +1548,16 @@ export function TableGrid({
15481548
)
15491549
if (issue) {
15501550
toast.error(issue)
1551-
setRenameError(true)
1551+
setRenameErrorColumnId(editingId)
15521552
return
15531553
}
15541554
}
1555-
setRenameError(false)
1555+
setRenameErrorColumnId(null)
15561556
void submitRename()
15571557
}, [])
15581558

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

@@ -4037,7 +4037,7 @@ export function TableGrid({
40374037

40384038
const handleRenameColumn = useCallback(
40394039
(columnName: string) => {
4040-
setRenameError(false)
4040+
setRenameErrorColumnId(null)
40414041
const column = columnsRef.current.find((candidate) => candidate.key === columnName)
40424042
columnRename.startRename(columnName, column?.name ?? columnName)
40434043
},
@@ -4934,7 +4934,7 @@ export function TableGrid({
49344934
renameValue={
49354935
columnRename.editingId === column.key ? columnRename.editValue : ''
49364936
}
4937-
renameError={renameError && columnRename.editingId === column.key}
4937+
renameError={renameErrorColumnId === column.key}
49384938
onRenameValueChange={handleRenameValueChange}
49394939
onRenameSubmit={handleRenameSubmit}
49404940
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)