From 19f2a74ba862b677f573ff2231e20f16d251fded Mon Sep 17 00:00:00 2001 From: zxhlyh Date: Sun, 27 Apr 2025 14:00:45 +0800 Subject: [PATCH] fix: check dsl version when create app from explore template (#18872) --- .../dsl-confirm-modal.tsx | 46 +++++ web/app/components/explore/app-list/index.tsx | 85 +++++---- .../explore/create-app-modal/index.tsx | 4 +- web/hooks/use-import-dsl.ts | 163 ++++++++++++++++++ 4 files changed, 260 insertions(+), 38 deletions(-) create mode 100644 web/app/components/app/create-from-dsl-modal/dsl-confirm-modal.tsx create mode 100644 web/hooks/use-import-dsl.ts diff --git a/web/app/components/app/create-from-dsl-modal/dsl-confirm-modal.tsx b/web/app/components/app/create-from-dsl-modal/dsl-confirm-modal.tsx new file mode 100644 index 0000000000..e6aadaa326 --- /dev/null +++ b/web/app/components/app/create-from-dsl-modal/dsl-confirm-modal.tsx @@ -0,0 +1,46 @@ +import { useTranslation } from 'react-i18next' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' + +type DSLConfirmModalProps = { + versions?: { + importedVersion: string + systemVersion: string + } + onCancel: () => void + onConfirm: () => void + confirmDisabled?: boolean +} +const DSLConfirmModal = ({ + versions = { importedVersion: '', systemVersion: '' }, + onCancel, + onConfirm, + confirmDisabled = false, +}: DSLConfirmModalProps) => { + const { t } = useTranslation() + + return ( + onCancel()} + className='w-[480px]' + > +
+
{t('app.newApp.appCreateDSLErrorTitle')}
+
+
{t('app.newApp.appCreateDSLErrorPart1')}
+
{t('app.newApp.appCreateDSLErrorPart2')}
+
+
{t('app.newApp.appCreateDSLErrorPart3')}{versions.importedVersion}
+
{t('app.newApp.appCreateDSLErrorPart4')}{versions.systemVersion}
+
+
+
+ + +
+
+ ) +} + +export default DSLConfirmModal diff --git a/web/app/components/explore/app-list/index.tsx b/web/app/components/explore/app-list/index.tsx index e217dda2b2..7e2d990bc8 100644 --- a/web/app/components/explore/app-list/index.tsx +++ b/web/app/components/explore/app-list/index.tsx @@ -1,12 +1,10 @@ 'use client' -import React, { useMemo, useState } from 'react' -import { useRouter } from 'next/navigation' +import React, { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' import useSWR from 'swr' import { useDebounceFn } from 'ahooks' -import Toast from '../../base/toast' import s from './style.module.css' import cn from '@/utils/classnames' import ExploreContext from '@/context/explore-context' @@ -14,17 +12,16 @@ import type { App } from '@/models/explore' import Category from '@/app/components/explore/category' import AppCard from '@/app/components/explore/app-card' import { fetchAppDetail, fetchAppList } from '@/service/explore' -import { importDSL } from '@/service/apps' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import CreateAppModal from '@/app/components/explore/create-app-modal' import type { CreateAppModalProps } from '@/app/components/explore/create-app-modal' import Loading from '@/app/components/base/loading' -import { NEED_REFRESH_APP_LIST_KEY } from '@/config' -import { useAppContext } from '@/context/app-context' -import { getRedirection } from '@/utils/app-redirection' import Input from '@/app/components/base/input' -import { DSLImportMode } from '@/models/app' -import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks' +import { + DSLImportMode, +} from '@/models/app' +import { useImportDSL } from '@/hooks/use-import-dsl' +import DSLConfirmModal from '@/app/components/app/create-from-dsl-modal/dsl-confirm-modal' type AppsProps = { onSuccess?: () => void @@ -39,8 +36,6 @@ const Apps = ({ onSuccess, }: AppsProps) => { const { t } = useTranslation() - const { isCurrentWorkspaceEditor } = useAppContext() - const { push } = useRouter() const { hasEditPermission } = useContext(ExploreContext) const allCategoriesEn = t('explore.apps.allCategories', { lng: 'en' }) @@ -115,7 +110,14 @@ const Apps = ({ const [currApp, setCurrApp] = React.useState(null) const [isShowCreateModal, setIsShowCreateModal] = React.useState(false) - const { handleCheckPluginDependencies } = usePluginDependencies() + + const { + handleImportDSL, + handleImportDSLConfirm, + versions, + isFetching, + } = useImportDSL() + const [showDSLConfirmModal, setShowDSLConfirmModal] = useState(false) const onCreate: CreateAppModalProps['onConfirm'] = async ({ name, icon_type, @@ -123,36 +125,34 @@ const Apps = ({ icon_background, description, }) => { - const { export_data, mode } = await fetchAppDetail( + const { export_data } = await fetchAppDetail( currApp?.app.id as string, ) - try { - const app = await importDSL({ - mode: DSLImportMode.YAML_CONTENT, - yaml_content: export_data, - name, - icon_type, - icon, - icon_background, - description, - }) - setIsShowCreateModal(false) - Toast.notify({ - type: 'success', - message: t('app.newApp.appCreated'), - }) - if (onSuccess) - onSuccess() - if (app.app_id) - await handleCheckPluginDependencies(app.app_id) - localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1') - getRedirection(isCurrentWorkspaceEditor, { id: app.app_id!, mode }, push) - } - catch { - Toast.notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) + const payload = { + mode: DSLImportMode.YAML_CONTENT, + yaml_content: export_data, + name, + icon_type, + icon, + icon_background, + description, } + await handleImportDSL(payload, { + onSuccess: () => { + setIsShowCreateModal(false) + }, + onPending: () => { + setShowDSLConfirmModal(true) + }, + }) } + const onConfirmDSL = useCallback(async () => { + await handleImportDSLConfirm({ + onSuccess, + }) + }, [handleImportDSLConfirm, onSuccess]) + if (!categories || categories.length === 0) { return (
@@ -225,9 +225,20 @@ const Apps = ({ appDescription={currApp?.app.description || ''} show={isShowCreateModal} onConfirm={onCreate} + confirmDisabled={isFetching} onHide={() => setIsShowCreateModal(false)} /> )} + { + showDSLConfirmModal && ( + setShowDSLConfirmModal(false)} + onConfirm={onConfirmDSL} + confirmDisabled={isFetching} + /> + ) + }
) } diff --git a/web/app/components/explore/create-app-modal/index.tsx b/web/app/components/explore/create-app-modal/index.tsx index d6d521833a..f30b286786 100644 --- a/web/app/components/explore/create-app-modal/index.tsx +++ b/web/app/components/explore/create-app-modal/index.tsx @@ -35,6 +35,7 @@ export type CreateAppModalProps = { description: string use_icon_as_answer_icon?: boolean }) => Promise + confirmDisabled?: boolean onHide: () => void } @@ -50,6 +51,7 @@ const CreateAppModal = ({ appMode, appUseIconAsAnswerIcon, onConfirm, + confirmDisabled, onHide, }: CreateAppModalProps) => { const { t } = useTranslation() @@ -160,7 +162,7 @@ const CreateAppModal = ({