mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 17:27:40 +00:00
119 lines
3.1 KiB
TypeScript
119 lines
3.1 KiB
TypeScript
import { Fragment } from "react";
|
|
import { faFile } from "@fortawesome/free-solid-svg-icons";
|
|
|
|
import {
|
|
Button,
|
|
EmptyState,
|
|
Table,
|
|
TableContainer,
|
|
TableSkeleton,
|
|
TBody,
|
|
Td,
|
|
Th,
|
|
THead,
|
|
Tr
|
|
} from "@app/components/v2";
|
|
import { useGetAuditLogs } from "@app/hooks/api";
|
|
import { TGetAuditLogsFilter } from "@app/hooks/api/auditLogs/types";
|
|
|
|
import { LogsTableRow } from "./LogsTableRow";
|
|
|
|
type Props = {
|
|
isOrgAuditLogs?: boolean;
|
|
showActorColumn: boolean;
|
|
filter?: TGetAuditLogsFilter;
|
|
remappedHeaders?: Partial<Record<TAuditLogTableHeader, string>>;
|
|
refetchInterval?: number;
|
|
};
|
|
|
|
const AUDIT_LOG_LIMIT = 15;
|
|
|
|
const TABLE_HEADERS = ["Timestamp (MM/DD/YYYY)", "Event", "Project", "Actor", "Source", "Metadata"] as const;
|
|
export type TAuditLogTableHeader = (typeof TABLE_HEADERS)[number];
|
|
|
|
export const LogsTable = ({
|
|
showActorColumn,
|
|
isOrgAuditLogs,
|
|
filter,
|
|
remappedHeaders,
|
|
refetchInterval
|
|
}: Props) => {
|
|
// Determine the project ID for filtering
|
|
const filterProjectId =
|
|
// Use the projectId from the filter if it exists
|
|
filter?.projectId || null;
|
|
|
|
const { data, isPending, isFetchingNextPage, hasNextPage, fetchNextPage } = useGetAuditLogs(
|
|
{
|
|
...filter,
|
|
limit: AUDIT_LOG_LIMIT
|
|
},
|
|
filterProjectId,
|
|
{
|
|
refetchInterval
|
|
}
|
|
);
|
|
|
|
const isEmpty = !isPending && !data?.pages?.[0].length;
|
|
|
|
return (
|
|
<div>
|
|
<TableContainer>
|
|
<Table>
|
|
<THead>
|
|
<Tr>
|
|
{TABLE_HEADERS.map((header, idx) => {
|
|
if (
|
|
(header === "Project" && !isOrgAuditLogs) ||
|
|
(header === "Actor" && !showActorColumn)
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Th key={`table-header-${idx + 1}`}>{remappedHeaders?.[header] || header}</Th>
|
|
);
|
|
})}
|
|
</Tr>
|
|
</THead>
|
|
<TBody>
|
|
{!isPending &&
|
|
data?.pages?.map((group, i) => (
|
|
<Fragment key={`audit-log-fragment-${i + 1}`}>
|
|
{group.map((auditLog) => (
|
|
<LogsTableRow
|
|
showActorColumn={showActorColumn}
|
|
isOrgAuditLogs={isOrgAuditLogs}
|
|
auditLog={auditLog}
|
|
key={`audit-log-${auditLog.id}`}
|
|
/>
|
|
))}
|
|
</Fragment>
|
|
))}
|
|
{isPending && <TableSkeleton innerKey="logs-table" columns={5} key="logs" />}
|
|
{isEmpty && (
|
|
<Tr>
|
|
<Td colSpan={5}>
|
|
<EmptyState title="No audit logs on file" icon={faFile} />
|
|
</Td>
|
|
</Tr>
|
|
)}
|
|
</TBody>
|
|
</Table>
|
|
</TableContainer>
|
|
{!isEmpty && (
|
|
<Button
|
|
className="mb-20 mt-4 px-4 py-3 text-sm"
|
|
isFullWidth
|
|
variant="star"
|
|
isLoading={isFetchingNextPage}
|
|
isDisabled={isFetchingNextPage || !hasNextPage}
|
|
onClick={() => fetchNextPage()}
|
|
>
|
|
{hasNextPage ? "Load More" : "End of logs"}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|