From ab263bb76a36ac832bedabfca16b424acc616a13 Mon Sep 17 00:00:00 2001
From: RachelElysia <71795832+RachelElysia@users.noreply.github.com>
Date: Mon, 11 Sep 2023 09:45:15 -0400
Subject: [PATCH] Fleet UI: [small released bug] Fix time cell with tooltip
component to not have a date restriction, add unit tests for edge cases
(#13824)
---
changes/14346-fix-cve-time-ago | 1 +
.../HumanTimeDiffWithDateTip.tests.tsx | 36 ++++++++++
.../HumanTimeDiffWithDateTip.tsx | 70 ++++++++++---------
.../ActivityItem/ActivityItem.tsx | 21 ++----
.../Vulnerabilities/Vulnerabilities.tsx | 1 -
frontend/utilities/constants.ts | 3 +
frontend/utilities/helpers.ts | 47 ++++++++++---
7 files changed, 121 insertions(+), 58 deletions(-)
create mode 100644 changes/14346-fix-cve-time-ago
create mode 100644 frontend/components/HumanTimeDiffWithDateTip/HumanTimeDiffWithDateTip.tests.tsx
diff --git a/changes/14346-fix-cve-time-ago b/changes/14346-fix-cve-time-ago
new file mode 100644
index 0000000000..e1333f1ea0
--- /dev/null
+++ b/changes/14346-fix-cve-time-ago
@@ -0,0 +1 @@
+- Fleet UI: Fix software vulnerabilities time ago column for old CVEs
diff --git a/frontend/components/HumanTimeDiffWithDateTip/HumanTimeDiffWithDateTip.tests.tsx b/frontend/components/HumanTimeDiffWithDateTip/HumanTimeDiffWithDateTip.tests.tsx
new file mode 100644
index 0000000000..2f06815930
--- /dev/null
+++ b/frontend/components/HumanTimeDiffWithDateTip/HumanTimeDiffWithDateTip.tests.tsx
@@ -0,0 +1,36 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import { renderWithSetup } from "test/test-utils";
+
+import HumanTimeDiffWithDateTip from "./HumanTimeDiffWithDateTip";
+
+const EMPTY_STRING = "Unavailable";
+const INVALID_STRING = "Invalid date";
+
+describe("HumanTimeDiffWithDateTip - component", () => {
+ it("renders tooltip on hover", async () => {
+ const { user } = renderWithSetup(
+
Vulnerabilities
- {software?.vulnerabilities?.length ? ( <> {software && ( diff --git a/frontend/utilities/constants.ts b/frontend/utilities/constants.ts index 51cda895c2..14530e240b 100644 --- a/frontend/utilities/constants.ts +++ b/frontend/utilities/constants.ts @@ -39,6 +39,9 @@ export const FREQUENCY_DROPDOWN_OPTIONS = [ export const GITHUB_NEW_ISSUE_LINK = "https://github.com/fleetdm/fleet/issues/new?assignees=&labels=bug%2C%3Areproduce&template=bug-report.md"; +/** July 28, 2016 is the date of the initial commit to fleet/fleet. */ +export const INITIAL_FLEET_DATE = "2016-07-28T00:00:00Z"; + export const LOGGING_TYPE_OPTIONS = [ { label: "Snapshot", value: "snapshot" }, { label: "Differential", value: "differential" }, diff --git a/frontend/utilities/helpers.ts b/frontend/utilities/helpers.ts index 72d09475dd..77d9b6dba7 100644 --- a/frontend/utilities/helpers.ts +++ b/frontend/utilities/helpers.ts @@ -15,9 +15,10 @@ import { buildQueryStringFromParams } from "utilities/url"; import md5 from "js-md5"; import { formatDistanceToNow, - isAfter, - intervalToDuration, formatDuration, + intlFormat, + intervalToDuration, + isAfter, } from "date-fns"; import yaml from "js-yaml"; @@ -44,6 +45,7 @@ import { DEFAULT_GRAVATAR_LINK_FALLBACK, DEFAULT_GRAVATAR_LINK_DARK, DEFAULT_GRAVATAR_LINK_DARK_FALLBACK, + INITIAL_FLEET_DATE, PLATFORM_LABEL_DISPLAY_TYPES, } from "utilities/constants"; import { IScheduledQueryStats } from "interfaces/scheduled_query_stats"; @@ -586,7 +588,7 @@ export const humanHostLastRestart = ( !detailUpdatedAt || !uptime || detailUpdatedAt === DEFAULT_EMPTY_CELL_VALUE || - detailUpdatedAt < "2016-07-28T00:00:00Z" || + detailUpdatedAt < INITIAL_FLEET_DATE || typeof uptime !== "number" ) { return "Unavailable"; @@ -613,7 +615,7 @@ export const humanHostLastRestart = ( }; export const humanHostLastSeen = (lastSeen: string): string => { - if (!lastSeen || lastSeen < "2016-07-28T00:00:00Z") { + if (!lastSeen || lastSeen < INITIAL_FLEET_DATE) { return "Never"; } if (lastSeen === "Unavailable") { @@ -623,7 +625,7 @@ export const humanHostLastSeen = (lastSeen: string): string => { }; export const humanHostEnrolled = (enrolled: string): string => { - if (!enrolled || enrolled < "2016-07-28T00:00:00Z") { + if (!enrolled || enrolled < INITIAL_FLEET_DATE) { return "Never"; } return formatDistanceToNow(new Date(enrolled), { addSuffix: true }); @@ -636,8 +638,7 @@ export const humanHostMemory = (bytes: number): 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 || detailUpdated < "2016-07-28T00:00:00Z") { + if (!detailUpdated || detailUpdated < INITIAL_FLEET_DATE) { return "unavailable"; } try { @@ -647,6 +648,33 @@ export const humanHostDetailUpdated = (detailUpdated?: string): string => { } }; +/** Unlike humanHost helper functions, there are no Fleet-related date restrictions */ +export const humanLastSeen = (lastSeen: string): string => { + if (!lastSeen) { + return "Never"; + } + if (lastSeen === "Unavailable") { + return "Unavailable"; + } + + return formatDistanceToNow(new Date(lastSeen), { addSuffix: true }); +}; + +export const internationalTimeFormat = (date: number | Date): string => { + return intlFormat( + date, + { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", + }, + { locale: window.navigator.languages[0] } + ); +}; + const MAC_WINDOWS_DISK_ENCRYPTION_MESSAGES = { darwin: { enabled: @@ -687,8 +715,7 @@ 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 || lastRun < "2016-07-28T00:00:00Z") { + if (!lastRun || lastRun < INITIAL_FLEET_DATE) { return "Has not run"; } @@ -893,6 +920,8 @@ export default { humanHostEnrolled, humanHostMemory, humanHostDetailUpdated, + humanLastSeen, + internationalTimeFormat, getHostDiskEncryptionTooltipMessage, hostTeamName, humanQueryLastRun,