chore: finding details tweaks

This commit is contained in:
Pablo Lara
2024-11-20 08:31:29 +01:00
parent b28cfede8c
commit a2cc3e913d
16 changed files with 310 additions and 165 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ export const CustomDatePicker = () => {
CalendarTopContent={
<ButtonGroup
fullWidth
className="bg-content1 px-3 pb-2 pt-3 [&>button]:border-default-200/60 [&>button]:text-default-500"
className="bg-content1 px-3 pb-2 pt-3 dark:bg-prowler-blue-400 [&>button]:border-default-200/60 [&>button]:text-default-500"
radius="full"
size="sm"
variant="bordered"
@@ -1,8 +1,40 @@
"use client";
import { FindingDetail } from "@/components/findings/table";
import { FindingProps } from "@/types";
// import { usePathname, useRouter, useSearchParams } from "next/navigation";
// import { useEffect } from "react";
export const DataTableRowDetails = ({ finding }: { finding: FindingProps }) => {
return <FindingDetail findingDetails={finding} />;
import { FindingProps } from "@/types/components";
import { FindingDetail } from "./finding-detail";
export const DataTableRowDetails = ({
// entityId,
findingDetails,
}: {
entityId: string;
findingDetails: FindingProps;
}) => {
// const router = useRouter();
// const pathname = usePathname();
// const searchParams = useSearchParams();
// useEffect(() => {
// if (entityId) {
// const params = new URLSearchParams(searchParams.toString());
// params.set("id", entityId);
// router.push(`${pathname}?${params.toString()}`, { scroll: false });
// }
// return () => {
// if (entityId) {
// const cleanupParams = new URLSearchParams(searchParams.toString());
// cleanupParams.delete("id");
// router.push(`${pathname}?${cleanupParams.toString()}`, {
// scroll: false,
// });
// }
// };
// }, [entityId, pathname, router, searchParams]);
return <FindingDetail findingDetails={findingDetails} />;
};
+200 -108
View File
@@ -1,14 +1,11 @@
"use client";
import {
Table,
TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow,
} from "@nextui-org/react";
import { Snippet } from "@nextui-org/react";
import Link from "next/link";
import { SnippetId } from "@/components/ui/entities";
import { DateWithTime } from "@/components/ui/entities/date-with-time";
import { SeverityBadge } from "@/components/ui/table/severity-badge";
import { FindingProps } from "@/types";
export const FindingDetail = ({
@@ -17,108 +14,203 @@ export const FindingDetail = ({
findingDetails: FindingProps;
}) => {
const finding = findingDetails;
const attributes = finding.attributes;
const resource = finding.relationships.resource.attributes;
const remediation = attributes.check_metadata.remediation;
return (
<div className="space-y-4">
<div className="flex flex-col gap-6 rounded-lg">
{/* Header */}
<div className="flex items-center justify-between">
<Table aria-label="Example static collection table">
<TableHeader>
<TableColumn>Name </TableColumn>
<TableColumn>Value</TableColumn>
</TableHeader>
<TableBody>
<TableRow key="1">
<TableCell>Resource ID</TableCell>
<TableCell>{finding.relationships.resource.id}</TableCell>
</TableRow>
<TableRow key="2">
<TableCell>Resource ARN</TableCell>
<TableCell>
{finding.relationships.resource.attributes.uid}
</TableCell>
</TableRow>
<TableRow key="3">
<TableCell>Check ID</TableCell>
<TableCell>{finding.attributes.check_id}</TableCell>
</TableRow>
<TableRow key="4">
<TableCell>Types</TableCell>
<TableCell>
{finding.attributes.check_metadata.checktype}
</TableCell>
</TableRow>
<TableRow key="5">
<TableCell>Scan time</TableCell>
<TableCell>{finding.attributes.inserted_at}</TableCell>
</TableRow>
<TableRow key="6">
<TableCell>Prowler Finding ID</TableCell>
<TableCell>
{finding.relationships.resource.attributes.uid}
</TableCell>
</TableRow>
<TableRow key="7">
<TableCell>Severity</TableCell>
<TableCell>{finding.id}</TableCell>
</TableRow>
<TableRow key="8">
<TableCell>Status</TableCell>
<TableCell>{finding.attributes.status}</TableCell>
</TableRow>
<TableRow key="9">
<TableCell>Region</TableCell>
<TableCell>
{finding.relationships.resource.attributes.region}
</TableCell>
</TableRow>
<TableRow key="10">
<TableCell>Service</TableCell>
<TableCell>
{finding.relationships.resource.attributes.service}
</TableCell>
</TableRow>
<TableRow key="11">
<TableCell>Account</TableCell>
<TableCell>
{finding.relationships.provider.attributes.uid}
</TableCell>
</TableRow>
<TableRow key="12">
<TableCell>Details</TableCell>
<TableCell>{finding.attributes.status_extended}</TableCell>
</TableRow>
<TableRow key="13">
<TableCell>Risk</TableCell>
<TableCell>{finding.attributes.check_metadata.risk}</TableCell>
</TableRow>
<TableRow key="14">
<TableCell>Recommendation</TableCell>
<TableCell>
{
finding.attributes.check_metadata.remediation.recommendation
.text
}
</TableCell>
</TableRow>
<TableRow key="15">
<TableCell>CLI</TableCell>
<TableCell>
{finding.attributes.check_metadata.remediation.code.cli}
</TableCell>
</TableRow>
<TableRow key="16">
<TableCell>Other</TableCell>
<TableCell>
{finding.attributes.check_metadata.remediation.code.other}
</TableCell>
</TableRow>
<TableRow key="17">
<TableCell>Terraform</TableCell>
<TableCell>
{finding.attributes.check_metadata.remediation.code.terraform}
</TableCell>
</TableRow>
</TableBody>
</Table>
<div>
<h2 className="line-clamp-2 text-xl font-bold leading-tight text-gray-800 dark:text-prowler-theme-pale/90">
{attributes.check_metadata.checktitle}
</h2>
<p className="text-sm text-gray-500 dark:text-prowler-theme-pale/70">
{resource.service}
</p>
</div>
<div
className={`rounded-lg px-3 py-1 text-sm font-semibold ${
attributes.status === "PASS"
? "bg-green-100 text-green-600"
: attributes.status === "MANUAL"
? "bg-gray-100 text-gray-600"
: "bg-red-100 text-red-600"
}`}
>
{attributes.status}
</div>
</div>
{/* Check Metadata */}
<div className="flex flex-col gap-4 rounded-lg p-4 shadow dark:bg-prowler-blue-400">
<div className="flex items-center justify-between">
<h3 className="text-lg font-bold text-gray-800 dark:text-prowler-theme-pale/90">
Check Metadata
</h3>
<SeverityBadge severity={attributes.severity} />
</div>
{attributes.status === "FAIL" && (
<Snippet
className="max-w-full py-4"
color="danger"
hideCopyButton
hideSymbol
>
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Risk
</p>
<p className="whitespace-pre-line text-gray-800 dark:text-prowler-theme-pale/90">
{attributes.check_metadata.risk}
</p>
</Snippet>
)}
<div className="flex flex-col gap-2">
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Description
</p>
<p className="text-gray-800 dark:text-prowler-theme-pale/90">
{attributes.check_metadata.description}
</p>
</div>
<div className="flex flex-col gap-2">
<h3 className="text-sm font-semibold dark:text-prowler-theme-pale">
Remediation
</h3>
<div className="text-gray-800 dark:text-prowler-theme-pale/90">
{remediation.recommendation && (
<>
<p className="text-sm font-semibold">Recommendation:</p>
<p>{remediation.recommendation.text}</p>
<Link
target="_blank"
href={remediation.recommendation.url}
className="mt-2 inline-block text-sm text-blue-500 underline"
>
Learn more
</Link>
</>
)}
{remediation.code &&
Object.values(remediation.code).some(Boolean) && (
<>
<p className="mt-4 text-sm font-semibold">
Check these links:
</p>
<div className="flex flex-col gap-2">
{remediation.code.cli && (
<div>
<p className="text-sm font-semibold">CLI Command:</p>
<Snippet hideSymbol size="sm" className="max-w-full">
<p className="whitespace-pre-line">
{remediation.code.cli}
</p>
</Snippet>
</div>
)}
{Object.entries(remediation.code)
.filter(([key]) => key !== "cli")
.map(([key, value]) =>
value ? (
<Link
key={key}
href={value}
target="_blank"
className="text-sm font-medium text-blue-500"
>
{key === "other"
? "External doc"
: key.charAt(0).toUpperCase() +
key.slice(1).toLowerCase()}
</Link>
) : null,
)}
</div>
</>
)}
</div>
</div>
</div>
{/* Resources Section */}
<div className="flex flex-col gap-4 rounded-lg p-4 shadow dark:bg-prowler-blue-400">
<h3 className="text-lg font-bold text-gray-800 dark:text-prowler-theme-pale/90">
Resource Details
</h3>
<div className="grid grid-cols-2 gap-6">
<div className="col-span-2">
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Resource ID
</p>
<Snippet size="sm" hideSymbol className="max-w-full">
<p className="whitespace-pre-line">{resource.uid}</p>
</Snippet>
</div>
<div>
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Resource Name
</p>
<p className="text-gray-800 dark:text-prowler-theme-pale/90">
{resource.name}
</p>
</div>
<div>
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Region
</p>
<p className="text-gray-800 dark:text-prowler-theme-pale/90">
{resource.region}
</p>
</div>
<div>
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Resource Type
</p>
<p className="text-gray-800 dark:text-prowler-theme-pale/90">
{resource.type}
</p>
</div>
<div>
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Severity
</p>
<SeverityBadge severity={attributes.severity} />
</div>
{resource.tags &&
Object.entries(resource.tags).map(([key, value]) => (
<div key={key}>
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Tag: {key}
</p>
<SnippetId
entityId={value}
hideSymbol
size="sm"
className="max-w-full"
>
<p className="whitespace-pre-line">{value}</p>
</SnippetId>
</div>
))}
<div className="col-span-2 grid grid-cols-2 gap-6">
<div>
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Inserted At
</p>
<DateWithTime inline dateTime={resource.inserted_at} />
</div>
<div>
<p className="text-sm font-semibold dark:text-prowler-theme-pale">
Updated At
</p>
<DateWithTime inline dateTime={resource.updated_at} />
</div>
</div>
</div>
</div>
</div>
);
@@ -32,7 +32,7 @@ export const InvitationDetails = ({ attributes }: InvitationDetailsProps) => {
<div className="flex flex-col gap-x-4 gap-y-8">
<Card
isBlurred
className="border-none bg-background/60 dark:bg-default-100/50"
className="border-none bg-background/60 dark:bg-prowler-blue-800"
shadow="sm"
>
<CardBody>
@@ -55,7 +55,7 @@ export const WorkflowSendInvite = () => {
<VerticalSteps
hideProgressBars
currentStep={currentStep}
stepClassName="border border-default-200 dark:border-default-50 aria-[current]:bg-default-100 dark:aria-[current]:bg-default-50 cursor-default"
stepClassName="border border-default-200 dark:border-default-50 aria-[current]:bg-default-100 dark:aria-[current]:bg-prowler-blue-800 cursor-default"
steps={steps}
/>
<Spacer y={4} />
@@ -67,7 +67,7 @@ export const WorkflowAddProvider = () => {
<VerticalSteps
hideProgressBars
currentStep={currentStep}
stepClassName="border border-default-200 dark:border-default-50 aria-[current]:bg-default-100 dark:aria-[current]:bg-default-50 cursor-default"
stepClassName="border border-default-200 dark:border-default-50 aria-[current]:bg-default-100 dark:aria-[current]:bg-prowler-blue-800 cursor-default"
steps={steps}
/>
<Spacer y={4} />
+52 -37
View File
@@ -17,22 +17,25 @@ export const ScanDetail = ({ scanDetails }: ScanDetailsProps) => {
const taskDetails = scanDetails.taskDetails;
return (
<div className="space-y-4">
<div className="flex flex-col gap-6 rounded-lg">
{/* Header */}
<div className="flex items-center justify-between">
<div className="flex flex-col items-baseline md:flex-row md:gap-x-4">
<h2 className="text-2xl font-bold">Scan Details</h2>
</div>
<h2 className="text-2xl font-bold text-gray-800 dark:text-prowler-theme-pale/90">
Scan Details
</h2>
<StatusBadge
size="lg"
status={scanOnDemand.state}
loadingProgress={scanOnDemand.progress}
/>
</div>
<Divider />
<div className="relative z-0 flex w-full flex-col justify-between gap-4 overflow-auto rounded-large bg-content1 p-4 shadow-small">
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<div className="space-y-4">
<Divider className="border-gray-300 dark:border-gray-600" />
{/* Details Section */}
<div className="flex flex-col gap-4 rounded-lg p-4 shadow dark:bg-prowler-blue-400">
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
<div className="flex flex-col gap-4">
<DetailItem label="Scan Name" value={scanOnDemand.name} />
<DetailItem
label="ID"
@@ -49,7 +52,7 @@ export const ScanDetail = ({ scanDetails }: ScanDetailsProps) => {
value={`${scanOnDemand.duration} seconds`}
/>
</div>
<div className="space-y-4">
<div className="flex flex-col gap-4">
<DateItem
label="Started At"
value={
@@ -68,7 +71,7 @@ export const ScanDetail = ({ scanDetails }: ScanDetailsProps) => {
dateTime={scanOnDemand.completed_at.toString()}
/>
) : (
"Not Started"
"Not Completed"
)
}
/>
@@ -109,17 +112,21 @@ export const ScanDetail = ({ scanDetails }: ScanDetailsProps) => {
</div>
</div>
</div>
<Card className="relative w-full border-small border-default-100 p-3 shadow-lg">
<CardHeader className="py-2">
<h2 className="text-2xl font-bold">Scan arguments</h2>
{/* Scan Arguments Section */}
<Card className="rounded-lg p-4 shadow dark:bg-prowler-blue-400">
<CardHeader className="pb-4">
<h3 className="text-lg font-bold text-gray-800 dark:text-prowler-theme-pale/90">
Scan Arguments
</h3>
</CardHeader>
<Divider />
<CardBody className="p-4">
<Divider className="border-gray-300 dark:border-gray-600" />
<CardBody className="pt-4">
<div className="flex flex-col gap-2">
<span className="font-semibold text-default-500">Checks</span>
<span className="text-default-700">
<span className="text-sm font-semibold text-gray-600 dark:text-gray-300">
Checks
</span>
<span className="text-gray-800 dark:text-prowler-theme-pale/90">
{(scanOnDemand.scanner_args as any)?.checks_to_execute?.join(
", ",
) || "N/A"}
@@ -127,25 +134,28 @@ export const ScanDetail = ({ scanDetails }: ScanDetailsProps) => {
</div>
</CardBody>
</Card>
{/* Task Details Section */}
{taskDetails && (
<Card className="relative w-full border-small border-default-100 p-3 shadow-lg">
<CardHeader className="py-2">
<h2 className="text-2xl font-bold">State details</h2>
<Card className="rounded-lg p-4 shadow dark:bg-prowler-blue-400">
<CardHeader className="pb-4">
<h3 className="text-lg font-bold text-gray-800 dark:text-prowler-theme-pale/90">
State Details
</h3>
</CardHeader>
<Divider />
<CardBody className="p-4">
<div className="flex flex-col gap-2">
<Divider className="border-gray-300 dark:border-gray-600" />
<CardBody className="pt-4">
<div className="flex flex-col gap-4">
<DetailItem label="State" value={taskDetails.attributes.state} />
<DetailItem
label="Completed At"
value={taskDetails.attributes.completed_at}
value={taskDetails.attributes.completed_at || "N/A"}
/>
{taskDetails.attributes.result && (
<>
<DetailItem
label="Error Type"
value={taskDetails.attributes.result.exc_type}
value={taskDetails.attributes.result.exc_type || "N/A"}
/>
{taskDetails.attributes.result.exc_message && (
<DetailItem
@@ -157,12 +167,13 @@ export const ScanDetail = ({ scanDetails }: ScanDetailsProps) => {
)}
</>
)}
<DetailItem
label="Checks to Execute"
value={taskDetails.attributes.task_args.checks_to_execute?.join(
", ",
)}
value={
taskDetails.attributes.task_args.checks_to_execute?.join(
", ",
) || "N/A"
}
/>
</div>
</CardBody>
@@ -180,8 +191,10 @@ const DateItem = ({
value: React.ReactNode;
}) => (
<div className="flex items-center justify-between">
<span className="font-semibold text-default-500">{label}:</span>
<span className="text-default-700">{value}</span>
<p className="text-sm font-semibold text-gray-600 dark:text-gray-300">
{label}:
</p>
<p className="text-gray-800 dark:text-prowler-theme-pale/90">{value}</p>
</div>
);
@@ -193,7 +206,9 @@ const DetailItem = ({
value: React.ReactNode;
}) => (
<div className="flex items-center justify-between">
<span className="font-semibold text-default-500">{label}:</span>
<span className="text-default-700">{value}</span>
<p className="text-sm font-semibold text-gray-600 dark:text-gray-300">
{label}:
</p>
<p className="text-gray-800 dark:text-prowler-theme-pale/90">{value}</p>
</div>
);
+2 -1
View File
@@ -8,7 +8,8 @@ import { NextUIColors, NextUIVariants } from "@/types";
export const buttonClasses = {
base: "px-4 inline-flex items-center justify-center relative z-0 text-center whitespace-nowrap",
primary: "bg-default-100 hover:bg-default-200 text-default-800",
primary:
"bg-default-100 hover:bg-default-200 text-default-800 dark:bg-prowler-blue-800",
secondary: "bg-prowler-grey-light dark:bg-prowler-grey-medium text-white",
action: "bg-prowler-theme-green font-bold text-prowler-theme-midnight",
dashed:
+5 -1
View File
@@ -4,11 +4,13 @@ import React from "react";
interface DateWithTimeProps {
dateTime: string | null; // e.g., "2024-07-17T09:55:14.191475Z"
showTime?: boolean;
inline?: boolean;
}
export const DateWithTime: React.FC<DateWithTimeProps> = ({
dateTime,
showTime = true,
inline = false,
}) => {
if (!dateTime) return <span>--</span>;
const date = parseISO(dateTime);
@@ -17,7 +19,9 @@ export const DateWithTime: React.FC<DateWithTimeProps> = ({
return (
<div className="max-w-fit">
<div className="flex flex-col items-start">
<div
className={`flex ${inline ? "flex-row items-center gap-2" : "flex-col"}`}
>
<span className="text-md font-semibold">{formattedDate}</span>
{showTime && (
<span className="text-sm text-gray-500">{formattedTime}</span>
+2 -2
View File
@@ -31,7 +31,7 @@ const SheetOverlay = React.forwardRef<
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
const sheetVariants = cva(
"fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out dark:bg-neutral-950",
"fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out dark:bg-neutral-950 dark:border-prowler-blue-800",
{
variants: {
side: {
@@ -40,7 +40,7 @@ const sheetVariants = cva(
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
"inset-y-0 right-0 h-full w-3/4 border-t-1 border-b-1 border-l-2 data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
},
},
defaultVariants: {
+1 -1
View File
@@ -27,7 +27,7 @@ export function TriggerSheet({
<SheetTrigger className="flex items-center gap-2">
{triggerComponent}
</SheetTrigger>
<SheetContent className="my-4 max-h-[calc(100vh-2rem)] max-w-[95vw] overflow-y-auto rounded-l-xl pt-10 md:my-8 md:max-h-[calc(100vh-4rem)] md:max-w-[55vw]">
<SheetContent className="my-4 max-h-[calc(100vh-2rem)] max-w-[95vw] overflow-y-auto rounded-l-xl pt-10 dark:bg-prowler-theme-midnight md:my-8 md:max-h-[calc(100vh-4rem)] md:max-w-[55vw]">
<SheetHeader>
<SheetTitle className="sr-only">{title}</SheetTitle>
<SheetDescription className="sr-only">{description}</SheetDescription>
+1 -1
View File
@@ -280,7 +280,7 @@ const Sidebar = React.forwardRef<HTMLElement, SidebarProps>(
itemClasses={{
...itemClasses,
base: clsx(
"px-3 rounded-large data-[selected=true]:bg-default-100",
"px-3 rounded-large data-[selected=true]:bg-default-100 dark:data-[selected=true]:bg-prowler-blue-800",
itemClasses?.base,
),
title: clsx(
@@ -49,7 +49,7 @@ export function DataTablePagination({ metadata }: DataTablePaginationProps) {
<div className="flex items-center space-x-2">
<Link
aria-label="Go to first page"
className="page-link relative block rounded border-0 bg-transparent px-3 py-1.5 text-gray-800 outline-none transition-all duration-300 hover:bg-gray-200 hover:text-gray-800 focus:shadow-none"
className="page-link relative block rounded border-0 bg-transparent px-3 py-1.5 text-gray-800 outline-none transition-all duration-300 hover:bg-gray-200 hover:text-gray-800 focus:shadow-none dark:text-prowler-theme-green"
href={createPageUrl(1)}
aria-disabled="true"
>
@@ -57,7 +57,7 @@ export function DataTablePagination({ metadata }: DataTablePaginationProps) {
</Link>
<Link
aria-label="Go to previous page"
className="page-link relative block rounded border-0 bg-transparent px-3 py-1.5 text-gray-800 outline-none transition-all duration-300 hover:bg-gray-200 hover:text-gray-800 focus:shadow-none"
className="page-link relative block rounded border-0 bg-transparent px-3 py-1.5 text-gray-800 outline-none transition-all duration-300 hover:bg-gray-200 hover:text-gray-800 focus:shadow-none dark:text-prowler-theme-green"
href={createPageUrl(currentPage - 1)}
aria-disabled="true"
>
@@ -65,14 +65,14 @@ export function DataTablePagination({ metadata }: DataTablePaginationProps) {
</Link>
<Link
aria-label="Go to next page"
className="page-link relative block rounded border-0 bg-transparent px-3 py-1.5 text-gray-800 outline-none transition-all duration-300 hover:bg-gray-200 hover:text-gray-800 focus:shadow-none"
className="page-link relative block rounded border-0 bg-transparent px-3 py-1.5 text-gray-800 outline-none transition-all duration-300 hover:bg-gray-200 hover:text-gray-800 focus:shadow-none dark:text-prowler-theme-green"
href={createPageUrl(currentPage + 1)}
>
<ChevronRightIcon className="size-4" aria-hidden="true" />
</Link>
<Link
aria-label="Go to last page"
className="page-link relative block rounded border-0 bg-transparent px-3 py-1.5 text-gray-800 outline-none transition-all duration-300 hover:bg-gray-200 hover:text-gray-800 focus:shadow-none"
className="page-link relative block rounded border-0 bg-transparent px-3 py-1.5 text-gray-800 outline-none transition-all duration-300 hover:bg-gray-200 hover:text-gray-800 focus:shadow-none dark:text-prowler-theme-green"
href={createPageUrl(totalPages)}
>
<DoubleArrowRightIcon className="size-4" aria-hidden="true" />
+1 -1
View File
@@ -63,7 +63,7 @@ export function DataTable<TData, TValue>({
<DataTableFilterCustom filters={customFilters || []} />
</div>
)}
<div className="relative z-0 flex w-full flex-col justify-between gap-4 overflow-auto rounded-large bg-content1 p-4 shadow-small">
<div className="relative z-0 flex w-full flex-col justify-between gap-4 overflow-auto rounded-large bg-content1 p-4 shadow-small dark:bg-prowler-blue-400">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
+1 -1
View File
@@ -75,7 +75,7 @@ const TableHead = React.forwardRef<
<th
ref={ref}
className={cn(
"h-10 whitespace-nowrap bg-default-100 px-4 text-left align-middle text-tiny font-semibold text-foreground-500 outline-none first:rounded-l-lg last:rounded-r-lg data-[focus-visible=true]:z-10 data-[hover=true]:text-foreground-400 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-offset-2 data-[focus-visible=true]:outline-focus dark:text-slate-400 rtl:text-right rtl:first:rounded-l-[unset] rtl:first:rounded-r-lg rtl:last:rounded-l-lg rtl:last:rounded-r-[unset] [&:has([role=checkbox])]:pr-0",
"h-10 whitespace-nowrap bg-default-100 px-4 text-left align-middle text-tiny font-semibold text-foreground-500 outline-none first:rounded-l-lg last:rounded-r-lg data-[focus-visible=true]:z-10 data-[hover=true]:text-foreground-400 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-offset-2 data-[focus-visible=true]:outline-focus dark:bg-prowler-blue-800 dark:text-slate-400 rtl:text-right rtl:first:rounded-l-[unset] rtl:first:rounded-r-lg rtl:last:rounded-l-lg rtl:last:rounded-r-[unset] [&:has([role=checkbox])]:pr-0",
className,
)}
{...props}
+1
View File
@@ -31,6 +31,7 @@ module.exports = {
},
blue: {
800: "#1e293bff",
400: "#1A202C",
},
grey: {
medium: "#353a4d",