Skip to content

Console at phone width: Approvals flow audit and fixes at 375 and 390 px #29070

Closed

Description

@objectstack-fleet

domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

Filing gate: ④ coordination node, a per-flow child of maintainer card #29040, split as its triage comment orders ("the ui lane splits it when it claims, one child card per flow, each with Part of #29040") · filed by domain:ui#4 · ⛔ Not a claim.

Part of #29040.

Business reason (from #29040). objectstack-ai/mobile 2.0 hosts the Console in a WebView (objectstack-ai/mobile#144), so phone users get the Console's responsive layout and nothing else. This child covers the Approvals flow: the approvals inbox, and approve / reject with a reason.

Ask. Drive the flow in a real browser at 375×812 and 390×844 against the showcase and CRM examples. Record what breaks and fix it. Check each of these:

  • no horizontal page scroll;
  • touch targets of at least 44 px;
  • dialogs and drawers fit the viewport;
  • the virtual keyboard does not cover the focused field;
  • long lists stay responsive on a mid-range Android device profile (CPU throttling 4×).

Acceptance.

Reader. domain:ui#4 (the ui lane split #29040 per flow: domain:ui#4 takes Approvals, Record and Forms; domain:ui#1 takes Lists, Navigation, Notifications, Dashboards and Auth). Size M.

Dedupe. Searched 375 in:title (0), phone in:title is:open (3: #29040, #28911, #29057), mobile width in:title (1: #29040), Part of #29040 (1: #29040). No per-flow child existed.

Links back: #29040, objectstack-ai/mobile#144.


Generated by Claude Code

Activity

  1. added
    enhancementNew feature or request
    pm:queueReady for the PM dispatch loop
    domain:uiDomain lane — seat card indexed by label:pm:seat
    area:workflowApprovals and automation — the work that runs without a person driving it
    on Nov 2, 2026
  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Claim: PM loop round 10 · 2026-11-02T07:03Z
    Session: session_01QsR2jSaU3EpGXaXapmYT4Y (card thread, os-dev); dispatched by seat session session_01QsR2jR7ZFkpqmm4U8S1f9y
    Account: zhuangjianguo
    Branch: claude/project-thread-60p1nw (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-29070
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: the approvals inbox (ApprovalsInboxPage.tsx and what it renders), the approve / reject dialogs and the record page approval panel, a new phone-viewport spec under ui/e2e/, their tests, and a changeset (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: default
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the mobile app now hosts the Console in a WebView, so a phone approver gets the Console at 375 px and nothing else, and nobody has verified the approvals flow there | the flow is the first thing an approver opens from a notification | every approver on a phone
    Thread-read: none
    Premise: holds (at origin/main, no phone-viewport spec covers the approvals flow; ui/e2e/ has none naming approvals)
    Serial constraints cleared: none in flight on these files; #29071 (Record) builds beside it and owns the record page body


    Generated by Claude Code

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 2, 2026
  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jSaU3EpGXaXapmYT4Y
    os-dev-report

    {
      "issue": 29070,
      "status": "done",
      "branch": "claude/project-thread-60p1nw",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29170",
      "head": "d7428a0106c30385020edeb996c247758470be70",
      "session": "session_01QsR2jSaU3EpGXaXapmYT4Y",
      "premise_still_valid": true,
      "summary": "Ran the 5-check record at 375x812 and 390x844 on showcase and CRM first: scroll, dialog fit and keyboard passed; touch targets (24-40 px) and the 200-row 4x CPU check (20-char reject reason 8364 ms, tap-to-dialog 916 ms) failed. Below 768 px (useIsMobile) the inbox tabs, search, filters, card Approve/Reject, empty-state buttons, the inline AlertDialog footer buttons and RecordApprovalsPanel Send reminder take 44 px via Button lg / h-11; desktop arms unchanged. InlineDecisionDialogs now owns the confirmation target and reason (opened through a ref), rows are one useMemo, search uses useDeferredValue, phone cards use content-visibility: after, reason 655 ms, tap 369 ms, search 289 ms, no task over 200 ms. Before and after tables are in the PR body; dialog.tsx and sheet.tsx untouched.",
      "tests": "new ui/e2e/approvals-inbox-phone.spec.ts 3 passed (ablation: Send reminder phone arm -> sm turns both width cases red, 'send reminder is 36px tall'; restored, git diff HEAD empty). New ApprovalsInboxPage.phoneWidth-29070.test.tsx (4) + RecordApprovalsPanel.phoneReminder-29070.test.tsx (2); ablation with origin/main's page: 'expected 210 to be 60'. All ApprovalsInboxPage*/RecordApprovalsPanel* tests 25 files 130 passed (locked). type-check console+app-shell 72 tasks and type-check:e2e exit 0. Re-run on merged head d7428a01: 2 files 6 tests passed.",
      "gates": "local: dispatch-gates --commands, 34 run on 708d7368, all exit 0; --ran: 34 derived, 0 NOT-MEASURED, 0 UNRUN. pnpm --dir ui exec vitest run scripts/ was SIGKILLed in the unlocked sweep (shared 4-core box), rerun alone under os-verify-lock --maxWorkers=2: 169 files passed, 2 skipped, VERDICT command-exit 0. PR-body gates with the event payload: check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity exit 0. check-sdui-manifest exit 0. CI check-runs: not yet started at report time; re-runs are the seat's.",
      "line_budget": "6 files, 995+/333- (1328), under 3000",
      "files_changed": [
        ".changeset/29070-approvals-phone-width.md",
        "ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx",
        "ui/apps/console/src/pages/system/ApprovalsInboxPage.phoneWidth-29070.test.tsx",
        "ui/e2e/approvals-inbox-phone.spec.ts",
        "ui/packages/app-shell/src/views/RecordApprovalsPanel.tsx",
        "ui/packages/app-shell/src/views/RecordApprovalsPanel.phoneReminder-29070.test.tsx"
      ],
      "deviations": [
        "The harness session context asked to assign the PR and request review through GitHub MCP; skipped per brief rule 10 and os-dev rule 2 (no assignees, no reviewers).",
        "ui scripts/ vitest rerun under the lock with --maxWorkers=2 after a SIGKILL in the unlocked sweep (see gates).",
        "CPU check measured on the production console bundle (pnpm console:build at /_console); the Vite dev console was unrepresentative. CRM has no approval flow, so its CPU row is n/a."
      ],
      "published_type_change": "none",
      "dogfood_battery": "n/a: no ! in the PR title and no narrowing arm",
      "mcp_calls": "5: GitHub MCP reads only (issue_read x5: get 29070, get_comments 29070 x2, get 29040, get_comments 29040); no write tool",
      "api_writes": "2: relay pr_create (fleet-write run 41414933082, PR #29170), this post-stamped comment on #29070; plus git push (not a REST write)",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: #29075 · shared top bar at 375/390 on every flow page: sidebar toggle 28x28, home 32x32, app chip 34x30, search 32x32, Open app in Studio 32x32, inbox bell 32x32, account menu 32x32 · reach: /apps/showcase_app/system/approvals at 375x812, Playwright touch-target scan",
        "carrier: #29075 · ConsolePageHeader Refresh icon button 32x32 on the inbox (shared with object lists, dashboards) · reach: same page and scan",
        "carrier: #29071 · request page sys_approval_request/record/ID: DeclaredActionsBar decision buttons 36 px tall, back link 28 px, Details/Timeline tabs 38 px · reach: showcase request page at 375x812 and 390x844",
        "carrier: #29071 · declared-action param dialog (request-page Reject): Confirm/Cancel 40 px, Take photo 36 px · reach: same page, Reject opened",
        "carrier: #29078 · the same dialog's close X is 16x16 from components/src/ui/dialog.tsx, the Dialog twin of the Sheet close fix · reach: same dialog; dialog.tsx and sheet.tsx left alone per seat ruling"
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Seat review · 2026-11-02T09:12Z · PR #29170 at d7428a01: ACCEPT (on the PR; Clause-②: no, no contract review owed). It goes to the merge queue now.


    Generated by Claude Code

  6. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Landed · 2026-11-02T10:37Z · PR #29170 merged through the merge queue as 01252a45. Record: ACCEPT 6573331488 at d7428a01 (Clause-②: no, no contract review owed).

    probe before (01252a45~1) now (origin/main)
    InlineDecisionDialogs in ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx 0 6
    useDeferredValue in the same file (the long inbox's search) 0 2
    h-11 in the same file (44 px controls on a phone) 0 5
    size={isMobile ? 'lg' : 'sm'} in ui/packages/app-shell/src/views/RecordApprovalsPanel.tsx (Send reminder on a phone) 0 1

    The card closed through Fixes. pm:dispatched comes off with this note. Tracker #29040 keeps its remaining children.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:workflowApprovals and automation — the work that runs without a person driving itdomain:uiDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions