Files
fleet/frontend/components/CommandPalette/groups/controls.ts
T
Nico b10642be3c 44954 custom host vitals (#49334)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44954 

# 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


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added Custom Host Vitals management (create/edit/delete, search) with
copyable variable tokens and per-host values.
* Show Custom Host Vitals on host details, including role-based editing.
* Enabled Custom Host Vitals in host-vitals labels and the activity
feed.
* Extended GitOps to manage global Custom Host Vitals declaratively
(including dry-run behavior).
* Split Controls → Variables into Global Variables and Custom Host
Vitals, including routing updates.

* **Bug Fixes**
* Improved validation and expansion of Custom Host Vital references
across scripts, profiles, installers, and deployments, with clearer
failures when values are missing or invalid.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 19:35:27 -03:00

256 lines
7.7 KiB
TypeScript

import paths from "router/paths";
import { ICommandItem, ICommandPaletteContext } from "../helpers";
import { IDerivedContext } from "./derivations";
const buildControlsItems = (
ctx: ICommandPaletteContext,
derived: IDerivedContext
): ICommandItem[] => {
const {
canAccessControls,
canAccessVariables,
isPremiumTier,
isAdminOrMaintainer,
withTeamId,
} = ctx;
const { hasTeamOrUnassigned } = derived;
// Controls pages don't support "All fleets" (includeAllTeams: false),
// so only show when a team or unassigned is selected. Also gated by
// canAccessControls (maintainers, admins, technicians).
if (!canAccessControls || !hasTeamOrUnassigned) return [];
return [
// OS updates is Premium-only — OSUpdates renders <PremiumFeatureMessage />
// on Free.
...(isPremiumTier
? [
{
id: "controls-os-updates",
label: "OS updates",
group: "Controls" as const,
path: withTeamId(paths.CONTROLS_OS_UPDATES),
keywords: [
"minimum version",
"deadline",
"nudge",
"macos",
"windows",
"ios",
"ipados",
"patch",
],
},
]
: []),
// OS settings sub-routes
{
id: "controls-os-settings",
label: "OS settings",
group: "Controls" as const,
path: withTeamId(paths.CONTROLS_OS_SETTINGS),
keywords: [
"enforce",
"remotely",
"profiles",
"operating system settings",
],
subItems: [
// Disk encryption is Premium-only.
...(isPremiumTier
? [
{
id: "controls-disk-encryption",
label: "Disk encryption",
path: withTeamId(paths.CONTROLS_DISK_ENCRYPTION),
keywords: [
"filevault",
"filevault2",
"bitlocker",
"recovery key",
],
},
]
: []),
{
id: "controls-custom-settings",
label: "Configuration profiles",
path: withTeamId(paths.CONTROLS_CUSTOM_SETTINGS),
keywords: [
"custom profiles",
"mobileconfig",
"deploy",
"ddm",
"windows csp",
],
},
// Assets are premium-only
...(isPremiumTier
? [
{
id: "controls-assets",
label: "Assets",
path: withTeamId(paths.CONTROLS_ASSETS),
keywords: ["assets", "ddm"],
},
]
: []),
// Certificates and Passwords — Premium-only, admin/maintainer only.
...(isPremiumTier && isAdminOrMaintainer
? [
{
id: "controls-certificates",
label: "Certificates",
path: withTeamId(paths.CONTROLS_CERTIFICATES),
keywords: [
"scep",
"est",
"pki",
"digicert",
"ndes",
"certificate authority",
"ca",
],
},
{
id: "controls-passwords",
label: "Passwords",
path: withTeamId(paths.CONTROLS_PASSWORDS),
keywords: ["rotation", "recovery", "macos", "laps"],
},
]
: []),
// Host names — Premium-only, admin/maintainer only. Supported for
// both fleets and "No team" / Unassigned.
...(isPremiumTier && isAdminOrMaintainer
? [
{
id: "controls-host-name-template",
label: "Host names",
path: withTeamId(paths.CONTROLS_HOST_NAME_TEMPLATE),
keywords: [
"rename",
"naming",
"template",
"convention",
"device name",
],
},
]
: []),
],
},
// Setup experience sub-routes — Premium-only.
...(isPremiumTier
? [
{
id: "controls-setup-experience",
label: "Setup experience",
group: "Controls" as const,
path: withTeamId(paths.CONTROLS_SETUP_EXPERIENCE),
keywords: [
"customize",
"end user",
"enrollment",
"onboarding",
"first run",
],
subItems: [
{
id: "controls-users",
label: "Users",
path: withTeamId(paths.CONTROLS_USERS),
keywords: ["idp", "login", "sso"],
},
{
id: "controls-bootstrap-package",
label: "Bootstrap package",
path: withTeamId(paths.CONTROLS_BOOTSTRAP_PACKAGE),
keywords: ["pkg", "deploy"],
},
{
id: "controls-install-software",
label: "Install software",
path: withTeamId(paths.CONTROLS_INSTALL_SOFTWARE("macos")),
keywords: ["automatic install"],
},
{
id: "controls-run-script",
label: "Run script",
path: withTeamId(paths.CONTROLS_RUN_SCRIPT),
keywords: ["shell", "post-enrollment"],
},
{
id: "controls-setup-assistant",
label: "Setup Assistant",
path: withTeamId(paths.CONTROLS_SETUP_ASSISTANT),
keywords: ["apple", "dep", "ade"],
},
],
},
]
: []),
// Scripts
{
id: "controls-scripts",
label: "Scripts",
group: "Controls" as const,
path: withTeamId(paths.CONTROLS_SCRIPTS),
keywords: [
"remediate",
"macos",
"windows",
"linux",
"bash",
"powershell",
"automation",
],
subItems: [
{
id: "controls-scripts-library",
label: "Script library",
path: withTeamId(paths.CONTROLS_SCRIPTS_LIBRARY),
keywords: ["saved", "uploaded", "manage"],
},
{
id: "controls-scripts-batch-progress",
label: "Script batch progress",
path: withTeamId(paths.CONTROLS_SCRIPTS_BATCH_PROGRESS),
keywords: ["status", "running", "results"],
},
],
},
// Variables — including its Global variables and Custom host vitals
// sub-tabs. Gated on canAccessVariables (admins + maintainers) since the
// Controls sub-nav hides this section from technicians.
...(canAccessVariables
? [
{
id: "controls-variables",
label: "Variables",
group: "Controls" as const,
path: withTeamId(paths.CONTROLS_VARIABLES),
keywords: ["custom", "scripts", "profiles"],
subItems: [
{
id: "controls-global-variables",
label: "Global variables",
path: withTeamId(paths.CONTROLS_VARIABLES_GLOBAL_VARIABLES),
keywords: ["custom", "secret"],
},
{
id: "controls-custom-host-vitals",
label: "Custom host vitals",
path: withTeamId(paths.CONTROLS_VARIABLES_CUSTOM_HOST_VITALS),
keywords: ["host", "vital", "custom", "host vital"],
},
],
},
]
: []),
];
};
export default buildControlsItems;