| 'use client' |
|
|
| import { useCallback, useEffect, useState } from 'react' |
| import { useTranslation } from 'react-i18next' |
| import { useParams } from 'next/navigation' |
| import useSWRInfinite from 'swr/infinite' |
| import { flatten } from 'lodash-es' |
| import produce from 'immer' |
| import { |
| RiRobot2Fill, |
| RiRobot2Line, |
| } from '@remixicon/react' |
| import Nav from '../nav' |
| import { type NavItem } from '../nav/nav-selector' |
| import { fetchAppList } from '@/service/apps' |
| import CreateAppTemplateDialog from '@/app/components/app/create-app-dialog' |
| import CreateAppModal from '@/app/components/app/create-app-modal' |
| import CreateFromDSLModal from '@/app/components/app/create-from-dsl-modal' |
| 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, |
| activeTab: string, |
| keywords: string, |
| ) => { |
| if (!pageIndex || previousPageData.has_more) { |
| const params: any = { url: 'apps', params: { page: pageIndex + 1, limit: 30, name: keywords } } |
|
|
| if (activeTab !== 'all') |
| params.params.mode = activeTab |
| else |
| delete params.params.mode |
|
|
| return params |
| } |
| return null |
| } |
|
|
| const AppNav = () => { |
| const { t } = useTranslation() |
| const { appId } = useParams() |
| const { isCurrentWorkspaceEditor } = useAppContext() |
| const appDetail = useAppStore(state => state.appDetail) |
| const [showNewAppDialog, setShowNewAppDialog] = useState(false) |
| const [showNewAppTemplateDialog, setShowNewAppTemplateDialog] = useState(false) |
| const [showCreateFromDSLModal, setShowCreateFromDSLModal] = useState(false) |
| const [navItems, setNavItems] = useState<NavItem[]>([]) |
|
|
| const { data: appsData, setSize, mutate } = useSWRInfinite( |
| appId |
| ? (pageIndex: number, previousPageData: AppListResponse) => getKey(pageIndex, previousPageData, 'all', '') |
| : () => null, |
| fetchAppList, |
| { revalidateFirstPage: false }, |
| ) |
|
|
| const handleLoadmore = useCallback(() => { |
| setSize(size => size + 1) |
| }, [setSize]) |
|
|
| const openModal = (state: string) => { |
| if (state === 'blank') |
| setShowNewAppDialog(true) |
| if (state === 'template') |
| setShowNewAppTemplateDialog(true) |
| if (state === 'dsl') |
| setShowCreateFromDSLModal(true) |
| } |
|
|
| useEffect(() => { |
| if (appsData) { |
| const appItems = flatten(appsData?.map(appData => appData.data)) |
| const navItems = appItems.map((app) => { |
| const link = ((isCurrentWorkspaceEditor, app) => { |
| if (!isCurrentWorkspaceEditor) { |
| 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` |
| } |
| })(isCurrentWorkspaceEditor, app) |
| return { |
| id: app.id, |
| icon_type: app.icon_type, |
| icon: app.icon, |
| icon_background: app.icon_background, |
| icon_url: app.icon_url, |
| name: app.name, |
| mode: app.mode, |
| link, |
| } |
| }) |
| setNavItems(navItems) |
| } |
| }, [appsData, isCurrentWorkspaceEditor, setNavItems]) |
|
|
| |
| 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 ( |
| <> |
| <Nav |
| isApp |
| icon={<RiRobot2Line className='w-4 h-4' />} |
| activeIcon={<RiRobot2Fill className='w-4 h-4' />} |
| text={t('common.menus.apps')} |
| activeSegment={['apps', 'app']} |
| link='/apps' |
| curNav={appDetail} |
| navs={navItems} |
| createText={t('common.menus.newApp')} |
| onCreate={openModal} |
| onLoadmore={handleLoadmore} |
| /> |
| <CreateAppModal |
| show={showNewAppDialog} |
| onClose={() => setShowNewAppDialog(false)} |
| onSuccess={() => mutate()} |
| /> |
| <CreateAppTemplateDialog |
| show={showNewAppTemplateDialog} |
| onClose={() => setShowNewAppTemplateDialog(false)} |
| onSuccess={() => mutate()} |
| /> |
| <CreateFromDSLModal |
| show={showCreateFromDSLModal} |
| onClose={() => setShowCreateFromDSLModal(false)} |
| onSuccess={() => mutate()} |
| /> |
| </> |
| ) |
| } |
|
|
| export default AppNav |
|
|