From c17001bb4f8775684ce52c15f80975a8b53e86a5 Mon Sep 17 00:00:00 2001 From: sumit_chaturvedi Date: Mon, 2 Jun 2025 08:53:29 +0530 Subject: [PATCH] srn refactoring --- ui/app/(prowler)/compliance/page.tsx | 32 ++------ ui/app/(prowler)/findings/page.tsx | 42 ++--------- .../ui/custom/custom-dropdown-filter.tsx | 3 +- ui/lib/provider-helpers.ts | 73 +++++++++++++++++++ 4 files changed, 85 insertions(+), 65 deletions(-) diff --git a/ui/app/(prowler)/compliance/page.tsx b/ui/app/(prowler)/compliance/page.tsx index 56b6dc9d62..2034f4be16 100644 --- a/ui/app/(prowler)/compliance/page.tsx +++ b/ui/app/(prowler)/compliance/page.tsx @@ -5,7 +5,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, @@ -16,6 +15,7 @@ import { DataCompliance } from "@/components/compliance/data-compliance"; import { FilterControls } from "@/components/filters"; import { ContentLayout } from "@/components/ui"; import { DataTableFilterCustom } from "@/components/ui/table/data-table-filter-custom"; +import { getProviderDetailsByScan } from "@/lib/provider-helpers"; import { ComplianceOverviewData, ScanProps, SearchParamsProps } from "@/types"; export default async function Compliance({ @@ -34,6 +34,7 @@ export default async function Compliance({ "filter[state]": "completed", }, pageSize: 50, + include: "provider", }); if (!scansData?.data) { @@ -41,31 +42,10 @@ export default async function Compliance({ } // Expand scans with provider information - const expandedScansData = await Promise.all( - scansData.data.map(async (scan: ScanProps) => { - const providerId = scan.relationships?.provider?.data?.id; - - if (!providerId) { - return { ...scan, providerInfo: null }; - } - - const formData = new FormData(); - formData.append("id", providerId); - - const providerData = await getProvider(formData); - - return { - ...scan, - providerInfo: providerData?.data - ? { - provider: providerData.data.attributes.provider, - uid: providerData.data.attributes.uid, - alias: providerData.data.attributes.alias, - } - : null, - }; - }), - ); + const expandedScansData = scansData.data.map((scan: ScanProps) => ({ + id: scan.id, + ...getProviderDetailsByScan(scan, scansData.included, "flat"), + })); const selectedScanId = searchParams.scanId || expandedScansData[0]?.id || null; diff --git a/ui/app/(prowler)/findings/page.tsx b/ui/app/(prowler)/findings/page.tsx index 92e5a0cb80..11b5cc746a 100644 --- a/ui/app/(prowler)/findings/page.tsx +++ b/ui/app/(prowler)/findings/page.tsx @@ -26,13 +26,9 @@ import { import { createProviderDetailsMapping, extractProviderUIDs, + getProviderDetailsByScan, } from "@/lib/provider-helpers"; -import { - FindingProps, - IncludeProps, - ScanProps, - SearchParamsProps, -} from "@/types/components"; +import { FindingProps, ScanProps, SearchParamsProps } from "@/types/components"; export default async function Findings({ searchParams, @@ -89,43 +85,15 @@ export default async function Findings({ scan.attributes.unique_resource_count > 1, ) .map((scan: ScanProps) => ({ + ...scan, id: scan.id, - name: scan.attributes.name, - providerId: scan.relationships.provider.data.id, - completed_at: scan.attributes.completed_at, })); const completedScanIds = completedScans?.map((scan: ScanProps) => scan.id) || []; - const providerDetailsAssociatedWithScans = completedScans?.map( - (scan: { - id: string; - name: string; - providerId: string; - completed_at: string; - }) => { - const providerId = scan.providerId; - - const providerDetails = scansData.included.find( - (provider: IncludeProps) => - provider.type === "providers" && provider.id === providerId, - ); - - return { - [scan.id]: { - providerInfo: { - provider: providerDetails?.attributes?.provider, - alias: providerDetails?.attributes?.alias, - uid: providerDetails?.attributes?.uid, - }, - attributes: { - name: scan.name, - completed_at: scan.completed_at, - }, - }, - }; - }, + const providerDetailsAssociatedWithScans = scansData.data.map( + (scan: ScanProps) => getProviderDetailsByScan(scan, scansData.included), ); return ( diff --git a/ui/components/ui/custom/custom-dropdown-filter.tsx b/ui/components/ui/custom/custom-dropdown-filter.tsx index 1fea76b910..8a686c0eab 100644 --- a/ui/components/ui/custom/custom-dropdown-filter.tsx +++ b/ui/components/ui/custom/custom-dropdown-filter.tsx @@ -14,9 +14,8 @@ import { ChevronDown, X } from "lucide-react"; import { useSearchParams } from "next/navigation"; import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { CustomDropdownFilterProps } from "@/types"; - import { ComplianceScanInfo } from "@/components/compliance"; +import { CustomDropdownFilterProps } from "@/types"; export const CustomDropdownFilter = ({ filter, diff --git a/ui/lib/provider-helpers.ts b/ui/lib/provider-helpers.ts index 3a6871bc9d..9637625467 100644 --- a/ui/lib/provider-helpers.ts +++ b/ui/lib/provider-helpers.ts @@ -1,3 +1,4 @@ +import { IncludeProps, ScanProps } from "@/types"; import { ProviderProps, ProvidersApiResponse, @@ -48,3 +49,75 @@ export const createProviderDetailsMapping = ( }; }); }; + +/** + * Extracts and formats provider details associated with a given scan. + * + * @param scan - The scan object containing scan attributes and provider relationship data. + * @param included - An array of included related resources (e.g., providers). + * @param format - Optional. Specifies the structure of the returned object. + * - "keyed" (default): Returns an object keyed by scan ID with providerInfo and attributes. + * - "flat": Returns a flat object containing providerInfo and attributes. + * - "merged": Returns the full scan object with providerInfo merged in. + * + * @returns An object containing provider information and scan attributes in the specified format. + * + * @example + * const result = getProviderDetailsByScan(scan, included, "flat"); + * // { + * // providerInfo: { provider: 'Example Provider', alias: 'EP', uid: '123' }, + * // attributes: { name: 'Scan 1', started_at: '2024-01-01', completed_at: '2024-01-02' } + * // } + */ +export const getProviderDetailsByScan = ( + scan: ScanProps, + included: IncludeProps[], + format: "keyed" | "flat" | "merged" = "keyed", +) => { + const providerId = scan.relationships?.provider?.data?.id; + + const providerDetails = providerId + ? included.find( + (provider) => + provider.type === "providers" && provider.id === providerId, + ) + : null; + + const providerInfo = { + provider: providerDetails?.attributes?.provider, + alias: providerDetails?.attributes?.alias ?? null, + uid: providerDetails?.attributes?.uid ?? null, + }; + + const attributes = { + name: scan.attributes?.name, + started_at: scan.attributes?.started_at, + completed_at: scan.attributes?.completed_at, + }; + + // --- FORMAT 1: keyed (default) + if (format === "keyed") { + return { + [scan.id]: { + providerInfo, + attributes, + }, + }; + } + + // --- FORMAT 2: flat object + if (format === "flat") { + return { + providerInfo, + attributes, + }; + } + + // --- FORMAT 3: merged into full scan object + if (format === "merged") { + return { + ...scan, + providerInfo, + }; + } +};