import { FC } from 'react';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableRow from '@mui/material/TableRow';
import Checkbox from '@mui/material/Checkbox';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
import EnhancedTableHead from './TableHead';
import EditableTableHead from './TableEditableHead';
import ActionBar from './ActionBar';
import LoadingTable from './LoadingTable';
import CopyButton from '../advancedSearch/CopyButton';
import type { Theme } from '@mui/material/styles';
import type { TableType } from './Types';
/**
* Enhanced Table Component
*
* Usage example with spacer column:
*
*
* The spacer column will:
* - Have width: 'auto' and minWidth: 'auto'
* - Display no content
* - Naturally absorb remaining horizontal space without forcing table width
* - Prevent unnecessary horizontal scrollbars
*/
const EnhancedTable: FC = props => {
let {
selected,
onSelected,
isSelected,
onSelectedAll,
rows = [],
colDefinitions,
primaryKey,
// whether show checkbox in the first column
// set true as default
openCheckBox = true,
disableSelect,
noData,
// whether change table row background color when mouse hover
// set true as default
showHoverStyle = true,
isLoading,
headEditable = false,
// editable heads required param, contains heads components and its value
editHeads = [],
// if table cell max width not be passed, table row will use 300px as default
tableCellMaxWidth = '300px',
handleSort,
order,
orderBy,
rowDecorator = () => ({}),
rowHeight,
// whether to add a spacer column to control space distribution
addSpacerColumn = false,
} = props;
const hasData = rows && rows.length > 0;
// Add spacer column definition if needed
const finalColDefinitions = addSpacerColumn
? [
...colDefinitions,
{
id: '__spacer__',
align: 'left' as const,
disablePadding: false,
label: '',
getStyle: () => ({
width: '66.7%',
minWidth: 'auto',
}),
formatter: () => null,
},
]
: colDefinitions;
return (
({
width: '100%',
flexGrow: 1,
color: theme.palette.text.primary,
backgroundColor: theme.palette.background.paper,
})}
>
{!headEditable ? (
) : (
)}
{!isLoading ? (
{hasData ? (
rows.map((row, index) => {
const isItemSelected = isSelected(row);
const labelId = `enhanced-table-checkbox-${index}`;
return (
onSelected(event, row)}
aria-checked={isItemSelected}
tabIndex={-1}
selected={isItemSelected && !disableSelect}
sx={
[
showHoverStyle && {
'&:hover': {
'& td': {
background: 'inherit',
},
'& .hoverActionCell': {
'& span': {
opacity: 1,
},
},
},
},
isItemSelected &&
!disableSelect && {
'& td': {
background: 'inherit',
},
},
rowDecorator(row),
].filter(Boolean) as any
}
>
{openCheckBox && (
({
width: '38px',
borderBottom: `1px solid ${theme.palette.divider}`,
})}
>
)}
{finalColDefinitions.map((colDef, i) => {
const { actionBarConfigs = [], needCopy = false } =
colDef;
const cellStyleFromDef = colDef.getStyle
? colDef.getStyle(row[colDef.id])
: {};
// Skip rendering for spacer column
if (colDef.id === '__spacer__') {
return (
({
borderBottom: `1px solid ${theme.palette.divider}`,
}),
cellStyleFromDef,
]}
>
{/* Empty content for spacer column */}
);
}
return colDef.showActionCell ? (
({
borderBottom: `1px solid ${theme.palette.divider}`,
'& p': {
display: 'inline-block',
verticalAlign: 'middle',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
maxWidth: tableCellMaxWidth,
},
}),
(theme: Theme) => ({
padding: theme.spacing(1, 1.5),
}),
colDef.isHoverAction && {
transition: '0.2s all',
padding: 0,
width: '50px',
'& span': {
opacity: 0,
},
},
cellStyleFromDef,
].filter(Boolean) as any
}
className={
colDef.isHoverAction ? 'hoverActionCell' : ''
} // Keep class for targeting in rowHoverStyles
key={colDef.id}
>
) : (
({
overflow: 'hidden',
borderBottom: `1px solid ${theme.palette.divider}`,
'& p': {
display: 'inline-block',
verticalAlign: 'middle',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
maxWidth: tableCellMaxWidth,
},
}),
(theme: Theme) => ({
padding: theme.spacing(1),
}),
cellStyleFromDef,
].filter(Boolean) as any
}
>
{typeof row[colDef.id] !== 'undefined' && (
<>
{colDef.formatter ? (
colDef.onClick ? (
) : (
{colDef.formatter(
row,
row[colDef.id],
i
)}
)
) : colDef.onClick ? (
) : (
{row[colDef.id]}
)}
{needCopy && (
({
'& svg': {
fontSize: '13px',
},
marginLeft: theme.spacing(0.5),
})}
/>
)}
>
)}
);
})}
);
})
) : (
({
paddingTop: theme.spacing(6),
textAlign: 'center',
letterSpacing: '0.5px',
color: theme.palette.text.secondary,
})}
colSpan={
openCheckBox
? finalColDefinitions.length + 1
: finalColDefinitions.length
}
>
{noData}
)}
) : (
({
paddingTop: theme.spacing(6),
textAlign: 'center',
letterSpacing: '0.5px',
color: theme.palette.text.secondary,
})}
colSpan={
openCheckBox
? finalColDefinitions.length + 1
: finalColDefinitions.length
}
>
)}
);
};
export default EnhancedTable;