From 4ee346c69d62bd98f65af0231280e2e002300713 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sun, 18 Jan 2026 01:24:36 +0000 Subject: [PATCH] Add data source editor hook --- .../molecules/DataSourceEditorDialog.tsx | 42 ++++---------- src/hooks/data/use-data-source-editor.ts | 58 +++++++++++++++++++ 2 files changed, 68 insertions(+), 32 deletions(-) create mode 100644 src/hooks/data/use-data-source-editor.ts diff --git a/src/components/molecules/DataSourceEditorDialog.tsx b/src/components/molecules/DataSourceEditorDialog.tsx index 5b13f15..38098d4 100644 --- a/src/components/molecules/DataSourceEditorDialog.tsx +++ b/src/components/molecules/DataSourceEditorDialog.tsx @@ -1,4 +1,3 @@ -import { useEffect, useState } from 'react' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { DataSource } from '@/types/json-ui' @@ -7,6 +6,7 @@ import { DataSourceIdField } from '@/components/molecules/data-source-editor/Dat import { KvSourceFields } from '@/components/molecules/data-source-editor/KvSourceFields' import { StaticSourceFields } from '@/components/molecules/data-source-editor/StaticSourceFields' 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' interface DataSourceEditorDialogProps { @@ -24,11 +24,15 @@ export function DataSourceEditorDialog({ onOpenChange, onSave, }: DataSourceEditorDialogProps) { - const [editingSource, setEditingSource] = useState(dataSource) - - useEffect(() => { - setEditingSource(dataSource) - }, [dataSource]) + const { + editingSource, + updateField, + addDependency, + removeDependency, + availableDeps, + selectedDeps, + unselectedDeps, + } = useDataSourceEditor(dataSource, allDataSources) const handleSave = () => { if (!editingSource) return @@ -36,34 +40,8 @@ export function DataSourceEditorDialog({ onOpenChange(false) } - const updateField = (field: K, value: DataSource[K]) => { - if (!editingSource) return - setEditingSource({ ...editingSource, [field]: value }) - } - - const addDependency = (depId: string) => { - if (!editingSource || editingSource.type !== 'computed') return - const deps = editingSource.dependencies || [] - if (!deps.includes(depId)) { - updateField('dependencies', [...deps, depId]) - } - } - - const removeDependency = (depId: string) => { - if (!editingSource || editingSource.type !== 'computed') return - const deps = editingSource.dependencies || [] - updateField('dependencies', deps.filter(d => d !== depId)) - } - if (!editingSource) return null - const availableDeps = allDataSources.filter( - ds => ds.id !== editingSource.id && ds.type !== 'computed', - ) - - const selectedDeps = editingSource.dependencies || [] - const unselectedDeps = availableDeps.filter(ds => !selectedDeps.includes(ds.id)) - return ( diff --git a/src/hooks/data/use-data-source-editor.ts b/src/hooks/data/use-data-source-editor.ts new file mode 100644 index 0000000..8c5c9af --- /dev/null +++ b/src/hooks/data/use-data-source-editor.ts @@ -0,0 +1,58 @@ +import { useCallback, useEffect, useMemo, useState } from 'react' +import { DataSource } from '@/types/json-ui' + +export function useDataSourceEditor( + dataSource: DataSource | null, + allDataSources: DataSource[], +) { + const [editingSource, setEditingSource] = useState(dataSource) + + useEffect(() => { + setEditingSource(dataSource) + }, [dataSource]) + + const updateField = useCallback((field: K, value: DataSource[K]) => { + setEditingSource(prev => (prev ? { ...prev, [field]: value } : prev)) + }, []) + + 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(dep => dep !== depId) } + }) + }, []) + + 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( + () => availableDeps.filter(ds => !selectedDeps.includes(ds.id)), + [availableDeps, selectedDeps], + ) + + return { + editingSource, + updateField, + addDependency, + removeDependency, + availableDeps, + selectedDeps, + unselectedDeps, + } +}