Skip to content

Commit 4375366

Browse files
authored
feat(dashboard): embed renewed react console
1 parent 24e234c commit 4375366

56 files changed

Lines changed: 5644 additions & 26 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,12 @@ scripts/s3-autoloop/progress.md
1616
scripts/s3-autoloop/done.md
1717
scripts/s3-autoloop/iteration-*.out
1818
scripts/s3-autoloop/prompt-*.*
19+
scripts/dashboard-design-renewal-autoloop/.run-loop.lock
20+
scripts/dashboard-design-renewal-autoloop/.circuit-state
21+
scripts/dashboard-design-renewal-autoloop/runner.jsonl
22+
scripts/dashboard-design-renewal-autoloop/runner.log
23+
scripts/dashboard-design-renewal-autoloop/state.env
24+
scripts/dashboard-design-renewal-autoloop/progress.md
25+
scripts/dashboard-design-renewal-autoloop/done.md
26+
scripts/dashboard-design-renewal-autoloop/iteration-*.out
27+
scripts/dashboard-design-renewal-autoloop/prompt-*.*

docs/design-dashboard-shell.md

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
# Common Dashboard Shell Design
2+
3+
## Summary
4+
5+
`devcloud` の dashboard は、Mail、S3、今後追加される SQS、DynamoDB、GCS などを横断して使う operational console とする。
6+
7+
現在は Go-served static HTML で Mail/S3 を提供しているが、今後の service 数、state、dialogs、routing、shared components の増加を考えると、dashboard は React/Vite へ段階移行する。最終形は「Go binary が built assets を配信し、開発時だけ Vite を使う」構成にする。
8+
9+
## Goals
10+
11+
- `/` で利用可能な service を一覧できる。
12+
- `/mail``/s3` など各 service dashboard が同じ shell、navigation、status pattern を共有する。
13+
- service 固有 UI は独立しつつ、tokens、layout、loading/error/empty states は共通化する。
14+
- production 実行時に Node/Vite を要求しない。
15+
- Mail/S3 の既存 API と E2E を壊さずに移行できる。
16+
17+
## Non-Goals
18+
19+
- AWS Console の完全再現。
20+
- 認証、ユーザー管理、multi-tenant 管理画面。
21+
- Electron/Tauri など desktop app 化。
22+
- 初期段階で全 dashboard を一括 React 移行すること。
23+
24+
## Product Role
25+
26+
Common Dashboard Shell は、local cloud emulator の状態を一箇所で確認する cockpit である。マーケティング画面ではなく、開発中に繰り返し開く作業画面として、静かで速く、失敗状態が分かりやすいことを優先する。
27+
28+
## Information Architecture
29+
30+
```txt
31+
Dashboard Shell
32+
Service Index (/)
33+
service cards
34+
endpoint summary
35+
health summary
36+
37+
App Frame
38+
top bar
39+
devcloud identity
40+
service switcher
41+
global status
42+
refresh / reset entry points
43+
44+
service surface
45+
Mail (/mail)
46+
S3 (/s3)
47+
future services (/sqs, /dynamodb, /gcs)
48+
49+
activity footer
50+
last request
51+
storage path
52+
API status
53+
```
54+
55+
## Route Model
56+
57+
| Route | Purpose |
58+
| --- | --- |
59+
| `/` | Service index |
60+
| `/mail` | Mail inbox dashboard |
61+
| `/s3` | S3 Object Explorer |
62+
| `/api/dashboard/services` | Common service registry/status |
63+
| `/api/messages/*` | Mail API |
64+
| `/api/s3/*` | S3 dashboard API |
65+
66+
Future services should follow `/api/{service}/...` unless a service has an existing protocol endpoint.
67+
68+
## React Architecture
69+
70+
```txt
71+
web/dashboard/
72+
package.json
73+
vite.config.ts
74+
src/
75+
main.tsx
76+
app/
77+
App.tsx
78+
routes.tsx
79+
shell/
80+
AppShell.tsx
81+
ServiceIndex.tsx
82+
ServiceSwitcher.tsx
83+
StatusBar.tsx
84+
ActivityFooter.tsx
85+
services/
86+
mail/
87+
MailDashboard.tsx
88+
api.ts
89+
types.ts
90+
s3/
91+
S3Dashboard.tsx
92+
BucketSidebar.tsx
93+
ObjectBrowser.tsx
94+
ObjectInspector.tsx
95+
api.ts
96+
types.ts
97+
ui/
98+
Button.tsx
99+
EmptyState.tsx
100+
Panel.tsx
101+
Tabs.tsx
102+
Dialog.tsx
103+
styles/
104+
tokens.css
105+
globals.css
106+
107+
internal/dashboard/
108+
server.go
109+
assets.go embed built assets
110+
```
111+
112+
Production build:
113+
114+
```bash
115+
cd web/dashboard
116+
npm run build
117+
go test ./...
118+
```
119+
120+
Runtime:
121+
122+
```txt
123+
devcloud binary -> serves embedded React assets
124+
```
125+
126+
The daemon must not require Node.js at runtime.
127+
128+
## Shared UI Model
129+
130+
### App Shell
131+
132+
The shell owns:
133+
134+
- service navigation
135+
- shared responsive grid
136+
- refresh orchestration
137+
- high-level service health
138+
- common loading/error/empty patterns
139+
140+
Service pages own:
141+
142+
- service-specific data fetching
143+
- domain tables and inspectors
144+
- dialogs and destructive action confirmation
145+
- protocol-specific labels and metadata
146+
147+
### Layout
148+
149+
Desktop:
150+
151+
```txt
152+
+--------------------------------------------------------------------------------+
153+
| devcloud [Mail] [S3] [future] status Refresh |
154+
+--------------------------------------------------------------------------------+
155+
| service-specific dashboard surface |
156+
| |
157+
+--------------------------------------------------------------------------------+
158+
| activity / storage / last request |
159+
+--------------------------------------------------------------------------------+
160+
```
161+
162+
S3 may keep its 3-pane Object Explorer inside the shared shell. Mail may keep its 2-pane Calm Inspector inside the same frame.
163+
164+
Mobile:
165+
166+
- service switcher becomes a compact horizontal nav.
167+
- service-specific panes collapse into route-like stacked views.
168+
- destructive actions move into explicit dialogs or bottom sheets.
169+
170+
## Design Tokens
171+
172+
Use one token source shared by Mail/S3.
173+
174+
```txt
175+
surface/base #F7F8F5
176+
surface/panel #FFFFFF
177+
surface/subtle #EEF1EC
178+
text/primary #1D211C
179+
text/secondary #5F675D
180+
border/default #D9DED5
181+
accent/primary #176B4D
182+
accent/object #245B8F
183+
accent/warning #9A5B13
184+
accent/danger #B42318
185+
code/background #101511
186+
code/text #E8EFE7
187+
radius/md 8px
188+
```
189+
190+
Service-specific accents are allowed only as secondary signals. The whole dashboard must not become one-note blue/slate, purple, beige, or espresso.
191+
192+
## Service Registry
193+
194+
Add a small registry so `/` and the shell do not hardcode every service.
195+
196+
```go
197+
type DashboardService struct {
198+
ID string `json:"id"`
199+
Name string `json:"name"`
200+
Path string `json:"path"`
201+
Status string `json:"status"`
202+
Endpoint string `json:"endpoint,omitempty"`
203+
Description string `json:"description"`
204+
}
205+
```
206+
207+
Initial response:
208+
209+
```json
210+
{
211+
"services": [
212+
{"id":"mail","name":"Mail","path":"/mail","status":"running","endpoint":"smtp://127.0.0.1:1025"},
213+
{"id":"s3","name":"S3","path":"/s3","status":"running","endpoint":"http://127.0.0.1:4566"}
214+
]
215+
}
216+
```
217+
218+
Disabled services should appear as `disabled` only if configured but not running. Unconfigured future services should not be shown by default.
219+
220+
## API Client Strategy
221+
222+
Each service owns a typed API client:
223+
224+
```txt
225+
services/mail/api.ts
226+
services/s3/api.ts
227+
```
228+
229+
Shared fetch wrapper:
230+
231+
- adds timeout
232+
- normalizes JSON/text errors
233+
- never logs payload bodies or credentials
234+
- returns typed errors for disabled services and network failures
235+
236+
## Migration Plan
237+
238+
### Phase 1: Shell Contract
239+
240+
- Add `docs/design-dashboard-shell.md`.
241+
- Add `/api/dashboard/services`.
242+
- Keep current static Mail/S3 pages.
243+
244+
### Phase 2: React Scaffold
245+
246+
- Add `web/dashboard` with Vite + React + TypeScript.
247+
- Build a shell-only React app that renders `/`, `/mail`, `/s3` placeholders.
248+
- Embed built assets from Go.
249+
- Keep existing Go static pages available behind compatibility routes during transition if needed.
250+
251+
### Phase 3: S3 React Page
252+
253+
- Port S3 Object Explorer first because it has the most state.
254+
- Preserve existing `/api/s3/*` contract.
255+
- Add Playwright or script-level visual smoke once the route is React-driven.
256+
257+
### Phase 4: Mail React Page
258+
259+
- Port Mail inbox after the shell and S3 patterns stabilize.
260+
- Preserve `/api/messages/*`.
261+
262+
### Phase 5: Shared Component Hardening
263+
264+
- Extract shared `Panel`, `Toolbar`, `Inspector`, `EmptyState`, `Dialog`, `ServiceSwitcher`.
265+
- Add accessibility and keyboard navigation tests.
266+
267+
## Acceptance Criteria
268+
269+
1. `/` shows all enabled services and links to `/mail` and `/s3`.
270+
2. `/mail` and `/s3` share shell navigation and visual tokens.
271+
3. Production `devcloud up` serves dashboard assets without Node.js.
272+
4. `go test ./...`, `scripts/mail-e2e.sh`, and `scripts/s3-e2e.sh` pass.
273+
5. Disabled services are not exposed as running through dashboard APIs.
274+
6. Dynamic service data is rendered through React escaping or safe DOM APIs, not raw `innerHTML`.
275+
276+
## Risks and Mitigations
277+
278+
| Risk | Impact | Mitigation |
279+
| --- | --- | --- |
280+
| React build adds runtime complexity | local binary becomes harder to run | embed built assets; Node only for development |
281+
| Big-bang rewrite breaks Mail/S3 | dashboard regressions | migrate one route at a time |
282+
| API contracts drift during UI port | E2E failures | keep existing dashboard APIs and scripts |
283+
| UI bundle grows quickly | slower startup and review noise | keep dependency set small; avoid broad component libraries initially |
284+
| XSS via object/message data | security issue | rely on React escaping and avoid `dangerouslySetInnerHTML` |
285+
286+
## Open Questions
287+
288+
1. Should React dashboard assets be committed after build, or generated in CI/release only?
289+
2. Should `/mail` and `/s3` remain direct routes forever, or move to `/services/mail` style later?
290+
3. Should the mock directories remain separate once `web/dashboard` exists?
291+
4. Should React migration start with S3 only, or shell + service index first?

