mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 21:47:20 +00:00
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #40077 # Details Fixes an unreleased bug where rewriting the location with `fleet_id` in the string would not properly set the current team in the useTeamParam hook. This is because we haven't fully switched over to `fleet_id` internally yet, so we still need to check for `team_id` until we do. Also updated a few lingering instances of "team" in the user-facing text. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. n/a, unreleased bug ## Testing - [ ] Added/updated automated tests no tests to speak of - [X] QA'd all new/changed functionality manually On main branch, was able to reproduce the issue where selecting an option from the "All software" dropdown on the Software page caused the selected fleet to be reset. On this branch, the selected fleet was maintained after making a selection. For unreleased bug fixes in a release candidate, one of: - [X] Confirmed that the fix is not expected to adversely impact load test results
161 lines
4.3 KiB
JavaScript
161 lines
4.3 KiB
JavaScript
import React from "react";
|
|
import PropTypes from "prop-types";
|
|
import classNames from "classnames";
|
|
import { filter, includes, isEqual, noop } from "lodash";
|
|
|
|
import targetInterface from "interfaces/target";
|
|
import TargetDetails from "../TargetDetails";
|
|
import { targetFilter } from "./helpers";
|
|
import TargetOption from "../TargetOption";
|
|
|
|
const baseClass = "target-list";
|
|
|
|
const SelectTargetsMenuWrapper = (
|
|
onMoreInfoClick,
|
|
moreInfoTarget,
|
|
handleBackToResults,
|
|
isPremiumTier
|
|
) => {
|
|
const SelectTargetsMenu = ({
|
|
focusedOption,
|
|
instancePrefix,
|
|
onFocus,
|
|
onSelect,
|
|
optionClassName,
|
|
optionComponent,
|
|
options,
|
|
valueArray = [],
|
|
valueKey,
|
|
onOptionRef,
|
|
}) => {
|
|
const Option = optionComponent;
|
|
|
|
const renderTargets = (targetType) => {
|
|
const targets = filter(options, targetFilter(targetType));
|
|
const targetsOutput = [];
|
|
const targetTitle = targetType === "all" ? "all hosts" : targetType;
|
|
|
|
targetsOutput.push(
|
|
<p className={`${baseClass}__type`} key={`type-${targetType}-key`}>
|
|
{targetTitle}
|
|
</p>
|
|
);
|
|
|
|
if (targets.length === 0) {
|
|
if (targetType === "all") {
|
|
return false;
|
|
}
|
|
|
|
targetsOutput.push(
|
|
<span
|
|
className={`${baseClass}__not-found`}
|
|
key={`${targetType}-notfound`}
|
|
>
|
|
Unable to find any matching {targetType}.
|
|
</span>
|
|
);
|
|
|
|
return targetsOutput;
|
|
}
|
|
|
|
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);
|
|
};
|
|
|
|
return (
|
|
<Option
|
|
className={className}
|
|
instancePrefix={instancePrefix}
|
|
isDisabled={isDisabled}
|
|
isFocused={isFocused}
|
|
isSelected={isSelected}
|
|
key={`option-${target[valueKey]}-${target.id}`}
|
|
onFocus={onFocus}
|
|
onSelect={noop}
|
|
option={target}
|
|
optionIndex={index}
|
|
ref={setRef}
|
|
>
|
|
<TargetOption
|
|
target={target}
|
|
onSelect={onSelect}
|
|
onMoreInfoClick={onMoreInfoClick}
|
|
/>
|
|
</Option>
|
|
);
|
|
})
|
|
);
|
|
|
|
return targetsOutput;
|
|
};
|
|
|
|
const hasHostTargets = () => {
|
|
return options.find((option) => option.count !== 0) !== undefined;
|
|
};
|
|
|
|
const renderTargetGroups = (
|
|
<>
|
|
{renderTargets("all")}
|
|
{isPremiumTier && renderTargets("fleets")}
|
|
{renderTargets("labels")}
|
|
{renderTargets("hosts")}
|
|
</>
|
|
);
|
|
|
|
return (
|
|
<div className={baseClass}>
|
|
<div className={`${baseClass}__options`}>
|
|
{hasHostTargets() ? (
|
|
renderTargetGroups
|
|
) : (
|
|
<>
|
|
<div className={`${baseClass}__no-hosts`}>
|
|
<div className={`${baseClass}__no-hosts-heading`}>
|
|
You have no hosts to run this report against.
|
|
</div>
|
|
Expecting to see hosts? Try again in a few seconds as the system
|
|
catches up.
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
<div className={`${baseClass}__option-details`}>
|
|
<TargetDetails
|
|
target={moreInfoTarget}
|
|
className={`${baseClass}__spotlight`}
|
|
handleBackToResults={handleBackToResults}
|
|
/>
|
|
</div>
|
|
</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,
|
|
isPremiumTier: PropTypes.bool,
|
|
};
|
|
|
|
return SelectTargetsMenu;
|
|
};
|
|
|
|
export default SelectTargetsMenuWrapper;
|