mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 13:01:56 +00:00
chore: clean finding folder
This commit is contained in:
@@ -1,93 +0,0 @@
|
||||
import { Divider } from "@nextui-org/react";
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
FindingsCardContent,
|
||||
FindingsCardDetail,
|
||||
FindingsCardScan,
|
||||
FindingsCardType,
|
||||
} from "@/components/findings";
|
||||
import { FindingProps } from "@/types";
|
||||
interface FindingsCardProps {
|
||||
selectedRow: FindingProps;
|
||||
}
|
||||
|
||||
export const FindingsCard: React.FC<FindingsCardProps> = ({ selectedRow }) => {
|
||||
const { attributes, card } = selectedRow || {};
|
||||
const { CheckTitle } = attributes || {};
|
||||
const {
|
||||
resourceLink,
|
||||
resourceId,
|
||||
resourceARN,
|
||||
checkLink,
|
||||
checkId,
|
||||
type,
|
||||
scanTime,
|
||||
findingLink,
|
||||
findingId,
|
||||
details,
|
||||
riskDetails,
|
||||
riskLink,
|
||||
recommendationDetails,
|
||||
recommendationLink,
|
||||
referenceInformation,
|
||||
referenceLink,
|
||||
} = card || {};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
"max-h-[calc(100vh-146px)] overflow-y-auto rounded-md border bg-background transition-all duration-300",
|
||||
{
|
||||
"ml-2 w-1/3 translate-x-0 p-3 opacity-100": selectedRow,
|
||||
"w-0 translate-x-full opacity-0": !selectedRow,
|
||||
},
|
||||
)}
|
||||
>
|
||||
<p className="mb-3 font-bold">{CheckTitle}</p>
|
||||
<Divider />
|
||||
|
||||
<FindingsCardContent
|
||||
title="Resource ID:"
|
||||
url={resourceLink}
|
||||
description={resourceId}
|
||||
/>
|
||||
<FindingsCardContent title="Resource ARN:" description={resourceARN} />
|
||||
<FindingsCardContent
|
||||
title="Check ID:"
|
||||
url={checkLink}
|
||||
description={checkId}
|
||||
/>
|
||||
<FindingsCardType type={type} />
|
||||
<FindingsCardScan title="Scan Time:" dateTime={scanTime} />
|
||||
<FindingsCardContent
|
||||
title="Prowler Finding ID:"
|
||||
url={findingLink}
|
||||
description={findingId}
|
||||
/>
|
||||
|
||||
<FindingsCardDetail title="Details:" description={details} />
|
||||
<FindingsCardDetail
|
||||
title="Risk:"
|
||||
url={riskLink}
|
||||
description={riskDetails}
|
||||
type="risk"
|
||||
/>
|
||||
<FindingsCardDetail
|
||||
title="Recommendation:"
|
||||
url={recommendationLink}
|
||||
description={recommendationDetails}
|
||||
type="recommendation"
|
||||
/>
|
||||
<FindingsCardDetail
|
||||
title="Reference Information:"
|
||||
url={referenceLink}
|
||||
description={referenceInformation}
|
||||
type="reference"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Link } from "@nextui-org/react";
|
||||
import React from "react";
|
||||
|
||||
interface FindingsCardContentProps {
|
||||
title: string;
|
||||
url?: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export const FindingsCardContent: React.FC<FindingsCardContentProps> = ({
|
||||
title,
|
||||
url,
|
||||
description,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<p className="mt-3 text-sm font-bold">{title}</p>
|
||||
{url ? (
|
||||
<Link className="text-sm" href={url}>
|
||||
{description}
|
||||
</Link>
|
||||
) : (
|
||||
<p className="text-sm">{description}</p>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
import { Button, Link } from "@nextui-org/react";
|
||||
import React from "react";
|
||||
|
||||
interface FindingsCardDetailProps {
|
||||
title: string;
|
||||
url?: string;
|
||||
description: string;
|
||||
type?: DetailType;
|
||||
}
|
||||
|
||||
type DetailType = "default" | "risk" | "recommendation" | "reference";
|
||||
|
||||
const getDetailColorClass = (type: DetailType): string => {
|
||||
switch (type) {
|
||||
case "risk":
|
||||
return "border-red-200";
|
||||
case "recommendation":
|
||||
return "border-green-200";
|
||||
case "reference":
|
||||
return "border-gray-200";
|
||||
case "default":
|
||||
default:
|
||||
return "border-yellow-200";
|
||||
}
|
||||
};
|
||||
|
||||
export const FindingsCardDetail: React.FC<FindingsCardDetailProps> = ({
|
||||
title,
|
||||
url,
|
||||
description,
|
||||
type = "default",
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{description && (
|
||||
<div
|
||||
className={`mt-3 rounded-md border-2 text-sm ${getDetailColorClass(type)} p-2`}
|
||||
>
|
||||
<p className="mb-2 flex items-center justify-between font-bold">
|
||||
<span>{title}</span>
|
||||
{url && (
|
||||
<Button
|
||||
href={url}
|
||||
as={Link}
|
||||
color="primary"
|
||||
variant="flat"
|
||||
isExternal
|
||||
size="sm"
|
||||
>
|
||||
View Source
|
||||
</Button>
|
||||
)}
|
||||
</p>
|
||||
<p>{description}</p>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
import { format, parseISO } from "date-fns";
|
||||
import React from "react";
|
||||
|
||||
interface FindingsCardScanProps {
|
||||
title: string;
|
||||
dateTime: string;
|
||||
}
|
||||
|
||||
export const FindingsCardScan: React.FC<FindingsCardScanProps> = ({
|
||||
title,
|
||||
dateTime = "",
|
||||
}) => {
|
||||
const date = dateTime && parseISO(dateTime);
|
||||
const formattedDate = date && format(date, "MMM dd, yyyy");
|
||||
const formattedTime = date && format(date, "p 'UTC'");
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="mt-3 text-sm font-bold">{title}</p>
|
||||
<p className="text-sm">
|
||||
{formattedDate} at {formattedTime}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
interface FindingsCardTypeProps {
|
||||
type: string[];
|
||||
}
|
||||
|
||||
export const FindingsCardType: React.FC<FindingsCardTypeProps> = ({
|
||||
type = [],
|
||||
}) => {
|
||||
const typeContent = () => {
|
||||
if (type.length > 0) {
|
||||
return type.join(", ");
|
||||
}
|
||||
return type[0];
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="mt-3 text-sm font-bold">
|
||||
{type.length > 1 ? "Types:" : "Type:"}
|
||||
</p>
|
||||
<p className="text-sm">{typeContent()}</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,8 +1 @@
|
||||
export * from "./FindingsCard";
|
||||
export * from "./FindingsCardContent";
|
||||
export * from "./FindingsCardDetail";
|
||||
export * from "./FindingsCardScan";
|
||||
export * from "./FindingsCardType";
|
||||
export * from "./table/ColumnsFindings";
|
||||
export * from "./table/DataTableFindings";
|
||||
export * from "./table/SkeletonTableFindings";
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
DropdownMenu,
|
||||
DropdownTrigger,
|
||||
} from "@nextui-org/react";
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
|
||||
import { VerticalDotsIcon } from "@/components/icons";
|
||||
import { SeverityBadge } from "@/components/ui/table";
|
||||
import { FindingProps } from "@/types";
|
||||
|
||||
const getFindingsAttributes = (row: { original: FindingProps }) => {
|
||||
return row.original.attributes;
|
||||
};
|
||||
|
||||
export const ColumnsFindings: ColumnDef<FindingProps>[] = [
|
||||
{
|
||||
accessorKey: "checkTitle",
|
||||
header: "Check",
|
||||
cell: ({ row }) => {
|
||||
const { CheckTitle } = getFindingsAttributes(row);
|
||||
return <p className="text-sm">{CheckTitle}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "severity",
|
||||
header: "Severity",
|
||||
cell: ({ row }) => {
|
||||
const { severity } = getFindingsAttributes(row);
|
||||
return <SeverityBadge severity={severity} />;
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
accessorKey: "region",
|
||||
header: "Region",
|
||||
cell: ({ row }) => {
|
||||
const { region } = getFindingsAttributes(row);
|
||||
return <p className="text-nowrap text-sm">{region}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "service",
|
||||
header: "Service",
|
||||
cell: ({ row }) => {
|
||||
const { service } = getFindingsAttributes(row);
|
||||
return <p className="text-sm">{service}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "account",
|
||||
header: "Account",
|
||||
cell: ({ row }) => {
|
||||
const { account } = getFindingsAttributes(row);
|
||||
return <p className="text-sm">{account}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "actions",
|
||||
header: () => (
|
||||
<div className="relative flex items-center justify-end gap-2">
|
||||
<Dropdown className="border-1 border-default-200 bg-background">
|
||||
<DropdownTrigger>
|
||||
<Button isIconOnly radius="full" size="sm" variant="light">
|
||||
<VerticalDotsIcon className="text-default-400" />
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu>
|
||||
<DropdownItem>Mute Findings for Selected Filters</DropdownItem>
|
||||
<DropdownItem>Configure Muted Findings</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -1,133 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@nextui-org/react";
|
||||
import {
|
||||
ColumnDef,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getPaginationRowModel,
|
||||
Row,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { FindingsCard } from "@/components/findings";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { FindingProps } from "@/types";
|
||||
|
||||
interface DataTableFindingsProps<TData extends FindingProps, TValue> {
|
||||
columns: ColumnDef<TData, TValue>[];
|
||||
data: TData[];
|
||||
}
|
||||
|
||||
export function DataTableFindings<TData extends FindingProps, TValue>({
|
||||
columns,
|
||||
data,
|
||||
}: DataTableFindingsProps<TData, TValue>) {
|
||||
const table = useReactTable({
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
});
|
||||
|
||||
const selectedRow = table.getSelectedRowModel().rows[0]?.original;
|
||||
|
||||
const onClick = (row: Row<TData>) => {
|
||||
table.resetRowSelection(true);
|
||||
row.toggleSelected();
|
||||
return;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex w-full flex-row">
|
||||
<div
|
||||
className={clsx("transition-all duration-300", {
|
||||
"w-2/3": selectedRow,
|
||||
"w-full": !selectedRow,
|
||||
})}
|
||||
>
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && "selected"}
|
||||
onClick={() => onClick(row)}
|
||||
className={"hover:cursor-pointer"}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id}>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext(),
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
No results.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
<div className="flex items-center justify-end space-x-2 py-4">
|
||||
<Button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<Button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<FindingsCard selectedRow={selectedRow} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user