refactor: resilient integration queries + simplification
- Extract settleIntegrationQueries helper (Promise.allSettled + logging) so one failing integration no longer kills the entire widget - Convert 16 widget routers from Promise.all to settleIntegrationQueries - Add onSettled query invalidation to downloads and media-requests mutations - Inline 4 single-use firewall useUpdating* hooks - Deduplicate firewall router (4 identical procedures → shared factory) - Fix system-resources chart duplicate initial point (ref-based dedup) - Simplify docker table refresh (refetch + isFetching, drop manual state) - Trim invalidateIntegrationCacheAsync to session-store only (dead scan) - Fix Beszel getAlerts: inner Promise.allSettled so systems failure doesn't discard alerts
This commit is contained in:
24 files changed
+242
-408
No files matched your search
@@ -111,10 +111,11 @@ export default function DownloadClientsWidget({
|
||||
return statuses;
|
||||
}, [currentItems]);
|
||||
|
||||
//Get API mutation functions
|
||||
const { mutate: mutateResumeItem } = clientApi.widget.downloads.resumeItem.useMutation();
|
||||
const { mutate: mutatePauseItem } = clientApi.widget.downloads.pauseItem.useMutation();
|
||||
const { mutate: mutateDeleteItem } = clientApi.widget.downloads.deleteItem.useMutation();
|
||||
const utils = clientApi.useUtils();
|
||||
const invalidateDownloads = { onSettled: () => void utils.widget.downloads.getJobsAndStatuses.invalidate() };
|
||||
const { mutate: mutateResumeItem } = clientApi.widget.downloads.resumeItem.useMutation(invalidateDownloads);
|
||||
const { mutate: mutatePauseItem } = clientApi.widget.downloads.pauseItem.useMutation(invalidateDownloads);
|
||||
const { mutate: mutateDeleteItem } = clientApi.widget.downloads.deleteItem.useMutation(invalidateDownloads);
|
||||
|
||||
//Flatten Data array for which each element has it's integration, data (base + calculated) and actions. Memoized on data subscription
|
||||
const data = useMemo<ExtendedDownloadClientItem[]>(
|
||||
|
||||
@@ -29,10 +29,10 @@ export default function FirewallWidget({ integrationIds, width, itemId }: Widget
|
||||
}
|
||||
}, []);
|
||||
|
||||
const firewallsCpuData = useUpdatingCpuStatus(integrationIds);
|
||||
const firewallsMemoryData = useUpdatingMemoryStatus(integrationIds);
|
||||
const firewallsVersionData = useUpdatingVersionStatus(integrationIds);
|
||||
const firewallsInterfacesData = useUpdatingInterfacesStatus(integrationIds);
|
||||
const { data: firewallsCpuData = [] } = clientApi.widget.firewall.getFirewallCpuStatus.useQuery({ integrationIds });
|
||||
const { data: firewallsMemoryData = [] } = clientApi.widget.firewall.getFirewallMemoryStatus.useQuery({ integrationIds });
|
||||
const { data: firewallsVersionData = [] } = clientApi.widget.firewall.getFirewallVersionStatus.useQuery({ integrationIds });
|
||||
const { data: firewallsInterfacesData = [] } = clientApi.widget.firewall.getFirewallInterfacesStatus.useQuery({ integrationIds });
|
||||
|
||||
const initialSelectedFirewall = firewallsVersionData[0] ? firewallsVersionData[0].integration.id : "undefined";
|
||||
const isTiny = width < 256;
|
||||
@@ -182,37 +182,6 @@ export default function FirewallWidget({ integrationIds, width, itemId }: Widget
|
||||
);
|
||||
}
|
||||
|
||||
export const useUpdatingCpuStatus = (integrationIds: string[]) => {
|
||||
const { data: firewallsCpuData = [] } = clientApi.widget.firewall.getFirewallCpuStatus.useQuery({
|
||||
integrationIds,
|
||||
});
|
||||
|
||||
return firewallsCpuData;
|
||||
};
|
||||
|
||||
export const useUpdatingMemoryStatus = (integrationIds: string[]) => {
|
||||
const { data: firewallsMemoryData = [] } = clientApi.widget.firewall.getFirewallMemoryStatus.useQuery({
|
||||
integrationIds,
|
||||
});
|
||||
|
||||
return firewallsMemoryData;
|
||||
};
|
||||
|
||||
export const useUpdatingVersionStatus = (integrationIds: string[]) => {
|
||||
const { data: firewallsVersionData = [] } = clientApi.widget.firewall.getFirewallVersionStatus.useQuery({
|
||||
integrationIds,
|
||||
});
|
||||
return firewallsVersionData;
|
||||
};
|
||||
|
||||
export const useUpdatingInterfacesStatus = (integrationIds: string[]) => {
|
||||
const { data: firewallsInterfacesData = [] } = clientApi.widget.firewall.getFirewallInterfacesStatus.useQuery({
|
||||
integrationIds,
|
||||
});
|
||||
|
||||
return firewallsInterfacesData;
|
||||
};
|
||||
|
||||
export function formatBitsPerSec(bytes: number, decimals: number): string {
|
||||
if (bytes === 0) return "0 b/s";
|
||||
|
||||
|
||||
@@ -198,7 +198,10 @@ interface DecisionButtonsProps {
|
||||
}
|
||||
|
||||
const DecisionButtons = ({ requestId, integrationId }: DecisionButtonsProps) => {
|
||||
const { mutate: mutateRequestAnswer } = clientApi.widget.mediaRequests.answerRequest.useMutation();
|
||||
const utils = clientApi.useUtils();
|
||||
const { mutate: mutateRequestAnswer } = clientApi.widget.mediaRequests.answerRequest.useMutation({
|
||||
onSettled: () => void utils.widget.mediaRequests.getLatestRequests.invalidate(),
|
||||
});
|
||||
const t = useScopedI18n("widget.mediaRequests-requestList");
|
||||
const handleDecision = (answer: RouterInputs["widget"]["mediaRequests"]["answerRequest"]["answer"]) => {
|
||||
mutateRequestAnswer({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Box, Group, Stack } from "@mantine/core";
|
||||
import { useElementSize } from "@mantine/hooks";
|
||||
|
||||
@@ -43,7 +43,10 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo
|
||||
{ cpu: number; memory: number; gpu: number; network: { up: number; down: number } | null }[]
|
||||
>(() => (data[0] ? [toChartItem(data[0].healthInfo)] : []));
|
||||
|
||||
const lastUpdatedAt = useRef(dataUpdatedAt);
|
||||
useEffect(() => {
|
||||
if (dataUpdatedAt === lastUpdatedAt.current) return;
|
||||
lastUpdatedAt.current = dataUpdatedAt;
|
||||
const firstItem = data[0];
|
||||
if (!firstItem) return;
|
||||
setItems((prev) => [...prev, toChartItem(firstItem.healthInfo)].slice(-MAX_QUEUE_SIZE));
|
||||
|
||||
Reference in new issue
Block a user