Improve AI logic

This commit is contained in:
Urtzi Alfaro
2025-11-05 13:34:56 +01:00
parent 5c87fbcf48
commit 394ad3aea4
218 changed files with 30627 additions and 7658 deletions

View File

@@ -9,6 +9,8 @@ interface ModelDetailsModalProps {
isOpen: boolean;
onClose: () => void;
model: TrainedModelResponse;
onRetrain?: (settings: any) => void;
onViewPredictions?: (modelId: string) => void;
}
// Helper function to determine performance color based on accuracy
@@ -89,7 +91,9 @@ const FeatureTag: React.FC<{ feature: string }> = ({ feature }) => {
const ModelDetailsModal: React.FC<ModelDetailsModalProps> = ({
isOpen,
onClose,
model
model,
onRetrain,
onViewPredictions
}) => {
// Early return if model is not provided
if (!model) {
@@ -173,7 +177,9 @@ const ModelDetailsModal: React.FC<ModelDetailsModalProps> = ({
},
{
label: "Período de Entrenamiento",
value: `${formatDate((model as any).training_start_date || model.training_period?.start_date || new Date().toISOString())} - ${formatDate((model as any).training_end_date || model.training_period?.end_date || new Date().toISOString())}`
value: model.data_period_start && model.data_period_end
? `${formatDate(model.data_period_start)} a ${formatDate(model.data_period_end)}`
: 'Datos no disponibles'
}
]
},
@@ -307,7 +313,9 @@ const ModelDetailsModal: React.FC<ModelDetailsModalProps> = ({
},
{
label: "Período de Entrenamiento",
value: `${formatDate((model as any).training_start_date || model.training_period?.start_date || new Date().toISOString())} a ${formatDate((model as any).training_end_date || model.training_period?.end_date || new Date().toISOString())}`,
value: model.data_period_start && model.data_period_end
? `${formatDate(model.data_period_start)} a ${formatDate(model.data_period_end)}`
: 'Datos no disponibles',
span: 2
}
]
@@ -360,16 +368,27 @@ const ModelDetailsModal: React.FC<ModelDetailsModalProps> = ({
label: 'Actualizar Modelo',
variant: 'primary' as const,
onClick: () => {
// TODO: Implement model retraining functionality
// This should trigger a new training job for the product
// Implement model retraining functionality
// This triggers a new training job for the product using the existing API
if (onRetrain && model?.inventory_product_id) {
onRetrain({
seasonality_mode: 'additive',
daily_seasonality: true,
weekly_seasonality: true,
yearly_seasonality: false,
});
}
}
},
{
label: 'Ver Predicciones',
variant: 'secondary' as const,
onClick: () => {
// TODO: Navigate to forecast history or predictions view
// This should show historical predictions vs actual sales
// Navigate to forecast history or predictions view
// This shows historical predictions vs actual sales
if (onViewPredictions && model?.model_id) {
onViewPredictions(model.model_id);
}
}
}
];
@@ -401,4 +420,4 @@ const ModelDetailsModal: React.FC<ModelDetailsModalProps> = ({
);
};
export default ModelDetailsModal;
export default ModelDetailsModal;

View File

@@ -330,8 +330,8 @@ export const RetrainModelModal: React.FC<RetrainModelModalProps> = ({
}
};
// Define tab-style actions for header navigation - memoized
const actions: EditViewModalAction[] = React.useMemo(() => [
// Header navigation actions (tabs)
const headerActions = React.useMemo(() => [
{
label: t('models:retrain.modes.quick', 'Rápido'),
icon: Zap,
@@ -358,8 +358,11 @@ export const RetrainModelModal: React.FC<RetrainModelModalProps> = ({
return (
<EditViewModal
isOpen={isOpen}
onClose={onClose}
mode="edit"
onClose={() => {
setMode('quick');
onClose();
}}
mode="edit" // Keep in edit mode so it shows Cancel/Save
title={t('models:retrain.title', 'Reentrenar Modelo')}
subtitle={ingredient.name}
statusIndicator={{
@@ -371,9 +374,10 @@ export const RetrainModelModal: React.FC<RetrainModelModalProps> = ({
}}
size="lg"
sections={sections}
actions={actions}
actions={headerActions}
actionsPosition="header"
showDefaultActions={true}
showDefaultActions={true} // Enable default actions (Cancel/Save)
saveLabel={t('models:retrain.start', 'Iniciar Reentrenamiento')} // Custom save button label for retraining
onSave={handleRetrain}
onFieldChange={handleFieldChange}
loading={isLoading}

View File

@@ -272,6 +272,7 @@ export const UploadSalesDataStep: React.FC<UploadSalesDataStepProps> = ({
const ingredientData = {
name: item.suggested_name,
product_type: item.product_type,
category: item.category,
unit_of_measure: item.unit_of_measure,
low_stock_threshold: minimumStock,

View File

@@ -41,7 +41,14 @@ import {
ChefHat,
ClipboardCheck,
BrainCircuit,
Cog
Cog,
TrendingUp,
Gauge,
PlayCircle,
Layers,
Lightbulb,
Activity,
List
} from 'lucide-react';
export interface SidebarProps {
@@ -120,6 +127,13 @@ const iconMap: Record<string, React.ComponentType<{ className?: string }>> = {
'clipboard-check': ClipboardCheck,
'brain-circuit': BrainCircuit,
cog: Cog,
analytics: TrendingUp,
performance: Gauge,
simulation: PlayCircle,
scenarios: Layers,
insights: Lightbulb,
events: Activity,
list: List,
};
/**
@@ -182,10 +196,14 @@ export const Sidebar = forwardRef<SidebarRef, SidebarProps>(({
'/app/database': 'navigation.data',
'/app/database/inventory': 'navigation.inventory',
'/app/analytics': 'navigation.analytics',
'/app/analytics/production': 'navigation.production_analytics',
'/app/analytics/procurement': 'navigation.procurement_analytics',
'/app/analytics/forecasting': 'navigation.forecasting',
'/app/analytics/scenario-simulation': 'navigation.scenario_simulation',
'/app/analytics/sales': 'navigation.sales',
'/app/analytics/performance': 'navigation.performance',
'/app/analytics/sales': 'navigation.sales_analytics',
'/app/analytics/performance': 'navigation.performance_kpis',
'/app/analytics/ai-insights': 'navigation.ai_insights',
'/app/analytics/events': 'navigation.system_events',
'/app/ai': 'navigation.insights',
'/app/communications': 'navigation.communications',
'/app/communications/notifications': 'navigation.notifications',

View File

@@ -82,6 +82,11 @@ export interface EditViewModalProps {
isRefetching?: boolean; // External refetch state (from React Query)
onSaveComplete?: () => Promise<void>; // Async callback for triggering refetch
refetchTimeout?: number; // Timeout in ms for refetch (default: 3000)
// Custom default action labels
cancelLabel?: string; // Custom label for cancel button
saveLabel?: string; // Custom label for save button
editLabel?: string; // Custom label for edit button
}
/**
@@ -351,6 +356,10 @@ export const EditViewModal: React.FC<EditViewModalProps> = ({
isRefetching = false,
onSaveComplete,
refetchTimeout = 3000,
// Custom default action labels
cancelLabel,
saveLabel,
editLabel,
}) => {
const { t } = useTranslation(['common']);
const StatusIcon = statusIndicator?.icon;
@@ -449,13 +458,13 @@ export const EditViewModal: React.FC<EditViewModalProps> = ({
if (mode === 'view') {
defaultActions.push(
{
label: t('common:modals.actions.cancel', 'Cancelar'),
label: cancelLabel || t('common:modals.actions.cancel', 'Cancelar'),
variant: 'outline',
onClick: onClose,
disabled: isProcessing,
},
{
label: t('common:modals.actions.edit', 'Editar'),
label: editLabel || t('common:modals.actions.edit', 'Editar'),
variant: 'primary',
onClick: handleEdit,
disabled: isProcessing,
@@ -464,13 +473,13 @@ export const EditViewModal: React.FC<EditViewModalProps> = ({
} else {
defaultActions.push(
{
label: t('common:modals.actions.cancel', 'Cancelar'),
label: cancelLabel || t('common:modals.actions.cancel', 'Cancelar'),
variant: 'outline',
onClick: handleCancel,
disabled: isProcessing,
},
{
label: t('common:modals.actions.save', 'Guardar'),
label: saveLabel || t('common:modals.actions.save', 'Guardar'),
variant: 'primary',
onClick: handleSave,
disabled: isProcessing,