Skip to content

Commit 44b11d9

Browse files
authored
Merge pull request #276 from objectstack-ai/copilot/optimize-mobile-user-experience
2 parents 28d6857 + 74069fb commit 44b11d9

30 files changed

Lines changed: 197 additions & 117 deletions

ROADMAP.md

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
11
# ObjectOS Roadmap
22

3-
> **Version**: 14.1.0
4-
> **Date**: February 12, 2026
5-
> **Status**: Phase PDeveloper Experience ✅ Complete
3+
> **Version**: 15.0.0
4+
> **Date**: February 13, 2026
5+
> **Status**: Phase QMobile UX Optimization ✅ Complete
66
> **Spec SDK**: `@objectstack/spec@3.0.2`
77
> **ObjectUI**: `@object-ui/*@2.0.0`
88
99
---
1010

1111
## Executive Summary
1212

13-
ObjectOS is a metadata-driven enterprise runtime platform built on the ObjectStack protocol. With all 19 server-side plugins fully implemented, spec compliance at 100%, and the Admin Console operational with 31 pages (including record create/edit), **Phases A–P are complete**. The platform has completed **Phase PDeveloper Experience**, delivering documentation accuracy, code quality tooling, test infrastructure standardization, and developer onboarding improvements.
13+
ObjectOS is a metadata-driven enterprise runtime platform built on the ObjectStack protocol. With all 19 server-side plugins fully implemented, spec compliance at 100%, and the Admin Console operational with 31 pages (including record create/edit), **Phases A–Q are complete**. The platform has completed **Phase QMobile UX Optimization**, delivering responsive layouts, adaptive table columns, touch-friendly headers, and responsive typography across all 31 pages of the Admin Console.
1414

1515
The integration of **@object-ui** (6 packages at v2.0.0) marks a strategic shift: the Admin Console's Business App Shell now leverages @object-ui's `SchemaRenderer` for metadata-driven UI rendering, replacing hand-built components with protocol-compliant controls.
1616

17-
**All roadmap phases are now complete.** The platform is production-ready with comprehensive developer tooling, coverage reporting, plugin scaffolding, and environment health checks.
17+
**All roadmap phases are now complete.** The platform is production-ready with comprehensive developer tooling, coverage reporting, plugin scaffolding, environment health checks, and mobile-optimized UI.
1818

1919
> **@objectstack/\* v3.0.1 Upgrade**: All ObjectStack SDK packages upgraded to v3.0.1 — the latest patch release of the 3.x series, bringing bug fixes and performance improvements while maintaining full protocol compatibility.
2020
2121
### What Changed
2222

23-
| Before (Plan v14.0) | After (Plan v14.1 — This Roadmap) |
24-
| ---------------------------------- | ------------------------------------------------------------------------------------------------------ |
25-
| @objectstack/\* packages at v3.0.0 | **@objectstack/\* packages upgraded to v3.0.1** — latest patch release with bug fixes and improvements |
26-
| Spec SDK at 3.0.0 | Spec SDK updated to 3.0.1 — full protocol compatibility maintained |
23+
| Before (Plan v14.1) | After (Plan v15.0 — This Roadmap) |
24+
| -------------------------------------------- | ------------------------------------------------------------------------------------------------ |
25+
| Phase P was the last completed phase | **Phase Q — Mobile UX Optimization** complete across all 31 Admin Console pages |
26+
| Cards used fixed `px-6` padding | Cards use responsive `px-4 sm:px-6` padding for mobile comfort |
27+
| Layout headers fixed at `h-16 px-4` | Headers adapt to `h-14 px-3` on mobile, `h-16 px-4` on desktop |
28+
| Tables showed all columns on all screens | Non-essential table columns hidden on mobile via `hidden sm:table-cell` / `hidden md:table-cell` |
29+
| Page headings used fixed `text-2xl` | Headings use responsive `text-xl sm:text-2xl` across all pages |
30+
| Header + action button rows used inline flex | Header sections stack vertically on mobile via `flex-col sm:flex-row` |
2731

2832
---
2933

@@ -104,6 +108,7 @@ The integration of **@object-ui** (6 packages at v2.0.0) marks a strategic shift
104108
| **N** | **Enterprise Features** | **Feb 2026** | **✅ Complete** |
105109
| **O** | **Platform Expansion** | **Feb 2026** | **✅ Complete** |
106110
| **P** | **Developer Experience** | **Feb–Apr 2026** | **✅ Complete** |
111+
| **Q** | **Mobile UX Optimization** | **Feb 2026** | **✅ Complete** |
107112

108113
### Phase G Outcomes
109114

@@ -454,6 +459,63 @@ A comprehensive scan of the entire codebase identified the following improvement
454459

455460
---
456461

