mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-29 01:40:51 +00:00
perf: modal
This commit is contained in:
@@ -5,9 +5,9 @@
|
|||||||
"Warning": "Warning",
|
"Warning": "Warning",
|
||||||
"app": {
|
"app": {
|
||||||
"App Detail": "App Detail",
|
"App Detail": "App Detail",
|
||||||
"My Apps": "My Apps",
|
"Confirm Del App Tip": "Confirm to delete the app and all its chats",
|
||||||
"Confirm Save App Tip": "After saving, the advanced orchestration configuration will be overwritten. Make sure that the application does not use advanced orchestration.",
|
"Confirm Save App Tip": "After saving, the advanced orchestration configuration will be overwritten. Make sure that the application does not use advanced orchestration.",
|
||||||
"Confirm Del App Tip": "Confirm to delete the app and all its chats"
|
"My Apps": "My Apps"
|
||||||
},
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"Confirm to clear history": "Confirm to clear history?",
|
"Confirm to clear history": "Confirm to clear history?",
|
||||||
@@ -28,5 +28,9 @@
|
|||||||
"Datasets": "DataSets",
|
"Datasets": "DataSets",
|
||||||
"Store": "Store",
|
"Store": "Store",
|
||||||
"Tools": "Tools"
|
"Tools": "Tools"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"Bill Detail": "Bill Detail",
|
||||||
|
"Pay": "Pay"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,9 +5,9 @@
|
|||||||
"Warning": "提示",
|
"Warning": "提示",
|
||||||
"app": {
|
"app": {
|
||||||
"App Detail": "应用详情",
|
"App Detail": "应用详情",
|
||||||
"My Apps": "我的应用",
|
"Confirm Del App Tip": "确认删除该应用及其所有聊天记录?",
|
||||||
"Confirm Save App Tip": "保存后将会覆盖高级编排配置,请确保该应用未使用高级编排功能。",
|
"Confirm Save App Tip": "保存后将会覆盖高级编排配置,请确保该应用未使用高级编排功能。",
|
||||||
"Confirm Del App Tip": "确认删除该应用及其所有聊天记录?"
|
"My Apps": "我的应用"
|
||||||
},
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"Confirm to clear history": "确认清空该应用的聊天记录?",
|
"Confirm to clear history": "确认清空该应用的聊天记录?",
|
||||||
@@ -28,5 +28,9 @@
|
|||||||
"Datasets": "知识库",
|
"Datasets": "知识库",
|
||||||
"Store": "应用市场",
|
"Store": "应用市场",
|
||||||
"Tools": "工具"
|
"Tools": "工具"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"Bill Detail": "账单详情",
|
||||||
|
"Pay": "充值"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,13 +2,9 @@ import React, { useState } from 'react';
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
Flex,
|
Flex,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalCloseButton,
|
|
||||||
Table,
|
Table,
|
||||||
Thead,
|
Thead,
|
||||||
Tbody,
|
Tbody,
|
||||||
@@ -26,6 +22,7 @@ import { AddIcon, DeleteIcon } from '@chakra-ui/icons';
|
|||||||
import { getErrText, useCopyData } from '@/utils/tools';
|
import { getErrText, useCopyData } from '@/utils/tools';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import MyIcon from '../Icon';
|
import MyIcon from '../Icon';
|
||||||
|
import MyModal from '../MyModal';
|
||||||
|
|
||||||
const APIKeyModal = ({ onClose }: { onClose: () => void }) => {
|
const APIKeyModal = ({ onClose }: { onClose: () => void }) => {
|
||||||
const { Loading } = useLoading();
|
const { Loading } = useLoading();
|
||||||
@@ -60,100 +57,86 @@ const APIKeyModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen onClose={onClose}>
|
<MyModal isOpen onClose={onClose} w={'600px'}>
|
||||||
<ModalOverlay />
|
<Box py={3} px={5}>
|
||||||
<ModalContent w={'600px'} maxW={'90vw'} position={'relative'}>
|
<Box fontWeight={'bold'} fontSize={'2xl'}>
|
||||||
|
API 秘钥管理
|
||||||
|
</Box>
|
||||||
|
<Box fontSize={'sm'} color={'myGray.600'}>
|
||||||
|
如果你不想 API 秘钥被滥用,请勿将秘钥直接放置在前端使用~
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<ModalBody minH={'300px'} maxH={['70vh', '500px']} overflow={'overlay'}>
|
||||||
|
<TableContainer mt={2} position={'relative'}>
|
||||||
|
<Table>
|
||||||
|
<Thead>
|
||||||
|
<Tr>
|
||||||
|
<Th>Api Key</Th>
|
||||||
|
<Th>创建时间</Th>
|
||||||
|
<Th>最后一次使用时间</Th>
|
||||||
|
<Th />
|
||||||
|
</Tr>
|
||||||
|
</Thead>
|
||||||
|
<Tbody fontSize={'sm'}>
|
||||||
|
{apiKeys.map(({ id, apiKey, createTime, lastUsedTime }) => (
|
||||||
|
<Tr key={id}>
|
||||||
|
<Td>{apiKey}</Td>
|
||||||
|
<Td>{dayjs(createTime).format('YYYY/MM/DD HH:mm:ss')}</Td>
|
||||||
|
<Td>
|
||||||
|
{lastUsedTime
|
||||||
|
? dayjs(lastUsedTime).format('YYYY/MM/DD HH:mm:ss')
|
||||||
|
: '没有使用过'}
|
||||||
|
</Td>
|
||||||
|
<Td>
|
||||||
|
<IconButton
|
||||||
|
icon={<DeleteIcon />}
|
||||||
|
size={'xs'}
|
||||||
|
aria-label={'delete'}
|
||||||
|
variant={'base'}
|
||||||
|
colorScheme={'gray'}
|
||||||
|
onClick={() => onclickRemove(id)}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</Tbody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
|
<ModalFooter>
|
||||||
|
<Button
|
||||||
|
variant="base"
|
||||||
|
leftIcon={<AddIcon color={'myGray.600'} fontSize={'sm'} />}
|
||||||
|
onClick={() => onclickCreateApiKey()}
|
||||||
|
>
|
||||||
|
新建秘钥
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
|
||||||
|
<Loading loading={isGetting || isCreating || isDeleting} fixed={false} />
|
||||||
|
<MyModal isOpen={!!apiKey} w={'400px'} onClose={() => setApiKey('')}>
|
||||||
<Box py={3} px={5}>
|
<Box py={3} px={5}>
|
||||||
<Box fontWeight={'bold'} fontSize={'2xl'}>
|
<Box fontWeight={'bold'} fontSize={'2xl'}>
|
||||||
API 秘钥管理
|
新的 API 秘钥
|
||||||
</Box>
|
</Box>
|
||||||
<Box fontSize={'sm'} color={'myGray.600'}>
|
<Box fontSize={'sm'} color={'myGray.600'}>
|
||||||
如果你不想 API 秘钥被滥用,请勿将秘钥直接放置在前端使用~
|
请保管好你的秘钥,秘钥不会再次展示~
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<ModalCloseButton />
|
<ModalBody>
|
||||||
<ModalBody minH={'300px'} maxH={['70vh', '500px']} overflow={'overlay'}>
|
<Flex bg={'myGray.100'} px={3} py={2} cursor={'pointer'} onClick={() => copyData(apiKey)}>
|
||||||
<TableContainer mt={2} position={'relative'}>
|
<Box flex={1}>{apiKey}</Box>
|
||||||
<Table>
|
<MyIcon name={'copy'} w={'16px'}></MyIcon>
|
||||||
<Thead>
|
</Flex>
|
||||||
<Tr>
|
|
||||||
<Th>Api Key</Th>
|
|
||||||
<Th>创建时间</Th>
|
|
||||||
<Th>最后一次使用时间</Th>
|
|
||||||
<Th />
|
|
||||||
</Tr>
|
|
||||||
</Thead>
|
|
||||||
<Tbody fontSize={'sm'}>
|
|
||||||
{apiKeys.map(({ id, apiKey, createTime, lastUsedTime }) => (
|
|
||||||
<Tr key={id}>
|
|
||||||
<Td>{apiKey}</Td>
|
|
||||||
<Td>{dayjs(createTime).format('YYYY/MM/DD HH:mm:ss')}</Td>
|
|
||||||
<Td>
|
|
||||||
{lastUsedTime
|
|
||||||
? dayjs(lastUsedTime).format('YYYY/MM/DD HH:mm:ss')
|
|
||||||
: '没有使用过'}
|
|
||||||
</Td>
|
|
||||||
<Td>
|
|
||||||
<IconButton
|
|
||||||
icon={<DeleteIcon />}
|
|
||||||
size={'xs'}
|
|
||||||
aria-label={'delete'}
|
|
||||||
variant={'base'}
|
|
||||||
colorScheme={'gray'}
|
|
||||||
onClick={() => onclickRemove(id)}
|
|
||||||
/>
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
|
||||||
))}
|
|
||||||
</Tbody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button
|
<Button variant="base" onClick={() => setApiKey('')}>
|
||||||
variant="base"
|
好的
|
||||||
leftIcon={<AddIcon color={'myGray.600'} fontSize={'sm'} />}
|
|
||||||
onClick={() => onclickCreateApiKey()}
|
|
||||||
>
|
|
||||||
新建秘钥
|
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
</MyModal>
|
||||||
<Loading loading={isGetting || isCreating || isDeleting} fixed={false} />
|
</MyModal>
|
||||||
</ModalContent>
|
|
||||||
<Modal isOpen={!!apiKey} onClose={() => setApiKey('')}>
|
|
||||||
<ModalOverlay />
|
|
||||||
<ModalContent w={'400px'} maxW={'90vw'}>
|
|
||||||
<Box py={3} px={5}>
|
|
||||||
<Box fontWeight={'bold'} fontSize={'2xl'}>
|
|
||||||
新的 API 秘钥
|
|
||||||
</Box>
|
|
||||||
<Box fontSize={'sm'} color={'myGray.600'}>
|
|
||||||
请保管好你的秘钥,秘钥不会再次展示~
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
<ModalCloseButton />
|
|
||||||
<ModalBody>
|
|
||||||
<Flex
|
|
||||||
bg={'myGray.100'}
|
|
||||||
px={3}
|
|
||||||
py={2}
|
|
||||||
cursor={'pointer'}
|
|
||||||
onClick={() => copyData(apiKey)}
|
|
||||||
>
|
|
||||||
<Box flex={1}>{apiKey}</Box>
|
|
||||||
<MyIcon name={'copy'} w={'16px'}></MyIcon>
|
|
||||||
</Flex>
|
|
||||||
</ModalBody>
|
|
||||||
<ModalFooter>
|
|
||||||
<Button variant="base" onClick={() => setApiKey('')}>
|
|
||||||
好的
|
|
||||||
</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
</Modal>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,15 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { ModalBody, Box, useTheme } from '@chakra-ui/react';
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalBody,
|
|
||||||
ModalCloseButton,
|
|
||||||
ModalHeader,
|
|
||||||
Box,
|
|
||||||
useTheme
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { ChatItemType } from '@/types/chat';
|
import { ChatItemType } from '@/types/chat';
|
||||||
|
import MyModal from '../MyModal';
|
||||||
|
|
||||||
const ContextModal = ({
|
const ContextModal = ({
|
||||||
context = [],
|
context = [],
|
||||||
@@ -21,35 +13,23 @@ const ContextModal = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<MyModal isOpen={true} onClose={onClose} title={`完整对话记录(${context.length}条)`} h={'80vh'}>
|
||||||
<Modal isOpen={true} onClose={onClose}>
|
<ModalBody pt={0} whiteSpace={'pre-wrap'} textAlign={'justify'} fontSize={'sm'}>
|
||||||
<ModalOverlay />
|
{context.map((item, i) => (
|
||||||
<ModalContent
|
<Box
|
||||||
position={'relative'}
|
key={i}
|
||||||
maxW={'min(90vw, 700px)'}
|
p={2}
|
||||||
h={'80vh'}
|
borderRadius={'lg'}
|
||||||
overflow={'overlay'}
|
border={theme.borders.base}
|
||||||
>
|
_notLast={{ mb: 2 }}
|
||||||
<ModalHeader>完整对话记录({context.length}条)</ModalHeader>
|
position={'relative'}
|
||||||
<ModalCloseButton />
|
>
|
||||||
<ModalBody pt={0} whiteSpace={'pre-wrap'} textAlign={'justify'} fontSize={'sm'}>
|
<Box fontWeight={'bold'}>{item.obj}</Box>
|
||||||
{context.map((item, i) => (
|
<Box>{item.value}</Box>
|
||||||
<Box
|
</Box>
|
||||||
key={i}
|
))}
|
||||||
p={2}
|
</ModalBody>
|
||||||
borderRadius={'lg'}
|
</MyModal>
|
||||||
border={theme.borders.base}
|
|
||||||
_notLast={{ mb: 2 }}
|
|
||||||
position={'relative'}
|
|
||||||
>
|
|
||||||
<Box fontWeight={'bold'}>{item.obj}</Box>
|
|
||||||
<Box>{item.value}</Box>
|
|
||||||
</Box>
|
|
||||||
))}
|
|
||||||
</ModalBody>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,21 +1,13 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import {
|
import { ModalBody, ModalCloseButton, ModalHeader, Box, useTheme } from '@chakra-ui/react';
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalBody,
|
|
||||||
ModalCloseButton,
|
|
||||||
ModalHeader,
|
|
||||||
Box,
|
|
||||||
useTheme
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import MyIcon from '@/components/Icon';
|
|
||||||
import InputDataModal from '@/pages/kb/detail/components/InputDataModal';
|
|
||||||
import { getKbDataItemById } from '@/api/plugins/kb';
|
import { getKbDataItemById } from '@/api/plugins/kb';
|
||||||
import { useLoading } from '@/hooks/useLoading';
|
import { useLoading } from '@/hooks/useLoading';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { getErrText } from '@/utils/tools';
|
import { getErrText } from '@/utils/tools';
|
||||||
import { QuoteItemType } from '@/types/chat';
|
import { QuoteItemType } from '@/types/chat';
|
||||||
|
import MyIcon from '@/components/Icon';
|
||||||
|
import InputDataModal from '@/pages/kb/detail/components/InputDataModal';
|
||||||
|
import MyModal from '../MyModal';
|
||||||
|
|
||||||
const QuoteModal = ({
|
const QuoteModal = ({
|
||||||
onUpdateQuote,
|
onUpdateQuote,
|
||||||
@@ -69,67 +61,59 @@ const QuoteModal = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal isOpen={true} onClose={onClose}>
|
<MyModal isOpen={true} onClose={onClose} h={'80vh'}>
|
||||||
<ModalOverlay />
|
<ModalHeader>
|
||||||
<ModalContent
|
知识库引用({rawSearch.length}条)
|
||||||
position={'relative'}
|
<Box fontSize={'sm'} fontWeight={'normal'}>
|
||||||
maxW={'min(90vw, 700px)'}
|
注意: 修改知识库内容成功后,此处不会显示变更情况。点击编辑后,会显示知识库最新的内容。
|
||||||
h={'80vh'}
|
</Box>
|
||||||
overflow={'overlay'}
|
</ModalHeader>
|
||||||
>
|
<ModalCloseButton />
|
||||||
<ModalHeader>
|
<ModalBody pt={0} whiteSpace={'pre-wrap'} textAlign={'justify'} fontSize={'sm'}>
|
||||||
知识库引用({rawSearch.length}条)
|
{rawSearch.map((item) => (
|
||||||
<Box fontSize={'sm'} fontWeight={'normal'}>
|
<Box
|
||||||
注意: 修改知识库内容成功后,此处不会显示变更情况。点击编辑后,会显示知识库最新的内容。
|
key={item.id}
|
||||||
</Box>
|
flex={'1 0 0'}
|
||||||
</ModalHeader>
|
p={2}
|
||||||
<ModalCloseButton />
|
borderRadius={'lg'}
|
||||||
<ModalBody pt={0} whiteSpace={'pre-wrap'} textAlign={'justify'} fontSize={'sm'}>
|
border={theme.borders.base}
|
||||||
{rawSearch.map((item) => (
|
_notLast={{ mb: 2 }}
|
||||||
|
position={'relative'}
|
||||||
|
_hover={{ '& .edit': { display: 'flex' } }}
|
||||||
|
>
|
||||||
|
{item.source && <Box color={'myGray.600'}>({item.source})</Box>}
|
||||||
|
<Box>{item.q}</Box>
|
||||||
|
<Box>{item.a}</Box>
|
||||||
<Box
|
<Box
|
||||||
key={item.id}
|
className="edit"
|
||||||
flex={'1 0 0'}
|
display={'none'}
|
||||||
p={2}
|
position={'absolute'}
|
||||||
borderRadius={'lg'}
|
right={0}
|
||||||
border={theme.borders.base}
|
top={0}
|
||||||
_notLast={{ mb: 2 }}
|
bottom={0}
|
||||||
position={'relative'}
|
w={'40px'}
|
||||||
_hover={{ '& .edit': { display: 'flex' } }}
|
bg={'rgba(255,255,255,0.9)'}
|
||||||
|
alignItems={'center'}
|
||||||
|
justifyContent={'center'}
|
||||||
|
boxShadow={'-10px 0 10px rgba(255,255,255,1)'}
|
||||||
>
|
>
|
||||||
{item.source && <Box color={'myGray.600'}>({item.source})</Box>}
|
<MyIcon
|
||||||
<Box>{item.q}</Box>
|
name={'edit'}
|
||||||
<Box>{item.a}</Box>
|
w={'18px'}
|
||||||
<Box
|
h={'18px'}
|
||||||
className="edit"
|
cursor={'pointer'}
|
||||||
display={'none'}
|
color={'myGray.600'}
|
||||||
position={'absolute'}
|
_hover={{
|
||||||
right={0}
|
color: 'myBlue.700'
|
||||||
top={0}
|
}}
|
||||||
bottom={0}
|
onClick={() => onclickEdit(item)}
|
||||||
w={'40px'}
|
/>
|
||||||
bg={'rgba(255,255,255,0.9)'}
|
|
||||||
alignItems={'center'}
|
|
||||||
justifyContent={'center'}
|
|
||||||
boxShadow={'-10px 0 10px rgba(255,255,255,1)'}
|
|
||||||
>
|
|
||||||
<MyIcon
|
|
||||||
name={'edit'}
|
|
||||||
w={'18px'}
|
|
||||||
h={'18px'}
|
|
||||||
cursor={'pointer'}
|
|
||||||
color={'myGray.600'}
|
|
||||||
_hover={{
|
|
||||||
color: 'myBlue.700'
|
|
||||||
}}
|
|
||||||
onClick={() => onclickEdit(item)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
</Box>
|
||||||
</ModalBody>
|
))}
|
||||||
<Loading fixed={false} />
|
</ModalBody>
|
||||||
</ModalContent>
|
<Loading fixed={false} />
|
||||||
</Modal>
|
</MyModal>
|
||||||
{editDataItem && (
|
{editDataItem && (
|
||||||
<InputDataModal
|
<InputDataModal
|
||||||
onClose={() => setEditDataItem(undefined)}
|
onClose={() => setEditDataItem(undefined)}
|
||||||
|
@@ -5,19 +5,40 @@ import {
|
|||||||
ModalContent,
|
ModalContent,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
ModalProps
|
ModalContentProps
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
import { DefaultTFuncReturn } from 'i18next';
|
||||||
|
|
||||||
interface Props extends ModalProps {
|
interface Props extends ModalContentProps {
|
||||||
showCloseBtn?: boolean;
|
showCloseBtn?: boolean;
|
||||||
title?: string;
|
title?: any;
|
||||||
|
isCentered?: boolean;
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MyModal = ({ isOpen, onClose, title, children, showCloseBtn = true, ...props }: Props) => {
|
const MyModal = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
title,
|
||||||
|
children,
|
||||||
|
showCloseBtn = true,
|
||||||
|
isCentered,
|
||||||
|
w = 'auto',
|
||||||
|
maxW = ['90vw', '600px'],
|
||||||
|
...props
|
||||||
|
}: Props) => {
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={onClose} autoFocus={false} {...props}>
|
<Modal isOpen={isOpen} onClose={onClose} autoFocus={false} isCentered={isCentered}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent
|
||||||
|
w={w}
|
||||||
|
minW={['300px', '400px']}
|
||||||
|
maxW={maxW}
|
||||||
|
position={'relative'}
|
||||||
|
overflow={'overlay'}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
{!!title && <ModalHeader>{title}</ModalHeader>}
|
{!!title && <ModalHeader>{title}</ModalHeader>}
|
||||||
{showCloseBtn && <ModalCloseButton />}
|
{showCloseBtn && <ModalCloseButton />}
|
||||||
{children}
|
{children}
|
||||||
|
@@ -1,41 +1,26 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { Button, ModalFooter, ModalBody, Image } from '@chakra-ui/react';
|
||||||
Box,
|
import MyModal from '../MyModal';
|
||||||
Button,
|
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalFooter,
|
|
||||||
ModalBody,
|
|
||||||
ModalCloseButton,
|
|
||||||
Image
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
|
|
||||||
const WxConcat = ({ onClose }: { onClose: () => void }) => {
|
const WxConcat = ({ onClose }: { onClose: () => void }) => {
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={true} onClose={onClose}>
|
<MyModal isOpen={true} onClose={onClose} title={'联系方式-wx'}>
|
||||||
<ModalOverlay />
|
<ModalBody textAlign={'center'}>
|
||||||
<ModalContent>
|
<Image
|
||||||
<ModalHeader>联系方式-wx</ModalHeader>
|
style={{ margin: 'auto' }}
|
||||||
<ModalCloseButton />
|
src={'https://otnvvf-imgs.oss.laf.run/wx300.jpg'}
|
||||||
<ModalBody textAlign={'center'}>
|
width={'200px'}
|
||||||
<Image
|
height={'200px'}
|
||||||
style={{ margin: 'auto' }}
|
alt=""
|
||||||
src={'https://otnvvf-imgs.oss.laf.run/wx300.jpg'}
|
/>
|
||||||
width={'200px'}
|
</ModalBody>
|
||||||
height={'200px'}
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</ModalBody>
|
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant={'base'} onClick={onClose}>
|
<Button variant={'base'} onClick={onClose}>
|
||||||
关闭
|
关闭
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</MyModal>
|
||||||
</Modal>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -14,15 +14,6 @@ const { definePartsStyle: selectPart, defineMultiStyleConfig: selectMultiStyle }
|
|||||||
const { definePartsStyle: numInputPart, defineMultiStyleConfig: numInputMultiStyle } =
|
const { definePartsStyle: numInputPart, defineMultiStyleConfig: numInputMultiStyle } =
|
||||||
createMultiStyleConfigHelpers(numberInputAnatomy.keys);
|
createMultiStyleConfigHelpers(numberInputAnatomy.keys);
|
||||||
|
|
||||||
// modal 弹窗
|
|
||||||
const ModalTheme = defineMultiStyleConfig({
|
|
||||||
baseStyle: definePartsStyle({
|
|
||||||
dialog: {
|
|
||||||
maxW: '90vw'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
// 按键
|
// 按键
|
||||||
const Button = defineStyleConfig({
|
const Button = defineStyleConfig({
|
||||||
baseStyle: {
|
baseStyle: {
|
||||||
@@ -313,7 +304,6 @@ export const theme = extendTheme({
|
|||||||
primary2: 'linear-gradient(to bottom right, #2152d9 0%,#3370ff 30%,#4e83fd 80%, #85b1ff 100%)'
|
primary2: 'linear-gradient(to bottom right, #2152d9 0%,#3370ff 30%,#4e83fd 80%, #85b1ff 100%)'
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Modal: ModalTheme,
|
|
||||||
Button,
|
Button,
|
||||||
Input,
|
Input,
|
||||||
Textarea,
|
Textarea,
|
||||||
|
@@ -1,16 +1,6 @@
|
|||||||
import React, { useCallback, useRef } from 'react';
|
import React, { useCallback, useRef } from 'react';
|
||||||
import {
|
import { ModalFooter, ModalBody, Input, useDisclosure, Button } from '@chakra-ui/react';
|
||||||
Modal,
|
import MyModal from '@/components/MyModal';
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalFooter,
|
|
||||||
ModalBody,
|
|
||||||
ModalCloseButton,
|
|
||||||
Input,
|
|
||||||
useDisclosure,
|
|
||||||
Button
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
|
|
||||||
export const useEditInfo = ({
|
export const useEditInfo = ({
|
||||||
title,
|
title,
|
||||||
@@ -58,28 +48,23 @@ export const useEditInfo = ({
|
|||||||
// eslint-disable-next-line react/display-name
|
// eslint-disable-next-line react/display-name
|
||||||
const EditModal = useCallback(
|
const EditModal = useCallback(
|
||||||
() => (
|
() => (
|
||||||
<Modal isOpen={isOpen} onClose={onClose}>
|
<MyModal isOpen={isOpen} onClose={onClose} title={title}>
|
||||||
<ModalOverlay />
|
<ModalBody>
|
||||||
<ModalContent>
|
<Input
|
||||||
<ModalHeader>{title}</ModalHeader>
|
ref={inputRef}
|
||||||
<ModalCloseButton />
|
defaultValue={defaultValue.current}
|
||||||
<ModalBody>
|
placeholder={placeholder}
|
||||||
<Input
|
autoFocus
|
||||||
ref={inputRef}
|
maxLength={20}
|
||||||
defaultValue={defaultValue.current}
|
/>
|
||||||
placeholder={placeholder}
|
</ModalBody>
|
||||||
autoFocus
|
<ModalFooter>
|
||||||
maxLength={20}
|
<Button mr={3} variant={'base'} onClick={onClose}>
|
||||||
/>
|
取消
|
||||||
</ModalBody>
|
</Button>
|
||||||
<ModalFooter>
|
<Button onClick={onclickConfirm}>确认</Button>
|
||||||
<Button mr={3} variant={'base'} onClick={onClose}>
|
</ModalFooter>
|
||||||
取消
|
</MyModal>
|
||||||
</Button>
|
|
||||||
<Button onClick={onclickConfirm}>确认</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
),
|
),
|
||||||
[isOpen, onClose, onclickConfirm, placeholder, title]
|
[isOpen, onClose, onclickConfirm, placeholder, title]
|
||||||
);
|
);
|
||||||
|
@@ -10,7 +10,7 @@ import NProgress from 'nprogress'; //nprogress module
|
|||||||
import Router from 'next/router';
|
import Router from 'next/router';
|
||||||
import { clientInitData, feConfigs } from '@/store/static';
|
import { clientInitData, feConfigs } from '@/store/static';
|
||||||
import { appWithTranslation, useTranslation } from 'next-i18next';
|
import { appWithTranslation, useTranslation } from 'next-i18next';
|
||||||
import { getLangStore, setLangStore } from '@/utils/i18n';
|
import { getLangStore } from '@/utils/i18n';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
@@ -47,8 +47,6 @@ function App({ Component, pageProps }: AppProps) {
|
|||||||
setGoogleVerKey(googleClientVerKey);
|
setGoogleVerKey(googleClientVerKey);
|
||||||
setBaiduTongji(baiduTongji);
|
setBaiduTongji(baiduTongji);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
setLangStore('zh');
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@@ -1,9 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalBody,
|
ModalBody,
|
||||||
Flex,
|
Flex,
|
||||||
Box,
|
Box,
|
||||||
@@ -19,64 +15,64 @@ import { UserBillType } from '@/types/user';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { BillSourceMap } from '@/constants/user';
|
import { BillSourceMap } from '@/constants/user';
|
||||||
import { formatPrice } from '@/utils/user';
|
import { formatPrice } from '@/utils/user';
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const BillDetail = ({ bill, onClose }: { bill: UserBillType; onClose: () => void }) => {
|
const BillDetail = ({ bill, onClose }: { bill: UserBillType; onClose: () => void }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={true} onClose={onClose} isCentered>
|
<MyModal isOpen={true} onClose={onClose} title={t('user.Bill Detail')}>
|
||||||
<ModalOverlay />
|
<ModalBody>
|
||||||
<ModalContent minW={'min(90vw,600px)'}>
|
<Flex alignItems={'center'} pb={4}>
|
||||||
<ModalHeader>账单详情</ModalHeader>
|
<Box flex={'0 0 80px'}>订单号:</Box>
|
||||||
<ModalBody>
|
<Box>{bill.id}</Box>
|
||||||
<Flex alignItems={'center'} pb={4}>
|
</Flex>
|
||||||
<Box flex={'0 0 80px'}>订单号:</Box>
|
<Flex alignItems={'center'} pb={4}>
|
||||||
<Box>{bill.id}</Box>
|
<Box flex={'0 0 80px'}>生成时间:</Box>
|
||||||
</Flex>
|
<Box>{dayjs(bill.time).format('YYYY/MM/DD HH:mm:ss')}</Box>
|
||||||
<Flex alignItems={'center'} pb={4}>
|
</Flex>
|
||||||
<Box flex={'0 0 80px'}>生成时间:</Box>
|
<Flex alignItems={'center'} pb={4}>
|
||||||
<Box>{dayjs(bill.time).format('YYYY/MM/DD HH:mm:ss')}</Box>
|
<Box flex={'0 0 80px'}>应用名:</Box>
|
||||||
</Flex>
|
<Box>{bill.appName}</Box>
|
||||||
<Flex alignItems={'center'} pb={4}>
|
</Flex>
|
||||||
<Box flex={'0 0 80px'}>应用名:</Box>
|
<Flex alignItems={'center'} pb={4}>
|
||||||
<Box>{bill.appName}</Box>
|
<Box flex={'0 0 80px'}>来源:</Box>
|
||||||
</Flex>
|
<Box>{BillSourceMap[bill.source]}</Box>
|
||||||
<Flex alignItems={'center'} pb={4}>
|
</Flex>
|
||||||
<Box flex={'0 0 80px'}>来源:</Box>
|
<Flex alignItems={'center'} pb={4}>
|
||||||
<Box>{BillSourceMap[bill.source]}</Box>
|
<Box flex={'0 0 80px'}>总金额:</Box>
|
||||||
</Flex>
|
<Box fontWeight={'bold'}>{bill.total}元</Box>
|
||||||
<Flex alignItems={'center'} pb={4}>
|
</Flex>
|
||||||
<Box flex={'0 0 80px'}>总金额:</Box>
|
<Box pb={4}>
|
||||||
<Box fontWeight={'bold'}>{bill.total}元</Box>
|
<Box flex={'0 0 80px'} mb={1}>
|
||||||
</Flex>
|
扣费模块
|
||||||
<Box pb={4}>
|
|
||||||
<Box flex={'0 0 80px'} mb={1}>
|
|
||||||
扣费模块
|
|
||||||
</Box>
|
|
||||||
<TableContainer>
|
|
||||||
<Table>
|
|
||||||
<Thead>
|
|
||||||
<Tr>
|
|
||||||
<Th>模块名</Th>
|
|
||||||
<Th>AI模型</Th>
|
|
||||||
<Th>Token长度</Th>
|
|
||||||
<Th>费用</Th>
|
|
||||||
</Tr>
|
|
||||||
</Thead>
|
|
||||||
<Tbody>
|
|
||||||
{bill.list.map((item, i) => (
|
|
||||||
<Tr key={i}>
|
|
||||||
<Td>{item.moduleName}</Td>
|
|
||||||
<Td>{item.model}</Td>
|
|
||||||
<Td>{item.tokenLen}</Td>
|
|
||||||
<Td>{formatPrice(item.amount)}</Td>
|
|
||||||
</Tr>
|
|
||||||
))}
|
|
||||||
</Tbody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</Box>
|
</Box>
|
||||||
</ModalBody>
|
<TableContainer>
|
||||||
</ModalContent>
|
<Table>
|
||||||
</Modal>
|
<Thead>
|
||||||
|
<Tr>
|
||||||
|
<Th>模块名</Th>
|
||||||
|
<Th>AI模型</Th>
|
||||||
|
<Th>Token长度</Th>
|
||||||
|
<Th>费用</Th>
|
||||||
|
</Tr>
|
||||||
|
</Thead>
|
||||||
|
<Tbody>
|
||||||
|
{bill.list.map((item, i) => (
|
||||||
|
<Tr key={i}>
|
||||||
|
<Td>{item.moduleName}</Td>
|
||||||
|
<Td>{item.model}</Td>
|
||||||
|
<Td>{item.tokenLen}</Td>
|
||||||
|
<Td>{formatPrice(item.amount)}</Td>
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</Tbody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Box>
|
||||||
|
</ModalBody>
|
||||||
|
</MyModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -121,7 +121,7 @@ const UserInfo = () => {
|
|||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box flex={'0 0 50px'}>余额:</Box>
|
<Box flex={'0 0 50px'}>余额:</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<strong>{userInfo?.balance}</strong> 元
|
<strong>{userInfo?.balance.toFixed(3)}</strong> 元
|
||||||
</Box>
|
</Box>
|
||||||
<Button size={['xs', 'sm']} w={['70px', '80px']} ml={5} onClick={onOpenPayModal}>
|
<Button size={['xs', 'sm']} w={['70px', '80px']} ml={5} onClick={onOpenPayModal}>
|
||||||
充值
|
充值
|
||||||
|
@@ -1,26 +1,17 @@
|
|||||||
import React, { useState, useCallback } from 'react';
|
import React, { useState, useCallback } from 'react';
|
||||||
import {
|
import { ModalFooter, ModalBody, Button, Input, Box, Grid } from '@chakra-ui/react';
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalFooter,
|
|
||||||
ModalBody,
|
|
||||||
ModalCloseButton,
|
|
||||||
Button,
|
|
||||||
Input,
|
|
||||||
Box,
|
|
||||||
Grid
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { getPayCode, checkPayResult } from '@/api/user';
|
import { getPayCode, checkPayResult } from '@/api/user';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { getErrText } from '@/utils/tools';
|
import { getErrText } from '@/utils/tools';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import Markdown from '@/components/Markdown';
|
import Markdown from '@/components/Markdown';
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
|
||||||
const PayModal = ({ onClose }: { onClose: () => void }) => {
|
const PayModal = ({ onClose }: { onClose: () => void }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { t } = useTranslation();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const [inputVal, setInputVal] = useState<number | ''>('');
|
const [inputVal, setInputVal] = useState<number | ''>('');
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -71,46 +62,42 @@ const PayModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<MyModal
|
||||||
<Modal
|
isOpen={true}
|
||||||
isOpen={true}
|
onClose={() => {
|
||||||
onClose={() => {
|
if (payId) return;
|
||||||
if (payId) return;
|
onClose();
|
||||||
onClose();
|
}}
|
||||||
}}
|
title={t('user.Pay')}
|
||||||
>
|
showCloseBtn={!payId}
|
||||||
<ModalOverlay />
|
>
|
||||||
<ModalContent minW={'auto'}>
|
<ModalBody py={0}>
|
||||||
<ModalHeader>充值</ModalHeader>
|
{!payId && (
|
||||||
{!payId && <ModalCloseButton />}
|
<>
|
||||||
|
<Grid gridTemplateColumns={'repeat(4,1fr)'} gridGap={5} mb={4}>
|
||||||
<ModalBody py={0}>
|
{[10, 20, 50, 100].map((item) => (
|
||||||
{!payId && (
|
<Button
|
||||||
<>
|
key={item}
|
||||||
<Grid gridTemplateColumns={'repeat(4,1fr)'} gridGap={5} mb={4}>
|
variant={item === inputVal ? 'solid' : 'outline'}
|
||||||
{[10, 20, 50, 100].map((item) => (
|
onClick={() => setInputVal(item)}
|
||||||
<Button
|
>
|
||||||
key={item}
|
{item}元
|
||||||
variant={item === inputVal ? 'solid' : 'outline'}
|
</Button>
|
||||||
onClick={() => setInputVal(item)}
|
))}
|
||||||
>
|
</Grid>
|
||||||
{item}元
|
<Box mb={4}>
|
||||||
</Button>
|
<Input
|
||||||
))}
|
value={inputVal}
|
||||||
</Grid>
|
type={'number'}
|
||||||
<Box mb={4}>
|
step={1}
|
||||||
<Input
|
placeholder={'其他金额,请取整数'}
|
||||||
value={inputVal}
|
onChange={(e) => {
|
||||||
type={'number'}
|
setInputVal(Math.floor(+e.target.value));
|
||||||
step={1}
|
}}
|
||||||
placeholder={'其他金额,请取整数'}
|
></Input>
|
||||||
onChange={(e) => {
|
</Box>
|
||||||
setInputVal(Math.floor(+e.target.value));
|
<Markdown
|
||||||
}}
|
source={`
|
||||||
></Input>
|
|
||||||
</Box>
|
|
||||||
<Markdown
|
|
||||||
source={`
|
|
||||||
| 计费项 | 价格: 元/ 1K tokens(包含上下文)|
|
| 计费项 | 价格: 元/ 1K tokens(包含上下文)|
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 知识库 - 索引 | 0.002 |
|
| 知识库 - 索引 | 0.002 |
|
||||||
@@ -118,36 +105,34 @@ const PayModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
| FastAI16k - 对话 | 0.03 |
|
| FastAI16k - 对话 | 0.03 |
|
||||||
| FastAI-Plus - 对话 | 0.45 |
|
| FastAI-Plus - 对话 | 0.45 |
|
||||||
| 文件拆分 | 0.03 |`}
|
| 文件拆分 | 0.03 |`}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{/* 付费二维码 */}
|
{/* 付费二维码 */}
|
||||||
<Box textAlign={'center'}>
|
<Box textAlign={'center'}>
|
||||||
{payId && <Box mb={3}>请微信扫码支付: {inputVal}元,请勿关闭页面</Box>}
|
{payId && <Box mb={3}>请微信扫码支付: {inputVal}元,请勿关闭页面</Box>}
|
||||||
<Box id={'payQRCode'} display={'inline-block'}></Box>
|
<Box id={'payQRCode'} display={'inline-block'}></Box>
|
||||||
</Box>
|
</Box>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
{!payId && (
|
{!payId && (
|
||||||
<>
|
<>
|
||||||
<Button variant={'base'} onClick={onClose}>
|
<Button variant={'base'} onClick={onClose}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
ml={3}
|
ml={3}
|
||||||
isLoading={loading}
|
isLoading={loading}
|
||||||
isDisabled={!inputVal || inputVal === 0}
|
isDisabled={!inputVal || inputVal === 0}
|
||||||
onClick={handleClickPay}
|
onClick={handleClickPay}
|
||||||
>
|
>
|
||||||
获取充值二维码
|
获取充值二维码
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</MyModal>
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ enum TabEnum {
|
|||||||
const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||||
const tabList = useRef([
|
const tabList = useRef([
|
||||||
{ icon: 'meLight', label: '个人信息', id: TabEnum.info, Component: <BillTable /> },
|
{ icon: 'meLight', label: '个人信息', id: TabEnum.info, Component: <BillTable /> },
|
||||||
{ icon: 'billRecordLight', label: '消费记录', id: TabEnum.bill, Component: <BillTable /> },
|
{ icon: 'billRecordLight', label: '使用记录', id: TabEnum.bill, Component: <BillTable /> },
|
||||||
{ icon: 'payRecordLight', label: '充值记录', id: TabEnum.pay, Component: <PayRecordTable /> },
|
{ icon: 'payRecordLight', label: '充值记录', id: TabEnum.pay, Component: <PayRecordTable /> },
|
||||||
{ icon: 'informLight', label: '通知', id: TabEnum.inform, Component: <InformTable /> },
|
{ icon: 'informLight', label: '通知', id: TabEnum.inform, Component: <InformTable /> },
|
||||||
{ icon: 'loginoutLight', label: '登出', id: TabEnum.loginout, Component: () => <></> }
|
{ icon: 'loginoutLight', label: '登出', id: TabEnum.loginout, Component: () => <></> }
|
||||||
|
@@ -1,50 +1,17 @@
|
|||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { NodeProps } from 'reactflow';
|
import { NodeProps } from 'reactflow';
|
||||||
import {
|
import { Box, Button, Table, Thead, Tbody, Tr, Th, Td, TableContainer } from '@chakra-ui/react';
|
||||||
Box,
|
import { AddIcon } from '@chakra-ui/icons';
|
||||||
Button,
|
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalFooter,
|
|
||||||
ModalBody,
|
|
||||||
NumberInput,
|
|
||||||
NumberInputField,
|
|
||||||
NumberInputStepper,
|
|
||||||
NumberIncrementStepper,
|
|
||||||
NumberDecrementStepper,
|
|
||||||
Table,
|
|
||||||
Thead,
|
|
||||||
Tbody,
|
|
||||||
Tr,
|
|
||||||
Th,
|
|
||||||
Td,
|
|
||||||
TableContainer,
|
|
||||||
Flex,
|
|
||||||
Switch,
|
|
||||||
Input,
|
|
||||||
useDisclosure,
|
|
||||||
useTheme,
|
|
||||||
Grid,
|
|
||||||
FormControl
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { AddIcon, SmallAddIcon } from '@chakra-ui/icons';
|
|
||||||
import NodeCard from '../modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { FlowModuleItemType } from '@/types/flow';
|
import { FlowModuleItemType } from '@/types/flow';
|
||||||
import Container from '../modules/Container';
|
import Container from '../modules/Container';
|
||||||
import { SystemInputEnum, VariableInputEnum } from '@/constants/app';
|
import { SystemInputEnum, VariableInputEnum } from '@/constants/app';
|
||||||
import type { VariableItemType } from '@/types/app';
|
import type { VariableItemType } from '@/types/app';
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import { useFieldArray } from 'react-hook-form';
|
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
||||||
|
import VariableEditModal from '../../../VariableEditModal';
|
||||||
|
|
||||||
const VariableTypeList = [
|
|
||||||
{ label: '文本', icon: 'settingLight', key: VariableInputEnum.input },
|
|
||||||
{ label: '下拉单选', icon: 'settingLight', key: VariableInputEnum.select }
|
|
||||||
];
|
|
||||||
export const defaultVariable: VariableItemType = {
|
export const defaultVariable: VariableItemType = {
|
||||||
id: nanoid(),
|
id: nanoid(),
|
||||||
key: 'key',
|
key: 'key',
|
||||||
@@ -58,8 +25,6 @@ export const defaultVariable: VariableItemType = {
|
|||||||
const NodeUserGuide = ({
|
const NodeUserGuide = ({
|
||||||
data: { inputs, outputs, onChangeNode, ...props }
|
data: { inputs, outputs, onChangeNode, ...props }
|
||||||
}: NodeProps<FlowModuleItemType>) => {
|
}: NodeProps<FlowModuleItemType>) => {
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const variables = useMemo(
|
const variables = useMemo(
|
||||||
() =>
|
() =>
|
||||||
(inputs.find((item) => item.key === SystemInputEnum.variables)
|
(inputs.find((item) => item.key === SystemInputEnum.variables)
|
||||||
@@ -67,25 +32,7 @@ const NodeUserGuide = ({
|
|||||||
[inputs]
|
[inputs]
|
||||||
);
|
);
|
||||||
|
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [editVariable, setEditVariable] = useState<VariableItemType>();
|
||||||
const { isOpen, onClose, onOpen } = useDisclosure();
|
|
||||||
|
|
||||||
const { reset, getValues, setValue, register, control, handleSubmit } = useForm<{
|
|
||||||
variable: VariableItemType;
|
|
||||||
}>({
|
|
||||||
defaultValues: {
|
|
||||||
variable: defaultVariable
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
|
||||||
fields: selectEnums,
|
|
||||||
append: appendEnums,
|
|
||||||
remove: removeEnums
|
|
||||||
} = useFieldArray({
|
|
||||||
control,
|
|
||||||
name: 'variable.enums'
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateVariables = useCallback(
|
const updateVariables = useCallback(
|
||||||
(value: VariableItemType[]) => {
|
(value: VariableItemType[]) => {
|
||||||
@@ -102,9 +49,9 @@ const NodeUserGuide = ({
|
|||||||
const onclickSubmit = useCallback(
|
const onclickSubmit = useCallback(
|
||||||
({ variable }: { variable: VariableItemType }) => {
|
({ variable }: { variable: VariableItemType }) => {
|
||||||
updateVariables(variables.map((item) => (item.id === variable.id ? variable : item)));
|
updateVariables(variables.map((item) => (item.id === variable.id ? variable : item)));
|
||||||
onClose();
|
setEditVariable(undefined);
|
||||||
},
|
},
|
||||||
[onClose, updateVariables, variables]
|
[updateVariables, variables]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -134,8 +81,7 @@ const NodeUserGuide = ({
|
|||||||
w={'16px'}
|
w={'16px'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onOpen();
|
setEditVariable(item);
|
||||||
reset({ variable: item });
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<MyIcon
|
<MyIcon
|
||||||
@@ -159,8 +105,7 @@ const NodeUserGuide = ({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
const newVariable = { ...defaultVariable, id: nanoid() };
|
const newVariable = { ...defaultVariable, id: nanoid() };
|
||||||
updateVariables(variables.concat(newVariable));
|
updateVariables(variables.concat(newVariable));
|
||||||
reset({ variable: newVariable });
|
setEditVariable(newVariable);
|
||||||
onOpen();
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
新增
|
新增
|
||||||
@@ -168,133 +113,13 @@ const NodeUserGuide = ({
|
|||||||
</Box>
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
</NodeCard>
|
</NodeCard>
|
||||||
<Modal isOpen={isOpen} onClose={() => {}}>
|
{!!editVariable && (
|
||||||
<ModalOverlay />
|
<VariableEditModal
|
||||||
<ModalContent maxW={'Min(400px,90vw)'}>
|
defaultVariable={editVariable}
|
||||||
<ModalHeader display={'flex'}>
|
onClose={() => setEditVariable(undefined)}
|
||||||
<MyIcon name={'variable'} mr={2} w={'24px'} color={'#FF8A4C'} />
|
onSubmit={onclickSubmit}
|
||||||
变量设置
|
/>
|
||||||
</ModalHeader>
|
)}
|
||||||
<ModalBody>
|
|
||||||
<Flex alignItems={'center'}>
|
|
||||||
<Box w={'70px'}>必填</Box>
|
|
||||||
<Switch {...register('variable.required')} />
|
|
||||||
</Flex>
|
|
||||||
<Flex mt={5} alignItems={'center'}>
|
|
||||||
<Box w={'80px'}>变量名</Box>
|
|
||||||
<Input {...register('variable.label', { required: '变量名不能为空' })} />
|
|
||||||
</Flex>
|
|
||||||
<Flex mt={5} alignItems={'center'}>
|
|
||||||
<Box w={'80px'}>变量 key</Box>
|
|
||||||
<Input {...register('variable.key', { required: '变量 key 不能为空' })} />
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Box mt={5} mb={2}>
|
|
||||||
字段类型
|
|
||||||
</Box>
|
|
||||||
<Grid gridTemplateColumns={'repeat(2,130px)'} gridGap={4}>
|
|
||||||
{VariableTypeList.map((item) => (
|
|
||||||
<Flex
|
|
||||||
key={item.key}
|
|
||||||
px={4}
|
|
||||||
py={1}
|
|
||||||
border={theme.borders.base}
|
|
||||||
borderRadius={'md'}
|
|
||||||
cursor={'pointer'}
|
|
||||||
{...(item.key === getValues('variable.type')
|
|
||||||
? {
|
|
||||||
bg: 'myWhite.600'
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
_hover: {
|
|
||||||
boxShadow: 'md'
|
|
||||||
},
|
|
||||||
onClick: () => {
|
|
||||||
setValue('variable.type', item.key);
|
|
||||||
setRefresh(!refresh);
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<MyIcon name={item.icon as any} w={'16px'} />
|
|
||||||
<Box ml={3}>{item.label}</Box>
|
|
||||||
</Flex>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{getValues('variable.type') === VariableInputEnum.input && (
|
|
||||||
<>
|
|
||||||
<Box mt={5} mb={2}>
|
|
||||||
最大长度
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<NumberInput max={100} min={1} step={1} position={'relative'}>
|
|
||||||
<NumberInputField
|
|
||||||
{...register('variable.maxLen', {
|
|
||||||
min: 1,
|
|
||||||
max: 100,
|
|
||||||
valueAsNumber: true
|
|
||||||
})}
|
|
||||||
max={100}
|
|
||||||
/>
|
|
||||||
<NumberInputStepper>
|
|
||||||
<NumberIncrementStepper />
|
|
||||||
<NumberDecrementStepper />
|
|
||||||
</NumberInputStepper>
|
|
||||||
</NumberInput>
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{getValues('variable.type') === VariableInputEnum.select && (
|
|
||||||
<>
|
|
||||||
<Box mt={5} mb={2}>
|
|
||||||
选项
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
{selectEnums.map((item, i) => (
|
|
||||||
<Flex key={item.id} mb={2} alignItems={'center'}>
|
|
||||||
<FormControl>
|
|
||||||
<Input
|
|
||||||
{...register(`variable.enums.${i}.value`, {
|
|
||||||
required: '选项内容不能为空'
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<MyIcon
|
|
||||||
ml={3}
|
|
||||||
name={'delete'}
|
|
||||||
w={'16px'}
|
|
||||||
cursor={'pointer'}
|
|
||||||
p={2}
|
|
||||||
borderRadius={'lg'}
|
|
||||||
_hover={{ bg: 'red.100' }}
|
|
||||||
onClick={() => removeEnums(i)}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
))}
|
|
||||||
</Box>
|
|
||||||
<Button
|
|
||||||
variant={'solid'}
|
|
||||||
w={'100%'}
|
|
||||||
textAlign={'left'}
|
|
||||||
leftIcon={<SmallAddIcon />}
|
|
||||||
bg={'myGray.100 !important'}
|
|
||||||
onClick={() => appendEnums({ value: '' })}
|
|
||||||
>
|
|
||||||
添加选项
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</ModalBody>
|
|
||||||
|
|
||||||
<ModalFooter>
|
|
||||||
<Button variant={'base'} mr={3} onClick={onClose}>
|
|
||||||
取消
|
|
||||||
</Button>
|
|
||||||
<Button onClick={handleSubmit(onclickSubmit)}>确认</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -27,9 +27,9 @@ import {
|
|||||||
} from '@/types/flow';
|
} from '@/types/flow';
|
||||||
import { AppModuleItemType } from '@/types/app';
|
import { AppModuleItemType } from '@/types/app';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
import { putAppById } from '@/api/app';
|
|
||||||
import { useRequest } from '@/hooks/useRequest';
|
import { useRequest } from '@/hooks/useRequest';
|
||||||
import type { AppSchema } from '@/types/mongoSchema';
|
import type { AppSchema } from '@/types/mongoSchema';
|
||||||
|
import { useUserStore } from '@/store/user';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
@@ -92,6 +92,7 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||||
const ChatTestRef = useRef<ChatTestComponentRef>(null);
|
const ChatTestRef = useRef<ChatTestComponentRef>(null);
|
||||||
|
const { updateAppDetail } = useUserStore();
|
||||||
const { x, y, zoom } = useViewport();
|
const { x, y, zoom } = useViewport();
|
||||||
const [nodes, setNodes, onNodesChange] = useNodesState<FlowModuleItemType>([]);
|
const [nodes, setNodes, onNodesChange] = useNodesState<FlowModuleItemType>([]);
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||||
@@ -245,7 +246,7 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => {
|
|||||||
|
|
||||||
const { mutate: onclickSave, isLoading } = useRequest({
|
const { mutate: onclickSave, isLoading } = useRequest({
|
||||||
mutationFn: () => {
|
mutationFn: () => {
|
||||||
return putAppById(app._id, {
|
return updateAppDetail(app._id, {
|
||||||
modules: flow2AppModules()
|
modules: flow2AppModules()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@@ -460,22 +460,32 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
相似度: {getValues('kb.searchSimilarity')}, 单次搜索数量: {getValues('kb.searchLimit')},
|
相似度: {getValues('kb.searchSimilarity')}, 单次搜索数量: {getValues('kb.searchLimit')},
|
||||||
空搜索时拒绝回复: {getValues('kb.searchEmptyText') !== '' ? 'true' : 'false'}
|
空搜索时拒绝回复: {getValues('kb.searchEmptyText') !== '' ? 'true' : 'false'}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Grid templateColumns={['1fr', 'repeat(2,1fr)']} my={2} gridGap={[2, 4]}>
|
<Grid templateColumns={['repeat(2,1fr)', 'repeat(3,1fr)']} my={2} gridGap={[2, 4]}>
|
||||||
{selectedKbList.map((item) => (
|
{selectedKbList.map((item) => (
|
||||||
<Flex
|
<MyTooltip key={item._id} label={'查看知识库详情'}>
|
||||||
key={item._id}
|
<Flex
|
||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
p={2}
|
p={2}
|
||||||
bg={'white'}
|
bg={'white'}
|
||||||
boxShadow={'0 4px 8px -2px rgba(16,24,40,.1),0 2px 4px -2px rgba(16,24,40,.06)'}
|
boxShadow={'0 4px 8px -2px rgba(16,24,40,.1),0 2px 4px -2px rgba(16,24,40,.06)'}
|
||||||
borderRadius={'md'}
|
borderRadius={'md'}
|
||||||
border={theme.borders.base}
|
border={theme.borders.base}
|
||||||
>
|
cursor={'pointer'}
|
||||||
<Avatar src={item.avatar} w={'18px'} mr={1} />
|
onClick={() =>
|
||||||
<Box flex={'1 0 0'} w={0} className={'textEllipsis'} fontSize={'sm'}>
|
router.push({
|
||||||
{item.name}
|
pathname: '/kb/detail',
|
||||||
</Box>
|
query: {
|
||||||
</Flex>
|
kbId: item._id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Avatar src={item.avatar} w={'18px'} mr={1} />
|
||||||
|
<Box flex={'1 0 0'} w={0} className={'textEllipsis'} fontSize={'sm'}>
|
||||||
|
{item.name}
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</MyTooltip>
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
|
@@ -6,13 +6,8 @@ import {
|
|||||||
FormControl,
|
FormControl,
|
||||||
Input,
|
Input,
|
||||||
Textarea,
|
Textarea,
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalBody,
|
ModalBody
|
||||||
ModalCloseButton
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { AppSchema } from '@/types/mongoSchema';
|
import { AppSchema } from '@/types/mongoSchema';
|
||||||
@@ -23,6 +18,7 @@ import { getErrText } from '@/utils/tools';
|
|||||||
import { useUserStore } from '@/store/user';
|
import { useUserStore } from '@/store/user';
|
||||||
import { useRequest } from '@/hooks/useRequest';
|
import { useRequest } from '@/hooks/useRequest';
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
|
||||||
const InfoModal = ({
|
const InfoModal = ({
|
||||||
defaultApp,
|
defaultApp,
|
||||||
@@ -120,61 +116,56 @@ const InfoModal = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={true} onClose={onClose}>
|
<MyModal isOpen={true} onClose={onClose} title={'应用信息设置'}>
|
||||||
<ModalOverlay />
|
<ModalBody>
|
||||||
<ModalContent maxW={'min(90vw,470px)'}>
|
<Box>头像 & 名称</Box>
|
||||||
<ModalHeader>应用信息设置</ModalHeader>
|
<Flex mt={2} alignItems={'center'}>
|
||||||
<ModalCloseButton />
|
<Avatar
|
||||||
<ModalBody>
|
src={getValues('avatar')}
|
||||||
<Box>头像 & 名称</Box>
|
w={['26px', '34px']}
|
||||||
<Flex mt={2} alignItems={'center'}>
|
h={['26px', '34px']}
|
||||||
<Avatar
|
cursor={'pointer'}
|
||||||
src={getValues('avatar')}
|
borderRadius={'lg'}
|
||||||
w={['26px', '34px']}
|
mr={4}
|
||||||
h={['26px', '34px']}
|
title={'点击切换头像'}
|
||||||
cursor={'pointer'}
|
onClick={() => onOpenSelectFile()}
|
||||||
borderRadius={'lg'}
|
/>
|
||||||
mr={4}
|
<FormControl>
|
||||||
title={'点击切换头像'}
|
<Input
|
||||||
onClick={() => onOpenSelectFile()}
|
bg={'myWhite.600'}
|
||||||
/>
|
placeholder={'给应用设置一个名称'}
|
||||||
<FormControl>
|
{...register('name', {
|
||||||
<Input
|
required: '展示名称不能为空'
|
||||||
bg={'myWhite.600'}
|
})}
|
||||||
placeholder={'给应用设置一个名称'}
|
></Input>
|
||||||
{...register('name', {
|
</FormControl>
|
||||||
required: '展示名称不能为空'
|
</Flex>
|
||||||
})}
|
<Box mt={7} mb={1}>
|
||||||
></Input>
|
应用介绍
|
||||||
</FormControl>
|
</Box>
|
||||||
</Flex>
|
{/* <Box color={'myGray.500'} mb={2} fontSize={'sm'}>
|
||||||
<Box mt={7} mb={1}>
|
|
||||||
应用介绍
|
|
||||||
</Box>
|
|
||||||
{/* <Box color={'myGray.500'} mb={2} fontSize={'sm'}>
|
|
||||||
该介绍主要用于记忆和在应用市场展示
|
该介绍主要用于记忆和在应用市场展示
|
||||||
</Box> */}
|
</Box> */}
|
||||||
<Textarea
|
<Textarea
|
||||||
rows={4}
|
rows={4}
|
||||||
maxLength={500}
|
maxLength={500}
|
||||||
placeholder={'给你的 AI 应用一个介绍'}
|
placeholder={'给你的 AI 应用一个介绍'}
|
||||||
bg={'myWhite.600'}
|
bg={'myWhite.600'}
|
||||||
{...register('intro')}
|
{...register('intro')}
|
||||||
/>
|
/>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant={'base'} mr={3} onClick={onClose}>
|
<Button variant={'base'} mr={3} onClick={onClose}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
<Button isLoading={btnLoading} onClick={saveUpdateModel}>
|
<Button isLoading={btnLoading} onClick={saveUpdateModel}>
|
||||||
保存
|
保存
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
|
||||||
|
|
||||||
<File onSelect={onSelectFile} />
|
<File onSelect={onSelectFile} />
|
||||||
</Modal>
|
</MyModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -4,13 +4,9 @@ import {
|
|||||||
Flex,
|
Flex,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalCloseButton,
|
|
||||||
useTheme,
|
useTheme,
|
||||||
Textarea
|
Textarea
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
@@ -22,6 +18,7 @@ import type { SelectedKbType } from '@/types/plugin';
|
|||||||
import { useGlobalStore } from '@/store/global';
|
import { useGlobalStore } from '@/store/global';
|
||||||
import MySlider from '@/components/Slider';
|
import MySlider from '@/components/Slider';
|
||||||
import MyTooltip from '@/components/MyTooltip';
|
import MyTooltip from '@/components/MyTooltip';
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
|
||||||
export type KbParamsType = {
|
export type KbParamsType = {
|
||||||
searchSimilarity: number;
|
searchSimilarity: number;
|
||||||
@@ -45,17 +42,15 @@ export const KBSelectModal = ({
|
|||||||
const { isPc } = useGlobalStore();
|
const { isPc } = useGlobalStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={true} isCentered={!isPc} onClose={onClose}>
|
<MyModal
|
||||||
<ModalOverlay />
|
isOpen={true}
|
||||||
<ModalContent
|
isCentered={!isPc}
|
||||||
display={'flex'}
|
maxW={['90vw', '800px']}
|
||||||
flexDirection={'column'}
|
w={'800px'}
|
||||||
w={'800px'}
|
onClose={onClose}
|
||||||
maxW={'90vw'}
|
>
|
||||||
h={['90vh', 'auto']}
|
<Flex flexDirection={'column'} h={['90vh', 'auto']}>
|
||||||
>
|
|
||||||
<ModalHeader>关联的知识库({selectedKbList.length})</ModalHeader>
|
<ModalHeader>关联的知识库({selectedKbList.length})</ModalHeader>
|
||||||
<ModalCloseButton />
|
|
||||||
<ModalBody
|
<ModalBody
|
||||||
flex={['1 0 0', '0 0 auto']}
|
flex={['1 0 0', '0 0 auto']}
|
||||||
maxH={'80vh'}
|
maxH={'80vh'}
|
||||||
@@ -115,8 +110,8 @@ export const KBSelectModal = ({
|
|||||||
完成
|
完成
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</Flex>
|
||||||
</Modal>
|
</MyModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,11 +132,8 @@ export const KbParamsModal = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={true} onClose={onClose}>
|
<MyModal isOpen={true} onClose={onClose} title={'搜索参数调整'}>
|
||||||
<ModalOverlay />
|
<Flex flexDirection={'column'}>
|
||||||
<ModalContent display={'flex'} flexDirection={'column'} w={'600px'} maxW={'90vw'}>
|
|
||||||
<ModalHeader>搜索参数调整</ModalHeader>
|
|
||||||
<ModalCloseButton />
|
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Box display={['block', 'flex']} pt={3} pb={5}>
|
<Box display={['block', 'flex']} pt={3} pb={5}>
|
||||||
<Box flex={'0 0 100px'} mb={[8, 0]}>
|
<Box flex={'0 0 100px'} mb={[8, 0]}>
|
||||||
@@ -214,8 +206,8 @@ export const KbParamsModal = ({
|
|||||||
完成
|
完成
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</Flex>
|
||||||
</Modal>
|
</MyModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Flex,
|
Flex,
|
||||||
Box,
|
Box,
|
||||||
@@ -11,19 +11,9 @@ import {
|
|||||||
Td,
|
Td,
|
||||||
Tbody,
|
Tbody,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalCloseButton,
|
|
||||||
FormControl,
|
FormControl,
|
||||||
Slider,
|
|
||||||
SliderTrack,
|
|
||||||
SliderFilledTrack,
|
|
||||||
SliderThumb,
|
|
||||||
SliderMark,
|
|
||||||
Input
|
Input
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||||
@@ -36,12 +26,12 @@ import { formatTimeToChatTime, useCopyData, getErrText } from '@/utils/tools';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { defaultShareChat } from '@/constants/model';
|
import { defaultShareChat } from '@/constants/model';
|
||||||
import type { ShareChatEditType } from '@/types/app';
|
import type { ShareChatEditType } from '@/types/app';
|
||||||
import MyTooltip from '@/components/MyTooltip';
|
|
||||||
import { useRequest } from '@/hooks/useRequest';
|
import { useRequest } from '@/hooks/useRequest';
|
||||||
import { formatPrice } from '@/utils/user';
|
import { formatPrice } from '@/utils/user';
|
||||||
|
import MyTooltip from '@/components/MyTooltip';
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
|
||||||
const Share = ({ appId }: { appId: string }) => {
|
const Share = ({ appId }: { appId: string }) => {
|
||||||
const { toast } = useToast();
|
|
||||||
const { Loading, setIsLoading } = useLoading();
|
const { Loading, setIsLoading } = useLoading();
|
||||||
const { copyData } = useCopyData();
|
const { copyData } = useCopyData();
|
||||||
const {
|
const {
|
||||||
@@ -175,42 +165,41 @@ const Share = ({ appId }: { appId: string }) => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
{/* create shareChat modal */}
|
{/* create shareChat modal */}
|
||||||
<Modal isOpen={isOpenCreateShareChat} onClose={onCloseCreateShareChat}>
|
<MyModal
|
||||||
<ModalOverlay />
|
isOpen={isOpenCreateShareChat}
|
||||||
<ModalContent maxW={'min(90vw,500px)'}>
|
onClose={onCloseCreateShareChat}
|
||||||
<ModalHeader>创建免登录窗口</ModalHeader>
|
title={'创建免登录窗口'}
|
||||||
<ModalCloseButton />
|
>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box flex={'0 0 60px'} w={0}>
|
<Box flex={'0 0 60px'} w={0}>
|
||||||
名称:
|
名称:
|
||||||
</Box>
|
</Box>
|
||||||
<Input
|
<Input
|
||||||
placeholder="记录名字,仅用于展示"
|
placeholder="记录名字,仅用于展示"
|
||||||
maxLength={20}
|
maxLength={20}
|
||||||
{...registerShareChat('name', {
|
{...registerShareChat('name', {
|
||||||
required: '记录名称不能为空'
|
required: '记录名称不能为空'
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant={'base'} mr={3} onClick={onCloseCreateShareChat}>
|
<Button variant={'base'} mr={3} onClick={onCloseCreateShareChat}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
isLoading={creating}
|
isLoading={creating}
|
||||||
onClick={submitShareChat((data) => onclickCreateShareChat(data))}
|
onClick={submitShareChat((data) => onclickCreateShareChat(data))}
|
||||||
>
|
>
|
||||||
确认
|
确认
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</MyModal>
|
||||||
</Modal>
|
|
||||||
<Loading loading={isFetching} fixed={false} />
|
<Loading loading={isFetching} fixed={false} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@@ -2,9 +2,6 @@ import React, { useState } from 'react';
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
@@ -28,6 +25,7 @@ import { useForm } from 'react-hook-form';
|
|||||||
import { useFieldArray } from 'react-hook-form';
|
import { useFieldArray } from 'react-hook-form';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
|
||||||
const VariableTypeList = [
|
const VariableTypeList = [
|
||||||
{ label: '文本', icon: 'settingLight', key: VariableInputEnum.input },
|
{ label: '文本', icon: 'settingLight', key: VariableInputEnum.input },
|
||||||
@@ -67,133 +65,130 @@ const VariableEditModal = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={true} onClose={onClose}>
|
<MyModal isOpen={true} onClose={onClose}>
|
||||||
<ModalOverlay />
|
<ModalHeader display={'flex'}>
|
||||||
<ModalContent maxW={'Min(400px,90vw)'}>
|
<MyIcon name={'variable'} mr={2} w={'24px'} color={'#FF8A4C'} />
|
||||||
<ModalHeader display={'flex'}>
|
变量设置
|
||||||
<MyIcon name={'variable'} mr={2} w={'24px'} color={'#FF8A4C'} />
|
</ModalHeader>
|
||||||
变量设置
|
<ModalBody>
|
||||||
</ModalHeader>
|
<Flex alignItems={'center'}>
|
||||||
<ModalBody>
|
<Box w={'70px'}>必填</Box>
|
||||||
<Flex alignItems={'center'}>
|
<Switch {...register('variable.required')} />
|
||||||
<Box w={'70px'}>必填</Box>
|
</Flex>
|
||||||
<Switch {...register('variable.required')} />
|
<Flex mt={5} alignItems={'center'}>
|
||||||
</Flex>
|
<Box w={'80px'}>变量名</Box>
|
||||||
<Flex mt={5} alignItems={'center'}>
|
<Input {...register('variable.label', { required: '变量名不能为空' })} />
|
||||||
<Box w={'80px'}>变量名</Box>
|
</Flex>
|
||||||
<Input {...register('variable.label', { required: '变量名不能为空' })} />
|
<Flex mt={5} alignItems={'center'}>
|
||||||
</Flex>
|
<Box w={'80px'}>变量 key</Box>
|
||||||
<Flex mt={5} alignItems={'center'}>
|
<Input {...register('variable.key', { required: '变量 key 不能为空' })} />
|
||||||
<Box w={'80px'}>变量 key</Box>
|
</Flex>
|
||||||
<Input {...register('variable.key', { required: '变量 key 不能为空' })} />
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Box mt={5} mb={2}>
|
<Box mt={5} mb={2}>
|
||||||
字段类型
|
字段类型
|
||||||
</Box>
|
</Box>
|
||||||
<Grid gridTemplateColumns={'repeat(2,130px)'} gridGap={4}>
|
<Grid gridTemplateColumns={'repeat(2,130px)'} gridGap={4}>
|
||||||
{VariableTypeList.map((item) => (
|
{VariableTypeList.map((item) => (
|
||||||
<Flex
|
<Flex
|
||||||
key={item.key}
|
key={item.key}
|
||||||
px={4}
|
px={4}
|
||||||
py={1}
|
py={1}
|
||||||
border={theme.borders.base}
|
border={theme.borders.base}
|
||||||
borderRadius={'md'}
|
borderRadius={'md'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
{...(item.key === getValues('variable.type')
|
{...(item.key === getValues('variable.type')
|
||||||
? {
|
? {
|
||||||
bg: 'myWhite.600'
|
bg: 'myWhite.600'
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
_hover: {
|
||||||
|
boxShadow: 'md'
|
||||||
|
},
|
||||||
|
onClick: () => {
|
||||||
|
setValue('variable.type', item.key);
|
||||||
|
setRefresh(!refresh);
|
||||||
}
|
}
|
||||||
: {
|
})}
|
||||||
_hover: {
|
>
|
||||||
boxShadow: 'md'
|
<MyIcon name={item.icon as any} w={'16px'} />
|
||||||
},
|
<Box ml={3}>{item.label}</Box>
|
||||||
onClick: () => {
|
</Flex>
|
||||||
setValue('variable.type', item.key);
|
))}
|
||||||
setRefresh(!refresh);
|
</Grid>
|
||||||
}
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<MyIcon name={item.icon as any} w={'16px'} />
|
|
||||||
<Box ml={3}>{item.label}</Box>
|
|
||||||
</Flex>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{getValues('variable.type') === VariableInputEnum.input && (
|
{getValues('variable.type') === VariableInputEnum.input && (
|
||||||
<>
|
<>
|
||||||
<Box mt={5} mb={2}>
|
<Box mt={5} mb={2}>
|
||||||
最大长度
|
最大长度
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<NumberInput max={100} min={1} step={1} position={'relative'}>
|
<NumberInput max={100} min={1} step={1} position={'relative'}>
|
||||||
<NumberInputField
|
<NumberInputField
|
||||||
{...register('variable.maxLen', {
|
{...register('variable.maxLen', {
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 100,
|
max: 100,
|
||||||
valueAsNumber: true
|
valueAsNumber: true
|
||||||
})}
|
})}
|
||||||
max={100}
|
max={100}
|
||||||
/>
|
/>
|
||||||
<NumberInputStepper>
|
<NumberInputStepper>
|
||||||
<NumberIncrementStepper />
|
<NumberIncrementStepper />
|
||||||
<NumberDecrementStepper />
|
<NumberDecrementStepper />
|
||||||
</NumberInputStepper>
|
</NumberInputStepper>
|
||||||
</NumberInput>
|
</NumberInput>
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{getValues('variable.type') === VariableInputEnum.select && (
|
{getValues('variable.type') === VariableInputEnum.select && (
|
||||||
<>
|
<>
|
||||||
<Box mt={5} mb={2}>
|
<Box mt={5} mb={2}>
|
||||||
选项
|
选项
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
{selectEnums.map((item, i) => (
|
{selectEnums.map((item, i) => (
|
||||||
<Flex key={item.id} mb={2} alignItems={'center'}>
|
<Flex key={item.id} mb={2} alignItems={'center'}>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
{...register(`variable.enums.${i}.value`, {
|
{...register(`variable.enums.${i}.value`, {
|
||||||
required: '选项内容不能为空'
|
required: '选项内容不能为空'
|
||||||
})}
|
})}
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<MyIcon
|
|
||||||
ml={3}
|
|
||||||
name={'delete'}
|
|
||||||
w={'16px'}
|
|
||||||
cursor={'pointer'}
|
|
||||||
p={2}
|
|
||||||
borderRadius={'lg'}
|
|
||||||
_hover={{ bg: 'red.100' }}
|
|
||||||
onClick={() => removeEnums(i)}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</FormControl>
|
||||||
))}
|
<MyIcon
|
||||||
</Box>
|
ml={3}
|
||||||
<Button
|
name={'delete'}
|
||||||
variant={'solid'}
|
w={'16px'}
|
||||||
w={'100%'}
|
cursor={'pointer'}
|
||||||
textAlign={'left'}
|
p={2}
|
||||||
leftIcon={<SmallAddIcon />}
|
borderRadius={'lg'}
|
||||||
bg={'myGray.100 !important'}
|
_hover={{ bg: 'red.100' }}
|
||||||
onClick={() => appendEnums({ value: '' })}
|
onClick={() => removeEnums(i)}
|
||||||
>
|
/>
|
||||||
添加选项
|
</Flex>
|
||||||
</Button>
|
))}
|
||||||
</>
|
</Box>
|
||||||
)}
|
<Button
|
||||||
</ModalBody>
|
variant={'solid'}
|
||||||
|
w={'100%'}
|
||||||
|
textAlign={'left'}
|
||||||
|
leftIcon={<SmallAddIcon />}
|
||||||
|
bg={'myGray.100 !important'}
|
||||||
|
onClick={() => appendEnums({ value: '' })}
|
||||||
|
>
|
||||||
|
添加选项
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant={'base'} mr={3} onClick={onClose}>
|
<Button variant={'base'} mr={3} onClick={onClose}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={handleSubmit(onSubmit)}>确认</Button>
|
<Button onClick={handleSubmit(onSubmit)}>确认</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</MyModal>
|
||||||
</Modal>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -3,9 +3,6 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Flex,
|
Flex,
|
||||||
Button,
|
Button,
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
@@ -26,6 +23,7 @@ import { useGlobalStore } from '@/store/global';
|
|||||||
import { useRequest } from '@/hooks/useRequest';
|
import { useRequest } from '@/hooks/useRequest';
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
import MyTooltip from '@/components/MyTooltip';
|
import MyTooltip from '@/components/MyTooltip';
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
|
||||||
type FormType = {
|
type FormType = {
|
||||||
avatar: string;
|
avatar: string;
|
||||||
@@ -92,92 +90,89 @@ const CreateModal = ({ onClose, onSuccess }: { onClose: () => void; onSuccess: (
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen onClose={onClose} isCentered={!isPc}>
|
<MyModal isOpen onClose={onClose} isCentered={!isPc}>
|
||||||
<ModalOverlay />
|
<ModalHeader fontSize={'2xl'}>创建属于你的 AI 应用</ModalHeader>
|
||||||
<ModalContent maxW={'min(700px,90vw)'}>
|
<ModalBody>
|
||||||
<ModalHeader fontSize={'2xl'}>创建属于你的 AI 应用</ModalHeader>
|
<Box color={'myGray.800'} fontWeight={'bold'}>
|
||||||
<ModalBody>
|
取个响亮的名字
|
||||||
<Box color={'myGray.800'} fontWeight={'bold'}>
|
</Box>
|
||||||
取个响亮的名字
|
<Flex mt={3} alignItems={'center'}>
|
||||||
</Box>
|
<MyTooltip label={'点击设置头像'}>
|
||||||
<Flex mt={3} alignItems={'center'}>
|
<Avatar
|
||||||
<MyTooltip label={'点击设置头像'}>
|
flexShrink={0}
|
||||||
<Avatar
|
src={getValues('avatar')}
|
||||||
flexShrink={0}
|
w={['32px', '36px']}
|
||||||
src={getValues('avatar')}
|
h={['32px', '36px']}
|
||||||
w={['32px', '36px']}
|
cursor={'pointer'}
|
||||||
h={['32px', '36px']}
|
borderRadius={'md'}
|
||||||
cursor={'pointer'}
|
onClick={onOpenSelectFile}
|
||||||
borderRadius={'md'}
|
|
||||||
onClick={onOpenSelectFile}
|
|
||||||
/>
|
|
||||||
</MyTooltip>
|
|
||||||
<Input
|
|
||||||
flex={1}
|
|
||||||
ml={4}
|
|
||||||
autoFocus
|
|
||||||
bg={'myWhite.600'}
|
|
||||||
{...register('name', {
|
|
||||||
required: '应用名不能为空~'
|
|
||||||
})}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</MyTooltip>
|
||||||
<Box mt={[4, 7]} mb={[0, 3]} color={'myGray.800'} fontWeight={'bold'}>
|
<Input
|
||||||
从模板中选择
|
flex={1}
|
||||||
</Box>
|
ml={4}
|
||||||
<Grid
|
autoFocus
|
||||||
userSelect={'none'}
|
bg={'myWhite.600'}
|
||||||
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)']}
|
{...register('name', {
|
||||||
gridGap={[2, 4]}
|
required: '应用名不能为空~'
|
||||||
>
|
})}
|
||||||
{appTemplates.map((item) => (
|
/>
|
||||||
<Card
|
</Flex>
|
||||||
key={item.id}
|
<Box mt={[4, 7]} mb={[0, 3]} color={'myGray.800'} fontWeight={'bold'}>
|
||||||
border={theme.borders.base}
|
从模板中选择
|
||||||
p={3}
|
</Box>
|
||||||
borderRadius={'md'}
|
<Grid
|
||||||
cursor={'pointer'}
|
userSelect={'none'}
|
||||||
boxShadow={'sm'}
|
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)']}
|
||||||
{...(getValues('templateId') === item.id
|
gridGap={[2, 4]}
|
||||||
? {
|
>
|
||||||
bg: 'myWhite.600'
|
{appTemplates.map((item) => (
|
||||||
|
<Card
|
||||||
|
key={item.id}
|
||||||
|
border={theme.borders.base}
|
||||||
|
p={3}
|
||||||
|
borderRadius={'md'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
boxShadow={'sm'}
|
||||||
|
{...(getValues('templateId') === item.id
|
||||||
|
? {
|
||||||
|
bg: 'myWhite.600'
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
_hover: {
|
||||||
|
boxShadow: 'md'
|
||||||
}
|
}
|
||||||
: {
|
})}
|
||||||
_hover: {
|
onClick={() => {
|
||||||
boxShadow: 'md'
|
setValue('templateId', item.id);
|
||||||
}
|
setRefresh((state) => !state);
|
||||||
})}
|
}}
|
||||||
onClick={() => {
|
>
|
||||||
setValue('templateId', item.id);
|
<Flex alignItems={'center'}>
|
||||||
setRefresh((state) => !state);
|
<Avatar src={item.avatar} borderRadius={'md'} w={'20px'} />
|
||||||
}}
|
<Box ml={3} fontWeight={'bold'}>
|
||||||
>
|
{item.name}
|
||||||
<Flex alignItems={'center'}>
|
|
||||||
<Avatar src={item.avatar} borderRadius={'md'} w={'20px'} />
|
|
||||||
<Box ml={3} fontWeight={'bold'}>
|
|
||||||
{item.name}
|
|
||||||
</Box>
|
|
||||||
</Flex>
|
|
||||||
<Box fontSize={'sm'} mt={4}>
|
|
||||||
{item.intro}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Card>
|
</Flex>
|
||||||
))}
|
<Box fontSize={'sm'} mt={4}>
|
||||||
</Grid>
|
{item.intro}
|
||||||
</ModalBody>
|
</Box>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant={'base'} mr={3} onClick={onClose}>
|
<Button variant={'base'} mr={3} onClick={onClose}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
<Button isLoading={creating} onClick={handleSubmit((data) => onclickCreate(data))}>
|
<Button isLoading={creating} onClick={handleSubmit((data) => onclickCreate(data))}>
|
||||||
确认创建
|
确认创建
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
|
||||||
|
|
||||||
<File onSelect={onSelectFile} />
|
<File onSelect={onSelectFile} />
|
||||||
</Modal>
|
</MyModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,23 +1,13 @@
|
|||||||
import React, { useState, useCallback } from 'react';
|
import React, { useState, useCallback } from 'react';
|
||||||
import {
|
import { Box, Flex, Button, Textarea, IconButton } from '@chakra-ui/react';
|
||||||
Box,
|
|
||||||
Flex,
|
|
||||||
Button,
|
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalCloseButton,
|
|
||||||
Textarea,
|
|
||||||
IconButton
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { postKbDataFromList, putKbDataById, delOneKbDataByDataId } from '@/api/plugins/kb';
|
import { postKbDataFromList, putKbDataById, delOneKbDataByDataId } from '@/api/plugins/kb';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { TrainingModeEnum } from '@/constants/plugin';
|
import { TrainingModeEnum } from '@/constants/plugin';
|
||||||
import { getErrText } from '@/utils/tools';
|
import { getErrText } from '@/utils/tools';
|
||||||
import MyIcon from '@/components/Icon';
|
|
||||||
import { vectorModelList } from '@/store/static';
|
import { vectorModelList } from '@/store/static';
|
||||||
|
import MyIcon from '@/components/Icon';
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
|
||||||
export type FormData = { dataId?: string; a: string; q: string };
|
export type FormData = { dataId?: string; a: string; q: string };
|
||||||
|
|
||||||
@@ -133,19 +123,15 @@ const InputDataModal = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={true} onClose={onClose} isCentered>
|
<MyModal
|
||||||
<ModalOverlay />
|
isOpen={true}
|
||||||
<ModalContent
|
onClose={onClose}
|
||||||
m={0}
|
isCentered
|
||||||
display={'flex'}
|
title={defaultValues.dataId ? '变更数据' : '手动导入数据'}
|
||||||
flexDirection={'column'}
|
w={'90vw'}
|
||||||
h={'90vh'}
|
maxW={'90vw'}
|
||||||
maxW={'90vw'}
|
>
|
||||||
position={'relative'}
|
<Flex display={'flex'} flexDirection={'column'} h={'90vh'}>
|
||||||
>
|
|
||||||
<ModalHeader>{defaultValues.dataId ? '变更数据' : '手动导入数据'}</ModalHeader>
|
|
||||||
<ModalCloseButton />
|
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
display={'flex'}
|
display={'flex'}
|
||||||
flexDirection={['column', 'row']}
|
flexDirection={['column', 'row']}
|
||||||
@@ -225,8 +211,8 @@ const InputDataModal = ({
|
|||||||
{defaultValues.dataId ? '确认变更' : '确认导入'}
|
{defaultValues.dataId ? '确认变更' : '确认导入'}
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ModalContent>
|
</Flex>
|
||||||
</Modal>
|
</MyModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user