fix(web): tool checklist
This commit is contained in:
@@ -79,7 +79,6 @@ const specialValidators: Record<string, (val: any) => boolean> = {
|
||||
}
|
||||
|
||||
function isEmpty(val: any): boolean {
|
||||
console.log('validateNode isEmpty', val, val === undefined || val === null || val === '')
|
||||
if (val === undefined || val === null || val === '') return true
|
||||
if (Array.isArray(val)) return val.length === 0
|
||||
return false
|
||||
@@ -98,7 +97,6 @@ function validateNode(type: string, config: Record<string, any>): CheckError[] {
|
||||
const specialKey = `${type}.${field}`
|
||||
const specialValidator = specialValidators[specialKey]
|
||||
const isInvalid = specialValidator ? specialValidator(val) : isEmpty(val)
|
||||
console.log('validateNode', val, specialKey, specialValidator, isEmpty(val))
|
||||
if (isInvalid) errors.push({ key: specialKey, message: '' })
|
||||
})
|
||||
|
||||
@@ -114,62 +112,6 @@ function validateNode(type: string, config: Record<string, any>): CheckError[] {
|
||||
return errors
|
||||
}
|
||||
|
||||
export async function runCheckOnGraph(
|
||||
graph: import('@antv/x6').Graph,
|
||||
t: (key: string) => string
|
||||
): Promise<NodeCheckResult[]> {
|
||||
const nodes = graph.getNodes()
|
||||
const edges = graph.getEdges()
|
||||
const targetIds = new Set<string>()
|
||||
const childTargetIds = new Set<string>()
|
||||
edges.forEach(e => {
|
||||
targetIds.add(e.getTargetCellId())
|
||||
const srcData = graph.getCellById(e.getSourceCellId())?.getData()
|
||||
const tgtData = graph.getCellById(e.getTargetCellId())?.getData()
|
||||
if (srcData?.cycle && tgtData?.cycle && srcData.cycle === tgtData.cycle) {
|
||||
childTargetIds.add(e.getTargetCellId())
|
||||
}
|
||||
})
|
||||
|
||||
const checked: NodeCheckResult[] = []
|
||||
for (const node of nodes) {
|
||||
const data = node.getData()
|
||||
if (!data || ['add-node', 'notes', 'cycle-start', 'break'].includes(data.type)) continue
|
||||
|
||||
const errors: CheckError[] = []
|
||||
const isChildNode = !!data.cycle
|
||||
const hasIncoming = isChildNode ? childTargetIds.has(node.id) : !['start', 'cycle-start'].includes(data.type) ? targetIds.has(node.id) : true
|
||||
if (!hasIncoming) errors.push({ key: 'notConnected', message: t('workflow.notConnected') })
|
||||
|
||||
const configErrors = validateNode(data.type, data.config ?? {})
|
||||
configErrors.forEach(e => {
|
||||
errors.push({ key: e.key, message: `${t(`workflow.checkListErrors.${e.key}`)} ${t('workflow.cannotBeEmpty')}`.trim() })
|
||||
})
|
||||
|
||||
if (data.type === 'tool') {
|
||||
const toolId = data.config?.tool_id?.defaultValue ?? data.config?.tool_id
|
||||
const toolParameters = data.config?.tool_parameters?.defaultValue ?? data.config?.tool_parameters ?? {}
|
||||
if (toolId) {
|
||||
try {
|
||||
const methods = await getToolMethods(toolId) as Array<{ name: string; parameters: Array<{ name: string; required: boolean }> }>
|
||||
const operation = toolParameters?.operation
|
||||
const method = operation ? methods.find(m => m.name === operation) : methods[0]
|
||||
if (method) {
|
||||
method.parameters
|
||||
.filter(p => p.required && (toolParameters[p.name] === undefined || toolParameters[p.name] === null || toolParameters[p.name] === ''))
|
||||
.forEach(p => errors.push({ key: 'tool.tool_parameters', message: `${p.name} ${t('workflow.cannotBeEmpty')}` }))
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
checked.push({ id: node.id, name: data.name || t(`workflow.${data.type}`), type: data.type, icon: nodeIconMap[data.type] ?? '', errors })
|
||||
}
|
||||
}
|
||||
return checked
|
||||
}
|
||||
|
||||
const CheckList: FC<CheckListProps> = ({ workflowRef, appId }) => {
|
||||
const { t } = useTranslation()
|
||||
const [open, setOpen] = useState(false)
|
||||
@@ -222,7 +164,8 @@ const CheckList: FC<CheckListProps> = ({ workflowRef, appId }) => {
|
||||
if (data.type === 'tool') {
|
||||
const toolId = data.config?.tool_id?.defaultValue ?? data.config?.tool_id
|
||||
const toolParameters = data.config?.tool_parameters?.defaultValue ?? data.config?.tool_parameters ?? {}
|
||||
if (toolId) {
|
||||
|
||||
if (typeof toolId === 'string') {
|
||||
try {
|
||||
const methods = await getToolMethods(toolId) as Array<{ name: string; parameters: Array<{ name: string; required: boolean }> }>
|
||||
const operation = toolParameters?.operation
|
||||
@@ -251,21 +194,27 @@ const CheckList: FC<CheckListProps> = ({ workflowRef, appId }) => {
|
||||
return checked
|
||||
}, [workflowRef.current?.graphRef?.current, t])
|
||||
|
||||
const scheduleCheckRef = useRef<() => void>()
|
||||
|
||||
const scheduleCheck = useCallback(() => {
|
||||
clearTimeout(timerRef.current)
|
||||
timerRef.current = setTimeout(async () => {
|
||||
setCheckResults(appId, await runCheck())
|
||||
}, 500)
|
||||
}, 300)
|
||||
}, [runCheck])
|
||||
|
||||
scheduleCheckRef.current = scheduleCheck
|
||||
|
||||
useEffect(() => {
|
||||
const graph = workflowRef.current?.graphRef?.current
|
||||
console.log('graph')
|
||||
if (!graph) return
|
||||
const events = ['node:added', 'node:removed', 'node:change:data', 'edge:added', 'edge:removed']
|
||||
events.forEach(e => graph.on(e, scheduleCheck))
|
||||
scheduleCheck()
|
||||
const handler = () => scheduleCheckRef.current?.()
|
||||
const events = ['node:added', 'node:removed', 'node:change:data', 'edge:added', 'edge:removed', 'edge:connected', 'edge:changed']
|
||||
events.forEach(e => graph.on(e, handler))
|
||||
scheduleCheckRef.current?.()
|
||||
return () => {
|
||||
events.forEach(e => graph.off(e, scheduleCheck))
|
||||
events.forEach(e => graph.off(e, handler))
|
||||
clearTimeout(timerRef.current)
|
||||
}
|
||||
}, [workflowRef.current?.graphRef?.current])
|
||||
|
||||
Reference in New Issue
Block a user