Browse Source

Task node of SWITCH (#5939)

2.0.7-release
myangle1120 3 years ago committed by GitHub
parent
commit
c37f1488bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/config.js
  2. 3
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.scss
  3. 17
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
  4. 223
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/switch.vue
  5. BIN
      dolphinscheduler-ui/src/js/conf/home/pages/dag/img/toolbar_SWITCH.png
  6. 4
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  7. 4
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

4
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/config.js

@ -308,6 +308,10 @@ const tasksType = {
CONDITIONS: { CONDITIONS: {
desc: 'CONDITIONS', desc: 'CONDITIONS',
color: '#E46F13' color: '#E46F13'
},
SWITCH: {
desc: 'SWITCH',
color: '#E46F13'
} }
} }

3
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.scss

@ -113,6 +113,9 @@
.icos-CONDITIONS { .icos-CONDITIONS {
background: url("../img/toolbar_CONDITIONS.png") no-repeat 50% 50%; background: url("../img/toolbar_CONDITIONS.png") no-repeat 50% 50%;
} }
.icos-SWITCH{
background: url("../img/toolbar_SWITCH.png") no-repeat 50% 50%;
}
.toolbar { .toolbar {
width: 60px; width: 60px;
height: 100%; height: 100%;

17
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue

@ -95,7 +95,7 @@
</m-list-box> </m-list-box>
<!-- Delay execution time --> <!-- Delay execution time -->
<m-list-box v-if="nodeData.taskType !== 'SUB_PROCESS' && nodeData.taskType !== 'CONDITIONS' && nodeData.taskType !== 'DEPENDENT'"> <m-list-box v-if="nodeData.taskType !== 'SUB_PROCESS' && nodeData.taskType !== 'CONDITIONS' && nodeData.taskType !== 'DEPENDENT'&& nodeData.taskType !== 'SWITCH'">
<div slot="text">{{$t('Delay execution time')}}</div> <div slot="text">{{$t('Delay execution time')}}</div>
<div slot="content"> <div slot="content">
<m-select-input v-model="delayTime" :list="[0,1,5,10]"></m-select-input> <m-select-input v-model="delayTime" :list="[0,1,5,10]"></m-select-input>
@ -258,6 +258,13 @@
:backfill-item="backfillItem" :backfill-item="backfillItem"
:pre-node="nodeData.preNode"> :pre-node="nodeData.preNode">
</m-conditions> </m-conditions>
<m-switch
v-if="nodeData.taskType === 'SWITCH'"
ref="SWITCH"
@on-switch-result="_onSwitchResult"
:backfill-item="backfillItem"
:nodeData="nodeData"
></m-switch>
<!-- Pre-tasks in workflow --> <!-- Pre-tasks in workflow -->
<m-pre-tasks <m-pre-tasks
v-if="['SHELL', 'SUB_PROCESS'].indexOf(nodeData.taskType) > -1" v-if="['SHELL', 'SUB_PROCESS'].indexOf(nodeData.taskType) > -1"
@ -293,6 +300,7 @@
import mHttp from './tasks/http' import mHttp from './tasks/http'
import mDatax from './tasks/datax' import mDatax from './tasks/datax'
import mConditions from './tasks/conditions' import mConditions from './tasks/conditions'
import mSwitch from './tasks/switch.vue'
import mSqoop from './tasks/sqoop' import mSqoop from './tasks/sqoop'
import mSubProcess from './tasks/sub_process' import mSubProcess from './tasks/sub_process'
import mSelectInput from './_source/selectInput' import mSelectInput from './_source/selectInput'
@ -328,6 +336,7 @@
successNode: [], successNode: [],
failedNode: [] failedNode: []
}, },
switchResult: {},
// dependence // dependence
dependence: {}, dependence: {},
// cache dependence // cache dependence
@ -386,6 +395,9 @@
_onDependent (o) { _onDependent (o) {
this.dependence = Object.assign(this.dependence, {}, o) this.dependence = Object.assign(this.dependence, {}, o)
}, },
_onSwitchResult (o) {
this.switchResult = o
},
/** /**
* Pre-tasks in workflow * Pre-tasks in workflow
*/ */
@ -480,6 +492,7 @@
desc: this.desc, desc: this.desc,
runFlag: this.runFlag, runFlag: this.runFlag,
conditionResult: this.conditionResult, conditionResult: this.conditionResult,
switchResult: this.switchResult,
dependence: this.cacheDependence, dependence: this.cacheDependence,
maxRetryTimes: this.maxRetryTimes, maxRetryTimes: this.maxRetryTimes,
retryInterval: this.retryInterval, retryInterval: this.retryInterval,
@ -604,6 +617,7 @@
desc: this.desc, desc: this.desc,
runFlag: this.runFlag, runFlag: this.runFlag,
conditionResult: this.conditionResult, conditionResult: this.conditionResult,
switchResult: this.switchResult,
dependence: this.dependence, dependence: this.dependence,
maxRetryTimes: this.maxRetryTimes, maxRetryTimes: this.maxRetryTimes,
retryInterval: this.retryInterval, retryInterval: this.retryInterval,
@ -801,6 +815,7 @@
mDatax, mDatax,
mSqoop, mSqoop,
mConditions, mConditions,
mSwitch,
mSelectInput, mSelectInput,
mTimeoutAlarm, mTimeoutAlarm,
mDependentTimeout, mDependentTimeout,

