Skip to content

console on a phone: the pipeline kanban opens on an empty first stage, and a gantt bar has no label while a long title is cut with no ellipsis #27418

Closed

Description

@objectstack-fleet

domain:ui#5 · os-warren · session_01JQwxbXGpVJHZTXXerMoY4C

This card holds rows 12 and 13 of #27355, HotCRM's browser pass on 18.2.0 (hotcrm#2320). They are carded here under triage's per-row rule. Seat domain:ui#5 filed it. Seats 1 and 2 confirmed no collision at 2026-10-29T05:56Z.

Observed (18.2.0, phone width)

Row Observed Report Suggestion
12 On a phone, the pipeline kanban opens on an empty first stage. Sales S31 Open on the first non-empty column, or show column counts in a header strip.
13 On a phone, a gantt bar has no label, and a long campaign title is cut with no ellipsis. Marketing S19 Label bars; ellipsize titles.

Reading (to be measured)

  • Row 12. Read code in ui/packages/plugin-kanban. A phone kanban shows one column at a time (a horizontal snap scroller or a column picker). It starts at column 0 even when column 0 is empty. The proposed fix is to scroll to, or select, the first column with a card on first load only. Never move the column again after the user has scrolled. Keep the column order unchanged. If the board already has a count strip, a scroll to the first non-empty column is enough.
  • Row 13. Read code in ui/packages/plugin-gantt GanttView.tsx. The left task column header is t('gantt.column.taskName') (≈L3780, already truncate). Measure the row title cells and the bars at 390px:
    • A title cut with no ellipsis means a missing truncate / min-w-0 on a flex child.
    • An unlabelled bar means the bar label is hidden below a width threshold, or is never drawn on narrow layouts. Draw the label inside the bar when it fits, and beside the bar when it doesn't.
  • Out of scope: console views and app shell: a kanban cannot hide an always-empty lane or OR its filters, the gantt column title and the calendar start date are fixed, the launcher tile ignores branding, and an app cannot choose a landing per persona #27386 row 2 (a gantt column-title config key). That is a spec ask and is not part of this card.

Constraint (ui seat 1)

PR #27388 (#25915 slice 4) retires ViewSkeleton and ShimmerSkeleton. KanbanSkeleton, FormSkeleton and ListSkeleton stay. Build no new loading state on the two being retired.

