mirror of
https://github.com/YuzuZensai/Minikura.git
synced 2026-09-13 18:59:25 +00:00
✨ feat: improve Kubernetes resource monitoring
This commit is contained in:
@@ -6,28 +6,53 @@ import type {
|
||||
K8sConfigMapSummary,
|
||||
K8sServiceSummary,
|
||||
K8sStatus,
|
||||
PodInfo,
|
||||
StatefulSetInfo,
|
||||
} from "@minikura/api";
|
||||
import { LABEL_PREFIX } from "@minikura/api";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { api } from "@/lib/api-client";
|
||||
|
||||
function getErrorMessage(error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
return error.message;
|
||||
}
|
||||
|
||||
if (typeof error === "object" && error) {
|
||||
const value = "value" in error ? error.value : error;
|
||||
if (typeof value === "object" && value && "message" in value) {
|
||||
return String(value.message);
|
||||
}
|
||||
}
|
||||
|
||||
return "Failed to fetch Kubernetes resources";
|
||||
}
|
||||
|
||||
export function useK8sResources() {
|
||||
const [status, setStatus] = useState<K8sStatus | null>(null);
|
||||
const [pods, setPods] = useState<PodInfo[]>([]);
|
||||
const [statefulSets, setStatefulSets] = useState<StatefulSetInfo[]>([]);
|
||||
const [deployments, setDeployments] = useState<DeploymentInfo[]>([]);
|
||||
const [services, setServices] = useState<K8sServiceSummary[]>([]);
|
||||
const [configMaps, setConfigMaps] = useState<K8sConfigMapSummary[]>([]);
|
||||
const [minecraftServers, setMinecraftServers] = useState<CustomResourceSummary[]>([]);
|
||||
const [reverseProxyServers, setReverseProxyServers] = useState<CustomResourceSummary[]>([]);
|
||||
const [status, _setStatus] = useState<K8sStatus>({ initialized: false });
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [initialLoading, setInitialLoading] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const hasLoaded = useRef(false);
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
const isInitialLoad = !hasLoaded.current;
|
||||
|
||||
if (!isInitialLoad) {
|
||||
setRefreshing(true);
|
||||
}
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const [
|
||||
_statusRes,
|
||||
_podsRes,
|
||||
statusRes,
|
||||
podsRes,
|
||||
deploymentsRes,
|
||||
statefulSetsRes,
|
||||
servicesRes,
|
||||
@@ -45,6 +70,14 @@ export function useK8sResources() {
|
||||
api.api.k8s["reverse-proxy-servers"].get(),
|
||||
]);
|
||||
|
||||
if (statusRes.status === "fulfilled" && statusRes.value.data) {
|
||||
setStatus(statusRes.value.data as K8sStatus);
|
||||
}
|
||||
|
||||
if (podsRes.status === "fulfilled" && podsRes.value.data) {
|
||||
setPods(podsRes.value.data as PodInfo[]);
|
||||
}
|
||||
|
||||
if (statefulSetsRes.status === "fulfilled" && statefulSetsRes.value.data) {
|
||||
setStatefulSets(statefulSetsRes.value.data as StatefulSetInfo[]);
|
||||
}
|
||||
@@ -68,33 +101,54 @@ export function useK8sResources() {
|
||||
if (reverseProxyServersRes.status === "fulfilled" && reverseProxyServersRes.value.data) {
|
||||
setReverseProxyServers(reverseProxyServersRes.value.data as CustomResourceSummary[]);
|
||||
}
|
||||
|
||||
const failedRequest = [
|
||||
statusRes,
|
||||
podsRes,
|
||||
deploymentsRes,
|
||||
statefulSetsRes,
|
||||
servicesRes,
|
||||
configMapsRes,
|
||||
minecraftServersRes,
|
||||
reverseProxyServersRes,
|
||||
].find((result) => result.status === "rejected" || Boolean(result.value.error));
|
||||
|
||||
if (failedRequest) {
|
||||
setError(
|
||||
getErrorMessage(
|
||||
failedRequest.status === "rejected" ? failedRequest.reason : failedRequest.value.error
|
||||
)
|
||||
);
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
const errorMessage =
|
||||
err instanceof Error ? err.message : "Failed to fetch Kubernetes resources";
|
||||
setError(errorMessage);
|
||||
setError(getErrorMessage(err));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
hasLoaded.current = true;
|
||||
setInitialLoading(false);
|
||||
setRefreshing(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: fetchData intentionally omitted to avoid infinite loop
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
const interval = setInterval(fetchData, 30000);
|
||||
void fetchData();
|
||||
const interval = setInterval(() => {
|
||||
void fetchData();
|
||||
}, 30000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
}, [fetchData]);
|
||||
|
||||
return {
|
||||
status,
|
||||
pods,
|
||||
statefulSets,
|
||||
deployments,
|
||||
services,
|
||||
configMaps,
|
||||
minecraftServers,
|
||||
reverseProxyServers,
|
||||
status,
|
||||
loading,
|
||||
initialLoading,
|
||||
refreshing,
|
||||
error,
|
||||
refresh: fetchData,
|
||||
labelPrefix: LABEL_PREFIX,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user