223
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/switch.vue

@ -0,0 +1,223 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
<template>
<div class="conditions-model">
<m-list-box>
<div slot="text">{{$t('condition')}}</div>
<div slot="content">
<div class="dep-opt">
<a href="javascript:"
@click="!isDetails && _addDep()"
class="add-dep">
<em v-if="!isLoading" class="el-icon-circle-plus-outline" :class="_isDetails" data-toggle="tooltip" :title="$t('Add')"></em>
<em v-if="isLoading" class="el-icon-loading as as-spin" data-toggle="tooltip" :title="$t('Add')"></em>
</a>
</div>
<div class="dep-list-model">
<div v-for="(el,index) in dependItemList" :key='index' class="switch-list">
<label style="display:block">
<textarea :id="`code-switch-mirror${index}`" :name="`code-switch-mirror${index}`" style="opacity: 0;">
</textarea>
</label>
<span class="text-b" style="padding-left: 0">{{$t('Branch flow')}}</span>
<el-select style="width: 157px;" size="small" v-model="el.nextNode" clearable>
<el-option v-for="item in nodeData.rearList" :key="item.value" :value="item.value" :label="item.label"></el-option>
</el-select>
<span class="operation">
<a href="javascript:" class="delete" @click="!isDetails && _removeDep(index)" v-if="index === (dependItemList.length - 1)">
<em class="iconfont el-icon-delete" :class="_isDetails" data-toggle="tooltip" data-container="body" :title="$t('Delete')" ></em>
</a>
<a href="javascript:" class="add" @click="!isDetails && _addDep()" v-if="index === (dependItemList.length - 1)">
<em class="iconfont el-icon-circle-plus-outline" :class="_isDetails" data-toggle="tooltip" data-container="body" :title="$t('Add')"></em>
</a>
</span>
</div>
</div>
</div>
</m-list-box>
<m-list-box>
<div slot="text">{{$t('Branch flow')}}</div>
<div slot="content">
<el-select style="width: 157px;" size="small" v-model="nextNode" clearable :disabled="isDetails">
<el-option v-for="item in nodeData.rearList" :key="item.value" :value="item.value" :label="item.label"></el-option>
</el-select>
</div>
</m-list-box>
</div>
</template>
<script>
import _ from 'lodash'
import mListBox from './_source/listBox'
import disabledState from '@/module/mixin/disabledState'
import codemirror from '@/conf/home/pages/resource/pages/file/pages/_source/codemirror'
let editArray = []
export default {
name: 'dependence',
data () {
return {
nextNode: '',
relation: 'AND',
dependItemList: [],
editArray: [],
isLoading: false,
oldList: []
}
},
mixins: [disabledState],
props: {
nodeData: Object,
backfillItem: Object,
rearList: Array
},
methods: {
editList (index) {
// editor
const self = this
const editor = codemirror(`code-switch-mirror${index}`, {
mode: 'shell',
readOnly: this.isInstance
}, this)
editor.on('change', function () {
const outputList = _.cloneDeep(self.dependItemList)
outputList[index].condition = editor.getValue()
self.dependItemList = outputList
})
this.keypress = () => {
if (!editor.getOption('readOnly')) {
editor.showHint({
completeSingle: false
})
}
}
editor.on('keypress', this.keypress)
editor.setValue(this.dependItemList[index].condition || '')
editor.setSize('580px', '60px')
editArray.push(editor)
this.oldList = _.cloneDeep(this.dependItemList)
return editArray
},
_addDep () {
if (!this.isLoading) {
this.isLoading = true
this.dependItemList.push({
condition: '',
nextNode: ''
})
let dependItemListLen = this.dependItemList.length
if (dependItemListLen > 0) {
setTimeout(() => {
this.editList(dependItemListLen - 1)
this.isLoading = false
}, 200)
}
this._removeTip()
}
},
_removeDep (i) {
this.dependItemList.splice(i, 1)
this._removeTip()
},
_removeTip () {
$('body').find('.tooltip.fade.top.in').remove()
},
_verification () {
let flag = this.dependItemList.some((item) => {
return !item.condition
})
if (flag) {
this.$message.warning(`${this.$t('The condition content cannot be empty')}`)
return false
}
let params = {
dependTaskList: this.dependItemList || [],
nextNode: this.nextNode || ''
}
this.$emit('on-switch-result', params)
return true
}
},
watch: {},
beforeCreate () {
},
created () {
const o = this.backfillItem
if (!_.isEmpty(o)) {
let switchResult = o.switchResult || {}
this.dependItemList = _.cloneDeep(switchResult.dependTaskList) || []
this.nextNode = _.cloneDeep(switchResult.nextNode) || ''
}
},
mounted () {
if (this.dependItemList && this.dependItemList.length > 0) {
setTimeout(() => {
this.dependItemList.forEach((item, index) => {
this.editList(index)
})
})
}
},
destroyed () {
},
computed: {
},
components: { mListBox }
}
</script>
<style lang="scss" rel="stylesheet/scss">
.conditions-model {
margin-top: -10px;
.dep-opt {
margin-bottom: 10px;
padding-top: 3px;
line-height: 24px;
.add-dep {
color: #0097e0;
margin-right: 10px;
i {
font-size: 18px;
vertical-align: middle;
}
}
}
.dep-list-model{
position: relative;
min-height: 0px;
.switch-list {
margin-bottom: 6px;
.operation {
padding-left: 4px;
a {
i {
font-size: 18px;
vertical-align: middle;
}
}
.delete {
color: #ff0000;
}
.add {
color: #0097e0;
}
}
}
}
}
</style>

