Skip to content

Self service categories - #47098

Merged
jkatz01 merged 10 commits into
mainfrom
feat/39018-self-service-categories
Jun 8, 2026
Merged

Self service categories#47098
jkatz01 merged 10 commits into
mainfrom
feat/39018-self-service-categories

Conversation

@jkatz01

@jkatz01 jkatz01 commented Jun 8, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #39018

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 for more information.

  • Input data is properly validated, SELECT * is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.

  • Timeouts are implemented and retries are limited to avoid infinite loops

  • If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes

Testing

  • Added/updated automated tests

  • Where appropriate, automated tests simulate multiple hosts and test for host isolation (updates to one hosts's records do not affect another)

  • QA'd all new/changed functionality manually

    • Tested the basic functionality on a different branch with the same commits but before they were merged to this feature branch. Test plan not checked yet.

Database migrations

  • Checked schema for all modified table for columns that will auto-update timestamps during migration.
  • Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects.
  • Ensured the correct collation is explicitly set for character columns (COLLATE utf8mb4_unicode_ci).

New Fleet configuration settings

Some changes to how gitops works for this feature will be fixed as an unreleased issue.

  • Verified that the setting is exported via fleetctl generate-gitops
  • Verified the setting is documented in a separate PR to the GitOps documentation
  • Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional)
  • Verified that any relevant UI is disabled when GitOps mode is enabled

Summary by CodeRabbit

Release Notes

  • New Features
    • Added self-service software category management page under Software > Library (Premium feature)
    • Replaced static category sidebar with dynamic category dropdown on device self-service page
    • Added "Install all (n)" button to install multiple software titles by category with confirmation modal
    • Extended activity history to track self-service bulk install actions
    • Added GitOps support for managing self-service software categories

jkatz01 and others added 10 commits May 29, 2026 18:38
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46390 
Migration to add a non nullable team_id column. I chose this approach so
that server code doesn't have to deal with a potentially null team id
for categories. It first adds team_id=0 to all the existing categories,
then duplicates that for every fleet so that default categories can be
edited and deleted by admins.

It also renames the default categories to include the emojis in their
name, which required updating some test expectations, and also mapping
default names to the new ones for Fleet maintained apps. If we don't do
that, FMA's manifests would have to all be updated right after 4.87
releases and every user would have to migrate immediately. This would
also break existing gitops files if the names aren't mapped. The
alternative would be to keep the names unchanged, and add custom logic
in various places to insert the emojis in the backend and frontend.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.


## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually

## Database migrations

- [x] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [x] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [x] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46391 

# 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.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46392 
A few things in this PR:
- updated the conversion from old default category to the new ones with
the emoji included that was introduced in the feature branch. It takes
into account what exists in the database now so if an admin wants to add
for example "Productivity" without the emoji as a category it won't get
overwritten.
- updated a few places to ignore missing categories rather than error
(what we do for adding a single FMA currently)
- updated permissions for "gitops" users 
- added everything needed for gitops, generate-gitops support using the
existing endpoints from the last PR.

Didn't add logs like "[+] applied X self service categories" since it
wasn't mentioned in the docs, but wouldn't be too hard to add.


# Checklist for submitter


## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually

## New Fleet configuration settings

- [x] Verified that the setting is exported via `fleetctl
generate-gitops`
- [x] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [x] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled
    - Currently missing, at least on this branch
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46393 

# 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.

- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually
**Related issue:** Resolves #39018

Follow-ups to the self-service custom categories work, landing on
`feat/39018-self-service-categories`:

1. **Match categories by full name (with emoji).** Drops the client-side
emoji-prefix stripping in `helpers.ts`. Both sides of the comparison
(custom category and software's `categories`) carry the emoji prefix, so
lowercase exact match works.
2. **Render `installed_all_self_service_software` activity.** New host
activity item + global feed template, matching the BE contract
(`self_service_category_id|name`, `software_titles_count`). Falls back
to an un-scoped "End user installed all the software in self-service."
when the install-all wasn't category-scoped.
3. **VPP edit modal: dynamic custom categories.** `EditSoftwareModal`
now passes `teamId` through `SoftwareVppForm` →
`SoftwareOptionsSelector`, so the VPP edit modal fetches custom
categories from the API instead of falling back to the hardcoded list.
`teamId === 0` (no team) is covered.

  ## Checklist for submitter

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented...

  ## Testing

  - [x] Added/updated automated tests
  - [x] QA'd all new/changed functionality manually

---------

Co-authored-by: jkatz01 <yehonatankatz@gmail.com>
…service-categories

Bump migration, fix failing test and nilaway check
@jkatz01
jkatz01 force-pushed the feat/39018-self-service-categories branch from 480f4c5 to e34126a Compare June 8, 2026 16:15
@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.35005% with 166 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.16%. Comparing base (6313e75) to head (e34126a).
⚠️ Report is 13 commits behind head on main.

Files with missing lines Patch % Lines
ee/server/service/categories.go 61.29% 28 Missing and 20 partials ⚠️
server/service/categories.go 60.00% 19 Missing and 3 partials ⚠️
...es/20260608160653_AddTeamIDToSoftwareCategories.go 78.04% 10 Missing and 8 partials ⚠️
server/datastore/mysql/software.go 84.00% 7 Missing and 5 partials ⚠️
server/service/client.go 61.29% 6 Missing and 6 partials ⚠️
...rvice/components/CategoryFilter/CategoryFilter.tsx 87.35% 11 Missing ⚠️
...perienceModal/CategoriesEndUserExperienceModal.tsx 22.22% 7 Missing ⚠️
server/datastore/mysql/software_installers.go 83.33% 4 Missing and 3 partials ⚠️
server/service/software_installers.go 62.50% 5 Missing and 1 partial ⚠️
server/service/client_software.go 77.77% 2 Missing and 2 partials ⚠️
... and 10 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #47098      +/-   ##
==========================================
+ Coverage   67.04%   67.16%   +0.12%     
==========================================
  Files        2894     2907      +13     
  Lines      225026   226129    +1103     
  Branches    11772    11719      -53     
==========================================
+ Hits       150867   151878    +1011     
- Misses      60489    60533      +44     
- Partials    13670    13718      +48     
Flag Coverage Δ
backend 68.80% <74.18%> (+0.04%) ⬆️
backend-activity 85.64% <ø> (ø)
frontend 57.64% <94.80%> (+0.63%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jkatz01
jkatz01 marked this pull request as ready for review June 8, 2026 16:37
@jkatz01
jkatz01 requested review from a team as code owners June 8, 2026 16:37
@jkatz01
jkatz01 merged commit 36c708d into main Jun 8, 2026
54 of 55 checks passed
@jkatz01
jkatz01 deleted the feat/39018-self-service-categories branch June 8, 2026 16:48
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

This PR adds team-scoped self-service software categories across backend, GitOps, and frontend flows. It introduces category CRUD, migration and datastore changes, GitOps parsing and generation for self_service_categories, a new self-service categories management page, and device-side support for category filtering plus “Install all” actions. It also adds new activity types, authz rules, API endpoints, tests, and route/service wiring.

Possibly related PRs

  • fleetdm/fleet#45659: Shares the self-service activity feed rendering path and adds related activity template behavior for self-service software actions.
  • fleetdm/fleet#46480: Also changes GitOps YAML rewrite behavior for software-related configuration output.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/39018-self-service-categories

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Self-service: Custom self-service software categories, with “Install all in category" button

3 participants