Files
multica/apps/mobile/components
e10287cf1b MUL-6457 feat(mobile): resolve custom issue statuses by category (#7286)
* feat(mobile): resolve custom issue statuses by category (MUL-6457)

Mobile had no awareness of the workspace status catalog, so the custom
statuses web can now define (MUL-6243) degraded badly on iOS: an issue on a
custom status disappeared from My Issues and the workspace Issues list
entirely, the status picker could not offer one, and filter rows rendered a
raw key or nothing at all. `custom_issue_statuses` is a deployment-level
flag, so creating a status on web hit iOS users of the same deployment
immediately.

The root cause is one mistake repeated: mobile bucketed and labelled issues
by status KEY, while a status key's presentation and behavior come from its
CATEGORY. A `qa` bucket existed and no section ever read it.

- Fetch the catalog once per workspace (`GET /api/issue-statuses`, archived
  included so an issue left on an archived status keeps its real name).
- Group lists by category via `groupIssuesByCategory`, extracted from the two
  screens that held the same fifteen lines — and the same bug — twice.
  Grouping reads the server-resolved `status_category`, so it never waits on
  the catalog and never guesses while one is in flight.
- Offer `statusOptions()` in both the picker and the status filter, so a
  status settable in one can never be missing from the other.
- Resolve name and colour through the catalog wherever a status key is shown
  (detail chip, search, inbox row and detail label, timeline). Built-ins keep
  mobile's own copy and their category token; the glyph is per category, so a
  custom status reads as the same kind of thing.
- Keep `status_category` consistent with an optimistic status write, so the
  detail cache cannot feed a stale category to the recent-issues rows.

A workspace with no custom statuses renders exactly as before: a built-in key
is its own category, so every lookup resolves without the catalog.

Co-authored-by: multica-agent <[email protected]>

* fix(mobile): name custom statuses on rows and judge closed by category

Addresses review on #7286.

A section header names a CATEGORY, so "Code Review" and "QA" both land under
In Review and the row was the only place left to tell them apart — and it said
nothing. `IssueRow` now renders a `<CustomStatusChip>` next to the title,
mirroring web's `list-row.tsx`. It stays silent for a status that already is
its category's built-in, so a workspace with no custom statuses renders exactly
as before. Covering it in `IssueRow` reaches all four surfaces at once: My
Issues, the workspace Issues list, project detail, and pins.

The icon-only entry points had the same identity loss with no room for a chip,
so they get the catalog colour instead — `IssueRow`'s `showStatus` path (pins),
the mention suggestion bar, and the mention picker.

Separately, the mention bar dimmed closed issues with `status === "done"`, so
an issue on a custom status in the done category rendered at full opacity as
though the work were still open. It now asks the question every status-coupled
rule actually asks — does this issue BEHAVE as done or cancelled — through
`issueBehavesAsAny`, mirroring the core helper of the same name.

Also adds the `// @vitest-environment node` pragma the repo asks for on the two
new pure-logic suites. Mobile's vitest config is already node-only, so this is
documentation rather than a behavior change.

Co-authored-by: multica-agent <[email protected]>

---------

Co-authored-by: J <[email protected]>
Co-authored-by: multica-agent <[email protected]>
2026-08-20 14:23:59 +08:00
..