blob: 69bd8edd9d06ae6ffb96a7074f0146a1a726d2ba [file] [log] [blame]
/*
* 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="list-model" style="position: relative;">
<div class="table-box">
<table class="fixed">
<tr>
<th scope="col" style="min-width: 50px">
<x-checkbox @on-change="_topCheckBoxClick" v-model="checkAll"></x-checkbox>
</th>
<th scope="col" style="min-width: 30px">
<span>{{$t('#')}}</span>
</th>
<th scope="col" style="min-width: 200px;max-width: 300px;">
<span>{{$t('Process Name')}}</span>
</th>
<th scope="col" style="min-width: 30px">
<span>{{$t('State')}}</span>
</th>
<th scope="col" style="min-width: 70px">
<span>{{$t('Run Type')}}</span>
</th>
<th scope="col" style="min-width: 130px">
<span>{{$t('Scheduling Time')}}</span>
</th>
<th scope="col" style="min-width: 130px">
<span>{{$t('Start Time')}}</span>
</th>
<th scope="col" style="min-width: 130px">
<span>{{$t('End Time')}}</span>
</th>
<th scope="col" style="min-width: 60px">
<span>{{$t('Duration')}}s</span>
</th>
<th scope="col" style="min-width: 60px">
<span>{{$t('Run Times')}}</span>
</th>
<th scope="col" style="min-width: 55px">
<span>{{$t('fault-tolerant sign')}}</span>
</th>
<th scope="col" style="min-width: 135px">
<span>{{$t('Executor')}}</span>
</th>
<th scope="col" :style="{'min-width': ((Math.max(list.length && list[0].host.length, 22) + 40) * 6) + 'px'}">
<span>{{$t('host')}}</span>
</th>
<th scope="col" style="min-width: 230px">
<span>{{$t('Operation')}}</span>
</th>
</tr>
<tr v-for="(item, $index) in list" :key="item.id">
<td width="50"><x-checkbox v-model="item.isCheck" :disabled="item.state === 'RUNNING_EXEUTION' || item.state === 'READY_STOP' || item.state === 'READY_PAUSE'" @on-change="_arrDelChange"></x-checkbox></td>
<td width="50">
<span>{{parseInt(pageNo === 1 ? ($index + 1) : (($index + 1) + (pageSize * (pageNo - 1))))}}</span>
</td>
<td style="min-width: 200px;max-width: 300px;padding-right: 10px;">
<span class="ellipsis" style="padding-left: 4px;"><router-link :to="{ path: '/projects/instance/list/' + item.id , query:{id: item.processDefinitionId}}" tag="a" class="links" :title="item.name">{{item.name}}</router-link></span>
</td>
<td>
<span v-html="_rtState(item.state)" style="cursor: pointer;"></span>
</td>
<td><span>{{_rtRunningType(item.commandType)}}</span></td>
<td>
<span v-if="item.scheduleTime">{{item.scheduleTime | formatDate}}</span>
<span v-else>-</span>
</td>
<td>
<span v-if="item.startTime">{{item.startTime | formatDate}}</span>
<span v-else>-</span>
</td>
<td>
<span v-if="item.endTime">{{item.endTime | formatDate}}</span>
<span v-else>-</span>
</td>
<td width="70"><span>{{item.duration || '-'}}</span></td>
<td width="70"><span>{{item.runTimes}}</span></td>
<td><span>{{item.recovery}}</span></td>
<td>
<span v-if="item.executorName">{{item.executorName}}</span>
<span v-else>-</span>
</td>
<td><span>{{item.host || '-'}}</span></td>
<td style="z-index: inherit;">
<div v-show="item.disabled">
<x-button type="info"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:title="$t('Edit')"
@click="_reEdit(item)"
icon="ans-icon-edit"
:disabled="item.state !== 'SUCCESS' && item.state !== 'PAUSE' && item.state !== 'FAILURE' && item.state !== 'STOP'"></x-button>
<x-button type="info"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:title="$t('Rerun')"
@click="_reRun(item,$index)"
icon="ans-icon-refresh"
:disabled="item.state !== 'SUCCESS' && item.state !== 'PAUSE' && item.state !== 'FAILURE' && item.state !== 'STOP'"></x-button>
<x-button type="success"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:title="$t('Recovery Failed')"
@click="_restore(item,$index)"
icon="ans-icon-fail-empty"
:disabled="item.state !== 'FAILURE'"></x-button>
<x-button type="error"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:title="item.state === 'STOP' ? $t('Recovery Suspend') : $t('Stop')"
@click="_stop(item,$index)"
:icon="item.state === 'STOP' ? 'ans-icon-pause-solid' : 'ans-icon-stop'"
:disabled="item.state !== 'RUNNING_EXEUTION' && item.state != 'STOP'"></x-button>
<x-button type="warning"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:title="item.state === 'PAUSE' ? $t('Recovery Suspend') : $t('Pause')"
@click="_suspend(item,$index)"
:icon="item.state === 'PAUSE' ? 'ans-icon-pause-solid' : 'ans-icon-pause'"
:disabled="item.state !== 'RUNNING_EXEUTION' && item.state !== 'PAUSE'"></x-button>
<x-poptip
:ref="'poptip-delete-' + $index"
placement="top-end"
width="90">
<p>{{$t('Delete?')}}</p>
<div style="text-align: right; margin: 0;padding-top: 4px;">
<x-button type="text" size="xsmall" shape="circle" @click="_closeDelete($index)">{{$t('Cancel')}}</x-button>
<x-button type="primary" size="xsmall" shape="circle" @click="_delete(item,$index)">{{$t('Confirm')}}</x-button>
</div>
<template slot="reference">
<x-button
icon="ans-icon-trash"
type="error"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:disabled="item.state !== 'SUCCESS' && item.state !== 'FAILURE' && item.state !== 'STOP' && item.state !== 'PAUSE'"
:title="$t('delete')">
</x-button>
</template>
</x-poptip>
<x-button type="info"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:title="$t('Gantt')"
@click="_gantt(item)"
icon="ans-icon-gantt">
</x-button>
</div>
<div v-show="!item.disabled">
<!--Edit-->
<x-button
type="info"
shape="circle"
size="xsmall"
icon="ans-icon-edit"
disabled="true">
</x-button>
<!--Rerun-->
<x-button
v-show="buttonType === 'run'"
type="info"
shape="circle"
size="xsmall"
disabled="true">
{{item.count}}
</x-button>
<x-button
v-show="buttonType !== 'run'"
type="info"
shape="circle"
size="xsmall"
icon="ans-icon-refresh"
disabled="true">
</x-button>
<!--Recovery Failed-->
<x-button
v-show="buttonType === 'store'"
type="success"
shape="circle"
size="xsmall"
disabled="true">
{{item.count}}
</x-button>
<x-button
v-show="buttonType !== 'store'"
type="success"
shape="circle"
size="xsmall"
icon="ans-icon-fail-empty"
disabled="true">
</x-button>
<!--Stop-->
<!--<x-button-->
<!--type="error"-->
<!--shape="circle"-->
<!--size="xsmall"-->
<!--icon="ans-icon-pause"-->
<!--disabled="true">-->
<!--</x-button>-->
<!--倒计时 => Recovery Suspend/Pause-->
<x-button
v-show="(item.state === 'PAUSE' || item.state == 'STOP') && buttonType === 'suspend'"
type="warning"
shape="circle"
size="xsmall"
disabled="true">
{{item.count}}
</x-button>
<!--Recovery Suspend-->
<x-button
v-show="(item.state === 'PAUSE' || item.state == 'STOP') && buttonType !== 'suspend'"
type="warning"
shape="circle"
size="xsmall"
icon="ans-icon-pause-solid"
disabled="true">
</x-button>
<!--Pause-->
<x-button
v-show="item.state !== 'PAUSE'"
type="warning"
shape="circle"
size="xsmall"
icon="ans-icon-stop"
disabled="true">
</x-button>
<!--Stop-->
<x-button
v-show="item.state !== 'STOP'"
type="warning"
shape="circle"
size="xsmall"
icon="ans-icon-pause"
disabled="true">
</x-button>
<!--delete-->
<x-button
type="error"
shape="circle"
size="xsmall"
icon="ans-icon-trash"
:disabled="true">
</x-button>
<!--Gantt-->
<x-button
type="info"
shape="circle"
size="xsmall"
icon="ans-icon-gantt"
disabled="true">
</x-button>
</div>
</td>
</tr>
</table>
</div>
<x-poptip
v-show="strDelete !== ''"
ref="poptipDeleteAll"
placement="bottom-start"
width="90">
<p>{{$t('Delete?')}}</p>
<div style="text-align: right; margin: 0;padding-top: 4px;">
<x-button type="text" size="xsmall" shape="circle" @click="_closeDelete(-1)">{{$t('Cancel')}}</x-button>
<x-button type="primary" size="xsmall" shape="circle" @click="_delete({},-1)">{{$t('Confirm')}}</x-button>
</div>
<template slot="reference">
<x-button size="xsmall" style="position: absolute; bottom: -48px; left: 22px;" >{{$t('Delete')}}</x-button>
</template>
</x-poptip>
</div>
</template>
<script>
import _ from 'lodash'
import { mapActions } from 'vuex'
import { tasksState, runningType } from '@/conf/home/pages/dag/_source/config'
export default {
name: 'list',
data () {
return {
// data
list: [],
// btn type
buttonType: '',
strDelete: '',
checkAll: false
}
},
props: {
processInstanceList: Array,
pageNo: Number,
pageSize: Number
},
methods: {
...mapActions('dag', ['editExecutorsState', 'deleteInstance', 'batchDeleteInstance']),
/**
* Return run type
*/
_rtRunningType (code) {
return _.filter(runningType, v => v.code === code)[0].desc
},
/**
* Return status
*/
_rtState (code) {
let o = tasksState[code]
return `<em class="ansfont ${o.icoUnicode} ${o.isSpin ? 'as as-spin' : ''}" style="color:${o.color}" data-toggle="tooltip" data-container="body" title="${o.desc}"></em>`
},
/**
* Close the delete layer
*/
_closeDelete (i) {
// close batch
if (i < 0) {
this.$refs['poptipDeleteAll'].doClose()
return
}
// close one
this.$refs[`poptip-delete-${i}`][0].doClose()
},
/**
* delete
*/
_delete (item, i) {
// remove tow++
if (i < 0) {
this._batchDelete()
return
}
// remove one
this.deleteInstance({
processInstanceId: item.id
}).then(res => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this._onUpdate()
this.$message.success(res.msg)
}).catch(e => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this.$message.error(e.msg || '')
})
},
/**
* edit
*/
_reEdit (item) {
this.$router.push({ path: `/projects/instance/list/${item.id}` })
},
/**
* Rerun
* @param REPEAT_RUNNING
*/
_reRun (item, index) {
this._countDownFn({
id: item.id,
executeType: 'REPEAT_RUNNING',
index: index,
buttonType: 'run'
})
},
/**
* Resume running
* @param PAUSE => RECOVER_SUSPENDED_PROCESS
* @param FAILURE => START_FAILURE_TASK_PROCESS
*/
_restore (item, index) {
this._countDownFn({
id: item.id,
executeType: 'START_FAILURE_TASK_PROCESS',
index: index,
buttonType: 'store'
})
},
/**
* stop
* @param STOP
*/
_stop (item, index) {
if(item.state == 'STOP') {
this._countDownFn({
id: item.id,
executeType: 'RECOVER_SUSPENDED_PROCESS',
index: index,
buttonType: 'suspend'
})
} else {
this._upExecutorsState({
processInstanceId: item.id,
executeType: 'STOP'
})
}
},
/**
* pause
* @param PAUSE
*/
_suspend (item, index) {
if (item.state === 'PAUSE') {
this._countDownFn({
id: item.id,
executeType: 'RECOVER_SUSPENDED_PROCESS',
index: index,
buttonType: 'suspend'
})
} else {
this._upExecutorsState({
processInstanceId: item.id,
executeType: 'PAUSE'
})
}
},
/**
* operating
*/
_upExecutorsState (o) {
this.editExecutorsState(o).then(res => {
this.$message.success(res.msg)
$('body').find('.tooltip.fade.top.in').remove()
this._onUpdate()
}).catch(e => {
this.$message.error(e.msg || '')
this._onUpdate()
})
},
/**
* Countdown method refresh
*/
_countDownFn (param) {
this.buttonType = param.buttonType
this.editExecutorsState({
processInstanceId: param.id,
executeType: param.executeType
}).then(res => {
this.list[param.index].disabled = false
$('body').find('.tooltip.fade.top.in').remove()
this.$forceUpdate()
this.$message.success(res.msg)
// Countdown
this._countDown(() => {
this._onUpdate()
}, param.index)
}).catch(e => {
this.$message.error(e.msg || '')
this._onUpdate()
})
},
/**
* update
*/
_onUpdate () {
this.$emit('on-update')
},
/**
* list data handle
*/
_listDataHandle (data) {
if (data.length) {
_.map(data, v => {
v.disabled = true
v.count = 9
})
}
return data
},
/**
* Countdown
*/
_countDown (fn, index) {
const TIME_COUNT = 10
let timer
let $count
if (!timer) {
$count = TIME_COUNT
timer = setInterval(() => {
if ($count > 0 && $count <= TIME_COUNT) {
$count--
this.list[index].count = $count
this.$forceUpdate()
} else {
fn()
clearInterval(timer)
timer = null
}
}, 1000)
}
},
_gantt (item) {
this.$router.push({ path: `/projects/instance/gantt/${item.id}` })
},
_topCheckBoxClick (is) {
_.map(this.list , v => v.isCheck = v.state === ('RUNNING_EXEUTION') || v.state === ('READY_STOP') || v.state === ('READY_PAUSE')? false : is)
this._arrDelChange()
},
_arrDelChange (v) {
let arr = []
this.list.forEach((item)=>{
if (item.isCheck) {
arr.push(item.id)
}
})
this.strDelete = _.join(arr, ',')
if (v === false) {
this.checkAll = false
}
},
_batchDelete () {
this.$refs['poptipDeleteAll'].doClose()
this.batchDeleteInstance({
processInstanceIds: this.strDelete
}).then(res => {
this._onUpdate()
this.checkAll = false
this.strDelete = ''
this.$message.success(res.msg)
}).catch(e => {
this.checkAll = false
this.strDelete = ''
this.$message.error(e.msg || '')
})
}
},
watch: {
processInstanceList: {
handler (a) {
this.checkAll = false
this.list = []
setTimeout(() => {
this.list = _.cloneDeep(this._listDataHandle(a))
})
},
immediate: true,
deep: true
},
pageNo () {
this.strDelete = ''
}
},
created () {
},
mounted () {
},
components: { }
}
</script>