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:
Sophia Dao
2024-08-01 17:41:05 -05:00
parent 6a7b6f3e6b
commit 2bfa37ca2e
5 changed files with 214 additions and 5 deletions
+49 -5
View File
@@ -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)",
},
},
]}
/>
);
};
+2
View File
@@ -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>
);
};
+12
View File
@@ -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;
};
}