mirror of
https://github.com/langgenius/dify.git
synced 2026-04-20 18:57:19 +08:00
refactor: extract sqlite table hook
This commit is contained in:
@ -1,11 +1,12 @@
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useEffect, useMemo, useReducer, useRef, useState } from 'react'
|
||||
import { useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { useSQLiteDatabase } from '../../hooks/use-sqlite-database'
|
||||
import TablePanel from './table-panel'
|
||||
import TableSelector from './table-selector'
|
||||
import { useSQLiteTable } from './use-sqlite-table'
|
||||
|
||||
type SQLiteFilePreviewProps = {
|
||||
downloadUrl: string
|
||||
@ -18,51 +19,6 @@ const SQLiteFilePreview: FC<SQLiteFilePreviewProps> = ({
|
||||
const { tables, isLoading, error, queryTable } = useSQLiteDatabase(downloadUrl)
|
||||
const [selectedTableId, setSelectedTableId] = useState<string>('')
|
||||
const tableScrollRef = useRef<HTMLDivElement | null>(null)
|
||||
const [tableState, dispatch] = useReducer((
|
||||
current: {
|
||||
data: Awaited<ReturnType<typeof queryTable>> | null
|
||||
isLoading: boolean
|
||||
error: Error | null
|
||||
},
|
||||
action:
|
||||
| { type: 'reset' }
|
||||
| { type: 'loading' }
|
||||
| { type: 'success', data: Awaited<ReturnType<typeof queryTable>> | null }
|
||||
| { type: 'error', error: Error },
|
||||
) => {
|
||||
switch (action.type) {
|
||||
case 'reset':
|
||||
return {
|
||||
data: null,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
}
|
||||
case 'loading':
|
||||
return {
|
||||
data: null,
|
||||
isLoading: true,
|
||||
error: null,
|
||||
}
|
||||
case 'success':
|
||||
return {
|
||||
data: action.data,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
}
|
||||
case 'error':
|
||||
return {
|
||||
data: null,
|
||||
isLoading: false,
|
||||
error: action.error,
|
||||
}
|
||||
default:
|
||||
return current
|
||||
}
|
||||
}, {
|
||||
data: null,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
})
|
||||
|
||||
const selectedTable = useMemo(() => {
|
||||
if (tables.length === 0)
|
||||
@ -71,35 +27,7 @@ const SQLiteFilePreview: FC<SQLiteFilePreviewProps> = ({
|
||||
return selectedTableId
|
||||
return tables[0]
|
||||
}, [selectedTableId, tables])
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedTable) {
|
||||
dispatch({ type: 'reset' })
|
||||
return
|
||||
}
|
||||
|
||||
let cancelled = false
|
||||
|
||||
const loadTable = async () => {
|
||||
dispatch({ type: 'loading' })
|
||||
|
||||
try {
|
||||
const data = await queryTable(selectedTable)
|
||||
if (!cancelled)
|
||||
dispatch({ type: 'success', data })
|
||||
}
|
||||
catch (err) {
|
||||
if (!cancelled)
|
||||
dispatch({ type: 'error', error: err instanceof Error ? err : new Error(String(err)) })
|
||||
}
|
||||
}
|
||||
|
||||
loadTable()
|
||||
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [queryTable, selectedTable])
|
||||
const tableState = useSQLiteTable({ selectedTable, queryTable })
|
||||
|
||||
if (!downloadUrl) {
|
||||
return (
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
import type { SQLiteQueryResult } from '../../hooks/sqlite/types'
|
||||
import { useEffect, useReducer } from 'react'
|
||||
|
||||
type TableState = {
|
||||
data: SQLiteQueryResult | null
|
||||
isLoading: boolean
|
||||
error: Error | null
|
||||
}
|
||||
|
||||
type TableAction
|
||||
= | { type: 'reset' }
|
||||
| { type: 'loading' }
|
||||
| { type: 'success', data: SQLiteQueryResult | null }
|
||||
| { type: 'error', error: Error }
|
||||
|
||||
type UseSQLiteTableArgs = {
|
||||
selectedTable: string
|
||||
queryTable: (tableName: string, limit?: number) => Promise<SQLiteQueryResult | null>
|
||||
}
|
||||
|
||||
const initialTableState: TableState = {
|
||||
data: null,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
}
|
||||
|
||||
export const useSQLiteTable = ({
|
||||
selectedTable,
|
||||
queryTable,
|
||||
}: UseSQLiteTableArgs): TableState => {
|
||||
const [tableState, dispatch] = useReducer((current: TableState, action: TableAction): TableState => {
|
||||
switch (action.type) {
|
||||
case 'reset':
|
||||
return {
|
||||
data: null,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
}
|
||||
case 'loading':
|
||||
return {
|
||||
data: null,
|
||||
isLoading: true,
|
||||
error: null,
|
||||
}
|
||||
case 'success':
|
||||
return {
|
||||
data: action.data,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
}
|
||||
case 'error':
|
||||
return {
|
||||
data: null,
|
||||
isLoading: false,
|
||||
error: action.error,
|
||||
}
|
||||
default:
|
||||
return current
|
||||
}
|
||||
}, initialTableState)
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedTable) {
|
||||
dispatch({ type: 'reset' })
|
||||
return
|
||||
}
|
||||
|
||||
let cancelled = false
|
||||
|
||||
const loadTable = async () => {
|
||||
dispatch({ type: 'loading' })
|
||||
|
||||
try {
|
||||
const data = await queryTable(selectedTable)
|
||||
if (!cancelled)
|
||||
dispatch({ type: 'success', data })
|
||||
}
|
||||
catch (err) {
|
||||
if (!cancelled)
|
||||
dispatch({ type: 'error', error: err instanceof Error ? err : new Error(String(err)) })
|
||||
}
|
||||
}
|
||||
|
||||
loadTable()
|
||||
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [queryTable, selectedTable])
|
||||
|
||||
return tableState
|
||||
}
|
||||
Reference in New Issue
Block a user