mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 21:47:20 +00:00
751 lines
21 KiB
TypeScript
751 lines
21 KiB
TypeScript
/* eslint-disable react/prop-types */
|
|
// disable this rule as it was throwing an error in Header and Cell component
|
|
// definitions for the selection row for some reason when we dont really need it.
|
|
import React from "react";
|
|
import { CellProps, Column } from "react-table";
|
|
import ReactTooltip from "react-tooltip";
|
|
|
|
import { IDeviceUser, IHost } from "interfaces/host";
|
|
import {
|
|
isAndroid,
|
|
isAppleDevice,
|
|
isMobilePlatform,
|
|
} from "interfaces/platform";
|
|
import { isBYODAccountDrivenUserEnrollment } from "interfaces/mdm";
|
|
import { ROLLING_ARCH_LINUX_VERSIONS } from "interfaces/software";
|
|
|
|
import TooltipWrapperArchLinuxRolling from "components/TooltipWrapperArchLinuxRolling";
|
|
import Checkbox from "components/forms/fields/Checkbox";
|
|
import DiskSpaceIndicator from "pages/hosts/components/DiskSpaceIndicator";
|
|
import HeaderCell from "components/TableContainer/DataTable/HeaderCell/HeaderCell";
|
|
import HostMdmStatusCell from "components/TableContainer/DataTable/HostMdmStatusCell/HostMdmStatusCell";
|
|
import IssueCell from "components/TableContainer/DataTable/IssueCell/IssueCell";
|
|
import LinkCell from "components/TableContainer/DataTable/LinkCell/LinkCell";
|
|
import StatusIndicator from "components/StatusIndicator";
|
|
import TextCell from "components/TableContainer/DataTable/TextCell/TextCell";
|
|
import TooltipTruncatedTextCell from "components/TableContainer/DataTable/TooltipTruncatedTextCell";
|
|
import TooltipWrapper from "components/TooltipWrapper";
|
|
import { HumanTimeDiffWithFleetLaunchCutoff } from "components/HumanTimeDiffWithDateTip";
|
|
import NotSupported from "components/NotSupported";
|
|
|
|
import {
|
|
humanHostMemory,
|
|
humanHostLastSeen,
|
|
hostTeamName,
|
|
tooltipTextWithLineBreaks,
|
|
} from "utilities/helpers";
|
|
import { COLORS } from "styles/var/colors";
|
|
import {
|
|
IHeaderProps,
|
|
IStringCellProps,
|
|
INumberCellProps,
|
|
} from "interfaces/datatable_config";
|
|
import PATHS from "router/paths";
|
|
import { DEFAULT_EMPTY_CELL_VALUE } from "utilities/constants";
|
|
import { getHostStatusTooltipText } from "../helpers";
|
|
|
|
type IHostTableColumnConfig = Column<IHost> & {
|
|
// This is used to prevent these columns from being hidden. This will be
|
|
// used in EditColumnsModal to prevent these columns from being hidden.
|
|
disableHidden?: boolean;
|
|
// We add title in the column config to be able to use it in the EditColumnsModal
|
|
// as well
|
|
title?: string;
|
|
};
|
|
|
|
type IHostTableHeaderProps = IHeaderProps<IHost>;
|
|
type IHostTableStringCellProps = IStringCellProps<IHost>;
|
|
type IHostTableNumberCellProps = INumberCellProps<IHost>;
|
|
type ISelectionCellProps = CellProps<IHost>;
|
|
type IIssuesCellProps = CellProps<IHost, IHost["issues"]>;
|
|
type IDeviceUserCellProps = CellProps<IHost, IHost["device_mapping"]>;
|
|
|
|
const condenseDeviceUsers = (users: IDeviceUser[]): string[] => {
|
|
if (!users?.length) {
|
|
return [];
|
|
}
|
|
const condensed =
|
|
users.length === 4
|
|
? users
|
|
.slice(-4)
|
|
|
|
.map((u) => u.email)
|
|
.reverse()
|
|
: users
|
|
.slice(-3)
|
|
.map((u) => u.email)
|
|
.reverse() || [];
|
|
return users.length > 4
|
|
? condensed.concat(`+${users.length - 3} more`) // TODO: confirm limit
|
|
: condensed;
|
|
};
|
|
|
|
const lastSeenTime = (status: string, seenTime: string): string => {
|
|
if (status !== "online") {
|
|
return `Last seen: ${humanHostLastSeen(seenTime)}`;
|
|
}
|
|
return "Online";
|
|
};
|
|
|
|
const allHostTableHeaders = (teamId?: number): IHostTableColumnConfig[] => [
|
|
// We are using React Table useRowSelect functionality for the selection header.
|
|
// More information on its API can be found here
|
|
// https://react-table.tanstack.com/docs/api/useRowSelect
|
|
{
|
|
id: "selection",
|
|
Header: (cellProps: IHostTableHeaderProps) => {
|
|
const props = cellProps.getToggleAllRowsSelectedProps();
|
|
const checkboxProps = {
|
|
value: props.checked,
|
|
indeterminate: props.indeterminate,
|
|
onChange: () => cellProps.toggleAllRowsSelected(),
|
|
};
|
|
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
|
},
|
|
Cell: (cellProps: ISelectionCellProps) => {
|
|
const props = cellProps.row.getToggleRowSelectedProps();
|
|
const checkboxProps = {
|
|
value: props.checked,
|
|
onChange: () => cellProps.row.toggleRowSelected(),
|
|
};
|
|
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
|
},
|
|
disableHidden: true,
|
|
},
|
|
{
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell value="Host" isSortedDesc={cellProps.column.isSortedDesc} />
|
|
),
|
|
accessor: "display_name",
|
|
id: "display_name",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
return (
|
|
<LinkCell
|
|
value={cellProps.cell.value}
|
|
path={PATHS.HOST_DETAILS(cellProps.row.original.id, teamId)}
|
|
title={lastSeenTime(
|
|
cellProps.row.original.status,
|
|
cellProps.row.original.seen_time
|
|
)}
|
|
/>
|
|
);
|
|
},
|
|
disableHidden: true,
|
|
},
|
|
// Fleet
|
|
{
|
|
title: "Fleet",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell value="Fleet" isSortedDesc={cellProps.column.isSortedDesc} />
|
|
),
|
|
accessor: "team_name",
|
|
id: "team_name",
|
|
Cell: (cellProps) => (
|
|
<TextCell value={cellProps.cell.value} formatter={hostTeamName} />
|
|
),
|
|
},
|
|
// Operating system (OS)
|
|
{
|
|
title: "Operating system",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Operating system"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "os_version",
|
|
id: "os_version",
|
|
// TODO(android): is Android supported? what about the os versions endpoint and dashboard card?
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
const os_version = cellProps.cell.value;
|
|
const versionForRender = ROLLING_ARCH_LINUX_VERSIONS.includes(
|
|
os_version
|
|
) ? (
|
|
// wrap a tooltip around the "rolling" suffix
|
|
<>
|
|
{os_version.slice(0, -8)}
|
|
<TooltipWrapperArchLinuxRolling />
|
|
</>
|
|
) : (
|
|
os_version
|
|
);
|
|
return <TooltipTruncatedTextCell value={versionForRender} />;
|
|
},
|
|
},
|
|
// Hardware model
|
|
{
|
|
title: "Hardware model",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Hardware model"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "hardware_model",
|
|
id: "hardware_model",
|
|
Cell: (cellProps: IHostTableStringCellProps) => (
|
|
<TextCell value={cellProps.cell.value} />
|
|
),
|
|
},
|
|
// User email
|
|
{
|
|
title: "User email",
|
|
Header: "User email",
|
|
disableSortBy: true,
|
|
accessor: "device_mapping",
|
|
id: "device_mapping",
|
|
Cell: (cellProps: IDeviceUserCellProps) => {
|
|
// TODO(android): is android supported?
|
|
const numUsers = cellProps.cell.value?.length || 0;
|
|
const users = condenseDeviceUsers(cellProps.cell.value || []);
|
|
if (users.length > 1) {
|
|
return (
|
|
<TooltipWrapper
|
|
tipContent={tooltipTextWithLineBreaks(users)}
|
|
underline={false}
|
|
showArrow
|
|
position="top"
|
|
tipOffset={10}
|
|
>
|
|
<TextCell italic value={`${numUsers} users`} />
|
|
</TooltipWrapper>
|
|
);
|
|
}
|
|
if (users.length === 1) {
|
|
return <TextCell value={users[0]} />;
|
|
}
|
|
return <TextCell />;
|
|
},
|
|
},
|
|
// UUID
|
|
{
|
|
title: "UUID",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell value="UUID" isSortedDesc={cellProps.column.isSortedDesc} />
|
|
),
|
|
accessor: "uuid",
|
|
id: "uuid",
|
|
Cell: ({ cell: { value } }: IHostTableStringCellProps) =>
|
|
value ? <TooltipTruncatedTextCell value={value} /> : <TextCell />,
|
|
},
|
|
// Serial number
|
|
{
|
|
title: "Serial number",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Serial number"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "hardware_serial",
|
|
id: "hardware_serial",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
// TODO(android): is iOS/iPadOS supported?
|
|
if (
|
|
isAndroid(cellProps.row.original.platform) ||
|
|
isBYODAccountDrivenUserEnrollment(
|
|
cellProps.row.original.mdm.enrollment_status
|
|
)
|
|
) {
|
|
return NotSupported;
|
|
}
|
|
return <TextCell value={cellProps.cell.value} />;
|
|
},
|
|
},
|
|
// Last fetched
|
|
{
|
|
title: "Last fetched",
|
|
Header: (cellProps: IHostTableHeaderProps) => {
|
|
const titleWithToolTip = (
|
|
<TooltipWrapper
|
|
tipContent={
|
|
<>
|
|
The last time the host
|
|
<br /> reported vitals.
|
|
</>
|
|
}
|
|
>
|
|
Last fetched
|
|
</TooltipWrapper>
|
|
);
|
|
return (
|
|
<HeaderCell
|
|
value={titleWithToolTip}
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
);
|
|
},
|
|
accessor: "detail_updated_at",
|
|
id: "detail_updated_at",
|
|
Cell: (cellProps: IHostTableStringCellProps) => (
|
|
// TODO(android): android doesn't support refetch?
|
|
<TextCell
|
|
value={{ timeString: cellProps.cell.value }}
|
|
formatter={HumanTimeDiffWithFleetLaunchCutoff}
|
|
/>
|
|
),
|
|
},
|
|
// Disk space available
|
|
{
|
|
title: "Disk space available",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Disk space available"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "gigs_disk_space_available",
|
|
id: "gigs_disk_space_available",
|
|
Cell: (cellProps: IHostTableNumberCellProps) => {
|
|
const {
|
|
platform,
|
|
percent_disk_space_available,
|
|
gigs_disk_space_available,
|
|
gigs_total_disk_space,
|
|
gigs_all_disk_space,
|
|
} = cellProps.row.original;
|
|
if (platform === "chrome") {
|
|
return NotSupported;
|
|
}
|
|
return (
|
|
<DiskSpaceIndicator
|
|
gigsDiskSpaceAvailable={gigs_disk_space_available}
|
|
percentDiskSpaceAvailable={percent_disk_space_available}
|
|
gigsTotalDiskSpace={gigs_total_disk_space}
|
|
gigsAllDiskSpace={gigs_all_disk_space}
|
|
platform={platform}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
// CPU
|
|
{
|
|
title: "CPU",
|
|
Header: "CPU",
|
|
disableSortBy: true,
|
|
accessor: "cpu_type",
|
|
id: "cpu_type",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
if (
|
|
cellProps.row.original.platform === "ios" ||
|
|
cellProps.row.original.platform === "ipados"
|
|
) {
|
|
return NotSupported;
|
|
}
|
|
return <TextCell value={cellProps.cell.value} />;
|
|
},
|
|
},
|
|
// RAM
|
|
{
|
|
title: "RAM",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell value="RAM" isSortedDesc={cellProps.column.isSortedDesc} />
|
|
),
|
|
accessor: "memory",
|
|
id: "memory",
|
|
Cell: (cellProps: IHostTableNumberCellProps) => {
|
|
if (
|
|
cellProps.row.original.platform === "ios" ||
|
|
cellProps.row.original.platform === "ipados"
|
|
) {
|
|
return NotSupported;
|
|
}
|
|
return (
|
|
<TextCell value={cellProps.cell.value} formatter={humanHostMemory} />
|
|
);
|
|
},
|
|
},
|
|
// MAC address
|
|
{
|
|
title: "MAC address",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="MAC address"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "primary_mac",
|
|
id: "primary_mac",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
// TODO(android): is iOS/iPadOS supported?
|
|
if (isAndroid(cellProps.row.original.platform)) {
|
|
return NotSupported;
|
|
}
|
|
return <TextCell value={cellProps.cell.value} />;
|
|
},
|
|
},
|
|
// Status
|
|
{
|
|
title: "Status",
|
|
Header: (cellProps: IHostTableHeaderProps) => {
|
|
const titleWithToolTip = (
|
|
<TooltipWrapper
|
|
tipContent={
|
|
<>
|
|
Online hosts will respond to a live report. Currently only
|
|
supported for macOS, Windows, and Linux.
|
|
</>
|
|
}
|
|
className="status-header"
|
|
>
|
|
Status
|
|
</TooltipWrapper>
|
|
);
|
|
return (
|
|
<HeaderCell
|
|
value={cellProps.rows.length === 1 ? "Status" : titleWithToolTip}
|
|
disableSortBy
|
|
/>
|
|
);
|
|
},
|
|
disableSortBy: true,
|
|
accessor: "status",
|
|
id: "status",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
if (isMobilePlatform(cellProps.row.original.platform)) {
|
|
return NotSupported;
|
|
}
|
|
|
|
// Show "---" for ABM devices with Pending enrollment status
|
|
if (
|
|
cellProps.row.original.mdm?.enrollment_status === "Pending" &&
|
|
isAppleDevice(cellProps.row.original.platform)
|
|
) {
|
|
const tooltip = {
|
|
tooltipText: getHostStatusTooltipText(DEFAULT_EMPTY_CELL_VALUE),
|
|
};
|
|
return (
|
|
<StatusIndicator value={DEFAULT_EMPTY_CELL_VALUE} tooltip={tooltip} />
|
|
);
|
|
}
|
|
|
|
const value = cellProps.cell.value;
|
|
const tooltip = {
|
|
tooltipText: getHostStatusTooltipText(value),
|
|
};
|
|
return <StatusIndicator value={value} tooltip={tooltip} />;
|
|
},
|
|
},
|
|
// Issues
|
|
{
|
|
title: "Issues",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell value="Issues" isSortedDesc={cellProps.column.isSortedDesc} />
|
|
),
|
|
accessor: "issues",
|
|
id: "issues",
|
|
sortDescFirst: true,
|
|
Cell: (cellProps: IIssuesCellProps) => {
|
|
if (isMobilePlatform(cellProps.row.original.platform)) {
|
|
return NotSupported;
|
|
}
|
|
return (
|
|
<IssueCell
|
|
issues={cellProps.row.original.issues}
|
|
rowId={cellProps.row.original.id}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
// MDM status
|
|
{
|
|
title: "MDM status",
|
|
Header: () => {
|
|
const titleWithToolTip = (
|
|
<TooltipWrapper
|
|
tipContent={
|
|
<>
|
|
Settings can be updated remotely on hosts with MDM turned
|
|
<br />
|
|
on. To filter by MDM status, head to the Dashboard page.
|
|
</>
|
|
}
|
|
>
|
|
MDM status
|
|
</TooltipWrapper>
|
|
);
|
|
return <HeaderCell value={titleWithToolTip} disableSortBy />;
|
|
},
|
|
disableSortBy: true,
|
|
accessor: (originalRow) => originalRow.mdm.enrollment_status,
|
|
id: "mdm.enrollment_status",
|
|
Cell: HostMdmStatusCell,
|
|
},
|
|
// MDM server URL
|
|
{
|
|
title: "MDM server URL",
|
|
Header: () => {
|
|
const titleWithToolTip = (
|
|
<TooltipWrapper
|
|
tipContent={
|
|
<>
|
|
The MDM server that updates settings on the host. To
|
|
<br />
|
|
filter by MDM server URL, head to the Dashboard page.
|
|
</>
|
|
}
|
|
>
|
|
MDM server URL
|
|
</TooltipWrapper>
|
|
);
|
|
return <HeaderCell value={titleWithToolTip} disableSortBy />;
|
|
},
|
|
disableSortBy: true,
|
|
accessor: (originalRow) => originalRow.mdm.server_url,
|
|
id: "mdm.server_url",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
if (cellProps.row.original.platform === "chrome") {
|
|
return NotSupported;
|
|
}
|
|
if (cellProps.cell.value) {
|
|
return <TooltipTruncatedTextCell value={cellProps.cell.value} />;
|
|
}
|
|
return <span className="text-muted">{DEFAULT_EMPTY_CELL_VALUE}</span>;
|
|
},
|
|
},
|
|
// Hostname
|
|
{
|
|
title: "Hostname",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Hostname"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "hostname",
|
|
id: "hostname",
|
|
Cell: (cellProps: IHostTableStringCellProps) => (
|
|
<TooltipTruncatedTextCell value={cellProps.cell.value} />
|
|
),
|
|
},
|
|
// Computer name
|
|
{
|
|
title: "Computer name",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Computer name"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "computer_name",
|
|
id: "computer_name",
|
|
Cell: (cellProps: IHostTableStringCellProps) => (
|
|
<TextCell value={cellProps.cell.value} />
|
|
),
|
|
},
|
|
// Private IP address
|
|
{
|
|
title: "Private IP address",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Private IP address"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "primary_ip",
|
|
id: "primary_ip",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
if (isMobilePlatform(cellProps.row.original.platform)) {
|
|
return NotSupported;
|
|
}
|
|
return <TextCell value={cellProps.cell.value} />;
|
|
},
|
|
},
|
|
// Public IP address
|
|
{
|
|
title: "Public IP address",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value={
|
|
<TooltipWrapper tipContent="The IP address the host uses to connect to Fleet.">
|
|
Public IP address
|
|
</TooltipWrapper>
|
|
}
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "public_ip",
|
|
id: "public_ip",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
if (isMobilePlatform(cellProps.row.original.platform)) {
|
|
return NotSupported;
|
|
}
|
|
return (
|
|
<TextCell value={cellProps.cell.value ?? DEFAULT_EMPTY_CELL_VALUE} />
|
|
);
|
|
},
|
|
},
|
|
// Osquery
|
|
{
|
|
title: "Osquery",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Osquery"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "osquery_version",
|
|
id: "osquery_version",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
if (isMobilePlatform(cellProps.row.original.platform)) {
|
|
return NotSupported;
|
|
}
|
|
return <TextCell value={cellProps.cell.value} />;
|
|
},
|
|
},
|
|
// Last seen
|
|
{
|
|
title: "Last seen",
|
|
Header: (cellProps: IHostTableHeaderProps) => {
|
|
const titleWithToolTip = (
|
|
<TooltipWrapper
|
|
tipContent={
|
|
<>
|
|
The last time the <br />
|
|
host was online.
|
|
</>
|
|
}
|
|
>
|
|
Last seen
|
|
</TooltipWrapper>
|
|
);
|
|
return (
|
|
<HeaderCell
|
|
value={titleWithToolTip}
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
);
|
|
},
|
|
accessor: "seen_time",
|
|
id: "seen_time",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
if (isMobilePlatform(cellProps.row.original.platform)) {
|
|
return NotSupported;
|
|
}
|
|
return (
|
|
<TextCell
|
|
value={{ timeString: cellProps.cell.value }}
|
|
formatter={HumanTimeDiffWithFleetLaunchCutoff}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
// Last restarted
|
|
{
|
|
title: "Last restarted",
|
|
Header: (cellProps: IHostTableHeaderProps) => (
|
|
<HeaderCell
|
|
value="Last restarted"
|
|
isSortedDesc={cellProps.column.isSortedDesc}
|
|
/>
|
|
),
|
|
accessor: "last_restarted_at",
|
|
id: "last_restarted_at",
|
|
Cell: (cellProps: IHostTableStringCellProps) => {
|
|
const { platform, last_restarted_at } = cellProps.row.original;
|
|
|
|
if (isMobilePlatform(platform) || platform === "chrome") {
|
|
return NotSupported;
|
|
}
|
|
return (
|
|
<TextCell
|
|
value={{
|
|
timeString: last_restarted_at,
|
|
}}
|
|
formatter={HumanTimeDiffWithFleetLaunchCutoff}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
];
|
|
|
|
const defaultHiddenColumns = [
|
|
"hostname",
|
|
"computer_name",
|
|
"device_mapping",
|
|
"primary_mac",
|
|
"public_ip",
|
|
"cpu_type",
|
|
// TODO: should those be mdm.<blah>?
|
|
"mdm.server_url",
|
|
"mdm.enrollment_status",
|
|
"memory",
|
|
"uptime",
|
|
"uuid",
|
|
"seen_time",
|
|
"hardware_model",
|
|
"hardware_serial",
|
|
];
|
|
|
|
/**
|
|
* Will generate a host table column configuration based off of the current user
|
|
* permissions and license tier of fleet they are on.
|
|
*/
|
|
const generateAvailableTableHeaders = ({
|
|
isFreeTier = true,
|
|
isOnlyObserver = true,
|
|
teamId,
|
|
}: {
|
|
isFreeTier: boolean | undefined;
|
|
isOnlyObserver: boolean | undefined;
|
|
teamId?: number;
|
|
}): IHostTableColumnConfig[] => {
|
|
return allHostTableHeaders(teamId).reduce(
|
|
(columns: Column<IHost>[], currentColumn: Column<IHost>) => {
|
|
// skip over column headers that are not shown in free observer tier
|
|
if (isFreeTier) {
|
|
if (
|
|
isOnlyObserver &&
|
|
["selection", "team_name"].includes(currentColumn.id || "")
|
|
) {
|
|
return columns;
|
|
// skip over column headers that are not shown in free admin/maintainer
|
|
}
|
|
if (
|
|
currentColumn.id === "team_name" ||
|
|
currentColumn.id === "mdm.server_url" ||
|
|
currentColumn.id === "mdm.enrollment_status"
|
|
) {
|
|
return columns;
|
|
}
|
|
} else if (isOnlyObserver && currentColumn.id === "selection") {
|
|
// In premium tier, we want to check user role to enable/disable select column
|
|
return columns;
|
|
}
|
|
|
|
columns.push(currentColumn);
|
|
return columns;
|
|
},
|
|
[]
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Will generate a host table column configuration that a user currently sees.
|
|
*/
|
|
const generateVisibleTableColumns = ({
|
|
hiddenColumns,
|
|
isFreeTier = true,
|
|
isOnlyObserver = true,
|
|
teamId,
|
|
}: {
|
|
hiddenColumns: string[];
|
|
isFreeTier: boolean | undefined;
|
|
isOnlyObserver: boolean | undefined;
|
|
teamId?: number;
|
|
}): IHostTableColumnConfig[] => {
|
|
// remove columns set as hidden by the user.
|
|
return generateAvailableTableHeaders({
|
|
isFreeTier,
|
|
isOnlyObserver,
|
|
teamId,
|
|
}).filter((column) => {
|
|
return !hiddenColumns.includes(column.id as string);
|
|
});
|
|
};
|
|
|
|
export {
|
|
defaultHiddenColumns,
|
|
generateAvailableTableHeaders,
|
|
generateVisibleTableColumns,
|
|
};
|