feat: refine Archive Management Table with double sorting and CDN sync status

This commit is contained in:
dyzulk
2026-01-07 10:54:41 +07:00
parent 90ea7bb4a2
commit 8ff136d086
2 changed files with 38 additions and 14 deletions

View File

@@ -25,6 +25,7 @@ interface CaCertificate {
issuer_name?: string;
issuer_serial?: string;
family_id?: string;
last_synced_at?: string;
}
interface ArchiveManagementTableProps {
@@ -45,16 +46,26 @@ export default function ArchiveManagementTable({
return type.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
};
const filteredCertificates = useMemo(() => {
return certificates.filter((cert) => {
const search = searchTerm.toLowerCase();
return (
cert.common_name.toLowerCase().includes(search) ||
cert.ca_type.toLowerCase().includes(search) ||
cert.serial_number.toLowerCase().includes(search) ||
cert.uuid.toLowerCase().includes(search)
);
});
const filteredAndSortedCertificates = useMemo(() => {
return [...certificates]
.filter((cert) => {
const search = searchTerm.toLowerCase();
return (
cert.common_name.toLowerCase().includes(search) ||
cert.ca_type.toLowerCase().includes(search) ||
cert.serial_number.toLowerCase().includes(search) ||
cert.uuid.toLowerCase().includes(search)
);
})
.sort((a, b) => {
// Primary Sort: Validity Period (Latest first)
const dateA = new Date(a.valid_from).getTime();
const dateB = new Date(b.valid_from).getTime();
if (dateB !== dateA) return dateB - dateA;
// Secondary Sort: Family ID
return (a.family_id || "").localeCompare(b.family_id || "");
});
}, [certificates, searchTerm]);
return (
@@ -102,10 +113,23 @@ export default function ArchiveManagementTable({
</TableHeader>
<TableBody className="divide-y divide-gray-100 dark:divide-white/[0.05]">
{filteredCertificates.map((cert) => (
{filteredAndSortedCertificates.map((cert) => (
<TableRow key={cert.uuid} className={`hover:bg-gray-50 dark:hover:bg-white/[0.02] transition-colors ${cert.is_latest ? 'bg-blue-50/30 dark:bg-blue-900/10' : ''}`}>
<TableCell className="px-5 py-4 text-start font-mono text-theme-xs text-gray-500 dark:text-gray-400">
{cert.uuid}
<div className="flex flex-col gap-1">
<span>{cert.uuid}</span>
{cert.last_synced_at ? (
<div className="flex items-center gap-1.5">
<span className="flex h-1.5 w-1.5 rounded-full bg-success-500"></span>
<span className="text-[9px] text-success-600 font-bold uppercase tracking-wider">Synced to CDN</span>
</div>
) : (
<div className="flex items-center gap-1.5 opacity-60">
<span className="flex h-1.5 w-1.5 rounded-full bg-warning-500"></span>
<span className="text-[9px] text-warning-600 font-bold uppercase tracking-wider">Local Only</span>
</div>
)}
</div>
</TableCell>
<TableCell className="px-5 py-4 text-start">
{cert.family_id ? (
@@ -166,7 +190,7 @@ export default function ArchiveManagementTable({
</TableCell>
</TableRow>
))}
{filteredCertificates.length === 0 && (
{filteredAndSortedCertificates.length === 0 && (
<TableRow>
<TableCell colSpan={7} className="px-5 py-10 text-center text-gray-500 dark:text-gray-400">
No versions found.

View File

@@ -674,7 +674,7 @@
"status_valid": "Valid",
"status_expired": "Expired",
"self_signed": "Self-Signed",
"renew_button": "Renew Now",
"renew_button": "Renew",
"no_ca_search": "No CAs matched \"{term}\"",
"no_ca_found": "No Root CA certificates found. Start by initializing the Certification Authority."
},