Merge pull request #93 from johndoe6345789/codex/extract-logic-into-custom-hooks

Extract data source & component binding dialog state into hooks
This commit is contained in:
2026-01-18 01:27:36 +00:00
committed by GitHub
2 changed files with 78 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ import { StaticSourceFields } from '@/components/molecules/data-source-editor/St
import { ComputedSourceFields } from '@/components/molecules/data-source-editor/ComputedSourceFields'
import { useDataSourceEditor } from '@/hooks/data/use-data-source-editor'
import dataSourceEditorCopy from '@/data/data-source-editor-dialog.json'
import { useDataSourceEditor } from '@/hooks/use-data-source-editor'
interface DataSourceEditorDialogProps {
open: boolean

View File

@@ -0,0 +1,77 @@
import { useCallback, useEffect, useMemo, useState } from 'react'
import { DataSource } from '@/types/json-ui'
interface UseDataSourceEditorParams {
dataSource: DataSource | null
allDataSources: DataSource[]
onSave: (dataSource: DataSource) => void
onOpenChange: (open: boolean) => void
}
export function useDataSourceEditor({
dataSource,
allDataSources,
onSave,
onOpenChange,
}: UseDataSourceEditorParams) {
const [editingSource, setEditingSource] = useState<DataSource | null>(dataSource)
useEffect(() => {
setEditingSource(dataSource)
}, [dataSource])
const updateField = useCallback(<K extends keyof DataSource>(field: K, value: DataSource[K]) => {
setEditingSource((prev) => {
if (!prev) return prev
return { ...prev, [field]: value }
})
}, [])
const addDependency = useCallback((depId: string) => {
setEditingSource((prev) => {
if (!prev || prev.type !== 'computed') return prev
const deps = prev.dependencies || []
if (deps.includes(depId)) return prev
return { ...prev, dependencies: [...deps, depId] }
})
}, [])
const removeDependency = useCallback((depId: string) => {
setEditingSource((prev) => {
if (!prev || prev.type !== 'computed') return prev
const deps = prev.dependencies || []
return { ...prev, dependencies: deps.filter((id) => id !== depId) }
})
}, [])
const handleSave = useCallback(() => {
if (!editingSource) return
onSave(editingSource)
onOpenChange(false)
}, [editingSource, onOpenChange, onSave])
const availableDeps = useMemo(() => {
if (!editingSource) return []
return allDataSources.filter(
(ds) => ds.id !== editingSource.id && ds.type !== 'computed',
)
}, [allDataSources, editingSource])
const selectedDeps = useMemo(() => editingSource?.dependencies || [], [editingSource])
const unselectedDeps = useMemo(() => {
if (!editingSource) return []
return availableDeps.filter((ds) => !selectedDeps.includes(ds.id))
}, [availableDeps, editingSource, selectedDeps])
return {
editingSource,
updateField,
addDependency,
removeDependency,
handleSave,
availableDeps,
selectedDeps,
unselectedDeps,
}
}