mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-28 07:34:56 +00:00
Extract dialog state hooks
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { useState } from 'react'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { BindingEditor } from '@/components/molecules/BindingEditor'
|
||||
import { DataSource, UIComponent } from '@/types/json-ui'
|
||||
import { Link } from '@phosphor-icons/react'
|
||||
import { useComponentBindingDialog } from '@/hooks/use-component-binding-dialog'
|
||||
|
||||
interface ComponentBindingDialogProps {
|
||||
open: boolean
|
||||
@@ -21,18 +21,11 @@ export function ComponentBindingDialog({
|
||||
onOpenChange,
|
||||
onSave,
|
||||
}: ComponentBindingDialogProps) {
|
||||
const [editingComponent, setEditingComponent] = useState<UIComponent | null>(component)
|
||||
|
||||
const handleSave = () => {
|
||||
if (!editingComponent) return
|
||||
onSave(editingComponent)
|
||||
onOpenChange(false)
|
||||
}
|
||||
|
||||
const updateBindings = (bindings: Record<string, any>) => {
|
||||
if (!editingComponent) return
|
||||
setEditingComponent({ ...editingComponent, bindings })
|
||||
}
|
||||
const { editingComponent, handleSave, updateBindings } = useComponentBindingDialog({
|
||||
component,
|
||||
onSave,
|
||||
onOpenChange,
|
||||
})
|
||||
|
||||
if (!editingComponent) return null
|
||||
|
||||
|
||||
@@ -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'
|
||||
@@ -8,6 +7,7 @@ import { KvSourceFields } from '@/components/molecules/data-source-editor/KvSour
|
||||
import { StaticSourceFields } from '@/components/molecules/data-source-editor/StaticSourceFields'
|
||||
import { ComputedSourceFields } from '@/components/molecules/data-source-editor/ComputedSourceFields'
|
||||
import dataSourceEditorCopy from '@/data/data-source-editor-dialog.json'
|
||||
import { useDataSourceEditor } from '@/hooks/use-data-source-editor'
|
||||
|
||||
interface DataSourceEditorDialogProps {
|
||||
open: boolean
|
||||
@@ -24,46 +24,24 @@ export function DataSourceEditorDialog({
|
||||
onOpenChange,
|
||||
onSave,
|
||||
}: DataSourceEditorDialogProps) {
|
||||
const [editingSource, setEditingSource] = useState<DataSource | null>(dataSource)
|
||||
|
||||
useEffect(() => {
|
||||
setEditingSource(dataSource)
|
||||
}, [dataSource])
|
||||
|
||||
const handleSave = () => {
|
||||
if (!editingSource) return
|
||||
onSave(editingSource)
|
||||
onOpenChange(false)
|
||||
}
|
||||
|
||||
const updateField = <K extends keyof DataSource>(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))
|
||||
}
|
||||
const {
|
||||
editingSource,
|
||||
updateField,
|
||||
addDependency,
|
||||
removeDependency,
|
||||
handleSave,
|
||||
availableDeps,
|
||||
selectedDeps,
|
||||
unselectedDeps,
|
||||
} = useDataSourceEditor({
|
||||
dataSource,
|
||||
allDataSources,
|
||||
onSave,
|
||||
onOpenChange,
|
||||
})
|
||||
|
||||
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 (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
|
||||
|
||||
39
src/hooks/use-component-binding-dialog.ts
Normal file
39
src/hooks/use-component-binding-dialog.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { UIComponent } from '@/types/json-ui'
|
||||
|
||||
interface UseComponentBindingDialogParams {
|
||||
component: UIComponent | null
|
||||
onSave: (component: UIComponent) => void
|
||||
onOpenChange: (open: boolean) => void
|
||||
}
|
||||
|
||||
export function useComponentBindingDialog({
|
||||
component,
|
||||
onSave,
|
||||
onOpenChange,
|
||||
}: UseComponentBindingDialogParams) {
|
||||
const [editingComponent, setEditingComponent] = useState<UIComponent | null>(component)
|
||||
|
||||
useEffect(() => {
|
||||
setEditingComponent(component)
|
||||
}, [component])
|
||||
|
||||
const updateBindings = useCallback((bindings: Record<string, any>) => {
|
||||
setEditingComponent((prev) => {
|
||||
if (!prev) return prev
|
||||
return { ...prev, bindings }
|
||||
})
|
||||
}, [])
|
||||
|
||||
const handleSave = useCallback(() => {
|
||||
if (!editingComponent) return
|
||||
onSave(editingComponent)
|
||||
onOpenChange(false)
|
||||
}, [editingComponent, onOpenChange, onSave])
|
||||
|
||||
return {
|
||||
editingComponent,
|
||||
updateBindings,
|
||||
handleSave,
|
||||
}
|
||||
}
|
||||
77
src/hooks/use-data-source-editor.ts
Normal file
77
src/hooks/use-data-source-editor.ts
Normal 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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user