1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-05 05:45:22 +02:00

refactor(activity-logs): migrate auth logs table to react [EE-4715] (#10890)

This commit is contained in:
Chaim Lev-Ari 2024-04-09 08:10:25 +03:00 committed by GitHub
parent bd271ec5a1
commit 7e53d01d0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 181 additions and 197 deletions

View file

@ -0,0 +1,57 @@
import { History } from 'lucide-react';
import { Datatable } from '@@/datatables';
import { AuthLog } from './types';
import { columns } from './columns';
export function AuthenticationLogsTable({
dataset,
currentPage,
keyword,
limit,
onChangeKeyword,
onChangeLimit,
onChangePage,
onChangeSort,
sort,
totalItems,
}: {
keyword: string;
onChangeKeyword(keyword: string): void;
sort: { key: string; desc: boolean };
onChangeSort(sort: { key: string; desc: boolean }): void;
limit: number;
onChangeLimit(limit: number): void;
currentPage: number;
onChangePage(page: number): void;
totalItems: number;
dataset?: Array<AuthLog>;
}) {
return (
<Datatable<AuthLog>
title="Authentication Events"
titleIcon={History}
columns={columns}
dataset={dataset || []}
isLoading={!dataset}
settingsManager={{
pageSize: limit,
search: keyword,
setPageSize: onChangeLimit,
setSearch: onChangeKeyword,
setSortBy: (key, desc) =>
onChangeSort({ key: key || 'timestamp', desc }),
sortBy: {
id: sort.key,
desc: sort.desc,
},
}}
page={currentPage}
onPageChange={onChangePage}
isServerSidePagination
totalCount={totalItems}
disableSelect
/>
);
}

View file

@ -0,0 +1,74 @@
import { createColumnHelper } from '@tanstack/react-table';
import { Check, X } from 'lucide-react';
import { isoDateFromTimestamp } from '@/portainer/filters/filters';
import { multiple } from '@@/datatables/filter-types';
import { filterHOC } from '@@/datatables/Filter';
import { Icon } from '@@/Icon';
import { ActivityType, AuthLog, AuthMethodType } from './types';
const activityTypesProps = {
[ActivityType.AuthSuccess]: {
label: 'Authentication success',
icon: Check,
mode: 'success',
},
[ActivityType.AuthFailure]: {
label: 'Authentication failure',
icon: X,
mode: 'danger',
},
[ActivityType.Logout]: { label: 'Logout', icon: undefined, mode: undefined },
} as const;
const columnHelper = createColumnHelper<AuthLog>();
export const columns = [
columnHelper.accessor('timestamp', {
header: 'Time',
cell: ({ getValue }) => {
const value = getValue();
return value ? isoDateFromTimestamp(value) : '';
},
}),
columnHelper.accessor('origin', {
header: 'Origin',
}),
columnHelper.accessor(({ context }) => AuthMethodType[context] || '', {
header: 'Context',
enableColumnFilter: true,
filterFn: multiple,
meta: {
filter: filterHOC('Filter'),
},
}),
columnHelper.accessor('username', {
header: 'User',
}),
columnHelper.accessor((item) => activityTypesProps[item.type].label, {
header: 'Result',
enableColumnFilter: true,
filterFn: multiple,
meta: {
filter: filterHOC('Filter'),
},
cell({ row: { original: item } }) {
const props = activityTypesProps[item.type];
if (!props) {
return null;
}
const { label, icon, mode } = props;
return (
<span className="flex gap-1 items-center">
{label}
{icon && mode && <Icon icon={icon} mode={mode} />}
</span>
);
},
}),
];

View file

@ -0,0 +1,20 @@
export enum AuthMethodType {
Internal = 1,
LDAP,
OAuth,
}
export enum ActivityType {
AuthSuccess = 1,
AuthFailure,
Logout,
}
export interface AuthLog {
timestamp: number;
context: AuthMethodType;
id: number;
username: string;
type: ActivityType;
origin: string;
}