docs/design-mail-ui.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,12 +459,13 @@ Reason:
459459

460460
- No frontend build tool is required for v0.
461461
- Single binary distribution stays simple.
462-
- Later migration to React/Vue/Svelte remains possible if dashboard complexity grows.
462+
- Future React migration should happen through the shared dashboard shell in `docs/design-dashboard-shell.md`, not as a one-off Mail rewrite.
463463

464464
Mock handling rules:
465465

466466
- Keep `mock/mail` useful as a visual and interaction reference.
467-
- Do not copy the mock's React dependency graph into the Go dashboard implementation.
467+
- Do not copy the mock's React dependency graph directly into the Go dashboard implementation.
468+
- When Mail is ported to React, implement it under the common `web/dashboard` shell and keep Go serving embedded built assets at runtime.
468469
- Keep v0-only UI actions active; future areas such as Search, Activity, SMTP log, Help, and Settings should be hidden or disabled until implemented.
469470
- HTML email preview must be sanitized before rendering. If sanitization is not implemented, show the plain text body and raw source instead.
470471
- Do not commit generated OS files such as `.DS_Store`.

docs/design-s3-ui.md

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,12 @@ aws --endpoint-url http://127.0.0.1:4566 s3api head-object --bucket demo --key R
626626

627627
## Implementation Strategy
628628

