fix(web): workflow switch to evaluation

This commit is contained in:
JzoNg 2026-04-29 22:25:47 +08:00
parent 00319f0e43
commit b0478f4df7
9 changed files with 295 additions and 192 deletions

View File

@ -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<AppPublisherProps, 'onPublish'> & {
onPublish?: (params?: ModelAndParameter | PublishWorkflowParams, features?: any) => Promise<any> | any
publishedConfig?: any
onPublish?: (params?: AppPublisherPublishParams, features?: Features) => Promise<unknown> | 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])

View File

@ -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<PublishWorkflowParams, 'title' | 'releaseNotes'> & {
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> | any
onRestore?: () => Promise<any> | any
onPublish?: (params?: AppPublisherPublishParams) => Promise<unknown> | unknown
onRestore?: () => Promise<unknown> | 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<WorkflowTypeConversionTarget, {
targetType: WorkflowTypeConversionTarget
publishLabelKey: WorkflowTypeSwitchLabelKey
switchLabelKey: WorkflowTypeSwitchLabelKey
tipKey: WorkflowTypeSwitchLabelKey
}> = {
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<EvaluationWorkflowAssociatedTarget[]>([])
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}
/>

View File

@ -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<AppPublisherProps, | 'debugWithMultipleModel'
| 'draftUpdatedAt'
| 'multipleModelConfigs'
@ -37,12 +35,7 @@ type SummarySectionProps = Pick<AppPublisherProps, | 'debugWithMultipleModel'
published: boolean
publishShortcut: string[]
upgradeHighlightStyle: CSSProperties
workflowTypeSwitchConfig?: {
targetType: WorkflowTypeConversionTarget
publishLabelKey: WorkflowTypeSwitchLabelKey
switchLabelKey: WorkflowTypeSwitchLabelKey
tipKey: WorkflowTypeSwitchLabelKey
}
workflowTypeSwitchConfig?: WorkflowTypeSwitchConfig
workflowTypeSwitchDisabled: boolean
workflowTypeSwitchDisabledReason?: string
}

View File

@ -0,0 +1,229 @@
import type { ModelAndParameter } from '../configuration/debug/types'
import type { App, AppSSO } from '@/types/app'
import type { EvaluationWorkflowAssociatedTarget } from '@/types/evaluation'
import type { I18nKeysWithPrefix } from '@/types/i18n'
import type { PublishWorkflowParams, WorkflowKind, WorkflowTypeConversionTarget } from '@/types/workflow'
import { toast } from '@langgenius/dify-ui/toast'
import { useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { fetchAppDetailDirect } from '@/service/apps'
import { useConvertWorkflowTypeMutation } from '@/service/use-apps'
import { useEvaluationWorkflowAssociatedTargets } from '@/service/use-evaluation'
import { AppTypeEnum } from '@/types/app'
type WorkflowTypeSwitchLabelKey = I18nKeysWithPrefix<'workflow', 'common.'>
export type WorkflowTypeSwitchConfig = {
targetType: WorkflowTypeConversionTarget
publishLabelKey: WorkflowTypeSwitchLabelKey
switchLabelKey: WorkflowTypeSwitchLabelKey
tipKey: WorkflowTypeSwitchLabelKey
}
const WORKFLOW_TYPE_SWITCH_CONFIG: Record<WorkflowTypeConversionTarget, WorkflowTypeSwitchConfig> = {
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<AppSSO>
canAccessSnippetsAndEvaluation: boolean
hasHumanInputNode: boolean
hasTriggerNode: boolean
onPublish: (params?: ModelAndParameter | PublishWorkflowParams) => Promise<void>
onPublishedSwitch: () => void
published: boolean
publishedAt?: number
publishDisabled: boolean
setAppDetail: (appDetail?: App & Partial<AppSSO>) => 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<EvaluationWorkflowAssociatedTarget[]>([])
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,
}
}

View File

@ -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

View File

@ -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())

View File

@ -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<string>([
...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)

View File

@ -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 = {

View File

@ -429,6 +429,8 @@ export type PublishWorkflowParams = {
export type WorkflowTypeConversionTarget = 'workflow' | 'evaluation'
export type WorkflowKind = 'standard' | 'evaluation'
export type UpdateWorkflowParams = {
url: string
title: string