feat(web): share chat & app chat support files
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
import { forwardRef, useImperativeHandle, useState, useMemo } from 'react';
|
||||
import { Form, Select, Steps, Flex, Alert, Row, Col, Statistic, Input, Button } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { UploadWorkflowModalData, UploadWorkflowModalRef } from '../types'
|
||||
import RbModal from '@/components/RbModal'
|
||||
import UploadFiles from '@/components/Upload/UploadFiles'
|
||||
import { fileUploadUrl } from '@/api/fileStorage'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
|
||||
interface UploadWorkflowModalProps {
|
||||
refresh: () => void;
|
||||
}
|
||||
const steps = [
|
||||
'upload',
|
||||
'complex',
|
||||
'node',
|
||||
'configCheck',
|
||||
'sureInfo',
|
||||
'completed'
|
||||
]
|
||||
const UploadWorkflowModal = forwardRef<UploadWorkflowModalRef, UploadWorkflowModalProps>(({
|
||||
refresh
|
||||
}, ref) => {
|
||||
const { t } = useTranslation();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [form] = Form.useForm<UploadWorkflowModalData>();
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [current, setCurrent] = useState<number>(5);
|
||||
|
||||
// 封装取消方法,添加关闭弹窗逻辑
|
||||
const handleClose = () => {
|
||||
setVisible(false);
|
||||
form.resetFields();
|
||||
setLoading(false)
|
||||
};
|
||||
|
||||
const handleOpen = () => {
|
||||
form.resetFields();
|
||||
setVisible(true);
|
||||
};
|
||||
// 封装保存方法,添加提交逻辑
|
||||
const handleSave = () => {
|
||||
switch(current) {
|
||||
case 0:
|
||||
setCurrent(1)
|
||||
break;
|
||||
case 1:
|
||||
setCurrent(2)
|
||||
break;
|
||||
case 2:
|
||||
setCurrent(3)
|
||||
break;
|
||||
case 3:
|
||||
setCurrent(4)
|
||||
break;
|
||||
case 4:
|
||||
setCurrent(5)
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
default:
|
||||
setCurrent(prev => prev + 1)
|
||||
break;
|
||||
}
|
||||
// form
|
||||
// .validateFields()
|
||||
// .then(() => {
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log('err', err)
|
||||
// });
|
||||
}
|
||||
|
||||
// 暴露给父组件的方法
|
||||
useImperativeHandle(ref, () => ({
|
||||
handleOpen,
|
||||
handleClose
|
||||
}));
|
||||
|
||||
const handleLastStep = () => {
|
||||
setCurrent(prev => prev - 1)
|
||||
}
|
||||
const handleJump = (type: string) => {
|
||||
switch(type) {
|
||||
case 'detail':
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const getFooter = useMemo(() => {
|
||||
switch(current) {
|
||||
case 0:
|
||||
return [
|
||||
<Button key="back" onClick={handleClose}>
|
||||
{t('common.cancel')}
|
||||
</Button>,
|
||||
<Button
|
||||
key="submit"
|
||||
type="primary"
|
||||
loading={loading}
|
||||
onClick={handleSave}
|
||||
>
|
||||
{t('application.nextStep')}
|
||||
</Button>
|
||||
]
|
||||
case 5:
|
||||
return [
|
||||
<Button key="back" onClick={() => handleJump('list')}>
|
||||
{t('application.gotoList')}
|
||||
</Button>,
|
||||
<Button
|
||||
key="submit"
|
||||
type="primary"
|
||||
loading={loading}
|
||||
onClick={() => handleJump('detail')}
|
||||
>
|
||||
{t('application.gotoDetail')}
|
||||
</Button>
|
||||
]
|
||||
default:
|
||||
return [
|
||||
<Button onClick={handleClose}>
|
||||
{t('common.cancel')}
|
||||
</Button>,
|
||||
<Button key="back" onClick={handleLastStep}>
|
||||
{t('application.lastStep')}
|
||||
</Button>,
|
||||
<Button
|
||||
key="submit"
|
||||
type="primary"
|
||||
loading={loading}
|
||||
onClick={handleSave}
|
||||
>
|
||||
{t('application.nextStep')}
|
||||
</Button>
|
||||
]
|
||||
}
|
||||
}, [current])
|
||||
|
||||
return (
|
||||
<RbModal
|
||||
title={t('application.importWorkflow')}
|
||||
open={visible}
|
||||
onCancel={handleClose}
|
||||
okText={t('application.nextStep')}
|
||||
onOk={handleSave}
|
||||
footer={getFooter}
|
||||
width={1000}
|
||||
>
|
||||
<div className='rb:p-3 rb:bg-[#FBFDFF] rb:rounded-lg rb:border rb:border-[#DFE4ED] rb:mb-3'>
|
||||
<Steps
|
||||
labelPlacement="vertical"
|
||||
size="small"
|
||||
current={current}
|
||||
items={steps.map(key => ({ title: t(`application.${key}`) }))}
|
||||
/>
|
||||
</div>
|
||||
{current === 0 &&
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
>
|
||||
<Form.Item name="provider" label={t('application.workflowProvider')}>
|
||||
<Select
|
||||
placeholder={t('common.pleaseSelect')}
|
||||
options={[
|
||||
{ label: 'Dify', value: 'dify' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="file" valuePropName="fileList" noStyle>
|
||||
<UploadFiles
|
||||
action={fileUploadUrl}
|
||||
isCanDrag={true}
|
||||
fileSize={100}
|
||||
multiple={true}
|
||||
maxCount={1}
|
||||
fileType={['yml', 'yaml', 'zip', 'json']}
|
||||
onChange={(fileList) => {
|
||||
console.log('文件列表变化:', fileList);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
}
|
||||
|
||||
{current === 1 &&
|
||||
<Flex vertical gap={12} className="rb:w-[70%]! rb:mx-auto!">
|
||||
{['fileType', 'parse', 'nodes', 'variable'].map(key => (
|
||||
<Alert key={key} message={key} type="success" showIcon />
|
||||
))}
|
||||
|
||||
<Row gutter={12}>
|
||||
{['complex', 'nodes', 'task'].map(key => (
|
||||
<Col key={key} span={8}>
|
||||
<Statistic title={key} value={0} className="rb:text-center rb:border rb:border-[#DFE4ED] rb:rounded-lg rb:py-3!" />
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
</Flex>
|
||||
}
|
||||
|
||||
{/* 节点映射 */}
|
||||
{current === 2 &&
|
||||
<Flex vertical gap={12} className="rb:w-[70%]! rb:mx-auto!">
|
||||
<RbCard>
|
||||
<Flex justify="space-around">
|
||||
<div> Left Node</div>
|
||||
→
|
||||
<div>
|
||||
<Select
|
||||
placeholder={t('common.pleaseSelect')}
|
||||
className="rb:w-50"
|
||||
/>
|
||||
</div>
|
||||
</Flex>
|
||||
</RbCard>
|
||||
</Flex>
|
||||
}
|
||||
{current === 3 &&
|
||||
<Flex vertical gap={12} className="rb:w-[70%]! rb:mx-auto!">
|
||||
|
||||
</Flex>
|
||||
}
|
||||
{current === 4 &&
|
||||
<Form form={form} layout="horizontal" className="rb:w-[70%]! rb:mx-auto!">
|
||||
<div className="rb:text-[#5B6167] rb:font-medium">{t('application.baseInfo')}</div>
|
||||
<Form.Item name="name" label={t('application.workflowName')} rules={[{ required: true }]}>
|
||||
<Input placeholder={t('common.pleaseEnter')} />
|
||||
</Form.Item>
|
||||
<Form.Item name="source" label={t('application.source')}>
|
||||
source
|
||||
</Form.Item>
|
||||
<Form.Item name="fileName" label={t('application.fileName')}>
|
||||
fileName
|
||||
</Form.Item>
|
||||
<Form.Item name="fileSize" label={t('application.fileSize')}>
|
||||
fileSize
|
||||
</Form.Item>
|
||||
<Form.Item name="desciption" label={t('application.desciption')}>
|
||||
<Input.TextArea placeholder={t('common.pleaseEnter')} />
|
||||
</Form.Item>
|
||||
|
||||
<div className="rb:text-[#5B6167] rb:font-medium">{t('application.importStatistic')}</div>
|
||||
<Row gutter={12}>
|
||||
{['complex', 'nodes', 'task'].map(key => (
|
||||
<Col key={key} span={8}>
|
||||
<Statistic title={key} value={0} className="rb:text-center rb:border rb:border-[#DFE4ED] rb:rounded-lg rb:py-3!" />
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
</Form>
|
||||
}
|
||||
{current === 5 &&
|
||||
<Flex justify="center" vertical gap={12} className="rb:w-[70%]! rb:mx-auto! rb:text-center">
|
||||
<div>导入成功</div>
|
||||
<div>您的工作流已成功导入,可以在应用管理中查看和管理</div>
|
||||
</Flex>
|
||||
}
|
||||
</RbModal>
|
||||
);
|
||||
});
|
||||
|
||||
export default UploadWorkflowModal;
|
||||
@@ -12,18 +12,19 @@
|
||||
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Row, Col, App, Select } from 'antd';
|
||||
import { Button, Row, Col, App, Select, Space } from 'antd';
|
||||
import clsx from 'clsx';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
|
||||
import type { Application, ApplicationModalRef, Query } from './types';
|
||||
import ApplicationModal, { types } from './components/ApplicationModal';
|
||||
import type { Application, ApplicationModalRef, Query, UploadWorkflowModalRef } from './types';
|
||||
import SearchInput from '@/components/SearchInput'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import { getApplicationListUrl, deleteApplication } from '@/api/application'
|
||||
import PageScrollList, { type PageScrollListRef } from '@/components/PageScrollList'
|
||||
import { formatDateTime } from '@/utils/format';
|
||||
import UploadWorkflowModal from './components/UploadWorkflowModal'
|
||||
|
||||
/**
|
||||
* Application management main component
|
||||
@@ -35,6 +36,7 @@ const ApplicationManagement: React.FC = () => {
|
||||
const [query, setQuery] = useState<Query>({} as Query);
|
||||
const applicationModalRef = useRef<ApplicationModalRef>(null);
|
||||
const scrollListRef = useRef<PageScrollListRef>(null)
|
||||
const uploadWorkflowModalRef = useRef<UploadWorkflowModalRef>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Convert URLSearchParams to a plain object for easier access
|
||||
@@ -80,6 +82,10 @@ const ApplicationManagement: React.FC = () => {
|
||||
const handleChangeType = (value?: string) => {
|
||||
setQuery(prev => ({...prev, type: value}))
|
||||
}
|
||||
|
||||
const handleImport = () => {
|
||||
uploadWorkflowModalRef.current?.handleOpen()
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Row gutter={16} className="rb:mb-4">
|
||||
@@ -104,9 +110,14 @@ const ApplicationManagement: React.FC = () => {
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12} className="rb:text-right">
|
||||
<Button type="primary" onClick={handleCreate}>
|
||||
{t('application.createApplication')}
|
||||
</Button>
|
||||
<Space size={12}>
|
||||
<Button onClick={handleImport}>
|
||||
{t('application.importWorkflow')}
|
||||
</Button>
|
||||
<Button type="primary" onClick={handleCreate}>
|
||||
{t('application.createApplication')}
|
||||
</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -156,8 +167,13 @@ const ApplicationManagement: React.FC = () => {
|
||||
ref={applicationModalRef}
|
||||
refresh={refresh}
|
||||
/>
|
||||
|
||||
<UploadWorkflowModal
|
||||
ref={uploadWorkflowModalRef}
|
||||
refresh={refresh}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ApplicationManagement;
|
||||
export default ApplicationManagement
|
||||
@@ -173,3 +173,10 @@ export interface ApiExtensionModalRef {
|
||||
/** Open API extension modal */
|
||||
handleOpen: () => void;
|
||||
}
|
||||
|
||||
|
||||
export interface UploadWorkflowModalData {
|
||||
}
|
||||
export interface UploadWorkflowModalRef {
|
||||
handleOpen: () => void;
|
||||
}
|
||||
Reference in New Issue
Block a user