629+
### Common Shell Direction
630+
631+
The next dashboard architecture is defined in `docs/design-dashboard-shell.md`.
632+
633+
v0.1 can remain Go-served static HTML/CSS/JS, but future multi-service expansion should move S3 into the shared React/Vite dashboard shell. Production runtime must remain a single Go binary that serves embedded built assets and does not require Node.js.
634+
629635
### v0.1 Static Dashboard
630636

631637
Use the same production direction as Mail:
@@ -647,29 +653,30 @@ internal/dashboard/
647653
Routes:
648654

649655
```txt
650-
/ existing service landing or Mail default
656+
/ service landing
651657
/mail Mail dashboard
652658
/s3 S3 dashboard
653659
```
654660

655-
If routing simplicity is preferred for the next implementation slice, `/` may remain Mail and `/s3` can be added independently.
661+
`/` is the service landing and should remain the entry point for all enabled dashboards.
656662

657663
### Mock Reference
658664

659665
`mock/s3/` is the interactive reference artifact for this design. It should be used to validate layout, density, empty states, dialogs, and responsive behavior before implementing the Go-served dashboard.
660666

661-
Do not port the mock's React/Vite dependency graph into production by default. The production dashboard remains static HTML/CSS/JS served from Go unless a separate architecture decision changes that direction.
667+
Do not copy the mock's React/Vite dependency graph directly into production. When React migration proceeds, implement S3 under `web/dashboard` according to the shared shell design.
662668

