Updae theme and fix some bug (#1711)

This commit is contained in:
Archer 2024-06-07 12:54:30 +08:00 committed by GitHub
parent 19c8a06d51
commit b20d075d35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
153 changed files with 1587 additions and 1436 deletions

View File

@ -0,0 +1,22 @@
---
title: 'V4.8.4(进行中)'
description: 'FastGPT V4.8.4 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 821
---
<!-- ## 升级指南
- fastgpt 镜像 tag 修改成 v4.8.4
- fastgpt-sandbox 镜像 tag 修改成 v4.8.4 (选择性,无变更)
- 商业版镜像 tag 修改成 v4.8.4 -->
## V4.8.4 更新说明
1. 新增 - 应用使用新权限系统。
2. 优化 - 文本分割增加连续换行、制表符清除,避免大文本性能问题。
3. 修复 - Debug 模式下,相同 source 和 target 内容,导致连线显示异常。
4. 修复 - 定时执行初始化错误。
5. 调整组件库全局theme。

View File

@ -102,6 +102,8 @@ const commonSplit = (props: SplitProps): SplitResponse => {
text = text.replace(/(```[\s\S]*?```|~~~[\s\S]*?~~~)/g, function (match) { text = text.replace(/(```[\s\S]*?```|~~~[\s\S]*?~~~)/g, function (match) {
return match.replace(/\n/g, codeBlockMarker); return match.replace(/\n/g, codeBlockMarker);
}); });
// replace invalid \n
text = text.replace(/(\r?\n|\r){3,}/g, '\n\n\n');
// The larger maxLen is, the next sentence is less likely to trigger splitting // The larger maxLen is, the next sentence is less likely to trigger splitting
const stepReges: { reg: RegExp; maxLen: number }[] = [ const stepReges: { reg: RegExp; maxLen: number }[] = [
@ -338,7 +340,7 @@ const commonSplit = (props: SplitProps): SplitResponse => {
*/ */
export const splitText2Chunks = (props: SplitProps): SplitResponse => { export const splitText2Chunks = (props: SplitProps): SplitResponse => {
let { text = '' } = props; let { text = '' } = props;
const start = Date.now();
const splitWithCustomSign = text.split(CUSTOM_SPLIT_SIGN); const splitWithCustomSign = text.split(CUSTOM_SPLIT_SIGN);
const splitResult = splitWithCustomSign.map((item) => { const splitResult = splitWithCustomSign.map((item) => {
@ -348,7 +350,7 @@ export const splitText2Chunks = (props: SplitProps): SplitResponse => {
return commonSplit(props); return commonSplit(props);
}); });
console.log(Date.now() - start);
return { return {
chunks: splitResult.map((item) => item.chunks).flat(), chunks: splitResult.map((item) => item.chunks).flat(),
chars: splitResult.reduce((sum, item) => sum + item.chars, 0) chars: splitResult.reduce((sum, item) => sum + item.chars, 0)

View File

@ -1,6 +1,6 @@
import { FlowNodeTypeEnum } from '../../node/constant'; import { FlowNodeTypeEnum } from '../../node/constant';
import { FlowNodeTemplateType } from '../../type/index.d'; import { FlowNodeTemplateType } from '../../type/index.d';
import { FlowNodeTemplateTypeEnum, WorkflowIOValueTypeEnum } from '../../constants'; import { FlowNodeTemplateTypeEnum } from '../../constants';
import { getHandleConfig } from '../utils'; import { getHandleConfig } from '../utils';
export const SystemConfigNode: FlowNodeTemplateType = { export const SystemConfigNode: FlowNodeTemplateType = {

View File

@ -8,7 +8,7 @@ import { detectFileEncoding } from '@fastgpt/global/common/file/tools';
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common'; import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
import { MongoRawTextBuffer } from '../../buffer/rawText/schema'; import { MongoRawTextBuffer } from '../../buffer/rawText/schema';
import { readRawContentByFileBuffer } from '../read/utils'; import { readRawContentByFileBuffer } from '../read/utils';
import { PassThrough } from 'stream'; import { gridFsStream2Buffer } from './utils';
export function getGFSCollection(bucket: `${BucketNameEnum}`) { export function getGFSCollection(bucket: `${BucketNameEnum}`) {
MongoFileSchema; MongoFileSchema;
@ -113,35 +113,16 @@ export async function getDownloadStream({
fileId: string; fileId: string;
}) { }) {
const bucket = getGridBucket(bucketName); const bucket = getGridBucket(bucketName);
const stream = bucket.openDownloadStream(new Types.ObjectId(fileId)); const encodeStream = bucket.openDownloadStream(new Types.ObjectId(fileId), { end: 100 });
const copyStream = stream.pipe(new PassThrough()); const rawStream = bucket.openDownloadStream(new Types.ObjectId(fileId));
/* get encoding */ /* get encoding */
const buffer = await (() => { const buffer = await gridFsStream2Buffer(encodeStream);
return new Promise<Buffer>((resolve, reject) => {
let tmpBuffer: Buffer = Buffer.from([]);
stream.on('data', (chunk) => {
if (tmpBuffer.length < 20) {
tmpBuffer = Buffer.concat([tmpBuffer, chunk]);
}
if (tmpBuffer.length >= 20) {
resolve(tmpBuffer);
}
});
stream.on('end', () => {
resolve(tmpBuffer);
});
stream.on('error', (err) => {
reject(err);
});
});
})();
const encoding = detectFileEncoding(buffer); const encoding = detectFileEncoding(buffer);
return { return {
fileStream: copyStream, fileStream: rawStream,
encoding encoding
// encoding: 'utf-8' // encoding: 'utf-8'
}; };
@ -169,32 +150,21 @@ export const readFileContentFromMongo = async ({
filename: fileBuffer.metadata?.filename || '' filename: fileBuffer.metadata?.filename || ''
}; };
} }
const start = Date.now();
const [file, { encoding, fileStream }] = await Promise.all([ const [file, { encoding, fileStream }] = await Promise.all([
getFileById({ bucketName, fileId }), getFileById({ bucketName, fileId }),
getDownloadStream({ bucketName, fileId }) getDownloadStream({ bucketName, fileId })
]); ]);
// console.log('get file stream', Date.now() - start);
if (!file) { if (!file) {
return Promise.reject(CommonErrEnum.fileNotFound); return Promise.reject(CommonErrEnum.fileNotFound);
} }
const extension = file?.filename?.split('.')?.pop()?.toLowerCase() || ''; const extension = file?.filename?.split('.')?.pop()?.toLowerCase() || '';
const fileBuffers = await (() => { const fileBuffers = await gridFsStream2Buffer(fileStream);
return new Promise<Buffer>((resolve, reject) => { // console.log('get file buffer', Date.now() - start);
let buffer = Buffer.from([]);
fileStream.on('data', (chunk) => {
buffer = Buffer.concat([buffer, chunk]);
});
fileStream.on('end', () => {
resolve(buffer);
});
fileStream.on('error', (err) => {
reject(err);
});
});
})();
const { rawText } = await readRawContentByFileBuffer({ const { rawText } = await readRawContentByFileBuffer({
extension, extension,

View File

@ -0,0 +1,15 @@
export const gridFsStream2Buffer = (stream: NodeJS.ReadableStream) => {
return new Promise<Buffer>((resolve, reject) => {
let tmpBuffer: Buffer = Buffer.from([]);
stream.on('data', (chunk) => {
tmpBuffer = Buffer.concat([tmpBuffer, chunk]);
});
stream.on('end', () => {
resolve(tmpBuffer);
});
stream.on('error', (err) => {
reject(err);
});
});
};

View File

@ -49,11 +49,13 @@ const DateRangePicker = ({
py={1} py={1}
borderRadius={'sm'} borderRadius={'sm'}
cursor={'pointer'} cursor={'pointer'}
bg={'myWhite.600'} bg={'myGray.100'}
fontSize={'sm'} fontSize={'sm'}
onClick={() => setShowSelected(true)} onClick={() => setShowSelected(true)}
> >
<Box>{formatSelected}</Box> <Box color={'myGray.600'} fontWeight={'400'}>
{formatSelected}
</Box>
<MyIcon ml={2} name={'date'} w={'16px'} color={'myGray.600'} /> <MyIcon ml={2} name={'date'} w={'16px'} color={'myGray.600'} />
</Flex> </Flex>
{showSelected && ( {showSelected && (

View File

@ -5,7 +5,7 @@ import { DraggableProvided } from 'react-beautiful-dnd';
const DragIcon = ({ provided, ...props }: { provided: DraggableProvided } & BoxProps) => { const DragIcon = ({ provided, ...props }: { provided: DraggableProvided } & BoxProps) => {
return ( return (
<Box {...provided.dragHandleProps} {...props}> <Box {...provided.dragHandleProps} {...props} lineHeight={1}>
<DragHandleIcon color={'myGray.500'} _hover={{ color: 'primary.600' }} /> <DragHandleIcon color={'myGray.500'} _hover={{ color: 'primary.600' }} />
</Box> </Box>
); );

View File

@ -12,7 +12,7 @@ const EmptyTip = ({ text, ...props }: Props) => {
return ( return (
<Flex mt={5} flexDirection={'column'} alignItems={'center'} py={'10vh'} {...props}> <Flex mt={5} flexDirection={'column'} alignItems={'center'} py={'10vh'} {...props}>
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} /> <MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
<Box mt={2} color={'myGray.500'}> <Box mt={2} color={'myGray.500'} fontSize={'sm'}>
{text || t('common.empty.Common Tip')} {text || t('common.empty.Common Tip')}
</Box> </Box>
</Flex> </Flex>

View File

@ -0,0 +1,17 @@
import React from 'react';
import { Box, BoxProps } from '@chakra-ui/react';
const FormLabel = ({
children,
...props
}: BoxProps & {
children: React.ReactNode;
}) => {
return (
<Box color={'myGray.900'} fontSize={'sm'} {...props}>
{children}
</Box>
);
};
export default FormLabel;

View File

@ -56,7 +56,7 @@ const CustomRightDrawer = ({
)} )}
</> </>
)} )}
<Box flex={'1'} fontSize={'lg'}> <Box flex={'1'} fontSize={'md'}>
{title} {title}
</Box> </Box>
<CloseButton position={'relative'} fontSize={'sm'} top={0} right={0} onClick={onClose} /> <CloseButton position={'relative'} fontSize={'sm'} top={0} right={0} onClick={onClose} />

View File

@ -61,7 +61,7 @@ const MyRightDrawer = ({
)} )}
</> </>
)} )}
<Box flex={'1'} fontSize={'lg'}> <Box flex={'1'} fontSize={'md'}>
{title} {title}
</Box> </Box>
<DrawerCloseButton position={'relative'} fontSize={'sm'} top={0} right={0} /> <DrawerCloseButton position={'relative'} fontSize={'sm'} top={0} right={0} />

View File

@ -9,6 +9,7 @@ import {
MenuItemProps MenuItemProps
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import MyIcon from '../Icon'; import MyIcon from '../Icon';
import MyDivider from '../MyDivider';
type MenuItemType = 'primary' | 'danger'; type MenuItemType = 'primary' | 'danger';
@ -18,12 +19,15 @@ export type Props = {
Button: React.ReactNode; Button: React.ReactNode;
trigger?: 'hover' | 'click'; trigger?: 'hover' | 'click';
menuList: { menuList: {
label?: string;
children: {
isActive?: boolean; isActive?: boolean;
label: string | React.ReactNode;
icon?: string;
type?: MenuItemType; type?: MenuItemType;
icon?: string;
label: string | React.ReactNode;
onClick: () => any; onClick: () => any;
}[]; }[];
}[];
}; };
const MyMenu = ({ const MyMenu = ({
@ -49,9 +53,11 @@ const MyMenu = ({
}; };
const menuItemStyles: MenuItemProps = { const menuItemStyles: MenuItemProps = {
borderRadius: 'sm', borderRadius: 'sm',
py: 3, py: 2,
px: 3,
display: 'flex', display: 'flex',
alignItems: 'center' alignItems: 'center',
fontSize: 'sm'
}; };
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const closeTimer = useRef<any>(); const closeTimer = useRef<any>();
@ -109,23 +115,32 @@ const MyMenu = ({
'0px 2px 4px rgba(161, 167, 179, 0.25), 0px 0px 1px rgba(121, 141, 159, 0.25);' '0px 2px 4px rgba(161, 167, 179, 0.25), 0px 0px 1px rgba(121, 141, 159, 0.25);'
} }
> >
{menuList.map((item, i) => ( {menuList.map((item, i) => {
return (
<Box key={i}>
{item.label && <Box fontSize={'sm'}>{item.label}</Box>}
{i !== 0 && <MyDivider h={'1.5px'} my={1} />}
{item.children.map((child, index) => (
<MenuItem <MenuItem
key={i} key={index}
{...menuItemStyles} {...menuItemStyles}
{...typeMapStyle[item.type || 'primary']} {...typeMapStyle[child.type || 'primary']}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setIsOpen(false); setIsOpen(false);
item.onClick && item.onClick(); child.onClick && child.onClick();
}} }}
color={item.isActive ? 'primary.700' : 'myGray.600'} color={child.isActive ? 'primary.700' : 'myGray.600'}
whiteSpace={'pre-wrap'} whiteSpace={'pre-wrap'}
_notLast={{ mb: 0.5 }}
> >
{!!item.icon && <MyIcon name={item.icon as any} w={'16px'} mr={2} />} {!!child.icon && <MyIcon name={child.icon as any} w={'16px'} mr={2} />}
{item.label} <Box>{child.label}</Box>
</MenuItem> </MenuItem>
))} ))}
</Box>
);
})}
</MenuList> </MenuList>
</Box> </Box>
</Menu> </Menu>

View File

@ -64,6 +64,7 @@ const MyModal = ({
borderBottom={'1px solid #F4F6F8'} borderBottom={'1px solid #F4F6F8'}
roundedTop={'lg'} roundedTop={'lg'}
py={'10px'} py={'10px'}
fontSize={'md'}
> >
{iconSrc && ( {iconSrc && (
<> <>

View File

@ -1,7 +1,7 @@
import { Box, Flex, useDisclosure, useOutsideClick } from '@chakra-ui/react'; import { Box, Flex, useDisclosure, useOutsideClick } from '@chakra-ui/react';
import React, { useRef } from 'react'; import React, { useRef } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import FillTag from '../Tag/index'; import MyTag from '../Tag/index';
import MyIcon from '../Icon'; import MyIcon from '../Icon';
export type SelectProps = { export type SelectProps = {
@ -51,7 +51,7 @@ const MultipleSelect = ({
if (!listItem) return null; if (!listItem) return null;
return ( return (
<FillTag colorSchema="blue" p={2} cursor={'default'}> <MyTag colorSchema="blue" p={2} cursor={'default'}>
{listItem.alias || listItem.label} {listItem.alias || listItem.label}
<MyIcon <MyIcon
name={'common/closeLight'} name={'common/closeLight'}
@ -63,7 +63,7 @@ const MultipleSelect = ({
onSelect(value.filter((i) => i !== item)); onSelect(value.filter((i) => i !== item));
}} }}
/> />
</FillTag> </MyTag>
); );
})} })}
{value.length === 0 && placeholder && ( {value.length === 0 && placeholder && (

View File

@ -135,6 +135,7 @@ const MySelect = (
} }
}} }}
whiteSpace={'pre-wrap'} whiteSpace={'pre-wrap'}
fontSize={'sm'}
> >
{item.label} {item.label}
</MenuItem> </MenuItem>

View File

@ -9,7 +9,7 @@ type Props = IconProps & {
const QuestionTip = ({ label, maxW, ...props }: Props) => { const QuestionTip = ({ label, maxW, ...props }: Props) => {
return ( return (
<MyTooltip label={label} maxW={maxW}> <MyTooltip label={label} maxW={maxW}>
<QuestionOutlineIcon {...props} /> <QuestionOutlineIcon w={'0.9rem'} {...props} />
</MyTooltip> </MyTooltip>
); );
}; };

View File

@ -17,7 +17,7 @@ const MyTooltip = ({ children, forceShow = false, shouldWrapChildren = true, ...
})} })}
> >
<Tooltip <Tooltip
className="tooltip" className="chakra-tooltip"
bg={'white'} bg={'white'}
arrowShadowColor={'rgba(0,0,0,0.05)'} arrowShadowColor={'rgba(0,0,0,0.05)'}
hasArrow hasArrow

View File

@ -2,7 +2,6 @@ import React from 'react';
import { Box, Flex, useTheme, Grid, type GridProps } from '@chakra-ui/react'; import { Box, Flex, useTheme, Grid, type GridProps } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '../MyTooltip'; import MyTooltip from '../MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import QuestionTip from '../MyTooltip/QuestionTip'; import QuestionTip from '../MyTooltip/QuestionTip';
// @ts-ignore // @ts-ignore
@ -95,6 +94,7 @@ const LeftRadio = ({
color={'myGray.900'} color={'myGray.900'}
fontWeight={item.desc ? '500' : 'normal'} fontWeight={item.desc ? '500' : 'normal'}
whiteSpace={'nowrap'} whiteSpace={'nowrap'}
fontSize={'sm'}
> >
{typeof item.title === 'string' ? t(item.title) : item.title} {typeof item.title === 'string' ? t(item.title) : item.title}
</Box> </Box>

View File

@ -23,6 +23,7 @@ const RowTabs = ({ list, value, onChange, py = '7px', px = '12px', ...props }: P
borderColor={'borderColor.base'} borderColor={'borderColor.base'}
bg={'myGray.50'} bg={'myGray.50'}
gap={'4px'} gap={'4px'}
fontSize={'sm'}
{...props} {...props}
> >
{list.map((item) => ( {list.map((item) => (

View File

@ -1,69 +1,78 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Flex, type FlexProps } from '@chakra-ui/react'; import { Flex, type FlexProps } from '@chakra-ui/react';
type ColorSchemaType = 'blue' | 'green' | 'red' | 'yellow' | 'gray' | 'purple' | 'adora';
interface Props extends FlexProps { interface Props extends FlexProps {
children: React.ReactNode | React.ReactNode[]; children: React.ReactNode | React.ReactNode[];
colorSchema?: 'blue' | 'green' | 'gray' | 'purple'; colorSchema?: ColorSchemaType;
type?: 'fill' | 'solid'; type?: 'fill' | 'borderFill' | 'borderSolid';
} }
const MyTag = ({ children, colorSchema = 'blue', type = 'fill', ...props }: Props) => { const colorMap: Record<
const theme = useMemo(() => { ColorSchemaType,
const fillMap = { {
blue: { borderColor: string;
borderColor: 'primary.200', bg: string;
bg: 'primary.50', color: string;
color: 'primary.700' }
> = {
yellow: {
borderColor: 'yellow.200',
bg: 'yellow.50',
color: 'yellow.600'
}, },
green: { green: {
borderColor: 'green.200', borderColor: 'green.200',
bg: 'green.50', bg: 'green.50',
color: 'green.600' color: 'green.600'
}, },
purple: { red: {
borderColor: '#ECF', borderColor: 'red.200',
bg: '#F6EEFA', bg: 'red.50',
color: '#A558C9' color: 'red.600'
}, },
gray: { gray: {
borderColor: 'myGray.200', borderColor: 'myGray.200',
bg: 'myGray.50', bg: 'myGray.50',
color: 'myGray.700' color: 'myGray.700'
} },
};
const solidMap = {
blue: { blue: {
borderColor: 'primary.200', borderColor: 'primary.200',
bg: 'primary.50',
color: 'primary.600' color: 'primary.600'
}, },
green: {
borderColor: 'green.200',
color: 'green.600'
},
purple: { purple: {
borderColor: '#ECF', borderColor: '#ECF',
color: '#9E53C1' bg: '#F6EEFA',
color: '#A558C9'
}, },
gray: { adora: {
borderColor: 'myGray.200', borderColor: '#D3CAFF',
color: 'myGray.700' bg: '#F0EEFF',
color: '#6F5DD7'
} }
}; };
return type === 'fill' ? fillMap[colorSchema] : solidMap[colorSchema];
const MyTag = ({ children, colorSchema = 'blue', type = 'fill', ...props }: Props) => {
const theme = useMemo(() => {
return colorMap[colorSchema];
}, [colorSchema]); }, [colorSchema]);
return ( return (
<Flex <Flex
px={2} px={2.5}
lineHeight={1} lineHeight={1}
py={1} py={1}
borderRadius={'sm'} borderRadius={'sm'}
fontSize={'sm'} fontSize={'xs'}
alignItems={'center'} alignItems={'center'}
whiteSpace={'nowrap'} whiteSpace={'nowrap'}
borderWidth={'1px'} borderWidth={'1px'}
{...props}
{...theme} {...theme}
{...props}
borderColor={type !== 'fill' ? theme.borderColor : 'transparent'}
bg={type !== 'borderSolid' ? theme.bg : 'transparent'}
> >
{children} {children}
</Flex> </Flex>

View File

@ -105,7 +105,7 @@ export default function Editor({
> >
<Box <Box
color={'myGray.400'} color={'myGray.400'}
fontSize={'11px'} fontSize={'mini'}
userSelect={'none'} userSelect={'none'}
whiteSpace={'pre-wrap'} whiteSpace={'pre-wrap'}
wordBreak={'break-all'} wordBreak={'break-all'}

View File

@ -6,7 +6,7 @@
border-radius: var(--chakra-radii-md); border-radius: var(--chakra-radii-md);
padding: 8px 12px; padding: 8px 12px;
background: var(--chakra-colors-gray-50); background: var(--chakra-colors-gray-50);
font-size: 14px; font-size: var(--chakra-fontSizes-sm);
overflow-y: auto; overflow-y: auto;
} }
@ -18,7 +18,7 @@
border-radius: var(--chakra-radii-sm); border-radius: var(--chakra-radii-sm);
padding: 6px 8px; padding: 6px 8px;
background: #fff; background: #fff;
font-size: 14px; font-size: var(--chakra-fontSizes-sm);
overflow-y: auto; overflow-y: auto;
} }

View File

@ -142,7 +142,7 @@ const NodeInputSelect = ({
return ( return (
<MyMenu <MyMenu
offset={[0, -1]} offset={[-0.5, -0.5]}
Button={ Button={
<Button <Button
size={'xs'} size={'xs'}
@ -154,7 +154,7 @@ const NodeInputSelect = ({
<Box fontWeight={'medium'}>{renderTypeData.title}</Box> <Box fontWeight={'medium'}>{renderTypeData.title}</Box>
</Button> </Button>
} }
menuList={filterMenuList} menuList={[{ children: filterMenuList }]}
/> />
); );
}; };

View File

@ -115,7 +115,7 @@ export function useScrollPagination<
<MyBox isLoading={isLoading} ref={containerRef} overflow={'overlay'} {...props}> <MyBox isLoading={isLoading} ref={containerRef} overflow={'overlay'} {...props}>
<Box ref={wrapperRef}>{children}</Box> <Box ref={wrapperRef}>{children}</Box>
{noMore.current && list.length > 0 && ( {noMore.current && list.length > 0 && (
<Box py={4} textAlign={'center'} color={'myGray.600'} fontSize={'sm'}> <Box py={4} textAlign={'center'} color={'myGray.600'} fontSize={'xs'}>
{t('common.No more data')} {t('common.No more data')}
</Box> </Box>
)} )}

View File

@ -5,6 +5,9 @@ export const useToast = (props?: UseToastOptions) => {
const toast = uToast({ const toast = uToast({
position: 'top', position: 'top',
duration: 2000, duration: 2000,
containerStyle: {
fontSize: 'sm'
},
...props ...props
}); });

View File

@ -4,13 +4,14 @@ import {
switchAnatomy, switchAnatomy,
selectAnatomy, selectAnatomy,
numberInputAnatomy, numberInputAnatomy,
checkboxAnatomy checkboxAnatomy,
tableAnatomy,
radioAnatomy
} from '@chakra-ui/anatomy'; } from '@chakra-ui/anatomy';
import { createMultiStyleConfigHelpers, defineStyle } from '@chakra-ui/styled-system'; import { createMultiStyleConfigHelpers, defineStyle } from '@chakra-ui/styled-system';
const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers( const { definePartsStyle: modalPart, defineMultiStyleConfig: modalMultiStyle } =
modalAnatomy.keys createMultiStyleConfigHelpers(modalAnatomy.keys);
);
const { definePartsStyle: switchPart, defineMultiStyleConfig: switchMultiStyle } = const { definePartsStyle: switchPart, defineMultiStyleConfig: switchMultiStyle } =
createMultiStyleConfigHelpers(switchAnatomy.keys); createMultiStyleConfigHelpers(switchAnatomy.keys);
const { definePartsStyle: selectPart, defineMultiStyleConfig: selectMultiStyle } = const { definePartsStyle: selectPart, defineMultiStyleConfig: selectMultiStyle } =
@ -19,6 +20,10 @@ const { definePartsStyle: numInputPart, defineMultiStyleConfig: numInputMultiSty
createMultiStyleConfigHelpers(numberInputAnatomy.keys); createMultiStyleConfigHelpers(numberInputAnatomy.keys);
const { definePartsStyle: checkBoxPart, defineMultiStyleConfig: checkBoxMultiStyle } = const { definePartsStyle: checkBoxPart, defineMultiStyleConfig: checkBoxMultiStyle } =
createMultiStyleConfigHelpers(checkboxAnatomy.keys); createMultiStyleConfigHelpers(checkboxAnatomy.keys);
const { definePartsStyle: tablePart, defineMultiStyleConfig: tableMultiStyle } =
createMultiStyleConfigHelpers(tableAnatomy.keys);
const { definePartsStyle: radioParts, defineMultiStyleConfig: radioStyle } =
createMultiStyleConfigHelpers(radioAnatomy.keys);
const shadowLight = '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)'; const shadowLight = '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)';
@ -65,7 +70,7 @@ const Button = defineStyleConfig({
borderRadius: '8px' borderRadius: '8px'
}, },
md: { md: {
fontSize: 'md', fontSize: 'sm',
px: '20px', px: '20px',
py: 0, py: 0,
h: '36px', h: '36px',
@ -73,7 +78,7 @@ const Button = defineStyleConfig({
borderRadius: '8px' borderRadius: '8px'
}, },
mdSquare: { mdSquare: {
fontSize: 'md', fontSize: 'sm',
px: '0', px: '0',
py: 0, py: 0,
h: '36px', h: '36px',
@ -267,9 +272,6 @@ const Button = defineStyleConfig({
}); });
const Input: ComponentStyleConfig = { const Input: ComponentStyleConfig = {
baseStyle: {
fontsize: '1rem'
},
sizes: { sizes: {
sm: defineStyle({ sm: defineStyle({
field: { field: {
@ -312,13 +314,15 @@ const NumberInput = numInputMultiStyle({
sm: defineStyle({ sm: defineStyle({
field: { field: {
h: '32px', h: '32px',
borderRadius: 'md' borderRadius: 'md',
fontsize: 'sm'
} }
}), }),
md: defineStyle({ md: defineStyle({
field: { field: {
h: '40px', h: '40px',
borderRadius: 'md' borderRadius: 'md',
fontsize: 'sm'
} }
}) })
}, },
@ -359,6 +363,7 @@ const Textarea: ComponentStyleConfig = {
border: '1px solid', border: '1px solid',
borderRadius: 'md', borderRadius: 'md',
borderColor: 'myGray.200', borderColor: 'myGray.200',
fontSize: 'sm',
_hover: { _hover: {
borderColor: '' borderColor: ''
}, },
@ -406,12 +411,34 @@ const Select = selectMultiStyle({
} }
}); });
const Radio = radioStyle({
baseStyle: radioParts({
control: {
_hover: {
borderColor: 'primary.300',
bg: 'primary.50'
},
_checked: {
borderColor: 'primary.600',
bg: 'primary.50',
boxShadow: shadowLight,
_before: {
bg: 'primary.600'
},
_hover: {
bg: 'primary.50'
}
}
}
})
});
const Checkbox = checkBoxMultiStyle({ const Checkbox = checkBoxMultiStyle({
baseStyle: checkBoxPart({ baseStyle: checkBoxPart({
label: { label: {
fontFamily: 'mono' // change the font family of the label fontFamily: 'mono' // change the font family of the label
}, },
control: { control: {
borderRadius: 'xs',
bg: 'none', bg: 'none',
_checked: { _checked: {
bg: 'primary.50', bg: 'primary.50',
@ -429,10 +456,10 @@ const Checkbox = checkBoxMultiStyle({
}) })
}); });
const Modal = defineMultiStyleConfig({ const Modal = modalMultiStyle({
baseStyle: definePartsStyle({ baseStyle: modalPart({
body: { body: {
py: [3, 5], py: [2, 4],
px: [5, 7] px: [5, 7]
}, },
footer: { footer: {
@ -441,20 +468,62 @@ const Modal = defineMultiStyleConfig({
}) })
}); });
const Table = tableMultiStyle({
sizes: {
md: defineStyle({
table: {
fontsize: 'sm'
},
thead: {
tr: {
bg: 'myGray.100',
fontSize: 'sm',
th: {
borderBottom: 'none',
overflow: 'hidden',
'&:first-of-type': {
borderLeftRadius: 'md'
},
'&:last-of-type': {
borderRightRadius: 'md'
}
}
}
},
tbody: {
tr: {
td: {
overflow: 'hidden',
'&:first-of-type': {
borderLeftRadius: 'md'
},
'&:last-of-type': {
borderRightRadius: 'md'
}
}
}
}
})
},
defaultProps: {
size: 'md'
}
});
// 全局主题 // 全局主题
export const theme = extendTheme({ export const theme = extendTheme({
styles: { styles: {
global: { global: {
'html, body': { 'html, body': {
fontSize: '14px', color: 'myGray.600',
color: 'myGray.900', fontWeight: 'normal',
fontWeight: 400,
height: '100%', height: '100%',
overflow: 'hidden' overflow: 'hidden'
}, },
a: { a: {
color: 'primary.600' color: 'primary.600'
}, },
'*': { '*': {
_focusVisible: { _focusVisible: {
boxShadow: 'none' boxShadow: 'none'
@ -586,16 +655,17 @@ export const theme = extendTheme({
body: 'PingFang,Noto Sans,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"' body: 'PingFang,Noto Sans,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"'
}, },
fontSizes: { fontSizes: {
mini: '0.75rem',
xs: '0.8rem', xs: '0.8rem',
sm: '0.93rem', sm: '0.875rem',
md: '1rem', md: '1rem',
lg: '1.15rem', lg: '1.25rem',
xl: '1.3rem', xl: '1.5rem',
'2xl': '1.45rem', '2xl': '1.75rem',
'3xl': '1.6rem', '3xl': '2rem',
'4xl': '1.75rem', '4xl': '2.25rem',
'5xl': '1.9rem', '5xl': '2.8rem',
'6xl': '2.05rem' '6xl': '3.6rem'
}, },
borders: { borders: {
sm: '1px solid #E8EBF0', sm: '1px solid #E8EBF0',
@ -644,6 +714,8 @@ export const theme = extendTheme({
Select, Select,
NumberInput, NumberInput,
Checkbox, Checkbox,
Modal Modal,
Table,
Radio
} }
}); });

View File

@ -532,6 +532,7 @@
"Go Dataset": "前往知识库", "Go Dataset": "前往知识库",
"Intro Placeholder": "这个知识库还没有介绍~", "Intro Placeholder": "这个知识库还没有介绍~",
"Manual collection": "手动数据集", "Manual collection": "手动数据集",
"externalFile": "外部文件库",
"My Dataset": "我的知识库", "My Dataset": "我的知识库",
"Name": "知识库名称", "Name": "知识库名称",
"Query extension intro": "开启问题优化功能,可以提高提高连续对话时,知识库搜索的精度。开启该功能后,在进行知识库搜索时,会根据对话记录,利用 AI 补全问题缺失的信息。", "Query extension intro": "开启问题优化功能,可以提高提高连续对话时,知识库搜索的精度。开启该功能后,在进行知识库搜索时,会根据对话记录,利用 AI 补全问题缺失的信息。",
@ -585,8 +586,7 @@
"success": "开始同步" "success": "开始同步"
} }
}, },
"training": { "training": {}
}
}, },
"data": { "data": {
"Auxiliary Data": "辅助数据", "Auxiliary Data": "辅助数据",

View File

@ -3,7 +3,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
import { Box, Flex, Image, Spinner, Textarea } from '@chakra-ui/react'; import { Box, Flex, Image, Spinner, Textarea } from '@chakra-ui/react';
import React, { useRef, useEffect, useCallback } from 'react'; import React, { useRef, useEffect, useCallback } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '../../MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
import { compressImgFileAndUpload } from '@/web/common/file/controller'; import { compressImgFileAndUpload } from '@/web/common/file/controller';

View File

@ -7,7 +7,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type'; import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import MyTag from '@fastgpt/web/components/common/Tag/index'; import MyTag from '@fastgpt/web/components/common/Tag/index';
import MyTooltip from '../../MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils'; import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils';
import ChatBoxDivider from '@/components/core/chat/Divider'; import ChatBoxDivider from '@/components/core/chat/Divider';
@ -108,9 +108,9 @@ const ResponseTags = ({
<MyTooltip key={item.collectionId} label={t('core.chat.quote.Read Quote')}> <MyTooltip key={item.collectionId} label={t('core.chat.quote.Read Quote')}>
<Flex <Flex
alignItems={'center'} alignItems={'center'}
fontSize={'sm'} fontSize={'xs'}
border={theme.borders.sm} border={theme.borders.sm}
py={1} py={1.5}
px={2} px={2}
borderRadius={'sm'} borderRadius={'sm'}
_hover={{ _hover={{
@ -149,7 +149,7 @@ const ResponseTags = ({
<MyTooltip label="查看引用"> <MyTooltip label="查看引用">
<MyTag <MyTag
colorSchema="blue" colorSchema="blue"
type="solid" type="borderSolid"
cursor={'pointer'} cursor={'pointer'}
onClick={() => setQuoteModalData({ rawSearch: quoteList })} onClick={() => setQuoteModalData({ rawSearch: quoteList })}
> >
@ -164,7 +164,7 @@ const ResponseTags = ({
<MyTag <MyTag
colorSchema="green" colorSchema="green"
cursor={'pointer'} cursor={'pointer'}
type="solid" type="borderSolid"
onClick={() => setContextModalData(historyPreview)} onClick={() => setContextModalData(historyPreview)}
> >
{historyPreview.length} {historyPreview.length}
@ -174,20 +174,25 @@ const ResponseTags = ({
</> </>
)} )}
{llmModuleAccount > 1 && ( {llmModuleAccount > 1 && (
<MyTag type="solid" colorSchema="blue"> <MyTag type="borderSolid" colorSchema="blue">
AI AI
</MyTag> </MyTag>
)} )}
{isPc && runningTime > 0 && ( {isPc && runningTime > 0 && (
<MyTooltip label={'模块运行时间和'}> <MyTooltip label={'模块运行时间和'}>
<MyTag colorSchema="purple" type="solid" cursor={'default'}> <MyTag colorSchema="purple" type="borderSolid" cursor={'default'}>
{runningTime}s {runningTime}s
</MyTag> </MyTag>
</MyTooltip> </MyTooltip>
)} )}
<MyTooltip label={t('core.chat.response.Read complete response tips')}> <MyTooltip label={t('core.chat.response.Read complete response tips')}>
<MyTag colorSchema="gray" type="solid" cursor={'pointer'} onClick={onOpenWholeModal}> <MyTag
colorSchema="gray"
type="borderSolid"
cursor={'pointer'}
onClick={onOpenWholeModal}
>
{t('core.chat.response.Read complete response')} {t('core.chat.response.Read complete response')}
</MyTag> </MyTag>
</MyTooltip> </MyTooltip>

View File

@ -8,6 +8,7 @@ import DatasetSelectModal, { useDatasetSelect } from '@/components/core/dataset/
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { AdminFbkType } from '@fastgpt/global/core/chat/type.d'; import { AdminFbkType } from '@fastgpt/global/core/chat/type.d';
import SelectCollections from '@/web/core/dataset/components/SelectCollections'; import SelectCollections from '@/web/core/dataset/components/SelectCollections';
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
const InputDataModal = dynamic(() => import('@/pages/dataset/detail/components/InputDataModal')); const InputDataModal = dynamic(() => import('@/pages/dataset/detail/components/InputDataModal'));
@ -76,7 +77,7 @@ const SelectMarkCollection = ({
> >
<Flex alignItems={'center'} h={'38px'}> <Flex alignItems={'center'} h={'38px'}>
<Avatar src={item.avatar} w={['24px', '28px', '32px']}></Avatar> <Avatar src={item.avatar} w={['24px', '28px', '32px']}></Avatar>
<Box ml={3} fontWeight={'bold'} fontSize={['md', 'lg', 'xl']}> <Box ml={3} fontWeight={'bold'} fontSize={['md', 'lg']}>
{item.name} {item.name}
</Box> </Box>
</Flex> </Flex>
@ -89,14 +90,7 @@ const SelectMarkCollection = ({
})() })()
)} )}
</Grid> </Grid>
{datasets.length === 0 && ( {datasets.length === 0 && <EmptyTip text={'这个目录已经没东西可选了~'}></EmptyTip>}
<Flex mt={'10vh'} flexDirection={'column'} alignItems={'center'}>
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
<Box mt={2} color={'myGray.500'}>
西~
</Box>
</Flex>
)}
</ModalBody> </ModalBody>
</DatasetSelectModal> </DatasetSelectModal>
)} )}

View File

@ -6,13 +6,13 @@ import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/cons
import Tabs from '../../Tabs'; import Tabs from '../../Tabs';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import MyTooltip from '../../MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import Markdown from '../../Markdown'; import Markdown from '../../Markdown';
import { QuoteList } from './QuoteModal'; import { QuoteList } from './QuoteModal';
import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constants'; import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constants';
import { formatNumber } from '@fastgpt/global/common/math/tools'; import { formatNumber } from '@fastgpt/global/common/math/tools';
import { useI18n } from '@/web/context/I18n'; import { useI18n } from '@/web/context/I18n';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
function RowRender({ function RowRender({
children, children,
@ -22,10 +22,10 @@ function RowRender({
}: { children: React.ReactNode; label: string } & BoxProps) { }: { children: React.ReactNode; label: string } & BoxProps) {
return ( return (
<Box mb={3}> <Box mb={3}>
<Box fontSize={['sm', 'md']} mb={mb} flex={'0 0 90px'}> <Box fontSize={'sm'} mb={mb} flex={'0 0 90px'}>
{label}: {label}:
</Box> </Box>
<Box borderRadius={'sm'} fontSize={'sm'} bg={'myGray.50'} {...props}> <Box borderRadius={'sm'} fontSize={['xs', 'sm']} bg={'myGray.50'} {...props}>
{children} {children}
</Box> </Box>
</Box> </Box>
@ -98,9 +98,7 @@ const WholeResponseModal = ({
title={ title={
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
{t('core.chat.response.Complete Response')} {t('core.chat.response.Complete Response')}
<MyTooltip label={'从左往右,为各个模块的响应顺序'}> <QuestionTip ml={2} label={'从左往右,为各个模块的响应顺序'}></QuestionTip>
<QuestionOutlineIcon ml={2} />
</MyTooltip>
</Flex> </Flex>
} }
> >

View File

@ -32,7 +32,7 @@ import {
} from '@/web/core/chat/api'; } from '@/web/core/chat/api';
import type { AdminMarkType } from './components/SelectMarkCollection'; import type { AdminMarkType } from './components/SelectMarkCollection';
import MyTooltip from '../MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { postQuestionGuide } from '@/web/core/ai/api'; import { postQuestionGuide } from '@/web/core/ai/api';
import type { import type {

View File

@ -10,7 +10,7 @@ import Avatar from '../Avatar';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
import MyTooltip from '../MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { getDocPath } from '@/web/common/system/doc'; import { getDocPath } from '@/web/common/system/doc';
export enum NavbarTypeEnum { export enum NavbarTypeEnum {

View File

@ -4,7 +4,7 @@ import 'katex/dist/katex.min.css';
import ChatBoxDivider from '@/components/core/chat/Divider'; import ChatBoxDivider from '@/components/core/chat/Divider';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { EventNameEnum, eventBus } from '@/web/common/utils/eventbus'; import { EventNameEnum, eventBus } from '@/web/common/utils/eventbus';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
const QuestionGuide = ({ text }: { text: string }) => { const QuestionGuide = ({ text }: { text: string }) => {
@ -31,7 +31,7 @@ const QuestionGuide = ({ text }: { text: string }) => {
key={text} key={text}
alignItems={'center'} alignItems={'center'}
flexWrap={'wrap'} flexWrap={'wrap'}
fontSize={'sm'} fontSize={'xs'}
border={theme.borders.sm} border={theme.borders.sm}
py={'1px'} py={'1px'}
px={3} px={3}

View File

@ -105,16 +105,16 @@
font-size: inherit; font-size: inherit;
} }
.markdown h1 { .markdown h1 {
font-size: 28px; font-size: var(--chakra-fontSizes-2xl);
} }
.markdown h2 { .markdown h2 {
font-size: 24px; font-size: var(--chakra-fontSizes-xl);
} }
.markdown h3 { .markdown h3 {
font-size: 18px; font-size: var(--chakra-fontSizes-lg);
} }
.markdown h4 { .markdown h4 {
font-size: 16px; font-size: var(--chakra-fontSizes-md);
} }
.markdown h5 { .markdown h5 {
font-size: 14px; font-size: 14px;
@ -346,6 +346,7 @@
tab-size: 4; tab-size: 4;
word-spacing: normal; word-spacing: normal;
width: 100%; width: 100%;
font-size: var(--chakra-fontSizes-sm);
* { * {
word-break: break-word; word-break: break-word;

View File

@ -10,7 +10,7 @@ import styles from './index.module.scss';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { Link, Button } from '@chakra-ui/react'; import { Link, Button } from '@chakra-ui/react';
import MyTooltip from '../MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { EventNameEnum, eventBus } from '@/web/common/utils/eventbus'; import { EventNameEnum, eventBus } from '@/web/common/utils/eventbus';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';

View File

@ -1,35 +0,0 @@
import React from 'react';
import { Tooltip, TooltipProps } from '@chakra-ui/react';
import { useSystemStore } from '@/web/common/system/useSystemStore';
interface Props extends TooltipProps {
forceShow?: boolean;
}
const MyTooltip = ({ children, forceShow = false, shouldWrapChildren = true, ...props }: Props) => {
const { isPc } = useSystemStore();
return isPc || forceShow ? (
<Tooltip
className="tooltip"
bg={'white'}
arrowShadowColor={' rgba(0,0,0,0.05)'}
hasArrow
arrowSize={12}
offset={[-15, 15]}
color={'myGray.800'}
px={4}
py={2}
borderRadius={'8px'}
whiteSpace={'pre-wrap'}
boxShadow={'1px 1px 10px rgba(0,0,0,0.2)'}
shouldWrapChildren={shouldWrapChildren}
{...props}
>
{children}
</Tooltip>
) : (
<>{children}</>
);
};
export default MyTooltip;

View File

@ -37,9 +37,9 @@ const PromptTemplate = ({
: {})} : {})}
onClick={() => setSelectTemplateTitle(item)} onClick={() => setSelectTemplateTitle(item)}
> >
<Box>{item.title}</Box> <Box color={'myGray.900'}>{item.title}</Box>
<Box color={'myGray.600'} fontSize={'sm'} whiteSpace={'pre-wrap'}> <Box color={'myGray.500'} fontSize={'xs'} whiteSpace={'pre-wrap'}>
{item.desc} {item.desc}
</Box> </Box>
</Box> </Box>

View File

@ -17,17 +17,17 @@ const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) =>
switch (size) { switch (size) {
case 'sm': case 'sm':
return { return {
fontSize: 'sm', fontSize: 'xs',
inlineP: 1 inlineP: 1
}; };
case 'md': case 'md':
return { return {
fontSize: 'md', fontSize: 'sm',
inlineP: 2 inlineP: 2
}; };
case 'lg': case 'lg':
return { return {
fontSize: 'lg', fontSize: 'md',
inlineP: 3 inlineP: 3
}; };
} }
@ -55,7 +55,8 @@ const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) =>
color: 'myGray.600' color: 'myGray.600'
})} })}
_hover={{ _hover={{
bg: 'myGray.05' color: 'primary.600',
bg: 'myGray.100'
}} }}
onClick={() => { onClick={() => {
if (activeId === item.id) return; if (activeId === item.id) return;

View File

@ -47,7 +47,6 @@ const MySlider = ({
max={max} max={max}
min={min} min={min}
step={step} step={step}
size={'lg'}
value={value} value={value}
width={width} width={width}
onChange={onChange} onChange={onChange}

View File

@ -18,19 +18,19 @@ const Tabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
switch (size) { switch (size) {
case 'sm': case 'sm':
return { return {
fontSize: 'sm', fontSize: 'xs',
outP: '3px', outP: '3px',
inlineP: 1 inlineP: 1
}; };
case 'md': case 'md':
return { return {
fontSize: ['sm', 'md'], fontSize: 'sm',
outP: '4px', outP: '4px',
inlineP: 1 inlineP: 1
}; };
case 'lg': case 'lg':
return { return {
fontSize: ['md', 'lg'], fontSize: ['sm', 'md'],
outP: '5px', outP: '5px',
inlineP: 2 inlineP: 2
}; };

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { Box, Flex, useTheme, Grid, type GridProps, theme, Image } from '@chakra-ui/react'; import { Box, Flex, useTheme, Grid, type GridProps, theme, Image, Radio } from '@chakra-ui/react';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
@ -36,7 +36,7 @@ const MyRadio = ({
const { toast } = useToast(); const { toast } = useToast();
return ( return (
<Grid gridGap={[3, 5]} fontSize={['sm', 'md']} {...props}> <Grid gridGap={[3, 5]} {...props}>
{list.map((item) => ( {list.map((item) => (
<Flex <Flex
key={item.value} key={item.value}
@ -44,8 +44,7 @@ const MyRadio = ({
cursor={'pointer'} cursor={'pointer'}
userSelect={'none'} userSelect={'none'}
py={3} py={3}
pl={'14px'} px={'4'}
pr={hiddenCircle ? '14px' : '36px'}
p={p !== undefined ? `${p} !important` : undefined} p={p !== undefined ? `${p} !important` : undefined}
border={theme.borders.sm} border={theme.borders.sm}
borderWidth={'1.5px'} borderWidth={'1.5px'}
@ -62,27 +61,6 @@ const MyRadio = ({
borderColor: 'primary.400' borderColor: 'primary.400'
} }
})} })}
_after={{
content: '""',
display: hiddenCircle ? 'none' : 'block',
position: 'absolute',
right: '14px',
w: '16px',
h: '16px',
mr: 1,
borderRadius: '16px',
transition: '0.2s',
boxSizing: 'border-box',
...(value === item.value
? {
border: '5px solid',
borderColor: 'primary.600'
}
: {
border: '2px solid',
borderColor: 'myGray.200'
})
}}
onClick={() => { onClick={() => {
if (item.forbidTip) { if (item.forbidTip) {
toast({ toast({
@ -103,14 +81,17 @@ const MyRadio = ({
)} )}
</> </>
)} )}
<Box pr={hiddenCircle ? 0 : 2} color={'myGray.800'}> <Box pr={hiddenCircle ? 0 : 2} flex={'1 0 0'}>
<Box>{typeof item.title === 'string' ? t(item.title) : item.title}</Box> <Box fontSize={'sm'} color={'myGray.800'}>
{typeof item.title === 'string' ? t(item.title) : item.title}
</Box>
{!!item.desc && ( {!!item.desc && (
<Box fontSize={'xs'} color={'myGray.500'} lineHeight={1.2}> <Box fontSize={'mini'} color={'myGray.500'} lineHeight={1.2}>
{t(item.desc)} {t(item.desc)}
</Box> </Box>
)} )}
</Box> </Box>
<Radio isChecked={value === item.value} />
</Flex> </Flex>
))} ))}
</Grid> </Grid>

View File

@ -37,7 +37,7 @@ const ParentPaths = (props: {
{concatPaths.map((item, i) => ( {concatPaths.map((item, i) => (
<Flex key={item.parentId || i} alignItems={'center'}> <Flex key={item.parentId || i} alignItems={'center'}>
<Box <Box
fontSize={['sm', fontSize || 'lg']} fontSize={['sm', fontSize || 'md']}
py={1} py={1}
px={[1, 2]} px={[1, 2]}
borderRadius={'md'} borderRadius={'md'}

View File

@ -38,7 +38,7 @@ const RowTabs = ({ list, value, onChange, py = '7px', px = '12px', ...props }: P
})} })}
> >
{item.icon && <MyIcon name={item.icon as any} mr={1} w={'14px'} />} {item.icon && <MyIcon name={item.icon as any} mr={1} w={'14px'} />}
<Box>{item.label}</Box> <Box fontSize={'sm'}>{item.label}</Box>
</Flex> </Flex>
))} ))}
</Box> </Box>

View File

@ -9,7 +9,7 @@ import {
TextareaProps, TextareaProps,
useDisclosure useDisclosure
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';

View File

@ -19,8 +19,6 @@ import type { SettingAIDataType } from '@fastgpt/global/core/app/type.d';
import { getDocPath } from '@/web/common/system/doc'; import { getDocPath } from '@/web/common/system/doc';
import AIModelSelector from '@/components/Select/AIModelSelector'; import AIModelSelector from '@/components/Select/AIModelSelector';
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d'; import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
const AIChatSettingsModal = ({ const AIChatSettingsModal = ({
@ -65,7 +63,8 @@ const AIChatSettingsModal = ({
const LabelStyles: BoxProps = { const LabelStyles: BoxProps = {
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
fontSize: ['sm', 'md'], fontSize: 'sm',
color: 'myGray.900',
width: ['80px', '90px'] width: ['80px', '90px']
}; };
@ -209,14 +208,14 @@ const AIChatSettingsModal = ({
<Flex mt={8} alignItems={'center'}> <Flex mt={8} alignItems={'center'}>
<Box {...LabelStyles}> <Box {...LabelStyles}>
{t('core.app.Ai response')} {t('core.app.Ai response')}
<MyTooltip label={t('core.module.template.AI response switch tip')}> <QuestionTip
<QuestionOutlineIcon ml={1} /> ml={1}
</MyTooltip> label={t('core.module.template.AI response switch tip')}
></QuestionTip>
</Box> </Box>
<Box flex={1} ml={'10px'}> <Box flex={1} ml={'10px'}>
<Switch <Switch
isChecked={getValues(NodeInputKeyEnum.aiChatIsResponseText)} isChecked={getValues(NodeInputKeyEnum.aiChatIsResponseText)}
size={'lg'}
onChange={(e) => { onChange={(e) => {
const value = e.target.checked; const value = e.target.checked;
setValue(NodeInputKeyEnum.aiChatIsResponseText, value); setValue(NodeInputKeyEnum.aiChatIsResponseText, value);

View File

@ -12,9 +12,8 @@ import {
useTheme useTheme
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import MySlider from '@/components/Slider'; import MySlider from '@/components/Slider';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constants'; import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constants';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
@ -29,6 +28,8 @@ import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
import { useUserStore } from '@/web/support/user/useUserStore'; import { useUserStore } from '@/web/support/user/useUserStore';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import SelectAiModel from '@/components/Select/AIModelSelector'; import SelectAiModel from '@/components/Select/AIModelSelector';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
export type DatasetParamsProps = { export type DatasetParamsProps = {
searchMode: `${DatasetSearchModeEnum}`; searchMode: `${DatasetSearchModeEnum}`;
@ -158,8 +159,7 @@ const DatasetParamsModal = ({
cursor={'pointer'} cursor={'pointer'}
userSelect={'none'} userSelect={'none'}
py={3} py={3}
pl={'14px'} px={4}
pr={'16px'}
border={theme.borders.sm} border={theme.borders.sm}
borderWidth={'1.5px'} borderWidth={'1.5px'}
borderRadius={'md'} borderRadius={'md'}
@ -191,8 +191,8 @@ const DatasetParamsModal = ({
> >
<MyIcon name="core/dataset/rerank" w={'18px'} mr={'14px'} /> <MyIcon name="core/dataset/rerank" w={'18px'} mr={'14px'} />
<Box pr={2} color={'myGray.800'} flex={'1 0 0'}> <Box pr={2} color={'myGray.800'} flex={'1 0 0'}>
<Box>{t('core.dataset.search.ReRank')}</Box> <Box fontSize={'sm'}>{t('core.dataset.search.ReRank')}</Box>
<Box fontSize={['xs', 'sm']} color={'myGray.500'}> <Box fontSize={'xs'} color={'myGray.500'}>
{t('core.dataset.search.ReRank desc')} {t('core.dataset.search.ReRank desc')}
</Box> </Box>
</Box> </Box>
@ -208,12 +208,13 @@ const DatasetParamsModal = ({
<Box pt={5}> <Box pt={5}>
{limit !== undefined && ( {limit !== undefined && (
<Box display={['block', 'flex']}> <Box display={['block', 'flex']}>
<Box flex={'0 0 120px'} mb={[8, 0]}> <Flex flex={'0 0 120px'} mb={[8, 0]}>
{t('core.dataset.search.Max Tokens')} <FormLabel>{t('core.dataset.search.Max Tokens')}</FormLabel>
<MyTooltip label={t('core.dataset.search.Max Tokens Tips')} forceShow> <QuestionTip
<QuestionOutlineIcon ml={1} /> ml={1}
</MyTooltip> label={t('core.dataset.search.Max Tokens Tips')}
</Box> ></QuestionTip>
</Flex>
<Box flex={1} mx={4}> <Box flex={1} mx={4}>
<MySlider <MySlider
markList={[ markList={[
@ -233,12 +234,13 @@ const DatasetParamsModal = ({
</Box> </Box>
)} )}
<Box display={['block', 'flex']} mt={10}> <Box display={['block', 'flex']} mt={10}>
<Box flex={'0 0 120px'} mb={[8, 0]}> <Flex flex={'0 0 120px'} mb={[8, 0]}>
{t('core.dataset.search.Min Similarity')} <FormLabel>{t('core.dataset.search.Min Similarity')}</FormLabel>
<MyTooltip label={t('core.dataset.search.Min Similarity Tips')} forceShow> <QuestionTip
<QuestionOutlineIcon ml={1} /> ml={1}
</MyTooltip> label={t('core.dataset.search.Min Similarity Tips')}
</Box> ></QuestionTip>
</Flex>
<Box flex={1} mx={4}> <Box flex={1} mx={4}>
{showSimilarity ? ( {showSimilarity ? (
<MySlider <MySlider
@ -264,7 +266,7 @@ const DatasetParamsModal = ({
)} )}
{currentTabType === SearchSettingTabEnum.queryExtension && ( {currentTabType === SearchSettingTabEnum.queryExtension && (
<Box> <Box>
<Box fontSize={'xs'} color={'myGray.500'}> <Box transform={'translateY(-5px)'} fontSize={'xs'} color={'myGray.500'}>
{t('core.dataset.Query extension intro')} {t('core.dataset.Query extension intro')}
</Box> </Box>
<Flex mt={3} alignItems={'center'}> <Flex mt={3} alignItems={'center'}>
@ -274,8 +276,8 @@ const DatasetParamsModal = ({
{datasetSearchUsingCfrForm === true && ( {datasetSearchUsingCfrForm === true && (
<> <>
<Flex mt={4} alignItems={'center'}> <Flex mt={4} alignItems={'center'}>
<Box flex={'0 0 100px'}>{t('core.ai.Model')}</Box> <FormLabel flex={['0 0 80px', '1 0 0']}>{t('core.ai.Model')}</FormLabel>
<Box flex={'1 0 0'}> <Box flex={['1 0 0', '0 0 300px']}>
<SelectAiModel <SelectAiModel
width={'100%'} width={'100%'}
value={queryExtensionModel} value={queryExtensionModel}
@ -288,10 +290,11 @@ const DatasetParamsModal = ({
</Flex> </Flex>
<Box mt={3}> <Box mt={3}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
{t('core.app.edit.Query extension background prompt')} <FormLabel>{t('core.app.edit.Query extension background prompt')}</FormLabel>
<MyTooltip label={t('core.app.edit.Query extension background tip')} forceShow> <QuestionTip
<QuestionOutlineIcon display={['none', 'inline']} ml={1} /> ml={1}
</MyTooltip> label={t('core.app.edit.Query extension background tip')}
></QuestionTip>
</Flex> </Flex>
<Box mt={1}> <Box mt={1}>
<PromptEditor <PromptEditor

View File

@ -13,7 +13,7 @@ import {
import Avatar from '@/components/Avatar'; import Avatar from '@/components/Avatar';
import type { SelectedDatasetType } from '@fastgpt/global/core/workflow/api.d'; import type { SelectedDatasetType } from '@fastgpt/global/core/workflow/api.d';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants'; import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
@ -163,7 +163,7 @@ export const DatasetSelectModal = ({
className="textEllipsis" className="textEllipsis"
ml={3} ml={3}
fontWeight={'bold'} fontWeight={'bold'}
fontSize={['md', 'lg', 'xl']} fontSize={['md', 'lg']}
> >
{item.name} {item.name}
</Box> </Box>

View File

@ -1,5 +1,5 @@
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { import {
Box, Box,
Button, Button,
@ -34,10 +34,10 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
import { readCsvRawText } from '@fastgpt/web/common/file/utils'; import { readCsvRawText } from '@fastgpt/web/common/file/utils';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useRequest } from 'ahooks';
import HighlightText from '@fastgpt/web/components/common/String/HighlightText'; import HighlightText from '@fastgpt/web/components/common/String/HighlightText';
import { defaultChatInputGuideConfig } from '@fastgpt/global/core/app/constants'; import { defaultChatInputGuideConfig } from '@fastgpt/global/core/app/constants';
import ChatFunctionTip from './Tip'; import ChatFunctionTip from './Tip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const csvTemplate = `"第一列内容" const csvTemplate = `"第一列内容"
"只会将第一列内容导入,其余列会被忽略" "只会将第一列内容导入,其余列会被忽略"
@ -85,10 +85,10 @@ const InputGuideConfig = ({
return ( return (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/inputGuides'} mr={2} w={'20px'} /> <MyIcon name={'core/app/inputGuides'} mr={2} w={'20px'} />
<HStack> <Flex alignItems={'center'}>
<Box>{chatT('Input guide')}</Box> <FormLabel>{chatT('Input guide')}</FormLabel>
<ChatFunctionTip type={'inputGuide'} /> <ChatFunctionTip type={'inputGuide'} />
</HStack> </Flex>
<Box flex={1} /> <Box flex={1} />
<MyTooltip label={chatT('Config input guide')}> <MyTooltip label={chatT('Config input guide')}>
<Button <Button
@ -109,10 +109,9 @@ const InputGuideConfig = ({
> >
<ModalBody px={[5, 16]} py={[4, 8]} w={'500px'}> <ModalBody px={[5, 16]} py={[4, 8]} w={'500px'}>
<Flex justifyContent={'space-between'} alignItems={'center'}> <Flex justifyContent={'space-between'} alignItems={'center'}>
{t('Is open')} <FormLabel>{t('Is open')}</FormLabel>
<Switch <Switch
isChecked={isOpenQuestionGuide} isChecked={isOpenQuestionGuide}
size={'lg'}
onChange={(e) => { onChange={(e) => {
onChange({ onChange({
...value, ...value,
@ -124,7 +123,7 @@ const InputGuideConfig = ({
{isOpenQuestionGuide && ( {isOpenQuestionGuide && (
<> <>
<Flex mt={8} alignItems={'center'}> <Flex mt={8} alignItems={'center'}>
{chatT('Input guide lexicon')} <FormLabel>{chatT('Input guide lexicon')}</FormLabel>
<Box fontSize={'xs'} px={2} bg={'myGray.100'} ml={1} rounded={'full'}> <Box fontSize={'xs'} px={2} bg={'myGray.100'} ml={1} rounded={'full'}>
{total} {total}
</Box> </Box>
@ -142,7 +141,7 @@ const InputGuideConfig = ({
</Flex> </Flex>
<> <>
<Flex mt={8} alignItems={'center'}> <Flex mt={8} alignItems={'center'}>
{chatT('Custom input guide url')} <FormLabel>{chatT('Custom input guide url')}</FormLabel>
<Flex <Flex
onClick={() => window.open(getDocPath('/docs/course/chat_input_guide'))} onClick={() => window.open(getDocPath('/docs/course/chat_input_guide'))}
color={'primary.700'} color={'primary.700'}
@ -203,7 +202,7 @@ const LexiconConfigModal = ({ appId, onClose }: { appId: string; onClose: () =>
refreshDeps: [searchKey], refreshDeps: [searchKey],
debounceWait: 300, debounceWait: 300,
itemHeight: 46, itemHeight: 48,
overscan: 20, overscan: 20,
pageSize: 20, pageSize: 20,
@ -381,6 +380,7 @@ const LexiconConfigModal = ({ appId, onClose }: { appId: string; onClose: () =>
<ScrollList <ScrollList
px={8} px={8}
flex={'1 0 0'} flex={'1 0 0'}
fontSize={'sm'}
EmptyChildren={<EmptyTip text={chatT('Chat input guide lexicon is empty')} />} EmptyChildren={<EmptyTip text={chatT('Chat input guide lexicon is empty')} />}
> >
{list.map((data, index) => { {list.map((data, index) => {
@ -394,7 +394,7 @@ const LexiconConfigModal = ({ appId, onClose }: { appId: string; onClose: () =>
key={index} key={index}
alignItems={'center'} alignItems={'center'}
h={10} h={10}
mt={3} mt={2}
_hover={{ _hover={{
'& .icon-list': { '& .icon-list': {
display: 'flex' display: 'flex'
@ -402,7 +402,6 @@ const LexiconConfigModal = ({ appId, onClose }: { appId: string; onClose: () =>
}} }}
> >
<Checkbox <Checkbox
size={'lg'}
mr={2} mr={2}
isChecked={selected} isChecked={selected}
onChange={(e) => { onChange={(e) => {

View File

@ -3,6 +3,7 @@ import { Box, Flex, Switch, type SwitchProps } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import ChatFunctionTip from './Tip'; import ChatFunctionTip from './Tip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
// question generator switch // question generator switch
const QGSwitch = (props: SwitchProps) => { const QGSwitch = (props: SwitchProps) => {
@ -10,7 +11,7 @@ const QGSwitch = (props: SwitchProps) => {
return ( return (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/chat/QGFill'} mr={2} w={'20px'} /> <MyIcon name={'core/chat/QGFill'} mr={2} w={'20px'} />
<Box fontWeight={'medium'}>{t('core.app.Question Guide')}</Box> <FormLabel>{t('core.app.Question Guide')}</FormLabel>
<ChatFunctionTip type={'nextQuestion'} /> <ChatFunctionTip type={'nextQuestion'} />
<Box flex={1} /> <Box flex={1} />
<Switch {...props} /> <Switch {...props} />

View File

@ -1,4 +1,13 @@
import { Box, Button, Flex, ModalBody, useDisclosure, Switch, Textarea } from '@chakra-ui/react'; import {
Box,
Button,
Flex,
ModalBody,
useDisclosure,
Switch,
Textarea,
HStack
} from '@chakra-ui/react';
import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
@ -10,6 +19,7 @@ import dynamic from 'next/dynamic';
import type { MultipleSelectProps } from '@fastgpt/web/components/common/MySelect/type.d'; import type { MultipleSelectProps } from '@fastgpt/web/components/common/MySelect/type.d';
import { cronParser2Fields } from '@fastgpt/global/common/string/time'; import { cronParser2Fields } from '@fastgpt/global/common/string/time';
import TimezoneSelect from '@fastgpt/web/components/common/MySelect/TimezoneSelect'; import TimezoneSelect from '@fastgpt/web/components/common/MySelect/TimezoneSelect';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const MultipleRowSelect = dynamic( const MultipleRowSelect = dynamic(
() => import('@fastgpt/web/components/common/MySelect/MultipleRowSelect') () => import('@fastgpt/web/components/common/MySelect/MultipleRowSelect')
@ -135,7 +145,7 @@ const ScheduledTriggerConfig = ({
defaultPrompt?: string; defaultPrompt?: string;
}) => { }) => {
onChange({ onChange({
cronString: cronString ?? value?.cronString ?? '0 0 * * *', cronString: cronString ?? value?.cronString ?? '',
timezone: timezone ?? value?.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone, timezone: timezone ?? value?.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,
defaultPrompt: defaultPrompt ?? value?.defaultPrompt ?? '' defaultPrompt: defaultPrompt ?? value?.defaultPrompt ?? ''
}); });
@ -243,10 +253,10 @@ const ScheduledTriggerConfig = ({
<> <>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/schedulePlan'} w={'20px'} /> <MyIcon name={'core/app/schedulePlan'} w={'20px'} />
<Flex alignItems={'center'} ml={2} flex={1}> <HStack ml={2} flex={1} spacing={1}>
{t('core.app.Interval timer run')} <FormLabel>{t('core.app.Interval timer run')}</FormLabel>
<QuestionTip ml={1} label={t('core.app.Interval timer tip')} /> <QuestionTip label={t('core.app.Interval timer tip')} />
</Flex> </HStack>
<MyTooltip label={t('core.app.Config schedule plan')}> <MyTooltip label={t('core.app.Config schedule plan')}>
<Button <Button
variant={'transparentBase'} variant={'transparentBase'}
@ -269,9 +279,8 @@ const ScheduledTriggerConfig = ({
> >
<ModalBody> <ModalBody>
<Flex justifyContent={'space-between'} alignItems={'center'}> <Flex justifyContent={'space-between'} alignItems={'center'}>
<Box flex={'0 0 80px'}> {t('core.app.schedule.Open schedule')}</Box> <FormLabel flex={'0 0 80px'}> {t('core.app.schedule.Open schedule')}</FormLabel>
<Switch <Switch
size={'lg'}
isChecked={isOpenSchedule} isChecked={isOpenSchedule}
onChange={(e) => { onChange={(e) => {
if (e.target.checked) { if (e.target.checked) {
@ -285,7 +294,7 @@ const ScheduledTriggerConfig = ({
{isOpenSchedule && ( {isOpenSchedule && (
<> <>
<Flex alignItems={'center'} mt={5}> <Flex alignItems={'center'} mt={5}>
<Box flex={'0 0 80px'}></Box> <FormLabel flex={'0 0 80px'}></FormLabel>
<Box flex={'1 0 0'}> <Box flex={'1 0 0'}>
<MultipleRowSelect <MultipleRowSelect
label={formatLabel} label={formatLabel}
@ -298,7 +307,7 @@ const ScheduledTriggerConfig = ({
</Box> </Box>
</Flex> </Flex>
<Flex alignItems={'center'} mt={5}> <Flex alignItems={'center'} mt={5}>
<Box flex={'0 0 80px'}></Box> <FormLabel flex={'0 0 80px'}></FormLabel>
<Box flex={'1 0 0'}> <Box flex={'1 0 0'}>
<TimezoneSelect <TimezoneSelect
value={timezone} value={timezone}
@ -309,7 +318,7 @@ const ScheduledTriggerConfig = ({
</Box> </Box>
</Flex> </Flex>
<Box mt={5}> <Box mt={5}>
<Box mb={1}>{t('core.app.schedule.Default prompt')}</Box> <FormLabel mb={1}>{t('core.app.schedule.Default prompt')}</FormLabel>
<Textarea <Textarea
value={defaultPrompt} value={defaultPrompt}
rows={8} rows={8}

View File

@ -1,5 +1,5 @@
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { Box, Button, Flex, ModalBody, useDisclosure, Image } from '@chakra-ui/react'; import { Box, Button, Flex, ModalBody, useDisclosure, Image } from '@chakra-ui/react';
import React, { useCallback, useMemo } from 'react'; import React, { useCallback, useMemo } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
@ -12,6 +12,7 @@ import MySlider from '@/components/Slider';
import MySelect from '@fastgpt/web/components/common/MySelect'; import MySelect from '@fastgpt/web/components/common/MySelect';
import { defaultTTSConfig } from '@fastgpt/global/core/app/constants'; import { defaultTTSConfig } from '@fastgpt/global/core/app/constants';
import ChatFunctionTip from './Tip'; import ChatFunctionTip from './Tip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const TTSSelect = ({ const TTSSelect = ({
value = defaultTTSConfig, value = defaultTTSConfig,
@ -81,7 +82,7 @@ const TTSSelect = ({
return ( return (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/tts'} mr={2} w={'20px'} /> <MyIcon name={'core/app/simpleMode/tts'} mr={2} w={'20px'} />
<Box fontWeight={'medium'}>{t('core.app.TTS')}</Box> <FormLabel>{t('core.app.TTS')}</FormLabel>
<ChatFunctionTip type={'tts'} /> <ChatFunctionTip type={'tts'} />
<Box flex={1} /> <Box flex={1} />
<MyTooltip label={t('core.app.Select TTS')}> <MyTooltip label={t('core.app.Select TTS')}>
@ -108,11 +109,11 @@ const TTSSelect = ({
> >
<ModalBody px={[5, 16]} py={[4, 8]}> <ModalBody px={[5, 16]} py={[4, 8]}>
<Flex justifyContent={'space-between'} alignItems={'center'}> <Flex justifyContent={'space-between'} alignItems={'center'}>
{t('core.app.tts.Speech model')} <FormLabel>{t('core.app.tts.Speech model')}</FormLabel>
<MySelect w={'220px'} value={formatValue} list={list} onchange={onclickChange} /> <MySelect w={'220px'} value={formatValue} list={list} onchange={onclickChange} />
</Flex> </Flex>
<Flex mt={8} justifyContent={'space-between'}> <Flex mt={8} justifyContent={'space-between'}>
{t('core.app.tts.Speech speed')} <FormLabel>{t('core.app.tts.Speech speed')}</FormLabel>
<MySlider <MySlider
markList={[ markList={[
{ label: '0.3', value: 0.3 }, { label: '0.3', value: 0.3 },

View File

@ -65,7 +65,7 @@ const ChatFunctionTip = ({ type }: { type: `${FnTypeEnum}` }) => {
</Box> </Box>
</Box> </Box>
</Flex> </Flex>
<Image src={data.imgUrl} w={'100%'} minH={['auto', '200px']} mt={2} alt={''} /> <Image src={data.imgUrl} w={'100%'} minH={['auto', '250px']} mt={2} alt={''} />
</Box> </Box>
} }
/> />

View File

@ -22,7 +22,7 @@ import {
TableContainer, TableContainer,
useDisclosure useDisclosure
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons'; import { SmallAddIcon } from '@chakra-ui/icons';
import { VariableInputEnum, variableMap } from '@fastgpt/global/core/workflow/constants'; import { VariableInputEnum, variableMap } from '@fastgpt/global/core/workflow/constants';
import type { VariableItemType } from '@fastgpt/global/core/app/type.d'; import type { VariableItemType } from '@fastgpt/global/core/app/type.d';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
@ -31,12 +31,12 @@ 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 '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import MyTooltip from '@/components/MyTooltip';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import MyRadio from '@/components/common/MyRadio'; import MyRadio from '@/components/common/MyRadio';
import { formatEditorVariablePickerIcon } from '@fastgpt/global/core/workflow/utils'; import { formatEditorVariablePickerIcon } from '@fastgpt/global/core/workflow/utils';
import ChatFunctionTip from './Tip'; import ChatFunctionTip from './Tip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const VariableEdit = ({ const VariableEdit = ({
variables = [], variables = [],
@ -96,9 +96,9 @@ const VariableEdit = ({
<Box> <Box>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/variable'} w={'20px'} /> <MyIcon name={'core/app/simpleMode/variable'} w={'20px'} />
<Box ml={2} fontWeight={'medium'}> <FormLabel ml={2} fontWeight={'medium'}>
{t('core.module.Variable')} {t('core.module.Variable')}
</Box> </FormLabel>
<ChatFunctionTip type={'variable'} /> <ChatFunctionTip type={'variable'} />
<Box flex={1} /> <Box flex={1} />
<Button <Button
@ -118,14 +118,19 @@ const VariableEdit = ({
{formatVariables.length > 0 && ( {formatVariables.length > 0 && (
<Box mt={2} borderRadius={'md'} overflow={'hidden'} borderWidth={'1px'} borderBottom="none"> <Box mt={2} borderRadius={'md'} overflow={'hidden'} borderWidth={'1px'} borderBottom="none">
<TableContainer> <TableContainer>
<Table bg={'white'}> <Table>
<Thead> <Thead>
<Tr bg={'myGray.50'}> <Tr>
<Th w={'18px !important'} p={0} /> <Th
<Th>{t('core.module.variable.variable name')}</Th> fontSize={'mini'}
<Th>{t('core.module.variable.key')}</Th> borderRadius={'none !important'}
<Th>{t('common.Require Input')}</Th> w={'18px !important'}
<Th></Th> p={0}
/>
<Th fontSize={'mini'}>{t('core.module.variable.variable name')}</Th>
<Th fontSize={'mini'}>{t('core.module.variable.key')}</Th>
<Th fontSize={'mini'}>{t('common.Require Input')}</Th>
<Th fontSize={'mini'} borderRadius={'none !important'}></Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
@ -174,12 +179,12 @@ const VariableEdit = ({
<ModalBody> <ModalBody>
{variableType !== VariableInputEnum.custom && ( {variableType !== VariableInputEnum.custom && (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box w={'70px'}>{t('common.Require Input')}</Box> <FormLabel w={'70px'}>{t('common.Require Input')}</FormLabel>
<Switch {...registerEdit('variable.required')} /> <Switch {...registerEdit('variable.required')} />
</Flex> </Flex>
)} )}
<Flex mt={5} alignItems={'center'}> <Flex mt={5} alignItems={'center'}>
<Box w={'80px'}>{t('core.module.variable.variable name')}</Box> <FormLabel w={'80px'}>{t('core.module.variable.variable name')}</FormLabel>
<Input <Input
{...registerEdit('variable.label', { {...registerEdit('variable.label', {
required: t('core.module.variable.variable name is required') required: t('core.module.variable.variable name is required')
@ -187,7 +192,7 @@ const VariableEdit = ({
/> />
</Flex> </Flex>
<Flex mt={5} alignItems={'center'}> <Flex mt={5} alignItems={'center'}>
<Box w={'80px'}>{t('core.module.variable.key')}</Box> <FormLabel w={'80px'}>{t('core.module.variable.key')}</FormLabel>
<Input <Input
{...registerEdit('variable.key', { {...registerEdit('variable.key', {
required: t('core.module.variable.key is required') required: t('core.module.variable.key is required')
@ -195,9 +200,9 @@ const VariableEdit = ({
/> />
</Flex> </Flex>
<Box mt={5} mb={2}> <FormLabel mt={5} mb={2}>
{t('core.workflow.Variable.Variable type')} {t('core.workflow.Variable.Variable type')}
</Box> </FormLabel>
<MyRadio <MyRadio
gridGap={4} gridGap={4}
gridTemplateColumns={'repeat(2,1fr)'} gridTemplateColumns={'repeat(2,1fr)'}
@ -220,9 +225,9 @@ const VariableEdit = ({
{variableType === VariableInputEnum.input && ( {variableType === VariableInputEnum.input && (
<> <>
<Box mt={5} mb={2}> <FormLabel mt={5} mb={2}>
{t('core.module.variable.text max length')} {t('core.module.variable.text max length')}
</Box> </FormLabel>
<Box> <Box>
<NumberInput max={500} min={1} step={1} position={'relative'}> <NumberInput max={500} min={1} step={1} position={'relative'}>
<NumberInputField <NumberInputField

View File

@ -4,6 +4,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import ChatFunctionTip from './Tip'; import ChatFunctionTip from './Tip';
import MyTextarea from '@/components/common/Textarea/MyTextarea'; import MyTextarea from '@/components/common/Textarea/MyTextarea';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const WelcomeTextConfig = (props: TextareaProps) => { const WelcomeTextConfig = (props: TextareaProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -11,7 +12,7 @@ const WelcomeTextConfig = (props: TextareaProps) => {
<> <>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/chat'} w={'20px'} /> <MyIcon name={'core/app/simpleMode/chat'} w={'20px'} />
<Box ml={2}>{t('core.app.Welcome Text')}</Box> <FormLabel ml={2}>{t('core.app.Welcome Text')}</FormLabel>
<ChatFunctionTip type={'welcome'} /> <ChatFunctionTip type={'welcome'} />
</Flex> </Flex>
<MyTextarea <MyTextarea

View File

@ -1,5 +1,5 @@
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { Box, Button, Flex, ModalBody, useDisclosure, Switch } from '@chakra-ui/react'; import { Box, Button, Flex, ModalBody, useDisclosure, Switch } from '@chakra-ui/react';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
@ -7,6 +7,7 @@ import type { AppWhisperConfigType } from '@fastgpt/global/core/app/type.d';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { defaultWhisperConfig } from '@fastgpt/global/core/app/constants'; import { defaultWhisperConfig } from '@fastgpt/global/core/app/constants';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const WhisperConfig = ({ const WhisperConfig = ({
isOpenAudio, isOpenAudio,
@ -33,7 +34,7 @@ const WhisperConfig = ({
return ( return (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/whisper'} mr={2} w={'20px'} /> <MyIcon name={'core/app/simpleMode/whisper'} mr={2} w={'20px'} />
<Box fontWeight={'medium'}>{t('core.app.Whisper')}</Box> <FormLabel>{t('core.app.Whisper')}</FormLabel>
<Box flex={1} /> <Box flex={1} />
<MyTooltip label={t('core.app.Config whisper')}> <MyTooltip label={t('core.app.Config whisper')}>
<Button <Button
@ -54,10 +55,9 @@ const WhisperConfig = ({
> >
<ModalBody px={[5, 16]} py={[4, 8]}> <ModalBody px={[5, 16]} py={[4, 8]}>
<Flex justifyContent={'space-between'} alignItems={'center'}> <Flex justifyContent={'space-between'} alignItems={'center'}>
{t('core.app.whisper.Switch')} <FormLabel>{t('core.app.whisper.Switch')}</FormLabel>
<Switch <Switch
isChecked={isOpenWhisper} isChecked={isOpenWhisper}
size={'lg'}
onChange={(e) => { onChange={(e) => {
onChange({ onChange({
...value, ...value,
@ -68,12 +68,11 @@ const WhisperConfig = ({
</Flex> </Flex>
{isOpenWhisper && ( {isOpenWhisper && (
<Flex mt={8} alignItems={'center'}> <Flex mt={8} alignItems={'center'}>
{t('core.app.whisper.Auto send')} <FormLabel>{t('core.app.whisper.Auto send')}</FormLabel>
<QuestionTip label={t('core.app.whisper.Auto send tip')} /> <QuestionTip label={t('core.app.whisper.Auto send tip')} />
<Box flex={'1 0 0'} /> <Box flex={'1 0 0'} />
<Switch <Switch
isChecked={value.autoSend} isChecked={value.autoSend}
size={'lg'}
onChange={(e) => { onChange={(e) => {
onChange({ onChange({
...value, ...value,
@ -86,12 +85,11 @@ const WhisperConfig = ({
{isOpenWhisper && isAutoSend && ( {isOpenWhisper && isAutoSend && (
<> <>
<Flex mt={8} alignItems={'center'}> <Flex mt={8} alignItems={'center'}>
{t('core.app.whisper.Auto tts response')} <FormLabel>{t('core.app.whisper.Auto tts response')}</FormLabel>
<QuestionTip label={t('core.app.whisper.Auto tts response tip')} /> <QuestionTip label={t('core.app.whisper.Auto tts response tip')} />
<Box flex={'1 0 0'} /> <Box flex={'1 0 0'} />
<Switch <Switch
isChecked={value.autoTTSResponse} isChecked={value.autoTTSResponse}
size={'lg'}
onChange={(e) => { onChange={(e) => {
onChange({ onChange({
...value, ...value,

View File

@ -5,7 +5,7 @@ import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/ty
import NextLink from 'next/link'; import NextLink from 'next/link';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import MyBox from '@fastgpt/web/components/common/MyBox'; import MyBox from '@fastgpt/web/components/common/MyBox';
import { SearchScoreTypeEnum, SearchScoreTypeMap } from '@fastgpt/global/core/dataset/constants'; import { SearchScoreTypeEnum, SearchScoreTypeMap } from '@fastgpt/global/core/dataset/constants';

View File

@ -1,6 +1,6 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Box, BoxProps } from '@chakra-ui/react'; import { Box, BoxProps } from '@chakra-ui/react';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { getCollectionSourceAndOpen } from '@/web/core/dataset/hooks/readCollectionSource'; import { getCollectionSourceAndOpen } from '@/web/core/dataset/hooks/readCollectionSource';
import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils'; import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils';

View File

@ -39,13 +39,15 @@ const SearchParamsTip = ({
> >
<Table fontSize={'xs'} overflow={'overlay'}> <Table fontSize={'xs'} overflow={'overlay'}>
<Thead> <Thead>
<Tr color={'myGray.600'}> <Tr bg={'transparent !important'}>
<Th>{t('core.dataset.search.search mode')}</Th> <Th fontSize={'mini'}>{t('core.dataset.search.search mode')}</Th>
<Th>{t('core.dataset.search.Max Tokens')}</Th> <Th fontSize={'mini'}>{t('core.dataset.search.Max Tokens')}</Th>
<Th>{t('core.dataset.search.Min Similarity')}</Th> <Th fontSize={'mini'}>{t('core.dataset.search.Min Similarity')}</Th>
{hasReRankModel && <Th>{t('core.dataset.search.ReRank')}</Th>} {hasReRankModel && <Th fontSize={'mini'}>{t('core.dataset.search.ReRank')}</Th>}
<Th>{t('core.module.template.Query extension')}</Th> <Th fontSize={'mini'}>{t('core.module.template.Query extension')}</Th>
{hasEmptyResponseMode && <Th>{t('core.dataset.search.Empty result response')}</Th>} {hasEmptyResponseMode && (
<Th fontSize={'mini'}>{t('core.dataset.search.Empty result response')}</Th>
)}
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>

View File

@ -12,7 +12,7 @@ import { SmallCloseIcon } from '@chakra-ui/icons';
import { Box, Flex, IconButton } from '@chakra-ui/react'; import { Box, Flex, IconButton } from '@chakra-ui/react';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { streamFetch } from '@/web/common/api/fetch'; import { streamFetch } from '@/web/common/api/fetch';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useUserStore } from '@/web/support/user/useUserStore'; import { useUserStore } from '@/web/support/user/useUserStore';
import ChatBox from '@/components/ChatBox'; import ChatBox from '@/components/ChatBox';
import type { ComponentRef, StartChatFnProps } from '@/components/ChatBox/type.d'; import type { ComponentRef, StartChatFnProps } from '@/components/ChatBox/type.d';
@ -107,7 +107,7 @@ const ChatTest = (
transition={'.2s ease'} transition={'.2s ease'}
> >
<Flex py={4} px={5} whiteSpace={'nowrap'}> <Flex py={4} px={5} whiteSpace={'nowrap'}>
<Box fontSize={'xl'} fontWeight={'bold'} flex={1}> <Box fontSize={'lg'} fontWeight={'bold'} flex={1}>
{t('core.chat.Debug test')} {t('core.chat.Debug test')}
</Box> </Box>
<MyTooltip label={t('core.chat.Restart')}> <MyTooltip label={t('core.chat.Restart')}>

View File

@ -47,7 +47,7 @@ enum TemplateTypeEnum {
'teamPlugin' = 'teamPlugin' 'teamPlugin' = 'teamPlugin'
} }
const sliderWidth = 380; const sliderWidth = 390;
const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => { const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -138,6 +138,7 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
bottom={0} bottom={0}
w={`${sliderWidth}px`} w={`${sliderWidth}px`}
onClick={onClose} onClick={onClose}
fontSize={'sm'}
/> />
<Flex <Flex
zIndex={3} zIndex={3}
@ -184,8 +185,6 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
<IconButton <IconButton
size={'sm'} size={'sm'}
icon={<MyIcon name={'common/backFill'} w={'14px'} color={'myGray.700'} />} icon={<MyIcon name={'common/backFill'} w={'14px'} color={'myGray.700'} />}
w={'26px'}
h={'26px'}
borderColor={'myGray.300'} borderColor={'myGray.300'}
variant={'grayBase'} variant={'grayBase'}
aria-label={''} aria-label={''}
@ -212,6 +211,7 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
_hover={{ _hover={{
color: 'primary.600' color: 'primary.600'
}} }}
fontSize={'sm'}
onClick={() => router.push('/plugin/list')} onClick={() => router.push('/plugin/list')}
> >
<Box></Box> <Box></Box>
@ -341,7 +341,7 @@ const RenderList = React.memo(function RenderList({
> >
{item.label && ( {item.label && (
<Flex> <Flex>
<Box fontWeight={'bold'} flex={1}> <Box fontSize={'sm'} fontWeight={'bold'} flex={1}>
{t(item.label)} {t(item.label)}
</Box> </Box>
</Flex> </Flex>
@ -405,11 +405,11 @@ const RenderList = React.memo(function RenderList({
> >
<Avatar <Avatar
src={template.avatar} src={template.avatar}
w={'30px'} w={'1.7rem'}
objectFit={'contain'} objectFit={'contain'}
borderRadius={'0'} borderRadius={'0'}
/> />
<Box color={'black'} ml={5} flex={'1 0 0'}> <Box color={'black'} fontSize={'sm'} ml={5} flex={'1 0 0'}>
{t(template.name)} {t(template.name)}
</Box> </Box>
</Flex> </Flex>
@ -421,7 +421,7 @@ const RenderList = React.memo(function RenderList({
</Box> </Box>
</Box> </Box>
); );
}, [formatTemplates, isPc, onAddNode, onClose, setCurrentParent, t, templates.length]); }, [appT, formatTemplates, isPc, onAddNode, onClose, setCurrentParent, t, templates.length]);
return Render; return Render;
}); });

View File

@ -74,7 +74,7 @@ const SelectAppModal = ({
})} })}
> >
<Avatar src={app.avatar} w={['16px', '22px']} /> <Avatar src={app.avatar} w={['16px', '22px']} />
<Box fontWeight={'bold'} ml={1}> <Box fontSize={'sm'} color={'myGray.900'} ml={1}>
{app.name} {app.name}
</Box> </Box>
</Flex> </Flex>

View File

@ -21,9 +21,10 @@ const ButtonEdge = (props: EdgeProps) => {
sourcePosition, sourcePosition,
targetPosition, targetPosition,
selected, selected,
sourceHandleId,
source, source,
sourceHandleId,
target, target,
targetHandleId,
style style
} = props; } = props;
@ -86,12 +87,13 @@ const ButtonEdge = (props: EdgeProps) => {
const edgeColor = useMemo(() => { const edgeColor = useMemo(() => {
const targetEdge = workflowDebugData?.runtimeEdges.find( const targetEdge = workflowDebugData?.runtimeEdges.find(
(edge) => edge.source === source && edge.target === target (edge) => edge.sourceHandle === sourceHandleId && edge.targetHandle === targetHandleId
); );
if (!targetEdge) { if (!targetEdge) {
if (highlightEdge) return '#3370ff'; if (highlightEdge) return '#3370ff';
return '#94B5FF'; return '#94B5FF';
} }
console.log(targetEdge);
// debug mode // debug mode
const colorMap = { const colorMap = {
[RuntimeEdgeStatusEnum.active]: '#39CC83', [RuntimeEdgeStatusEnum.active]: '#39CC83',
@ -99,7 +101,7 @@ const ButtonEdge = (props: EdgeProps) => {
[RuntimeEdgeStatusEnum.skipped]: '#8A95A7' [RuntimeEdgeStatusEnum.skipped]: '#8A95A7'
}; };
return colorMap[targetEdge.status]; return colorMap[targetEdge.status];
}, [highlightEdge, source, target, workflowDebugData?.runtimeEdges]); }, [highlightEdge, sourceHandleId, targetHandleId, workflowDebugData?.runtimeEdges]);
const memoEdgeLabel = useMemo(() => { const memoEdgeLabel = useMemo(() => {
const arrowTransform = (() => { const arrowTransform = (() => {

View File

@ -219,7 +219,7 @@ export const useDebug = () => {
if (input.valueType === WorkflowIOValueTypeEnum.boolean) { if (input.valueType === WorkflowIOValueTypeEnum.boolean) {
return ( return (
<Box> <Box>
<Switch size={'lg'} {...register(input.key)} /> <Switch {...register(input.key)} />
</Box> </Box>
); );
} }

View File

@ -28,7 +28,7 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/index.d'; import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { connectionLineStyle, defaultEdgeOptions } from '../constants'; import { connectionLineStyle, defaultEdgeOptions } from '../constants';
import { useConfirm } from '@fastgpt/web/hooks/useConfirm'; import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { useKeyboard } from './hooks/useKeyboard'; import { useKeyboard } from './hooks/useKeyboard';

View File

@ -9,7 +9,7 @@ import type { ClassifyQuestionAgentItemType } from '@fastgpt/global/core/workflo
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io.d'; import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io.d';
import { getNanoid } from '@fastgpt/global/common/string/tools'; import { getNanoid } from '@fastgpt/global/common/string/tools';
import { SourceHandle } from './render/Handle'; import { SourceHandle } from './render/Handle';

View File

@ -13,10 +13,11 @@ import type { ContextExtractAgentItemType } from '@fastgpt/global/core/workflow/
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import MySelect from '@fastgpt/web/components/common/MySelect'; import MySelect from '@fastgpt/web/components/common/MySelect';
import { fnValueTypeSelect } from '@/web/core/workflow/constants/dataType'; import { fnValueTypeSelect } from '@/web/core/workflow/constants/dataType';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
export const defaultField: ContextExtractAgentItemType = { export const defaultField: ContextExtractAgentItemType = {
valueType: 'string', valueType: 'string',
@ -53,17 +54,15 @@ const ExtractFieldModal = ({
> >
<ModalBody> <ModalBody>
<Flex mt={2} alignItems={'center'}> <Flex mt={2} alignItems={'center'}>
<Flex alignItems={'center'} flex={['0 0 80px', '0 0 100px']}> <Flex alignItems={'center'} flex={['1 0 80px', '1 0 100px']}>
{t('core.module.extract.Required')} <FormLabel>{t('core.module.extract.Required')}</FormLabel>
<MyTooltip label={t('core.module.extract.Required Description')} forceShow> <QuestionTip ml={1} label={t('core.module.extract.Required Description')}></QuestionTip>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Flex> </Flex>
<Switch {...register('required')} /> <Switch {...register('required')} />
</Flex> </Flex>
{required && ( {required && (
<Flex mt={5} alignItems={'center'}> <Flex mt={5} alignItems={'center'}>
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Default value')}</Box> <FormLabel flex={['0 0 80px', '0 0 100px']}>{t('core.module.Default value')}</FormLabel>
<Input <Input
bg={'myGray.50'} bg={'myGray.50'}
placeholder={t('core.module.Default value placeholder')} placeholder={t('core.module.Default value placeholder')}
@ -73,7 +72,7 @@ const ExtractFieldModal = ({
)} )}
<Flex alignItems={'center'} mt={5}> <Flex alignItems={'center'} mt={5}>
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Data Type')}</Box> <FormLabel flex={['0 0 80px', '0 0 100px']}>{t('core.module.Data Type')}</FormLabel>
<Box flex={'1 0 0'}> <Box flex={'1 0 0'}>
<MySelect <MySelect
list={fnValueTypeSelect} list={fnValueTypeSelect}
@ -86,7 +85,7 @@ const ExtractFieldModal = ({
</Flex> </Flex>
<Flex mt={5} alignItems={'center'}> <Flex mt={5} alignItems={'center'}>
<Box flex={['0 0 80px', '0 0 100px']}>{t('Field name')}</Box> <FormLabel flex={['0 0 80px', '0 0 100px']}>{t('Field name')}</FormLabel>
<Input <Input
bg={'myGray.50'} bg={'myGray.50'}
placeholder="name/age/sql" placeholder="name/age/sql"
@ -94,7 +93,9 @@ const ExtractFieldModal = ({
/> />
</Flex> </Flex>
<Flex mt={5} alignItems={'center'}> <Flex mt={5} alignItems={'center'}>
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Field Description')}</Box> <FormLabel flex={['0 0 80px', '0 0 100px']}>
{t('core.module.Field Description')}
</FormLabel>
<Input <Input
bg={'myGray.50'} bg={'myGray.50'}
placeholder={t('core.module.extract.Field Description Placeholder')} placeholder={t('core.module.extract.Field Description Placeholder')}
@ -104,10 +105,10 @@ const ExtractFieldModal = ({
{(valueType === 'string' || valueType === 'number') && ( {(valueType === 'string' || valueType === 'number') && (
<Box mt={5}> <Box mt={5}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<FormLabel>
{t('core.module.extract.Enum Value')}({t('common.choosable')}) {t('core.module.extract.Enum Value')}({t('common.choosable')})
<MyTooltip label={t('core.module.extract.Enum Description')} forceShow> </FormLabel>
<QuestionOutlineIcon ml={1} /> <QuestionTip ml={1} label={t('core.module.extract.Enum Description')}></QuestionTip>
</MyTooltip>
</Flex> </Flex>
<Textarea <Textarea

View File

@ -78,10 +78,12 @@ const NodeExtract = ({ data }: NodeProps<FlowNodeItemType>) => {
<Table bg={'white'}> <Table bg={'white'}>
<Thead> <Thead>
<Tr> <Tr>
<Th bg={'myGray.50'}></Th> <Th bg={'myGray.50'} borderRadius={'none !important'}>
</Th>
<Th bg={'myGray.50'}></Th> <Th bg={'myGray.50'}></Th>
<Th bg={'myGray.50'}></Th> <Th bg={'myGray.50'}></Th>
<Th bg={'myGray.50'}></Th> <Th bg={'myGray.50'} borderRadius={'none !important'}></Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>

View File

@ -26,7 +26,6 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io.d'; import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io.d';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import JSONEditor from '@fastgpt/web/components/common/Textarea/JsonEditor'; import JSONEditor from '@fastgpt/web/components/common/Textarea/JsonEditor';
import { formatEditorVariablePickerIcon } from '@fastgpt/global/core/workflow/utils'; import { formatEditorVariablePickerIcon } from '@fastgpt/global/core/workflow/utils';
import { EditorVariablePickerType } from '@fastgpt/web/components/common/Textarea/PromptEditor/type'; import { EditorVariablePickerType } from '@fastgpt/web/components/common/Textarea/PromptEditor/type';
@ -40,6 +39,7 @@ import { WorkflowContext } from '../../../context';
import { getWorkflowGlobalVariables } from '@/web/core/workflow/utils'; import { getWorkflowGlobalVariables } from '@/web/core/workflow/utils';
import { useMemoizedFn } from 'ahooks'; import { useMemoizedFn } from 'ahooks';
import { AppContext } from '@/web/core/app/context/appContext'; import { AppContext } from '@/web/core/app/context/appContext';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
const CurlImportModal = dynamic(() => import('./CurlImportModal')); const CurlImportModal = dynamic(() => import('./CurlImportModal'));
export const HttpHeaders = [ export const HttpHeaders = [
@ -305,9 +305,10 @@ export function RenderHttpProps({
<Box> <Box>
<Flex alignItems={'center'} mb={2} fontWeight={'medium'} color={'myGray.600'}> <Flex alignItems={'center'} mb={2} fontWeight={'medium'} color={'myGray.600'}>
{t('core.module.Http request props')} {t('core.module.Http request props')}
<MyTooltip label={t('core.module.http.Props tip', { variable: variableText })}> <QuestionTip
<QuestionOutlineIcon ml={1} /> ml={1}
</MyTooltip> label={t('core.module.http.Props tip', { variable: variableText })}
></QuestionTip>
</Flex> </Flex>
<Tabs <Tabs
list={[ list={[
@ -468,12 +469,17 @@ const RenderForm = ({
const Render = useMemo(() => { const Render = useMemo(() => {
return ( return (
<Box mt={2} borderRadius={'md'} overflow={'hidden'} borderWidth={'1px'} borderBottom={'none'}>
<TableContainer overflowY={'visible'} overflowX={'unset'}> <TableContainer overflowY={'visible'} overflowX={'unset'}>
<Table> <Table>
<Thead> <Thead>
<Tr> <Tr>
<Th px={2}>{t('core.module.http.Props name')}</Th> <Th px={2} borderBottomLeftRadius={'none !important'}>
<Th px={2}>{t('core.module.http.Props value')}</Th> {t('core.module.http.Props name')}
</Th>
<Th px={2} borderBottomRadius={'none !important'}>
{t('core.module.http.Props value')}
</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
@ -504,7 +510,9 @@ const RenderForm = ({
variables={variables} variables={variables}
onBlur={(val) => { onBlur={(val) => {
setList((prevList) => setList((prevList) =>
prevList.map((item, i) => (i === index ? { ...item, value: val } : item)) prevList.map((item, i) =>
i === index ? { ...item, value: val } : item
)
); );
setShouldUpdateNode(true); setShouldUpdateNode(true);
}} }}
@ -551,6 +559,7 @@ const RenderForm = ({
</Tbody> </Tbody>
</Table> </Table>
</TableContainer> </TableContainer>
</Box>
); );
}, [ }, [
handleAddNewProps, handleAddNewProps,

View File

@ -65,11 +65,8 @@ const ListItem = ({
> >
<Container w={snapshot.isDragging ? '' : 'full'} className="nodrag"> <Container w={snapshot.isDragging ? '' : 'full'} className="nodrag">
<Flex mb={4} alignItems={'center'}> <Flex mb={4} alignItems={'center'}>
<DragIcon {ifElseList.length > 1 && <DragIcon provided={provided} />}
visibility={ifElseList.length > 1 ? 'visible' : 'hidden'} <Box color={'black'} fontSize={'md'} ml={2}>
provided={provided}
/>
<Box color={'black'} fontSize={'lg'} ml={2}>
{getElseIFLabel(conditionIndex)} {getElseIFLabel(conditionIndex)}
</Box> </Box>
{conditionItem.list?.length > 1 && ( {conditionItem.list?.length > 1 && (

View File

@ -91,7 +91,7 @@ const NodeIfElse = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
<Container position={'relative'}> <Container position={'relative'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box color={'black'} fontSize={'lg'} ml={2}> <Box color={'black'} fontSize={'md'} ml={2}>
{IfElseResultEnum.ELSE} {IfElseResultEnum.ELSE}
</Box> </Box>
<SourceHandle <SourceHandle

View File

@ -129,7 +129,6 @@ function QuestionGuide({ chatConfig: { questionGuide = false }, setAppDetail }:
return ( return (
<QGSwitch <QGSwitch
isChecked={questionGuide} isChecked={questionGuide}
size={'md'}
onChange={(e) => { onChange={(e) => {
const value = e.target.checked; const value = e.target.checked;
setAppDetail((state) => ({ setAppDetail((state) => ({

View File

@ -224,7 +224,6 @@ const NodeVariableUpdate = ({ data, selected }: NodeProps<FlowNodeItemType>) =>
if (valueType === WorkflowIOValueTypeEnum.boolean) { if (valueType === WorkflowIOValueTypeEnum.boolean) {
return ( return (
<Switch <Switch
size="lg"
defaultChecked={updateItem.value?.[1] === 'true'} defaultChecked={updateItem.value?.[1] === 'true'}
onChange={(e) => handleUpdate(String(e.target.checked))} onChange={(e) => handleUpdate(String(e.target.checked))}
/> />

View File

@ -26,6 +26,7 @@ import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '@fastgpt/global/core/
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput/index'; import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput/index';
import { useI18n } from '@/web/context/I18n'; import { useI18n } from '@/web/context/I18n';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const JsonEditor = dynamic(() => import('@fastgpt/web/components/common/Textarea/JsonEditor')); const JsonEditor = dynamic(() => import('@fastgpt/web/components/common/Textarea/JsonEditor'));
const EmptyTip = dynamic(() => import('@fastgpt/web/components/common/EmptyTip')); const EmptyTip = dynamic(() => import('@fastgpt/web/components/common/EmptyTip'));
@ -304,7 +305,7 @@ const FieldEditModal = ({
<Stack flex={1} gap={5}> <Stack flex={1} gap={5}>
{showInputTypeSelect && ( {showInputTypeSelect && (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Input Type')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Input Type')}</FormLabel>
<Box flex={1}> <Box flex={1}>
<MySelect <MySelect
list={inputTypeList} list={inputTypeList}
@ -320,7 +321,7 @@ const FieldEditModal = ({
)} )}
{showValueTypeSelect && !showInputTypeSelect && ( {showValueTypeSelect && !showInputTypeSelect && (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Data Type')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Data Type')}</FormLabel>
<Box flex={1}> <Box flex={1}>
<MySelect <MySelect
w={'full'} w={'full'}
@ -336,7 +337,7 @@ const FieldEditModal = ({
)} )}
{showKeyInput && ( {showKeyInput && (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Field Name')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Field Name')}</FormLabel>
<Input <Input
bg={'myGray.50'} bg={'myGray.50'}
placeholder="appointment/sql" placeholder="appointment/sql"
@ -348,9 +349,9 @@ const FieldEditModal = ({
)} )}
{showDescriptionInput && ( {showDescriptionInput && (
<Box alignItems={'flex-start'}> <Box alignItems={'flex-start'}>
<Box flex={'0 0 70px'} mb={'1px'}> <FormLabel flex={'0 0 70px'} mb={'1px'}>
{t('core.module.Field Description')} {t('core.module.Field Description')}
</Box> </FormLabel>
<Textarea <Textarea
bg={'myGray.50'} bg={'myGray.50'}
placeholder={ placeholder={
@ -366,18 +367,18 @@ const FieldEditModal = ({
{showInputTypeSelect && ( {showInputTypeSelect && (
<Stack flex={1} gap={5}> <Stack flex={1} gap={5}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{workflowT('Field required')}</Box> <FormLabel flex={'0 0 70px'}>{workflowT('Field required')}</FormLabel>
<Switch {...register('required')} /> <Switch {...register('required')} />
</Flex> </Flex>
{showToolInput && ( {showToolInput && (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}></Box> <FormLabel flex={'0 0 70px'}></FormLabel>
<Switch {...register('isToolInput')} /> <Switch {...register('isToolInput')} />
</Flex> </Flex>
)} )}
{showValueTypeSelect && ( {showValueTypeSelect && (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Data Type')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Data Type')}</FormLabel>
<Box flex={1}> <Box flex={1}>
<MySelect <MySelect
w={'full'} w={'full'}
@ -393,7 +394,7 @@ const FieldEditModal = ({
)} )}
{showDefaultValue && ( {showDefaultValue && (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Default Value')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Default Value')}</FormLabel>
{inputType === FlowNodeInputTypeEnum.numberInput && ( {inputType === FlowNodeInputTypeEnum.numberInput && (
<Input <Input
bg={'myGray.50'} bg={'myGray.50'}
@ -430,7 +431,7 @@ const FieldEditModal = ({
)} )}
{showMaxLenInput && ( {showMaxLenInput && (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Max Length')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Max Length')}</FormLabel>
<MyNumberInput <MyNumberInput
flex={'1 0 0'} flex={'1 0 0'}
bg={'myGray.50'} bg={'myGray.50'}
@ -447,7 +448,7 @@ const FieldEditModal = ({
{showMinMaxInput && ( {showMinMaxInput && (
<> <>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Max Value')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Max Value')}</FormLabel>
<MyNumberInput <MyNumberInput
flex={'1 0 0'} flex={'1 0 0'}
bg={'myGray.50'} bg={'myGray.50'}
@ -459,7 +460,7 @@ const FieldEditModal = ({
/> />
</Flex> </Flex>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Min Value')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Min Value')}</FormLabel>
<MyNumberInput <MyNumberInput
flex={'1 0 0'} flex={'1 0 0'}
bg={'myGray.50'} bg={'myGray.50'}
@ -475,13 +476,13 @@ const FieldEditModal = ({
{showDynamicInput && ( {showDynamicInput && (
<Stack gap={5}> <Stack gap={5}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Input Type')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Input Type')}</FormLabel>
<Box flex={1} fontWeight={'bold'}> <Box flex={1} fontWeight={'bold'}>
{t('core.workflow.inputType.Reference')} {t('core.workflow.inputType.Reference')}
</Box> </Box>
</Flex> </Flex>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.module.Data Type')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.module.Data Type')}</FormLabel>
<Box flex={1}> <Box flex={1}>
<MySelect <MySelect
list={dataTypeSelectList} list={dataTypeSelectList}
@ -496,7 +497,7 @@ const FieldEditModal = ({
</Box> </Box>
</Flex> </Flex>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 70px'}>{t('core.workflow.inputType.Required')}</Box> <FormLabel flex={'0 0 70px'}>{t('core.workflow.inputType.Required')}</FormLabel>
<Box flex={1}> <Box flex={1}>
<Switch {...register('dynamicParamDefaultValue.required')} /> <Switch {...register('dynamicParamDefaultValue.required')} />
</Box> </Box>

View File

@ -1,4 +1,4 @@
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { Box, BoxProps } from '@chakra-ui/react'; import { Box, BoxProps } from '@chakra-ui/react';
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';

View File

@ -23,7 +23,7 @@ import { WorkflowContext } from '../../../context';
import { useI18n } from '@/web/context/I18n'; import { useI18n } from '@/web/context/I18n';
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants'; import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
import { QuestionOutlineIcon } from '@chakra-ui/icons'; import { QuestionOutlineIcon } from '@chakra-ui/icons';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
type Props = FlowNodeItemType & { type Props = FlowNodeItemType & {
@ -140,7 +140,7 @@ const NodeCard = (props: Props) => {
{/* avatar and name */} {/* avatar and name */}
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Avatar src={avatar} borderRadius={'0'} objectFit={'contain'} w={'30px'} h={'30px'} /> <Avatar src={avatar} borderRadius={'0'} objectFit={'contain'} w={'30px'} h={'30px'} />
<Box ml={3} fontSize={'lg'} fontWeight={'medium'}> <Box ml={3} fontSize={'md'} fontWeight={'medium'}>
{t(name)} {t(name)}
</Box> </Box>
{!menuForbid?.rename && ( {!menuForbid?.rename && (

View File

@ -2,8 +2,7 @@ import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io.d';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { Box, Flex } from '@chakra-ui/react'; import { Box, Flex } from '@chakra-ui/react';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import NodeInputSelect from '@fastgpt/web/components/core/workflow/NodeInputSelect'; import NodeInputSelect from '@fastgpt/web/components/core/workflow/NodeInputSelect';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
@ -14,6 +13,7 @@ import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/consta
import ValueTypeLabel from '../ValueTypeLabel'; import ValueTypeLabel from '../ValueTypeLabel';
import { useContextSelector } from 'use-context-selector'; import { useContextSelector } from 'use-context-selector';
import { WorkflowContext } from '@/components/core/workflow/context'; import { WorkflowContext } from '@/components/core/workflow/context';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
const FieldEditModal = dynamic(() => import('../FieldEditModal')); const FieldEditModal = dynamic(() => import('../FieldEditModal'));
type Props = { type Props = {
@ -62,19 +62,20 @@ const InputLabel = ({ nodeId, input }: Props) => {
return ( return (
<Flex className="nodrag" cursor={'default'} alignItems={'center'} position={'relative'}> <Flex className="nodrag" cursor={'default'} alignItems={'center'} position={'relative'}>
<Box position={'relative'} fontWeight={'medium'} color={'myGray.600'}> <Flex
alignItems={'center'}
position={'relative'}
fontWeight={'medium'}
color={'myGray.600'}
>
{required && ( {required && (
<Box position={'absolute'} left={-2} top={-1} color={'red.600'}> <Box position={'absolute'} left={-2} top={-1} color={'red.600'}>
* *
</Box> </Box>
)} )}
{t(label)} {t(label)}
{description && ( {description && <QuestionTip ml={1} label={t(description)}></QuestionTip>}
<MyTooltip label={t(description)} forceShow> </Flex>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
)}
</Box>
{/* value type */} {/* value type */}
{renderType === FlowNodeInputTypeEnum.reference && <ValueTypeLabel valueType={valueType} />} {renderType === FlowNodeInputTypeEnum.reference && <ValueTypeLabel valueType={valueType} />}
{/* edit config */} {/* edit config */}

View File

@ -85,7 +85,7 @@ const SelectDatasetRender = ({ inputs = [], item, nodeId }: RenderInputProps) =>
w={0} w={0}
className="textEllipsis" className="textEllipsis"
fontWeight={'bold'} fontWeight={'bold'}
fontSize={['md', 'lg', 'xl']} fontSize={['md', 'lg']}
> >
{item.name} {item.name}
</Box> </Box>

View File

@ -6,12 +6,11 @@ import { useForm } from 'react-hook-form';
import { PromptTemplateItem } from '@fastgpt/global/core/ai/type'; import { PromptTemplateItem } from '@fastgpt/global/core/ai/type';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { ModalBody } from '@chakra-ui/react'; import { ModalBody } from '@chakra-ui/react';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { import {
Prompt_QuotePromptList, Prompt_QuotePromptList,
Prompt_QuoteTemplateList Prompt_QuoteTemplateList
} from '@fastgpt/global/core/ai/prompt/AIChat'; } from '@fastgpt/global/core/ai/prompt/AIChat';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor'; import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
import PromptTemplate from '@/components/PromptTemplate'; import PromptTemplate from '@/components/PromptTemplate';
import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants'; import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
@ -23,6 +22,8 @@ import { WorkflowContext } from '@/components/core/workflow/context';
import { getWorkflowGlobalVariables } from '@/web/core/workflow/utils'; import { getWorkflowGlobalVariables } from '@/web/core/workflow/utils';
import { useCreation } from 'ahooks'; import { useCreation } from 'ahooks';
import { AppContext } from '@/web/core/app/context/appContext'; import { AppContext } from '@/web/core/app/context/appContext';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const LabelStyles: BoxProps = { const LabelStyles: BoxProps = {
fontSize: ['sm', 'md'] fontSize: ['sm', 'md']
@ -178,18 +179,17 @@ const SettingQuotePrompt = (props: RenderInputProps) => {
<ModalBody> <ModalBody>
<Box> <Box>
<Flex {...LabelStyles} mb={1}> <Flex {...LabelStyles} mb={1}>
{t('core.app.Quote templates')} <FormLabel>{t('core.app.Quote templates')}</FormLabel>
<MyTooltip <QuestionTip
ml={1}
label={t('template.Quote Content Tip', { label={t('template.Quote Content Tip', {
default: Prompt_QuoteTemplateList[0].value default: Prompt_QuoteTemplateList[0].value
})} })}
forceShow ></QuestionTip>
>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
<Box flex={1} /> <Box flex={1} />
<Box <Box
{...selectTemplateBtn} {...selectTemplateBtn}
fontSize={'sm'}
onClick={() => onClick={() =>
setSelectTemplateData({ setSelectTemplateData({
title: t('core.app.Select quote template'), title: t('core.app.Select quote template'),
@ -216,15 +216,13 @@ const SettingQuotePrompt = (props: RenderInputProps) => {
</Box> </Box>
<Box mt={4}> <Box mt={4}>
<Flex {...LabelStyles} mb={1}> <Flex {...LabelStyles} mb={1}>
{t('core.app.Quote prompt')} <FormLabel>{t('core.app.Quote prompt')}</FormLabel>
<MyTooltip <QuestionTip
ml={1}
label={t('template.Quote Prompt Tip', { label={t('template.Quote Prompt Tip', {
default: Prompt_QuotePromptList[0].value default: Prompt_QuotePromptList[0].value
})} })}
forceShow ></QuestionTip>
>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
</Flex> </Flex>
<PromptEditor <PromptEditor
variables={quotePromptVariables} variables={quotePromptVariables}

View File

@ -51,15 +51,17 @@ const VariableTable = ({
borderRadius={'md'} borderRadius={'md'}
overflow={'hidden'} overflow={'hidden'}
borderWidth={'1px'} borderWidth={'1px'}
borderBottom="none" borderBottom={'none'}
> >
<TableContainer> <TableContainer>
<Table bg={'white'}> <Table bg={'white'}>
<Thead> <Thead>
<Tr> <Tr>
<Th>{t('core.module.variable.variable name')}</Th> <Th borderBottomLeftRadius={'none !important'}>
{t('core.module.variable.variable name')}
</Th>
<Th>{t('core.workflow.Value type')}</Th> <Th>{t('core.workflow.Value type')}</Th>
<Th></Th> <Th borderBottomRightRadius={'none !important'}></Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>

View File

@ -105,7 +105,7 @@ const PublishHistoriesSlider = () => {
<Button <Button
mx={'20px'} mx={'20px'}
variant={'whitePrimary'} variant={'whitePrimary'}
mb={1} mb={2}
isDisabled={!selectedHistoryId} isDisabled={!selectedHistoryId}
onClick={() => { onClick={() => {
setSelectedHistoryId(undefined); setSelectedHistoryId(undefined);
@ -125,7 +125,7 @@ const PublishHistoriesSlider = () => {
<Flex <Flex
key={data.index} key={data.index}
alignItems={'center'} alignItems={'center'}
py={4} py={3}
px={3} px={3}
borderRadius={'md'} borderRadius={'md'}
cursor={'pointer'} cursor={'pointer'}

View File

@ -15,10 +15,6 @@ import {
useTheme, useTheme,
Link, Link,
Input, Input,
MenuList,
MenuItem,
MenuButton,
Menu,
IconButton IconButton
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { import {
@ -31,7 +27,7 @@ import type { EditApiKeyProps } from '@/global/support/openapi/api.d';
import { useQuery, useMutation } from '@tanstack/react-query'; import { useQuery, useMutation } from '@tanstack/react-query';
import { useLoading } from '@fastgpt/web/hooks/useLoading'; import { useLoading } from '@fastgpt/web/hooks/useLoading';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { AddIcon, QuestionOutlineIcon } from '@chakra-ui/icons'; import { AddIcon } from '@chakra-ui/icons';
import { useCopyData } from '@/web/common/hooks/useCopyData'; import { useCopyData } from '@/web/common/hooks/useCopyData';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
@ -39,11 +35,12 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { useRequest } from '@fastgpt/web/hooks/useRequest'; import { useRequest } from '@fastgpt/web/hooks/useRequest';
import MyTooltip from '@/components/MyTooltip';
import { getDocPath } from '@/web/common/system/doc'; import { getDocPath } from '@/web/common/system/doc';
import MyMenu from '@fastgpt/web/components/common/MyMenu'; import MyMenu from '@fastgpt/web/components/common/MyMenu';
import { useConfirm } from '@fastgpt/web/hooks/useConfirm'; import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { useI18n } from '@/web/context/I18n'; import { useI18n } from '@/web/context/I18n';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
type EditProps = EditApiKeyProps & { _id?: string }; type EditProps = EditApiKeyProps & { _id?: string };
const defaultEditData: EditProps = { const defaultEditData: EditProps = {
@ -91,7 +88,7 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
<Box display={['block', 'flex']} py={[0, 3]} px={5} alignItems={'center'}> <Box display={['block', 'flex']} py={[0, 3]} px={5} alignItems={'center'}>
<Box flex={1}> <Box flex={1}>
<Flex alignItems={'flex-end'}> <Flex alignItems={'flex-end'}>
<Box fontSize={['md', 'xl']} fontWeight={'bold'}> <Box color={'myGray.900'} fontSize={'lg'}>
{t('support.openapi.Api manager')} {t('support.openapi.Api manager')}
</Box> </Box>
{feConfigs?.docUrl && ( {feConfigs?.docUrl && (
@ -100,18 +97,19 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
target={'_blank'} target={'_blank'}
ml={1} ml={1}
color={'primary.500'} color={'primary.500'}
fontSize={'sm'}
> >
{t('common.Read document')} {t('common.Read document')}
</Link> </Link>
)} )}
</Flex> </Flex>
<Box fontSize={'sm'} color={'myGray.600'}> <Box fontSize={'xs'} color={'myGray.600'}>
{tips} {tips}
</Box> </Box>
</Box> </Box>
<Flex <Flex
mt={[2, 0]} mt={[2, 0]}
bg={'myWhite.600'} bg={'myGray.100'}
py={2} py={2}
px={4} px={4}
borderRadius={'md'} borderRadius={'md'}
@ -119,10 +117,10 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
userSelect={'none'} userSelect={'none'}
onClick={() => copyData(baseUrl, t('support.openapi.Copy success'))} onClick={() => copyData(baseUrl, t('support.openapi.Copy success'))}
> >
<Box border={theme.borders.md} px={2} borderRadius={'md'} fontSize={'sm'}> <Box border={theme.borders.md} px={2} borderRadius={'md'} fontSize={'xs'}>
{t('support.openapi.Api baseurl')} {t('support.openapi.Api baseurl')}
</Box> </Box>
<Box ml={2} color={'myGray.900'} fontSize={['sm', 'md']}> <Box ml={2} fontSize={'sm'}>
{baseUrl} {baseUrl}
</Box> </Box>
</Flex> </Flex>
@ -199,6 +197,8 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
/> />
} }
menuList={[ menuList={[
{
children: [
{ {
label: t('common.Edit'), label: t('common.Edit'),
icon: 'edit', icon: 'edit',
@ -216,6 +216,8 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
type: 'danger', type: 'danger',
onClick: () => openConfirm(() => onclickRemove(_id))() onClick: () => openConfirm(() => onclickRemove(_id))()
} }
]
}
]} ]}
/> />
</Td> </Td>
@ -248,10 +250,8 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
iconSrc="/imgs/modal/key.svg" iconSrc="/imgs/modal/key.svg"
title={ title={
<Box> <Box>
<Box fontWeight={'bold'} fontSize={'xl'}> <Box fontWeight={'bold'}>{t('support.openapi.New api key')}</Box>
{t('support.openapi.New api key')} <Box fontSize={'xs'} color={'myGray.600'}>
</Box>
<Box fontSize={'sm'} color={'myGray.600'}>
{t('support.openapi.New api key tip')} {t('support.openapi.New api key tip')}
</Box> </Box>
</Box> </Box>
@ -332,7 +332,7 @@ function EditKeyModal({
> >
<ModalBody> <ModalBody>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 90px'}>{t('Name')}:</Box> <FormLabel flex={'0 0 90px'}>{t('Name')}</FormLabel>
<Input <Input
placeholder={publishT('key alias') || 'key alias'} placeholder={publishT('key alias') || 'key alias'}
maxLength={20} maxLength={20}
@ -344,12 +344,10 @@ function EditKeyModal({
{feConfigs?.isPlus && ( {feConfigs?.isPlus && (
<> <>
<Flex alignItems={'center'} mt={4}> <Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}> <FormLabel display={'flex'} flex={'0 0 90px'} alignItems={'center'}>
{t('support.outlink.Max usage points')}: {t('support.outlink.Max usage points')}
<MyTooltip label={t('support.outlink.Max usage points tip')}> <QuestionTip ml={1} label={t('support.outlink.Max usage points tip')}></QuestionTip>
<QuestionOutlineIcon ml={1} /> </FormLabel>
</MyTooltip>
</Flex>
<Input <Input
{...register('limit.maxUsagePoints', { {...register('limit.maxUsagePoints', {
min: -1, min: -1,
@ -360,9 +358,7 @@ function EditKeyModal({
/> />
</Flex> </Flex>
<Flex alignItems={'center'} mt={4}> <Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}> <FormLabel flex={'0 0 90px'}>{t('common.Expired Time')}</FormLabel>
{t('common.Expired Time')}:
</Flex>
<Input <Input
type="datetime-local" type="datetime-local"
defaultValue={ defaultValue={

View File

@ -9,6 +9,8 @@ import { Permission } from '@fastgpt/global/support/permission/controller';
const PermissionIconText = ({ const PermissionIconText = ({
permission, permission,
defaultPermission, defaultPermission,
w = '1rem',
fontSize = 'mini',
...props ...props
}: { }: {
permission?: `${PermissionTypeEnum}`; permission?: `${PermissionTypeEnum}`;
@ -25,9 +27,9 @@ const PermissionIconText = ({
}, [defaultPermission, permission]); }, [defaultPermission, permission]);
return PermissionTypeMap[per] ? ( return PermissionTypeMap[per] ? (
<Flex alignItems={'center'} {...props}> <Flex alignItems={'center'} fontSize={fontSize} {...props}>
<MyIcon name={PermissionTypeMap[per]?.iconLight as any} w={'14px'} /> <MyIcon name={PermissionTypeMap[per]?.iconLight as any} w={w} />
<Box ml={'2px'} lineHeight={1}> <Box ml={'2px'} lineHeight={1} fontSize={'xs'}>
{t(PermissionTypeMap[per]?.label)} {t(PermissionTypeMap[per]?.label)}
</Box> </Box>
</Flex> </Flex>

View File

@ -93,13 +93,12 @@ export function AddMemberModal({ onClose }: AddModalPropsType) {
p="4" p="4"
minH="200px" minH="200px"
> >
<InputGroup alignItems="center" h="32px" my="2" py="1"> <InputGroup alignItems="center" size="sm">
<InputLeftElement> <InputLeftElement>
<MyIcon name="common/searchLight" w="16px" color={'myGray.500'} /> <MyIcon name="common/searchLight" w="16px" color={'myGray.500'} />
</InputLeftElement> </InputLeftElement>
<Input <Input
placeholder="搜索用户名" placeholder="搜索用户名"
fontSize="lg"
bgColor="myGray.50" bgColor="myGray.50"
onChange={(e) => setSearchText(e.target.value)} onChange={(e) => setSearchText(e.target.value)}
/> />
@ -128,7 +127,6 @@ export function AddMemberModal({ onClose }: AddModalPropsType) {
}} }}
> >
<Checkbox <Checkbox
size="lg"
mr="3" mr="3"
isChecked={selectedMemberIdList.includes(member.tmbId)} isChecked={selectedMemberIdList.includes(member.tmbId)}
onChange={onChange} onChange={onChange}
@ -167,9 +165,7 @@ export function AddMemberModal({ onClose }: AddModalPropsType) {
_notLast={{ mb: 2 }} _notLast={{ mb: 2 }}
> >
<Avatar src={member.avatar} w="24px" /> <Avatar src={member.avatar} w="24px" />
<Box w="full" fontSize="lg"> <Box w="full">{member.memberName}</Box>
{member.memberName}
</Box>
<MyIcon <MyIcon
name="common/closeLight" name="common/closeLight"
w="16px" w="16px"
@ -202,7 +198,7 @@ export function AddMemberModal({ onClose }: AddModalPropsType) {
h={'32px'} h={'32px'}
> >
{perLabel} {perLabel}
<ChevronDownIcon fontSize={'lg'} /> <ChevronDownIcon fontSize={'md'} />
</Flex> </Flex>
} }
onChange={(v) => setSelectedPermission(v)} onChange={(v) => setSelectedPermission(v)}

View File

@ -64,10 +64,13 @@ function ManageModal({ onClose }: ManageModalProps) {
<Tr> <Tr>
<Th border="none"></Th> <Th border="none"></Th>
<Th border="none"></Th> <Th border="none"></Th>
<Th border="none"></Th> <Th border="none" w={'40px'}>
</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
<Tr h={'10px'} />
{collaboratorList?.map((item) => { {collaboratorList?.map((item) => {
return ( return (
<Tr <Tr

View File

@ -143,6 +143,7 @@ function PermissionSelect({
} }
zIndex={99} zIndex={99}
overflowY={'auto'} overflowY={'auto'}
whiteSpace={'pre-wrap'}
> >
{/* The list of single select permissions */} {/* The list of single select permissions */}
{permissionSelectList.singleCheckBoxList.map((item) => { {permissionSelectList.singleCheckBoxList.map((item) => {
@ -164,12 +165,14 @@ function PermissionSelect({
: {})} : {})}
{...MenuStyle} {...MenuStyle}
onClick={change} onClick={change}
maxW={['70vw', '300px']} maxW={['70vw', '260px']}
> >
<Radio size="lg" isChecked={selectedSingleValue === item.value} /> <Radio isChecked={selectedSingleValue === item.value} />
<Box ml={4}> <Box ml={4}>
<Box>{item.name}</Box> <Box>{item.name}</Box>
<Box color={'myGray.500'}>{item.description}</Box> <Box color={'myGray.500'} fontSize={'mini'}>
{item.description}
</Box>
</Box> </Box>
</Flex> </Flex>
); );

View File

@ -34,7 +34,7 @@ function MemberManger() {
return ( return (
<> <>
<Flex alignItems="center" flexDirection="row" justifyContent="space-between" w="full"> <Flex alignItems="center" flexDirection="row" justifyContent="space-between" w="full">
<Box></Box> <Box fontSize={'sm'}></Box>
<Flex flexDirection="row" gap="2"> <Flex flexDirection="row" gap="2">
<Button <Button
size="sm" size="sm"

View File

@ -97,9 +97,9 @@ function TeamCard() {
py={4} py={4}
borderBottom={'1.5px solid'} borderBottom={'1.5px solid'}
borderBottomColor={'myGray.100'} borderBottomColor={'myGray.100'}
mb={3} mb={2}
> >
<Box fontSize={['lg', 'xl']} fontWeight={'bold'} alignItems={'center'}> <Box fontSize={['sm', 'md']} fontWeight={'bold'} alignItems={'center'}>
{userInfo?.team.teamName} {userInfo?.team.teamName}
</Box> </Box>
{userInfo?.team.role === TeamMemberRoleEnum.owner && ( {userInfo?.team.role === TeamMemberRoleEnum.owner && (

View File

@ -1,4 +1,4 @@
import { Box, Button, Flex, IconButton } from '@chakra-ui/react'; import { Box, Button, Flex, IconButton, Text } from '@chakra-ui/react';
import Avatar from '@/components/Avatar'; import Avatar from '@/components/Avatar';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
@ -28,7 +28,7 @@ function TeamList() {
h={'40px'} h={'40px'}
borderBottom={'1.5px solid rgba(0, 0, 0, 0.05)'} borderBottom={'1.5px solid rgba(0, 0, 0, 0.05)'}
> >
<Box flex={['0 0 auto', 1]} fontWeight={'bold'} fontSize={['md', 'lg']}> <Box flex={['0 0 auto', 1]} fontSize={['sm', 'md']}>
{t('common.Team')} {t('common.Team')}
</Box> </Box>
{/* if there is no team */} {/* if there is no team */}
@ -73,6 +73,7 @@ function TeamList() {
<Box <Box
flex={'1 0 0'} flex={'1 0 0'}
w={0} w={0}
fontSize={'sm'}
{...(team.role === TeamMemberRoleEnum.owner {...(team.role === TeamMemberRoleEnum.owner
? { ? {
fontWeight: 'bold' fontWeight: 'bold'

View File

@ -8,7 +8,7 @@ import { getErrText } from '@fastgpt/global/common/error/utils';
import { useRequest } from '@fastgpt/web/hooks/useRequest'; import { useRequest } from '@fastgpt/web/hooks/useRequest';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import { Box, Button, Flex, Input, ModalBody, ModalFooter } from '@chakra-ui/react'; import { Box, Button, Flex, Input, ModalBody, ModalFooter } from '@chakra-ui/react';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import Avatar from '@/components/Avatar'; import Avatar from '@/components/Avatar';
import { postCreateTeam, putUpdateTeam } from '@/web/support/user/team/api'; import { postCreateTeam, putUpdateTeam } from '@/web/support/user/team/api';
import { CreateTeamProps } from '@fastgpt/global/support/user/team/controller.d'; import { CreateTeamProps } from '@fastgpt/global/support/user/team/controller.d';

View File

@ -21,7 +21,9 @@ function MemberTable() {
const { t } = useTranslation(); const { t } = useTranslation();
const { members, refetchMembers } = useContextSelector(TeamModalContext, (v) => v); const { members, refetchMembers } = useContextSelector(TeamModalContext, (v) => v);
const { ConfirmModal: ConfirmRemoveMemberModal, openConfirm: openRemoveMember } = useConfirm({}); const { ConfirmModal: ConfirmRemoveMemberModal, openConfirm: openRemoveMember } = useConfirm({
type: 'delete'
});
const { mutate: onRemoveMember, isLoading: isRemovingMember } = useRequest({ const { mutate: onRemoveMember, isLoading: isRemovingMember } = useRequest({
mutationFn: delRemoveMember, mutationFn: delRemoveMember,
@ -34,14 +36,14 @@ function MemberTable() {
return ( return (
<MyBox isLoading={isRemovingMember}> <MyBox isLoading={isRemovingMember}>
<TableContainer overflow={'unset'}> <TableContainer overflow={'unset'} fontSize={'sm'}>
<Table overflow={'unset'}> <Table overflow={'unset'}>
<Thead bg={'myWhite.400'}> <Thead bg={'myWhite.400'}>
<Tr> <Tr>
<Th>{t('common.Username')}</Th> <Th borderRadius={'none !important'}>{t('common.Username')}</Th>
<Th>{t('user.team.Role')}</Th> <Th>{t('user.team.Role')}</Th>
<Th>{t('common.Status')}</Th> <Th>{t('common.Status')}</Th>
<Th>{t('common.Action')}</Th> <Th borderRadius={'none !important'}>{t('common.Action')}</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
@ -67,22 +69,19 @@ function MemberTable() {
Button={ Button={
<MenuButton <MenuButton
_hover={{ _hover={{
bg: 'myWhite.600' color: 'primary.600'
}} }}
borderRadius={'md'} borderRadius={'md'}
px={2} px={2}
py={1} py={1}
lineHeight={1} lineHeight={1}
> >
<MyIcon <MyIcon name={'edit'} cursor={'pointer'} w="1rem" />
name={'edit'}
cursor={'pointer'}
w="14px"
_hover={{ color: 'primary.500' }}
/>
</MenuButton> </MenuButton>
} }
menuList={[ menuList={[
{
children: [
{ {
label: t('user.team.Remove Member Tip'), label: t('user.team.Remove Member Tip'),
onClick: () => onClick: () =>
@ -98,6 +97,8 @@ function MemberTable() {
}) })
)() )()
} }
]
}
]} ]}
/> />
)} )}

View File

@ -78,13 +78,13 @@ function AddManagerModal({ onClose, onSuccess }: { onClose: () => void; onSucces
borderColor="myGray.200" borderColor="myGray.200"
> >
<Flex flexDirection="column" p="4"> <Flex flexDirection="column" p="4">
<InputGroup alignItems="center" h="32px" my="2" py="1"> <InputGroup alignItems="center" size={'sm'}>
<InputLeftElement> <InputLeftElement>
<MyIcon name="common/searchLight" w="16px" color={'myGray.500'} /> <MyIcon name="common/searchLight" w="16px" color={'myGray.500'} />
</InputLeftElement> </InputLeftElement>
<Input <Input
placeholder="搜索用户名" placeholder="搜索用户名"
fontSize="lg" fontSize="sm"
bg={'myGray.50'} bg={'myGray.50'}
onChange={(e) => { onChange={(e) => {
setSearchKey(e.target.value); setSearchKey(e.target.value);
@ -98,7 +98,6 @@ function AddManagerModal({ onClose, onSuccess }: { onClose: () => void; onSucces
py="2" py="2"
px={3} px={3}
borderRadius={'md'} borderRadius={'md'}
fontSize="lg"
alignItems="center" alignItems="center"
key={member.tmbId} key={member.tmbId}
cursor={'pointer'} cursor={'pointer'}
@ -112,8 +111,8 @@ function AddManagerModal({ onClose, onSuccess }: { onClose: () => void; onSucces
} }
}} }}
> >
<Checkbox isChecked={selected.includes(member)} size="lg" /> <Checkbox isChecked={selected.includes(member)} />
<Avatar src={member.avatar} w="24px" /> <Avatar ml={2} src={member.avatar} w="1.5rem" />
{member.memberName} {member.memberName}
</Flex> </Flex>
); );
@ -135,11 +134,13 @@ function AddManagerModal({ onClose, onSuccess }: { onClose: () => void; onSucces
_hover={{ bg: 'myGray.50' }} _hover={{ bg: 'myGray.50' }}
_notLast={{ mb: 2 }} _notLast={{ mb: 2 }}
> >
<Avatar src={member.avatar} w="24px" /> <Avatar src={member.avatar} w="1.5rem" />
<Box w="full" fontSize="lg"> <Box w="full">{member.memberName}</Box>
{member.memberName} <MyIcon
</Box> name={'common/closeLight'}
<CloseButton w={'1rem'}
cursor={'pointer'}
_hover={{ color: 'red.600' }}
onClick={() => onClick={() =>
setSelected([...selected.filter((item) => item.tmbId != member.tmbId)]) setSelected([...selected.filter((item) => item.tmbId != member.tmbId)])
} }

View File

@ -47,7 +47,7 @@ function PermissionManage() {
justifyContent={'space-between'} justifyContent={'space-between'}
> >
<Flex> <Flex>
<Box fontSize={['md', 'lg']} fontWeight={'bold'} alignItems={'center'}> <Box fontSize={['sm', 'md']} fontWeight={'bold'} alignItems={'center'}>
{t('user.team.role.Admin')} {t('user.team.role.Admin')}
</Box> </Box>
<Box <Box

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Box, Button, Flex, Image, useDisclosure } from '@chakra-ui/react'; import { Box, Button, Flex, Image, useDisclosure } from '@chakra-ui/react';
import { useUserStore } from '@/web/support/user/useUserStore'; import { useUserStore } from '@/web/support/user/useUserStore';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';

View File

@ -6,9 +6,9 @@ import { Box, Flex, Grid } from '@chakra-ui/react';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { AI_POINT_USAGE_CARD_ROUTE } from '@/web/support/wallet/sub/constants'; import { AI_POINT_USAGE_CARD_ROUTE } from '@/web/support/wallet/sub/constants';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
const StandardPlanContentList = ({ const StandardPlanContentList = ({
level, level,
@ -43,7 +43,7 @@ const StandardPlanContentList = ({
}, [subPlans?.standard, level, mode]); }, [subPlans?.standard, level, mode]);
return planContent ? ( return planContent ? (
<Grid gap={4}> <Grid gap={4} fontSize={'sm'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'price/right'} w={'16px'} mr={3} /> <MyIcon name={'price/right'} w={'16px'} mr={3} />
<Box color={'myGray.600'}> <Box color={'myGray.600'}>
@ -92,14 +92,13 @@ const StandardPlanContentList = ({
amount: planContent.totalPoints amount: planContent.totalPoints
})} })}
</Box> </Box>
<MyTooltip label={t('support.wallet.subscription.AI points click to read tip')}> <QuestionTip
<QuestionOutlineIcon ml={1}
ml={'2px'} label={t('support.wallet.subscription.AI points click to read tip')}
onClick={() => { onClick={() => {
router.push(AI_POINT_USAGE_CARD_ROUTE); router.push(AI_POINT_USAGE_CARD_ROUTE);
}} }}
/> ></QuestionTip>
</MyTooltip>
</Flex> </Flex>
</Flex> </Flex>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>

View File

@ -32,6 +32,7 @@ import { standardSubLevelMap, subModeMap } from '@fastgpt/global/support/wallet/
import MySelect from '@fastgpt/web/components/common/MySelect'; import MySelect from '@fastgpt/web/components/common/MySelect';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import { usePagination } from '@fastgpt/web/hooks/usePagination'; import { usePagination } from '@fastgpt/web/hooks/usePagination';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
const BillTable = () => { const BillTable = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -187,58 +188,68 @@ function BillDetailModal({ bill, onClose }: { bill: BillSchemaType; onClose: ()
> >
<ModalBody> <ModalBody>
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.bill.Number')}:</Box> <FormLabel flex={'0 0 120px'}>{t('support.wallet.bill.Number')}:</FormLabel>
<Box>{bill.orderId}</Box> <Box>{bill.orderId}</Box>
</Flex> </Flex>
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.usage.Time')}:</Box> <FormLabel flex={'0 0 120px'}>{t('support.wallet.usage.Time')}:</FormLabel>
<Box>{dayjs(bill.createTime).format('YYYY/MM/DD HH:mm:ss')}</Box> <Box>{dayjs(bill.createTime).format('YYYY/MM/DD HH:mm:ss')}</Box>
</Flex> </Flex>
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.bill.Status')}:</Box> <FormLabel flex={'0 0 120px'}>{t('support.wallet.bill.Status')}:</FormLabel>
<Box>{t(billStatusMap[bill.status]?.label)}</Box> <Box>{t(billStatusMap[bill.status]?.label)}</Box>
</Flex> </Flex>
{!!bill.metadata?.payWay && ( {!!bill.metadata?.payWay && (
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.bill.payWay.Way')}:</Box> <FormLabel flex={'0 0 120px'}>{t('support.wallet.bill.payWay.Way')}:</FormLabel>
<Box>{t(billPayWayMap[bill.metadata.payWay]?.label)}</Box> <Box>{t(billPayWayMap[bill.metadata.payWay]?.label)}</Box>
</Flex> </Flex>
)} )}
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.Amount')}:</Box> <FormLabel flex={'0 0 120px'}>{t('support.wallet.Amount')}:</FormLabel>
<Box>{formatStorePrice2Read(bill.price)}</Box> <Box>{formatStorePrice2Read(bill.price)}</Box>
</Flex> </Flex>
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.bill.Type')}:</Box> <FormLabel flex={'0 0 120px'}>{t('support.wallet.bill.Type')}:</FormLabel>
<Box>{t(billTypeMap[bill.type]?.label)}</Box> <Box>{t(billTypeMap[bill.type]?.label)}</Box>
</Flex> </Flex>
{!!bill.metadata?.subMode && ( {!!bill.metadata?.subMode && (
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.subscription.mode.Period')}:</Box> <FormLabel flex={'0 0 120px'}>
{t('support.wallet.subscription.mode.Period')}:
</FormLabel>
<Box>{t(subModeMap[bill.metadata.subMode]?.label)}</Box> <Box>{t(subModeMap[bill.metadata.subMode]?.label)}</Box>
</Flex> </Flex>
)} )}
{!!bill.metadata?.standSubLevel && ( {!!bill.metadata?.standSubLevel && (
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.subscription.Stand plan level')}:</Box> <FormLabel flex={'0 0 120px'}>
{t('support.wallet.subscription.Stand plan level')}:
</FormLabel>
<Box>{t(standardSubLevelMap[bill.metadata.standSubLevel]?.label)}</Box> <Box>{t(standardSubLevelMap[bill.metadata.standSubLevel]?.label)}</Box>
</Flex> </Flex>
)} )}
{bill.metadata?.month !== undefined && ( {bill.metadata?.month !== undefined && (
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.subscription.Month amount')}:</Box> <FormLabel flex={'0 0 120px'}>
{t('support.wallet.subscription.Month amount')}:
</FormLabel>
<Box>{bill.metadata?.month}</Box> <Box>{bill.metadata?.month}</Box>
</Flex> </Flex>
)} )}
{bill.metadata?.datasetSize !== undefined && ( {bill.metadata?.datasetSize !== undefined && (
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.subscription.Extra dataset size')}:</Box> <FormLabel flex={'0 0 120px'}>
{t('support.wallet.subscription.Extra dataset size')}:
</FormLabel>
<Box>{bill.metadata?.datasetSize}</Box> <Box>{bill.metadata?.datasetSize}</Box>
</Flex> </Flex>
)} )}
{bill.metadata?.extraPoints !== undefined && ( {bill.metadata?.extraPoints !== undefined && (
<Flex alignItems={'center'} pb={4}> <Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 120px'}>{t('support.wallet.subscription.Extra ai points')}:</Box> <FormLabel flex={'0 0 120px'}>
{t('support.wallet.subscription.Extra ai points')}:
</FormLabel>
<Box>{bill.metadata.extraPoints}</Box> <Box>{bill.metadata.extraPoints}</Box>
</Flex> </Flex>
)} )}

View File

@ -38,12 +38,12 @@ const Individuation = () => {
return ( return (
<Box py={[3, '28px']} px={['5vw', '64px']}> <Box py={[3, '28px']} px={['5vw', '64px']}>
<Flex alignItems={'center'} fontSize={'xl'} h={'30px'}> <Flex alignItems={'center'} fontSize={'lg'} h={'30px'}>
<MyIcon mr={2} name={'support/user/individuation'} w={'20px'} /> <MyIcon mr={2} name={'support/user/individuation'} w={'20px'} />
{t('support.account.Individuation')} {t('support.account.Individuation')}
</Flex> </Flex>
<Card mt={6} px={[3, 10]} py={[3, 7]}> <Card mt={6} px={[3, 10]} py={[3, 7]} fontSize={'sm'}>
<Flex alignItems={'center'} w={['85%', '350px']}> <Flex alignItems={'center'} w={['85%', '350px']}>
<Box flex={'0 0 80px'}>{t('user.Language')}:&nbsp;</Box> <Box flex={'0 0 80px'}>{t('user.Language')}:&nbsp;</Box>
<Box flex={'1 0 0'}> <Box flex={'1 0 0'}>

View File

@ -9,7 +9,8 @@ import {
Link, Link,
Progress, Progress,
Grid, Grid,
Image Image,
BoxProps
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { UserUpdateParams } from '@/types/user'; import { UserUpdateParams } from '@/types/user';
@ -17,7 +18,6 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
import { useUserStore } from '@/web/support/user/useUserStore'; import { useUserStore } from '@/web/support/user/useUserStore';
import type { UserType } from '@fastgpt/global/support/user/type.d'; import type { UserType } from '@fastgpt/global/support/user/type.d';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
import { compressImgFileAndUpload } from '@/web/common/file/controller'; import { compressImgFileAndUpload } from '@/web/common/file/controller';
@ -25,7 +25,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import Avatar from '@/components/Avatar'; import Avatar from '@/components/Avatar';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/usage/tools'; import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/usage/tools';
import { putUpdateMemberName } from '@/web/support/user/team/api'; import { putUpdateMemberName } from '@/web/support/user/team/api';
@ -43,6 +43,7 @@ import {
import StandardPlanContentList from '@/components/support/wallet/StandardPlanContentList'; import StandardPlanContentList from '@/components/support/wallet/StandardPlanContentList';
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant'; import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
const StandDetailModal = dynamic(() => import('./standardDetailModal')); const StandDetailModal = dynamic(() => import('./standardDetailModal'));
const TeamMenu = dynamic(() => import('@/components/support/user/team/TeamMenu')); const TeamMenu = dynamic(() => import('@/components/support/user/team/TeamMenu'));
@ -158,20 +159,26 @@ const MyInfo = () => {
[onclickSave, t, toast, userInfo] [onclickSave, t, toast, userInfo]
); );
const labelStyles: BoxProps = {
flex: '0 0 80px',
fontSize: 'sm',
color: 'myGray.900'
};
return ( return (
<Box> <Box>
{/* user info */} {/* user info */}
{isPc && ( {isPc && (
<Flex alignItems={'center'} fontSize={'xl'} h={'30px'}> <Flex alignItems={'center'} fontSize={'md'} h={'30px'}>
<MyIcon mr={2} name={'support/user/userLight'} w={'20px'} /> <MyIcon mr={2} name={'support/user/userLight'} w={'1.25rem'} />
{t('support.user.User self info')} {t('support.user.User self info')}
</Flex> </Flex>
)} )}
<Box mt={[0, 6]}> <Box mt={[0, 6]} fontSize={'sm'}>
{isPc ? ( {isPc ? (
<Flex alignItems={'center'} cursor={'pointer'}> <Flex alignItems={'center'} cursor={'pointer'}>
<Box flex={'0 0 80px'}>{t('support.user.Avatar')}:&nbsp;</Box> <Box {...labelStyles}>{t('support.user.Avatar')}:&nbsp;</Box>
<MyTooltip label={t('common.avatar.Select Avatar')}> <MyTooltip label={t('common.avatar.Select Avatar')}>
<Box <Box
@ -219,7 +226,7 @@ const MyInfo = () => {
)} )}
{feConfigs.isPlus && ( {feConfigs.isPlus && (
<Flex mt={[0, 4]} alignItems={'center'}> <Flex mt={[0, 4]} alignItems={'center'}>
<Box flex={'0 0 80px'}>{t('user.Member Name')}:&nbsp;</Box> <Box {...labelStyles}>{t('user.Member Name')}:&nbsp;</Box>
<Input <Input
flex={'1 0 0'} flex={'1 0 0'}
defaultValue={userInfo?.team?.memberName || 'Member'} defaultValue={userInfo?.team?.memberName || 'Member'}
@ -238,12 +245,12 @@ const MyInfo = () => {
</Flex> </Flex>
)} )}
<Flex alignItems={'center'} mt={6}> <Flex alignItems={'center'} mt={6}>
<Box flex={'0 0 80px'}>{t('user.Account')}:&nbsp;</Box> <Box {...labelStyles}>{t('user.Account')}:&nbsp;</Box>
<Box flex={1}>{userInfo?.username}</Box> <Box flex={1}>{userInfo?.username}</Box>
</Flex> </Flex>
{feConfigs.isPlus && ( {feConfigs.isPlus && (
<Flex mt={6} alignItems={'center'}> <Flex mt={6} alignItems={'center'}>
<Box flex={'0 0 80px'}>{t('user.Password')}:&nbsp;</Box> <Box {...labelStyles}>{t('user.Password')}:&nbsp;</Box>
<Box flex={1}>*****</Box> <Box flex={1}>*****</Box>
<Button size={'sm'} variant={'whitePrimary'} onClick={onOpenUpdatePsw}> <Button size={'sm'} variant={'whitePrimary'} onClick={onOpenUpdatePsw}>
{t('user.Change')} {t('user.Change')}
@ -251,7 +258,7 @@ const MyInfo = () => {
</Flex> </Flex>
)} )}
<Flex mt={6} alignItems={'center'}> <Flex mt={6} alignItems={'center'}>
<Box flex={'0 0 80px'}>{t('user.Team')}:&nbsp;</Box> <Box {...labelStyles}>{t('user.Team')}:&nbsp;</Box>
<Box flex={1}> <Box flex={1}>
<TeamMenu /> <TeamMenu />
</Box> </Box>
@ -259,9 +266,7 @@ const MyInfo = () => {
{feConfigs.isPlus && ( {feConfigs.isPlus && (
<Box mt={6} whiteSpace={'nowrap'}> <Box mt={6} whiteSpace={'nowrap'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box flex={'0 0 80px'} fontSize={'md'}> <Box {...labelStyles}>{t('user.team.Balance')}:&nbsp;</Box>
{t('user.team.Balance')}:&nbsp;
</Box>
<Box flex={1}> <Box flex={1}>
<strong>{formatStorePrice2Read(userInfo?.team?.balance).toFixed(3)}</strong> <strong>{formatStorePrice2Read(userInfo?.team?.balance).toFixed(3)}</strong>
</Box> </Box>
@ -373,7 +378,7 @@ const PlanUsage = () => {
return standardPlan ? ( return standardPlan ? (
<Box mt={[6, 0]}> <Box mt={[6, 0]}>
<Flex fontSize={'xl'} h={'30px'}> <Flex fontSize={'lg'} h={'30px'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon mr={2} name={'support/account/plans'} w={'20px'} /> <MyIcon mr={2} name={'support/account/plans'} w={'20px'} />
{t('support.wallet.subscription.Team plan and usage')} {t('support.wallet.subscription.Team plan and usage')}
@ -392,12 +397,12 @@ const PlanUsage = () => {
borderColor={'borderColor.low'} borderColor={'borderColor.low'}
borderRadius={'md'} borderRadius={'md'}
> >
<Flex px={[5, 10]} py={[3, 6]}> <Flex px={[5, 7]} py={[3, 6]}>
<Box flex={'1 0 0'}> <Box flex={'1 0 0'}>
<Box color={'myGray.600'} fontSize="sm"> <Box color={'myGray.600'} fontSize="sm">
{t('support.wallet.subscription.Current plan')} {t('support.wallet.subscription.Current plan')}
</Box> </Box>
<Box fontWeight={'bold'} fontSize="xl"> <Box fontWeight={'bold'} fontSize="lg">
{t(planName)} {t(planName)}
</Box> </Box>
@ -412,18 +417,18 @@ const PlanUsage = () => {
</Box> </Box>
</> </>
) : ( ) : (
<Flex mt="2" color={'#485264'} fontSize="sm"> <Flex mt="2" color={'#485264'} fontSize="xs">
<Box>{t('support.wallet.Plan expired time')}:</Box> <Box>{t('support.wallet.Plan expired time')}:</Box>
<Box ml={2}>{formatTime2YMD(standardPlan?.expiredTime)}</Box> <Box ml={2}>{formatTime2YMD(standardPlan?.expiredTime)}</Box>
</Flex> </Flex>
)} )}
</Box> </Box>
<Button onClick={() => router.push('/price')}> <Button onClick={() => router.push('/price')} w={'8rem'} size="sm">
{t('support.wallet.subscription.Upgrade plan')} {t('support.wallet.subscription.Upgrade plan')}
</Button> </Button>
</Flex> </Flex>
<Box py={3} borderTopWidth={'1px'} borderTopColor={'borderColor.base'}> <Box py={3} borderTopWidth={'1px'} borderTopColor={'borderColor.base'}>
<Box py={[0, 3]} px={[5, 10]} overflow={'auto'}> <Box py={[0, 3]} px={[5, 7]} overflow={'auto'}>
<StandardPlanContentList <StandardPlanContentList
level={standardPlan?.currentSubLevel} level={standardPlan?.currentSubLevel}
mode={standardPlan.currentMode} mode={standardPlan.currentMode}
@ -443,8 +448,8 @@ const PlanUsage = () => {
> >
<Flex> <Flex>
<Flex flex={'1 0 0'} alignItems={'flex-end'}> <Flex flex={'1 0 0'} alignItems={'flex-end'}>
<Box fontSize={'xl'}></Box> <Box fontSize={'md'}></Box>
<Box fontSize={'sm'} color={'myGray.500'}> <Box fontSize={'xs'} color={'myGray.500'}>
() ()
</Box> </Box>
</Flex> </Flex>
@ -455,15 +460,18 @@ const PlanUsage = () => {
alignItems={'center'} alignItems={'center'}
color={'primary.600'} color={'primary.600'}
cursor={'pointer'} cursor={'pointer'}
fontSize={'sm'}
> >
<MyIcon ml={1} name={'common/rightArrowLight'} w={'12px'} /> <MyIcon ml={1} name={'common/rightArrowLight'} w={'12px'} />
</Link> </Link>
</Flex> </Flex>
<Box width={'100%'} mt={5}> <Box width={'100%'} mt={5} fontSize={'sm'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box fontWeight={'bold'}>{t('support.user.team.Dataset usage')}</Box> <Box fontWeight={'bold'} color={'myGray.900'}>
{t('support.user.team.Dataset usage')}
</Box>
<Box color={'myGray.600'} ml={2}> <Box color={'myGray.600'} ml={2}>
{datasetUsageMap.usedSize}/{datasetUsageMap.maxSize} {datasetUsageMap.usedSize}/{datasetUsageMap.maxSize}
</Box> </Box>
@ -482,13 +490,16 @@ const PlanUsage = () => {
/> />
</Box> </Box>
</Box> </Box>
<Box mt="9" width={'100%'}> <Box mt="9" width={'100%'} fontSize={'sm'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box fontWeight={'bold'}>{t('support.wallet.subscription.AI points usage')}</Box> <Box fontWeight={'bold'} color={'myGray.900'}>
<MyTooltip label={t('support.wallet.subscription.AI points usage tip')}> {t('support.wallet.subscription.AI points usage')}
<QuestionOutlineIcon ml={'2px'} /> </Box>
</MyTooltip> <QuestionTip
ml={1}
label={t('support.wallet.subscription.AI points usage tip')}
></QuestionTip>
<Box color={'myGray.600'} ml={2}> <Box color={'myGray.600'} ml={2}>
{aiPointsUsageMap.used}/{aiPointsUsageMap.max} {aiPointsUsageMap.used}/{aiPointsUsageMap.max}
</Box> </Box>
@ -557,6 +568,7 @@ const Other = () => {
alignItems={'center'} alignItems={'center'}
userSelect={'none'} userSelect={'none'}
textDecoration={'none !important'} textDecoration={'none !important'}
fontSize={'sm'}
> >
<MyIcon name={'common/courseLight'} w={'18px'} color={'myGray.600'} /> <MyIcon name={'common/courseLight'} w={'18px'} color={'myGray.600'} />
<Box ml={2} flex={1}> <Box ml={2} flex={1}>
@ -578,6 +590,7 @@ const Other = () => {
alignItems={'center'} alignItems={'center'}
userSelect={'none'} userSelect={'none'}
textDecoration={'none !important'} textDecoration={'none !important'}
fontSize={'sm'}
> >
<MyIcon name={'core/app/aiLight'} w={'18px'} /> <MyIcon name={'core/app/aiLight'} w={'18px'} />
<Box ml={2} flex={1}> <Box ml={2} flex={1}>
@ -589,7 +602,7 @@ const Other = () => {
{feConfigs?.lafEnv && userInfo?.team.role === TeamMemberRoleEnum.owner && ( {feConfigs?.lafEnv && userInfo?.team.role === TeamMemberRoleEnum.owner && (
<Flex <Flex
bg={'white'} bg={'white'}
py={4} py={3}
px={6} px={6}
border={theme.borders.sm} border={theme.borders.sm}
borderWidth={'1.5px'} borderWidth={'1.5px'}
@ -598,6 +611,7 @@ const Other = () => {
cursor={'pointer'} cursor={'pointer'}
userSelect={'none'} userSelect={'none'}
onClick={onOpenLaf} onClick={onOpenLaf}
fontSize={'sm'}
> >
<Image src="/imgs/workflow/laf.png" w={'18px'} alt="laf" /> <Image src="/imgs/workflow/laf.png" w={'18px'} alt="laf" />
<Box ml={2} flex={1}> <Box ml={2} flex={1}>
@ -615,7 +629,7 @@ const Other = () => {
{feConfigs?.show_openai_account && ( {feConfigs?.show_openai_account && (
<Flex <Flex
bg={'white'} bg={'white'}
py={4} py={3}
px={6} px={6}
border={theme.borders.sm} border={theme.borders.sm}
borderWidth={'1.5px'} borderWidth={'1.5px'}
@ -624,6 +638,7 @@ const Other = () => {
cursor={'pointer'} cursor={'pointer'}
userSelect={'none'} userSelect={'none'}
onClick={onOpenOpenai} onClick={onOpenOpenai}
fontSize={'sm'}
> >
<MyIcon name={'common/openai'} w={'18px'} color={'myGray.600'} /> <MyIcon name={'common/openai'} w={'18px'} color={'myGray.600'} />
<Box ml={2} flex={1}> <Box ml={2} flex={1}>
@ -644,6 +659,7 @@ const Other = () => {
leftIcon={<MyIcon name={'modal/concat'} w={'18px'} color={'myGray.600'} />} leftIcon={<MyIcon name={'modal/concat'} w={'18px'} color={'myGray.600'} />}
onClick={onOpenConcat} onClick={onOpenConcat}
h={'48px'} h={'48px'}
fontSize={'sm'}
> >
</Button> </Button>

View File

@ -8,6 +8,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import { usePagination } from '@fastgpt/web/hooks/usePagination'; import { usePagination } from '@fastgpt/web/hooks/usePagination';
import { useLoading } from '@fastgpt/web/hooks/useLoading'; import { useLoading } from '@fastgpt/web/hooks/useLoading';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
const InformTable = () => { const InformTable = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -78,14 +79,7 @@ const InformTable = () => {
)} )}
</Box> </Box>
))} ))}
{!isLoading && informs.length === 0 && ( {!isLoading && informs.length === 0 && <EmptyTip text={'暂无通知~'}></EmptyTip>}
<Flex flex={'1 0 0'} flexDirection={'column'} alignItems={'center'} pt={'10vh'}>
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
<Box mt={2} color={'myGray.500'}>
~
</Box>
</Flex>
)}
</Box> </Box>
{total > pageSize && ( {total > pageSize && (

View File

@ -19,14 +19,15 @@ import { useQuery } from '@tanstack/react-query';
import { getPromotionInitData, getPromotionRecords } from '@/web/support/activity/promotion/api'; import { getPromotionInitData, getPromotionRecords } from '@/web/support/activity/promotion/api';
import { useUserStore } from '@/web/support/user/useUserStore'; import { useUserStore } from '@/web/support/user/useUserStore';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import { useCopyData } from '@/web/common/hooks/useCopyData'; import { useCopyData } from '@/web/common/hooks/useCopyData';
import type { PromotionRecordType } from '@/global/support/api/userRes.d'; import type { PromotionRecordType } from '@/global/support/api/userRes.d';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { usePagination } from '@fastgpt/web/hooks/usePagination'; import { usePagination } from '@fastgpt/web/hooks/usePagination';
import { useLoading } from '@fastgpt/web/hooks/useLoading'; import { useLoading } from '@fastgpt/web/hooks/useLoading';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
const Promotion = () => { const Promotion = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -55,7 +56,7 @@ const Promotion = () => {
p: [4, 5], p: [4, 5],
border: theme.borders.base, border: theme.borders.base,
textAlign: 'center', textAlign: 'center',
fontSize: ['md', 'xl'], fontSize: ['md', 'lg'],
borderRadius: 'md' borderRadius: 'md'
}; };
const titleStyles: BoxProps = { const titleStyles: BoxProps = {
@ -78,18 +79,14 @@ const Promotion = () => {
<Box {...statisticsStyles}> <Box {...statisticsStyles}>
<Flex alignItems={'center'} justifyContent={'center'}> <Flex alignItems={'center'} justifyContent={'center'}>
<Box>{t('user.Promotion Rate')}</Box> <Box>{t('user.Promotion Rate')}</Box>
<MyTooltip label={t('user.Promotion rate tip')}> <QuestionTip ml={1} label={t('user.Promotion rate tip')}></QuestionTip>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Flex> </Flex>
<Box {...titleStyles}>{userInfo?.promotionRate || 15}%</Box> <Box {...titleStyles}>{userInfo?.promotionRate || 15}%</Box>
</Box> </Box>
<Box {...statisticsStyles}> <Box {...statisticsStyles}>
<Flex alignItems={'center'} justifyContent={'center'}> <Flex alignItems={'center'} justifyContent={'center'}>
<Box>{t('user.Invite Url')}</Box> <Box>{t('user.Invite Url')}</Box>
<MyTooltip label={t('user.Invite url tip')}> <QuestionTip ml={1} label={t('user.Invite url tip')}></QuestionTip>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Flex> </Flex>
<Button <Button
mt={4} mt={4}
@ -127,14 +124,7 @@ const Promotion = () => {
</Table> </Table>
</TableContainer> </TableContainer>
{!isLoading && promotionRecords.length === 0 && ( {!isLoading && promotionRecords.length === 0 && <EmptyTip text="无邀请记录~"></EmptyTip>}
<Flex mt={'10vh'} flexDirection={'column'} alignItems={'center'}>
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
<Box mt={2} color={'myGray.500'}>
~
</Box>
</Flex>
)}
{total > pageSize && ( {total > pageSize && (
<Flex mt={4} justifyContent={'flex-end'}> <Flex mt={4} justifyContent={'flex-end'}>
<Pagination /> <Pagination />

Some files were not shown because too many files have changed in this diff Show More