BIN
dolphinscheduler-ui/src/js/conf/home/pages/dag/img/toolbar_SWITCH.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

4
dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js

@ -695,5 +695,7 @@ export default {
'The workflow canvas is abnormal and cannot be saved, please recreate': 'The workflow canvas is abnormal and cannot be saved, please recreate', 'The workflow canvas is abnormal and cannot be saved, please recreate': 'The workflow canvas is abnormal and cannot be saved, please recreate',
Info: 'Info', Info: 'Info',
'Datasource userName': 'owner', 'Datasource userName': 'owner',
'Resource userName': 'owner' 'Resource userName': 'owner',
condition: 'condition',
'The condition content cannot be empty': 'The condition content cannot be empty'
} }

4
dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -694,5 +694,7 @@ export default {
'The workflow canvas is abnormal and cannot be saved, please recreate': '该工作流画布异常无法保存请重新创建', 'The workflow canvas is abnormal and cannot be saved, please recreate': '该工作流画布异常无法保存请重新创建',
Info: '提示', Info: '提示',
'Datasource userName': '所属用户', 'Datasource userName': '所属用户',
'Resource userName': '所属用户' 'Resource userName': '所属用户',
condition: '条件',
'The condition content cannot be empty': '条件内容不能为空'
} }

Loading…
Cancel
Save