Skip to content

Fleet UI: Split out inventory vs. library team level views - #44467

Merged
RachelElysia merged 17 commits into
mainfrom
42576-inventory-page
May 1, 2026
Merged

Fleet UI: Split out inventory vs. library team level views#44467
RachelElysia merged 17 commits into
mainfrom
42576-inventory-page

Conversation

@RachelElysia

@RachelElysia RachelElysia commented Apr 30, 2026

Copy link
Copy Markdown
Member

Issue

Closes #42576
Closes #42577

Description

  • Separation of Software inventory vs. software library

Screenrecording of update

https://fleetdm.zoom.us/clips/share/FvbT3kGxRPyvSKEeHoJ4Qg

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.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Summary by CodeRabbit

  • New Features

    • Added premium-only "Library" tab and a dedicated Software Library view with search, filters, and table improvements.
    • Inventory view introduced as the primary Software tab (replacing legacy titles view).
  • Bug Fixes

    • Disabled tabs no longer show a “not-allowed” cursor and keep hover background transparent.
  • Refactor

    • Simplified software filtering (removed installable/all dropdown) and updated software routes/navigation.
    • Increased default pagination for software lists.

@codecov

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 52.24719% with 85 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.65%. Comparing base (a59f1fd) to head (3fc31cc).
⚠️ Report is 53 commits behind head on main.

Files with missing lines Patch % Lines
...oftwareLibraryTable/SoftwareLibraryTableConfig.tsx 10.52% 51 Missing ⚠️
frontend/pages/SoftwarePage/SoftwarePage.tsx 31.81% 15 Missing ⚠️
...rary/SoftwareLibraryTable/SoftwareLibraryTable.tsx 85.13% 11 Missing ⚠️
...etailsPage/EditSoftwareModal/EditSoftwareModal.tsx 0.00% 5 Missing ⚠️
...reTitleDetailsPage/EditIconModal/EditIconModal.tsx 33.33% 2 Missing ⚠️
.../SoftwareInventoryTable/SoftwareInventoryTable.tsx 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #44467      +/-   ##
==========================================
- Coverage   66.75%   66.65%   -0.11%     
==========================================
  Files        2633     2643      +10     
  Lines      211736   212212     +476     
  Branches     9387     9681     +294     
==========================================
+ Hits       141354   141457     +103     
- Misses      57541    57912     +371     
- Partials    12841    12843       +2     
Flag Coverage Δ
frontend 54.15% <52.24%> (-0.60%) ⬇️

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

☔ View full report in Codecov by Sentry.
📢 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.

@coderabbitai

