Improve the frontend 2
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
||||
useModelPerformance,
|
||||
useTenantTrainingStatistics
|
||||
} from '../../../../api/hooks/training';
|
||||
import { ModelDetailsModal } from '../../../../components/domain/forecasting';
|
||||
import { ModelDetailsModal, RetrainModelModal } from '../../../../components/domain/forecasting';
|
||||
import type { IngredientResponse } from '../../../../api/types/inventory';
|
||||
import type { TrainedModelResponse, SingleProductTrainingRequest } from '../../../../api/types/training';
|
||||
|
||||
@@ -47,6 +47,7 @@ const ModelsConfigPage: React.FC = () => {
|
||||
const [selectedIngredient, setSelectedIngredient] = useState<IngredientResponse | null>(null);
|
||||
const [selectedModel, setSelectedModel] = useState<TrainedModelResponse | null>(null);
|
||||
const [showTrainingModal, setShowTrainingModal] = useState(false);
|
||||
const [showRetrainModal, setShowRetrainModal] = useState(false);
|
||||
const [showModelDetailsModal, setShowModelDetailsModal] = useState(false);
|
||||
const [trainingSettings, setTrainingSettings] = useState<Partial<SingleProductTrainingRequest>>({
|
||||
seasonality_mode: 'additive',
|
||||
@@ -183,9 +184,38 @@ const ModelsConfigPage: React.FC = () => {
|
||||
setShowTrainingModal(true);
|
||||
};
|
||||
|
||||
|
||||
const handleStartRetraining = (ingredient: IngredientResponse) => {
|
||||
setSelectedIngredient(ingredient);
|
||||
|
||||
// Find and set the model for this ingredient
|
||||
const model = modelStatuses.find(status => status.ingredient.id === ingredient.id)?.model;
|
||||
if (model) {
|
||||
setSelectedModel(model);
|
||||
}
|
||||
|
||||
setShowRetrainModal(true);
|
||||
};
|
||||
|
||||
const handleRetrain = async (settings: SingleProductTrainingRequest) => {
|
||||
if (!selectedIngredient) return;
|
||||
|
||||
try {
|
||||
await trainMutation.mutateAsync({
|
||||
tenantId,
|
||||
inventoryProductId: selectedIngredient.id,
|
||||
request: settings
|
||||
});
|
||||
|
||||
addToast(`Reentrenamiento iniciado para ${selectedIngredient.name}`, { type: 'success' });
|
||||
setShowRetrainModal(false);
|
||||
setSelectedIngredient(null);
|
||||
setSelectedModel(null);
|
||||
} catch (error) {
|
||||
addToast('Error al reentrenar el modelo', { type: 'error' });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
if (ingredientsLoading || modelsLoading) {
|
||||
return (
|
||||
@@ -238,7 +268,7 @@ const ModelsConfigPage: React.FC = () => {
|
||||
},
|
||||
{
|
||||
title: 'Precisión Promedio',
|
||||
value: statsError ? 'N/A' : (statistics?.average_accuracy ? `${Number(statistics.average_accuracy).toFixed(1)}%` : 'N/A'),
|
||||
value: statsError ? 'N/A' : (statistics?.models?.average_accuracy !== undefined && statistics?.models?.average_accuracy !== null ? `${Number(statistics.models.average_accuracy).toFixed(1)}%` : 'N/A'),
|
||||
icon: TrendingUp,
|
||||
variant: 'success',
|
||||
},
|
||||
@@ -354,7 +384,7 @@ const ModelsConfigPage: React.FC = () => {
|
||||
...(status.hasModel ? [{
|
||||
label: 'Reentrenar',
|
||||
icon: RotateCcw,
|
||||
onClick: () => handleStartTraining(status.ingredient),
|
||||
onClick: () => handleStartRetraining(status.ingredient),
|
||||
priority: 'secondary' as const
|
||||
}] : [])
|
||||
]}
|
||||
@@ -451,6 +481,22 @@ const ModelsConfigPage: React.FC = () => {
|
||||
model={selectedModel}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Retrain Model Modal */}
|
||||
{selectedIngredient && (
|
||||
<RetrainModelModal
|
||||
isOpen={showRetrainModal}
|
||||
onClose={() => {
|
||||
setShowRetrainModal(false);
|
||||
setSelectedIngredient(null);
|
||||
setSelectedModel(null);
|
||||
}}
|
||||
ingredient={selectedIngredient}
|
||||
currentModel={selectedModel}
|
||||
onRetrain={handleRetrain}
|
||||
isLoading={trainMutation.isPending}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user