Uecko_ERP/modules/customer-invoices/src/web/components/customer-invoices-list-grid.tsx

161 lines
4.5 KiB
TypeScript
Raw Normal View History

2025-07-02 08:57:09 +00:00
import { AG_GRID_LOCALE_ES } from "@ag-grid-community/locale";
2025-09-16 17:41:27 +00:00
import type {
SizeColumnsToContentStrategy,
SizeColumnsToFitGridStrategy,
SizeColumnsToFitProvidedWidthStrategy,
ValueFormatterParams,
} from "ag-grid-community";
import { AllCommunityModule, ColDef, GridOptions, ModuleRegistry } from "ag-grid-community";
import { useMemo, useState } from "react";
2025-05-17 19:12:01 +00:00
2025-07-02 08:57:09 +00:00
import { MoneyDTO } from "@erp/core";
import { formatDate, formatMoney } from "@erp/core/client";
2025-09-16 17:41:27 +00:00
import { Button } from "@repo/shadcn-ui/components";
2025-05-17 19:47:08 +00:00
import { AgGridReact } from "ag-grid-react";
2025-09-16 17:41:27 +00:00
import { ChevronRightIcon } from "lucide-react";
import { useNavigate } from "react-router-dom";
2025-06-24 18:38:57 +00:00
import { useCustomerInvoicesQuery } from "../hooks";
2025-07-10 10:45:59 +00:00
import { useTranslation } from "../i18n";
2025-07-07 18:25:13 +00:00
import { CustomerInvoiceStatusBadge } from "./customer-invoice-status-badge";
2025-05-17 19:12:01 +00:00
2025-09-16 17:41:27 +00:00
ModuleRegistry.registerModules([AllCommunityModule]);
2025-05-17 19:12:01 +00:00
// Create new GridExample component
2025-07-07 18:25:13 +00:00
export const CustomerInvoicesListGrid = () => {
2025-07-09 17:56:15 +00:00
const { t } = useTranslation();
2025-09-16 17:41:27 +00:00
const navigate = useNavigate();
const {
data: customersData,
isLoading: isLoadingCustomerInvoices,
isError: isLoadError,
error: loadError,
} = useCustomerInvoicesQuery({
2025-09-11 15:38:33 +00:00
pagination: {
2025-09-11 17:52:50 +00:00
pageSize: 999,
2025-09-11 15:38:33 +00:00
},
});
2025-05-17 19:12:01 +00:00
// Column Definitions: Defines & controls grid columns.
const [colDefs] = useState<ColDef[]>([
{
2025-09-11 15:14:51 +00:00
field: "status",
2025-07-02 08:57:09 +00:00
filter: true,
2025-09-11 15:14:51 +00:00
headerName: t("pages.list.grid_columns.status"),
2025-07-07 18:25:13 +00:00
cellRenderer: (params: ValueFormatterParams) => {
return <CustomerInvoiceStatusBadge status={params.value} />;
},
2025-05-27 17:47:03 +00:00
},
2025-07-07 18:25:13 +00:00
{ field: "invoice_number", headerName: t("pages.list.grid_columns.invoice_number") },
2025-09-11 15:14:51 +00:00
{ field: "series", headerName: t("pages.list.grid_columns.series") },
2025-07-07 18:25:13 +00:00
2025-05-27 17:47:03 +00:00
{
2025-09-04 17:57:04 +00:00
field: "invoice_date",
headerName: t("pages.list.grid_columns.invoice_date"),
2025-07-02 08:57:09 +00:00
valueFormatter: (params: ValueFormatterParams) => {
return formatDate(params.value);
},
},
2025-09-11 15:14:51 +00:00
{ field: "recipient.tin" },
{ field: "recipient.name" },
{ field: "recipient.city" },
{ field: "recipient.province" },
{ field: "recipient.postal_code" },
{
field: "taxable_amount",
headerName: t("pages.list.grid_columns.taxable_amount"),
valueFormatter: (params: ValueFormatterParams) => {
const rawValue: MoneyDTO = params.value;
return formatMoney(rawValue);
},
},
2025-05-17 19:12:01 +00:00
{
2025-09-11 15:14:51 +00:00
field: "taxes_amount",
headerName: t("pages.list.grid_columns.taxable_amount"),
valueFormatter: (params: ValueFormatterParams) => {
const rawValue: MoneyDTO = params.value;
return formatMoney(rawValue);
},
},
{
field: "total_amount",
headerName: t("pages.list.grid_columns.total_amount"),
2025-05-17 19:12:01 +00:00
valueFormatter: (params: ValueFormatterParams) => {
2025-07-02 08:57:09 +00:00
const rawValue: MoneyDTO = params.value;
return formatMoney(rawValue);
2025-05-17 19:12:01 +00:00
},
},
2025-09-12 18:07:38 +00:00
{
2025-09-16 17:41:27 +00:00
colId: "actions",
headerName: t("pages.list.grid_columns.actions", "Actions"),
2025-09-12 18:07:38 +00:00
cellRenderer: (params: ValueFormatterParams) => {
2025-09-16 17:41:27 +00:00
const { data } = params;
return (
<Button
variant='secondary'
size='icon'
className='size-8'
onClick={() => {
navigate(`${data.id}/edit`);
}}
>
<ChevronRightIcon />
</Button>
);
2025-09-12 18:07:38 +00:00
},
},
2025-05-17 19:12:01 +00:00
]);
2025-09-16 17:41:27 +00:00
const autoSizeStrategy = useMemo<
| SizeColumnsToFitGridStrategy
| SizeColumnsToFitProvidedWidthStrategy
| SizeColumnsToContentStrategy
>(() => {
return {
type: "fitGridWidth",
defaultMinWidth: 100,
columnLimits: [{ colId: "actions", minWidth: 75, maxWidth: 75 }],
};
}, []);
const gridOptions: GridOptions = useMemo(
() => ({
columnDefs: colDefs,
autoSizeStrategy: autoSizeStrategy,
defaultColDef: {
editable: false,
flex: 1,
filter: false,
sortable: false,
resizable: true,
},
pagination: true,
paginationPageSize: 10,
paginationPageSizeSelector: [10, 20, 30, 50],
localeText: AG_GRID_LOCALE_ES,
}),
[autoSizeStrategy, colDefs]
);
2025-05-17 19:12:01 +00:00
// Container: Defines the grid's theme & dimensions.
return (
2025-05-18 11:53:00 +00:00
<div
2025-05-20 10:08:24 +00:00
className='ag-theme-alpine'
style={{
height: "100%",
width: "100%",
}}
2025-05-18 11:53:00 +00:00
>
2025-09-16 17:41:27 +00:00
<AgGridReact
rowData={customersData?.items ?? []}
loading={isLoadingCustomerInvoices}
{...gridOptions}
/>
2025-05-17 19:12:01 +00:00
</div>
);
};