Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-277Done

5.2.5 Attachments panel UI on the issue detail page — strip/list, upload (button + drag-drop), download, gated delete, "Show more" paging

Estimate: 35m · Depends on: 5.2.2, 5.2.4

The management surface: an AttachmentsPanel in app/(authed)/issues/[key]/_components/, mounted in the detail page's reserved Epic-5 slot (between Relationships and Activity per the 5.2.4 design). Built on the 5.2.2 service routes; design-gated by 5.2.4.

Build: the section card (count + view toggle + Attach button); strip and list views per the design (the toggle persisted like 5.1.5's sort preference); per-card download (direct blob URL) + delete (confirm popover; hidden without permission; disabled + tooltip on editor-sourced); the whole-panel dropzone + multi-file picker feeding POST /api/work-items/[id]/attachments with per-file progress + inline typed errors (413/415/429 mapped to the localized messages lib/blob/uploadClient.ts already owns — reuse, don't fork); "Show more (N)" driving the cursor read; skeleton / empty / error states; viewer read-only. Mutations via Server Actions / route calls + router.refresh() (the shipped detail-page pattern). Image thumbnails render from the blob URL (unguessable-public — the recorded serving decision); non-images get the MIME-family glyph from the design's map.

A11y: cards/rows keyboard-reachable with text-conveyed state (source, permissions); the dropzone is an enhancement over the always-present labelled Attach button (drag-only upload would be a keyboard hole); confirm popover focus-managed; extends the detail-route strict axe sweep.

Acceptance criteria

  • The panel matches attachments.mock.html panel-for-panel (strip + list + toggle, card anatomy, editor-sourced indicator + disabled delete + tooltip, upload progress, inline errors, "Show more (N)", skeleton/empty/error, delete confirm, viewer read-only).
  • Upload works via button AND drag-drop (multi-file, per-file progress + per-file error isolation); a viewer sees neither affordance; delete honours the role matrix and the editor-sourced block end-to-end.
  • The list is paged (50 + Show-more, no scroll-position loss); an issue with 120+ attachments never triggers an unbounded read.
  • Colour/shape only through --el-*/element tokens; the strict axe sweep over the detail route with a populated panel stays clean.
  • Component/integration tests: role-matrix rendering, paging, upload error mapping, editor-sourced block; existing detail E2E stays green.

Context refs

  • design/work-items/attachments.mock.html + design-notes (5.2.4) — THE layout authority
  • 5.2.2 routes/DTOs; lib/blob/uploadClient.ts (error-message mapping to reuse)
  • app/(authed)/issues/[key]/page.tsx + _components/ (the reserved slot, ContentSectionCard, the Server-Action + refresh pattern)
  • 5.1.5 (the sibling section that lands beside it — coordinate placement order if both are in flight); finding #57