# 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 1. **Steps buried at the bottom** — Details and Intake Form sections are "screen space goblins" that push the step list down, especially on smaller screens 2. **No drag reorder** — grip handles are visible but non-functional; reordering requires deleting and re-creating steps 3. **Adding steps is tedious** — new steps append at the bottom but don't auto-expand, requiring an extra click 4. **No overview at a glance** — collapsed sections don't show useful summaries; users expand just to check what's there 5. **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-auto` scrolling → `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 component - `summary` — rich one-line summary string shown when collapsed - `defaultExpanded` — whether to start expanded (default: `false`) - `children` — expanded content - `onEdit` — 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-expanded` and `aria-controls` pointing to section content `id` - 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 Address` - `6 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.create` with resulting `tree_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 estimates - `Steps (4 steps)` — when no time estimates set - `Steps (0 steps)` — empty state (note: store currently enforces minimum one `procedure_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 `GripVertical` handle on each step card - Dragged card lifts with `shadow-lg` and 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_order` recalculation) - 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 `` + `` - Each step card wrapped in `useSortable()` hook - Drag overlay shows a simplified card (just step number + title) - `onDragEnd` handler reorders the `steps` array 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-10` within 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 changes - `IntakeFieldEditor.tsx` — field editor, no changes - `proceduralEditorStore.ts` steps/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)