Skip to content

Commit

Permalink
perf: Workflow Canvas Rendering (#2250)
Browse files Browse the repository at this point in the history
  • Loading branch information
shaohuzhang1 authored Feb 12, 2025
1 parent 9705f6c commit 3336f30
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 53 deletions.
51 changes: 3 additions & 48 deletions ui/src/workflow/common/NodeCascader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,51 +49,12 @@ const wheel = (e: any) => {
function visibleChange(bool: boolean) {
if (bool) {
options.value = getIncomingNode(props.nodeModel.id)
options.value = props.nodeModel.get_up_node_field_list(false, true)
}
}
function _getIncomingNode(id: String, startId: String, value: Array<any>) {
let list = props.nodeModel.graphModel.getNodeIncomingNode(id)
list = list.filter((item: any) => item.id !== startId)
let firstElement = null
if (list.length > 0) {
list.forEach((item: any) => {
if (!value.some((obj: any) => obj.id === item.id)) {
if (!value.some((value_item) => value_item.value === item.id)) {
value.unshift({
value: item.id,
label: item.properties.stepName,
type: item.type,
children: item.properties?.config?.fields || []
})
if (item.properties?.globalFields && item.type === 'start-node') {
firstElement = {
value: 'global',
label: t('views.applicationWorkflow.variable.global'),
type: 'global',
children: item.properties?.config?.globalFields || []
}
}
}
}
})
list.forEach((item: any) => {
_getIncomingNode(item.id, startId, value)
})
}
if (firstElement) {
value.unshift(firstElement)
}
return value
}
function getIncomingNode(id: string) {
return _getIncomingNode(id, id, [])
}
const validate = () => {
const incomingNodeValue = getIncomingNode(props.nodeModel.id)
options.value = incomingNodeValue
const incomingNodeValue = props.nodeModel.get_up_node_field_list(false, true)
if (!data.value || data.value.length === 0) {
return Promise.reject(t('views.applicationWorkflow.variable.ReferencingRequired'))
}
Expand All @@ -113,15 +74,9 @@ const validate = () => {
}
return Promise.resolve('')
}
props.nodeModel.graphModel.eventCenter.on('refresh_incoming_node_field', () => {
options.value = getIncomingNode(props.nodeModel.id)
})
props.nodeModel.graphModel.eventCenter.on('refreshFileUploadConfig', () => {
options.value = getIncomingNode(props.nodeModel.id)
})
defineExpose({ validate })
onMounted(() => {
options.value = getIncomingNode(props.nodeModel.id)
options.value = props.nodeModel.get_up_node_field_list(false, true)
})
</script>
<style scoped></style>
69 changes: 65 additions & 4 deletions ui/src/workflow/common/app-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,25 @@ import i18n from '@/locales'
import { WorkflowType } from '@/enums/workflow'
import { nodeDict } from '@/workflow/common/data'
import { isActive, connect, disconnect } from './teleport'
import { t } from '@/locales'
import { type Dict } from '@/api/type/common'
class AppNode extends HtmlResize.view {
isMounted
r?: any
component: any
app: any
root?: any
VueNode: any
up_node_field_dict?: Dict<Array<any>>
constructor(props: any, VueNode: any) {
super(props)
this.component = VueNode
this.isMounted = false
props.model.clear_next_node_field = this.clear_next_node_field.bind(this)
props.model.get_up_node_field_dict = this.get_up_node_field_dict.bind(this)
props.model.get_node_field_list = this.get_node_field_list.bind(this)
props.model.get_up_node_field_list = this.get_up_node_field_list.bind(this)

if (props.model.properties.noRender) {
delete props.model.properties.noRender
} else {
Expand All @@ -30,21 +38,74 @@ class AppNode extends HtmlResize.view {
}
}
function getNodesName(num: number) {
let number = num
const number = num
const name = props.model.properties.stepName + number
if (!props.graphModel.nodes?.some((node: any) => node.properties.stepName === name.trim())) {
props.model.properties.stepName = name
} else {
number += 1
getNodesName(number)
getNodesName(number + 1)
}
}
props.model.properties.config = nodeDict[props.model.type].properties.config
if (props.model.properties.height) {
props.model.height = props.model.properties.height
}
}
get_node_field_list() {
const result = []
if (this.props.model.type === 'start-node') {
result.push({
value: 'global',
label: t('views.applicationWorkflow.variable.global'),
type: 'global',
children: this.props.model.properties?.config?.globalFields || []
})
}
result.push({
value: this.props.model.id,
label: this.props.model.properties.stepName,
type: this.props.model.type,
children: this.props.model.properties?.config?.fields || []
})
return result
}
get_up_node_field_dict(contain_self: boolean, use_cache: boolean) {
if (!this.up_node_field_dict || !use_cache) {
const up_node_list = this.props.graphModel.getNodeIncomingNode(this.props.model.id)
this.up_node_field_dict = up_node_list
.filter((node) => node.id != 'start-node')
.map((node) => node.get_up_node_field_dict(true, use_cache))
.reduce((pre, next) => ({ ...pre, ...next }), {})
}
if (contain_self) {
return {
...this.up_node_field_dict,
[this.props.model.id]: this.get_node_field_list()
}
}
return this.up_node_field_dict ? this.up_node_field_dict : {}
}

get_up_node_field_list(contain_self: boolean, use_cache: boolean) {
const result = Object.values(this.get_up_node_field_dict(contain_self, use_cache)).reduce(
(pre, next) => [...pre, ...next],
[]
)
const start_node_field_list = this.props.graphModel
.getNodeModelById('start-node')
.get_node_field_list()
return [...start_node_field_list, ...result]
}

clear_next_node_field(contain_self: boolean) {
const next_node_list = this.props.graphModel.getNodeOutgoingNode(this.props.model.id)
next_node_list.forEach((node) => {
node.clear_next_node_field(true)
})
if (contain_self) {
this.up_node_field_dict = undefined
}
}
getAnchorShape(anchorData: any) {
const { x, y, type } = anchorData
let isConnect = false
Expand Down Expand Up @@ -276,7 +337,7 @@ class AppNodeModel extends HtmlResize.model {
}

setAttributes() {
const { t } = i18n.global;
const { t } = i18n.global
this.width = this.get_width()
const isLoop = (node_id: string, target_node_id: string) => {
const up_node_list = this.graphModel.getNodeIncomingNode(node_id)
Expand Down
1 change: 0 additions & 1 deletion ui/src/workflow/common/edge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ class CustomEdge2 extends BezierEdge {
super.componentWillUnmount()
}
if (isActive()) {
console.log('unmount')
disconnect(this.targetId())
}
this.unmountVueComponent()
Expand Down
4 changes: 4 additions & 0 deletions ui/src/workflow/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ const renderGraphData = (data?: any) => {
lf.value.deleteEdge(id)
})
})
lf.value.graphModel.eventCenter.on('anchor:drop', (data: any) => {
// 清除当前节点下面的子节点的所有缓存
data.nodeModel.clear_next_node_field(false)
})
setTimeout(() => {
lf.value?.fitView()
Expand Down

0 comments on commit 3336f30

Please sign in to comment.