Browse Source

copy configs from taskDefinition (#6179)

2.0.7-release
Wangyizhi1 3 years ago committed by GitHub
parent
commit
ca488fcfa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 232
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/copyFromTask.vue
  2. 710
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
  3. 9
      dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js
  4. 4
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  5. 4
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

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

@ -0,0 +1,232 @@
/*
* 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>
<list-box>
<div slot="text">{{ $t("Copy from") }}</div>
<div slot="content" class="copy-from" ref="copyFrom">
<div class="copy-from-content">
<el-input
class="copy-from-input"
v-model="searchVal"
:placeholder="getTaskName(value) || $t('Please choose')"
@focus="inputFocus"
@input="searchValChange"
size="small"
:suffix-icon="
dropdownVisible ? 'el-icon-arrow-up' : 'el-icon-arrow-down'
"
></el-input>
<div class="copy-from-dropdown" v-show="dropdownVisible">
<div class="scroll-box">
<ul v-infinite-scroll="load">
<li
v-for="taskDefinition in taskDefinitions"
:key="taskDefinition.code"
class="dropdown-item"
@click="itemClick(taskDefinition)"
>
{{ taskDefinition.name }}
</li>
</ul>
<p class="dropdown-msg" v-if="loading">{{ $t("Loading...") }}</p>
<p class="dropdown-msg" v-if="noMore">{{ $t("No more...") }}</p>
</div>
</div>
</div>
</div>
</list-box>
</template>
<script>
import ListBox from '../tasks/_source/listBox'
import { mapActions } from 'vuex'
export default {
name: 'copy-from-task',
props: {
taskType: String
},
inject: ['formModel'],
data () {
return {
pageNo: 1,
pageSize: 10,
searchVal: '',
value: '',
loading: false,
noMore: false,
taskDefinitions: [],
dropdownVisible: false
}
},
mounted () {
document.addEventListener('click', this.outsideClick)
this.load()
},
destroyed () {
document.removeEventListener('click', this.outsideClick)
},
methods: {
...mapActions('dag', ['getTaskDefinitions']),
outsideClick (e) {
const elem = this.$refs.copyFrom
if (!elem.contains(e.target) && this.dropdownVisible) {
this.dropdownVisible = false
}
},
searchValChange (val) {
this.load(true)
},
load (override) {
if (this.loading) return
if (override) {
this.noMore = false
this.pageNo = 1
}
if (this.noMore) return
this.loading = true
this.getTaskDefinitions({
pageNo: this.pageNo,
pageSize: this.pageSize,
searchVal: this.searchVal,
taskType: this.taskType
}).then((res) => {
this.taskDefinitions = override ? res.totalList : this.taskDefinitions.concat(res.totalList)
this.pageNo = res.currentPage + 1
this.noMore = this.taskDefinitions.length >= res.total
this.loading = false
})
},
itemClick (taskDefinition) {
this.value = taskDefinition.code
this.searchVal = taskDefinition.name
this.dropdownVisible = false
if (this.formModel) {
const backfillItem = this.formModel.taskToBackfillItem(taskDefinition)
this.formModel.backfillRefresh = false
this.$nextTick(() => {
this.formModel.backfillItem = backfillItem
this.formModel.backfill(backfillItem, true)
this.formModel.backfillRefresh = true
})
}
},
inputFocus () {
this.searchVal = ''
this.dropdownVisible = true
},
inputBlur () {
this.dropdownVisible = false
},
getTaskName (code) {
const taskDefinition = this.taskDefinitions.find(
(taskDefinition) => taskDefinition.code === code
)
return taskDefinition ? taskDefinition.name : ''
}
},
components: {
ListBox
}
}
</script>
<style lang="scss" scoped>
.copy-from {
position: relative;
&-content {
width: 100%;
}
&-input {
width: 100%;
}
&-dropdown {
width: 100%;
position: absolute;
padding: 6px 0;
top: 42px;
left: 0;
z-index: 10;
border: 1px solid #e4e7ed;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
.scroll-box {
width: 100%;
max-height: 200px;
overflow: auto;
}
.dropdown-item {
font-size: 14px;
padding: 0 20px;
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #606266;
height: 34px;
line-height: 34px;
box-sizing: border-box;
cursor: pointer;
&:hover {
background-color: #f5f7fa;
}
&.selected {
color: #409eff;
font-weight: 700;
}
}
&:before,
&:after {
content: "";
position: absolute;
display: block;
width: 0;
height: 0;
top: -6px;
left: 35px;
border-width: 6px;
border-top-width: 0;
border-color: transparent;
border-bottom-color: #fff;
border-style: solid;
z-index: 10;
}
&:before {
top: -8px;
left: 33px;
border-width: 8px;
border-top-width: 0;
border-bottom-color: #ebeef5;
z-index: 9;
}
.dropdown-msg {
text-align: center;
color: #666;
font-size: 12px;
line-height: 34px;
margin: 0;
}
}
}
</style>

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

@ -17,21 +17,38 @@
<template>
<div class="form-model-wrapper" v-clickoutside="_handleClose">
<div class="title-box">
<span class="name">{{$t('Current node settings')}}</span>
<span class="name">{{ $t("Current node settings") }}</span>
<span class="go-subtask">
<!-- Component can't pop up box to do component processing -->
<m-log v-if="taskInstance" :item="backfillItem" :task-instance-id="taskInstance.id">
<template slot="history"><a href="javascript:" @click="_seeHistory" ><em class="ansicon el-icon-alarm-clock"></em><em>{{$t('View history')}}</em></a></template>
<template slot="log"><a href="javascript:"><em class="ansicon el-icon-document"></em><em>{{$t('View log')}}</em></a></template>
<m-log
v-if="taskInstance"
:item="backfillItem"
:task-instance-id="taskInstance.id"
>
<template slot="history"
><a href="javascript:" @click="_seeHistory"
><em class="ansicon el-icon-alarm-clock"></em
><em>{{ $t("View history") }}</em></a
></template
>
<template slot="log"
><a href="javascript:"
><em class="ansicon el-icon-document"></em
><em>{{ $t("View log") }}</em></a
></template
>
</m-log>
<a href="javascript:" @click="_goSubProcess" v-if="_isGoSubProcess"><em class="ansicon ri-node-tree"></em><em>{{$t('Enter this child node')}}</em></a>
<a href="javascript:" @click="_goSubProcess" v-if="_isGoSubProcess"
><em class="ansicon ri-node-tree"></em
><em>{{ $t("Enter this child node") }}</em></a
>
</span>
</div>
<div class="content-box" v-if="isContentBox">
<div class="form-model">
<!-- Node name -->
<m-list-box>
<div slot="text">{{$t('Node name')}}</div>
<div slot="text">{{ $t("Node name") }}</div>
<div slot="content">
<el-input
type="text"
@ -40,41 +57,50 @@
:disabled="isDetails"
:placeholder="$t('Please enter name (required)')"
maxlength="100"
@blur="_verifName()">
@blur="_verifName()"
>
</el-input>
</div>
</m-list-box>
<!-- Copy from task -->
<copy-from-task v-if="!isDetails" :taskType="nodeData.taskType" />
<!-- Running sign -->
<m-list-box>
<div slot="text">{{$t('Run flag')}}</div>
<div slot="text">{{ $t("Run flag") }}</div>
<div slot="content">
<el-radio-group v-model="runFlag" size="small">
<el-radio :label="'YES'" :disabled="isDetails">{{$t('Normal')}}</el-radio>
<el-radio :label="'NO'" :disabled="isDetails">{{$t('Prohibition execution')}}</el-radio>
<el-radio :label="'YES'" :disabled="isDetails">{{
$t("Normal")
}}</el-radio>
<el-radio :label="'NO'" :disabled="isDetails">{{
$t("Prohibition execution")
}}</el-radio>
</el-radio-group>
</div>
</m-list-box>
<!-- description -->
<m-list-box>
<div slot="text">{{$t('Description')}}</div>
<div slot="text">{{ $t("Description") }}</div>
<div slot="content">
<el-input
:rows="2"
type="textarea"
:disabled="isDetails"
v-model="desc"
:placeholder="$t('Please enter description')">
:placeholder="$t('Please enter description')"
>
</el-input>
</div>
</m-list-box>
<!-- Task priority -->
<m-list-box>
<div slot="text">{{$t('Task priority')}}</div>
<div slot="text">{{ $t("Task priority") }}</div>
<div slot="content">
<span class="label-box" style="width: 193px;display: inline-block;">
<span class="label-box" style="width: 193px; display: inline-block">
<m-priority v-model="taskInstancePriority"></m-priority>
</span>
</div>
@ -82,207 +108,305 @@
<!-- Worker group and environment -->
<m-list-box>
<div slot="text">{{$t('Worker group')}}</div>
<div slot="text">{{ $t("Worker group") }}</div>
<div slot="content">
<span class="label-box" style="width: 193px;display: inline-block;">
<span class="label-box" style="width: 193px; display: inline-block">
<m-worker-groups v-model="workerGroup"></m-worker-groups>
</span>
<span class="text-b">{{$t('Environment Name')}}</span>
<m-related-environment v-model="environmentCode" :workerGroup="workerGroup" v-on:environmentCodeEvent="_onUpdateEnvironmentCode"></m-related-environment>
<span class="text-b">{{ $t("Environment Name") }}</span>
<m-related-environment
v-model="environmentCode"
:workerGroup="workerGroup"
v-on:environmentCodeEvent="_onUpdateEnvironmentCode"
></m-related-environment>
</div>
</m-list-box>
<!-- Number of failed retries -->
<m-list-box v-if="nodeData.taskType !== 'SUB_PROCESS'">
<div slot="text">{{$t('Number of failed retries')}}</div>
<div slot="text">{{ $t("Number of failed retries") }}</div>
<div slot="content">
<m-select-input v-model="maxRetryTimes" :list="[0,1,2,3,4]"></m-select-input>
<span>({{$t('Times')}})</span>
<span class="text-b">{{$t('Failed retry interval')}}</span>
<m-select-input v-model="retryInterval" :list="[1,10,30,60,120]"></m-select-input>
<span>({{$t('Minute')}})</span>
<m-select-input
v-model="maxRetryTimes"
:list="[0, 1, 2, 3, 4]"
></m-select-input>
<span>({{ $t("Times") }})</span>
<span class="text-b">{{ $t("Failed retry interval") }}</span>
<m-select-input
v-model="retryInterval"
:list="[1, 10, 30, 60, 120]"
></m-select-input>
<span>({{ $t("Minute") }})</span>
</div>
</m-list-box>
<!-- Delay execution time -->
<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>
<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="content">
<m-select-input v-model="delayTime" :list="[0,1,5,10]"></m-select-input>
<span>({{$t('Minute')}})</span>
<m-select-input
v-model="delayTime"
:list="[0, 1, 5, 10]"
></m-select-input>
<span>({{ $t("Minute") }})</span>
</div>
</m-list-box>
<!-- Branch flow -->
<m-list-box v-if="nodeData.taskType === 'CONDITIONS'">
<div slot="text">{{$t('State')}}</div>
<div slot="text">{{ $t("State") }}</div>
<div slot="content">
<span class="label-box" style="width: 193px;display: inline-block;">
<el-select style="width: 157px;" size="small" v-model="successNode" :disabled="true">
<el-option v-for="item in stateList" :key="item.value" :value="item.value" :label="item.label"></el-option>
<span class="label-box" style="width: 193px; display: inline-block">
<el-select
style="width: 157px"
size="small"
v-model="successNode"
:disabled="true"
>
<el-option
v-for="item in stateList"
:key="item.value"
:value="item.value"
:label="item.label"
></el-option>
</el-select>
</span>
<span class="text-b" style="padding-left: 38px">{{$t('Branch flow')}}</span>
<el-select style="width: 157px;" size="small" v-model="successBranch" clearable :disabled="isDetails">
<el-option v-for="item in postTasks" :key="item.code" :value="item.name" :label="item.name"></el-option>
<span class="text-b" style="padding-left: 38px">{{
$t("Branch flow")
}}</span>
<el-select
style="width: 157px"
size="small"
v-model="successBranch"
clearable
:disabled="isDetails"
>
<el-option
v-for="item in postTasks"
:key="item.code"
:value="item.name"
:label="item.name"
></el-option>
</el-select>
</div>
</m-list-box>
<m-list-box v-if="nodeData.taskType === 'CONDITIONS'">
<div slot="text">{{$t('State')}}</div>
<div slot="text">{{ $t("State") }}</div>
<div slot="content">
<span class="label-box" style="width: 193px;display: inline-block;">
<el-select style="width: 157px;" size="small" v-model="failedNode" :disabled="true">
<el-option v-for="item in stateList" :key="item.value" :value="item.value" :label="item.label"></el-option>
<span class="label-box" style="width: 193px; display: inline-block">
<el-select
style="width: 157px"
size="small"
v-model="failedNode"
:disabled="true"
>
<el-option
v-for="item in stateList"
:key="item.value"
:value="item.value"
:label="item.label"
></el-option>
</el-select>
</span>
<span class="text-b" style="padding-left: 38px">{{$t('Branch flow')}}</span>
<el-select style="width: 157px;" size="small" v-model="failedBranch" clearable :disabled="isDetails">
<el-option v-for="item in postTasks" :key="item.code" :value="item.name" :label="item.name"></el-option>
<span class="text-b" style="padding-left: 38px">{{
$t("Branch flow")
}}</span>
<el-select
style="width: 157px"
size="small"
v-model="failedBranch"
clearable
:disabled="isDetails"
>
<el-option
v-for="item in postTasks"
:key="item.code"
:value="item.name"
:label="item.name"
></el-option>
</el-select>
</div>
</m-list-box>
<!-- Task timeout alarm -->
<m-timeout-alarm
v-if="nodeData.taskType !== 'DEPENDENT'"
ref="timeout"
:backfill-item="backfillItem"
@on-timeout="_onTimeout">
</m-timeout-alarm>
<!-- Dependent timeout alarm -->
<m-dependent-timeout
v-if="nodeData.taskType === 'DEPENDENT'"
ref="dependentTimeout"
:backfill-item="backfillItem"
@on-timeout="_onDependentTimeout">
</m-dependent-timeout>
<div v-if="backfillRefresh">
<!-- Task timeout alarm -->
<m-timeout-alarm
v-if="nodeData.taskType !== 'DEPENDENT'"
ref="timeout"
:backfill-item="backfillItem"
@on-timeout="_onTimeout"
>
</m-timeout-alarm>
<!-- Dependent timeout alarm -->
<m-dependent-timeout
v-if="nodeData.taskType === 'DEPENDENT'"
ref="dependentTimeout"
:backfill-item="backfillItem"
@on-timeout="_onDependentTimeout"
>
</m-dependent-timeout>
<!-- shell node -->
<m-shell
v-if="nodeData.taskType === 'SHELL'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="SHELL"
:backfill-item="backfillItem">
</m-shell>
<!-- waterdrop node -->
<m-waterdrop
v-if="nodeData.taskType === 'WATERDROP'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="WATERDROP"
:backfill-item="backfillItem">
</m-waterdrop>
<!-- sub_process node -->
<m-sub-process
v-if="nodeData.taskType === 'SUB_PROCESS'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
@on-set-process-name="_onSetProcessName"
ref="SUB_PROCESS"
:backfill-item="backfillItem">
</m-sub-process>
<!-- procedure node -->
<m-procedure
v-if="nodeData.taskType === 'PROCEDURE'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="PROCEDURE"
:backfill-item="backfillItem">
</m-procedure>
<!-- sql node -->
<m-sql
v-if="nodeData.taskType === 'SQL'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="SQL"
:create-node-id="nodeData.id"
:backfill-item="backfillItem">
</m-sql>
<!-- spark node -->
<m-spark
v-if="nodeData.taskType === 'SPARK'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="SPARK"
:backfill-item="backfillItem">
</m-spark>
<m-flink
v-if="nodeData.taskType === 'FLINK'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="FLINK"
:backfill-item="backfillItem">
</m-flink>
<!-- mr node -->
<m-mr
v-if="nodeData.taskType === 'MR'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="MR"
:backfill-item="backfillItem">
</m-mr>
<!-- python node -->
<m-python
v-if="nodeData.taskType === 'PYTHON'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="PYTHON"
:backfill-item="backfillItem">
</m-python>
<!-- dependent node -->
<m-dependent
v-if="nodeData.taskType === 'DEPENDENT'"
@on-dependent="_onDependent"
@on-cache-dependent="_onCacheDependent"
ref="DEPENDENT"
:backfill-item="backfillItem">
</m-dependent>
<m-http
v-if="nodeData.taskType === 'HTTP'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="HTTP"
:backfill-item="backfillItem">
</m-http>
<m-datax
v-if="nodeData.taskType === 'DATAX'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="DATAX"
:backfill-item="backfillItem">
</m-datax>
<m-sqoop
v-if="nodeData.taskType === 'SQOOP'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="SQOOP"
:backfill-item="backfillItem">
</m-sqoop>
<m-conditions
v-if="nodeData.taskType === 'CONDITIONS'"
ref="CONDITIONS"
@on-dependent="_onDependent"
@on-cache-dependent="_onCacheDependent"
:backfill-item="backfillItem"
:prev-tasks="prevTasks">
</m-conditions>
<m-switch
v-if="nodeData.taskType === 'SWITCH'"
ref="SWITCH"
@on-switch-result="_onSwitchResult"
:backfill-item="backfillItem"
:nodeData="nodeData"
></m-switch>
<!-- shell node -->
<m-shell
v-if="nodeData.taskType === 'SHELL'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="SHELL"
:backfill-item="backfillItem"
>
</m-shell>
<!-- waterdrop node -->
<m-waterdrop
v-if="nodeData.taskType === 'WATERDROP'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="WATERDROP"
:backfill-item="backfillItem"
>
</m-waterdrop>
<!-- sub_process node -->
<m-sub-process
v-if="nodeData.taskType === 'SUB_PROCESS'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
@on-set-process-name="_onSetProcessName"
ref="SUB_PROCESS"
:backfill-item="backfillItem"
>
</m-sub-process>
<!-- procedure node -->
<m-procedure
v-if="nodeData.taskType === 'PROCEDURE'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="PROCEDURE"
:backfill-item="backfillItem"
>
</m-procedure>
<!-- sql node -->
<m-sql
v-if="nodeData.taskType === 'SQL'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="SQL"
:create-node-id="nodeData.id"
:backfill-item="backfillItem"
>
</m-sql>
<!-- spark node -->
<m-spark
v-if="nodeData.taskType === 'SPARK'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="SPARK"
:backfill-item="backfillItem"
>
</m-spark>
<m-flink
v-if="nodeData.taskType === 'FLINK'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="FLINK"
:backfill-item="backfillItem"
>
</m-flink>
<!-- mr node -->
<m-mr
v-if="nodeData.taskType === 'MR'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="MR"
:backfill-item="backfillItem"
>
</m-mr>
<!-- python node -->
<m-python
v-if="nodeData.taskType === 'PYTHON'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="PYTHON"
:backfill-item="backfillItem"
>
</m-python>
<!-- dependent node -->
<m-dependent
v-if="nodeData.taskType === 'DEPENDENT'"
@on-dependent="_onDependent"
@on-cache-dependent="_onCacheDependent"
ref="DEPENDENT"
:backfill-item="backfillItem"
>
</m-dependent>
<m-http
v-if="nodeData.taskType === 'HTTP'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="HTTP"
:backfill-item="backfillItem"
>
</m-http>
<m-datax
v-if="nodeData.taskType === 'DATAX'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="DATAX"
:backfill-item="backfillItem"
>
</m-datax>
<m-sqoop
v-if="nodeData.taskType === 'SQOOP'"
@on-params="_onParams"
@on-cache-params="_onCacheParams"
ref="SQOOP"
:backfill-item="backfillItem"
>
</m-sqoop>
<m-conditions
v-if="nodeData.taskType === 'CONDITIONS'"
ref="CONDITIONS"
@on-dependent="_onDependent"
@on-cache-dependent="_onCacheDependent"
:backfill-item="backfillItem"
:prev-tasks="prevTasks"
>
</m-conditions>
<m-switch
v-if="nodeData.taskType === 'SWITCH'"
ref="SWITCH"
@on-switch-result="_onSwitchResult"
:backfill-item="backfillItem"
:nodeData="nodeData"
></m-switch>
</div>
<!-- Pre-tasks in workflow -->
<m-pre-tasks ref="preTasks" v-if="['SHELL', 'SUB_PROCESS'].indexOf(nodeData.taskType) > -1" :code="code"/>
<m-pre-tasks
ref="preTasks"
v-if="['SHELL', 'SUB_PROCESS'].indexOf(nodeData.taskType) > -1"
:code="code"
/>
</div>
</div>
<div class="bottom-box">
<div class="submit" style="background: #fff;">
<el-button type="text" size="small" id="cancelBtn"> {{$t('Cancel')}} </el-button>
<el-button type="primary" size="small" round :loading="spinnerLoading" @click="ok()" :disabled="isDetails">{{spinnerLoading ? $t('Loading...') : $t('Confirm add')}} </el-button>
<div class="submit" style="background: #fff">
<el-button type="text" size="small" id="cancelBtn">
{{ $t("Cancel") }}
</el-button>
<el-button
type="primary"
size="small"
round
:loading="spinnerLoading"
@click="ok()"
:disabled="isDetails"
>{{ spinnerLoading ? $t("Loading...") : $t("Confirm add") }}
</el-button>
</div>
</div>
</div>
@ -318,6 +442,7 @@
import disabledState from '@/module/mixin/disabledState'
import mPriority from '@/module/components/priority/priority'
import { findComponentDownward } from '@/module/util/'
import CopyFromTask from './_source/copyFromTask.vue'
export default {
name: 'form-model',
@ -384,7 +509,14 @@
],
// for CONDITIONS
postTasks: [],
prevTasks: []
prevTasks: [],
// refresh part of the formModel, after set backfillItem outside
backfillRefresh: true
}
},
provide () {
return {
formModel: this
}
},
/**
@ -408,7 +540,11 @@
id: task.id,
maxRetryTimes: task.failRetryTimes,
name: task.name,
params: _.omit(task.taskParams, ['conditionResult', 'dependence']),
params: _.omit(task.taskParams, [
'conditionResult',
'dependence',
'waitStartTimeout'
]),
retryInterval: task.failRetryInterval,
runFlag: task.flag,
taskInstancePriority: task.taskPriority,
@ -448,13 +584,17 @@
*/
_onDependentTimeout (o) {
this.timeout = Object.assign(this.timeout, {}, o.waitCompleteTimeout)
this.waitStartTimeout = Object.assign(this.waitStartTimeout, {}, o.waitStartTimeout)
this.waitStartTimeout = Object.assign(
this.waitStartTimeout,
{},
o.waitStartTimeout
)
},
/**
* Click external to close the current component
*/
_handleClose () {
// this.close()
// this.close()
},
/**
* Jump to task instance
@ -468,25 +608,39 @@
*/
_goSubProcess () {
if (_.isEmpty(this.backfillItem)) {
this.$message.warning(`${i18n.$t('The newly created sub-Process has not yet been executed and cannot enter the sub-Process')}`)
this.$message.warning(
`${i18n.$t(
'The newly created sub-Process has not yet been executed and cannot enter the sub-Process'
)}`
)
return
}
if (this.router.history.current.name === 'projects-instance-details') {
if (!this.taskInstance) {
this.$message.warning(`${i18n.$t('The task has not been executed and cannot enter the sub-Process')}`)
this.$message.warning(
`${i18n.$t(
'The task has not been executed and cannot enter the sub-Process'
)}`
)
return
}
this.store.dispatch('dag/getSubProcessId', { taskId: this.taskInstance.id }).then(res => {
this.$emit('onSubProcess', {
subProcessId: res.data.subProcessInstanceId,
fromThis: this
this.store
.dispatch('dag/getSubProcessId', { taskId: this.taskInstance.id })
.then((res) => {
this.$emit('onSubProcess', {
subProcessId: res.data.subProcessInstanceId,
fromThis: this
})
})
.catch((e) => {
this.$message.error(e.msg || '')
})
}).catch(e => {
this.$message.error(e.msg || '')
})
} else {
const processDefinitionId = this.backfillItem.params.processDefinitionId
const process = this.processListS.find(process => process.processDefinition.id === processDefinitionId)
const processDefinitionId =
this.backfillItem.params.processDefinitionId
const process = this.processListS.find(
(process) => process.processDefinition.id === processDefinitionId
)
this.$emit('onSubProcess', {
subProcessCode: process.processDefinition.code,
fromThis: this
@ -519,8 +673,16 @@
this.$message.warning(`${i18n.$t('Please enter name (required)')}`)
return false
}
if (this.successBranch !== '' && this.successBranch !== null && this.successBranch === this.failedBranch) {
this.$message.warning(`${i18n.$t('Cannot select the same node for successful branch flow and failed branch flow')}`)
if (
this.successBranch !== '' &&
this.successBranch !== null &&
this.successBranch === this.failedBranch
) {
this.$message.warning(
`${i18n.$t(
'Cannot select the same node for successful branch flow and failed branch flow'
)}`
)
return false
}
if (this.name === this.backfillItem.name) {
@ -528,7 +690,7 @@
}
// Name repeat depends on dom backfill dependent store
const tasks = this.store.state.dag.tasks
const task = tasks.find(t => t.name === 'this.name')
const task = tasks.find((t) => t.name === 'this.name')
if (task) {
this.$message.warning(`${i18n.$t('Name already exists')}`)
return false
@ -536,11 +698,15 @@
return true
},
_verifWorkGroup () {
let item = this.store.state.security.workerGroupsListAll.find(item => {
let item = this.store.state.security.workerGroupsListAll.find((item) => {
return item.id === this.workerGroup
})
if (item === undefined) {
this.$message.warning(`${i18n.$t('The Worker group no longer exists, please select the correct Worker group!')}`)
this.$message.warning(
`${i18n.$t(
'The Worker group no longer exists, please select the correct Worker group!'
)}`
)
return false
}
return true
@ -619,20 +785,29 @@
* set run flag
* TODO
*/
_setRunFlag () {
},
/**
*
*/
_setRunFlag () {},
_setEdgeLabel () {
if (this.successBranch || this.failedBranch) {
const canvas = findComponentDownward(this.dagChart, 'dag-canvas')
const edges = canvas.getEdges()
const successTask = this.postTasks.find(t => t.name === this.successBranch)
const failedTask = this.postTasks.find(t => t.name === this.failedBranch)
const sEdge = edges.find(edge => successTask && edge.sourceId === this.code && edge.targetId === successTask.code)
const fEdge = edges.find(edge => failedTask && edge.sourceId === this.code && edge.targetId === failedTask.code)
const successTask = this.postTasks.find(
(t) => t.name === this.successBranch
)
const failedTask = this.postTasks.find(
(t) => t.name === this.failedBranch
)
const sEdge = edges.find(
(edge) =>
successTask &&
edge.sourceId === this.code &&
edge.targetId === successTask.code
)
const fEdge = edges.find(
(edge) =>
failedTask &&
edge.sourceId === this.code &&
edge.targetId === failedTask.code
)
sEdge && canvas.setEdgeLabel(sEdge.id, this.$t('Success'))
fEdge && canvas.setEdgeLabel(fEdge.id, this.$t('Failed'))
}
@ -659,6 +834,57 @@
flag: flag,
fromThis: this
})
},
backfill (backfillItem, copyFromTask) {
const o = backfillItem
// Non-null objects represent backfill
if (!_.isEmpty(o)) {
this.code = o.code
!copyFromTask && (this.name = o.name)
this.taskInstancePriority = o.taskInstancePriority
this.runFlag = o.runFlag || 'YES'
this.desc = o.desc
this.maxRetryTimes = o.maxRetryTimes
this.retryInterval = o.retryInterval
this.delayTime = o.delayTime
if (o.conditionResult) {
this.successBranch = o.conditionResult.successNode[0]
this.failedBranch = o.conditionResult.failedNode[0]
}
// If the workergroup has been deleted, set the default workergroup
for (
let i = 0;
i < this.store.state.security.workerGroupsListAll.length;
i++
) {
let workerGroup = this.store.state.security.workerGroupsListAll[i].id
if (o.workerGroup === workerGroup) {
break
}
}
if (o.workerGroup === undefined) {
this.store
.dispatch('dag/getTaskInstanceList', {
pageSize: 10,
pageNo: 1,
processInstanceId: this.nodeData.instanceId,
name: o.name
})
.then((res) => {
this.workerGroup = res.totalList[0].workerGroup
})
} else {
this.workerGroup = o.workerGroup
}
this.environmentCode = o.environmentCode
this.params = o.params || {}
this.dependence = o.dependence || {}
this.cacheDependence = o.dependence || {}
} else {
this.workerGroup = this.store.state.security.workerGroupsListAll[0].id
}
this.cacheBackfillItem = JSON.parse(JSON.stringify(o))
this.isContentBox = true
}
},
created () {
@ -666,7 +892,7 @@
let taskList = this.store.state.dag.tasks
let o = {}
if (taskList.length) {
taskList.forEach(task => {
taskList.forEach((task) => {
if (task.code === this.nodeData.id) {
const backfillItem = this.taskToBackfillItem(task)
o = backfillItem
@ -675,46 +901,7 @@
})
}
this.code = this.nodeData.id
// Non-null objects represent backfill
if (!_.isEmpty(o)) {
this.code = o.code
this.name = o.name
this.taskInstancePriority = o.taskInstancePriority
this.runFlag = o.runFlag || 'YES'
this.desc = o.desc
this.maxRetryTimes = o.maxRetryTimes
this.retryInterval = o.retryInterval
this.delayTime = o.delayTime
if (o.conditionResult) {
this.successBranch = o.conditionResult.successNode[0]
this.failedBranch = o.conditionResult.failedNode[0]
}
// If the workergroup has been deleted, set the default workergroup
for (let i = 0; i < this.store.state.security.workerGroupsListAll.length; i++) {
let workerGroup = this.store.state.security.workerGroupsListAll[i].id
if (o.workerGroup === workerGroup) {
break
}
}
if (o.workerGroup === undefined) {
this.store.dispatch('dag/getTaskInstanceList', {
pageSize: 10, pageNo: 1, processInstanceId: this.nodeData.instanceId, name: o.name
}).then(res => {
this.workerGroup = res.totalList[0].workerGroup
})
} else {
this.workerGroup = o.workerGroup
}
this.environmentCode = o.environmentCode
this.params = o.params || {}
this.dependence = o.dependence || {}
this.cacheDependence = o.dependence || {}
} else {
this.workerGroup = this.store.state.security.workerGroupsListAll[0].id
}
this.cacheBackfillItem = JSON.parse(JSON.stringify(o))
this.isContentBox = true
this.backfill(o)
if (this.dagChart) {
const canvas = findComponentDownward(this.dagChart, 'dag-canvas')
@ -736,17 +923,11 @@
self.close()
})
},
updated () {
},
beforeDestroy () {
},
destroyed () {
},
updated () {},
beforeDestroy () {},
destroyed () {},
computed: {
...mapState('dag', [
'processListS',
'taskInstances'
]),
...mapState('dag', ['processListS', 'taskInstances']),
/**
* Child workflow entry show/hide
*/
@ -786,16 +967,17 @@
mPriority,
mWorkerGroups,
mRelatedEnvironment,
mPreTasks
mPreTasks,
CopyFromTask
}
}
</script>
<style lang="scss" rel="stylesheet/scss">
@import "./formModel";
.ans-radio-disabled {
.ans-radio-inner:after {
background-color: #6F8391
}
@import "./formModel";
.ans-radio-disabled {
.ans-radio-inner:after {
background-color: #6f8391;
}
}
</style>

9
dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js

@ -829,5 +829,14 @@ export default {
reject(e)
})
})
},
getTaskDefinitions ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`projects/${state.projectCode}/task-definition`, payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
}
}

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

@ -706,5 +706,7 @@ export default {
'Please enter environment desc': 'Please enter environment desc',
'Please select worker groups': 'Please select worker groups',
condition: 'condition',
'The condition content cannot be empty': 'The condition content cannot be empty'
'The condition content cannot be empty': 'The condition content cannot be empty',
'Copy from': 'Copy from',
'No more...': 'No more...'
}

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

@ -705,5 +705,7 @@ export default {
'Please enter environment desc': '请输入详细描述',
'Please select worker groups': '请选择Worker分组',
condition: '条件',
'The condition content cannot be empty': '条件内容不能为空'
'The condition content cannot be empty': '条件内容不能为空',
'Copy from': '从任务复制',
'No more...': '没有更多了...'
}

Loading…
Cancel
Save