Policies: Include/Exclude label targeting in Save policy modal (#33441) - #47213
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #47213 +/- ##
==========================================
- Coverage 67.20% 67.19% -0.02%
==========================================
Files 3069 3147 +78
Lines 226869 227029 +160
Branches 11887 11893 +6
==========================================
+ Hits 152467 152550 +83
- Misses 60661 60737 +76
- Partials 13741 13742 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
dccdba8 to
b5ee545
Compare
Replace the single-mode dropdown target selector in SaveNewPolicyModal with the tabbed Include/Exclude TargetLabelSelector, supporting a combined include + exclude scope with any/all modes. Add labels_exclude_all to the policy form types and forward it in team_policies create/update.
b5ee545 to
89fd02d
Compare
WalkthroughAdds an exclude-all label condition to policy types and includes it in team_policies create/update requests. Refactors SaveNewPolicyModal to use include/exclude tabs, separate include/exclude label state, and router-driven Add Label navigation; PolicyForm now passes the router prop. Tests are updated to mock the router and exercise the Exclude tab. A small style change updates TargetLabelSelector’s empty-state border. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Updates the “Save policy” modal to use the newer tabbed Include/Exclude label targeting UI (with Any/All modes) and extends the policy payload/types to include labels_exclude_all, aligning policy targeting capabilities with the newer TargetLabelSelector component.
Changes:
- Replace the old dropdown-based label targeting in
SaveNewPolicyModalwithTargetLabelSelectorinclude/exclude tabs and Any/All mode toggles. - Extend policy payload plumbing and TS types to include
labels_exclude_all. - Update the modal’s tests and pass a router instance down for “Add label” navigation.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/services/entities/team_policies.ts | Adds labels_exclude_all to the create/update request payloads for team policies. |
| frontend/pages/policies/edit/components/SaveNewPolicyModal/SaveNewPolicyModal.tsx | Switches to TargetLabelSelector with include/exclude tabs + Any/All toggles and builds the new label-scope payload. |
| frontend/pages/policies/edit/components/SaveNewPolicyModal/SaveNewPolicyModal.tests.tsx | Adds/updates tests for include/exclude label payload behavior and new modes. |
| frontend/pages/policies/edit/components/PolicyForm/PolicyForm.tsx | Passes router into SaveNewPolicyModal. |
| frontend/interfaces/policy.ts | Extends IPolicy/IPolicyFormData with labels_exclude_all. |
Comments suppressed due to low confidence (1)
frontend/pages/policies/edit/components/SaveNewPolicyModal/SaveNewPolicyModal.tsx:436
- PATHS.LABEL_NEW_DYNAMIC is marked deprecated in router/paths.ts (handled by the
/labels/newroute). For new navigation from this modal, prefer PATHS.NEW_LABEL to avoid introducing new uses of the deprecated path.
autofocus
disabled={disableForm}
/>
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const hasCustomLabels = | ||
| listNamesFromSelectedLabels(selectedIncludeLabels).length > 0 || | ||
| listNamesFromSelectedLabels(selectedExcludeLabels).length > 0; | ||
|
|
||
| const disableForm = | ||
| isFetchingAutofillDescription || isFetchingAutofillResolution; | ||
| const disableSave = | ||
| !platformSelector.isAnyPlatformSelected || | ||
| disableForm || | ||
| (selectedTargetType === "Custom" && | ||
| !Object.entries(selectedLabels).some(([, value]) => { | ||
| return value; | ||
| })); | ||
| (selectedTargetType === "Custom" && !hasCustomLabels); |
There was a problem hiding this comment.
Same as comment below, I'll tackle the backend changes in a follow-up PR. Merging this to main won't land to users yet and we can still save a single inclusion/exclusion as before.
| it("should send both include and exclude labels when both tabs have selections", async () => { | ||
| const onCreatePolicy = jest.fn(); | ||
| const props = { ...defaultProps, onCreatePolicy }; | ||
| render( | ||
| <PolicyProvider> |
There was a problem hiding this comment.
I'll tackle the backend in a separate PR. This is fine.
| @@ -0,0 +1 @@ | |||
| * Added the ability to target a policy to hosts using a combination of "include" and "exclude" labels. | |||
There was a problem hiding this comment.
added the changes file in this first PR of the series (will have follow-ups for Edit policy page + BE changes and gitops) so that I don't forget later.
juan-fdz-hawa
left a comment
There was a problem hiding this comment.
LGTM - The only tweak I'd suggest is using a callback (e.g., onAddLabelClicked) for the Add Label CTA when no labels exist. This keeps it consistent with the component's existing pattern.
Related issue: Resolves #46583
Figma: https://www.figma.com/design/0F1sw63SuYaKVWlcL7mnc6/-33441-Policies--Custom-targets-with-%22Include-any%22-and-%22Exclude-any%22?node-id=5303-5687&t=Fszpf83KhcZ7ViWh-0
Checklist for submitter
changes/,orbit/changes/oree/fleetd-chrome/changes.See Changes files for more information.
Testing
Added/updated automated tests
QA'd all new/changed functionality manually
Note: policy creation will fail if more than one inclusion/exclusion option is provided. This will be addressed as part of #46582 (we'll relax that check to make sure we can accept a combination).
Screen.Recording.2026-06-09.at.3.48.45.PM.mov
Screen.Recording.2026-06-09.at.3.49.30.PM.mov
Empty state:
Summary by CodeRabbit
New Features
Improvements
Tests
Style