Ver código fonte

Feat: merge the begin operator's url and file into one field #3355 (#3521)

### What problem does this PR solve?

Feat: merge the begin operator's url and file into one field #3355
### Type of change


- [x] New Feature (non-breaking change which adds functionality)
tags/v0.14.0
balibabu 11 meses atrás
pai
commit
4d42bcd517

+ 0
- 3
web/src/pages/flow/constant.tsx Ver arquivo

import upperFirst from 'lodash/upperFirst'; import upperFirst from 'lodash/upperFirst';
import { import {
CloudUpload, CloudUpload,
Link2,
ListOrdered, ListOrdered,
OptionIcon, OptionIcon,
TextCursorInput, TextCursorInput,
File = 'file', File = 'file',
Integer = 'integer', Integer = 'integer',
Boolean = 'boolean', Boolean = 'boolean',
Url = 'url',
} }


export const BeginQueryTypeIconMap = { export const BeginQueryTypeIconMap = {
[BeginQueryType.File]: CloudUpload, [BeginQueryType.File]: CloudUpload,
[BeginQueryType.Integer]: ListOrdered, [BeginQueryType.Integer]: ListOrdered,
[BeginQueryType.Boolean]: ToggleLeft, [BeginQueryType.Boolean]: ToggleLeft,
[BeginQueryType.Url]: Link2,
}; };

+ 0
- 1
web/src/pages/flow/form/generate-form/dynamic-parameters.tsx Ver arquivo

title: t('key'), title: t('key'),
dataIndex: 'key', dataIndex: 'key',
key: 'key', key: 'key',
width: 50,
onCell: (record: IGenerateParameter) => ({ onCell: (record: IGenerateParameter) => ({
record, record,
editable: true, editable: true,

+ 50
- 107
web/src/pages/flow/run-drawer/index.tsx Ver arquivo

import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import api from '@/utils/api'; import api from '@/utils/api';
import { getAuthorization } from '@/utils/authorization-util'; import { getAuthorization } from '@/utils/authorization-util';
import { InboxOutlined } from '@ant-design/icons';
import { UploadOutlined } from '@ant-design/icons';
import { import {
Button, Button,
Drawer, Drawer,
Flex,
Form, Form,
FormItemProps, FormItemProps,
Input, Input,
Upload, Upload,
} from 'antd'; } from 'antd';
import { pick } from 'lodash'; import { pick } from 'lodash';
import { Link2, Trash2 } from 'lucide-react';
import React, { useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { BeginQueryType } from '../constant'; import { BeginQueryType } from '../constant';
import { PopoverForm } from './popover-form'; import { PopoverForm } from './popover-form';


import { UploadChangeParam, UploadFile } from 'antd/es/upload'; import { UploadChangeParam, UploadFile } from 'antd/es/upload';
import { Link } from 'lucide-react';
import styles from './index.less'; import styles from './index.less';


const RunDrawer = ({ const RunDrawer = ({
[setRecord, showPopover], [setRecord, showPopover],
); );


const handleRemoveUrl = useCallback(
(key: number, index: number) => () => {
const list: any[] = form.getFieldValue(key);

form.setFieldValue(
key,
list.filter((_, idx) => idx !== index),
);
},
[form],
);

const getBeginNodeDataQuery = useGetBeginNodeDataQuery(); const getBeginNodeDataQuery = useGetBeginNodeDataQuery();
const query: BeginQuery[] = getBeginNodeDataQuery(); const query: BeginQuery[] = getBeginNodeDataQuery();


</Form.Item> </Form.Item>
), ),
[BeginQueryType.File]: ( [BeginQueryType.File]: (
<Form.Item
{...props}
valuePropName="fileList"
getValueFromEvent={normFile}
>
<Upload.Dragger
name="file"
action={api.parse}
multiple
headers={{ [Authorization]: getAuthorization() }}
onChange={onChange(q.optional)}
>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">{t('fileManager.uploadTitle')}</p>
<p className="ant-upload-hint">
{t('fileManager.uploadDescription')}
</p>
</Upload.Dragger>
</Form.Item>
<React.Fragment key={idx}>
<Form.Item label={q.name} required={!q.optional}>
<div className="relative">
<Form.Item
{...props}
valuePropName="fileList"
getValueFromEvent={normFile}
noStyle
>
<Upload
name="file"
action={api.parse}
multiple
headers={{ [Authorization]: getAuthorization() }}
onChange={onChange(q.optional)}
>
<Button icon={<UploadOutlined />}>
{t('common.upload')}
</Button>
</Upload>
</Form.Item>
<Form.Item
{...pick(props, ['key', 'label', 'rules'])}
required={!q.optional}
className={urlList.length > 0 ? 'mb-1' : ''}
noStyle
>
<PopoverForm visible={visible} switchVisible={switchVisible}>
<Button
onClick={handleShowPopover(idx)}
className="absolute left-1/2 top-0"
icon={<Link className="size-3" />}
>
{t('flow.pasteFileLink')}
</Button>
</PopoverForm>
</Form.Item>
</div>
</Form.Item>
<Form.Item name={idx} noStyle {...pick(props, ['rules'])} />
</React.Fragment>
), ),
[BeginQueryType.Integer]: ( [BeginQueryType.Integer]: (
<Form.Item {...props}> <Form.Item {...props}>
<Switch></Switch> <Switch></Switch>
</Form.Item> </Form.Item>
), ),
[BeginQueryType.Url]: (
<React.Fragment key={idx}>
<Form.Item
{...pick(props, ['key', 'label', 'rules'])}
required={!q.optional}
className={urlList.length > 0 ? 'mb-1' : ''}
>
<PopoverForm visible={visible} switchVisible={switchVisible}>
<Button
onClick={handleShowPopover(idx)}
className="text-buttonBlueText"
>
{t('flow.pasteFileLink')}
</Button>
</PopoverForm>
</Form.Item>
<Form.Item name={idx} noStyle {...pick(props, ['rules'])} />
<Form.Item
noStyle
shouldUpdate={(prevValues, curValues) =>
prevValues[idx] !== curValues[idx]
}
>
{({ getFieldValue }) => {
const urlInfo: { url: string; result: string }[] =
getFieldValue(idx) || [];
return urlInfo.length ? (
<Flex vertical gap={8} className="mb-3">
{urlInfo.map((u, index) => (
<div
key={index}
className="flex items-center justify-between gap-2 hover:bg-slate-100 group"
>
<Link2 className="size-5"></Link2>
<span className="flex-1 truncate"> {u.url}</span>
<Trash2
className="size-4 invisible group-hover:visible cursor-pointer"
onClick={handleRemoveUrl(idx, index)}
/>
</div>
))}
</Flex>
) : null;
}}
</Form.Item>
</React.Fragment>
),
}; };


return BeginQueryTypeMap[q.type as BeginQueryType]; return BeginQueryTypeMap[q.type as BeginQueryType];
}, },
[
form,
handleRemoveUrl,
handleShowPopover,
onChange,
switchVisible,
t,
visible,
],
[form, handleShowPopover, onChange, switchVisible, t, visible],
); );


