import { useTranslation } from 'react-i18next' import { useRouter } from 'next/navigation' import { useContext, useContextSelector } from 'use-context-selector' import cn from 'classnames' import React, { useCallback, useState } from 'react' import AppIcon from '../base/app-icon' import SwitchAppModal from '../app/switch-app-modal' import s from './style.module.css' import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger, } from '@/app/components/base/portal-to-follow-elem' import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows' import Divider from '@/app/components/base/divider' import Confirm from '@/app/components/base/confirm' import { useStore as useAppStore } from '@/app/components/app/store' import { ToastContext } from '@/app/components/base/toast' import AppsContext from '@/context/app-context' import { useProviderContext } from '@/context/provider-context' import { copyApp, deleteApp, exportAppConfig, updateAppInfo } from '@/service/apps' import DuplicateAppModal from '@/app/components/app/duplicate-modal' import type { DuplicateAppModalProps } from '@/app/components/app/duplicate-modal' import CreateAppModal from '@/app/components/explore/create-app-modal' import { AiText, ChatBot, CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication' import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel' import type { CreateAppModalProps } from '@/app/components/explore/create-app-modal' import { NEED_REFRESH_APP_LIST_KEY } from '@/config' import { getRedirection } from '@/utils/app-redirection' export type IAppInfoProps = { expand: boolean } const AppInfo = ({ expand }: IAppInfoProps) => { const { t } = useTranslation() const { notify } = useContext(ToastContext) const { replace } = useRouter() const { onPlanInfoChanged } = useProviderContext() const appDetail = useAppStore(state => state.appDetail) const setAppDetail = useAppStore(state => state.setAppDetail) const [open, setOpen] = useState(false) const [showEditModal, setShowEditModal] = useState(false) const [showDuplicateModal, setShowDuplicateModal] = useState(false) const [showConfirmDelete, setShowConfirmDelete] = useState(false) const [showSwitchTip, setShowSwitchTip] = useState('') const [showSwitchModal, setShowSwitchModal] = useState(false) const mutateApps = useContextSelector( AppsContext, state => state.mutateApps, ) const onEdit: CreateAppModalProps['onConfirm'] = useCallback(async ({ name, icon, icon_background, description, }) => { if (!appDetail) return try { const app = await updateAppInfo({ appID: appDetail.id, name, icon, icon_background, description, }) setShowEditModal(false) notify({ type: 'success', message: t('app.editDone'), }) setAppDetail(app) mutateApps() } catch (e) { notify({ type: 'error', message: t('app.editFailed') }) } }, [appDetail, mutateApps, notify, setAppDetail, t]) const onCopy: DuplicateAppModalProps['onConfirm'] = async ({ name, icon, icon_background }) => { if (!appDetail) return try { const newApp = await copyApp({ appID: appDetail.id, name, icon, icon_background, mode: appDetail.mode, }) setShowDuplicateModal(false) notify({ type: 'success', message: t('app.newApp.appCreated'), }) localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1') mutateApps() onPlanInfoChanged() getRedirection(true, newApp, replace) } catch (e) { notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) } } const onExport = async () => { if (!appDetail) return try { const { data } = await exportAppConfig(appDetail.id) const a = document.createElement('a') const file = new Blob([data], { type: 'application/yaml' }) a.href = URL.createObjectURL(file) a.download = `${appDetail.name}.yml` a.click() } catch (e) { notify({ type: 'error', message: t('app.exportFailed') }) } } const onConfirmDelete = useCallback(async () => { if (!appDetail) return try { await deleteApp(appDetail.id) notify({ type: 'success', message: t('app.appDeleted') }) mutateApps() onPlanInfoChanged() setAppDetail() replace('/apps') } catch (e: any) { notify({ type: 'error', message: `${t('app.appDeleteFailed')}${'message' in e ? `: ${e.message}` : ''}`, }) } setShowConfirmDelete(false) }, [appDetail, mutateApps, notify, onPlanInfoChanged, replace, t]) if (!appDetail) return null return (
setOpen(v => !v)} className='block' >
{appDetail.mode === 'advanced-chat' && ( )} {appDetail.mode === 'agent-chat' && ( )} {appDetail.mode === 'chat' && ( )} {appDetail.mode === 'completion' && ( )} {appDetail.mode === 'workflow' && ( )}
{expand && (
{appDetail.name}
{appDetail.mode === 'advanced-chat' && ( <>
{t('app.types.chatbot').toUpperCase()}
{t('app.newApp.advanced').toUpperCase()}
)} {appDetail.mode === 'agent-chat' && (
{t('app.types.agent').toUpperCase()}
)} {appDetail.mode === 'chat' && ( <>
{t('app.types.chatbot').toUpperCase()}
{(t('app.newApp.basic').toUpperCase())}
)} {appDetail.mode === 'completion' && ( <>
{t('app.types.completion').toUpperCase()}
{(t('app.newApp.basic').toUpperCase())}
)} {appDetail.mode === 'workflow' && (
{t('app.types.workflow').toUpperCase()}
)}
)}
{/* header */}
{appDetail.mode === 'advanced-chat' && ( )} {appDetail.mode === 'agent-chat' && ( )} {appDetail.mode === 'chat' && ( )} {appDetail.mode === 'completion' && ( )} {appDetail.mode === 'workflow' && ( )}
{appDetail.name}
{appDetail.mode === 'advanced-chat' && ( <>
{t('app.types.chatbot').toUpperCase()}
{t('app.newApp.advanced').toUpperCase()}
)} {appDetail.mode === 'agent-chat' && (
{t('app.types.agent').toUpperCase()}
)} {appDetail.mode === 'chat' && ( <>
{t('app.types.chatbot').toUpperCase()}
{(t('app.newApp.basic').toUpperCase())}
)} {appDetail.mode === 'completion' && ( <>
{t('app.types.completion').toUpperCase()}
{(t('app.newApp.basic').toUpperCase())}
)} {appDetail.mode === 'workflow' && (
{t('app.types.workflow').toUpperCase()}
)}
{/* desscription */} {appDetail.description && (
{appDetail.description}
)} {/* operations */}
{ setOpen(false) setShowEditModal(true) }}> {t('app.editApp')}
{ setOpen(false) setShowDuplicateModal(true) }}> {t('app.duplicate')}
{t('app.export')}
{(appDetail.mode === 'completion' || appDetail.mode === 'chat') && ( <>
setShowSwitchTip(appDetail.mode)} onMouseLeave={() => setShowSwitchTip('')} onClick={() => { setOpen(false) setShowSwitchModal(true) }} > {t('app.switch')}
)}
{ setOpen(false) setShowConfirmDelete(true) }}> {t('common.operation.delete')}
{/* switch tip */}
{showSwitchTip === 'chat' ? t('app.newApp.advanced') : t('app.types.workflow')} BETA
{t('app.newApp.advancedFor').toLocaleUpperCase()}
{t('app.newApp.advancedDescription')}
{showSwitchModal && ( setShowSwitchModal(false)} onSuccess={() => setShowSwitchModal(false)} /> )} {showEditModal && ( setShowEditModal(false)} /> )} {showDuplicateModal && ( setShowDuplicateModal(false)} /> )} {showConfirmDelete && ( setShowConfirmDelete(false)} onConfirm={onConfirmDelete} onCancel={() => setShowConfirmDelete(false)} /> )}
) } export default React.memo(AppInfo)