Browse Source

add MkTable

PhyoThandar 3 years ago
parent
commit
eb841ee4c3

+ 95 - 66
example/package-lock.json

@@ -56,6 +56,7 @@
         "@material-ui/icons": "^4.11.2",
         "@material-ui/lab": "^4.0.0-alpha.58",
         "create-react-library": "^3.1.1",
+        "react-redux": "^7.2.4",
         "react-router-dom": "^5.2.0"
       },
       "dependencies": {
@@ -14657,12 +14658,7 @@
         },
         "react": {
           "version": "file:https:/registry.npmjs.org/react/-/react-16.14.0.tgz",
-          "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
-          "requires": {
-            "loose-envify": "^1.1.0",
-            "object-assign": "^4.1.1",
-            "prop-types": "^15.6.2"
-          }
+          "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g=="
         },
         "react-app-polyfill": {
           "version": "1.0.6",
@@ -15123,13 +15119,7 @@
         },
         "react-dom": {
           "version": "file:https:/registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz",
-          "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==",
-          "requires": {
-            "loose-envify": "^1.1.0",
-            "object-assign": "^4.1.1",
-            "prop-types": "^15.6.2",
-            "scheduler": "^0.19.1"
-          }
+          "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw=="
         },
         "react-error-overlay": {
           "version": "6.0.8",
@@ -15143,56 +15133,7 @@
         },
         "react-scripts": {
           "version": "file:https:/registry.npmjs.org/react-scripts/-/react-scripts-3.4.4.tgz",
-          "integrity": "sha512-7J7GZyF/QvZkKAZLneiOIhHozvOMHey7hO9cdO9u68jjhGZlI8hDdOm6UyuHofn6Ajc9Uji5I6Psm/nKNuWdyw==",
-          "requires": {
-            "@svgr/webpack": "4.3.3",
-            "@typescript-eslint/eslint-plugin": "^2.10.0",
-            "@typescript-eslint/parser": "^2.10.0",
-            "babel-eslint": "10.1.0",
-            "babel-jest": "^24.9.0",
-            "babel-loader": "8.1.0",
-            "babel-plugin-named-asset-import": "^0.3.6",
-            "babel-preset-react-app": "^9.1.2",
-            "camelcase": "^5.3.1",
-            "case-sensitive-paths-webpack-plugin": "2.3.0",
-            "css-loader": "3.4.2",
-            "dotenv": "8.2.0",
-            "dotenv-expand": "5.1.0",
-            "eslint": "^6.6.0",
-            "eslint-config-react-app": "^5.2.1",
-            "eslint-loader": "3.0.3",
-            "eslint-plugin-flowtype": "4.6.0",
-            "eslint-plugin-jsx-a11y": "6.2.3",
-            "eslint-plugin-react-hooks": "^1.6.1",
-            "file-loader": "4.3.0",
-            "fs-extra": "^8.1.0",
-            "html-webpack-plugin": "4.0.0-beta.11",
-            "identity-obj-proxy": "3.0.0",
-            "jest": "24.9.0",
-            "jest-environment-jsdom-fourteen": "1.0.1",
-            "jest-resolve": "24.9.0",
-            "jest-watch-typeahead": "0.4.2",
-            "mini-css-extract-plugin": "0.9.0",
-            "optimize-css-assets-webpack-plugin": "5.0.3",
-            "pnp-webpack-plugin": "1.6.4",
-            "postcss-flexbugs-fixes": "4.1.0",
-            "postcss-loader": "3.0.0",
-            "postcss-normalize": "8.0.1",
-            "postcss-preset-env": "6.7.0",
-            "postcss-safe-parser": "4.0.1",
-            "react-app-polyfill": "^1.0.6",
-            "react-dev-utils": "^10.2.1",
-            "resolve-url-loader": "3.1.2",
-            "sass-loader": "8.0.2",
-            "style-loader": "0.23.1",
-            "terser-webpack-plugin": "2.3.8",
-            "ts-pnp": "1.1.6",
-            "url-loader": "2.3.0",
-            "webpack": "4.42.0",
-            "webpack-dev-server": "3.11.0",
-            "webpack-manifest-plugin": "2.2.0",
-            "workbox-webpack-plugin": "4.3.1"
-          }
+          "integrity": "sha512-7J7GZyF/QvZkKAZLneiOIhHozvOMHey7hO9cdO9u68jjhGZlI8hDdOm6UyuHofn6Ajc9Uji5I6Psm/nKNuWdyw=="
         },
         "react-transition-group": {
           "version": "4.4.1",
@@ -19399,11 +19340,71 @@
         }
       }
     },
+    "@types/hoist-non-react-statics": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+      "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
+      "requires": {
+        "@types/react": "*",
+        "hoist-non-react-statics": "^3.3.0"
+      }
+    },
+    "@types/prop-types": {
+      "version": "15.7.3",
+      "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
+      "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
+    },
+    "@types/react": {
+      "version": "17.0.6",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.6.tgz",
+      "integrity": "sha512-u/TtPoF/hrvb63LdukET6ncaplYsvCvmkceasx8oG84/ZCsoLxz9Z/raPBP4lTAiWW1Jb889Y9svHmv8R26dWw==",
+      "requires": {
+        "@types/prop-types": "*",
+        "@types/scheduler": "*",
+        "csstype": "^3.0.2"
+      }
+    },
+    "@types/react-redux": {
+      "version": "7.1.16",
+      "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz",
+      "integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==",
+      "requires": {
+        "@types/hoist-non-react-statics": "^3.3.0",
+        "@types/react": "*",
+        "hoist-non-react-statics": "^3.3.0",
+        "redux": "^4.0.0"
+      }
+    },
+    "@types/scheduler": {
+      "version": "0.16.1",
+      "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
+      "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA=="
+    },
     "clsx": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
       "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
     },
