fleet/frontend/components/forms/fields/SelectTargetsDropdown/SelectTargetsMenu/SelectTargetsMenu.jsx
Scott Gress 93c75cf1b2
Fix software group dropdown w/ fleet_id (#40079)
<!-- 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
2026-02-18 17:53:00 -06:00

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;