Epic: Art Studio → faithful ArtPipe (ProArt) UI/UX — land on Pipeline, adopt Eric's 4-view GitHub-dark shell #446

Open
opened 2026-07-07 05:49:43 +00:00 by spikerj · 3 comments
Owner

Goal

Clicking Art Studio in the menu should land in Eric's ArtPipe Pipeline view, and the whole tool should match his UI/UX (running reference: http://127.0.0.1:5050/; source read-only at /Volumes/art_pipe/art_pipe/src/artpipe). Today our Art Studio is Angular Material and composer-first — it looks nothing like his.

Approach (decided: re-skin + re-IA)

Restructure the art-studio entry into his 4-view shell and restyle our EXISTING, already-backend-wired Angular components to his look — do not rebuild from scratch. Keep all data wiring (services, SignalR, MediatR-backed endpoints); change the shell/IA and the skin.

Source of truth

  • IA / top nav: Pipeline (default landing) · Library · Metrics · Builder, + KPI strip, pipeline controls (Pause/Resume/Stop/Restart + idle status), System panel (Activity/Workers/Watcher), slide-out Generate drawer.
  • Theme tokens (GitHub-dark, exact): --bg:#0d1117 · --surface:#161b22 · --surface-2 · --border:#30363d · --text:#e6edf3 · --text-2 · --accent:#58a6ff · --ok:#3fb950 · --warn:#d29922 · --err:#f85149 · --purple:#bc8cff · --radius:6px · --radius-lg:8px · font -apple-system…, mono ui-monospace…. Primitives captured: .nav-*, .nav-kpi-chip.{accent,ok,warn,err}, .filter-chip, .card-*, .drawer.

View mapping (his view → our components to re-skin)

ArtPipe view Our existing components (reuse + restyle)
Pipeline (landing) ArtStudioShell frame + ArtPromptComposer (→ Generate drawer), ArtStageTimeline/ArtStageConsole, ArtAssetCard/ArtActivityPanel (Now-Running/queue), controls
Library ArtGallery / ArtAssetLibrary / ArtAssetCard
Metrics ArtMetricsDashboard + art-chart
Builder ArtPipelineBuilder
System panel ArtActivityPanel / ArtActivityLauncher (Activity/Workers/Watcher tabs)

Phased plan (one shippable, lint+build-verified Angular PR per phase)

  • P1 — Shell + theme foundation + Pipeline landing. New ArtPipe-style shell: brand + 4-tab nav + KPI strip + his GitHub-dark theme tokens (scoped to the feature). Route navigateToTool('art-studio') → Pipeline. Existing components slotted into tabs (un-restyled inner content OK this phase). This is the keystone; delivers "click Art Studio → land in his Pipeline with his chrome."
  • P2 — Pipeline view fidelity. Generate drawer, pipeline controls (Pause/Resume/Stop/Restart), Now-Running board, live console, queue-status — match his layout/interactions.
  • P3 — Library re-skin to his card grid + filter-chips.
  • P4 — Metrics re-skin (his stat cards / charts styling).
  • P5 — Builder re-skin + System panel (Activity/Workers/Watcher) fidelity.
  • P6 — polish pass: side-by-side diff vs :5050, close visual deltas.

Constraints

  • Angular; run pnpm run lint:fix + pnpm run lint:styles:fix + build before each PR. Keep transloco keys. Reuse backend wiring; no backend changes expected.

Tracking issue; per-phase PRs will reference this. Starting P1.