663669
### Later
664670

665-
When 3+ services exist, introduce a shared dashboard shell:
671+
When React migration starts, introduce the shared dashboard shell:
666672

667673
```txt
668-
internal/dashboard/static/
669-
shell.go
670-
mail.go
671-
s3.go
672-
components.go
674+
web/dashboard/
675+
src/app/shell/
676+
src/services/s3/
677+
678+
internal/dashboard/
679+
assets.go
673680
```
674681

675682
## E2E Test Plan
@@ -714,8 +721,9 @@ Browser-oriented checks:
714721

715722
## Open Questions
716723

717-
1. Should `/` become a service switcher once S3 is added, or should Mail remain default?
718-
2. Should upload be supported in the dashboard v0.1, or should v0.1 only inspect SDK/CLI uploads?
719-
3. Should object preview sanitize HTML objects or always show HTML as raw text?
720-
4. Should dashboard delete support recursive prefix deletion, or avoid bulk delete until versioning semantics are implemented?
721-
5. Should we create `mock/s3` before production UI implementation?
724+
Resolved: `/` is the service landing for enabled dashboards.
725+
726+
1. Should upload be supported in the dashboard v0.1, or should v0.1 only inspect SDK/CLI uploads?
727+
2. Should object preview sanitize HTML objects or always show HTML as raw text?
728+
3. Should dashboard delete support recursive prefix deletion, or avoid bulk delete until versioning semantics are implemented?
729+
4. Should built React assets be committed, or generated only in CI/release?

0 commit comments

Comments
 (0)