import DataTableFilterDataStructure from "@/core/utils/DataTableFilterDataStructure"; import { flattenArrayOfObjects } from "@/core/utils/flattenArrayOfObjects"; import { flattenObjectOfObjects } from "@/core/utils/flattenObjectOfObjects"; import isArrayEmpty from "@/core/utils/isArrayEmpty"; import useDataTable from "@/lib/hooks/useDataTable"; import useRequest from "@/lib/hooks/useRequest"; import { useMaterialReactTable } from "material-react-table"; import { useCallback, useEffect, useReducer, useState } from "react"; import useSWR from "swr"; import { FA_DATATABLE_LOCALIZATION } from "./localization/fa/datatable"; import DataTable_Paper from "./table/Paper"; const rowSelectionReducer = (state, action) => { switch (action.type) { case "TOGGLE_ROW": return { [action.payload]: true }; case "RESET": return {}; default: return state; } }; const DataTable_Main = (props) => { const request = useRequest(); const [rowSelection, dispatchRowSelection] = useReducer( rowSelectionReducer, {}, ); const { filterData, sortData, setSortData, hideData } = useDataTable(); const { need_filter, table_url, user_id, page_name, table_name, columns, initialStateProps, TableToolbar, table_title, RowActions, specific_data, specialFilter, } = props; const flatColumns = flattenArrayOfObjects(columns, "columns"); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 }); const [totalRowCount, setTotalRowCount] = useState(0); const flattenHideData = flattenObjectOfObjects(hideData); const onSortingChange = (event) => { setSortData(event); }; const fetchUrl = useCallback(() => { const params = new URLSearchParams(); params.set("start", `${pagination.pageIndex * pagination.pageSize}`); params.set("size", pagination.pageSize); if (specialFilter) { const filteredSpecialFilterData = Object.values(specialFilter).filter( (filter) => !isArrayEmpty(filter.value), ); params.set("filters", JSON.stringify(filteredSpecialFilterData || [])); } else { const filteredFilterData = DataTableFilterDataStructure( filterData, isArrayEmpty, ); params.set( "filters", JSON.stringify( filteredFilterData.length === 0 ? [] : filteredFilterData, ), ); } params.set( "sorting", JSON.stringify( Object.values(sortData).map(({ id, ...rest }) => ({ ...rest, id: id.replace(/__/g, "."), })), ), ); return `${table_url}?${params}`; }, [table_url, filterData, pagination, sortData, specialFilter]); const fetcher = async (url) => { try { const response = await request(url); setTotalRowCount(response.data?.meta?.totalRowCount); if (specific_data) { return specific_data(response.data); } else { return response.data?.data; } } catch (error) { throw error; } }; const { data, isValidating, mutate } = useSWR( props.data ? "" : fetchUrl(), fetcher, { revalidateIfStale: true, revalidateOnFocus: false, revalidateOnReconnect: true, keepPreviousData: true, }, ); useEffect(() => { if (!isValidating) return; dispatchRowSelection({ type: "RESET" }); }, [isValidating]); const table = useMaterialReactTable({ localization: FA_DATATABLE_LOCALIZATION, columns, data: data ?? [], muiTableBodyRowProps: ({ row }) => ({ onClick: () => dispatchRowSelection({ type: "TOGGLE_ROW", payload: row.id }), selected: !!rowSelection[row.id], }), initialState: { density: "compact", columnVisibility: flattenHideData, sorting: sortData, ...initialStateProps, }, state: { showProgressBars: isValidating || props.loading, columnVisibility: flattenHideData, sorting: sortData, pagination, rowSelection, }, muiTableHeadProps: { sx: { borderTop: "1px solid #e1e1e1", borderBottom: "2px solid #e1e1e1", }, }, muiTableHeadCellProps: { sx: { color: "primary.main", borderLeft: "1px solid #e1e1e1", "&:first-of-type": { borderLeft: "unset", }, }, }, muiTableBodyCellProps: { sx: { borderLeft: "1px solid #e1e1e1", "&:first-of-type": { borderLeft: "unset", }, }, }, manualFiltering: true, manualPagination: true, manualSorting: true, onPaginationChange: setPagination, onSortingChange: onSortingChange, rowCount: totalRowCount, renderTopToolbarCustomActions: ({ table }) => ( <> {TableToolbar && ( )} ), renderRowActions: ({ row }) => , ...props, }); return ( ); }; export default DataTable_Main;