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>
7.0 KiB
Step Library Page — Design
Date: February 24, 2026 Status: Approved Phase: 2.5 — Feature 1 of 3
What We're Building
Replace the "Coming Soon" stub in StepLibraryPage with a fully functional standalone Step Library. Users can browse, search, create, edit, delete, preview, and save steps to their own library.
All backend endpoints and frontend components are already built. This is primarily a wiring and UX integration task.
Scope
In scope:
- Full-page Step Library with header, filters, grouped results
- Create step flow (modal with
StepForm) - Edit step flow (same modal, pre-filled)
- Delete step with confirmation
- "Save to My Library" for steps you don't own (copies step as private)
- Preview via
StepDetailModal StepCardactions adapted for library context (vs. session insert context)
Out of scope:
- Rating/reviewing steps from this page (deferred — will come when steps are used in sessions)
- Admin category management (already exists in Admin Panel)
- Session custom step insertion (Feature 2 of 3)
Card Actions by Context
| Ownership | Actions |
|---|---|
| Your own step | Preview · Edit · Delete |
| Team or public step | Preview · Save to My Library |
"Save to My Library" POSTs a new step copying the title, step_type, content, category, and tags — with visibility: 'private' and the current user as owner.
Page Layout
┌─────────────────────────────────────────────────────────┐
│ Step Library [+ Create Step] │
│ Reusable steps you can insert into any flow │
├─────────────────────────────────────────────────────────┤
│ [Search...] [Category ▼] [Type ▼] [Rating ▼] [Sort▼]│
│ Popular Tags: [powershell] [dns] [quick-fix] ... │
├─────────────────────────────────────────────────────────┤
│ MY STEPS (3) [▲] │
│ ┌────────────┐ ┌────────────┐ │
│ │ StepCard │ │ StepCard │ (Preview · Edit · Del) │
│ └────────────┘ └────────────┘ │
│ │
│ TEAM STEPS (12) [▲] │
│ ┌────────────┐ ┌────────────┐ │
│ │ StepCard │ │ StepCard │ (Preview · Save) │
│ └────────────┘ └────────────┘ │
│ │
│ COMMUNITY (47) [▲] │
│ ┌────────────┐ ┌────────────┐ │
│ │ StepCard │ │ StepCard │ (Preview · Save) │
│ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────┘
Component Architecture
StepLibraryPage (rewritten)
- Owns modal state:
createOpen,editingStep,deletingStepId - Renders page header with "+ Create Step" button
- Renders
StepLibraryBrowserwith page-context props - Renders
StepFormModal(create/edit) - Renders delete confirmation dialog
StepLibraryBrowser (extend props)
Add props:
interface StepLibraryBrowserProps {
onInsert: (step: Step) => void // existing (used in session context)
onEdit?: (step: Step) => void // new — library page only
onDelete?: (stepId: string) => void // new — library page only
onSave?: (step: Step) => void // new — save to my library
onCreateNew?: () => void // existing
showCreateButton?: boolean // existing
currentUserId?: string // new — to determine ownership
}
StepCard (extend props)
Add props mirroring the browser:
interface StepCardProps {
step: StepListItem
onPreview: (step: StepListItem) => void
onInsert?: (step: StepListItem) => void // optional — session context
onEdit?: (step: StepListItem) => void // library context
onDelete?: (stepId: string) => void // library context
onSave?: (step: StepListItem) => void // library context
currentUserId?: string
}
StepCard renders actions based on which callbacks are present and whether step.created_by === currentUserId.
StepFormModal (new wrapper component)
Thin modal shell around the existing StepForm:
- Fixed header ("Create Step" or "Edit Step")
- Scrollable body with
StepForm - Handles create (
stepsApi.create) and update (stepsApi.update) API calls - Calls
onSuccess(step)so the browser list can refresh
Data Flow
Create
- User clicks "+ Create Step"
StepFormModalopens in create mode- On submit →
stepsApi.create(data)→onSuccess→ reload steps
Edit
- User clicks Edit on their own step card
stepsApi.get(stepId)fetches full step (need content fields)StepFormModalopens pre-filled with step data- On submit →
stepsApi.update(id, data)→onSuccess→ reload steps
Delete
- User clicks Delete on their own step card
- Confirmation dialog: "Delete '[title]'? This cannot be undone."
- On confirm →
stepsApi.delete(id)→ remove from local state
Save to My Library
- User clicks "Save to My Library" on a team/public step
- No confirmation needed — silent copy
stepsApi.create({ ...step fields, visibility: 'private' })→ toast "Saved to My Steps"- Reload steps so the copy appears under "My Steps"
Files to Change
| File | Change |
|---|---|
pages/StepLibraryPage.tsx |
Rewrite — wire up browser + modals |
components/step-library/StepCard.tsx |
Add onEdit, onDelete, onSave, currentUserId props; render contextual buttons |
components/step-library/StepLibraryBrowser.tsx |
Add onEdit, onDelete, onSave, currentUserId props; pass through to cards; expose refresh trigger |
components/step-library/StepFormModal.tsx |
Create — thin modal wrapper around StepForm |
No backend changes required.
StepCard Button Layout
Own step:
[Preview] [Edit] [🗑]
Edit and Preview are full-width-ish buttons; delete is an icon-only button in red on hover.
Others' step:
[Preview] [Save to My Library]
Both full-width buttons, same pattern as current Insert layout.