This is an automated email from the ASF dual-hosted git repository.
leonbao pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new ca488fc copy configs from taskDefinition (#6179)
ca488fc is described below
commit ca488fcfa662b4371a9b3a207db0b000f9b352cf
Author: Wangyizhi1 <[email protected]>
AuthorDate: Mon Sep 13 14:47:26 2021 +0800
copy configs from taskDefinition (#6179)
---
.../dag/_source/formModel/_source/copyFromTask.vue | 232 +++++++
.../home/pages/dag/_source/formModel/formModel.vue | 710 +++++++++++++--------
.../src/js/conf/home/store/dag/actions.js | 9 +
.../src/js/module/i18n/locale/en_US.js | 4 +-
.../src/js/module/i18n/locale/zh_CN.js | 4 +-
5 files changed, 693 insertions(+), 266 deletions(-)
diff --git
a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/copyFromTask.vue
b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/copyFromTask.vue
new file mode 100644
index 0000000..cc5ad42
--- /dev/null
+++
b/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>
diff --git
a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
index 22294cd..774a6fe 100644
---
a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
+++
b/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>
diff --git a/dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js
b/dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js
index d1dabb4..3459502 100644
--- a/dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js
+++ b/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)
+ })
+ })
}
}
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
index 99164b7..e72a1d0 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
+++ b/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...'
}
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
index f84d5ff..0393534 100644
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
+++ b/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...': '没有更多了...'
}