feat: enhance getScans API to support fields and include parameters; … (#8140)

This commit is contained in:
Alejandro Bailo
2025-07-01 08:13:48 +02:00
committed by GitHub
parent f930739a3d
commit e650d19a30
4 changed files with 62 additions and 22 deletions

View File

@@ -16,6 +16,8 @@ export const getScans = async ({
sort = "",
filters = {},
pageSize = 10,
fields = {},
include = "",
}) => {
const headers = await getAuthHeaders({ contentType: false });
@@ -27,6 +29,12 @@ export const getScans = async ({
if (pageSize) url.searchParams.append("page[size]", pageSize.toString());
if (query) url.searchParams.append("filter[search]", query);
if (sort) url.searchParams.append("sort", sort);
if (include) url.searchParams.append("include", include);
// Handle fields parameters
Object.entries(fields).forEach(([key, value]) => {
url.searchParams.append(`fields[${key}]`, String(value));
});
// Handle multiple filters
Object.entries(filters).forEach(([key, value]) => {

View File

@@ -115,7 +115,9 @@ export default async function ComplianceDetail({
>
{selectedScanId && selectedScan && (
<div className="flex max-w-[328px] flex-col items-start">
<ComplianceScanInfo scan={selectedScan} />
<div className="rounded-lg bg-gray-50 p-2 dark:bg-gray-800">
<ComplianceScanInfo scan={selectedScan} />
</div>
<Spacer y={8} />
</div>
)}

View File

@@ -3,7 +3,6 @@ import { Suspense } from "react";
import { getCompliancesOverview } from "@/actions/compliances";
import { getComplianceOverviewMetadataInfo } from "@/actions/compliances";
import { getProvider } from "@/actions/providers";
import { getScans } from "@/actions/scans";
import {
ComplianceCard,
@@ -36,34 +35,41 @@ export default async function Compliance({
"filter[state]": "completed",
},
pageSize: 50,
fields: {
scans: "name,completed_at,provider",
},
include: "provider",
});
if (!scansData?.data) {
return <NoScansAvailable />;
}
// Expand scans with provider information - only include scans with valid provider
const expandedScansData: ExpandedScanData[] = await Promise.all(
scansData.data
.filter((scan: ScanProps) => scan.relationships?.provider?.data?.id)
.map(async (scan: ScanProps) => {
const providerId = scan.relationships!.provider!.data!.id;
// Process scans with provider information from included data
const expandedScansData: ExpandedScanData[] = scansData.data
.filter((scan: ScanProps) => scan.relationships?.provider?.data?.id)
.map((scan: ScanProps) => {
const providerId = scan.relationships!.provider!.data!.id;
const formData = new FormData();
formData.append("id", providerId);
// Find the provider data in the included array
const providerData = scansData.included?.find(
(item: any) => item.type === "providers" && item.id === providerId,
);
const providerData = await getProvider(formData);
if (!providerData) {
return null;
}
return {
...scan,
providerInfo: {
provider: providerData.data.attributes.provider,
uid: providerData.data.attributes.uid,
alias: providerData.data.attributes.alias,
},
};
}),
);
return {
...scan,
providerInfo: {
provider: providerData.attributes.provider,
uid: providerData.attributes.uid,
alias: providerData.attributes.alias,
},
};
})
.filter(Boolean) as ExpandedScanData[];
const selectedScanId =
searchParams.scanId || expandedScansData[0]?.id || null;
@@ -140,7 +146,7 @@ const SSRComplianceGrid = async ({
query,
});
const type = compliancesData?.data?.[0]?.type;
const type = compliancesData?.data?.type;
// Check if the response contains no data
if (

View File

@@ -67,3 +67,27 @@ export interface ExpandedScanData extends ScanProps {
alias: string;
};
}
export interface ScansApiResponse {
links: {
first: string;
last: string;
next: string | null;
prev: string | null;
};
data: ScanProps[];
included?: Array<{
type: string;
id: string;
attributes: any;
relationships?: any;
}>;
meta: {
pagination: {
page: number;
pages: number;
count: number;
};
version: string;
};
}