diff --git a/docs/ItemTable Responsive Examples/Cell Component override.jpg b/docs/ItemTable Responsive Examples/Cell Component override.jpg new file mode 100644 index 0000000..bd8afcb Binary files /dev/null and b/docs/ItemTable Responsive Examples/Cell Component override.jpg differ diff --git a/docs/ItemTable Responsive Examples/Default ItemTable behavior.jpg b/docs/ItemTable Responsive Examples/Default ItemTable behavior.jpg new file mode 100644 index 0000000..842bece Binary files /dev/null and b/docs/ItemTable Responsive Examples/Default ItemTable behavior.jpg differ diff --git a/docs/ItemTable Responsive Examples/Row Component override example.jpg b/docs/ItemTable Responsive Examples/Row Component override example.jpg new file mode 100644 index 0000000..221dc18 Binary files /dev/null and b/docs/ItemTable Responsive Examples/Row Component override example.jpg differ diff --git a/docs/ItemTable Responsive Examples/mui-datatables example.gif b/docs/ItemTable Responsive Examples/mui-datatables example.gif new file mode 100644 index 0000000..db42e7d Binary files /dev/null and b/docs/ItemTable Responsive Examples/mui-datatables example.gif differ diff --git a/package-lock.json b/package-lock.json index d122340..7d01605 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1516,38 +1516,20 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - } + "@react-dnd/asap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.0.tgz", + "integrity": "sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==" }, - "@npmcli/move-file": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", - "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } + "@react-dnd/invariant": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-2.0.0.tgz", + "integrity": "sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==" }, - "@popperjs/core": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.5.3.tgz", - "integrity": "sha512-RFwCobxsvZ6j7twS7dHIZQZituMIDJJNHS/qY6iuthVebxS3zhRY+jaC2roEKiAYaVuTcGmX6Luc6YBcf6zJVg==", - "dev": true + "@react-dnd/shallowequal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", + "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" }, "@sheerun/mutationobserver-shim": { "version": "0.3.3", @@ -1854,6 +1836,15 @@ "@types/node": "*" } }, + "@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/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -5297,6 +5288,11 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, "detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", @@ -5362,6 +5358,16 @@ "path-type": "^3.0.0" } }, + "dnd-core": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-11.1.3.tgz", + "integrity": "sha512-QugF55dNW+h+vzxVJ/LSJeTeUw9MCJ2cllhmVThVPEtF16ooBkxj0WBE5RB+AceFxMFo1rO6bJKXtqKl+JNnyA==", + "requires": { + "@react-dnd/asap": "^4.0.0", + "@react-dnd/invariant": "^2.0.0", + "redux": "^4.0.4" + } + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -6378,6 +6384,14 @@ } } }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "expect": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", @@ -6782,6 +6796,17 @@ } } }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -6951,6 +6976,20 @@ } } }, + "frontend-collective-react-dnd-scrollzone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/frontend-collective-react-dnd-scrollzone/-/frontend-collective-react-dnd-scrollzone-1.0.2.tgz", + "integrity": "sha512-me/D9PZJq9j/sjEjs/OPmm6V6nbaHbhgeQiwrWu0t35lhwAOKWc+QBzzKKcZQeboYTkgE8UvCD9el+5ANp+g5Q==", + "requires": { + "hoist-non-react-statics": "^3.1.0", + "lodash.throttle": "^4.0.1", + "prop-types": "^15.5.9", + "raf": "^3.2.0", + "react": "^16.3.0", + "react-display-name": "^0.2.0", + "react-dom": "^16.3.0" + } + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -7370,6 +7409,14 @@ "react-is": "^16.7.0" } }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "requires": { + "parse-passwd": "^1.0.0" + } + }, "hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", @@ -7826,6 +7873,11 @@ } } }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -9219,11 +9271,51 @@ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha1-EnqX8CrcQXUalU0ksN4X4QDgOOs=" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, + "lodash.find": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", + "integrity": "sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha1-I+89lTVWUgOmbO/VuDD4SJEa+0g=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -9246,6 +9338,11 @@ "lodash._reinterpolate": "^3.0.0" } }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -9802,6 +9899,29 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "mui-datatables": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/mui-datatables/-/mui-datatables-3.4.1.tgz", + "integrity": "sha512-4g62AXt5gyRdc3qUux9Zn8zH4NZOOWRFApU/W42LpWyGXLaNtUlOapsFteWCUloga9YF/Hd51QvhH8+aSkHULQ==", + "requires": { + "clsx": "^1.1.1", + "lodash.assignwith": "^4.2.0", + "lodash.clonedeep": "^4.5.0", + "lodash.debounce": "^4.0.8", + "lodash.find": "^4.6.0", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "lodash.isundefined": "^3.0.1", + "lodash.memoize": "^4.1.2", + "lodash.merge": "^4.6.2", + "prop-types": "^15.7.2", + "react-dnd": "^11.1.3", + "react-dnd-html5-backend": "^11.1.3", + "react-sortable-tree": "^2.7.1", + "react-to-print": "^2.8.0", + "webpack-cli": "^3.3.11" + } + }, "multicast-dns": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", @@ -10650,6 +10770,11 @@ "json-parse-better-errors": "^1.0.1" } }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", @@ -12261,6 +12386,30 @@ } } }, + "react-display-name": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz", + "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==" + }, + "react-dnd": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz", + "integrity": "sha512-8rtzzT8iwHgdSC89VktwhqdKKtfXaAyC4wiqp0SywpHG12TTLvfOoL6xNEIUWXwIEWu+CFfDn4GZJyynCEuHIQ==", + "requires": { + "@react-dnd/shallowequal": "^2.0.0", + "@types/hoist-non-react-statics": "^3.3.1", + "dnd-core": "^11.1.3", + "hoist-non-react-statics": "^3.3.0" + } + }, + "react-dnd-html5-backend": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-11.1.3.tgz", + "integrity": "sha512-/1FjNlJbW/ivkUxlxQd7o3trA5DE33QiRZgxent3zKme8DwF4Nbw3OFVhTRFGaYhHFNL1rZt6Rdj1D78BjnNLw==", + "requires": { + "dnd-core": "^11.1.3" + } + }, "react-docgen": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-5.3.1.tgz", @@ -12370,6 +12519,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "react-redux": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.1.tgz", @@ -12509,6 +12663,20 @@ "integrity": "sha512-bL5W5mAxSW6+cLwqqVWY47Silqgy2DKDTR4hDBrLrUqC5BXc29YVx17l2IZk5v36VcDEq1Bszu2oHm1qBwKqBA==", "dev": true }, + "react-sortable-tree": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/react-sortable-tree/-/react-sortable-tree-2.8.0.tgz", + "integrity": "sha512-gTjwxRNt7z0FC76KeNTnGqx1qUSlV3N78mMPRushBpSUXzZYhiFNsWHUIruyPnaAbw4SA7LgpItV7VieAuwDpw==", + "requires": { + "frontend-collective-react-dnd-scrollzone": "^1.0.2", + "lodash.isequal": "^4.5.0", + "prop-types": "^15.6.1", + "react-dnd": "^11.1.3", + "react-dnd-html5-backend": "^11.1.3", + "react-lifecycles-compat": "^3.0.4", + "react-virtualized": "^9.21.2" + } + }, "react-styleguidist": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/react-styleguidist/-/react-styleguidist-11.1.0.tgz", @@ -13380,6 +13548,19 @@ } } }, + "react-table": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.5.1.tgz", + "integrity": "sha512-rprrUElCqvj79lyY2XbUoYLzwA5Mm4CGS8ElQ8OyzocvmkvCcmunvvfbpIg9Jm9HnMBjVZcVyPFPZ1BFelIBKw==" + }, + "react-to-print": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/react-to-print/-/react-to-print-2.10.0.tgz", + "integrity": "sha512-1xCUHGiNkgl2H7xtzyo0KsJHO3B51vuZumwHYYOatT4eQklkAswJDJREOUcGRAm8XO/J0+k3p6v0mNs2Vr6fWA==", + "requires": { + "prop-types": "^15.7.2" + } + }, "react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -13391,6 +13572,19 @@ "prop-types": "^15.6.2" } }, + "react-virtualized": { + "version": "9.22.2", + "resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.2.tgz", + "integrity": "sha512-5j4h4FhxTdOpBKtePSs1yk6LDNT4oGtUwjT7Nkh61Z8vv3fTG/XeOf8J4li1AYaexOwTXnw0HFVxsV0GBUqwRw==", + "requires": { + "@babel/runtime": "^7.7.2", + "clsx": "^1.0.4", + "dom-helpers": "^5.1.3", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -13799,6 +13993,39 @@ "resolve-from": "^3.0.0" } }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + } + } + }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -16312,6 +16539,34 @@ } } }, + "webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "webpack-dev-middleware": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", diff --git a/package.json b/package.json index ffc06e3..f547f7d 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,9 @@ "material-table": "^1.63.1", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-scripts": "3.4.1", + "react-table": "^7.5.1" "react-router-dom": "^5.2.0", - "react-scripts": "3.4.1" }, "scripts": { "start:frontend": "react-scripts start", diff --git a/src/App.js b/src/App.js index 1f4eb7f..be33935 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,6 @@ import React, { useState, useEffect } from "react"; import { ThemeProvider } from "@material-ui/core/styles"; -import { Box, makeStyles } from "@material-ui/core"; +import { Box, makeStyles, Paper } from "@material-ui/core"; import { Route } from "react-router-dom"; import clsx from "clsx"; import webqueueTheme from "./theme"; @@ -13,7 +13,7 @@ function App() { const [darkMode, setDarkMode] = useState(false); const [activeItem, setActiveItem] = useState({}); const [sidebarOpen, setSidebarOpen] = useState(false); - const [items, setItems] = useState([]) + const [items, setItems] = useState([]); useEffect(() => { fetch("/api/ce") @@ -55,7 +55,7 @@ function App() { }, }); const classes = useStyles(); - + return ( @@ -63,7 +63,7 @@ function App() { - + @@ -94,7 +94,7 @@ function App() { /> } - + ); } diff --git a/src/components/EmailHeader/EmailHeader.js b/src/components/EmailHeader/EmailHeader.js new file mode 100644 index 0000000..3af9c0c --- /dev/null +++ b/src/components/EmailHeader/EmailHeader.js @@ -0,0 +1,73 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Card, CardHeader, makeStyles } from "@material-ui/core"; +import UserAvatar from "../UserAvatar/"; +import webqueue2Theme from "../../theme"; + +export default function EmailHeader({name, date, email}){ + + const theme = webqueue2Theme(false); + const useStyles = makeStyles({ + "verticalPadding": { + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(1), + }, + "removeCardHeaderPadding": { + padding: "0" + } + }); + const classes = useStyles(); + + /** + * Returns the title for the user. + * @param {string} name Name of the user. + * @param {string} email Email address of the user. + * @example + * // Has alias and name + * return "campb303 (Justin Campbell)" + * // Has alias but no name + * return "campb303" + * // Has no alias and no name + * return "" + * @returns {string} + */ + function buildTitle(name, email){ + let title = ""; + const isNotEmpty = (value) => { + return value === "" || value === null ? false : true; + }; + if (isNotEmpty(name)){ + title += `${name}`; + }; + if (isNotEmpty(email)){ + title += ` <${email}>` + } + return title; + }; + + return( + + } + title={buildTitle(name, email)} + subheader={Date(date)} + classes={{root: classes.removeCardHeaderPadding}} + /> + + ); +}; + +EmailHeader.propTypes = { + /** Name of the user. */ + "name": PropTypes.string, + /** Date of the message. */ + "date": PropTypes.string, + /** Email address of the user. */ + "email": PropTypes.string +}; + +EmailHeader.defaultProps = { + "name": "", + "date": "", + "email": "" +}; \ No newline at end of file diff --git a/src/components/EmailHeader/EmailHeader.md b/src/components/EmailHeader/EmailHeader.md new file mode 100644 index 0000000..e163f38 --- /dev/null +++ b/src/components/EmailHeader/EmailHeader.md @@ -0,0 +1,9 @@ +Description of EmailHeader. + +```jsx +import EmailHeader from "./EmailHeader"; + +``` +```jsx static + +``` \ No newline at end of file diff --git a/src/components/EmailHeader/index.js b/src/components/EmailHeader/index.js new file mode 100644 index 0000000..47c222d --- /dev/null +++ b/src/components/EmailHeader/index.js @@ -0,0 +1 @@ +export { default } from "./EmailHeader"; \ No newline at end of file diff --git a/src/components/ItemBodyView/ItemBodyView.js b/src/components/ItemBodyView/ItemBodyView.js new file mode 100644 index 0000000..bed15c1 --- /dev/null +++ b/src/components/ItemBodyView/ItemBodyView.js @@ -0,0 +1,105 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Timeline, TimelineItem, TimelineSeparator, TimelineConnector, TimelineContent, TimelineDot } from '@material-ui/lab'; +import { Typography, makeStyles } from "@material-ui/core"; +import webqueue2Theme from "../../theme"; +import EmailHeader from "../EmailHeader/"; +import { objectIsEmpty } from "../../utilities"; + +export default function ItemBodyView({ item }) { + + const theme = webqueue2Theme(false); + const useStyles = makeStyles((theme) => ({ + missingOppositeContent: { + '&:before': { + content: '""', + flex: 0, + padding: '0', + }, + }, + })); + const classes = useStyles(theme); + + const generateTimelineItem = (section) => { + switch(section.type) { + case "directoryInformation": + if (section.content.length === 0){ + return "No Directory Information"; + } else { + return "Directory Information Present" + } + case "initialMessage": + return( + <> + + {section.content.map((line, index) => {line})} + + ); + case "edit": + return( + <> + + {`${section.by} assigned thisat ${Date(section.datetime)}`} + + {section.content.map((line) => {line})} + + ); + case "status": + return( + <> + + {`${section.by} update the status to at ${Date(section.datetime)}`} + + {section.content.map((line) => {line})} + + ); + case "assign": + return ( + + {`${section.by} assigned this to ${section.to} at ${Date(section.datetime)}`} + + ); + case "replyToUser": + return( + <> + + {`${section.by} replied ${Date(section.datetime)}`} + + {section.content.map((line) => {line})} + + ); + case "replyFromUser": + return( + <> + + {section.content.map((line, index) => {line})} + + ); + default: + return "No Match Found"; + }; + }; + + return ( + + {objectIsEmpty(item) ? "" : item.content.map((section, index) => { + return ( + + + + + + + {generateTimelineItem(section)} + + + ); + })} + + ); +}; + +ItemBodyView.propTypes = { + /** The item to diplay. */ + "item": PropTypes.object.isRequired +}; \ No newline at end of file diff --git a/src/components/ItemBodyView/ItemBodyView.md b/src/components/ItemBodyView/ItemBodyView.md new file mode 100644 index 0000000..2c224d1 --- /dev/null +++ b/src/components/ItemBodyView/ItemBodyView.md @@ -0,0 +1,23 @@ +The ItemBodyView displays the seven actions possible in an item: + +- **Directory information**: present when a user submits a ticket from the Contact Us page +- **Initial Message**: the first message a user sends. +- **Edit:** an internal note to and from ECN staff. +- **Status:** an internal summary of the current/next task for the item. +- **Assignment:** the career account alias for the ECN employee the item is assigned to. +- **Reply To User:** a message sent from an ECN employee to a user. +- **Reply To ECN:** a message sent from the user to ECN that has been merged into an existing item. + +```jsx +import ItemBodyView from "./ItemBodyView"; + +const demoItem = {"queue": "ce", "number": 100, "lastUpdated": "08-27-20 09:49 PM", "headers": [{"type": "Merged-Time", "content": "Tue, 23 Jun 2020 13:31:53 -0400"}, {"type": "Merged-By", "content": "campb303"}, {"type": "QTime", "content": "1"}, {"type": "QTime-Updated-Time", "content": "Tue, 23 Jun 2020 13:28:50 EDT"}, {"type": "QTime-Updated-By", "content": "campb303"}, {"type": "Time", "content": "1"}, {"type": "Time-Updated-Time", "content": "Tue, 23 Jun 2020 13:28:50 EDT"}, {"type": "Time-Updated-By", "content": "campb303"}, {"type": "Replied-Time", "content": "Tue, 23 Jun 2020 13:28:48 -0400"}, {"type": "Replied-By", "content": "campb303"}, {"type": "Edited-Time", "content": "Tue, 23 Jun 2020 13:27:56 -0400"}, {"type": "Edited-By", "content": "campb303"}, {"type": "QAssigned-To", "content": "campb303"}, {"type": "QAssigned-To-Updated-Time", "content": "Tue, 23 Jun 2020 13:27:00 EDT"}, {"type": "QAssigned-To-Updated-By", "content": "campb303"}, {"type": "Assigned-To", "content": "campb303"}, {"type": "Assigned-To-Updated-Time", "content": "Tue, 23 Jun 2020 13:27:00 EDT"}, {"type": "Assigned-To-Updated-By", "content": "campb303"}, {"type": "QStatus", "content": "Dont Delete"}, {"type": "QStatus-Updated-Time", "content": "Tue, 23 Jun 2020 13:26:55 EDT"}, {"type": "QStatus-Updated-By", "content": "campb303"}, {"type": "Status", "content": "Dont Delete"}, {"type": "Status-Updated-Time", "content": "Tue, 23 Jun 2020 13:26:55 EDT"}, {"type": "Status-Updated-By", "content": "campb303"}, {"type": "Date", "content": "Tue, 23 Jun 2020 13:25:51 -0400"}, {"type": "From", "content": "Justin Campbell "}, {"type": "Message-ID", "content": "<911CE050-3240-4980-91DD-9C3EBB8DBCF8@purdue.edu>"}, {"type": "Subject", "content": "Beepboop"}, {"type": "To", "content": "cesite@ecn.purdue.edu"}, {"type": "Content-Type", "content": "text/plain; charset=\"utf-8\""}, {"type": "X-ECN-Queue-Original-Path", "content": "/home/pier/e/queue/Attachments/inbox/2020-06-23/208-original.txt"}, {"type": "X-ECN-Queue-Original-URL", "content": "https://engineering.purdue.edu/webqueue/Attachments/inbox/2020-06-23/208-original.txt"}], "content": [{"type": "directoryInformation", "content": []}, {"type": "initialMessage", "datetime": "2020-06-23T13:25:51-0400", "userName": "Justin Campbell", "userEmail": "campb303@purdue.edu", "ccRecipients": [], "content": ["Testtest\n"]}, {"type": "assign", "by": "campb303", "datetime": "2020-06-23T13:27:00-0400", "to": "campb303"}, {"type": "status", "by": "campb303", "datetime": "2020-06-23T13:26:55", "content": ["*** Status updated by: campb303 at: 6/23/2020 13:26:55 ***\n", "Dont Delete\n"]}, {"type": "edit", "by": "campb303", "datetime": "2020-06-23T13:27:56", "content": ["*** Edited by: campb303 at: 06/23/20 13:27:56 ***\n", "\n", "This be an edit my boy\n", "\n", "\n", "\n"]}, {"type": "replyToUser", "by": "campb303", "datetime": "2020-06-23T13:28:18", "content": ["*** Replied by: campb303 at: 06/23/20 13:28:18 ***\n", "\n", "This be a reply my son\n", "\n", "Justin\n", "ECN\n", "\n"]}, {"type": "replyFromUser", "datetime": "2020-06-23T13:30:45-0400", "subject": "Re: Beepboop", "userName": "Justin Campbell", "userEmail": "campb303@purdue.edu", "content": ["=== Additional information supplied by user ===\n", "\n", "Subject: Re: Beepboop\n", "From: Justin Campbell \n", "Date: Tue, 23 Jun 2020 13:30:45 -0400\n", "X-ECN-Queue-Original-Path: /home/pier/e/queue/Attachments/inbox/2020-06-23/212-original.txt\n", "X-ECN-Queue-Original-URL: https://engineering.purdue.edu/webqueue/Attachments/inbox/2020-06-23/212-original.txt\n", "\n", "Huzzah!\n", "\n", "===============================================\n", "\n"], "ccRecipients": []}], "isLocked": "ce 100 is locked by knewell using qvi", "userEmail": "campb303@purdue.edu", "userName": "Justin Campbell", "userAlias": "campb303", "assignedTo": "campb303", "subject": "Beepboop", "status": "Dont Delete", "priority": "", "department": "", "building": "", "dateReceived": "2020-06-23T13:25:51-0400"}; + +
+ +
+``` + +```jsx static + +``` \ No newline at end of file diff --git a/src/components/ItemBodyView/index.js b/src/components/ItemBodyView/index.js new file mode 100644 index 0000000..076a727 --- /dev/null +++ b/src/components/ItemBodyView/index.js @@ -0,0 +1,3 @@ +import ItemBodyView from "./ItemBodyView"; + +export default ItemBodyView; \ No newline at end of file diff --git a/src/components/ItemMetadataView/ItemMetadataView.js b/src/components/ItemMetadataView/ItemMetadataView.js index f6fda1e..e0f27bc 100644 --- a/src/components/ItemMetadataView/ItemMetadataView.js +++ b/src/components/ItemMetadataView/ItemMetadataView.js @@ -1,44 +1,47 @@ import React from 'react'; -import PropTypes from 'prop-types' -import { makeStyles, Grid, Paper } from '@material-ui/core'; -import { Alert } from '@material-ui/lab' +import PropTypes from 'prop-types'; +import { makeStyles, Typography } from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import webqueue2Theme from "../../theme"; +import EmailHeader from '../EmailHeader/EmailHeader'; export default function ItemMetadataView({item}){ + + const theme = webqueue2Theme(false); + const useStyles = makeStyles({ + "verticalSpacing": { + marginTop: theme.spacing(1), + marginBottom: theme.spacing(1), + }, + "removeCardHeaderPadding": { + padding: "0" + } + }); + const classes = useStyles(); + const LockedAlert = () => { return ( {item.isLocked} ); - } - const useStyles = makeStyles({ - "gridContainer": { - paddingTop: ".75em", - } - }); - - const classes = useStyles(); + }; - const metadataFields = ["userEmail", "userAlias", "subject", "dateReceived", - "assignedTo", "status", "priority", "department", "building"]; - return( <> {item.isLocked ? LockedAlert() : ""} - - {metadataFields.map((field) => { - const title = field.toUpperCase(); - const subtitle = item[field] === undefined ? "Unknown" : item[field]; - return ( - - - {title}: {subtitle} - - - ); - })} - + + + {item.subject} + + + + + + Status, assignments, priority, refile, archive and delete controls coming soon to a theater near you. + + ); } diff --git a/src/components/ItemMetadataView/ItemMetadataView.md b/src/components/ItemMetadataView/ItemMetadataView.md index 5d4f5f3..641eff7 100644 --- a/src/components/ItemMetadataView/ItemMetadataView.md +++ b/src/components/ItemMetadataView/ItemMetadataView.md @@ -4,7 +4,9 @@ The ItemMetadataView displays the metadata for an item as part of the [ItemView] import Paper from "@material-ui/core"; import ItemMetadataView from "./ItemMetadataView"; -
+const demoItem = {"queue": "ce", "number": 100, "lastUpdated": "07-23-20 10:11 PM", "headers": [{"type": "Merged-Time", "content": "Tue, 23 Jun 2020 13:31:53 -0400"}, {"type": "Merged-By", "content": "campb303"}, {"type": "QTime", "content": "1"}, {"type": "QTime-Updated-Time", "content": "Tue, 23 Jun 2020 13:28:50 EDT"}, {"type": "QTime-Updated-By", "content": "campb303"}, {"type": "Time", "content": "1"}, {"type": "Time-Updated-Time", "content": "Tue, 23 Jun 2020 13:28:50 EDT"}, {"type": "Time-Updated-By", "content": "campb303"}, {"type": "Replied-Time", "content": "Tue, 23 Jun 2020 13:28:48 -0400"}, {"type": "Replied-By", "content": "campb303"}, {"type": "Edited-Time", "content": "Tue, 23 Jun 2020 13:27:56 -0400"}, {"type": "Edited-By", "content": "campb303"}, {"type": "QAssigned-To", "content": "campb303"}, {"type": "QAssigned-To-Updated-Time", "content": "Tue, 23 Jun 2020 13:27:00 EDT"}, {"type": "QAssigned-To-Updated-By", "content": "campb303"}, {"type": "Assigned-To", "content": "campb303"}, {"type": "Assigned-To-Updated-Time", "content": "Tue, 23 Jun 2020 13:27:00 EDT"}, {"type": "Assigned-To-Updated-By", "content": "campb303"}, {"type": "QStatus", "content": "Dont Delete"}, {"type": "QStatus-Updated-Time", "content": "Tue, 23 Jun 2020 13:26:55 EDT"}, {"type": "QStatus-Updated-By", "content": "campb303"}, {"type": "Status", "content": "Dont Delete"}, {"type": "Status-Updated-Time", "content": "Tue, 23 Jun 2020 13:26:55 EDT"}, {"type": "Status-Updated-By", "content": "campb303"}, {"type": "Date", "content": "Tue, 23 Jun 2020 13:25:51 -0400"}, {"type": "From", "content": "Justin Campbell "}, {"type": "Message-ID", "content": "<911CE050-3240-4980-91DD-9C3EBB8DBCF8@purdue.edu>"}, {"type": "Subject", "content": "Beepboop"}, {"type": "To", "content": "cesite@ecn.purdue.edu"}, {"type": "Content-Type", "content": "text/plain; charset=\"utf-8\""}, {"type": "X-ECN-Queue-Original-Path", "content": "/home/pier/e/queue/Attachments/inbox/2020-06-23/208-original.txt"}], "content": ["Testtest\n", "\n", "*** Status updated by: campb303 at: 6/23/2020 13:26:55 ***\n", "Dont Delete\n", "*** Edited by: campb303 at: 06/23/20 13:27:56 ***\n", "\n", "This be an edit my boy\n", "\n", "\n", "\n", "*** Replied by: campb303 at: 06/23/20 13:28:18 ***\n", "\n", "This be a reply my son\n", "\n", "Justin\n", "ECN\n", "\n", "=== Additional information supplied by user ===\n", "\n", "Subject: Re: Beepboop\n", "From: Justin Campbell \n", "Date: Tue, 23 Jun 2020 13:30:45 -0400\n", "X-ECN-Queue-Original-Path: /home/pier/e/queue/Attachments/inbox/2020-06-23/212-original.txt\n", "X-ECN-Queue-Original-URL: https://engineering.purdue.edu/webqueue/Attachments/inbox/2020-06-23/212-original.txt\n", "\n", "Huzzah!\n", "\n", "===============================================\n"], "isLocked": "ce 100 is locked by knewell using qvi", "userEmail": "campb303@purdue.edu", "userName": "Justin Campbell", "userAlias": "campb303", "assignedTo": "campb303", "subject": "Beepboop", "status": "Dont Delete", "priority": "", "department": "", "building": "", "dateReceived": "Tue, 23 Jun 2020 13:25:51 -0400"}; + +
``` diff --git a/src/components/ItemTable/ItemTable.js b/src/components/ItemTable/ItemTable.js index 3cb47b3..b9b0f0b 100644 --- a/src/components/ItemTable/ItemTable.js +++ b/src/components/ItemTable/ItemTable.js @@ -1,51 +1,117 @@ -import React from 'react'; +import React, { useState, useEffect } from "react"; +import { useTable, useFilters, useFlexLayout, useSortBy } from "react-table"; +import { makeStyles, Table, TableBody, TableCell, TableHead, TableRow, TableContainer, TableSortLabel, Paper, Grid, IconButton, useTheme, } from "@material-ui/core"; import { useHistory } from "react-router-dom"; -import PropTypes from 'prop-types' -import MaterialTable from "material-table"; - - -export default function ItemTable({ items }) { - - const columns = [ - { title: 'Queue', field: 'queue', filterPlaceholder: "Ex: \"ME\"" }, - { title: 'Item #', field: 'number', filterPlaceholder: "Ex: \"42\"" }, - { title: 'From', field: 'userAlias', filterPlaceholder: "Ex: \"campb303\"" }, - { title: 'Assigned To', field: 'assignedTo', filterPlaceholder: "Ex: \"sundeep\"" }, - { title: 'Subject', field: 'subject', filterPlaceholder: "Ex: \"Install Libraries\"" }, - { title: 'Status', field: 'status', filterPlaceholder: "Ex: \"Wating for Reply\"" }, - { title: 'Priority', field: 'priority', filterPlaceholder: "Ex: \"covid\"" }, - { title: 'Last Updated', field: 'lastUpdated', filterPlaceholder: "Ex: \"07-27-20 12:54 PM\"" }, - { title: 'Department', field: 'department', filterPlaceholder: "Ex: \"Business Office\"" }, - { title: 'Building', field: 'building', filterPlaceholder: "Ex: \"KNOY\"" }, - { title: 'Date Received', field: 'dateReceived', filterPlaceholder: "Ex: \"07-20-20 03:32 AM\"" }, - ] - - const options = { - "filtering": true, - "paging": false, - "search": false, - "draggable": false, - "padding": "dense", - } - - const history = useHistory(); - - return ( - { - history.push(`/${rowData.queue}/${rowData.number}`); - }} - /> - ); -} +import ItemTableFilter from "../ItemTableFilter/" -ItemTable.propTypes = { +export default function ItemTable({ items, onRowClick }) { + + const theme = useTheme(); + const useStyles = makeStyles({ + // Fully visible for active icons + activeSortIcon: { + opacity: 1, + }, + // Half visible for inactive icons + inactiveSortIcon: { + opacity: 0.2, + }, + bandedRows: { + '&:nth-of-type(even)': { + backgroundColor: theme.palette.type === 'light' ? theme.palette.grey[50] : theme.palette.grey[700], + }, + }, + }); + const classes = useStyles(); + + const history = useHistory(); + + const columns = React.useMemo( + () => [ + { Header: 'Queue', accessor: 'queue', }, + { Header: 'Item #', accessor: 'number' }, + { Header: 'Assigned To', accessor: 'assignedTo' }, + { Header: 'Subject', accessor: 'subject' }, + { Header: 'Status', accessor: 'status', }, + { Header: 'Priority', accessor: 'priority' }, + { Header: 'Last Updated', accessor: 'lastUpdated' }, + { Header: 'Department', accessor: 'department' }, + { Header: 'Building', accessor: 'building' }, + { Header: 'Date Received', accessor: 'dateReceived' }, + ], []); - /** Array of items from all active queues to display in table. */ - "items": PropTypes.array.isRequired - -} + const tableInstance = () => useTable( + { + columns, + data, + defaultColumn: { + Filter: ({ column: { Header, setFilter } }) => { + return ( + setFilter(event.target.value)} + /> + ); + } + } + }, + useFilters, useFlexLayout, useSortBy + ); + const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = tableInstance(); + + return ( + + + + {headerGroups.map(headerGroup => ( + + {headerGroup.headers.map(column => ( + + + + + {column.render("Filter")} + + + + + + + + + + ))} + + ))} + + + {rows.map((row, i) => { + prepareRow(row); + return ( + + {row.cells.map(cell => ( + + {cell.render("Cell")} + + ))} + + ); + })} + +
+
+ ); +}; + +ItemTable.propTypes = { + /** Array of items from all active queues to display in table. */ + "items": PropTypes.array.isRequi +}; \ No newline at end of file diff --git a/src/components/ItemTableFilter/ItemTableFilter.js b/src/components/ItemTableFilter/ItemTableFilter.js new file mode 100644 index 0000000..cf03ea7 --- /dev/null +++ b/src/components/ItemTableFilter/ItemTableFilter.js @@ -0,0 +1,57 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { TextField, useTheme, makeStyles } from "@material-ui/core"; +import { yellow } from '@material-ui/core/colors'; + +export default function ItemTableFilter({ label, onChange }) { + const theme = useTheme(); + const useStyles = makeStyles({ + root: { + '& label.Mui-focused': { + color: theme.palette.type === "light" ? "black" : "white", + }, + '& .MuiOutlinedInput-root': { + '& fieldset': { + borderColor: theme.palette.type === "light" ? theme.palette.action.disabled : "white", + }, + '&:hover fieldset': { + borderColor: theme.palette.type === "light" ? "black" : "white", + }, + '&.Mui-focused fieldset': { + borderColor: theme.palette.type === "light" ? "black" : "white", + }, + '&.Mui-focused label': { + borderColor: theme.palette.type === "light" ? "black" : "white", + }, + }, + }, + }); + + const classes = useStyles(); + + return ( + <> + + + ); + +}; + +ItemTableFilter.propTypes = { + /** The label that appears inside the search box. */ + "label": PropTypes.string, + /** The callback function that sets a column's filter value. */ + "onChange": PropTypes.func.isRequired +}; + +ItemTableFilter.defaultProps = { + "label": "" +} \ No newline at end of file diff --git a/src/components/ItemTableFilter/ItemTableFilter.md b/src/components/ItemTableFilter/ItemTableFilter.md new file mode 100644 index 0000000..d83faec --- /dev/null +++ b/src/components/ItemTableFilter/ItemTableFilter.md @@ -0,0 +1,22 @@ +This ItemTableFilter double as a column header and entry box for filtering in a column. At its core, it is a input element of type search. + +```jsx +import { Paper, makeStyles } from "@material-ui/core"; +import ItemTableFilter from "./ItemTableFilter"; + +const useStyles = makeStyles({ + "paper": { + width: "200px", + } +}); + +const classes = useStyles(); + + + null} /> + +``` + +```jsx static + null} /> +``` \ No newline at end of file diff --git a/src/components/ItemTableFilter/index.js b/src/components/ItemTableFilter/index.js new file mode 100644 index 0000000..e97c772 --- /dev/null +++ b/src/components/ItemTableFilter/index.js @@ -0,0 +1 @@ +export { default } from "./ItemTableFilter"; \ No newline at end of file diff --git a/src/components/ItemView/ItemView.js b/src/components/ItemView/ItemView.js index dc0ba21..1a9eacf 100644 --- a/src/components/ItemView/ItemView.js +++ b/src/components/ItemView/ItemView.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from "prop-types"; -import { Paper, Typography, makeStyles } from '@material-ui/core'; +import { Paper, makeStyles } from '@material-ui/core'; import ItemMetadataView from "../ItemMetadataView/" +import ItemBodyView from "../ItemBodyView"; export default function ItemView({ activeItem }){ @@ -15,14 +16,8 @@ export default function ItemView({ activeItem }){ return( - - - - {activeItem["content"] ? activeItem["content"].map(line => ( - - {line} - - )): "" } + + ); }; diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js new file mode 100644 index 0000000..9a56370 --- /dev/null +++ b/src/components/UserAvatar/UserAvatar.js @@ -0,0 +1,21 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Avatar } from "@material-ui/core"; + +export default function UserAvatar({userName, userAlias}){ + + return( + + {userName === "" ? null : userName.charAt(0)} + + ); +}; + +UserAvatar.propTypes = { + /** The name of the user. */ + "userName": PropTypes.string +}; + +UserAvatar.defaultProps = { + "userName": "" +}; \ No newline at end of file diff --git a/src/components/UserAvatar/UserAvatar.md b/src/components/UserAvatar/UserAvatar.md new file mode 100644 index 0000000..40c9a48 --- /dev/null +++ b/src/components/UserAvatar/UserAvatar.md @@ -0,0 +1,23 @@ +The UserAvatar displays a graphical representation of a person and is meant to be used in conjunction with other identifiers like names or emails. + +--- + +The UserAvatar will the first letter of the `userName` prop. +```jsx +import UserAvatar from "./UserAvatar"; + +``` + +```jsx static + +``` + +If no value, a null value, or an empty string is passed to the UserAvatar, it will fall back to a generic icon. +```jsx +import UserAvatar from "./UserAvatar"; + +``` + +```jsx static + +``` \ No newline at end of file diff --git a/src/components/UserAvatar/index.js b/src/components/UserAvatar/index.js new file mode 100644 index 0000000..3f9a167 --- /dev/null +++ b/src/components/UserAvatar/index.js @@ -0,0 +1,3 @@ +import UserAvatar from "./UserAvatar"; + +export default UserAvatar; \ No newline at end of file diff --git a/src/theme.js b/src/theme.js index 37236ff..459372e 100644 --- a/src/theme.js +++ b/src/theme.js @@ -1,3 +1,4 @@ +import { cyan, deepOrange, deepPurple, lightGreen, lightBlue, teal, purple } from '@material-ui/core/colors'; import { createMuiTheme } from '@material-ui/core/styles' /** @@ -8,12 +9,22 @@ import { createMuiTheme } from '@material-ui/core/styles' * @param {boolean} [darkMode=false] Whether theme should be dark or not. * @returns {Theme} MUI Theme. */ -export default function theme(darkMode=false){ +export default function theme(darkMode = false) { return ( createMuiTheme({ "palette": { + primary: deepPurple, + + secondary: { + main: teal[200], + }, + "type": darkMode ? "dark" : "light", - } + + "edit": { + main: "#ffe56433", + } + }, }) ); } \ No newline at end of file