Skip to content
Snippets Groups Projects

Draft: Feature/project info publications modal + table

Closed Tadeusz Miesiąc requested to merge feature/project-info-publications-modal into development
25 files
+ 436
6
Compare changes
  • Side-by-side
  • Inline
Files
25
import { ONE, ZERO } from '@/constants/common';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import {
totalSizeSelector,
paginationSelector,
isLoadingSelector,
} from '@/redux/publications/publications.selectors';
import { getPublications } from '@/redux/publications/publications.thunks';
import { Button } from '@/shared/Button';
import { Publication } from '@/types/models';
import {
createColumnHelper,
flexRender,
getCoreRowModel,
useReactTable,
} from '@tanstack/react-table';
import { useEffect, useState } from 'react';
const columnHelper = createColumnHelper<Publication>();
const columns = [
columnHelper.accessor(row => row.publication.article.pubmedId, { header: 'Pubmed ID' }),
columnHelper.accessor(row => row.publication.article.title, { header: 'Title' }),
columnHelper.accessor(row => row.publication.article.authors, { header: 'Authors' }),
columnHelper.accessor(row => row.publication.article.journal, { header: 'Journal' }),
columnHelper.accessor(row => row.publication.article.year, { header: 'Year' }),
// eslint-disable-next-line @typescript-eslint/no-unused-vars
columnHelper.accessor(row => '{link to element on map}', { header: 'Elements on map' }),
// eslint-disable-next-line @typescript-eslint/no-unused-vars
columnHelper.accessor(row => '{link to submap}', { header: 'Submaps' }),
];
type PublicationsTableProps = {
data: Publication[];
};
export const PublicationsTable = ({ data }: PublicationsTableProps): JSX.Element => {
const dispatch = useAppDispatch();
const pagesCount = useAppSelector(totalSizeSelector);
const isPublicationsLoading = useAppSelector(isLoadingSelector);
const reduxPagination = useAppSelector(paginationSelector);
const [pagination, setPagination] = useState(reduxPagination);
useEffect(() => {
dispatch(getPublications({ page: pagination.pageIndex, length: pagination.pageSize }));
}, [pagination, dispatch]);
const table = useReactTable({
state: {
pagination,
},
columns,
data,
getCoreRowModel: getCoreRowModel(),
manualPagination: true,
pageCount: pagesCount,
onPaginationChange: setPagination,
});
return (
<div className="flex max-h-full w-full flex-col items-center justify-center bg-white p-6">
<div className="overflow-y-auto">
<table className="table-auto overflow-auto text-sm">
<thead className="sticky top-0 bg-white-pearl">
{table.getHeaderGroups().map(headerGroup => (
<tr key={headerGroup.id} className="border-y ">
{headerGroup.headers.map(header => (
<th key={header.id} className="whitespace-nowrap py-2.5">
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
</th>
))}
</tr>
))}
</thead>
<tbody>
{data &&
table.getRowModel().rows.map(row => (
<tr key={row.id} className="even:bg-lotion">
{row.getVisibleCells().map(cell => (
<td key={cell.id} className="p-3">
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
<div className="flex w-full flex-row justify-end border-t">
<div className="mt-6 flex flex-row items-center">
<Button
variantStyles="quiet"
className="text-primary-500"
onClick={() => table.setPageIndex(ZERO)}
disabled={isPublicationsLoading}
>
First page
</Button>
<Button
variantStyles="secondary"
onClick={() => table.previousPage()}
disabled={isPublicationsLoading}
>
Previous page
</Button>
<div className="mx-4 text-sm font-semibold">
Page {table.getState().pagination.pageIndex + ONE} out of {table.getPageCount()}
</div>
<Button
variantStyles="secondary"
onClick={() => table.nextPage()}
disabled={isPublicationsLoading}
>
Next page
</Button>
<Button
variantStyles="quiet"
className="text-primary-500"
onClick={() => table.setPageIndex(table.getPageCount() - ONE)}
disabled={isPublicationsLoading}
>
Last page
</Button>
</div>
</div>
</div>
);
};
Loading