mixnode datagrid performant

This commit is contained in:
Aid Thompson
2021-11-23 15:20:23 +00:00
parent ab7f24dc1f
commit 58537224df
6 changed files with 184 additions and 79 deletions
@@ -17,6 +17,8 @@ export const CustomColumnHeading: React.FC<{ headingTitle: string }> = ({
fontWeight: 'bold',
fontSize: 14,
padding: 0,
// border: '1px solid red',
// minWidth: 300,
}}
data-testid={headingTitle}
>
@@ -0,0 +1,105 @@
import * as React from 'react';
import { makeStyles } from '@mui/styles';
import {
DataGrid,
GridColDef,
GridColumns,
GridRowModel,
GridSortModel,
useGridApiContext,
useGridState,
} from '@mui/x-data-grid';
import Pagination from '@mui/material/Pagination';
import { SxProps } from '@mui/system';
import { LinearProgress } from '@mui/material';
const useStyles = makeStyles({
root: {
display: 'flex',
},
});
export const cellStyles: SxProps = {
width: '100%',
padding: 0,
maxHeight: 100,
color: 'inherit',
textDecoration: 'none',
fontWeight: 400,
fontSize: 12,
lineHeight: 2,
textAlign: 'start',
wordBreak: 'break-word',
whiteSpace: 'break-spaces',
};
function CustomPagination() {
const apiRef = useGridApiContext();
const [state] = useGridState(apiRef);
const classes = useStyles();
return (
<Pagination
className={classes.root}
sx={{ mt: 2 }}
color="primary"
count={state.pagination.pageCount}
page={state.pagination.page + 1}
onChange={(event, value) => apiRef.current.setPage(value - 1)}
/>
);
}
type DataGridProps = {
columns: GridColDef[];
pagination?: boolean;
hideFooter?: boolean | undefined;
pageSize?: string | undefined;
rows: {
id: number | null;
lastName: string | null;
firstName: string | null;
age: number | null;
}[];
loading?: boolean;
};
export const NewniversalDataGrid: React.FC<DataGridProps> = ({
rows,
columns,
loading,
pagination,
hideFooter,
pageSize,
}) => {
if (loading) return <LinearProgress />;
if (!loading)
return (
<DataGrid
pagination={pagination ? true : undefined}
rows={rows}
components={{
Pagination: CustomPagination,
}}
columns={columns}
pageSize={Number(pageSize)}
rowsPerPageOptions={[5]}
disableSelectionOnClick
autoHeight
hideFooter={hideFooter}
style={{
width: '100%',
border: 'none',
}}
/>
);
return null;
};
NewniversalDataGrid.defaultProps = {
loading: false,
pagination: false,
hideFooter: true,
pageSize: '10',
// sortModel: undefined,
};
+4 -4
View File
@@ -25,7 +25,7 @@ export const TableToolbar: React.FC<TableToolBarProps> = ({
width: '100%',
marginBottom: 2,
display: 'flex',
flexDirection: matches ? 'column' : 'row',
flexDirection: matches ? 'column-reverse' : 'row',
justifyContent: 'space-between',
}}
>
@@ -35,8 +35,8 @@ export const TableToolbar: React.FC<TableToolBarProps> = ({
value={pageSize}
onChange={onChangePageSize}
sx={{
width: 200,
marginBottom: matches ? 2 : 0,
width: matches ? 100 : 200,
// marginBottom: matches ? 2 : 0,
}}
>
<MenuItem value={10} data-testid="ten">
@@ -53,7 +53,7 @@ export const TableToolbar: React.FC<TableToolBarProps> = ({
</MenuItem>
</Select>
<TextField
sx={{ width: 350 }}
sx={{ width: matches ? '100%' : 350, marginBottom: matches ? 2 : 0 }}
value={searchTerm}
data-testid="search-box"
placeholder="search"
+68 -67
View File
@@ -1,21 +1,20 @@
import * as React from 'react';
import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
import { printableCoin } from '@nymproject/nym-validator-client';
import { Button, Grid, Link as MuiLink, Card } from '@mui/material';
import { Link as RRDLink } from 'react-router-dom';
import { Button, Grid, Link as MuiLink } from '@mui/material';
import { SelectChangeEvent } from '@mui/material/Select';
import {
cellStyles,
UniversalDataGrid,
} from 'src/components/Universal-DataGrid';
import { useMainContext } from 'src/context/main';
import { mixnodeToGridRow } from 'src/utils';
import { TableToolbar } from 'src/components/TableToolbar';
import { MixNodeResponse } from 'src/typeDefs/explorer-api';
import { BIG_DIPPER } from 'src/api/constants';
import { ContentCard } from 'src/components/ContentCard';
import { CustomColumnHeading } from 'src/components/CustomColumnHeading';
import { Title } from 'src/components/Title';
import {
NewniversalDataGrid,
cellStyles,
} from 'src/components/Newniversal-DataGrid';
export const PageMixnodes: React.FC = () => {
const { mixnodes } = useMainContext();
@@ -51,8 +50,9 @@ export const PageMixnodes: React.FC = () => {
const columns: GridColDef[] = [
{
field: 'owner',
headerName: 'Owner',
renderHeader: () => <CustomColumnHeading headingTitle="Owner" />,
flex: 3,
width: 380,
headerAlign: 'left',
headerClassName: 'MuiDataGrid-header-override',
renderCell: (params: GridRenderCellParams) => (
@@ -68,10 +68,10 @@ export const PageMixnodes: React.FC = () => {
},
{
field: 'identity_key',
headerName: 'Identity Key',
renderHeader: () => <CustomColumnHeading headingTitle="Identity Key" />,
flex: 3,
width: 380,
headerAlign: 'left',
headerClassName: 'MuiDataGrid-header-override',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={cellStyles}
@@ -86,11 +86,11 @@ export const PageMixnodes: React.FC = () => {
{
field: 'bond',
headerName: 'Bond',
type: 'number',
headerAlign: 'left',
flex: 1,
headerClassName: 'MuiDataGrid-header-override',
renderHeader: () => <CustomColumnHeading headingTitle="Bond" />,
type: 'number',
headerClassName: 'MuiDataGrid-header-override',
width: 150,
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => {
const bondAsPunk = printableCoin({
amount: params.value as string,
@@ -107,44 +107,11 @@ export const PageMixnodes: React.FC = () => {
);
},
},
{
field: 'self_percentage',
headerName: 'Self %',
headerAlign: 'left',
type: 'number',
width: 99,
headerClassName: 'MuiDataGrid-header-override',
renderHeader: () => <CustomColumnHeading headingTitle="Self %" />,
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={cellStyles}
component={RRDLink}
to={`/network-components/mixnodes/${params.row.identity_key}`}
>
{params.value}%
</MuiLink>
),
},
{
field: 'host',
renderHeader: () => <CustomColumnHeading headingTitle="Host" />,
flex: 1,
headerAlign: 'left',
headerClassName: 'MuiDataGrid-header-override',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={cellStyles}
component={RRDLink}
to={`/network-components/mixnodes/${params.row.identity_key}`}
>
{params.value}
</MuiLink>
),
},
{
field: 'location',
headerName: 'Location',
renderHeader: () => <CustomColumnHeading headingTitle="Location" />,
flex: 1,
width: 150,
headerAlign: 'left',
headerClassName: 'MuiDataGrid-header-override',
renderCell: (params: GridRenderCellParams) => (
@@ -157,12 +124,47 @@ export const PageMixnodes: React.FC = () => {
),
},
{
field: 'layer',
headerAlign: 'left',
field: 'self_percentage',
headerName: 'Self %',
width: 110,
headerClassName: 'MuiDataGrid-header-override',
renderHeader: () => <CustomColumnHeading headingTitle="Layer" />,
flex: 1,
renderHeader: () => <CustomColumnHeading headingTitle="Self %" />,
type: 'number',
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={cellStyles}
component={RRDLink}
to={`/network-components/mixnodes/${params.row.identity_key}`}
>
{params.value}%
</MuiLink>
),
},
{
field: 'host',
headerName: 'Host',
renderHeader: () => <CustomColumnHeading headingTitle="Host" />,
headerClassName: 'MuiDataGrid-header-override',
width: 110,
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={cellStyles}
component={RRDLink}
to={`/network-components/mixnodes/${params.row.identity_key}`}
>
{params.value}
</MuiLink>
),
},
{
field: 'layer',
headerName: 'Layer',
renderHeader: () => <CustomColumnHeading headingTitle="Layer" />,
headerClassName: 'MuiDataGrid-header-override',
width: 110,
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={{ ...cellStyles, textAlign: 'left' }}
@@ -182,30 +184,29 @@ export const PageMixnodes: React.FC = () => {
return (
<>
<Title text="Mixnodes" />
<Grid>
<Grid item>
<ContentCard>
<Grid container>
<Grid item xs={12}>
<Card
sx={{
padding: 2,
height: '100%',
// border: '1px solid blue',
}}
>
<TableToolbar
onChangeSearch={handleSearch}
onChangePageSize={handlePageSize}
pageSize={pageSize}
searchTerm={searchTerm}
/>
<UniversalDataGrid
loading={mixnodes?.isLoading}
columnsData={columns}
rows={mixnodeToGridRow(filteredMixnodes)}
pageSize={pageSize}
<NewniversalDataGrid
pagination
rows={mixnodeToGridRow(filteredMixnodes)}
columns={columns}
hideFooter={false}
sortModel={[
{
field: 'bond',
sort: 'desc',
},
]}
pageSize={pageSize}
/>
</ContentCard>
</Card>
</Grid>
</Grid>
</>
+1 -1
View File
@@ -4,7 +4,7 @@
the theme declaration in index.tsx or the style prop
in <DataGrid /> */
.MuiDataGrid-sortIcon {
.MuiDataGrid-sortIcon, .MuiDataGrid-menuIcon {
display: none !important;
}
+4 -7
View File
@@ -65,9 +65,7 @@ export function countryDataToGridRow(
return sorted;
}
export function mixnodeToGridRow(
arrayOfMixnodes: MixNodeResponse,
): MixnodeRowType[] {
export function mixnodeToGridRow(arrayOfMixnodes: MixNodeResponse): any {
return !arrayOfMixnodes
? []
: arrayOfMixnodes.map((mn) => {
@@ -75,16 +73,15 @@ export function mixnodeToGridRow(
const delegations = Number(mn.total_delegation.amount) || 0;
const totalBond = pledge + delegations;
const selfPercentage = ((pledge * 100) / totalBond).toFixed(2);
return {
id: mn.owner,
owner: mn.owner,
location: mn?.location?.country_name || '',
identity_key: mn.mix_node.identity_key || '',
bond: totalBond || 0,
location: mn?.location?.country_name || '',
self_percentage: selfPercentage,
host: mn.mix_node.host || '',
layer: mn.layer || '',
host: mn?.mix_node?.host || '',
layer: mn?.layer || '',
};
});
}