feat(web): nodeProperties's ui update

This commit is contained in:
zhaoying
2026-01-19 14:49:48 +08:00
parent 2891f2c068
commit ff6bdc1bed
44 changed files with 1267 additions and 814 deletions

View File

@@ -93,6 +93,7 @@ const AuthConfigModal = forwardRef<AuthConfigModalRef, AuthConfigModalProps>(({
initialValues={{
auth: 'none'
}}
size="middle"
>
<FormItem
name="auth"
@@ -102,6 +103,7 @@ const AuthConfigModal = forwardRef<AuthConfigModalRef, AuthConfigModalProps>(({
]}
>
<Select
size="middle"
options={[
{ value: 'none', label: t('workflow.config.http-request.none') },
{ value: 'api_key', label: t('workflow.config.http-request.apiKey') },
@@ -117,6 +119,7 @@ const AuthConfigModal = forwardRef<AuthConfigModalRef, AuthConfigModalProps>(({
]}
>
<Select
size="middle"
options={[
{ value: 'basic', label: t('workflow.config.http-request.basic') },
{ value: 'bearer', label: t('workflow.config.http-request.bearer') },
@@ -132,7 +135,7 @@ const AuthConfigModal = forwardRef<AuthConfigModalRef, AuthConfigModalProps>(({
{ required: true, message: t('common.pleaseEnter') }
]}
>
<Input placeholder={t('common.pleaseEnter')} />
<Input size="middle" placeholder={t('common.pleaseEnter')} />
</FormItem>
}
<FormItem
@@ -142,7 +145,7 @@ const AuthConfigModal = forwardRef<AuthConfigModalRef, AuthConfigModalProps>(({
{ required: true, message: t('common.pleaseEnter') }
]}
>
<Input placeholder={t('common.pleaseEnter')} />
<Input size="middle" placeholder={t('common.pleaseEnter')} />
</FormItem>
</>}
</Form>

View File

@@ -1,7 +1,6 @@
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next'
import { Button, Select, Table, Form, type TableProps } from 'antd';
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
import { PlusOutlined } from '@ant-design/icons';
import type { Suggestion } from '../../Editor/plugin/AutocompletePlugin';
import Empty from '@/components/Empty';
import VariableSelect from '../VariableSelect';
@@ -19,6 +18,7 @@ interface EditableTableProps {
options?: Suggestion[];
typeOptions?: { value: string, label: string }[]
filterBooleanType?: boolean;
size?: "small"
}
const EditableTable: React.FC<EditableTableProps> = ({
@@ -26,7 +26,8 @@ const EditableTable: React.FC<EditableTableProps> = ({
title,
options = [],
typeOptions = [],
filterBooleanType = false
filterBooleanType = false,
size = 'small'
}) => {
const { t } = useTranslation();
@@ -38,21 +39,24 @@ const EditableTable: React.FC<EditableTableProps> = ({
const getColumns = (remove: (index: number) => void): TableProps<TableRow>['columns'] => {
const hasType = typeOptions.length > 0;
const baseWidth = hasType ? '35%' : '45%';
const cellClassName="rb:p-1!"
const contentClassName ="rb:w-[108px]! rb:text-[12px]!"
return [
{
title: t('workflow.config.name'),
dataIndex: 'name',
width: baseWidth,
className: cellClassName,
render: (_: any, __: TableRow, index: number) => (
<Form.Item name={[index, 'name']} noStyle>
<VariableSelect
placeholder={t('common.pleaseSelect')}
size="small"
// size="small"
options={options}
filterBooleanType={filterBooleanType}
popupMatchSelectWidth={false}
className={contentClassName}
size={size}
/>
</Form.Item>
)
@@ -61,18 +65,20 @@ const EditableTable: React.FC<EditableTableProps> = ({
title: t('workflow.config.type'),
dataIndex: 'type',
width: '20%',
className: cellClassName,
render: (_: any, __: TableRow, index: number) => (
<Form.Item shouldUpdate noStyle>
{(form) => (
<Form.Item name={[index, 'type']} noStyle>
<Select
placeholder={t('common.pleaseSelect')}
size="small"
// size="small"
options={typeOptions}
popupMatchSelectWidth={false}
onChange={() => {
form.setFieldValue([...Array.isArray(parentName) ? parentName : [parentName], index, 'value'], undefined);
}}
size={size}
/>
</Form.Item>
)}
@@ -82,7 +88,7 @@ const EditableTable: React.FC<EditableTableProps> = ({
{
title: t('workflow.config.value'),
dataIndex: 'value',
width: baseWidth,
className: cellClassName,
render: (_: any, __: TableRow, index: number) => (
<Form.Item
shouldUpdate={(prevValues, currentValues) => {
@@ -102,10 +108,12 @@ const EditableTable: React.FC<EditableTableProps> = ({
<Form.Item name={[index, 'value']} noStyle>
<VariableSelect
placeholder={t('common.pleaseSelect')}
size="small"
// size="small"
options={filteredOptions}
filterBooleanType={filterBooleanType}
popupMatchSelectWidth={false}
className={contentClassName}
size={size}
/>
</Form.Item>
);
@@ -116,9 +124,12 @@ const EditableTable: React.FC<EditableTableProps> = ({
{
title: '',
dataIndex: 'actions',
width: '10%',
className: cellClassName,
render: (_: any, __: TableRow, index: number) => (
<Button type="text" icon={<DeleteOutlined />} onClick={() => remove(index)} />
<div
className="rb:ml-1 rb:size-4 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/workflow/deleteBg.svg')] rb:hover:bg-[url('@/assets/images/workflow/deleteBg_hover.svg')]"
onClick={() => remove(index)}
></div>
)
}
];
@@ -129,13 +140,11 @@ const EditableTable: React.FC<EditableTableProps> = ({
<Form.List name={parentName}>
{(fields, { add, remove }) => {
const AddButton = ({ block = false }: { block?: boolean }) => (
<Button
type={block ? "dashed" : "text"}
<Button
icon={block ? undefined : <PlusOutlined />}
onClick={() => add(createNewRow())}
size="small"
block={block}
className={block ? "rb:mt-1" : ""}
className={block ? "rb:mt-1 rb:text-[12px]! rb:bg-transparent!" : "rb:text-[12px]!"}
>
{block && `+${t('common.add')}`}
</Button>
@@ -145,8 +154,8 @@ const EditableTable: React.FC<EditableTableProps> = ({
<>
{title && (
<div className="rb:flex rb:items-center rb:mb-2 rb:justify-between">
<div className="rb:font-medium">{title}</div>
<AddButton />
<div className="rb:font-medium rb:text-[12px] rb:leading-4.5">{title}</div>
<AddButton block={true} />
</div>
)}
@@ -161,8 +170,9 @@ const EditableTable: React.FC<EditableTableProps> = ({
columns={getColumns(remove)}
pagination={false}
size="small"
rowClassName="rb:p-0! rb:bg-[#F6F8FC]!"
locale={{ emptyText: <Empty size={88} /> }}
scroll={{ x: 'max-content' }}
style={{ width: '274px' }}
/>
{!title && <AddButton block />}

View File

@@ -1,6 +1,7 @@
import { type FC, useRef } from "react";
import { type FC, useRef, useState } from "react";
import { useTranslation } from 'react-i18next'
import { Form, Row, Col, Select, Button, Divider, InputNumber, Switch, Input } from 'antd'
import { CaretDownOutlined, CaretRightOutlined, SettingOutlined } from '@ant-design/icons';
import Editor from '../../Editor'
import type { Suggestion } from '../../Editor/plugin/AutocompletePlugin'
import AuthConfigModal from './AuthConfigModal'
@@ -65,15 +66,23 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
}
}
console.log('HttpRequest', values)
const [collapsed, setCollapsed] = useState(true)
const handleToggle = () => {
setCollapsed((prev: boolean) => !prev)
}
return (
<>
<div className="rb:flex rb:items-center rb:justify-between rb:mb-4">
<div>API</div>
<Button onClick={handleChangeAuth}>{t('workflow.config.http-request.auth')}</Button>
<div className="rb:flex rb:items-center rb:justify-between rb:mb-1">
<div className="rb:font-medium rb:text-[12px] rb:leading-4.5">API</div>
<Button onClick={handleChangeAuth}
size="small"
type="text"
icon={<SettingOutlined />}
className="rb:mt-1 rb:text-[12px]!"
>{t('workflow.config.http-request.auth')}: {!values?.auth?.auth_type || values?.auth?.auth_type === 'none' ? t('workflow.config.http-request.none') : t('workflow.config.http-request.apiKey')}</Button>
</div>
<Row gutter={16}>
<Row gutter={4}>
<Col span={8}>
<Form.Item name="method">
<Select
@@ -85,35 +94,43 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
{ label: 'PUT', value: 'PUT' },
{ label: 'DELETE', value: 'DELETE' },
]}
className="rb:bg-transparent!"
/>
</Form.Item>
</Col>
<Col span={16}>
<Form.Item name="url">
<Editor options={options.filter(vo => vo.dataType === 'string' || vo.dataType === 'number')} variant="outlined" />
<Editor
options={options.filter(vo => vo.dataType === 'string' || vo.dataType === 'number')}
variant="outlined"
type="input"
size="small"
/>
</Form.Item>
</Col>
</Row>
<Form.Item name="auth" hidden>
</Form.Item>
<Form.Item name="headers">
<Form.Item name="headers" noStyle>
<EditableTable
size="small"
parentName="headers"
title="HEADERS"
options={options.filter(vo => vo.dataType === 'string' || vo.dataType === 'number')}
/>
</Form.Item>
<Form.Item name="params">
<Form.Item name="params" noStyle>
<EditableTable
size="small"
parentName="params"
title="PARAMS"
options={options.filter(vo => vo.dataType === 'string' || vo.dataType === 'number')}
/>
</Form.Item>
<Form.Item label="BODY">
<Form.Item label="BODY" className="rb:mb-0!">
<Form.Item name={['body', 'content_type']}>
<Select
placeholder={t('common.pleaseSelect')}
@@ -131,6 +148,7 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
{values?.body?.content_type === 'form-data' &&
<Form.Item name={['body', 'data']} noStyle>
<EditableTable
size="small"
parentName={['body', 'data']}
options={options.filter(vo => vo.dataType === 'string' || vo.dataType === 'number')}
typeOptions={[
@@ -143,6 +161,7 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
{values?.body?.content_type === 'x-www-form-urlencoded' &&
<Form.Item name={['body', 'data']} noStyle>
<EditableTable
size="small"
parentName={['body', 'data']}
options={options.filter(vo => vo.dataType === 'string' || vo.dataType === 'number')}
filterBooleanType={true}
@@ -150,7 +169,7 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
</Form.Item>
}
{values?.body?.content_type === 'json' &&
<Form.Item name={['body', 'data']}>
<Form.Item name={['body', 'data']} noStyle>
<MessageEditor
key="json"
parentName={['body', 'data']}
@@ -161,7 +180,7 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
</Form.Item>
}
{values?.body?.content_type === 'raw' &&
<Form.Item name={['body', 'data']}>
<Form.Item name={['body', 'data']} noStyle>
<MessageEditor
key="raw"
parentName={['body', 'data']}
@@ -172,7 +191,7 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
</Form.Item>
}
{values?.body?.content_type === 'binary' &&
<Form.Item name={['body', 'data']}>
<Form.Item name={['body', 'data']} noStyle>
<VariableSelect
placeholder={t('common.pleaseSelect')}
options={options.filter(vo => vo.dataType.includes('file'))}
@@ -182,15 +201,19 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
}
</Form.Item>
<Divider />
<Form.Item layout="horizontal" name="verify_ssl" label={t('workflow.config.http-request.verify_ssl')}>
<Form.Item layout="horizontal" name="verify_ssl" label={t('workflow.config.http-request.verify_ssl')} className="rb:mb-0!">
<Switch />
</Form.Item>
<Divider />
<div>{t('workflow.config.http-request.timeouts')}</div>
<div className="rb:font-medium rb:text-[12px] rb:leading-4.5 rb:mb-2.5 rb:cursor-pointer" onClick={handleToggle}>
{t('workflow.config.http-request.timeouts')}
{collapsed ? <CaretRightOutlined /> : <CaretDownOutlined />}
</div>
<Form.Item
name={['timeouts', 'connect_timeout']}
label={t('workflow.config.http-request.connect_timeout')}
hidden={collapsed}
>
<InputNumber
placeholder={t('common.pleaseEnter')}
@@ -201,6 +224,7 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
<Form.Item
name={['timeouts', 'read_timeout']}
label={t('workflow.config.http-request.read_timeout')}
hidden={collapsed}
>
<InputNumber
placeholder={t('common.pleaseEnter')}
@@ -211,6 +235,7 @@ const HttpRequest: FC<{ options: Suggestion[]; selectedNode?: any; graphRef?: an
<Form.Item
name={['timeouts', 'write_timeout']}
label={t('workflow.config.http-request.write_timeout')}
hidden={collapsed}
>
<InputNumber
placeholder={t('common.pleaseEnter')}