diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx index d4df7e8bd3..86996969d2 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx @@ -88,10 +88,19 @@ const AppDetailLayout: FC = (props) => { useEffect(() => { setAppDetail() fetchAppDetail({ url: '/apps', id: appId }).then((res) => { - setAppDetail(res) - setNavigation(getNavigations(appId, isCurrentWorkspaceManager, res.mode)) + // redirections + if ((res.mode === 'workflow' || res.mode === 'advanced-chat') && (pathname).endsWith('configuration')) { + router.replace(`/app/${appId}/workflow`) + } + else if ((res.mode !== 'workflow' && res.mode !== 'advanced-chat') && (pathname).endsWith('workflow')) { + router.replace(`/app/${appId}/configuration`) + } + else { + setAppDetail(res) + setNavigation(getNavigations(appId, isCurrentWorkspaceManager, res.mode)) + } }) - }, [appId, getNavigations, isCurrentWorkspaceManager, setAppDetail]) + }, [appId, getNavigations, isCurrentWorkspaceManager, pathname, router, setAppDetail]) if (!appDetail) { return ( @@ -101,12 +110,6 @@ const AppDetailLayout: FC = (props) => { ) } - // redirections - if ((appDetail.mode === 'workflow' || appDetail.mode === 'advanced-chat') && (pathname).endsWith('configuration')) - router.replace(`/app/${appId}/workflow`) - if ((appDetail.mode !== 'workflow' && appDetail.mode !== 'advanced-chat') && (pathname).endsWith('workflow')) - router.replace(`/app/${appId}/configuration`) - return (
{appDetail && ( diff --git a/web/app/components/header/app-nav/index.tsx b/web/app/components/header/app-nav/index.tsx index a3682cc752..55c6575015 100644 --- a/web/app/components/header/app-nav/index.tsx +++ b/web/app/components/header/app-nav/index.tsx @@ -1,17 +1,20 @@ 'use client' -import { useCallback, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' -import { useParams, usePathname } from 'next/navigation' -import useSWR from 'swr' +import { useParams } from 'next/navigation' +// import useSWR from 'swr' import useSWRInfinite from 'swr/infinite' import { flatten } from 'lodash-es' +import produce from 'immer' import Nav from '../nav' +import { type NavItem } from '../nav/nav-selector' import { Robot, RobotActive } from '../../base/icons/src/public/header-nav/studio' -import { fetchAppDetail, fetchAppList } from '@/service/apps' +import { fetchAppList } from '@/service/apps' import CreateAppDialog from '@/app/components/app/create-app-dialog' import type { AppListResponse } from '@/models/app' import { useAppContext } from '@/context/app-context' +import { useStore as useAppStore } from '@/app/components/app/store' const getKey = (pageIndex: number, previousPageData: AppListResponse) => { if (!pageIndex || previousPageData.has_more) @@ -21,19 +24,58 @@ const getKey = (pageIndex: number, previousPageData: AppListResponse) => { const AppNav = () => { const { t } = useTranslation() - const { isCurrentWorkspaceManager } = useAppContext() - - const [showNewAppDialog, setShowNewAppDialog] = useState(false) const { appId } = useParams() - const isAppDetailPage = usePathname().split('/').includes('app') - const { data: currentApp } = useSWR((appId && isAppDetailPage) ? { url: '/apps', id: appId } : null, fetchAppDetail) + const { isCurrentWorkspaceManager } = useAppContext() + const { appDetail } = useAppStore() + const [showNewAppDialog, setShowNewAppDialog] = useState(false) + const [navItems, setNavItems] = useState([]) + const { data: appsData, setSize } = useSWRInfinite(appId ? getKey : () => null, fetchAppList, { revalidateFirstPage: false }) - const appItems = flatten(appsData?.map(appData => appData.data)) const handleLoadmore = useCallback(() => { setSize(size => size + 1) }, [setSize]) + useEffect(() => { + if (appsData) { + const appItems = flatten(appsData?.map(appData => appData.data)) + const navItems = appItems.map((app) => { + const link = ((isCurrentWorkspaceManager, app) => { + if (!isCurrentWorkspaceManager) { + return `/app/${app.id}/overview` + } + else { + if (app.mode === 'workflow' || app.mode === 'advanced-chat') + return `/app/${app.id}/workflow` + else + return `/app/${app.id}/configuration` + } + })(isCurrentWorkspaceManager, app) + return { + id: app.id, + icon: app.icon, + icon_background: app.icon_background, + name: app.name, + link, + } + }) + setNavItems(navItems) + } + }, [appsData, isCurrentWorkspaceManager, setNavItems]) + + // update current app name + useEffect(() => { + if (appDetail) { + const newNavItems = produce(navItems, (draft: NavItem[]) => { + navItems.forEach((app, index) => { + if (app.id === appDetail.id) + draft[index].name = appDetail.name + }) + }) + setNavItems(newNavItems) + } + }, [appDetail, navItems]) + return ( <>