From 78af071fceae054933f3ced7bbc7905cdfb2a220 Mon Sep 17 00:00:00 2001 From: gillespi314 <73313222+gillespi314@users.noreply.github.com> Date: Mon, 15 Aug 2022 15:09:27 -0500 Subject: [PATCH] Handle invalid time values on host details page (#7217) --- .../details/DeviceUserPage/DeviceUserPage.tsx | 5 +- .../HostDetailsPage/HostDetailsPage.tsx | 7 +- .../details/cards/HostSummary/HostSummary.tsx | 2 +- frontend/utilities/helpers.ts | 70 +++++++++++++------ 4 files changed, 57 insertions(+), 27 deletions(-) diff --git a/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx b/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx index f33d1f7721..9a0e96f660 100644 --- a/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx +++ b/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx @@ -229,6 +229,7 @@ const DeviceUserPage = ({ const statusClassName = classnames("status", `status--${host?.status}`); const renderDeviceUserPage = () => { + const failing_policies_count = titleData?.issues; return (
{isLoadingHost ? ( @@ -252,9 +253,9 @@ const DeviceUserPage = ({ {isPremiumTier && (
- {titleData.issues.failing_policies_count > 0 && ( + {failing_policies_count > 0 && ( - {titleData.issues.failing_policies_count} + {failing_policies_count} )} Policies diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx index c68c1d7358..78e78bfb9a 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx @@ -536,6 +536,7 @@ const HostDetailsPage = ({ } const statusClassName = classnames("status", `status--${host?.status}`); + const failingPoliciesCount = titleData?.issues; return ( @@ -571,10 +572,8 @@ const HostDetailsPage = ({ Software Schedule - {titleData.issues.failing_policies_count > 0 && ( - - {titleData.issues.failing_policies_count} - + {failingPoliciesCount > 0 && ( + {failingPoliciesCount} )} Policies diff --git a/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx b/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx index 98d203dfbe..94b246db9a 100644 --- a/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx +++ b/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx @@ -15,7 +15,7 @@ const baseClass = "host-summary"; interface IHostSummaryProps { statusClassName: string; - titleData: any; + titleData: any; // TODO: create interfaces for this and use consistently across host pages and related helpers isPremiumTier?: boolean; isOnlyObserver?: boolean; toggleOSPolicyModal?: () => void; diff --git a/frontend/utilities/helpers.ts b/frontend/utilities/helpers.ts index 42e65507be..3a10d21655 100644 --- a/frontend/utilities/helpers.ts +++ b/frontend/utilities/helpers.ts @@ -590,27 +590,47 @@ export const humanHostLastRestart = ( detailUpdatedAt: string, uptime: number ): string => { - const currentDate = new Date(); - const updatedDate = new Date(detailUpdatedAt); - const millisecondsLastUpdated = currentDate.getTime() - updatedDate.getTime(); + if ( + !detailUpdatedAt || + !uptime || + detailUpdatedAt === "---" || + detailUpdatedAt < "2016-07-28T00:00:00Z" || + typeof uptime !== "number" + ) { + return "Unavailable"; + } + try { + const currentDate = new Date(); + const updatedDate = new Date(detailUpdatedAt); + const millisecondsLastUpdated = + currentDate.getTime() - updatedDate.getTime(); - // Sum of calculated milliseconds since last updated with uptime - const millisecondsLastRestart = - millisecondsLastUpdated + uptime / NANOSECONDS_PER_MILLISECOND; + // Sum of calculated milliseconds since last updated with uptime + const millisecondsLastRestart = + millisecondsLastUpdated + uptime / NANOSECONDS_PER_MILLISECOND; - const restartDate = new Date(); - restartDate.setMilliseconds( - restartDate.getMilliseconds() - millisecondsLastRestart - ); + const restartDate = new Date(); + restartDate.setMilliseconds( + restartDate.getMilliseconds() - millisecondsLastRestart + ); - return formatDistanceToNow(new Date(restartDate), { addSuffix: true }); + return formatDistanceToNow(new Date(restartDate), { addSuffix: true }); + } catch { + return "Unavailable"; + } }; export const humanHostLastSeen = (lastSeen: string): string => { + if (!lastSeen || lastSeen < "2016-07-28T00:00:00Z") { + return "Never"; + } return format(new Date(lastSeen), "MMM d yyyy, HH:mm:ss"); }; export const humanHostEnrolled = (enrolled: string): string => { + if (!enrolled || enrolled < "2016-07-28T00:00:00Z") { + return "Never"; + } return formatDistanceToNow(new Date(enrolled), { addSuffix: true }); }; @@ -618,15 +638,18 @@ export const humanHostMemory = (bytes: number): string => { return `${inGigaBytes(bytes)} GB`; }; -export const humanHostDetailUpdated = (detailUpdated: string): string => { +export const humanHostDetailUpdated = (detailUpdated?: string): string => { // Handles the case when a host has checked in to Fleet but // its details haven't been updated. // July 28, 2016 is the date of the initial commit to fleet/fleet. - if (detailUpdated < "2016-07-28T00:00:00Z") { - return "Never"; + if (!detailUpdated || detailUpdated < "2016-07-28T00:00:00Z") { + return "unavailable"; + } + try { + return formatDistanceToNow(new Date(detailUpdated), { addSuffix: true }); + } catch { + return "unavailable"; } - - return formatDistanceToNow(new Date(detailUpdated), { addSuffix: true }); }; export const hostTeamName = (teamName: string | null): string => { @@ -640,11 +663,15 @@ export const hostTeamName = (teamName: string | null): string => { export const humanQueryLastRun = (lastRun: string): string => { // Handles the case when a query has never been ran. // July 28, 2016 is the date of the initial commit to fleet/fleet. - if (lastRun < "2016-07-28T00:00:00Z") { + if (!lastRun || lastRun < "2016-07-28T00:00:00Z") { return "Has not run"; } - return formatDistanceToNow(new Date(lastRun), { addSuffix: true }); + try { + return formatDistanceToNow(new Date(lastRun), { addSuffix: true }); + } catch { + return "Unavailable"; + } }; export const licenseExpirationWarning = (expiration: string): boolean => { @@ -768,7 +795,10 @@ export const getValidatedTeamId = ( // returns a mixture of props from host export const normalizeEmptyValues = ( hostData: Partial -): { [key: string]: any } => { +): Record< + string, + number | string | boolean | Record +> => { return reduce( hostData, (result, value, key) => { @@ -784,7 +814,7 @@ export const normalizeEmptyValues = ( }; export const wrapFleetHelper = ( - helperFn: (value: any) => string, // number or string or never + helperFn: (value: any) => string, // TODO: replace any with unknown and improve type narrowing by callers value: string ): string => { return value === "---" ? value : helperFn(value);