perf: modal

This commit is contained in:
archer
2023-07-26 16:01:21 +08:00
parent ffdef41bf2
commit c06a9fb52b
23 changed files with 696 additions and 997 deletions

View File

@@ -1,50 +1,17 @@
import React, { useCallback, useMemo, useState } from 'react';
import { NodeProps } from 'reactflow';
import {
Box,
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 { Box, Button, Table, Thead, Tbody, Tr, Th, Td, TableContainer } from '@chakra-ui/react';
import { AddIcon } from '@chakra-ui/icons';
import NodeCard from '../modules/NodeCard';
import { FlowModuleItemType } from '@/types/flow';
import Container from '../modules/Container';
import { SystemInputEnum, VariableInputEnum } from '@/constants/app';
import type { VariableItemType } from '@/types/app';
import MyIcon from '@/components/Icon';
import { useForm } from 'react-hook-form';
import { useFieldArray } from 'react-hook-form';
import { customAlphabet } from 'nanoid';
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 = {
id: nanoid(),
key: 'key',
@@ -58,8 +25,6 @@ export const defaultVariable: VariableItemType = {
const NodeUserGuide = ({
data: { inputs, outputs, onChangeNode, ...props }
}: NodeProps<FlowModuleItemType>) => {
const theme = useTheme();
const variables = useMemo(
() =>
(inputs.find((item) => item.key === SystemInputEnum.variables)
@@ -67,25 +32,7 @@ const NodeUserGuide = ({
[inputs]
);
const [refresh, setRefresh] = useState(false);
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 [editVariable, setEditVariable] = useState<VariableItemType>();
const updateVariables = useCallback(
(value: VariableItemType[]) => {
@@ -102,9 +49,9 @@ const NodeUserGuide = ({
const onclickSubmit = useCallback(
({ variable }: { variable: VariableItemType }) => {
updateVariables(variables.map((item) => (item.id === variable.id ? variable : item)));
onClose();
setEditVariable(undefined);
},
[onClose, updateVariables, variables]
[updateVariables, variables]
);
return (
@@ -134,8 +81,7 @@ const NodeUserGuide = ({
w={'16px'}
cursor={'pointer'}
onClick={() => {
onOpen();
reset({ variable: item });
setEditVariable(item);
}}
/>
<MyIcon
@@ -159,8 +105,7 @@ const NodeUserGuide = ({
onClick={() => {
const newVariable = { ...defaultVariable, id: nanoid() };
updateVariables(variables.concat(newVariable));
reset({ variable: newVariable });
onOpen();
setEditVariable(newVariable);
}}
>
@@ -168,133 +113,13 @@ const NodeUserGuide = ({
</Box>
</Container>
</NodeCard>
<Modal isOpen={isOpen} onClose={() => {}}>
<ModalOverlay />
<ModalContent maxW={'Min(400px,90vw)'}>
<ModalHeader display={'flex'}>
<MyIcon name={'variable'} mr={2} w={'24px'} color={'#FF8A4C'} />
</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>
{!!editVariable && (
<VariableEditModal
defaultVariable={editVariable}
onClose={() => setEditVariable(undefined)}
onSubmit={onclickSubmit}
/>
)}
</>
);
};

View File

@@ -27,9 +27,9 @@ import {
} from '@/types/flow';
import { AppModuleItemType } from '@/types/app';
import { customAlphabet } from 'nanoid';
import { putAppById } from '@/api/app';
import { useRequest } from '@/hooks/useRequest';
import type { AppSchema } from '@/types/mongoSchema';
import { useUserStore } from '@/store/user';
import dynamic from 'next/dynamic';
import MyIcon from '@/components/Icon';
@@ -92,6 +92,7 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => {
const theme = useTheme();
const reactFlowWrapper = useRef<HTMLDivElement>(null);
const ChatTestRef = useRef<ChatTestComponentRef>(null);
const { updateAppDetail } = useUserStore();
const { x, y, zoom } = useViewport();
const [nodes, setNodes, onNodesChange] = useNodesState<FlowModuleItemType>([]);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
@@ -245,7 +246,7 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => {
const { mutate: onclickSave, isLoading } = useRequest({
mutationFn: () => {
return putAppById(app._id, {
return updateAppDetail(app._id, {
modules: flow2AppModules()
});
},

View File

@@ -460,22 +460,32 @@ const Settings = ({ appId }: { appId: string }) => {
: {getValues('kb.searchSimilarity')}, : {getValues('kb.searchLimit')},
: {getValues('kb.searchEmptyText') !== '' ? 'true' : 'false'}
</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) => (
<Flex
key={item._id}
alignItems={'center'}
p={2}
bg={'white'}
boxShadow={'0 4px 8px -2px rgba(16,24,40,.1),0 2px 4px -2px rgba(16,24,40,.06)'}
borderRadius={'md'}
border={theme.borders.base}
>
<Avatar src={item.avatar} w={'18px'} mr={1} />
<Box flex={'1 0 0'} w={0} className={'textEllipsis'} fontSize={'sm'}>
{item.name}
</Box>
</Flex>
<MyTooltip key={item._id} label={'查看知识库详情'}>
<Flex
alignItems={'center'}
p={2}
bg={'white'}
boxShadow={'0 4px 8px -2px rgba(16,24,40,.1),0 2px 4px -2px rgba(16,24,40,.06)'}
borderRadius={'md'}
border={theme.borders.base}
cursor={'pointer'}
onClick={() =>
router.push({
pathname: '/kb/detail',
query: {
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>
</Box>

View File

@@ -6,13 +6,8 @@ import {
FormControl,
Input,
Textarea,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton
ModalBody
} from '@chakra-ui/react';
import { useForm } from 'react-hook-form';
import { AppSchema } from '@/types/mongoSchema';
@@ -23,6 +18,7 @@ import { getErrText } from '@/utils/tools';
import { useUserStore } from '@/store/user';
import { useRequest } from '@/hooks/useRequest';
import Avatar from '@/components/Avatar';
import MyModal from '@/components/MyModal';
const InfoModal = ({
defaultApp,
@@ -120,61 +116,56 @@ const InfoModal = ({
);
return (
<Modal isOpen={true} onClose={onClose}>
<ModalOverlay />
<ModalContent maxW={'min(90vw,470px)'}>
<ModalHeader></ModalHeader>
<ModalCloseButton />
<ModalBody>
<Box> & </Box>
<Flex mt={2} alignItems={'center'}>
<Avatar
src={getValues('avatar')}
w={['26px', '34px']}
h={['26px', '34px']}
cursor={'pointer'}
borderRadius={'lg'}
mr={4}
title={'点击切换头像'}
onClick={() => onOpenSelectFile()}
/>
<FormControl>
<Input
bg={'myWhite.600'}
placeholder={'给应用设置一个名称'}
{...register('name', {
required: '展示名称不能为空'
})}
></Input>
</FormControl>
</Flex>
<Box mt={7} mb={1}>
</Box>
{/* <Box color={'myGray.500'} mb={2} fontSize={'sm'}>
<MyModal isOpen={true} onClose={onClose} title={'应用信息设置'}>
<ModalBody>
<Box> & </Box>
<Flex mt={2} alignItems={'center'}>
<Avatar
src={getValues('avatar')}
w={['26px', '34px']}
h={['26px', '34px']}
cursor={'pointer'}
borderRadius={'lg'}
mr={4}
title={'点击切换头像'}
onClick={() => onOpenSelectFile()}
/>
<FormControl>
<Input
bg={'myWhite.600'}
placeholder={'给应用设置一个名称'}
{...register('name', {
required: '展示名称不能为空'
})}
></Input>
</FormControl>
</Flex>
<Box mt={7} mb={1}>
</Box>
{/* <Box color={'myGray.500'} mb={2} fontSize={'sm'}>
该介绍主要用于记忆和在应用市场展示
</Box> */}
<Textarea
rows={4}
maxLength={500}
placeholder={'给你的 AI 应用一个介绍'}
bg={'myWhite.600'}
{...register('intro')}
/>
</ModalBody>
<Textarea
rows={4}
maxLength={500}
placeholder={'给你的 AI 应用一个介绍'}
bg={'myWhite.600'}
{...register('intro')}
/>
</ModalBody>
<ModalFooter>
<Button variant={'base'} mr={3} onClick={onClose}>
</Button>
<Button isLoading={btnLoading} onClick={saveUpdateModel}>
</Button>
</ModalFooter>
</ModalContent>
<ModalFooter>
<Button variant={'base'} mr={3} onClick={onClose}>
</Button>
<Button isLoading={btnLoading} onClick={saveUpdateModel}>
</Button>
</ModalFooter>
<File onSelect={onSelectFile} />
</Modal>
</MyModal>
);
};

View File

@@ -4,13 +4,9 @@ import {
Flex,
Box,
Button,
Modal,
ModalOverlay,
ModalContent,
ModalBody,
ModalHeader,
ModalFooter,
ModalCloseButton,
useTheme,
Textarea
} from '@chakra-ui/react';
@@ -22,6 +18,7 @@ import type { SelectedKbType } from '@/types/plugin';
import { useGlobalStore } from '@/store/global';
import MySlider from '@/components/Slider';
import MyTooltip from '@/components/MyTooltip';
import MyModal from '@/components/MyModal';
export type KbParamsType = {
searchSimilarity: number;
@@ -45,17 +42,15 @@ export const KBSelectModal = ({
const { isPc } = useGlobalStore();
return (
<Modal isOpen={true} isCentered={!isPc} onClose={onClose}>
<ModalOverlay />
<ModalContent
display={'flex'}
flexDirection={'column'}
w={'800px'}
maxW={'90vw'}
h={['90vh', 'auto']}
>
<MyModal
isOpen={true}
isCentered={!isPc}
maxW={['90vw', '800px']}
w={'800px'}
onClose={onClose}
>
<Flex flexDirection={'column'} h={['90vh', 'auto']}>
<ModalHeader>({selectedKbList.length})</ModalHeader>
<ModalCloseButton />
<ModalBody
flex={['1 0 0', '0 0 auto']}
maxH={'80vh'}
@@ -115,8 +110,8 @@ export const KBSelectModal = ({
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</Flex>
</MyModal>
);
};
@@ -137,11 +132,8 @@ export const KbParamsModal = ({
});
return (
<Modal isOpen={true} onClose={onClose}>
<ModalOverlay />
<ModalContent display={'flex'} flexDirection={'column'} w={'600px'} maxW={'90vw'}>
<ModalHeader></ModalHeader>
<ModalCloseButton />
<MyModal isOpen={true} onClose={onClose} title={'搜索参数调整'}>
<Flex flexDirection={'column'}>
<ModalBody>
<Box display={['block', 'flex']} pt={3} pb={5}>
<Box flex={'0 0 100px'} mb={[8, 0]}>
@@ -214,8 +206,8 @@ export const KbParamsModal = ({
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</Flex>
</MyModal>
);
};

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useState } from 'react';
import React, { useState } from 'react';
import {
Flex,
Box,
@@ -11,19 +11,9 @@ import {
Td,
Tbody,
useDisclosure,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
FormControl,
Slider,
SliderTrack,
SliderFilledTrack,
SliderThumb,
SliderMark,
Input
} from '@chakra-ui/react';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
@@ -36,12 +26,12 @@ import { formatTimeToChatTime, useCopyData, getErrText } from '@/utils/tools';
import { useForm } from 'react-hook-form';
import { defaultShareChat } from '@/constants/model';
import type { ShareChatEditType } from '@/types/app';
import MyTooltip from '@/components/MyTooltip';
import { useRequest } from '@/hooks/useRequest';
import { formatPrice } from '@/utils/user';
import MyTooltip from '@/components/MyTooltip';
import MyModal from '@/components/MyModal';
const Share = ({ appId }: { appId: string }) => {
const { toast } = useToast();
const { Loading, setIsLoading } = useLoading();
const { copyData } = useCopyData();
const {
@@ -175,42 +165,41 @@ const Share = ({ appId }: { appId: string }) => {
</Flex>
)}
{/* create shareChat modal */}
<Modal isOpen={isOpenCreateShareChat} onClose={onCloseCreateShareChat}>
<ModalOverlay />
<ModalContent maxW={'min(90vw,500px)'}>
<ModalHeader></ModalHeader>
<ModalCloseButton />
<ModalBody>
<FormControl>
<Flex alignItems={'center'}>
<Box flex={'0 0 60px'} w={0}>
:
</Box>
<Input
placeholder="记录名字,仅用于展示"
maxLength={20}
{...registerShareChat('name', {
required: '记录名称不能为空'
})}
/>
</Flex>
</FormControl>
</ModalBody>
<MyModal
isOpen={isOpenCreateShareChat}
onClose={onCloseCreateShareChat}
title={'创建免登录窗口'}
>
<ModalBody>
<FormControl>
<Flex alignItems={'center'}>
<Box flex={'0 0 60px'} w={0}>
:
</Box>
<Input
placeholder="记录名字,仅用于展示"
maxLength={20}
{...registerShareChat('name', {
required: '记录名称不能为空'
})}
/>
</Flex>
</FormControl>
</ModalBody>
<ModalFooter>
<Button variant={'base'} mr={3} onClick={onCloseCreateShareChat}>
</Button>
<ModalFooter>
<Button variant={'base'} mr={3} onClick={onCloseCreateShareChat}>
</Button>
<Button
isLoading={creating}
onClick={submitShareChat((data) => onclickCreateShareChat(data))}
>
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<Button
isLoading={creating}
onClick={submitShareChat((data) => onclickCreateShareChat(data))}
>
</Button>
</ModalFooter>
</MyModal>
<Loading loading={isFetching} fixed={false} />
</Box>
);

View File

@@ -2,9 +2,6 @@ import React, { useState } from 'react';
import {
Box,
Button,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
@@ -28,6 +25,7 @@ import { useForm } from 'react-hook-form';
import { useFieldArray } from 'react-hook-form';
import { customAlphabet } from 'nanoid';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
import MyModal from '@/components/MyModal';
const VariableTypeList = [
{ label: '文本', icon: 'settingLight', key: VariableInputEnum.input },
@@ -67,133 +65,130 @@ const VariableEditModal = ({
});
return (
<Modal isOpen={true} onClose={onClose}>
<ModalOverlay />
<ModalContent maxW={'Min(400px,90vw)'}>
<ModalHeader display={'flex'}>
<MyIcon name={'variable'} mr={2} w={'24px'} color={'#FF8A4C'} />
</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>
<MyModal isOpen={true} onClose={onClose}>
<ModalHeader display={'flex'}>
<MyIcon name={'variable'} mr={2} w={'24px'} color={'#FF8A4C'} />
</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'
<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);
}
: {
_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>
})}
>
<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.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)}
{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: '选项内容不能为空'
})}
/>
</Flex>
))}
</Box>
<Button
variant={'solid'}
w={'100%'}
textAlign={'left'}
leftIcon={<SmallAddIcon />}
bg={'myGray.100 !important'}
onClick={() => appendEnums({ value: '' })}
>
</Button>
</>
)}
</ModalBody>
</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(onSubmit)}></Button>
</ModalFooter>
</ModalContent>
</Modal>
<ModalFooter>
<Button variant={'base'} mr={3} onClick={onClose}>
</Button>
<Button onClick={handleSubmit(onSubmit)}></Button>
</ModalFooter>
</MyModal>
);
};

View File

@@ -3,9 +3,6 @@ import {
Box,
Flex,
Button,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
@@ -26,6 +23,7 @@ import { useGlobalStore } from '@/store/global';
import { useRequest } from '@/hooks/useRequest';
import Avatar from '@/components/Avatar';
import MyTooltip from '@/components/MyTooltip';
import MyModal from '@/components/MyModal';
type FormType = {
avatar: string;
@@ -92,92 +90,89 @@ const CreateModal = ({ onClose, onSuccess }: { onClose: () => void; onSuccess: (
});
return (
<Modal isOpen onClose={onClose} isCentered={!isPc}>
<ModalOverlay />
<ModalContent maxW={'min(700px,90vw)'}>
<ModalHeader fontSize={'2xl'}> AI </ModalHeader>
<ModalBody>
<Box color={'myGray.800'} fontWeight={'bold'}>
</Box>
<Flex mt={3} alignItems={'center'}>
<MyTooltip label={'点击设置头像'}>
<Avatar
flexShrink={0}
src={getValues('avatar')}
w={['32px', '36px']}
h={['32px', '36px']}
cursor={'pointer'}
borderRadius={'md'}
onClick={onOpenSelectFile}
/>
</MyTooltip>
<Input
flex={1}
ml={4}
autoFocus
bg={'myWhite.600'}
{...register('name', {
required: '应用名不能为空~'
})}
<MyModal isOpen onClose={onClose} isCentered={!isPc}>
<ModalHeader fontSize={'2xl'}> AI </ModalHeader>
<ModalBody>
<Box color={'myGray.800'} fontWeight={'bold'}>
</Box>
<Flex mt={3} alignItems={'center'}>
<MyTooltip label={'点击设置头像'}>
<Avatar
flexShrink={0}
src={getValues('avatar')}
w={['32px', '36px']}
h={['32px', '36px']}
cursor={'pointer'}
borderRadius={'md'}
onClick={onOpenSelectFile}
/>
</Flex>
<Box mt={[4, 7]} mb={[0, 3]} color={'myGray.800'} fontWeight={'bold'}>
</Box>
<Grid
userSelect={'none'}
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)']}
gridGap={[2, 4]}
>
{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'
</MyTooltip>
<Input
flex={1}
ml={4}
autoFocus
bg={'myWhite.600'}
{...register('name', {
required: '应用名不能为空~'
})}
/>
</Flex>
<Box mt={[4, 7]} mb={[0, 3]} color={'myGray.800'} fontWeight={'bold'}>
</Box>
<Grid
userSelect={'none'}
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)']}
gridGap={[2, 4]}
>
{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: {
boxShadow: 'md'
}
})}
onClick={() => {
setValue('templateId', item.id);
setRefresh((state) => !state);
}}
>
<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}
})}
onClick={() => {
setValue('templateId', item.id);
setRefresh((state) => !state);
}}
>
<Flex alignItems={'center'}>
<Avatar src={item.avatar} borderRadius={'md'} w={'20px'} />
<Box ml={3} fontWeight={'bold'}>
{item.name}
</Box>
</Card>
))}
</Grid>
</ModalBody>
</Flex>
<Box fontSize={'sm'} mt={4}>
{item.intro}
</Box>
</Card>
))}
</Grid>
</ModalBody>
<ModalFooter>
<Button variant={'base'} mr={3} onClick={onClose}>
</Button>
<Button isLoading={creating} onClick={handleSubmit((data) => onclickCreate(data))}>
</Button>
</ModalFooter>
</ModalContent>
<ModalFooter>
<Button variant={'base'} mr={3} onClick={onClose}>
</Button>
<Button isLoading={creating} onClick={handleSubmit((data) => onclickCreate(data))}>
</Button>
</ModalFooter>
<File onSelect={onSelectFile} />
</Modal>
</MyModal>
);
};