update api configuration for panel iot and adjust ai insight
This commit is contained in:
1 parent
a2b5b10977
commit
20d04acb3e
20 files changed
+814
-177
No files matched your search
@@ -72,6 +72,9 @@ const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
|
||||
null
|
||||
);
|
||||
|
||||
const selectedFlock = flocks.find((flock) => flock.id === selectedFlockId) ?? null;
|
||||
const hasIotUrl = Boolean((selectedFlock?.iot_api_url || '').trim());
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedChartKey) return;
|
||||
const onKey = (event: KeyboardEvent) => {
|
||||
@@ -107,7 +110,7 @@ const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [selectedKandang, refreshToken]);
|
||||
}, [selectedKandang]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedCycle || selectedFlockId == null) {
|
||||
@@ -259,12 +262,36 @@ const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
|
||||
const datePickerMin = selectedCycle?.start_date ?? undefined;
|
||||
const datePickerMax = selectedCycle ? resolveCycleBoundDate(selectedCycle) : undefined;
|
||||
|
||||
const refresh = () => {
|
||||
const pullFromApi = async () => {
|
||||
if (!selectedFlockId || !hasIotUrl) return;
|
||||
setRefreshing(true);
|
||||
setRefreshToken((token) => token + 1);
|
||||
window.setTimeout(() => setRefreshing(false), 500);
|
||||
setError(null);
|
||||
try {
|
||||
await api.panelIot.sync({ flock_id: selectedFlockId });
|
||||
setRefreshToken((token) => token + 1);
|
||||
} catch (err) {
|
||||
setError(errorMessage(err));
|
||||
} finally {
|
||||
setRefreshing(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedFlockId || !hasIotUrl) return;
|
||||
const id = window.setInterval(() => {
|
||||
if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return;
|
||||
void (async () => {
|
||||
try {
|
||||
await api.panelIot.sync({ flock_id: selectedFlockId });
|
||||
setRefreshToken((token) => token + 1);
|
||||
} catch {
|
||||
// Live follow stays quiet; manual pull surfaces errors.
|
||||
}
|
||||
})();
|
||||
}, 60_000);
|
||||
return () => window.clearInterval(id);
|
||||
}, [selectedFlockId, hasIotUrl]);
|
||||
|
||||
if (!selectedCycle) return <EmptyFarm onSettings={onSettings} />;
|
||||
|
||||
return (
|
||||
@@ -292,12 +319,13 @@ const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
|
||||
</select>
|
||||
<button
|
||||
type="button"
|
||||
onClick={refresh}
|
||||
disabled={refreshing}
|
||||
onClick={() => void pullFromApi()}
|
||||
disabled={refreshing || !hasIotUrl}
|
||||
className="rounded-lg border border-slate-300 bg-slate-50 px-3 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-100 disabled:opacity-60"
|
||||
title={hasIotUrl ? 'Tarik data dari API IoT' : 'Setel URL IoT di Pengaturan'}
|
||||
>
|
||||
<i className={`fa-solid fa-rotate-right mr-1 ${refreshing ? 'fa-spin' : ''}`} />
|
||||
Refresh
|
||||
{refreshing ? 'Sinkron…' : 'Tarik API'}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
@@ -305,6 +333,12 @@ const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => {
|
||||
|
||||
{error && <Banner kind="error">{error}</Banner>}
|
||||
|
||||
{selectedFlockId != null && !hasIotUrl && (
|
||||
<Banner kind="error">
|
||||
Flock ini belum punya URL API Panel IoT. Setel di Pengaturan → Flock.
|
||||
</Banner>
|
||||
)}
|
||||
|
||||
{selectedFlockId == null ? (
|
||||
<div className={cardClass}>
|
||||
<p className="py-8 text-center text-slate-400">Pilih flock untuk melihat data panel IoT.</p>
|
||||
|
||||
Reference in new issue
Block a user