mirror of https://github.com/langgenius/dify.git
feat: http key value inputs
This commit is contained in:
parent
d673b4c219
commit
589ac9b22c
|
|
@ -1,6 +1,6 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import cn from 'classnames'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Method } from '../types'
|
||||
|
|
@ -38,7 +38,6 @@ const ApiInput: FC<Props> = ({
|
|||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
const [isFocus, setIsFocus] = useState(false)
|
||||
const availableVarList = useAvailableVarList(nodeId, {
|
||||
onlyLeafNodeVar: false,
|
||||
|
|
@ -47,10 +46,6 @@ const ApiInput: FC<Props> = ({
|
|||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (isFocus)
|
||||
inputRef.current?.focus()
|
||||
}, [isFocus])
|
||||
return (
|
||||
<div className='flex items-start space-x-1'>
|
||||
<Selector
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import React from 'react'
|
||||
import type { KeyValue } from '../../types'
|
||||
import KeyValueEdit from './key-value-edit'
|
||||
import BulkEdit from './bulk-edit'
|
||||
|
||||
type Props = {
|
||||
readonly: boolean
|
||||
list: KeyValue[]
|
||||
onChange: (newList: KeyValue[]) => void
|
||||
onAdd: () => void
|
||||
isKeyValueEdit: boolean
|
||||
toggleKeyValueEdit: () => void
|
||||
// toggleKeyValueEdit: () => void
|
||||
}
|
||||
|
||||
const KeyValueList: FC<Props> = ({
|
||||
|
|
@ -19,47 +17,40 @@ const KeyValueList: FC<Props> = ({
|
|||
list,
|
||||
onChange,
|
||||
onAdd,
|
||||
isKeyValueEdit,
|
||||
toggleKeyValueEdit,
|
||||
// toggleKeyValueEdit,
|
||||
}) => {
|
||||
const handleBulkValueChange = useCallback((value: string) => {
|
||||
const newList = value.split('\n').map((item) => {
|
||||
const [key, value] = item.split(':')
|
||||
return {
|
||||
key: key ? key.trim() : '',
|
||||
value: value ? value.trim() : '',
|
||||
}
|
||||
})
|
||||
onChange(newList)
|
||||
}, [onChange])
|
||||
// const handleBulkValueChange = useCallback((value: string) => {
|
||||
// const newList = value.split('\n').map((item) => {
|
||||
// const [key, value] = item.split(':')
|
||||
// return {
|
||||
// key: key ? key.trim() : '',
|
||||
// value: value ? value.trim() : '',
|
||||
// }
|
||||
// })
|
||||
// onChange(newList)
|
||||
// }, [onChange])
|
||||
|
||||
const bulkList = (() => {
|
||||
const res = list.map((item) => {
|
||||
if (!item.key && !item.value)
|
||||
return ''
|
||||
if (!item.value)
|
||||
return item.key
|
||||
return `${item.key}:${item.value}`
|
||||
}).join('\n')
|
||||
return res
|
||||
})()
|
||||
return (
|
||||
<>
|
||||
{isKeyValueEdit
|
||||
? <KeyValueEdit
|
||||
readonly={readonly}
|
||||
list={list}
|
||||
onChange={onChange}
|
||||
onAdd={onAdd}
|
||||
onSwitchToBulkEdit={toggleKeyValueEdit}
|
||||
/>
|
||||
: <BulkEdit
|
||||
value={bulkList}
|
||||
onChange={handleBulkValueChange}
|
||||
onSwitchToKeyValueEdit={toggleKeyValueEdit}
|
||||
/>
|
||||
}
|
||||
</>
|
||||
)
|
||||
// const bulkList = (() => {
|
||||
// const res = list.map((item) => {
|
||||
// if (!item.key && !item.value)
|
||||
// return ''
|
||||
// if (!item.value)
|
||||
// return item.key
|
||||
// return `${item.key}:${item.value}`
|
||||
// }).join('\n')
|
||||
// return res
|
||||
// })()
|
||||
return <KeyValueEdit
|
||||
readonly={readonly}
|
||||
list={list}
|
||||
onChange={onChange}
|
||||
onAdd={onAdd}
|
||||
// onSwitchToBulkEdit={toggleKeyValueEdit}
|
||||
/>
|
||||
// : <BulkEdit
|
||||
// value={bulkList}
|
||||
// onChange={handleBulkValueChange}
|
||||
// onSwitchToKeyValueEdit={toggleKeyValueEdit}
|
||||
// />
|
||||
}
|
||||
export default React.memo(KeyValueList)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import produce from 'immer'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import type { KeyValue } from '../../../types'
|
||||
import KeyValueItem from './item'
|
||||
import TooltipPlus from '@/app/components/base/tooltip-plus'
|
||||
import { EditList } from '@/app/components/base/icons/src/vender/solid/communication'
|
||||
// import TooltipPlus from '@/app/components/base/tooltip-plus'
|
||||
// import { EditList } from '@/app/components/base/icons/src/vender/solid/communication'
|
||||
|
||||
const i18nPrefix = 'workflow.nodes.http'
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ type Props = {
|
|||
list: KeyValue[]
|
||||
onChange: (newList: KeyValue[]) => void
|
||||
onAdd: () => void
|
||||
onSwitchToBulkEdit: () => void
|
||||
// onSwitchToBulkEdit: () => void
|
||||
}
|
||||
|
||||
const KeyValueList: FC<Props> = ({
|
||||
|
|
@ -23,7 +23,7 @@ const KeyValueList: FC<Props> = ({
|
|||
list,
|
||||
onChange,
|
||||
onAdd,
|
||||
onSwitchToBulkEdit,
|
||||
// onSwitchToBulkEdit,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ const KeyValueList: FC<Props> = ({
|
|||
<div className='w-1/2 h-full pl-3 border-r border-gray-200'>{t(`${i18nPrefix}.key`)}</div>
|
||||
<div className='flex w-1/2 h-full pl-3 pr-1 items-center justify-between'>
|
||||
<div>{t(`${i18nPrefix}.value`)}</div>
|
||||
{!readonly && (
|
||||
{/* {!readonly && (
|
||||
<TooltipPlus
|
||||
popupContent={t(`${i18nPrefix}.bulkEdit`)}
|
||||
>
|
||||
|
|
@ -61,7 +61,7 @@ const KeyValueList: FC<Props> = ({
|
|||
>
|
||||
<EditList className='w-3 h-3' />
|
||||
</div>
|
||||
</TooltipPlus>)}
|
||||
</TooltipPlus>)} */}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import cn from 'classnames'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import RemoveButton from '@/app/components/workflow/nodes/_base/components/remove-button'
|
||||
import SupportVarInput from '@/app/components/workflow/nodes/_base/components/support-var-input'
|
||||
import Input from '@/app/components/workflow/nodes/_base/components/input-support-select-var'
|
||||
|
||||
type Props = {
|
||||
className?: string
|
||||
|
|
@ -25,15 +25,11 @@ const InputItem: FC<Props> = ({
|
|||
placeholder,
|
||||
readOnly,
|
||||
}) => {
|
||||
const hasValue = !!value
|
||||
const [isEdit, {
|
||||
setTrue: setIsEditTrue,
|
||||
setFalse: setIsEditFalse,
|
||||
}] = useBoolean(false)
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange(e.target.value)
|
||||
}, [onChange])
|
||||
const hasValue = !!value
|
||||
|
||||
const [isFocus, setIsFocus] = useState(false)
|
||||
|
||||
const handleRemove = useCallback((e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
|
|
@ -41,34 +37,47 @@ const InputItem: FC<Props> = ({
|
|||
}, [onRemove])
|
||||
|
||||
return (
|
||||
<div className={cn(className, !isEdit && 'hover:bg-gray-50 hover:cursor-text', 'relative flex h-full items-center pl-2')}>
|
||||
{(isEdit && !readOnly)
|
||||
<div className={cn(className, 'hover:bg-gray-50 hover:cursor-text', 'relative flex h-full items-center')}>
|
||||
{(!readOnly)
|
||||
? (
|
||||
<input
|
||||
type='text'
|
||||
className='w-full h-[18px] leading-[18px] pl-0.5 text-gray-900 text-xs font-normal placeholder:text-gray-300 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200'
|
||||
// <input
|
||||
// type='text'
|
||||
// className='w-full h-[18px] leading-[18px] pl-0.5 text-gray-900 text-xs font-normal placeholder:text-gray-300 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200'
|
||||
// value={value}
|
||||
// onChange={handleChange}
|
||||
// onBlur={setIsEditFalse}
|
||||
// autoFocus
|
||||
// placeholder={placeholder}
|
||||
// readOnly={readOnly}
|
||||
// />
|
||||
<Input
|
||||
className={cn(isFocus ? 'bg-gray-100' : 'bg-width', 'w-0 grow px-3 py-1')}
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
onBlur={setIsEditFalse}
|
||||
autoFocus
|
||||
placeholder={placeholder}
|
||||
onChange={onChange}
|
||||
readOnly={readOnly}
|
||||
nodesOutputVars={[]}
|
||||
onFocusChange={setIsFocus}
|
||||
placeholder={t('workflow.nodes.http.apiPlaceholder')!}
|
||||
placeholderClassName='!leading-[21px]'
|
||||
/>
|
||||
)
|
||||
: <div
|
||||
className="pl-0.5 w-full h-[18px] leading-[18px]"
|
||||
onClick={setIsEditTrue}
|
||||
>
|
||||
{!hasValue && <div className='text-gray-300 text-xs font-normal'>{placeholder}</div>}
|
||||
{hasValue && (
|
||||
<SupportVarInput
|
||||
wrapClassName='w-0 grow truncate flex items-center'
|
||||
textClassName='text-gray-900 text-xs font-normal'
|
||||
<Input
|
||||
className={cn(isFocus ? 'shadow-xs bg-gray-50 border-gray-300' : 'bg-gray-100 border-gray-100', 'w-0 grow rounded-lg px-3 py-[6px] border')}
|
||||
value={value}
|
||||
readonly
|
||||
onChange={onChange}
|
||||
readOnly={readOnly}
|
||||
nodesOutputVars={[]}
|
||||
onFocusChange={setIsFocus}
|
||||
placeholder={t('workflow.nodes.http.apiPlaceholder')!}
|
||||
placeholderClassName='!leading-[21px]'
|
||||
/>
|
||||
)}
|
||||
{hasRemove && !isEdit && (
|
||||
{hasRemove && !isFocus && (
|
||||
<RemoveButton
|
||||
className='group-hover:block hidden absolute right-1 top-0.5'
|
||||
onClick={handleRemove}
|
||||
|
|
|
|||
|
|
@ -45,10 +45,9 @@ const KeyValueItem: FC<Props> = ({
|
|||
|
||||
return (
|
||||
// group class name is for hover row show remove button
|
||||
<div className={cn(className, 'group flex items-center h-7 border-t border-gray-200')}>
|
||||
<div className={cn(className, 'group flex items-center h-min-7 border-t border-gray-200')}>
|
||||
<div className='w-1/2 h-full border-r border-gray-200'>
|
||||
<InputItem
|
||||
className='pr-2.5'
|
||||
value={payload.key}
|
||||
onChange={handleChange('key')}
|
||||
hasRemove={false}
|
||||
|
|
@ -58,7 +57,6 @@ const KeyValueItem: FC<Props> = ({
|
|||
</div>
|
||||
<div className='w-1/2 h-full'>
|
||||
<InputItem
|
||||
className='pr-1'
|
||||
value={payload.value}
|
||||
onChange={handleChange('value')}
|
||||
hasRemove={!readonly && canRemove}
|
||||
|
|
|
|||
|
|
@ -37,13 +37,9 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
|
|||
headers,
|
||||
setHeaders,
|
||||
addHeader,
|
||||
isHeaderKeyValueEdit,
|
||||
toggleIsHeaderKeyValueEdit,
|
||||
params,
|
||||
setParams,
|
||||
addParam,
|
||||
isParamKeyValueEdit,
|
||||
toggleIsParamKeyValueEdit,
|
||||
setBody,
|
||||
isShowAuthorization,
|
||||
showAuthorization,
|
||||
|
|
@ -110,8 +106,6 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
|
|||
onChange={setHeaders}
|
||||
onAdd={addHeader}
|
||||
readonly={readOnly}
|
||||
isKeyValueEdit={isHeaderKeyValueEdit}
|
||||
toggleKeyValueEdit={toggleIsHeaderKeyValueEdit}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
|
|
@ -122,8 +116,6 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
|
|||
onChange={setParams}
|
||||
onAdd={addParam}
|
||||
readonly={readOnly}
|
||||
isKeyValueEdit={isParamKeyValueEdit}
|
||||
toggleKeyValueEdit={toggleIsParamKeyValueEdit}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
|
|
|
|||
Loading…
Reference in New Issue