update all page to refresh immidiately without clicking sync button or refreshing the whole page
This commit is contained in:
1 parent
d5b0c12c40
commit
83a41fbbcb
15 files changed
+490
-151
No files matched your search
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user