'use client'; import React, { useMemo, useState } from 'react'; import { Box, Flex, Button, useDisclosure, Input, InputGroup } from '@chakra-ui/react'; import { AddIcon } from '@chakra-ui/icons'; import { serviceSideProps } from '@/web/common/i18n/utils'; import { useUserStore } from '@/web/support/user/useUserStore'; import { useTranslation } from 'next-i18next'; import dynamic from 'next/dynamic'; import MyMenu from '@fastgpt/web/components/common/MyMenu'; import { FolderIcon } from '@fastgpt/global/common/file/image/constants'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { postCreateAppFolder } from '@/web/core/app/api/app'; import type { EditFolderFormType } from '@fastgpt/web/components/common/MyModal/EditFolderModal'; import { useContextSelector } from 'use-context-selector'; import AppListContextProvider, { AppListContext } from '@/pageComponents/dashboard/apps/context'; import FolderPath from '@/components/common/folder/Path'; import { useRouter } from 'next/router'; import FolderSlideCard from '@/components/common/folder/SlideCard'; import { delAppById, resumeInheritPer } from '@/web/core/app/api'; import { AppPermissionList } from '@fastgpt/global/support/permission/app/constant'; import { deleteAppCollaborators, getCollaboratorList, postUpdateAppCollaborators } from '@/web/core/app/api/collaborator'; import type { CreateAppType } from '@/pageComponents/dashboard/apps/CreateModal'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; import MyBox from '@fastgpt/web/components/common/MyBox'; import { useSystem } from '@fastgpt/web/hooks/useSystem'; import MyIcon from '@fastgpt/web/components/common/Icon'; import JsonImportModal from '@/pageComponents/dashboard/apps/JsonImportModal'; import DashboardContainer from '@/pageComponents/dashboard/Container'; import List from '@/pageComponents/dashboard/apps/List'; import MCPToolsEditModal from '@/pageComponents/dashboard/apps/MCPToolsEditModal'; import { getUtmWorkflow } from '@/web/support/marketing/utils'; import { useMount } from 'ahooks'; const CreateModal = dynamic(() => import('@/pageComponents/dashboard/apps/CreateModal')); const EditFolderModal = dynamic( () => import('@fastgpt/web/components/common/MyModal/EditFolderModal') ); const HttpEditModal = dynamic(() => import('@/pageComponents/dashboard/apps/HttpPluginEditModal')); const MyApps = ({ MenuIcon }: { MenuIcon: JSX.Element }) => { const { t } = useTranslation(); const router = useRouter(); const { isPc } = useSystem(); const { paths, parentId, myApps, appType, loadMyApps, onUpdateApp, setMoveAppId, isFetchingApps, folderDetail, refetchFolderDetail, searchKey, setSearchKey } = useContextSelector(AppListContext, (v) => v); const { userInfo } = useUserStore(); const [createAppType, setCreateAppType] = useState(); const { isOpen: isOpenCreateHttpPlugin, onOpen: onOpenCreateHttpPlugin, onClose: onCloseCreateHttpPlugin } = useDisclosure(); const { isOpen: isOpenCreateMCPTools, onOpen: onOpenCreateMCPTools, onClose: onCloseCreateMCPTools } = useDisclosure(); const [editFolder, setEditFolder] = useState(); const { isOpen: isOpenJsonImportModal, onOpen: onOpenJsonImportModal, onClose: onCloseJsonImportModal } = useDisclosure(); //if there is a workflow url in the session storage, open the json import modal and import the workflow useMount(() => { if (getUtmWorkflow()) { onOpenJsonImportModal(); } }); const { runAsync: onCreateFolder } = useRequest2(postCreateAppFolder, { onSuccess() { loadMyApps(); }, errorToast: 'Error' }); const { runAsync: onDeleFolder } = useRequest2(delAppById, { onSuccess() { router.replace({ query: { parentId: folderDetail?.parentId } }); }, errorToast: 'Error' }); const appTypeName = useMemo(() => { const map: Record = { all: t('common:core.module.template.Team app'), [AppTypeEnum.simple]: t('app:type.Simple bot'), [AppTypeEnum.workflow]: t('app:type.Workflow bot'), [AppTypeEnum.plugin]: t('app:type.Plugin'), [AppTypeEnum.httpPlugin]: t('app:type.Http plugin'), [AppTypeEnum.folder]: t('common:Folder'), [AppTypeEnum.toolSet]: t('app:type.MCP tools'), [AppTypeEnum.tool]: t('app:type.MCP tools') }; return map[appType] || map['all']; }, [appType, t]); const RenderSearchInput = useMemo( () => ( setSearchKey(e.target.value)} placeholder={t('app:search_app')} maxLength={30} pl={8} bg={'white'} /> ), [searchKey, setSearchKey, t] ); return ( {paths.length > 0 && ( { router.push({ query: { ...router.query, parentId } }); }} /> )} 0 ? 3 : [4, 6]} alignItems={'center'} gap={3}> {isPc ? ( {appTypeName} ) : ( MenuIcon )} {isPc && RenderSearchInput} {(folderDetail ? folderDetail.permission.hasWritePer && folderDetail?.type !== AppTypeEnum.httpPlugin : userInfo?.team.permission.hasAppCreatePer) && ( }> {t('common:new_create')} } menuList={[ { children: [ { icon: 'core/app/simpleBot', label: t('app:type.Simple bot'), description: t('app:type.Create simple bot tip'), onClick: () => setCreateAppType(AppTypeEnum.simple) }, { icon: 'core/app/type/workflowFill', label: t('app:type.Workflow bot'), description: t('app:type.Create workflow tip'), onClick: () => setCreateAppType(AppTypeEnum.workflow) }, { icon: 'core/app/type/pluginFill', label: t('app:type.Plugin'), description: t('app:type.Create one plugin tip'), onClick: () => setCreateAppType(AppTypeEnum.plugin) }, { icon: 'core/app/type/httpPluginFill', label: t('app:type.Http plugin'), description: t('app:type.Create http plugin tip'), onClick: onOpenCreateHttpPlugin }, { icon: 'core/app/type/mcpToolsFill', label: t('app:type.MCP tools'), description: t('app:type.Create mcp tools tip'), onClick: onOpenCreateMCPTools } ] }, { children: [ { icon: 'core/app/type/jsonImport', label: t('app:type.Import from json'), description: t('app:type.Import from json tip'), onClick: onOpenJsonImportModal } ] }, { children: [ { icon: FolderIcon, label: t('common:Folder'), onClick: () => setEditFolder({}) } ] } ]} /> )} {!isPc && {RenderSearchInput}} {/* Folder slider */} {!!folderDetail && isPc && ( Promise.all([refetchFolderDetail(), loadMyApps()])} resumeInheritPermission={() => resumeInheritPer(folderDetail._id)} isInheritPermission={folderDetail.inheritPermission} hasParent={!!folderDetail.parentId} refreshDeps={[folderDetail._id, folderDetail.inheritPermission]} name={folderDetail.name} intro={folderDetail.intro} onEdit={() => { setEditFolder({ id: folderDetail._id, name: folderDetail.name, intro: folderDetail.intro }); }} onMove={() => setMoveAppId(folderDetail._id)} deleteTip={t('app:confirm_delete_folder_tip')} onDelete={() => onDeleFolder(folderDetail._id)} managePer={{ permission: folderDetail.permission, onGetCollaboratorList: () => getCollaboratorList(folderDetail._id), permissionList: AppPermissionList, onUpdateCollaborators: (props) => postUpdateAppCollaborators({ ...props, appId: folderDetail._id }), refreshDeps: [folderDetail._id, folderDetail.inheritPermission], onDelOneCollaborator: async (params) => deleteAppCollaborators({ ...params, appId: folderDetail._id }) }} /> )} {!!editFolder && ( setEditFolder(undefined)} onCreate={(data) => onCreateFolder({ ...data, parentId })} onEdit={({ id, ...data }) => onUpdateApp(id, data)} /> )} {!!createAppType && ( setCreateAppType(undefined)} /> )} {isOpenCreateHttpPlugin && } {isOpenCreateMCPTools && } {isOpenJsonImportModal && } ); }; function ContextRender() { return ( {({ MenuIcon }) => ( )} ); } export default ContextRender; export async function getServerSideProps(content: any) { return { props: { ...(await serviceSideProps(content, ['app', 'user'])) } }; }