Skip to content

Work Site

Started: 2025-01-09 Status: Phase 4 in progress

Table of Contents

Problem

No easy way to start/restart all dev servers, or navigate between them.

Goal

One command to restart all servers, plus a hub page for quick navigation.

What We Built

UX Layout

┌────────────────────────╮╭───────────┐
│       Work Sites       ││  Restart  │
└───────---───-──────────╯╰───────────┘
╭────────────────╮╭───────────────────╮
│    Dev Docs    ││     Projects      │
└────────────────╯╰───────────────────┘
╭────────────────────╮╭───────────────╮
│    Local Public    ││     More      │
└────-───────────────╯╰───────-───────┘

Conceptual layout — shows groupings, not exact visual appearance

Key takeaways:

  • Four rows: title, segments, feedback, actions
  • Feedback row shows project/mode and previews destination URL
  • Three layers: background, boxes, elements

Dual Purpose: Dispatch and Status

The hub serves two complementary purposes:

Dispatch — Pick project/mode, pick action, go Status — Hover to preview what would happen before committing

The feedback row provides preflight confirmation: hovering over action buttons shows the destination URL, removing guesswork. Hovering over project/mode buttons temporarily previews that selection (including updating action button states) without committing.

Button Color Scheme

  1. Choices

    1. Chosen — green with white text
    2. Not chosen — dark blue with gray text
    3. Unavailable — dark blue at 30% opacity
  2. Action — dark blue with white text

Visual Language

Shares visual language with Design Intuition (di):

  • Rounded rectangle boxes as containers
  • Three-layer hierarchy: background → boxes → elements
  • Muted blues/purples for containers, darker blues for buttons
  • Clean separation between groups

dev-servers.sh

Location: ~/GitHub/shared/notes/tools/sites/dev-servers.sh

Starts/restarts dev servers, kills existing processes on ports first.

SitePortDirCommand
api5171shared/notes/tools/sitespython3 dev-api.py
hub5170shared/notes/tools/sitespython3 -m http.server 5170
ws5173wsyarn dev
di5174diyarn dev
ws-docs5176wsyarn docs:dev
shared5177sharedyarn docs:dev

Usage:

bash
restart              # start all (via alias)
~/GitHub/shared/notes/tools/sites/dev-servers.sh ws      # just ws
~/GitHub/shared/notes/tools/sites/dev-servers.sh all --kill-only  # kill all

Logs: ~/GitHub/shared/notes/tools/logs/<n>.log

dev-api.py

Location: ~/GitHub/shared/notes/tools/sites/dev-api.py

Simple API server that executes dev-servers.sh commands. Listens on port 5171.

Endpoints:

  • POST /restart-all — Restarts all dev servers (excludes hub and api)
  • POST /start — Restarts a specific site (body: {"site": "ws"})

dev-hub.html

Location: ~/GitHub/shared/notes/tools/sites/dev-hub.html

URL: http://localhost:5170/dev-hub.html

Segmented Controls

KeyControl
1Dev mode
2Docs mode
Wws project
Ddi project
Sshared project
Een project

Action Buttons

KeyAction
EnterRestart (restarts all dev servers)
LLocal (navigate to localhost)
PPublic (navigate to deployed site)
RRepo (GitHub)
YDeploy (Netlify deploys)
NDNS (Netlify domain settings)
BBubble (plugin editor, ws only)

UI Features

  • Keyboard badges on all buttons
  • Dark theme with green accent for active state
  • Invalid mode/project combos are disabled
  • Dynamic title-box width adjustment (accommodates Restart/Restarting text change)
  • Sticky action highlight — last hovered action stays highlighted until another is hovered
  • Preview on hover — hovering project/mode buttons shows preview in feedback row and updates action button disabled states
  • Selection persists in localStorage across sessions

Shell Alias

Add to ~/.zshrc:

bash
alias restart="~/GitHub/shared/notes/tools/sites/dev-servers.sh all"

Setup

bash
chmod +x ~/GitHub/shared/notes/tools/sites/dev-servers.sh
echo 'alias restart="~/GitHub/shared/notes/tools/sites/dev-servers.sh all"' >> ~/.zshrc
source ~/.zshrc

Implementation Phases

Phase 1: Static Hub v2 ✅

  • [x] Replace dev-hub.html with new layout
  • [x] Add segmented controls (Dev/Docs, ws/di/shared)
  • [x] Add action buttons (Start/Local/Public)
  • [x] Disable invalid combos (di docs, shared dev)
  • [x] Add keyboard shortcuts
  • [x] Local/Public buttons work (navigate)
  • [x] Start button shows command (no execution yet)

Phase 2: Extended Actions ✅

  • [x] Add Repo button (R) → GitHub repo page
  • [x] Add Deploy button (Y) → Netlify deploy page
  • [x] Add DNS button (N) → Netlify DNS settings
  • [x] Add Bubble button (B) → Bubble plugin page (ws only)
  • [x] Add "en" project
  • [x] Update config with URLs per project
  • [x] Disable buttons for projects that don't have that resource
  • [x] Add keyboard badges to buttons

Phase 3: Restart Server Execution ✅

  • [x] Create local API endpoint (dev-api.py) to trigger dev-servers.sh
  • [x] Restart button calls endpoint
  • [x] Show feedback (button text changes to "Restarting" for 7 seconds)

Phase 4: Public URLs

  • [x] a. Gather all currently working public URLs for each project
  • [x] b. Add public URLs to dev-hub.html config
  • [x] c. Public button navigates to deployed site
  • [x] d. Update behavior matrix in docs

Phase 5: Final Doc Deploys to Netlify

  • [x] reorganize tools
  • [ ] shared
  • [ ] di

Current Deployment Status

ProjectDeployPublic
app
wswebseriouslyhttps://webseriously.org
didesignintuition
sharedn/a
enn/a
documentation
wswebseriously-documentation
didesignintuition-documentation
sharedn/a
enn/a

Evolving the UI

See evolve.md for the general pattern.

This project followed that journey — from basic layout through hover previews to edge case refinement.

Iterations

  1. Connected lines — Initial design used visual separators (lines with rounded ends) connecting groups. Felt cluttered.
  2. Standalone boxes — Removed connecting lines. Each group became an independent rounded rectangle. Cleaner, but rows felt disconnected.
  3. Row alignment — Added dynamic width matching so all rows share the same visual width. Used JavaScript to measure and sync.
  4. Two-box title row — Title and Restart button in separate boxes side-by-side. Required complex width calculation (total - button - gap).
  5. Single-box title row — Merged title and Restart into one box. Title uses flex: 1 to fill space and center. Simpler code, cleaner result.