Merge develop → main: fix opened items banner + remove strikethrough

This commit is contained in:
dadaloop82
2026-05-16 20:33:03 +00:00
2 changed files with 14 additions and 2 deletions
-1
View File
@@ -5751,7 +5751,6 @@ body.cooking-mode-active .app-header {
opacity: 0.75; opacity: 0.75;
} }
.alert-item-spoiled .alert-item-name { .alert-item-spoiled .alert-item-name {
text-decoration: line-through;
color: var(--text-light); color: var(--text-light);
} }
+14 -1
View File
@@ -3926,11 +3926,12 @@ async function loadBannerAlerts() {
if (!banner) { _bannerLoading = false; console.warn('[Banner] #alert-banner not found'); return; } if (!banner) { _bannerLoading = false; console.warn('[Banner] #alert-banner not found'); return; }
try { try {
const [invData, predData, anomalyData, finishedData] = await Promise.all([ const [invData, predData, anomalyData, finishedData, statsData] = await Promise.all([
api('inventory_list'), api('inventory_list'),
api('consumption_predictions').catch(err => { console.warn('[Banner] predictions fetch failed:', err); return { predictions: [] }; }), api('consumption_predictions').catch(err => { console.warn('[Banner] predictions fetch failed:', err); return { predictions: [] }; }),
api('inventory_anomalies').catch(err => { console.warn('[Banner] anomalies fetch failed:', err); return { anomalies: [] }; }), api('inventory_anomalies').catch(err => { console.warn('[Banner] anomalies fetch failed:', err); return { anomalies: [] }; }),
api('inventory_finished_items').catch(err => { console.warn('[Banner] finished_items fetch failed:', err); return { finished: [] }; }), api('inventory_finished_items').catch(err => { console.warn('[Banner] finished_items fetch failed:', err); return { finished: [] }; }),
api('stats').catch(() => ({ opened: [] })),
]); ]);
const items = invData.inventory || []; const items = invData.inventory || [];
const confirmed = getReviewConfirmed(); const confirmed = getReviewConfirmed();
@@ -3971,6 +3972,18 @@ async function loadBannerAlerts() {
_queuedItemIds.add(item.id); _queuedItemIds.add(item.id);
}); });
// 1b. Opened items the SERVER considers not edible (is_edible=false from stats).
// The client-side getExpiredSafety check above uses conservative thresholds (e.g.
// conserve are 'ok' for 30 days past), but the server uses product-specific AI shelf
// life. Trust the server: any opened item with is_edible=false that isn't already
// queued goes into the banner as expired.
const openedNotEdible = (statsData.opened || []).filter(oi => !oi.is_edible && !_queuedItemIds.has(oi.id) && !confirmed['exp_' + oi.id]);
openedNotEdible.forEach(oi => {
const daysOI = Math.abs(oi.days_to_expiry ?? 0);
_bannerQueue.push({ type: 'expired', data: { ...oi, days_expired: daysOI } });
_queuedItemIds.add(oi.id);
});
// 2. Suspicious quantities ("expiring soon" shown only in dashboard sections, not in banner) // 2. Suspicious quantities ("expiring soon" shown only in dashboard sections, not in banner)
// Group items by product identity to detect sibling entries in other locations. // Group items by product identity to detect sibling entries in other locations.
// A "low quantity" alert is suppressed when other stock of the same product exists // A "low quantity" alert is suppressed when other stock of the same product exists