fix: Prevent undefined rendering in reasoning translations
Fixed React error #306 (text content mismatch) caused by undefined values in reasoning translations. Root cause: Translation functions could return undefined when: - Translation key doesn't exist - reasoning_data has unexpected structure - parameters are missing Changes: - Added defaultValue to all translation calls - Added || fallback operators to ensure strings are always returned - Added proper null/undefined checks with empty string fallbacks - Enhanced getInsightDescription with multiple fallback levels This ensures all translation functions return valid strings, preventing React hydration mismatches and rendering errors on the dashboard.
This commit is contained in:
@@ -34,7 +34,8 @@ export function useReasoningTranslation() {
|
|||||||
return t('purchaseOrder.low_stock_detection', {
|
return t('purchaseOrder.low_stock_detection', {
|
||||||
supplier_name: 'Unknown',
|
supplier_name: 'Unknown',
|
||||||
product_names_joined: 'Items',
|
product_names_joined: 'Items',
|
||||||
days_until_stockout: 7
|
days_until_stockout: 7,
|
||||||
|
defaultValue: 'Purchase order required for inventory replenishment'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,10 +46,11 @@ export function useReasoningTranslation() {
|
|||||||
...parameters,
|
...parameters,
|
||||||
product_names_joined: Array.isArray(parameters.product_names)
|
product_names_joined: Array.isArray(parameters.product_names)
|
||||||
? parameters.product_names.join(', ')
|
? parameters.product_names.join(', ')
|
||||||
: parameters.product_names || 'Items'
|
: parameters.product_names || 'Items',
|
||||||
|
defaultValue: `Purchase order: ${type}`
|
||||||
};
|
};
|
||||||
|
|
||||||
return t(`purchaseOrder.${type}`, params);
|
return t(`purchaseOrder.${type}`, params) || `Purchase order: ${type}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,12 +62,17 @@ export function useReasoningTranslation() {
|
|||||||
product_name: 'Product',
|
product_name: 'Product',
|
||||||
predicted_demand: 0,
|
predicted_demand: 0,
|
||||||
current_stock: 0,
|
current_stock: 0,
|
||||||
confidence_score: 85
|
confidence_score: 85,
|
||||||
|
defaultValue: 'Production batch scheduled based on demand forecast'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { type, parameters } = reasoningData;
|
const { type, parameters } = reasoningData;
|
||||||
return t(`productionBatch.${type}`, parameters);
|
const params = {
|
||||||
|
...parameters,
|
||||||
|
defaultValue: `Production batch: ${type}`
|
||||||
|
};
|
||||||
|
return t(`productionBatch.${type}`, params) || `Production batch: ${type}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,10 +87,11 @@ export function useReasoningTranslation() {
|
|||||||
...consequenceData,
|
...consequenceData,
|
||||||
affected_products_joined: Array.isArray(consequenceData.affected_products)
|
affected_products_joined: Array.isArray(consequenceData.affected_products)
|
||||||
? consequenceData.affected_products.join(', ')
|
? consequenceData.affected_products.join(', ')
|
||||||
: consequenceData.affected_products || 'products'
|
: consequenceData.affected_products || 'products',
|
||||||
|
defaultValue: `Impact: ${consequenceData.type}`
|
||||||
};
|
};
|
||||||
|
|
||||||
return t(`consequence.${consequenceData.type}`, params);
|
return t(`consequence.${consequenceData.type}`, params) || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,7 +99,7 @@ export function useReasoningTranslation() {
|
|||||||
*/
|
*/
|
||||||
const translateSeverity = (severity?: string): string => {
|
const translateSeverity = (severity?: string): string => {
|
||||||
if (!severity) return '';
|
if (!severity) return '';
|
||||||
return t(`severity.${severity}`);
|
return t(`severity.${severity}`, { defaultValue: severity }) || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,7 +107,7 @@ export function useReasoningTranslation() {
|
|||||||
*/
|
*/
|
||||||
const translateTrigger = (trigger?: string): string => {
|
const translateTrigger = (trigger?: string): string => {
|
||||||
if (!trigger) return '';
|
if (!trigger) return '';
|
||||||
return t(`triggers.${trigger}`);
|
return t(`triggers.${trigger}`, { defaultValue: trigger }) || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -137,13 +137,18 @@ const AIInsightsPage: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return t(`${category}.${insight.reasoning_data.type}`, insight.reasoning_data.parameters);
|
const params = {
|
||||||
|
...insight.reasoning_data.parameters,
|
||||||
|
defaultValue: insight.description || `${category}: ${insight.reasoning_data.type}`
|
||||||
|
};
|
||||||
|
const translated = t(`${category}.${insight.reasoning_data.type}`, params);
|
||||||
|
return translated || insight.description || `AI Insight: ${insight.reasoning_data.type}`;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Fall back to description if translation key not found
|
// Fall back to description if translation key not found
|
||||||
return insight.description;
|
return insight.description || 'AI Insight';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return insight.description;
|
return insight.description || 'AI Insight';
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user