"use client"; import React, { forwardRef, useEffect, useImperativeHandle, useState, } from "react"; import BAIconButton from "./BAIconButton"; import { DeleteOutlined, EditOutlined, PlusOutlined, CloseOutlined, CheckOutlined, FileExcelOutlined, PrinterOutlined, } from "@ant-design/icons"; import BABox from "./BABox"; import BAButton from "./BAButton"; import BAPagination from "./BAPagination"; import BAModal from "./BAModal"; import { formElement } from "./BAComponentSwitcher"; import { Grid, message, Popconfirm, theme } from "antd"; import BALoader from "./BALoader"; import BAinput from "./BAInput"; import classNames from "classnames"; import BASelect from "./BASelect"; import BABackdropLoader from "./BABackdropLoader"; import BADate from "./BADate"; import * as XLSX from "xlsx"; import BAPera from "./BAPera"; import { formattedDate, formattedNumber } from "./config/helpers"; import BAScreenHeader from "./BAScreenHeader"; import createApiFunction from "./config/apimethods"; const { useBreakpoint } = Grid; type propsType = { cols: any[]; controller: string; apiName?: string; exportUrl?: string; onAddEdit?: any; onView?: any; title: string; sortColumn?: string; sortDirection?: string; formElement?: formElement[]; extraActions?: { displayField: any; isHide: boolean; }[]; disableAdd?: boolean; disableEdit?: boolean; disablePost?: boolean; disableView?: boolean; disableDelete?: boolean; disableExport?: boolean; allowPrint?: boolean; extraParams?: any; exportParams?: any; extraHeaders?: any; getDataTrigger?: any; modelGetter?: any; rec_id?: any; conditionalColumns?: { label: string; displayField: any }[]; getByRequest?: boolean; modelAlias?: any; customButton?: React.ReactNode[]; fieldsToDelete?: string[]; convertToNumber?: string[]; disableCompId?: boolean; reqFields?: string[]; isUpdateReq?: boolean; extraBody?: any; searchParams?: any; rowPrint?: any; apiFunctions: any }; export default forwardRef(function BASetupGrid(props: propsType, ref: any) { const { cols, controller, extraParams = {}, apiName, onAddEdit, title, disableAdd, disableEdit, disableDelete, extraActions, extraHeaders = [], conditionalColumns, modelGetter, customButton, extraBody, searchParams, disableExport, allowPrint, rowPrint, apiFunctions } = props; const { Get, Delete } = apiFunctions const { token }: any = theme.useToken() const [listData, setListData] = useState([]); const [printLoader, setPrintLoader] = useState(false); const [loader, setLoader] = useState(false); const [excelLoader, setExcelLoader] = useState(false); const [gridSearchObj, setGridSearchObj] = useState({}); const [exportModal, setExportModal] = useState(false); const [paginationConfig, setPaginationConfig] = useState({ pageSize: 10, page: 1, totalRecords: 0, }); const screens = useBreakpoint(); const isMobile = !screens.md; // md = 768px breakpoint const addEditClick = (row?: any) => { if (onAddEdit) { onAddEdit(row); } }; const getExcelData = async () => { const updatedSearchObj = Object.fromEntries( Object.entries(gridSearchObj).filter(([_, value]) => value !== undefined && value !== null) ); let res: any = await Get(`${controller}`, null, { pageNo: 1, pageSize: 1000000000, selector: cols.map((col) => col.key).filter(Boolean).join(","), filter: JSON.stringify({ ...updatedSearchObj, ...extraParams }), }) if (res?.data?.rows) { return res.data.rows; } } const exportToExcel = async (currentPage?: boolean, summary?: boolean) => { if (currentPage) { const worksheetData = []; const headers = cols.map((col: any) => col.key); worksheetData.push(headers); // Prepare data rows listData.forEach((row: any) => { const rowData = cols.map((col: any) => { const value = row[col.key]; // Handle date formatting if necessary if (col.type === "date" && value) { return formattedDate(value); // Adjust date format as needed } return value !== undefined && value !== null ? value : ""; }); worksheetData.push(rowData); }); // Create a worksheet from the data const worksheet = XLSX.utils.aoa_to_sheet(worksheetData); // Create a workbook and append the worksheet const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, title); // XLSX to Excel XLSX.writeFile(workbook, `${title}.xlsx`); } else { setExcelLoader(true); let list: any = await getExcelData(); if (!list) { message.error("No data available for export."); return; } const worksheetData = []; const headers = cols.map((col: any) => col.key); worksheetData.push(headers); // Prepare data rows list.forEach((row: any) => { const rowData = cols.map((col: any) => { const value = row[col.key]; // Handle date formatting if necessary if (col.type === "date" && value) { return formattedDate(value); // Adjust date format as needed } return value !== undefined && value !== null ? value : ""; }); worksheetData.push(rowData); }); // Create a worksheet from the data const worksheet = XLSX.utils.aoa_to_sheet(worksheetData); // Create a workbook and append the worksheet const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, title); // XLSX to Excel XLSX.writeFile(workbook, `${title}.xlsx`); setExcelLoader(false); } setExportModal(false); } const getData = (pgObj?: any, SearchObj?: any) => { setLoader(true); const updatedSearchObj = Object.fromEntries( Object.entries(SearchObj ? SearchObj : gridSearchObj).filter(([_, value]) => value !== undefined && value !== null) ); Get(`${controller}`, null, { pageNo: pgObj ? pgObj.page : paginationConfig.page, pageSize: pgObj ? pgObj.pageSize : paginationConfig.pageSize, selector: cols.map((col) => col.key).filter(Boolean).join(","), filter: JSON.stringify({ ...updatedSearchObj, ...extraParams }), ...searchParams ? { ...searchParams } : {}, }) .then((res: any) => { if (res?.rows) { setListData([...res.data?.rows]); setPaginationConfig({ ...paginationConfig, totalRecords: res.data?.totalCounts }); } else { message.error(res.message || "An error occurred."); } setLoader(false); }) .catch(() => { setLoader(false); message.error("Failed to fetch data. Please try again."); }); }; useImperativeHandle(ref, () => ({ invokeChildFunction: getData, })); const deleteRecord = (id: any) => { setPrintLoader(true); Delete(`${controller}`, id) .then(() => { message.success("Record Deleted Successfully"); getData(); }) .catch((err: any) => { message.error(err?.error); }).finally(() => { setPrintLoader(false); }); }; const printRecord = (id: any) => { if (rowPrint) { rowPrint(id) } } useEffect(() => { getData(); }, []); useEffect(() => { if (extraParams?.length) getData() }, [extraParams]) return ( <> exportToExcel(true)} label="Current Page" /> exportToExcel(false)} label="Export All Data" /> {apiName && exportToExcel(false, true)} label="Export Detailed" />} } /> ({ displayField: () => item, })) || []), { displayField: () => isMobile ? } onClick={() => { setExportModal(true); }} /> : } label="Export as Excel" onClick={() => { setExportModal(true); }} />, isHide: disableExport, }, { displayField: () => isMobile ? } onClick={() => addEditClick()} /> : } label="Add New" onClick={() => addEditClick()} />, isHide: disableAdd, }, ]} /> {extraBody} {loader ? ( ) : (<> {extraActions && extraActions.length > 0 && ( )} {conditionalColumns && conditionalColumns.length > 0 ? conditionalColumns.map((col: any, index: number) => ( )) : null} {cols.map((col: any, index: number) => ( ))} {extraActions && extraActions.length > 0 && ( )} {cols.map((col: any, index: number) => ( ))} {listData.length > 0 ? ( listData.map((row: any, rowIndex: number) => ( {extraActions && extraActions.length > 0 && ( )} {cols.map((col: any, colIndex: number) => ( ))} {conditionalColumns && conditionalColumns.length > 0 ? conditionalColumns.map((col: any, index: number) => ( )) : null} )) ) : ( )}
{col.label} {col.label} {col.HeaderField ? col.HeaderField() : ""}
{Object.entries(gridSearchObj).length > 0 && ( { setGridSearchObj({}); getData(null, {}); }} icon={} /> )} {col.type === "enum" ? { gridSearchObj[col.key] = e; setGridSearchObj({ ...gridSearchObj }); let obj = { ...gridSearchObj } obj[col.key] = e getData(null, { ...obj }); }} options={col.filterEnums} label="" value={gridSearchObj[col.key]} /> : col.type === "date" ? <> {!col.hideFilter && { gridSearchObj[col.key] = new Date(e).toLocaleString(); setGridSearchObj({ ...gridSearchObj }); let obj = { ...gridSearchObj } obj[col.key] = formattedDate(new Date(e)) getData(null, { ...obj }); }} label={""} />} : { if (event.key === "Enter") { getData(); } }} value={gridSearchObj[col.key]} onChange={(ev: any) => { gridSearchObj[col.key] = ev.target.value; setGridSearchObj({ ...gridSearchObj }); }} label={""} />}
{extraActions && extraActions.map( (exAction: any, exIndex: number) => ( {exAction.isHide ? null : exAction.displayField(row, getData)} ) )} {!disableEdit && ( { addEditClick(row); if (modelGetter) modelGetter({ ...row }) }} className="text-black hover:text-[#DB052C] m-1 text-lg hover:scale-125" /> )} {!disableDelete && ( deleteRecord(row.id)} okText="Yes" cancelText="No" > { }} className="text-black hover:text-[#DB052C] m-1 text-lg hover:scale-125" /> )} {allowPrint && ( { printRecord(row.id); }} className="text-black hover:text-[#DB052C] m-1 text-lg hover:scale-125" /> )} {col.displayField ? ( col.displayField(row) ) : col.type === "status" ? ( row[col.key] ? : ) : col.type === "number" ? ( {formattedNumber(row[col.key])} ) : col.type === "date" ? ( {formattedDate(row[col.key])} ) : ( row[col.key] )} {col.displayField(row)}
No Data Found
{listData.length > 0 && listData.map((row: any, rowIndex: number) => ( {cols.map((col: any, colIndex: number) => ( {col.label} {col.displayField ? ( col.displayField(row) ) : col.type === "status" ? ( row[col.key] ? ( ) : ( ) ) : col.type === "number" ? ( {formattedNumber(row[col.key])} ) : col.type === "link" ? ( printRecord(row.id)} > {row[col.key]} ) : col.type === "date" ? ( {formattedDate(row[col.key])} ) : ( row[col.key] || "--" )} ))} {extraActions && extraActions.map( (exAction: any, exIndex: number) => ( {exAction.isHide ? null : exAction.displayField(row, getData)} ) )} {!disableEdit && ( { addEditClick(row); if (modelGetter) modelGetter({ ...row }) }} className="text-black hover:text-[#DB052C] m-1 text-lg hover:scale-125" /> )} {!disableDelete && ( deleteRecord(row.id)} okText="Yes" cancelText="No" > { }} className="text-black hover:text-[#DB052C] m-1 text-lg hover:scale-125" /> )} {conditionalColumns && conditionalColumns.length > 0 ? conditionalColumns.map((col: any, index: number) => ( {col.displayField(row)} )) : null} ))} )}
{ getData({ page: page, pageSize: pageSize, }); }} />
); });