From 117b84116efcf059d46c9d9717f7653b443a544a Mon Sep 17 00:00:00 2001 From: JzoNg Date: Fri, 23 Feb 2024 00:05:55 +0800 Subject: [PATCH] app list modification --- web/app/(commonLayout)/apps/AppCard.tsx | 91 +++++++++++++---- web/app/(commonLayout)/apps/AppModeLabel.tsx | 56 +++++------ web/app/(commonLayout)/apps/Apps.tsx | 18 ++-- web/app/(commonLayout)/apps/NewAppCard.tsx | 30 ++++-- web/app/(commonLayout)/apps/style.module.css | 2 +- web/app/(commonLayout)/datasets/Container.tsx | 4 +- web/app/(commonLayout)/list.module.css | 2 +- .../components/app/duplicate-modal/index.tsx | 98 +++++++++++++++++++ .../app/duplicate-modal/style.module.css | 36 +++++++ .../vender/line/mapsAndTravel/route.svg | 10 ++ .../src/vender/line/mapsAndTravel/Route.json | 66 +++++++++++++ .../src/vender/line/mapsAndTravel/Route.tsx | 16 +++ .../src/vender/line/mapsAndTravel/index.ts | 1 + .../components/base/tab-slider-new/index.tsx | 38 +++++++ web/i18n/en-US/app.ts | 12 ++- web/i18n/pt-BR/app.ts | 13 ++- web/i18n/uk-UA/app.ts | 14 ++- web/i18n/zh-Hans/app.ts | 10 +- web/models/app.ts | 2 - web/models/explore.ts | 3 +- web/types/app.ts | 3 +- 21 files changed, 430 insertions(+), 95 deletions(-) create mode 100644 web/app/components/app/duplicate-modal/index.tsx create mode 100644 web/app/components/app/duplicate-modal/style.module.css create mode 100644 web/app/components/base/icons/assets/vender/line/mapsAndTravel/route.svg create mode 100644 web/app/components/base/icons/src/vender/line/mapsAndTravel/Route.json create mode 100644 web/app/components/base/icons/src/vender/line/mapsAndTravel/Route.tsx create mode 100644 web/app/components/base/tab-slider-new/index.tsx diff --git a/web/app/(commonLayout)/apps/AppCard.tsx b/web/app/(commonLayout)/apps/AppCard.tsx index bc6e84fab7..b7c6fe6ce8 100644 --- a/web/app/(commonLayout)/apps/AppCard.tsx +++ b/web/app/(commonLayout)/apps/AppCard.tsx @@ -13,7 +13,9 @@ import type { ConfigParams } from '@/app/components/app/overview/settings' import type { App } from '@/types/app' import Confirm from '@/app/components/base/confirm' import { ToastContext } from '@/app/components/base/toast' -import { deleteApp, fetchAppDetail, updateAppSiteConfig } from '@/service/apps' +import { createApp, deleteApp, fetchAppDetail, updateAppSiteConfig } from '@/service/apps' +import DuplicateAppModal from '@/app/components/app/duplicate-modal' +import type { DuplicateAppModalProps } from '@/app/components/app/duplicate-modal' import AppIcon from '@/app/components/base/app-icon' import AppsContext, { useAppContext } from '@/context/app-context' import type { HtmlContentProps } from '@/app/components/base/popover' @@ -21,6 +23,7 @@ import CustomPopover from '@/app/components/base/popover' import Divider from '@/app/components/base/divider' import { asyncRunSafe } from '@/utils' import { useProviderContext } from '@/context/provider-context' +import { NEED_REFRESH_APP_LIST_KEY } from '@/config' export type AppCardProps = { app: App @@ -39,8 +42,9 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { state => state.mutateApps, ) - const [showConfirmDelete, setShowConfirmDelete] = useState(false) const [showSettingsModal, setShowSettingsModal] = useState(false) + const [showDuplicateModal, setShowDuplicateModal] = useState(false) + const [showConfirmDelete, setShowConfirmDelete] = useState(false) const [detailState, setDetailState] = useState<{ loading: boolean detail?: App @@ -69,11 +73,10 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { const [err, res] = await asyncRunSafe( fetchAppDetail({ url: '/apps', id: app.id }), ) - if (!err) { + if (!err) setDetailState({ loading: false, detail: res }) - setShowSettingsModal(true) - } - else { setDetailState({ loading: false }) } + else + setDetailState({ loading: false }) } const onSaveSiteConfig = useCallback( @@ -103,12 +106,49 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { [app.id], ) + const onCreate: DuplicateAppModalProps['onConfirm'] = async ({ name, icon, icon_background }) => { + const { app_model_config: model_config } = await fetchAppDetail({ url: '/apps', id: app.id }) + + try { + const newApp = await createApp({ + name, + icon, + icon_background, + mode: app.mode, + config: model_config, + }) + setShowDuplicateModal(false) + notify({ + type: 'success', + message: t('app.newApp.appCreated'), + }) + localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1') + push(`/app/${newApp.id}/${isCurrentWorkspaceManager ? 'configuration' : 'overview'}`) + } + catch (e) { + notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) + } + } + const Operations = (props: HtmlContentProps) => { const onClickSettings = async (e: React.MouseEvent) => { e.stopPropagation() props.onClick?.() e.preventDefault() await getAppDetail() + setShowSettingsModal(true) + } + const onClickDuplicate = async (e: React.MouseEvent) => { + e.stopPropagation() + props.onClick?.() + e.preventDefault() + setShowDuplicateModal(true) + } + const onClickExport = async (e: React.MouseEvent) => { + e.stopPropagation() + props.onClick?.() + e.preventDefault() + // TODO export } const onClickDelete = async (e: React.MouseEvent) => { e.stopPropagation() @@ -121,7 +161,13 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { - + + +
{ >
@@ -175,9 +221,26 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { {app.model_config?.pre_prompt}
- +
- + {showSettingsModal && detailState.detail && ( + setShowSettingsModal(false)} + onSave={onSaveSiteConfig} + /> + )} + {showDuplicateModal && ( + setShowDuplicateModal(false)} + /> + )} {showConfirmDelete && ( { onCancel={() => setShowConfirmDelete(false)} /> )} - {showSettingsModal && detailState.detail && ( - setShowSettingsModal(false)} - onSave={onSaveSiteConfig} - /> - )}
) diff --git a/web/app/(commonLayout)/apps/AppModeLabel.tsx b/web/app/(commonLayout)/apps/AppModeLabel.tsx index bbe6154bec..242770f526 100644 --- a/web/app/(commonLayout)/apps/AppModeLabel.tsx +++ b/web/app/(commonLayout)/apps/AppModeLabel.tsx @@ -2,52 +2,40 @@ import { useTranslation } from 'react-i18next' import { type AppMode } from '@/types/app' -import { - AiText, - CuteRobote, -} from '@/app/components/base/icons/src/vender/solid/communication' +import { CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication' import { BubbleText } from '@/app/components/base/icons/src/vender/solid/education' +import { Route } from '@/app/components/base/icons/src/vender/line/mapsAndTravel' export type AppModeLabelProps = { mode: AppMode - isAgent?: boolean - className?: string } const AppModeLabel = ({ mode, - isAgent, - className, }: AppModeLabelProps) => { const { t } = useTranslation() return ( -
- { - mode === 'completion' && ( - <> - - {t('app.newApp.completeApp')} - - ) - } - { - mode === 'chat' && !isAgent && ( - <> - - {t('appDebug.assistantType.chatAssistant.name')} - - ) - } - { - mode === 'chat' && isAgent && ( - <> - - {t('appDebug.assistantType.agentAssistant.name')} - - ) - } -
+ <> + {mode === 'chat' && ( +
+ + {t('app.types.chatbot')} +
+ )} + {mode === 'agent' && ( +
+ + {t('app.types.agent')} +
+ )} + {mode === 'workflow' && ( +
+ + {t('app.types.workflow')} +
+ )} + ) } diff --git a/web/app/(commonLayout)/apps/Apps.tsx b/web/app/(commonLayout)/apps/Apps.tsx index 106f90810d..6b95e96886 100644 --- a/web/app/(commonLayout)/apps/Apps.tsx +++ b/web/app/(commonLayout)/apps/Apps.tsx @@ -11,7 +11,7 @@ import { fetchAppList } from '@/service/apps' import { useAppContext } from '@/context/app-context' import { NEED_REFRESH_APP_LIST_KEY } from '@/config' import { CheckModal } from '@/hooks/use-pay' -import TabSlider from '@/app/components/base/tab-slider' +import TabSliderNew from '@/app/components/base/tab-slider-new' import { SearchLg } from '@/app/components/base/icons/src/vender/line/general' import { XCircle } from '@/app/components/base/icons/src/vender/solid/general' @@ -48,8 +48,9 @@ const Apps = () => { const anchorRef = useRef(null) const options = [ { value: 'all', text: t('app.types.all') }, - { value: 'chat', text: t('app.types.assistant') }, - { value: 'completion', text: t('app.types.completion') }, + { value: 'chat', text: t('app.types.chatbot') }, + { value: 'agent', text: t('app.types.agent') }, + { value: 'workflow', text: t('app.types.workflow') }, ] useEffect(() => { @@ -88,6 +89,11 @@ const Apps = () => { return ( <>
+
- -