mirror of
https://github.com/langgenius/dify.git
synced 2024-11-16 19:59:50 +08:00
23e3413655
Co-authored-by: StyleZhang <jasonapring2015@outlook.com>
120 lines
3.2 KiB
TypeScript
120 lines
3.2 KiB
TypeScript
import { useState } from 'react'
|
|
import Operate from './Operate'
|
|
import KeyInput from './KeyInput'
|
|
import { useValidate } from './hooks'
|
|
import type { Form, KeyFrom, Status, ValidateValue } from './declarations'
|
|
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
|
import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
|
|
|
|
export type KeyValidatorProps = {
|
|
type: string
|
|
title: React.ReactNode
|
|
status: Status
|
|
forms: Form[]
|
|
keyFrom: KeyFrom
|
|
onSave: (v: ValidateValue) => Promise<boolean | undefined>
|
|
}
|
|
|
|
const KeyValidator = ({
|
|
type,
|
|
title,
|
|
status,
|
|
forms,
|
|
keyFrom,
|
|
onSave,
|
|
}: KeyValidatorProps) => {
|
|
const triggerKey = `plugins/${type}`
|
|
const { eventEmitter } = useEventEmitterContextContext()
|
|
const [isOpen, setIsOpen] = useState(false)
|
|
const prevValue = forms.reduce((prev: ValidateValue, next: Form) => {
|
|
prev[next.key] = next.value
|
|
return prev
|
|
}, {})
|
|
const [value, setValue] = useState(prevValue)
|
|
const [validate, validating, validatedStatusState] = useValidate(value)
|
|
|
|
eventEmitter?.useSubscription((v) => {
|
|
if (v !== triggerKey) {
|
|
setIsOpen(false)
|
|
setValue(prevValue)
|
|
validate({ before: () => false })
|
|
}
|
|
})
|
|
|
|
const handleCancel = () => {
|
|
eventEmitter?.emit('')
|
|
}
|
|
|
|
const handleSave = async () => {
|
|
if (await onSave(value))
|
|
eventEmitter?.emit('')
|
|
}
|
|
|
|
const handleAdd = () => {
|
|
setIsOpen(true)
|
|
eventEmitter?.emit(triggerKey)
|
|
}
|
|
|
|
const handleEdit = () => {
|
|
setIsOpen(true)
|
|
eventEmitter?.emit(triggerKey)
|
|
}
|
|
|
|
const handleChange = (form: Form, val: string) => {
|
|
setValue({ ...value, [form.key]: val })
|
|
|
|
if (form.validate)
|
|
validate(form.validate)
|
|
}
|
|
|
|
const handleFocus = (form: Form) => {
|
|
if (form.handleFocus)
|
|
form.handleFocus(value, setValue)
|
|
}
|
|
|
|
return (
|
|
<div className='mb-2 border-[0.5px] border-gray-200 bg-gray-50 rounded-md'>
|
|
<div className={
|
|
`flex items-center justify-between px-4 h-[52px] cursor-pointer ${isOpen && 'border-b-[0.5px] border-b-gray-200'}`
|
|
}>
|
|
{title}
|
|
<Operate
|
|
isOpen={isOpen}
|
|
status={status}
|
|
onCancel={handleCancel}
|
|
onSave={handleSave}
|
|
onAdd={handleAdd}
|
|
onEdit={handleEdit}
|
|
/>
|
|
</div>
|
|
{
|
|
isOpen && (
|
|
<div className='px-4 py-3'>
|
|
{
|
|
forms.map(form => (
|
|
<KeyInput
|
|
key={form.key}
|
|
className='mb-4'
|
|
name={form.title}
|
|
placeholder={form.placeholder}
|
|
value={value[form.key] || ''}
|
|
onChange={v => handleChange(form, v)}
|
|
onFocus={() => handleFocus(form)}
|
|
validating={validating}
|
|
validatedStatusState={validatedStatusState}
|
|
/>
|
|
))
|
|
}
|
|
<a className="flex items-center text-xs cursor-pointer text-primary-600" href={keyFrom.link} target={'_blank'}>
|
|
{keyFrom.text}
|
|
<LinkExternal02 className='w-3 h-3 ml-1 text-primary-600' />
|
|
</a>
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default KeyValidator
|