|
- // material-ui
- import { useState, useEffect, useRef } from 'react';
- import { Box } from "@mui/material";
- import {
- DataGrid, GridOverlay,
- } from "@mui/x-data-grid";
- import * as HttpUtils from "utils/HttpUtils";
- import { FormattedMessage, useIntl } from "react-intl";
- import { TablePagination, Typography } from '@mui/material';
- import { getSearchCriteria, checkSearchCriteriaPath } from "auth/utils";
-
- /** When Gazette Issue No. is selected, load all matching rows (no start/limit). */
- function hasGazetteIssueFilter(params) {
- const issueId = params?.issueId;
- return issueId != null && issueId !== "";
- }
-
- // ==============================|| EVENT TABLE ||============================== //
-
- export function FiDataGrid({ rows, columns, sx, autoHeight = true,
- hideFooterSelectedRowCount, rowModesModel, editMode,
- pageSizeOptions, filterItems, customPageSize, doLoad, applyGridOnReady, applySearch,
- tab, height, maxHeight, pagination = true, serverSorting = false,
- disablePagingOnGazetteIssue = true, ...props }) {
- const intl = useIntl();
- const [_rows, set_rows] = useState([]);
- const [_doLoad, set_doLoad] = useState({});
- const [_columns, set_columns] = useState([]);
- const [_rowModesModel, set_rowModesModel] = useState({});
- const [_editMode, set_editMode] = useState("row");
- const [_pageSizeOptions, set_pageSizeOptions] = useState([10]);
- const [_filterItems, set_filterItems] = useState([]);
- const [loading, setLoading] = useState(false);
-
- const [page, setPage] = useState(0);
- const [pageSize, setPageSize] = useState(10);
- const [sortModel, setSortModel] = useState([]);
- // const [_autoHeight, set_autoHeight] = useState(true);
- const [myHideFooterSelectedRowCount, setMyHideFooterSelectedRowCount] = useState(true);
- const [_sx, set_sx] = useState({
- padding: "4 2 4 2",
- lineHeight: "normal",
- '& .MuiDataGrid-cell': {
- borderTop: 1,
- borderBottom: 1,
- borderColor: "#EEE",
- },
- '& .MuiDataGrid-footerContainer': {
- border: 1,
- borderColor: "#EEE"
- },
- "& .MuiDataGrid-columnHeaderTitle": {
- whiteSpace: "normal",
- lineHeight: "normal"
- },
- "& .MuiDataGrid-columnHeader": {
- // Forced to use important since overriding inline styles
- height: "unset !important"
- },
- });
-
- const effectiveAutoHeight = autoHeight && !height && !maxHeight;
-
- const containerSx = {
- width: '100%',
- minWidth: 0,
- ...(height ? { height } : {}),
- ...(maxHeight ? { maxHeight, height: '100%' } : {}),
- overflow: 'hidden',
- };
-
- const [rowCount, setRowCount] = useState(0);
-
- useEffect(() => {
- if (doLoad !== undefined && Object.keys(doLoad).length>0 ){
- if(applySearch!=undefined){
- if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
- const localStorageSearchCriteria = getSearchCriteria(window.location.pathname)
- // console.log(localStorageSearchCriteria)
- if(localStorageSearchCriteria.start!=undefined){
- // console.log(localStorageSearchCriteria)
- setPage(localStorageSearchCriteria.start/pageSize);
- }
- }
- }else{
- setPage(0);
- setPageSize(parseInt(event.target.value, 10));
- }
- if (serverSorting) {
- if (doLoad.params?.sort && doLoad.params?.direction) {
- setSortModel([{
- field: doLoad.params.sort,
- sort: String(doLoad.params.direction).toLowerCase()
- }]);
- } else {
- setSortModel([]);
- }
- }
- set_doLoad(doLoad);
- setLoading(true)
- }
- }, [doLoad]);
-
- const handleSortModelChange = (newModel) => {
- if (!serverSorting) return;
- setSortModel(newModel);
- setPage(0);
-
- const params = { ...(_doLoad.params || {}) };
- if (newModel?.length > 0 && newModel[0].field && newModel[0].sort) {
- params.sort = newModel[0].field;
- params.direction = newModel[0].sort;
- } else {
- delete params.sort;
- delete params.direction;
- }
- if (!pagination || (disablePagingOnGazetteIssue && hasGazetteIssueFilter(params))) {
- delete params.start;
- delete params.limit;
- } else {
- params.start = 0;
- params.limit = pageSize;
- }
-
- if (applySearch != undefined) {
- applySearch(params);
- } else {
- set_doLoad({ ..._doLoad, params });
- setLoading(true);
- }
- };
-
- const ignorePaging = !pagination || (disablePagingOnGazetteIssue && hasGazetteIssueFilter(_doLoad?.params));
- const effectivePagination = pagination && !ignorePaging;
-
- useEffect(() => {
- getDataList();
- }, [_doLoad, page]);
-
-
- useEffect(() => {
- if (sx) {
- set_sx(sx);
- }
- if (hideFooterSelectedRowCount) {
- setMyHideFooterSelectedRowCount(hideFooterSelectedRowCount);
- }
- if (rowModesModel) {
- set_rowModesModel(rowModesModel)
- }
- if (rows) {
- set_rows(rows)
- setRowCount(rows.length)
- }
- if (columns) {
- set_columns(columns)
- }
- if (pageSizeOptions) {
- set_pageSizeOptions(pageSizeOptions)
- }
- // if (autoHeight !== undefined) {
- // set_autoHeight(autoHeight)
- // }
- if (editMode) {
- set_editMode(editMode);
- }
- if (filterItems) {
- set_filterItems(filterItems);
- }
- if (customPageSize) {
- setPageSize(customPageSize);
- }
- // console.log(_doLoad)
- if (_doLoad !== undefined && Object.keys(_doLoad).length==0 ){
- setLoading(false)
- if (applyGridOnReady !== undefined){
- applyGridOnReady(false)
- }
- }
- }, [sx, hideFooterSelectedRowCount, rowModesModel, rows, columns, pageSizeOptions, autoHeight, editMode, filterItems, customPageSize]);
-
- const handleChangePage = (event, newPage) => {
- setPage(newPage);
- };
-
- const handleChangePageSize = (event) => {
- setPageSize(parseInt(event.target.value, 10));
- setPage(0);
- };
-
- function CustomNoRowsOverlay() {
- return (
- <GridOverlay
- sx={{
- width: "100%",
- justifyContent: "flex-start", // align overlay to left
- pl: 2, // padding-left to match grid cells
- }}
- >
- <Typography variant="body1" sx={{ textAlign: "left", width: "100%" }}>
- <FormattedMessage id="noRecordFound" />
- </Typography>
- </GridOverlay>
- );
- }
-
-
- function getDataList() {
- // console.log(Object.keys(_doLoad.params).length > 0)
- // console.log(Object.keys(_doLoad.params).length > 0)
-
- if (_doLoad?.url == null){
- setLoading(false)
- return;
- }
- if (_doLoad.params == undefined) return;
- if (_doLoad.params.searchCriteria !== undefined) return;
- if (_doLoad.params == null) _doLoad.params = {};
- if (!pagination || (disablePagingOnGazetteIssue && hasGazetteIssueFilter(_doLoad.params))) {
- delete _doLoad.params.start;
- delete _doLoad.params.limit;
- } else {
- _doLoad.params.start = page * pageSize;
- _doLoad.params.limit = pageSize;
- }
- if(checkSearchCriteriaPath(window.location.pathname)){
- if(window.location.pathname === "/publicNotice"){
- if (tab != undefined && tab ==="application"){
- localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:_doLoad.params}))
- }
- }else if (window.location.pathname != "/publicNotice"){
- localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:_doLoad.params}))
- }
- }
-
- HttpUtils.get({
- url: _doLoad.url,
- params: _doLoad.params,
- onSuccess: function (responseData) {
- set_rows(responseData?.records);
- setRowCount(responseData?.count);
- if (_doLoad.callback != null) {
- _doLoad.callback(responseData);
- }
- setLoading(false)
- // console.log(applyGridOnReady)
- if (applyGridOnReady !== undefined){
- applyGridOnReady(false)
- }
- },
- onError: function (error){
- console.log(error)
- setLoading(false)
- if (applyGridOnReady !== undefined){
- applyGridOnReady(false)
- }
- }
- });
- }
-
- const gridRootRef = useRef(null);
-
- useEffect(() => {
- const root = gridRootRef.current;
- if (!root) return;
-
- const sortText = intl.formatMessage({ id: "sort", defaultMessage: "Sort" });
-
- const apply = () => {
- // 1) Make ALL column headers tabbable (optional; DataGrid already manages focus well)
- root
- .querySelectorAll('.MuiDataGrid-columnHeaders [role="columnheader"]')
- .forEach((el) => {
- if (el.getAttribute("tabindex") !== "0") el.setAttribute("tabindex", "0");
- });
-
- // 2) Localize sort icon button label (handles "sort"/"Sort"/any old value)
- const sortButtons = root.querySelectorAll(
- '.MuiDataGrid-columnHeaders button.MuiIconButton-root'
- );
-
- sortButtons.forEach((btn) => {
- const al = (btn.getAttribute("aria-label") || "").trim().toLowerCase();
- const ti = (btn.getAttribute("title") || "").trim().toLowerCase();
-
- // Only rewrite the ones that are the sort icon buttons
- if (al === "sort" || ti === "sort") {
- btn.setAttribute("aria-label", sortText);
- btn.setAttribute("title", sortText);
- }
- });
- };
-
- apply();
-
- const obs = new MutationObserver(apply);
- obs.observe(root, { childList: true, subtree: true });
-
- return () => obs.disconnect();
- }, [intl]);
-
- return (
- <Box sx={containerSx} ref={gridRootRef} role="table">
- <DataGrid
- {...props}
- rows={_rows}
- rowCount={rowCount || 0}
- columns={_columns}
- disableColumnMenu
- shrinkWrap
- rowModesModel={_rowModesModel}
- pageSizeOptions={effectivePagination ? _pageSizeOptions : []}
- editMode={_editMode}
- autoHeight={effectiveAutoHeight}
- hideFooterSelectedRowCount={myHideFooterSelectedRowCount}
- filterModel={{ items: _filterItems }}
- loading={loading}
- paginationMode={effectivePagination ? "server" : undefined}
- sortingMode={serverSorting ? "server" : undefined}
- sortModel={serverSorting ? sortModel : undefined}
- onSortModelChange={serverSorting ? handleSortModelChange : undefined}
- sx={{
- ..._sx,
- '& .MuiDataGrid-virtualScroller': {
- overflowY: height || maxHeight ? 'auto' : 'visible',
- overflowX: height || maxHeight ? 'auto' : 'visible',
- },
- // 👇 completely hide the footer when pagination is off
- ...(!effectivePagination && {
- '& .MuiDataGrid-footerContainer': {
- display: 'none',
- },
- }),
- }}
- components={{
- NoRowsOverlay: CustomNoRowsOverlay,
- ...(effectivePagination
- ? {
- Pagination: () => (
- <TablePagination
- component="div"
- count={rowCount || 0}
- page={page}
- rowsPerPage={pageSize}
- rowsPerPageOptions={_pageSizeOptions}
- labelDisplayedRows={() => {
- const total = rowCount || 0;
- if (!_rows?.length || total === 0) {
- return `0-0 ${intl.formatMessage({ id: "of" })} ${total}`;
- }
- const from = page * pageSize + 1;
- const to = Math.min(page * pageSize + _rows.length, total);
- return `${from}-${to} ${intl.formatMessage({ id: "of" })} ${total}`;
- }}
- labelRowsPerPage={intl.formatMessage({ id: "rowsPerPage" }) + ":"}
- getItemAriaLabel={(type) => {
- if (type === 'previous') {
- return intl.formatMessage({ id: 'paginationPrev' });
- }
- if (type === 'next') {
- return intl.formatMessage({ id: 'paginationNext' });
- }
- return '';
- }}
- onPageChange={handleChangePage}
- onRowsPerPageChange={handleChangePageSize}
- />
- ),
- }
- : {}),
- }}
- />
-
- </Box>
- );
- }
|