MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-431

6.14.1 Design — the "this epic is not public" placeholder (tree-expand + detail child-panel) + the private-epic public row + the project-admin set-private control

Done
Description

Estimate: 50m

Type: design (THE design gate — produced FIRST; every UI code subtask here — 6.14.5, 6.14.6, 6.14.7 — depends on this card and is blocked until it lands). Produce the surface design assets under motir-core/design/epic-privacy/, composing ONLY shipped components/ui/* primitives + --el-* colour tokens + [data-display-style] shape tokens (NO Tier-0 --color-*, no hand-rolled spacing/radius), mirroring 7.0.1’s multi-panel design-card shape.

The surfaces to draw (every panel — the multi-panel rule, mistake #31):

  • Panel 1 — the private epic’s PUBLIC row (in the tree + the roadmap/board). How a private epic appears to a public/non-member viewer: the epic title + kind icon (IssueTypeIcon) STILL shown, plus a "private" badge (a Pill tone) that reads e.g. "Not public", and crucially NO child count, NO progress bar / rollup, NO point total — draw the row deliberately WITHOUT those aggregate tells (contrast it with a normal epic row that DOES show count/progress so the difference is explicit in the mock). Note in writing that the tells are stripped server-side, not just visually omitted.
  • Panel 2 — the TREE-EXPAND placeholder. When the public viewer EXPANDS the private epic in the work-item tree, the children rows are replaced by a single "this epic is not public" placeholder row (an EmptyState-family inline panel) — the exact copy, the icon, and the one-line explanation ("The project admin has kept this epic’s contents private."). Draw it inline at the child-indent level so it reads as "this is where the children would be".
  • Panel 3 — the DETAIL child-panel placeholder. On the epic’s work-item DETAIL page, the CHILD PANEL (the panel that lists children/sub-issues) shows the same "this epic is not public" statement instead of a child list — drawn in the detail-page child-panel slot (distinct framing from the inline tree row; same copy + tone).
  • Panel 4 — the project-admin "set epic private" control. The control the project admin (6.4) uses on the epic to set/unset private — e.g. a toggle / segmented control in the epic’s actions or settings area, with explanatory copy ("Private epics stay visible as a row to the public, but their stories/tasks and progress are hidden from non-members."), its ON and OFF states, and the project-admin-gated / read-only-for-non-admins treatment.
  • Panel 5 — the MEMBER view (the contrast / control case). The SAME private epic as a project MEMBER sees it: children present, real count / progress / points shown, NO placeholder — so the mock makes the member-bypass explicit and the reviewer can see exactly what the public viewer is denied.
  • Panel 6 — states. The placeholder’s appearance in a dense tree (many siblings), the badge at the board/roadmap card scale, and the admin control’s loading / disabled (non-admin) / error states.

Write design/epic-privacy/design-notes.md naming every primitive composed (e.g. IssueTypeIcon for the epic hue, Pill for the "private" badge tone, the EmptyState family for the placeholder, the toggle/segmented primitive for the admin control), the EXACT copy for the placeholder (tree + detail), the badge label, and the admin-control explanation + states, the per---el-* colour role for every element (use the palette, not grey-only — finding #54; e.g. the "private" badge tint, the placeholder’s muted-but-legible tone), and a "primitives composed (no hand-rolling)" checklist. It MUST state, in writing, that (a) the epic ROW stays visible (title + badge) while its children + aggregate tells (count / progress / points) are ABSENT for public viewers, (b) the same "not public" copy appears in BOTH the tree-expand and the detail child-panel, (c) members see everything (no placeholder), and (d) the set-private control is project-admin-gated.

Acceptance criteria

  • design/epic-privacy/*.mock.html renders the six panels above, referencing ONLY --el-* + [data-display-style] tokens (no Tier-0 --color-*, no hand-rolled spacing/radius) + shipped components/ui/*.
  • The private-epic public row is drawn with title + "private" badge and WITHOUT child count / progress / point total (contrasted against a normal epic row that shows them); the member-view panel shows the same epic WITH children + rollups.
  • The "this epic is not public" placeholder is drawn in BOTH the tree-expand (inline at child indent) and the detail child-panel slots, with identical copy; the project-admin set-private control is drawn with ON/OFF + the admin-gated / read-only-for-non-admins states.
  • design-notes.md names every primitive + the exact placeholder / badge / admin-control copy + the per-element --el-* role, and states the row-visible / children-and-tells-absent / two-places / member-bypass / admin-gated invariants; AA contrast holds for the "private" badge tint + the placeholder text.

Context refs

  • scripts/plan-seed/data/story-7.0.ts § 7.0.1 — the multi-panel design-card shape to mirror.
  • scripts/plan-seed/data/story-6.12.ts § 6.12.1 — the public project-view / board / roadmap design this composes with (the public row + the public surfaces the badge/placeholder appear on).
  • GitLab confidential issues (https://docs.gitlab.com/ee/user/project/issues/confidential_issues.html) + Canny public-roadmap visibility (https://help.canny.io/en/articles/3828148-public-roadmap) — the hidden-from-non-members + "what shows publicly" surfaces being mirrored.
  • motir-core/components/ui/*, app/globals.css (the --el-* + [data-display-style] token layers), motir-core/CLAUDE.md § colour + shape tokens; IssueTypeIcon / Pill / EmptyState (the kind-hue + badge + placeholder primitives).