fleet/frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/InstallerStatusTable/InstallerStatusTableConfig.tsx
RachelElysia c9e66b221e
Frontend: Lint warning cleanup part 1 (#43411)
## Issue
- First batch of @iansltx 's work of cleaning up lint warnings #43387 

## Description
- Quick PR review and grabbed as many confirmed low-risk quick wins as I
could `git checkout lint-cleanup <file/path/1> <file/path/2>`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

This release contains internal code improvements with one minor UI
tweak:

* **Style**
* Dropdown menu background color adjusted for clearer contrast in action
lists
* **Refactor**
* Improved type safety across the codebase with stricter TypeScript
annotations
  * Removed unused imports and constants to reduce code clutter
* Enhanced React hook dependency arrays for more consistent component
behavior
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Rachel Perkins <rachel@Rachels-MacBook-Pro.local>
Co-authored-by: Ian Littman <iansltx@gmail.com>
2026-04-10 19:49:52 -05:00

252 lines
6.9 KiB
TypeScript

import React from "react";
import { ISoftwareTitleVersion } from "interfaces/software";
import PATHS from "router/paths";
import { getPathWithQueryParams } from "utilities/url";
import { generateResultsCountText } from "components/TableContainer/utilities/TableContainerUtils";
import LinkCell from "components/TableContainer/DataTable/LinkCell";
import TooltipWrapper from "components/TooltipWrapper";
import Icon from "components/Icon";
import HeaderCell from "components/TableContainer/DataTable/HeaderCell";
interface ISoftwareTitleDetailsTableConfigProps {
softwareId?: number;
teamId?: number;
baseClass?: string;
isScriptPackage?: boolean;
isAndroidPlayStoreApp?: boolean;
}
interface ICellProps {
cell: {
value: number;
};
row: {
original: ISoftwareTitleVersion;
};
}
interface IStatusDisplayOption {
displayName: string;
iconName: "success" | "pending-outline" | "error";
tooltip: (isAndroidPlayStoreApp?: boolean) => React.ReactNode;
}
// "pending" and "failed" each encompass both "_install" and "_uninstall" sub-statuses
type SoftwareInstallDisplayStatus = "installed" | "pending" | "failed";
type SoftwareScriptDisplayStatus =
| "ran_script"
| "pending_script"
| "failed_script";
const STATUS_DISPLAY_OPTIONS: Record<
SoftwareInstallDisplayStatus | SoftwareScriptDisplayStatus,
IStatusDisplayOption
> = {
installed: {
displayName: "Installed",
iconName: "success",
tooltip: (isAndroidPlayStoreApp) => {
return isAndroidPlayStoreApp ? null : (
<>
Software is installed on these hosts (install script finished
<br />
with exit code 0). Currently, if the software is uninstalled, the
<br />
&quot;Installed&quot; status won&apos;t be updated.
</>
);
},
},
pending: {
displayName: "Pending",
iconName: "pending-outline",
tooltip: (isAndroidPlayStoreApp) => {
return isAndroidPlayStoreApp ? (
<>
Software will be installed or configuration will
<br />
be applied the next time the host checks in.
</>
) : (
<>
Fleet is installing/uninstalling or will
<br />
do so when the host comes online.
</>
);
},
},
failed: {
displayName: "Failed",
iconName: "error",
tooltip: (isAndroidPlayStoreApp) => {
return isAndroidPlayStoreApp ? (
<>Software failed to install or configuration failed to apply.</>
) : (
<>
These hosts failed to install/uninstall software.
<br />
Click on a host to view error(s).
</>
);
},
},
ran_script: {
displayName: "Ran",
iconName: "success",
tooltip: () => (
<>
The script successfully
<br />
ran on these hosts.
</>
),
},
pending_script: {
displayName: "Pending",
iconName: "pending-outline",
tooltip: () => (
<>
Fleet is running the script or will do so
<br />
when the host comes online.
</>
),
},
failed_script: {
displayName: "Failed",
iconName: "error",
tooltip: () => (
<>
These hosts failed to run the script.
<br />
Click on a host to view error(s).
</>
),
},
};
const generateSoftwareTitleDetailsTableConfig = ({
softwareId,
teamId,
baseClass,
isScriptPackage,
isAndroidPlayStoreApp,
}: ISoftwareTitleDetailsTableConfigProps) => {
const tableHeaders = [
{
accessor: "installed",
disableSortBy: true,
title: isScriptPackage ? "Ran" : "Installed",
Header: () => {
const displayData = isScriptPackage
? STATUS_DISPLAY_OPTIONS.ran_script
: STATUS_DISPLAY_OPTIONS.installed;
const titleWithTooltip = (
<TooltipWrapper
position="top"
tipContent={displayData.tooltip(isAndroidPlayStoreApp)}
underline={false}
showArrow
tipOffset={10}
>
<div className={`${baseClass}__status-title`}>
<Icon name={displayData.iconName} />
<div>{displayData.displayName}</div>
</div>
</TooltipWrapper>
);
return <HeaderCell value={titleWithTooltip} disableSortBy />;
},
Cell: (cellProps: ICellProps) => {
return (
<LinkCell
value={generateResultsCountText("hosts", cellProps.cell.value)}
path={getPathWithQueryParams(PATHS.MANAGE_HOSTS, {
software_title_id: softwareId,
software_status: "installed",
fleet_id: teamId,
})}
/>
);
},
},
{
accessor: "pending",
disableSortBy: true,
title: "Pending",
Header: () => {
const displayData = isScriptPackage
? STATUS_DISPLAY_OPTIONS.pending_script
: STATUS_DISPLAY_OPTIONS.pending;
return (
<TooltipWrapper
position="top"
tipContent={displayData.tooltip(isAndroidPlayStoreApp)}
underline={false}
showArrow
tipOffset={10}
>
<div className={`${baseClass}__status-title`}>
<Icon name={displayData.iconName} />
<div>{displayData.displayName}</div>
</div>
</TooltipWrapper>
);
},
Cell: (cellProps: ICellProps) => {
return (
<LinkCell
value={generateResultsCountText("hosts", cellProps.cell.value)}
path={getPathWithQueryParams(PATHS.MANAGE_HOSTS, {
software_title_id: softwareId,
software_status: "pending",
fleet_id: teamId,
})}
/>
);
},
},
{
accessor: "failed",
disableSortBy: true,
title: "Failed",
Header: () => {
const displayData = isScriptPackage
? STATUS_DISPLAY_OPTIONS.failed_script
: STATUS_DISPLAY_OPTIONS.failed;
return (
<TooltipWrapper
position="top"
tipContent={displayData.tooltip(isAndroidPlayStoreApp)}
underline={false}
showArrow
tipOffset={10}
>
<div className={`${baseClass}__status-title`}>
<Icon name={displayData.iconName} />
<div>{displayData.displayName}</div>
</div>
</TooltipWrapper>
);
},
Cell: (cellProps: ICellProps) => {
return (
<LinkCell
value={generateResultsCountText("hosts", cellProps.cell.value)}
path={getPathWithQueryParams(PATHS.MANAGE_HOSTS, {
software_title_id: softwareId,
software_status: "failed",
fleet_id: teamId,
})}
/>
);
},
},
];
return tableHeaders;
};
export default generateSoftwareTitleDetailsTableConfig;