+    "csstype": {
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz",
+      "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw=="
+    },
+    "hoist-non-react-statics": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+      "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+      "requires": {
+        "react-is": "^16.7.0"
+      },
+      "dependencies": {
+        "react-is": {
+          "version": "16.13.1",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+          "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+        }
+      }
+    },
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -19542,6 +19543,26 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
       "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
     },
+    "react-redux": {
+      "version": "7.2.4",
+      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz",
+      "integrity": "sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA==",
+      "requires": {
+        "@babel/runtime": "^7.12.1",
+        "@types/react-redux": "^7.1.16",
+        "hoist-non-react-statics": "^3.3.2",
+        "loose-envify": "^1.4.0",
+        "prop-types": "^15.7.2",
+        "react-is": "^16.13.1"
+      },
+      "dependencies": {
+        "react-is": {
+          "version": "16.13.1",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+          "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+        }
+      }
+    },
     "react-router-dom": {
       "version": "file:../node_modules/react-router-dom",
       "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
@@ -24185,9 +24206,9 @@
           "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
         },
         "electron-to-chromium": {
-          "version": "1.3.730",
-          "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.730.tgz",
-          "integrity": "sha512-1Tr3h09wXhmqXnvDyrRe6MFgTeU0ZXy3+rMJWTrOHh/HNesWwBBrKnMxRJWZ86dzs8qQdw2c7ZE1/qeGHygImA=="
+          "version": "1.3.732",
+          "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz",
+          "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw=="
         },
         "elliptic": {
           "version": "6.5.4",
@@ -33103,6 +33124,14 @@
         }
       }
     },
