Form Quality Parity & Reusable Media Components #9

Open
opened 2026-03-10 13:16:18 +00:00 by mik-tf · 0 comments
Owner

Standalone tracker for bringing all Dioxus WASM island forms to full Bootstrap-quality parity, and adding reusable media components (markdown editor, PDF viewer). Based on Kristof's feedback.

Related:

Background

Hero OS has two UI layers:

  1. Bootstrap _ui serviceshero_*_ui crates serve HTML templates with Bootstrap 5.3.3. These already look polished and are the visual reference (the gold standard).
  2. Dioxus WASM islands (Archipelagos) — Rust/Dioxus components compiled to WASM, running inside the Hero OS shell.

Issue #7 made significant progress closing the gap between the two. The islands already inherit a lot of Bootstrap's look and feel through:

  • styles.css — single source of truth for all visual rules, using CSS custom properties that mirror Bootstrap's design language
  • Class-based styling — all Dioxus components emit semantic HTML with CSS classes (no inline styles), matching Bootstrap's pattern
  • Shadow DOM style adoption — islands share the host page's stylesheets via adoptedStyleSheets
  • Component libraryTextField, TextareaField, CheckboxField, Badge, Card, Tabs, Alert, Spinner, ToggleSwitch, FormGroup — all emitting correct Bootstrap-aligned classes
  • 7 forms already migrated to core components with -313 lines net reduction

The gap is smaller but not fully closed. This issue finishes the job.

Design system reference: https://forge.ourworld.tf/lhumina_code/hero_archipelagos/src/branch/development/docs/DESIGN_SYSTEM.md

The three-layer architecture:

  • Layer 1 (Structure): Dioxus components emit semantic HTML with CSS classes, no inline styles
  • Layer 2 (Semantics): styles.css defines all visual rules using CSS custom properties
  • Layer 3 (Appearance): theme.rs sets CSS variables at :root, enabling theme switching

Tasks

1. BizTools Priority

  • Business forms (CRM, projects, invoices, quotes, milestones, stories) are the top priority
  • These should be the first forms polished to full Bootstrap parity
  • Use the Bootstrap _ui equivalents as the visual reference

2. Form Quality — All Archipelagos Forms

  • Audit every island form against its Bootstrap _ui equivalent
  • Ensure all forms use the core component library
  • Fix spacing, alignment, typography, and dark/light consistency
  • Add proper validation states and error styling

3. Object Linking

  • Forms should link between related objects (e.g. CRM contact → projects, project → milestones)
  • Clickable references that navigate between islands
  • Consistent link styling across all contexts