coderabbitai Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR splits the legacy "Software Titles" UI into two distinct views: Inventory and Library. It renames routes (introduces /software/inventory and /software/library, removes /software/titles), updates navigation and tab logic, removes the software dropdown filter, introduces a self-service toggle for Library, adapts tables/components/styles for inventory vs library semantics, and adds/updates tests and React Query cache invalidations to include the new library scope.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: splitting the Software UI into separate Inventory and Library views at the team level.
Description check ✅ Passed The description includes issue references (#42576, #42577), a brief description of the feature, and testing confirmation, but omits confirmation of the required changes file.
Linked Issues check ✅ Passed The PR substantially implements objectives from #42576 and #42577: Inventory tab created with filters, Library tab added with premium feature gating, both showing 50-item pagination, vulnerability filters moved appropriately, self-service toggle added to Library, and cache invalidation added across multiple software-edit flows.
Out of Scope Changes check ✅ Passed Changes remain tightly scoped to the Inventory/Library split and supporting refactoring (route paths, component renames, query helpers, cache invalidation for consistency). No unrelated features or scope creep detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 42576-inventory-page

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.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@RachelElysia
RachelElysia marked this pull request as ready for review April 30, 2026 13:14
@RachelElysia
RachelElysia requested a review from a team as a code owner April 30, 2026 13:14
Copilot AI review requested due to automatic review settings April 30, 2026 13:14

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@RachelElysia

Copy link
Copy Markdown
Member Author

@claude review

@RachelElysia
RachelElysia marked this pull request as draft April 30, 2026 13:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@frontend/pages/SoftwarePage/components/tables/EmptySoftwareTable/EmptySoftwareTable.tsx`:
- Line 44: EmptySoftwareTable currently treats an omitted noSearchQuery as
"filtered" because !undefined === true; fix this by giving noSearchQuery a
default of true in the component props/destructuring so the computed isFiltered
(const isFiltered = vulnFiltersCount > 0 || !noSearchQuery) behaves correctly
when callers omit the prop; update the EmptySoftwareTable props signature (or
destructured default) to set noSearchQuery = true and adjust any TS types if
necessary.

In `@frontend/pages/SoftwarePage/SoftwareInventory/_styles.scss`:
- Around line 2-3: Add the required blank line before the declaration to satisfy
the stylelint rule: in _styles.scss, insert an empty line between the `@include`
vertical-page-tab-panel-layout; statement and the margin-top:
$gap-page-component; declaration so the declaration-empty-line-before rule no
longer fails.

In
`@frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tests.tsx`:
- Around line 149-150: The test currently uses screen.queryByText("Add filter")
which can falsely pass when the UI renders a different copy; update the
assertion in SoftwareInventoryTable.tests.tsx to target the exact filter control
text or use a role/name query for the button (e.g., the actual copy "Add
filters" or a getByRole query with name "Add filter(s)") so the test verifies
the specific filter control is absent in the empty-state; locate the two failing
assertions that call queryByText and replace the second with a role/name or
exact-text query that matches the real filter button label used by the
SoftwareInventoryTable component.

In `@frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibrary.tsx`:
- Around line 78-82: The query's enabled flag only checks
window.location.pathname and fires on first render even when no concrete team is
selected; update the enabled condition to also require a concrete team id so the
library query doesn't run for "All fleets" (e.g. change enabled to:
window.location.pathname === PATHS.SOFTWARE_LIBRARY && Boolean(teamId) && teamId
!== 'all'), using the existing teamId value passed into or obtained by
SoftwareLibrary/SoftwarePage so the query only runs when a real teamId is
present.

In
`@frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTable.tsx`:
- Around line 86-93: The page reset logic always sets page to 0 unless
changedParam === "pageIndex", which also resets pages on mount (changedParam ===
""), so update the page value computation in the onQueryChange handler (the
arrow that takes newTableQuery and changedParam) to preserve
newTableQuery.pageIndex when changedParam is falsy/empty and only force page = 0
when a meaningful non-page parameter actually changed; in practice change the
ternary that sets page to: if changedParam === "pageIndex" ->
newTableQuery.pageIndex; else if changedParam is falsy (""/undefined) ->
newTableQuery.pageIndex; else -> 0, and apply the same fix where this logic
appears around onQueryChange (lines ~103-115).

In `@frontend/router/index.tsx`:
- Around line 375-383: The SoftwareLibrary route is exposed to all authenticated
users even though SoftwarePage's premiumSoftwareSubNav only shows Library for
premium users; wrap the <Route path="library" component={SoftwareLibrary}> with
the same premium guard used elsewhere (e.g., wrap it in <PremiumRoutes> or
replace it with a route that redirects non-premium users) so non-premium users
cannot deep-link to /software/library; locate the Route block under SoftwarePage
in frontend/router/index.tsx and apply the same gating pattern used for premium
tabs or add a conditional redirect that checks the user's premium status before
rendering SoftwareLibrary.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 89f0ed14-6ea4-4e44-8d19-ca97c893ffd0

📥 Commits

Reviewing files that changed from the base of the PR and between a2f16fc and 18b2935.

📒 Files selected for processing (47)
  • frontend/components/TabNav/_styles.scss
  • frontend/components/top_nav/SiteTopNav/navItems.ts
  • frontend/pages/DashboardPage/DashboardPage.tsx
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAddPage.tsx
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStore/SoftwareAppStoreAndroid/SoftwareAppStoreAndroid.tsx
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStore/SoftwareAppStoreVpp/SoftwareAppStoreVpp.tsx
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareCustomPackage/SoftwareCustomPackage.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventory.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tests.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTableConfig.tests.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTableConfig.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareVersionsTableConfig.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/_styles.scss
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/helpers.tests.ts
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/helpers.ts
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/index.ts
  • frontend/pages/SoftwarePage/SoftwareInventory/_styles.scss
  • frontend/pages/SoftwarePage/SoftwareInventory/index.ts
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibrary.tsx
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTable.tests.tsx
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTable.tsx
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTableConfig.tests.tsx
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTableConfig.tsx
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/_styles.scss
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/index.ts
  • frontend/pages/SoftwarePage/SoftwareLibrary/_styles.scss
  • frontend/pages/SoftwarePage/SoftwareLibrary/index.ts
  • frontend/pages/SoftwarePage/SoftwarePage.tests.tsx
  • frontend/pages/SoftwarePage/SoftwarePage.tsx
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareTitleDetailsPage.tsx
  • frontend/pages/SoftwarePage/SoftwareTitles/SoftwareTable/index.ts
  • frontend/pages/SoftwarePage/SoftwareTitles/index.ts
  • frontend/pages/SoftwarePage/components/modals/SoftwareFiltersModal/SoftwareFiltersModal.tsx
  • frontend/pages/SoftwarePage/components/tables/EmptySoftwareTable/EmptySoftwareTable.tsx
  • frontend/pages/hosts/details/cards/Software/DeviceSoftwareTableConfig.tsx
  • frontend/pages/hosts/details/cards/Software/HostSoftware.tsx
  • frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tsx
  • frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx
  • frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx
  • frontend/router/index.tsx
  • frontend/router/paths.ts
  • frontend/services/entities/software.ts
  • frontend/utilities/endpoints.ts
  • frontend/utilities/numbers/index.ts
  • frontend/utilities/numbers/numberUtils.tests.ts
  • frontend/utilities/numbers/numberUtils.ts
💤 Files with no reviewable changes (2)
  • frontend/pages/SoftwarePage/SoftwareTitles/index.ts
  • frontend/pages/SoftwarePage/SoftwareTitles/SoftwareTable/index.ts

Comment thread frontend/pages/SoftwarePage/SoftwareInventory/_styles.scss
Comment thread frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibrary.tsx
Comment thread frontend/router/index.tsx

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Splits the existing Software “titles” view into separate Inventory and Library tab routes, updating routing, table configs, filters, and related navigation so team-level software views behave differently depending on “All fleets” vs. a specific fleet selection.

Changes:

  • Added new /software/inventory and /software/library routes and updated SoftwarePage tab navigation (including legacy /software/titles redirect).
  • Implemented a new Library tab/table (self-service-only toggle, installed vs. library version columns) and refactored Inventory table config/helpers.
  • Extracted isValidNumber into a shared utilities/numbers module and adjusted tests accordingly.

Reviewed changes

Copilot reviewed 45 out of 47 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/utilities/numbers/numberUtils.ts Introduces shared isValidNumber helper.
frontend/utilities/numbers/numberUtils.tests.ts Updates tests to use the new numbers utility entrypoint.
frontend/utilities/numbers/index.ts Adds barrel export for utilities/numbers.
frontend/utilities/endpoints.ts Adds clarifying comment for SOFTWARE_TITLES usage across Inventory/Library.
frontend/services/entities/software.ts Expands titles query-key scope to include software-library.
frontend/router/paths.ts Replaces SOFTWARE_TITLES route constant with SOFTWARE_INVENTORY/SOFTWARE_LIBRARY.
frontend/router/index.tsx Updates software routing, adds inventory/library routes and legacy redirect.
frontend/pages/policies/ManagePoliciesPage/components/InstallSoftwareModal/InstallSoftwareModal.tsx Updates “go to software” link target for adding software.
frontend/pages/hosts/details/cards/Software/HostSoftwareTableConfig.tsx Repoints helpers import to Inventory table helpers.
frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tsx Repoints helpers import to Inventory table helpers; removes now-unused imports.
frontend/pages/hosts/details/cards/Software/HostSoftware.tsx Repoints helpers import to Inventory table helpers.
frontend/pages/hosts/details/cards/Software/DeviceSoftwareTableConfig.tsx Repoints helpers import to Inventory table helpers.
frontend/pages/SoftwarePage/components/tables/EmptySoftwareTable/EmptySoftwareTable.tsx Removes now-deleted dropdown-filter handling from empty states.
frontend/pages/SoftwarePage/components/modals/SoftwareFiltersModal/SoftwareFiltersModal.tsx Repoints helpers import to Inventory helpers.
frontend/pages/SoftwarePage/SoftwareTitles/index.ts Removes legacy SoftwareTitles export.
frontend/pages/SoftwarePage/SoftwareTitles/SoftwareTable/index.ts Removes legacy SoftwareTable export.
frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareTitleDetailsPage.tsx Updates redirect target after installer deletion to Library route.
frontend/pages/SoftwarePage/SoftwarePage.tsx Adds Inventory/Library tabs, disables Library on All fleets, bumps per-page default to 50, adds bounce logic.
frontend/pages/SoftwarePage/SoftwarePage.tests.tsx Adds unit tests for tab arrays and getTabIndex.
frontend/pages/SoftwarePage/SoftwareLibrary/index.ts Adds Library tab entrypoint export.
frontend/pages/SoftwarePage/SoftwareLibrary/_styles.scss Renames base class for Library tab layout styling.
frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/index.ts Adds Library table entrypoint export.
frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/_styles.scss Adds Library table-specific layout/styling overrides.
frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTableConfig.tsx Defines Library table columns including installed/library version split.
frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTableConfig.tests.tsx Adds header/config tests for Library table.
frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTable.tsx Implements Library table behavior (search, paging, self-service toggle, empty states).
frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTable.tests.tsx Adds Library table rendering/empty-state tests.
frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibrary.tsx Implements Library tab data fetch via getSoftwareTitles with availableForInstall.
frontend/pages/SoftwarePage/SoftwareInventory/index.ts Adds Inventory tab entrypoint export.
frontend/pages/SoftwarePage/SoftwareInventory/_styles.scss Adds Inventory tab layout styling wrapper.
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/index.ts Adds Inventory table entrypoint export.
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/helpers.ts Removes dropdown filter logic; uses shared isValidNumber; keeps vuln filter helpers.
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/helpers.tests.ts Moves getVulnerabilities tests to the new helpers location.
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/_styles.scss Renames base class and removes dropdown filter styling.
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareVersionsTableConfig.tsx Adds versions-table config for Inventory “Show versions” mode.
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTableConfig.tsx Adds titles-table config for Inventory tab (incl. vulnerabilities).
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTableConfig.tests.tsx Adds header/config tests for Inventory table.
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tsx Refactors Inventory table implementation (removes old dropdown filter).
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tests.tsx Updates tests for Inventory table after dropdown removal.
frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventory.tsx Renames SoftwareTitles tab to SoftwareInventory and updates query enabling to new route.
frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareCustomPackage/SoftwareCustomPackage.tsx Updates cancel/back navigation target to Library route.
frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStore/SoftwareAppStoreVpp/SoftwareAppStoreVpp.tsx Updates cancel/back navigation target to Library route.
frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStore/SoftwareAppStoreAndroid/SoftwareAppStoreAndroid.tsx Updates cancel/back navigation target to Library route.
frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAddPage.tsx Updates back URL to Library route.
frontend/pages/DashboardPage/DashboardPage.tsx Updates dashboard software widget link target to Inventory route.
frontend/components/top_nav/SiteTopNav/navItems.ts Updates Software nav default pathname to Inventory and adjusts comment example.
frontend/components/TabNav/_styles.scss Tweaks disabled tab hover styling for Tooltip-wrapped disabled tab.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frontend/components/top_nav/SiteTopNav/navItems.ts
Comment thread frontend/router/index.tsx
Comment thread frontend/router/index.tsx Outdated
Comment thread frontend/services/entities/software.ts
Comment on lines 74 to 78
&--disabled {
cursor: not-allowed;
&:hover {
background-color: transparent;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 The &--disabled rule on .react-tabs__tab was changed to only override the hover background, dropping the cursor: not-allowed declaration that previously lived there. With this PR introducing a disabled Library tab in SoftwarePage when 'All fleets' is selected, hovering it now shows the default cursor instead of the standard not-allowed affordance. Easy fix: keep both the cursor rule and the new hover override.

Extended reasoning...

What changed. In frontend/components/TabNav/_styles.scss, the .react-tabs__tab--disabled rule was rewritten from cursor: not-allowed; to:

&--disabled {
  &:hover {
    background-color: transparent;
  }
}

The cursor: not-allowed declaration was replaced, not augmented, so disabled tabs no longer get the not-allowed cursor.

Why it matters for this PR. Before this PR there were no disabled Tabs in TabNav, so the missing cursor was latent. This PR makes it user-visible by introducing a disabled Library tab in SoftwarePage.tsx (renderBody) when isAllTeamsSelected is true. The disabled <Tab> is wrapped in a TooltipWrapper saying "Select a fleet to view its software library," but the visual cursor cue is now missing.

Why nothing else restores it. A grep across the frontend shows the only cursor: not-allowed declarations live in unrelated form components (Radio, Checkbox, InputFieldWithIcon, SQLEditor, TargetChipSelector). The react-tabs library doesn't ship a stylesheet that adds this either, and TooltipWrapper has no cursor rule. Browsers don't apply a special cursor to a disabled <li> by default (react-tabs renders Tabs as <li>), so the disabled Library tab will hover with the default pointer cursor.

Step-by-step proof.

  1. Switch the team selector to "All fleets" on the Software page — isAllTeamsSelected becomes true.
  2. renderBody in SoftwarePage.tsx renders the Library tab with disabled and class react-tabs__tab--disabled.
  3. Hover the Library tab. The cascade for .react-tabs__tab--disabled:hover matches the new rule (background-color: transparent) but no cursor declaration applies at any specificity for the disabled state.
  4. The browser falls back to the default cursor (or pointer from UA tab styling), instead of not-allowed. Compare to the prior behavior where &--disabled { cursor: not-allowed; } set it explicitly.

Impact. UX/a11y affordance regression — small but user-visible. The disabled tab still won't fire onSelect (react-tabs respects the disabled prop) and the tooltip still explains why it's disabled, so functionality is intact.

Fix. Keep both declarations:

&--disabled {
  cursor: not-allowed;
  &:hover {
    background-color: transparent;
  }
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use the not-allowed in a lot of places so I was removing it on purpose since it was distracting with a cursor change and tooltip

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RachelElysia

Copy link
Copy Markdown
Member Author

@claude review

Comment thread frontend/pages/SoftwarePage/SoftwarePage.tsx
@RachelElysia
RachelElysia marked this pull request as ready for review April 30, 2026 21:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibrary.tsx`:
- Around line 81-83: The query enabling condition should include the feature
flag so the data-fetch won't run when software is disabled: update the query's
enabled predicate to require isSoftwareEnabled && teamId !== undefined &&
window.location.pathname === PATHS.SOFTWARE_LIBRARY; also update the
error-render branch in SoftwareLibraryTable (the logic that currently renders
TableDataError) to only show TableDataError when isSoftwareEnabled is true so
the disabled-state UX displays instead of the error UI.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3749d428-0331-4422-8a99-16414cffbc65

📥 Commits

Reviewing files that changed from the base of the PR and between 18b2935 and 3fc31cc.

📒 Files selected for processing (22)
  • frontend/components/TabNav/_styles.scss
  • frontend/components/TableContainer/TableContainer.tsx
  • frontend/components/TableContainer/_styles.scss
  • frontend/components/top_nav/SiteTopNav/navItems.ts
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStore/SoftwareAppStoreAndroid/SoftwareAppStoreAndroid.tsx
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStore/SoftwareAppStoreVpp/SoftwareAppStoreVpp.tsx
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareCustomPackage/SoftwareCustomPackage.tsx
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetMaintainedAppDetailsPage.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tests.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tsx
  • frontend/pages/SoftwarePage/SoftwareInventory/_styles.scss
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibrary.tsx
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTable.tests.tsx
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/SoftwareLibraryTable.tsx
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/_styles.scss
  • frontend/pages/SoftwarePage/SoftwarePage.tsx
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/EditIconModal/EditIconModal.tsx
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/EditSoftwareModal/EditSoftwareModal.tsx
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareTitleDetailsPage.tsx
  • frontend/pages/SoftwarePage/components/tables/EmptySoftwareTable/EmptySoftwareTable.tsx
  • frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tsx
  • frontend/router/index.tsx
💤 Files with no reviewable changes (1)
  • frontend/components/TableContainer/TableContainer.tsx
✅ Files skipped from review due to trivial changes (4)
  • frontend/pages/SoftwarePage/SoftwareInventory/_styles.scss
  • frontend/components/TableContainer/_styles.scss
  • frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibraryTable/_styles.scss
  • frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • frontend/components/TabNav/_styles.scss
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareCustomPackage/SoftwareCustomPackage.tsx
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareTitleDetailsPage.tsx
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStore/SoftwareAppStoreAndroid/SoftwareAppStoreAndroid.tsx
  • frontend/pages/hosts/details/cards/Software/HostSoftwareTable/HostSoftwareTable.tsx
  • frontend/router/index.tsx

Comment on lines +81 to +83
enabled:
teamId !== undefined &&
window.location.pathname === PATHS.SOFTWARE_LIBRARY,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Gate the query with isSoftwareEnabled to preserve disabled-state UX.

On Line 81, the query still runs when software is disabled. If that request errors, Lines 91-93 render TableDataError instead of the intended disabled state in SoftwareLibraryTable.

Suggested fix
       enabled:
+        isSoftwareEnabled &&
         teamId !== undefined &&
         window.location.pathname === PATHS.SOFTWARE_LIBRARY,

Also applies to: 91-93

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/SoftwarePage/SoftwareLibrary/SoftwareLibrary.tsx` around lines
81 - 83, The query enabling condition should include the feature flag so the
data-fetch won't run when software is disabled: update the query's enabled
predicate to require isSoftwareEnabled && teamId !== undefined &&
window.location.pathname === PATHS.SOFTWARE_LIBRARY; also update the
error-render branch in SoftwareLibraryTable (the logic that currently renders
TableDataError) to only show TableDataError when isSoftwareEnabled is true so
the disabled-state UX displays instead of the error UI.

@cdcme cdcme left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RachelElysia Read through this and ran through the UI locally, looks great! Didn't see anything jumping out to me, approving.

@RachelElysia
RachelElysia merged commit fd50c99 into main May 1, 2026
22 of 24 checks passed
@RachelElysia
RachelElysia deleted the 42576-inventory-page branch May 1, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants