Browse Source

[Feature-5498][JsonSplit-api] add task status (#6119)

* Refresh task status

* add version drawer

* Fix missing log button
2.0.7-release
Wangyizhi1 3 years ago committed by GitHub
parent
commit
5d06702711
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 50
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/canvas.vue
  2. 52
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/nodeStatus.js
  3. 30
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/nodeStatus.scss
  4. 70
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/statusMenu.vue
  5. 29
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/toolbar.vue
  6. 40
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/x6-helper.js
  7. 3
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.scss
  8. 273
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue
  9. 18
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
  10. 14
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/log.vue
  11. 10
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/loading.scss
  12. 5
      dolphinscheduler-ui/src/js/conf/home/pages/dag/definitionDetails.vue
  13. 14
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
  14. 5
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/versions.vue
  15. 4
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue
  16. 19
      dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js
  17. 7
      dolphinscheduler-ui/src/js/conf/home/store/dag/state.js
  18. 7
      dolphinscheduler-ui/src/js/module/components/secondaryMenu/secondaryMenu.vue

50
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/canvas.vue

@ -28,16 +28,15 @@
<div ref="paper" class="paper"></div>
<div ref="minimap" class="minimap"></div>
<context-menu ref="contextMenu" />
<status-menu ref="statusMenu" />
</div>
</div>
</template>
<script>
import _ from 'lodash'
import { Graph, DataUri } from '@antv/x6'
import dagTaskbar from './taskbar.vue'
import contextMenu from './contextMenu.vue'
import statusMenu from './statusMenu.vue'
import {
NODE_PROPS,
EDGE_PROPS,
@ -48,12 +47,13 @@
X6_EDGE_NAME,
NODE_HIGHLIGHT_PROPS,
PORT_HIGHLIGHT_PROPS,
EDGE_HIGHLIGHT_PROPS
EDGE_HIGHLIGHT_PROPS,
NODE_STATUS_MARKUP
} from './x6-helper'
import { DagreLayout } from '@antv/layout'
import { tasksType } from '../config'
import _ from 'lodash'
import { tasksType, tasksState } from '../config'
import { mapActions, mapMutations } from 'vuex'
import nodeStatus from './nodeStatus'
export default {
name: 'dag-canvas',
@ -82,8 +82,7 @@
inject: ['dagChart'],
components: {
dagTaskbar,
contextMenu,
statusMenu
contextMenu
},
methods: {
...mapActions('dag', ['genTaskCodeList']),
@ -234,20 +233,9 @@
// nodes and edges hover
this.graph.on('cell:mouseenter', (data) => {
const { cell, e } = data
const { left: cL, top: cT } =
this.$refs.container.getBoundingClientRect()
const cX = e.clientX - cL
const cY = e.clientY - cT
const isStatusIcon = (tagName) =>
tagName && tagName.toLocaleLowerCase() === 'i'
if (isStatusIcon(e.target.tagName)) {
this.$refs.statusMenu.show(cX, cY)
this.$refs.statusMenu.setCurrentTask({
name: cell.data.taskName,
type: cell.data.taskType,
code: Number(cell.id)
})
} else {
tagName && (tagName.toLocaleLowerCase() === 'em' || tagName.toLocaleLowerCase() === 'body')
if (!isStatusIcon(e.target.tagName)) {
this.setHighlight(cell)
}
})
@ -255,7 +243,6 @@
if (!this.graph.isSelected(cell)) {
this.resetHighlight(cell)
}
this.$refs.statusMenu.hide()
})
// select
this.graph.on('cell:selected', ({ cell }) => {
@ -676,6 +663,27 @@
unlockScroller () {
this.graph.unlockScroller()
},
/**
* set node status icon
* @param {number} code
* @param {string} state
*/
setNodeStatus ({ code, state, taskInstance }) {
code += ''
const stateProps = tasksState[state]
const node = this.graph.getCellById(code)
if (node) {
// Destroy the previous dom
node.removeMarkup()
node.setMarkup(NODE_PROPS.markup.concat(NODE_STATUS_MARKUP))
const nodeView = this.graph.findViewByCell(node)
const el = nodeView.find('div')[0]
nodeStatus({
stateProps,
taskInstance
}).$mount(el)
}
},
/**
* Drag && Drop Event
*/

52
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/nodeStatus.js

@ -0,0 +1,52 @@
/*
* 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.
*/
import Vue from 'vue'
import './nodeStatus.scss'
import i18n from '@/module/i18n'
import { formatDate } from '@/module/filter/filter'
const nodeStatus = ({ stateProps, taskInstance }) => {
const Instance = new Vue({
data: {},
methods: {},
render (h) {
return (
<el-tooltip placement="top">
<div slot="content">
<ul class="status-info">
<li>{i18n.$t('Name')}{taskInstance.name}</li>
<li>{i18n.$t('State')}{stateProps.desc}</li>
<li>{i18n.$t('type')}{taskInstance.taskType}</li>
<li>{i18n.$t('host')}{taskInstance.host || '-'}</li>
<li>{i18n.$t('Retry Count')}{taskInstance.retryTimes}</li>
<li>{i18n.$t('Submit Time')}{formatDate(taskInstance.submitTime)}</li>
<li>{i18n.$t('Start Time')}{formatDate(taskInstance.startTime)}</li>
<li>{i18n.$t('End Time')}{taskInstance.endTime ? formatDate(taskInstance.endTime) : '-'}</li>
</ul>
</div>
<em ref="statusIcon" class={`status-icon ${stateProps.icoUnicode}`} style={{
color: stateProps.color
}}></em>
</el-tooltip>
)
}
})
return Instance
}
export default nodeStatus

30
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/nodeStatus.scss

@ -0,0 +1,30 @@
/*
* 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.
*/
.status-icon {
width: 100%;
height: 100%;
display: block;
font-size: 18px;
}
.status-info {
margin-bottom: 0;
li {
margin-bottom: 5px;
}
}

70
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/statusMenu.vue

@ -1,70 +0,0 @@
/*
* 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="dag-status-menu"
v-show="visible"
:style="{
left: `${left}px`,
top: `${top}px`,
}"
>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'dag-status-menu',
inject: ['dagChart', 'dagCanvas'],
data () {
return {
visible: false,
left: 0,
top: 0,
currentTask: {
code: 0,
name: '',
type: ''
}
}
},
computed: {
...mapState('dag', ['tasks'])
},
methods: {
setCurrentTask (task) {
this.currentTask = { ...this.currentTask, ...task }
},
show (x = 0, y = 0) {
this.dagCanvas.lockScroller()
this.visible = true
this.left = x
this.top = y
},
hide () {
this.dagCanvas.unlockScroller()
this.visible = false
}
}
}
</script>
<style lang="scss" scoped>
@import "./contextMenu";
</style>

29
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/toolbar.vue

@ -73,13 +73,19 @@
<i
:class="[
'custom-ico',
dagChart.fullScreen
? 'full-screen-close'
: 'full-screen-open',
dagChart.fullScreen ? 'full-screen-close' : 'full-screen-open',
]"
@click="toggleFullScreen"
></i>
</el-tooltip>
<el-tooltip
class="toolbar-operation"
:content="$t('Refresh DAG status')"
placement="bottom"
v-if="dagChart.type === 'instance'"
>
<i class="el-icon-refresh" @click="refreshTaskStatus"></i>
</el-tooltip>
<el-tooltip
class="toolbar-operation last"
:content="$t('Format DAG')"
@ -87,6 +93,15 @@
>
<i class="custom-ico graph-format" @click="chartFormat"></i>
</el-tooltip>
<el-button
class="toolbar-el-btn"
type="primary"
size="mini"
v-if="dagChart.type === 'definition'"
@click="showVersions"
icon="el-icon-info"
>{{$t('Version Info')}}</el-button
>
<el-button
class="toolbar-el-btn"
type="primary"
@ -180,8 +195,9 @@
const canvas = this.getDagCanvasRef()
canvas.format()
},
// TODO
refreshTaskState () {},
refreshTaskStatus () {
this.dagChart.refreshTaskStatus()
},
returnToListPage () {
let $name = this.$route.name
if ($name && $name.indexOf('definition') !== -1) {
@ -189,6 +205,9 @@
} else {
this.$router.push({ name: 'projects-instance-list' })
}
},
showVersions () {
this.dagChart.showVersions()
}
}
}

40
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/x6-helper.js

@ -132,6 +132,22 @@ export const PORT_HIGHLIGHT_PROPS = {
[X6_PORT_IN_NAME]: {}
}
export const NODE_STATUS_MARKUP = [{
tagName: 'foreignObject',
selector: 'fo',
children: [
{
tagName: 'body',
selector: 'fo-body',
ns: 'http://www.w3.org/1999/xhtml',
children: [{
tagName: 'div',
selector: 'status'
}]
}
]
}]
export const NODE_PROPS = {
width: 220,
height: 48,
@ -148,22 +164,6 @@ export const NODE_PROPS = {
tagName: 'text',
selector: 'title'
}
// {
// tagName: 'foreignObject',
// selector: 'fo',
// children: [
// {
// tagName: 'body',
// selector: 'fo-body',
// ns: 'http://www.w3.org/1999/xhtml',
// children: [{
// tagName: 'i',
// selector: 'state',
// className: 'state-icon el-icon-circle-check'
// }]
// }
// ]
// }
],
attrs: {
body: {
@ -196,14 +196,6 @@ export const NODE_PROPS = {
refY: -25,
width: 18,
height: 18
},
state: {
style: {
display: 'block',
width: '100%',
height: '100%',
fontSize: '18px'
}
}
},
ports: {

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

@ -27,6 +27,7 @@
height: 100%;
top: 0;
left: 0;
z-index: 9999;
z-index: 1000;
}
}

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

@ -54,6 +54,16 @@
></m-start>
</el-dialog>
<edge-edit-model ref="edgeEditModel" />
<el-drawer :visible.sync="versionDrawer" size="" :with-header="false">
<m-versions
:versionData="versionData"
:isInstance="type === 'instance'"
@mVersionSwitchProcessDefinitionVersion="switchProcessVersion"
@mVersionGetProcessDefinitionVersionsPage="getProcessVersions"
@mVersionDeleteProcessDefinitionVersion="deleteProcessVersion"
@closeVersion="closeVersion"
></m-versions>
</el-drawer>
</div>
</template>
@ -66,6 +76,7 @@
import mUdp from '../_source/udp/udp.vue'
import mStart from '../../projects/pages/definition/pages/list/_source/start.vue'
import edgeEditModel from './canvas/edgeEditModel.vue'
import mVersions from '../../projects/pages/definition/pages/list/_source/versions.vue'
const DEFAULT_NODE_DATA = {
id: null,
@ -84,46 +95,79 @@
mFormModel,
mUdp,
mStart,
edgeEditModel
edgeEditModel,
mVersions
},
provide () {
return {
dagChart: this
}
},
inject: ['definitionDetails'],
props: {
type: String,
releaseState: String
},
data () {
return {
definitionCode: 0,
// full screen mode
fullScreen: false,
// whether the task config drawer is visible
taskDrawer: false,
nodeData: { ...DEFAULT_NODE_DATA },
// whether the save dialog is visible
saveDialog: false,
isLoading: false,
definitionCode: 0,
// whether the start dialog is visible
startDialog: false,
startTaskName: ''
startTaskName: '',
// whether the version drawer is visible
versionDrawer: false,
versionData: {
processDefinition: {
id: null,
version: '',
releaseState: ''
},
processDefinitionVersions: [],
total: null,
pageNo: null,
pageSize: null
},
// the task status refresh timer
statusTimer: null
}
},
mounted () {
// TODO
window._debug = this
if (this.type === 'instance') {
this.definitionCode = this.$route.query.id
this.definitionCode = this.$route.query.code
} else if (this.type === 'definition') {
this.definitionCode = this.$route.params.code
}
// auto resize canvas
this.resizeDebounceFunc = debounce(this.canvasResize, 200)
window.addEventListener('resize', this.resizeDebounceFunc)
// init graph
this.$refs.canvas.graphInit(!this.isDetails)
// backfill graph with tasks, locations and connects
this.backfill()
// refresh task status
if (this.type === 'instance') {
this.refreshTaskStatus()
// status polling
this.statusTimer = setInterval(() => {
this.refreshTaskStatus()
}, 90000)
}
},
unmounted () {
beforeDestroy () {
clearInterval(this.statusTimer)
window.removeEventListener('resize', this.resizeDebounceFunc)
},
computed: {
@ -134,7 +178,8 @@
'isEditDag',
'name',
'isDetails',
'projectCode'
'projectCode',
'version'
])
},
methods: {
@ -196,12 +241,12 @@
})
this.toggleTaskDrawer(true)
},
addTaskInfo ({ item, fromThis }) {
addTaskInfo ({ item }) {
this.addTask(item)
this.$refs.canvas.setNodeName(item.code, item.name)
this.taskDrawer = false
},
closeTaskDrawer ({ item, flag, fromThis }) {
closeTaskDrawer ({ flag }) {
if (flag) {
const canvas = this.$refs.canvas
canvas.removeNode(this.nodeData.id)
@ -213,76 +258,69 @@
*/
toggleSaveDialog (value) {
this.saveDialog = value
if (value) {
this.$nextTick(() => {
this.$refs.mUdp.reloadParam()
})
}
},
onSave (sourceType) {
this.toggleSaveDialog(false)
return new Promise((resolve, reject) => {
this.isLoading = true
let tasks = this.tasks || []
const edges = this.$refs.canvas.getEdges()
const nodes = this.$refs.canvas.getNodes()
const connects = this.buildConnects(edges, tasks)
this.setConnects(connects)
const locations = nodes.map(node => {
const locations = nodes.map((node) => {
return {
taskCode: node.id,
x: node.position.x,
y: node.position.y
}
})
this.setLocations(locations)
resolve({
connects: connects,
tasks: tasks,
locations: locations
})
}).then((res) => {
if (this._verifConditions(res.tasks)) {
if (this.verifyConditions(res.tasks)) {
this.loading(true)
const definitionCode = this.definitionCode
if (definitionCode) {
/**
* Edit
* @param saveInstanceEditDAGChart => Process instance editing
* @param saveEditDAGChart => Process definition editing
*/
// Edit
return this[
this.type === 'instance' ? 'updateInstance' : 'updateDefinition'
](definitionCode)
.then((res) => {
// this.$message.success(res.msg)
this.$message({
message: res.msg,
type: 'success',
offset: 80
})
this.isLoading = false
// Jump process definition
if (this.type === 'instance') {
this.$router.push({
path: `/projects/${this.projectCode}/instance/list/${definitionCode}`
path: `/projects/${this.projectCode}/instance/list`
})
} else {
this.$router.push({
path: `/projects/${this.projectCode}/definition/list/${definitionCode}`
path: `/projects/${this.projectCode}/definition/list`
})
}
})
.catch((e) => {
this.$message.error(e.msg || '')
this.isLoading = false
})
.finally((e) => {
this.loading(false)
})
} else {
// New
// Create
return this.saveDAGchart()
.then((res) => {
this.$message.success(res.msg)
this.isLoading = false
// source @/conf/home/pages/dag/_source/editAffirmModel/index.js
if (sourceType !== 'affirm') {
// Jump process definition
@ -290,15 +328,17 @@
}
})
.catch((e) => {
this.$message.error(e.msg || '')
this.setName('')
this.isLoading = false
this.$message.error(e.msg || '')
})
.finally((e) => {
this.loading(false)
})
}
}
})
},
_verifConditions (value) {
verifyConditions (value) {
let tasks = value
let bool = true
tasks.map((v) => {
@ -319,7 +359,6 @@
'Successful branch flow and failed branch flow are required'
)}`
)
this.isLoading = false
return false
}
return true
@ -334,7 +373,7 @@
const nodes = []
const edges = []
tasks.forEach((task) => {
const location = locations.find(l => l.taskCode === task.code) || {}
const location = locations.find((l) => l.taskCode === task.code) || {}
const node = this.$refs.canvas.genNodeJSON(
task.code,
task.taskType,
@ -346,14 +385,16 @@
)
nodes.push(node)
})
connects.filter(r => !!r.preTaskCode).forEach((c) => {
const edge = this.$refs.canvas.genEdgeJSON(
c.preTaskCode,
c.postTaskCode,
c.name
)
edges.push(edge)
})
connects
.filter((r) => !!r.preTaskCode)
.forEach((c) => {
const edge = this.$refs.canvas.genEdgeJSON(
c.preTaskCode,
c.postTaskCode,
c.name
)
edges.push(edge)
})
return {
nodes,
edges
@ -375,11 +416,11 @@
edgeLabel: edge.label || ''
}
})
tasks.forEach(task => {
tasks.forEach((task) => {
tasksMap[task.code] = task
})
return tasks.map(task => {
return tasks.map((task) => {
const preTask = preTaskMap[task.code]
return {
name: preTask ? preTask.edgeLabel : '',
@ -461,31 +502,137 @@
*/
edgeIsValid (edge) {
const { sourceId } = edge
const sourceTask = this.tasks.find(task => task.code === sourceId)
const sourceTask = this.tasks.find((task) => task.code === sourceId)
if (sourceTask.taskType === 'CONDITIONS') {
const edges = this.$refs.canvas.getEdges()
return edges.filter(e => e.sourceId === sourceTask.code).length <= 2
return edges.filter((e) => e.sourceId === sourceTask.code).length <= 2
}
return true
},
/**
* Task status
*/
refreshTaskStatus () {
const instanceId = this.$route.params.id
this.loading(true)
this.getTaskState(instanceId)
.then((res) => {
this.$message(this.$t('Refresh status succeeded'))
const { taskList } = res.data
if (taskList) {
taskList.forEach((taskInstance) => {
this.$refs.canvas.setNodeStatus({
code: taskInstance.taskCode,
state: taskInstance.state,
taskInstance
})
})
}
})
.finally(() => {
this.loading(false)
})
},
/**
* Loading
* @param {boolean} visible
*/
loading (visible) {
if (visible) {
this.spinner = this.$loading({
lock: true,
text: this.$t('Loading...'),
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.4)',
customClass: 'dag-fullscreen-loading'
})
} else {
this.spinner && this.spinner.close()
}
},
/**
* change process definition version
*/
showVersions () {
this.getProcessDefinitionVersionsPage({
pageNo: 1,
pageSize: 10,
code: this.definitionCode
})
.then((res) => {
let processDefinitionVersions = res.data.totalList
let total = res.data.total
let pageSize = res.data.pageSize
let pageNo = res.data.currentPage
// this.versionData.processDefinition.id = this.urlParam.id
this.versionData.processDefinition.code = this.definitionCode
this.versionData.processDefinition.version = this.version
this.versionData.processDefinition.releaseState = this.releaseState
this.versionData.processDefinitionVersions =
processDefinitionVersions
this.versionData.total = total
this.versionData.pageNo = pageNo
this.versionData.pageSize = pageSize
this.versionDrawer = true
})
.catch((e) => {
this.$message.error(e.msg || '')
})
},
closeVersion () {
this.versionDrawer = false
},
switchProcessVersion ({ version, processDefinitionCode }) {
// this.$store.state.dag.isSwitchVersion = true
this.switchProcessDefinitionVersion({
version: version,
code: processDefinitionCode
}).then(res => {
this.$message.success($t('Switch Version Successfully'))
this.closeVersion()
this.definitionDetails._reset()
}).catch(e => {
// this.$store.state.dag.isSwitchVersion = false
this.$message.error(e.msg || '')
})
},
getProcessVersions ({ pageNo, pageSize, processDefinitionCode }) {
this.getProcessDefinitionVersionsPage({
pageNo: pageNo,
pageSize: pageSize,
code: processDefinitionCode
}).then(res => {
this.versionData.processDefinitionVersions = res.data.totalList
this.versionData.total = res.data.total
this.versionData.pageSize = res.data.pageSize
this.versionData.pageNo = res.data.currentPage
}).catch(e => {
this.$message.error(e.msg || '')
})
},
deleteProcessVersion ({ version, processDefinitionCode }) {
this.deleteProcessDefinitionVersion({
version: version,
code: processDefinitionCode
}).then(res => {
this.$message.success(res.msg || '')
this.getProcessVersions({
pageNo: 1,
pageSize: 10,
processDefinitionCode: processDefinitionCode
})
}).catch(e => {
this.$message.error(e.msg || '')
})
}
}
}
</script>
<style lang="scss" scoped>
.dag-chart {
width: 100%;
height: calc(100vh - 100px);
padding: 10px;
background: #f2f3f7;
@import "./dag";
</style>
&.full-screen {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 9999;
}
}
<style lang="scss">
@import "./loading";
</style>

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

@ -20,7 +20,7 @@
<span class="name">{{$t('Current node settings')}}</span>
<span class="go-subtask">
<!-- Component can't pop up box to do component processing -->
<m-log :item="backfillItem">
<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>
@ -459,12 +459,11 @@
return
}
if (this.router.history.current.name === 'projects-instance-details') {
let stateId = $(`#${this.nodeData.id}`).attr('data-state-id') || null
if (!stateId) {
if (!this.taskInstance) {
this.$message.warning(`${i18n.$t('The task has not been executed and cannot enter the sub-Process')}`)
return
}
this.store.dispatch('dag/getSubProcessId', { taskId: stateId }).then(res => {
this.store.dispatch('dag/getSubProcessId', { taskId: this.taskInstance.id }).then(res => {
this.$emit('onSubProcess', {
subProcessId: res.data.subProcessInstanceId,
fromThis: this
@ -701,13 +700,22 @@
},
computed: {
...mapState('dag', [
'processListS'
'processListS',
'taskInstances'
]),
/**
* Child workflow entry show/hide
*/
_isGoSubProcess () {
return this.nodeData.taskType === 'SUB_PROCESS' && this.name
},
taskInstance () {
if (this.taskInstances.length > 0) {
return this.taskInstances.find(
(instance) => instance.taskCode === this.nodeData.id
)
}
return null
}
},
components: {

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

@ -16,7 +16,7 @@
*/
<template>
<span class="log-model">
<span v-if="stateId && item.type !== 'SUB_PROCESS'">
<span v-if="taskInstanceId && item.type !== 'SUB_PROCESS'">
<slot name="history"></slot>
<span @click="_ckLog">
<slot name="log" ></slot>
@ -79,8 +79,6 @@
store,
router,
isLog: false,
// TODO
stateId: $(`#${this.item.id}`).attr('data-state-id') || null,
isScreen: false,
loadingIndex: 0,
isData: true,
@ -96,7 +94,11 @@
type: String,
default: 'from'
},
logId: Number
logId: Number,
taskInstanceId: {
type: Number,
default: 0
}
},
methods: {
_refreshLog () {
@ -170,7 +172,7 @@
*/
_downloadLog () {
downloadFile('log/download-log', {
taskInstanceId: this.stateId || this.logId
taskInstanceId: this.taskInstanceId || this.logId
})
},
/**
@ -244,7 +246,7 @@
computed: {
_rtParam () {
return {
taskInstanceId: this.stateId || this.logId,
taskInstanceId: this.taskInstanceId || this.logId,
skipLineNum: parseInt(`${this.loadingIndex ? this.loadingIndex + '000' : 0}`),
limit: parseInt(`${this.loadingIndex ? this.loadingIndex + 1 : 1}000`)
}

10
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/canvas/statusMenu.scss → dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/loading.scss

@ -14,3 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.dag-fullscreen-loading{
.el-loading-spinner i {
color: #fff;
font-size: 18px;
}
.el-loading-text{
color: #fff;
}
}

5
dolphinscheduler-ui/src/js/conf/home/pages/dag/definitionDetails.vue

@ -37,6 +37,11 @@
releaseState: ''
}
},
provide () {
return {
definitionDetails: this
}
},
mixins: [disabledState],
props: {},
methods: {

14
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue

@ -337,13 +337,13 @@
* @param processDefinitionId the process definition id
* @param fromThis fromThis
*/
mVersionSwitchProcessDefinitionVersion ({ version, processDefinitionId, fromThis }) {
mVersionSwitchProcessDefinitionVersion ({ version, processDefinitionCode, fromThis }) {
this.switchProcessDefinitionVersion({
version: version,
processDefinitionId: processDefinitionId
code: processDefinitionCode
}).then(res => {
this.$message.success($t('Switch Version Successfully'))
this.$router.push({ path: `/projects/${this.projectId}/definition/list/${processDefinitionId}` })
this.$router.push({ path: `/projects/${this.projectCode}/definition/list/${processDefinitionCode}` })
}).catch(e => {
this.$message.error(e.msg || '')
})
@ -360,7 +360,7 @@
this.getProcessDefinitionVersionsPage({
pageNo: pageNo,
pageSize: pageSize,
processDefinitionCode: processDefinitionCode
code: processDefinitionCode
}).then(res => {
this.versionData.processDefinitionVersions = res.data.totalList
this.versionData.total = res.data.total
@ -377,10 +377,10 @@
* @param processDefinitionId the process definition id user want to delete
* @param fromThis fromThis
*/
mVersionDeleteProcessDefinitionVersion ({ version, processDefinitionId, processDefinitionCode, fromThis }) {
mVersionDeleteProcessDefinitionVersion ({ version, processDefinitionCode, fromThis }) {
this.deleteProcessDefinitionVersion({
version: version,
processDefinitionId: processDefinitionId
code: processDefinitionCode
}).then(res => {
this.$message.success(res.msg || '')
this.mVersionGetProcessDefinitionVersionsPage({
@ -397,7 +397,7 @@
this.getProcessDefinitionVersionsPage({
pageNo: 1,
pageSize: 10,
processDefinitionCode: item.code
code: item.code
}).then(res => {
let processDefinitionVersions = res.data.totalList
let total = res.data.total

5
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/versions.vue

@ -60,7 +60,7 @@
icon="el-icon-info"
iconColor="red"
:title="$t('Delete?')"
@onConfirm="_mVersionDeleteProcessDefinitionVersion(scope.row,scope.row.id)"
@onConfirm="_mVersionDeleteProcessDefinitionVersion(scope.row)"
>
<el-button :disabled="scope.row.version === versionData.processDefinition.version || isInstance" type="danger" size="mini" icon="el-icon-delete" circle slot="reference"></el-button>
</el-popconfirm>
@ -120,7 +120,7 @@
_mVersionSwitchProcessDefinitionVersion (item) {
this.$emit('mVersionSwitchProcessDefinitionVersion', {
version: item.version,
processDefinitionId: this.versionData.processDefinition.id,
processDefinitionCode: this.versionData.processDefinition.code,
fromThis: this
})
},
@ -131,7 +131,6 @@
_mVersionDeleteProcessDefinitionVersion (item) {
this.$emit('mVersionDeleteProcessDefinitionVersion', {
version: item.version,
processDefinitionId: this.versionData.processDefinition.id,
processDefinitionCode: this.versionData.processDefinition.code,
fromThis: this
})

4
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue

@ -25,7 +25,7 @@
<el-popover trigger="hover" placement="top">
<p>{{ scope.row.name }}</p>
<div slot="reference" class="name-wrapper">
<router-link :to="{ path: `/projects/${projectId}/instance/list/${scope.row.id}` , query:{id: scope.row.processDefinitionId}}" tag="a" class="links"><span class="ellipsis">{{ scope.row.name }}</span></router-link>
<router-link :to="{ path: `/projects/${projectCode}/instance/list/${scope.row.id}` , query:{code: scope.row.processDefinitionCode}}" tag="a" class="links"><span class="ellipsis">{{ scope.row.name }}</span></router-link>
</div>
</el-popover>
</template>
@ -482,7 +482,7 @@
mounted () {
},
computed: {
...mapState('dag', ['projectId'])
...mapState('dag', ['projectCode'])
},
components: { }
}

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

@ -17,7 +17,6 @@
import _ from 'lodash'
import io from '@/module/io'
import { tasksState } from '@/conf/home/pages/dag/_source/config'
export default {
/**
@ -25,19 +24,11 @@ export default {
*/
getTaskState ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`projects/${state.projectCode}/process-instances/${payload}/tasks`, payload, res => {
const arr = _.map(res.data.taskList, v => {
return _.cloneDeep(_.assign(tasksState[v.state], {
name: v.name,
stateId: v.id,
dependentResult: v.dependentResult
}))
})
resolve({
list: arr,
processInstanceState: res.data.processInstanceState,
taskList: res.data.taskList
})
io.get(`projects/${state.projectCode}/process-instances/${payload}/tasks`, {
processInstanceId: payload
}, res => {
state.taskInstances = res.data.taskList
resolve(res)
}).catch(e => {
reject(e)
})

7
dolphinscheduler-ui/src/js/conf/home/store/dag/state.js

@ -35,8 +35,6 @@ export default {
globalParams: [],
// Node information
tasks: [],
// Node cache information, cache the previous input
cacheTasks: {},
// Timeout alarm
timeout: 0,
// tenant code
@ -121,7 +119,6 @@ export default {
instanceListS: [],
// Operating state
isDetails: false,
startup: {
}
startup: {},
taskInstances: []
}

7
dolphinscheduler-ui/src/js/module/components/secondaryMenu/secondaryMenu.vue

@ -56,6 +56,7 @@
<script>
import { mapState } from 'vuex'
import menu from './_source/menu'
import { findComponentDownward } from '@/module/util/'
export default {
name: 'secondary-menu',
@ -89,6 +90,12 @@
} else {
sessionStorage.setItem('isLeft', 1)
}
const routeName = this.$route.name
if (routeName === 'projects-instance-details' || routeName === 'projects-instance-details' || routeName === 'definition-create') {
const dag = findComponentDownward(this.$root, 'dag-chart')
dag && dag.canvasResize()
}
}
},
mounted () {

Loading…
Cancel
Save