462+
## Phase Q — Mobile UX Optimization (v3.0.0 — February 2026) ✅
463+
464+
> **Goal**: Evaluate every page and component in the Admin Console, optimize mobile user experience with responsive layouts, adaptive tables, and touch-friendly interactions.
465+
466+
### Q.1 — Shared Component Optimization
467+
468+
| # | Task | Priority | Status |
469+
| ----- | --------------------------------------------------------------------- | :------: | :----: |
470+
| Q.1.1 | Card component: responsive padding (`px-4 sm:px-6`) for all sub-parts | 🔴 ||
471+
| Q.1.2 | SettingsLayout: compact mobile header (`h-14 px-3 sm:h-16 sm:px-4`) | 🔴 ||
472+
| Q.1.3 | AppLayout: compact mobile header with truncated breadcrumbs | 🔴 ||
473+
| Q.1.4 | SettingsLayout: hide ObjectOS label on mobile (`hidden sm:inline`) | 🟡 ||
474+
475+
### Q.2 — Page-Level Responsive Typography
476+
477+
| # | Task | Priority | Status |
478+
| ----- | ------------------------------------------------------------------------------ | :------: | :----: |
479+
| Q.2.1 | All settings page headings: `text-xl sm:text-2xl` (16 pages) | 🔴 ||
480+
| Q.2.2 | Home page: responsive hero text (`text-3xl sm:text-5xl`, `text-lg sm:text-xl`) | 🟡 ||
481+
| Q.2.3 | Business app page headings: `text-xl sm:text-2xl` (5 pages) | 🟡 ||
482+
| Q.2.4 | Organization page headings: `text-xl sm:text-2xl` (5 pages) | 🟡 ||
483+
| Q.2.5 | ObjectUI demo heading: `text-xl sm:text-3xl` | 🟢 ||
484+
485+
### Q.3 — Responsive Table Columns
486+
487+
| # | Task | Priority | Status |
488+
| ----- | ------------------------------------------------------------------------------ | :------: | :----: |
489+
| Q.3.1 | Members table: hide "Joined" column on mobile (`hidden sm:table-cell`) | 🔴 ||
490+
| Q.3.2 | Audit table: hide Record ID / User / Changes columns progressively | 🔴 ||
491+
| Q.3.3 | Jobs table: hide Priority / Created / Retries columns on mobile | 🟡 ||
492+
| Q.3.4 | Invitations tables: hide Expires / Sent columns on mobile | 🟡 ||
493+
| Q.3.5 | Metrics tables: hide Labels / Description columns; histogram hide P50/P99/Max | 🟡 ||
494+
| Q.3.6 | Permissions table: hide Label / Description / Type / Objects columns on mobile | 🟡 ||
495+
| Q.3.7 | Plugins table: hide Version / Uptime / Services / Security columns on mobile | 🟡 ||
496+
| Q.3.8 | Security sessions table: hide IP Address / Created columns on mobile | 🟡 ||
497+
| Q.3.9 | Notifications table: hide Configuration column on mobile | 🟢 ||
498+
499+
### Q.4 — Responsive Header + Action Layouts
500+
501+
| # | Task | Priority | Status |
502+
| ----- | ----------------------------------------------------------------------------- | :------: | :----: |
503+
| Q.4.1 | Members page: header + Invite button stack on mobile (`flex-col sm:flex-row`) | 🔴 ||
504+
| Q.4.2 | Teams page: header + Create Team button stack on mobile | 🟡 ||
505+
| Q.4.3 | Jobs card header: title + filter dropdown stack on mobile | 🟡 ||
506+
| Q.4.4 | Object list toolbar: stack on mobile | 🟡 ||
507+
| Q.4.5 | Object record: title + action buttons stack on mobile | 🟡 ||
508+
| Q.4.6 | Stats card grids: `sm:grid-cols-2 md:grid-cols-4` (Jobs, Notifications) | 🟢 ||
509+
510+
### Q.5 — Mobile-Specific Enhancements
511+
512+
| # | Task | Priority | Status |
513+
| ----- | -------------------------------------------------------------------------- | :------: | :----: |
514+
| Q.5.1 | Members invite button: short label on mobile (`Invite` vs `Invite Member`) | 🟢 ||
515+
| Q.5.2 | Content area padding: `p-3 sm:p-4` in both layouts | 🟡 ||
516+
517+
---
518+
457519
## Release Timeline
458520

459521
### v1.0.0 — Production Release (Target: March 2026)
@@ -540,6 +602,15 @@ A comprehensive scan of the entire codebase identified the following improvement
540602
- ADR directory with ADR-001 (Vitest standardization) ✅
541603
- GitHub issue templates (bug report, feature request, plugin proposal) ✅
542604