+    "redux": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz",
+      "integrity": "sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==",
+      "requires": {
+        "@babel/runtime": "^7.9.2"
+      }
+    },
     "regenerator-runtime": {
       "version": "0.13.7",
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",

+ 1 - 1
example/src/App.js

@@ -7,7 +7,7 @@ import EditIcon from '@material-ui/icons/Edit';
 import DeleteIcon from '@material-ui/icons/Delete';
 import SaveIcon from '@material-ui/icons/Save';
 import CancelIcon from '@material-ui/icons/Cancel';
-import ResponsiveDrawer from './ResponsiveDrawer';
+import ResponsiveDrawer from './components/ResponsiveDrawer';
 
 const App = () => {
   const pediatricians = [

+ 0 - 0
example/src/MkFormPage.js → example/src/components/MkFormPage.js


+ 93 - 0
example/src/components/MkTablePage.js

@@ -0,0 +1,93 @@
+import React from 'react'
+import { MkTable } from '@mokkon/reactjs'
+import '@mokkon/reactjs/dist/index.css';
+// import { connect, useSelector } from 'react-redux';
+
+const MkTablePage = (props) => {
+  // const [page, setPage] = useSelector(0);
+  // const [rowPerPage, setRowPerPage] = useSelector(10);
+
+  const data = {
+    delete_time: 0,
+    name: "Vendor 13",
+    address: "address",
+    id: 'qwerty',
+    update_time: 1610341578878,
+    updated_by: "Nine Nine",
+    updated_by_id: "kShMtHkcwTNjwm-lfzSBvAzdSo1J8dIpAz6_Ct85HPg",
+    // status: 'joined'
+  }
+
+  const _data = {
+    delete_time: 0,
+    id: 'asdfg',
+    name: "Vendor",
+    address: "address",
+    update_time: 1610341578878,
+    updated_by: "Nine Nine",
+    updated_by_id: "kShMtHkcwTNjwm-lfzSBvAzdSo1J8dIpAz6_Ct85HPg",
+    // status: 'joined'
+  }
+
+  const headCells = [
+    { id: 'sr', numeric: true, disablePadding: false, label: 'No.', width: '15px' },
+    { id: 'name', numeric: false, disablePadding: false, label: 'Name', width: '15px' },
+  ];
+
+  const handleUpdate = (data) => {
+    console.log('update data :', data);
+  }
+
+  const handleDelete = (e, data) => {
+    console.log('delete data :', data);
+  }
+
+  const handleSave = (e, data) => {
+    console.log('save data :', data);
+  }
+
+  const handleCancel = (e, data) => {
+    console.log('cancel data :', data);
+  }
+
+  const handleOnActions = (data) => {
+    console.log('handleOnActions :', data);
+  }
+
+  const handleChangePaginatePage = (v) => {
+    // setPage(v);
+    console.log('handleOnActions :', data);
+  }
+
+  const handleRowPerPage = (v) => {
+    // setRowPerPage(v);
+    console.log('handleOnActions :', data);
+  }
+
+  var tableData = [data, _data, data, _data, data, _data, data, _data, data, _data, data, _data];
+
+  return <div>
+    <div className="root">
+      {/*table template */}
+      <div className="listContainer">
+        <MkTable
+          headers={headCells}
+          data={tableData}
+          page={0}
+          rowsPerPage={10}
+          order={'asc'}
+          orderBy={'name'}
+          // onUpdateData={(value, data) => console.log('table update data')}
+          // onReloadData={() => console.log('table reload data')}
+          // onChangeRowsPerPage={(v) => console.log('table change row per page')}
+          // onChangePage={(page) => console.log('table change page')}
+          onUpdateDataRow={() => { }}
+          onChangePaginatePage={(newPage) => { handleChangePaginatePage(newPage) }}
+          onGetData={() => { }}
+          onChangeRowPerPage={(rowPerPage) => { handleRowPerPage(rowPerPage) }}
+        ></MkTable>
+      </div>
+    </div>  </div>
+}
+
+export default (MkTablePage);

+ 2 - 0
example/src/ResponsiveDrawer.js → example/src/components/ResponsiveDrawer.js

@@ -20,6 +20,7 @@ import MkFormPage from './MkFormPage';
 import { Route, Router, Switch } from 'react-router-dom';
 import WelcomPage from './WelcomPage';
 import { createBrowserHistory } from 'history';
+import MkTablePage from './MkTablePage';
 
 const browserHistory = createBrowserHistory();
 
@@ -154,6 +155,7 @@ function ResponsiveDrawer(props) {
           <Switch>
             <Route path="/" component={WelcomPage} exact />
             <Route path="/MkForm" component={MkFormPage} />
+            <Route path="/MkTable" component={MkTablePage} />
           </Switch>
         </Router>
       </main>

+ 0 - 0
example/src/WelcomPage.js → example/src/components/WelcomPage.js


+ 6 - 1
example/src/index.js

@@ -3,5 +3,10 @@ import './index.css'
 import React from 'react'
 import ReactDOM from 'react-dom'
 import App from './App'
+import { Provider } from 'react-redux'
+// import configureStore from './store'
+// const store = configureStore();
 
-ReactDOM.render(<App />, document.getElementById('root'))
+ReactDOM.render(
+        <App />
+    , document.getElementById('root'))

+ 0 - 0
example/src/reducers/app.js


+ 12 - 0
example/src/store.js

@@ -0,0 +1,12 @@
+
+import { createStore, applyMiddleware } from "redux";
+import thunk from 'redux-thunk'
+import allReducers from './reducers'
+
+export default function configureStore() {
+    const store = createStore(
+        allReducers,
+        applyMiddleware(thunk)
+    );
+    return store;
+}

+ 1 - 0
package.json

@@ -55,6 +55,7 @@
     "@material-ui/icons": "^4.11.2",
     "@material-ui/lab": "^4.0.0-alpha.58",
     "create-react-library": "^3.1.1",
+    "react-redux": "^7.2.4",
     "react-router-dom": "^5.2.0"
   }
 }

+ 3 - 3
src/InfoPage/InfoPage.js → src/MkInfo/MkInfo.js

@@ -63,7 +63,7 @@ function getDataString(data, fieldName) {
 }
 
 
-function InfoPage(props) {
+function MkInfo(props) {
     const classes = useStyles();
     const {
         infoData,
@@ -215,7 +215,7 @@ function InfoPage(props) {
     );
 }
 
-InfoPage.propTypes = {
+MkInfo.propTypes = {
     history: PropTypes.object,
     infoData: PropTypes.object,
     displayFields: PropTypes.array,
@@ -224,4 +224,4 @@ InfoPage.propTypes = {
     actions: PropTypes.any
 };
 
-export default (InfoPage);
+export default (MkInfo);

+ 0 - 0
src/InfoPage/index.js → src/MkInfo/index.js


+ 548 - 0
src/MkTable/MkTable.js

@@ -0,0 +1,548 @@
+import React, { useEffect } from 'react';
+import PropTypes from 'prop-types';
+import { makeStyles } from '@material-ui/core/styles';
+import Table from '@material-ui/core/Table';
+import TableBody from '@material-ui/core/TableBody';
+import TableCell from '@material-ui/core/TableCell';
+import TableContainer from '@material-ui/core/TableContainer';
+import TableHead from '@material-ui/core/TableHead';
+import TablePagination from '@material-ui/core/TablePagination';
+import TableRow from '@material-ui/core/TableRow';
+import TableSortLabel from '@material-ui/core/TableSortLabel';
+import Typography from '@material-ui/core/Typography';
+import EditIcon from '@material-ui/icons/Edit';
+import { Grid, IconButton } from '@material-ui/core';
+import CircularProgress from '@material-ui/core/CircularProgress';
+// import { connect, useSelector } from 'react-redux';
+import { withStyles } from '@material-ui/core/styles';
+// import { changePaginatePage, changeRowPerPage, getDataRecords, refreshRecord } from '../actions/app';
+// import RowMenu from './RowMenu';
+// import ConfirmDialog from './ConfirmDialog';
+
+function descendingComparator(a, b, _orderBy) {
+    if (b[_orderBy] < a[_orderBy]) {
+        return -1;
+    }
+    if (b[_orderBy] > a[_orderBy]) {
+        return 1;
+    }
+    return 0;
+}
+
+function getComparator(_order, _orderBy) {
+    return _order === 'desc'
+        ? (a, b) => descendingComparator(a, b, _orderBy)
+        : (a, b) => -descendingComparator(a, b, _orderBy);
+}
+
+function stableSort(array, comparator) {
+    const stabilizedThis = array.map((el, index) => [el, index]);
+    stabilizedThis.sort((a, b) => {
+        const _order = comparator(a[0], b[0]);
+        if (_order !== 0) return _order;
+        return a[1] - b[1];
+    });
+    return stabilizedThis.map((el) => el[0]);
+}
+
+const StyledTableCell = withStyles((theme) => ({
+    head: {
+        backgroundColor: '#0d47a1a8',
+        color: theme.palette.common.white,
+    },
+    body: {
+        fontSize: 14,
+    },
+}))(TableCell);
+
+
+function EnhancedTableHead(props) {
+    const { classes, _order, _orderBy, onRequestSort, headCells, dispatch, query } = props;
+    const createSortHandler = (property) => (event) => {
+        onRequestSort(event, property);
+        // dispatch(refreshRecord());
+        // dispatch(getDataRecords(query));
+    };
+
+    return (
+        <TableHead>
+            <TableRow>
+                {headCells.map((headCell) => (
+                    <StyledTableCell
+                        key={headCell.id}
+                        align={headCell.numeric ? 'right' : 'left'}
+                        padding={headCell.disablePadding ? 'none' : 'default'}
+                        sortDirection={_orderBy === headCell.id ? _order : false}
+                        style={{ width: headCell.id === 'sr' ? '15px' : headCell.width ? headCell.width : '' }}
+                    >
+                        {headCell.id !== 'sr' ?
+                            <TableSortLabel
+                                active={_orderBy === headCell.id}
+                                direction={_orderBy === headCell.id ? _order : 'asc'}
+                                onClick={createSortHandler(headCell.id)}
+                                style={{ whiteSpace: "nowrap" }}
+                            >
+                                {headCell.label}
+                                {_orderBy === headCell.id ? (
+                                    <span className={classes.visuallyHidden}>
+                                        {_order === 'desc' ? 'sorted descending' : 'sorted ascending'}
+                                    </span>
+                                ) : null}
+                            </TableSortLabel>
+                            : <TableSortLabel
+                                hideSortIcon={true}
+                                align="right"
+                            >
+                                {headCell.label}
+
+                            </TableSortLabel>
+                        }
+
+                    </StyledTableCell>
+                ))}
+                <StyledTableCell style={{ width: '150px' }} />
+
+            </TableRow>
+        </TableHead>
+    );
+}
+
+EnhancedTableHead.propTypes = {
+    classes: PropTypes.object.isRequired,
+    onRequestSort: PropTypes.func.isRequired,
+    onSelectAllClick: PropTypes.func.isRequired,
+    _order: PropTypes.oneOf(['asc', 'desc']).isRequired,
+    _orderBy: PropTypes.string.isRequired,
+    rowCount: PropTypes.number.isRequired,
+};
+
+const useStyles = makeStyles((theme) => ({
+    root: {
+        width: '100%',
+    },
+    paper: {
+        width: '100%',
+        marginBottom: theme.spacing(2),
+    },
+    table: {
+        // minWidth: 750,
+        tableLayout: 'fixed'
+    },
+    visuallyHidden: {
+        b_order: 0,
+        clip: 'rect(0 0 0 0)',
+        height: 1,
+        margin: -1,
+        overflow: 'hidden',
+        padding: 0,
+        position: 'absolute',
+        top: 20,
+        width: 1,
+    },
+    underline: {
+        "&&&:before": {
+            b_orderBottom: "none"
+        },
+        "&&:after": {
+            b_orderBottom: "none"
+        }
+    },
+    bomLink: {
+        cursor: "pointer",
+        color: theme.primary,
+        textDecoration: "underline",
+    }
+}));
+
+const StyledTableRow = withStyles((theme) => ({
+    root: {
+        '&:nth-of-type(even)': {
+            backgroundColor: '#0d47a11c',
+        },
+    },
+}))(TableRow);
+
+function getUpdatedDate(p) {
+    var statusDate = p['updated_date'];
+    var day = '';
+    if (statusDate !== undefined) {
+        var convertDate = new Date(statusDate.toDate());
+        var dd = String(convertDate.getDate()).padStart(2, '0');
+        var mm = String(convertDate.getMonth() + 1).padStart(2, '0'); //January is 0!
+        var yyyy = convertDate.getFullYear();
+
+        day = mm + '/' + dd + '/' + yyyy;
+    }
+
+    return day.toString();
+}
+
+export const formatDateToLocal = (date, withTime = true) => {
+    if (!date) return "";
+    var d = new Date(date);
+    var ampm = d.getHours() >= 12 ? 'PM' : 'AM';
+    var hours = d.getHours() > 12 ? d.getHours() - 12 : d.getHours();
+    if (withTime) {
+        return ("0" + (d.getMonth() + 1)).slice(-2) + "/" + ("0"
+            + d.getDate()).slice(-2) + "/" + d.getFullYear()
+            + " " + ("0" + (hours)).slice(-2)
+            + ":" + ("0" + (d.getMinutes())).slice(-2)
+            + ":" + ("0" + (d.getSeconds())).slice(-2)
+            + " " + ampm;
+    } else {
+        return ("0" + (d.getMonth() + 1)).slice(-2) + "/" + ("0"
+            + d.getDate()).slice(-2) + "/" + d.getFullYear();
+    }
+}
+
+function RowMenu(props) {
+    const { row, actions, onSelectedAction, showEdit = false, onRowEdit } = props;
+    const [anchorEl, setAnchorEl] = React.useState(null);
+
+    const handleMenuClick = (event) => {
+        event.stopPropagation();
+        setAnchorEl(event.currentTarget);
+    };
+
+    const handleSelectMenu = (e, row, action) => {
+        e.stopPropagation();
+        onSelectedAction(row, action.action_name);
+        setAnchorEl(null);
+    }
+
+    const handleClose = (e) => {
+        setAnchorEl(null);
+        e.stopPropagation();
+    };
+
+    const handleEdit = (e) => {
+        onRowEdit(row);
+        e.stopPropagation();
+    }
+
+    return (
+        <>
+            <Menu
+                id={`actions-${row.id}`}
+                anchorEl={anchorEl}
+                keepMounted
+                open={Boolean(anchorEl)}
+                onClose={handleClose}
+            >
+                {actions.map((action) => {
+                    return <MenuItem key={action.display_name}
+                        onClick={(e) => handleSelectMenu(e, row, action)}
+                    >
+                        {action.display_name}
+                    </MenuItem>
+                }
+                )}
+            </Menu>
+            <Grid style={{ display: 'flex' }}>
+                <IconButton
+                    id={`edit-${row.id}`}
+                    aria-label="more"
+                    aria-controls="long-menu"
+                    aria-haspopup="true"
+                    onClick={handleEdit}
+                >
+                    <EditIcon />
+                </IconButton>
+
+                <IconButton
+                    id={`dropdown-${row.id}`}
+                    aria-label="more"
+                    aria-controls="long-menu"
+                    aria-haspopup="true"
+                    onClick={handleMenuClick}
+                >
+                    <ExpandMore />
+                </IconButton>
+            </Grid>
+
+        </>
+    );
+}
+
+RowMenu.propTypes = {
+    row: PropTypes.object.isRequired,
+    actions: PropTypes.array.isRequired,
+    onSelectedAction: PropTypes.func.isRequired,
+    showEdit: PropTypes.bool,
+    onRowEdit: PropTypes.func
+}
+
+function ConfirmDialog(props) {
+    const { type, itemName, openDialog, onCancel, onContinue } = props;
+    const [open, setOpen] = React.useState(openDialog);
+
+    const handleClose = () => {
+        setOpen(false);
+        onCancel(false);
+    };
+
+    const handleContinue = () => {
+        onContinue(true);
+    }
+
+    return (
+        <div>
+            <Dialog
+                open={open}
+                onClose={handleClose}
+                aria-labelledby="alert-dialog-title"
+                aria-describedby="alert-dialog-description"
+            >
+                <DialogTitle id="alert-dialog-title">{"Delete this " + type + ' "' + itemName + '"?'}</DialogTitle>
+
+                <DialogActions>
+                    <Button onClick={handleClose} color="primary">
+                        Cancel
+            </Button>
+                    <Button onClick={handleContinue} color="primary" autoFocus>
+                        Delete
+            </Button>
+                </DialogActions>
+            </Dialog>
+        </div>
+    );
+}
+
+ConfirmDialog.propTypes = {
+    history: PropTypes.object,
+    type: PropTypes.string,
+    itemName: PropTypes.string,
+    openDialog: PropTypes.bool,
+    onCancel: PropTypes.func,
+    onContinue: PropTypes.func
+};
+
+function MkTable(props) {
+    const classes = useStyles();
+    const { dispatch,
+        data = [],
+        headers = [],
+        actions,
+        query,
+        onActions, title,
+        page = 0,
+        rowsPerPage = 10,
+        noMoreToLoad = false,
+        order,
+        orderBy,
+        isLoading = false,
+        onChangePaginatePage,
+        onGetData,        
+        onUpdateDataRow,
+        onChangeRowPerPage,
+
+    } = props;
+
+    const [_rowsPerPage, setRowsPerPage] = React.useState(rowsPerPage);
+    const [_page, setPage] = React.useState(page);
+    const [_noMoreToLoad, setNoMoreToLoad] = React.useState(noMoreToLoad);
+    const [_order, setOrder] = React.useState(order);
+    const [_orderBy, setOrderBy] = React.useState(orderBy);
+    const [_isLoading, setIsLoading] = React.useState(isLoading);
+    const [_isConfirm, setIsConfirm] = React.useState(false);
+
+    const handleSelectMenu = (row, action) => {
+        if (action === 'delete') {
+            setItemName(row.name === undefined ? row.product_desc : row.name);
+            setIsConfirm(true);
+            setRow(row);
+            setAction(action);
+        } else {
+            onActions(row, action);
+        }
+    }
+
+    const handleDelete = (v) => {
+        setIsConfirm(false);
+        onActions(row, action);
+    }
+
+    const handleCancel = (v) => {
+        setIsConfirm(false);
+    }
+
+    const handleRowEdit = (row) => {
+        onUpdateDataRow(row);
+    }
+
+    var offset = _page * _rowsPerPage;
+
+    // useEffect(() => {
+    //     setNoMoreToLoad(selector.noMoreToLoad);
+    //     setPage(selector.page);
+    //     setOrder(selector._order);
+    //     setOrderBy(selector._orderBy);
+    //     setIsLoading(selector.loading);
+    //     setRowsPerPage(selector.rowsPerPage);
+    // }, [selector]);
+
+    // useEffect(() => {
+    //     var rowsPerPage = localStorage.getItem('rowPerPage');
+    //     if (rowsPerPage !== null) {
+    //         setRowsPerPage(parseInt(rowsPerPage));
+    //         // dispatch(changeRowPerPage(parseInt(rowsPerPage)));
+    //     }
+    // }, [dispatch]);
+
+    const handleRequestSort = (event, property) => {
+        const isAsc = _orderBy === property && _order === 'asc';
+        setOrder(isAsc ? 'desc' : 'asc');
+        setOrderBy(property);
+    };
+
+    const handleChangePage = (event, newPage) => {
+        if (!noMoreToLoad && (newPage + 1) * _rowsPerPage >= data.length) {
+            // dispatch(getDataRecords(query));
+            onGetData();
+        }
+        // dispatch(changePaginatePage(newPage));
+        onChangePaginatePage(newPage);
+    };
+
+    const handleChangeRowsPerPage = (event) => {
+        localStorage.setItem("rowPerPage", parseInt(event.target.value));
+        // dispatch(changeRowPerPage(parseInt(localStorage.getItem('rowPerPage'))));
+        // dispatch(refreshRecord());
+        // dispatch(getDataRecords(query));
+        onChangeRowPerPage(parseInt(localStorage.getItem('rowPerPage')));
+    };
+
+    const getStatus = (data, header) => {
+        var v = data[header.id];
+        var color = 'red';
+        if (v == 'Pending') {
+            color = 'red';
+        } else if (v == 'Started') {
+            color = 'orange';
+        } else {
+            color = 'green';
+        }
+        return (<TableCell key={header.id} align={header.numeric ? 'right' : 'left'} ><Typography style={{ color: 'red', fontWeight: '500' }}>{data[header.id]}</Typography></TableCell>);
+    };
+
+    // const isSelected = (name) => selected.indexOf(name) !== -1;
+
+    // const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage);
+
+    return (
+        <div className={classes.root}>
+            <Grid container>
+                <Grid item>
+                    <TableContainer>
+                        <Table
+                            className={classes.table}
+                            aria-labelledby="tableTitle"
+                            size='small'
+                            aria-label="enhanced table"
+                        >
+                            <EnhancedTableHead
+                                classes={classes}
+                                headCells={headers}
+                                _order={_order}
+                                _orderBy={_orderBy}
+                                onRequestSort={handleRequestSort}
+                                rowCount={data.length !== undefined ? data.length : 0}
+                                dispatch={dispatch}
+                                query={query}
+                            />
+
+                            <TableBody>
+                                {isLoading ? <StyledTableRow >
+                                    <TableCell colSpan={headers.length} align="center"> <CircularProgress /></TableCell>
+                                </StyledTableRow> :
+                                    (data.length !== 0 ? stableSort(data, getComparator(_order, _orderBy))
+                                        .slice(_page * _rowsPerPage, _page * _rowsPerPage + _rowsPerPage)
+                                        .map((row, index) => {
+                                            return (
+                                                <StyledTableRow
+                                                    hover
+                                                    role="checkbox"
+                                                    tabIndex={-1}
+                                                    key={row.id}
+                                                    id={row.id}
+                                                >
+
+                                                    {headers.map((h, i) => {
+                                                        if (h.id === 'sr') {
+                                                            return (<TableCell key={h.id} align="right" style={{ width: '15px' }}>{++offset}</TableCell>);
+                                                        }
+                                                        if (h.id === 'status') {
+                                                            getStatus(row, h);
+                                                            return (<TableCell key={h.id} align={h.numeric ? 'right' : 'left'}>{row[h.id]}</TableCell>);
+                                                        }
+                                                        if (h.id === 'updated_date') {
+                                                            return (<TableCell key={h.id} align={h.numeric ? 'right' : 'left'} style={{ width: h.width }}>{getUpdatedDate(row)}</TableCell>);
+                                                        } else {
+                                                            return (<TableCell key={h.id} align={h.numeric ? 'right' : 'left'} style={{ width: h.width }}
+                                                            >{row[h.id]}</TableCell>);
+                                                        }
+                                                    })}
+                                                    {actions ?
+                                                        <TableCell style={{ width: '150px' }}>
+                                                            <RowMenu
+                                                                actions={actions}
+                                                                row={row}
+                                                                showEdit={true}
+                                                                onRowEdit={(data) => handleRowEdit(data)}
+                                                                onSelectedAction={(data, actionName) => handleSelectMenu(data, actionName)}
+                                                            />
+                                                        </TableCell>
+                                                        : <TableCell style={{ width: '150px' }}>
+                                                            <IconButton onClick={(event) => handleRowEdit(row)}><EditIcon /></IconButton>
+                                                        </TableCell>}
+                                                </StyledTableRow>
+
+                                            );
+                                        }) : <StyledTableRow style={{ width: '100%' }}></StyledTableRow>)}
+                            </TableBody>
+                        </Table>
+                    </TableContainer>
+
+                    <TablePagination
+                        rowsPerPageOptions={[10, 30, 50]}
+                        labelDisplayedRows={function ({ from, to, count }) { }}
+                        component="div"
+                        count={data.length}
+                        rowsPerPage={_rowsPerPage}
+                        page={_page}
+                        onChangePage={handleChangePage}
+                        onChangeRowsPerPage={handleChangeRowsPerPage}
+                    />
+                </Grid></Grid>
+            {_isConfirm ? <ConfirmDialog
+                type={title}
+                itemName={itemName}
+                openDialog={_isConfirm}
+                onCancel={(v) => handleCancel(v)}
+                onContinue={(v) => handleDelete(v)}></ConfirmDialog> : <div />}
+        </div>
+    );
+}
+
+MkTable.propTypes = {
+    history: PropTypes.object,
+    headers: PropTypes.array.isRequired,
+    data: PropTypes.array.isRequired,
+    query: PropTypes.object,
+    onProductBOMClick: PropTypes.func,
+    onActions: PropTypes.func,
+    actions: PropTypes.array,
+    title: PropTypes.string,
+    order: PropTypes.any,
+    orderBy: PropTypes.any,
+    rowsPerPage: PropTypes.any,
+    noMoreToLoad: PropTypes.any,
+    order: PropTypes.any,
+    orderBy: PropTypes.any,
+    isLoading: PropTypes.any,
+    onChangePaginatePage: PropTypes.any,
+    onGetData: PropTypes.any,
+    onChangeRowPerPage: PropTypes.any
+};
+
+export default (MkTable);

+ 1 - 0
src/MkTable/index.js

@@ -0,0 +1 @@
+export { default } from '.';

+ 0 - 287
src/TableTemplate/TableTemplate.js

@@ -1,287 +0,0 @@
-import React, { useEffect } from 'react';
-import PropTypes from 'prop-types';
-import { makeStyles } from '@material-ui/core/styles';
-import Table from '@material-ui/core/Table';
-import TableBody from '@material-ui/core/TableBody';
-import TableCell from '@material-ui/core/TableCell';
-import TableContainer from '@material-ui/core/TableContainer';
-import TableHead from '@material-ui/core/TableHead';
-import TablePagination from '@material-ui/core/TablePagination';
-import TableRow from '@material-ui/core/TableRow';
-import TableSortLabel from '@material-ui/core/TableSortLabel';
-import { Grid } from '@material-ui/core';
-
-function descendingComparator(a, b, orderBy) {
-    if (b[orderBy] < a[orderBy]) {
-        return -1;
-    }
-    if (b[orderBy] > a[orderBy]) {
-        return 1;
-    }
-    return 0;
-}
-
-function getComparator(order, orderBy) {
-    return order === 'desc'
-        ? (a, b) => descendingComparator(a, b, orderBy)
-        : (a, b) => -descendingComparator(a, b, orderBy);
-}
-
-function stableSort(array, comparator) {
-    const stabilizedThis = array.map((el, index) => [el, index]);
-    stabilizedThis.sort((a, b) => {
-        const order = comparator(a[0], b[0]);
-        if (order !== 0) return order;
-        return a[1] - b[1];
-    });
-    return stabilizedThis.map((el) => el[0]);
-}
-
-function EnhancedTableHead(props) {
-    const { classes,
-        order,
-        orderBy,
-        onRequestSort,
-        onRefreshData,
-        headCells } = props;
-    const createSortHandler = (property) => (event) => {
-        onRequestSort(event, property);
-        onRefreshData();
-    };
-
-    return (
-        <TableHead>
-            <TableRow>
-                {headCells.map((headCell) => (
-                    <TableCell
-                        key={headCell.id}
-                        align={headCell.numeric ? 'right' : 'left'}
-                        padding={headCell.disablePadding ? 'none' : 'default'}
-                        sortDirection={orderBy === headCell.id ? order : false}
-                    >
-                        {headCell.id != 'id' ?
-                            <TableSortLabel
-                                active={orderBy === headCell.id}
-                                direction={orderBy === headCell.id ? order : 'asc'}
-                                onClick={createSortHandler(headCell.id)}
-                            >
-                                {headCell.label}
-                                {orderBy === headCell.id ? (
-                                    <span className={classes.visuallyHidden}>
-                                        {order === 'desc' ? 'sorted descending' : 'sorted ascending'}
-                                    </span>
-                                ) : null}
-                            </TableSortLabel>
-                            : <TableSortLabel
-                                hideSortIcon={true}
-                            >
-                                {headCell.label}
-
-                            </TableSortLabel>
-                        }
-
-                    </TableCell>
-                ))}
-            </TableRow>
-        </TableHead>
-    );
-}
-
-EnhancedTableHead.propTypes = {
-    classes: PropTypes.object.isRequired,
-    numSelected: PropTypes.number.isRequired,
-    onRequestSort: PropTypes.func.isRequired,
-    onRefreshData: PropTypes.func.isRequired,
-    onSelectAllClick: PropTypes.func.isRequired,
-    order: PropTypes.oneOf(['asc', 'desc']).isRequired,
-    orderBy: PropTypes.string.isRequired,
-    rowCount: PropTypes.number.isRequired,
-};
-
-const useStyles = makeStyles((theme) => ({
-    root: {
-        width: '100%',
-    },
-    paper: {
-        width: '100%',
-        marginBottom: theme.spacing(2),
-    },
-    table: {
-        minWidth: 750,
-    },
-    visuallyHidden: {
-        border: 0,
-        clip: 'rect(0 0 0 0)',
-        height: 1,
-        margin: -1,
-        overflow: 'hidden',
-        padding: 0,
-        position: 'absolute',
-        top: 20,
-        width: 1,
-    },
-    underline: {
-        "&&&:before": {
-            borderBottom: "none"
-        },
-        "&&:after": {
-            borderBottom: "none"
-        }
-    }
-}));
-
-function TableTemplate(props) {
-    const classes = useStyles();
-    const {
-        data = [],
-        headers = [],
-        onUpdateData,
-        onReloadData,
-        onChangePage,
-        onChangeRowsPerPage,
-        rowsPerPage = 10,
-        page = 0,
-        order = 'asc',
-        orderBy
-    } = props;
-
-    const [selected, setSelected] = React.useState([]);
-    const [dense, setDense] = React.useState(false);
-    const [rowDataPerPage, setRowsPerPage] = React.useState(rowsPerPage != undefined ? rowsPerPage : 10);
-    const [paginatePage, setPage] = React.useState(page != undefined ? page : 0);
-    const [paginateOrder, setOrder] = React.useState(order != undefined ? order : 'asc');
-    const [paginateOrderBy, setOrderBy] = React.useState(orderBy != undefined ? orderBy : 'name');
-
-    var offset = paginatePage * rowDataPerPage;
-
-    const handleRequestSort = (event, property) => {
-        const isAsc = orderBy === property && order === 'asc';
-        setOrder(isAsc ? 'desc' : 'asc');
-        setOrderBy(property);
-    };
-
-    const handleSelectAllClick = (event) => {
-        if (event.target.checked) {
-            const newSelecteds = data.map((n) => n.name);
-            setSelected(newSelecteds);
-            return;
-        }
-        setSelected([]);
-    };
-
-    const handleClick = (event, rowdata) => {
-        onUpdateData(true, rowdata);
-    };
-
-    const handleChangePage = (event, newPage) => {
-        onChangePage(newPage);
-
-    };
-
-    const handleReloadData = () => {
-        onReloadData();
-    }
-
-    const handleChangeRowsPerPage = (event) => {
-        setRowsPerPage(parseInt(event.target.value, 10));
-        onChangeRowsPerPage(parseInt(event.target.value));
-        onReloadData();
-    };
-
-    const isSelected = (name) => selected.indexOf(name) !== -1;
-
-    const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage);
-
-    return (
-        <div className={classes.root}>
-            <Grid container>
-                <Grid item style={{ marginRight: '10%' }}>
-
-                    <TableContainer>
-                        <Table
-                            className={classes.table}
-                            aria-labelledby="tableTitle"
-                            size={dense ? 'small' : 'medium'}
-                            aria-label="enhanced table"
-                        >
-                            <EnhancedTableHead
-                                classes={classes}
-                                numSelected={selected.length}
-                                headCells={headers}
-                                order={order}
-                                orderBy={orderBy}
-                                onSelectAllClick={handleSelectAllClick}
-                                onRequestSort={handleRequestSort}
-                                onRefreshData={handleReloadData}
-                                rowCount={data.length}
-                            />
-                            <TableBody>
-                                {data.length != 0 ? stableSort(data, getComparator(order, orderBy))
-                                    .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
-                                    .map((row, index) => {
-                                        const isItemSelected = isSelected(row.name);
-                                        const labelId = `enhanced-table-checkbox-${index}`;
-
-                                        return (
-                                            <TableRow
-                                                hover
-                                                onClick={(event) => handleClick(event, row)}
-                                                role="checkbox"
-                                                aria-checked={isItemSelected}
-                                                tabIndex={-1}
-                                                key={index}
-                                                selected={isItemSelected}
-                                            >
-
-                                                {headers.map((h, i) => {
-                                                    if (h.id == 'id') {
-                                                        return (<TableCell key={h.id} align="right">{++offset}</TableCell>);
-                                                    } else {
-                                                        return (<TableCell key={h.id} align="right">{row[h.id]}</TableCell>);
-                                                    }
-                                                })}
-
-                                            </TableRow>
-                                        );
-                                    }) : <div></div>}
-                                {emptyRows > 0 && (
-                                    <TableRow style={{ height: (dense ? 33 : 53) * emptyRows }}>
-                                        <TableCell colSpan={6} />
-                                    </TableRow>
-                                )}
-                            </TableBody>
-                        </Table>
-                    </TableContainer>
-
-                    <TablePagination
-                        rowsPerPageOptions={[5, 10, 20, 30]}
-                        labelDisplayedRows={function ({ from, to, count }) { }}
-                        component="div"
-                        count={data.length}
-                        rowsPerPage={rowsPerPage}
-                        rowsPerPage={rowsPerPage}
-                        page={page}
-                        onChangePage={handleChangePage}
-                        onChangeRowsPerPage={handleChangeRowsPerPage}
-                    />
-                </Grid></Grid>
-        </div>
-    );
-}
-
-TableTemplate.propTypes = {
-    history: PropTypes.object,
-    headers: PropTypes.array.isRequired,
-    data: PropTypes.array.isRequired,
-    onUpdateData: PropTypes.func,
-    onReloadData: PropTypes.func,
-    onChangePage: PropTypes.func,
-    onChangeRowsPerPage: PropTypes.func,
-    query: PropTypes.object,
-    page: PropTypes.any,
-    rowsPerPage: PropTypes.any,
-    order: PropTypes.any,
-    orderBy: PropTypes.any
-};
-
-export default (TableTemplate);

+ 0 - 1
src/TableTemplate/index.js

@@ -1 +0,0 @@
-export { default } from '../TableTemplate';

+ 2 - 2
src/index.js

@@ -1,4 +1,4 @@
 export { default as List } from './List/List';
 export { default as MkForm } from './MkForm/MkForm';
-export { default as TableTemplate } from './TableTemplate/TableTemplate';
-export { default as InfoPage } from './InfoPage/InfoPage';
+export { default as MkTable } from './MkTable/MkTable';
+export { default as MkInfo } from './MkInfo/MkInfo';