Move completed plan docs to docs/plans/archive/. Add survey migration 046 and reference HTML/plan files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
12 KiB
Procedural & Maintenance Editor Redesign — Design
Date: 2026-02-19 Scope: Restructure the procedural/maintenance flow editor for better space utilization, collapsible sections, drag-to-reorder steps, and maintenance-specific schedule management
Overview
The current procedural editor (ProceduralEditorPage.tsx) uses a scrolling document layout where Details, Intake Form, and Steps stack vertically. The Details and Intake Form sections consume significant screen space, pushing the step list — the core editing surface — to the bottom. This redesign converts the page to a fixed-height editor with collapsible sections and drag-to-reorder steps.
Problems Solved
- Steps buried at the bottom — Details and Intake Form sections are "screen space goblins" that push the step list down, especially on smaller screens
- No drag reorder — grip handles are visible but non-functional; reordering requires deleting and re-creating steps
- Adding steps is tedious — new steps append at the bottom but don't auto-expand, requiring an extra click
- No overview at a glance — collapsed sections don't show useful summaries; users expand just to check what's there
- Maintenance flows lack inline schedule management — schedule/targets are only configurable on the detail page, not during initial creation
Layout Architecture
Current Layout (Scrolling Document)
┌─────────────────────────────────────┐
│ Header (back, title, save, publish) │ ← scrolls with page
├─────────────────────────────────────┤
│ Details Card (~200px) │ ← always expanded
│ Name, Description, Tags, Public │
├─────────────────────────────────────┤
│ Intake Form Card (~150-400px) │ ← always expanded
│ Field editors... │
├─────────────────────────────────────┤
│ Steps Card (whatever's left) │ ← pushed to bottom
│ Step list... │
└─────────────────────────────────────┘
↕ entire page scrolls
New Layout (Fixed-Height Editor)
┌─────────────────────────────────────┐
│ Toolbar (sticky) │ ← fixed, never scrolls
├─────────────────────────────────────┤
│ ▶ Details: "DC Build" · 3 tags · … │ ← collapsed one-liner
│ ▶ Intake Form: 3 fields: Host, … │ ← collapsed one-liner
│ ▶ Schedule: Mon 2:00 AM · 5 targets│ ← maintenance only
├─────────────────────────────────────┤
│ │
│ Steps (flex-1, scrolls alone) │ ← gets all remaining height
│ ┌─ 1. Check prerequisites ───────┐│
│ ├─ 2. Install AD DS role ────────┤│
│ ├─ 3. Promote to DC ────────────┤│
│ ├─ 4. Verify replication ───────┤│
│ └─ + Add Step ───────────────────┘│
│ │
└─────────────────────────────────────┘
Key Layout Changes
- Page:
container mx-autoscrolling →flex flex-col h-full overflow-hidden - Toolbar: Scrolls with page → sticky at top (matches troubleshooting editor pattern)
- Sections: Always-expanded cards → collapsible one-liners with rich summaries
- Step list: Stacked in scroll flow →
flex-1 overflow-y-auto(independent scrolling)
Collapsible Sections
Shared Wrapper: CollapsibleEditorSection
A reusable component used by Details, Intake Form, and Maintenance Schedule.
Props:
title— section label ("Details", "Intake Form", "Schedule")icon— Lucide icon componentsummary— rich one-line summary string shown when collapseddefaultExpanded— whether to start expanded (default:false)children— expanded contentonEdit— optional callback for the Edit button (alternative to expanding)
Collapsed state: Single row with icon, title, summary text, and expand chevron. Entire row is clickable.
Expanded state: Full content slides down with a subtle animation. Collapse chevron rotates.
Accordion mode: Single-open by default — expanding one section collapses others. Controlled by parent page component.
Accessibility:
- Toggle button has
aria-expandedandaria-controlspointing to section contentid - Content region has matching
id - Keyboard operable (Enter/Space to toggle)
- Focus remains stable after toggle
Details Section — Collapsed Summary
Format: "Flow Name" · N tags · Public/Private
Examples:
"Domain Controller Build" · 3 tags · Public"New Procedure" · No tags · Private(new flow, default expanded)
New flow behavior: Details section starts expanded when creating a new flow (name is required), collapses after the user provides a name and clicks away or expands another section.
Intake Form Section — Collapsed Summary
Format: N fields: Field1, Field2, Field3 (field names truncated if many)
Examples:
3 fields: Hostname, Domain Name, IP Address6 fields: Hostname, Domain, IP, DNS, Gateway, …(truncated with ellipsis)No fields defined(empty state)
Maintenance Schedule Section
Only renders when treeType === 'maintenance'.
New flow (no schedule): Section starts expanded with:
- Cron expression builder (frequency picker: daily/weekly/monthly + time + timezone)
- Target list selector (dropdown of saved target lists, or create new inline)
- These fields write to local UI draft state (NOT tree_structure)
- On save: tree saved first, then schedule created via
maintenanceSchedulesApi.createwith resultingtree_id - If schedule create fails: tree save remains successful, show actionable error, preserve draft
Existing flow (has schedule): Collapsed summary:
- Format:
"Every Monday at 2:00 AM UTC · 5 targets" - Expand to modify schedule and targets
Existing flow (no schedule yet): Shows collapsed with summary "No schedule configured" + "Set Up" button that expands the section.
Step List Improvements
Empty State
When the step list has 0 steps, show a centered empty state instead of a blank area:
┌──────────────────────────┐
│ 📋 │
│ Add your first step │
│ │
│ Steps define the actions │
│ engineers follow during │
│ this procedure. │
│ │
│ [+ Add Step] [+ Section]│
└──────────────────────────┘
When 1-2 steps exist, the list renders normally — no special treatment needed since the steps themselves fill the space adequately.
Step Count + Time in Header
The Steps section header shows aggregate info:
Steps (4 steps · ~25 min estimated)— when steps have time estimatesSteps (4 steps)— when no time estimates setSteps (0 steps)— empty state (note: store currently enforces minimum oneprocedure_step, so 0-step state only appears if invariant is intentionally changed)
Auto-Expand New Steps
When addStep() is called, the new step is automatically expanded (setExpandedStepId(newStep.id)) and the step list scrolls to the bottom to show it. This eliminates the extra click to start editing.
Same for addSectionHeader() — auto-expand for immediate title editing.
Drag-to-Reorder
Library: @dnd-kit/core + @dnd-kit/sortable
Behavior:
- Drag via the
GripVerticalhandle on each step card - Dragged card lifts with
shadow-lgand slight scale - Drop target: blue insertion line between steps
- Section headers are draggable — moving a section header moves it independently (steps below stay in place)
- On drop: update the store's step array order (array-index based only, no
display_orderrecalculation) - Keyboard accessible: focus grip handle, Enter/Space to pick up, arrow keys to move, Enter to drop, Escape to cancel
Implementation:
- Wrap step list in
<DndContext>+<SortableContext> - Each step card wrapped in
useSortable()hook - Drag overlay shows a simplified card (just step number + title)
onDragEndhandler reorders thestepsarray in the procedural editor store
Collapsed Step Cards
Current cards are already compact. Minor tightening:
- Step number badge + content type icon + title + time estimate + chevron + delete (on hover)
- No changes to the collapsed card layout — it's already well-designed
Toolbar
Matches the troubleshooting editor's toolbar pattern:
┌─────────────────────────────────────────────────────────────┐
│ ← Back Edit Procedure — DC Build [Unsaved] │ Save │ Publish │
└─────────────────────────────────────────────────────────────┘
- Left: Back button (→
/my-trees), flow type icon, title with flow name - Right: Unsaved indicator, Save Draft button, Publish button (gradient)
- Sticky:
sticky top-0 z-10within the editor area (not the app shell)
Maintenance flows show Wrench icon + "Edit Maintenance Flow" title.
File Changes
Modified Files
| File | Changes |
|---|---|
ProceduralEditorPage.tsx |
Layout restructure: scrolling → fixed-height, collapsible sections, toolbar refactor |
StepList.tsx |
Drag reorder with @dnd-kit, auto-expand on add, empty state, step count header |
IntakeFormBuilder.tsx |
Wrap in collapsible section with field-name summary |
proceduralEditorStore.ts |
reorderSteps(fromIndex, toIndex) action, auto-expand on add |
New Files
| File | Purpose |
|---|---|
components/procedural-editor/CollapsibleEditorSection.tsx |
Shared collapsible wrapper with summary display |
components/procedural-editor/MaintenanceScheduleSection.tsx |
Schedule builder + collapsed summary for maintenance flows |
Existing Dependencies Used
@dnd-kit/core— drag-and-drop framework (already installed)@dnd-kit/sortable— sortable preset for ordered lists (already installed)@dnd-kit/utilities— CSS utilities for transforms (already installed)
Existing APIs Used
frontend/src/api/maintenanceSchedules.ts— schedule CRUD via separate endpoints (NOT tree_structure)frontend/src/api/targetLists.ts— target list selection for schedules
Unchanged
StepEditor.tsx— inline step editing form, no changesIntakeFieldEditor.tsx— field editor, no changesproceduralEditorStore.tssteps/intakeForm data model — no schema changes- Backend — no API changes needed
- Troubleshooting tree editor — completely separate, unaffected
Not Included (YAGNI)
- No drag-to-reorder intake form fields (low value, fields rarely reordered)
- No inline cron expression text input (use friendly frequency picker instead)
- No step templates or presets
- No bulk step operations (select multiple, delete, move)
- No step preview/dry-run from the editor
- No undo/redo for the procedural editor (separate effort)