'use client' import { useState } from 'react' import { Pin, Pencil, Trash2 } from 'lucide-react' import { SafeMarkdown } from '@/components/safe-markdown' import { deleteKbEntry } from '@/lib/actions' import { OpsAclEditor } from '@/components/ops/ops-acl-editor' import { toast } from 'sonner' import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { useConfirm } from '@/components/ui/confirm' import type { AclRoleOption, KbEntry } from '../types' import { VISIBILITY_LABELS, VISIBILITY_COLORS } from '../types' // ─── KB Entry Row ────────────────────────────────────────────────────────────── export function KbEntryRow({ entry, onEdit, onDelete, canManageAcl, aclRoleOptions, aclByEntity, }: { entry: KbEntry onEdit: (e: KbEntry) => void onDelete: (id: string) => void canManageAcl?: boolean aclRoleOptions?: AclRoleOption[] aclByEntity?: Record }) { const confirm = useConfirm() const [viewing, setViewing] = useState(false) const aclEntityType: 'kb' | 'process' = entry.tags?.includes('process') ? 'process' : 'kb' const aclInitial = aclByEntity?.[`${aclEntityType}:${entry.id}`] ?? [] async function handleDelete(e: React.MouseEvent) { e.stopPropagation() if (!(await confirm({ title: 'Delete entry', description: `"${entry.title}" will be permanently removed.`, confirmText: 'Delete', destructive: true }))) return const result = await deleteKbEntry(entry.id) if ('error' in result && result.error) { toast.error(result.error); return } toast.success('Entry deleted') onDelete(entry.id) } function handleEdit(e: React.MouseEvent) { e.stopPropagation() onEdit(entry) } return ( <>
setViewing(true)} className={`flex items-start gap-3 px-4 py-4 hover:bg-muted/20 transition group border-l-4 cursor-pointer ${ entry.is_pinned ? entry.visibility === 'admin_only' ? 'border-l-red-400' : entry.visibility === 'board' ? 'border-l-amber-400' : 'border-l-primary' : 'border-l-transparent' }`} >
{entry.icon || ( )}

{entry.title}

{entry.is_pinned && }

{entry.content?.slice(0, 120)}

{entry.area && {entry.area} · } updated {new Date(entry.updated_at).toLocaleDateString()} by {entry.updated_by_name}

{VISIBILITY_LABELS[entry.visibility] ?? entry.visibility}
{ if (!o) setViewing(false) }}>
{entry.icon && {entry.icon}} {entry.title} {entry.is_pinned && }

{entry.area && {entry.area} · } {VISIBILITY_LABELS[entry.visibility] ?? entry.visibility} {' · '} updated {new Date(entry.updated_at).toLocaleDateString()} by {entry.updated_by_name ?? 'unknown'}

{entry.content ?? ''} {canManageAcl && ( )}
) }