4. Reusable Markdown Editor (from lhumina_code/hero_os#22)

  • 2-pane layout: edit left, preview right
  • Syntax highlighting
  • Save-back capability: editor links back to the originating component/field
  • Reusable from any island that needs markdown editing (CRM descriptions, project notes, etc.)

5. Reusable PDF Viewer (from lhumina_code/hero_os#22)

  • Single viewer component used everywhere
  • Full-screen capable
  • Reusable across all islands

Branching Model

All repos use development as the default branch.

  • development : default, always deployable
  • development_{name} : feature branches for fast-paced AI-assisted development
  • main : releases (when ready)

One branch, one commit, one issue

AI-assisted development generates many commits fast. To keep history clean and traceable, we follow a strict rule:

  • Each feature branch (development_{name}) is squashed into one commit before merging to development
  • That commit message links to the issue, e.g.: https://forge.ourworld.tf/lhumina_code/home/issues/9 — Form Quality Parity & Reusable Media Components
  • One branch = one commit = one issue on development

This means every commit on development represents a complete, reviewed piece of work and links directly to the issue that describes it.

Workflow

  1. Branch development_{name} from latest development
  2. Work on development_{name} (as many commits as needed)
  3. Merge development into development_{name} periodically (never rebase, always merge)
  4. When ready, squash into one commit with the issue URL as the commit message
  5. Merge development_{name} into development

Repos involved:

Repo Purpose
hero_os CSS styles (styles.css, theme.rs)
hero_archipelagos Components, forms, editors, islands
hero_osis Seed data (if needed)
hero_services Docker build (Dockerfile.dev)

Deployment

Tier Image Tag Gateway Port Status
dev :dev herodev.gent02.grid.tf 8805 Live
demo :demo herodemo.gent02.grid.tf 8806 Live
prod :prod TBD TBD Not deployed

Registry: forge.ourworld.tf/lhumina_code/hero_zero
VM: TFGrid Node 8, Mycelium 495:72fa:8ec3:9264:ff0f:c0a8:abad:234c

Deploy Commands

# SSH to VM
ssh -6 root@495:72fa:8ec3:9264:ff0f:c0a8:abad:234c

# --- Local Docker build (from hero_services dir) ---
cd hero_services
DOCKER_BUILDKIT=1 docker build --ssh default -f Dockerfile.dev -t forge.ourworld.tf/lhumina_code/hero_zero:dev ..

# --- Push to registry ---
docker push forge.ourworld.tf/lhumina_code/hero_zero:dev

# --- Deploy to herodev ---
ssh -6 root@495:72fa:8ec3:9264:ff0f:c0a8:abad:234c \
  'docker pull forge.ourworld.tf/lhumina_code/hero_zero:dev && \
   docker stop herodev; docker rm herodev; \
   docker run -d --name herodev --restart unless-stopped \
     -p 8805:6666 -v /root/.ssh:/root/.ssh:ro \
     forge.ourworld.tf/lhumina_code/hero_zero:dev'

# --- Tag and deploy to herodemo (only after human confirms herodev) ---
docker tag forge.ourworld.tf/lhumina_code/hero_zero:dev forge.ourworld.tf/lhumina_code/hero_zero:demo
docker push forge.ourworld.tf/lhumina_code/hero_zero:demo

ssh -6 root@495:72fa:8ec3:9264:ff0f:c0a8:abad:234c \
  'docker pull forge.ourworld.tf/lhumina_code/hero_zero:demo && \
   docker stop herodemo; docker rm herodemo; \
   docker run -d --name herodemo --restart unless-stopped \
     -p 8806:6666 -v /root/.ssh:/root/.ssh:ro \
     forge.ourworld.tf/lhumina_code/hero_zero:demo'

# --- Check logs ---
ssh -6 root@495:72fa:8ec3:9264:ff0f:c0a8:abad:234c 'docker logs herodev 2>&1 | tail -20'

DevOps Pipeline

Step What Who Gate
1 Code — implement changes AI --
2 Local Docker build AI must compile
3 Deploy to herodev AI --
4 Human test on herodev Human must confirm
5 Commit & push AI only after step 4
6 Remote Docker build AI must compile
7 Deploy to herodev (again) AI --
8 Human test on herodev Human must confirm
9 Tag :demo AI only after step 8
10 Human test on herodemo Human must confirm
11 Update this issue AI --

Rules:

  • Never push before human confirms on herodev (step 4 -> step 5)
  • Never tag :demo before human confirms remote build (step 8 -> step 9)
  • Never rebase, always merge
  • herodev gets changes first, herodemo only after confirmation
  • No hot-swapping WASM — always do full Docker rebuild + deploy

Operational Lessons (from Issues #7 & #8)

  1. Docker cache can go stale — sometimes --no-cache is needed when cargo dependencies change or layers are cached from a different branch.
  2. Container name conflicts — always docker stop + rm the old container before docker run. Watch for leftover containers (e.g. hero_zero) holding ports.
  3. Registry workflow is the right path — build locally → docker push to registry → docker pull on VM → docker run. Don't build on the VM.
  4. Never break herodemo — herodev is the playground. Only tag :demo and redeploy herodemo after human confirms herodev works. Non-negotiable.
  5. Port mapping — container exposes 6666 internally, mapped to 8805 (herodev) and 8806 (herodemo).
  6. Cargo cache layer — the Dockerfile has a cargo cache layer that speeds rebuilds from ~30min to ~5-10min, but only when dependencies haven't changed drastically.
  7. SSH agent forwarding--no-cache builds require --ssh default flag for git clone steps inside Docker.
Standalone tracker for bringing all Dioxus WASM island forms to full Bootstrap-quality parity, and adding reusable media components (markdown editor, PDF viewer). Based on Kristof's feedback. **Related:** - https://forge.ourworld.tf/lhumina_code/home/issues/7 — UI Component Library & Form Quality (completed) - https://forge.ourworld.tf/lhumina_code/home/issues/8 — Differentiate Identity Seed Data (prerequisite) - https://forge.ourworld.tf/lhumina_code/home/issues/5 — Production Readiness Plan (master tracker) - https://forge.ourworld.tf/lhumina_code/hero_os/issues/22 — PDF, Image Viewer, Markdown Editor - https://forge.ourworld.tf/lhumina_code/-/projects/13 — Project board ### Background Hero OS has two UI layers: 1. **Bootstrap `_ui` services** — `hero_*_ui` crates serve HTML templates with Bootstrap 5.3.3. These already look polished and are the visual reference (the gold standard). 2. **Dioxus WASM islands (Archipelagos)** — Rust/Dioxus components compiled to WASM, running inside the Hero OS shell. Issue #7 made significant progress closing the gap between the two. The islands already inherit a lot of Bootstrap's look and feel through: - **`styles.css`** — single source of truth for all visual rules, using CSS custom properties that mirror Bootstrap's design language - **Class-based styling** — all Dioxus components emit semantic HTML with CSS classes (no inline styles), matching Bootstrap's pattern - **Shadow DOM style adoption** — islands share the host page's stylesheets via `adoptedStyleSheets` - **Component library** — `TextField`, `TextareaField`, `CheckboxField`, `Badge`, `Card`, `Tabs`, `Alert`, `Spinner`, `ToggleSwitch`, `FormGroup` — all emitting correct Bootstrap-aligned classes - **7 forms already migrated** to core components with -313 lines net reduction The gap is smaller but not fully closed. This issue finishes the job. **Design system reference:** https://forge.ourworld.tf/lhumina_code/hero_archipelagos/src/branch/development/docs/DESIGN_SYSTEM.md The three-layer architecture: - **Layer 1 (Structure):** Dioxus components emit semantic HTML with CSS classes, no inline styles - **Layer 2 (Semantics):** `styles.css` defines all visual rules using CSS custom properties - **Layer 3 (Appearance):** `theme.rs` sets CSS variables at `:root`, enabling theme switching ### Tasks #### 1. BizTools Priority - Business forms (CRM, projects, invoices, quotes, milestones, stories) are the top priority - These should be the first forms polished to full Bootstrap parity - Use the Bootstrap `_ui` equivalents as the visual reference #### 2. Form Quality — All Archipelagos Forms - Audit every island form against its Bootstrap `_ui` equivalent - Ensure all forms use the core component library - Fix spacing, alignment, typography, and dark/light consistency - Add proper validation states and error styling #### 3. Object Linking - Forms should link between related objects (e.g. CRM contact → projects, project → milestones) - Clickable references that navigate between islands - Consistent link styling across all contexts #### 4. Reusable Markdown Editor (from https://forge.ourworld.tf/lhumina_code/hero_os/issues/22) - 2-pane layout: edit left, preview right - Syntax highlighting - Save-back capability: editor links back to the originating component/field - Reusable from any island that needs markdown editing (CRM descriptions, project notes, etc.) #### 5. Reusable PDF Viewer (from https://forge.ourworld.tf/lhumina_code/hero_os/issues/22) - Single viewer component used everywhere - Full-screen capable - Reusable across all islands ### Branching Model All repos use `development` as the default branch. - `development` : default, always deployable - `development_{name}` : feature branches for fast-paced AI-assisted development - `main` : releases (when ready) #### One branch, one commit, one issue AI-assisted development generates many commits fast. To keep history clean and traceable, we follow a strict rule: - Each feature branch (`development_{name}`) is squashed into **one commit** before merging to `development` - That commit message links to the issue, e.g.: `https://forge.ourworld.tf/lhumina_code/home/issues/9 — Form Quality Parity & Reusable Media Components` - One branch = one commit = one issue on `development` This means every commit on `development` represents a complete, reviewed piece of work and links directly to the issue that describes it. #### Workflow 1. Branch `development_{name}` from latest `development` 2. Work on `development_{name}` (as many commits as needed) 3. Merge `development` into `development_{name}` periodically (never rebase, always merge) 4. When ready, squash into one commit with the issue URL as the commit message 5. Merge `development_{name}` into `development` **Repos involved:** | Repo | Purpose | |------|---------| | [`hero_os`](https://forge.ourworld.tf/lhumina_code/hero_os) | CSS styles (`styles.css`, `theme.rs`) | | [`hero_archipelagos`](https://forge.ourworld.tf/lhumina_code/hero_archipelagos) | Components, forms, editors, islands | | [`hero_osis`](https://forge.ourworld.tf/lhumina_code/hero_osis) | Seed data (if needed) | | [`hero_services`](https://forge.ourworld.tf/lhumina_code/hero_services) | Docker build (`Dockerfile.dev`) | ### Deployment | Tier | Image Tag | Gateway | Port | Status | |------|-----------|---------|------|--------| | **dev** | `:dev` | `herodev.gent02.grid.tf` | 8805 | Live | | **demo** | `:demo` | `herodemo.gent02.grid.tf` | 8806 | Live | | **prod** | `:prod` | TBD | TBD | Not deployed | **Registry:** `forge.ourworld.tf/lhumina_code/hero_zero` **VM:** TFGrid Node 8, Mycelium `495:72fa:8ec3:9264:ff0f:c0a8:abad:234c` ### Deploy Commands ```bash # SSH to VM ssh -6 root@495:72fa:8ec3:9264:ff0f:c0a8:abad:234c # --- Local Docker build (from hero_services dir) --- cd hero_services DOCKER_BUILDKIT=1 docker build --ssh default -f Dockerfile.dev -t forge.ourworld.tf/lhumina_code/hero_zero:dev .. # --- Push to registry --- docker push forge.ourworld.tf/lhumina_code/hero_zero:dev # --- Deploy to herodev --- ssh -6 root@495:72fa:8ec3:9264:ff0f:c0a8:abad:234c \ 'docker pull forge.ourworld.tf/lhumina_code/hero_zero:dev && \ docker stop herodev; docker rm herodev; \ docker run -d --name herodev --restart unless-stopped \ -p 8805:6666 -v /root/.ssh:/root/.ssh:ro \ forge.ourworld.tf/lhumina_code/hero_zero:dev' # --- Tag and deploy to herodemo (only after human confirms herodev) --- docker tag forge.ourworld.tf/lhumina_code/hero_zero:dev forge.ourworld.tf/lhumina_code/hero_zero:demo docker push forge.ourworld.tf/lhumina_code/hero_zero:demo ssh -6 root@495:72fa:8ec3:9264:ff0f:c0a8:abad:234c \ 'docker pull forge.ourworld.tf/lhumina_code/hero_zero:demo && \ docker stop herodemo; docker rm herodemo; \ docker run -d --name herodemo --restart unless-stopped \ -p 8806:6666 -v /root/.ssh:/root/.ssh:ro \ forge.ourworld.tf/lhumina_code/hero_zero:demo' # --- Check logs --- ssh -6 root@495:72fa:8ec3:9264:ff0f:c0a8:abad:234c 'docker logs herodev 2>&1 | tail -20' ``` ### DevOps Pipeline | Step | What | Who | Gate | |------|------|-----|------| | 1 | **Code** — implement changes | AI | -- | | 2 | **Local Docker build** | AI | must compile | | 3 | **Deploy to herodev** | AI | -- | | 4 | **Human test on herodev** | Human | must confirm | | 5 | **Commit & push** | AI | only after step 4 | | 6 | **Remote Docker build** | AI | must compile | | 7 | **Deploy to herodev (again)** | AI | -- | | 8 | **Human test on herodev** | Human | must confirm | | 9 | **Tag `:demo`** | AI | only after step 8 | | 10 | **Human test on herodemo** | Human | must confirm | | 11 | **Update this issue** | AI | -- | **Rules:** - Never push before human confirms on herodev (step 4 -> step 5) - Never tag `:demo` before human confirms remote build (step 8 -> step 9) - Never rebase, always merge - herodev gets changes first, herodemo only after confirmation - No hot-swapping WASM — always do full Docker rebuild + deploy ### Operational Lessons (from Issues #7 & #8) 1. **Docker cache can go stale** — sometimes `--no-cache` is needed when cargo dependencies change or layers are cached from a different branch. 2. **Container name conflicts** — always `docker stop + rm` the old container before `docker run`. Watch for leftover containers (e.g. `hero_zero`) holding ports. 3. **Registry workflow is the right path** — build locally → `docker push` to registry → `docker pull` on VM → `docker run`. Don't build on the VM. 4. **Never break herodemo** — herodev is the playground. Only tag `:demo` and redeploy herodemo after human confirms herodev works. Non-negotiable. 5. **Port mapping** — container exposes 6666 internally, mapped to 8805 (herodev) and 8806 (herodemo). 6. **Cargo cache layer** — the Dockerfile has a cargo cache layer that speeds rebuilds from ~30min to ~5-10min, but only when dependencies haven't changed drastically. 7. **SSH agent forwarding** — `--no-cache` builds require `--ssh default` flag for git clone steps inside Docker.
mik-tf added this to the ACTIVE project 2026-03-10 15:37:51 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/home#9
No description provided.