mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-29 09:44:47 +00:00
System plugin (#2091)
* System template (#2082) * feat: system plugin (#2024) * add plugin cost & change plugin avatar (#2030) * add plugin cost & change plugin avatar * add author * feat: duckduckgo plugin * duckduck search * perf: templates select system plugin * perf: system plugin avatar * feat: duckduck plugins * doc * perf: plugin classify * perf: icon avatar component * perf: system template avatar --------- Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com> * feat: system plugin search * perf: plugin packages important * perf: source avatar * nextconfig * perf: i18n * perf: default model * perf: system plugin author --------- Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
@@ -23,7 +23,7 @@ import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
|
||||
import { compressImgFileAndUpload } from '@/web/common/file/controller';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import { useRouter } from 'next/router';
|
||||
|
@@ -27,7 +27,7 @@ import { useTranslation } from 'next-i18next';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { getTeamMembers } from '@/web/support/user/team/api';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
import { formatNumber } from '@fastgpt/global/common/math/tools';
|
||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||
|
@@ -1,26 +1,55 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import type { NextApiResponse } from 'next';
|
||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||
import { NodeTemplateListItemType } from '@fastgpt/global/core/workflow/type/node.d';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { getCommunityPluginsTemplateList } from '@fastgpt/plugins/register';
|
||||
import { getSystemPluginTemplates } from '@fastgpt/plugins/register';
|
||||
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
||||
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||
import { replaceRegChars } from '@fastgpt/global/common/string/tools';
|
||||
|
||||
export type GetSystemPluginTemplatesBody = {
|
||||
searchKey?: string;
|
||||
parentId: ParentIdType;
|
||||
};
|
||||
|
||||
async function handler(
|
||||
req: NextApiRequest,
|
||||
req: ApiRequestProps<GetSystemPluginTemplatesBody>,
|
||||
res: NextApiResponse<any>
|
||||
): Promise<NodeTemplateListItemType[]> {
|
||||
await authCert({ req, authToken: true });
|
||||
|
||||
// const data: NodeTemplateListItemType[] =
|
||||
// global.communityPlugins?.map((plugin) => ({
|
||||
// id: plugin.id,
|
||||
// templateType: plugin.templateType ?? FlowNodeTemplateTypeEnum.other,
|
||||
// flowNodeType: FlowNodeTypeEnum.pluginModule,
|
||||
// avatar: plugin.avatar,
|
||||
// name: plugin.name,
|
||||
// intro: plugin.intro
|
||||
// })) || [];
|
||||
const { searchKey, parentId } = req.body;
|
||||
|
||||
return getCommunityPluginsTemplateList();
|
||||
const formatParentId = parentId || null;
|
||||
|
||||
return getSystemPluginTemplates().then((res) =>
|
||||
res
|
||||
// Just show the active plugins
|
||||
.filter((item) => item.isActive)
|
||||
.map<NodeTemplateListItemType>((plugin) => ({
|
||||
id: plugin.id,
|
||||
isFolder: plugin.isFolder,
|
||||
parentId: plugin.parentId,
|
||||
templateType: plugin.templateType ?? FlowNodeTemplateTypeEnum.other,
|
||||
flowNodeType: FlowNodeTypeEnum.pluginModule,
|
||||
avatar: plugin.avatar,
|
||||
name: plugin.name,
|
||||
intro: plugin.intro,
|
||||
isTool: plugin.isTool,
|
||||
currentCost: plugin.currentCost,
|
||||
author: plugin.author
|
||||
}))
|
||||
.filter((item) => {
|
||||
if (searchKey) {
|
||||
if (item.isFolder) return false;
|
||||
const regx = new RegExp(`${replaceRegChars(searchKey)}`, 'i');
|
||||
return regx.test(item.name) || regx.test(item.intro || '');
|
||||
}
|
||||
return item.parentId === formatParentId;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
||||
|
35
projects/app/src/pages/api/core/app/plugin/path.ts
Normal file
35
projects/app/src/pages/api/core/app/plugin/path.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { ParentIdType, ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
||||
import { getSystemPluginTemplates } from '@fastgpt/plugins/register';
|
||||
|
||||
export type pathQuery = {
|
||||
parentId: ParentIdType;
|
||||
};
|
||||
|
||||
export type pathBody = {};
|
||||
|
||||
export type pathResponse = Promise<ParentTreePathItemType[]>;
|
||||
|
||||
async function handler(
|
||||
req: ApiRequestProps<pathBody, pathQuery>,
|
||||
res: ApiResponseType<any>
|
||||
): Promise<pathResponse> {
|
||||
const { parentId } = req.query;
|
||||
|
||||
if (!parentId) return [];
|
||||
|
||||
const plugins = await getSystemPluginTemplates();
|
||||
const plugin = plugins.find((item) => item.id === parentId);
|
||||
|
||||
if (!plugin) return [];
|
||||
|
||||
return [
|
||||
{
|
||||
parentId: plugin.id,
|
||||
parentName: plugin.name
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
@@ -30,7 +30,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
});
|
||||
|
||||
const response = await ai.chat.completions.create({
|
||||
model: 'gpt-3.5-turbo',
|
||||
model: 'gpt-4o-mini',
|
||||
max_tokens: 1,
|
||||
messages: [{ role: 'user', content: 'hi' }]
|
||||
});
|
||||
|
@@ -16,7 +16,7 @@ import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
|
||||
import { compressImgFileAndUpload } from '@/web/common/file/controller';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
|
||||
|
@@ -13,7 +13,7 @@ import {
|
||||
import { useRouter } from 'next/router';
|
||||
import { AppSchema } from '@fastgpt/global/core/app/type.d';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import TagsEditModal from '../TagsEditModal';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
|
@@ -18,7 +18,7 @@ import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import VariableEdit from '@/components/core/app/VariableEdit';
|
||||
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
|
||||
@@ -242,8 +242,15 @@ const EditForm = ({
|
||||
})
|
||||
}
|
||||
>
|
||||
<Avatar src={item.avatar} w={'18px'} mr={1} />
|
||||
<Box flex={'1 0 0'} w={0} className={'textEllipsis'} fontSize={'sm'}>
|
||||
<Avatar src={item.avatar} w={'1.5rem'} borderRadius={'sm'} />
|
||||
<Box
|
||||
ml={2}
|
||||
flex={'1 0 0'}
|
||||
w={0}
|
||||
className={'textEllipsis'}
|
||||
fontSize={'sm'}
|
||||
color={'myGray.900'}
|
||||
>
|
||||
{item.name}
|
||||
</Box>
|
||||
</Flex>
|
||||
@@ -292,8 +299,15 @@ const EditForm = ({
|
||||
borderColor: 'primary.300'
|
||||
}}
|
||||
>
|
||||
<Avatar src={item.avatar} w={'1rem'} mr={1} />
|
||||
<Box flex={'1 0 0'} w={0} className={'textEllipsis'} fontSize={'sm'}>
|
||||
<Avatar src={item.avatar} w={'1.5rem'} borderRadius={'sm'} />
|
||||
<Box
|
||||
ml={2}
|
||||
flex={'1 0 0'}
|
||||
w={0}
|
||||
className={'textEllipsis'}
|
||||
fontSize={'sm'}
|
||||
color={'myGray.900'}
|
||||
>
|
||||
{item.name}
|
||||
</Box>
|
||||
<DeleteIcon
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@@ -26,21 +26,27 @@ import {
|
||||
FlowNodeTemplateType,
|
||||
NodeTemplateListItemType
|
||||
} from '@fastgpt/global/core/workflow/type/node.d';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { AddIcon } from '@chakra-ui/icons';
|
||||
import { getPreviewPluginNode, getSystemPlugTemplates } from '@/web/core/app/api/plugin';
|
||||
import {
|
||||
getPreviewPluginNode,
|
||||
getSystemPlugTemplates,
|
||||
getSystemPluginPaths
|
||||
} from '@/web/core/app/api/plugin';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import JsonEditor from '@fastgpt/web/components/common/Textarea/JsonEditor';
|
||||
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import { getTeamPlugTemplates } from '@/web/core/app/api/plugin';
|
||||
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||
import { getAppFolderPath } from '@/web/core/app/api/app';
|
||||
import FolderPath from '@/components/common/folder/Path';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import CoseTooltip from '@/components/core/app/plugin/CoseTooltip';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
|
||||
type Props = {
|
||||
selectedTools: FlowNodeTemplateType[];
|
||||
@@ -63,9 +69,7 @@ const ToolSelectModal = ({ onClose, ...props }: Props & { onClose: () => void })
|
||||
const { data: templates = [], loading: isLoading } = useRequest2(
|
||||
async () => {
|
||||
if (templateType === TemplateTypeEnum.systemPlugin) {
|
||||
return (await getSystemPlugTemplates()).filter(
|
||||
(item) => item.isTool && item.name.toLowerCase().includes(searchKey.toLowerCase())
|
||||
);
|
||||
return getSystemPlugTemplates({ parentId, searchKey });
|
||||
} else if (templateType === TemplateTypeEnum.teamPlugin) {
|
||||
return getTeamPlugTemplates({
|
||||
parentId,
|
||||
@@ -82,10 +86,20 @@ const ToolSelectModal = ({ onClose, ...props }: Props & { onClose: () => void })
|
||||
}
|
||||
);
|
||||
|
||||
const { data: paths = [] } = useRequest2(() => getAppFolderPath(parentId), {
|
||||
manual: false,
|
||||
refreshDeps: [parentId]
|
||||
});
|
||||
const { data: paths = [] } = useRequest2(
|
||||
() => {
|
||||
if (templateType === TemplateTypeEnum.teamPlugin) return getAppFolderPath(parentId);
|
||||
return getSystemPluginPaths(parentId);
|
||||
},
|
||||
{
|
||||
manual: false,
|
||||
refreshDeps: [parentId]
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setParentId('');
|
||||
}, [templateType, searchKey]);
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
@@ -129,7 +143,7 @@ const ToolSelectModal = ({ onClose, ...props }: Props & { onClose: () => void })
|
||||
</InputGroup>
|
||||
</Box>
|
||||
{/* route components */}
|
||||
{templateType === TemplateTypeEnum.teamPlugin && !searchKey && parentId && (
|
||||
{!searchKey && parentId && (
|
||||
<Flex mt={2} px={[3, 6]}>
|
||||
<FolderPath
|
||||
paths={paths}
|
||||
@@ -145,6 +159,7 @@ const ToolSelectModal = ({ onClose, ...props }: Props & { onClose: () => void })
|
||||
templates={templates}
|
||||
isLoadingData={isLoading}
|
||||
setParentId={setParentId}
|
||||
showCost={templateType === TemplateTypeEnum.systemPlugin}
|
||||
{...props}
|
||||
/>
|
||||
</MyBox>
|
||||
@@ -160,13 +175,16 @@ const RenderList = React.memo(function RenderList({
|
||||
isLoadingData,
|
||||
onAddTool,
|
||||
onRemoveTool,
|
||||
setParentId
|
||||
setParentId,
|
||||
showCost
|
||||
}: Props & {
|
||||
templates: NodeTemplateListItemType[];
|
||||
isLoadingData: boolean;
|
||||
setParentId: React.Dispatch<React.SetStateAction<ParentIdType>>;
|
||||
showCost?: boolean;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const { feConfigs } = useSystemStore();
|
||||
const [configTool, setConfigTool] = useState<FlowNodeTemplateType>();
|
||||
const onCloseConfigTool = useCallback(() => setConfigTool(undefined), []);
|
||||
|
||||
@@ -195,57 +213,78 @@ const RenderList = React.memo(function RenderList({
|
||||
const selected = selectedTools.some((tool) => tool.pluginId === item.id);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
<MyTooltip
|
||||
key={item.id}
|
||||
alignItems={'center'}
|
||||
p={[4, 5]}
|
||||
_notLast={{
|
||||
borderBottomWidth: '1px',
|
||||
borderBottomColor: 'myGray.150'
|
||||
}}
|
||||
_hover={{
|
||||
bg: 'myGray.50'
|
||||
}}
|
||||
placement={'bottom'}
|
||||
shouldWrapChildren={false}
|
||||
label={
|
||||
<Box>
|
||||
<Flex alignItems={'center'}>
|
||||
<Avatar
|
||||
src={item.avatar}
|
||||
w={'1.75rem'}
|
||||
objectFit={'contain'}
|
||||
borderRadius={'sm'}
|
||||
/>
|
||||
<Box fontWeight={'bold'} ml={2} color={'myGray.900'}>
|
||||
{t(item.name as any)}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box mt={2} color={'myGray.500'}>
|
||||
{t(item.intro as any) || t('common:core.workflow.Not intro')}
|
||||
</Box>
|
||||
{showCost && <CoseTooltip cost={item.currentCost} />}
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
<Avatar
|
||||
src={item.avatar}
|
||||
w={['26px', '32px']}
|
||||
objectFit={'contain'}
|
||||
borderRadius={'0'}
|
||||
/>
|
||||
<Box ml={5} flex={'1 0 0'}>
|
||||
<Box color={'black'}>{t(item.name as any)}</Box>
|
||||
{item.intro && (
|
||||
<Box className="textEllipsis3" color={'myGray.500'} fontSize={'xs'}>
|
||||
{t(item.intro as any)}
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
position={'relative'}
|
||||
p={[4, 5]}
|
||||
_notLast={{
|
||||
borderBottomWidth: '1px',
|
||||
borderBottomColor: 'myGray.150'
|
||||
}}
|
||||
_hover={{
|
||||
bg: 'myGray.50'
|
||||
}}
|
||||
>
|
||||
<Avatar src={item.avatar} w={'2rem'} objectFit={'contain'} borderRadius={'md'} />
|
||||
|
||||
<Box ml={3} flex={'1 0 0'} color={'myGray.900'}>
|
||||
{t(item.name as any)}
|
||||
</Box>
|
||||
{item.author !== undefined && (
|
||||
<Box fontSize={'xs'} mr={3}>
|
||||
{`by ${item.author || feConfigs.systemTitle}`}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
{selected ? (
|
||||
<Button
|
||||
size={'sm'}
|
||||
variant={'grayDanger'}
|
||||
leftIcon={<MyIcon name={'delete'} w={'14px'} />}
|
||||
onClick={() => onRemoveTool(item)}
|
||||
>
|
||||
{t('common:common.Remove')}
|
||||
</Button>
|
||||
) : item.isFolder ? (
|
||||
<Button size={'sm'} variant={'whiteBase'} onClick={() => setParentId(item.id)}>
|
||||
{t('common:common.Open')}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
size={'sm'}
|
||||
variant={'whiteBase'}
|
||||
leftIcon={<AddIcon fontSize={'10px'} />}
|
||||
isLoading={isLoading}
|
||||
onClick={() => onClickAdd(item)}
|
||||
>
|
||||
{t('common:common.Add')}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
{selected ? (
|
||||
<Button
|
||||
size={'sm'}
|
||||
variant={'grayDanger'}
|
||||
leftIcon={<MyIcon name={'delete'} w={'14px'} />}
|
||||
onClick={() => onRemoveTool(item)}
|
||||
>
|
||||
{t('common:common.Remove')}
|
||||
</Button>
|
||||
) : item.isFolder ? (
|
||||
<Button size={'sm'} variant={'whiteBase'} onClick={() => setParentId(item.id)}>
|
||||
{t('common:common.Open')}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
size={'sm'}
|
||||
variant={'whiteBase'}
|
||||
leftIcon={<AddIcon fontSize={'10px'} />}
|
||||
isLoading={isLoading}
|
||||
onClick={() => onClickAdd(item)}
|
||||
>
|
||||
{t('common:common.Add')}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
</MyTooltip>
|
||||
);
|
||||
})}
|
||||
{!!configTool && (
|
||||
|
@@ -10,7 +10,6 @@ import { WorkflowContext, getWorkflowStore } from '../WorkflowComponents/context
|
||||
import { useInterval } from 'ahooks';
|
||||
import { AppContext, TabEnum } from '../context';
|
||||
import RouteTab from '../RouteTab';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
|
@@ -4,7 +4,7 @@ import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext, TabEnum } from '../context';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
@@ -159,7 +159,7 @@ const AppCard = ({ showSaveStatus }: { showSaveStatus: boolean }) => {
|
||||
return (
|
||||
<HStack>
|
||||
<InfoMenu>
|
||||
<Avatar src={appDetail.avatar} w={'1.75rem'} />
|
||||
<Avatar src={appDetail.avatar} w={'1.75rem'} borderRadius={'md'} />
|
||||
</InfoMenu>
|
||||
<Box>
|
||||
<InfoMenu>
|
||||
|
@@ -1,17 +1,30 @@
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { Box, Flex, IconButton, Input, InputGroup, InputLeftElement, css } from '@chakra-ui/react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Divider,
|
||||
Flex,
|
||||
IconButton,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
css
|
||||
} from '@chakra-ui/react';
|
||||
import type {
|
||||
NodeTemplateListItemType,
|
||||
NodeTemplateListType
|
||||
} from '@fastgpt/global/core/workflow/type/node.d';
|
||||
import { useViewport, XYPosition } from 'reactflow';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import { nodeTemplate2FlowNode } from '@/web/core/workflow/utils';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { getPreviewPluginNode, getSystemPlugTemplates } from '@/web/core/app/api/plugin';
|
||||
import {
|
||||
getPreviewPluginNode,
|
||||
getSystemPlugTemplates,
|
||||
getSystemPluginPaths
|
||||
} from '@/web/core/app/api/plugin';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { workflowNodeTemplateList } from '@fastgpt/web/core/workflow/constants';
|
||||
@@ -33,6 +46,7 @@ import { useWorkflowUtils } from './hooks/useUtils';
|
||||
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import CoseTooltip from '@/components/core/app/plugin/CoseTooltip';
|
||||
|
||||
type ModuleTemplateListProps = {
|
||||
isOpen: boolean;
|
||||
@@ -40,6 +54,7 @@ type ModuleTemplateListProps = {
|
||||
};
|
||||
type RenderListProps = {
|
||||
templates: NodeTemplateListItemType[];
|
||||
type: TemplateTypeEnum;
|
||||
onClose: () => void;
|
||||
parentId: ParentIdType;
|
||||
setParentId: React.Dispatch<React.SetStateAction<ParentIdType>>;
|
||||
@@ -51,7 +66,7 @@ enum TemplateTypeEnum {
|
||||
'teamPlugin' = 'teamPlugin'
|
||||
}
|
||||
|
||||
const sliderWidth = 390;
|
||||
const sliderWidth = 420;
|
||||
|
||||
const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -104,7 +119,7 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||
refreshDeps: [basicNodeTemplates, nodeList, hasToolNode, templateType, searchKey, parentId]
|
||||
}
|
||||
);
|
||||
const { data: teamApps, loading: isLoadingTeamApp } = useRequest2(
|
||||
const { data: teamAndSystemApps, loading: isLoadingTeamApp } = useRequest2(
|
||||
async () => {
|
||||
if (templateType === TemplateTypeEnum.teamPlugin) {
|
||||
return getTeamPlugTemplates({
|
||||
@@ -113,6 +128,12 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||
type: [AppTypeEnum.folder, AppTypeEnum.httpPlugin, AppTypeEnum.plugin]
|
||||
}).then((res) => res.filter((app) => app.id !== appId));
|
||||
}
|
||||
if (templateType === TemplateTypeEnum.systemPlugin) {
|
||||
return getSystemPlugTemplates({
|
||||
searchKey,
|
||||
parentId
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
manual: false,
|
||||
@@ -120,29 +141,28 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||
refreshDeps: [templateType, searchKey, parentId]
|
||||
}
|
||||
);
|
||||
const { data: systemPlugins, loading: isLoadingSystemPlugins } = useRequest2(
|
||||
async () => {
|
||||
if (templateType === TemplateTypeEnum.systemPlugin) {
|
||||
return getSystemPlugTemplates();
|
||||
}
|
||||
|
||||
const isLoading = isLoadingTeamApp;
|
||||
const templates = useMemo(
|
||||
() => basicNodes || teamAndSystemApps || [],
|
||||
[basicNodes, teamAndSystemApps]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setParentId('');
|
||||
}, [templateType, searchKey]);
|
||||
|
||||
const { data: paths = [] } = useRequest2(
|
||||
() => {
|
||||
if (templateType === TemplateTypeEnum.teamPlugin) return getAppFolderPath(parentId);
|
||||
return getSystemPluginPaths(parentId);
|
||||
},
|
||||
{
|
||||
manual: false,
|
||||
refreshDeps: [templateType]
|
||||
refreshDeps: [parentId]
|
||||
}
|
||||
);
|
||||
|
||||
const isLoading = isLoadingTeamApp || isLoadingSystemPlugins;
|
||||
const templates = useMemo(
|
||||
() => basicNodes || teamApps || systemPlugins || [],
|
||||
[basicNodes, systemPlugins, teamApps]
|
||||
);
|
||||
|
||||
const { data: paths = [] } = useRequest2(() => getAppFolderPath(parentId), {
|
||||
manual: false,
|
||||
refreshDeps: [parentId]
|
||||
});
|
||||
|
||||
const Render = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
@@ -154,6 +174,7 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||
left={0}
|
||||
bottom={0}
|
||||
w={`${sliderWidth}px`}
|
||||
maxW={'100%'}
|
||||
onClick={onClose}
|
||||
fontSize={'sm'}
|
||||
/>
|
||||
@@ -176,30 +197,35 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||
userSelect={'none'}
|
||||
overflow={isOpen ? 'none' : 'hidden'}
|
||||
>
|
||||
{/* Header */}
|
||||
<Box pl={'20px'} mb={3} pr={'10px'} whiteSpace={'nowrap'} overflow={'hidden'}>
|
||||
{/* Tabs */}
|
||||
<Flex flex={'1 0 0'} alignItems={'center'} gap={3}>
|
||||
<FillRowTabs
|
||||
list={[
|
||||
{
|
||||
icon: 'core/modules/basicNode',
|
||||
label: t('common:core.module.template.Basic Node'),
|
||||
value: TemplateTypeEnum.basic
|
||||
},
|
||||
{
|
||||
icon: 'core/modules/systemPlugin',
|
||||
label: t('common:core.module.template.System Plugin'),
|
||||
value: TemplateTypeEnum.systemPlugin
|
||||
},
|
||||
{
|
||||
icon: 'core/modules/teamPlugin',
|
||||
label: t('common:core.module.template.Team Plugin'),
|
||||
value: TemplateTypeEnum.teamPlugin
|
||||
}
|
||||
]}
|
||||
py={'5px'}
|
||||
value={templateType}
|
||||
onChange={(e) => setTemplateType(e as TemplateTypeEnum)}
|
||||
/>
|
||||
<Box flex={'1 0 0'}>
|
||||
<FillRowTabs
|
||||
list={[
|
||||
{
|
||||
icon: 'core/modules/basicNode',
|
||||
label: t('core.module.template.Basic Node'),
|
||||
value: TemplateTypeEnum.basic
|
||||
},
|
||||
{
|
||||
icon: 'core/modules/systemPlugin',
|
||||
label: t('core.module.template.System Plugin'),
|
||||
value: TemplateTypeEnum.systemPlugin
|
||||
},
|
||||
{
|
||||
icon: 'core/modules/teamPlugin',
|
||||
label: t('core.module.template.Team Plugin'),
|
||||
value: TemplateTypeEnum.teamPlugin
|
||||
}
|
||||
]}
|
||||
width={'100%'}
|
||||
py={'5px'}
|
||||
value={templateType}
|
||||
onChange={(e) => setTemplateType(e as TemplateTypeEnum)}
|
||||
/>
|
||||
</Box>
|
||||
{/* close icon */}
|
||||
<IconButton
|
||||
size={'sm'}
|
||||
@@ -210,7 +236,9 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||
onClick={onClose}
|
||||
/>
|
||||
</Flex>
|
||||
{templateType === TemplateTypeEnum.teamPlugin && (
|
||||
{/* Search */}
|
||||
{(templateType === TemplateTypeEnum.teamPlugin ||
|
||||
templateType === TemplateTypeEnum.systemPlugin) && (
|
||||
<Flex mt={2} alignItems={'center'} h={10}>
|
||||
<InputGroup mr={4} h={'full'}>
|
||||
<InputLeftElement h={'full'} alignItems={'center'} display={'flex'}>
|
||||
@@ -224,28 +252,52 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||
/>
|
||||
</InputGroup>
|
||||
<Box flex={1} />
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
cursor={'pointer'}
|
||||
_hover={{
|
||||
color: 'primary.600'
|
||||
}}
|
||||
fontSize={'sm'}
|
||||
onClick={() => router.push('/app/list')}
|
||||
>
|
||||
<Box>去创建</Box>
|
||||
<MyIcon name={'common/rightArrowLight'} w={'14px'} />
|
||||
{templateType === TemplateTypeEnum.teamPlugin && (
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
cursor={'pointer'}
|
||||
_hover={{
|
||||
color: 'primary.600'
|
||||
}}
|
||||
fontSize={'sm'}
|
||||
onClick={() => router.push('/app/list')}
|
||||
gap={1}
|
||||
>
|
||||
<Box>去创建</Box>
|
||||
<MyIcon name={'common/rightArrowLight'} w={'0.8rem'} />
|
||||
</Flex>
|
||||
)}
|
||||
{templateType === TemplateTypeEnum.systemPlugin &&
|
||||
feConfigs.systemPluginCourseUrl && (
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
cursor={'pointer'}
|
||||
_hover={{
|
||||
color: 'primary.600'
|
||||
}}
|
||||
fontSize={'sm'}
|
||||
onClick={() => window.open(feConfigs.systemPluginCourseUrl)}
|
||||
gap={1}
|
||||
>
|
||||
<Box>贡献插件</Box>
|
||||
<MyIcon name={'common/rightArrowLight'} w={'0.8rem'} />
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
)}
|
||||
{/* paths */}
|
||||
{(templateType === TemplateTypeEnum.teamPlugin ||
|
||||
templateType === TemplateTypeEnum.systemPlugin) &&
|
||||
!searchKey &&
|
||||
parentId && (
|
||||
<Flex alignItems={'center'} mt={2}>
|
||||
<FolderPath paths={paths} FirstPathDom={null} onClick={setParentId} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
)}
|
||||
{templateType === TemplateTypeEnum.teamPlugin && !searchKey && parentId && (
|
||||
<Flex alignItems={'center'} mt={2}>
|
||||
<FolderPath paths={paths} FirstPathDom={null} onClick={setParentId} />
|
||||
</Flex>
|
||||
)}
|
||||
)}
|
||||
</Box>
|
||||
<RenderList
|
||||
templates={templates}
|
||||
type={templateType}
|
||||
onClose={onClose}
|
||||
parentId={parentId}
|
||||
setParentId={setParentId}
|
||||
@@ -262,14 +314,18 @@ export default React.memo(NodeTemplatesModal);
|
||||
|
||||
const RenderList = React.memo(function RenderList({
|
||||
templates,
|
||||
type,
|
||||
onClose,
|
||||
parentId,
|
||||
setParentId
|
||||
}: RenderListProps) {
|
||||
const { t } = useTranslation();
|
||||
const { appT } = useI18n();
|
||||
const { feConfigs } = useSystemStore();
|
||||
|
||||
const { isPc } = useSystem();
|
||||
const isSystemPlugin = type === TemplateTypeEnum.systemPlugin;
|
||||
|
||||
const { x, y, zoom } = useViewport();
|
||||
const { setLoading } = useSystemStore();
|
||||
const { toast } = useToast();
|
||||
@@ -337,7 +393,7 @@ const RenderList = React.memo(function RenderList({
|
||||
flowNodeType: templateNode.flowNodeType,
|
||||
pluginId: templateNode.pluginId
|
||||
}),
|
||||
intro: t(templateNode.intro || ('' as any))
|
||||
intro: t(templateNode.intro as any)
|
||||
},
|
||||
position: { x: mouseX, y: mouseY - 20 },
|
||||
selected: true
|
||||
@@ -371,9 +427,9 @@ const RenderList = React.memo(function RenderList({
|
||||
}
|
||||
})}
|
||||
>
|
||||
{item.label && (
|
||||
{item.label && formatTemplates.length > 1 && (
|
||||
<Flex>
|
||||
<Box fontSize={'sm'} fontWeight={'bold'} flex={1}>
|
||||
<Box fontSize={'sm'} fontWeight={'500'} flex={1} color={'myGray.900'}>
|
||||
{t(item.label as any)}
|
||||
</Box>
|
||||
</Flex>
|
||||
@@ -385,27 +441,29 @@ const RenderList = React.memo(function RenderList({
|
||||
key={template.id}
|
||||
placement={'right'}
|
||||
label={
|
||||
<Box>
|
||||
<Box py={2}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Avatar
|
||||
src={template.avatar}
|
||||
w={'24px'}
|
||||
w={'1.75rem'}
|
||||
objectFit={'contain'}
|
||||
borderRadius={'0'}
|
||||
borderRadius={'sm'}
|
||||
/>
|
||||
<Box fontWeight={'bold'} ml={3}>
|
||||
<Box fontWeight={'bold'} ml={3} color={'myGray.900'}>
|
||||
{t(template.name as any)}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box mt={2} color={'myGray.500'}>
|
||||
{t(template.intro as any) || t('common:core.workflow.Not intro')}
|
||||
</Box>
|
||||
{isSystemPlugin && <CoseTooltip cost={template.currentCost} />}
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
p={5}
|
||||
py={4}
|
||||
px={3}
|
||||
cursor={'pointer'}
|
||||
_hover={{ bg: 'myWhite.600' }}
|
||||
borderRadius={'sm'}
|
||||
@@ -436,13 +494,24 @@ const RenderList = React.memo(function RenderList({
|
||||
>
|
||||
<Avatar
|
||||
src={template.avatar}
|
||||
w={'1.7rem'}
|
||||
w={'2rem'}
|
||||
objectFit={'contain'}
|
||||
borderRadius={'0'}
|
||||
borderRadius={'md'}
|
||||
/>
|
||||
<Box color={'black'} fontSize={'sm'} ml={5} flex={'1 0 0'}>
|
||||
<Box
|
||||
color={'myGray.900'}
|
||||
fontWeight={'500'}
|
||||
fontSize={'sm'}
|
||||
ml={3}
|
||||
flex={'1 0 0'}
|
||||
>
|
||||
{t(template.name as any)}
|
||||
</Box>
|
||||
{template.author !== undefined && (
|
||||
<Box fontSize={'xs'} color={'myGray.500'}>
|
||||
{`by ${template.author || feConfigs.systemTitle}`}
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
</MyTooltip>
|
||||
))}
|
||||
@@ -452,7 +521,17 @@ const RenderList = React.memo(function RenderList({
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}, [appT, formatTemplates, isPc, onAddNode, onClose, setParentId, t, templates.length]);
|
||||
}, [
|
||||
appT,
|
||||
formatTemplates,
|
||||
isPc,
|
||||
isSystemPlugin,
|
||||
onAddNode,
|
||||
onClose,
|
||||
setParentId,
|
||||
t,
|
||||
templates.length
|
||||
]);
|
||||
|
||||
return Render;
|
||||
});
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Box, Button, Card, Flex } from '@chakra-ui/react';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import type { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/node.d';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
|
||||
@@ -137,7 +137,7 @@ const NodeCard = (props: Props) => {
|
||||
|
||||
{/* avatar and name */}
|
||||
<Flex alignItems={'center'}>
|
||||
<Avatar src={avatar} borderRadius={'0'} objectFit={'contain'} w={'30px'} h={'30px'} />
|
||||
<Avatar src={avatar} borderRadius={'sm'} objectFit={'contain'} w={'30px'} h={'30px'} />
|
||||
<Box ml={3} fontSize={'md'} fontWeight={'medium'}>
|
||||
{t(name as any)}
|
||||
</Box>
|
||||
|
@@ -19,7 +19,7 @@ import { AppContext } from '@/pages/app/detail/components/context';
|
||||
const MultipleRowSelect = dynamic(
|
||||
() => import('@fastgpt/web/components/common/MySelect/MultipleRowSelect')
|
||||
);
|
||||
const Avatar = dynamic(() => import('@/components/Avatar'));
|
||||
const Avatar = dynamic(() => import('@fastgpt/web/components/common/Avatar'));
|
||||
|
||||
type SelectProps = {
|
||||
value?: ReferenceValueProps;
|
||||
@@ -120,8 +120,8 @@ export const useReference = ({
|
||||
return {
|
||||
label: (
|
||||
<Flex alignItems={'center'}>
|
||||
<Avatar mr={1} src={node.avatar} w={'14px'} borderRadius={'ms'} />
|
||||
<Box>{t(node.name as any)}</Box>
|
||||
<Avatar src={node.avatar} w={'1.25rem'} borderRadius={'xs'} />
|
||||
<Box ml={1}>{t(node.name as any)}</Box>
|
||||
</Flex>
|
||||
),
|
||||
value: node.nodeId,
|
||||
|
@@ -2,7 +2,7 @@ import React, { useMemo } from 'react';
|
||||
import type { RenderInputProps } from '../type';
|
||||
import { Box, Button, useDisclosure } from '@chakra-ui/react';
|
||||
import { SelectAppItemType } from '@fastgpt/global/core/workflow/template/system/runApp/type';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import SelectAppModal from '../../../../SelectAppModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
|
@@ -3,7 +3,7 @@ import type { RenderInputProps } from '../type';
|
||||
import { Box, Button, Flex, Grid, useDisclosure, useTheme } from '@chakra-ui/react';
|
||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
||||
import { SelectedDatasetType } from '@fastgpt/global/core/workflow/api';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
|
@@ -18,9 +18,8 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { postCreateApp } from '@/web/core/app/api';
|
||||
import { useRouter } from 'next/router';
|
||||
import { simpleBotTemplates, workflowTemplates, pluginTemplates } from '@/web/core/app/templates';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@@ -150,7 +149,7 @@ const CreateModal = ({ onClose, type }: { type: CreateAppType; onClose: () => vo
|
||||
w={['28px', '32px']}
|
||||
h={['28px', '32px']}
|
||||
cursor={'pointer'}
|
||||
borderRadius={'sm'}
|
||||
borderRadius={'md'}
|
||||
onClick={onOpenSelectFile}
|
||||
/>
|
||||
</MyTooltip>
|
||||
@@ -195,7 +194,7 @@ const CreateModal = ({ onClose, type }: { type: CreateAppType; onClose: () => vo
|
||||
}}
|
||||
>
|
||||
<Flex alignItems={'center'}>
|
||||
<Avatar src={item.avatar} borderRadius={'md'} w={'20px'} />
|
||||
<Avatar src={item.avatar} borderRadius={'md'} w={'1.5rem'} />
|
||||
<Box ml={3} color={'myGray.900'}>
|
||||
{t(item.name as any)}
|
||||
</Box>
|
||||
|
@@ -21,7 +21,7 @@ import { compressImgFileAndUpload } from '@/web/common/file/controller';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { HttpPluginImgUrl, MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
|
||||
|
@@ -4,7 +4,7 @@ import { useRouter } from 'next/router';
|
||||
import { delAppById, putAppById, resumeInheritPer } from '@/web/core/app/api';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import PermissionIconText from '@/components/support/permission/IconText';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||
|
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Flex, useTheme, Box } from '@chakra-ui/react';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import ToolMenu from './ToolMenu';
|
||||
import type { ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
@@ -3,7 +3,7 @@ import { Box, Button, Flex, useTheme, IconButton } from '@chakra-ui/react';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
|
||||
import { useRouter } from 'next/router';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@@ -145,7 +145,7 @@ const ChatHistorySlider = ({
|
||||
})
|
||||
}
|
||||
>
|
||||
<Avatar src={appAvatar} />
|
||||
<Avatar src={appAvatar} borderRadius={'md'} />
|
||||
<Box flex={'1 0 0'} w={0} ml={2} fontWeight={'bold'} className={'textEllipsis'}>
|
||||
{appName}
|
||||
</Box>
|
||||
|
@@ -4,7 +4,7 @@ import { useMarkdown } from '@/web/common/hooks/useMarkdown';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
const Markdown = dynamic(() => import('@/components/Markdown'));
|
||||
const Avatar = dynamic(() => import('@/components/Avatar'));
|
||||
const Avatar = dynamic(() => import('@fastgpt/web/components/common/Avatar'));
|
||||
|
||||
const Empty = ({
|
||||
showChatProblem,
|
||||
|
@@ -3,7 +3,7 @@ import { Flex, Box, IconButton, HStack } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import { AppListItemType } from '@fastgpt/global/core/app/type';
|
||||
import MyDivider from '@fastgpt/web/components/common/MyDivider';
|
||||
import MyPopover from '@fastgpt/web/components/common/MyPopover/index';
|
||||
@@ -152,7 +152,7 @@ const SliderApps = ({ apps, activeAppId }: { apps: AppListItemType[]; activeAppI
|
||||
onClick: () => onChangeApp(item._id)
|
||||
})}
|
||||
>
|
||||
<Avatar src={item.avatar} w={'24px'} />
|
||||
<Avatar src={item.avatar} w={'1.5rem'} borderRadius={'md'} />
|
||||
<Box ml={2} className={'textEllipsis'}>
|
||||
{item.name}
|
||||
</Box>
|
||||
|
@@ -8,7 +8,7 @@ import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { compressImgFileAndUpload } from '@/web/common/file/controller';
|
||||
import type { DatasetItemType } from '@fastgpt/global/core/dataset/type.d';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
|
@@ -2,7 +2,7 @@ import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Box, Flex, IconButton, useTheme, Progress } from '@chakra-ui/react';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import { DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import DatasetTypeTag from '@/components/core/dataset/DatasetTypeTag';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
|
@@ -8,7 +8,7 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { postCreateDataset } from '@/web/core/dataset/api';
|
||||
|
@@ -8,7 +8,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useRouter } from 'next/router';
|
||||
import PermissionIconText from '@/components/support/permission/IconText';
|
||||
import DatasetTypeTag from '@/components/core/dataset/DatasetTypeTag';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import { DatasetItemType } from '@fastgpt/global/core/dataset/type';
|
||||
|
@@ -10,7 +10,7 @@ import {
|
||||
useTheme,
|
||||
Grid
|
||||
} from '@chakra-ui/react';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
|
Reference in New Issue
Block a user