From 84975ae428fac85f3e5374a5dd8b67cd57ae4c55 Mon Sep 17 00:00:00 2001 From: zhangdonghao Date: Sun, 21 Sep 2025 22:48:19 +0800 Subject: [PATCH] [Fix][UI] Optimize detail and finish-jobs components --- .../server/rest/service/JobInfoService.java | 2 +- .../src/views/jobs/detail.tsx | 30 +++++++++++++++---- .../src/views/jobs/finished-jobs.tsx | 5 ++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/JobInfoService.java b/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/JobInfoService.java index 977aa14e190..09ac57100de 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/JobInfoService.java +++ b/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/JobInfoService.java @@ -104,7 +104,7 @@ public JsonArray getJobsByStateJson(String state) { } return jobState.getJobStatus().name().equals(state.toUpperCase()); }) - .sorted(Comparator.comparing(JobState::getFinishTime)) + .sorted(Comparator.comparing(JobState::getFinishTime, Comparator.reverseOrder())) .map( jobState -> { Long jobId = jobState.getJobId(); diff --git a/seatunnel-engine/seatunnel-engine-ui/src/views/jobs/detail.tsx b/seatunnel-engine/seatunnel-engine-ui/src/views/jobs/detail.tsx index f5e7ed12b4d..f8f14b101f3 100644 --- a/seatunnel-engine/seatunnel-engine-ui/src/views/jobs/detail.tsx +++ b/seatunnel-engine/seatunnel-engine-ui/src/views/jobs/detail.tsx @@ -25,7 +25,7 @@ import { NDrawer, NDrawerContent } from 'naive-ui' -import { computed, defineComponent, reactive, ref, watch } from 'vue' +import {computed, defineComponent, onUnmounted, reactive, ref, watch} from 'vue' import { getJobInfo } from '@/service/job' import { useRoute } from 'vue-router' import type { Job, Vertex } from '@/service/job/types' @@ -47,19 +47,23 @@ export default defineComponent({ const job = reactive({} as Job) const duration = ref('') let timer: NodeJS.Timeout + let fetchTimer: NodeJS.Timeout const fetch = async () => { const res = await getJobInfo(jobId) Object.assign(job, res) clearInterval(timer) const d = parse(res.createTime, 'yyyy-MM-dd HH:mm:ss', new Date()) duration.value = getRemainTime(Math.abs(Date.now() - d.getTime())) - setTimeout(fetch, 5000) - if (job.jobStatus !== 'RUNNING') { + if (isTerminalState(job.jobStatus)) { + clearTimeout(fetchTimer) return } - timer = setInterval(() => { - duration.value = getRemainTime(Math.abs(Date.now() - d.getTime())) - }, 1000) + fetchTimer = setTimeout(fetch, 5000) + if (isRunningState(job.jobStatus)) { + timer = setInterval(() => { + duration.value = getRemainTime(Math.abs(Date.now() - d.getTime())) + }, 1000) + } } fetch() @@ -70,6 +74,20 @@ export default defineComponent({ } watch(() => select.value, change) + // Clear the timer when the component is uninstalled + onUnmounted(() => { + clearInterval(timer) + clearTimeout(fetchTimer) + }) + + const isTerminalState = (status: string) => { + return ['FINISHED', 'FAILED', 'CANCELED','SAVEPOINT_DONE'].includes(status) + } + + const isRunningState = (status: string) => { + return status === 'RUNNING' + } + const tableData = computed(() => { return job.jobDag?.vertexInfoMap?.filter((v) => v.type !== 'transform') || [] }) diff --git a/seatunnel-engine/seatunnel-engine-ui/src/views/jobs/finished-jobs.tsx b/seatunnel-engine/seatunnel-engine-ui/src/views/jobs/finished-jobs.tsx index 202feef1584..6d916c8d3ca 100644 --- a/seatunnel-engine/seatunnel-engine-ui/src/views/jobs/finished-jobs.tsx +++ b/seatunnel-engine/seatunnel-engine-ui/src/views/jobs/finished-jobs.tsx @@ -66,6 +66,11 @@ export default defineComponent({ key: 'createTime', sorter: 'default' }, + { + title: 'Finish Time', + key: 'finishTime', + sorter: 'default' + }, { title: 'Status', key: 'jobStatus',