fleet/frontend/components/StatusIndicatorWithIcon/StatusIndicatorWithIcon.tsx
jacobshandling 9ab0eb2acd
UI: Update conditional access on a per-policy basis (#28658)
## For #28049 , #28610

- **Implement front end ability to enable or disable conditional access
on a per-policy basis**
- **Update policy status UI to include new "action required" state,
representing a failed policy on a host with conditional access enabled**
- Additional improvements

<img width="1624" alt="Screenshot 2025-04-29 at 1 32 33 PM"
src="https://github.com/user-attachments/assets/960b3348-b0e2-48b8-bcff-28f91f64fd01"
/>

<img width="1624" alt="Screenshot 2025-04-29 at 12 15 39 PM"
src="https://github.com/user-attachments/assets/b0e0cf1f-a693-4e0b-b18a-a44ee258975f"
/>

<img width="1624" alt="Screenshot 2025-04-29 at 12 15 49 PM"
src="https://github.com/user-attachments/assets/15f7bea1-7338-4997-93bf-8baeb308e3f0"
/>

<img width="1400" alt="updated policies table headers"
src="https://github.com/user-attachments/assets/164fd84a-a9ee-4dfe-8d73-b4e82e27edbc"
/>

- [x] Changes file added for user-visible changes in `changes/`
- [ ] Added/updated automated tests
- [x] A detailed QA plan exists on the associated ticket (if it isn't
there, work with the product group's QA engineer to add it)
- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2025-05-01 11:43:38 -07:00

85 lines
2 KiB
TypeScript

import React from "react";
import classnames from "classnames";
import { IconNames } from "components/icons";
import Icon from "components/Icon";
import TooltipWrapper from "components/TooltipWrapper";
const baseClass = "status-indicator-with-icon";
export type IndicatorStatus =
| "success"
| "successPartial"
| "pending"
| "pendingPartial"
| "error"
| "failure"
| "actionRequired";
interface IStatusIndicatorWithIconProps {
status: IndicatorStatus;
value: string;
tooltip?: {
tooltipText: string | JSX.Element;
position?: "top" | "bottom";
};
layout?: "horizontal" | "vertical";
className?: string;
/** Classname to add to the value text */
valueClassName?: string;
}
const statusIconNameMapping: Record<IndicatorStatus, IconNames> = {
success: "success",
successPartial: "success-outline",
pending: "pending",
pendingPartial: "pending-outline",
error: "error",
failure: "error-outline",
actionRequired: "error",
};
const StatusIndicatorWithIcon = ({
status,
value,
tooltip,
layout = "horizontal",
className,
valueClassName,
}: IStatusIndicatorWithIconProps) => {
const classNames = classnames(baseClass, className);
const valueClasses = classnames(`${baseClass}__value`, valueClassName, {
[`${baseClass}__value-vertical`]: layout === "vertical",
});
const valueContent = (
<span className={valueClasses}>
<Icon
name={statusIconNameMapping[status]}
color={status === "failure" ? "ui-fleet-black-50" : undefined}
/>
<span>{value}</span>
</span>
);
const indicatorContent = tooltip ? (
<TooltipWrapper
className={`${baseClass}__tooltip`}
tooltipClass="indicator-tip-text"
position="top"
tipContent={tooltip.tooltipText}
tipOffset={10}
showArrow
underline={false}
fixedPositionStrategy
>
{valueContent}
</TooltipWrapper>
) : (
<span>{valueContent}</span>
);
return <div className={classNames}>{indicatorContent}</div>;
};
export default StatusIndicatorWithIcon;