feat: procedural editor redesign with collapsible sections and DnD #84
@@ -1,14 +1,15 @@
|
||||
import { useEffect, useState, useCallback } from 'react'
|
||||
import { useParams, useNavigate, useSearchParams } from 'react-router-dom'
|
||||
import { Save, ArrowLeft, ListOrdered, Wrench, Settings, FileText } from 'lucide-react'
|
||||
import { Save, ArrowLeft, ListOrdered, Wrench, Settings, FileText, Calendar } from 'lucide-react'
|
||||
import { treesApi } from '@/api/trees'
|
||||
import { useProceduralEditorStore } from '@/store/proceduralEditorStore'
|
||||
import { CollapsibleEditorSection } from '@/components/procedural-editor/CollapsibleEditorSection'
|
||||
import { IntakeFormBuilder } from '@/components/procedural-editor/IntakeFormBuilder'
|
||||
import { MaintenanceScheduleSection, getScheduleSummary } from '@/components/procedural-editor/MaintenanceScheduleSection'
|
||||
import { StepList } from '@/components/procedural-editor/StepList'
|
||||
import { TagInput } from '@/components/common/TagInput'
|
||||
import { toast } from '@/lib/toast'
|
||||
import type { TreeType } from '@/types'
|
||||
import type { TreeType, MaintenanceSchedule, TargetList } from '@/types'
|
||||
|
||||
type SectionKey = 'details' | 'intake' | 'schedule'
|
||||
|
||||
@@ -49,10 +50,19 @@ export function ProceduralEditorPage() {
|
||||
isEditMode ? null : 'details'
|
||||
)
|
||||
|
||||
// Schedule state for collapsed summary
|
||||
const [schedule, setSchedule] = useState<MaintenanceSchedule | null>(null)
|
||||
const [scheduleTargetList, setScheduleTargetList] = useState<TargetList | null>(null)
|
||||
|
||||
const toggleSection = useCallback((key: SectionKey) => {
|
||||
setExpandedSection(prev => prev === key ? null : key)
|
||||
}, [])
|
||||
|
||||
const handleScheduleLoaded = useCallback((s: MaintenanceSchedule | null, tl: TargetList | null) => {
|
||||
setSchedule(s)
|
||||
setScheduleTargetList(tl)
|
||||
}, [])
|
||||
|
||||
// Load tree or init new
|
||||
useEffect(() => {
|
||||
if (isEditMode && id) {
|
||||
@@ -123,6 +133,8 @@ export function ProceduralEditorPage() {
|
||||
isPublic ? 'Public' : 'Private',
|
||||
].join(' \u00b7 ')
|
||||
|
||||
const scheduleSummary = getScheduleSummary(schedule, scheduleTargetList)
|
||||
|
||||
const intakeSummary = intakeForm.length === 0
|
||||
? 'No fields defined'
|
||||
: `${intakeForm.length} field${intakeForm.length !== 1 ? 's' : ''}: ${intakeForm.map(f => f.label || f.variable_name).slice(0, 4).join(', ')}${intakeForm.length > 4 ? ', \u2026' : ''}`
|
||||
@@ -241,6 +253,21 @@ export function ProceduralEditorPage() {
|
||||
>
|
||||
<IntakeFormBuilder />
|
||||
</CollapsibleEditorSection>
|
||||
|
||||
{isMaintenance && (
|
||||
<CollapsibleEditorSection
|
||||
title="Schedule"
|
||||
icon={<Calendar className="h-4 w-4" />}
|
||||
summary={scheduleSummary}
|
||||
expanded={expandedSection === 'schedule'}
|
||||
onToggle={() => toggleSection('schedule')}
|
||||
>
|
||||
<MaintenanceScheduleSection
|
||||
treeId={treeId}
|
||||
onScheduleLoaded={handleScheduleLoaded}
|
||||
/>
|
||||
</CollapsibleEditorSection>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Step List — flex-1, scrolls independently */}
|
||||
|
||||
Reference in New Issue
Block a user