refactor(admin): split sdk-flow page.tsx into colocated components
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>
This commit is contained in:
114
admin-compliance/app/sdk/sdk-flow/_components/StepTable.tsx
Normal file
114
admin-compliance/app/sdk/sdk-flow/_components/StepTable.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
'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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user