Files
breakpilot-compliance/admin-compliance/app/sdk/rbac/_components/PoliciesTab.tsx
Sharang Parnerkar d5287f4bdd refactor(admin): split rbac page.tsx into colocated components
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 22:50:55 +02:00

98 lines
3.7 KiB
TypeScript

'use client'
import React from 'react'
import type { LLMPolicy } from '../_types'
interface Props {
policies: LLMPolicy[]
onCreate: () => void
onEdit: (p: LLMPolicy) => void
onDelete: (id: string) => void
onToggleActive: (p: LLMPolicy) => void
}
export function PoliciesTab({ policies, onCreate, onEdit, onDelete, onToggleActive }: Props) {
return (
<div>
<div className="flex justify-between items-center mb-4">
<h2 className="text-lg font-semibold">{policies.length} LLM-Policies</h2>
<button
onClick={onCreate}
className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700"
>
+ Policy erstellen
</button>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
{policies.map(policy => (
<div key={policy.id} className={`bg-white rounded-xl border p-5 ${
policy.is_active ? 'border-gray-200' : 'border-gray-100 opacity-60'
}`}>
<div className="flex items-start justify-between mb-3">
<div>
<h3 className="font-semibold text-gray-900">{policy.name}</h3>
<p className="text-xs text-gray-500 mt-0.5">{policy.description}</p>
</div>
<button
onClick={() => onToggleActive(policy)}
className={`px-2 py-0.5 rounded text-xs font-medium ${
policy.is_active ? 'bg-green-50 text-green-700' : 'bg-gray-100 text-gray-500'
}`}
>
{policy.is_active ? 'Aktiv' : 'Inaktiv'}
</button>
</div>
<div className="space-y-2 text-sm">
{(policy.allowed_models || []).length > 0 && (
<div>
<span className="text-gray-500">Erlaubte Models: </span>
<div className="flex flex-wrap gap-1 mt-1">
{policy.allowed_models.map(m => (
<span key={m} className="px-1.5 py-0.5 bg-blue-50 text-blue-700 rounded text-xs">{m}</span>
))}
</div>
</div>
)}
<div className="flex justify-between text-gray-600">
<span>Rate-Limit</span>
<span className="font-mono text-xs">{policy.rate_limit_rpm} req/min, {policy.rate_limit_tpd} tok/tag</span>
</div>
<div className="flex justify-between text-gray-600">
<span>Max Tokens/Request</span>
<span className="font-mono text-xs">{policy.max_tokens_per_request}</span>
</div>
<div className="flex gap-3">
{policy.pii_detection_required && (
<span className="px-2 py-0.5 bg-amber-50 text-amber-700 rounded text-xs">PII-Erkennung</span>
)}
{policy.pii_redaction_required && (
<span className="px-2 py-0.5 bg-red-50 text-red-700 rounded text-xs">PII-Redaktion</span>
)}
</div>
</div>
<div className="flex justify-end gap-2 mt-3 pt-3 border-t border-gray-100">
<button
onClick={() => onEdit(policy)}
className="text-sm text-purple-600 hover:text-purple-700"
>
Bearbeiten
</button>
<button
onClick={() => onDelete(policy.id)}
className="text-sm text-red-600 hover:text-red-700"
>
Loeschen
</button>
</div>
</div>
))}
</div>
{policies.length === 0 && (
<div className="text-center py-12 text-gray-400">Keine LLM-Policies vorhanden</div>
)}
</div>
)
}