.
This commit is contained in:
parent
fe816b73f8
commit
a673a3f3d3
@ -22,8 +22,7 @@ import { IListQuotes_Response_DTO, MoneyValue, UTCDateValue } from "@shared/cont
|
|||||||
import { ColumnDef, Row } from "@tanstack/react-table";
|
import { ColumnDef, Row } from "@tanstack/react-table";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import { FilePenLineIcon, MoreVerticalIcon } from "lucide-react";
|
import { FilePenLineIcon, MoreVerticalIcon } from "lucide-react";
|
||||||
import { useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { Trans } from "react-i18next";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useQuotes } from "../hooks";
|
import { useQuotes } from "../hooks";
|
||||||
import { QuotePDFPreview } from "./QuotePDFPreview";
|
import { QuotePDFPreview } from "./QuotePDFPreview";
|
||||||
@ -37,7 +36,13 @@ export const QuotesDataTable = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { pagination, globalFilter, isFiltered } = useDataTableContext();
|
const { pagination, globalFilter, isFiltered } = useDataTableContext();
|
||||||
const [focusedQuote, setFocusedQuote] = useState<IListQuotes_Response_DTO | undefined>(undefined);
|
|
||||||
|
const [activeRow, setActiveRow] = useState<Row<IListQuotes_Response_DTO> | undefined>(undefined);
|
||||||
|
|
||||||
|
const resetActiveRowIndex = (id?: number) => {
|
||||||
|
setActiveRowIndex(id ? id : 0);
|
||||||
|
};
|
||||||
|
|
||||||
const { useList } = useQuotes();
|
const { useList } = useQuotes();
|
||||||
|
|
||||||
const { data, isPending, isError, error } = useList({
|
const { data, isPending, isError, error } = useList({
|
||||||
@ -124,7 +129,7 @@ export const QuotesDataTable = ({
|
|||||||
cell: ({ row }: { row: Row<IListQuotes_Response_DTO> }) => (
|
cell: ({ row }: { row: Row<IListQuotes_Response_DTO> }) => (
|
||||||
<div className='flex items-center gap-1 ml-auto'>
|
<div className='flex items-center gap-1 ml-auto'>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
size='sm'
|
size='sm'
|
||||||
variant='outline'
|
variant='outline'
|
||||||
@ -136,14 +141,12 @@ export const QuotesDataTable = ({
|
|||||||
>
|
>
|
||||||
<FilePenLineIcon className='h-3.5 w-3.5' />
|
<FilePenLineIcon className='h-3.5 w-3.5' />
|
||||||
<span className='lg:sr-only xl:not-sr-only xl:whitespace-nowrap'>
|
<span className='lg:sr-only xl:not-sr-only xl:whitespace-nowrap'>
|
||||||
<Trans i18nKey={"quotes.list.columns.actions.edit"} />
|
{t("quotes.list.columns.actions.edit")}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<p>
|
<p>{t("quotes.list.columns.actions.edit")}</p>
|
||||||
<Trans i18nKey={"quotes.list.columns.actions.edit"} />
|
|
||||||
</p>
|
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
@ -170,16 +173,27 @@ export const QuotesDataTable = ({
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleOnPaginationChange = () => {
|
||||||
|
//setActiveRow(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
const { table } = useDataTable({
|
const { table } = useDataTable({
|
||||||
data: data?.items ?? [],
|
data: data?.items ?? [],
|
||||||
columns: columns,
|
columns: columns,
|
||||||
pageCount: data?.total_pages ?? -1,
|
pageCount: data?.total_pages ?? -1,
|
||||||
|
onPaginationChange: handleOnPaginationChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleOnRowClick = (row: Row<IListQuotes_Response_DTO>) => {
|
const handleOnRowClick = (row: Row<IListQuotes_Response_DTO>) => {
|
||||||
setFocusedQuote(row.original);
|
setActiveRow(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (table && data && data?.total_pages > 0) {
|
||||||
|
setActiveRow(table.getRowModel().rows[0]);
|
||||||
|
}
|
||||||
|
}, [data, table]);
|
||||||
|
|
||||||
if (isError) {
|
if (isError) {
|
||||||
return <ErrorOverlay subtitle={(error as Error).message} />;
|
return <ErrorOverlay subtitle={(error as Error).message} />;
|
||||||
}
|
}
|
||||||
@ -215,12 +229,13 @@ export const QuotesDataTable = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ResizablePanelGroup direction='horizontal' className='flex items-stretch flex-1 gap-4'>
|
<ResizablePanelGroup direction='horizontal' className='flex items-stretch flex-1 gap-4'>
|
||||||
<ResizablePanel defaultSize={75} className='flex items-stretch flex-1'>
|
<ResizablePanel defaultSize={preview ? 75 : 100} className='flex items-stretch flex-1'>
|
||||||
<DataTable
|
<DataTable
|
||||||
table={table}
|
table={table}
|
||||||
paginationOptions={{ visible: true }}
|
paginationOptions={{ visible: true }}
|
||||||
className='grid items-start flex-1 gap-4 auto-rows-max md:gap-8 lg:col-span-2'
|
className='grid items-start flex-1 gap-4 auto-rows-max md:gap-8 lg:col-span-2'
|
||||||
onRowClick={handleOnRowClick}
|
onRowClick={handleOnRowClick}
|
||||||
|
activeRowIndex={activeRow?.index}
|
||||||
>
|
>
|
||||||
<DataTableToolbar table={table} />
|
<DataTableToolbar table={table} />
|
||||||
</DataTable>
|
</DataTable>
|
||||||
@ -228,7 +243,7 @@ export const QuotesDataTable = ({
|
|||||||
{preview && <ResizableHandle withHandle />}
|
{preview && <ResizableHandle withHandle />}
|
||||||
{preview && (
|
{preview && (
|
||||||
<ResizablePanel defaultSize={25} className='flex items-stretch flex-1'>
|
<ResizablePanel defaultSize={25} className='flex items-stretch flex-1'>
|
||||||
<QuotePDFPreview quote={focusedQuote} className='flex-1' />
|
<QuotePDFPreview quote={activeRow?.original} className='flex-1' />
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
)}
|
)}
|
||||||
</ResizablePanelGroup>
|
</ResizablePanelGroup>
|
||||||
|
|||||||
@ -46,6 +46,7 @@ export type DataTableProps<TData> = PropsWithChildren<{
|
|||||||
rowClassName?: string;
|
rowClassName?: string;
|
||||||
cellClassName?: string;
|
cellClassName?: string;
|
||||||
onRowClick?: (row: Row<TData>) => void;
|
onRowClick?: (row: Row<TData>) => void;
|
||||||
|
activeRowIndex?: number;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export function DataTable<TData>({
|
export function DataTable<TData>({
|
||||||
@ -62,6 +63,7 @@ export function DataTable<TData>({
|
|||||||
rowClassName,
|
rowClassName,
|
||||||
cellClassName,
|
cellClassName,
|
||||||
onRowClick,
|
onRowClick,
|
||||||
|
activeRowIndex,
|
||||||
}: DataTableProps<TData>) {
|
}: DataTableProps<TData>) {
|
||||||
const headerVisible = headerOptions?.visible;
|
const headerVisible = headerOptions?.visible;
|
||||||
|
|
||||||
@ -106,11 +108,20 @@ export function DataTable<TData>({
|
|||||||
{table.getRowModel().rows?.length ? (
|
{table.getRowModel().rows?.length ? (
|
||||||
table.getRowModel().rows.map((row) => (
|
table.getRowModel().rows.map((row) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
onClick={() => (onRowClick ? onRowClick(row) : null)}
|
onClick={() => {
|
||||||
|
if (onRowClick) {
|
||||||
|
onRowClick(row);
|
||||||
|
}
|
||||||
|
}}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
key={row.id}
|
key={row.id}
|
||||||
data-state={row.getIsSelected() && "selected"}
|
data-state={row.getIsSelected() && "selected"}
|
||||||
className={cn(row.getIsSelected() ? "bg-accent" : "", rowClassName)}
|
className={cn(
|
||||||
|
row.getIsSelected() || activeRowIndex === row.index
|
||||||
|
? "bg-accent cursor-pointer"
|
||||||
|
: "cursor-pointer",
|
||||||
|
rowClassName
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => (
|
{row.getVisibleCells().map((cell) => (
|
||||||
<TableCell key={cell.id} className={cellClassName}>
|
<TableCell key={cell.id} className={cellClassName}>
|
||||||
|
|||||||
@ -115,6 +115,8 @@ interface UseDataTableProps<TData, TValue> {
|
|||||||
* @type boolean
|
* @type boolean
|
||||||
*/
|
*/
|
||||||
enableAdvancedFilter?: boolean;
|
enableAdvancedFilter?: boolean;
|
||||||
|
|
||||||
|
onPaginationChange?: OnChangeFn<PaginationState>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useDataTable<TData, TValue>({
|
export function useDataTable<TData, TValue>({
|
||||||
@ -124,6 +126,7 @@ export function useDataTable<TData, TValue>({
|
|||||||
enableSorting = false,
|
enableSorting = false,
|
||||||
enableHiding = false,
|
enableHiding = false,
|
||||||
enableRowSelection = false,
|
enableRowSelection = false,
|
||||||
|
onPaginationChange,
|
||||||
}: UseDataTableProps<TData, TValue>) {
|
}: UseDataTableProps<TData, TValue>) {
|
||||||
const { pagination, setPagination, sorting } = useDataTableContext();
|
const { pagination, setPagination, sorting } = useDataTableContext();
|
||||||
|
|
||||||
@ -136,6 +139,9 @@ export function useDataTable<TData, TValue>({
|
|||||||
const newPagination = updater(pagination);
|
const newPagination = updater(pagination);
|
||||||
setPagination(newPagination);
|
setPagination(newPagination);
|
||||||
}
|
}
|
||||||
|
if (onPaginationChange) {
|
||||||
|
onPaginationChange(updater);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortingUpdater: OnChangeFn<SortingState> = (updater) => {
|
const sortingUpdater: OnChangeFn<SortingState> = (updater) => {
|
||||||
@ -157,6 +163,7 @@ export function useDataTable<TData, TValue>({
|
|||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data,
|
||||||
columns: getTableColumns(),
|
columns: getTableColumns(),
|
||||||
|
//autoResetPageIndex: true,
|
||||||
pageCount: pageCount ?? -1,
|
pageCount: pageCount ?? -1,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user