mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
fix(scans): detail drawer fails after dependencies migration (#8856)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
|
||||
interface AutoRefreshProps {
|
||||
@@ -9,16 +9,21 @@ interface AutoRefreshProps {
|
||||
|
||||
export function AutoRefresh({ hasExecutingScan }: AutoRefreshProps) {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasExecutingScan) return;
|
||||
|
||||
// Don't auto-refresh if scan details drawer is open
|
||||
const scanId = searchParams.get("scanId");
|
||||
if (scanId) return;
|
||||
|
||||
const interval = setInterval(() => {
|
||||
router.refresh();
|
||||
}, 5000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [hasExecutingScan, router]);
|
||||
}, [hasExecutingScan, router, searchParams]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Tooltip } from "@heroui/tooltip";
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
|
||||
import { InfoIcon } from "@/components/icons";
|
||||
import { TableLink } from "@/components/ui/custom";
|
||||
@@ -21,19 +21,44 @@ const getScanData = (row: { original: ScanProps }) => {
|
||||
};
|
||||
|
||||
const ScanDetailsCell = ({ row }: { row: any }) => {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const scanId = searchParams.get("scanId");
|
||||
const isOpen = scanId === row.original.id;
|
||||
const scanState = row.original.attributes?.state;
|
||||
const isExecuting = scanState === "executing" || scanState === "available";
|
||||
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
if (isExecuting) return;
|
||||
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
|
||||
if (open) {
|
||||
params.set("scanId", row.original.id);
|
||||
} else {
|
||||
params.delete("scanId");
|
||||
}
|
||||
|
||||
router.push(`?${params.toString()}`, { scroll: false });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex w-9 items-center justify-center">
|
||||
<TriggerSheet
|
||||
triggerComponent={<InfoIcon className="text-primary" size={16} />}
|
||||
triggerComponent={
|
||||
<InfoIcon
|
||||
className={
|
||||
isExecuting ? "cursor-default text-gray-400" : "text-primary"
|
||||
}
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
title="Scan Details"
|
||||
description="View the scan details"
|
||||
defaultOpen={isOpen}
|
||||
open={isOpen}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<DataTableRowDetails entityId={row.original.id} />
|
||||
{isOpen && <DataTableRowDetails entityId={row.original.id} />}
|
||||
</TriggerSheet>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,36 +1,20 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { getProvider } from "@/actions/providers";
|
||||
import { getScan } from "@/actions/scans";
|
||||
import { getTask } from "@/actions/task";
|
||||
import { ScanDetail } from "@/components/scans/table";
|
||||
import { Alert } from "@/components/ui/alert/Alert";
|
||||
import { checkTaskStatus } from "@/lib";
|
||||
import { ScanProps } from "@/types";
|
||||
|
||||
import { SkeletonScanDetail } from "./skeleton-scan-detail";
|
||||
|
||||
export const DataTableRowDetails = ({ entityId }: { entityId: string }) => {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const [scanDetails, setScanDetails] = useState<ScanProps | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Add scanId to URL
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
params.set("scanId", entityId);
|
||||
router.push(`?${params.toString()}`, { scroll: false });
|
||||
|
||||
// Cleanup function: remove scanId from URL when component unmounts
|
||||
return () => {
|
||||
const newParams = new URLSearchParams(searchParams.toString());
|
||||
newParams.delete("scanId");
|
||||
router.push(`?${newParams.toString()}`, { scroll: false });
|
||||
};
|
||||
}, [entityId, router, searchParams]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchScanDetails = async () => {
|
||||
try {
|
||||
@@ -76,12 +60,7 @@ export const DataTableRowDetails = ({ entityId }: { entityId: string }) => {
|
||||
}, [entityId]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Alert className="text-small text-center font-bold text-gray-500">
|
||||
Scan details are loading and will be available once the scan is
|
||||
completed.
|
||||
</Alert>
|
||||
);
|
||||
return <SkeletonScanDetail />;
|
||||
}
|
||||
|
||||
if (!scanDetails) {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
export const SkeletonScanDetail = () => {
|
||||
return (
|
||||
<div className="flex flex-col gap-6 rounded-lg">
|
||||
{/* Header Skeleton */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="bg-default-200 h-8 w-24 animate-pulse rounded-full" />
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="bg-default-200 relative h-8 w-8 animate-pulse rounded-full" />
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="bg-default-200 h-4 w-32 animate-pulse rounded" />
|
||||
<div className="bg-default-200 h-3 w-24 animate-pulse rounded" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Scan Details Section Skeleton */}
|
||||
<div className="dark:bg-prowler-blue-400 flex flex-col gap-4 rounded-lg p-4 shadow">
|
||||
<div className="bg-default-200 h-5 w-32 animate-pulse rounded" />
|
||||
|
||||
{/* First grid row */}
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<div key={`grid1-${index}`} className="flex flex-col gap-2">
|
||||
<div className="bg-default-200 h-4 w-24 animate-pulse rounded" />
|
||||
<div className="bg-default-200 h-5 w-full animate-pulse rounded" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Second grid row */}
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<div key={`grid2-${index}`} className="flex flex-col gap-2">
|
||||
<div className="bg-default-200 h-4 w-20 animate-pulse rounded" />
|
||||
<div className="bg-default-200 h-5 w-full animate-pulse rounded" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Scan ID field */}
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="bg-default-200 h-4 w-20 animate-pulse rounded" />
|
||||
<div className="bg-default-200 h-10 w-full animate-pulse rounded" />
|
||||
</div>
|
||||
|
||||
{/* Third grid row */}
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<div key={`grid3-${index}`} className="flex flex-col gap-2">
|
||||
<div className="bg-default-200 h-4 w-24 animate-pulse rounded" />
|
||||
<div className="bg-default-200 h-5 w-full animate-pulse rounded" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -12,6 +12,7 @@ interface TriggerSheetProps {
|
||||
title: string;
|
||||
description: string;
|
||||
children: React.ReactNode;
|
||||
open?: boolean;
|
||||
defaultOpen?: boolean;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
@@ -21,11 +22,12 @@ export function TriggerSheet({
|
||||
title,
|
||||
description,
|
||||
children,
|
||||
open,
|
||||
defaultOpen = false,
|
||||
onOpenChange,
|
||||
}: TriggerSheetProps) {
|
||||
return (
|
||||
<Sheet defaultOpen={defaultOpen} onOpenChange={onOpenChange}>
|
||||
<Sheet open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>
|
||||
<SheetTrigger className="flex items-center gap-2">
|
||||
{triggerComponent}
|
||||
</SheetTrigger>
|
||||
|
||||
Reference in New Issue
Block a user