Skip to content

Commit 9e0fc2c

Browse files
committed
fixes
1 parent f588b36 commit 9e0fc2c

File tree

4 files changed

+42
-46
lines changed

4 files changed

+42
-46
lines changed

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/row-modal/row-modal.tsx

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,9 @@ export interface RowModalProps {
4242

4343
function createInitialRowData(columns: ColumnDefinition[]): Record<string, unknown> {
4444
const initial: Record<string, unknown> = {}
45-
columns.forEach((col) => {
46-
if (col.type === 'boolean') {
47-
initial[col.name] = false
48-
} else {
49-
initial[col.name] = ''
50-
}
51-
})
45+
for (const col of columns) {
46+
initial[col.name] = col.type === 'boolean' ? false : ''
47+
}
5248
return initial
5349
}
5450

@@ -57,16 +53,13 @@ function cleanRowData(
5753
rowData: Record<string, unknown>
5854
): Record<string, unknown> {
5955
const cleanData: Record<string, unknown> = {}
60-
61-
columns.forEach((col) => {
62-
const value = rowData[col.name]
56+
for (const col of columns) {
6357
try {
64-
cleanData[col.name] = cleanCellValue(value, col)
58+
cleanData[col.name] = cleanCellValue(rowData[col.name], col)
6559
} catch {
6660
throw new Error(`Invalid JSON for field: ${col.name}`)
6761
}
68-
})
69-
62+
}
7063
return cleanData
7164
}
7265

@@ -89,8 +82,7 @@ export function RowModal({ mode, isOpen, onClose, table, row, rowIds, onSuccess
8982
const workspaceId = params.workspaceId as string
9083
const tableId = table.id
9184

92-
const schema = table?.schema
93-
const columns = schema?.columns || []
85+
const columns = table.schema?.columns || []
9486

9587
const [rowData, setRowData] = useState<Record<string, unknown>>(() =>
9688
getInitialRowData(mode, columns, row)

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

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ export function Table({
237237
const ghostRef = useRef<HTMLDivElement>(null)
238238
const tableFilterRef = useRef<TableFilterHandle>(null)
239239
const isDraggingRef = useRef(false)
240+
const dragEscapeCleanupRef = useRef<(() => void) | null>(null)
240241

241242
const { tableData, isLoadingTable, rows, isLoadingRows } = useTableData({
242243
workspaceId,
@@ -715,7 +716,6 @@ export function Table({
715716
const scrollRect = scroll.getBoundingClientRect()
716717
const tableEl = element.closest('table')
717718

718-
// Position the ghost at the dragged column's location
719719
ghost.style.left = `${dragged.left}px`
720720
ghost.style.width = `${dragged.width}px`
721721
ghost.style.height = `${tableEl ? tableEl.offsetHeight : scroll.scrollHeight}px`
@@ -746,6 +746,7 @@ export function Table({
746746
element.removeEventListener('pointercancel', handleCancel)
747747
document.removeEventListener('keydown', handleKeyDown)
748748
element.releasePointerCapture(pointerId)
749+
dragEscapeCleanupRef.current = null
749750
if (shouldCommit) commit()
750751
ghost.style.display = 'none'
751752
ghost.style.transform = 'translateX(0)'
@@ -758,7 +759,6 @@ export function Table({
758759
const delta = ev.clientX - startX
759760
ghost.style.transform = `translateX(${delta}px)`
760761

761-
// Determine which column the cursor is over
762762
const tableX = ev.clientX - scrollRect.left + scroll.scrollLeft
763763
let target = boundaries[boundaries.length - 1]
764764
let side: 'left' | 'right' = 'right'
@@ -771,7 +771,6 @@ export function Table({
771771
}
772772

773773
if (target.name === columnName) {
774-
// Hovering over self — suppress the indicator
775774
if (dropTargetColumnNameRef.current !== null) {
776775
setDropTargetColumnName(null)
777776
}
@@ -795,6 +794,7 @@ export function Table({
795794
element.addEventListener('pointerup', handleUp)
796795
element.addEventListener('pointercancel', handleCancel)
797796
document.addEventListener('keydown', handleKeyDown)
797+
dragEscapeCleanupRef.current = () => cleanup(false)
798798
},
799799
[]
800800
)
@@ -833,6 +833,12 @@ export function Table({
833833
return () => document.removeEventListener('mouseup', handleMouseUp)
834834
}, [])
835835

836+
useEffect(() => {
837+
return () => {
838+
dragEscapeCleanupRef.current?.()
839+
}
840+
}, [])
841+
836842
useEffect(() => {
837843
if (!selectionAnchor) return
838844
const { rowIndex, colIndex } = selectionAnchor
@@ -1466,10 +1472,10 @@ export function Table({
14661472
}, [])
14671473

14681474
const generateColumnName = useCallback(() => {
1469-
const existing = schemaColumnsRef.current.map((c) => c.name.toLowerCase())
1475+
const existing = new Set(schemaColumnsRef.current.map((c) => c.name.toLowerCase()))
14701476
let name = 'untitled'
14711477
let i = 2
1472-
while (existing.includes(name.toLowerCase())) {
1478+
while (existing.has(name)) {
14731479
name = `untitled_${i}`
14741480
i++
14751481
}
@@ -2906,10 +2912,9 @@ const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({
29062912
const renameInputRef = useRef<HTMLInputElement>(null)
29072913

29082914
useEffect(() => {
2909-
if (isRenaming && renameInputRef.current) {
2910-
renameInputRef.current.focus()
2911-
renameInputRef.current.select()
2912-
}
2915+
if (!isRenaming || !renameInputRef.current) return
2916+
renameInputRef.current.focus()
2917+
renameInputRef.current.select()
29132918
}, [isRenaming])
29142919

29152920
const handleResizePointerDown = useCallback(
@@ -2958,7 +2963,6 @@ const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({
29582963
const handleThPointerDown = useCallback(
29592964
(e: React.PointerEvent) => {
29602965
if (isRenaming || e.button !== 0) return
2961-
if ((e.target as HTMLElement).closest('button')) return
29622966
e.preventDefault()
29632967

29642968
const th = e.currentTarget as HTMLElement
@@ -3042,24 +3046,25 @@ const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({
30423046
)}
30433047
</div>
30443048
) : (
3045-
<div className='flex h-full w-full min-w-0 items-center'>
3049+
<div className='flex h-full w-full min-w-0 items-center px-2 py-[7px]'>
3050+
<ColumnTypeIcon type={column.type} />
3051+
<span className='ml-1.5 min-w-0 overflow-clip text-ellipsis whitespace-nowrap font-medium text-[var(--text-primary)] text-small'>
3052+
{column.name}
3053+
</span>
3054+
{sortDirection && (
3055+
<span className='ml-1 shrink-0'>
3056+
<SortDirectionIndicator direction={sortDirection} />
3057+
</span>
3058+
)}
30463059
<DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}>
30473060
<DropdownMenuTrigger asChild>
30483061
<button
30493062
type='button'
3050-
onClick={(e) => onColumnSelect?.(colIndex, e.shiftKey)}
3051-
className='flex min-w-0 flex-1 cursor-pointer items-center px-2 py-[7px] outline-none'
3063+
onPointerDown={(e) => e.stopPropagation()}
3064+
onClick={() => onColumnSelect?.(colIndex, false)}
3065+
className='ml-1 flex shrink-0 cursor-pointer items-center opacity-0 outline-none transition-opacity group-hover:opacity-100'
30523066
>
3053-
<ColumnTypeIcon type={column.type} />
3054-
<span className='ml-1.5 min-w-0 overflow-clip text-ellipsis whitespace-nowrap font-medium text-[var(--text-primary)] text-small'>
3055-
{column.name}
3056-
</span>
3057-
{sortDirection && (
3058-
<span className='ml-1 shrink-0'>
3059-
<SortDirectionIndicator direction={sortDirection} />
3060-
</span>
3061-
)}
3062-
<ChevronDown className='ml-1 h-[7px] w-[9px] shrink-0 text-[var(--text-muted)] opacity-0 transition-opacity group-hover:opacity-100' />
3067+
<ChevronDown className='h-[7px] w-[9px] text-[var(--text-muted)]' />
30633068
</button>
30643069
</DropdownMenuTrigger>
30653070
<DropdownMenuContent align='start' sideOffset={0}>

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/hooks/use-export-table.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { useCallback, useState } from 'react'
3+
import { useCallback, useRef, useState } from 'react'
44
import { usePostHog } from 'posthog-js/react'
55
import { toast } from '@/components/emcn'
66
import { downloadFile, sanitizePathSegment } from '@/lib/core/utils/file-download'
@@ -29,12 +29,12 @@ export function useExportTable({
2929
}: UseExportTableParams) {
3030
const posthog = usePostHog()
3131
const [isExporting, setIsExporting] = useState(false)
32+
const isExportingRef = useRef(false)
3233

3334
const handleExportTable = useCallback(async () => {
34-
if (!canExport || !workspaceId || !tableId || isExporting) {
35-
return
36-
}
35+
if (!canExport || !workspaceId || !tableId || isExportingRef.current) return
3736

37+
isExportingRef.current = true
3838
setIsExporting(true)
3939

4040
try {
@@ -63,12 +63,12 @@ export function useExportTable({
6363
duration: 5000,
6464
})
6565
} finally {
66+
isExportingRef.current = false
6667
setIsExporting(false)
6768
}
6869
}, [
6970
canExport,
7071
columns,
71-
isExporting,
7272
posthog,
7373
queryOptions.filter,
7474
queryOptions.sort,

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,8 @@ export function Tables() {
6868
const { data: tables = [], isLoading, error } = useTablesList(workspaceId)
6969
const { data: members } = useWorkspaceMembersQuery(workspaceId)
7070

71-
if (error) {
72-
logger.error('Failed to load tables:', error)
73-
}
71+
if (error) logger.error('Failed to load tables:', error)
72+
7473
const deleteTable = useDeleteTable(workspaceId)
7574
const createTable = useCreateTable(workspaceId)
7675
const uploadCsv = useUploadCsvToTable()

0 commit comments

Comments
 (0)