2021-04-12 13:32:25 +00:00
|
|
|
import React from "react";
|
|
|
|
|
import PropTypes from "prop-types";
|
|
|
|
|
import classNames from "classnames";
|
|
|
|
|
import { filter, includes, isEqual, noop } from "lodash";
|
2016-11-14 17:32:13 +00:00
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
import targetInterface from "interfaces/target";
|
|
|
|
|
import TargetDetails from "../TargetDetails";
|
|
|
|
|
import { targetFilter } from "./helpers";
|
|
|
|
|
import TargetOption from "../TargetOption";
|
2016-11-14 17:32:13 +00:00
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
const baseClass = "target-list";
|
2016-11-14 17:32:13 +00:00
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
const SelectTargetsMenuWrapper = (
|
|
|
|
|
onMoreInfoClick,
|
|
|
|
|
moreInfoTarget,
|
|
|
|
|
handleBackToResults
|
|
|
|
|
) => {
|
2016-11-14 17:32:13 +00:00
|
|
|
const SelectTargetsMenu = ({
|
|
|
|
|
focusedOption,
|
|
|
|
|
instancePrefix,
|
|
|
|
|
onFocus,
|
|
|
|
|
onSelect,
|
|
|
|
|
optionClassName,
|
|
|
|
|
optionComponent,
|
|
|
|
|
options,
|
|
|
|
|
valueArray = [],
|
|
|
|
|
valueKey,
|
|
|
|
|
onOptionRef,
|
|
|
|
|
}) => {
|
|
|
|
|
const Option = optionComponent;
|
2016-11-23 21:10:32 +00:00
|
|
|
|
2016-11-14 17:32:13 +00:00
|
|
|
const renderTargets = (targetType) => {
|
2016-12-05 22:48:46 +00:00
|
|
|
const targets = filter(options, targetFilter(targetType));
|
2017-03-02 16:52:31 +00:00
|
|
|
const targetsOutput = [];
|
2021-04-12 13:32:25 +00:00
|
|
|
const targetTitle = targetType === "all" ? "all hosts" : targetType;
|
2017-03-02 16:52:31 +00:00
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
targetsOutput.push(
|
|
|
|
|
<p className={`${baseClass}__type`} key={`type-${targetType}-key`}>
|
|
|
|
|
{targetTitle}
|
|
|
|
|
</p>
|
|
|
|
|
);
|
2016-11-14 17:32:13 +00:00
|
|
|
|
2016-11-23 21:10:32 +00:00
|
|
|
if (targets.length === 0) {
|
2021-04-12 13:32:25 +00:00
|
|
|
if (targetType === "all") {
|
2017-03-02 16:52:31 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
targetsOutput.push(
|
|
|
|
|
<span
|
|
|
|
|
className={`${baseClass}__not-found`}
|
|
|
|
|
key={`${targetType}-notfound`}
|
|
|
|
|
>
|
|
|
|
|
Unable to find any matching {targetType}.
|
|
|
|
|
</span>
|
|
|
|
|
);
|
2017-03-02 16:52:31 +00:00
|
|
|
|
|
|
|
|
return targetsOutput;
|
2016-11-23 21:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
targetsOutput.push(
|
|
|
|
|
targets.map((target, index) => {
|
|
|
|
|
const { disabled: isDisabled } = target;
|
|
|
|
|
const isSelected = includes(valueArray, target);
|
|
|
|
|
const isFocused = isEqual(focusedOption, target);
|
|
|
|
|
const className = classNames(optionClassName, {
|
|
|
|
|
"Select-option": true,
|
|
|
|
|
"is-selected": isSelected,
|
|
|
|
|
"is-focused": isFocused,
|
|
|
|
|
"is-disabled": true,
|
|
|
|
|
});
|
|
|
|
|
const setRef = (ref) => {
|
|
|
|
|
onOptionRef(ref, isFocused);
|
|
|
|
|
};
|
2016-11-14 17:32:13 +00:00
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
return (
|
|
|
|
|
<Option
|
|
|
|
|
className={className}
|
|
|
|
|
instancePrefix={instancePrefix}
|
|
|
|
|
isDisabled={isDisabled}
|
|
|
|
|
isFocused={isFocused}
|
|
|
|
|
isSelected={isSelected}
|
2021-04-19 22:14:43 +00:00
|
|
|
key={`option-${target[valueKey]}-${target.id}`}
|
2021-04-12 13:32:25 +00:00
|
|
|
onFocus={onFocus}
|
|
|
|
|
onSelect={noop}
|
|
|
|
|
option={target}
|
|
|
|
|
optionIndex={index}
|
|
|
|
|
ref={setRef}
|
|
|
|
|
>
|
|
|
|
|
<TargetOption
|
|
|
|
|
target={target}
|
|
|
|
|
onSelect={onSelect}
|
|
|
|
|
onMoreInfoClick={onMoreInfoClick}
|
|
|
|
|
/>
|
|
|
|
|
</Option>
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
);
|
2017-03-02 16:52:31 +00:00
|
|
|
|
|
|
|
|
return targetsOutput;
|
2016-11-14 17:32:13 +00:00
|
|
|
};
|
|
|
|
|
|
2021-06-04 16:37:56 +00:00
|
|
|
const hasHostTargets = () => {
|
|
|
|
|
return options.find((option) => option.count !== 0) !== undefined;
|
|
|
|
|
};
|
|
|
|
|
|
2016-11-14 17:32:13 +00:00
|
|
|
return (
|
2016-11-23 21:10:32 +00:00
|
|
|
<div className={baseClass}>
|
|
|
|
|
<div className={`${baseClass}__options`}>
|
2021-06-04 16:37:56 +00:00
|
|
|
{hasHostTargets ? (
|
|
|
|
|
<>
|
|
|
|
|
{renderTargets("all")}
|
|
|
|
|
{renderTargets("teams")}
|
|
|
|
|
{renderTargets("labels")}
|
|
|
|
|
{renderTargets("hosts")}
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
<div className={`${baseClass}__no-hosts`}>
|
|
|
|
|
<div className={`${baseClass}__no-hosts-heading`}>
|
|
|
|
|
You have no hosts to run this query against.
|
|
|
|
|
</div>
|
|
|
|
|
Expecting to see hosts? Try again in a few seconds as the system
|
|
|
|
|
catches up.
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
2016-11-14 17:32:13 +00:00
|
|
|
</div>
|
2021-04-12 13:32:25 +00:00
|
|
|
<TargetDetails
|
|
|
|
|
target={moreInfoTarget}
|
|
|
|
|
className={`${baseClass}__spotlight`}
|
|
|
|
|
handleBackToResults={handleBackToResults}
|
|
|
|
|
/>
|
2016-11-14 17:32:13 +00:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
SelectTargetsMenu.propTypes = {
|
|
|
|
|
focusedOption: targetInterface,
|
|
|
|
|
instancePrefix: PropTypes.string,
|
|
|
|
|
onFocus: PropTypes.func,
|
|
|
|
|
onSelect: PropTypes.func,
|
|
|
|
|
optionClassName: PropTypes.string,
|
|
|
|
|
optionComponent: PropTypes.node,
|
|
|
|
|
options: PropTypes.arrayOf(targetInterface),
|
|
|
|
|
valueArray: PropTypes.arrayOf(targetInterface),
|
|
|
|
|
valueKey: PropTypes.string,
|
|
|
|
|
onOptionRef: PropTypes.func,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return SelectTargetsMenu;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default SelectTargetsMenuWrapper;
|