feat(sdk): add global seq numbering and visibleWhen for SDK flow navigation
Fix interleaved step ordering by introducing global sequence numbers (100-4700) instead of package-relative order. Add conditional visibility (visibleWhen) for optional steps like Import and DSFA. Fix TOM/workflow prerequisite bugs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -264,13 +264,11 @@ function SidebarContent({ onNavigate }: SidebarContentProps) {
|
||||
return packageCompletion[prevPkg.id] < 100
|
||||
}
|
||||
|
||||
// Get visible steps based on customer type
|
||||
const getVisibleSteps = (packageId: SDKPackageId): SDKStep[] => {
|
||||
// Filter steps based on visibleWhen conditions
|
||||
const getVisibleStepsForPackage = (packageId: SDKPackageId): SDKStep[] => {
|
||||
const steps = getStepsForPackage(packageId)
|
||||
return steps.filter(step => {
|
||||
if (step.id === 'import' && state.customerType === 'new') {
|
||||
return false
|
||||
}
|
||||
if (step.visibleWhen) return step.visibleWhen(state)
|
||||
return true
|
||||
})
|
||||
}
|
||||
@@ -282,7 +280,7 @@ function SidebarContent({ onNavigate }: SidebarContentProps) {
|
||||
<PackageSection
|
||||
key={pkg.id}
|
||||
pkg={pkg}
|
||||
steps={getVisibleSteps(pkg.id)}
|
||||
steps={getVisibleStepsForPackage(pkg.id)}
|
||||
completion={packageCompletion[pkg.id]}
|
||||
currentStepId={currentStepId}
|
||||
completedSteps={state.completedSteps}
|
||||
@@ -296,43 +294,6 @@ function SidebarContent({ onNavigate }: SidebarContentProps) {
|
||||
{/* Pipeline Flow */}
|
||||
<PipelineFlow />
|
||||
|
||||
{/* Zusatzmodule */}
|
||||
<div className="pt-3 border-t border-slate-200 dark:border-gray-700">
|
||||
<div className="text-xs font-medium text-slate-500 dark:text-slate-400 mb-2 px-1">
|
||||
Zusatzmodule
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
{[
|
||||
{ href: '/sdk/rag', label: 'Legal RAG', icon: '🔍' },
|
||||
{ href: '/sdk/quality', label: 'AI Quality', icon: '✅' },
|
||||
{ href: '/sdk/security-backlog', label: 'Security Backlog', icon: '⚠️' },
|
||||
{ href: '/sdk/compliance-hub', label: 'Compliance Hub', icon: '📊' },
|
||||
{ href: '/sdk/dsms', label: 'DSMS', icon: '🛡️' },
|
||||
{ href: '/sdk/academy', label: 'Academy', icon: '🎓' },
|
||||
{ href: '/sdk/whistleblower', label: 'Whistleblower', icon: '📢' },
|
||||
{ href: '/sdk/incidents', label: 'Incidents', icon: '🚨' },
|
||||
{ href: '/sdk/reporting', label: 'Reporting', icon: '📈' },
|
||||
{ href: '/sdk/industry-templates', label: 'Branchenvorlagen', icon: '🏢' },
|
||||
{ href: '/sdk/document-crawler', label: 'Doc Crawler', icon: '📄' },
|
||||
{ href: '/sdk/advisory-board', label: 'Beirat', icon: '💬' },
|
||||
].map(mod => (
|
||||
<Link
|
||||
key={mod.href}
|
||||
href={mod.href}
|
||||
onClick={onNavigate}
|
||||
className={`flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm transition-colors ${
|
||||
pathname === mod.href
|
||||
? 'bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 font-medium'
|
||||
: 'text-slate-600 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-gray-800'
|
||||
}`}
|
||||
>
|
||||
<span className="text-base">{mod.icon}</span>
|
||||
<span className="truncate">{mod.label}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Info */}
|
||||
{currentStep && (
|
||||
<div className="pt-3 border-t border-slate-200 dark:border-gray-700">
|
||||
|
||||
@@ -347,14 +347,11 @@ export function SDKSidebar({ collapsed = false, onCollapsedChange }: SDKSidebarP
|
||||
return steps.some(s => s.url === pathname)
|
||||
}
|
||||
|
||||
// Filter steps based on customer type
|
||||
const getVisibleSteps = (packageId: SDKPackageId): SDKStep[] => {
|
||||
// Filter steps based on visibleWhen conditions
|
||||
const getVisibleStepsForPackage = (packageId: SDKPackageId): SDKStep[] => {
|
||||
const steps = getStepsForPackage(packageId)
|
||||
return steps.filter(step => {
|
||||
// Hide import step for new customers
|
||||
if (step.id === 'import' && state.customerType === 'new') {
|
||||
return false
|
||||
}
|
||||
if (step.visibleWhen) return step.visibleWhen(state)
|
||||
return true
|
||||
})
|
||||
}
|
||||
@@ -397,7 +394,7 @@ export function SDKSidebar({ collapsed = false, onCollapsedChange }: SDKSidebarP
|
||||
{/* Navigation - 5 Packages */}
|
||||
<nav className="flex-1 overflow-y-auto">
|
||||
{SDK_PACKAGES.map(pkg => {
|
||||
const steps = getVisibleSteps(pkg.id)
|
||||
const steps = getVisibleStepsForPackage(pkg.id)
|
||||
const isLocked = isPackageLocked(pkg.id)
|
||||
const isActive = isPackageActive(pkg.id)
|
||||
|
||||
@@ -513,116 +510,20 @@ export function SDKSidebar({ collapsed = false, onCollapsedChange }: SDKSidebarP
|
||||
isActive={pathname === '/sdk/dsms'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/academy"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M12 14l9-5-9-5-9 5 9 5zm0 0l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14zm-4 6v-7.5l4-2.222" />
|
||||
</svg>
|
||||
}
|
||||
label="Academy"
|
||||
isActive={pathname === '/sdk/academy'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/training"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
|
||||
</svg>
|
||||
}
|
||||
label="Training"
|
||||
isActive={pathname === '/sdk/training'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/whistleblower"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M11 5.882V19.24a1.76 1.76 0 01-3.417.592l-2.147-6.15M18 13a3 3 0 100-6M5.436 13.683A4.001 4.001 0 017 6h1.832c4.1 0 7.625-1.234 9.168-3v14c-1.543-1.766-5.067-3-9.168-3H7a3.988 3.988 0 01-1.564-.317z" />
|
||||
</svg>
|
||||
}
|
||||
label="Whistleblower"
|
||||
isActive={pathname === '/sdk/whistleblower'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/incidents"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
}
|
||||
label="Incidents"
|
||||
isActive={pathname === '/sdk/incidents'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/reporting"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||
</svg>
|
||||
}
|
||||
label="Reporting"
|
||||
isActive={pathname === '/sdk/reporting'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/gci"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M11 3.055A9.001 9.001 0 1020.945 13H11V3.055z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M20.488 9H15V3.512A9.025 9.025 0 0120.488 9z" />
|
||||
</svg>
|
||||
}
|
||||
label="GCI Score"
|
||||
isActive={pathname === '/sdk/gci'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/industry-templates"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
|
||||
</svg>
|
||||
}
|
||||
label="Branchenvorlagen"
|
||||
isActive={pathname === '/sdk/industry-templates'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/document-crawler"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M10 21h7a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v11m0 5l4.879-4.879m0 0a3 3 0 104.243-4.242 3 3 0 00-4.243 4.242z" />
|
||||
</svg>
|
||||
}
|
||||
label="Doc Crawler"
|
||||
isActive={pathname === '/sdk/document-crawler'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/advisory-board"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
|
||||
</svg>
|
||||
}
|
||||
label="Beirat"
|
||||
isActive={pathname === '/sdk/advisory-board'}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
{state.companyProfile?.machineBuilder?.ceMarkingRequired && (
|
||||
<AdditionalModuleItem
|
||||
href="/sdk/iace"
|
||||
icon={
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
|
||||
</svg>
|
||||
}
|
||||
label="CE-Compliance (IACE)"
|
||||
isActive={pathname?.startsWith('/sdk/iace') ?? false}
|
||||
collapsed={collapsed}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user