Skip to content

Tree row icons + single-line layout + drop/paste artifact upload#27

Merged
Extentsoftware merged 4 commits intomainfrom
ui/tree-row-icons-and-attach-drop
May 10, 2026
Merged

Tree row icons + single-line layout + drop/paste artifact upload#27
Extentsoftware merged 4 commits intomainfrom
ui/tree-row-icons-and-attach-drop

Conversation

@Extentsoftware
Copy link
Copy Markdown
Owner

Summary

Three small UX wins addressing direct feedback after running the new multi-feature kickoff.

Tree rows

  • FEAT / CAP text labels become single-glyph icons (◆ initiative, ● feature, ○ capability, ▸ slice) with hover tooltips for the full type name.
  • Tree row grid widens from three to four columns so the phase pill sits inline; rows are now a single line tall.
  • Feature and initiative titles render bold so the parent is unmistakable above the capabilities nested under it.

Artifact attach

  • New drop / paste / pick zone above the existing attach form. Drop a file or click choose a file (a hidden Blazor InputFile); paste an image fires /js/attach-paste.js which forwards the clipboard image as base64 through [JSInvokable] OnImagePastedAsync.
  • Uploaded bytes go through IArtifactBlobStore.PutAsync (ADR-0018) — the returned loom-artifact:// URI auto-fills the canonical pointer; the PO can adjust title / kind before clicking Attach.
  • 25 MB cap with inline error surface.

Test plan

  • dotnet build Loom.sln -p:TreatWarningsAsErrors=true clean.
  • Manual: open Operating Picture, hover the type icon — tooltip reads "Feature" / "Capability" etc.; rows are single-line; feature titles render bolder.
  • Manual: in a Feature Workspace, click + Attach. Drop a PNG onto the dropzone — title auto-fills from filename, blob persists, attach completes.
  • Manual: paste an image (Print Screen → Ctrl+V) while the dropzone is visible — same outcome with auto-generated pasted-… filename.

🤖 Generated with Claude Code

Marcus Poulton added 4 commits May 10, 2026 19:35
Three small UX wins on the Operating Picture and Feature Workspace.

Tree rows
- Replace the FEAT / CAP text labels with single-glyph type icons
  (◆/●/○/▸) that carry a hover tooltip with the full type name.
  Initiatives and features get the accent colour; capabilities stay
  muted so the eye finds the parent first.
- Widen the row grid from three to four columns so the phase pill
  sits inline instead of wrapping below — rows are now one line tall.
- Bold feature and initiative titles so the parent is unmistakable
  next to the capabilities below it.

Artifact attach
- Add a drop / paste / pick zone above the existing attach form.
  Drop a file or click "choose a file" routes through the standard
  Blazor InputFile path; paste an image fires the new
  /js/attach-paste.js helper which forwards the clipboard image to a
  [JSInvokable] OnImagePastedAsync method as base64.
- Uploaded bytes go through IArtifactBlobStore.PutAsync (ADR-0018) and
  the resulting loom-artifact:// URI auto-fills the canonical pointer
  fields. The PO can edit title / kind before clicking Attach.
- 25 MB cap, surfaced inline; failures don't break the form.
The first cut of the dropzone hid the Blazor InputFile inside a label
and intercepted drop with @ondrop:preventDefault, which blocked the
browser from routing the dropped file to the input. Click-to-pick
worked, drag-drop didn't.

- The InputFile is now an absolutely-positioned overlay (transparent,
  full-size) so the browser routes both clicks and drops to it
  natively. The visible content sits beneath with pointer-events:none
  on text and pointer-events:auto on buttons so the "clear" action
  still works.
- Paste listener now binds on window in capture phase. Document-level
  paste can be missed when no editable element has focus; window +
  capture is what other Blazor paste-upload patterns use.
- Added console.debug breadcrumbs in attach-paste.js so missing
  triggers are diagnosable from devtools without server logs.
Pasting a small (~25 KB) image into the artifact attach panel killed
the Blazor circuit: the default SignalR MaximumReceiveMessageSize is
32 KB, and a 25 KB image expands past that after base64 + JSON
envelope.

- Program.cs raises MaximumReceiveMessageSize to 64 MB so a paste up
  to the existing 25 MB upload cap fits comfortably with overhead.
- attach-paste.js no longer dedupes by elementId — when the circuit
  reconnects after a disconnect, the JS listener still holds a dead
  DotNetObjectReference. We now tear down any prior listener for the
  same element and install a fresh one so paste events reach the
  live circuit.
@Extentsoftware Extentsoftware merged commit a863492 into main May 10, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant