Refactor frontend API calls into hooks and complete task states

This commit is contained in:
2026-03-20 15:18:04 +01:00
parent d30d138146
commit 28a7610276
16 changed files with 483 additions and 409 deletions

View File

@@ -25,15 +25,10 @@ import {
ArrowSync24Regular,
} from "@fluentui/react-icons";
import { ApiError } from "../../api/client";
import type { ServerSettingsUpdate, MapColorThresholdsResponse, MapColorThresholdsUpdate } from "../../types/config";
import type { ServerSettingsUpdate, MapColorThresholdsUpdate } from "../../types/config";
import { useServerSettings } from "../../hooks/useConfig";
import { useAutoSave } from "../../hooks/useAutoSave";
import {
fetchMapColorThresholds,
updateMapColorThresholds,
reloadConfig,
restartFail2Ban,
} from "../../api/config";
import { useMapColorThresholds } from "../../hooks/useMapColorThresholds";
import { AutoSaveIndicator } from "./AutoSaveIndicator";
import { ServerHealthSection } from "./ServerHealthSection";
import { useConfigStyles } from "./configStyles";
@@ -48,7 +43,7 @@ const LOG_LEVELS = ["CRITICAL", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG"];
*/
export function ServerTab(): React.JSX.Element {
const styles = useConfigStyles();
const { settings, loading, error, updateSettings, flush } =
const { settings, loading, error, updateSettings, flush, reload, restart } =
useServerSettings();
const [logLevel, setLogLevel] = useState("");
const [logTarget, setLogTarget] = useState("");
@@ -62,11 +57,15 @@ export function ServerTab(): React.JSX.Element {
const [isRestarting, setIsRestarting] = useState(false);
// Map color thresholds
const [mapThresholds, setMapThresholds] = useState<MapColorThresholdsResponse | null>(null);
const {
thresholds: mapThresholds,
error: mapThresholdsError,
refresh: refreshMapThresholds,
updateThresholds: updateMapThresholds,
} = useMapColorThresholds();
const [mapThresholdHigh, setMapThresholdHigh] = useState("");
const [mapThresholdMedium, setMapThresholdMedium] = useState("");
const [mapThresholdLow, setMapThresholdLow] = useState("");
const [mapLoadError, setMapLoadError] = useState<string | null>(null);
const effectiveLogLevel = logLevel || settings?.log_level || "";
const effectiveLogTarget = logTarget || settings?.log_target || "";
@@ -105,11 +104,11 @@ export function ServerTab(): React.JSX.Element {
}
}, [flush]);
const handleReload = useCallback(async () => {
const handleReload = async (): Promise<void> => {
setIsReloading(true);
setMsg(null);
try {
await reloadConfig();
await reload();
setMsg({ text: "fail2ban reloaded successfully", ok: true });
} catch (err: unknown) {
setMsg({
@@ -119,13 +118,13 @@ export function ServerTab(): React.JSX.Element {
} finally {
setIsReloading(false);
}
}, []);
};
const handleRestart = useCallback(async () => {
const handleRestart = async (): Promise<void> => {
setIsRestarting(true);
setMsg(null);
try {
await restartFail2Ban();
await restart();
setMsg({ text: "fail2ban restart initiated", ok: true });
} catch (err: unknown) {
setMsg({
@@ -135,27 +134,15 @@ export function ServerTab(): React.JSX.Element {
} finally {
setIsRestarting(false);
}
}, []);
// Load map color thresholds on mount.
const loadMapThresholds = useCallback(async (): Promise<void> => {
try {
const data = await fetchMapColorThresholds();
setMapThresholds(data);
setMapThresholdHigh(String(data.threshold_high));
setMapThresholdMedium(String(data.threshold_medium));
setMapThresholdLow(String(data.threshold_low));
setMapLoadError(null);
} catch (err) {
setMapLoadError(
err instanceof ApiError ? err.message : "Failed to load map color thresholds",
);
}
}, []);
};
useEffect(() => {
void loadMapThresholds();
}, [loadMapThresholds]);
if (!mapThresholds) return;
setMapThresholdHigh(String(mapThresholds.threshold_high));
setMapThresholdMedium(String(mapThresholds.threshold_medium));
setMapThresholdLow(String(mapThresholds.threshold_low));
}, [mapThresholds]);
// Map threshold validation and auto-save.
const mapHigh = Number(mapThresholdHigh);
@@ -190,9 +177,10 @@ export function ServerTab(): React.JSX.Element {
const saveMapThresholds = useCallback(
async (payload: MapColorThresholdsUpdate): Promise<void> => {
await updateMapColorThresholds(payload);
await updateMapThresholds(payload);
await refreshMapThresholds();
},
[],
[refreshMapThresholds, updateMapThresholds],
);
const { status: mapSaveStatus, errorText: mapSaveErrorText, retry: retryMapSave } =
@@ -332,10 +320,10 @@ export function ServerTab(): React.JSX.Element {
</div>
{/* Map Color Thresholds section */}
{mapLoadError ? (
{mapThresholdsError ? (
<div className={styles.sectionCard}>
<MessageBar intent="error">
<MessageBarBody>{mapLoadError}</MessageBarBody>
<MessageBarBody>{mapThresholdsError}</MessageBarBody>
</MessageBar>
</div>
) : mapThresholds ? (