diff --git a/src/pages/audit-report/types/index.ts b/src/pages/audit-report/types/index.ts
index 9184e27e1..0d10e1894 100644
--- a/src/pages/audit-report/types/index.ts
+++ b/src/pages/audit-report/types/index.ts
@@ -433,6 +433,10 @@ export interface ViewResult {
namespace?: string;
name: string;
+ refreshStatus?: "cache" | "fresh" | "error";
+ refreshError?: string;
+ responseSource?: "cache" | "fresh";
+
lastRefreshedAt?: string;
columns?: ViewColumnDef[];
rows?: ViewRow[];
diff --git a/src/pages/views/components/SingleView.tsx b/src/pages/views/components/SingleView.tsx
index e83d1ee48..a9a122655 100644
--- a/src/pages/views/components/SingleView.tsx
+++ b/src/pages/views/components/SingleView.tsx
@@ -1,9 +1,16 @@
-import React from "react";
+import React, { useEffect, useState } from "react";
import Age from "../../../ui/Age/Age";
import ViewLayout from "./ViewLayout";
import ViewWithSections from "./ViewWithSections";
import { useViewData } from "../hooks/useViewData";
import { ErrorViewer } from "@flanksource-ui/components/ErrorViewer";
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle
+} from "@flanksource-ui/components/ui/dialog";
interface SingleViewProps {
id: string;
@@ -19,32 +26,43 @@ const SingleView: React.FC = ({ id }) => {
currentVariables,
handleForceRefresh
} = useViewData({ viewId: id });
+ const [refreshErrorOpen, setRefreshErrorOpen] = useState(false);
- if (isLoading && !viewResult) {
+ const refreshError =
+ viewResult?.refreshStatus === "error" ? viewResult.refreshError : undefined;
+ const isCachedResponse = viewResult?.responseSource === "cache";
+
+ useEffect(() => {
+ if (refreshError && isCachedResponse) {
+ setRefreshErrorOpen(true);
+ }
+ }, [refreshError, isCachedResponse, viewResult?.requestFingerprint]);
+
+ if (error && !viewResult) {
return (
-
-
-
Loading view results...
-
+
);
}
- if (error) {
+ if (isLoading && !viewResult) {
return (
-
+
+
+
Loading view results...
+
);
}
@@ -68,27 +86,43 @@ const SingleView: React.FC = ({ id }) => {
const { icon, title, name } = viewResult;
return (
-
- Last refreshed:{" "}
-
-
- )
- }
- >
-
-
+ <>
+
+
+ Last refreshed:{" "}
+
+
+ )
+ }
+ >
+
+
+ >
);
};
diff --git a/src/pages/views/hooks/useViewData.ts b/src/pages/views/hooks/useViewData.ts
index d2fcff12f..422fd211b 100644
--- a/src/pages/views/hooks/useViewData.ts
+++ b/src/pages/views/hooks/useViewData.ts
@@ -49,6 +49,10 @@ export function useViewData({
const variables = isDisplayPluginMode ? displayPluginVariables : undefined;
+ const viewQueryKey = isDisplayPluginMode
+ ? ["viewDataById", viewId, configId, variables]
+ : ["view-result", viewId];
+
const {
data: viewResult,
isLoading: isLoadingViewResult,
@@ -56,9 +60,7 @@ export function useViewData({
error: viewResultError,
refetch
} = useQuery({
- queryKey: isDisplayPluginMode
- ? ["viewDataById", viewId, configId, variables]
- : ["view-result", viewId],
+ queryKey: viewQueryKey,
queryFn: () => {
const headers = forceRefreshRef.current
? { "cache-control": "max-age=1" }
@@ -120,6 +122,16 @@ export function useViewData({
: result.data?.name
? [{ namespace: result.data.namespace ?? "", name: result.data.name }]
: [];
+ const currentNamespace = result.data?.namespace ?? viewResult?.namespace;
+ const currentName = result.data?.name ?? viewResult?.name;
+ const refsToInvalidate = sectionsToRefresh.filter(
+ (section) =>
+ !(
+ currentName &&
+ section.name === currentName &&
+ section.namespace === (currentNamespace ?? "")
+ )
+ );
if (isDisplayPluginMode) {
await queryClient.invalidateQueries({
@@ -127,14 +139,8 @@ export function useViewData({
});
}
- await queryClient.invalidateQueries({
- queryKey: isDisplayPluginMode
- ? ["viewDataById", viewId, configId, variables]
- : ["view-result", viewId]
- });
-
await Promise.all(
- sectionsToRefresh.flatMap((section) => [
+ refsToInvalidate.flatMap((section) => [
queryClient.invalidateQueries({
queryKey: ["view-result", section.namespace, section.name]
}),
@@ -147,12 +153,13 @@ export function useViewData({
])
);
}, [
+ viewResult?.namespace,
+ viewResult?.name,
allSectionRefs,
configId,
isDisplayPluginMode,
queryClient,
refetch,
- variables,
viewId
]);