feat(NetworkMapScheduler): add next scheduled run time to settings response and update frontend to display next run time
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m36s

This commit is contained in:
2026-02-18 14:11:27 +07:00
parent 1fda3a5f4e
commit 8cc3575902
4 changed files with 33 additions and 26 deletions
+2 -25
View File
@@ -278,31 +278,8 @@ export default function NetworkMapDashboard() {
fetchData();
}, [fetchData]);
useEffect(() => {
if (!loading && servers.length > 0 && connections.length > 0) {
const cacheMaxAgeMs = Math.max((pingCacheSeconds || 60) * 1000, 60 * 1000);
if (cacheAppliedAtRef.current && Date.now() - cacheAppliedAtRef.current < cacheMaxAgeMs) {
return;
}
requestPings();
}
return () => {
pingAbortRef.current = true;
};
}, [loading, connections.length, pingCacheSeconds, requestPings]);
useEffect(() => {
if (!loading && connections.length > 0) {
const cacheMaxAgeMs = Math.max((pingCacheSeconds || 60) * 1000, 60 * 1000);
if (cacheAppliedAtRef.current && Date.now() - cacheAppliedAtRef.current < cacheMaxAgeMs) {
return;
}
requestSpeeds();
}
return () => {
speedAbortRef.current = true;
};
}, [loading, connections.length, pingCacheSeconds, requestSpeeds]);
// Пинг и скорость не запускаются автоматически при открытии карты (даже если кеш просрочен).
// Обновление только по кнопкам «Пинг» и «Скорость» или по планировщику.
const handleRefreshPings = () => {
requestPings();
+13
View File
@@ -23,6 +23,7 @@ export default function NetworkMapSchedulerPage() {
runSpeedTest: true,
logMaxLines: 500,
});
const [nextRunAt, setNextRunAt] = useState(null);
const [logs, setLogs] = useState([]);
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
@@ -42,6 +43,7 @@ export default function NetworkMapSchedulerPage() {
runSpeedTest: data.runSpeedTest !== false,
logMaxLines: Math.max(LOG_LINES_MIN, Math.min(LOG_LINES_MAX, Number(data.logMaxLines) || 500)),
});
setNextRunAt(typeof data.nextRunAt === 'number' ? data.nextRunAt : null);
} catch (e) {
setError(e?.response?.data?.message || e?.message || 'Не удалось загрузить настройки');
}
@@ -72,6 +74,12 @@ export default function NetworkMapSchedulerPage() {
return () => clearInterval(t);
}, [fetchLogs]);
useEffect(() => {
if (!settings.enabled || !nextRunAt) return;
const t = setInterval(fetchSettings, 60 * 1000);
return () => clearInterval(t);
}, [settings.enabled, nextRunAt, fetchSettings]);
useEffect(() => {
if (autoScroll && logEndRef.current) {
logEndRef.current.scrollIntoView({ behavior: 'smooth' });
@@ -182,6 +190,11 @@ export default function NetworkMapSchedulerPage() {
<span className="form-check-label">Включить планировщик</span>
</label>
<div className="form-hint">Периодически обновлять пинг и скорость по связям из «Сетевые настройки»</div>
{settings.enabled && nextRunAt != null && (
<div className="mt-2 text-muted small">
Следующий запуск: {new Date(nextRunAt).toLocaleString('ru-RU', { dateStyle: 'short', timeStyle: 'medium' })}
</div>
)}
</div>
<div className="mb-3">