200 lines
5.4 KiB
JavaScript
200 lines
5.4 KiB
JavaScript
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 && (
|
|
<TableToolbar
|
|
table={table}
|
|
mutate={mutate}
|
|
filterData={specialFilter || filterData}
|
|
/>
|
|
)}
|
|
</>
|
|
),
|
|
renderRowActions: ({ row }) => <RowActions row={row} mutate={mutate} />,
|
|
...props,
|
|
});
|
|
|
|
return (
|
|
<DataTable_Paper
|
|
table={table}
|
|
table_title={table_title}
|
|
need_filter={need_filter}
|
|
mutate={mutate}
|
|
table_url={table_url}
|
|
columns={flatColumns}
|
|
user_id={user_id}
|
|
page_name={page_name}
|
|
table_name={table_name}
|
|
special_data={props.data}
|
|
special_filter={specialFilter}
|
|
setFilterData={props.setFilterData}
|
|
/>
|
|
);
|
|
};
|
|
export default DataTable_Main;
|