## Goal Clicking **Art Studio** in the menu should land in Eric's ArtPipe **Pipeline** view, and the whole tool should match his UI/UX (running reference: `http://127.0.0.1:5050/`; source read-only at `/Volumes/art_pipe/art_pipe/src/artpipe`). Today our Art Studio is Angular Material and composer-first — it looks nothing like his. ## Approach (decided: **re-skin + re-IA**) Restructure the `art-studio` entry into his **4-view shell** and restyle our EXISTING, already-backend-wired Angular components to his look — do **not** rebuild from scratch. Keep all data wiring (services, SignalR, MediatR-backed endpoints); change the shell/IA and the skin. ## Source of truth - **IA / top nav:** `Pipeline` (default landing) · `Library` · `Metrics` · `Builder`, + KPI strip, pipeline controls (Pause/Resume/Stop/Restart + `idle` status), System panel (Activity/Workers/Watcher), slide-out **Generate drawer**. - **Theme tokens (GitHub-dark, exact):** `--bg:#0d1117` · `--surface:#161b22` · `--surface-2` · `--border:#30363d` · `--text:#e6edf3` · `--text-2` · `--accent:#58a6ff` · `--ok:#3fb950` · `--warn:#d29922` · `--err:#f85149` · `--purple:#bc8cff` · `--radius:6px` · `--radius-lg:8px` · font `-apple-system…`, mono `ui-monospace…`. Primitives captured: `.nav-*`, `.nav-kpi-chip.{accent,ok,warn,err}`, `.filter-chip`, `.card-*`, `.drawer`. ## View mapping (his view → our components to re-skin) | ArtPipe view | Our existing components (reuse + restyle) | |---|---| | **Pipeline** (landing) | `ArtStudioShell` frame + `ArtPromptComposer` (→ Generate drawer), `ArtStageTimeline`/`ArtStageConsole`, `ArtAssetCard`/`ArtActivityPanel` (Now-Running/queue), controls | | **Library** | `ArtGallery` / `ArtAssetLibrary` / `ArtAssetCard` | | **Metrics** | `ArtMetricsDashboard` + `art-chart` | | **Builder** | `ArtPipelineBuilder` | | **System** panel | `ArtActivityPanel` / `ArtActivityLauncher` (Activity/Workers/Watcher tabs) | ## Phased plan (one shippable, lint+build-verified Angular PR per phase) - **P1 — Shell + theme foundation + Pipeline landing.** New ArtPipe-style shell: brand + 4-tab nav + KPI strip + his GitHub-dark theme tokens (scoped to the feature). Route `navigateToTool('art-studio')` → Pipeline. Existing components slotted into tabs (un-restyled inner content OK this phase). *This is the keystone; delivers "click Art Studio → land in his Pipeline with his chrome."* - **P2 — Pipeline view fidelity.** Generate drawer, pipeline controls (Pause/Resume/Stop/Restart), Now-Running board, live console, queue-status — match his layout/interactions. - **P3 — Library** re-skin to his card grid + filter-chips. - **P4 — Metrics** re-skin (his stat cards / charts styling). - **P5 — Builder** re-skin + **System panel** (Activity/Workers/Watcher) fidelity. - **P6 — polish pass**: side-by-side diff vs `:5050`, close visual deltas. ## Constraints - Angular; run `pnpm run lint:fix` + `pnpm run lint:styles:fix` + build before each PR. Keep transloco keys. Reuse backend wiring; no backend changes expected. Tracking issue; per-phase PRs will reference this. Starting P1.
Author
Owner

P2 build spec — Pipeline view fidelity (grounded in his actual markup at :5050)

Extracted his Pipeline view DOM so P2 mirrors it faithfully. Structure:

1. Runner control bar — buttons with state-driven visibility (display:none until applicable):

  • Pause (.btn-muted, runnerAction('pause')), Resume (.btn-primary, runnerAction('resume')), Stop (.btn-danger, runnerAction('stop')), Restart (.btn-muted, restartServer()), Stop continuous (#btnStopContinuous, stopContinuous()), + an idle/running status label.
  • Mapping caveat: his Pause/Resume/Stop control a local runner process. Our model is per-asset stage-runs + a global activity feed with no whole-pipeline pause. Decision for P2: surface what we actually have — the continuous-wave Stop (we already have continuousRunning/stop in the shell), per-asset Cancel/Restart (existing), and a live status pill — and omit Pause/Resume until/unless a runner-control backend exists. Don't render dead buttons.

2. Now-Running / queue boardcard-body/card-tags/card-tag/card-actions/card-dismiss tiles + queue-status. Map to our ArtActivityPanel (queue/now-running) + ArtAssetCard, restyled to his card CSS.

3. Generate drawer#drawerOverlay + .drawer (right slide-out, 420px, from his CSS) + #drawerQueue. Wrap our ArtPromptComposer in this drawer, opened by a Generate button in the control bar. His .drawer/.drawer-overlay CSS already captured.

4. KPI strip (nav right side, deferred from P1): real chips from our activity/usage — e.g. Queued / Running counts + health — no fabricated numbers.

Approach: build a lib-artpipe-pipeline-view that composes the above from our existing services (ArtStudioService, ART_ASSET_PROGRESS_SOURCE, activity), and swap the shell's pipeline @case from <lib-art-studio-shell/> to it. Reuse all data wiring. His .btn-primary/.btn-muted/.btn-danger/.card-*/.drawer classes → .artpipe-* tokens from P1.

Building this as its own PR once #142 (P1) merges (keeps the stack shallow for review).

## P2 build spec — Pipeline view fidelity (grounded in his actual markup at :5050) Extracted his Pipeline view DOM so P2 mirrors it faithfully. Structure: **1. Runner control bar** — buttons with state-driven visibility (`display:none` until applicable): - `Pause` (`.btn-muted`, `runnerAction('pause')`), `Resume` (`.btn-primary`, `runnerAction('resume')`), `Stop` (`.btn-danger`, `runnerAction('stop')`), `Restart` (`.btn-muted`, `restartServer()`), `Stop` continuous (`#btnStopContinuous`, `stopContinuous()`), + an `idle`/running status label. - **Mapping caveat:** his Pause/Resume/Stop control a *local runner process*. Our model is per-asset stage-runs + a global activity feed with no whole-pipeline pause. **Decision for P2:** surface what we actually have — the **continuous-wave Stop** (we already have `continuousRunning`/stop in the shell), per-asset **Cancel/Restart** (existing), and a live **status pill** — and omit Pause/Resume until/unless a runner-control backend exists. Don't render dead buttons. **2. Now-Running / queue board** — `card-body`/`card-tags`/`card-tag`/`card-actions`/`card-dismiss` tiles + `queue-status`. Map to our `ArtActivityPanel` (queue/now-running) + `ArtAssetCard`, restyled to his card CSS. **3. Generate drawer** — `#drawerOverlay` + `.drawer` (right slide-out, 420px, from his CSS) + `#drawerQueue`. Wrap our `ArtPromptComposer` in this drawer, opened by a **Generate** button in the control bar. His `.drawer`/`.drawer-overlay` CSS already captured. **4. KPI strip** (nav right side, deferred from P1): real chips from our activity/usage — e.g. Queued / Running counts + health — no fabricated numbers. **Approach:** build a `lib-artpipe-pipeline-view` that composes the above from our existing services (`ArtStudioService`, `ART_ASSET_PROGRESS_SOURCE`, activity), and swap the shell's `pipeline` `@case` from `<lib-art-studio-shell/>` to it. Reuse all data wiring. His `.btn-primary/.btn-muted/.btn-danger/.card-*/.drawer` classes → `.artpipe-*` tokens from P1. Building this as its own PR once **#142 (P1)** merges (keeps the stack shallow for review).
Author
Owner

P2 progress + an architectural gate on the runner control bar

Shipped: P2a nav KPI chips — PR #143 (stacked on #142). Live Active/Running pills polled from the staff getActivity snapshot, ArtPipe GitHub-dark styling, staff-only + degrades silently. build + lint + stylelint green.

Also folded into #142 (shell chrome scope): nav System-activity launcher (#390) and the doubled-header fix (ArtStudioShell gained a chromeless input; Pipeline view passes it; staff review link relocated to nav-right).

Gate found — runner control bar is NOT a frontend-only slice. Eric's Pipeline centers on a runner control bar (Pause / Resume / Stop / Restart + idle/running state) that drives a global continuous runner. Our backend has no equivalentArtStudioController exposes only per-asset actions (submit, {id}/cancel, {id}/restart/{stage}, DELETE {id}) plus queries/gallery. There is no pause/resume/stop-runner/restart-runner endpoint, and our processing model is per-asset submissions, not a controllable continuous runner.

So faithful control-bar fidelity needs a decision + backend work, not a re-skin:

  • Option A — adapt the bar to our model: surface what we actually have (per-asset cancel/restart-stage, the existing continuous-run stop) in his control-bar styling, and show idle/running from the activity snapshot. Frontend-only, honest, ships now — but it's his look over our semantics, not his controls.
  • Option B — add real runner controls: new backend endpoints + a runner-state concept (pause/resume/stop/restart the pipeline globally), then wire his bar 1:1. Cross-repo, larger, a go-live-scope decision.

Recommendation: ship Option A as P2b (safe, faithful-looking, no backend), and track Option B separately if you want true global runner control. The remaining P2 pieces (Now-Running board, Generate drawer, stage console styling) are frontend-only re-skins and remain clean once #142/#143 merge.

Ask: merge the #142→#143 stack when you get a chance (both fully verified) so P2b lands on clean master instead of deepening the stack; and pick A vs B for the control bar.

## P2 progress + an architectural gate on the runner control bar **Shipped:** P2a nav KPI chips — **PR #143** (stacked on #142). Live Active/Running pills polled from the staff `getActivity` snapshot, ArtPipe GitHub-dark styling, staff-only + degrades silently. build + lint + stylelint green. Also folded into #142 (shell chrome scope): nav System-activity launcher (#390) and the doubled-header fix (`ArtStudioShell` gained a `chromeless` input; Pipeline view passes it; staff review link relocated to nav-right). **Gate found — runner control bar is NOT a frontend-only slice.** Eric's Pipeline centers on a **runner control bar** (Pause / Resume / Stop / Restart + idle/running state) that drives a *global continuous runner*. Our backend has **no equivalent** — `ArtStudioController` exposes only **per-asset** actions (`submit`, `{id}/cancel`, `{id}/restart/{stage}`, `DELETE {id}`) plus queries/gallery. There is no pause/resume/stop-runner/restart-runner endpoint, and our processing model is per-asset submissions, not a controllable continuous runner. So faithful control-bar fidelity needs a **decision + backend work**, not a re-skin: - **Option A — adapt the bar to our model:** surface what we actually have (per-asset cancel/restart-stage, the existing continuous-run stop) in his control-bar *styling*, and show idle/running from the activity snapshot. Frontend-only, honest, ships now — but it's his *look* over our *semantics*, not his controls. - **Option B — add real runner controls:** new backend endpoints + a runner-state concept (pause/resume/stop/restart the pipeline globally), then wire his bar 1:1. Cross-repo, larger, a go-live-scope decision. **Recommendation:** ship **Option A** as P2b (safe, faithful-looking, no backend), and track Option B separately if you want true global runner control. The remaining P2 pieces (Now-Running board, Generate drawer, stage console styling) are frontend-only re-skins and remain clean once #142/#143 merge. **Ask:** merge the #142→#143 stack when you get a chance (both fully verified) so P2b lands on clean master instead of deepening the stack; and pick A vs B for the control bar.
Author
Owner

P1+P2a merged — and a design-system fork for the Pipeline re-skin

Merged to master (e04fcea): #142 (P1 shell + theme + landing + System affordance + double-header fix) and #143 (P2a KPI chips + Now-Running board + WAI-ARIA tabs + specs + i18n a11y). Local branches cleaned up.

Key discovery before re-skinning the Pipeline content: the studio content is not un-themed — libraries/spikersoft-theme/src/lib/_art-studio.scss is a deliberate theme layer that already maps Eric's exact ArtPipe palette (accent #58a6ff → --color-primary, ok #3fb950 → --color-success, …) but intentionally re-expresses his flat panels as glass washes — "never his raw hex" — and inherits light/dark from the app theme via semantic tokens.

So "make the Pipeline match :5050" is a design-language decision, not a mechanical re-skin — and it collides with a documented team convention. Two ways:

  • Option A — Eric-flat fidelity (literal :5050): override the surface/bg/text tokens scoped to .artpipe-shell to Eric's flat GitHub-dark (#0d1117 / #161b22 / #21262d, hard borders, no glass). Because the studio-shell + children all theme off these tokens, the whole ArtPipe content (all 4 views) re-skins via one scoped token block — clean, low-code-risk, reviewable. Matches your "everything should be exactly the same as his." Consistent with my P1 chrome (which already uses his flat hex). Downside: overrides the theme authors' deliberate "glass, never raw hex" decision inside the ArtPipe surface (rest of app untouched).
  • Option B — preserve our glass design system: keep the deliberate glass re-expression; just ensure the ArtPipe surface renders in the dark theme scope so the content sits correctly in the frame. More consistent with the rest of our app; less literal to Eric (glass panels, not his flat ones).

My read: your repeated "honor every aspect / exactly the same as his" points to A, and A is a clean scoped token override I can ship as a reviewable PR (you eyeball it vs :5050). But overriding another dev's documented design convention is your call, not mine — hence flagging rather than shipping. Which do you want?

## P1+P2a merged ✅ — and a design-system fork for the Pipeline re-skin **Merged to master (`e04fcea`):** #142 (P1 shell + theme + landing + System affordance + double-header fix) and #143 (P2a KPI chips + Now-Running board + WAI-ARIA tabs + specs + i18n a11y). Local branches cleaned up. **Key discovery before re-skinning the Pipeline content:** the studio content is **not** un-themed — `libraries/spikersoft-theme/src/lib/_art-studio.scss` is a deliberate theme layer that already maps Eric's exact ArtPipe palette (`accent #58a6ff → --color-primary`, `ok #3fb950 → --color-success`, …) but **intentionally re-expresses his flat panels as glass washes — "never his raw hex"** — and inherits light/dark from the app theme via semantic tokens. So "make the Pipeline match :5050" is a **design-language decision**, not a mechanical re-skin — and it collides with a documented team convention. Two ways: - **Option A — Eric-flat fidelity (literal :5050):** override the surface/bg/text tokens *scoped to `.artpipe-shell`* to Eric's flat GitHub-dark (`#0d1117 / #161b22 / #21262d`, hard borders, no glass). Because the studio-shell + children all theme off these tokens, the whole ArtPipe content (all 4 views) re-skins via one scoped token block — clean, low-code-risk, reviewable. Matches your "everything should be exactly the same as his." Consistent with my P1 chrome (which already uses his flat hex). **Downside:** overrides the theme authors' deliberate "glass, never raw hex" decision *inside the ArtPipe surface* (rest of app untouched). - **Option B — preserve our glass design system:** keep the deliberate glass re-expression; just ensure the ArtPipe surface renders in the **dark** theme scope so the content sits correctly in the frame. More consistent with the rest of our app; less literal to Eric (glass panels, not his flat ones). **My read:** your repeated "honor every aspect / exactly the same as his" points to **A**, and A is a clean scoped token override I can ship as a reviewable PR (you eyeball it vs :5050). But overriding another dev's documented design convention is your call, not mine — hence flagging rather than shipping. Which do you want?
Sign in to join this conversation.