Skip to content

Fleet UI: Mobile self-service page - #34758

Merged
RachelElysia merged 11 commits into
feat-32247-ios-ipados-self-servicefrom
32247-selfservice-mobile-width
Oct 31, 2025
Merged

Fleet UI: Mobile self-service page#34758
RachelElysia merged 11 commits into
feat-32247-ios-ipados-self-servicefrom
32247-selfservice-mobile-width

Conversation

@RachelElysia

@RachelElysia RachelElysia commented Oct 24, 2025

Copy link
Copy Markdown
Member

Issue

Closes #32247

Description

Screenrecording

https://fleetdm.zoom.us/clips/share/4C1e4TubTy2Cz9GDYByUdw

TODO

  • Rename useIsMobile to useIsMobileWidth
  • Certificate error state
  • Vertically center the loading state
  • Fix the dropdown being cut off if there's only a few apps
  • Horizontally center empty state
  • Confirm with design: help text vs. tooltips (yes, switch to tooltip only for consistency)
  • Confirm with design: Edit icon modal self-service preview (yes, new edit modal self service view if ios/ipad app)
  • Add tests (added tests to new tile status action component)

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

NOTE: not E2E tested, and this PR merge is blocked by BE merge

Summary by CodeRabbit

Release Notes

  • New Features

    • Added mobile-responsive Self-service experience with tile-based grid layout
    • Enhanced iOS/iPadOS support with platform-specific tooltips and content
    • Implemented responsive design improvements for smaller screens
  • Bug Fixes

    • Corrected import paths for component references
    • Fixed form field spacing on mobile layouts
  • Refactor

    • Updated internal component structure for better mobile compatibility
    • Restructured Self-service components for improved modularity

@RachelElysia
RachelElysia force-pushed the 32247-selfservice-mobile-width branch from bd0db0e to c24765c Compare October 28, 2025 21:04
@RachelElysia
RachelElysia marked this pull request as ready for review October 28, 2025 21:05
@RachelElysia
RachelElysia requested a review from a team as a code owner October 28, 2025 21:05
@ghernandez345

Copy link
Copy Markdown
Contributor

@coderabbitai summay

@coderabbitai

coderabbitai Bot commented Oct 29, 2025

Copy link
Copy Markdown
Contributor

@ghernandez345: I'll generate a summary for this PR.

✅ Actions performed

Summary regeneration triggered.

@coderabbitai

coderabbitai Bot commented Oct 29, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This PR adds mobile-responsive UI support for iOS/iPadOS self-service software installation on the device page. It introduces mobile detection, component refactoring for mobile-optimized layouts, iOS/iPadOS-specific tooltip handling, type updates from IHostSoftwareWithUiStatus to IDeviceSoftwareWithUiStatus, and conditional screen size validation.

Changes

Cohort / File(s) Change Summary
Mobile Detection & Core Layout
frontend/hooks/useIsMobile.tsx, frontend/layouts/CoreLayout/CoreLayout.tsx, frontend/layouts/CoreLayout/_styles.scss, frontend/layouts/UnsupportedScreenSize/helpers.ts
New useIsMobile hook with MOBILE_BREAKPOINT of 768px; CoreLayout now conditionally displays UnsupportedScreenSize and applies "low-width-supported" class based on shouldShowUnsupportedScreen helper; added responsive CSS overrides to show app wrapper and nav on small screens.
Self-Service Component Refactoring
frontend/pages/hosts/details/cards/Software/SelfService/SelfService.tsx, frontend/pages/hosts/details/cards/Software/SelfService/SelfServiceCard/SelfServiceCard.tsx, frontend/pages/hosts/details/cards/Software/SelfService/components/SelfService.../*
Replaced inline header/filters/table rendering with modular components: SelfServiceHeader, SelfServiceFilters, SelfServiceTable, SelfServiceTiles; added isMobileView prop enabling mobile-optimized tile layout; type migration from IHostSoftwareWithUiStatus to IDeviceSoftwareWithUiStatus.
New Mobile-Optimized Components
frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceHeader/SelfServiceHeader.tsx, frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceFilters/SelfServiceFilters.tsx, frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTable/SelfServiceTable.tsx, frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTiles/SelfServiceTiles.tsx, frontend/pages/hosts/details/cards/Software/SelfService/components/TileActionStatus/TileActionStatus.tsx
New components with barrel exports for modular self-service UI rendering: header with optional "mobile-header" variant, search/category filters, table container, and tile-based mobile layout with per-tile action buttons.
iOS/iPadOS & Tooltip Updates
frontend/pages/SoftwarePage/helpers.tsx, frontend/pages/SoftwarePage/components/forms/SoftwareOptionsSelector/SoftwareOptionsSelector.tsx, frontend/pages/SoftwarePage/components/forms/PackageForm/PackageForm.tsx, frontend/pages/SoftwarePage/components/forms/SoftwareVppForm/SoftwareVppForm.tsx, frontend/components/TableContainer/DataTable/SoftwareNameCell/SoftwareNameCell.tsx, frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStoreVpp/SoftwareAppStoreVpp.tsx, frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareCustomPackage/SoftwareCustomPackage.tsx
Replaced static SELF_SERVICE_TOOLTIP with getSelfServiceTooltip(isIosOrIpadosApp) and getSelfServiceHelpText(isIosOrIpadosApp) functions for platform-specific content; added isIosOrIpadosApp props throughout component tree; threaded iOS/iPadOS detection via isIpadOrIphoneSoftwareSource helper.
Type Migrations & Helpers
frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTable/SelfServiceTableConfig.tsx, frontend/pages/hosts/details/cards/Software/SelfService/helpers.ts
Updated filterSoftwareByCategory and table configuration types from IHostSoftwareWithUiStatus to IDeviceSoftwareWithUiStatus; adjusted import paths for restructured components.
Device User Page & Mobile View
frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx, frontend/pages/hosts/details/DeviceUserPage/_styles.scss, frontend/pages/hosts/details/_styles.scss
Added useIsMobile hook to DeviceUserPage; conditional rendering of simplified mobile SelfService layout; applied variant="mobile" to Spinner; added "device-user-mobile" CSS class; centered EmptyTable via align-self.
Component Prop & Variant Updates
frontend/components/CardHeader/CardHeader.tsx, frontend/components/CardHeader/_styles.scss, frontend/components/EmptyTable/EmptyTable.tsx, frontend/components/EmptyTable/_styles.scss, frontend/components/Spinner/Spinner.tsx, frontend/components/Spinner/_styles.scss, frontend/components/TooltipTruncatedText/TooltipTruncatedText.tsx
Added variant?: "mobile-header" prop to CardHeader; variant?: "mobile" to EmptyTable and Spinner; isMobileView?: boolean to TooltipTruncatedText with click-based tooltip trigger on mobile; corresponding CSS classes for mobile styling.
Software Details & Preview Updates
frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/EditIconModal/EditIconModal.tsx, frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/EditIconModal/_styles.scss, frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/EditSoftwareModal/EditSoftwareModal.tsx, frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/SoftwareInstallerCard.tsx, frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareSummaryCard/SoftwareSummaryCard.tsx, frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareTitleDetailsPage.tsx, frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/helpers.ts, frontend/pages/SoftwarePage/components/modals/CategoriesEndUserExperienceModal/CategoriesEndUserExperienceModal.tsx
Added isIosOrIpadosApp prop threading through Edit modals and installer cards; new mobile preview card variant in EditIconModal; conditional modal image source (PreviewSelfServicePreviewMobile); added selfServiceVersion field to previewInfo; extracted source field in installer info.
Modal & Form Adjustments
frontend/pages/hosts/details/cards/HostSoftwareLibrary/HostSoftwareLibrary.tsx, frontend/pages/SoftwarePage/components/forms/SoftwareOptionsSelector/SoftwareOptionsSelector.tests.tsx
Updated SoftwareUpdateModal import path; updated test assertions to expect "automatic installation" message only (removed "self-service" reference for iOS/iPadOS).
Style Cleanup
frontend/styles/global/_global.scss
Removed zero-gap override for last checkbox form-field.

Sequence Diagram

sequenceDiagram
    actor User
    participant Device as Mobile Device<br/>(width < 768px)
    participant SelfService as SelfService Page
    participant Header as SelfServiceHeader
    participant Tiles as SelfServiceTiles
    participant Modal as CategoriesEndUserExperienceModal
    participant Detector as isIpadOrIphoneSoftwareSource

    Device->>SelfService: Render SelfService (isMobileView=true)
    SelfService->>Detector: Check source (isIosOrIpadosApp?)
    
    alt isMobileView is true
        SelfService->>Header: Render mobile variant<br/>(variant="mobile-header")
        SelfService->>Tiles: Render tile layout<br/>(vs table)
        Header->>Header: Use CardHeader<br/>with BEM--mobile-header
        Tiles->>Tiles: Grid of software tiles<br/>with per-tile actions
        User->>Tiles: Click "Install"
        Tiles->>Modal: Open preview modal
        Detector->>Modal: Pass isIosOrIpadosApp=true
        Modal->>Modal: Show mobile preview image<br/>(CategoriesEndUserExperiencePreviewMobile)
    else Desktop view
        SelfService->>SelfService: Render traditional layout<br/>(SearchField + Table)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • SelfServiceCard refactoring (SelfServiceCard.tsx): Major restructuring from inline components to modular pattern; new mobile rendering path with different state handling (filtering, pagination, empty states)
  • Type migration thoroughness (IHostSoftwareWithUiStatusIDeviceSoftwareWithUiStatus): Verify all affected files have been updated and imports corrected; check for any missed references
  • Mobile detection & screen size logic (useIsMobile.tsx, shouldShowUnsupportedScreen): Verify breakpoint consistency (768px) and overlay behavior across all relevant pages/routes
  • iOS/iPadOS prop threading (isIosOrIpadosApp): Trace flow from helpers through multiple component levels to ensure correct values reach all tooltip/preview consumers
  • CSS media query interactions (CoreLayout/_styles.scss): Verify the "low-width-supported" class override doesn't conflict with other responsive styles
  • New component integration (SelfServiceTiles, TileActionStatus, etc.): Verify tile layout, action callbacks, and error/loading state handling work correctly in mobile context

Possibly related PRs

Suggested reviewers

  • jacobshandling
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 32247-selfservice-mobile-width

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b4275ba and 3cbc076.

⛔ Files ignored due to path filters (2)
  • assets/images/categories-end-user-experience-preview-mobile@2x.png is excluded by !**/*.png
  • assets/images/preview-self-service-mobile-icon.png is excluded by !**/*.png
📒 Files selected for processing (52)
  • frontend/components/CardHeader/CardHeader.tsx (1 hunks)
  • frontend/components/CardHeader/_styles.scss (1 hunks)
  • frontend/components/EmptyTable/EmptyTable.tsx (2 hunks)
  • frontend/components/EmptyTable/_styles.scss (1 hunks)
  • frontend/components/MainContent/_styles.scss (1 hunks)
  • frontend/components/Spinner/Spinner.tsx (2 hunks)
  • frontend/components/Spinner/_styles.scss (1 hunks)
  • frontend/components/TableContainer/DataTable/SoftwareNameCell/SoftwareNameCell.tsx (6 hunks)
  • frontend/components/TooltipTruncatedText/TooltipTruncatedText.tsx (4 hunks)
  • frontend/hooks/useIsMobile.tsx (1 hunks)
  • frontend/layouts/CoreLayout/CoreLayout.tsx (3 hunks)
  • frontend/layouts/CoreLayout/_styles.scss (2 hunks)
  • frontend/layouts/UnsupportedScreenSize/helpers.ts (1 hunks)
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareAppStoreVpp/SoftwareAppStoreVpp.tsx (3 hunks)
  • frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareCustomPackage/SoftwareCustomPackage.tsx (3 hunks)
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/EditIconModal/EditIconModal.tsx (6 hunks)
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/EditIconModal/_styles.scss (3 hunks)
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/EditSoftwareModal/EditSoftwareModal.tsx (3 hunks)
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareInstallerCard/SoftwareInstallerCard.tsx (5 hunks)
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareSummaryCard/SoftwareSummaryCard.tsx (1 hunks)
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareTitleDetailsPage.tsx (2 hunks)
  • frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/helpers.ts (1 hunks)
  • frontend/pages/SoftwarePage/components/forms/PackageForm/PackageForm.tsx (2 hunks)
  • frontend/pages/SoftwarePage/components/forms/SoftwareOptionsSelector/SoftwareOptionsSelector.tests.tsx (2 hunks)
  • frontend/pages/SoftwarePage/components/forms/SoftwareOptionsSelector/SoftwareOptionsSelector.tsx (3 hunks)
  • frontend/pages/SoftwarePage/components/forms/SoftwareVppForm/SoftwareVppForm.tsx (3 hunks)
  • frontend/pages/SoftwarePage/components/modals/CategoriesEndUserExperienceModal/CategoriesEndUserExperienceModal.tsx (1 hunks)
  • frontend/pages/SoftwarePage/helpers.tsx (1 hunks)
  • frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx (8 hunks)
  • frontend/pages/hosts/details/DeviceUserPage/_styles.scss (2 hunks)
  • frontend/pages/hosts/details/_styles.scss (1 hunks)
  • frontend/pages/hosts/details/cards/HostSoftwareLibrary/HostSoftwareLibrary.tsx (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/SelfService.tsx (11 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/SelfServiceCard/SelfServiceCard.tsx (5 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/_styles.scss (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/CategoriesMenu/CategoriesMenu.tsx (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceFilters/SelfServiceFilters.tsx (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceFilters/index.ts (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceHeader/SelfServiceHeader.tsx (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceHeader/index.ts (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTable/SelfServiceTable.tsx (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTable/SelfServiceTableConfig.tsx (3 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTable/index.ts (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTiles/SelfServiceTiles.tsx (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTiles/_styles.scss (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/SelfServiceTiles/index.ts (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/TileActionStatus/TileActionStatus.tsx (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/TileActionStatus/_styles.scss (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/TileActionStatus/index.ts (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/components/UpdatesCard/UpdateSoftwareItem/UpdateSoftwareItem.tsx (1 hunks)
  • frontend/pages/hosts/details/cards/Software/SelfService/helpers.ts (2 hunks)
  • frontend/styles/global/_global.scss (0 hunks)

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

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

@ghernandez345 ghernandez345 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.

Looks good. nothing major to change. jsut a few suggestions and questions

data-tip
data-for={tooltipId}
// toggle trigger events based on prop
data-event={isMobileView ? "click" : "mouseenter focus"}

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.

im guessing this is changing the triggering event for showing the tooltip for mobile. Will click work ok here or is a touch event better in this case? I know there are many dom touch events and Im wondering if those are more appropriate here instead of a "click" event.

My guess is that click will work just fine but we probably wanna test it on a real mobile device to see if click or touchstart or touchend work better.

Comment thread frontend/hooks/useIsMobileWidth.tsx
);

// Define paths that will not show the unsupported screen overlay
const lowWidthSupportedPathsRegex = [deviceSelfServiceRegex];

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.

for these is it possible to use the paths we have defined in router/paths.ts? that way if thsoe change then we wont have to come back here to make changes as well

Comment thread frontend/pages/hosts/details/cards/Software/debug.test4153215438 Outdated
@codecov

codecov Bot commented Oct 30, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.50538% with 53 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.21%. Comparing base (b3df8b7) to head (c6652ef).
⚠️ Report is 60 commits behind head on feat-32247-ios-ipados-self-service.

Files with missing lines Patch % Lines
...reTitleDetailsPage/EditIconModal/EditIconModal.tsx 33.33% 9 Missing and 1 partial ⚠️
...e/components/SelfServiceTiles/SelfServiceTiles.tsx 23.07% 10 Missing ⚠️
...details/cards/Software/SelfService/SelfService.tsx 35.71% 9 Missing ⚠️
...end/components/DeviceUserError/DeviceUserError.tsx 53.33% 7 Missing ⚠️
...re/SelfService/SelfServiceCard/SelfServiceCard.tsx 64.70% 6 Missing ⚠️
frontend/hooks/useIsMobileWidth.tsx 76.47% 4 Missing ⚠️
...es/hosts/details/DeviceUserPage/DeviceUserPage.tsx 73.33% 4 Missing ⚠️
...er/DataTable/SoftwareNameCell/SoftwareNameCell.tsx 66.66% 1 Missing ⚠️
...e/components/SelfServiceTable/SelfServiceTable.tsx 90.90% 1 Missing ⚠️
...onents/SelfServiceTable/SelfServiceTableConfig.tsx 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                          Coverage Diff                           @@
##           feat-32247-ios-ipados-self-service   #34758      +/-   ##
======================================================================
- Coverage                               66.21%   66.21%   -0.01%     
======================================================================
  Files                                    2073     2080       +7     
  Lines                                  174715   174893     +178     
  Branches                                 7172     7173       +1     
======================================================================
+ Hits                                   115694   115804     +110     
- Misses                                  48386    48453      +67     
- Partials                                10635    10636       +1     
Flag Coverage Δ
frontend 53.79% <71.50%> (+0.06%) ⬆️

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.

@RachelElysia
RachelElysia dismissed ghernandez345’s stale review October 31, 2025 14:56

ready for re-review, still can't merge until BE is merged

@RachelElysia
RachelElysia changed the base branch from main to feat-32247-ios-ipados-self-service October 31, 2025 16:43
@RachelElysia
RachelElysia merged commit 5d2fe13 into feat-32247-ios-ipados-self-service Oct 31, 2025
15 checks passed
@RachelElysia
RachelElysia deleted the 32247-selfservice-mobile-width branch October 31, 2025 16:49
@RachelElysia
RachelElysia restored the 32247-selfservice-mobile-width branch November 7, 2025 20:34
cdcme added a commit that referenced this pull request Nov 7, 2025
Implements #32247. This is the complete feature branch, consolidating:

- #35018
- #34758
- #35009
- #35181
- #35342

---------

Co-authored-by: Jonathan Katz <44128041+jkatz01@users.noreply.github.com>
Co-authored-by: RachelElysia <71795832+RachelElysia@users.noreply.github.com>
Co-authored-by: Martin Angers <martin.n.angers@gmail.com>
Co-authored-by: jkatz01 <yehonatankatz@gmail.com>
page: 0,
sort_header: "name",
sort_direction: "asc" as "asc" | "desc",
page_size: 9999, // 4.77 Design decision to remove UI pagination

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.

fixed #35917

@RachelElysia
RachelElysia deleted the 32247-selfservice-mobile-width branch April 7, 2026 19:16
@coderabbitai coderabbitai Bot mentioned this pull request Apr 13, 2026
1 task
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.

My device page (self-service) for iOS/iPadOS

2 participants