From b0478f4df7ef51790d38859e18aa5572b8dbaf03 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Wed, 29 Apr 2026 22:25:47 +0800 Subject: [PATCH] fix(web): workflow switch to evaluation --- .../app/app-publisher/features-wrapper.tsx | 19 +- .../components/app/app-publisher/index.tsx | 209 ++++------------ .../components/app/app-publisher/sections.tsx | 13 +- .../app-publisher/use-workflow-type-switch.ts | 229 ++++++++++++++++++ .../configuration/hooks/use-configuration.ts | 4 +- .../workflow-header/features-trigger.tsx | 5 +- .../workflow/utils/evaluation-workflow.ts | 3 +- web/types/app.ts | 3 +- web/types/workflow.ts | 2 + 9 files changed, 295 insertions(+), 192 deletions(-) create mode 100644 web/app/components/app/app-publisher/use-workflow-type-switch.ts diff --git a/web/app/components/app/app-publisher/features-wrapper.tsx b/web/app/components/app/app-publisher/features-wrapper.tsx index 8679b2830d..3189eb8990 100644 --- a/web/app/components/app/app-publisher/features-wrapper.tsx +++ b/web/app/components/app/app-publisher/features-wrapper.tsx @@ -1,7 +1,6 @@ -import type { AppPublisherProps } from '@/app/components/app/app-publisher' -import type { ModelAndParameter } from '@/app/components/app/configuration/debug/types' -import type { FileUpload } from '@/app/components/base/features/types' -import type { PublishWorkflowParams } from '@/types/workflow' +import type { AppPublisherProps, AppPublisherPublishParams } from '@/app/components/app/app-publisher' +import type { Features, FileUpload } from '@/app/components/base/features/types' +import type { ModelConfig } from '@/models/debug' import { AlertDialog, AlertDialogActions, @@ -21,9 +20,15 @@ import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' import { SupportUploadFileTypes } from '@/app/components/workflow/types' import { Resolution } from '@/types/app' +type PublishedModelConfig = ModelConfig & { + resetAppConfig?: () => void +} + type Props = Omit & { - onPublish?: (params?: ModelAndParameter | PublishWorkflowParams, features?: any) => Promise | any - publishedConfig?: any + onPublish?: (params?: AppPublisherPublishParams, features?: Features) => Promise | unknown + publishedConfig: { + modelConfig: PublishedModelConfig + } resetAppConfig?: () => void } @@ -71,7 +76,7 @@ const FeaturesWrappedAppPublisher = (props: Props) => { setRestoreConfirmOpen(false) }, [featuresStore, props]) - const handlePublish = useCallback((params?: ModelAndParameter | PublishWorkflowParams) => { + const handlePublish = useCallback((params?: AppPublisherPublishParams) => { return props.onPublish?.(params, features) }, [features, props]) diff --git a/web/app/components/app/app-publisher/index.tsx b/web/app/components/app/app-publisher/index.tsx index fc750971c1..5e24b71961 100644 --- a/web/app/components/app/app-publisher/index.tsx +++ b/web/app/components/app/app-publisher/index.tsx @@ -1,9 +1,7 @@ import type { ModelAndParameter } from '../configuration/debug/types' import type { CollaborationUpdate } from '@/app/components/workflow/collaboration/types/collaboration' import type { InputVar, Variable } from '@/app/components/workflow/types' -import type { EvaluationWorkflowAssociatedTarget } from '@/types/evaluation' -import type { I18nKeysWithPrefix } from '@/types/i18n' -import type { PublishWorkflowParams, WorkflowTypeConversionTarget } from '@/types/workflow' +import type { PublishWorkflowParams } from '@/types/workflow' import { Button } from '@langgenius/dify-ui/button' import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { toast } from '@langgenius/dify-ui/toast' @@ -32,11 +30,9 @@ import { useAppWhiteListSubjects, useGetUserCanAccessApp } from '@/service/acces import { fetchAppDetailDirect, publishToCreatorsPlatform } from '@/service/apps' import { fetchInstalledAppList } from '@/service/explore' import { systemFeaturesQueryOptions } from '@/service/system-features' -import { useConvertWorkflowTypeMutation } from '@/service/use-apps' -import { useEvaluationWorkflowAssociatedTargets } from '@/service/use-evaluation' import { useInvalidateAppWorkflow } from '@/service/use-workflow' import { fetchPublishedWorkflow } from '@/service/workflow' -import { AppModeEnum, AppTypeEnum } from '@/types/app' +import { AppModeEnum } from '@/types/app' import { basePath } from '@/utils/var' import { getKeyboardKeyCodeBySystem } from '../../workflow/utils' import AccessControl from '../app-access-control' @@ -47,12 +43,20 @@ import { PublisherSummarySection, } from './sections' import SuggestedAction from './suggested-action' +import { useWorkflowTypeSwitch } from './use-workflow-type-switch' import { getDisabledFunctionTooltip, getPublisherAppUrl, isPublisherAccessConfigured, } from './utils' +export type AppPublisherPublishParams + = | ModelAndParameter + | (Pick & { + url?: string + id?: string + }) + export type AppPublisherProps = { disabled?: boolean publishDisabled?: boolean @@ -62,8 +66,8 @@ export type AppPublisherProps = { debugWithMultipleModel?: boolean multipleModelConfigs?: ModelAndParameter[] /** modelAndParameter is passed when debugWithMultipleModel is true */ - onPublish?: (params?: any) => Promise | any - onRestore?: () => Promise | any + onPublish?: (params?: AppPublisherPublishParams) => Promise | unknown + onRestore?: () => Promise | unknown onToggle?: (state: boolean) => void crossAxisOffset?: number toolPublished?: boolean @@ -79,32 +83,6 @@ export type AppPublisherProps = { const PUBLISH_SHORTCUT = ['ctrl', '⇧', 'P'] -type WorkflowTypeSwitchLabelKey = I18nKeysWithPrefix<'workflow', 'common.'> - -const WORKFLOW_TYPE_SWITCH_CONFIG: Record = { - workflow: { - targetType: 'evaluation', - publishLabelKey: 'common.publishAsEvaluationWorkflow', - switchLabelKey: 'common.switchToEvaluationWorkflow', - tipKey: 'common.switchToEvaluationWorkflowTip', - }, - evaluation: { - targetType: 'workflow', - publishLabelKey: 'common.publishAsStandardWorkflow', - switchLabelKey: 'common.switchToStandardWorkflow', - tipKey: 'common.switchToStandardWorkflowTip', - }, -} as const - -const isWorkflowTypeConversionTarget = (type?: AppTypeEnum): type is WorkflowTypeConversionTarget => { - return type === 'workflow' || type === 'evaluation' -} - const AppPublisher = ({ disabled = false, publishDisabled = false, @@ -131,8 +109,6 @@ const AppPublisher = ({ const [published, setPublished] = useState(false) const [open, setOpen] = useState(false) const [showAppAccessControl, setShowAppAccessControl] = useState(false) - const [showEvaluationWorkflowSwitchConfirm, setShowEvaluationWorkflowSwitchConfirm] = useState(false) - const [evaluationWorkflowSwitchTargets, setEvaluationWorkflowSwitchTargets] = useState([]) const [embeddingModalOpen, setEmbeddingModalOpen] = useState(false) const [publishingToMarketplace, setPublishingToMarketplace] = useState(false) @@ -144,36 +120,9 @@ const AppPublisher = ({ const { data: systemFeatures } = useSuspenseQuery(systemFeaturesQueryOptions()) const { formatTimeFromNow } = useFormatTimeFromNow() const { app_base_url: appBaseURL = '', access_token: accessToken = '' } = appDetail?.site ?? {} - const { mutateAsync: convertWorkflowType, isPending: isConvertingWorkflowType } = useConvertWorkflowTypeMutation() const appURL = getPublisherAppUrl({ appBaseUrl: appBaseURL, accessToken, mode: appDetail?.mode }) const isChatApp = [AppModeEnum.CHAT, AppModeEnum.AGENT_CHAT, AppModeEnum.COMPLETION].includes(appDetail?.mode || AppModeEnum.CHAT) - const workflowTypeSwitchConfig = useMemo(() => { - if (!appDetail?.workflow_kind) - return WORKFLOW_TYPE_SWITCH_CONFIG.workflow - - if (!isWorkflowTypeConversionTarget(appDetail?.workflow_kind)) - return undefined - - return WORKFLOW_TYPE_SWITCH_CONFIG[appDetail.workflow_kind] - }, [appDetail?.workflow_kind]) - const isEvaluationWorkflowType = appDetail?.workflow_kind === AppTypeEnum.EVALUATION - const { - refetch: refetchEvaluationWorkflowAssociatedTargets, - isFetching: isFetchingEvaluationWorkflowAssociatedTargets, - } = useEvaluationWorkflowAssociatedTargets(appDetail?.id, { enabled: false }) - const workflowTypeSwitchDisabledReason = useMemo(() => { - if (workflowTypeSwitchConfig?.targetType !== AppTypeEnum.EVALUATION) - return undefined - - if (!canAccessSnippetsAndEvaluation) - return t('compliance.sandboxUpgradeTooltip', { ns: 'common' }) - - if (!hasHumanInputNode && !hasTriggerNode) - return undefined - - return t('common.switchToEvaluationWorkflowDisabledTip', { ns: 'workflow' }) - }, [canAccessSnippetsAndEvaluation, hasHumanInputNode, hasTriggerNode, t, workflowTypeSwitchConfig?.targetType]) const { data: userCanAccessApp, isLoading: isGettingUserCanAccessApp, refetch } = useGetUserCanAccessApp({ appId: appDetail?.id, enabled: false }) const { data: appAccessSubjects, isLoading: isGettingAppWhiteListSubjects } = useAppWhiteListSubjects(appDetail?.id, open && systemFeatures.webapp_auth.enabled && appDetail?.access_mode === AccessMode.SPECIFIC_GROUPS_MEMBERS) @@ -201,7 +150,7 @@ const AppPublisher = ({ refetch() }, [open, appDetail, refetch, systemFeatures]) - const handlePublish = useCallback(async (params?: ModelAndParameter | PublishWorkflowParams) => { + const handlePublish = useCallback(async (params?: AppPublisherPublishParams) => { try { await onPublish?.(params) setPublished(true) @@ -283,110 +232,34 @@ const AppPublisher = ({ } }, [appDetail, setAppDetail]) - const getWorkflowTypeSwitchPublishUrl = useCallback(() => { - if (!appDetail?.id || !workflowTypeSwitchConfig) - return undefined - - if (workflowTypeSwitchConfig.targetType === AppTypeEnum.EVALUATION) - return `/apps/${appDetail.id}/workflows/publish/evaluation` - - return `/apps/${appDetail.id}/workflows/publish` - }, [appDetail?.id, workflowTypeSwitchConfig]) - - const performWorkflowTypeSwitch = useCallback(async () => { - if (!appDetail?.id || !workflowTypeSwitchConfig) - return false - - try { - if (!publishedAt) { - const publishUrl = getWorkflowTypeSwitchPublishUrl() - if (!publishUrl) - return false - - await handlePublish({ - url: publishUrl, - title: '', - releaseNotes: '', - }) - - const latestAppDetail = await fetchAppDetailDirect({ - url: '/apps', - id: appDetail.id, - }) - setAppDetail(latestAppDetail) - setShowEvaluationWorkflowSwitchConfirm(false) - setEvaluationWorkflowSwitchTargets([]) - return true - } - - await convertWorkflowType({ - params: { - appId: appDetail.id, - }, - query: { - target_type: workflowTypeSwitchConfig.targetType, - }, - }) - - const latestAppDetail = await fetchAppDetailDirect({ - url: '/apps', - id: appDetail.id, - }) - setAppDetail(latestAppDetail) - - if (publishedAt) - setOpen(false) - - setShowEvaluationWorkflowSwitchConfirm(false) - setEvaluationWorkflowSwitchTargets([]) - return true - } - catch { - return false - } - }, [appDetail?.id, convertWorkflowType, getWorkflowTypeSwitchPublishUrl, handlePublish, publishedAt, setAppDetail, workflowTypeSwitchConfig]) - - const handleWorkflowTypeSwitch = useCallback(async () => { - if (!appDetail?.id || !workflowTypeSwitchConfig) - return - if (workflowTypeSwitchDisabledReason) { - toast.error(workflowTypeSwitchDisabledReason) - return - } - - if (appDetail.workflow_kind === AppTypeEnum.EVALUATION && workflowTypeSwitchConfig.targetType === AppTypeEnum.WORKFLOW) { - const associatedTargetsResult = await refetchEvaluationWorkflowAssociatedTargets() - - if (associatedTargetsResult.isError) { - toast.error(t('common.switchToStandardWorkflowConfirm.loadFailed', { ns: 'workflow' })) - return - } - - const associatedTargets = associatedTargetsResult.data?.items ?? [] - if (associatedTargets.length > 0) { - setEvaluationWorkflowSwitchTargets(associatedTargets) - setShowEvaluationWorkflowSwitchConfirm(true) - return - } - } - - await performWorkflowTypeSwitch() - }, [ - appDetail?.id, - appDetail?.workflow_kind, - performWorkflowTypeSwitch, - refetchEvaluationWorkflowAssociatedTargets, - t, - workflowTypeSwitchConfig, - workflowTypeSwitchDisabledReason, - ]) - - const handleEvaluationWorkflowSwitchConfirmOpenChange = useCallback((nextOpen: boolean) => { - setShowEvaluationWorkflowSwitchConfirm(nextOpen) - - if (!nextOpen) - setEvaluationWorkflowSwitchTargets([]) + const handlePublishedWorkflowTypeSwitch = useCallback(() => { + setOpen(false) }, []) + + const { + evaluationWorkflowSwitchTargets, + handleEvaluationWorkflowSwitchConfirmOpenChange, + handleWorkflowTypeSwitch, + isConvertingWorkflowType, + isEvaluationWorkflowType, + performWorkflowTypeSwitch, + showEvaluationWorkflowSwitchConfirm, + workflowTypeSwitchConfig, + workflowTypeSwitchDisabled, + workflowTypeSwitchDisabledReason, + } = useWorkflowTypeSwitch({ + appDetail, + canAccessSnippetsAndEvaluation, + hasHumanInputNode, + hasTriggerNode, + onPublish: handlePublish, + onPublishedSwitch: handlePublishedWorkflowTypeSwitch, + published, + publishedAt, + publishDisabled, + setAppDetail, + }) + const handlePublishToMarketplace = useCallback(async () => { if (!appDetail?.id || publishingToMarketplace) return @@ -485,7 +358,7 @@ const AppPublisher = ({ startNodeLimitExceeded={startNodeLimitExceeded} upgradeHighlightStyle={upgradeHighlightStyle} workflowTypeSwitchConfig={workflowTypeSwitchConfig} - workflowTypeSwitchDisabled={publishDisabled || published || isConvertingWorkflowType || isFetchingEvaluationWorkflowAssociatedTargets || Boolean(workflowTypeSwitchDisabledReason)} + workflowTypeSwitchDisabled={workflowTypeSwitchDisabled} workflowTypeSwitchDisabledReason={workflowTypeSwitchDisabledReason} onWorkflowTypeSwitch={handleWorkflowTypeSwitch} /> diff --git a/web/app/components/app/app-publisher/sections.tsx b/web/app/components/app/app-publisher/sections.tsx index 3bcad6a533..31fadf6697 100644 --- a/web/app/components/app/app-publisher/sections.tsx +++ b/web/app/components/app/app-publisher/sections.tsx @@ -1,8 +1,8 @@ import type { CSSProperties, ReactNode } from 'react' import type { ModelAndParameter } from '../configuration/debug/types' import type { AppPublisherProps } from './index' -import type { I18nKeysWithPrefix } from '@/types/i18n' -import type { PublishWorkflowParams, WorkflowTypeConversionTarget } from '@/types/workflow' +import type { WorkflowTypeSwitchConfig } from './use-workflow-type-switch' +import type { PublishWorkflowParams } from '@/types/workflow' import { Button } from '@langgenius/dify-ui/button' import { Tooltip, @@ -21,8 +21,6 @@ import PublishWithMultipleModel from './publish-with-multiple-model' import SuggestedAction from './suggested-action' import { ACCESS_MODE_MAP } from './utils' -type WorkflowTypeSwitchLabelKey = I18nKeysWithPrefix<'workflow', 'common.'> - type SummarySectionProps = Pick + +export type WorkflowTypeSwitchConfig = { + targetType: WorkflowTypeConversionTarget + publishLabelKey: WorkflowTypeSwitchLabelKey + switchLabelKey: WorkflowTypeSwitchLabelKey + tipKey: WorkflowTypeSwitchLabelKey +} + +const WORKFLOW_TYPE_SWITCH_CONFIG: Record = { + workflow: { + targetType: 'evaluation', + publishLabelKey: 'common.publishAsEvaluationWorkflow', + switchLabelKey: 'common.switchToEvaluationWorkflow', + tipKey: 'common.switchToEvaluationWorkflowTip', + }, + evaluation: { + targetType: 'workflow', + publishLabelKey: 'common.publishAsStandardWorkflow', + switchLabelKey: 'common.switchToStandardWorkflow', + tipKey: 'common.switchToStandardWorkflowTip', + }, +} as const + +const getWorkflowTypeSwitchConfig = (workflowKind?: WorkflowKind | null) => { + if (!workflowKind || workflowKind === 'standard') + return WORKFLOW_TYPE_SWITCH_CONFIG.workflow + + if (workflowKind === 'evaluation') + return WORKFLOW_TYPE_SWITCH_CONFIG.evaluation +} + +type UseWorkflowTypeSwitchParams = { + appDetail?: App & Partial + canAccessSnippetsAndEvaluation: boolean + hasHumanInputNode: boolean + hasTriggerNode: boolean + onPublish: (params?: ModelAndParameter | PublishWorkflowParams) => Promise + onPublishedSwitch: () => void + published: boolean + publishedAt?: number + publishDisabled: boolean + setAppDetail: (appDetail?: App & Partial) => void +} + +export const useWorkflowTypeSwitch = ({ + appDetail, + canAccessSnippetsAndEvaluation, + hasHumanInputNode, + hasTriggerNode, + onPublish, + onPublishedSwitch, + published, + publishedAt, + publishDisabled, + setAppDetail, +}: UseWorkflowTypeSwitchParams) => { + const { t } = useTranslation() + const [showEvaluationWorkflowSwitchConfirm, setShowEvaluationWorkflowSwitchConfirm] = useState(false) + const [evaluationWorkflowSwitchTargets, setEvaluationWorkflowSwitchTargets] = useState([]) + const { mutateAsync: convertWorkflowType, isPending: isConvertingWorkflowType } = useConvertWorkflowTypeMutation() + const { + refetch: refetchEvaluationWorkflowAssociatedTargets, + isFetching: isFetchingEvaluationWorkflowAssociatedTargets, + } = useEvaluationWorkflowAssociatedTargets(appDetail?.id, { enabled: false }) + + const workflowTypeSwitchConfig = useMemo(() => { + return getWorkflowTypeSwitchConfig(appDetail?.workflow_kind) + }, [appDetail?.workflow_kind]) + + const workflowTypeSwitchDisabledReason = useMemo(() => { + if (workflowTypeSwitchConfig?.targetType !== AppTypeEnum.EVALUATION) + return undefined + + if (!canAccessSnippetsAndEvaluation) + return t('compliance.sandboxUpgradeTooltip', { ns: 'common' }) + + if (!hasHumanInputNode && !hasTriggerNode) + return undefined + + return t('common.switchToEvaluationWorkflowDisabledTip', { ns: 'workflow' }) + }, [canAccessSnippetsAndEvaluation, hasHumanInputNode, hasTriggerNode, t, workflowTypeSwitchConfig?.targetType]) + + const getWorkflowTypeSwitchPublishUrl = useCallback(() => { + if (!appDetail?.id || !workflowTypeSwitchConfig) + return undefined + + if (workflowTypeSwitchConfig.targetType === AppTypeEnum.EVALUATION) + return `/apps/${appDetail.id}/workflows/publish/evaluation` + + return `/apps/${appDetail.id}/workflows/publish` + }, [appDetail?.id, workflowTypeSwitchConfig]) + + const resetEvaluationWorkflowSwitchConfirm = useCallback(() => { + setShowEvaluationWorkflowSwitchConfirm(false) + setEvaluationWorkflowSwitchTargets([]) + }, []) + + const performWorkflowTypeSwitch = useCallback(async () => { + if (!appDetail?.id || !workflowTypeSwitchConfig) + return false + + try { + if (!publishedAt) { + const publishUrl = getWorkflowTypeSwitchPublishUrl() + if (!publishUrl) + return false + + await onPublish({ + url: publishUrl, + title: '', + releaseNotes: '', + }) + + const latestAppDetail = await fetchAppDetailDirect({ + url: '/apps', + id: appDetail.id, + }) + setAppDetail(latestAppDetail) + resetEvaluationWorkflowSwitchConfirm() + return true + } + + await convertWorkflowType({ + params: { + appId: appDetail.id, + }, + query: { + target_type: workflowTypeSwitchConfig.targetType, + }, + }) + + const latestAppDetail = await fetchAppDetailDirect({ + url: '/apps', + id: appDetail.id, + }) + setAppDetail(latestAppDetail) + onPublishedSwitch() + resetEvaluationWorkflowSwitchConfirm() + return true + } + catch { + return false + } + }, [ + appDetail?.id, + convertWorkflowType, + getWorkflowTypeSwitchPublishUrl, + onPublish, + onPublishedSwitch, + publishedAt, + resetEvaluationWorkflowSwitchConfirm, + setAppDetail, + workflowTypeSwitchConfig, + ]) + + const handleWorkflowTypeSwitch = useCallback(async () => { + if (!appDetail?.id || !workflowTypeSwitchConfig) + return + + if (workflowTypeSwitchDisabledReason) { + toast.error(workflowTypeSwitchDisabledReason) + return + } + + if (appDetail.workflow_kind === AppTypeEnum.EVALUATION && workflowTypeSwitchConfig.targetType === AppTypeEnum.WORKFLOW) { + const associatedTargetsResult = await refetchEvaluationWorkflowAssociatedTargets() + + if (associatedTargetsResult.isError) { + toast.error(t('common.switchToStandardWorkflowConfirm.loadFailed', { ns: 'workflow' })) + return + } + + const associatedTargets = associatedTargetsResult.data?.items ?? [] + if (associatedTargets.length > 0) { + setEvaluationWorkflowSwitchTargets(associatedTargets) + setShowEvaluationWorkflowSwitchConfirm(true) + return + } + } + + await performWorkflowTypeSwitch() + }, [ + appDetail?.id, + appDetail?.workflow_kind, + performWorkflowTypeSwitch, + refetchEvaluationWorkflowAssociatedTargets, + t, + workflowTypeSwitchConfig, + workflowTypeSwitchDisabledReason, + ]) + + const handleEvaluationWorkflowSwitchConfirmOpenChange = useCallback((nextOpen: boolean) => { + setShowEvaluationWorkflowSwitchConfirm(nextOpen) + + if (!nextOpen) + setEvaluationWorkflowSwitchTargets([]) + }, []) + + return { + evaluationWorkflowSwitchTargets, + handleEvaluationWorkflowSwitchConfirmOpenChange, + handleWorkflowTypeSwitch, + isConvertingWorkflowType, + isEvaluationWorkflowType: appDetail?.workflow_kind === AppTypeEnum.EVALUATION, + performWorkflowTypeSwitch, + showEvaluationWorkflowSwitchConfirm, + workflowTypeSwitchConfig, + workflowTypeSwitchDisabled: publishDisabled + || published + || isConvertingWorkflowType + || isFetchingEvaluationWorkflowAssociatedTargets + || Boolean(workflowTypeSwitchDisabledReason), + workflowTypeSwitchDisabledReason, + } +} diff --git a/web/app/components/app/configuration/hooks/use-configuration.ts b/web/app/components/app/configuration/hooks/use-configuration.ts index 943642b545..118e18ec21 100644 --- a/web/app/components/app/configuration/hooks/use-configuration.ts +++ b/web/app/components/app/configuration/hooks/use-configuration.ts @@ -1,5 +1,6 @@ 'use client' import type { ComponentProps } from 'react' +import type { AppPublisherPublishParams } from '@/app/components/app/app-publisher' import type AppPublisher from '@/app/components/app/app-publisher/features-wrapper' import type { ModelAndParameter } from '@/app/components/app/configuration/debug/types' import type { Features as FeaturesData, OnFeaturesChange } from '@/app/components/base/features/types' @@ -21,7 +22,6 @@ import type { TextToSpeechConfig, } from '@/models/debug' import type { VisionSettings } from '@/types/app' -import type { PublishWorkflowParams } from '@/types/workflow' import { useBoolean, useGetState } from 'ahooks' import { clone } from 'es-toolkit/object' import { produce } from 'immer' @@ -481,7 +481,7 @@ export const useConfiguration = (): ConfigurationViewModel => { resolvedModelModeType, ]) - const onPublish = useCallback(async (params?: ModelAndParameter | PublishWorkflowParams, features?: FeaturesData) => { + const onPublish = useCallback(async (params?: AppPublisherPublishParams, features?: FeaturesData) => { const modelAndParameter = params && 'model' in params && 'provider' in params && 'parameters' in params ? params : undefined diff --git a/web/app/components/workflow-app/components/workflow-header/features-trigger.tsx b/web/app/components/workflow-app/components/workflow-header/features-trigger.tsx index a441532a7f..483cd3055d 100644 --- a/web/app/components/workflow-app/components/workflow-header/features-trigger.tsx +++ b/web/app/components/workflow-app/components/workflow-header/features-trigger.tsx @@ -1,11 +1,10 @@ -import type { ModelAndParameter } from '@/app/components/app/configuration/debug/types' +import type { AppPublisherPublishParams } from '@/app/components/app/app-publisher' import type { EndNodeType } from '@/app/components/workflow/nodes/end/types' import type { StartNodeType } from '@/app/components/workflow/nodes/start/types' import type { CommonEdgeType, Node, } from '@/app/components/workflow/types' -import type { PublishWorkflowParams } from '@/types/workflow' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' import { toast } from '@langgenius/dify-ui/toast' @@ -144,7 +143,7 @@ const FeaturesTrigger = () => { const needWarningNodes = useChecklist(nodes, edges) const updatePublishedWorkflow = useInvalidateAppWorkflow() - const onPublish = useCallback(async (params?: ModelAndParameter | PublishWorkflowParams) => { + const onPublish = useCallback(async (params?: AppPublisherPublishParams) => { const publishParams = params && 'title' in params ? params : undefined // First check if there are any items in the checklist // if (!validateBeforeRun()) diff --git a/web/app/components/workflow/utils/evaluation-workflow.ts b/web/app/components/workflow/utils/evaluation-workflow.ts index 40d4b2fb65..b09cb7dca9 100644 --- a/web/app/components/workflow/utils/evaluation-workflow.ts +++ b/web/app/components/workflow/utils/evaluation-workflow.ts @@ -1,3 +1,4 @@ +import type { WorkflowKind } from '@/types/workflow' import { AppTypeEnum } from '@/types/app' import { BlockEnum, TRIGGER_NODE_TYPES } from '../types' @@ -6,7 +7,7 @@ const EVALUATION_WORKFLOW_RESTRICTED_NODE_TYPES = new Set([ ...TRIGGER_NODE_TYPES, ]) -export const isEvaluationWorkflow = (appType?: string) => appType === AppTypeEnum.EVALUATION +export const isEvaluationWorkflow = (appType?: WorkflowKind | null) => appType === AppTypeEnum.EVALUATION export const isEvaluationWorkflowRestrictedNodeType = (nodeType?: string) => { if (!nodeType) diff --git a/web/types/app.ts b/web/types/app.ts index bd468ec75c..829bb6194f 100644 --- a/web/types/app.ts +++ b/web/types/app.ts @@ -9,6 +9,7 @@ import type { WeightedScoreEnum, } from '@/models/datasets' import type { AnnotationReplyConfig, ChatPromptConfig, CompletionPromptConfig, DatasetConfigs, PromptMode } from '@/models/debug' +import type { WorkflowKind } from '@/types/workflow' export type Theme = 'light' | 'dark' | 'system' export const Theme = { @@ -392,7 +393,7 @@ export type App = { /** whether workflow trigger has un-published draft */ has_draft_trigger?: boolean /** Type */ - workflow_kind?: AppTypeEnum + workflow_kind?: WorkflowKind | null } export type AppSSO = { diff --git a/web/types/workflow.ts b/web/types/workflow.ts index 5f342fe401..0d364209b0 100644 --- a/web/types/workflow.ts +++ b/web/types/workflow.ts @@ -429,6 +429,8 @@ export type PublishWorkflowParams = { export type WorkflowTypeConversionTarget = 'workflow' | 'evaluation' +export type WorkflowKind = 'standard' | 'evaluation' + export type UpdateWorkflowParams = { url: string title: string