mirror of
https://github.com/langgenius/dify.git
synced 2026-04-28 20:17:29 +08:00
feat: check before run
This commit is contained in:
parent
68f947c7e0
commit
ff5ab43f9c
@ -90,6 +90,17 @@ const FormItem: FC<Props> = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
type === InputVarType.json && (
|
||||||
|
<CodeEditor
|
||||||
|
value={value}
|
||||||
|
title={<span>JSON</span>}
|
||||||
|
language={CodeLanguage.json}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
type === InputVarType.files && (
|
type === InputVarType.files && (
|
||||||
<TextGenerationImageUploader
|
<TextGenerationImageUploader
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React from 'react'
|
import React, { useCallback } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import type { Props as FormProps } from './form'
|
import type { Props as FormProps } from './form'
|
||||||
@ -9,8 +9,9 @@ import Button from '@/app/components/base/button'
|
|||||||
import { StopCircle } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
|
import { StopCircle } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
|
||||||
import { Loading02, XClose } from '@/app/components/base/icons/src/vender/line/general'
|
import { Loading02, XClose } from '@/app/components/base/icons/src/vender/line/general'
|
||||||
import Split from '@/app/components/workflow/nodes/_base/components/split'
|
import Split from '@/app/components/workflow/nodes/_base/components/split'
|
||||||
import { NodeRunningStatus } from '@/app/components/workflow/types'
|
import { InputVarType, NodeRunningStatus } from '@/app/components/workflow/types'
|
||||||
import ResultPanel from '@/app/components/workflow/run/result-panel'
|
import ResultPanel from '@/app/components/workflow/run/result-panel'
|
||||||
|
import Toast from '@/app/components/base/toast'
|
||||||
|
|
||||||
const i18nPrefix = 'workflow.singleRun'
|
const i18nPrefix = 'workflow.singleRun'
|
||||||
|
|
||||||
@ -36,6 +37,26 @@ const BeforeRunForm: FC<BeforeRunFormProps> = ({
|
|||||||
|
|
||||||
const isFinished = runningStatus === NodeRunningStatus.Succeeded || runningStatus === NodeRunningStatus.Failed
|
const isFinished = runningStatus === NodeRunningStatus.Succeeded || runningStatus === NodeRunningStatus.Failed
|
||||||
const isRunning = runningStatus === NodeRunningStatus.Running
|
const isRunning = runningStatus === NodeRunningStatus.Running
|
||||||
|
|
||||||
|
const handleRun = useCallback(() => {
|
||||||
|
let errMsg = ''
|
||||||
|
forms.forEach((form) => {
|
||||||
|
form.inputs.forEach((input) => {
|
||||||
|
const value = form.values[input.variable]
|
||||||
|
if (!errMsg && input.required && (value === '' || value === undefined || value === null || (input.type === InputVarType.files && value.length === 0)))
|
||||||
|
errMsg = t('workflow.errorMsg.fieldRequired', { field: input.label })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if (errMsg) {
|
||||||
|
Toast.notify({
|
||||||
|
message: errMsg,
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
onRun()
|
||||||
|
}, [forms, onRun, t])
|
||||||
return (
|
return (
|
||||||
<div className='absolute inset-0 z-10 rounded-2xl pt-10' style={{
|
<div className='absolute inset-0 z-10 rounded-2xl pt-10' style={{
|
||||||
backgroundColor: 'rgba(16, 24, 40, 0.20)',
|
backgroundColor: 'rgba(16, 24, 40, 0.20)',
|
||||||
@ -73,7 +94,7 @@ const BeforeRunForm: FC<BeforeRunFormProps> = ({
|
|||||||
<StopCircle className='w-4 h-4 text-gray-500' />
|
<StopCircle className='w-4 h-4 text-gray-500' />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Button disabled={isRunning} type='primary' className='w-0 grow !h-8 flex items-center space-x-2' onClick={onRun}>
|
<Button disabled={isRunning} type='primary' className='w-0 grow !h-8 flex items-center space-x-2' onClick={handleRun}>
|
||||||
{isRunning && <Loading02 className='animate-spin w-4 h-4 text-white' />}
|
{isRunning && <Loading02 className='animate-spin w-4 h-4 text-white' />}
|
||||||
<div>{t(`${i18nPrefix}.${isRunning ? 'running' : 'startRun'}`)}</div>
|
<div>{t(`${i18nPrefix}.${isRunning ? 'running' : 'startRun'}`)}</div>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
} from '@/app/components/workflow/hooks'
|
} from '@/app/components/workflow/hooks'
|
||||||
import { toNodeOutputVars } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
import { toNodeOutputVars } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
||||||
|
|
||||||
import type { CheckValidRes, CommonNodeType, InputVar, ValueSelector, Var, Variable } from '@/app/components/workflow/types'
|
import type { CommonNodeType, InputVar, ValueSelector, Var, Variable } from '@/app/components/workflow/types'
|
||||||
import { BlockEnum, InputVarType, NodeRunningStatus, VarType } from '@/app/components/workflow/types'
|
import { BlockEnum, InputVarType, NodeRunningStatus, VarType } from '@/app/components/workflow/types'
|
||||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||||
import { singleNodeRun } from '@/service/workflow'
|
import { singleNodeRun } from '@/service/workflow'
|
||||||
@ -25,7 +25,7 @@ type Params<T> = {
|
|||||||
id: string
|
id: string
|
||||||
data: CommonNodeType<T>
|
data: CommonNodeType<T>
|
||||||
defaultRunInputData: Record<string, any>
|
defaultRunInputData: Record<string, any>
|
||||||
beforeRunCheckValid?: () => CheckValidRes
|
// beforeRunCheckValid?: () => CheckValidRes // has checked before run button clicked
|
||||||
}
|
}
|
||||||
|
|
||||||
const varTypeToInputVarType = (type: VarType, {
|
const varTypeToInputVarType = (type: VarType, {
|
||||||
@ -53,7 +53,7 @@ const useOneStepRun = <T>({
|
|||||||
id,
|
id,
|
||||||
data,
|
data,
|
||||||
defaultRunInputData,
|
defaultRunInputData,
|
||||||
beforeRunCheckValid = () => ({ isValid: true }),
|
// beforeRunCheckValid = () => ({ isValid: true }),
|
||||||
}: Params<T>) => {
|
}: Params<T>) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { getBeforeNodesInSameBranch } = useWorkflow()
|
const { getBeforeNodesInSameBranch } = useWorkflow()
|
||||||
@ -91,6 +91,11 @@ const useOneStepRun = <T>({
|
|||||||
const [canShowSingleRun, setCanShowSingleRun] = useState(false)
|
const [canShowSingleRun, setCanShowSingleRun] = useState(false)
|
||||||
const isShowSingleRun = data._isSingleRun && canShowSingleRun
|
const isShowSingleRun = data._isSingleRun && canShowSingleRun
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!checkValid) {
|
||||||
|
setCanShowSingleRun(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (data._isSingleRun) {
|
if (data._isSingleRun) {
|
||||||
const { isValid, errorMessage } = checkValid(data, t)
|
const { isValid, errorMessage } = checkValid(data, t)
|
||||||
setCanShowSingleRun(isValid)
|
setCanShowSingleRun(isValid)
|
||||||
@ -122,14 +127,14 @@ const useOneStepRun = <T>({
|
|||||||
const runningStatus = data._singleRunningStatus || NodeRunningStatus.NotStart
|
const runningStatus = data._singleRunningStatus || NodeRunningStatus.NotStart
|
||||||
const isCompleted = runningStatus === NodeRunningStatus.Succeeded || runningStatus === NodeRunningStatus.Failed
|
const isCompleted = runningStatus === NodeRunningStatus.Succeeded || runningStatus === NodeRunningStatus.Failed
|
||||||
const handleRun = async () => {
|
const handleRun = async () => {
|
||||||
const { isValid, errorMessage } = beforeRunCheckValid()
|
// const { isValid, errorMessage } = beforeRunCheckValid()
|
||||||
if (!isValid) {
|
// if (!isValid) {
|
||||||
Toast.notify({
|
// Toast.notify({
|
||||||
type: 'error',
|
// type: 'error',
|
||||||
message: errorMessage!,
|
// message: errorMessage!,
|
||||||
})
|
// })
|
||||||
return false
|
// return false
|
||||||
}
|
// }
|
||||||
handleNodeDataUpdate({
|
handleNodeDataUpdate({
|
||||||
id,
|
id,
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@ -48,12 +48,6 @@ const useConfig = (id: string, payload: CodeNodeType) => {
|
|||||||
id,
|
id,
|
||||||
data: inputs,
|
data: inputs,
|
||||||
defaultRunInputData: {},
|
defaultRunInputData: {},
|
||||||
beforeRunCheckValid: () => {
|
|
||||||
return {
|
|
||||||
isValid: true,
|
|
||||||
// errorMessage: 'xxxx',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const varInputs = toVarInputs(inputs.variables)
|
const varInputs = toVarInputs(inputs.variables)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user