mirror of
https://gitee.com/dolphinscheduler/DolphinScheduler.git
synced 2024-12-02 20:28:03 +08:00
[Feature][UI Next] Add Workflow Instance (#8356)
* add workflow list manage * support batch delete * add condition search * add interval to update data * fix table column I18n error * add icon for table state column * del redundant comment * fix delete data paging jump
This commit is contained in:
parent
d9df8319a2
commit
80d2ee7b11
@ -371,6 +371,7 @@ const project = {
|
||||
workflow_publish_status: 'Workflow Publish Status',
|
||||
schedule_publish_status: 'Schedule Publish Status',
|
||||
workflow_definition: 'Workflow Definition',
|
||||
workflow_instance: 'Workflow Instance',
|
||||
id: '#',
|
||||
status: 'Status',
|
||||
create_time: 'Create Time',
|
||||
@ -431,7 +432,45 @@ const project = {
|
||||
delete_confirm: 'Delete?',
|
||||
enter_name_tips: 'Please enter name',
|
||||
confirm_switch_version: 'Confirm Switch To This Version?',
|
||||
current_version: 'Current Version'
|
||||
current_version: 'Current Version',
|
||||
run_type: 'Run Type',
|
||||
scheduling_time: 'Scheduling Time',
|
||||
duration: 'Duration',
|
||||
run_times: 'Run Times',
|
||||
fault_tolerant_sign: 'Fault-tolerant Sign',
|
||||
dry_run_flag: 'Dry-run Flag',
|
||||
executor: 'Executor',
|
||||
host: 'Host',
|
||||
start_process: 'Start Process',
|
||||
execute_from_the_current_node: 'Execute from the current node',
|
||||
recover_tolerance_fault_process: 'Recover tolerance fault process',
|
||||
resume_the_suspension_process: 'Resume the suspension process',
|
||||
execute_from_the_failed_nodes: 'Execute from the failed nodes',
|
||||
scheduling_execution: 'Scheduling execution',
|
||||
rerun: 'Rerun',
|
||||
stop: 'Stop',
|
||||
pause: 'Pause',
|
||||
recovery_waiting_thread: 'Recovery waiting thread',
|
||||
recover_serial_wait: 'Recover serial wait',
|
||||
recovery_suspend: 'Recovery Suspend',
|
||||
recovery_failed: 'Recovery Failed',
|
||||
gantt: 'Gantt',
|
||||
name: 'Name',
|
||||
all_status: 'AllStatus',
|
||||
submit_success: 'Submitted successfully',
|
||||
running: 'Running',
|
||||
ready_to_pause: 'Ready to pause',
|
||||
ready_to_stop: 'Ready to stop',
|
||||
failed: 'Failed',
|
||||
need_fault_tolerance: 'Need fault tolerance',
|
||||
kill: 'Kill',
|
||||
waiting_for_thread: 'Waiting for thread',
|
||||
waiting_for_dependence: 'Waiting for dependence',
|
||||
waiting_for_dependency_to_complete: 'Waiting for dependency to complete',
|
||||
delay_execution: 'Delay execution',
|
||||
forced_success: 'Forced success',
|
||||
serial_wait: 'Serial wait',
|
||||
executing: 'Executing'
|
||||
},
|
||||
task: {
|
||||
task_name: 'Task Name',
|
||||
|
@ -366,6 +366,7 @@ const project = {
|
||||
workflow_publish_status: '工作流上线状态',
|
||||
schedule_publish_status: '定时状态',
|
||||
workflow_definition: '工作流定义',
|
||||
workflow_instance: '工作流实例',
|
||||
id: '编号',
|
||||
status: '状态',
|
||||
create_time: '创建时间',
|
||||
@ -430,7 +431,45 @@ const project = {
|
||||
enter_name_tips: '请输入名称',
|
||||
switch_version: '切换到该版本',
|
||||
confirm_switch_version: '确定切换到该版本吗?',
|
||||
current_version: '当前版本'
|
||||
current_version: '当前版本',
|
||||
run_type: '运行类型',
|
||||
scheduling_time: '调度时间',
|
||||
duration: '运行时长',
|
||||
run_times: '运行次数',
|
||||
fault_tolerant_sign: '容错标识',
|
||||
dry_run_flag: '空跑标识',
|
||||
executor: '执行用户',
|
||||
host: 'Host',
|
||||
start_process: '启动工作流',
|
||||
execute_from_the_current_node: '从当前节点开始执行',
|
||||
recover_tolerance_fault_process: '恢复被容错的工作流',
|
||||
resume_the_suspension_process: '恢复运行流程',
|
||||
execute_from_the_failed_nodes: '从失败节点开始执行',
|
||||
scheduling_execution: '调度执行',
|
||||
rerun: '重跑',
|
||||
stop: '停止',
|
||||
pause: '暂停',
|
||||
recovery_waiting_thread: '恢复等待线程',
|
||||
recover_serial_wait: '串行恢复',
|
||||
recovery_suspend: '恢复运行',
|
||||
recovery_failed: '恢复失败',
|
||||
gantt: '甘特图',
|
||||
name: '名称',
|
||||
all_status: '全部状态',
|
||||
submit_success: '提交成功',
|
||||
running: '正在运行',
|
||||
ready_to_pause: '准备暂停',
|
||||
ready_to_stop: '准备停止',
|
||||
failed: '失败',
|
||||
need_fault_tolerance: '需要容错',
|
||||
kill: 'Kill',
|
||||
waiting_for_thread: '等待线程',
|
||||
waiting_for_dependence: '等待依赖',
|
||||
waiting_for_dependency_to_complete: '等待依赖完成',
|
||||
delay_execution: '延时执行',
|
||||
forced_success: '强制成功',
|
||||
serial_wait: '串行等待',
|
||||
executing: '正在执行'
|
||||
},
|
||||
task: {
|
||||
task_name: '任务名称',
|
||||
|
@ -23,7 +23,7 @@ import {
|
||||
ProcessInstanceReq
|
||||
} from './types'
|
||||
|
||||
export function execute(data: ExecuteReq, code: ProjectCodeReq): any {
|
||||
export function execute(data: ExecuteReq, code: number): any {
|
||||
return axios({
|
||||
url: `/projects/${code}/executors/execute`,
|
||||
method: 'post',
|
||||
|
@ -29,7 +29,7 @@ import {
|
||||
|
||||
export function queryProcessInstanceListPaging(
|
||||
params: ProcessInstanceListReq,
|
||||
code: CodeReq
|
||||
code: number
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${code}/process-instances`,
|
||||
@ -40,7 +40,7 @@ export function queryProcessInstanceListPaging(
|
||||
|
||||
export function batchDeleteProcessInstanceByIds(
|
||||
data: BatchDeleteReq,
|
||||
code: CodeReq
|
||||
code: number
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${code}/process-instances/batch-delete`,
|
||||
@ -101,7 +101,7 @@ export function updateProcessInstance(
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteProcessInstanceById(id: IdReq, code: CodeReq): any {
|
||||
export function deleteProcessInstanceById(id: number, code: number): any {
|
||||
return axios({
|
||||
url: `/projects/${code}/process-instances/${id}`,
|
||||
method: 'delete'
|
||||
|
@ -34,7 +34,7 @@ interface ProcessInstanceListReq {
|
||||
|
||||
interface BatchDeleteReq {
|
||||
processInstanceIds: string
|
||||
projectName: string
|
||||
projectName?: string
|
||||
alertGroup?: string
|
||||
createTime?: string
|
||||
email?: string
|
||||
@ -82,6 +82,26 @@ interface ProcessInstanceReq {
|
||||
timeout?: string
|
||||
}
|
||||
|
||||
interface IWorkflowInstance {
|
||||
id: number
|
||||
name: string
|
||||
state: string
|
||||
commandType: string
|
||||
scheduleTime?: string
|
||||
processDefinitionCode?: number
|
||||
startTime: string
|
||||
endTime: string
|
||||
duration?: string
|
||||
runTimes: number
|
||||
recovery: string
|
||||
dryRun: number
|
||||
executorName: string
|
||||
host: string
|
||||
count?: number
|
||||
disabled?: boolean
|
||||
buttonType?: string
|
||||
}
|
||||
|
||||
export {
|
||||
CodeReq,
|
||||
ProcessInstanceListReq,
|
||||
@ -90,5 +110,6 @@ export {
|
||||
TaskReq,
|
||||
LongestReq,
|
||||
IdReq,
|
||||
ProcessInstanceReq
|
||||
ProcessInstanceReq,
|
||||
IWorkflowInstance
|
||||
}
|
||||
|
@ -15,6 +15,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
SettingFilled,
|
||||
SettingOutlined,
|
||||
CloseCircleOutlined,
|
||||
PauseCircleOutlined,
|
||||
CheckCircleOutlined,
|
||||
EditOutlined,
|
||||
MinusCircleOutlined,
|
||||
CheckCircleFilled,
|
||||
LoadingOutlined,
|
||||
PauseCircleFilled,
|
||||
ClockCircleOutlined,
|
||||
StopFilled,
|
||||
StopOutlined,
|
||||
GlobalOutlined,
|
||||
IssuesCloseOutlined
|
||||
} from '@vicons/antd'
|
||||
import { ITaskState } from './types'
|
||||
|
||||
/**
|
||||
* Intelligent display kb m
|
||||
*/
|
||||
@ -46,3 +65,252 @@ export const fileTypeArr = [
|
||||
'ini',
|
||||
'js'
|
||||
]
|
||||
|
||||
/**
|
||||
* Operation type
|
||||
* @desc tooltip
|
||||
* @code identifier
|
||||
*/
|
||||
export const runningType = (t: any) => [
|
||||
{
|
||||
desc: `${t('project.workflow.start_process')}`,
|
||||
code: 'START_PROCESS'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.execute_from_the_current_node')}`,
|
||||
code: 'START_CURRENT_TASK_PROCESS'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.recover_tolerance_fault_process')}`,
|
||||
code: 'RECOVER_TOLERANCE_FAULT_PROCESS'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.resume_the_suspension_process')}`,
|
||||
code: 'RECOVER_SUSPENDED_PROCESS'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.execute_from_the_failed_nodes')}`,
|
||||
code: 'START_FAILURE_TASK_PROCESS'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.complement_data')}`,
|
||||
code: 'COMPLEMENT_DATA'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.scheduling_execution')}`,
|
||||
code: 'SCHEDULER'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.rerun')}`,
|
||||
code: 'REPEAT_RUNNING'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.pause')}`,
|
||||
code: 'PAUSE'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.stop')}`,
|
||||
code: 'STOP'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.recovery_waiting_thread')}`,
|
||||
code: 'RECOVER_WAITING_THREAD'
|
||||
},
|
||||
{
|
||||
desc: `${t('project.workflow.recover_serial_wait')}`,
|
||||
code: 'RECOVER_SERIAL_WAIT'
|
||||
}
|
||||
]
|
||||
|
||||
/**
|
||||
* State code table
|
||||
*/
|
||||
export const stateType = (t: any) => [
|
||||
{
|
||||
value: '',
|
||||
label: `${t('project.workflow.all_status')}`
|
||||
},
|
||||
{
|
||||
value: 'SUBMITTED_SUCCESS',
|
||||
label: `${t('project.workflow.submit_success')}`
|
||||
},
|
||||
{
|
||||
value: 'RUNNING_EXECUTION',
|
||||
label: `${t('project.workflow.running')}`
|
||||
},
|
||||
{
|
||||
value: 'READY_PAUSE',
|
||||
label: `${t('project.workflow.ready_to_pause')}`
|
||||
},
|
||||
{
|
||||
value: 'PAUSE',
|
||||
label: `${t('project.workflow.pause')}`
|
||||
},
|
||||
{
|
||||
value: 'READY_STOP',
|
||||
label: `${t('project.workflow.ready_to_stop')}`
|
||||
},
|
||||
{
|
||||
value: 'STOP',
|
||||
label: `${t('project.workflow.stop')}`
|
||||
},
|
||||
{
|
||||
value: 'FAILURE',
|
||||
label: `${t('project.workflow.failed')}`
|
||||
},
|
||||
{
|
||||
value: 'SUCCESS',
|
||||
label: `${t('project.workflow.success')}`
|
||||
},
|
||||
{
|
||||
value: 'NEED_FAULT_TOLERANCE',
|
||||
label: `${t('project.workflow.need_fault_tolerance')}`
|
||||
},
|
||||
{
|
||||
value: 'KILL',
|
||||
label: `${t('project.workflow.kill')}`
|
||||
},
|
||||
{
|
||||
value: 'WAITING_THREAD',
|
||||
label: `${t('project.workflow.waiting_for_thread')}`
|
||||
},
|
||||
{
|
||||
value: 'WAITING_DEPEND',
|
||||
label: `${t('project.workflow.waiting_for_dependency_to_complete')}`
|
||||
},
|
||||
{
|
||||
value: 'DELAY_EXECUTION',
|
||||
label: `${t('project.workflow.delay_execution')}`
|
||||
},
|
||||
{
|
||||
value: 'FORCED_SUCCESS',
|
||||
label: `${t('project.workflow.forced_success')}`
|
||||
},
|
||||
{
|
||||
value: 'SERIAL_WAIT',
|
||||
label: `${t('project.workflow.serial_wait')}`
|
||||
}
|
||||
]
|
||||
|
||||
/**
|
||||
* Task status
|
||||
* @id id
|
||||
* @desc tooltip
|
||||
* @color color
|
||||
* @icon icon
|
||||
* @isSpin is loading (Need to execute the code block to write if judgment)
|
||||
*/
|
||||
// TODO: Looking for a more suitable icon
|
||||
export const tasksState = (t: any): ITaskState => ({
|
||||
SUBMITTED_SUCCESS: {
|
||||
id: 0,
|
||||
desc: `${t('project.workflow.submit_success')}`,
|
||||
color: '#A9A9A9',
|
||||
icon: IssuesCloseOutlined,
|
||||
isSpin: false,
|
||||
classNames: 'submitted'
|
||||
},
|
||||
RUNNING_EXECUTION: {
|
||||
id: 1,
|
||||
desc: `${t('project.workflow.executing')}`,
|
||||
color: '#0097e0',
|
||||
icon: SettingFilled,
|
||||
isSpin: true,
|
||||
classNames: 'executing'
|
||||
},
|
||||
READY_PAUSE: {
|
||||
id: 2,
|
||||
desc: `${t('project.workflow.ready_to_pause')}`,
|
||||
color: '#07b1a3',
|
||||
icon: SettingOutlined,
|
||||
isSpin: false,
|
||||
classNames: 'submitted'
|
||||
},
|
||||
PAUSE: {
|
||||
id: 3,
|
||||
desc: `${t('project.workflow.pause')}`,
|
||||
color: '#057c72',
|
||||
icon: PauseCircleOutlined,
|
||||
isSpin: false,
|
||||
classNames: 'pause'
|
||||
},
|
||||
READY_STOP: {
|
||||
id: 4,
|
||||
desc: `${t('project.workflow.ready_to_stop')}`,
|
||||
color: '#FE0402',
|
||||
icon: StopFilled,
|
||||
isSpin: false
|
||||
},
|
||||
STOP: {
|
||||
id: 5,
|
||||
desc: `${t('project.workflow.stop')}`,
|
||||
color: '#e90101',
|
||||
icon: StopOutlined,
|
||||
isSpin: false
|
||||
},
|
||||
FAILURE: {
|
||||
id: 6,
|
||||
desc: `${t('project.workflow.failed')}`,
|
||||
color: '#000000',
|
||||
icon: CloseCircleOutlined,
|
||||
isSpin: false,
|
||||
classNames: 'failed'
|
||||
},
|
||||
SUCCESS: {
|
||||
id: 7,
|
||||
desc: `${t('project.workflow.success')}`,
|
||||
color: '#33cc00',
|
||||
icon: CheckCircleOutlined,
|
||||
isSpin: false,
|
||||
classNames: 'success'
|
||||
},
|
||||
NEED_FAULT_TOLERANCE: {
|
||||
id: 8,
|
||||
desc: `${t('project.workflow.need_fault_tolerance')}`,
|
||||
color: '#FF8C00',
|
||||
icon: EditOutlined,
|
||||
isSpin: false
|
||||
},
|
||||
KILL: {
|
||||
id: 9,
|
||||
desc: `${t('project.workflow.kill')}`,
|
||||
color: '#a70202',
|
||||
icon: MinusCircleOutlined,
|
||||
isSpin: false
|
||||
},
|
||||
WAITING_THREAD: {
|
||||
id: 10,
|
||||
desc: `${t('project.workflow.waiting_for_thread')}`,
|
||||
color: '#912eed',
|
||||
icon: ClockCircleOutlined,
|
||||
isSpin: false
|
||||
},
|
||||
WAITING_DEPEND: {
|
||||
id: 11,
|
||||
desc: `${t('project.workflow.waiting_for_dependence')}`,
|
||||
color: '#5101be',
|
||||
icon: GlobalOutlined,
|
||||
isSpin: false
|
||||
},
|
||||
DELAY_EXECUTION: {
|
||||
id: 12,
|
||||
desc: `${t('project.workflow.delay_execution')}`,
|
||||
color: '#5102ce',
|
||||
icon: PauseCircleFilled,
|
||||
isSpin: false
|
||||
},
|
||||
FORCED_SUCCESS: {
|
||||
id: 13,
|
||||
desc: `${t('project.workflow.forced_success')}`,
|
||||
color: '#5102ce',
|
||||
icon: CheckCircleFilled,
|
||||
isSpin: false
|
||||
},
|
||||
SERIAL_WAIT: {
|
||||
id: 14,
|
||||
desc: `${t('project.workflow.serial_wait')}`,
|
||||
color: '#5102ce',
|
||||
icon: LoadingOutlined,
|
||||
isSpin: false
|
||||
}
|
||||
})
|
||||
|
22
dolphinscheduler-ui-next/src/utils/types.ts
Normal file
22
dolphinscheduler-ui-next/src/utils/types.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
interface ITaskState {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export { ITaskState }
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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 { SearchOutlined } from '@vicons/antd'
|
||||
import {
|
||||
NGrid,
|
||||
NGridItem,
|
||||
NInput,
|
||||
NButton,
|
||||
NDatePicker,
|
||||
NSelect,
|
||||
NIcon
|
||||
} from 'naive-ui'
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { format } from 'date-fns'
|
||||
import { stateType } from '@/utils/common'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ProcessInstanceCondition',
|
||||
emits: ['handleSearch'],
|
||||
setup(props, ctx) {
|
||||
const searchValRef = ref('')
|
||||
const executorNameRef = ref('')
|
||||
const hostRef = ref('')
|
||||
const stateTypeRef = ref('')
|
||||
const startEndTimeRef = ref()
|
||||
|
||||
const handleSearch = () => {
|
||||
let startDate = ''
|
||||
let endDate = ''
|
||||
if (startEndTimeRef.value) {
|
||||
startDate = format(
|
||||
new Date(startEndTimeRef.value[0]),
|
||||
'yyyy-MM-dd hh:mm:ss'
|
||||
)
|
||||
endDate = format(
|
||||
new Date(startEndTimeRef.value[1]),
|
||||
'yyyy-MM-dd hh:mm:ss'
|
||||
)
|
||||
}
|
||||
|
||||
ctx.emit('handleSearch', {
|
||||
searchVal: searchValRef.value,
|
||||
executorName: executorNameRef.value,
|
||||
host: hostRef.value,
|
||||
stateType: stateTypeRef.value,
|
||||
startDate,
|
||||
endDate
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
searchValRef,
|
||||
executorNameRef,
|
||||
hostRef,
|
||||
stateTypeRef,
|
||||
startEndTimeRef,
|
||||
handleSearch
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { t } = useI18n()
|
||||
const options = stateType(t)
|
||||
return (
|
||||
<NGrid xGap={6} cols={24}>
|
||||
<NGridItem offset={5} span={3}>
|
||||
<NInput
|
||||
v-model:value={this.searchValRef}
|
||||
placeholder={t('project.workflow.name')}
|
||||
/>
|
||||
</NGridItem>
|
||||
<NGridItem span={3}>
|
||||
<NInput
|
||||
v-model:value={this.executorNameRef}
|
||||
placeholder={t('project.workflow.executor')}
|
||||
/>
|
||||
</NGridItem>
|
||||
<NGridItem span={3}>
|
||||
<NInput
|
||||
v-model:value={this.hostRef}
|
||||
placeholder={t('project.workflow.host')}
|
||||
/>
|
||||
</NGridItem>
|
||||
<NGridItem span={3}>
|
||||
<NSelect
|
||||
options={options}
|
||||
defaultValue={''}
|
||||
v-model:value={this.stateTypeRef}
|
||||
/>
|
||||
</NGridItem>
|
||||
<NGridItem span={6}>
|
||||
<NDatePicker
|
||||
type='datetimerange'
|
||||
clearable
|
||||
v-model:value={this.startEndTimeRef}
|
||||
/>
|
||||
</NGridItem>
|
||||
<NGridItem span={1}>
|
||||
<NButton type='primary' onClick={this.handleSearch}>
|
||||
<NIcon>
|
||||
<SearchOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
</NGridItem>
|
||||
</NGrid>
|
||||
)
|
||||
}
|
||||
})
|
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* 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 { defineComponent, PropType, toRefs } from 'vue'
|
||||
import { NSpace, NTooltip, NButton, NIcon, NPopconfirm } from 'naive-ui'
|
||||
import {
|
||||
DeleteOutlined,
|
||||
FormOutlined,
|
||||
InfoCircleFilled,
|
||||
SyncOutlined,
|
||||
CloseOutlined,
|
||||
CloseCircleOutlined,
|
||||
PauseCircleOutlined,
|
||||
ControlOutlined,
|
||||
PlayCircleOutlined
|
||||
} from '@vicons/antd'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { Router } from 'vue-router'
|
||||
import { IWorkflowInstance } from '@/service/modules/process-instances/types'
|
||||
|
||||
const props = {
|
||||
row: {
|
||||
type: Object as PropType<IWorkflowInstance>,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TableAction',
|
||||
props,
|
||||
emits: [
|
||||
'updateList',
|
||||
'reRun',
|
||||
'reStore',
|
||||
'stop',
|
||||
'suspend',
|
||||
'deleteInstance'
|
||||
],
|
||||
setup(props, ctx) {
|
||||
const router: Router = useRouter()
|
||||
|
||||
const handleEdit = () => {
|
||||
router.push({
|
||||
name: 'workflow-instance-detail',
|
||||
params: { id: props.row!.id },
|
||||
query: { code: props.row!.processDefinitionCode }
|
||||
})
|
||||
}
|
||||
|
||||
const handleReRun = () => {
|
||||
ctx.emit('reRun')
|
||||
}
|
||||
|
||||
const handleReStore = () => {
|
||||
ctx.emit('reStore')
|
||||
}
|
||||
|
||||
const handleStop = () => {
|
||||
ctx.emit('stop')
|
||||
}
|
||||
|
||||
const handleSuspend = () => {
|
||||
ctx.emit('suspend')
|
||||
}
|
||||
|
||||
const handleDeleteInstance = () => {
|
||||
ctx.emit('deleteInstance')
|
||||
}
|
||||
|
||||
return {
|
||||
handleEdit,
|
||||
handleReRun,
|
||||
handleReStore,
|
||||
handleStop,
|
||||
handleSuspend,
|
||||
handleDeleteInstance,
|
||||
...toRefs(props)
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { t } = useI18n()
|
||||
const state = this.row?.state
|
||||
|
||||
return (
|
||||
<NSpace>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.edit'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
tag='div'
|
||||
size='tiny'
|
||||
type='info'
|
||||
circle
|
||||
disabled={
|
||||
(state !== 'SUCCESS' &&
|
||||
state !== 'PAUSE' &&
|
||||
state !== 'FAILURE' &&
|
||||
state !== 'STOP') ||
|
||||
this.row?.disabled
|
||||
}
|
||||
onClick={this.handleEdit}
|
||||
>
|
||||
<NIcon>
|
||||
<FormOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.rerun'),
|
||||
trigger: () => {
|
||||
return (
|
||||
<NButton
|
||||
tag='div'
|
||||
size='tiny'
|
||||
type='info'
|
||||
circle
|
||||
onClick={this.handleReRun}
|
||||
disabled={
|
||||
(state !== 'SUCCESS' &&
|
||||
state !== 'PAUSE' &&
|
||||
state !== 'FAILURE' &&
|
||||
state !== 'STOP') ||
|
||||
this.row?.disabled
|
||||
}
|
||||
>
|
||||
{this.row?.buttonType === 'run' ? (
|
||||
<span>{this.row?.count}</span>
|
||||
) : (
|
||||
<NIcon>
|
||||
<SyncOutlined />
|
||||
</NIcon>
|
||||
)}
|
||||
</NButton>
|
||||
)
|
||||
}
|
||||
}}
|
||||
</NTooltip>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.recovery_failed'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
tag='div'
|
||||
size='tiny'
|
||||
type='primary'
|
||||
circle
|
||||
onClick={this.handleReStore}
|
||||
disabled={state !== 'FAILURE' || this.row?.disabled}
|
||||
>
|
||||
{this.row?.buttonType === 'store' ? (
|
||||
<span>{this.row?.count}</span>
|
||||
) : (
|
||||
<NIcon>
|
||||
<CloseCircleOutlined />
|
||||
</NIcon>
|
||||
)}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () =>
|
||||
state === 'PAUSE'
|
||||
? t('project.workflow.recovery_failed')
|
||||
: t('project.workflow.stop'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
tag='div'
|
||||
size='tiny'
|
||||
type='error'
|
||||
circle
|
||||
onClick={this.handleStop}
|
||||
disabled={
|
||||
(state !== 'RUNNING_EXECUTION' && state !== 'PAUSE') ||
|
||||
this.row?.disabled
|
||||
}
|
||||
>
|
||||
<NIcon>
|
||||
{state === 'STOP' ? (
|
||||
<PlayCircleOutlined />
|
||||
) : (
|
||||
<CloseOutlined />
|
||||
)}
|
||||
</NIcon>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () =>
|
||||
state === 'PAUSE'
|
||||
? t('project.workflow.recovery_suspend')
|
||||
: t('project.workflow.pause'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
tag='div'
|
||||
size='tiny'
|
||||
type='warning'
|
||||
circle
|
||||
disabled={
|
||||
(state !== 'RUNNING_EXECUTION' && state !== 'PAUSE') ||
|
||||
this.row?.disabled
|
||||
}
|
||||
onClick={this.handleSuspend}
|
||||
>
|
||||
<NIcon>
|
||||
{state === 'PAUSE' ? (
|
||||
<PlayCircleOutlined />
|
||||
) : (
|
||||
<PauseCircleOutlined />
|
||||
)}
|
||||
</NIcon>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.delete'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
tag='div'
|
||||
size='tiny'
|
||||
type='error'
|
||||
circle
|
||||
disabled={
|
||||
(state !== 'SUCCESS' &&
|
||||
state !== 'FAILURE' &&
|
||||
state !== 'STOP' &&
|
||||
state !== 'PAUSE') ||
|
||||
this.row?.disabled
|
||||
}
|
||||
>
|
||||
<NPopconfirm onPositiveClick={this.handleDeleteInstance}>
|
||||
{{
|
||||
default: () => t('project.workflow.delete_confirm'),
|
||||
icon: () => (
|
||||
<NIcon>
|
||||
<InfoCircleFilled />
|
||||
</NIcon>
|
||||
),
|
||||
trigger: () => (
|
||||
<NIcon>
|
||||
<DeleteOutlined />
|
||||
</NIcon>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.gantt'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
tag='div'
|
||||
size='tiny'
|
||||
type='info'
|
||||
circle
|
||||
/* TODO: Goto gantt*/
|
||||
disabled={this.row?.disabled}
|
||||
>
|
||||
<NIcon>
|
||||
<ControlOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
})
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
|
||||
.card {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 10px 0;
|
||||
.right {
|
||||
> .search {
|
||||
.list {
|
||||
float: right;
|
||||
margin: 3px 0 3px 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
table {
|
||||
width: 100%;
|
||||
tr {
|
||||
height: 40px;
|
||||
font-size: 12px;
|
||||
th,
|
||||
td {
|
||||
&:nth-child(1) {
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
th {
|
||||
&:nth-child(1) {
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
> span {
|
||||
font-size: 12px;
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.operation {
|
||||
> div {
|
||||
> div {
|
||||
margin-right: 5px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.startup {
|
||||
align-items: center;
|
||||
> div:first-child {
|
||||
width: 86%;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
color: #2080f0;
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
@ -15,11 +15,133 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineComponent } from 'vue'
|
||||
import { defineComponent, onMounted, onUnmounted, toRefs, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Card from '@/components/card'
|
||||
import {
|
||||
NButton,
|
||||
NDataTable,
|
||||
NPagination,
|
||||
NPopconfirm,
|
||||
NTooltip
|
||||
} from 'naive-ui'
|
||||
import { useTable } from './use-table'
|
||||
import ProcessInstanceCondition from './components/process-instance-condition'
|
||||
import { IWorkflowInstanceSearch } from './types'
|
||||
import styles from './index.module.scss'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'WorkflowInstanceList',
|
||||
setup() {
|
||||
return () => <div>WorkflowInstanceList</div>
|
||||
let setIntervalP: number
|
||||
const { variables, createColumns, getTableData, batchDeleteInstance } =
|
||||
useTable()
|
||||
|
||||
const requestData = () => {
|
||||
getTableData()
|
||||
}
|
||||
|
||||
const handleSearch = (params: IWorkflowInstanceSearch) => {
|
||||
variables.searchVal = params.searchVal
|
||||
variables.executorName = params.executorName
|
||||
variables.host = params.host
|
||||
variables.stateType = params.stateType
|
||||
variables.startDate = params.startDate
|
||||
variables.endDate = params.endDate
|
||||
variables.page = 1
|
||||
requestData()
|
||||
}
|
||||
|
||||
const handleChangePageSize = () => {
|
||||
variables.page = 1
|
||||
requestData()
|
||||
}
|
||||
|
||||
const handleBatchDelete = () => {
|
||||
batchDeleteInstance()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
createColumns(variables)
|
||||
requestData()
|
||||
|
||||
// Update timing list data
|
||||
setIntervalP = setInterval(() => {
|
||||
requestData()
|
||||
}, 9000)
|
||||
})
|
||||
|
||||
watch(useI18n().locale, () => {
|
||||
createColumns(variables)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(setIntervalP)
|
||||
})
|
||||
|
||||
return {
|
||||
requestData,
|
||||
handleSearch,
|
||||
handleChangePageSize,
|
||||
handleBatchDelete,
|
||||
...toRefs(variables)
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { t } = useI18n()
|
||||
|
||||
return (
|
||||
<div class={styles.content}>
|
||||
<Card class={styles.card}>
|
||||
<div class={styles.header}>
|
||||
<ProcessInstanceCondition onHandleSearch={this.handleSearch} />
|
||||
</div>
|
||||
</Card>
|
||||
<Card title={t('project.workflow.workflow_instance')}>
|
||||
<NDataTable
|
||||
rowKey={(row) => row.id}
|
||||
columns={this.columns}
|
||||
data={this.tableData}
|
||||
striped
|
||||
size={'small'}
|
||||
class={styles.table}
|
||||
scrollX={1800}
|
||||
v-model:checked-row-keys={this.checkedRowKeys}
|
||||
/>
|
||||
<div class={styles.pagination}>
|
||||
<NPagination
|
||||
v-model:page={this.page}
|
||||
v-model:page-size={this.pageSize}
|
||||
page-count={this.totalPage}
|
||||
show-size-picker
|
||||
page-sizes={[10, 30, 50]}
|
||||
show-quick-jumper
|
||||
onUpdatePage={this.requestData}
|
||||
onUpdatePageSize={this.handleChangePageSize}
|
||||
/>
|
||||
</div>
|
||||
<NTooltip>
|
||||
{{
|
||||
default: () => t('project.workflow.delete'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
tag='div'
|
||||
type='primary'
|
||||
disabled={this.checkedRowKeys.length <= 0}
|
||||
style='position: absolute; bottom: 10px; left: 10px;'
|
||||
>
|
||||
<NPopconfirm onPositiveClick={this.handleBatchDelete}>
|
||||
{{
|
||||
default: () => t('project.workflow.delete_confirm'),
|
||||
trigger: () => t('project.workflow.delete')
|
||||
}}
|
||||
</NPopconfirm>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 { ExecuteReq } from '@/service/modules/executors/types'
|
||||
|
||||
interface ICountDownParam extends ExecuteReq {
|
||||
index: number
|
||||
buttonType: 'run' | 'store' | 'suspend'
|
||||
}
|
||||
|
||||
interface IWorkflowInstanceSearch {
|
||||
searchVal: string
|
||||
executorName: string
|
||||
host: string
|
||||
stateType: string
|
||||
startDate: string
|
||||
endDate: string
|
||||
}
|
||||
|
||||
export { ICountDownParam, IWorkflowInstanceSearch }
|
@ -0,0 +1,381 @@
|
||||
/*
|
||||
* 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 _ from 'lodash'
|
||||
import { format } from 'date-fns'
|
||||
import { reactive, h, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { Router } from 'vue-router'
|
||||
import { NTooltip, NIcon, NSpin } from 'naive-ui'
|
||||
import { RowKey } from 'naive-ui/lib/data-table/src/interface'
|
||||
import {
|
||||
queryProcessInstanceListPaging,
|
||||
deleteProcessInstanceById,
|
||||
batchDeleteProcessInstanceByIds
|
||||
} from '@/service/modules/process-instances'
|
||||
import { execute } from '@/service/modules/executors'
|
||||
import TableAction from './components/table-action'
|
||||
import { runningType, tasksState } from '@/utils/common'
|
||||
import { IWorkflowInstance } from '@/service/modules/process-instances/types'
|
||||
import { ICountDownParam } from './types'
|
||||
import { ExecuteReq } from '@/service/modules/executors/types'
|
||||
import styles from './index.module.scss'
|
||||
|
||||
export function useTable() {
|
||||
const { t } = useI18n()
|
||||
const router: Router = useRouter()
|
||||
|
||||
const taskStateIcon = tasksState(t)
|
||||
|
||||
const variables = reactive({
|
||||
columns: [],
|
||||
checkedRowKeys: [] as Array<RowKey>,
|
||||
tableData: [] as Array<IWorkflowInstance>,
|
||||
page: ref(1),
|
||||
pageSize: ref(10),
|
||||
totalPage: ref(1),
|
||||
searchVal: ref(),
|
||||
executorName: ref(),
|
||||
host: ref(),
|
||||
stateType: ref(),
|
||||
startDate: ref(),
|
||||
endDate: ref(),
|
||||
projectCode: ref(Number(router.currentRoute.value.params.projectCode))
|
||||
})
|
||||
|
||||
const createColumns = (variables: any) => {
|
||||
variables.columns = [
|
||||
{
|
||||
type: 'selection'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.id'),
|
||||
key: 'id',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.workflow_name'),
|
||||
key: 'name',
|
||||
width: 200,
|
||||
render: (_row: IWorkflowInstance) =>
|
||||
h(
|
||||
'a',
|
||||
{
|
||||
href: 'javascript:',
|
||||
class: styles.links,
|
||||
onClick: () =>
|
||||
router.push({
|
||||
name: 'workflow-instance-detail',
|
||||
params: { id: _row.id },
|
||||
query: { code: _row.processDefinitionCode }
|
||||
})
|
||||
},
|
||||
{
|
||||
default: () => {
|
||||
return _row.name
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.status'),
|
||||
key: 'state',
|
||||
render: (_row: IWorkflowInstance) => {
|
||||
const stateIcon = taskStateIcon[_row.state]
|
||||
const iconElement = h(
|
||||
NIcon,
|
||||
{
|
||||
size: '18px',
|
||||
style: 'position: relative; top: 7.5px; left: 7.5px'
|
||||
},
|
||||
{
|
||||
default: () =>
|
||||
h(stateIcon.icon, {
|
||||
color: stateIcon.color
|
||||
})
|
||||
}
|
||||
)
|
||||
return h(
|
||||
NTooltip,
|
||||
{},
|
||||
{
|
||||
trigger: () => {
|
||||
if (stateIcon.isSpin) {
|
||||
return h(
|
||||
NSpin,
|
||||
{
|
||||
small: 'small'
|
||||
},
|
||||
{
|
||||
icon: () => iconElement
|
||||
}
|
||||
)
|
||||
} else {
|
||||
return iconElement
|
||||
}
|
||||
},
|
||||
default: () => stateIcon!.desc
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.run_type'),
|
||||
key: 'commandType',
|
||||
render: (_row: IWorkflowInstance) =>
|
||||
(
|
||||
_.filter(runningType(t), (v) => v.code === _row.commandType)[0] ||
|
||||
{}
|
||||
).desc
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.scheduling_time'),
|
||||
key: 'scheduleTime',
|
||||
render: (_row: IWorkflowInstance) =>
|
||||
_row.scheduleTime
|
||||
? format(new Date(_row.scheduleTime), 'yyyy-MM-dd HH:mm:ss')
|
||||
: '-'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.start_time'),
|
||||
key: 'startTime',
|
||||
render: (_row: IWorkflowInstance) =>
|
||||
_row.startTime
|
||||
? format(new Date(_row.startTime), 'yyyy-MM-dd HH:mm:ss')
|
||||
: '-'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.end_time'),
|
||||
key: 'endTime',
|
||||
render: (_row: IWorkflowInstance) =>
|
||||
_row.endTime
|
||||
? format(new Date(_row.endTime), 'yyyy-MM-dd HH:mm:ss')
|
||||
: '-'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.duration'),
|
||||
key: 'duration',
|
||||
render: (_row: IWorkflowInstance) => _row.duration || '-'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.run_times'),
|
||||
key: 'runTimes'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.fault_tolerant_sign'),
|
||||
key: 'recovery'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.dry_run_flag'),
|
||||
key: 'dryRun',
|
||||
render: (_row: IWorkflowInstance) => (_row.dryRun === 1 ? 'YES' : 'NO')
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.executor'),
|
||||
key: 'executorName'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.host'),
|
||||
key: 'host'
|
||||
},
|
||||
{
|
||||
title: t('project.workflow.operation'),
|
||||
key: 'operation',
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
className: styles.operation,
|
||||
render: (_row: IWorkflowInstance, index: number) =>
|
||||
h(TableAction, {
|
||||
row: _row,
|
||||
onReRun: () =>
|
||||
_countDownFn({
|
||||
index,
|
||||
processInstanceId: _row.id,
|
||||
executeType: 'REPEAT_RUNNING',
|
||||
buttonType: 'run'
|
||||
}),
|
||||
onReStore: () =>
|
||||
_countDownFn({
|
||||
index,
|
||||
processInstanceId: _row.id,
|
||||
executeType: 'START_FAILURE_TASK_PROCESS',
|
||||
buttonType: 'store'
|
||||
}),
|
||||
onStop: () => {
|
||||
if (_row.state === 'STOP') {
|
||||
_countDownFn({
|
||||
index,
|
||||
processInstanceId: _row.id,
|
||||
executeType: 'RECOVER_SUSPENDED_PROCESS',
|
||||
buttonType: 'suspend'
|
||||
})
|
||||
} else {
|
||||
_upExecutorsState({
|
||||
processInstanceId: _row.id,
|
||||
executeType: 'STOP'
|
||||
})
|
||||
}
|
||||
},
|
||||
onSuspend: () => {
|
||||
if (_row.state === 'PAUSE') {
|
||||
_countDownFn({
|
||||
index,
|
||||
processInstanceId: _row.id,
|
||||
executeType: 'RECOVER_SUSPENDED_PROCESS',
|
||||
buttonType: 'suspend'
|
||||
})
|
||||
} else {
|
||||
_upExecutorsState({
|
||||
processInstanceId: _row.id,
|
||||
executeType: 'PAUSE'
|
||||
})
|
||||
}
|
||||
},
|
||||
onDeleteInstance: () => deleteInstance(_row.id)
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const getTableData = () => {
|
||||
const params = {
|
||||
pageNo: variables.page,
|
||||
pageSize: variables.pageSize,
|
||||
searchVal: variables.searchVal,
|
||||
executorName: variables.executorName,
|
||||
host: variables.host,
|
||||
stateType: variables.stateType,
|
||||
startDate: variables.startDate,
|
||||
endDate: variables.endDate
|
||||
}
|
||||
queryProcessInstanceListPaging({ ...params }, variables.projectCode).then(
|
||||
(res: any) => {
|
||||
variables.totalPage = res.totalPage
|
||||
variables.tableData = res.totalList.map((item: any) => {
|
||||
return { ...item }
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const deleteInstance = (id: number) => {
|
||||
deleteProcessInstanceById(id, variables.projectCode)
|
||||
.then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
if (variables.tableData.length === 1 && variables.page > 1) {
|
||||
variables.page -= 1
|
||||
}
|
||||
|
||||
getTableData()
|
||||
})
|
||||
.catch((error: any) => {
|
||||
window.$message.error(error.message || '')
|
||||
getTableData()
|
||||
})
|
||||
}
|
||||
|
||||
const batchDeleteInstance = () => {
|
||||
const data = {
|
||||
processInstanceIds: _.join(variables.checkedRowKeys, ',')
|
||||
}
|
||||
|
||||
batchDeleteProcessInstanceByIds(data, variables.projectCode)
|
||||
.then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
|
||||
if (
|
||||
variables.tableData.length === variables.checkedRowKeys.length &&
|
||||
variables.page > 1
|
||||
) {
|
||||
variables.page -= 1
|
||||
}
|
||||
|
||||
variables.checkedRowKeys = []
|
||||
getTableData()
|
||||
})
|
||||
.catch((error: any) => {
|
||||
window.$message.error(error.message || '')
|
||||
getTableData()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* operating
|
||||
*/
|
||||
const _upExecutorsState = (param: ExecuteReq) => {
|
||||
execute(param, variables.projectCode)
|
||||
.then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
|
||||
getTableData()
|
||||
})
|
||||
.catch((error: any) => {
|
||||
window.$message.error(error.message || '')
|
||||
getTableData()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Countdown
|
||||
*/
|
||||
const _countDown = (fn: any, index: number) => {
|
||||
const TIME_COUNT = 10
|
||||
let timer: number | undefined
|
||||
let $count: number
|
||||
if (!timer) {
|
||||
$count = TIME_COUNT
|
||||
timer = setInterval(() => {
|
||||
if ($count > 0 && $count <= TIME_COUNT) {
|
||||
$count--
|
||||
variables.tableData[index].count = $count
|
||||
} else {
|
||||
fn()
|
||||
clearInterval(timer)
|
||||
timer = undefined
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Countdown method refresh
|
||||
*/
|
||||
const _countDownFn = (param: ICountDownParam) => {
|
||||
const { index } = param
|
||||
variables.tableData[index].buttonType = param.buttonType
|
||||
execute(param, variables.projectCode)
|
||||
.then(() => {
|
||||
variables.tableData[index].disabled = true
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
_countDown(() => {
|
||||
getTableData()
|
||||
}, index)
|
||||
})
|
||||
.catch((error: any) => {
|
||||
window.$message.error(error.message)
|
||||
getTableData()
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
variables,
|
||||
createColumns,
|
||||
getTableData,
|
||||
batchDeleteInstance
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user