diff --git a/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/header.tsx b/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/header.tsx new file mode 100644 index 0000000000..218691be37 --- /dev/null +++ b/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/header.tsx @@ -0,0 +1,27 @@ +import { RiCloseLine } from '@remixicon/react' +import React from 'react' +import { useTranslation } from 'react-i18next' + +type HeaderProps = { + onClose: () => void +} + +const Header = ({ + onClose, +}: HeaderProps) => { + const { t } = useTranslation() + + return ( +
+ {t('app.importFromDSL')} +
+ +
+
+ ) +} + +export default React.memo(Header) diff --git a/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/index.tsx b/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/index.tsx index d6203195b3..ffb2ee52e7 100644 --- a/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/index.tsx +++ b/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/index.tsx @@ -3,35 +3,29 @@ import { useMemo, useRef, useState } from 'react' import { useRouter } from 'next/navigation' import { useContext } from 'use-context-selector' import { useTranslation } from 'react-i18next' -import { RiCloseLine, RiCommandLine, RiCornerDownLeftLine } from '@remixicon/react' import { useDebounceFn, useKeyPress } from 'ahooks' import Button from '@/app/components/base/button' import Input from '@/app/components/base/input' import Modal from '@/app/components/base/modal' import { ToastContext } from '@/app/components/base/toast' -import { - importDSL, - importDSLConfirm, -} from '@/service/apps' import { DSLImportMode, DSLImportStatus, } from '@/models/app' -import { useSelector as useAppContextWithSelector } from '@/context/app-context' import { useProviderContextSelector } from '@/context/provider-context' import AppsFull from '@/app/components/billing/apps-full-in-dialog' -import { NEED_REFRESH_APP_LIST_KEY } from '@/config' -import { getRedirection } from '@/utils/app-redirection' -import cn from '@/utils/classnames' import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks' import { noop } from 'lodash-es' import Uploader from './uploader' +import Header from './header' +import Tab from './tab' +import { useImportPipelineDSL, useImportPipelineDSLConfirm } from '@/service/use-pipeline' type CreateFromDSLModalProps = { show: boolean onSuccess?: () => void onClose: () => void - activeTab?: string + activeTab?: CreateFromDSLModalTab dslUrl?: string } @@ -76,14 +70,14 @@ const CreateFromDSLModal = ({ setFileContent('') } - const isCurrentWorkspaceEditor = useAppContextWithSelector(state => state.isCurrentWorkspaceEditor) const plan = useProviderContextSelector(state => state.plan) const enableBilling = useProviderContextSelector(state => state.enableBilling) const isAppsFull = (enableBilling && plan.usage.buildApps >= plan.total.buildApps) const isCreatingRef = useRef(false) - // todo: replace with pipeline import DSL and check plugin dependencies + const { mutateAsync: importDSL } = useImportPipelineDSL() + const onCreate = async () => { if (currentTab === CreateFromDSLModalTab.FROM_FILE && !currentFile) return @@ -94,7 +88,6 @@ const CreateFromDSLModal = ({ isCreatingRef.current = true try { let response - if (currentTab === CreateFromDSLModalTab.FROM_FILE) { response = await importDSL({ mode: DSLImportMode.YAML_CONTENT, @@ -110,7 +103,7 @@ const CreateFromDSLModal = ({ if (!response) return - const { id, status, app_id, app_mode, imported_dsl_version, current_dsl_version } = response + const { id, status, pipeline_id, imported_dsl_version, current_dsl_version } = response if (status === DSLImportStatus.COMPLETED || status === DSLImportStatus.COMPLETED_WITH_WARNINGS) { if (onSuccess) onSuccess() @@ -122,9 +115,9 @@ const CreateFromDSLModal = ({ message: t(status === DSLImportStatus.COMPLETED ? 'app.newApp.appCreated' : 'app.newApp.caution'), children: status === DSLImportStatus.COMPLETED_WITH_WARNINGS && t('app.newApp.appCreateDSLWarning'), }) - if (app_id) - await handleCheckPluginDependencies(app_id) - getRedirection(isCurrentWorkspaceEditor, { id: app_id!, mode: app_mode }, push) + if (pipeline_id) + await handleCheckPluginDependencies(pipeline_id, true) + push(`datasets/${pipeline_id}/pipeline`) } else if (status === DSLImportStatus.PENDING) { setVersions({ @@ -142,8 +135,7 @@ const CreateFromDSLModal = ({ notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) } } - // eslint-disable-next-line unused-imports/no-unused-vars - catch (e) { + catch { notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) } finally { @@ -153,16 +145,13 @@ const CreateFromDSLModal = ({ const { run: handleCreateApp } = useDebounceFn(onCreate, { wait: 300 }) - useKeyPress(['meta.enter', 'ctrl.enter'], () => { - if (show && !isAppsFull && ((currentTab === CreateFromDSLModalTab.FROM_FILE && currentFile) || (currentTab === CreateFromDSLModalTab.FROM_URL && dslUrlValue))) - handleCreateApp() - }) - useKeyPress('esc', () => { if (show && !showErrorModal) onClose() }) + const { mutateAsync: importDSLConfirm } = useImportPipelineDSLConfirm() + const onDSLConfirm = async () => { try { if (!importId) @@ -171,7 +160,7 @@ const CreateFromDSLModal = ({ import_id: importId, }) - const { status, app_id, app_mode } = response + const { status, pipeline_id } = response if (status === DSLImportStatus.COMPLETED) { if (onSuccess) @@ -183,32 +172,19 @@ const CreateFromDSLModal = ({ type: 'success', message: t('app.newApp.appCreated'), }) - if (app_id) - await handleCheckPluginDependencies(app_id) - localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1') - getRedirection(isCurrentWorkspaceEditor, { id: app_id!, mode: app_mode }, push) + if (pipeline_id) + await handleCheckPluginDependencies(pipeline_id, true) + push(`datasets/${pipeline_id}/pipeline`) } else if (status === DSLImportStatus.FAILED) { notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) } } - // eslint-disable-next-line unused-imports/no-unused-vars - catch (e) { + catch { notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) } } - const tabs = [ - { - key: CreateFromDSLModalTab.FROM_FILE, - label: t('app.importFromDSLFile'), - }, - { - key: CreateFromDSLModalTab.FROM_URL, - label: t('app.importFromDSLUrl'), - }, - ] - const buttonDisabled = useMemo(() => { if (isAppsFull) return true @@ -226,36 +202,11 @@ const CreateFromDSLModal = ({ isShow={show} onClose={noop} > -
- {t('app.importFromDSL')} -
onClose()} - > - -
-
-
- { - tabs.map(tab => ( -
setCurrentTab(tab.key)} - > - {tab.label} - { - currentTab === tab.key && ( -
- ) - } -
- )) - } -
+
+
{ currentTab === CreateFromDSLModalTab.FROM_FILE && ( @@ -284,19 +235,17 @@ const CreateFromDSLModal = ({
)} -
- +
+
diff --git a/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/tab/index.tsx b/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/tab/index.tsx new file mode 100644 index 0000000000..46c671e346 --- /dev/null +++ b/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/tab/index.tsx @@ -0,0 +1,44 @@ +import React from 'react' +import { CreateFromDSLModalTab } from '@/app/components/app/create-from-dsl-modal' +import { useTranslation } from 'react-i18next' +import Item from './item' + +type TabProps = { + currentTab: CreateFromDSLModalTab + setCurrentTab: (tab: CreateFromDSLModalTab) => void +} + +const Tab = ({ + currentTab, + setCurrentTab, +}: TabProps) => { + const { t } = useTranslation() + + const tabs = [ + { + key: CreateFromDSLModalTab.FROM_FILE, + label: t('app.importFromDSLFile'), + }, + { + key: CreateFromDSLModalTab.FROM_URL, + label: t('app.importFromDSLUrl'), + }, + ] + + return ( +
+ { + tabs.map(tab => ( + + )) + } +
+ ) +} + +export default Tab diff --git a/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/tab/item.tsx b/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/tab/item.tsx new file mode 100644 index 0000000000..8474a832e4 --- /dev/null +++ b/web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/tab/item.tsx @@ -0,0 +1,33 @@ +import React from 'react' +import cn from '@/utils/classnames' + +type ItemProps = { + isActive: boolean + label: string + onClick: () => void +} + +const Item = ({ + isActive, + label, + onClick, +}: ItemProps) => { + return ( +
+ {label} + { + isActive && ( +
+ ) + } +
+ ) +} + +export default React.memo(Item) diff --git a/web/app/components/datasets/create-from-pipeline/create-options/index.tsx b/web/app/components/datasets/create-from-pipeline/create-options/index.tsx index 8893e04ca6..2a1bfd6abc 100644 --- a/web/app/components/datasets/create-from-pipeline/create-options/index.tsx +++ b/web/app/components/datasets/create-from-pipeline/create-options/index.tsx @@ -76,4 +76,4 @@ const CreateOptions = () => { ) } -export default React.memo(CreateOptions) +export default CreateOptions diff --git a/web/app/components/datasets/create-from-pipeline/list/template-card/actions.tsx b/web/app/components/datasets/create-from-pipeline/list/template-card/actions.tsx index f78f7bbae5..55a3e30d8a 100644 --- a/web/app/components/datasets/create-from-pipeline/list/template-card/actions.tsx +++ b/web/app/components/datasets/create-from-pipeline/list/template-card/actions.tsx @@ -10,7 +10,7 @@ type ActionsProps = { handleShowTemplateDetails: () => void showMoreOperations: boolean openEditModal: () => void - handleExportDSL: () => void + handleExportDSL: (includeSecret?: boolean) => void handleDelete: () => void } diff --git a/web/app/components/datasets/create-from-pipeline/list/template-card/index.tsx b/web/app/components/datasets/create-from-pipeline/list/template-card/index.tsx index 878c81ffa3..c967d26eeb 100644 --- a/web/app/components/datasets/create-from-pipeline/list/template-card/index.tsx +++ b/web/app/components/datasets/create-from-pipeline/list/template-card/index.tsx @@ -4,7 +4,12 @@ import Modal from '@/app/components/base/modal' import EditPipelineInfo from './edit-pipeline-info' import type { PipelineTemplate } from '@/models/pipeline' import Confirm from '@/app/components/base/confirm' -import { useDeletePipeline, useExportPipelineDSL, useImportPipelineDSL, usePipelineTemplateById } from '@/service/use-pipeline' +import { + useDeletePipeline, + useExportPipelineDSL, + useImportPipelineDSL, + usePipelineTemplateById, +} from '@/service/use-pipeline' import { downloadFile } from '@/utils/format' import Toast from '@/app/components/base/toast' import { DSLImportMode } from '@/models/app' @@ -30,7 +35,7 @@ const TemplateCard = ({ const [showDetailModal, setShowDetailModal] = useState(false) const { refetch: getPipelineTemplateInfo } = usePipelineTemplateById(pipeline.id, false) - const { mutateAsync: importPipelineDSL } = useImportPipelineDSL() + const { mutateAsync: importDSL } = useImportPipelineDSL() const { handleCheckPluginDependencies } = usePluginDependencies() const handleUseTemplate = useCallback(async () => { @@ -45,19 +50,16 @@ const TemplateCard = ({ } const request = { mode: DSLImportMode.YAML_CONTENT, - name: pipeline.name, yaml_content: pipelineTemplateInfo.export_data, - icon_info: pipeline.icon_info, - description: pipeline.description, } - const newPipeline = await importPipelineDSL(request) + const newPipeline = await importDSL(request) Toast.notify({ type: 'success', message: t('app.newApp.appCreated'), }) - if (newPipeline.dataset_id) - await handleCheckPluginDependencies(newPipeline.dataset_id) // todo: replace with pipeline dependency check - push(`dataset/${newPipeline.dataset_id}/pipeline`) + if (newPipeline.pipeline_id) + await handleCheckPluginDependencies(newPipeline.pipeline_id, true) + push(`dataset/${newPipeline.pipeline_id}/pipeline`) } catch { Toast.notify({ @@ -65,7 +67,7 @@ const TemplateCard = ({ message: t('datasetPipeline.creation.errorTip'), }) } - }, [getPipelineTemplateInfo, importPipelineDSL, pipeline, t, push, handleCheckPluginDependencies]) + }, [getPipelineTemplateInfo, importDSL, t, handleCheckPluginDependencies, push]) const handleShowTemplateDetails = useCallback(() => { setShowDetailModal(true) @@ -85,9 +87,12 @@ const TemplateCard = ({ const { mutateAsync: exportPipelineDSL, isPending: isExporting } = useExportPipelineDSL() - const handleExportDSL = useCallback(async () => { + const handleExportDSL = useCallback(async (includeSecret = false) => { if (isExporting) return - await exportPipelineDSL(pipeline.id, { + await exportPipelineDSL({ + pipeline_id: pipeline.id, + include_secret: includeSecret, + }, { onSuccess: (res) => { const blob = new Blob([res.data], { type: 'application/yaml' }) downloadFile({ diff --git a/web/app/components/datasets/list/container.tsx b/web/app/components/datasets/list/container.tsx index 8e7d122c86..7b70f78c57 100644 --- a/web/app/components/datasets/list/container.tsx +++ b/web/app/components/datasets/list/container.tsx @@ -115,7 +115,7 @@ const Container = () => { onChange={e => handleKeywordsChange(e.target.value)} onClear={() => handleKeywordsChange('')} /> -
+