605+
### v3.0.0 — Mobile UX Optimization (Target: February 2026)
606+
607+
- Phase Q: Mobile UX Optimization
608+
- Shared component responsive padding (Card, Layouts) ✅
609+
- Responsive typography across all 31 pages ✅
610+
- Adaptive table columns — hide non-essential columns on mobile ✅
611+
- Header + action button stacking on mobile ✅
612+
- Compact mobile headers and content padding ✅
613+
543614
### Master Timeline
544615

545616
```
@@ -581,6 +652,14 @@ Feb 2026 Sep 2026
581652
│ P.3 Test standardization │ │
582653
│ P.4 Onboarding (guides, templates, ADR) │ │
583654
│ v2.1–2.4 Releases │
655+
│ │ │
656+
├── Phase Q: Mobile UX Optimization ─────────┤ │
657+
│ Q.1 Shared component responsive padding │ │
658+
│ Q.2 Responsive typography (31 pages) │ │
659+
│ Q.3 Adaptive table columns │ │
660+
│ Q.4 Header + action stacking │ │
661+
│ Q.5 Mobile-specific enhancements │ │
662+
│ v3.0.0 Release │
584663
▼ ▼ ▼
585664
```
586665

@@ -721,5 +800,5 @@ User Action → React Component → @object-ui/react SchemaRenderer
721800
---
722801

723802
<div align="center">
724-
<sub>ObjectOS v14.1.0 Roadmap — All Phases Complete | Built with @objectstack/spec@3.0.1</sub>
803+
<sub>ObjectOS v15.0.0 Roadmap — All Phases Complete | Built with @objectstack/spec@3.0.2</sub>
725804
</div>

apps/web/src/components/layouts/AppLayout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ export function AppLayout() {
164164
</Sidebar>
165165

166166
<SidebarInset>
167-
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
167+
<header className="flex h-14 shrink-0 items-center gap-2 border-b px-3 sm:h-16 sm:px-4">
168168
<SidebarTrigger className="-ml-1" />
169169
<Separator orientation="vertical" className="mr-2 h-4" />
170170
{/* Breadcrumb navigation — H.2.3 */}
@@ -175,7 +175,7 @@ export function AppLayout() {
175175
recordTitle={breadcrumbRecordTitle}
176176
/>
177177
</header>
178-
<div className="flex flex-1 flex-col gap-4 p-4">
178+
<div className="flex flex-1 flex-col gap-4 p-3 sm:p-4">
179179
<Outlet />
180180
</div>
181181
</SidebarInset>

apps/web/src/components/layouts/SettingsLayout.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ export function SettingsLayout() {
114114
</Sidebar>
115115

116116
<SidebarInset>
117-
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
117+
<header className="flex h-14 shrink-0 items-center gap-2 border-b px-3 sm:h-16 sm:px-4">
118118
<SidebarTrigger className="-ml-1" />
119119
<Separator orientation="vertical" className="mr-2 h-4" />
120120
<div className="flex items-center gap-2">
121121
<Blocks className="size-5 text-primary" />
122-
<span className="font-semibold">ObjectOS</span>
122+
<span className="hidden font-semibold sm:inline">ObjectOS</span>
123123
</div>
124124
</header>
125-
<div className="flex flex-1 flex-col gap-4 p-4">
125+
<div className="flex flex-1 flex-col gap-4 p-3 sm:p-4">
126126
<Outlet />
127127
</div>
128128
</SidebarInset>

apps/web/src/components/ui/card.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
1818
return (
1919
<div
2020
data-slot="card-header"
21-
className={cn('flex flex-col gap-1.5 px-6', className)}
21+
className={cn('flex flex-col gap-1.5 px-4 sm:px-6', className)}
2222
{...props}
2323
/>
2424
);
@@ -45,12 +45,12 @@ function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
4545
}
4646

4747
function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
48-
return <div data-slot="card-content" className={cn('px-6', className)} {...props} />;
48+
return <div data-slot="card-content" className={cn('px-4 sm:px-6', className)} {...props} />;
4949
}
5050

5151
function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
5252
return (
53-
<div data-slot="card-footer" className={cn('flex items-center px-6', className)} {...props} />
53+
<div data-slot="card-footer" className={cn('flex items-center px-4 sm:px-6', className)} {...props} />
5454
);
5555
}
5656

apps/web/src/pages/apps/app.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export default function BusinessAppPage() {
5353
if (!appDef) {
5454
return (
5555
<div className="space-y-4">
56-
<h2 className="text-2xl font-bold tracking-tight">App not found</h2>
56+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">App not found</h2>
5757
<p className="text-muted-foreground">The requested business app is not installed.</p>
5858
</div>
5959
);
@@ -62,7 +62,7 @@ export default function BusinessAppPage() {
6262
return (
6363
<div className="space-y-6">
6464
<div>
65-
<h2 className="text-2xl font-bold tracking-tight">{appDef.label}</h2>
65+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">{appDef.label}</h2>
6666
<p className="text-muted-foreground">{appDef.description}</p>
6767
{appDef.active === false && (
6868
<Badge variant="outline" className="mt-2">

apps/web/src/pages/apps/object-list.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export default function ObjectListPage() {
8383
Back to app
8484
</Link>
8585
</Button>
86-
<h2 className="text-2xl font-bold tracking-tight">Object not found</h2>
86+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">Object not found</h2>
8787
<p className="text-muted-foreground">
8888
The object &ldquo;{objectName}&rdquo; is not defined in this application.
8989
</p>
@@ -103,14 +103,14 @@ export default function ObjectListPage() {
103103
<div className="space-y-6">
104104
{/* Header */}
105105
<div>
106-
<h2 className="text-2xl font-bold tracking-tight">
106+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">
107107
{objectDef.pluralLabel ?? objectDef.label ?? objectName}
108108
</h2>
109109
{objectDef.description && <p className="text-muted-foreground">{objectDef.description}</p>}
110110
</div>
111111

112112
{/* Toolbar — H.4.2 + I.2 bulk actions + I.6 CSV */}
113-
<div className="flex items-center justify-between">
113+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
114114
<ObjectToolbar
115115
objectDef={objectDef}
116116
total={total}

apps/web/src/pages/apps/object-record.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default function ObjectRecordPage() {
5656
Back to list
5757
</Link>
5858
</Button>
59-
<h2 className="text-2xl font-bold tracking-tight">Record not found</h2>
59+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">Record not found</h2>
6060
<p className="text-muted-foreground">The requested record does not exist.</p>
6161
</div>
6262
);
@@ -126,10 +126,10 @@ export default function ObjectRecordPage() {
126126
{objectDef.pluralLabel ?? objectDef.label ?? objectName}
127127
</Link>
128128
</Button>
129-
<div className="flex items-center gap-3">
130-
<h2 className="text-2xl font-bold tracking-tight">{recordTitle}</h2>
129+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center">
130+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">{recordTitle}</h2>
131131
{workflowStatus && <WorkflowStatusBadge status={workflowStatus} />}
132-
<div className="ml-auto flex items-center gap-2">
132+
<div className="flex items-center gap-2 sm:ml-auto">
133133
{/* Clone — I.5 */}
134134
<CloneRecordDialog
135135
objectDef={objectDef}

apps/web/src/pages/apps/record-create.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default function RecordCreatePage() {
4141
Back to list
4242
</Link>
4343
</Button>
44-
<h2 className="text-2xl font-bold tracking-tight">Object not found</h2>
44+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">Object not found</h2>
4545
<p className="text-muted-foreground">Cannot create a record for an undefined object.</p>
4646
</div>
4747
);
@@ -74,7 +74,7 @@ export default function RecordCreatePage() {
7474
{objectDef.pluralLabel ?? objectDef.label ?? objectName}
7575
</Link>
7676
</Button>
77-
<h2 className="text-2xl font-bold tracking-tight">New {objectDef.label ?? objectName}</h2>
77+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">New {objectDef.label ?? objectName}</h2>
7878
<p className="text-muted-foreground">
7979
Create a new {((objectDef?.label ?? objectName) || 'record').toLowerCase()} record.
8080
</p>

apps/web/src/pages/apps/record-edit.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default function RecordEditPage() {
4848
Back to list
4949
</Link>
5050
</Button>
51-
<h2 className="text-2xl font-bold tracking-tight">Record not found</h2>
51+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">Record not found</h2>
5252
<p className="text-muted-foreground">
5353
The requested record does not exist or you do not have permission to edit it.
5454
</p>
@@ -81,7 +81,7 @@ export default function RecordEditPage() {
8181
{recordTitle}
8282
</Link>
8383
</Button>
84-
<h2 className="text-2xl font-bold tracking-tight">Edit {recordTitle}</h2>
84+
<h2 className="text-xl font-bold tracking-tight sm:text-2xl">Edit {recordTitle}</h2>
8585
<p className="text-muted-foreground">
8686
Update this {((objectDef?.label ?? objectName) || 'record').toLowerCase()} record.
8787
</p>

apps/web/src/pages/home.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ export default function HomePage() {
3737
</div>
3838
</div>
3939

40-
<h1 className="text-5xl font-bold mb-4 text-foreground tracking-tight">
40+
<h1 className="text-3xl font-bold mb-4 text-foreground tracking-tight sm:text-5xl">
4141
Welcome to ObjectOS
4242
</h1>
43-
<p className="text-xl mb-8 text-muted-foreground">
43+
<p className="text-lg mb-8 text-muted-foreground sm:text-xl">
4444
A Business Operating System for the ObjectStack Ecosystem
4545
</p>
4646

0 commit comments

Comments
 (0)