Pandaaaa906

js_code_with_fault

Dec 14th, 2019
223
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import * as React from 'react';
  2.  
  3. import clsx from 'clsx';
  4. import scrollbarSize from 'dom-helpers/scrollbarSize';
  5. import ScrollSync from "react-virtualized/dist/commonjs/ScrollSync";
  6. import AutoSizer from "react-virtualized/dist/commonjs/AutoSizer";
  7. import {Grid as RVGrid} from "react-virtualized/dist/commonjs/Grid";
  8. import {ContentBox} from "./ContentBox";
  9.  
  10. import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
  11. import FirstPageIcon from '@material-ui/icons/FirstPage';
  12. import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';
  13. import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';
  14. import LastPageIcon from '@material-ui/icons/LastPage';
  15. import produce from "immer";
  16.  
  17. import {
  18.     Button,
  19.     Grid,
  20.     IconButton,
  21.     makeStyles,
  22.     Paper, Table as FTable,
  23.     TableCell, TableFooter, TablePagination, TableRow,
  24.     TextField,
  25.     useTheme,
  26.     withStyles,
  27. } from "@material-ui/core";
  28. import PropTypes from "prop-types";
  29. // import LastPageIcon from "@material-ui/core/SvgIcon/SvgIcon";
  30. import {Component} from "react";
  31. import Popper from "@material-ui/core/Popper";
  32. import Grow from "@material-ui/core/Grow";
  33. import ClickAwayListener from "@material-ui/core/ClickAwayListener";
  34. import MenuList from "@material-ui/core/MenuList";
  35. import MenuItem from "@material-ui/core/MenuItem";
  36. import Checkbox from "@material-ui/core/Checkbox";
  37. import InputLabel from "@material-ui/core/InputLabel";
  38. import Select from "@material-ui/core/Select";
  39.  
  40.  
  41.  
  42. const operators = ["=", "like", "is", ">", ">=", "<", "<=",];
  43. const useStyles1 = theme => ({
  44.     GridRow: {
  45.         position: 'relative',
  46.         // display: 'flex !important',
  47.         flexDirection: 'row !important',
  48.     },
  49.  
  50.     GridColumn: {
  51.         display: 'flex',
  52.         flexDirection: 'column',
  53.         flex: '1 1 auto',
  54.     },
  55.     LeftSideGridContainer: {
  56.         flex: '0 0 75px',
  57.         zIndex: 999,
  58.         display: 'flex',
  59.         backgroundColor: '#fff',
  60.         overflow: 'hidden',
  61.         boxShadow: '1px 0px 2px rgba(0, 0, 0, .2)'
  62.     },
  63.     LeftSideGrid: {
  64.         overflow: 'hidden !important',
  65.         display: 'flex',
  66.         zIndex: 999,
  67.         boxShadow: '1px -1px 2px rgba(0, 0, 0, .2)'
  68.     },
  69.  
  70.     HeaderGrid: {
  71.         width: '100%',
  72.         overflow: 'hidden !important',
  73.         boxShadow: '1px 1px 2px rgba(0, 0, 0, .2)'
  74.     },
  75.  
  76.     BodyGrid: {
  77.         // width: '100%',
  78.     },
  79.     evenRow: {
  80.     },
  81.     oddRow: {
  82.         backgroundColor: 'rgba(0, 0, 0, .1)',
  83.     },
  84.  
  85.     selectedRow: {
  86.         backgroundColor: 'rgba(0,185,255,0.5)'
  87.     },
  88.  
  89.     cell: {
  90.         width: '100%',
  91.         height: '100%',
  92.         display: 'flex',
  93.         flexDirection: 'column',
  94.         justifyContent: 'center',
  95.         alignItems: 'center',
  96.         textAlign: 'center',
  97.         padding: '0 .5em',
  98.         textOverflow: 'ellipsis',
  99.         overflow: 'hidden',
  100.         boxShadow: '1px 0px 2px rgba(0, 0, 0, .2)'
  101.         // whiteSpace: 'nowrap',
  102.     },
  103.     navigator:{
  104.         width: '400px',
  105.     },
  106.  
  107.     headerCell: {
  108.         height: '100%',
  109.         display: 'flex',
  110.         flexDirection: 'column',
  111.         justifyContent: 'center',
  112.         alignItems: 'center',
  113.         textAlign: 'center',
  114.         padding: '0 .5em',
  115.         fontWeight: 'bold',
  116.         boxShadow: '1px 1px 2px rgba(0, 0, 0, .2)'
  117.     },
  118.     leftCell: {
  119.         width: '100%',
  120.         height: '100%',
  121.         display: 'flex',
  122.         flexDirection: 'column',
  123.         justifyContent: 'center',
  124.         alignItems: 'center',
  125.         textAlign: 'center',
  126.         padding: '0 .5em',
  127.         fontWeight: 'bold',
  128.     },
  129.  
  130. });
  131.  
  132. function cellDefaultRenderer(rowData, col){
  133.     const type = col.type || 'text';
  134.     const value = rowData[col.field];
  135.     switch (type){
  136.         case "int":
  137.             return value;
  138.         case "float":
  139.             return value;
  140.         case "date":
  141.             if (value===null){
  142.                     return ;
  143.             }
  144.             const d = new Date(value);
  145.             return d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate();
  146.         case "img":
  147.             return (
  148.                 <div style={{textAlign: 'center', height:"100%", width:"100%"}}>
  149.                     <img src={value}
  150.                          style={{height:"auto", width:"auto", maxHeight:"100%", maxWidth:"100%"}}
  151.                          alt="N/A"
  152.                     />
  153.                 </div>
  154.             );
  155.         case "bool":
  156.             if (value===null){
  157.                 return (<div>N/A</div>)
  158.             }
  159.             return (
  160.                 <Grid container justify={"center"} alignItems={"center"}>
  161.                     <input type='checkbox' defaultChecked={value} disabled={true} />
  162.                 </Grid>
  163.                 );
  164.         default:
  165.             return (
  166.                 <Grid container justify={"center"} alignItems={"center"} title={value} >
  167.                     {value}
  168.                 </Grid>
  169.             );
  170.     }
  171. }
  172.  
  173.  
  174. class HeaderSelectCell extends React.Component {
  175.     render() {
  176.         const { checkboxOnClick } = this.props;
  177.         return (
  178.             <Grid container justify={"center"} alignItems={"center"}>
  179.                 <input type={"checkbox"} onClick={checkboxOnClick}/>
  180.             </Grid>
  181.         )
  182.     }
  183. }
  184.  
  185.  
  186. export class DT_MuiGrid extends Component {
  187.  
  188.     constructor(props, context) {
  189.         super(props, context);
  190.         const {columns, records, rowHeight, selectable} = this.props;
  191.         if (selectable&&columns[0].field!=='selected'){
  192.             columns.unshift({component:HeaderSelectCell, field:'selected', width:50, type:'bool', fixed: true})
  193.         }
  194.         this.columns = columns;
  195.  
  196.         this.fixed_cols = this.columns.filter(obj=>obj.fixed===true);
  197.         this.n_fixed_cols = this.fixed_cols.length;
  198.  
  199.         this.state = {
  200.             columnWidth: 75,
  201.             // height: 400,
  202.             overscanColumnCount: 0,
  203.             overscanRowCount: 5,
  204.             rowHeight: rowHeight,
  205.             rowCount: 100,
  206.             records: records,
  207.             page:0,
  208.         };
  209.     }
  210.  
  211.     render() {
  212.         const {
  213.             // height,
  214.             overscanColumnCount,
  215.             overscanRowCount,
  216.             rowHeight,
  217.         } = this.state;
  218.         const {classes, records}=this.props;
  219.         const rowCount = records.data&&records.data.length||0;
  220.  
  221.         return (
  222.             <div style={{height: "70vh"}}>
  223.                 <AutoSizer disableWidth>
  224.                     {({height})=>(
  225.                         <ContentBox>
  226.                             <ScrollSync>
  227.                                 {({
  228.                                       clientHeight,
  229.                                       clientWidth,
  230.                                       onScroll,
  231.                                       scrollHeight,
  232.                                       scrollLeft,
  233.                                       scrollTop,
  234.                                       scrollWidth,
  235.                                     }) => {
  236.                                     const x = scrollLeft / (scrollWidth - clientWidth);
  237.                                     const y = scrollTop / (scrollHeight - clientHeight);
  238.  
  239.                                     return (
  240.                                         <div className={classes.GridRow}>
  241.                                             <div style={{
  242.                                                 position: 'absolute',
  243.                                                 zIndex: 90,
  244.                                                 background: '#fff',
  245.                                             }}
  246.                                             >
  247.                                                 <div className={classes.LeftSideGridContainer}>
  248.                                                     <RVGrid
  249.                                                         cellRenderer={this._renderLeftHeaderCell}
  250.                                                         className={classes.HeaderGrid}
  251.                                                         width={this._getFixedColumnsWidth()}
  252.                                                         height={rowHeight}
  253.                                                         rowHeight={rowHeight}
  254.                                                         columnWidth={this._getColumnWidth}
  255.                                                         rowCount={1}
  256.                                                         columnCount={this.n_fixed_cols}
  257.                                                     />
  258.                                                 </div>
  259.                                                 <div
  260.                                                     className={classes.LeftSideGrid}
  261.                                                     style={{
  262.                                                         position: 'relate',
  263.                                                         left: 0,
  264.                                                         top: rowHeight,
  265.                                                     }}>
  266.                                                     <RVGrid
  267.                                                         overscanColumnCount={overscanColumnCount}
  268.                                                         overscanRowCount={overscanRowCount}
  269.                                                         cellRenderer={this._renderLeftSideCell}
  270.                                                         columnWidth={this._getColumnWidth}
  271.                                                         columnCount={this.n_fixed_cols}
  272.                                                         className={classes.LeftSideGrid}
  273.                                                         height={height + 1 - rowHeight - scrollbarSize()}
  274.                                                         rowHeight={rowHeight}
  275.                                                         rowCount={rowCount}
  276.                                                         scrollTop={scrollTop}
  277.                                                         width={this._getFixedColumnsWidth()}
  278.                                                     />
  279.                                                 </div>
  280.                                             </div>
  281.                                             <div >
  282.                                                 <div className={classes.GridColumn}>
  283.                                                     <AutoSizer disableHeight>
  284.                                                         {({width}) => (
  285.                                                             <div>
  286.                                                                 <div
  287.                                                                     style={{
  288.                                                                         height: rowHeight,
  289.                                                                         width: width - scrollbarSize(),
  290.                                                                     }}>
  291.                                                                     <RVGrid
  292.                                                                         className={classes.HeaderGrid}
  293.                                                                         columnWidth={this._getColumnWidth}
  294.                                                                         columnCount={this.columns.length}
  295.                                                                         height={rowHeight}
  296.                                                                         overscanColumnCount={overscanColumnCount}
  297.                                                                         cellRenderer={this._renderHeaderCell}
  298.                                                                         rowHeight={rowHeight}
  299.                                                                         rowCount={1}
  300.                                                                         scrollLeft={scrollLeft}
  301.                                                                         width={width - scrollbarSize()}
  302.                                                                     />
  303.                                                                 </div>
  304.                                                                 <div
  305.                                                                     style={{
  306.                                                                         height,
  307.                                                                         width,
  308.                                                                     }}>
  309.                                                                     <RVGrid
  310.                                                                         className={classes.BodyGrid}
  311.                                                                         columnWidth={this._getColumnWidth}
  312.                                                                         columnCount={this.columns.length}
  313.                                                                         height={height-rowHeight}
  314.                                                                         onScroll={onScroll}
  315.                                                                         overscanColumnCount={overscanColumnCount}
  316.                                                                         overscanRowCount={overscanRowCount}
  317.                                                                         cellRenderer={this._renderBodyCell}
  318.                                                                         rowHeight={rowHeight}
  319.                                                                         rowCount={rowCount}
  320.                                                                         width={width}
  321.                                                                     />
  322.                                                                 </div>
  323.                                                             </div>
  324.                                                         )}
  325.                                                     </AutoSizer>
  326.                                                 </div>
  327.                                             </div>
  328.                                         </div>
  329.                                     );
  330.                                 }}
  331.                             </ScrollSync>
  332.                         </ContentBox>
  333.                     )}
  334.                 </AutoSizer>
  335.             </div>
  336.         );
  337.     }
  338.  
  339.  
  340.     _getFixedColumnsWidth = () => {
  341.         const ret = this.fixed_cols.reduce( function(a, b){
  342.             return a + b['width'];
  343.         }, 0);
  344.         return ret
  345.     };
  346.    
  347.     _getColumnWidth = ({index, }) =>{
  348.         const {columns, } = this;
  349.         return columns[index]&&columns[index].width || 120
  350.     };
  351.  
  352.     _renderBodyCell = ({columnIndex, key, rowIndex, style}) => {
  353.         if (columnIndex < this.n_fixed_cols) {
  354.             return;
  355.         }
  356.         return this._renderLeftSideCell({columnIndex, key, rowIndex, style});
  357.     };
  358.  
  359.     _renderHeaderCell = ({columnIndex, key, rowIndex, style}) => {
  360.         if (columnIndex < this.n_fixed_cols) {
  361.             return;
  362.         }
  363.         return this._renderLeftHeaderCell({columnIndex, key, rowIndex, style});
  364.     };
  365.  
  366.     _renderLeftHeaderCell = ({columnIndex, key, style}) => {
  367.         const {classes, clearSelectedRow, nRowSelected} = this.props;
  368.         const col = this.columns[columnIndex];
  369.         let Wrapper = null;
  370.         if (typeof col["component"] === "undefined"){
  371.             Wrapper = ({children})=>(col.label)
  372.         }else{
  373.             const inner = <col.component checkboxOnClick={clearSelectedRow} defaultChecked={nRowSelected>0}/>;
  374.             Wrapper = ({children})=>(inner)
  375.         }
  376.         return (
  377.             <div className={classes.headerCell} key={key} style={style}>
  378.                 <Wrapper/>
  379.             </div>
  380.         );
  381.     };
  382.  
  383.     _onCellClick = (rowIndex) => (event) => {
  384.         const {onRowClick} = this.props;
  385.         onRowClick(rowIndex);
  386.     };
  387.  
  388.     _renderLeftSideCell = ({columnIndex, key, rowIndex, style}) => {
  389.         const {classes, records , onRowClick} = this.props;
  390.         let rowData = records.data&&records.data[rowIndex];
  391.         const rowClass = rowData.selected ? classes.selectedRow :(
  392.             rowIndex % 2 === 0
  393.                 ? classes.oddRow
  394.                 : classes.evenRow);
  395.         const classNames = clsx(rowClass, classes.cell);
  396.         const col = this.columns[columnIndex];
  397.  
  398.         const renderer = col.renderer&&typeof col.renderer==='function'?col.renderer:cellDefaultRenderer;
  399.         return (
  400.             <div className={classNames} key={key} style={style} onClick={this._onCellClick(rowIndex)}>
  401.                 {renderer(rowData, col)}
  402.             </div>
  403.         );
  404.     };
  405.  
  406. }
  407.  
  408. DT_MuiGrid.propTypes = {
  409.     classes: PropTypes.object.isRequired,
  410.     searchForm:PropTypes.object,
  411.     columns: PropTypes.arrayOf(
  412.         PropTypes.shape({
  413.             field: PropTypes.string.isRequired,
  414.             label: PropTypes.string,
  415.             numeric: PropTypes.bool,
  416.             width: PropTypes.number.isRequired,
  417.         }),
  418.     ).isRequired,
  419.     headerHeight: PropTypes.number,
  420.     onRowClick: PropTypes.func,
  421.     rowHeight: PropTypes.number,
  422.     match: PropTypes.object.isRequired,
  423.     selectable: PropTypes.bool,
  424. };
  425.  
  426. const GridExample = withStyles(useStyles1)(DT_MuiGrid);
  427. // export default GridExample;
  428.  
  429.  
  430. function TablePaginationActions(props) {
  431.     const classes = makeStyles(useStyles1)();
  432.     const theme = useTheme();
  433.     const { count, page, rowsPerPage, onChangePage } = props;
  434.  
  435.     function handleFirstPageButtonClick(event) {
  436.         onChangePage(event, 0);
  437.     }
  438.  
  439.     function handleBackButtonClick(event) {
  440.         onChangePage(event, page - 1);
  441.     }
  442.  
  443.     function handleNextButtonClick(event) {
  444.         onChangePage(event, page + 1);
  445.     }
  446.  
  447.     function handleLastPageButtonClick(event) {
  448.         onChangePage(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
  449.     }
  450.  
  451.     return (
  452.         <div className={classes.navigator}>
  453.             <IconButton
  454.                 onClick={handleFirstPageButtonClick}
  455.                 disabled={page === 0}
  456.                 aria-label="first page"
  457.             >
  458.                 {theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
  459.             </IconButton>
  460.             <IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
  461.                 {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
  462.             </IconButton>
  463.             <IconButton
  464.                 onClick={handleNextButtonClick}
  465.                 disabled={page >= Math.ceil(count / rowsPerPage) - 1}
  466.                 aria-label="next page"
  467.             >
  468.                 {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
  469.             </IconButton>
  470.             <IconButton
  471.                 onClick={handleLastPageButtonClick}
  472.                 disabled={page >= Math.ceil(count / rowsPerPage) - 1}
  473.                 aria-label="last page"
  474.             >
  475.                 {theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
  476.             </IconButton>
  477.         </div>
  478.     );
  479. }
  480.  
  481. TablePaginationActions.propTypes = {
  482.     count: PropTypes.number.isRequired,
  483.     onChangePage: PropTypes.func.isRequired,
  484.     page: PropTypes.number.isRequired,
  485.     rowsPerPage: PropTypes.number.isRequired,
  486. };
  487.  
  488. class DT_MuiToolbar extends Component {
  489.  
  490.     constructor(props){
  491.         super(props);
  492.         const {searches} = this.props;
  493.  
  494.         this.anchorRef = null;
  495.         this.state = {
  496.             open:false,
  497.             searches_form:searches.map((col, index)=>(
  498.                 {enabled:false, field:col.field, operator: col.operator, value: ''}
  499.             )),
  500.         };
  501.         this.global_searchValue = "";
  502.     }
  503.  
  504.     form = () => {
  505.         const {searches, } = this.props;
  506.         if (this.global_searchValue){
  507.             return {
  508.                 //TODO set operator according to column type
  509.                 searches:searches
  510.                     .filter((item, index, array)=>(
  511.                         (this.global_searchValue.match(/^[+-]?\d+(\.\d+)?$/) &&
  512.                             (item.type==="int" ||item.type==="float")) || (item.type==="text")
  513.                     ))
  514.                     .map((item, index)=>(
  515.                         {field:item.field, operator: item.operator, value: this.global_searchValue}
  516.                     )),
  517.                 searchLogic:"OR",
  518.             }
  519.         }
  520.         return {
  521.             searches: this.state.searches_form
  522.                 .filter((item, index, array)=>{
  523.                     return item.enabled
  524.                 })
  525.                 .map((item, index)=> {
  526.                     if (item.enabled){
  527.                         return {field:item.field, operator: item.operator, value: item.value}
  528.                     }
  529.                 }),
  530.             searchLogic:"AND",
  531.         }
  532.     };
  533.  
  534.     getsearchForm = () => {
  535.         const {page, rowsPerPage} = this.props;
  536.         return {
  537.             page:page,
  538.             rowsPerPage:rowsPerPage,
  539.             ...this.form(),
  540.         }
  541.     };
  542.  
  543.     refreshData = () => {
  544.         const { recordsSetter, api_url} = this.props;
  545.         const form = this.getsearchForm();
  546.         fetch(api_url, {
  547.             method:"post",
  548.             headers: {'Content-Type':'application/json'},
  549.             body:JSON.stringify(form)
  550.         })
  551.             .then(res => res.json())
  552.             .then(data=>{recordsSetter(data);})
  553.             .catch(err=>(console.log(err)));
  554.     };
  555.  
  556.     handleSearchBtnClick = (event) => {
  557.         event.preventDefault();
  558.         this.refreshData();
  559.     };
  560.  
  561.     componentDidMount(){
  562.         this.refreshData();
  563.     }
  564.  
  565.     componentDidUpdate(prevProps, prevState, snapshot){
  566.         const {page, rowsPerPage} = this.props;
  567.         if (page!==prevProps.page || rowsPerPage!==prevProps.rowsPerPage){
  568.             this.refreshData();
  569.         }
  570.     }
  571.  
  572.     handleInputChange = (event)=>{
  573.         this.global_searchValue = event.target.value;
  574.     };
  575.  
  576.     handleToggle = () => {
  577.         this.setState({open:!this.state.open})
  578.     };
  579.  
  580.     handleClose = (event) => {
  581.         if (this.anchorRef && this.anchorRef.contains(event.target)) {
  582.             return;
  583.         }
  584.         this.setState({open:!this.state.open})
  585.     };
  586.  
  587.     handleCheckBox = index => event => {
  588.         //this.state.searches[index].enabled = event.target.checked;
  589.         const value = event.target.checked;
  590.         this.setState(produce(draft=>{
  591.             draft.searches_form[index].enabled = value;
  592.         }));
  593.     };
  594.  
  595.     handleOperatorSelect = index => event => {
  596.         const value = event.target.value;
  597.         this.setState(produce(draft=>{
  598.             draft.searches_form[index].operator = value;
  599.         }));
  600.     };
  601.  
  602.     handleSearchValue = index => event => {
  603.         const value = event.target.value;
  604.         this.setState(produce(draft=>{
  605.             draft.searches_form[index].value = value;
  606.         }));
  607.     };
  608.  
  609.     render(){
  610.         const { classes, searches, buttons, toolbar} = this.props;
  611.         return (
  612.             <Grid container className={classes.toolbar_form} spacing={1} alignItems="center" style={{padding: "0 10px"}}>
  613.                 <Grid item>
  614.                     <form className={classes.container} noValidate
  615.                           autoComplete="off"
  616.                           onSubmit={this.handleSearchBtnClick}
  617.                     >
  618.                         <TextField
  619.                             id="searchValue"
  620.                             label="Search"
  621.                             className={classes.textField}
  622.                             margin="dense"
  623.                             variant="outlined"
  624.                             placeholder="All Fields"
  625.                             size="small"
  626.                             onChange={this.handleInputChange}
  627.                         />
  628.                     </form>
  629.                 </Grid>
  630.                 <Grid item >
  631.                     <Button
  632.                         className={classes.fab}
  633.                         color="primary"
  634.                         // size="small"
  635.                         aria-owns={this.state.open ? 'menu-list-grow' : undefined}
  636.                         aria-haspopup="true"
  637.                         onClick={this.handleToggle}
  638.                         ref={anchorRef=>{this.anchorRef=anchorRef}}
  639.                     >
  640.                         <ArrowDropDownIcon />
  641.                     </Button>
  642.                     <Popper open={this.state.open}
  643.                             anchorEl={this.anchorRef}
  644.                             transition disablePortal
  645.                             style={{zIndex: 999}}
  646.                     >
  647.                         {({ TransitionProps, placement }) => (
  648.                             <Grow
  649.                                 {...TransitionProps}
  650.                                 style={{transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom' }}
  651.                             >
  652.                                 <Paper style={{overflowY:"scroll", height:'70vh'}}>
  653.                                     <ClickAwayListener onClickAway={this.handleClose}>
  654.                                         <MenuList disableListWrap>
  655.                                             {searches.map((col, index)=>(
  656.                                                 <MenuItem dense disableGutters>
  657.                                                     <Checkbox
  658.                                                         checked={this.state.searches_form[index].enabled}
  659.                                                         onChange={this.handleCheckBox(index)}
  660.                                                     />
  661.                                                     <InputLabel>
  662.                                                         {col.label}
  663.                                                     </InputLabel>
  664.                                                     <Select
  665.                                                         value={this.state.searches_form[index].operator}
  666.                                                         onChange={this.handleOperatorSelect(index)}
  667.                                                     >
  668.                                                         {operators.map((item, index)=>(
  669.                                                             <MenuItem value={item} >{item}</MenuItem>
  670.                                                         ))}
  671.                                                     </Select>
  672.                                                     <TextField
  673.                                                         value={this.state.searches_form[index].value}
  674.                                                         onChange={this.handleSearchValue(index)}
  675.                                                     />
  676.                                                 </MenuItem>
  677.                                             ))}
  678.                                         </MenuList>
  679.                                     </ClickAwayListener>
  680.                                 </Paper>
  681.                             </Grow>
  682.                         )}
  683.                     </Popper>
  684.                 </Grid>
  685.                 <Grid item >
  686.                     <Button variant="contained" className={classes.button} color="primary" onClick={this.handleSearchBtnClick}>
  687.                         Search
  688.                     </Button>
  689.                 </Grid>
  690.                 {buttons.map((item, index)=>(
  691.                     <Grid item>
  692.                         <Button variant="contained" className={classes.button} color="primary" onClick={item.handler}>
  693.                             {item.caption}
  694.                         </Button>
  695.                     </Grid>
  696.                 ))}
  697.                 <Grid item>
  698.                     {React.createElement(toolbar)}
  699.                 </Grid>
  700.             </Grid>
  701.         )
  702.     }
  703. }
  704.  
  705. DT_MuiToolbar.propTypes = {
  706.     classes: PropTypes.object.isRequired,
  707.     api_url: PropTypes.string.isRequired,
  708.     searchForm:PropTypes.object,
  709.     columns: PropTypes.arrayOf(
  710.         PropTypes.shape({
  711.             field: PropTypes.string.isRequired,
  712.             label: PropTypes.string,
  713.             numeric: PropTypes.bool,
  714.             width: PropTypes.number.isRequired,
  715.         }),
  716.     ).isRequired,
  717.     searches:PropTypes.arrayOf(
  718.         PropTypes.shape({
  719.             field: PropTypes.string.isRequired,
  720.             label: PropTypes.string.isRequired,
  721.             type: PropTypes.string,
  722.             width: PropTypes.number.isRequired,
  723.         }),
  724.     ),
  725.     fixed_searches: PropTypes.arrayOf(
  726.         PropTypes.shape(PropTypes.object),
  727.     ),
  728.     recordsSetter: PropTypes.func.isRequired,
  729.     headerHeight: PropTypes.number,
  730.     page: PropTypes.number.isRequired,
  731.     rowsPerPage: PropTypes.number.isRequired,
  732.     rowHeight: PropTypes.number,
  733. };
  734.  
  735. const DT_Toolbar = withStyles(useStyles1)(DT_MuiToolbar);
  736.  
  737.  
  738. export class MuiDynamicTable extends Component{
  739.     constructor(props){
  740.         super(props);
  741.         const {settings, } = this.props;
  742.         //TODO FetchSetting
  743.         // setting start
  744.         this.api_url = settings.api_url;
  745.         this.columns = settings.columns;
  746.         this.searches = settings.searches;
  747.         this.rowsPerPageOptions = settings.rowsPerPageOptions;
  748.         this.rowsPerPage = settings.rowsPerPage;
  749.         this.buttons = settings.buttons;
  750.         this.toolbar = settings.toolbar;
  751.         this.rowHeight = settings.rowHeight||120;
  752.         this.selectable = settings.selectable;
  753.  
  754.         this.state = {
  755.             records:{},
  756.             page:0,
  757.             nRowSelected:0,
  758.         };
  759.     }
  760.  
  761.     handleChangePage = (event, newPage) => {
  762.         this.setState({page: newPage});
  763.     };
  764.  
  765.     setrowsPerPage = (value) => {
  766.         this.rowsPerPage = value;
  767.     };
  768.  
  769.     handleChangeRowsPerPage = (event) => {
  770.         const value = event.target.value;
  771.         this.setrowsPerPage(parseInt(value, 0));
  772.         this.setState({page: 0});
  773.     };
  774.  
  775.     // TODO
  776.     onRowClick = (rowIndex) => {
  777.         this.setState(produce(draftState=>{
  778.             const rowData = draftState.records.data[rowIndex];
  779.             if (typeof rowData["selected"] === "undefined"){
  780.                 rowData.selected = false
  781.             }
  782.             if (rowData.selected){
  783.                 draftState.nRowSelected--
  784.             }else{
  785.                 draftState.nRowSelected++
  786.             }
  787.             rowData.selected = !rowData.selected;
  788.         }));
  789.         // this.setState({nRowSelected: this.state.nRowSelected+1});
  790.         this.forceUpdate();
  791.     };
  792.  
  793.     // TODO
  794.     clearSelectedRow = (event) => {
  795.         this.setState(produce ((draft)=>{
  796.             for (let i=0; i<draft.records.data.length; i++){
  797.                 draft.records.data[i].selected = false
  798.             }
  799.         }));
  800.     };
  801.  
  802.     render(){
  803.         const {classes, match} = this.props;
  804.         return(
  805.                 <Paper style={{ height: '100%', width: '100%' }}>
  806.                     <DT_Toolbar
  807.                         recordsSetter={(newRecords)=>(this.setState({records:newRecords}))}
  808.                         page={this.state.page}
  809.                         rowsPerPage={this.rowsPerPage}
  810.                         api_url = {this.api_url}
  811.                         columns = {this.columns}
  812.                         searches = {this.searches}
  813.                         buttons = {this.buttons||[]}
  814.                         toolbar = {this.toolbar}
  815.                     />
  816.                     <GridExample
  817.                         columns={this.columns}
  818.                         records={this.state.records}
  819.                         onRowClick={this.onRowClick}
  820.                         match={match}
  821.                         rowHeight={this.rowHeight}
  822.                         selectable={this.selectable}
  823.                         clearSelectedRow={this.clearSelectedRow}
  824.                         nRowSelected={this.state.nRowSelected}
  825.                     />
  826.                     <div style={{display:"block"}}>
  827.                         <FTable className={classes.table}>
  828.                             <TableFooter>
  829.                                 <TableRow>
  830.                                     <TablePagination
  831.                                         rowsPerPageOptions={this.rowsPerPageOptions}
  832.                                         colSpan={3}
  833.                                         count={this.state.records.total||0}
  834.                                         rowsPerPage={this.rowsPerPage}
  835.                                         page={this.state.records.page||0}
  836.                                         SelectProps={{
  837.                                             inputProps: { 'aria-label': 'rows per page' },
  838.                                             native: true,
  839.                                         }}
  840.                                         onChangePage={this.handleChangePage}
  841.                                         onChangeRowsPerPage={this.handleChangeRowsPerPage}
  842.                                         ActionsComponent={TablePaginationActions}
  843.                                     />
  844.                                 </TableRow>
  845.                             </TableFooter>
  846.                         </FTable>
  847.                     </div>
  848.  
  849.                 </Paper>
  850.         )}
  851. }
  852.  
  853. MuiDynamicTable.propTypes = {
  854.     classes: PropTypes.object.isRequired,
  855.     setting_url: PropTypes.string,
  856.     match: PropTypes.object.isRequired,
  857.     settings: PropTypes.object.isRequired,
  858. };
  859.  
  860.  
  861. const DynamicTable = withStyles(useStyles1)(MuiDynamicTable);
  862. export default DynamicTable;
RAW Paste Data