Skip to content

Commit 131399e

Browse files
committed
fix(tables): keep sidebar renaming in reference foundation
1 parent 1aee818 commit 131399e

3 files changed

Lines changed: 44 additions & 25 deletions

File tree

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-config-sidebar/column-config-sidebar.test.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ function findButton(label: string): HTMLButtonElement | undefined {
104104
)
105105
}
106106

107+
function setInputValue(input: HTMLInputElement, value: string): void {
108+
const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set
109+
valueSetter?.call(input, value)
110+
input.dispatchEvent(new Event('input', { bubbles: true }))
111+
}
112+
107113
beforeEach(() => {
108114
globalThis.IS_REACT_ACT_ENVIRONMENT = true
109115
container = document.createElement('div')
@@ -184,7 +190,8 @@ describe('ColumnConfigSidebar', () => {
184190
expect(mockUpdateColumn).not.toHaveBeenCalled()
185191
})
186192

187-
it('edits Reference configuration without exposing column renaming', async () => {
193+
it('edits a Reference column name and target table together', async () => {
194+
const onColumnRename = vi.fn()
188195
await act(async () => {
189196
root.render(
190197
<ColumnConfigSidebar
@@ -198,20 +205,26 @@ describe('ColumnConfigSidebar', () => {
198205
}}
199206
workspaceId='workspace-1'
200207
tableId='table-current'
208+
onColumnRename={onColumnRename}
201209
/>
202210
)
203211
})
204212

205-
expect(container).not.toHaveTextContent('Column name')
206-
expect(container.querySelector('#column-sidebar-name')).toBeNull()
213+
const nameInput = container.querySelector<HTMLInputElement>('#column-sidebar-name')
214+
expect(nameInput?.value).toBe('Related row')
207215

216+
act(() => setInputValue(nameInput!, 'Renamed relation'))
208217
act(() => findCombobox('Select table')?.onChange?.('table-customers'))
209218
await act(async () => findButton('Save')?.click())
210219

211220
expect(mockUpdateColumn).toHaveBeenCalledWith({
212221
columnName: 'col-reference',
213-
updates: { referenceTableId: 'table-customers' },
222+
updates: {
223+
name: 'Renamed relation',
224+
referenceTableId: 'table-customers',
225+
},
214226
})
227+
expect(onColumnRename).toHaveBeenCalledWith('col-reference', 'Renamed relation')
215228
})
216229

217230
it('keeps Select options in the edit sidebar', async () => {

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

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ interface ColumnConfigSidebarProps {
5757
tableRowTtlEnabled: boolean
5858
workspaceId: string
5959
tableId: string
60+
/** Notify the grid so local layout metadata follows a successful rename. */
61+
onColumnRename?: (oldName: string, newName: string) => void
6062
}
6163

6264
/**
@@ -106,6 +108,7 @@ function ColumnConfigBody({
106108
tableRowTtlEnabled,
107109
workspaceId,
108110
tableId,
111+
onColumnRename,
109112
}: ColumnConfigBodyProps) {
110113
const updateColumn = useUpdateColumn({ workspaceId, tableId })
111114
const addColumn = useAddTableColumn({ workspaceId, tableId })
@@ -166,7 +169,7 @@ function ColumnConfigBody({
166169
}
167170

168171
async function handleSave() {
169-
if (config.mode === 'create' && !trimmedName) {
172+
if (!trimmedName) {
170173
setShowValidation(true)
171174
return
172175
}
@@ -198,6 +201,7 @@ function ColumnConfigBody({
198201
return
199202
}
200203

204+
const renamed = trimmedName !== (existingColumn?.name ?? config.columnName)
201205
const typeChanged = !!existingColumn && existingColumn.type !== typeInput
202206
const uniqueChanged =
203207
supportsUnique && !!existingColumn && !!existingColumn.unique !== uniqueInput
@@ -211,13 +215,15 @@ function ColumnConfigBody({
211215
wantsReference && existingColumn?.referenceTableId !== referenceTableInput
212216

213217
const updates: {
218+
name?: string
214219
type?: ColumnDefinition['type']
215220
unique?: boolean
216221
options?: SelectOption[]
217222
multiple?: boolean
218223
currencyCode?: string
219224
referenceTableId?: string
220225
} = {
226+
...(renamed ? { name: trimmedName } : {}),
221227
...(typeChanged ? { type: typeInput } : {}),
222228
...(uniqueChanged ? { unique: uniqueInput } : {}),
223229
...(uniqueCleared ? { unique: false } : {}),
@@ -236,7 +242,8 @@ function ColumnConfigBody({
236242
}
237243

238244
await updateColumn.mutateAsync({ columnName: config.columnName, updates })
239-
toast.success(`Saved "${existingColumn?.name ?? config.columnName}"`)
245+
if (renamed) onColumnRename?.(config.columnName, trimmedName)
246+
toast.success(`Saved "${trimmedName}"`)
240247
onClose()
241248
} catch (err) {
242249
if (isValidationError(err)) {
@@ -269,25 +276,23 @@ function ColumnConfigBody({
269276
</div>
270277

271278
<div className='flex-1 overflow-y-auto overflow-x-hidden px-2 pt-3 pb-2 [overflow-anchor:none]'>
272-
{config.mode === 'create' && (
273-
<div className='flex flex-col gap-[9.5px]'>
274-
<RequiredLabel htmlFor='column-sidebar-name'>Column name</RequiredLabel>
275-
<ChipInput
276-
id='column-sidebar-name'
277-
value={nameInput}
278-
onChange={(e) => {
279-
setNameInput(e.target.value)
280-
if (nameError) setNameError(null)
281-
}}
282-
spellCheck={false}
283-
autoComplete='off'
284-
error={Boolean((showValidation && !trimmedName) || nameError)}
285-
aria-invalid={(showValidation && !trimmedName) || nameError ? true : undefined}
286-
/>
287-
{showValidation && !trimmedName && <FieldError message='Column name is required' />}
288-
{nameError && !(showValidation && !trimmedName) && <FieldError message={nameError} />}
289-
</div>
290-
)}
279+
<div className='flex flex-col gap-[9.5px]'>
280+
<RequiredLabel htmlFor='column-sidebar-name'>Column name</RequiredLabel>
281+
<ChipInput
282+
id='column-sidebar-name'
283+
value={nameInput}
284+
onChange={(e) => {
285+
setNameInput(e.target.value)
286+
if (nameError) setNameError(null)
287+
}}
288+
spellCheck={false}
289+
autoComplete='off'
290+
error={Boolean((showValidation && !trimmedName) || nameError)}
291+
aria-invalid={(showValidation && !trimmedName) || nameError ? true : undefined}
292+
/>
293+
{showValidation && !trimmedName && <FieldError message='Column name is required' />}
294+
{nameError && !(showValidation && !trimmedName) && <FieldError message={nameError} />}
295+
</div>
291296

292297
{config.mode === 'edit' && (
293298
<>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,7 @@ export function Table({
16591659
}
16601660
workspaceId={workspaceId}
16611661
tableId={tableId}
1662+
onColumnRename={onColumnRename}
16621663
/>
16631664
<EnrichmentsSidebar
16641665
open={slideout.kind === 'enrichments'}

0 commit comments

Comments
 (0)