input field in datasource
parent
365157c37d
commit
69d1e3ec7d
@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
memo,
|
||||||
|
useMemo,
|
||||||
|
} from 'react'
|
||||||
|
import { ReactSortable } from 'react-sortablejs'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
import type { InputVar } from '@/models/pipeline'
|
||||||
|
import FieldItem from './field-item'
|
||||||
|
import type { SortableItem } from './types'
|
||||||
|
|
||||||
|
type FieldListContainerProps = {
|
||||||
|
className?: string
|
||||||
|
inputFields: InputVar[]
|
||||||
|
onListSortChange: (list: SortableItem[]) => void
|
||||||
|
onRemoveField: (id: string) => void
|
||||||
|
onEditField: (id: string) => void
|
||||||
|
readonly?: boolean
|
||||||
|
}
|
||||||
|
const FieldListContainer = ({
|
||||||
|
className,
|
||||||
|
inputFields,
|
||||||
|
onListSortChange,
|
||||||
|
onRemoveField,
|
||||||
|
onEditField,
|
||||||
|
readonly,
|
||||||
|
}: FieldListContainerProps) => {
|
||||||
|
const list = useMemo(() => {
|
||||||
|
return inputFields.map((content) => {
|
||||||
|
return ({
|
||||||
|
id: content.variable,
|
||||||
|
name: content.variable,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, [inputFields])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactSortable<SortableItem>
|
||||||
|
className={cn(className)}
|
||||||
|
list={list}
|
||||||
|
setList={onListSortChange}
|
||||||
|
handle='.handle'
|
||||||
|
ghostClass='opacity-50'
|
||||||
|
animation={150}
|
||||||
|
disabled={readonly}
|
||||||
|
>
|
||||||
|
{inputFields?.map((item, index) => (
|
||||||
|
<FieldItem
|
||||||
|
key={index}
|
||||||
|
readonly={readonly}
|
||||||
|
payload={item}
|
||||||
|
onRemove={onRemoveField}
|
||||||
|
onClickEdit={onEditField}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ReactSortable>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(FieldListContainer)
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
import {
|
||||||
|
useCallback,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react'
|
||||||
|
import { produce } from 'immer'
|
||||||
|
import type { InputVar } from '@/models/pipeline'
|
||||||
|
import type { SortableItem } from './types'
|
||||||
|
|
||||||
|
export const useFieldList = (
|
||||||
|
initialInputFields: InputVar[],
|
||||||
|
onInputFieldsChange: (value: InputVar[]) => void,
|
||||||
|
) => {
|
||||||
|
const [inputFields, setInputFields] = useState<InputVar[]>(initialInputFields)
|
||||||
|
const inputFieldsRef = useRef<InputVar[]>(inputFields)
|
||||||
|
const handleInputFieldsChange = useCallback((newInputFields: InputVar[]) => {
|
||||||
|
setInputFields(newInputFields)
|
||||||
|
inputFieldsRef.current = newInputFields
|
||||||
|
onInputFieldsChange(newInputFields)
|
||||||
|
}, [onInputFieldsChange])
|
||||||
|
|
||||||
|
const handleListSortChange = useCallback((list: SortableItem[]) => {
|
||||||
|
const newInputFields = list.map((item) => {
|
||||||
|
return inputFieldsRef.current.find(field => field.variable === item.name)
|
||||||
|
})
|
||||||
|
handleInputFieldsChange(newInputFields as InputVar[])
|
||||||
|
}, [handleInputFieldsChange])
|
||||||
|
|
||||||
|
const [editingField, setEditingField] = useState<InputVar | undefined>()
|
||||||
|
const [showInputFieldEditor, setShowInputFieldEditor] = useState(false)
|
||||||
|
const handleOpenInputFieldEditor = useCallback((id?: string) => {
|
||||||
|
const fieldToEdit = inputFieldsRef.current.find(field => field.variable === id)
|
||||||
|
setEditingField(fieldToEdit)
|
||||||
|
setShowInputFieldEditor(true)
|
||||||
|
}, [])
|
||||||
|
const handleCancelInputFieldEditor = useCallback(() => {
|
||||||
|
setShowInputFieldEditor(false)
|
||||||
|
setEditingField(undefined)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleRemoveField = useCallback((id: string) => {
|
||||||
|
const newInputFields = inputFieldsRef.current.filter(field => field.variable !== id)
|
||||||
|
handleInputFieldsChange(newInputFields)
|
||||||
|
}, [handleInputFieldsChange])
|
||||||
|
|
||||||
|
const handleSubmitField = useCallback((data: InputVar) => {
|
||||||
|
const newInputFields = produce(inputFieldsRef.current, (draft) => {
|
||||||
|
const currentIndex = draft.findIndex(field => field.variable === data.variable)
|
||||||
|
if (currentIndex === -1) {
|
||||||
|
draft.push(data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
draft[currentIndex] = data
|
||||||
|
})
|
||||||
|
handleInputFieldsChange(newInputFields)
|
||||||
|
}, [handleInputFieldsChange])
|
||||||
|
|
||||||
|
return {
|
||||||
|
inputFields,
|
||||||
|
handleInputFieldsChange,
|
||||||
|
handleListSortChange,
|
||||||
|
handleRemoveField,
|
||||||
|
handleSubmitField,
|
||||||
|
editingField,
|
||||||
|
showInputFieldEditor,
|
||||||
|
handleOpenInputFieldEditor,
|
||||||
|
handleCancelInputFieldEditor,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
export type SortableItem = {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue