// File: frontend/components/admin/ai/VersionHistory.tsx // Change Log: // - 2026-06-14: Created VersionHistory component with type filtering and nice badges (conforming to task T017) // - 2026-06-15: Added All Types view grouped by prompt type (T065) // - 2026-06-15: Added pagination (20 versions/page) (T075) import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { CheckCircle2, Trash2, BookOpen, Clock, StickyNote, Folder, ChevronLeft, ChevronRight } from 'lucide-react'; import { PromptVersion } from '@/lib/types/ai-prompts'; import { cn } from '@/lib/utils'; interface VersionHistoryProps { versions: PromptVersion[]; isLoading: boolean; onLoadTemplate: (version: PromptVersion) => void; onActivateVersion: (versionNumber: number) => void; onDeleteVersion: (versionNumber: number) => void; isActivating: boolean; isDeleting: boolean; showAllTypes?: boolean; } /** * คอมโพเนนต์แสดงประวัติเวอร์ชันของพรอมต์ตามประเภทที่กรองไว้ * หรือแสดงทุกประเภทแบบจัดกลุ่ม (T065) * แสดงรายการเวอร์ชันพร้อมปุ่มพรีโหลด เปิดใช้งาน และลบเวอร์ชันที่ไม่ต้องการ */ export default function VersionHistory({ versions, isLoading, onLoadTemplate, onActivateVersion, onDeleteVersion, isActivating, isDeleting, showAllTypes = false, }: VersionHistoryProps) { const { t } = useTranslation('ai'); const [currentPage, setCurrentPage] = useState(1); const PAGE_SIZE = 20; // T075: 20 versions per page if (isLoading) { return (
{t('prompt_management.version_history')}...
); } // Group versions by prompt type when showing all types const groupedVersions = showAllTypes ? versions.reduce((acc, version) => { const type = version.promptType; if (!acc[type]) { acc[type] = []; } acc[type].push(version); return acc; }, {} as Record) : null; const getPromptTypeLabel = (type: string): string => { const labels: Record = { ocr_extraction: 'สกัดข้อความ OCR (OCR Extraction)', rag_query_prompt: 'ค้นหาข้อมูล RAG (RAG Query)', rag_prep_prompt: 'เตรียมข้อมูล RAG (RAG Prep)', classification_prompt: 'จำแนกประเภทเอกสาร (Classification)', }; return labels[type] || type; }; // Pagination logic (T075) const totalPages = Math.ceil(versions.length / PAGE_SIZE); const startIndex = (currentPage - 1) * PAGE_SIZE; const endIndex = startIndex + PAGE_SIZE; const paginatedVersions = versions.slice(startIndex, endIndex); const handlePreviousPage = () => { setCurrentPage((prev) => Math.max(1, prev - 1)); }; const handleNextPage = () => { setCurrentPage((prev) => Math.min(totalPages, prev + 1)); }; return ( {showAllTypes ? `${t('prompt_management.version_history')} (${t('prompt_management.all_types')})` : t('prompt_management.version_history')} {versions.length === 0 ? (
{t('prompt_management.no_versions')}
) : showAllTypes && groupedVersions ? ( // Grouped view by prompt type (with pagination applied to each group) Object.entries(groupedVersions).map(([promptType, typeVersions]) => { const paginatedGroupVersions = typeVersions.slice(startIndex, endIndex); return (
{getPromptTypeLabel(promptType)}
{paginatedGroupVersions.map((version) => { const isActive = version.isActive === true; return (
v{version.versionNumber} {isActive ? ( {t('prompt_management.is_active')} ) : ( ร่าง (Inactive) )}
สร้าง: {new Date(version.createdAt).toLocaleString('th-TH')}
{!isActive && ( <> )}
{version.manualNote && (

{version.manualNote}

)}
); })}
); }) ) : ( // Single type view with pagination (T075) paginatedVersions.map((version) => { const isActive = version.isActive === true; return (
v{version.versionNumber} {isActive ? ( {t('prompt_management.is_active')} ) : ( ร่าง (Inactive) )}
สร้าง: {new Date(version.createdAt).toLocaleString('th-TH')}
{!isActive && ( <> )}
{version.manualNote && (

{version.manualNote}

)}
); }) )} {/* Pagination controls (T075) */} {totalPages > 1 && (
หน้า {currentPage} จาก {totalPages} ({versions.length} เวอร์ชัน)
)}
); }