mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
feat: allow compliance data selection by choosing a scan
This commit is contained in:
@@ -2,10 +2,12 @@ import { Spacer } from "@nextui-org/react";
|
|||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
|
|
||||||
import { getCompliancesOverview } from "@/actions/compliances";
|
import { getCompliancesOverview } from "@/actions/compliances";
|
||||||
|
import { getScans } from "@/actions/scans";
|
||||||
import {
|
import {
|
||||||
ComplianceCard,
|
ComplianceCard,
|
||||||
ComplianceSkeletonGrid,
|
ComplianceSkeletonGrid,
|
||||||
} from "@/components/compliance";
|
} from "@/components/compliance";
|
||||||
|
import { DataCompliance } from "@/components/compliance/data-compliance";
|
||||||
import { FilterControls } from "@/components/filters";
|
import { FilterControls } from "@/components/filters";
|
||||||
import { Header } from "@/components/ui";
|
import { Header } from "@/components/ui";
|
||||||
import { ComplianceOverviewData, SearchParamsProps } from "@/types";
|
import { ComplianceOverviewData, SearchParamsProps } from "@/types";
|
||||||
@@ -15,26 +17,33 @@ export default async function Compliance({
|
|||||||
}: {
|
}: {
|
||||||
searchParams: SearchParamsProps;
|
searchParams: SearchParamsProps;
|
||||||
}) {
|
}) {
|
||||||
const searchParamsKey = JSON.stringify(searchParams || {});
|
const scansData = await getScans({});
|
||||||
|
const scanList = scansData?.data.map((scan: any) => ({
|
||||||
|
id: scan.id,
|
||||||
|
name: scan.attributes.name || "Unnamed Scan",
|
||||||
|
state: scan.attributes.state,
|
||||||
|
progress: scan.attributes.progress,
|
||||||
|
}));
|
||||||
|
const selectedScanId = searchParams.scanId || scanList[0]?.id;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header title="Compliance" icon="fluent-mdl2:compliance-audit" />
|
<Header title="Compliance" icon="fluent-mdl2:compliance-audit" />
|
||||||
<Spacer y={4} />
|
<Spacer y={4} />
|
||||||
|
<div className="mb-6">
|
||||||
|
<DataCompliance scans={scanList} />
|
||||||
|
</div>
|
||||||
<FilterControls mutedFindings={false} />
|
<FilterControls mutedFindings={false} />
|
||||||
<Spacer y={8} />
|
<Spacer y={8} />
|
||||||
<Suspense key={searchParamsKey} fallback={<ComplianceSkeletonGrid />}>
|
<Suspense fallback={<ComplianceSkeletonGrid />}>
|
||||||
<SSRComplianceGrid />
|
<SSRComplianceGrid scanId={selectedScanId} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SSRComplianceGrid = async () => {
|
const SSRComplianceGrid = async ({ scanId }: { scanId: string }) => {
|
||||||
// const scanId = "01929f57-c0ee-7553-be0b-cbde006fb6f7";
|
|
||||||
const scanId = "0193358c-bd7f-7eec-b13a-2d4a648b8df";
|
|
||||||
const compliancesData = await getCompliancesOverview({ scanId });
|
const compliancesData = await getCompliancesOverview({ scanId });
|
||||||
console.log(compliancesData, "compliancesData");
|
|
||||||
|
|
||||||
if (compliancesData?.errors?.length > 0) {
|
if (compliancesData?.errors?.length > 0) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
|
import { SelectScanComplianceData } from "@/components/compliance/data-compliance";
|
||||||
|
|
||||||
|
interface DataComplianceProps {
|
||||||
|
scans: { id: string; name: string; state: string; progress: number }[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DataCompliance = ({ scans }: DataComplianceProps) => {
|
||||||
|
const router = useRouter();
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const selectedScanId = searchParams.get("scanId") || scans[0]?.id;
|
||||||
|
|
||||||
|
const handleSelectionChange = (selectedKey: string) => {
|
||||||
|
router.push(`?scanId=${selectedKey}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<div className="grid grid-cols-1 items-center gap-x-4 gap-y-4 md:grid-cols-2 xl:grid-cols-4">
|
||||||
|
<SelectScanComplianceData
|
||||||
|
scans={scans}
|
||||||
|
selectedScanId={selectedScanId}
|
||||||
|
onSelectionChange={handleSelectionChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./data-compliance";
|
||||||
|
export * from "./select-scan-compliance-data";
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Select, SelectItem } from "@nextui-org/react";
|
||||||
|
|
||||||
|
interface SelectScanComplianceDataProps {
|
||||||
|
scans: { id: string; name: string; state: string; progress: number }[];
|
||||||
|
selectedScanId: string;
|
||||||
|
onSelectionChange: (selectedKey: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SelectScanComplianceData = ({
|
||||||
|
scans,
|
||||||
|
selectedScanId,
|
||||||
|
onSelectionChange,
|
||||||
|
}: SelectScanComplianceDataProps) => {
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
aria-label="Select a Scan"
|
||||||
|
placeholder="Select a scan"
|
||||||
|
labelPlacement="outside"
|
||||||
|
size="md"
|
||||||
|
selectedKeys={new Set([selectedScanId])}
|
||||||
|
onSelectionChange={(keys) =>
|
||||||
|
onSelectionChange(Array.from(keys)[0] as string)
|
||||||
|
}
|
||||||
|
renderValue={() => {
|
||||||
|
const selectedItem = scans.find((item) => item.id === selectedScanId);
|
||||||
|
return selectedItem ? (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="font-bold">{selectedItem.name}</span>
|
||||||
|
<span className="text-sm text-gray-500">
|
||||||
|
State: {selectedItem.state}, Progress: {selectedItem.progress}%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
"Select a scan"
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{scans.map((scan) => (
|
||||||
|
<SelectItem key={scan.id} textValue={scan.name}>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="font-bold">{scan.name}</span>
|
||||||
|
<span className="text-sm text-gray-500">
|
||||||
|
State: {scan.state}, Progress: {scan.progress}%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
export * from "./ComplianceCard";
|
export * from "./compliance-card";
|
||||||
export * from "./ComplianceSkeletonGrid";
|
export * from "./compliance-skeleton-grid";
|
||||||
|
|||||||
Reference in New Issue
Block a user