diff --git a/changes/39987-clarify-not-supported-tooltips b/changes/39987-clarify-not-supported-tooltips
new file mode 100644
index 0000000000..08ae8c07fb
--- /dev/null
+++ b/changes/39987-clarify-not-supported-tooltips
@@ -0,0 +1,4 @@
+- Added tooltips to the "Agent", "Last restarted", and "Status" column headers on the Hosts page explaining which platforms are supported and why.
+- Fixed the "Last restarted" vital showing on ChromeOS hosts, where it's not actually collected.
+- Updated the "Last opened" tooltip on the Host details Software table to explain why it's only supported for native macOS, Windows, and Linux apps and packages.
+- Removed the `cellProps.rows.length === 1` workaround (which suppressed the tooltip whenever the table had exactly one row) by adding the correct CSS, which removes the tooltip overflowing if the host table is only 1 row.
diff --git a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx
index 677e3b622c..0a2ad02a7e 100644
--- a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx
@@ -397,26 +397,23 @@ const allHostTableHeaders = (teamId?: number): IHostTableColumnConfig[] => [
// Status
{
title: "Status",
- Header: (cellProps: IHostTableHeaderProps) => {
+ Header: () => {
const titleWithToolTip = (
- Online hosts will respond to a live report. Currently only
- supported for macOS, Windows, and Linux.
+ Only supported on hosts that run Fleet's agent: macOS,
+ Windows, Linux, and ChromeOS.
>
}
className="status-header"
+ tooltipClass="host-table-header-tooltip"
+ fixedPositionStrategy
>
Status
);
- return (
-
- );
+ return ;
},
disableSortBy: true,
accessor: "status",
@@ -592,9 +589,23 @@ const allHostTableHeaders = (teamId?: number): IHostTableColumnConfig[] => [
// Agent
{
title: "Agent",
- Header: (cellProps: IHostTableHeaderProps) => (
-
- ),
+ Header: (cellProps: IHostTableHeaderProps) => {
+ const titleWithToolTip = (
+
+ Agent
+
+ );
+ return (
+
+ );
+ },
accessor: (row) => row.orbit_version || row.osquery_version,
id: "agent",
Cell: (cellProps: IHostTableStringCellProps) => {
@@ -686,12 +697,23 @@ const allHostTableHeaders = (teamId?: number): IHostTableColumnConfig[] => [
// Last restarted
{
title: "Last restarted",
- Header: (cellProps: IHostTableHeaderProps) => (
-
- ),
+ Header: (cellProps: IHostTableHeaderProps) => {
+ const titleWithToolTip = (
+
+ Last restarted
+
+ );
+ return (
+
+ );
+ },
accessor: "last_restarted_at",
id: "last_restarted_at",
Cell: (cellProps: IHostTableStringCellProps) => {
diff --git a/frontend/pages/hosts/ManageHostsPage/_styles.scss b/frontend/pages/hosts/ManageHostsPage/_styles.scss
index fa50d2cdab..049b5f6fd7 100644
--- a/frontend/pages/hosts/ManageHostsPage/_styles.scss
+++ b/frontend/pages/hosts/ManageHostsPage/_styles.scss
@@ -251,3 +251,9 @@
padding-bottom: $pad-large;
}
}
+
+// The tooltip renders in a portal outside .manage-hosts, so this can't be
+// nested under that selector.
+.host-table-header-tooltip {
+ text-align: left;
+}
diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx
index 69e1e1ba9a..5945428274 100644
--- a/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx
+++ b/frontend/pages/hosts/details/cards/Software/HostSoftware.tsx
@@ -305,9 +305,8 @@ const HostSoftware = ({
router,
teamId: hostTeamId,
onShowInventoryVersions,
- platform,
});
- }, [isMyDevicePage, router, hostTeamId, onShowInventoryVersions, platform]);
+ }, [isMyDevicePage, router, hostTeamId, onShowInventoryVersions]);
const isLoading = isMyDevicePage
? deviceSoftwareLoading
diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx
index c7e27a2891..a5cb2f2649 100644
--- a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx
+++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tests.tsx
@@ -13,7 +13,6 @@ describe("HostSoftwareTableConfig - Last opened column", () => {
router: mockRouter,
teamId: 1,
onShowInventoryVersions: noop,
- platform: "windows",
});
const lastOpenedColumn = headers.find((h) => h.id === "Last opened") as any;
diff --git a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx
index ab2ae305a7..e5b09ea873 100644
--- a/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx
+++ b/frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx
@@ -7,13 +7,6 @@ import {
IHostSoftware,
isIpadOrIphoneSoftwareSource,
} from "interfaces/software";
-import {
- HostPlatform,
- isIPadOrIPhone,
- isLinuxLike,
- isMacOS,
- isWindows,
-} from "interfaces/platform";
import { IHeaderProps, IStringCellProps } from "interfaces/datatable_config";
import PATHS from "router/paths";
@@ -47,7 +40,6 @@ interface ISoftwareTableHeadersProps {
router: InjectedRouter;
teamId: number;
onShowInventoryVersions: (software: IHostSoftware) => void;
- platform: HostPlatform;
}
// NOTE: cellProps come from react-table
@@ -56,7 +48,6 @@ export const generateSoftwareTableHeaders = ({
router,
teamId,
onShowInventoryVersions,
- platform,
}: ISoftwareTableHeadersProps): ISoftwareTableConfig[] => {
const tableHeaders: ISoftwareTableConfig[] = [
{
@@ -132,24 +123,18 @@ export const generateSoftwareTableHeaders = ({
},
{
Header: (): JSX.Element => {
- let tooltipContent = <>>;
-
- if (isMacOS(platform)) {
- tooltipContent = (
- <>When the version installed most recently was last opened.>
- );
- } else if (isLinuxLike(platform) || isWindows(platform)) {
- tooltipContent = <>When any version was last opened.>;
- } else if (isIPadOrIPhone(platform)) {
- tooltipContent = <>Date and time of last open.>;
- }
-
- const lastOpenedHeader = tooltipContent ? (
-
+ const lastOpenedHeader = (
+
+ Only supported for macOS, Windows, and Linux native apps and
+ packages. Browser extensions, other package managers, and mobile
+ apps don't report this information.
+ >
+ }
+ >
Last opened
- ) : (
- "Last opened"
);
return ;
},
diff --git a/frontend/pages/hosts/details/cards/Vitals/Vitals.tests.tsx b/frontend/pages/hosts/details/cards/Vitals/Vitals.tests.tsx
index ca1fc88f57..f3125aed96 100644
--- a/frontend/pages/hosts/details/cards/Vitals/Vitals.tests.tsx
+++ b/frontend/pages/hosts/details/cards/Vitals/Vitals.tests.tsx
@@ -4,6 +4,7 @@ import { createCustomRenderer } from "test/test-utils";
import createMockHost, { createMockHostGeolocation } from "__mocks__/hostMock";
import { createMockHostMdmData } from "__mocks__/mdmMock";
+import { HostPlatform } from "interfaces/platform";
import { DEFAULT_EMPTY_CELL_VALUE } from "utilities/constants";
import Vitals from "./Vitals";
@@ -578,6 +579,47 @@ describe("Agent data", () => {
});
});
+describe("Last restarted vital", () => {
+ it.each(["darwin", "windows", "ubuntu"])(
+ "renders Last restarted for supported platform: %s",
+ (platform) => {
+ const mockHost = createMockHost({
+ platform: platform as HostPlatform,
+ last_restarted_at: "2023-01-01T00:00:00Z",
+ });
+
+ render();
+
+ expect(screen.getByText("Last restarted")).toBeInTheDocument();
+ }
+ );
+
+ it.each(["chrome", "ios", "ipados", "android"])(
+ "does not render Last restarted for unsupported platform: %s",
+ (platform) => {
+ const mockHost = createMockHost({
+ platform: platform as HostPlatform,
+ last_restarted_at: "2023-01-01T00:00:00Z",
+ });
+
+ render();
+
+ expect(screen.queryByText("Last restarted")).not.toBeInTheDocument();
+ }
+ );
+});
+
+describe("Munki version vital", () => {
+ it("renders the Munki version vital when its value is a normal version string", () => {
+ const mockHost = createMockHost({ platform: "darwin" });
+
+ render();
+
+ expect(screen.getByText("Munki version")).toBeInTheDocument();
+ expect(screen.getByText("5.5.1")).toBeInTheDocument();
+ });
+});
+
describe("Disk space field visibility", () => {
it("hides disk space field when storage measurement is not supported (sentinel value -1)", () => {
const mockHost = createMockHost({
diff --git a/frontend/pages/hosts/details/cards/Vitals/Vitals.tsx b/frontend/pages/hosts/details/cards/Vitals/Vitals.tsx
index 24ef40b03d..8bd898dbf0 100644
--- a/frontend/pages/hosts/details/cards/Vitals/Vitals.tsx
+++ b/frontend/pages/hosts/details/cards/Vitals/Vitals.tsx
@@ -371,7 +371,7 @@ const Vitals = ({
});
// Last restarted
- if (!isIosOrIpadosHost && !isAndroidHost) {
+ if (!isIosOrIpadosHost && !isAndroidHost && !isChromeHost) {
vitals.push({
sortKey: "Last restarted",
element: (