forked from Abdulbari/sgeUpdated
Add optimization to show data faster using Memo
This commit is contained in:
@@ -1,8 +1,16 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useMemo } from "react";
|
||||||
import { MaterialReactTable } from "material-react-table";
|
import { MaterialReactTable } from "material-react-table";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Card, CardHeader, CardTitle, Alert, Row, Col, Label } from "reactstrap";
|
import {
|
||||||
|
Card,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
Alert,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
Label,
|
||||||
|
} from "reactstrap";
|
||||||
import { getVMEmissionSummary } from "../../redux/actions/mainDataTables/index";
|
import { getVMEmissionSummary } from "../../redux/actions/mainDataTables/index";
|
||||||
import { getDataCenters } from "../../redux/actions/dataCenter";
|
import { getDataCenters } from "../../redux/actions/dataCenter";
|
||||||
import { editNumbers } from "../../components/edit-numbers";
|
import { editNumbers } from "../../components/edit-numbers";
|
||||||
@@ -44,7 +52,7 @@ function MainDataTables() {
|
|||||||
setError(null);
|
setError(null);
|
||||||
await dispatch(getVMEmissionSummary(selectedDataCenter.value));
|
await dispatch(getVMEmissionSummary(selectedDataCenter.value));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error in MainDataTables:', err);
|
console.error("Error in MainDataTables:", err);
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -54,30 +62,90 @@ function MainDataTables() {
|
|||||||
}
|
}
|
||||||
}, [selectedDataCenter, dispatch]);
|
}, [selectedDataCenter, dispatch]);
|
||||||
|
|
||||||
// Debug log for store data
|
// Memoize columns to prevent re-renders
|
||||||
useEffect(() => {
|
const columns = useMemo(
|
||||||
console.log('Current store data:', mainDataTablesStore);
|
() => [
|
||||||
}, [mainDataTablesStore]);
|
{
|
||||||
|
header: t("VM ID"),
|
||||||
|
accessorKey: "vmId",
|
||||||
|
size: 150,
|
||||||
|
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: t("VM Name"),
|
||||||
|
accessorKey: "vmName",
|
||||||
|
size: 200,
|
||||||
|
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: t("VM Power"),
|
||||||
|
accessorKey: "vmPower",
|
||||||
|
size: 120,
|
||||||
|
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: t("VM Status"),
|
||||||
|
accessorKey: "vmStatus",
|
||||||
|
size: 100,
|
||||||
|
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: t("Total Emission"),
|
||||||
|
accessorKey: "totalEmission",
|
||||||
|
size: 150,
|
||||||
|
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: t("Created Date"),
|
||||||
|
accessorKey: "createdDate",
|
||||||
|
size: 180,
|
||||||
|
Cell: ({ cell }) => (
|
||||||
|
<span>
|
||||||
|
{cell.getValue() ? new Date(cell.getValue()).toLocaleString() : "-"}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: t("Physical Machine"),
|
||||||
|
accessorKey: "physicalMachine",
|
||||||
|
size: 150,
|
||||||
|
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: t("Data Center"),
|
||||||
|
accessorKey: "dataCenter",
|
||||||
|
size: 150,
|
||||||
|
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "CO2",
|
||||||
|
accessorKey: "co2",
|
||||||
|
size: 100,
|
||||||
|
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "CH4",
|
||||||
|
accessorKey: "ch4",
|
||||||
|
size: 100,
|
||||||
|
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "N2O",
|
||||||
|
accessorKey: "n2o",
|
||||||
|
size: 100,
|
||||||
|
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[t]
|
||||||
|
);
|
||||||
|
|
||||||
const columns = [
|
// Memoize table data to prevent unnecessary re-renders
|
||||||
{ header: t("VM ID"), accessorKey: "vmId", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> },
|
const tableData = useMemo(() => {
|
||||||
{ header: t("VM Name"), accessorKey: "vmName", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> },
|
const data = mainDataTablesStore?.vmEmissionSummary || [];
|
||||||
{ header: t("VM Power"), accessorKey: "vmPower", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> },
|
console.log("VM Emission data count:", data.length);
|
||||||
{ header: t("VM Status"), accessorKey: "vmStatus", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> },
|
return data;
|
||||||
{ header: t("Total Emission"), accessorKey: "totalEmission", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> },
|
}, [mainDataTablesStore?.vmEmissionSummary]);
|
||||||
{ header: t("Created Date"), accessorKey: "createdDate", Cell: ({ cell }) => (<span>{cell.getValue() ? new Date(cell.getValue()).toLocaleString() : "-"}</span>), sortable: true },
|
|
||||||
{ header: t("Physical Machine"), accessorKey: "physicalMachine", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> },
|
|
||||||
{ header: t("Data Center"), accessorKey: "dataCenter", Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span> },
|
|
||||||
{ header: "CO2", accessorKey: "co2", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> },
|
|
||||||
{ header: "CH4", accessorKey: "ch4", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> },
|
|
||||||
{ header: "N2O", accessorKey: "n2o", Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span> },
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const tableData = mainDataTablesStore?.vmEmissionSummary || [];
|
|
||||||
console.log('VM Emission data:', tableData);
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
@@ -92,6 +160,11 @@ function MainDataTables() {
|
|||||||
<Card>
|
<Card>
|
||||||
<CardHeader className="border-bottom">
|
<CardHeader className="border-bottom">
|
||||||
<CardTitle tag="h4">{t("Raw Data")}</CardTitle>
|
<CardTitle tag="h4">{t("Raw Data")}</CardTitle>
|
||||||
|
{tableData.length > 0 && (
|
||||||
|
<small className="text-muted">
|
||||||
|
{tableData.length} records loaded
|
||||||
|
</small>
|
||||||
|
)}
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
{/* Datacenter Selection */}
|
{/* Datacenter Selection */}
|
||||||
@@ -109,41 +182,84 @@ function MainDataTables() {
|
|||||||
isSearchable
|
isSearchable
|
||||||
isLoading={dataCenterStore?.loading}
|
isLoading={dataCenterStore?.loading}
|
||||||
noOptionsMessage={() => t("No data centers available")}
|
noOptionsMessage={() => t("No data centers available")}
|
||||||
|
styles={{
|
||||||
|
menu: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
zIndex: 9999, // Ensure dropdown appears above other elements
|
||||||
|
}),
|
||||||
|
menuPortal: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
zIndex: 9999,
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
menuPortalTarget={document.body} // Render dropdown in body to avoid container overflow
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectedDataCenter ? (
|
{selectedDataCenter ? (
|
||||||
<MaterialReactTable
|
<MaterialReactTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={tableData}
|
data={tableData}
|
||||||
|
// Performance optimizations for large datasets
|
||||||
enableColumnFilters={true}
|
enableColumnFilters={true}
|
||||||
enableFilters={true}
|
enableFilters={true}
|
||||||
enableGlobalFilter={true}
|
enableGlobalFilter={true}
|
||||||
enablePagination={true}
|
enablePagination={true}
|
||||||
enableColumnResizing={true}
|
enableColumnResizing={false} // Disable resizing for better performance
|
||||||
enableStickyHeader={true}
|
enableStickyHeader={true}
|
||||||
muiTableContainerProps={{ sx: { maxHeight: 'calc(100vh - 180px)' } }}
|
enableRowVirtualization={true} // Enable virtualization for large datasets
|
||||||
muiTableProps={{
|
enableColumnVirtualization={false} // Keep columns visible
|
||||||
sx: {
|
// Pagination settings for large datasets
|
||||||
tableLayout: 'auto',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
initialState={{
|
initialState={{
|
||||||
pagination: {
|
pagination: {
|
||||||
pageSize: 100,
|
pageSize: 100, // Reduce page size for better performance
|
||||||
pageIndex: 0
|
pageIndex: 0,
|
||||||
},
|
},
|
||||||
sorting: [
|
sorting: [{ id: "createdDate", desc: true }],
|
||||||
{ id: 'createdDate', desc: true }
|
density: "compact",
|
||||||
],
|
|
||||||
density: 'compact'
|
|
||||||
}}
|
}}
|
||||||
|
// Performance-optimized table props
|
||||||
|
muiTableContainerProps={{
|
||||||
|
sx: {
|
||||||
|
maxHeight: "calc(100vh - 250px)",
|
||||||
|
minHeight: "400px",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
muiTableProps={{
|
||||||
|
sx: {
|
||||||
|
tableLayout: "fixed", // Better performance with fixed layout
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
// Pagination options
|
||||||
|
muiTablePaginationProps={{
|
||||||
|
rowsPerPageOptions: [10, 25, 50, 100],
|
||||||
|
showFirstButton: true,
|
||||||
|
showLastButton: true,
|
||||||
|
}}
|
||||||
|
// Loading and error states
|
||||||
state={{
|
state={{
|
||||||
isLoading: loading,
|
isLoading: loading || mainDataTablesStore?.loading,
|
||||||
showProgressBars: true,
|
showProgressBars: loading || mainDataTablesStore?.loading,
|
||||||
showSkeletons: true,
|
showSkeletons: loading || mainDataTablesStore?.loading,
|
||||||
}}
|
}}
|
||||||
|
// Disable features that can slow down large tables
|
||||||
|
enableRowSelection={false}
|
||||||
|
enableColumnOrdering={false}
|
||||||
|
enableColumnDragging={false}
|
||||||
|
enableDensityToggle={false}
|
||||||
|
enableFullScreenToggle={false}
|
||||||
|
// Custom loading overlay
|
||||||
|
renderProgressBarCell={({ cell }) => (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "20px",
|
||||||
|
backgroundColor: "#f0f0f0",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="p-4 text-center text-muted">
|
<div className="p-4 text-center text-muted">
|
||||||
|
|||||||
Reference in New Issue
Block a user