update all page to refresh immidiately without clicking sync button or refreshing the whole page

This commit is contained in:
Alberto-Audrix committed 2026-10-07 11:17:44 +07:00
1 parent d5b0c12c40
commit 83a41fbbcb
15 files changed
+490 -151

No files matched your search

+93 -4
View File
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
CartesianGrid,
Line,
@@ -69,7 +69,7 @@ type DaySummary = {
};
const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
const { selectedCycle, selectedKandang, selectedSite } = useFarm();
const { selectedCycle, selectedKandang, selectedSite, updateCycle } = useFarm();
const [flocks, setFlocks] = useState<Flock[]>([]);
const [selectedFlockId, setSelectedFlockId] = useState<number | null>(null);
const [dates, setDates] = useState<string[]>([]);
@@ -118,6 +118,69 @@ const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
};
}, [selectedKandang]);
const reload = useCallback(
async (isBackground = false) => {
if (!selectedCycle || selectedFlockId == null) {
return;
}
if (!isBackground) {
setLoading(true);
}
if (!isBackground) {
setError(null);
}
try {
const [dateList, freshCycle] = await Promise.all([
api.panelIot.dates({
cycle_id: selectedCycle.id,
flock_id: selectedFlockId,
}),
api.cycles?.retrieve?.(selectedCycle.id)?.catch(() => null) ?? Promise.resolve(null),
]);
if (freshCycle) {
updateCycle(selectedCycle.id, freshCycle);
}
const sortedDates = [...dateList].sort();
setDates(sortedDates);
const cycleMin = selectedCycle.start_date;
const cycleMax = resolveCycleBoundDate(selectedCycle);
const fallbackDate =
todayIso() > cycleMax ? cycleMax : todayIso() < cycleMin ? cycleMin : todayIso();
let dateToFetch = selectedDate;
if (!dateToFetch) {
if (sortedDates.length > 0) {
dateToFetch = sortedDates[sortedDates.length - 1] ?? fallbackDate;
} else {
dateToFetch = fallbackDate;
}
setSelectedDate(dateToFetch);
}
if (dateToFetch) {
const data = await api.panelIot.list({
cycle_id: selectedCycle.id,
flock_id: selectedFlockId,
date: dateToFetch,
});
const sorted = [...data].sort((a, b) =>
(a.timestamp ?? a.date).localeCompare(b.timestamp ?? b.date)
);
setDayRows(sorted);
}
} catch (err) {
if (!isBackground) {
setError(errorMessage(err));
}
} finally {
if (!isBackground) {
setLoading(false);
}
}
},
[selectedCycle, selectedFlockId, selectedDate, updateCycle]
);
useEffect(() => {
if (!selectedCycle || selectedFlockId == null) {
setDates([]);
@@ -159,7 +222,7 @@ const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
return () => {
cancelled = true;
};
}, [selectedCycle, selectedFlockId]);
}, [selectedCycle?.id, selectedFlockId]);
useEffect(() => {
if (!selectedCycle || selectedFlockId == null || !selectedDate) {
@@ -191,7 +254,33 @@ const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
return () => {
cancelled = true;
};
}, [selectedCycle, selectedFlockId, selectedDate]);
}, [selectedCycle?.id, selectedFlockId, selectedDate]);
useEffect(() => {
if (!selectedCycle || selectedFlockId == null) {
return;
}
const interval = setInterval(() => {
if (document.visibilityState === 'visible') {
void reload(true);
}
}, 60000);
const handleFocusOrVisibility = () => {
if (document.visibilityState === 'visible') {
void reload(true);
}
};
document.addEventListener('visibilitychange', handleFocusOrVisibility);
window.addEventListener('focus', handleFocusOrVisibility);
return () => {
clearInterval(interval);
document.removeEventListener('visibilitychange', handleFocusOrVisibility);
window.removeEventListener('focus', handleFocusOrVisibility);
};
}, [selectedCycle?.id, selectedFlockId, reload]);
const summary = useMemo<DaySummary | null>(() => {
if (dayRows.length === 0) return null;