const { handleRun } = useSaveGraphBeforeOpeningDebugDrawer(showChatModal!); const { handleRun } = useSaveGraphBeforeOpeningDebugDrawer(showChatModal!);
if (Array.isArray(value)) { if (Array.isArray(value)) {
nextValue = ``; nextValue = ``;


value.forEach((x, idx) => {
if (x?.originFileObj instanceof File) {
if (idx === 0) {
nextValue += `${x.name}\n\n${x.response?.data}\n\n`;
} else {
nextValue += `${x.response?.data}\n\n`;
}
} else {
if (idx === 0) {
nextValue += `${x.url}\n\n${x.result}\n\n`;
} else {
nextValue += `${x.result}\n\n`;
}
}
value.forEach((x) => {
nextValue +=
x?.originFileObj instanceof File
? `${x.name}\n${x.response?.data}\n----\n`
: `${x.url}\n${x.result}\n----\n`;
}); });
} }
return { ...item, value: nextValue }; return { ...item, value: nextValue };
const { basicForm } = forms; const { basicForm } = forms;
const urlInfo = basicForm.getFieldValue(currentRecord) || []; const urlInfo = basicForm.getFieldValue(currentRecord) || [];
basicForm.setFieldsValue({ basicForm.setFieldsValue({
[currentRecord]: [...urlInfo, values],
[currentRecord]: [...urlInfo, { ...values, name: values.url }],
}); });
hidePopover(); hidePopover();
} }

Carregando…
Cancelar
Salvar