From d0ab80ac924f35961e1ab7725d191a6241a4c49d Mon Sep 17 00:00:00 2001
From: gillespi314 <73313222+gillespi314@users.noreply.github.com>
Date: Mon, 12 Jun 2023 11:47:31 -0500
Subject: [PATCH] Revise UI for manage hosts empty state (#12285)
---
.../hosts/ManageHostsPage/HostsPageConfig.tsx | 28 +++++++
.../hosts/ManageHostsPage/ManageHostsPage.tsx | 76 ++++++++-----------
2 files changed, 58 insertions(+), 46 deletions(-)
diff --git a/frontend/pages/hosts/ManageHostsPage/HostsPageConfig.tsx b/frontend/pages/hosts/ManageHostsPage/HostsPageConfig.tsx
index 4641c16488..2fbaac795a 100644
--- a/frontend/pages/hosts/ManageHostsPage/HostsPageConfig.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/HostsPageConfig.tsx
@@ -2,6 +2,34 @@ import React from "react";
import Icon from "components/Icon";
+export const MANAGE_HOSTS_PAGE_FILTER_KEYS = [
+ "query",
+ "team_id",
+ "policy_id",
+ "policy_response",
+ "macos_settings",
+ "software_id",
+ "status",
+ "mdm_id",
+ "mdm_enrollment_status",
+ "os_id",
+ "os_name",
+ "os_version",
+ "munki_issue_id",
+ "low_disk_space",
+ "macos_settings_disk_encryption",
+ "bootstrap_package",
+] as const;
+
+// TODO: refactor to use this type as the location.query prop of the page
+export type ManageHostsPageQueryParams = Record<
+ | "page"
+ | "order_key"
+ | "order_direction"
+ | typeof MANAGE_HOSTS_PAGE_FILTER_KEYS[number],
+ string
+>;
+
export const LABEL_SLUG_PREFIX = "labels/";
export const DEFAULT_SORT_HEADER = "display_name";
diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
index b8718cd349..87df67a5bc 100644
--- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
@@ -83,6 +83,8 @@ import {
DEFAULT_PAGE_SIZE,
DEFAULT_PAGE_INDEX,
getHostSelectStatuses,
+ MANAGE_HOSTS_PAGE_FILTER_KEYS,
+ ManageHostsPageQueryParams,
} from "./HostsPageConfig";
import { isAcceptableStatus } from "./helpers";
@@ -1304,6 +1306,17 @@ const ManageHostsPage = ({
);
};
+ // TODO: try to reduce overlap between maybeEmptyHosts and includesFilterQueryParam
+ const maybeEmptyHosts =
+ hostsCount === 0 && searchQuery === "" && !labelID && !status;
+
+ const includesFilterQueryParam = MANAGE_HOSTS_PAGE_FILTER_KEYS.some(
+ (filter) =>
+ filter !== "team_id" &&
+ typeof queryParams === "object" &&
+ filter in queryParams // TODO: replace this with `Object.hasOwn(queryParams, filter)` when we upgrade to es2022
+ );
+
const renderTable = () => {
if (!config || !currentUser || !isRouteOk) {
return ;
@@ -1312,27 +1325,7 @@ const ManageHostsPage = ({
if (hasErrors) {
return ;
}
-
- // There are no hosts for this instance yet
- if (hostsCount === 0 && searchQuery === "" && !labelID && !status) {
- const {
- software_id,
- policy_id,
- mdm_id,
- mdm_enrollment_status,
- low_disk_space,
- } = queryParams || {};
- const includesNameCardFilter = !!(
- software_id ||
- policy_id ||
- mdm_id ||
- mdm_enrollment_status ||
- low_disk_space ||
- osId ||
- osName ||
- osVersion
- );
-
+ if (maybeEmptyHosts) {
const emptyState = () => {
const emptyHosts: IEmptyTableProps = {
iconName: "empty-hosts",
@@ -1340,13 +1333,12 @@ const ManageHostsPage = ({
info:
"Expecting to see devices? Try again in a few seconds as the system catches up.",
};
- if (includesNameCardFilter) {
+ if (includesFilterQueryParam) {
delete emptyHosts.iconName;
emptyHosts.header = "No hosts match the current criteria";
emptyHosts.info =
"Expecting to see new hosts? Try again in a few seconds as the system catches up.";
- }
- if (canEnrollHosts) {
+ } else if (canEnrollHosts) {
emptyHosts.header = "Add your devices to Fleet";
emptyHosts.info = "Generate an installer to add your own devices.";
emptyHosts.primaryButton = (
@@ -1396,12 +1388,6 @@ const ManageHostsPage = ({
});
tableColumns[tableColumns.length - 1].isLastColumn = true;
- // Update last column
- tableColumns.forEach((dataColumn) => {
- dataColumn.isLastColumn = false;
- });
- tableColumns[tableColumns.length - 1].isLastColumn = true;
-
const emptyState = () => {
const emptyHosts: IEmptyTableProps = {
header: "No hosts match the current criteria",
@@ -1503,6 +1489,11 @@ const ManageHostsPage = ({
);
};
+ const showAddHostsButton =
+ canEnrollHosts &&
+ !hasErrors &&
+ (!maybeEmptyHosts || includesFilterQueryParam);
+
return (
<>
@@ -1519,22 +1510,15 @@ const ManageHostsPage = ({
Manage enroll secret
)}
- {canEnrollHosts &&
- !hasErrors &&
- !(
- !status &&
- hostsCount === 0 &&
- searchQuery === "" &&
- !labelID
- ) && (
-
- )}
+ {showAddHostsButton && (
+
+ )}
{/* TODO: look at improving the props API for this component. Im thinking