Skip to content

Commit b8f2994

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

3 files changed

Lines changed: 45 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: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ interface ColumnConfigSidebarProps {
5757
tableRowTtlEnabled: boolean
5858
workspaceId: string
5959
tableId: string
60+
/** Notify parent of a rename so it can rewrite local `columnOrder` /
61+
* `columnWidths` keys that reference the old name. */
62+
onColumnRename?: (oldName: string, newName: string) => void
6063
}
6164

6265
/**
@@ -106,6 +109,7 @@ function ColumnConfigBody({
106109
tableRowTtlEnabled,
107110
workspaceId,
108111
tableId,
112+
onColumnRename,
109113
}: ColumnConfigBodyProps) {
110114
const updateColumn = useUpdateColumn({ workspaceId, tableId })
111115
const addColumn = useAddTableColumn({ workspaceId, tableId })
@@ -166,7 +170,7 @@ function ColumnConfigBody({
166170
}
167171

168172
async function handleSave() {
169-
if (config.mode === 'create' && !trimmedName) {
173+
if (!trimmedName) {
170174
setShowValidation(true)
171175
return
172176
}
@@ -198,6 +202,7 @@ function ColumnConfigBody({
198202
return
199203
}
200204

205+
const renamed = trimmedName !== (existingColumn?.name ?? config.columnName)
201206
const typeChanged = !!existingColumn && existingColumn.type !== typeInput
202207
const uniqueChanged =
203208
supportsUnique && !!existingColumn && !!existingColumn.unique !== uniqueInput
@@ -211,13 +216,15 @@ function ColumnConfigBody({
211216
wantsReference && existingColumn?.referenceTableId !== referenceTableInput
212217

213218
const updates: {
219+
name?: string
214220
type?: ColumnDefinition['type']
215221
unique?: boolean
216222
options?: SelectOption[]
217223
multiple?: boolean
218224
currencyCode?: string
219225
referenceTableId?: string
220226
} = {
227+
...(renamed ? { name: trimmedName } : {}),
221228
...(typeChanged ? { type: typeInput } : {}),
222229
...(uniqueChanged ? { unique: uniqueInput } : {}),
223230
...(uniqueCleared ? { unique: false } : {}),
@@ -236,7 +243,8 @@ function ColumnConfigBody({
236243
}
237244

238245
await updateColumn.mutateAsync({ columnName: config.columnName, updates })
239-
toast.success(`Saved "${existingColumn?.name ?? config.columnName}"`)
246+
if (renamed) onColumnRename?.(config.columnName, trimmedName)
247+
toast.success(`Saved "${trimmedName}"`)
240248
onClose()
241249
} catch (err) {
242250
if (isValidationError(err)) {
@@ -269,25 +277,23 @@ function ColumnConfigBody({
269277
</div>
270278

271279
<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-
)}
280+
<div className='flex flex-col gap-[9.5px]'>
281+
<RequiredLabel htmlFor='column-sidebar-name'>Column name</RequiredLabel>
282+
<ChipInput
283+
id='column-sidebar-name'
284+
value={nameInput}
285+
onChange={(e) => {
286+
setNameInput(e.target.value)
287+
if (nameError) setNameError(null)
288+
}}
289+
spellCheck={false}
290+
autoComplete='off'
291+
error={Boolean((showValidation && !trimmedName) || nameError)}
292+
aria-invalid={(showValidation && !trimmedName) || nameError ? true : undefined}
293+
/>
294+
{showValidation && !trimmedName && <FieldError message='Column name is required' />}
295+
{nameError && !(showValidation && !trimmedName) && <FieldError message={nameError} />}
296+
</div>
291297

292298
{config.mode === 'edit' && (
293299
<>

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)