-
Notifications
You must be signed in to change notification settings - Fork 16
Mobile Friendly Software
Software is the ninth module made mobileβfriendly, after Tickets, Assets, Calendar, Knowledge, Service Status, Watchtower, Problem Management and Change Management. Same hard rule: one @media (max-width: 768px) block, desktop byteβidentical.
π§° Codeβlevel catalogue of the techniques: Mobile: Techniques & Tricks.
Shipped as #1194, commit 32a2e428. LAYER 24.
viewport = 360 docScrollW = 1119 β on ALL SIX pages, identically
The same 1119 everywhere is itself the diagnosis: the cause cannot be in any one page. It was .header-right in the shared header row β the iOS reflowβtoβdesktop trap β and the module had simply never opted in. Three tags per page took all six to docScrollW === 360.
| Page | State |
|---|---|
software/ β the inventory |
Done β toolbar stacked, filter tabs swipe; the table itself needed nothing |
software/licences/ |
Done β toolbar stacked, table β card feed (24a, 24c) |
software/dashboard/ |
Done by opting in β .dashboard-page + .widget-grid from the Assets round |
software/dashboard/library.php |
Done β toolbar wrapped, table β card feed (24d) |
software/settings/ |
Done by opting in, plus 30px of padding trimmed (24e) |
software/help.php |
Done by opting in β inherits 16h |
π Three of six cost nothing, and the third one is the interesting case.
.software-table is not Software's class. Asset Management's Software tab uses the same name for the same kind of table, and LAYER 15a gave it a card feed β with a bare selector. So the moment this page was opted in, its 1555βrow inventory picked up a finished, deviceβtested layout.
This is Β§15 in its positive form. Two modules sharing a class name is usually a hazard; here it meant the work was already done.
Application Name 324 x 20 "001 Taxis"
Publisher 13 x 17 "β"
Installed On 34 x 17 "1"
I read "Publisher squeezed to 13px" and built a card feed to fix it. That was the card feed, working. 324px is the heading cell at display: block; 13px is the width of the text β in a cell already switched to display: inline.
β The signature of a card feed is cells of wildly unequal width AND height. A real table row shares one height across every cell β 43px here, as the desktop control shows. Three cells 20, 17 and 17px tall are not a table at all.
The duplicate was deleted. It would have outβspecified the shared rule and quietly forked the two modules' appearance.
The one thing 15a never needed and this page does: the loading spinner and empty state are a single colspan cell, which is also :first-child and so was being drawn as the card's heading.
.search-box { width: 350px; } /* the module's own stylesheet */.toolbar-right ran to 465px on the inventory and 561px on licences. Both toolbars stack, the search boxes go full width at 16px (antiβzoom), and the inventory's three filter tabs become a swipe strip.
Scoped to this module's own containers: .search-box and .toolbar-right are names Asset Management, Contracts, Forms and Process Mapper also use.
Six columns, every row 76px tall. As a card feed, five of the six values are selfβdescribing β a type badge, a date, a status pill, a cost. Only the quantity is ambiguous as a bare 15.
.licence-table tbody td:nth-child(3)::before { content: '\00d7 '; }It joins the type badge as "Subscription Γ 15". Γ is a symbol rather than a word, so unlike a CSSβgenerated text label it needs no translation β which is the usual reason this module's card feeds carry no column labels at all.
Adobe Creative Cloud
Adobe Inc.
[Subscription] Γ15 Β· 23 Jul 2026 Β· [Active] Β· Β£7560.00
Rows were 158px tall β the worst crush in the module.
Scoped to .library-container .widget-table rather than to Software, because Asset Management and Tickets carry the same page with the same two class names. Naming the structure means those two inherit it the day they are opted in; neither is today, so neither can see it now.
The table was already scrolling correctly: the deliberately blunt body[data-mobile-page="settings"] table rule catches any table on a settings page. But the shared shell rule keys on .container, and this page (like Morning Checks) uses .settings-container β so it kept 30px of desktop side padding, leaving the table a 264px window. Now 296px.
.library-toolbar-right ran to 527px, turning .dashboard-page into a 527px sideways scroller. The sweep reported zero genuine spills on that page.
The probe was working as written: it ignores anything with a scrolling ancestor, which is the falseβpositive filter added in Change Management Round 1. But here the ancestor scrolls by accident, not by design β .dashboard-page sets only overflow-y: auto, and per spec that computes overflow-x to auto as well (Β§12), exactly as .changes-main did.
A screenshot found it. No measurement did.
π A filter that suppresses false positives will eventually suppress a true one. The two are only distinguishable by whether the scrolling was intended β and that is a question about the CSS, not about the numbers. Where a page has an accidental scroller, "an ancestor scrolls" means "the bug is hidden", not "there is no bug".
| Check | Result |
|---|---|
docScrollW === innerWidth at 360px |
β all six pages β 1119 β 360 |
| Elements past the viewport | β zero, except the two intentional scrollers (inventory filter tabs 450, settings table 1010) |
| Accidental sideways scrollers | β
none β .dashboard-page 527 β contained |
| Licence table | 635 β 352px, rows 76 β 35 + one meta line |
| Widget table | 643 β 312px, rows 158 β 35 + meta + an action row |
| Settings table window | 264 β 296px, still scrolling sideways with its header |
| Desktop @ 1400px | every table table / table-header-group / table-row; toolbars still row at 15px 20px; search boxes still 350/240px at 13β14px; settings still 30px |
| Looked at, not only measured | β five pages β and it is the only thing that caught the library toolbar |
-
An unknown publisher reads as
β Β· 1on the inventory card. Theβis the module's own placeholder and the treatment is inherited from Asset Management, so changing it would change both modules for a cosmetic gain. Left alone deliberately. - The inventory is 1555 rows on a phone. The filter tabs and the search box are the answer to that; an infiniteβscroll or grouped view would be a feature, not a mobile fix.
- Asset Management's and Tickets' widget libraries are not opted in. They will inherit 24d's card feed and toolbar the day they are.
- MobileβFriendly β the overview and the rollout state
- Mobile: Techniques & Tricks β the codeβlevel catalogue
- Mobile: Assets β the round that had already built this module's biggest table
- Software β the module itself
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
- Architecture
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- π Date & Time Formats
- Theming & Dark Mode
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
-
MobileβFriendly
- β³ π« Mobile: Tickets
- β³ π» Mobile: Assets
- β³ π Mobile: Calendar
- β³ π Mobile: Knowledge
- β³ π¦ Mobile: Service Status
- β³ πΌ Mobile: Watchtower
- β³ π§© Mobile: Problem Management
- β³ π Mobile: Change Management
- β³ πΏ Mobile: Software
- β³ β Mobile: Tasks
- β³ π§° Mobile: Techniques & Tricks
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ π Ticket notes: internal or shared
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π’ Ticket numbering
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ ποΈ The folder pane
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- β³ π Scheduled work in your own calendar
- Problem Management
- Tasks
- Assets
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
- Forms
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)