[Feature][UI Next] Add project task instance. (#8220)
parent
756ea1181e
commit
d1f65053a8
|
|
@ -17,7 +17,7 @@
|
|||
"echarts": "^5.2.2",
|
||||
"lodash": "^4.17.21",
|
||||
"monaco-editor": "^0.31.1",
|
||||
"naive-ui": "2.23.2",
|
||||
"naive-ui": "2.24.6",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.9",
|
||||
"pinia-plugin-persistedstate": "^1.0.3",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -337,6 +337,38 @@ const project = {
|
|||
workflow_publish_status: 'Workflow Publish Status',
|
||||
schedule_publish_status: 'Schedule Publish Status'
|
||||
},
|
||||
task: {
|
||||
task_name: 'Task Name',
|
||||
workflow_instance: 'Workflow Instance',
|
||||
executor: 'Executor',
|
||||
node_type: 'Node Type',
|
||||
state: 'State',
|
||||
submit_time: 'Submit Time',
|
||||
start_time: 'Start Time',
|
||||
end_time: 'End Time',
|
||||
duration: 'Duration',
|
||||
retry_count: 'Retry Count',
|
||||
dry_run_flag: 'Dry Run Flag',
|
||||
host: 'Host',
|
||||
operation: 'Operation',
|
||||
submitted_success: 'Submitted Success',
|
||||
running_execution: 'Running Execution',
|
||||
ready_pause: 'Ready Pause',
|
||||
pause: 'Pause',
|
||||
ready_stop: 'Ready Stop',
|
||||
stop: 'Stop',
|
||||
failure: 'Failure',
|
||||
success: 'Success',
|
||||
need_fault_tolerance: 'Need Fault Tolerance',
|
||||
kill: 'Kill',
|
||||
waiting_thread: 'Waiting Thread',
|
||||
waiting_depend: 'Waiting Depend',
|
||||
delay_execution: 'Delay Execution',
|
||||
forced_success: 'Forced Success',
|
||||
serial_wait: 'Serial Wait',
|
||||
view_log: 'View Log',
|
||||
download_log: 'Download Log'
|
||||
},
|
||||
dag: {
|
||||
createWorkflow: 'Create Workflow',
|
||||
search: 'Search',
|
||||
|
|
|
|||
|
|
@ -336,6 +336,38 @@ const project = {
|
|||
workflow_publish_status: '工作流上线状态',
|
||||
schedule_publish_status: '定时状态'
|
||||
},
|
||||
task: {
|
||||
task_name: '任务名称',
|
||||
workflow_instance: '工作流实例',
|
||||
executor: '执行用户',
|
||||
node_type: '节点类型',
|
||||
state: '状态',
|
||||
submit_time: '提交时间',
|
||||
start_time: '开始时间',
|
||||
end_time: '结束时间',
|
||||
duration: '运行时间',
|
||||
retry_count: '重试次数',
|
||||
dry_run_flag: '空跑标识',
|
||||
host: '主机',
|
||||
operation: '操作',
|
||||
submitted_success: '提交成功',
|
||||
running_execution: '正在运行',
|
||||
ready_pause: '准备暂停',
|
||||
pause: '暂停',
|
||||
ready_stop: '准备停止',
|
||||
stop: '停止',
|
||||
failure: '失败',
|
||||
success: '成功',
|
||||
need_fault_tolerance: '需要容错',
|
||||
kill: '已被杀',
|
||||
waiting_thread: '等待线程',
|
||||
waiting_depend: '等待依赖完成',
|
||||
delay_execution: '延时执行',
|
||||
forced_success: '强制成功',
|
||||
serial_wait: '串行等待',
|
||||
view_log: '查看日志',
|
||||
download_log: '下载日志'
|
||||
},
|
||||
dag: {
|
||||
createWorkflow: '创建工作流',
|
||||
search: '搜索',
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { axios } from '@/service/service'
|
||||
import { axios, downloadFile } from '@/service/service'
|
||||
import { ProjectCodeReq, IdReq, TaskListReq } from './types'
|
||||
|
||||
export function queryTaskListPaging(
|
||||
|
|
@ -23,15 +23,19 @@ export function queryTaskListPaging(
|
|||
projectCode: ProjectCodeReq
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/task-instances`,
|
||||
url: `/projects/${projectCode.projectCode}/task-instances`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function forceSuccess(id: IdReq, projectCode: ProjectCodeReq): any {
|
||||
export function forceSuccess(taskId: IdReq, projectCode: ProjectCodeReq): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/task-instances/${id}/force-success`,
|
||||
url: `/projects/${projectCode.projectCode}/task-instances/${taskId.id}/force-success`,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function downloadLog(id: number): void {
|
||||
downloadFile(`log/download-log`, { taskInstanceId: id })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,4 +37,89 @@ interface TaskListReq {
|
|||
taskName?: string
|
||||
}
|
||||
|
||||
export { ProjectCodeReq, IdReq, TaskListReq }
|
||||
interface Dependency {
|
||||
localParams?: any
|
||||
varPool?: any
|
||||
dependTaskList?: any
|
||||
relation?: any
|
||||
resourceFilesList: any[]
|
||||
varPoolMap?: any
|
||||
localParametersMap?: any
|
||||
}
|
||||
|
||||
interface SwitchDependency extends Dependency {
|
||||
nextNode?: any
|
||||
resultConditionLocation: number
|
||||
dependTaskList?: any
|
||||
}
|
||||
|
||||
interface TotalList {
|
||||
taskComplete: boolean
|
||||
firstRun: boolean
|
||||
environmentCode: number
|
||||
processInstance?: any
|
||||
pid: number
|
||||
appLink: string
|
||||
taskCode: any
|
||||
switchTask: boolean
|
||||
host: string
|
||||
id: number
|
||||
state: string
|
||||
workerGroup: string
|
||||
conditionsTask: boolean
|
||||
processInstancePriority?: any
|
||||
processInstanceId: number
|
||||
dependency: Dependency
|
||||
alertFlag: string
|
||||
dependentResult?: any
|
||||
executePath: string
|
||||
switchDependency: SwitchDependency
|
||||
maxRetryTimes: number
|
||||
executorName: string
|
||||
subProcess: boolean
|
||||
submitTime: string
|
||||
taskGroupId: number
|
||||
name: string
|
||||
taskDefinitionVersion: number
|
||||
processInstanceName: string
|
||||
taskGroupPriority: number
|
||||
taskDefine?: any
|
||||
dryRun: number
|
||||
flag: string
|
||||
taskParams: string
|
||||
duration: string
|
||||
processDefine?: any
|
||||
taskType: string
|
||||
taskInstancePriority: string
|
||||
logPath: string
|
||||
startTime: string
|
||||
environmentConfig?: any
|
||||
executorId: number
|
||||
firstSubmitTime: string
|
||||
resources?: any
|
||||
retryTimes: number
|
||||
varPool: string
|
||||
dependTask: boolean
|
||||
delayTime: number
|
||||
retryInterval: number
|
||||
endTime: string
|
||||
}
|
||||
|
||||
interface TaskInstancesRes {
|
||||
totalList: TotalList[]
|
||||
total: number
|
||||
totalPage: number
|
||||
pageSize: number
|
||||
currentPage: number
|
||||
start: number
|
||||
}
|
||||
|
||||
export {
|
||||
ProjectCodeReq,
|
||||
IdReq,
|
||||
TaskListReq,
|
||||
Dependency,
|
||||
SwitchDependency,
|
||||
TotalList,
|
||||
TaskInstancesRes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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, onMounted, PropType, toRefs, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { NLog } from 'naive-ui'
|
||||
import { useModal } from './use-modal'
|
||||
import Modal from '@/components/modal'
|
||||
|
||||
const props = {
|
||||
showModalRef: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
row: {
|
||||
type: Object as PropType<any>,
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
|
||||
const LogModal = defineComponent({
|
||||
name: 'LogModal',
|
||||
props,
|
||||
emits: ['confirmModal'],
|
||||
setup(props, ctx) {
|
||||
const { t } = useI18n()
|
||||
const { variables, getLogs } = useModal()
|
||||
|
||||
const confirmModal = () => {
|
||||
ctx.emit('confirmModal', props.showModalRef)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.showModalRef,
|
||||
() => {
|
||||
if (props.showModalRef) {
|
||||
variables.id = props.row.id
|
||||
props.showModalRef && variables.id && getLogs()
|
||||
} else {
|
||||
variables.id = ''
|
||||
variables.logRef = ''
|
||||
variables.loadingRef = true
|
||||
variables.skipLineNum = 0
|
||||
variables.limit = 1000
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return { t, ...toRefs(variables), confirmModal }
|
||||
},
|
||||
render() {
|
||||
const { t } = this
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t('project.task.view_log')}
|
||||
show={this.showModalRef}
|
||||
cancelShow={false}
|
||||
onConfirm={this.confirmModal}
|
||||
style={{ width: '60%' }}
|
||||
>
|
||||
<NLog rows={30} log={this.logRef} loading={this.loadingRef} />
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default LogModal
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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 { reactive, ref } from 'vue'
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { queryLog } from '@/service/modules/log'
|
||||
|
||||
export function useModal() {
|
||||
const variables = reactive({
|
||||
id: ref(''),
|
||||
loadingRef: ref(true),
|
||||
logRef: ref(''),
|
||||
skipLineNum: ref(0),
|
||||
limit: ref(1000)
|
||||
})
|
||||
|
||||
const getLogs = () => {
|
||||
const { state } = useAsyncState(
|
||||
queryLog({
|
||||
taskInstanceId: Number(variables.id),
|
||||
limit: variables.limit,
|
||||
skipLineNum: variables.skipLineNum
|
||||
}).then((res: string) => {
|
||||
variables.logRef += res
|
||||
|
||||
if (res) {
|
||||
variables.limit += 1000
|
||||
variables.skipLineNum += 1000
|
||||
getLogs()
|
||||
} else {
|
||||
variables.loadingRef = false
|
||||
}
|
||||
}),
|
||||
{}
|
||||
)
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
return {
|
||||
variables,
|
||||
getLogs
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.table-card {
|
||||
margin-top: 8px;
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
|
@ -15,11 +15,158 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineComponent } from 'vue'
|
||||
import { defineComponent, onMounted, toRefs, watch } from 'vue'
|
||||
import {
|
||||
NSpace,
|
||||
NInput,
|
||||
NSelect,
|
||||
NDatePicker,
|
||||
NButton,
|
||||
NIcon,
|
||||
NDataTable,
|
||||
NPagination,
|
||||
NCard
|
||||
} from 'naive-ui'
|
||||
import { SearchOutlined } from '@vicons/antd'
|
||||
import { useTable } from './use-table'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Card from '@/components/card'
|
||||
import LogModal from './components/log-modal'
|
||||
import styles from './index.module.scss'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TaskInstanceList',
|
||||
const TaskInstance = defineComponent({
|
||||
name: 'task-instance',
|
||||
setup() {
|
||||
return () => <div>TaskInstanceList</div>
|
||||
const { t, variables, getTableData, createColumns } = useTable()
|
||||
|
||||
const requestTableData = () => {
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal,
|
||||
processInstanceId: variables.processInstanceId,
|
||||
host: variables.host,
|
||||
stateType: variables.stateType,
|
||||
datePickerRange: variables.datePickerRange,
|
||||
executorName: variables.executorName,
|
||||
processInstanceName: variables.processInstanceName
|
||||
})
|
||||
}
|
||||
|
||||
const onUpdatePageSize = () => {
|
||||
variables.page = 1
|
||||
requestTableData()
|
||||
}
|
||||
|
||||
const onSearch = () => {
|
||||
variables.page = 1
|
||||
requestTableData()
|
||||
}
|
||||
|
||||
const onConfirmModal = () => {
|
||||
variables.showModalRef = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
createColumns(variables)
|
||||
requestTableData()
|
||||
})
|
||||
|
||||
watch(useI18n().locale, () => {
|
||||
createColumns(variables)
|
||||
})
|
||||
|
||||
return {
|
||||
t,
|
||||
...toRefs(variables),
|
||||
requestTableData,
|
||||
onUpdatePageSize,
|
||||
onSearch,
|
||||
onConfirmModal
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { t, requestTableData, onUpdatePageSize, onSearch, onConfirmModal } =
|
||||
this
|
||||
|
||||
return (
|
||||
<>
|
||||
<NCard>
|
||||
<NSpace justify='end'>
|
||||
<NInput
|
||||
v-model={[this.searchVal, 'value']}
|
||||
size='small'
|
||||
placeholder={t('project.task.task_name')}
|
||||
clearable
|
||||
/>
|
||||
<NInput
|
||||
v-model={[this.processInstanceName, 'value']}
|
||||
size='small'
|
||||
placeholder={t('project.task.workflow_instance')}
|
||||
clearable
|
||||
/>
|
||||
<NInput
|
||||
v-model={[this.executorName, 'value']}
|
||||
size='small'
|
||||
placeholder={t('project.task.executor')}
|
||||
clearable
|
||||
/>
|
||||
<NInput
|
||||
v-model={[this.host, 'value']}
|
||||
size='small'
|
||||
placeholder={t('project.task.host')}
|
||||
clearable
|
||||
/>
|
||||
<NSelect
|
||||
v-model={[this.stateType, 'value']}
|
||||
size='small'
|
||||
options={this.generalOptions}
|
||||
placeholder={t('project.task.state')}
|
||||
style={{ width: '180px' }}
|
||||
clearable
|
||||
/>
|
||||
<NDatePicker
|
||||
v-model={[this.datePickerRange, 'value']}
|
||||
type='datetimerange'
|
||||
size='small'
|
||||
start-placeholder={t('project.task.start_time')}
|
||||
end-placeholder={t('project.task.end_time')}
|
||||
clearable
|
||||
/>
|
||||
<NButton size='small' type='primary' onClick={onSearch}>
|
||||
{{
|
||||
icon: () => (
|
||||
<NIcon>
|
||||
<SearchOutlined />
|
||||
</NIcon>
|
||||
)
|
||||
}}
|
||||
</NButton>
|
||||
</NSpace>
|
||||
</NCard>
|
||||
<Card class={styles['table-card']}>
|
||||
<NDataTable columns={this.columns} data={this.tableData} />
|
||||
<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={requestTableData}
|
||||
onUpdatePageSize={onUpdatePageSize}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
<LogModal
|
||||
showModalRef={this.showModalRef}
|
||||
row={this.row}
|
||||
onConfirmModal={onConfirmModal}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default TaskInstance
|
||||
|
|
|
|||
|
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* 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 { useI18n } from 'vue-i18n'
|
||||
import { h, reactive, ref } from 'vue'
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import {
|
||||
queryTaskListPaging,
|
||||
forceSuccess,
|
||||
downloadLog
|
||||
} from '@/service/modules/task-instances'
|
||||
import { NButton, NSpace, NTooltip } from 'naive-ui'
|
||||
import {
|
||||
AlignLeftOutlined,
|
||||
CheckCircleOutlined,
|
||||
DownloadOutlined
|
||||
} from '@vicons/antd'
|
||||
import { format } from 'date-fns'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { downloadFile } from '@/service/service'
|
||||
import type { TaskInstancesRes } from '@/service/modules/task-instances/types'
|
||||
|
||||
export function useTable() {
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
const projectCode = Number(route.params.projectCode)
|
||||
|
||||
const variables = reactive({
|
||||
columns: [],
|
||||
tableData: [],
|
||||
page: ref(1),
|
||||
pageSize: ref(10),
|
||||
searchVal: ref(null),
|
||||
processInstanceId: ref(null),
|
||||
host: ref(null),
|
||||
stateType: ref(null),
|
||||
datePickerRange: ref(null),
|
||||
executorName: ref(null),
|
||||
processInstanceName: ref(null),
|
||||
totalPage: ref(1),
|
||||
showModalRef: ref(false),
|
||||
statusRef: ref(0),
|
||||
row: {},
|
||||
generalOptions: [
|
||||
{
|
||||
label: t('project.task.submitted_success'),
|
||||
value: 'SUBMITTED_SUCCESS'
|
||||
},
|
||||
{
|
||||
label: t('project.task.running_execution'),
|
||||
value: 'RUNNING_EXECUTION'
|
||||
},
|
||||
{ label: t('project.task.ready_pause'), value: 'READY_PAUSE' },
|
||||
{ label: t('project.task.pause'), value: 'PAUSE' },
|
||||
{ label: t('project.task.ready_stop'), value: 'READY_STOP' },
|
||||
{ label: t('project.task.stop'), value: 'STOP' },
|
||||
{ label: t('project.task.failure'), value: 'FAILURE' },
|
||||
{ label: t('project.task.success'), value: 'SUCCESS' },
|
||||
{
|
||||
label: t('project.task.need_fault_tolerance'),
|
||||
value: 'NEED_FAULT_TOLERANCE'
|
||||
},
|
||||
{ label: t('project.task.kill'), value: 'KILL' },
|
||||
{ label: t('project.task.waiting_thread'), value: 'WAITING_THREAD' },
|
||||
{ label: t('project.task.waiting_depend'), value: 'WAITING_DEPEND' },
|
||||
{ label: t('project.task.delay_execution'), value: 'DELAY_EXECUTION' },
|
||||
{ label: t('project.task.forced_success'), value: 'FORCED_SUCCESS' },
|
||||
{ label: t('project.task.serial_wait'), value: 'SERIAL_WAIT' }
|
||||
]
|
||||
})
|
||||
|
||||
const createColumns = (variables: any) => {
|
||||
variables.columns = [
|
||||
{
|
||||
title: '#',
|
||||
key: 'index'
|
||||
},
|
||||
{
|
||||
title: t('project.task.task_name'),
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: t('project.task.workflow_instance'),
|
||||
key: 'processInstanceName',
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: t('project.task.executor'),
|
||||
key: 'executorName'
|
||||
},
|
||||
{
|
||||
title: t('project.task.node_type'),
|
||||
key: 'taskType'
|
||||
},
|
||||
{
|
||||
title: t('project.task.state'),
|
||||
key: 'state'
|
||||
},
|
||||
{
|
||||
title: t('project.task.submit_time'),
|
||||
key: 'submitTime',
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
title: t('project.task.start_time'),
|
||||
key: 'startTime',
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
title: t('project.task.end_time'),
|
||||
key: 'endTime',
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
title: t('project.task.duration'),
|
||||
key: 'duration',
|
||||
render: (row: any) => h('span', null, row.duration ? row.duration : '-')
|
||||
},
|
||||
{
|
||||
title: t('project.task.retry_count'),
|
||||
key: 'retryTimes'
|
||||
},
|
||||
{
|
||||
title: t('project.task.dry_run_flag'),
|
||||
key: 'dryRun'
|
||||
},
|
||||
{
|
||||
title: t('project.task.host'),
|
||||
key: 'host',
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
title: t('project.task.operation'),
|
||||
key: 'operation',
|
||||
width: 150,
|
||||
render(row: any) {
|
||||
return h(NSpace, null, {
|
||||
default: () => [
|
||||
h(
|
||||
NTooltip,
|
||||
{},
|
||||
{
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
circle: true,
|
||||
type: 'info',
|
||||
size: 'small',
|
||||
disabled: !(
|
||||
row.state === 'FAILURE' ||
|
||||
row.state === 'NEED_FAULT_TOLERANCE' ||
|
||||
row.state === 'KILL'
|
||||
),
|
||||
onClick: () => {
|
||||
handleForcedSuccess(row)
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: () => h(CheckCircleOutlined)
|
||||
}
|
||||
),
|
||||
default: () => t('project.task.serial_wait')
|
||||
}
|
||||
),
|
||||
h(
|
||||
NTooltip,
|
||||
{},
|
||||
{
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
circle: true,
|
||||
type: 'info',
|
||||
size: 'small',
|
||||
onClick: () => handleLog(row)
|
||||
},
|
||||
{
|
||||
icon: () => h(AlignLeftOutlined)
|
||||
}
|
||||
),
|
||||
default: () => t('project.task.view_log')
|
||||
}
|
||||
),
|
||||
h(
|
||||
NTooltip,
|
||||
{},
|
||||
{
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
circle: true,
|
||||
type: 'info',
|
||||
size: 'small',
|
||||
onClick: () => downloadLog(row.id)
|
||||
},
|
||||
{
|
||||
icon: () => h(DownloadOutlined)
|
||||
}
|
||||
),
|
||||
default: () => t('project.task.download_log')
|
||||
}
|
||||
)
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const handleLog = (row: any) => {
|
||||
variables.showModalRef = true
|
||||
variables.row = row
|
||||
}
|
||||
|
||||
const handleForcedSuccess = (row: any) => {
|
||||
forceSuccess({ id: row.id }, { projectCode }).then(() => {
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo:
|
||||
variables.tableData.length === 1 && variables.page > 1
|
||||
? variables.page - 1
|
||||
: variables.page,
|
||||
searchVal: variables.searchVal,
|
||||
processInstanceId: variables.processInstanceId,
|
||||
host: variables.host,
|
||||
stateType: variables.stateType,
|
||||
datePickerRange: variables.datePickerRange,
|
||||
executorName: variables.executorName,
|
||||
processInstanceName: variables.processInstanceName
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getTableData = (params: any) => {
|
||||
const data = {
|
||||
pageSize: params.pageSize,
|
||||
pageNo: params.pageNo,
|
||||
searchVal: params.searchVal,
|
||||
processInstanceId: params.processInstanceId,
|
||||
host: params.host,
|
||||
stateType: params.stateType,
|
||||
startDate: params.datePickerRange
|
||||
? format(new Date(params.datePickerRange[0]), 'yyyy-MM-dd HH:mm:ss')
|
||||
: '',
|
||||
endDate: params.datePickerRange
|
||||
? format(new Date(params.datePickerRange[1]), 'yyyy-MM-dd HH:mm:ss')
|
||||
: '',
|
||||
executorName: params.executorName,
|
||||
processInstanceName: params.processInstanceName
|
||||
}
|
||||
|
||||
const { state } = useAsyncState(
|
||||
queryTaskListPaging(data, { projectCode }).then(
|
||||
(res: TaskInstancesRes) => {
|
||||
variables.tableData = res.totalList.map((item, index) => {
|
||||
item.submitTime = format(
|
||||
new Date(item.submitTime),
|
||||
'yyyy-MM-dd HH:mm:ss'
|
||||
)
|
||||
item.startTime = format(
|
||||
new Date(item.startTime),
|
||||
'yyyy-MM-dd HH:mm:ss'
|
||||
)
|
||||
item.endTime = format(new Date(item.endTime), 'yyyy-MM-dd HH:mm:ss')
|
||||
return {
|
||||
index: index + 1,
|
||||
...item
|
||||
}
|
||||
}) as any
|
||||
}
|
||||
),
|
||||
{}
|
||||
)
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
variables,
|
||||
getTableData,
|
||||
createColumns
|
||||
}
|
||||
}
|
||||
|
|
@ -19,104 +19,104 @@ import { defineComponent, onMounted, toRefs, watch } from 'vue'
|
|||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { NSelect, NButton, NIcon, NSpace, NTooltip } from 'naive-ui'
|
||||
import { ReloadOutlined, EyeOutlined, EditOutlined } from '@vicons/antd'
|
||||
import { ReloadOutlined, EyeOutlined } from '@vicons/antd'
|
||||
import { useRelation } from './use-relation'
|
||||
import Card from '@/components/card'
|
||||
import Graph from './components/Graph'
|
||||
|
||||
const workflowRelation = defineComponent({
|
||||
name: 'workflow-relation',
|
||||
setup() {
|
||||
const { t, locale } = useI18n()
|
||||
const route = useRoute()
|
||||
const { variables, getWorkflowName, getOneWorkflow, getWorkflowList } =
|
||||
useRelation()
|
||||
name: 'workflow-relation',
|
||||
setup() {
|
||||
const { t, locale } = useI18n()
|
||||
const route = useRoute()
|
||||
const { variables, getWorkflowName, getOneWorkflow, getWorkflowList } =
|
||||
useRelation()
|
||||
|
||||
onMounted(() => {
|
||||
getWorkflowList(Number(route.params.projectCode))
|
||||
getWorkflowName(Number(route.params.projectCode))
|
||||
})
|
||||
onMounted(() => {
|
||||
getWorkflowList(Number(route.params.projectCode))
|
||||
getWorkflowName(Number(route.params.projectCode))
|
||||
})
|
||||
|
||||
const handleResetDate = () => {
|
||||
variables.seriesData = []
|
||||
variables.workflow && variables.workflow !== 0
|
||||
? getOneWorkflow(
|
||||
Number(variables.workflow),
|
||||
Number(route.params.projectCode)
|
||||
)
|
||||
: getWorkflowList(Number(route.params.projectCode))
|
||||
}
|
||||
const handleResetDate = () => {
|
||||
variables.seriesData = []
|
||||
variables.workflow && variables.workflow !== 0
|
||||
? getOneWorkflow(
|
||||
Number(variables.workflow),
|
||||
Number(route.params.projectCode)
|
||||
)
|
||||
: getWorkflowList(Number(route.params.projectCode))
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [variables.workflow, variables.labelShow, locale.value],
|
||||
() => {
|
||||
handleResetDate()
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => [variables.workflow, variables.labelShow, locale.value],
|
||||
() => {
|
||||
handleResetDate()
|
||||
}
|
||||
)
|
||||
|
||||
return { t, handleResetDate, ...toRefs(variables) }
|
||||
},
|
||||
render() {
|
||||
const { t, handleResetDate } = this
|
||||
return { t, handleResetDate, ...toRefs(variables) }
|
||||
},
|
||||
render() {
|
||||
const { t, handleResetDate } = this
|
||||
|
||||
return (
|
||||
<Card title={t('project.workflow.workflow_relation')}>
|
||||
{{
|
||||
default: () =>
|
||||
Object.keys(this.seriesData).length > 0 && (
|
||||
<Graph seriesData={this.seriesData} labelShow={this.labelShow} />
|
||||
),
|
||||
'header-extra': () => (
|
||||
<NSpace>
|
||||
<NSelect
|
||||
clearable
|
||||
style={{ width: '300px' }}
|
||||
placeholder={t('project.workflow.workflow_name')}
|
||||
options={this.workflowOptions}
|
||||
v-model={[this.workflow, 'value']}
|
||||
/>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.refresh'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
strong
|
||||
secondary
|
||||
circle
|
||||
type='info'
|
||||
onClick={handleResetDate}
|
||||
>
|
||||
<NIcon>
|
||||
<ReloadOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.show_hide_label'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
strong
|
||||
secondary
|
||||
circle
|
||||
type='info'
|
||||
onClick={() => (this.labelShow = !this.labelShow)}
|
||||
>
|
||||
<NIcon>
|
||||
<EyeOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
</NSpace>
|
||||
)
|
||||
}}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Card title={t('project.workflow.workflow_relation')}>
|
||||
{{
|
||||
default: () =>
|
||||
Object.keys(this.seriesData).length > 0 && (
|
||||
<Graph seriesData={this.seriesData} labelShow={this.labelShow} />
|
||||
),
|
||||
'header-extra': () => (
|
||||
<NSpace>
|
||||
<NSelect
|
||||
clearable
|
||||
style={{ width: '300px' }}
|
||||
placeholder={t('project.workflow.workflow_name')}
|
||||
options={this.workflowOptions}
|
||||
v-model={[this.workflow, 'value']}
|
||||
/>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.refresh'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
strong
|
||||
secondary
|
||||
circle
|
||||
type='info'
|
||||
onClick={handleResetDate}
|
||||
>
|
||||
<NIcon>
|
||||
<ReloadOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
<NTooltip trigger={'hover'}>
|
||||
{{
|
||||
default: () => t('project.workflow.show_hide_label'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
strong
|
||||
secondary
|
||||
circle
|
||||
type='info'
|
||||
onClick={() => (this.labelShow = !this.labelShow)}
|
||||
>
|
||||
<NIcon>
|
||||
<EyeOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NTooltip>
|
||||
</NSpace>
|
||||
)
|
||||
}}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default workflowRelation
|
||||
|
|
|
|||
Loading…
Reference in New Issue