/** * Saved Models Panel Component * * Displays a list of previously saved models that can be loaded or deleted. */ import React, { useEffect, useState, useCallback } from 'react'; import styles from './SavedModelsPanel.module.css'; import { getSavedModels, getSavedModelById, deleteSavedModel, type SavedModelSummary } from '@/core/api-client'; interface SavedModelsPanelProps { onLoadModel: (architecture: any) => void; onClose: () => void; } export const SavedModelsPanel: React.FC = ({ onLoadModel, onClose, }) => { const [models, setModels] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [loadingId, setLoadingId] = useState(null); const [deletingId, setDeletingId] = useState(null); // Fetch saved models on mount const fetchModels = useCallback(async () => { setLoading(true); setError(null); try { const data = await getSavedModels(); setModels(data); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load saved models'); } finally { setLoading(false); } }, []); useEffect(() => { fetchModels(); }, [fetchModels]); // Load a model const handleLoad = useCallback(async (id: number) => { setLoadingId(id); try { const model = await getSavedModelById(id); onLoadModel(model.architecture); onClose(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load model'); } finally { setLoadingId(null); } }, [onLoadModel, onClose]); // Delete a model const handleDelete = useCallback(async (id: number, e: React.MouseEvent) => { e.stopPropagation(); if (!confirm('Are you sure you want to delete this model?')) { return; } setDeletingId(id); try { await deleteSavedModel(id); setModels(prev => prev.filter(m => m.id !== id)); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to delete model'); } finally { setDeletingId(null); } }, []); // Format date const formatDate = (dateStr: string) => { const date = new Date(dateStr); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit', }); }; // Format parameters const formatParams = (params: number) => { if (params >= 1e9) return `${(params / 1e9).toFixed(1)}B`; if (params >= 1e6) return `${(params / 1e6).toFixed(1)}M`; if (params >= 1e3) return `${(params / 1e3).toFixed(1)}K`; return params.toString(); }; return (
e.stopPropagation()}>

>_ SAVED_MODELS

{loading && (
// LOADING SAVED MODELS...
)} {error && (
[ERROR] {error}
)} {!loading && !error && models.length === 0 && (
[--]

NO SAVED MODELS

UPLOAD AND PROCESS A MODEL TO SAVE IT HERE

)} {!loading && models.length > 0 && (
{models.map(model => (
handleLoad(model.id)} >
[NN]
{model.name}
{model.framework} | {model.layer_count} LAYERS | {formatParams(model.total_parameters)}
{formatDate(model.created_at)}
{loadingId === model.id ? (
) : ( <> )}
))}
)}
); }; export default SavedModelsPanel;