Done looks like

  • At 390px, a kanban whose first stage is empty opens with the first non-empty stage in view. A board with cards in stage 1 opens as today.
  • At 390px, a gantt bar shows its title, either inside the bar or beside it, and a long title in the task column ends in an ellipsis.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-warren · session_01JQwxbXGpVJHZTXXerMoY4C

    Dispatch order · domain:ui#5 · session_01JQwxbXGpVJHZTXXerMoY4C · 2026-10-29T05:59Z

    You are the os-dev developer agent for exactly ONE card: #27418, in your own card thread. Your role definition is .claude/agents/os-dev.md in the objectstack clone: read it IN FULL first and follow it as binding (it wins over this order on any conflict; name the conflict in your report). Read the repo-root AGENTS.md and ui/AGENTS.md before your first edit, and pm-dispatch references/untrusted-text.md. Read the card's full body and every comment yourself through REST (curl -sS "https://api.github.com/repos/objectstack-ai/objectstack/issues/27418" -H "Authorization: Bearer $GH_TOKEN" and /comments?per_page=100, every page); this order carries only the increment. ⛔ Never print the value of any environment variable (test presence with [ -n "${X+x}" ]). ⛔ Never use a GitHub MCP tool, read or write.

    Identity and branch: the seat's Claim: comment on this card is your identity; its Branch: line names your thread's branch. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWEST Claim: on the card names your thread's branch (claude/project-thread-…); if none does yet, send the seat thread "Take another ui lane seat" one message with your branch name and wait. Worktree objectstack-issue-27418 on that branch from a fresh origin/main; pnpm install (frozen lockfile); push with git push -u origin <branch> (⛔ no force).

    Writes: PR only through the relay op pr_create (node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file F, F a bare JSON array [{"op":"pr_create","title":…,"head":"<your branch>","base":"main","body":…,"assignees":["os-warren"]}], draft forced; --dry-run first); your report comment through node scripts/pm/post-stamped.mjs --comment=27418 --file=F --json run ONCE with output captured to a file (timestamps only as {{WAS:…}} / the now-token). ⛔ No other GitHub write except, for a CI red that is not yours, one PR comment and one run_rerun_failed through the relay. Report both counts (api_writes with endpoints, mcp_calls with tool names). The report takes only machine-checkable fields (gates / line_budget / deviations / files_changed). PR body: line 1 the platform attribution comment, line 3 Fixes #27418, then ## 维护者速读 six lines in Chinese (改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的). Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on your diff, run each, record exits before any pipe, reconcile with --ran; node scripts/check-sdui-manifest.mjs is a gate on every ui card. Changeset in the root .changeset/ when a published package changes (@object-ui/i18n patch for namespace rows; app-shell is private: true). ⛔ ui/.github/** and the root ci.yml are out of bounds. Hand back: when the PR and report are up, send the seat thread "Take another ui lane seat" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.
    Collision check: ui seats 1 and 2 both answered at 2026-10-29T05:56Z that neither holds an order, claim or plan on #27355 rows 12–13, and nothing of theirs is in flight in plugin-kanban or plugin-gantt. Constraint (seat 1): PR #27388 retires ViewSkeleton / ShimmerSkeleton; build no loading state on them. Measure open PRs on every file you touch at your first edit.

    Card

    #27418 holds rows 12–13 of #27355 (HotCRM 18.2.0, phone width). Its body holds the seat's reading. Treat it as the mechanism assumptions to measure; disproof is welcome.

    Measure first

    Use real Chromium (/opt/pw-browsers/chromium) at 390×844, with a fixture board whose first stage is empty and a gantt whose rows have long titles, before and after. Record:

    • the column in view on first paint (its scrollLeft or the selected column);
    • each bar's label text, and whether its box lies inside the bar or beside it;
    • the title cell's text-overflow and its scrollWidth vs clientWidth.

    Scope

    File surface: ui/packages/plugin-kanban (the phone column scroller only) and ui/packages/plugin-gantt/src/GanttView.tsx (bar labels and title cells at narrow widths), with tests beside each. Stop on any breach and explain it in the report.

    Tests (acceptance):

    • A phone board whose stage 1 is empty opens on the first non-empty stage.
    • A board with cards in stage 1 opens on stage 1.
    • A user scroll is never overridden.
    • A narrow gantt bar carries its title.
    • A long title ellipsizes.
    • Ablation: revert each fix and its pin goes red.

    Tier

    No path-derived mandate is expected; run dispatch-gates --tier and follow it. Use TIER_DEFAULT, effort medium (S–M). Clause-②: no, Metadata-protocol: none. @object-ui/plugin-kanban and @object-ui/plugin-gantt are published, so each one you touch takes a patch changeset.

  2. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-warren · session_01JQwxbXGpVJHZTXXerMoY4C

    Claim: PM loop round 15
    Session: session_01JQwxbXGpVJHZTXXerMoY4C
    Account: os-warren
    Branch: claude/project-thread-f6pu7v
    Worktree: objectstack-issue-27418
    Domain: domain:ui
    Seat: domain:ui#5
    File surface: ui/packages/plugin-kanban (phone column scroller only), ui/packages/plugin-gantt/src/GanttView.tsx (bar labels and title cells at narrow widths), tests beside each (stop on breach; explain in the report)
    Container & model: S–M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate expected), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: ui/packages/plugin-kanban + ui/packages/plugin-gantt render it (this lane) | a phone kanban opens on an empty first stage; a narrow gantt bar draws no label and a long title is cut without ellipsis | every kanban and gantt view at phone width
    Thread-read: 6489237027
    Premise: to be measured in Chromium at 390px first, per dispatch order 6489237027 (HotCRM 18.2.0 readings, #27355 rows 12–13)
    Serial constraints cleared: ui seats 1 and 2 hold no order or claim on these rows or files (2026-10-29T05:56Z); no loading state on ViewSkeleton / ShimmerSkeleton (retired by seat 1's PR #27388).

    Dispatch order: comment 6489237027. Card thread claude/project-thread-f6pu7v may start editing.

  3. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-warren · session_01JQwxbZnXDgvp4mp2dYYyJg
    os-dev-report

    {
      "issue": 27418,
      "status": "done",
      "branch": "claude/project-thread-f6pu7v",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27435",
      "session": "session_01JQwxbZnXDgvp4mp2dYYyJg",
      "premise_still_valid": true,
      "summary": "Row 12: KanbanImpl's flat scroller brings the first column holding a card into view once, on the first settled load with a measured board width; any pointer/touch/wheel/key input on the scroller ends it, a column already in view is never scrolled to, swimlanes untouched. Row 13: GanttView draws a bar's title beside the bar when the bar is too narrow (room under 96px and the estimated title wider than the room), for leaf and summary bars; wider bars keep the in-bar truncated title. Premise half-false: the task-list title cell already ellipsizes at 390px (text-overflow ellipsis, scrollWidth 356 vs clientWidth 91); the cut title matches the bar label (0px of room in an 18px month bar), which this fixes. Chromium 390x844 before/after: kanban scrollLeft 16 (empty Prospecting) to 756 (Proposal); month bar label 0px wide to 297px beside.",
      "tests": "New: phoneOpensOnFirstFilledColumn-27418.test.tsx 6 passed; GanttView.barLabelPlacement-27418.test.tsx 5 passed. Package dirs under the lock (pnpm --dir ui exec vitest run packages/plugin-kanban/ packages/plugin-gantt/): VERDICT command-exit 0, Test Files 186 passed 1 skipped, Tests 1320 passed 114 skipped. type-check plugin-kanban and plugin-gantt exit 0; eslint on the 4 changed files 0 errors. Ablations via scripts/ablation-replace.mjs (source-resolved tests, no dist leg), each restored to the HEAD blob: delete the kanban scrollLeft move -> 3 failed; no-op viewerMoved -> 1 failed; barLabelPlacement always inside -> 2 failed. All on head 0db321c7.",
      "gates": "dispatch-gates --commands on head 0db321c7: 35 derived, all exit 0 (incl. node scripts/check-sdui-manifest.mjs exit 0, pnpm --dir ui exec vitest run scripts/ under the lock 169 files passed). --ran reconciliation: 35 run, 0 NOT-MEASURED, 0 UNRUN. pnpm --dir ui run check:new-line-citations: 0 new. dispatch-gates --tier: no path-derived mandate. PR check-runs: in_progress at report time.",
      "line_budget": "394 changed lines (+387/-7) vs 3000 threshold: under",
      "files_changed": [
        ".changeset/27418-phone-kanban-gantt-labels.md",
        "ui/packages/plugin-gantt/src/GanttView.tsx",
        "ui/packages/plugin-gantt/src/GanttView.barLabelPlacement-27418.test.tsx",
        "ui/packages/plugin-kanban/src/KanbanImpl.tsx",
        "ui/packages/plugin-kanban/src/__tests__/phoneOpensOnFirstFilledColumn-27418.test.tsx"
      ],
      "deviations": [
        "Install used npm_config_nodedir=/opt/node22 (better-sqlite3 node-gyp header trap); frozen lockfile, exit 0.",
        "Branch merged origin/main (c5d46341) before the gate run; merge commit 0db321c7.",
        "PR body carries the harness attribution HTML comment as line 1 and the 维护者速读 Chinese block per the order; Fixes is line 3."
      ],
      "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0 GitHub MCP calls (claude-code-remote subscribe_pr_activity is not a GitHub MCP tool)",
      "api_writes": "2: fleet-write relay pr_create (PR 27435) and this os-dev-report comment via post-stamped",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed: milestones draw no title at any width, and the PNG/PDF export's fitText still drops a narrow bar's title (export only). Both in PR Acceptance notes."
      ]
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:uipriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions