From b5ac8285adb125416b970836347a6720a58ae6a4 Mon Sep 17 00:00:00 2001 From: Feynman Date: Thu, 24 Apr 2025 16:42:38 +0800 Subject: [PATCH 01/20] feat: synchronize settings with form values in SettingPanel component - Added a new watcher for `settings` to update the form values only when they differ, preventing unnecessary updates. - Implemented a method to sync form values with settings on changes, ensuring data consistency. - Enhanced the `created` lifecycle hook to include effects for syncing settings with form fields, avoiding infinite loops. - Refactored the `syncFormWithSettings` method to streamline the process of updating form values based on settings changes. --- .../src/components/migration/SettingPanel.vue | 49 ++ packages/dag/src/mixins/editor.js | 693 ++++++++++++------ packages/form/src/components/input/index.jsx | 3 +- 3 files changed, 500 insertions(+), 245 deletions(-) diff --git a/packages/dag/src/components/migration/SettingPanel.vue b/packages/dag/src/components/migration/SettingPanel.vue index 143697bfb0..0ed0aa6403 100644 --- a/packages/dag/src/components/migration/SettingPanel.vue +++ b/packages/dag/src/components/migration/SettingPanel.vue @@ -1548,6 +1548,16 @@ export default observer({ }, immediate: true, }, + + settings: { + handler(newSettings) { + // Only update if different to avoid loops + if (JSON.stringify(this.form.values) !== JSON.stringify(newSettings)) { + this.syncFormWithSettings() + } + }, + deep: true, + }, }, created() { @@ -1556,6 +1566,41 @@ export default observer({ this.lazySavePermissionsConfig = debounce(this.savePermissionsConfig, 300) this.getRolePermissions() + + // FIXME + this.form.addEffects('settingsSync', () => { + onFieldValueChange('*', (field) => { + if (field.path && field.path.length > 0) { + // Get the path as string (e.g., "name" or "syncPoints.0.dateTime") + const path = field.path.toString() + const pathArr = path.split('.') + + // Skip if the value is the same to avoid infinite loops + if (path in this.settings) { + const currentValue = this.settings[path] + if (JSON.stringify(currentValue) !== JSON.stringify(field.value)) { + this.settings[path] = field.value + } + } else { + // For nested paths, use property access to update deeply nested values + let obj = this.settings + const parts = pathArr.slice() + const lastPart = parts.pop() + + for (const part of parts) { + if (!(part in obj)) { + obj[part] = {} + } + obj = obj[part] + } + + if (JSON.stringify(obj[lastPart]) !== JSON.stringify(field.value)) { + obj[lastPart] = field.value + } + } + } + }) + }) }, mounted() { @@ -1634,6 +1679,10 @@ export default observer({ }) || [] }) }, + + syncFormWithSettings() { + this.form.setValues(this.settings) + }, }, }) diff --git a/packages/dag/src/mixins/editor.js b/packages/dag/src/mixins/editor.js index 1f3f6f5fdb..9d2b97c4c1 100644 --- a/packages/dag/src/mixins/editor.js +++ b/packages/dag/src/mixins/editor.js @@ -1,32 +1,47 @@ -import { h } from 'vue' -import { $on, $off, $once, $emit } from '../../utils/gogocodeTransfer' -import dayjs from 'dayjs' +import { observable } from '@formily/reactive' +import { + databaseTypesApi, + dataPermissionApi, + sharedCacheApi, + taskApi, +} from '@tap/api' +import { makeStatusAndDisabled } from '@tap/business' +import { showErrorMessage } from '@tap/business/src/components/error-message' +import resize from '@tap/component/src/directives/resize' +import { computed as reactiveComputed } from '@tap/form' +import { validateBySchema } from '@tap/form/src/shared/validate' import i18n from '@tap/i18n' +import { setPageTitle } from '@tap/shared' +import dagre from 'dagre' +import dayjs from 'dayjs' import { merge } from 'lodash-es' import Mousetrap from 'mousetrap' -import { databaseTypesApi, dataPermissionApi, sharedCacheApi, taskApi } from '@tap/api' -import { makeStatusAndDisabled } from '@tap/business' -import { connectorActiveStyle } from '../style' -import { DEFAULT_SETTINGS, NODE_HEIGHT, NODE_PREFIX, NODE_WIDTH } from '../constants' +import { h, markRaw } from 'vue' +import { mapActions, mapGetters, mapMutations, mapState } from 'vuex' +import { $emit, $off, $on, $once } from '../../utils/gogocodeTransfer' import { AddConnectionCommand, AddNodeCommand, AddNodeOnConnectionCommand, CommandManager, MoveNodeCommand, - QuickAddTargetCommand, QuickAddSourceCommand, + QuickAddTargetCommand, RemoveConnectionCommand, RemoveNodeCommand, } from '../command' -import { mapActions, mapGetters, mapMutations, mapState } from 'vuex' -import dagre from 'dagre' -import { validateBySchema } from '@tap/form/src/shared/validate' -import resize from '@tap/component/src/directives/resize' -import { observable } from '@formily/reactive' -import { setPageTitle } from '@tap/shared' -import { getSchema, getTableRenameByConfig, ifTableNameConfigEmpty } from '../util' -import { showErrorMessage } from '@tap/business/src/components/error-message' +import { + DEFAULT_SETTINGS, + NODE_HEIGHT, + NODE_PREFIX, + NODE_WIDTH, +} from '../constants' +import { connectorActiveStyle } from '../style' +import { + getSchema, + getTableRenameByConfig, + ifTableNameConfigEmpty, +} from '../util' export default { directives: { @@ -55,7 +70,11 @@ export default { } }, computed: { - ...mapState('dataflow', ['activeNodeId', 'showConsole', 'transformLoading']), + ...mapState('dataflow', [ + 'activeNodeId', + 'showConsole', + 'transformLoading', + ]), ...mapGetters('dataflow', [ 'allNodes', 'allEdges', @@ -69,13 +88,13 @@ export default { ]), selectBoxStyle() { - let attr = this.selectBoxAttr + const attr = this.selectBoxAttr return attr ? { - left: attr.x + 'px', - top: attr.y + 'px', - width: attr.w + 'px', - height: attr.h + 'px', + left: `${attr.x}px`, + top: `${attr.y}px`, + width: `${attr.w}px`, + height: `${attr.h}px`, } : null }, @@ -153,8 +172,8 @@ export default { const inputsMap = {} edges.forEach(({ source, target }) => { - let _source = outputsMap[source] - let _target = inputsMap[target] + const _source = outputsMap[source] + const _target = inputsMap[target] if (!_source) { outputsMap[source] = [target] @@ -204,8 +223,13 @@ export default { // 连线 edges.forEach(({ source, target }) => { this.jsPlumbIns.connect({ - uuids: [`${NODE_PREFIX}${source}_source`, `${NODE_PREFIX}${target}_target`], - cssClass: this.nodeById(source).attrs.disabled ? 'connection-disabled' : '', + uuids: [ + `${NODE_PREFIX}${source}_source`, + `${NODE_PREFIX}${target}_target`, + ], + cssClass: this.nodeById(source).attrs.disabled + ? 'connection-disabled' + : '', }) }) }, @@ -240,7 +264,7 @@ export default { this.allNodes.forEach((node) => { const sharedCache = [] - for (let key in usedShareCache) { + for (const key in usedShareCache) { if (usedShareCache[key].includes(node.id)) { const item = this.sharedCacheMap[key] || {} item.id && @@ -263,7 +287,10 @@ export default { // 心跳任务、共享缓存 if (['connHeartbeat', 'shareCache'].includes(syncType)) { flag = true - } else if (['logCollector'].includes(syncType) && type === 'hazelcastIMDG') { + } else if ( + ['logCollector'].includes(syncType) && + type === 'hazelcastIMDG' + ) { // 共享挖掘,目标节点 flag = true } @@ -287,7 +314,10 @@ export default { let { allowSource } = target.__Ctor allowSource = typeof allowSource === 'boolean' ? allowSource : true const connectionType = target.attrs.connectionType - if (!allowSource || (connectionType && !connectionType.includes('target'))) { + if ( + !allowSource || + (connectionType && !connectionType.includes('target')) + ) { showMsg && this.$message.error( i18n.t('packages_dag_node_only_as_source', { @@ -303,7 +333,10 @@ export default { let { allowTarget } = source.__Ctor allowTarget = typeof allowTarget === 'boolean' ? allowTarget : true const connectionType = source.attrs.connectionType - if (!allowTarget || (connectionType && !connectionType.includes('source'))) { + if ( + !allowTarget || + (connectionType && !connectionType.includes('source')) + ) { showMsg && this.$message.error( i18n.t('packages_dag_node_only_as_target', { @@ -322,7 +355,10 @@ export default { }) if (maxInputs !== -1 && connections.length >= maxInputs) { - showMsg && this.$message.error(i18n.t('packages_dag_mixins_editor_gaijiedianyijing')) + showMsg && + this.$message.error( + i18n.t('packages_dag_mixins_editor_gaijiedianyijing'), + ) return false } return true @@ -335,7 +371,10 @@ export default { }) if (maxOutputs !== -1 && connections.length >= maxOutputs) { - showMsg && this.$message.error(i18n.t('packages_dag_mixins_editor_gaijiedianyijing')) + showMsg && + this.$message.error( + i18n.t('packages_dag_mixins_editor_gaijiedianyijing'), + ) return false } return true @@ -378,7 +417,10 @@ export default { if (target.attrs.disabled) return false if (!this.checkAsTarget(target, showMsg)) return false if (!this.checkTargetMaxInputs(target, showMsg)) return false - return this.allowConnect(sourceId, targetId) && this.checkAllowTargetOrSource(source, target, showMsg) + return ( + this.allowConnect(sourceId, targetId) && + this.checkAllowTargetOrSource(source, target, showMsg) + ) }, checkGotoViewer() { @@ -410,7 +452,7 @@ export default { }) let def = 1 if (taskNames?.items.length) { - let arr = [0] + const arr = [0] taskNames.items.forEach((item) => { const res = item.name.match(new RegExp(`^${source}(\\d+)$`)) if (res && res[1]) arr.push(+res[1]) @@ -451,10 +493,10 @@ export default { onNodeDragMove(param) { if (!this.ifNodeDragStart) return - let { id, pos } = param - let nw = param.el.offsetWidth - let nh = param.el.offsetHeight - let diffPos = { x: 0, y: 0 } + const { id, pos } = param + const nw = param.el.offsetWidth + const nh = param.el.offsetHeight + const diffPos = { x: 0, y: 0 } let horiArr = [] let verArr = [] let rangeX = 10 @@ -462,9 +504,9 @@ export default { this.allNodes.forEach((item) => { if (item.id !== id) { - let [x, y] = item.attrs.position - let _x = x - pos[0] - let _y = y - pos[1] + const [x, y] = item.attrs.position + const _x = x - pos[0] + const _y = y - pos[1] if (Math.abs(_x) <= Math.abs(rangeX)) { if (_x === rangeX) { verArr.push(y) @@ -489,8 +531,8 @@ export default { pos[0] += diffPos.x pos[1] += diffPos.y - param.el.style.left = pos[0] + 'px' - param.el.style.top = pos[1] + 'px' + param.el.style.left = `${pos[0]}px` + param.el.style.top = `${pos[1]}px` this.jsPlumbIns.revalidate(param.el) // 重绘 let t = pos[1], @@ -507,51 +549,51 @@ export default { }) // 组装导航线 - let lines = [] + const lines = [] if (t < pos[1]) { - let top = t + 'px', - height = pos[1] - t + 'px' + const top = `${t}px`, + height = `${pos[1] - t}px` lines.push( { top, - left: pos[0] + 'px', + left: `${pos[0]}px`, height, }, { top, - left: pos[0] + nw + 'px', + left: `${pos[0] + nw}px`, height, }, ) } if (b > pos[1] + nh) { - let top = pos[1] + nh + 'px', - height = b - pos[1] - nh + 'px' + const top = `${pos[1] + nh}px`, + height = `${b - pos[1] - nh}px` lines.push( { top, - left: pos[0] + 'px', + left: `${pos[0]}px`, height, }, { top, - left: pos[0] + nw + 'px', + left: `${pos[0] + nw}px`, height, }, ) } if (l < pos[0]) { - let left = l + 'px', - width = pos[0] - l + 'px' + const left = `${l}px`, + width = `${pos[0] - l}px` lines.push( { - top: pos[1] + 'px', + top: `${pos[1]}px`, left, width, }, { - top: pos[1] + nh + 'px', + top: `${pos[1] + nh}px`, left, width, }, @@ -559,16 +601,16 @@ export default { } if (r > pos[0] + nw) { - let left = pos[0] + nw + 'px', - width = r - pos[0] - nw + 'px' + const left = `${pos[0] + nw}px`, + width = `${r - pos[0] - nw}px` lines.push( { - top: pos[1] + 'px', + top: `${pos[1]}px`, left, width, }, { - top: pos[1] + nh + 'px', + top: `${pos[1] + nh}px`, left, width, }, @@ -583,7 +625,8 @@ export default { this.$refs.paperScroller.autoResizePaper() - !isNotMove && this.command.exec(new MoveNodeCommand(oldProperties, newProperties)) + !isNotMove && + this.command.exec(new MoveNodeCommand(oldProperties, newProperties)) }, nodeSelectedById(id, setActive, deselectAllOthers) { @@ -668,11 +711,11 @@ export default { }, getNodesInSelection(selectBoxAttr) { - let $node = this.$refs.layoutContent.querySelector('.df-node') + const $node = this.$refs.layoutContent.querySelector('.df-node') if (!$node) return [] - let nw = $node.offsetWidth - let nh = $node.offsetHeight - let { x, y, bottom, right } = selectBoxAttr + const nw = $node.offsetWidth + const nh = $node.offsetHeight + const { x, y, bottom, right } = selectBoxAttr return this.allNodes.filter((node) => { const [left, top] = node.attrs.position @@ -687,7 +730,7 @@ export default { return source.type === 'database' } - for (let edge of sourceMap[source.id]) { + for (const edge of sourceMap[source.id]) { if (!this.isEndOfTable(nodeMap[edge.target], sourceMap, nodeMap)) { return false } @@ -699,16 +742,18 @@ export default { reformDataflow(data, fromWS) { makeStatusAndDisabled(data) if (data.status === 'edit') data.btnDisabled.start = false // 任务编辑中,在编辑页面可以启动 - this.dataflow['status'] = data.status - this.dataflow['disabledData'] = data.btnDisabled - this.dataflow['taskRecordId'] = data.taskRecordId - this.dataflow['stopTime'] = data.stopTime - this.dataflow['startTime'] = data.startTime - this.dataflow['lastStartDate'] = data.lastStartDate - this.dataflow['pingTime'] = data.pingTime + this.dataflow.status = data.status + this.dataflow.disabledData = data.btnDisabled + this.dataflow.taskRecordId = data.taskRecordId + this.dataflow.stopTime = data.stopTime + this.dataflow.startTime = data.startTime + this.dataflow.lastStartDate = data.lastStartDate + this.dataflow.pingTime = data.pingTime if (data.currentEventTimestamp) { - this.dataflow.currentEventTimestampLabel = dayjs(data.currentEventTimestamp).format('YYYY-MM-DD HH:mm:ss') + this.dataflow.currentEventTimestampLabel = dayjs( + data.currentEventTimestamp, + ).format('YYYY-MM-DD HH:mm:ss') } // this.$set(this.dataflow, 'shareCdcStop', data.shareCdcStop) @@ -727,7 +772,13 @@ export default { } }, - async confirmMessage(message, headline, type, confirmButtonText, cancelButtonText) { + async confirmMessage( + message, + headline, + type, + confirmButtonText, + cancelButtonText, + ) { try { await this.$confirm(message, headline, { confirmButtonText, @@ -736,7 +787,7 @@ export default { dangerouslyUseHTMLString: true, }) return true - } catch (e) { + } catch { return false } }, @@ -773,13 +824,21 @@ export default { this.initNodeView() } const routeName = this.$route.name - if (['DataflowViewer', 'MigrationMonitor', 'MigrateViewer', 'TaskMonitor'].includes(routeName)) { + if ( + [ + 'DataflowViewer', + 'MigrationMonitor', + 'MigrateViewer', + 'TaskMonitor', + ].includes(routeName) + ) { await this.openDataflow(id) // await this.startLoop() this.setStateReadonly(true) if ( routeName === 'MigrateViewer' || - (routeName === 'DataflowViewer' && ['renewing', 'renew_failed'].includes(this.dataflow.status)) + (routeName === 'DataflowViewer' && + ['renewing', 'renew_failed'].includes(this.dataflow.status)) ) { this.handleConsoleAutoLoad() } @@ -824,14 +883,22 @@ export default { this.$refs.paperScroller.toggleMiniView() }) Mousetrap(this.$refs.layoutContent).bind(['backspace', 'del'], () => { - if (!this.stateIsReadonly && document.getElementById('dfEditorContent').contains(document.activeElement)) { + if ( + !this.stateIsReadonly && + document + .querySelector('#dfEditorContent') + .contains(document.activeElement) + ) { this.handleDelete() } }) - Mousetrap(this.$refs.layoutContent).bind(['option+command+l', 'ctrl+alt+l'], (e) => { - e.preventDefault() - this.handleAutoLayout() - }) + Mousetrap(this.$refs.layoutContent).bind( + ['option+command+l', 'ctrl+alt+l'], + (e) => { + e.preventDefault() + this.handleAutoLayout() + }, + ) }, initNodeView() { @@ -847,7 +914,11 @@ export default { const connectionIns = info.connection info.connection.bind('click', () => { - if (this.stateIsReadonly || connectionIns.hasClass('connection-disabled')) return + if ( + this.stateIsReadonly || + connectionIns.hasClass('connection-disabled') + ) + return this.handleDeselectAllConnections() info.connection.showOverlay('removeConn') info.connection.showOverlay('addNodeOnConn') @@ -855,7 +926,11 @@ export default { this.selectConnection(connection) }) info.connection.bind('mouseover', () => { - if (this.stateIsReadonly || connectionIns.hasClass('connection-disabled')) return + if ( + this.stateIsReadonly || + connectionIns.hasClass('connection-disabled') + ) + return info.connection.showOverlay('removeConn') info.connection.showOverlay('addNodeOnConn') @@ -879,7 +954,9 @@ export default { location: 0.35, create() { const div = document.createElement('div') - div.title = i18n.t('packages_dag_components_dfnode_tianjiajiedian') + div.title = i18n.t( + 'packages_dag_components_dfnode_tianjiajiedian', + ) div.classList.add('conn-btn__wrap') div.innerHTML = `
` return div @@ -888,8 +965,15 @@ export default { events: { click: async (overlay) => { const rect = info.connection.canvas.getBoundingClientRect() - this.nodeMenu.connectionCenterPos = [rect.x + rect.width / 2, rect.y + rect.height / 2] - await this.showNodePopover('connection', connection, overlay.canvas) + this.nodeMenu.connectionCenterPos = [ + rect.x + rect.width / 2, + rect.y + rect.height / 2, + ] + await this.showNodePopover( + 'connection', + connection, + overlay.canvas, + ) }, }, }, @@ -933,7 +1017,11 @@ export default { if (this.stateIsReadonly) return false const { sourceId, targetId } = info - return this.checkCanBeConnected(this.getRealId(sourceId), this.getRealId(targetId), true) + return this.checkCanBeConnected( + this.getRealId(sourceId), + this.getRealId(targetId), + true, + ) }) jsPlumbIns.bind('beforeDrag', ({ sourceId }) => { @@ -951,7 +1039,9 @@ export default { if (this.stateIsReadonly) return false const source = this.nodeById(this.getRealId(info.sourceId)) const canBeConnectedNodes = this.allNodes.filter( - (target) => !target.attrs.disabled && this.checkCanBeConnected(source.id, target.id), + (target) => + !target.attrs.disabled && + this.checkCanBeConnected(source.id, target.id), ) this.setCanBeConnectedNodeIds(canBeConnectedNodes.map((n) => n.id)) }) @@ -1002,8 +1092,8 @@ export default { this.setEditVersion(result.editVersion) this.isSaving = false isOk = true - } catch (e) { - this.handleError(e) + } catch (error) { + this.handleError(error) } this.isSaving = false if (!needStart) this.$refs.console?.loadData() // 再load一下信息输出,并且停掉计时器 @@ -1038,16 +1128,17 @@ export default { }, findParentNodes(id, excludeId) { - let node = this.scope.findNodeById(id) + const node = this.scope.findNodeById(id) const nodes = [] - let parentIds = node.$inputs || [] + const parentIds = node.$inputs || [] for (const parentId of parentIds) { if (parentId === excludeId) continue - let node = this.scope.findNodeById(parentId) + const node = this.scope.findNodeById(parentId) - if (!node || node.__Ctor.maxInputs !== 1 || node.$outputs.length > 1) continue + if (!node || node.__Ctor.maxInputs !== 1 || node.$outputs.length > 1) + continue nodes.push(node) @@ -1060,12 +1151,12 @@ export default { }, findChildNodes(id) { - let node = this.scope.findNodeById(id) + const node = this.scope.findNodeById(id) const nodes = [] - let ids = node.$outputs || [] + const ids = node.$outputs || [] ids.forEach((id) => { - let child = this.scope.findNodeById(id) + const child = this.scope.findNodeById(id) if (!child) return @@ -1085,12 +1176,12 @@ export default { }, findAllChildNodes(id) { - let node = this.scope.findNodeById(id) + const node = this.scope.findNodeById(id) const nodes = [] - let ids = node.$outputs || [] + const ids = node.$outputs || [] - ids.forEach(id => { - let child = this.scope.findNodeById(id) + ids.forEach((id) => { + const child = this.scope.findNodeById(id) if (!child) return @@ -1105,8 +1196,8 @@ export default { }, handleDisableNode(node, value = true) { - node['disabled'] = value - node.attrs['disabled'] = value + node.disabled = value + node.attrs.disabled = value const parents = this.findParentNodes(node.id) const children = this.findChildNodes(node.id) @@ -1126,7 +1217,7 @@ export default { ) nodes.forEach((node) => { - node.attrs['disabled'] = value + node.attrs.disabled = value connections.push( ...this.jsPlumbIns.getConnections({ target: NODE_PREFIX + node.id, @@ -1237,7 +1328,8 @@ export default { } }) - hasMove && this.command.exec(new MoveNodeCommand(oldProperties, newProperties)) + hasMove && + this.command.exec(new MoveNodeCommand(oldProperties, newProperties)) this.$refs.paperScroller.autoResizePaper() this.$refs.paperScroller.centerContent() }, @@ -1256,15 +1348,17 @@ export default { nodeELIsConnected(s, t) { // const connections = this.jsPlumbIns.getConnections('*') - // eslint-disable-next-line + // console.log('connections', connections) - return this.jsPlumbIns.getConnections('*').some((c) => `${c.sourceId}` === s && `${c.targetId}` === t) + return this.jsPlumbIns + .getConnections('*') + .some((c) => String(c.sourceId) === s && String(c.targetId) === t) }, allowConnect(sourceId, targetId) { const allEdges = this.allEdges const map = allEdges.reduce((map, item) => { - let target = map[item.target] + const target = map[item.target] if (target) { target.push(item.source) } else { @@ -1282,7 +1376,7 @@ export default { isParent(sourceId, targetId, map) { let flag = false if (!map[sourceId]) return flag - for (let id of map[sourceId]) { + for (const id of map[sourceId]) { flag = id === targetId if (flag || this.isParent(id, targetId, map)) return true } @@ -1312,17 +1406,24 @@ export default { async validateNode(node) { try { - const schema = getSchema(node.__Ctor.formSchema, node, this.$store.state.dataflow.pdkPropertiesMap) + const schema = getSchema( + node.__Ctor.formSchema, + node, + this.$store.state.dataflow.pdkPropertiesMap, + ) await validateBySchema(schema, node, this.formScope || this.scope) this.clearNodeError(node.id) - } catch (e) { + } catch (error) { // eslint-disable-next-line no-console - console.log(i18n.t('packages_dag_mixins_editor_jiedianjiaoyancuo'), e) + console.log( + i18n.t('packages_dag_mixins_editor_jiedianjiaoyancuo'), + error, + ) if (node.type === 'table_rename_processor') { // 节点的特殊处理,直接拿表单校验结果设置错误信息 this.setNodeErrorMsg({ id: node.id, - msg: e[0].messages[0], + msg: error[0].messages[0], }) } else { this.setNodeError(node.id) @@ -1349,7 +1450,11 @@ export default { const { id } = node const minInputs = node.__Ctor.minInputs ?? 1 // 非数据节点至少有一个目标 - const minOutputs = (node.__Ctor.minOutputs ?? (node.type !== 'database' && node.type !== 'table')) ? 1 : 0 + const minOutputs = + (node.__Ctor.minOutputs ?? + (node.type !== 'database' && node.type !== 'table')) + ? 1 + : 0 const inputNum = node.$inputs.length const outputNum = node.$outputs.length @@ -1394,10 +1499,13 @@ export default { */ validateAgent() { let someErrorMsg - const nodes = this.allNodes.filter((node) => node.type === 'database' || node.type === 'table') + const nodes = this.allNodes.filter( + (node) => node.type === 'database' || node.type === 'table', + ) const accessNodeProcessIdArr = [ ...nodes.reduce((set, item) => { - item.attrs.accessNodeProcessId && set.add(item.attrs.accessNodeProcessId) + item.attrs.accessNodeProcessId && + set.add(item.attrs.accessNodeProcessId) return set }, new Set()), ] @@ -1413,7 +1521,10 @@ export default { let isError = false const agent = this.scope.$agentMap[chooseId] nodes.forEach((node) => { - if (node.attrs.accessNodeProcessId && chooseId !== node.attrs.accessNodeProcessId) { + if ( + node.attrs.accessNodeProcessId && + chooseId !== node.attrs.accessNodeProcessId + ) { this.setNodeErrorMsg({ id: node.id, msg: i18n.t('packages_dag_mixins_editor_gaijiedianbuzhi', { @@ -1424,7 +1535,8 @@ export default { isError = true } }) - isError && (someErrorMsg = i18n.t('packages_dag_mixins_editor_suoshuage')) + isError && + (someErrorMsg = i18n.t('packages_dag_mixins_editor_suoshuage')) } } else if (accessNodeProcessIdArr.length === 1) { // 如果画布上仅有一个所属agent,自动设置为任务的agent @@ -1432,7 +1544,8 @@ export default { this.$set( this.dataflow, 'accessNodeType', - this.scope.$agentMap[agentId]?.accessNodeType || 'MANUALLY_SPECIFIED_BY_THE_USER', + this.scope.$agentMap[agentId]?.accessNodeType || + 'MANUALLY_SPECIFIED_BY_THE_USER', ) this.$set(this.dataflow, 'accessNodeProcessId', agentId) } @@ -1442,7 +1555,7 @@ export default { async validateSetting() { try { await this.$refs.configPanel.validateSetting() - } catch (e) { + } catch { this.setActiveType('settings') return i18n.t('packages_dag_mixins_editor_renwushezhiyi') } @@ -1454,18 +1567,20 @@ export default { let hasNoStreamReadFunction = false this.allNodes.forEach((node) => { if (node.$outputs.length && !node.$inputs.length) { - const capbilitiesMap = node.attrs.capabilities.reduce((map, item) => { - map[item.id] = true - return map - }, {}) + const capbilitiesMap = node.attrs.capabilities.reduce( + (map, item) => { + map[item.id] = true + return map + }, + {}, + ) if ( - !( - capbilitiesMap['stream_read_function'] || - capbilitiesMap['raw_data_callback_filter_function'] || - capbilitiesMap['raw_data_callback_filter_function_v2'] || - (capbilitiesMap['query_by_advance_filter_function'] && capbilitiesMap['batch_read_function']) - ) + !capbilitiesMap.stream_read_function && + !capbilitiesMap.raw_data_callback_filter_function && + !capbilitiesMap.raw_data_callback_filter_function_v2 && + (!capbilitiesMap.query_by_advance_filter_function || + !capbilitiesMap.batch_read_function) ) { // 源不支持增量 hasNoStreamReadFunction = true @@ -1484,7 +1599,7 @@ export default { }, loadLeafNode(node) { - let arr = [] + const arr = [] if (node.$outputs.length) { node.$outputs.forEach((id) => { console.log('this.loadLeafNode(this.nodeById(id))', this.loadLeafNode(this.nodeById(id))) // eslint-disable-line @@ -1554,7 +1669,8 @@ export default { validateLink() { const firstSourceNode = this.allNodes.find((node) => !node.$inputs.length) - if (!firstSourceNode) return i18n.t('packages_dag_mixins_editor_renwulianlubu') + if (!firstSourceNode) + return i18n.t('packages_dag_mixins_editor_renwulianlubu') this.eachMap = {} this.eachOutputs(firstSourceNode) @@ -1567,14 +1683,14 @@ export default { let hasEnableDDL let hasEnableDDLAndIncreasesql let inBlacklist = false - let blacklist = [ + const blacklist = [ 'js_processor', 'custom_processor', 'migrate_js_processor', 'union_processor', 'migrate_union_processor', 'standard_js_processor', - 'standard_migrate_js_processor' + 'standard_migrate_js_processor', ] this.allNodes.forEach((node) => { // 开启了DDL @@ -1626,11 +1742,19 @@ export default { validateUnwind() { if (this.dataflow.syncType === 'migrate') return - const nodes = this.allNodes.filter((node) => node.type === 'unwind_processor') - for (let node of nodes) { - const childNodes = this.findChildNodes(node.id).filter((child) => child.type === 'table') + const nodes = this.allNodes.filter( + (node) => node.type === 'unwind_processor', + ) + for (const node of nodes) { + const childNodes = this.findChildNodes(node.id).filter( + (child) => child.type === 'table', + ) // console.log('childNodes', childNodes) - if (childNodes.some((childNode) => childNode.dmlPolicy?.insertPolicy !== 'just_insert')) { + if ( + childNodes.some( + (childNode) => childNode.dmlPolicy?.insertPolicy !== 'just_insert', + ) + ) { this.setNodeErrorMsg({ id: node.id, msg: i18n.t('packages_dag_unwind_validate_error'), @@ -1643,7 +1767,9 @@ export default { async validateTableRename() { if (this.dataflow.syncType !== 'migrate') return - const nodes = this.allNodes.filter((node) => node.type === 'table_rename_processor') + const nodes = this.allNodes.filter( + (node) => node.type === 'table_rename_processor', + ) // 只允许存在1个表编辑节点 if (nodes.length > 1) return i18n.t('packages_dag_table_rename_multiple') @@ -1651,7 +1777,7 @@ export default { // 表重名检查 const node = nodes[0] const parents = this.scope.findParentNodes(node.id) - let sourceNode = parents?.[0] + const sourceNode = parents?.[0] if (sourceNode?.type === 'database') { let tableNames = sourceNode.tableNames @@ -1677,7 +1803,7 @@ export default { return obj }, {}) - for (let name of tableNames) { + for (const name of tableNames) { let newName = name if (name in renameMap) { @@ -1706,7 +1832,9 @@ export default { async validateMigrateUnion() { if (this.dataflow.syncType !== 'migrate') return - const nodes = this.allNodes.filter((node) => node.type === 'migrate_union_processor') + const nodes = this.allNodes.filter( + (node) => node.type === 'migrate_union_processor', + ) if (nodes.length > 1) return i18n.t('packages_dag_migrate_union_multiple') }, @@ -1714,7 +1842,9 @@ export default { async validateMergeTableProcessor() { if (this.dataflow.syncType === 'migrate') return - const nodes = this.allNodes.filter(node => node.type === 'merge_table_processor') + const nodes = this.allNodes.filter( + (node) => node.type === 'merge_table_processor', + ) const validateMergeProperties = (items, isFirstLevel = true) => { for (const item of items) { @@ -1722,13 +1852,18 @@ export default { if (!isFirstLevel) { // 检查 joinKeys 是否为空数组 if (!item.joinKeys?.length) { - return i18n.t('packages_dag_join_keys_empty', { tableName: item.tableName }) + return i18n.t('packages_dag_join_keys_empty', { + tableName: item.tableName, + }) } // 检查每个 joinKey 的 source/target for (const [index, joinKey] of item.joinKeys.entries()) { if (!joinKey.source || !joinKey.target) { - return i18n.t('packages_dag_join_keys_field_empty', { tableName: item.tableName, index: index + 1 }) + return i18n.t('packages_dag_join_keys_field_empty', { + tableName: item.tableName, + index: index + 1, + }) } } } @@ -1744,12 +1879,12 @@ export default { return '' } - for (let node of nodes) { + for (const node of nodes) { const error = validateMergeProperties(node.mergeProperties) if (error) { this.setNodeErrorMsg({ id: node.id, - msg: error + msg: error, }) return error } @@ -1757,26 +1892,33 @@ export default { // 校验主从合并后面是否有js节点 const nextNodes = this.findAllChildNodes(node.id) - if (nextNodes.some(nextNode => nextNode.type === 'standard_js_processor')) { + if ( + nextNodes.some( + (nextNode) => nextNode.type === 'standard_js_processor', + ) + ) { return i18n.t('packages_dag_merge_table_js_node_error') } // 目标需要有 master_slave_merge 能力 const targetNode = nextNodes.find( - nextNode => - nextNode.type === 'table' && !nextNode.attrs?.capabilities?.find(({ id }) => id === 'master_slave_merge') + (nextNode) => + nextNode.type === 'table' && + !nextNode.attrs?.capabilities?.find( + ({ id }) => id === 'master_slave_merge', + ), ) if (targetNode) { return i18n.t('packages_dag_merge_table_table_not_allow_target', { - val: targetNode.databaseType + val: targetNode.databaseType, }) } } }, async eachValidate(...fns) { - for (let fn of fns) { + for (const fn of fns) { let result = fn() if (result) { if (result instanceof Promise) { @@ -1789,7 +1931,8 @@ export default { }, async validate() { - if (!this.dataflow.name) return this.$t('packages_dag_editor_cell_validate_empty_name') + if (!this.dataflow.name) + return this.$t('packages_dag_editor_cell_validate_empty_name') const nodes = this.allNodes.filter((node) => { return !node.disabled && !node.attrs.disabled @@ -1825,31 +1968,37 @@ export default { this.jsPlumbIns.select().removeClass('connection-highlight') const $elemBelow = document.elementFromPoint(...position) - if ($elemBelow?.nodeName === 'path' && $elemBelow.parentElement._jsPlumb) { + if ( + $elemBelow?.nodeName === 'path' && + $elemBelow.parentElement._jsPlumb + ) { $elemBelow.parentElement.classList.add('connection-highlight') } - let lines = [] + const lines = [] - if (document.getElementById('dfEditorContent').contains($elemBelow)) { + if (document.querySelector('#dfEditorContent').contains($elemBelow)) { el.style.transition = `transform 0.3s` el.style.transform = `scale(${this.scale})` - let nw = el.offsetWidth - let nh = el.offsetHeight - const pos = this.$refs.paperScroller.getDropPositionWithinPaper(position, { - width: nw, - height: nh, - }) - let diffPos = { x: 0, y: 0 } + const nw = el.offsetWidth + const nh = el.offsetHeight + const pos = this.$refs.paperScroller.getDropPositionWithinPaper( + position, + { + width: nw, + height: nh, + }, + ) + const diffPos = { x: 0, y: 0 } let horiArr = [] let verArr = [] let rangeX = 10 let rangeY = 10 this.allNodes.forEach((item) => { - let [x, y] = item.attrs.position - let _x = x - pos[0] - let _y = y - pos[1] + const [x, y] = item.attrs.position + const _x = x - pos[0] + const _y = y - pos[1] if (Math.abs(_x) <= Math.abs(rangeX)) { if (_x === rangeX) { verArr.push(y) @@ -1874,8 +2023,8 @@ export default { pos[1] += diffPos.y // console.log('diffPos', diffPos.x, diffPos.y) - el.style.left = parseInt(el.style.left) + diffPos.x * this.scale + 'px' - el.style.top = parseInt(el.style.top) + diffPos.y * this.scale + 'px' + el.style.left = `${Number.parseInt(el.style.left) + diffPos.x * this.scale}px` + el.style.top = `${Number.parseInt(el.style.top) + diffPos.y * this.scale}px` let t = pos[1], b = pos[1] + nh, @@ -1892,49 +2041,49 @@ export default { // 组装导航线 if (t < pos[1]) { - let top = t + 'px', - height = pos[1] - t + 'px' + const top = `${t}px`, + height = `${pos[1] - t}px` lines.push( { top, - left: pos[0] + 'px', + left: `${pos[0]}px`, height, }, { top, - left: pos[0] + nw + 'px', + left: `${pos[0] + nw}px`, height, }, ) } if (b > pos[1] + nh) { - let top = pos[1] + nh + 'px', - height = b - pos[1] - nh + 'px' + const top = `${pos[1] + nh}px`, + height = `${b - pos[1] - nh}px` lines.push( { top, - left: pos[0] + 'px', + left: `${pos[0]}px`, height, }, { top, - left: pos[0] + nw + 'px', + left: `${pos[0] + nw}px`, height, }, ) } if (l < pos[0]) { - let left = l + 'px', - width = pos[0] - l + 'px' + const left = `${l}px`, + width = `${pos[0] - l}px` lines.push( { - top: pos[1] + 'px', + top: `${pos[1]}px`, left, width, }, { - top: pos[1] + nh + 'px', + top: `${pos[1] + nh}px`, left, width, }, @@ -1942,16 +2091,16 @@ export default { } if (r > pos[0] + nw) { - let left = pos[0] + nw + 'px', - width = r - pos[0] - nw + 'px' + const left = `${pos[0] + nw}px`, + width = `${r - pos[0] - nw}px` lines.push( { - top: pos[1] + 'px', + top: `${pos[1]}px`, left, width, }, { - top: pos[1] + nh + 'px', + top: `${pos[1] + nh}px`, left, width, }, @@ -2003,7 +2152,10 @@ export default { handleAddNode(item) { const { x, y } = this.$refs.paperScroller.getPaperCenterPos() - const position = this.getNewNodePosition([x - NODE_WIDTH / 2, y - NODE_HEIGHT / 2], [120, 0]) + const position = this.getNewNodePosition( + [x - NODE_WIDTH / 2, y - NODE_HEIGHT / 2], + [120, 0], + ) const node = this.handleAddNodeToPos(position, item) if (position[1] !== y) { this.$refs.paperScroller.centerNode(node) @@ -2045,7 +2197,10 @@ export default { const spaceX = 120 const spaceY = 120 - const newPosition = [source.attrs.position[0] + NODE_WIDTH + spaceX, source.attrs.position[1]] + const newPosition = [ + source.attrs.position[0] + NODE_WIDTH + spaceX, + source.attrs.position[1], + ] let movePosition = [spaceX, 0] if (this.isSource(source)) { @@ -2068,7 +2223,10 @@ export default { const spaceX = 120 const spaceY = 120 - const newPosition = [target.attrs.position[0] - NODE_WIDTH - spaceX, target.attrs.position[1]] + const newPosition = [ + target.attrs.position[0] - NODE_WIDTH - spaceX, + target.attrs.position[1], + ] let movePosition = [-spaceX, 0] if (target.$inputs.length) { @@ -2118,21 +2276,30 @@ export default { addNodeOnConnByNodeMenu(nodeType) { const { nodeMenu } = this - const position = this.$refs.paperScroller.getDropPositionWithinPaper(nodeMenu.connectionCenterPos, { - width: NODE_WIDTH, - height: NODE_HEIGHT, - }) - this.addNodeOnConn(nodeType, position, nodeMenu.data.source, nodeMenu.data.target) + const position = this.$refs.paperScroller.getDropPositionWithinPaper( + nodeMenu.connectionCenterPos, + { + width: NODE_WIDTH, + height: NODE_HEIGHT, + }, + ) + this.addNodeOnConn( + nodeType, + position, + nodeMenu.data.source, + nodeMenu.data.target, + ) this.$nextTick(() => { this.handleAutoLayout() }) }, canUsePosition(position1, position2) { - if (Math.abs(position1[0] - position2[0]) <= NODE_WIDTH) { - if (Math.abs(position1[1] - position2[1]) <= NODE_HEIGHT) { - return false - } + if ( + Math.abs(position1[0] - position2[0]) <= NODE_WIDTH && + Math.abs(position1[1] - position2[1]) <= NODE_HEIGHT + ) { + return false } return true @@ -2169,7 +2336,7 @@ export default { handleError(error, msg = i18n.t('packages_dag_src_editor_chucuole')) { const code = error?.data?.code if (code === 'Task.ListWarnMessage') { - let names = [] + const names = [] if (error.data?.data) { const keys = Object.keys(error.data.data) keys.forEach((key) => { @@ -2200,7 +2367,9 @@ export default { }).then((resFlag) => { resFlag && location.reload() }) - } else if (['Task.ScheduleLimit', 'Task.ManuallyScheduleLimit'].includes(code)) { + } else if ( + ['Task.ScheduleLimit', 'Task.ManuallyScheduleLimit'].includes(code) + ) { this.handleShowUpgradeDialog(error.data) } else { showErrorMessage(error?.data) @@ -2213,7 +2382,9 @@ export default { this.dataflow.name = name taskApi.rename(this.dataflow.id, name).then( () => { - this.$message.success(this.$t('packages_dag_message_task_rename_success')) + this.$message.success( + this.$t('packages_dag_message_task_rename_success'), + ) this.titleSet() }, (error) => { @@ -2244,7 +2415,12 @@ export default { async handleStart() { const routeName = this.$route.name - const isDataflow = ['DataflowNew', 'DataflowEditor', 'DataflowViewer', 'TaskMonitor'].includes(routeName) + const isDataflow = [ + 'DataflowNew', + 'DataflowEditor', + 'DataflowViewer', + 'TaskMonitor', + ].includes(routeName) const buriedCode = isDataflow ? 'taskStart' : 'migrationStart' this.buried(buriedCode) @@ -2262,7 +2438,7 @@ export default { }, handleStop() { - let message = this.getConfirmMessage('stop') + const message = this.getConfirmMessage('stop') this.$confirm(message, '', { type: 'warning', @@ -2273,15 +2449,18 @@ export default { } this.initWS() this.dataflow.disabledData.stop = true - await taskApi.stop(this.dataflow.id).catch((e) => { - this.handleError(e, this.$t('packages_dag_message_operation_error')) + await taskApi.stop(this.dataflow.id).catch((error) => { + this.handleError( + error, + this.$t('packages_dag_message_operation_error'), + ) }) this.$message.success(this.$t('public_message_operation_success')) }) }, handleForceStop() { - let msg = this.getConfirmMessage('force_stop') + const msg = this.getConfirmMessage('force_stop') this.$confirm(msg, '', { type: 'warning', showClose: false, @@ -2297,7 +2476,7 @@ export default { }, handleReset() { - let msg = this.getConfirmMessage('initialize') + const msg = this.getConfirmMessage('initialize') this.$confirm(msg, '', { type: 'warning', }).then(async (resFlag) => { @@ -2310,17 +2489,23 @@ export default { this.toggleConsole(true) this.$refs.console?.startAuto('reset') // 信息输出自动加载 const data = await taskApi.reset(this.dataflow.id) - this.responseHandler(data, this.$t('public_message_operation_success')) - } catch (e) { - this.handleError(e, this.$t('packages_dag_message_operation_error')) + this.responseHandler( + data, + this.$t('public_message_operation_success'), + ) + } catch (error) { + this.handleError( + error, + this.$t('packages_dag_message_operation_error'), + ) } }) }, getConfirmMessage(operateStr) { - let message = operateStr + '_confirm_message' - let strArr = this.$t('packages_dag_dataFlow_' + message).split('xxx') - let msg = h('p', null, [ + const message = `${operateStr}_confirm_message` + const strArr = this.$t(`packages_dag_dataFlow_${message}`).split('xxx') + const msg = h('p', null, [ strArr[0], h( 'span', @@ -2335,15 +2520,15 @@ export default { }, responseHandler(data, msg) { - let failList = data?.fail || [] + const failList = data?.fail || [] if (failList.length) { - let msgMapping = { + const msgMapping = { 5: this.$t('packages_dag_dataFlow_multiError_notFound'), 6: this.$t('packages_dag_dataFlow_multiError_statusError'), 7: this.$t('packages_dag_dataFlow_multiError_otherError'), 8: this.$t('packages_dag_dataFlow_multiError_statusError'), } - let nameMapping = {} + const nameMapping = {} this.table.list.forEach((item) => { nameMapping[item.id] = item.name }) @@ -2368,7 +2553,9 @@ export default { const { parent_task_sign } = this.$route.query || {} const data = await taskApi.get(id, params, { parent_task_sign }) if (!data) { - this.$message.error(i18n.t('packages_dag_mixins_editor_renwubucunzai')) + this.$message.error( + i18n.t('packages_dag_mixins_editor_renwubucunzai'), + ) this.handlePageReturn() return } @@ -2393,8 +2580,8 @@ export default { this.startLoopTask(id) this.titleSet() return data - } catch (e) { - console.error(e) + } catch (error) { + console.error(error) this.$message.error(i18n.t('packages_dag_mixins_editor_renwujiazaichu')) this.handlePageReturn() } finally { @@ -2442,7 +2629,9 @@ export default { this.dataflow.taskRetryStartTime = data.taskRetryStartTime if (data.currentEventTimestamp) { - this.dataflow.currentEventTimestampLabel = dayjs(data.currentEventTimestamp).format('YYYY-MM-DD HH:mm:ss') + this.dataflow.currentEventTimestampLabel = dayjs( + data.currentEventTimestamp, + ).format('YYYY-MM-DD HH:mm:ss') } if (data.status === 'edit') data.btnDisabled.start = false // 任务编辑中,在编辑页面可以启动 @@ -2537,7 +2726,11 @@ export default { handleConsoleAutoLoad() { this.toggleConsole(true) - const logType = ['renewing', 'renew_failed'].includes(this.dataflow.status) ? 'reset' : 'checkDag' + const logType = ['renewing', 'renew_failed'].includes( + this.dataflow.status, + ) + ? 'reset' + : 'checkDag' this.$refs.console?.startAuto(logType) }, @@ -2574,9 +2767,9 @@ export default { }, }), }) - let tagsMap = {} - let doubleActiveMap = {} - let propertiesMap = {} + const tagsMap = {} + const doubleActiveMap = {} + const propertiesMap = {} databaseItems.forEach(({ properties, pdkHash, tags }) => { const nodeProperties = properties?.node @@ -2600,7 +2793,12 @@ export default { getIsDataflow() { const routeName = this.$route.name - return ['DataflowNew', 'DataflowEditor', 'DataflowViewer', 'TaskMonitor'].includes(routeName) + return [ + 'DataflowNew', + 'DataflowEditor', + 'DataflowViewer', + 'TaskMonitor', + ].includes(routeName) }, beforeStartTask() { @@ -2616,15 +2814,15 @@ export default { const buriedCode = this.getIsDataflow() ? 'taskStart' : 'migrationStart' taskApi .batchStart([this.dataflow.id], { - silenceMessage: true + silenceMessage: true, }) .then(() => { this.buried(buriedCode, { result: true }) this.gotoViewer() }) - .catch(e => { + .catch((error) => { this.buried(buriedCode, { result: false }) - this.handleError(e) + this.handleError(error) }) }, // 获取任务的按钮权限 @@ -2636,7 +2834,7 @@ export default { dataType: 'Task', dataId: id, }) - for (let key in this.buttonShowMap) { + for (const key in this.buttonShowMap) { this.buttonShowMap[key] = data.includes(key) } }, @@ -2657,13 +2855,12 @@ export default { !this.isDaas && this.$axios .get( - 'api/tcm/agent?filter=' + - encodeURIComponent( - JSON.stringify({ - size: 100, - page: 1, - }), - ), + `api/tcm/agent?filter=${encodeURIComponent( + JSON.stringify({ + size: 100, + page: 1, + }), + )}`, ) .then(async (data) => { const { items = [] } = data @@ -2673,7 +2870,12 @@ export default { return } - items.length <= 1 && items.some((t) => t.orderInfo?.chargeProvider === 'FreeTier' || !t.orderInfo?.amount) + items.length <= 1 && + items.some( + (t) => + t.orderInfo?.chargeProvider === 'FreeTier' || + !t.orderInfo?.amount, + ) ? this.handleShowUpgradeFee(err.message) : this.handleShowUpgradeCharges(err.message) }) @@ -2681,7 +2883,10 @@ export default { handleAddNodeToCenter(item) { const { x, y } = this.$refs.paperScroller.getPaperCenterPos() - const position = this.getNewNodePosition([x - NODE_WIDTH / 2, y - NODE_HEIGHT / 2], [0, 120]) + const position = this.getNewNodePosition( + [x - NODE_WIDTH / 2, y - NODE_HEIGHT / 2], + [0, 120], + ) const node = this.handleAddNodeToPos(position, item) if (position[1] !== y) { this.$refs.paperScroller.centerNode(node) @@ -2705,14 +2910,16 @@ export default { window.open( this.$router.resolve({ name: 'DataCapture', - params: { id: this.dataflow.id } + params: { id: this.dataflow.id }, }).href, - `DataCapture-${this.dataflow.id}` + `DataCapture-${this.dataflow.id}`, ) }, hasFeature(feature) { - return !this.isDaas || this.$store.getters['feature/hasFeature']?.(feature) - } - } + return ( + !this.isDaas || this.$store.getters['feature/hasFeature']?.(feature) + ) + }, + }, } diff --git a/packages/form/src/components/input/index.jsx b/packages/form/src/components/input/index.jsx index 6df7eff020..58999dc34b 100644 --- a/packages/form/src/components/input/index.jsx +++ b/packages/form/src/components/input/index.jsx @@ -11,13 +11,12 @@ export const Input = defineComponent({ }, setup(props, { attrs }) { return () => { - console.log('Input', attrs) return ( <_Input {...{ ...attrs, onBlur: (ev) => { - let val = ev.target.value + const val = ev.target.value let newVal = val if (props.trim) { From 0638ac63e6fddd13601647620bf1c3871a97b4dc Mon Sep 17 00:00:00 2001 From: Feynman Date: Thu, 24 Apr 2025 18:05:40 +0800 Subject: [PATCH 02/20] fix: correct event emission and improve router handling in connection components - Updated the event emission in `SceneDialog.vue` to use `this.$emit` for proper context. - Refactored the router push logic in `DatabaseForm.vue` to ensure `location.reload()` is called after the navigation promise resolves, enhancing reliability. - Adjusted the main element's border radius in `DatabaseForm.vue` for improved UI consistency. --- .../create-connection/SceneDialog.vue | 2 +- .../src/views/connections/DatabaseForm.vue | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/business/src/components/create-connection/SceneDialog.vue b/packages/business/src/components/create-connection/SceneDialog.vue index 6d2d1448c3..dd255ff3ba 100644 --- a/packages/business/src/components/create-connection/SceneDialog.vue +++ b/packages/business/src/components/create-connection/SceneDialog.vue @@ -631,7 +631,7 @@ export default { } if (this.selectorType === 'source_and_target' && !this.dialogMode) { - $emit(this, 'selected', item) + this.$emit('selected', item) return } diff --git a/packages/business/src/views/connections/DatabaseForm.vue b/packages/business/src/views/connections/DatabaseForm.vue index d37b6cecf7..dc9acfbdb6 100644 --- a/packages/business/src/views/connections/DatabaseForm.vue +++ b/packages/business/src/views/connections/DatabaseForm.vue @@ -348,14 +348,17 @@ export default { handleDatabaseType(item) { this.dialogDatabaseTypeVisible = false const { pdkHash, pdkId } = item - this.$router.push({ - name: 'connectionCreate', - query: { - pdkHash, - pdkId, - }, - }) - location.reload() + this.$router + .push({ + name: 'connectionCreate', + query: { + pdkHash, + pdkId, + }, + }) + .then(() => { + location.reload() + }) }, async getPdkForm() { const pdkHash = this.$route.query?.pdkHash @@ -1599,7 +1602,7 @@ export default { -
- - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - -
+ + + + + + + + + + + Date: Sat, 26 Apr 2025 05:42:12 +0800 Subject: [PATCH 04/20] fix: update v-model binding and enhance styles in components - Changed the v-model binding in `WebhookAlerts.vue` to use `v-model:value` for better compatibility with Vue 3. - Added a new style for active states in `element.scss` to improve UI feedback. - Updated font sizes for collapse headers in `var.scss` to ensure consistency across components. - Introduced a new `RightBoldOutlined` icon in `InstallElement.js` for enhanced visual representation. - Refactored the import order in `json-editor/index.jsx` for better readability and structure. --- apps/daas/src/views/setting/WebhookAlerts.vue | 2 +- packages/assets/styles/element.scss | 7 ++++++- packages/assets/styles/var.scss | 6 +++++- packages/component/src/InstallElement.js | 3 +++ packages/component/src/RightBoldOutlined.tsx | 15 +++++++++++++++ .../form/src/components/json-editor/index.jsx | 16 +++++++++------- 6 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 packages/component/src/RightBoldOutlined.tsx diff --git a/apps/daas/src/views/setting/WebhookAlerts.vue b/apps/daas/src/views/setting/WebhookAlerts.vue index adf2d5dd4a..f877dfad85 100644 --- a/apps/daas/src/views/setting/WebhookAlerts.vue +++ b/apps/daas/src/views/setting/WebhookAlerts.vue @@ -474,7 +474,7 @@ export default { + + +) diff --git a/packages/form/src/components/json-editor/index.jsx b/packages/form/src/components/json-editor/index.jsx index c80b0abe94..29b8d11c6a 100644 --- a/packages/form/src/components/json-editor/index.jsx +++ b/packages/form/src/components/json-editor/index.jsx @@ -1,6 +1,6 @@ -import { computed, defineComponent, ref, watch } from 'vue' -import { VCodeEditor } from '@tap/component' import { useField } from '@formily/vue' +import { VCodeEditor } from '@tap/component' +import { computed, defineComponent, ref, watch } from 'vue' export const JsonEditor = defineComponent({ props: { @@ -21,17 +21,19 @@ export const JsonEditor = defineComponent({ needFormat: Boolean, }, - setup(props, { emit, listeners }) { + setup(props, { emit, attrs }) { const fieldRef = useField() const editorVal = computed(() => { - return props.type === 'object' ? JSON.stringify(props.value, null, props.needFormat ? 2 : 0) : props.value + return props.type === 'object' + ? JSON.stringify(props.value, null, props.needFormat ? 2 : 0) + : props.value }) const onBlur = (val) => { if (val !== editorVal.value) { try { if (val && props.type === 'object') val = JSON.parse(val) - } catch (e) { - console.error(e) // eslint-disable-line + } catch (error) { + console.error(error) } emit('change', val) } @@ -53,7 +55,7 @@ export const JsonEditor = defineComponent({ height={props.height} onBlur={onBlur} options={options} - on={{ ...listeners }} + {...attrs} /> ) } From b5aa688ae57920473fff868892d78813f69e6d74 Mon Sep 17 00:00:00 2001 From: Feynman Date: Sat, 26 Apr 2025 23:31:55 +0800 Subject: [PATCH 05/20] feat: enhance filter inputs and button identifiers in List components - Added unique IDs to filter input fields in `List.vue` components for better accessibility and testing. - Introduced button names for task action buttons in `List.vue` to improve clarity and facilitate testing. - Updated the import structure in `TableSelector.vue` to include the new `RightBoldOutlined` icon for enhanced UI consistency. - Refactored button elements in `LeftSider.vue` to use `el-button` for a more consistent button style across the application. --- .../business/src/views/connections/List.vue | 1 + packages/business/src/views/task/List.vue | 7 + .../business/src/views/verification/List.vue | 8 +- packages/component/src/index.js | 2 + packages/dag/src/components/LeftSidebar.vue | 721 ++++++++++-------- .../form/table-selector/TableSelector.vue | 46 +- .../src/components/migration/LeftSider.vue | 39 +- 7 files changed, 506 insertions(+), 318 deletions(-) diff --git a/packages/business/src/views/connections/List.vue b/packages/business/src/views/connections/List.vue index 0ce105f539..c651467f48 100644 --- a/packages/business/src/views/connections/List.vue +++ b/packages/business/src/views/connections/List.vue @@ -632,6 +632,7 @@ export default { placeholder: this.$t('packages_business_connection_list_name'), key: 'keyword', type: 'input', + id: 'name-filter-input', }, ] }, diff --git a/packages/business/src/views/task/List.vue b/packages/business/src/views/task/List.vue index d2f89e03f9..cc75112a34 100644 --- a/packages/business/src/views/task/List.vue +++ b/packages/business/src/views/task/List.vue @@ -342,12 +342,14 @@ export default { key: 'status', type: 'select-inner', items: this.statusOptions, + id: 'status-filter-select', }, { label: this.$t('packages_business_task_list_sync_type'), key: 'type', type: 'select-inner', items: this.typeOptions, + id: 'type-filter-select', }, { label: this.$t('packages_business_task_monitor_mission_milestone'), @@ -361,6 +363,7 @@ export default { })), ], width: 240, + id: 'sync-status-filter-select', }, { label: i18n.t('public_agent_name'), @@ -402,6 +405,7 @@ export default { placeholder: this.$t('public_task_name'), key: 'keyword', type: 'input', + id: 'name-filter-input', }, ] @@ -1286,6 +1290,7 @@ export default { havePermission(row, 'Start') " v-readonlybtn="'SYNC_job_operation'" + name="start-task-btn" text type="primary" data-testid="start-task" @@ -1313,6 +1318,7 @@ export default { v-readonlybtn="'SYNC_job_operation'" text type="primary" + name="stop-task-btn" data-testid="stop-task" :disabled="row.btnDisabled.stop || $disabledReadonlyUserBtn()" @click="stop([row.id], row)" @@ -1397,6 +1403,7 @@ export default { v-readonlybtn="'SYNC_job_edition'" text type="primary" + name="delete-task-btn" data-testid="delete-task" :disabled="row.btnDisabled.delete || $disabledReadonlyUserBtn()" @click="del([row.id], row)" diff --git a/packages/business/src/views/verification/List.vue b/packages/business/src/views/verification/List.vue index f63e949e8d..697583ef30 100644 --- a/packages/business/src/views/verification/List.vue +++ b/packages/business/src/views/verification/List.vue @@ -263,6 +263,7 @@ export default { type: 'select-inner', items: this.verifyTypeList, selectedWidth: '200px', + id: 'type-filter-select', }, { label: this.$t('packages_business_verification_check_frequency'), @@ -279,6 +280,7 @@ export default { value: 'cron', }, ], + id: 'mode-filter-select', }, { label: this.$t('packages_business_verification_is_enabled'), @@ -295,17 +297,20 @@ export default { value: 2, }, ], + id: 'enabled-filter-select', }, { label: this.$t('packages_business_verification_result_title'), key: 'result', type: 'select-inner', items: this.validList, + id: 'result-filter-select', }, { placeholder: this.$t('packages_business_verification_task_name'), key: 'keyword', type: 'input', + id: 'name-filter-input', }, ] }, @@ -358,7 +363,6 @@ export default { v-readonlybtn="'datasource_creation'" class="btn btn-create" type="primary" - @click="handleCreate('pipeline')" > {{ @@ -369,7 +373,6 @@ export default { v-readonlybtn="'datasource_creation'" class="btn btn-create" type="primary" - @click="handleCreate('random')" > {{ @@ -401,7 +404,6 @@ export default { }} diff --git a/packages/component/src/index.js b/packages/component/src/index.js index 64f686e3f3..6785971d18 100644 --- a/packages/component/src/index.js +++ b/packages/component/src/index.js @@ -76,4 +76,6 @@ export * from './icon-button' export * from './CloseIcon' +export * from './RightBoldOutlined' + export * from './InstallElement' diff --git a/packages/dag/src/components/LeftSidebar.vue b/packages/dag/src/components/LeftSidebar.vue index 6b743f287f..486cffb56b 100644 --- a/packages/dag/src/components/LeftSidebar.vue +++ b/packages/dag/src/components/LeftSidebar.vue @@ -1,289 +1,26 @@ - - + + diff --git a/packages/dag/src/components/migration/SettingPanel.vue b/packages/dag/src/components/migration/SettingPanel.vue index 0ed0aa6403..cd68008f86 100644 --- a/packages/dag/src/components/migration/SettingPanel.vue +++ b/packages/dag/src/components/migration/SettingPanel.vue @@ -491,7 +491,7 @@ export default observer({ 'x-component-props': { type: 'datetime', align: 'right', - format: 'yyyy-MM-dd HH:mm:ss', + format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'timestamp', }, 'x-reactions': { @@ -600,7 +600,7 @@ export default observer({ type: 'void', 'x-component': 'div', 'x-component-props': { - class: 'flex align-center gap-2', + class: 'flex align-center gap-2 mt-1', }, 'x-reactions': { dependencies: ['type'], @@ -626,8 +626,10 @@ export default observer({ }, syncPointsDescBtn: { type: 'void', - 'x-component': 'Link', + 'x-component': 'Button', 'x-component-props': { + disabled: `{{$self.disabled}}`, + text: true, type: 'primary', onClick: '{{handleQuicklySyncPoints}}', }, diff --git a/packages/dag/src/components/steps/AdvancedSettingsStep.vue b/packages/dag/src/components/steps/AdvancedSettingsStep.vue index 25f3a911c4..6ea475407d 100644 --- a/packages/dag/src/components/steps/AdvancedSettingsStep.vue +++ b/packages/dag/src/components/steps/AdvancedSettingsStep.vue @@ -1108,7 +1108,7 @@ export default defineComponent({ 'x-component-props': { type: 'datetime', align: 'right', - format: 'yyyy-MM-dd HH:mm:ss', + format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'timestamp' }, 'x-reactions': { diff --git a/packages/dag/src/components/steps/TaskSettingsReadPretty.vue b/packages/dag/src/components/steps/TaskSettingsReadPretty.vue index d7a213ec4f..dc361e6aba 100644 --- a/packages/dag/src/components/steps/TaskSettingsReadPretty.vue +++ b/packages/dag/src/components/steps/TaskSettingsReadPretty.vue @@ -1031,7 +1031,7 @@ export default defineComponent({ 'x-component-props': { type: 'datetime', align: 'right', - format: 'yyyy-MM-dd HH:mm:ss', + format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'timestamp', }, 'x-reactions': { diff --git a/packages/dag/src/nodes/Table.js b/packages/dag/src/nodes/Table.js index ac46af1eb7..7027f8d4de 100644 --- a/packages/dag/src/nodes/Table.js +++ b/packages/dag/src/nodes/Table.js @@ -1291,7 +1291,7 @@ export class Table extends NodeType { 'x-component-props': { type: 'datetime', align: 'right', - format: 'yyyy-MM-dd HH:mm:ss', + format: 'YYYY-MM-DD HH:mm:ss', }, 'x-reactions': { dependencies: [ From e4fe288fe8a7f0389c878016bb76d26d02533d4d Mon Sep 17 00:00:00 2001 From: Feynman Date: Mon, 28 Apr 2025 13:42:07 +0800 Subject: [PATCH 17/20] refactor: simplify state management and enhance component structure across multiple files - Replaced `$set` with direct property assignment for improved performance and readability in `Setting.vue`, `WebhookAlerts.vue`, and `Cluster.vue`. - Updated the `VDivider` component to use a more concise return statement. - Refactored `MigrationMonitorSimple.vue` to streamline imports and improve overall structure. - Enhanced the `Node.vue` component by removing unnecessary parameters in the setup function. - Cleaned up commented-out code in `DataCapture.vue` and `editor.js` for better clarity. --- apps/daas/src/components/VDivider.vue | 30 +- apps/daas/src/views/cluster/Cluster.vue | 3 +- apps/daas/src/views/setting/Setting.vue | 4 +- apps/daas/src/views/setting/WebhookAlerts.vue | 9 +- .../business/src/components/TablePage.vue | 9 +- .../verification/components/ConditionBox.vue | 13 +- packages/dag/src/MigrationMonitorSimple.vue | 2089 ++++++++++------- packages/dag/src/components/monitor/Node.vue | 2 +- packages/dag/src/data-capture/DataCapture.vue | 2 - packages/dag/src/mixins/editor.js | 11 +- packages/ldp/src/Target.vue | 2 +- 11 files changed, 1235 insertions(+), 939 deletions(-) diff --git a/apps/daas/src/components/VDivider.vue b/apps/daas/src/components/VDivider.vue index adb1654bb6..979cf32e2d 100644 --- a/apps/daas/src/components/VDivider.vue +++ b/apps/daas/src/components/VDivider.vue @@ -1,8 +1,8 @@ diff --git a/apps/daas/src/views/cluster/Cluster.vue b/apps/daas/src/views/cluster/Cluster.vue index fed537e631..48600bfc9a 100644 --- a/apps/daas/src/views/cluster/Cluster.vue +++ b/apps/daas/src/views/cluster/Cluster.vue @@ -557,8 +557,7 @@ export default { clusterApi.editAgent(this.custId, data).then(() => { this.editAgentDialog = false this.$message.success(this.$t('public_message_save_ok')) - - this.$set(this.editAgentItem, 'agentName', this.agentName) + this.editAgentItem.agentName = this.agentName }) // .catch(() => { // }) diff --git a/apps/daas/src/views/setting/Setting.vue b/apps/daas/src/views/setting/Setting.vue index 58959fd02b..b5d97f128f 100644 --- a/apps/daas/src/views/setting/Setting.vue +++ b/apps/daas/src/views/setting/Setting.vue @@ -287,11 +287,11 @@ export default { }, handleChangeCert(target, value) { - this.$set(target, 'value', value) + target.value = value }, handleChangeName(target, name) { - this.$set(target, 'fileName', name) + target.fileName = name }, }, } diff --git a/apps/daas/src/views/setting/WebhookAlerts.vue b/apps/daas/src/views/setting/WebhookAlerts.vue index f877dfad85..e5308761cc 100644 --- a/apps/daas/src/views/setting/WebhookAlerts.vue +++ b/apps/daas/src/views/setting/WebhookAlerts.vue @@ -310,7 +310,7 @@ export default { }) }, handleSwitch(row) { - this.$set(this.switchStateMap, row.id, true) + this.switchStateMap[row.id] = true webhookApi[row.open ? 'close' : 'open'](row.id) .then(() => { row.open = !row.open @@ -320,15 +320,16 @@ export default { row.open = !row.open }) .finally(() => { - this.$delete(this.switchStateMap, row.id) + delete this.switchStateMap[row.id] }) }, async reSend(request) { - this.$set(this.resendStateMap, request.id, true) + this.resendStateMap[request.id] = true const result = await webhookApi.resend(request) Object.assign(request, this.mapHistory(result)) this.$message.success(this.$t('public_message_send_success')) - this.$delete(this.resendStateMap, request.id) + + delete this.resendStateMap[request.id] }, afterCloseHistory() { this.historyState.collapse = [] diff --git a/packages/business/src/components/TablePage.vue b/packages/business/src/components/TablePage.vue index 628bfc37fc..ba338bef6f 100644 --- a/packages/business/src/components/TablePage.vue +++ b/packages/business/src/components/TablePage.vue @@ -107,7 +107,7 @@ export default { this.handleKeyDown = (ev) => { this.shiftKeyPressed = ev.shiftKey } - this.handleKeyUp = (ev) => { + this.handleKeyUp = () => { setTimeout(() => { this.shiftKeyPressed = false }, 0) @@ -193,7 +193,7 @@ export default { this.dragState.isDragging = true const selection = this.multipleSelection - if (selection.find((it) => it.id === row.id)) { + if (selection.some((it) => it.id === row.id)) { this.dragState.draggingObjects = selection } else { this.dragState.draggingObjects = [row] @@ -318,11 +318,10 @@ export default { :default-sort="defaultSort" :draggable="draggable || classificationVisible" @selection-change="handleSelectionChange" - @sort-change="$emit('sort-change', $event)" + @sort-change="$emit('sortChange', $event)" @row-dragstart="handleDragStart" @row-dragend="handleDragEnd" @select="onSelectRow" - v-on="$listeners" > diff --git a/packages/business/src/views/verification/components/ConditionBox.vue b/packages/business/src/views/verification/components/ConditionBox.vue index 276114616b..74dfdebe70 100644 --- a/packages/business/src/views/verification/components/ConditionBox.vue +++ b/packages/business/src/views/verification/components/ConditionBox.vue @@ -2082,18 +2082,15 @@ return {result: 'failed',message: "记录不一致",data: targetRow} toggleCollate(item, value) { if (value) { const fields = Object.keys(item.collate || {}) + if (fields.length || !item.sortColumn) return const sortColumn = item.sortColumn.split(',') - this.$set( - item, - 'collate', - sortColumn.reduce((acc, key) => { - acc[key] = '' - return acc - }, {}), - ) + item.collate = sortColumn.reduce((acc, key) => { + acc[key] = '' + return acc + }, {}) } }, }, diff --git a/packages/dag/src/MigrationMonitorSimple.vue b/packages/dag/src/MigrationMonitorSimple.vue index 0a3c333b8c..ba05d99cef 100644 --- a/packages/dag/src/MigrationMonitorSimple.vue +++ b/packages/dag/src/MigrationMonitorSimple.vue @@ -1,531 +1,78 @@ - - - getTime() { - return Time.now() - }, +