.
This commit is contained in:
parent
910d84aa76
commit
ffd35bee3b
@ -29,27 +29,19 @@ export const CatalogDataTable = () => {
|
||||
{
|
||||
id: "id" as const,
|
||||
accessorKey: "id",
|
||||
enableResizing: false,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "article_id" as const,
|
||||
accessorKey: "id_article",
|
||||
enableResizing: false,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "catalog_name" as const,
|
||||
accessorKey: "catalog_name",
|
||||
enableResizing: false,
|
||||
size: 10,
|
||||
},
|
||||
{
|
||||
id: "description" as const,
|
||||
accessorKey: "description",
|
||||
header: () => <>{t("catalog.list.columns.description")}</>,
|
||||
enableResizing: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
id: "points" as const,
|
||||
@ -58,8 +50,6 @@ export const CatalogDataTable = () => {
|
||||
cell: ({ renderValue }: { renderValue: () => any }) => (
|
||||
<div className='text-right'>{renderValue()}</div>
|
||||
),
|
||||
enableResizing: false,
|
||||
size: 20,
|
||||
},
|
||||
{
|
||||
id: "retail_price" as const,
|
||||
@ -69,8 +59,6 @@ export const CatalogDataTable = () => {
|
||||
const price = MoneyValue.create(row.original.retail_price).object;
|
||||
return <div className='text-right'>{price.toFormat()}</div>;
|
||||
},
|
||||
enableResizing: false,
|
||||
size: 20,
|
||||
},
|
||||
],
|
||||
[]
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Button, ButtonProps } from "@/ui";
|
||||
import { t } from "i18next";
|
||||
import { PackagePlusIcon } from "lucide-react";
|
||||
@ -13,16 +12,8 @@ export const AppendCatalogArticleRowButton = ({
|
||||
className,
|
||||
...props
|
||||
}: AppendCatalogArticleRowButtonProps): JSX.Element => (
|
||||
<Button
|
||||
type='button'
|
||||
variant='outline'
|
||||
size='icon'
|
||||
className={cn(
|
||||
"w-full gap-1 border-dashed text-muted-foreground border-muted-foreground/50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<Button type='button' variant='outline' {...props}>
|
||||
{" "}
|
||||
<PackagePlusIcon className={label ? "w-4 h-4 mr-2" : "w-4 h-4"} />
|
||||
{label && <>{label}</>}
|
||||
</Button>
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Button, ButtonProps } from "@/ui";
|
||||
import { t } from "i18next";
|
||||
import { PlusCircleIcon } from "lucide-react";
|
||||
@ -13,16 +12,7 @@ export const AppendEmptyRowButton = ({
|
||||
className,
|
||||
...props
|
||||
}: AppendEmptyRowButtonProps): JSX.Element => (
|
||||
<Button
|
||||
type='button'
|
||||
variant='outline'
|
||||
size='icon'
|
||||
className={cn(
|
||||
"w-full gap-1 border-dashed text-muted-foreground border-muted-foreground/50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<Button type='button' variant='outline' {...props}>
|
||||
<PlusCircleIcon className={label ? "w-4 h-4 mr-2" : "w-4 h-4"} />
|
||||
{label && <>{label}</>}
|
||||
</Button>
|
||||
|
||||
@ -4,10 +4,11 @@ import { useCatalogList } from "@/app/catalog/hooks";
|
||||
import { DataTable } from "@/components";
|
||||
import { DataTableToolbar } from "@/components/DataTable/DataTableToolbar";
|
||||
import { useDataTable, useDataTableContext } from "@/lib/hooks";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Button } from "@/ui";
|
||||
import { IListArticles_Response_DTO, MoneyValue } from "@shared/contexts";
|
||||
import { ColumnDef, Row } from "@tanstack/react-table";
|
||||
import { t } from "i18next";
|
||||
import { PackagePlusIcon } from "lucide-react";
|
||||
import { useMemo } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
@ -28,58 +29,45 @@ export const CatalogPickerDataTable = ({ onSelect }: { onSelect: (data: unknown)
|
||||
{
|
||||
id: "description" as const,
|
||||
accessorKey: "description",
|
||||
enableResizing: false,
|
||||
header: () => null,
|
||||
cell: ({
|
||||
row,
|
||||
renderValue,
|
||||
}: {
|
||||
row: Row<IListArticles_Response_DTO>;
|
||||
renderValue: () => any;
|
||||
}) => {
|
||||
header: () => <>{t("catalog.list.columns.description")}</>,
|
||||
},
|
||||
{
|
||||
id: "points" as const,
|
||||
accessorKey: "points",
|
||||
header: () => <div className='text-right'>{t("catalog.list.columns.points")}</div>,
|
||||
cell: ({ renderValue }: { renderValue: () => any }) => (
|
||||
<div className='text-right'>{renderValue()}</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "retail_price" as const,
|
||||
accessorKey: "retail_price",
|
||||
header: () => <div className='text-right'>{t("catalog.list.columns.retail_price")}</div>,
|
||||
cell: ({ row }: { row: Row<IListArticles_Response_DTO> }) => {
|
||||
const price = MoneyValue.create(row.original.retail_price).object;
|
||||
const points = row.original.points;
|
||||
return (
|
||||
<button
|
||||
key={row.id}
|
||||
className={cn(
|
||||
"rounded-lg border p-3 w-full transition delay-150 duration-200 active:scale-95 hover:bg-primary ",
|
||||
""
|
||||
)}
|
||||
onClick={
|
||||
(event) => {
|
||||
event.preventDefault();
|
||||
onSelect && onSelect(row.original);
|
||||
}
|
||||
/*setMail({
|
||||
...mail,
|
||||
selected: item.id,
|
||||
})*/
|
||||
}
|
||||
>
|
||||
<div className='flex flex-row justify-between w-full space-x-6'>
|
||||
<div className='w-3/4 text-left grow line-clamp-2 text-muted-foreground hover:text-foreground'>
|
||||
{renderValue()}
|
||||
</div>
|
||||
<div className='w-1/4 text-right'>
|
||||
<dl className='flex flex-row justify-end space-x-1'>
|
||||
<dt className='text-xs font-medium text-accent-foreground/75'>
|
||||
{t("catalog.list.columns.points")}:
|
||||
</dt>
|
||||
<dd className='text-xs font-semibold'>{points}</dd>
|
||||
</dl>
|
||||
<dl className='flex flex-row justify-end space-x-1'>
|
||||
<dt className='text-xs font-medium text-accent-foreground/75'>
|
||||
{t("catalog.list.columns.retail_price")}:
|
||||
</dt>
|
||||
<dt className='text-xs font-semibold'>{price.toFormat()}</dt>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
return <div className='text-right'>{price.toFormat()}</div>;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "row-actions",
|
||||
header: () => null,
|
||||
cell: ({ row }: { row: Row<IListArticles_Response_DTO> }) => (
|
||||
<Button
|
||||
size='sm'
|
||||
variant='outline'
|
||||
className='h-8 gap-1'
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
onSelect && onSelect(row.original);
|
||||
}}
|
||||
>
|
||||
<PackagePlusIcon className='h-3.5 w-3.5' />
|
||||
<span className='lg:sr-only xl:not-sr-only xl:whitespace-nowrap'>
|
||||
{t("common.add")}
|
||||
</span>
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
}, []);
|
||||
|
||||
@ -119,12 +107,8 @@ export const CatalogPickerDataTable = ({ onSelect }: { onSelect: (data: unknown)
|
||||
<DataTable
|
||||
className='bg-transparent border-0 shadow-none'
|
||||
table={table}
|
||||
headerOptions={{ visible: false }}
|
||||
paginationOptions={{ visible: true, enablePageSizeSelector: false }}
|
||||
contentClassName='p-0'
|
||||
footerClassName='p-0'
|
||||
rowClassName='border-b-0'
|
||||
cellClassName='px-0'
|
||||
footerClassName='px-10 pt-2 border-t'
|
||||
>
|
||||
<DataTableToolbar fullWidthFilter={true} table={table} />
|
||||
</DataTable>
|
||||
|
||||
@ -1,14 +1,6 @@
|
||||
import { DataTableColumnHeader } from "@/components";
|
||||
import { Badge } from "@/ui";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/ui/table";
|
||||
import { ButtonGroup, DataTableColumnHeader } from "@/components";
|
||||
import { Badge, Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/ui";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/ui/table";
|
||||
import {
|
||||
DndContext,
|
||||
DragEndEvent,
|
||||
@ -30,6 +22,7 @@ import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable"
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import {
|
||||
ColumnDef,
|
||||
InitialTableState,
|
||||
Row,
|
||||
RowData,
|
||||
RowSelectionState,
|
||||
@ -65,6 +58,7 @@ export type QuoteItemsSortableDataTableProps = {
|
||||
columns: ColumnDef<unknown, unknown>[];
|
||||
data: Record<"id", string>[];
|
||||
defaultValues: Readonly<{ [x: string]: any }> | undefined;
|
||||
initialState?: InitialTableState;
|
||||
actions: Omit<UseFieldArrayReturn<FieldValues, "items">, "fields"> & Record<string, unknown>;
|
||||
};
|
||||
|
||||
@ -101,13 +95,17 @@ export function QuoteItemsSortableDataTable({
|
||||
columns,
|
||||
data,
|
||||
defaultValues,
|
||||
initialState,
|
||||
actions,
|
||||
}: QuoteItemsSortableDataTableProps) {
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
||||
const [activeId, setActiveId] = useState<UniqueIdentifier | null>();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
|
||||
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>(
|
||||
initialState?.columnVisibility || {}
|
||||
);
|
||||
|
||||
const sorteableRowIds = useMemo(() => data.map((item) => item.id), [data]);
|
||||
|
||||
const table = useReactTable({
|
||||
@ -116,6 +114,8 @@ export function QuoteItemsSortableDataTable({
|
||||
enableColumnResizing: false,
|
||||
columnResizeMode: "onChange",
|
||||
//defaultColumn,
|
||||
|
||||
initialState,
|
||||
state: {
|
||||
rowSelection,
|
||||
columnVisibility,
|
||||
@ -124,16 +124,21 @@ export function QuoteItemsSortableDataTable({
|
||||
enableMultiRowSelection: true,
|
||||
enableSorting: false,
|
||||
enableHiding: true,
|
||||
|
||||
onRowSelectionChange: setRowSelection,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getRowId: (originalRow: unknown) => originalRow?.id,
|
||||
|
||||
debugTable: false,
|
||||
debugHeaders: false,
|
||||
debugColumns: false,
|
||||
|
||||
defaultColumn: {
|
||||
size: 8, //starting column size
|
||||
minSize: 1, //enforced during column resizing
|
||||
maxSize: 96, //enforced during column resizing
|
||||
minSize: 0, //starting column size
|
||||
size: Number.MAX_SAFE_INTEGER, //enforced during column resizing
|
||||
maxSize: Number.MAX_SAFE_INTEGER, //enforced during column resizing
|
||||
},
|
||||
|
||||
meta: {
|
||||
insertItem: (rowIndex: number, data?: unknown) => {
|
||||
actions.insert(rowIndex, data || defaultValues?.items[0], { shouldFocus: true });
|
||||
@ -154,7 +159,7 @@ export function QuoteItemsSortableDataTable({
|
||||
|
||||
const data = table
|
||||
.getSelectedRowModel()
|
||||
.rows.map((row) => ({ ...row.original, id: undefined }));
|
||||
.rows.map((row: Row<any>) => ({ ...row.original, id: undefined }));
|
||||
|
||||
if (table.getRowModel().rows.length < lastIndex + 1) {
|
||||
actions.append(data);
|
||||
@ -184,7 +189,7 @@ export function QuoteItemsSortableDataTable({
|
||||
actions.remove();
|
||||
}
|
||||
},
|
||||
updateItem: (rowIndex: number, rowData: unknown, fieldName: string, value: unknown) => {
|
||||
updateItem: (rowIndex: number, rowData: any, fieldName: string, value: unknown) => {
|
||||
// Skip page index reset until after next rerender
|
||||
// skipAutoResetPageIndex();
|
||||
actions.update(rowIndex, { ...rowData, [`${fieldName}`]: value });
|
||||
@ -264,169 +269,189 @@ export function QuoteItemsSortableDataTable({
|
||||
onDragCancel={handleDragCancel}
|
||||
collisionDetection={closestCenter}
|
||||
>
|
||||
<QuoteItemsSortableDataTableToolbar table={table} />
|
||||
<Table className='table-fixed'>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id} className='hover:bg-transparent'>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id} className={`px-2 py-1 w-${header.getSize()}`}>
|
||||
{header.isPlaceholder ? null : (
|
||||
<DataTableColumnHeader table={table} header={header} />
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<SortableContext
|
||||
items={filterItems(sorteableRowIds)}
|
||||
strategy={verticalListSortingStrategy}
|
||||
>
|
||||
{filterItems(table.getRowModel().rows).map((row) => (
|
||||
<QuoteItemsSortableTableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id} className='px-2 py-1 align-top'>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
<Card>
|
||||
<CardHeader className='sticky z-10 border-b top-16 bg-card'>
|
||||
<CardTitle>
|
||||
<QuoteItemsSortableDataTableToolbar table={table} />
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Table className='table-fixed'>
|
||||
<TableHeader className='sticky top-0 z-10 bg-background'>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id} className='hover:bg-transparent'>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead
|
||||
key={header.id}
|
||||
className='px-2 py-1'
|
||||
style={{
|
||||
width:
|
||||
header.getSize() === Number.MAX_SAFE_INTEGER
|
||||
? "auto"
|
||||
: header.getSize(),
|
||||
}}
|
||||
>
|
||||
{header.isPlaceholder ? null : (
|
||||
<DataTableColumnHeader table={table} header={header} />
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<SortableContext
|
||||
items={filterItems(sorteableRowIds)}
|
||||
strategy={verticalListSortingStrategy}
|
||||
>
|
||||
{filterItems(table.getRowModel().rows).map((row) => (
|
||||
<QuoteItemsSortableTableRow key={(row as Row<any>).id} id={(row as Row<any>).id}>
|
||||
{(row as Row<any>).getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
key={cell.id}
|
||||
className='px-2 py-2 align-top'
|
||||
style={{
|
||||
width:
|
||||
cell.column.getSize() === Number.MAX_SAFE_INTEGER
|
||||
? "auto"
|
||||
: cell.column.getSize(),
|
||||
}}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</QuoteItemsSortableTableRow>
|
||||
))}
|
||||
</QuoteItemsSortableTableRow>
|
||||
))}
|
||||
</SortableContext>
|
||||
</TableBody>
|
||||
<TableFooter className='bg-default'>
|
||||
<TableRow className='hover:bg-default'>
|
||||
<TableCell colSpan={3} className='py-6'></TableCell>
|
||||
<TableCell colSpan={5} className='py-6'>
|
||||
<div className='grid grid-cols-2 gap-6'>
|
||||
<AppendEmptyRowButton onClick={() => table.options.meta?.appendItem()} />
|
||||
<AppendCatalogArticleRowButton
|
||||
onClick={() => table.options.meta?.pickCatalogArticle()}
|
||||
/>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell className='py-6'></TableCell>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
</Table>
|
||||
</SortableContext>
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
{createPortal(
|
||||
<DragOverlay dropAnimation={dropAnimationConfig} className={"z-40 opacity-100"}>
|
||||
{activeId && (
|
||||
<div className='relative flex flex-wrap'>
|
||||
{table.getSelectedRowModel().rows.length ? (
|
||||
<Badge
|
||||
variant='destructive'
|
||||
className='absolute z-50 flex items-center justify-center w-2 h-2 p-3 rounded-full top left -left-2 -top-2'
|
||||
>
|
||||
{table.getSelectedRowModel().rows.length}
|
||||
</Badge>
|
||||
) : null}
|
||||
<div className='absolute z-40 bg-white border rounded shadow opacity-100 top left hover:bg-white border-muted-foreground/50'>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.map(
|
||||
(row) =>
|
||||
row.id === activeId && (
|
||||
<TableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
className='p-1 align-top'
|
||||
key={cell.id}
|
||||
style={{ width: cell.column.getSize() }}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
{createPortal(
|
||||
<DragOverlay dropAnimation={dropAnimationConfig} className={"z-40 opacity-100"}>
|
||||
{activeId && (
|
||||
<div className='relative flex flex-wrap'>
|
||||
{table.getSelectedRowModel().rows.length ? (
|
||||
<Badge
|
||||
variant='destructive'
|
||||
className='absolute z-50 flex items-center justify-center w-2 h-2 p-3 rounded-full top left -left-2 -top-2'
|
||||
>
|
||||
{table.getSelectedRowModel().rows.length}
|
||||
</Badge>
|
||||
) : null}
|
||||
<div className='absolute z-40 bg-white border rounded shadow opacity-100 top left hover:bg-white border-muted-foreground/50'>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.map(
|
||||
(row) =>
|
||||
row.id === activeId && (
|
||||
<TableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
className='p-1 align-top'
|
||||
key={cell.id}
|
||||
style={{ width: cell.column.getSize() }}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
{table.getSelectedRowModel().rows.length > 1 && (
|
||||
<div className='absolute z-30 transform -translate-x-1 translate-y-1 bg-white border rounded shadow opacity-100 hover:bg-white border-muted-foreground/50 top left rotate-1'>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.map(
|
||||
(row) =>
|
||||
row.id === activeId && (
|
||||
<TableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
className='p-1 align-top'
|
||||
key={cell.id}
|
||||
style={{ width: cell.column.getSize() }}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{table.getSelectedRowModel().rows.length > 1 && (
|
||||
<div className='absolute z-30 transform -translate-x-1 translate-y-1 bg-white border rounded shadow opacity-100 hover:bg-white border-muted-foreground/50 top left rotate-1'>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.map(
|
||||
(row) =>
|
||||
row.id === activeId && (
|
||||
<TableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
className='p-1 align-top'
|
||||
key={cell.id}
|
||||
style={{ width: cell.column.getSize() }}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{table.getSelectedRowModel().rows.length > 2 && (
|
||||
<div className='absolute z-20 transform translate-x-1 -translate-y-1 bg-white border rounded shadow opacity-100 hover:bg-white border-muted-foreground/50 top left -rotate-1'>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.map(
|
||||
(row) =>
|
||||
row.id === activeId && (
|
||||
<TableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
className='p-1 align-top'
|
||||
key={cell.id}
|
||||
style={{ width: cell.column.getSize() }}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{table.getSelectedRowModel().rows.length > 3 && (
|
||||
<div className='absolute z-10 transform translate-x-2 -translate-y-2 bg-white border rounded shadow opacity-100 hover:bg-white border-muted-foreground/50 top left rotate-2'>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.map(
|
||||
(row) =>
|
||||
row.id === activeId && (
|
||||
<TableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
className='p-1 align-top'
|
||||
key={cell.id}
|
||||
style={{ width: cell.column.getSize() }}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{table.getSelectedRowModel().rows.length > 2 && (
|
||||
<div className='absolute z-20 transform translate-x-1 -translate-y-1 bg-white border rounded shadow opacity-100 hover:bg-white border-muted-foreground/50 top left -rotate-1'>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.map(
|
||||
(row) =>
|
||||
row.id === activeId && (
|
||||
<TableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
className='p-1 align-top'
|
||||
key={cell.id}
|
||||
style={{ width: cell.column.getSize() }}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{table.getSelectedRowModel().rows.length > 3 && (
|
||||
<div className='absolute z-10 transform translate-x-2 -translate-y-2 bg-white border rounded shadow opacity-100 hover:bg-white border-muted-foreground/50 top left rotate-2'>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.map(
|
||||
(row) =>
|
||||
row.id === activeId && (
|
||||
<TableRow key={row.id} id={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
className='p-1 align-top'
|
||||
key={cell.id}
|
||||
style={{ width: cell.column.getSize() }}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</DragOverlay>,
|
||||
document.body
|
||||
)}
|
||||
</DragOverlay>,
|
||||
document.body
|
||||
)}
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<ButtonGroup>
|
||||
<AppendEmptyRowButton onClick={() => table.options.meta?.appendItem()} />
|
||||
<AppendCatalogArticleRowButton
|
||||
onClick={() => table.options.meta?.pickCatalogArticle()}
|
||||
/>
|
||||
</ButtonGroup>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</DndContext>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,102 +1,92 @@
|
||||
import { Button, Separator, Tooltip, TooltipContent, TooltipTrigger } from "@/ui";
|
||||
import { Table } from "@tanstack/react-table";
|
||||
import { t } from "i18next";
|
||||
import { CirclePlusIcon, CopyPlusIcon, PackagePlusIcon, ScanIcon, Trash2Icon } from "lucide-react";
|
||||
import { CopyPlusIcon, ScanIcon, Trash2Icon } from "lucide-react";
|
||||
import { AppendCatalogArticleRowButton } from "./AppendCatalogArticleRowButton";
|
||||
import { AppendEmptyRowButton } from "./AppendEmptyRowButton";
|
||||
|
||||
export const QuoteItemsSortableDataTableToolbar = ({ table }: { table: Table<unknown> }) => {
|
||||
const selectedRowsCount = table.getSelectedRowModel().rows.length;
|
||||
|
||||
if (selectedRowsCount) {
|
||||
return (
|
||||
<nav className='sticky z-10 pt-4 bg-background top-16'>
|
||||
<div className='flex items-center h-12 p-1 rounded-md text-muted-foreground bg-primary '>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
disabled={!table.getSelectedRowModel().rows.length}
|
||||
onClick={() => table.options.meta?.duplicateItems()}
|
||||
>
|
||||
<CopyPlusIcon className='w-4 h-4 sm:mr-2' />
|
||||
<span className='sr-only sm:not-sr-only'>
|
||||
{t("common.duplicate_selected_rows")}
|
||||
</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t("common.duplicate_selected_rows_tooltip")}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
disabled={!table.getSelectedRowModel().rows.length}
|
||||
onClick={() => table.options.meta?.deleteItems()}
|
||||
>
|
||||
<Trash2Icon className='w-4 h-4 sm:mr-2' />
|
||||
<span className='sr-only sm:not-sr-only'>{t("common.remove_selected_rows")}</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t("common.remove_selected_rows_tooltip")}</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
disabled={!table.getSelectedRowModel().rows.length}
|
||||
onClick={() => table.resetRowSelection()}
|
||||
>
|
||||
<ScanIcon className='w-4 h-4 sm:mr-2' />
|
||||
<span className='sr-only sm:not-sr-only'>{t("common.reset_selected_rows")}</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t("common.reset_selected_rows_tooltip")}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Separator orientation='vertical' className='h-6 mx-1 bg-muted-foreground' />
|
||||
<p className='text-sm'>{t("common.rows_selected", { count: selectedRowsCount })}</p>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<nav className='sticky z-10 pt-4 bg-background top-16'>
|
||||
<div className='flex items-center h-12 p-1 rounded-md bg-accent text-muted-foreground'>
|
||||
<nav className='flex items-center h-12 p-1 rounded-md text-muted-foreground bg-muted '>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
onClick={() => table.options.meta?.appendItem()}
|
||||
disabled={!table.getSelectedRowModel().rows.length}
|
||||
onClick={() => table.options.meta?.duplicateItems()}
|
||||
>
|
||||
<CirclePlusIcon className='w-4 h-4 mr-2' />
|
||||
<span>{t("common.append_empty_row")}</span>
|
||||
<CopyPlusIcon className='w-4 h-4 sm:mr-2' />
|
||||
<span className='sr-only sm:not-sr-only'>
|
||||
{t("common.duplicate_selected_rows")}
|
||||
</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t("common.append_empty_row_tooltip")}</TooltipContent>
|
||||
<TooltipContent>{t("common.duplicate_selected_rows_tooltip")}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
onClick={() => table.options.meta?.pickCatalogArticle()}
|
||||
disabled={!table.getSelectedRowModel().rows.length}
|
||||
onClick={() => table.options.meta?.deleteItems()}
|
||||
>
|
||||
<PackagePlusIcon className='w-4 h-4 mr-2' />
|
||||
<span>{t("common.append_article")}</span>
|
||||
<Trash2Icon className='w-4 h-4 sm:mr-2' />
|
||||
<span className='sr-only sm:not-sr-only'>{t("common.remove_selected_rows")}</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t("common.append_article_tooltip")}</TooltipContent>
|
||||
<TooltipContent>{t("common.remove_selected_rows_tooltip")}</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
disabled={!table.getSelectedRowModel().rows.length}
|
||||
onClick={() => table.resetRowSelection()}
|
||||
>
|
||||
<ScanIcon className='w-4 h-4 sm:mr-2' />
|
||||
<span className='sr-only sm:not-sr-only'>{t("common.reset_selected_rows")}</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t("common.reset_selected_rows_tooltip")}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Separator orientation='vertical' className='h-6 mx-1 bg-muted-foreground' />
|
||||
<p className='text-sm'>{t("common.rows_selected", { count: selectedRowsCount })}</p>
|
||||
</div>
|
||||
<div className='flex items-center gap-2 ml-auto'></div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<nav className='flex items-center h-12 p-1 rounded-md bg-accent/75 text-muted-foreground'>
|
||||
<div className='flex space-x-2'>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<AppendEmptyRowButton
|
||||
variant='ghost'
|
||||
onClick={() => table.options.meta?.appendItem()}
|
||||
/>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t("common.append_empty_row_tooltip")}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<AppendCatalogArticleRowButton
|
||||
variant='ghost'
|
||||
onClick={() => table.options.meta?.pickCatalogArticle()}
|
||||
/>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{t("common.append_article_tooltip")}</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className='flex items-center gap-2 ml-auto'></div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import {
|
||||
ButtonGroup,
|
||||
ColorBadge,
|
||||
DataTable,
|
||||
DataTableSkeleton,
|
||||
@ -74,7 +75,7 @@ export const QuotesDataTable = ({
|
||||
<Button
|
||||
size='sm'
|
||||
variant='link'
|
||||
className='h-8 gap-1 text-left text-ellipsis'
|
||||
className='h-8 gap-1 px-0 text-left text-ellipsis'
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
navigate(`/quotes/edit/${original.id}`, { relative: "path" });
|
||||
@ -83,7 +84,6 @@ export const QuotesDataTable = ({
|
||||
<div className=''>{renderValue()}</div>
|
||||
</Button>
|
||||
),
|
||||
enableResizing: false,
|
||||
},
|
||||
|
||||
{
|
||||
@ -92,7 +92,6 @@ export const QuotesDataTable = ({
|
||||
header: () => <>{t("quotes.list.columns.status")}</>,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
cell: ({ row: { original } }) => <ColorBadge label={original.status} />,
|
||||
enableResizing: false,
|
||||
},
|
||||
{
|
||||
id: "date" as const,
|
||||
@ -108,14 +107,12 @@ export const QuotesDataTable = ({
|
||||
</div>
|
||||
);
|
||||
},
|
||||
enableResizing: false,
|
||||
},
|
||||
{
|
||||
id: "customer_reference" as const,
|
||||
accessorKey: "customer_reference",
|
||||
header: () => <>{t("quotes.list.columns.customer_reference")}</>,
|
||||
cell: ({ renderValue }) => <div className='text-left text-ellipsis'>{renderValue()}</div>,
|
||||
enableResizing: false,
|
||||
},
|
||||
{
|
||||
id: "customer_information" as const,
|
||||
@ -138,8 +135,7 @@ export const QuotesDataTable = ({
|
||||
})}
|
||||
</div>
|
||||
),
|
||||
enableResizing: false,
|
||||
size: 640,
|
||||
size: 600,
|
||||
},
|
||||
|
||||
{
|
||||
@ -152,13 +148,12 @@ export const QuotesDataTable = ({
|
||||
<div className='text-right'>{price.isSuccess ? price.object.toFormat() : "-"}</div>
|
||||
);
|
||||
},
|
||||
enableResizing: false,
|
||||
},
|
||||
{
|
||||
id: "row-actions",
|
||||
header: () => null,
|
||||
cell: ({ row }: { row: Row<IListQuotes_Response_DTO> }) => (
|
||||
<div className='flex items-center gap-1 ml-auto'>
|
||||
<ButtonGroup>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
@ -200,9 +195,8 @@ export const QuotesDataTable = ({
|
||||
<DropdownMenuItem>{t("common.archive")}</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</ButtonGroup>
|
||||
),
|
||||
enableResizing: false,
|
||||
},
|
||||
],
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
@ -33,7 +33,9 @@ export const CatalogPickerDialog = ({
|
||||
</DataTableProvider>
|
||||
|
||||
<DialogFooter>
|
||||
<Button type='submit'>{t("common.close")}</Button>
|
||||
<Button type='submit' onClick={() => onOpenChange(false)}>
|
||||
{t("common.close")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@ -11,7 +11,7 @@ import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/ui";
|
||||
import { CurrencyData, Language, Quantity } from "@shared/contexts";
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
import { t } from "i18next";
|
||||
import { ChevronDownIcon, ChevronUpIcon, CopyIcon, Trash2Icon } from "lucide-react";
|
||||
import { ChevronDownIcon, ChevronUpIcon, Trash2Icon } from "lucide-react";
|
||||
import { useCallback, useState } from "react";
|
||||
import { useFieldArray, useFormContext } from "react-hook-form";
|
||||
import { useDetailColumns } from "../../hooks";
|
||||
@ -46,21 +46,20 @@ export const QuoteDetailsCardEditor = ({
|
||||
header: () => (
|
||||
<HashIcon aria-label='Orden de fila' className='items-center justify-center w-4 h-4' />
|
||||
),
|
||||
accessorFn: (originalRow: unknown, index: number) => index + 1,
|
||||
accessorFn: (_: unknown, index: number) => index + 1,
|
||||
size: 5,
|
||||
enableHiding: false,
|
||||
enableSorting: false,
|
||||
enableResizing: false,
|
||||
},*/
|
||||
|
||||
{
|
||||
id: "description" as const,
|
||||
accessorKey: "description",
|
||||
header: t("quotes.form_fields.items.description.label"),
|
||||
size: 24,
|
||||
cell: ({ row: { index } }) => {
|
||||
return <FormTextAreaField autoSize {...register(`items.${index}.description`)} />;
|
||||
},
|
||||
size: 500,
|
||||
},
|
||||
{
|
||||
id: "quantity" as const,
|
||||
@ -68,7 +67,6 @@ export const QuoteDetailsCardEditor = ({
|
||||
header: () => (
|
||||
<div className='text-right'>{t("quotes.form_fields.items.quantity.label")}</div>
|
||||
),
|
||||
size: 6,
|
||||
cell: ({ row: { index } }) => {
|
||||
return (
|
||||
<FormQuantityField
|
||||
@ -103,7 +101,6 @@ export const QuoteDetailsCardEditor = ({
|
||||
header: () => (
|
||||
<div className='text-right'>{t("quotes.form_fields.items.subtotal_price.label")}</div>
|
||||
),
|
||||
size: 12,
|
||||
cell: ({ row: { index } }) => {
|
||||
return (
|
||||
<FormCurrencyField
|
||||
@ -120,7 +117,6 @@ export const QuoteDetailsCardEditor = ({
|
||||
{
|
||||
id: "discount" as const,
|
||||
accessorKey: "discount",
|
||||
size: 6,
|
||||
header: () => (
|
||||
<div className='text-right'>{t("quotes.form_fields.items.discount.label")}</div>
|
||||
),
|
||||
@ -140,7 +136,6 @@ export const QuoteDetailsCardEditor = ({
|
||||
header: () => (
|
||||
<div className='text-right'>{t("quotes.form_fields.items.total_price.label")}</div>
|
||||
),
|
||||
size: 12,
|
||||
cell: ({ row: { index } }) => {
|
||||
return (
|
||||
<FormCurrencyField
|
||||
@ -157,17 +152,17 @@ export const QuoteDetailsCardEditor = ({
|
||||
},
|
||||
],
|
||||
{
|
||||
enableDragHandleColumn: true,
|
||||
enableDragHandleColumn: false, // <--- Desactivado temporalmente
|
||||
enableSelectionColumn: true,
|
||||
enableActionsColumn: true,
|
||||
rowActionFn: (props) => {
|
||||
const { table, row } = props;
|
||||
return [
|
||||
{
|
||||
/*{
|
||||
label: t("common.duplicate_row"),
|
||||
icon: <CopyIcon className='w-4 h-4 mr-2' />,
|
||||
onClick: () => table.options.meta?.duplicateItems(row.index),
|
||||
},
|
||||
},*/
|
||||
{
|
||||
label: t("common.insert_row_above"),
|
||||
icon: <ChevronUpIcon className='w-4 h-4 mr-2' />,
|
||||
|
||||
@ -36,12 +36,9 @@ export function useDetailColumns<TData = unknown, TValue = unknown>(
|
||||
),*/
|
||||
header: () => null,
|
||||
cell: (info) => <DataTableRowDragHandleCell rowId={info.row.id} />,
|
||||
size: 2,
|
||||
minSize: 2,
|
||||
maxSize: 2,
|
||||
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
size: 40,
|
||||
});
|
||||
}
|
||||
|
||||
@ -74,9 +71,7 @@ export function useDetailColumns<TData = unknown, TValue = unknown>(
|
||||
),
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
size: 2,
|
||||
minSize: 2,
|
||||
maxSize: 2,
|
||||
size: 40,
|
||||
});
|
||||
}
|
||||
|
||||
@ -90,18 +85,11 @@ export function useDetailColumns<TData = unknown, TValue = unknown>(
|
||||
/>
|
||||
),*/
|
||||
cell: (props) => {
|
||||
return (
|
||||
<div className='w-full mx-auto text-center'>
|
||||
<DataTableRowActions rowContext={props} actions={rowActionFn} />
|
||||
</div>
|
||||
);
|
||||
return <DataTableRowActions rowContext={props} actions={rowActionFn} />;
|
||||
},
|
||||
size: 4,
|
||||
minSize: 4,
|
||||
maxSize: 4,
|
||||
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
size: 48,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,9 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import React from "react";
|
||||
|
||||
export const ButtonGroup = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("ml-auto flex items-center gap-2", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
export const ButtonGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn("flex items-center gap-2", className)} {...props} />
|
||||
)
|
||||
);
|
||||
ButtonGroup.displayName = "ButtonGroup";
|
||||
|
||||
@ -89,17 +89,18 @@ export function DataTable<TData>({
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id} className={rowClassName}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead
|
||||
key={header.id}
|
||||
colSpan={header.colSpan}
|
||||
style={{ width: header.getSize() }}
|
||||
>
|
||||
<DataTableColumnHeader table={table} header={header} />
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
{headerGroup.headers.map((header) => (
|
||||
<TableHead
|
||||
key={header.id}
|
||||
colSpan={header.colSpan}
|
||||
style={{
|
||||
width:
|
||||
header.getSize() === Number.MAX_SAFE_INTEGER ? "auto" : header.getSize(),
|
||||
}}
|
||||
>
|
||||
<DataTableColumnHeader table={table} header={header} />
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
@ -124,7 +125,16 @@ export function DataTable<TData>({
|
||||
)}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id} className={cellClassName}>
|
||||
<TableCell
|
||||
key={cell.id}
|
||||
className={cellClassName}
|
||||
style={{
|
||||
width:
|
||||
cell.column.getSize() === Number.MAX_SAFE_INTEGER
|
||||
? "auto"
|
||||
: cell.column.getSize(),
|
||||
}}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
))}
|
||||
|
||||
@ -32,7 +32,7 @@ export function DataTableColumnHeader<TData, TValue>({
|
||||
: flexRender(header.column.columnDef.header, header.getContext())}
|
||||
</div>
|
||||
|
||||
{header.column.getCanResize() && (
|
||||
{false && header.column.getCanResize() && (
|
||||
<Separator
|
||||
orientation='vertical'
|
||||
className={cn(
|
||||
|
||||
@ -75,7 +75,7 @@ export function DataTablePagination<TData>({
|
||||
enablePageSizeSelector ? "justify-end" : "justify-between"
|
||||
)}
|
||||
>
|
||||
<div className='flex w-[100px] items-center justify-center'>
|
||||
<div className='flex w-[150px] items-center justify-start'>
|
||||
<p className='text-sm font-medium '>
|
||||
{t("common.num_page_of_total", {
|
||||
count: table.getState().pagination.pageIndex + 1,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
Button,
|
||||
DropdownMenu,
|
||||
@ -42,13 +41,8 @@ export function DataTableRowActions<TData = any, TValue = unknown>({
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
aria-haspopup='true'
|
||||
size='icon'
|
||||
variant='link'
|
||||
className={cn("w-4 h-4 mt-2 text-ring hover:text-muted-foreground", className)}
|
||||
>
|
||||
<MoreVerticalIcon className='w-4 h-4' />
|
||||
<Button size='icon' variant='outline' className='w-8 h-8'>
|
||||
<MoreVerticalIcon className='h-3.5 w-3.5' />
|
||||
<span className='sr-only'>{t("common.open_menu")}</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
@ -134,7 +134,11 @@ export function SortableDataTable({ columns, data, actions }: SortableDataTableP
|
||||
columns,
|
||||
enableColumnResizing: false,
|
||||
columnResizeMode: "onChange",
|
||||
//defaultColumn,
|
||||
defaultColumn: {
|
||||
minSize: 0,
|
||||
size: Number.MAX_SAFE_INTEGER,
|
||||
maxSize: Number.MAX_SAFE_INTEGER,
|
||||
},
|
||||
state: {
|
||||
rowSelection,
|
||||
columnVisibility,
|
||||
|
||||
@ -207,9 +207,9 @@ export function useDataTable<TData, TValue>({
|
||||
debugColumns: false,
|
||||
|
||||
defaultColumn: {
|
||||
size: 96, //starting column size
|
||||
minSize: 96, //enforced during column resizing
|
||||
maxSize: 500, //enforced during column resizing
|
||||
minSize: 0, //starting column size
|
||||
size: Number.MAX_SAFE_INTEGER, //enforced during column resizing
|
||||
maxSize: Number.MAX_SAFE_INTEGER, //enforced during column resizing
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
"upload": "Upload",
|
||||
"continue": "Continue",
|
||||
"close": "Close",
|
||||
"add": "Add",
|
||||
"sort_asc": "Asc",
|
||||
"sort_asc_description": "In ascending order. Click to sort descending order.",
|
||||
"sort_desc": "Desc",
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
"upload": "Cargar",
|
||||
"continue": "Continuar",
|
||||
"close": "Cerrar",
|
||||
"add": "Añadir",
|
||||
"sort_asc": "Asc",
|
||||
"sort_asc_description": "En order ascendente. Click para ordenar descendentemente.",
|
||||
"sort_desc": "Desc",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user