import React, { useCallback, useEffect, useState, useContext, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { Box, useTheme, Checkbox, CircularProgress, Typography, Grid } from '@mui/material'; import { DataGrid, type GridColDef, type GridValidRowModel } from '@mui/x-data-grid'; import { type Coordinator } from '../../models'; import RobotAvatar from '../RobotAvatar'; import { Link, LinkOff } from '@mui/icons-material'; import { AppContext, type UseAppStoreType } from '../../contexts/AppContext'; import { type UseFederationStoreType, FederationContext } from '../../contexts/FederationContext'; import headerStyleFix from '../DataGrid/HeaderFix'; interface FederationTableProps { maxWidth?: number; maxHeight?: number; fillContainer?: boolean; } const FederationTable = ({ maxWidth = 90, maxHeight = 50, fillContainer = false, }: FederationTableProps): JSX.Element => { const { t } = useTranslation(); const { federation, sortedCoordinators, federationUpdatedAt } = useContext(FederationContext); const { setOpen, settings } = useContext(AppContext); const theme = useTheme(); const [pageSize, setPageSize] = useState(0); // all sizes in 'em' const fontSize = theme.typography.fontSize; const verticalHeightFrame = 3.3; const verticalHeightRow = 3.27; const defaultPageSize = Math.max( Math.floor((maxHeight - verticalHeightFrame) / verticalHeightRow), 1, ); const height = defaultPageSize * verticalHeightRow + verticalHeightFrame; const [useDefaultPageSize, setUseDefaultPageSize] = useState(true); useEffect(() => { if (useDefaultPageSize) { setPageSize(defaultPageSize); } }, [federationUpdatedAt]); const localeText = { MuiTablePagination: { labelRowsPerPage: t('Coordinators per page:') }, noResultsOverlayLabel: t('No coordinators found.'), }; const onClickCoordinator = function (shortAlias: string): void { setOpen((open) => { return { ...open, coordinator: shortAlias }; }); }; const aliasObj = useCallback((width: number) => { return { field: 'longAlias', headerName: t('Coordinator'), width: width * fontSize, renderCell: (params: any) => { const coordinator = federation.coordinators[params.row.shortAlias]; return ( { onClickCoordinator(params.row.shortAlias); }} alignItems='center' spacing={1} > {params.row.longAlias} ); }, }; }, []); const enabledObj = useCallback( (width: number) => { return { field: 'enabled', headerName: t('Enabled'), width: width * fontSize, renderCell: (params: any) => { return ( { onEnableChange(params.row.shortAlias); }} /> ); }, }; }, [federationUpdatedAt], ); const upObj = useCallback( (width: number) => { return { field: 'up', headerName: t('Up'), width: width * fontSize, renderCell: (params: any) => { return (
{ onClickCoordinator(params.row.shortAlias); }} > {Boolean(params.row.loadingInfo) && Boolean(params.row.enabled) ? ( ) : params.row.info !== undefined ? ( ) : ( )}
); }, }; }, [federationUpdatedAt], ); const columnSpecs = { alias: { priority: 2, order: 1, normal: { width: 12.1, object: aliasObj, }, }, up: { priority: 3, order: 2, normal: { width: 3.5, object: upObj, }, }, enabled: { priority: 1, order: 3, normal: { width: 5, object: enabledObj, }, }, }; const filteredColumns = function (): { columns: Array>; width: number; } { const useSmall = maxWidth < 30; const selectedColumns: object[] = []; let width: number = 0; for (const value of Object.values(columnSpecs)) { const colWidth = Number( useSmall && Boolean(value.small) ? value.small.width : value.normal.width, ); const colObject = useSmall && Boolean(value.small) ? value.small.object : value.normal.object; if (width + colWidth < maxWidth || selectedColumns.length < 2) { width = width + colWidth; selectedColumns.push([colObject(colWidth, false), value.order]); } else { selectedColumns.push([colObject(colWidth, true), value.order]); } } // sort columns by column.order value selectedColumns.sort(function (first, second) { return first[1] - second[1]; }); const columns: Array> = selectedColumns.map(function (item) { return item[0]; }); return { columns, width: width * 0.9 }; }; const { columns, width } = filteredColumns(); const onEnableChange = function (shortAlias: string): void { if (federation.getCoordinator(shortAlias).enabled === true) { federation.disableCoordinator(shortAlias); } else { federation.enableCoordinator(shortAlias); } }; const reorderedCoordinators = useMemo(() => { return sortedCoordinators.reduce((coordinators, key) => { coordinators[key] = federation.coordinators[key]; return coordinators; }, {}); }, [settings.network, federationUpdatedAt]); return ( params.shortAlias} columns={columns} checkboxSelection={false} pageSize={pageSize} rowsPerPageOptions={width < 22 ? [] : [0, pageSize, defaultPageSize * 2, 50, 100]} onPageSizeChange={(newPageSize) => { setPageSize(newPageSize); setUseDefaultPageSize(false); }} hideFooter={true} /> ); }; export default FederationTable;