feat: http key value inputs

This commit is contained in:
Joel 2024-03-29 17:24:30 +08:00
parent d673b4c219
commit 589ac9b22c
6 changed files with 78 additions and 93 deletions

View File

@ -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

View File

@ -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)

View File

@ -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>
{

View File

@ -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}

View File

@ -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}

View File

@ -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