From 624f8e77cba33c7a1c69fe5d5b6babe57ce820d8 Mon Sep 17 00:00:00 2001 From: Allan Carr Date: Thu, 7 Nov 2024 13:56:53 -0800 Subject: [PATCH 1/3] IO-3017 Lifecycle Average Time Signed-off-by: Allan Carr --- .../job-lifecycle-dashboard.component.jsx | 15 ++++++++++----- client/src/translations/en_us/common.json | 2 ++ client/src/translations/es/common.json | 2 ++ client/src/translations/fr/common.json | 2 ++ server/job/job-lifecycle.js | 10 ++++++++-- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/client/src/components/dashboard-components/job-lifecycle/job-lifecycle-dashboard.component.jsx b/client/src/components/dashboard-components/job-lifecycle/job-lifecycle-dashboard.component.jsx index 38d939c89..5f52d62c6 100644 --- a/client/src/components/dashboard-components/job-lifecycle/job-lifecycle-dashboard.component.jsx +++ b/client/src/components/dashboard-components/job-lifecycle/job-lifecycle-dashboard.component.jsx @@ -1,10 +1,10 @@ import { Card, Table, Tag } from "antd"; -import LoadingSkeleton from "../../loading-skeleton/loading-skeleton.component"; -import { useTranslation } from "react-i18next"; -import React, { useEffect, useState } from "react"; -import dayjs from "../../../utils/day"; -import DashboardRefreshRequired from "../refresh-required.component"; import axios from "axios"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import dayjs from "../../../utils/day"; +import LoadingSkeleton from "../../loading-skeleton/loading-skeleton.component"; +import DashboardRefreshRequired from "../refresh-required.component"; const fortyFiveDaysAgo = () => dayjs().subtract(45, "day").toLocaleString(); @@ -46,6 +46,11 @@ export default function JobLifecycleDashboardComponent({ data, bodyshop, ...card dataIndex: "humanReadable", key: "humanReadable" }, + { + title: t("job_lifecycle.columns.average_human_readable"), + dataIndex: "averageHumanReadable", + key: "averageHumanReadable" + }, { title: t("job_lifecycle.columns.status_count"), key: "statusCount", diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 38f13e032..d91c369fd 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -1338,6 +1338,8 @@ }, "job_lifecycle": { "columns": { + "average_human_readable": "Average Human Readable", + "average_value": "Average Value", "duration": "Duration", "end": "End", "human_readable": "Human Readable", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index ed7760e9d..7658ca3ce 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -1338,6 +1338,8 @@ }, "job_lifecycle": { "columns": { + "average_human_readable": "", + "average_value": "", "duration": "", "end": "", "human_readable": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 4a64bcc55..a109a127d 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -1338,6 +1338,8 @@ }, "job_lifecycle": { "columns": { + "average_human_readable": "", + "average_value": "", "duration": "", "end": "", "human_readable": "", diff --git a/server/job/job-lifecycle.js b/server/job/job-lifecycle.js index 744639bcf..feb093d6e 100644 --- a/server/job/job-lifecycle.js +++ b/server/job/job-lifecycle.js @@ -81,13 +81,17 @@ const jobLifecycle = async (req, res) => { const percentage = (value / finalTotal) * 100; const color = getLifecycleStatusColor(status); const roundedPercentage = `${Math.round(percentage)}%`; + const averageValue = value / jobIDs.length; + const averageHumanReadable = durationToHumanReadable(moment.duration(averageValue)); finalSummations.push({ status, value, humanReadable, percentage, color, - roundedPercentage + roundedPercentage, + averageValue, + averageHumanReadable }); }); @@ -100,7 +104,9 @@ const jobLifecycle = async (req, res) => { totalStatuses: finalSummations.length, total: finalTotal, statusCounts: finalStatusCounts, - humanReadable: durationToHumanReadable(moment.duration(finalTotal)) + humanReadable: durationToHumanReadable(moment.duration(finalTotal)), + averageValue: finalTotal / jobIDs.length, + averageHumanReadable: durationToHumanReadable(moment.duration(finalTotal / jobIDs.length)) } }); }; From a14b2340b0647e1bdf7d3802dc8adffd21d7ab85 Mon Sep 17 00:00:00 2001 From: Allan Carr Date: Fri, 8 Nov 2024 09:24:58 -0800 Subject: [PATCH 2/3] IO-3017 Lifecycle NaN prevention Signed-off-by: Allan Carr --- server/job/job-lifecycle.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/server/job/job-lifecycle.js b/server/job/job-lifecycle.js index feb093d6e..ddd58a834 100644 --- a/server/job/job-lifecycle.js +++ b/server/job/job-lifecycle.js @@ -78,10 +78,10 @@ const jobLifecycle = async (req, res) => { Object.keys(flatGroupedAllDurations).forEach((status) => { const value = flatGroupedAllDurations[status].reduce((acc, curr) => acc + curr.value, 0); const humanReadable = durationToHumanReadable(moment.duration(value)); - const percentage = (value / finalTotal) * 100; + const percentage = finalTotal > 0 ? (value / finalTotal) * 100 : 0; const color = getLifecycleStatusColor(status); const roundedPercentage = `${Math.round(percentage)}%`; - const averageValue = value / jobIDs.length; + const averageValue = _size(jobIDs) > 0 ? value / jobIDs.length : 0; const averageHumanReadable = durationToHumanReadable(moment.duration(averageValue)); finalSummations.push({ status, @@ -105,8 +105,11 @@ const jobLifecycle = async (req, res) => { total: finalTotal, statusCounts: finalStatusCounts, humanReadable: durationToHumanReadable(moment.duration(finalTotal)), - averageValue: finalTotal / jobIDs.length, - averageHumanReadable: durationToHumanReadable(moment.duration(finalTotal / jobIDs.length)) + averageValue: _size(jobIDs) > 0 ? finalTotal / jobIDs.length : 0, + averageHumanReadable: + _size(jobIDs) > 0 + ? durationToHumanReadable(moment.duration(finalTotal / jobIDs.length)) + : durationToHumanReadable(moment.duration(0)) } }); }; From 3b19432974974c4dd103f5eb88473eb816ea63c1 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 8 Nov 2024 09:32:58 -0800 Subject: [PATCH 3/3] feature/IO-3017-Lifecycle-Average-Time - Small fixes Signed-off-by: Dave Richer --- server/job/job-lifecycle.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/job/job-lifecycle.js b/server/job/job-lifecycle.js index ddd58a834..7076069f6 100644 --- a/server/job/job-lifecycle.js +++ b/server/job/job-lifecycle.js @@ -81,7 +81,7 @@ const jobLifecycle = async (req, res) => { const percentage = finalTotal > 0 ? (value / finalTotal) * 100 : 0; const color = getLifecycleStatusColor(status); const roundedPercentage = `${Math.round(percentage)}%`; - const averageValue = _size(jobIDs) > 0 ? value / jobIDs.length : 0; + const averageValue = _.size(jobIDs) > 0 ? value / jobIDs.length : 0; const averageHumanReadable = durationToHumanReadable(moment.duration(averageValue)); finalSummations.push({ status, @@ -105,9 +105,9 @@ const jobLifecycle = async (req, res) => { total: finalTotal, statusCounts: finalStatusCounts, humanReadable: durationToHumanReadable(moment.duration(finalTotal)), - averageValue: _size(jobIDs) > 0 ? finalTotal / jobIDs.length : 0, + averageValue: _.size(jobIDs) > 0 ? finalTotal / jobIDs.length : 0, averageHumanReadable: - _size(jobIDs) > 0 + _.size(jobIDs) > 0 ? durationToHumanReadable(moment.duration(finalTotal / jobIDs.length)) : durationToHumanReadable(moment.duration(0)) }