Extract BetriebOverviewPanel, DetailPanel, FlowCanvas, FlowToolbar, StepTable, useFlowGraph hook and helpers into _components/ so page.tsx drops from 1019 to 156 LOC (under the 300 soft target). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
115 lines
4.1 KiB
TypeScript
115 lines
4.1 KiB
TypeScript
'use client'
|
|
|
|
import { SDK_FLOW_STEPS, FLOW_PACKAGES, type SDKFlowStep } from '../flow-data'
|
|
import { completionColor, type PackageFilter } from './helpers'
|
|
|
|
export function StepTable({
|
|
packageFilter,
|
|
selectedStep,
|
|
setSelectedStep,
|
|
visibleCount,
|
|
totalCount,
|
|
}: {
|
|
packageFilter: PackageFilter
|
|
selectedStep: SDKFlowStep | null
|
|
setSelectedStep: (s: SDKFlowStep) => void
|
|
visibleCount: number
|
|
totalCount: number
|
|
}) {
|
|
return (
|
|
<div className="bg-white rounded-xl border border-slate-200 shadow-sm overflow-hidden">
|
|
<div className="px-4 py-3 bg-slate-50 border-b">
|
|
<h3 className="font-medium text-slate-700">
|
|
Alle Steps ({visibleCount}
|
|
{packageFilter !== 'alle' ? ` / ${totalCount}` : ''})
|
|
</h3>
|
|
</div>
|
|
<div className="divide-y max-h-96 overflow-y-auto">
|
|
{SDK_FLOW_STEPS.filter(
|
|
s => packageFilter === 'alle' || s.package === packageFilter
|
|
).map(step => {
|
|
const pkg = FLOW_PACKAGES[step.package]
|
|
return (
|
|
<button
|
|
key={step.id}
|
|
onClick={() => setSelectedStep(step)}
|
|
className={`w-full flex items-center gap-3 p-3 text-left transition-colors ${
|
|
selectedStep?.id === step.id
|
|
? 'bg-purple-50'
|
|
: 'hover:bg-slate-50'
|
|
}`}
|
|
>
|
|
<span
|
|
className="w-8 h-8 rounded-lg flex items-center justify-center text-xs font-bold shrink-0"
|
|
style={{ background: pkg.color.bg, color: pkg.color.text }}
|
|
>
|
|
{step.seq}
|
|
</span>
|
|
<div className="flex-1 min-w-0">
|
|
<div className="font-medium text-slate-800 text-sm">
|
|
{step.name}
|
|
</div>
|
|
<div className="text-xs text-slate-500 flex items-center gap-2 mt-0.5">
|
|
{step.checkpointId && (
|
|
<span
|
|
className={`px-1 py-0 rounded text-[10px] font-medium ${
|
|
step.checkpointType === 'REQUIRED'
|
|
? 'bg-red-100 text-red-600'
|
|
: 'bg-yellow-100 text-yellow-600'
|
|
}`}
|
|
>
|
|
{step.checkpointId}
|
|
</span>
|
|
)}
|
|
{step.dbTables.length > 0 && (
|
|
<span className="text-slate-400">
|
|
DB: {step.dbTables.join(', ')}
|
|
</span>
|
|
)}
|
|
{step.ragCollections.length > 0 && (
|
|
<span className="text-green-600">
|
|
RAG: {step.ragCollections.length}
|
|
</span>
|
|
)}
|
|
{step.isOptional && (
|
|
<span className="text-slate-400 italic">optional</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
{step.completion !== undefined ? (
|
|
<div className="shrink-0 w-24 mr-2">
|
|
<div className="flex items-center justify-between mb-0.5">
|
|
<span
|
|
className="text-[10px] font-bold"
|
|
style={{ color: completionColor(step.completion) }}
|
|
>
|
|
{step.completion}%
|
|
</span>
|
|
</div>
|
|
<div className="h-1.5 bg-slate-100 rounded-full overflow-hidden">
|
|
<div
|
|
className="h-full rounded-full"
|
|
style={{
|
|
width: `${step.completion}%`,
|
|
background: completionColor(step.completion),
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="shrink-0 w-24 mr-2" />
|
|
)}
|
|
<span
|
|
className="px-2 py-0.5 rounded text-[10px] font-medium shrink-0"
|
|
style={{ background: pkg.color.bg, color: pkg.color.text }}
|
|
>
|
|
{pkg.nameShort}
|
|
</span>
|
|
</button>
|
|
)
|
|
})}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|