fleet/frontend/components/forms/FormField/FormField.tsx
RachelElysia 3dd1219a27
Fleet UI: Filter software/version tables by vulnerability score and exploitability (#21278)
## Issue
Story #19099 
Subtask #20706 

## Description
- Additions to Software > Software tab to filter software and versions
by vulnerable, known exploit, and CVSS score
- Includes a new "Add filters" button which has dynamic tooltip and
button text
- New responsive design to the table header controls
- New modal to customize vulnerability filters
- Handles edge case where user types in a custom CVSS score in URL

## TODO list
- [x] Design, confirm and build empty states
- [x] search bar is showing on empty state, fix this
- [x] Disabled state color for dropdown placeholder text
- [x] Add tests to the modal
- [ ] Test with API when API is ready (good flow to check, choose from
dropdown, then toggle versions on)

## Screen recording
TODO

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Added/updated tests
- [ ] Manual QA for all new/changed functionality
2024-08-20 09:41:49 -04:00

93 lines
2 KiB
TypeScript

import React from "react";
import classnames from "classnames";
import { isEmpty } from "lodash";
import TooltipWrapper from "components/TooltipWrapper";
import { PlacesType } from "react-tooltip-5";
// all form-field styles are defined in _global.scss, which apply here and elsewhere
const baseClass = "form-field";
export interface IFormFieldProps {
children: JSX.Element;
label: Array<any> | JSX.Element | string;
name: string;
helpText?: Array<any> | JSX.Element | string;
type?: string;
error?: string;
className?: string;
tooltip?: React.ReactNode;
labelTooltipPosition?: PlacesType;
disabled?: boolean;
}
const FormField = ({
children,
className,
error,
helpText,
label,
name,
type,
tooltip,
labelTooltipPosition,
disabled,
}: IFormFieldProps): JSX.Element => {
const renderLabel = () => {
const labelWrapperClasses = classnames(`${baseClass}__label`, {
[`${baseClass}__label--error`]: !isEmpty(error),
[`${baseClass}__label--disabled`]: disabled,
});
if (!label) {
return false;
}
return (
<label
className={labelWrapperClasses}
htmlFor={name}
data-has-tooltip={!!tooltip}
>
{error ||
(tooltip ? (
<TooltipWrapper
tipContent={tooltip}
position={labelTooltipPosition}
clickable={false} // Not block form behind tooltip
>
{label as string}
</TooltipWrapper>
) : (
<>{label}</>
))}
</label>
);
};
const renderHelpText = () => {
if (helpText) {
return <span className={`${baseClass}__help-text`}>{helpText}</span>;
}
return false;
};
const formFieldClass = classnames(
baseClass,
{
[`${baseClass}--${type}`]: !isEmpty(type),
},
className
);
return (
<div className={formFieldClass}>
{renderLabel()}
{children}
{renderHelpText()}
</div>
);
};
export default FormField;