ruvector/studio/hooks/ui/useCsvFileDrop.ts
rUv 814f595995 feat(studio): Add complete RuVector Studio application
Major additions:
- Complete Next.js studio application with 1600+ components
- Docker support (Dockerfile.combined, docker-compose.yml)
- GCP deployment documentation and benchmarks
- SQL benchmark scripts for performance testing
- Sentry integration for monitoring
- Comprehensive test suite and mocks

Studio features:
- Dashboard and admin interfaces
- Data visualization components
- Authentication and user management
- API integration with RuVector backend
- Static data and public assets

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:04:48 +00:00

76 lines
2.1 KiB
TypeScript

import { type DragEvent, useCallback, useState } from 'react'
import { type ImportDataFileDroppedEvent } from 'common/telemetry-constants'
import { flagInvalidFileImport } from 'components/interfaces/TableGridEditor/SidePanelEditor/SpreadsheetImport/SpreadsheetImport.utils'
interface UseCsvFileDropOptions {
enabled: boolean
onFileDropped: (file: File) => void
onTelemetryEvent?: (eventName: ImportDataFileDroppedEvent['action']) => void
}
interface UseCsvFileDropReturn {
isDraggedOver: boolean
isValidFile: boolean
onDragOver: (event: DragEvent<HTMLDivElement>) => void
onFileDrop: (event: DragEvent<HTMLDivElement>) => void
}
export function useCsvFileDrop({
enabled,
onFileDropped,
onTelemetryEvent,
}: UseCsvFileDropOptions): UseCsvFileDropReturn {
const [isDraggedOver, setIsDraggedOver] = useState(false)
const [isValidFile, setIsValidFile] = useState(false)
const onDragOver = useCallback(
(event: DragEvent<HTMLDivElement>) => {
if (!enabled) return
const [item] = event.dataTransfer.items
// ignore non files drop, like column headers
if (item && item.kind !== 'file') return
if (event.type === 'dragover' && !isDraggedOver) {
setIsDraggedOver(true)
setIsValidFile(item.type === 'text/csv')
} else if (event.type === 'dragleave' || event.type === 'drop') {
setIsDraggedOver(false)
setIsValidFile(false)
}
event.stopPropagation()
event.preventDefault()
},
[enabled, isDraggedOver, isValidFile]
)
const onFileDrop = useCallback(
(event: DragEvent<HTMLDivElement>) => {
if (!enabled) return
onDragOver(event)
const [file] = event.dataTransfer.files
const [item] = event.dataTransfer.items
// ignore non files drop, like column headers
if (item && item.kind !== 'file') return
if (flagInvalidFileImport(file)) return
onFileDropped(file)
onTelemetryEvent?.('import_data_dropzone_file_added')
},
[enabled, onDragOver, onFileDropped, onTelemetryEvent]
)
return {
isValidFile: isValidFile && isDraggedOver,
isDraggedOver,
onDragOver,
onFileDrop,
}
}