fleet/frontend/components/LiveQuery/TargetsInput/TargetsInput.tsx

125 lines
3.8 KiB
TypeScript
Raw Normal View History

2022-06-10 18:29:45 +00:00
import React from "react";
import { Row } from "react-table";
import { isEmpty, pullAllBy } from "lodash";
2022-06-10 18:29:45 +00:00
import { IHost } from "interfaces/host";
import { HOSTS_SEARCH_BOX_PLACEHOLDER } from "utilities/constants";
2022-06-10 18:29:45 +00:00
import DataError from "components/DataError";
// @ts-ignore
import InputFieldWithIcon from "components/forms/fields/InputFieldWithIcon/InputFieldWithIcon";
2022-06-10 18:29:45 +00:00
import TableContainer from "components/TableContainer";
import { ITargestInputHostTableConfig } from "./TargetsInputHostsTableConfig";
2022-06-10 18:29:45 +00:00
interface ITargetsInputProps {
tabIndex?: number;
2022-06-10 18:29:45 +00:00
searchText: string;
searchResults: IHost[];
isTargetsLoading: boolean;
hasFetchError: boolean;
targetedHosts: IHost[];
searchResultsTableConfig: ITargestInputHostTableConfig[];
selectedHostsTableConifg: ITargestInputHostTableConfig[];
/** disabled pagination for the results table. The pagination is currently
* client side pagination. Defaults to `false` */
disablePagination?: boolean;
label?: string;
placeholder?: string;
autofocus?: boolean;
2022-06-10 18:29:45 +00:00
setSearchText: (value: string) => void;
handleRowSelect: (value: Row<IHost>) => void;
2022-06-10 18:29:45 +00:00
}
const baseClass = "targets-input";
const DEFAULT_LABEL = "Target specific hosts";
2022-06-10 18:29:45 +00:00
const TargetsInput = ({
tabIndex,
searchText,
searchResults,
isTargetsLoading,
hasFetchError,
targetedHosts,
searchResultsTableConfig,
selectedHostsTableConifg,
disablePagination = false,
label = DEFAULT_LABEL,
placeholder = HOSTS_SEARCH_BOX_PLACEHOLDER,
autofocus = false,
2022-06-10 18:29:45 +00:00
handleRowSelect,
setSearchText,
}: ITargetsInputProps): JSX.Element => {
const dropdownHosts =
searchResults && pullAllBy(searchResults, targetedHosts, "display_name");
2022-06-10 18:29:45 +00:00
const isActiveSearch =
!isEmpty(searchText) && (!hasFetchError || isTargetsLoading);
const isSearchError = !isEmpty(searchText) && hasFetchError;
return (
<div>
<div className={baseClass}>
<InputFieldWithIcon
autofocus={autofocus}
2022-06-10 18:29:45 +00:00
type="search"
iconSvg="search"
2022-06-10 18:29:45 +00:00
value={searchText}
tabIndex={tabIndex}
iconPosition="start"
label={label}
placeholder={placeholder}
2022-06-10 18:29:45 +00:00
onChange={setSearchText}
/>
{isActiveSearch && (
<div className={`${baseClass}__hosts-search-dropdown`}>
<TableContainer<Row<IHost>>
columnConfigs={searchResultsTableConfig}
2022-06-10 18:29:45 +00:00
data={dropdownHosts}
isLoading={isTargetsLoading}
resultsTitle=""
emptyComponent={() => (
<div className="empty-search">
<div className="empty-search__inner">
<h4>No hosts match the current search criteria.</h4>
<p>
Expecting to see hosts? Try again in a few seconds as the
system catches up.
</p>
</div>
</div>
)}
showMarkAllPages={false}
isAllPagesSelected={false}
disableCount
disablePagination
disableMultiRowSelect
onClickRow={handleRowSelect}
2022-06-10 18:29:45 +00:00
/>
</div>
)}
{isSearchError && (
<div className={`${baseClass}__hosts-search-dropdown`}>
<DataError />
</div>
)}
<div className={`${baseClass}__hosts-selected-table`}>
<TableContainer
columnConfigs={selectedHostsTableConifg}
2022-06-10 18:29:45 +00:00
data={targetedHosts}
isLoading={false}
resultsTitle=""
showMarkAllPages={false}
isAllPagesSelected={false}
disableCount
disablePagination={disablePagination}
isClientSidePagination={!disablePagination}
2022-06-10 18:29:45 +00:00
emptyComponent={() => <></>}
/>
</div>
</div>
</div>
);
};
export default TargetsInput;