diff --git a/package-lock.json b/package-lock.json index fca3d27..932eb71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1245,31 +1245,24 @@ } }, "@fortawesome/fontawesome-common-types": { - "version": "0.2.34", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.34.tgz", - "integrity": "sha512-XcIn3iYbTEzGIxD0/dY5+4f019jIcEIWBiHc3KrmK/ROahwxmZ/s+tdj97p/5K0klz4zZUiMfUlYP0ajhSJjmA==" + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz", + "integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw==" }, "@fortawesome/fontawesome-svg-core": { - "version": "1.2.34", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.34.tgz", - "integrity": "sha512-0KNN0nc5eIzaJxlv43QcDmTkDY1CqeN6J7OCGSs+fwGPdtv0yOQqRjieopBCmw+yd7uD3N2HeNL3Zm5isDleLg==", + "version": "1.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz", + "integrity": "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==", "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.34" - }, - "dependencies": { - "@fortawesome/fontawesome-common-types": { - "version": "0.2.34", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.34.tgz", - "integrity": "sha512-XcIn3iYbTEzGIxD0/dY5+4f019jIcEIWBiHc3KrmK/ROahwxmZ/s+tdj97p/5K0klz4zZUiMfUlYP0ajhSJjmA==" - } + "@fortawesome/fontawesome-common-types": "^0.2.35" } }, "@fortawesome/free-solid-svg-icons": { - "version": "5.15.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.2.tgz", - "integrity": "sha512-ZfCU+QjaFsdNZmOGmfqEWhzI3JOe37x5dF4kz9GeXvKn/sTxhqMtZ7mh3lBf76SvcYY5/GKFuyG7p1r4iWMQqw==", + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz", + "integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==", "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.34" + "@fortawesome/fontawesome-common-types": "^0.2.35" } }, "@fortawesome/react-fontawesome": { @@ -4205,9 +4198,9 @@ } }, "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, "clean-css": { "version": "4.2.3", @@ -4975,9 +4968,9 @@ } }, "d3": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-6.6.0.tgz", - "integrity": "sha512-fWyMfZDSOLksXeYuiHM/uHap7pKgypUnOGY8jiTfmmAWH1HM6ErPtnHiKEdqs7DtZqbombUgaKwq3B5Pjm7GOQ==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-6.7.0.tgz", + "integrity": "sha512-hNHRhe+yCDLUG6Q2LwvR/WdNFPOJQ5VWqsJcwIYVeI401+d2/rrCjxSXkiAdIlpx7/73eApFB4Olsmh3YN7a6g==", "requires": { "d3-array": "2", "d3-axis": "2", @@ -5025,16 +5018,19 @@ } }, "d3-time": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.0.0.tgz", - "integrity": "sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "requires": { + "d3-array": "2" + } } } }, "d3-array": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.0.tgz", - "integrity": "sha512-T6H/qNldyD/1OlRkJbonb3u3MPhNwju8OPxYv0YSjDb/B2RUeeBEHzIpNrYiinwpmz8+am+puMrpcrDWgY9wRg==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", "requires": { "internmap": "^1.0.0" } @@ -5186,15 +5182,25 @@ "integrity": "sha512-0D9P8TRj6qDAtHhRQn6EfdOtHMfsUWanl3yb/84C4DqpZ+VsgfI5iTVRNRbELCfNvRfpMr8OrqqUTQ6ANGCijw==" }, "d3-scale": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.3.tgz", - "integrity": "sha512-8E37oWEmEzj57bHcnjPVOBS3n4jqakOeuv1EDdQSiSrYnMCBdMd3nc4HtKk7uia8DUHcY/CGuJ42xxgtEYrX0g==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", "requires": { "d3-array": "^2.3.0", "d3-format": "1 - 2", "d3-interpolate": "1.2.0 - 2", - "d3-time": "1 - 2", + "d3-time": "^2.1.1", "d3-time-format": "2 - 3" + }, + "dependencies": { + "d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "requires": { + "d3-array": "2" + } + } } }, "d3-scale-chromatic": { @@ -7765,9 +7771,9 @@ "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, "highlight.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.6.0.tgz", - "integrity": "sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ==" + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", + "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==" }, "history": { "version": "4.10.1", @@ -10901,12 +10907,12 @@ } }, "lowlight": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.19.0.tgz", - "integrity": "sha512-NIskvQ1d1ovKyUytkMpT8+8Bhq3Ub54os1Xp4RAC9uNbXH1YVRf5NERq7JNzapEe5BzUc1Cj4F0I+eLBBFj6hA==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", "requires": { "fault": "^1.0.0", - "highlight.js": "~10.6.0" + "highlight.js": "~10.7.0" } }, "lru-cache": { @@ -13456,9 +13462,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13481,9 +13487,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13496,9 +13502,9 @@ } }, "rc-slider": { - "version": "9.7.1", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.1.tgz", - "integrity": "sha512-r9r0dpFA3PEvxBhIfVi1lVzxuSogWxeY+tGvi2AqMM1rPgaOXQ7WbtT+9kVFkJ9K8TntA/vYPgiCCKfN29KTkw==", + "version": "9.7.2", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.2.tgz", + "integrity": "sha512-mVaLRpDo6otasBs6yVnG02ykI3K6hIrLTNfT5eyaqduFv95UODI9PDS6fWuVVehVpdS4ENgOSwsTjrPVun+k9g==", "requires": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", @@ -13508,9 +13514,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13523,18 +13529,18 @@ } }, "rc-tooltip": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.0.1.tgz", - "integrity": "sha512-3AnxhUS0j74xAV3khrKw8o6rg+Ima3nw09DJBezMPnX3ImQUAnayWsPSlN1mEnihjA43rcFkGM1emiKE+CXyMQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.0.tgz", + "integrity": "sha512-pFqD1JZwNIpbdcefB7k5xREoHAWM/k3yQwYF0iminbmDXERgq4rvBfUwIvlCqqZSM7HDr9hYeYr6ZsVNaKtvCQ==", "requires": { "@babel/runtime": "^7.11.2", "rc-trigger": "^5.0.0" }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13547,9 +13553,9 @@ } }, "rc-trigger": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.0.tgz", - "integrity": "sha512-fpC1ZkM/IgIIDfF6XHx3Hb2zXy9wvdI5eMh+6DdLygk6Z3HGmkri6ZCXg9a0wfF9AFuzlYTeBLS1uRASZRsnMQ==", + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.5.tgz", + "integrity": "sha512-RlF5RpWqK+JeiFeQVOzwjLFzpNe2FowoXc/42azz+20wr/bYF1Q/MwprUK+3+vs/oFhLC0ht3/NlrslAo/OoWA==", "requires": { "@babel/runtime": "^7.11.2", "classnames": "^2.2.6", @@ -13559,9 +13565,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13574,9 +13580,9 @@ } }, "rc-util": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.6.6.tgz", - "integrity": "sha512-GLAqlODTuVu4V5dZpcDhM7i1pM0BCck2i5u1tW7PO0ZlmX385BhCJOWKqpJXvv4oh3rR5iC2zsJgb1B8hU5FJw==", + "version": "5.9.8", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.9.8.tgz", + "integrity": "sha512-typLSHYGf5irvGLYQshs0Ra3aze086h0FhzsAkyirMunYZ7b3Te8gKa5PVaanoHaZa9sS6qx98BxgysoRP+6Tw==", "requires": { "@babel/runtime": "^7.12.5", "react-is": "^16.12.0", @@ -13584,9 +13590,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -13612,9 +13618,9 @@ } }, "react": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", - "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -13905,13 +13911,13 @@ } }, "react-dom": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", - "integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "scheduler": "^0.20.1" + "scheduler": "^0.20.2" } }, "react-draggable": { @@ -15148,9 +15154,9 @@ } }, "scheduler": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.1.tgz", - "integrity": "sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -16178,9 +16184,9 @@ } }, "swagger-client": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.13.1.tgz", - "integrity": "sha512-Hmy4+wVVa3kveWzC7PIeUwiAY5qcYbm4XlC4uZ7e5kAePfB2cprXImiqrZHIzL+ndU0YTN7I+9w/ZayTisn3Jg==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.13.2.tgz", + "integrity": "sha512-kamtyXtmbZiA2C5YTVqJYgoPJgzqtM5RbeP23Rt/YPYjMArTKZ2fjx1UTsI0aSbws0GluU5pVHiGp8YMciSUfw==", "requires": { "@babel/runtime-corejs3": "^7.11.2", "btoa": "^1.2.1", @@ -16213,26 +16219,29 @@ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==" + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "requires": { + "side-channel": "^1.0.4" + } } } }, "swagger-ui-react": { - "version": "3.45.0", - "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-3.45.0.tgz", - "integrity": "sha512-wCoZEWfhg6/6u0sY2Kks1zDua2aMQnSMnS10/N/40G4h2SGr6Qfqex5ca5uaJvprpLLIPUv4BcRHs++ZTxjK4A==", + "version": "3.47.1", + "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-3.47.1.tgz", + "integrity": "sha512-KPfhRE3kJnN9/yKrPIvKNrZYzGxSLQOEc0gVUlYXrMh6iQ5rR/fW8s9xXCV0ivOOvhvr09LQ5H3ZjwAIbvUHoA==", "requires": { - "@babel/runtime-corejs3": "^7.13.9", + "@babel/runtime-corejs3": "^7.13.10", "@braintree/sanitize-url": "^5.0.0", "@kyleshockey/object-assign-deep": "^0.4.2", "@kyleshockey/xml": "^1.0.2", "base64-js": "^1.5.1", - "classnames": "^2.2.6", + "classnames": "^2.3.1", "css.escape": "1.5.1", "deep-extend": "0.6.0", - "dompurify": "^2.2.6", + "dompurify": "^2.2.7", "ieee754": "^1.2.1", "immutable": "^3.x.x", "js-file-download": "^0.4.12", @@ -16255,7 +16264,7 @@ "reselect": "^4.0.0", "serialize-error": "^2.1.0", "sha.js": "^2.4.11", - "swagger-client": "^3.13.1", + "swagger-client": "^3.13.2", "url-parse": "^1.5.1", "xml-but-prettier": "^1.0.1", "zenscroll": "^4.0.2" @@ -16794,9 +16803,9 @@ } }, "typescript": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", - "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==" + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" }, "ua-parser-js": { "version": "0.7.24", @@ -17653,8 +17662,7 @@ }, "ssri": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "resolved": "", "requires": { "figgy-pudding": "^3.5.1" } @@ -18442,9 +18450,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "yallist": { "version": "4.0.0", diff --git a/package.json b/package.json index f7ba094..775dc24 100644 --- a/package.json +++ b/package.json @@ -3,17 +3,17 @@ "version": "0.1.0", "private": true, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^1.2.34", - "@fortawesome/free-solid-svg-icons": "^5.15.2", + "@fortawesome/fontawesome-svg-core": "^1.2.35", + "@fortawesome/free-solid-svg-icons": "^5.15.3", "@fortawesome/react-fontawesome": "^0.1.14", "@rjsf/core": "^2.5.1", "babel-runtime": "^6.26.0", "bootstrap": "^4.6.0", - "classnames": "^2.2.6", - "d3": "^6.6.0", - "d3-array": "^2.12.0", + "classnames": "^2.3.1", + "d3": "^6.7.0", + "d3-array": "^2.12.1", "d3-axis": "^2.1.0", - "d3-scale": "^3.2.3", + "d3-scale": "^3.3.0", "d3-scale-chromatic": "^2.0.0", "d3-selection": "^2.0.0", "d3-shape": "^2.1.0", @@ -33,15 +33,15 @@ "multiselect-react-dropdown": "^1.6.11", "popper.js": "^1.16.1", "prop-types": "^15.7.2", - "rc-slider": "^9.7.1", - "react": "^17.0.1", + "rc-slider": "^9.7.2", + "react": "^17.0.2", "react-bootstrap": "^1.5.2", "react-collapse": "^5.1.0", "react-color": "^2.19.3", "react-contexify": "^5.0.0", "react-dnd": "^13.1.1", "react-dnd-html5-backend": "^12.1.1", - "react-dom": "^17.0.1", + "react-dom": "^17.0.2", "react-fullscreenable": "^2.5.1-0", "react-grid-system": "^7.1.2", "react-json-view": "^1.21.3", @@ -52,8 +52,8 @@ "react-svg-pan-zoom": "^3.10.0", "react-trafficlight": "^5.2.1", "superagent": "^6.1.0", - "swagger-ui-react": "^3.45.0", - "typescript": "^4.2.3" + "swagger-ui-react": "^3.47.1", + "typescript": "^4.2.4" }, "devDependencies": {}, "scripts": { diff --git a/src/common/icon-button.js b/src/common/icon-button.js index a905dd1..2a65b95 100644 --- a/src/common/icon-button.js +++ b/src/common/icon-button.js @@ -25,31 +25,32 @@ import Icon from '../common/icon'; class IconButton extends React.Component { render() { - const altButtonStyle = { - marginLeft: '10px', + let btn = + + let button; + if (!this.props.tooltip || this.props.hidetooltip) { + button = btn; + } else { + button = {this.props.tooltip}} > + {btn} + } - const iconStyle = { - height: '30px', - width: '30px' - } - - return {this.props.tooltip}} > - - + return button; } } diff --git a/src/common/icon-toggle-button.js b/src/common/icon-toggle-button.js new file mode 100644 index 0000000..e9adc8a --- /dev/null +++ b/src/common/icon-toggle-button.js @@ -0,0 +1,62 @@ +/** + * This file is part of VILLASweb. + * + * VILLASweb is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * VILLASweb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with VILLASweb. If not, see . + ******************************************************************************/ + +import React from 'react'; + +import { ToggleButton, ButtonGroup, Tooltip, OverlayTrigger } from 'react-bootstrap'; + +import Icon from './icon'; + + +class IconToggleButton extends React.Component { + + render() { + let tooltip = this.props.checked ? this.props.tooltipChecked : this.props.tooltipUnchecked; + + return {tooltip}} > + + + {this.props.checked ? + + : + + } + + + + } +} + +export default IconToggleButton; diff --git a/src/common/table-column.js b/src/common/table-column.js index fb9905a..042010b 100644 --- a/src/common/table-column.js +++ b/src/common/table-column.js @@ -27,7 +27,10 @@ class TableColumn extends Component { deleteButton: false, showDeleteButton: null, exportButton: false, + signalButton: false, duplicateButton: false, + isLocked: null, + locked: false, link: '/', linkKey: '', dataIndex: false, diff --git a/src/common/table.js b/src/common/table.js index dfba04f..8ea1579 100644 --- a/src/common/table.js +++ b/src/common/table.js @@ -20,6 +20,9 @@ import _ from 'lodash'; import { Table, Button, Form, Tooltip, OverlayTrigger } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import Icon from './icon'; +import IconToggleButton from './icon-toggle-button'; +import IconButton from '../common/icon-button'; + class CustomTable extends Component { constructor(props) { @@ -45,6 +48,7 @@ class CustomTable extends Component { static addCell(data, index, child) { // add data to cell let content = null; + let childkey = 0; if ('dataKeys' in child.props) { for (let key of child.props.dataKeys) { @@ -90,7 +94,7 @@ class CustomTable extends Component { onClick={() => child.props.onDownload(contentkey)} disabled={child.props.onDownload == null}> {contentkey + ' '} - + ); }); @@ -125,26 +129,26 @@ class CustomTable extends Component { cell.push(index); } + let isLocked = child.props.locked || (child.props.isLocked != null && child.props.isLocked(index)); + // add buttons - let showEditButton = child.props.showEditButton !== null && child.props.showEditButton !== undefined + let showEditButton = child.props.showEditButton !== null && child.props.showEditButton !== undefined ? child.props.showEditButton(index) : true; if (child.props.editButton && showEditButton) { cell.push( - Edit } - > - - - ); + child.props.onEdit(index)} + variant={'table-control-button'} + />) } if (child.props.checkbox) { @@ -164,89 +168,112 @@ class CustomTable extends Component { ); } + if (child.props.lockButton) { + cell.push( + child.props.onChangeLock(index)} + checked={isLocked} + checkedIcon='lock' + uncheckedIcon='lock-open' + tooltipChecked='Scenario is locked, cannot be edited' + tooltipUnchecked='Scenario is unlocked, can be edited' + disabled={false} + variant={'table-control-button'} + /> + ); + } + if (child.props.exportButton) { cell.push( - Export } - > - - - ); + child.props.onExport(index)} + variant={'table-control-button'} + />); + } + + if (child.props.signalButton) { + cell.push( + child.props.onAutoConf(index)} + variant={'table-control-button'} + />); } if (child.props.duplicateButton) { cell.push( - Duplicate } > - - - ); + child.props.onDuplicate(index)} + variant={'table-control-button'} + />); } if (child.props.addRemoveFilesButton) { cell.push( - Add/remove File(s)} > - - - ); + child.props.onAddRemove(index)} + variant={'table-control-button'} + />); } if (child.props.downloadAllButton) { cell.push( - Download All Files} > - - - ); + child.props.onDownloadAll(index)} + variant={'table-control-button'} + />); } - let showDeleteButton = child.props.showDeleteButton !== null && child.props.showDeleteButton !== undefined + let showDeleteButton = child.props.showDeleteButton !== null && child.props.showDeleteButton !== undefined ? child.props.showDeleteButton(index) : true; if (child.props.deleteButton && showDeleteButton) { cell.push( - Delete } > - - - ); + child.props.onDelete(index)} + variant={'table-control-button'} + />); } return cell; @@ -351,14 +378,14 @@ class CustomTable extends Component { value={cell} onChange={(event) => children[cellIndex].props.onInlineChange(event, rowIndex, cellIndex)} ref={ref => { this.activeInput = ref; }} /> - : + : { cell.map((element, elementIndex) => {element} ) } - } + } }) } diff --git a/src/componentconfig/config-table.js b/src/componentconfig/config-table.js index f18fb6d..665850e 100644 --- a/src/componentconfig/config-table.js +++ b/src/componentconfig/config-table.js @@ -298,6 +298,15 @@ class ConfigTable extends Component { } render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } + return (
{/*Component Configurations table*/} @@ -308,12 +317,20 @@ class ConfigTable extends Component { tooltip='Add Component Configuration' onClick={() => this.addConfig()} icon='plus' + disabled={this.props.locked} + hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> this.setState({ importConfigModal: true })} icon='upload' + disabled={this.props.locked} + hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> @@ -343,6 +360,7 @@ class ConfigTable extends Component { editButton onEdit={index => this.setState({ editOutputSignalsModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} width={150} + locked={this.props.locked} /> this.setState({ editInputSignalsModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} width={150} + locked={this.props.locked} /> this.signalsAutoConf(index)} - width={150} + title='Autoconfigure Signals' + signalButton + onAutoConf={(index) => this.signalsAutoConf(index)} + width={170} + locked={this.props.locked} /> this.setState({ deleteConfigModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} onExport={index => this.exportConfig(index)} onDuplicate={index => this.duplicateConfig(index)} + locked={this.props.locked} /> diff --git a/src/dashboard/dashboard-button-group.js b/src/dashboard/dashboard-button-group.js index be73aad..ddacfa0 100644 --- a/src/dashboard/dashboard-button-group.js +++ b/src/dashboard/dashboard-button-group.js @@ -17,114 +17,77 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Button,OverlayTrigger, Tooltip } from 'react-bootstrap'; -import Icon from "../common/icon"; +import IconButton from '../common/icon-button'; + +const buttonStyle = { + marginLeft: '12px', + height: '44px', + width: '35px', +}; + +const iconStyle = { + height: '25px', + width: '25px' +} + +let buttonkey = 0; class DashboardButtonGroup extends React.Component { - render() { - const buttonStyle = { - marginLeft: '12px', - height: '44px', - width : '35px', - }; - const iconStyle = { - height: '25px', - width : '25px' + getBtn(icon, tooltip, clickFn, locked = false) { + if (locked) { + return + } else { + return } + } + render() { const buttons = []; - let key = 0; - - /*if (this.props.fullscreen) { - return null; - }*/ + buttonkey = 0; if (this.props.editing) { - buttons.push( - Save changes } > - - , - Discard changes } > - - - ); + buttons.push(this.getBtn("save", "Save changes", this.props.onSave)); + buttons.push(this.getBtn("times", "Discard changes", this.props.onCancel)); } else { if (this.props.fullscreen !== true) { - buttons.push( - Change to fullscreen view } > - - - ); + buttons.push(this.getBtn("expand", "Change to fullscreen view", this.props.onFullscreen)); } else { - buttons.push( - Back to normal view } > - - - ); + buttons.push(this.getBtn("compress", "Back to normal view", this.props.onFullscreen)); } if (this.props.paused) { - buttons.push( - Continue simulation } > - - - ); + buttons.push(this.getBtn("play", "Continue simulation", this.props.onUnpause)); } else { - buttons.push( - Pause simulation } > - - - ); + buttons.push(this.getBtn("pause", "Pause simulation", this.props.onPause)); } if (this.props.fullscreen !== true) { - buttons.push( - Add, edit or delete files of scenario }> - - - ); - - buttons.push( - Add, edit or delete input signals }> - - - ); - - buttons.push( - Add, edit or delete output signals }> - - - ); - - buttons.push( - Add widgets and edit layout }> - - - ); + let tooltip = this.props.locked ? "View files of scenario" : "Add, edit or delete files of scenario"; + buttons.push(this.getBtn("file", tooltip, this.props.onEditFiles)); + buttons.push(this.getBtn("sign-in-alt", "Add, edit or delete input signals", this.props.onEditInputSignals, this.props.locked)); + buttons.push(this.getBtn("sign-out-alt", "Add, edit or delete output signals", this.props.onEditOutputSignals, this.props.locked)); + buttons.push(this.getBtn("pen", "Add widgets and edit layout", this.props.onEdit, this.props.locked)); } } diff --git a/src/dashboard/dashboard-table.js b/src/dashboard/dashboard-table.js index cb96fdb..589366b 100644 --- a/src/dashboard/dashboard-table.js +++ b/src/dashboard/dashboard-table.js @@ -137,6 +137,14 @@ class DashboardTable extends Component { } render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } return (
@@ -148,12 +156,20 @@ class DashboardTable extends Component { tooltip='Add Dashboard' onClick={() => this.setState({newDashboardModal: true})} icon='plus' + disabled={this.props.locked} + hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> this.setState({importDashboardModal: true})} icon='upload' + disabled={this.props.locked} + hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> @@ -198,6 +214,7 @@ class DashboardTable extends Component { })} onExport={index => this.exportDashboard(index)} onDuplicate={index => this.duplicateDashboard(index)} + locked={this.props.locked} /> diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index 7eebb2a..ee838f3 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -27,6 +27,7 @@ import WidgetContextMenu from '../widget/widget-context-menu'; import WidgetToolbox from '../widget/widget-toolbox'; import WidgetArea from '../widget/widget-area'; import DashboardButtonGroup from './dashboard-button-group'; +import IconToggleButton from '../common/icon-toggle-button'; import DashboardStore from './dashboard-store'; import SignalStore from '../signal/signal-store' @@ -35,6 +36,8 @@ import WidgetStore from '../widget/widget-store'; import ICStore from '../ic/ic-store' import ConfigStore from '../componentconfig/config-store' import AppDispatcher from '../common/app-dispatcher'; +import ScenarioStore from '../scenario/scenario-store'; + import 'react-contexify/dist/ReactContexify.min.css'; import WidgetContainer from '../widget/widget-container'; @@ -45,7 +48,7 @@ class Dashboard extends Component { static lastWidgetKey = 0; static webSocketsOpened = false; static getStores() { - return [DashboardStore, FileStore, WidgetStore, SignalStore, ConfigStore, ICStore]; + return [DashboardStore, FileStore, WidgetStore, SignalStore, ConfigStore, ICStore, ScenarioStore]; } static calculateState(prevState, props) { @@ -80,9 +83,14 @@ class Dashboard extends Component { // filter component configurations to the ones that belong to this scenario let configs = []; let files = []; + let locked = false; if (dashboard !== undefined) { configs = ConfigStore.getState().filter(config => config.scenarioID === dashboard.scenarioID); files = FileStore.getState().filter(file => file.scenarioID === dashboard.scenarioID); + let scenario = ScenarioStore.getState().find(s => s.id === dashboard.scenarioID); + if (scenario) { + locked = scenario.isLocked; + } if (dashboard.height === 0) { dashboard.height = 400; } @@ -144,6 +152,7 @@ class Dashboard extends Component { widgetOrigIDs: prevState.widgetOrigIDs || [], maxWidgetHeight: maxHeight || null, + locked, }; } @@ -216,6 +225,13 @@ class Dashboard extends Component { param: '?scenarioID=' + this.state.dashboard.scenarioID, token: this.state.sessionToken }); + + // load scenario for 'isLocked' value + AppDispatcher.dispatch({ + type: 'scenarios/start-load', + data: this.state.dashboard.scenarioID, + token: this.state.sessionToken + }); } } @@ -482,6 +498,15 @@ class Dashboard extends Component { return
{"Loading Dashboard..."}
} + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '25px', + width: '25px' + } + const grid = this.state.dashboard.grid; const boxClasses = classNames('section', 'box', { 'fullscreen-padding': this.props.isFullscreen }); let draggable = this.state.editing; @@ -489,10 +514,26 @@ class Dashboard extends Component { return (
-

{this.state.dashboard.name}

+

+ {this.state.dashboard.name} + + + +

this.onClose()} blendOutCancel = {true} @@ -139,6 +141,7 @@ class EditFilesDialog extends React.Component { onDelete={(index) => this.deleteFile(index)} editButton onEdit={index => this.setState({ editModal: true, modalFile: this.props.files[index] })} + locked={this.props.locked} /> @@ -146,13 +149,17 @@ class EditFilesDialog extends React.Component {
Add file
- this.selectUploadFile(event)} /> + this.selectUploadFile(event)} + disabled={this.props.locked} + /> diff --git a/src/result/result-table.js b/src/result/result-table.js index 92b8b62..a38d160 100644 --- a/src/result/result-table.js +++ b/src/result/result-table.js @@ -154,19 +154,31 @@ class ResultTable extends Component { } render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } return (
{/*Result table*/}

Results - + this.setState({ newResultModal: true })} icon='plus' + disabled={this.props.locked} + hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> - +

@@ -208,6 +220,7 @@ class ResultTable extends Component { onEdit={index => this.setState({ editResultsModal: true, modalResultsIndex: index })} onDownloadAll={(index) => this.downloadResultData(this.props.results[index])} onDelete={(index) => this.setState({ deleteResultsModal: true, modalResultsData: this.props.results[index], modalResultsIndex: index })} + locked={this.props.locked} />
diff --git a/src/scenario/scenario-users-table.js b/src/scenario/scenario-users-table.js index c93b356..26eb06f 100644 --- a/src/scenario/scenario-users-table.js +++ b/src/scenario/scenario-users-table.js @@ -16,11 +16,11 @@ ******************************************************************************/ import React, {Component} from "react"; -import {Button, Form, InputGroup} from "react-bootstrap"; +import { Form, InputGroup} from "react-bootstrap"; import {Redirect} from "react-router-dom"; import Table from "../common/table"; import TableColumn from "../common/table-column"; -import Icon from "../common/icon"; +import IconButton from "../common/icon-button"; import DeleteDialog from "../common/dialogs/delete-dialog"; import AppDispatcher from "../common/app-dispatcher"; @@ -82,15 +82,6 @@ class ScenarioUsersTable extends Component { return (); } - const altButtonStyle = { - marginLeft: '10px', - } - - const iconStyle = { - height: '30px', - width: '30px' - } - return (
{/*Scenario Users table*/} @@ -124,6 +115,7 @@ class ScenarioUsersTable extends Component { deleteUserName: this.props.scenario.users[index].username, modalUserIndex: index })} + locked={this.props.locked} /> @@ -141,13 +133,14 @@ class ScenarioUsersTable extends Component { /> - + this.addUser()} + icon='plus' + disabled={this.props.locked} + hidetooltip={this.props.locked} + /> diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 1e1033c..ac618d7 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -20,6 +20,7 @@ import { Container } from 'flux/utils'; import AppDispatcher from '../common/app-dispatcher'; import IconButton from '../common/icon-button'; +import IconToggleButton from '../common/icon-toggle-button'; import ScenarioStore from './scenario-store'; import ICStore from '../ic/ic-store'; @@ -70,26 +71,24 @@ class Scenario extends React.Component { } componentDidMount() { - - let token = localStorage.getItem("token") let scenarioID = parseInt(this.props.match.params.scenario, 10) //load selected scenario AppDispatcher.dispatch({ type: 'scenarios/start-load', data: scenarioID, - token: token + token: this.state.sessionToken }); AppDispatcher.dispatch({ type: 'scenarios/start-load-users', data: scenarioID, - token: token + token: this.state.sessionToken }); // load ICs to enable that component configs and dashboards work with them AppDispatcher.dispatch({ type: 'ics/start-load', - token: token + token: this.state.sessionToken }); } @@ -112,11 +111,35 @@ class Scenario extends React.Component { this.setState({ filesEditModal: false }); } + /* ############################################## + * Change locked state of scenario + ############################################## */ + + onChangeLock() { + let data = {}; + data.id = this.state.scenario.id; + data.isLocked = !this.state.scenario.isLocked; + + AppDispatcher.dispatch({ + type: 'scenarios/start-edit', + data, + token: this.state.sessionToken + }); + } + /* ############################################## * Render method ############################################## */ render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } const tableHeadingStyle = { paddingTop: '30px' @@ -126,16 +149,36 @@ class Scenario extends React.Component { return

Loading Scenario...

; } + let tooltip = this.state.scenario.isLocked ? "View files of scenario" : "Add, edit or delete files of scenario"; + return
-

{this.state.scenario.name}

+

+ {this.state.scenario.name} + + this.onChangeLock()} + checked={this.state.scenario.isLocked} + checkedIcon='lock' + uncheckedIcon='lock-open' + tooltipChecked='Scenario is locked, cannot be edited' + tooltipUnchecked='Scenario is unlocked, can be edited' + disabled={this.state.currentUser.role !== "Admin"} + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> + +

diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 9d81a74..89b52d9 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -73,7 +73,7 @@ class Scenarios extends Component { } closeNewModal(data) { - if(data) { + if (data) { AppDispatcher.dispatch({ type: 'scenarios/start-add', data: data, @@ -218,7 +218,7 @@ class Scenarios extends Component { jsonObj["configs"] = this.getConfigs(scenario.id); jsonObj["dashboards"] = this.getDashboards(scenario.id); - if(jsonObj) { + if (jsonObj) { AppDispatcher.dispatch({ type: 'scenarios/start-add', data: jsonObj, @@ -227,68 +227,99 @@ class Scenarios extends Component { } } - modifyRunningColumn(running){ - return + isLocked(index) { + return this.state.scenarios[index].isLocked; + } + + onLock(index) { + let data = {}; + data.id = this.state.scenarios[index].id; + data.isLocked = !this.state.scenarios[index].isLocked; + + AppDispatcher.dispatch({ + type: 'scenarios/start-edit', + data, + token: this.state.sessionToken + }); } render() { + const buttonStyle = { + marginLeft: '10px', + } + + const iconStyle = { + height: '30px', + width: '30px' + } + return
-

Scenarios +

Scenarios - this.setState({ newModal: true })} - icon='plus' - /> - this.setState({ importModal: true })} - icon='upload' - /> - -

- - - {this.state.currentUser.role === "Admin" ? - - : <> - } - this.setState({ newModal: true })} + icon='plus' + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> - this.modifyRunningColumn(running)} + this.setState({ importModal: true })} + icon='upload' + buttonStyle={buttonStyle} + iconStyle={iconStyle} /> + + + +
+ {this.state.currentUser.role === "Admin" ? this.setState({ editModal: true, modalScenario: this.state.scenarios[index] })} - onDelete={index => this.setState({ deleteModal: true, modalScenario: this.state.scenarios[index] })} - onExport={index => this.exportScenario(index)} - onDuplicate={index => this.duplicateScenario(index)} + title='ID' + dataKey='id' /> -
+ : <> + } + + {this.state.currentUser.role === "Admin" ? + this.onLock(index)} + isLocked={index => this.isLocked(index)} + /> + : <> + } + this.setState({ editModal: true, modalScenario: this.state.scenarios[index] })} + onDelete={index => this.setState({ deleteModal: true, modalScenario: this.state.scenarios[index] })} + onExport={index => this.exportScenario(index)} + onDuplicate={index => this.duplicateScenario(index)} + isLocked={index => this.isLocked(index)} + /> + - this.closeNewModal(data)} /> - this.closeEditModal(data)} scenario={this.state.modalScenario} /> - this.closeImportModal(data)} nodes={this.state.nodes} /> + this.closeNewModal(data)} /> + this.closeEditModal(data)} scenario={this.state.modalScenario} /> + this.closeImportModal(data)} nodes={this.state.nodes} /> - this.closeDeleteModal(e)} /> -
; + this.closeDeleteModal(e)} /> +
; } }