Grid.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import { FC, MouseEvent } from 'react';
  2. import React from 'react';
  3. import { makeStyles } from '@material-ui/core/styles';
  4. import Grid from '@material-ui/core/Grid';
  5. import Breadcrumbs from '@material-ui/core/Breadcrumbs';
  6. import TablePagination from '@material-ui/core/TablePagination';
  7. import Typography from '@material-ui/core/Typography';
  8. import CustomToolbar from './ToolBar';
  9. import Table from './Table';
  10. import { AttuGridType } from './Types';
  11. import { useTranslation } from 'react-i18next';
  12. import TablePaginationActions from './TablePaginationActions';
  13. const userStyle = makeStyles(theme => ({
  14. loading: {
  15. height: '100%',
  16. display: 'flex',
  17. alignItems: 'center',
  18. justifyContent: 'center',
  19. padding: theme.spacing(20),
  20. width: '100%',
  21. },
  22. tableTitle: {
  23. '& .last': {
  24. color: 'rgba(0, 0, 0, 0.54)',
  25. },
  26. },
  27. noData: {
  28. pointerEvents: 'none',
  29. color: '#999',
  30. textAlign: 'center',
  31. height: '50vh',
  32. display: 'grid',
  33. justifyContent: 'center',
  34. alignContent: 'center',
  35. fontSize: '32px',
  36. },
  37. pagenation: {
  38. '& .MuiTablePagination-caption': {
  39. position: 'absolute',
  40. left: 0,
  41. bottom: 0,
  42. top: 0,
  43. display: 'flex',
  44. alignItems: 'center',
  45. '& .rows': {
  46. color: 'rgba(0,0,0,0.33)',
  47. marginLeft: theme.spacing(1),
  48. },
  49. },
  50. },
  51. noBottomPadding: {
  52. paddingBottom: '0 !important',
  53. display: 'flex',
  54. flexDirection: 'column',
  55. },
  56. wrapper: {
  57. height: '100%',
  58. },
  59. container: {
  60. flexWrap: 'nowrap',
  61. flexDirection: 'column',
  62. },
  63. }));
  64. /**
  65. *
  66. * @param rowCount required. totoal data count for pagination
  67. * @param rowsPerPage per page for pagination, default is 10
  68. * @param primaryKey required. The unique column for your data. use for checkbox and render key.
  69. * @param onChangePage handle page change
  70. * @param labelDisplayedRows Custom pagination label function, return string;
  71. * @param page current page for pagination
  72. * @param showToolbar control toolbar display. default is false
  73. * @param rows table data you want to render
  74. * @param colDefinitions Define how to render table heder.
  75. * @param isLoading table loading status
  76. * @param title Render breadcrumbs
  77. * @param openCheckBox control checkbox display. default is true
  78. * @param disableSelect disable table row select. default false
  79. * @param noData when table is empty, what tip we need to show.
  80. * @param showHoverStyle control table row hover style display
  81. * @param headEditable if true, user can edit header.
  82. * @param editHeads Only headEditable is true will render editHeads
  83. * @param tableCellMaxWidth Define table cell max width, default is 300
  84. * @param handlesort how to sort table, if it's undefined, then you can not sort table
  85. * @param order 'desc' | 'asc'. sort direction
  86. * @param order order by which table field
  87. * @returns
  88. */
  89. const AttuGrid: FC<AttuGridType> = props => {
  90. const classes = userStyle();
  91. // i18n
  92. const { t: commonTrans } = useTranslation();
  93. const gridTrans = commonTrans('grid');
  94. const {
  95. rowCount = 20,
  96. rowsPerPage = 10,
  97. primaryKey = 'id',
  98. showToolbar = false,
  99. toolbarConfigs = [],
  100. onChangePage = (
  101. e: MouseEvent<HTMLButtonElement> | null,
  102. nextPageNum: number
  103. ) => {
  104. console.log('nextPageNum', nextPageNum);
  105. },
  106. labelDisplayedRows,
  107. page = 0,
  108. rows = [],
  109. colDefinitions = [],
  110. isLoading = false,
  111. title,
  112. openCheckBox = true,
  113. disableSelect = false,
  114. noData = gridTrans.noData,
  115. showHoverStyle = true,
  116. headEditable = false,
  117. editHeads = [],
  118. selected = [],
  119. setSelected = () => {},
  120. setRowsPerPage = () => {},
  121. tableCellMaxWidth,
  122. handleSort,
  123. order,
  124. orderBy,
  125. showPagination = true,
  126. } = props;
  127. const _isSelected = (row: { [x: string]: any }) => {
  128. // console.log("row selected test", row[primaryKey]);
  129. return selected.some((s: any) => s[primaryKey] === row[primaryKey]);
  130. };
  131. const _onSelected = (event: React.MouseEvent, row: { [x: string]: any }) => {
  132. let newSelected: any[] = ([] as any[]).concat(selected);
  133. if (_isSelected(row)) {
  134. newSelected = newSelected.filter(s => s[primaryKey] !== row[primaryKey]);
  135. } else {
  136. newSelected.push(row);
  137. }
  138. setSelected(newSelected);
  139. };
  140. const _onSelectedAll = (event: React.ChangeEvent) => {
  141. if ((event.target as HTMLInputElement).checked) {
  142. const newSelecteds = rows;
  143. setSelected(newSelecteds);
  144. return;
  145. }
  146. setSelected([]);
  147. };
  148. const defaultLabelRows = ({ from = 0, to = 0, count = 0 }) => {
  149. return (
  150. <>
  151. <Typography variant="body2" component="span">
  152. {from} - {to}
  153. </Typography>
  154. <Typography variant="body2" className="rows" component="span">
  155. {gridTrans.of} {count} {gridTrans.rows}
  156. </Typography>
  157. </>
  158. );
  159. };
  160. return (
  161. <Grid
  162. container
  163. classes={{ root: classes.wrapper, container: classes.container }}
  164. spacing={3}
  165. >
  166. {title && (
  167. <Grid item xs={12} className={classes.tableTitle}>
  168. <Breadcrumbs separator="›" aria-label="breadcrumb">
  169. {title.map(
  170. (v: any, i: number) =>
  171. v && (
  172. <Typography
  173. key={v}
  174. className={i === title.length - 1 ? 'last' : ''}
  175. variant="h6"
  176. color="textPrimary"
  177. >
  178. {v}
  179. </Typography>
  180. )
  181. )}
  182. </Breadcrumbs>
  183. </Grid>
  184. )}
  185. {(showToolbar || toolbarConfigs.length > 0) && (
  186. <Grid item>
  187. <CustomToolbar
  188. toolbarConfigs={toolbarConfigs}
  189. selected={selected}
  190. ></CustomToolbar>
  191. </Grid>
  192. )}
  193. <Grid item xs={12} className={classes.noBottomPadding}>
  194. <Table
  195. openCheckBox={openCheckBox}
  196. primaryKey={primaryKey}
  197. rows={rows}
  198. selected={selected}
  199. colDefinitions={colDefinitions}
  200. onSelectedAll={_onSelectedAll}
  201. onSelected={_onSelected}
  202. isSelected={_isSelected}
  203. disableSelect={disableSelect}
  204. noData={noData}
  205. showHoverStyle={showHoverStyle}
  206. isLoading={isLoading}
  207. setPageSize={setRowsPerPage}
  208. headEditable={headEditable}
  209. editHeads={editHeads}
  210. tableCellMaxWidth={tableCellMaxWidth}
  211. handleSort={handleSort}
  212. order={order}
  213. orderBy={orderBy}
  214. ></Table>
  215. {rowCount && showPagination ? (
  216. <TablePagination
  217. component="div"
  218. colSpan={3}
  219. count={rowCount}
  220. page={page}
  221. labelDisplayedRows={labelDisplayedRows || defaultLabelRows}
  222. rowsPerPage={rowsPerPage}
  223. rowsPerPageOptions={[]}
  224. onChangePage={onChangePage}
  225. className={classes.pagenation}
  226. ActionsComponent={TablePaginationActions}
  227. />
  228. ) : null}
  229. </Grid>
  230. </Grid>
  231. );
  232. };
  233. export default AttuGrid;