mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
feat(findings): WIP - add in initial data table setup, add in some hardcoded value for display purposes, future skeleton loader
This commit is contained in:
@@ -1,13 +1,57 @@
|
||||
import React from "react";
|
||||
import { Spacer } from "@nextui-org/react";
|
||||
import React, { Suspense } from "react";
|
||||
|
||||
import { Header } from "@/components";
|
||||
import {
|
||||
ColumnsFindings,
|
||||
DataTable,
|
||||
Header,
|
||||
SkeletonTableFindings,
|
||||
} from "@/components";
|
||||
|
||||
export default function Findings() {
|
||||
export default async function Findings() {
|
||||
return (
|
||||
<>
|
||||
<Header title="Findings" icon="ph:list-checks-duotone" />
|
||||
|
||||
<p>Hi hi from Findings page</p>
|
||||
<Spacer />
|
||||
<div className="flex flex-col items-end w-full">
|
||||
<Spacer y={6} />
|
||||
<Suspense fallback={<SkeletonTableFindings />}>
|
||||
<SSRDataTable />
|
||||
</Suspense>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const SSRDataTable = async () => {
|
||||
return (
|
||||
<DataTable
|
||||
columns={ColumnsFindings}
|
||||
data={[
|
||||
{
|
||||
id: "12345",
|
||||
attributes: {
|
||||
CheckTitle:
|
||||
"Ensure users of groups with AdministratorAccess policy have MFA tokens enabled",
|
||||
severity: "high",
|
||||
status: "fail",
|
||||
region: "us-west-2",
|
||||
service: "cloudformation",
|
||||
account: "dev (106908755756)",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "67891",
|
||||
attributes: {
|
||||
CheckTitle: "Find secrets in CloudFormation outputs",
|
||||
severity: "low",
|
||||
status: "success",
|
||||
region: "us-east-1",
|
||||
service: "cloudformation",
|
||||
account: "stg (987654321987)",
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
export * from "./providers/DateWithTime";
|
||||
export * from "./providers/ProviderInfo";
|
||||
export * from "./providers/ScanStatus";
|
||||
export * from "./providers/table/ColumnsFindings";
|
||||
export * from "./providers/table/ColumnsProviders";
|
||||
export * from "./providers/table/DataTable";
|
||||
export * from "./providers/table/SkeletonTableFindings";
|
||||
export * from "./providers/table/SkeletonTableProvider";
|
||||
export * from "./ui/alert/Alert";
|
||||
export * from "./ui/header/Header";
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
DropdownMenu,
|
||||
DropdownTrigger,
|
||||
} from "@nextui-org/react";
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
|
||||
import { VerticalDotsIcon } from "@/components/icons";
|
||||
import { FindingsProps } from "@/types";
|
||||
|
||||
const getFindingsAttributes = (row: { original: FindingsProps }) => {
|
||||
return row.original.attributes;
|
||||
};
|
||||
|
||||
export const ColumnsFindings: ColumnDef<FindingsProps>[] = [
|
||||
{
|
||||
accessorKey: "checkTitle",
|
||||
header: "Check",
|
||||
cell: ({ row }) => {
|
||||
const { CheckTitle } = getFindingsAttributes(row);
|
||||
return <p className="text-medium">{CheckTitle}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "severity",
|
||||
header: "Severity",
|
||||
cell: ({ row }) => {
|
||||
const { severity } = getFindingsAttributes(row);
|
||||
return <p className="text-medium">{severity}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "status",
|
||||
header: "Status",
|
||||
cell: ({ row }) => {
|
||||
const { status } = getFindingsAttributes(row);
|
||||
return <p className="text-medium">{status}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "region",
|
||||
header: "Region",
|
||||
cell: ({ row }) => {
|
||||
const { region } = getFindingsAttributes(row);
|
||||
return <p className="text-medium">{region}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "service",
|
||||
header: "Service",
|
||||
cell: ({ row }) => {
|
||||
const { service } = getFindingsAttributes(row);
|
||||
return <p className="text-medium">{service}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "account",
|
||||
header: "Account",
|
||||
cell: ({ row }) => {
|
||||
const { account } = getFindingsAttributes(row);
|
||||
return <p className="text-medium">{account}</p>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "actions",
|
||||
header: () => (
|
||||
<div className="relative flex justify-end items-center gap-2">
|
||||
<Dropdown className="bg-background border-1 border-default-200">
|
||||
<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>
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,65 @@
|
||||
import { Card, Skeleton } from "@nextui-org/react";
|
||||
import React from "react";
|
||||
|
||||
export const SkeletonTableFindings = () => {
|
||||
return (
|
||||
<Card className="w-full h-full space-y-5 p-4" radius="sm">
|
||||
{/* Table headers */}
|
||||
<div className="hidden md:flex justify-between">
|
||||
<Skeleton className="w-1/12 rounded-lg">
|
||||
<div className="h-8 bg-default-200"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="w-2/12 rounded-lg">
|
||||
<div className="h-8 bg-default-200"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="w-2/12 rounded-lg">
|
||||
<div className="h-8 bg-default-200"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="w-2/12 rounded-lg">
|
||||
<div className="h-8 bg-default-200"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="w-2/12 rounded-lg">
|
||||
<div className="h-8 bg-default-200"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="w-1/12 rounded-lg">
|
||||
<div className="h-8 bg-default-200"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="w-1/12 rounded-lg">
|
||||
<div className="h-8 bg-default-200"></div>
|
||||
</Skeleton>
|
||||
</div>
|
||||
|
||||
{/* Table body */}
|
||||
<div className="space-y-3">
|
||||
{[...Array(3)].map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex flex-col md:flex-row justify-between items-center space-x-0 md:space-x-4"
|
||||
>
|
||||
<Skeleton className="w-full md:w-1/12 rounded-lg mb-2 md:mb-0">
|
||||
<div className="h-12 bg-default-300"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="w-full md:w-2/12 rounded-lg mb-2 md:mb-0">
|
||||
<div className="h-12 bg-default-300"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="hidden sm:flex md:w-2/12 rounded-lg mb-2 md:mb-0">
|
||||
<div className="h-12 bg-default-300"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="hidden sm:flex md:w-2/12 rounded-lg mb-2 md:mb-0">
|
||||
<div className="h-12 bg-default-300"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="hidden sm:flex md:w-2/12 rounded-lg mb-2 md:mb-0">
|
||||
<div className="h-12 bg-default-300"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="hidden sm:flex md:w-1/12 rounded-lg mb-2 md:mb-0">
|
||||
<div className="h-12 bg-default-300"></div>
|
||||
</Skeleton>
|
||||
<Skeleton className="hidden sm:flex md:w-1/12 rounded-lg mb-2 md:mb-0">
|
||||
<div className="h-12 bg-default-300"></div>
|
||||
</Skeleton>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
@@ -35,3 +35,15 @@ export interface ProviderProps {
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface FindingsProps {
|
||||
id: string;
|
||||
attributes: {
|
||||
CheckTitle: string;
|
||||
severity: string;
|
||||
status: string;
|
||||
region: string;
|
||||
service: string;
|
||||
account: string;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user