mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com>
165 lines
5.1 KiB
TypeScript
165 lines
5.1 KiB
TypeScript
"use client";
|
|
|
|
import { ColumnDef, RowSelectionState } from "@tanstack/react-table";
|
|
|
|
import {
|
|
DataTableRowActions,
|
|
FindingTriageStatusCell,
|
|
} from "@/components/findings/table";
|
|
import { NotificationIndicator } from "@/components/findings/table/notification-indicator";
|
|
import { Checkbox } from "@/components/shadcn";
|
|
import { DateWithTime } from "@/components/shadcn/entities";
|
|
import {
|
|
DataTableColumnHeader,
|
|
SeverityBadge,
|
|
StatusFindingBadge,
|
|
} from "@/components/shadcn/table";
|
|
import type {
|
|
FindingTriageDetailLoadHandler,
|
|
FindingTriageNoteLoadHandler,
|
|
FindingTriageUpdateHandler,
|
|
} from "@/types/findings-triage";
|
|
import type { ResourceFinding } from "@/types/resources";
|
|
|
|
export const getResourceFindingsColumns = (
|
|
rowSelection: RowSelectionState,
|
|
selectableRowCount: number,
|
|
onNavigate: (id: string) => void,
|
|
onMuteComplete?: (findingIds: string[]) => void,
|
|
onTriageUpdateAction?: FindingTriageUpdateHandler,
|
|
onTriageNoteLoadAction?: FindingTriageNoteLoadHandler,
|
|
onTriageDetailLoadAction?: FindingTriageDetailLoadHandler,
|
|
): ColumnDef<ResourceFinding>[] => {
|
|
const selectedCount = Object.values(rowSelection).filter(Boolean).length;
|
|
const isAllSelected =
|
|
selectedCount > 0 && selectedCount === selectableRowCount;
|
|
const isSomeSelected =
|
|
selectedCount > 0 && selectedCount < selectableRowCount;
|
|
|
|
return [
|
|
{
|
|
id: "notification",
|
|
header: () => null,
|
|
cell: ({ row }) => (
|
|
<div className="flex items-center justify-center pr-4">
|
|
<NotificationIndicator
|
|
delta={row.original.attributes.delta}
|
|
isMuted={row.original.attributes.muted}
|
|
mutedReason={row.original.attributes.muted_reason}
|
|
showDeltaWhenMuted
|
|
reserveMutedSlot
|
|
/>
|
|
</div>
|
|
),
|
|
enableSorting: false,
|
|
enableHiding: false,
|
|
},
|
|
{
|
|
id: "select",
|
|
header: ({ table }) => (
|
|
<div className="ml-1 flex w-6 items-center justify-center pr-4">
|
|
<Checkbox
|
|
checked={
|
|
isAllSelected ? true : isSomeSelected ? "indeterminate" : false
|
|
}
|
|
onCheckedChange={(checked) =>
|
|
table.toggleAllPageRowsSelected(checked === true)
|
|
}
|
|
aria-label="Select all"
|
|
disabled={selectableRowCount === 0}
|
|
/>
|
|
</div>
|
|
),
|
|
cell: ({ row }) => (
|
|
<div className="ml-1 flex w-6 items-center justify-center pr-4">
|
|
<Checkbox
|
|
checked={!!rowSelection[row.id]}
|
|
disabled={row.original.attributes.muted}
|
|
onCheckedChange={(checked) => row.toggleSelected(checked === true)}
|
|
aria-label="Select row"
|
|
/>
|
|
</div>
|
|
),
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: "status",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Status" />
|
|
),
|
|
cell: ({ row }) => (
|
|
<StatusFindingBadge status={row.original.attributes.status || "-"} />
|
|
),
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: "finding",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Finding" />
|
|
),
|
|
cell: ({ row }) => (
|
|
<button
|
|
onClick={() => onNavigate(row.original.id)}
|
|
className="text-text-neutral-primary hover:text-button-tertiary max-w-[300px] cursor-pointer truncate text-left text-sm hover:underline"
|
|
>
|
|
{row.original.attributes.check_metadata?.checktitle ||
|
|
"Unknown check"}
|
|
</button>
|
|
),
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: "severity",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Severity" />
|
|
),
|
|
cell: ({ row }) => (
|
|
<SeverityBadge severity={row.original.attributes.severity || "-"} />
|
|
),
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: "updated_at",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Time" />
|
|
),
|
|
cell: ({ row }) => (
|
|
<DateWithTime dateTime={row.original.attributes.updated_at || "-"} />
|
|
),
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
id: "triage",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Triage" />
|
|
),
|
|
cell: ({ row }) => (
|
|
<FindingTriageStatusCell
|
|
triage={row.original.triage}
|
|
findingContext={{
|
|
title:
|
|
row.original.attributes.check_metadata?.checktitle || "Finding",
|
|
}}
|
|
onTriageUpdateAction={onTriageUpdateAction}
|
|
onTriageDetailLoadAction={onTriageDetailLoadAction}
|
|
/>
|
|
),
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
id: "actions",
|
|
header: () => <div className="w-10" />,
|
|
cell: ({ row }) => (
|
|
<DataTableRowActions
|
|
row={row}
|
|
onMuteComplete={onMuteComplete}
|
|
onTriageUpdateAction={onTriageUpdateAction}
|
|
onTriageNoteLoadAction={onTriageNoteLoadAction}
|
|
onTriageDetailLoadAction={onTriageDetailLoadAction}
|
|
/>
|
|
),
|
|
enableSorting: false,
|
|
},
|
|
];
|
|
};
|