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 #36093 # Checklist for submitter - [x] 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. # Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Queries/reports ### Team user with team report (observer_can_run = true) Created user with the following assignments: <img width="596" height="285" alt="Screenshot 2026-03-02 at 4 58 47 PM" src="https://github.com/user-attachments/assets/a3a8e7dd-2bfc-40f9-948c-b26b016162ae" /> Created report on **Workstations (canary)** fleet with **observers_can_run = true** <img width="1020" height="711" alt="Screenshot 2026-03-02 at 5 09 25 PM" src="https://github.com/user-attachments/assets/58aa98c7-8cbd-4a7a-a159-f4b40a65f2c9" /> Logged in with newly-created user, selected the report above to run it as a live report. - Verified that **Servers (canary)** is disabled => user is **Observer** on that fleet, but query belongs to **Workstations (canary)**. - All the other fleets are enabled: - User is **Observer+ or more** in those fleets. - User is **Observer** in **Workstations (canary)** => enabled because report belongs to this fleet, AND **observer_can_run = true**. <img width="986" height="823" alt="Screenshot 2026-03-02 at 5 07 29 PM" src="https://github.com/user-attachments/assets/b6b7aa4b-5036-46e3-8497-3a77f93a3a2c" /> ### Global user with team report (observer_can_run = true) - Created global Observer user. - Accessed same report created above for **Workstations (canary)** fleet with **observers_can_run = true**. - Logged in with newly-created user, selected the report above to run it as a live report. - Verified that the only target available is **Workstations (canary)**: <img width="1087" height="883" alt="Screenshot 2026-03-03 at 10 47 05 AM" src="https://github.com/user-attachments/assets/9fc8d4d4-6a38-4ecb-98fe-b56b46ac4f74" /> ### Global user with global report (observer_can_run = true) Global Observer user can target all fleets. <img width="1329" height="609" alt="Screenshot 2026-03-03 at 10 56 03 AM" src="https://github.com/user-attachments/assets/059d4eb2-546f-4a19-9eee-b64dd0250bf1" /> <img width="981" height="818" alt="Screenshot 2026-03-03 at 10 57 50 AM" src="https://github.com/user-attachments/assets/afa0ee58-3457-4838-a96e-dd508d924079" /> ### Global user with global report (observer_can_run = false) Global Observer user can't target any fleet. <img width="691" height="574" alt="Screenshot 2026-03-03 at 10 59 57 AM" src="https://github.com/user-attachments/assets/f328d547-ed06-4c30-ac22-5df7bb32240a" /> <img width="985" height="814" alt="Screenshot 2026-03-03 at 11 00 06 AM" src="https://github.com/user-attachments/assets/bb55da11-ea3f-40c7-bd98-652880d9e8f9" /> ## Policies On the FE, the same component is used to display the targets for Live Policies, so just making sure that I didn't introduce any regression. ### Global technician user, all fleets policy Can select all fleets. <img width="1130" height="858" alt="Screenshot 2026-03-03 at 11 13 40 AM" src="https://github.com/user-attachments/assets/8d9d97c4-9946-4c4c-9a8a-d79c65d9cb33" /> ### Team user with team policy Created user: - **Technician** on **Servers**. - **Observer** on **Servers (canary)**. <img width="745" height="770" alt="Screenshot 2026-03-03 at 11 18 11 AM" src="https://github.com/user-attachments/assets/56973c34-49bb-4007-9fac-09cf5315bdff" /> Can only select **Servers** as a target: <img width="999" height="754" alt="Screenshot 2026-03-03 at 11 18 56 AM" src="https://github.com/user-attachments/assets/82d14a8f-46e1-41f5-9355-d717477c85d8" /> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com>
58 lines
1.4 KiB
TypeScript
58 lines
1.4 KiB
TypeScript
import React from "react";
|
|
import {
|
|
ISelectLabel,
|
|
ISelectTeam,
|
|
ISelectTargetsEntity,
|
|
} from "interfaces/target";
|
|
import Icon from "components/Icon";
|
|
import {
|
|
PlatformLabelNameFromAPI,
|
|
LABEL_DISPLAY_MAP,
|
|
} from "utilities/constants";
|
|
|
|
interface ITargetChipSelectorProps {
|
|
entity: ISelectLabel | ISelectTeam;
|
|
isSelected: boolean;
|
|
onClick: (
|
|
value: ISelectLabel | ISelectTeam
|
|
) => React.MouseEventHandler<HTMLButtonElement>;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
const isBuiltInLabel = (
|
|
entity: ISelectTargetsEntity
|
|
): entity is ISelectLabel & { label_type: "builtin" } => {
|
|
return "label_type" in entity && entity.label_type === "builtin";
|
|
};
|
|
|
|
const TargetChipSelector = ({
|
|
entity,
|
|
isSelected,
|
|
onClick,
|
|
disabled,
|
|
}: ITargetChipSelectorProps): JSX.Element => {
|
|
const displayText = (): string => {
|
|
if (isBuiltInLabel(entity)) {
|
|
const labelName = entity.name as PlatformLabelNameFromAPI;
|
|
if (labelName in LABEL_DISPLAY_MAP) {
|
|
return LABEL_DISPLAY_MAP[labelName] || labelName;
|
|
}
|
|
}
|
|
|
|
return entity.name || "Missing display name";
|
|
};
|
|
|
|
return (
|
|
<button
|
|
className="target-chip-selector"
|
|
data-selected={isSelected}
|
|
disabled={disabled}
|
|
onClick={(e) => onClick(entity)(e)}
|
|
>
|
|
<Icon name={isSelected ? "check" : "plus"} color="ui-fleet-black-75" />
|
|
<span className="selector-name">{displayText()}</span>
|
|
</button>
|
|
);
|
|
};
|
|
|
|
export default TargetChipSelector;
|