mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
Merge branch 'master' into feature-use-json-schema
This commit is contained in:
commit
ec6887d8a8
15 changed files with 630 additions and 394 deletions
212
package-lock.json
generated
212
package-lock.json
generated
|
@ -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",
|
||||
|
|
22
package.json
22
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": {
|
||||
|
|
|
@ -25,31 +25,32 @@ import Icon from '../common/icon';
|
|||
class IconButton extends React.Component {
|
||||
|
||||
render() {
|
||||
const altButtonStyle = {
|
||||
marginLeft: '10px',
|
||||
let btn = <Button
|
||||
variant={this.props.variant ? this.props.variant : 'light'}
|
||||
disabled={this.props.disabled}
|
||||
onClick={this.props.onClick}
|
||||
style={this.props.buttonStyle}
|
||||
>
|
||||
<Icon
|
||||
icon={this.props.icon}
|
||||
classname={'icon-color'}
|
||||
style={this.props.iconStyle}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
let button;
|
||||
if (!this.props.tooltip || this.props.hidetooltip) {
|
||||
button = btn;
|
||||
} else {
|
||||
button = <OverlayTrigger
|
||||
key={this.props.ikey}
|
||||
placement={this.props.tipPlacement ? this.props.tipPlacement : 'top'}
|
||||
overlay={<Tooltip id={`tooltip-${this.props.ikey}`}>{this.props.tooltip}</Tooltip>} >
|
||||
{btn}
|
||||
</OverlayTrigger>
|
||||
}
|
||||
|
||||
const iconStyle = {
|
||||
height: '30px',
|
||||
width: '30px'
|
||||
}
|
||||
|
||||
return <OverlayTrigger
|
||||
key={this.props.ikey}
|
||||
placement={'top'}
|
||||
overlay={<Tooltip id={`tooltip-${"add"}`}>{this.props.tooltip}</Tooltip>} >
|
||||
<Button
|
||||
variant='light'
|
||||
onClick={this.props.onClick}
|
||||
style={altButtonStyle}
|
||||
>
|
||||
<Icon
|
||||
icon={this.props.icon}
|
||||
classname={'icon-color'}
|
||||
style={iconStyle}
|
||||
/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
return button;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
62
src/common/icon-toggle-button.js
Normal file
62
src/common/icon-toggle-button.js
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
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 <OverlayTrigger
|
||||
key={this.props.ikey}
|
||||
placement={'top'}
|
||||
overlay={<Tooltip id={`tooltip-${this.props.ikey}`}>{tooltip}</Tooltip>} >
|
||||
<ButtonGroup toggle>
|
||||
<ToggleButton
|
||||
variant={this.props.variant ? this.props.variant : 'light'}
|
||||
type='checkbox'
|
||||
onChange={this.props.onChange}
|
||||
style={this.props.buttonStyle}
|
||||
disabled={this.props.disabled}
|
||||
checked={this.props.checked}
|
||||
>
|
||||
{this.props.checked ?
|
||||
<Icon
|
||||
icon={this.props.checkedIcon}
|
||||
classname={'icon-color'}
|
||||
style={this.props.iconStyle}
|
||||
/>
|
||||
:
|
||||
<Icon
|
||||
icon={this.props.uncheckedIcon}
|
||||
classname={'icon-color'}
|
||||
style={this.props.iconStyle}
|
||||
/>
|
||||
}
|
||||
</ToggleButton>
|
||||
</ButtonGroup>
|
||||
</OverlayTrigger>
|
||||
}
|
||||
}
|
||||
|
||||
export default IconToggleButton;
|
|
@ -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,
|
||||
|
|
|
@ -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 + ' '}
|
||||
<Icon icon='file-download' />
|
||||
<Icon icon='file-download' classname={'icon-color'}/>
|
||||
</Button>
|
||||
</OverlayTrigger>);
|
||||
});
|
||||
|
@ -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(
|
||||
<OverlayTrigger
|
||||
key={0}
|
||||
placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"edit"}`}> Edit </Tooltip>}
|
||||
>
|
||||
<Button
|
||||
variant='table-control-button'
|
||||
onClick={() => child.props.onEdit(index)}
|
||||
disabled={child.props.onEdit == null} >
|
||||
<Icon icon='edit' />
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
<IconButton
|
||||
key={childkey++}
|
||||
ikey={childkey++}
|
||||
icon={'edit'}
|
||||
disabled={child.props.onEdit == null || isLocked}
|
||||
hidetooltip={isLocked}
|
||||
tooltip={"Edit"}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={() => 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(
|
||||
<IconToggleButton
|
||||
ikey={childkey++}
|
||||
onChange={() => 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(
|
||||
<OverlayTrigger
|
||||
key={1}
|
||||
placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"export"}`}> Export </Tooltip>}
|
||||
>
|
||||
<Button
|
||||
variant='table-control-button'
|
||||
onClick={() => child.props.onExport(index)}
|
||||
disabled={child.props.onExport == null}>
|
||||
<Icon icon='download' />
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
<IconButton
|
||||
key={childkey++}
|
||||
ikey={childkey++}
|
||||
icon={'download'}
|
||||
disabled={child.props.onExport == null}
|
||||
tooltip={"Export"}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={() => child.props.onExport(index)}
|
||||
variant={'table-control-button'}
|
||||
/>);
|
||||
}
|
||||
|
||||
if (child.props.signalButton) {
|
||||
cell.push(
|
||||
<IconButton
|
||||
key={childkey++}
|
||||
ikey={childkey++}
|
||||
icon={'wave-square'}
|
||||
disabled={child.props.onAutoConf == null || child.props.locked }
|
||||
hidetooltip={isLocked}
|
||||
tooltip={"Autoconfigure Signals"}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={() => child.props.onAutoConf(index)}
|
||||
variant={'table-control-button'}
|
||||
/>);
|
||||
}
|
||||
|
||||
if (child.props.duplicateButton) {
|
||||
cell.push(
|
||||
<OverlayTrigger
|
||||
key={2}
|
||||
placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"duplicate"}`}> Duplicate </Tooltip>} >
|
||||
<Button
|
||||
variant='table-control-button'
|
||||
onClick={() => child.props.onDuplicate(index)}
|
||||
disabled={child.props.onDuplicate == null}>
|
||||
<Icon icon='copy' />
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
<IconButton
|
||||
key={childkey++}
|
||||
ikey={childkey++}
|
||||
icon={'copy'}
|
||||
disabled={child.props.onDuplicate == null || child.props.locked}
|
||||
hidetooltip={isLocked}
|
||||
tooltip={"Duplicate"}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={() => child.props.onDuplicate(index)}
|
||||
variant={'table-control-button'}
|
||||
/>);
|
||||
}
|
||||
|
||||
if (child.props.addRemoveFilesButton) {
|
||||
cell.push(
|
||||
<OverlayTrigger
|
||||
key={3}
|
||||
placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"export"}`}>Add/remove File(s)</Tooltip>} >
|
||||
<Button
|
||||
variant='table-control-button'
|
||||
onClick={() => child.props.onAddRemove(index)}
|
||||
disabled={child.props.onAddRemove == null}>
|
||||
<Icon icon='file' />
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
<IconButton
|
||||
key={childkey++}
|
||||
ikey={childkey++}
|
||||
icon={'file'}
|
||||
disabled={child.props.onAddRemove == null || isLocked}
|
||||
hidetooltip={isLocked}
|
||||
tooltip={"Add/remove File(s)"}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={() => child.props.onAddRemove(index)}
|
||||
variant={'table-control-button'}
|
||||
/>);
|
||||
}
|
||||
|
||||
if (child.props.downloadAllButton) {
|
||||
cell.push(
|
||||
<OverlayTrigger
|
||||
key={4}
|
||||
placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"export"}`}>Download All Files</Tooltip>} >
|
||||
<Button
|
||||
variant='table-control-button'
|
||||
onClick={() => child.props.onDownloadAll(index)}
|
||||
disabled={child.props.onDownloadAll == null}>
|
||||
<Icon icon='file-download' />
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
<IconButton
|
||||
key={childkey++}
|
||||
ikey={childkey++}
|
||||
icon={'file-download'}
|
||||
disabled={child.props.onDownloadAll == null}
|
||||
tooltip={"Download All Files"}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={() => 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(
|
||||
<OverlayTrigger
|
||||
key={5}
|
||||
placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"delete"}`}> Delete </Tooltip>} >
|
||||
<Button
|
||||
variant='table-control-button'
|
||||
onClick={() => child.props.onDelete(index)}
|
||||
disabled={child.props.onDelete == null}>
|
||||
<Icon icon='trash' />
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
<IconButton
|
||||
key={childkey++}
|
||||
ikey={childkey++}
|
||||
icon={'trash'}
|
||||
disabled={child.props.onDelete == null || isLocked}
|
||||
hidetooltip={isLocked}
|
||||
tooltip={"Delete"}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={() => 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; }} />
|
||||
: <span>
|
||||
: <span>
|
||||
{
|
||||
cell.map((element, elementIndex) =>
|
||||
<span key={elementIndex}>{element}</span>
|
||||
)
|
||||
}
|
||||
</span>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
})
|
||||
}
|
||||
|
|
|
@ -298,6 +298,15 @@ class ConfigTable extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const buttonStyle = {
|
||||
marginLeft: '10px',
|
||||
}
|
||||
|
||||
const iconStyle = {
|
||||
height: '30px',
|
||||
width: '30px'
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/*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}
|
||||
/>
|
||||
<IconButton
|
||||
ikey={1}
|
||||
tooltip='Import Component Configuration'
|
||||
onClick={() => this.setState({ importConfigModal: true })}
|
||||
icon='upload'
|
||||
disabled={this.props.locked}
|
||||
hidetooltip={this.props.locked}
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
</span>
|
||||
</h2>
|
||||
|
@ -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}
|
||||
/>
|
||||
<TableColumn
|
||||
title='# Input Signals'
|
||||
|
@ -350,12 +368,14 @@ class ConfigTable extends Component {
|
|||
editButton
|
||||
onEdit={index => this.setState({ editInputSignalsModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })}
|
||||
width={150}
|
||||
locked={this.props.locked}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Import Signals'
|
||||
exportButton
|
||||
onExport={(index) => this.signalsAutoConf(index)}
|
||||
width={150}
|
||||
title='Autoconfigure Signals'
|
||||
signalButton
|
||||
onAutoConf={(index) => this.signalsAutoConf(index)}
|
||||
width={170}
|
||||
locked={this.props.locked}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Infrastructure Component'
|
||||
|
@ -375,6 +395,7 @@ class ConfigTable extends Component {
|
|||
onDelete={(index) => 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}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
|
|
|
@ -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 <IconButton
|
||||
key={buttonkey++}
|
||||
ikey={buttonkey}
|
||||
icon={icon}
|
||||
disabled={true}
|
||||
hidetooltip={true}
|
||||
tooltip={tooltip}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={clickFn}
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
} else {
|
||||
return <IconButton
|
||||
key={buttonkey++}
|
||||
ikey={buttonkey}
|
||||
icon={icon}
|
||||
tooltip={tooltip}
|
||||
tipPlacement={'bottom'}
|
||||
onClick={clickFn}
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const buttons = [];
|
||||
let key = 0;
|
||||
|
||||
/*if (this.props.fullscreen) {
|
||||
return null;
|
||||
}*/
|
||||
buttonkey = 0;
|
||||
|
||||
if (this.props.editing) {
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"save"}`}> Save changes </Tooltip>} >
|
||||
<Button variant= 'light' size="lg" key={key} onClick={this.props.onSave} style={buttonStyle}>
|
||||
<Icon icon="save" classname='icon-color' style={iconStyle} />
|
||||
</Button>
|
||||
</OverlayTrigger>,
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"cancel"}`}> Discard changes </Tooltip>} >
|
||||
<Button key={key} variant= 'light' size="lg" onClick={this.props.onCancel} style={buttonStyle}>
|
||||
<Icon icon="times" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
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(
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"expand"}`}> Change to fullscreen view </Tooltip>} >
|
||||
<Button key={key} variant= 'light' size="lg" onClick={this.props.onFullscreen} style={buttonStyle}>
|
||||
<Icon icon="expand" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
buttons.push(this.getBtn("expand", "Change to fullscreen view", this.props.onFullscreen));
|
||||
} else {
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"compress"}`}> Back to normal view </Tooltip>} >
|
||||
<Button key={key} variant= 'light' size="lg" onClick={this.props.onFullscreen} style={buttonStyle}>
|
||||
<Icon icon="compress" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
buttons.push(this.getBtn("compress", "Back to normal view", this.props.onFullscreen));
|
||||
}
|
||||
|
||||
if (this.props.paused) {
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"play"}`}> Continue simulation </Tooltip>} >
|
||||
<Button key={key} variant= 'light' size="lg" onClick={this.props.onUnpause} style={buttonStyle}>
|
||||
<Icon icon="play" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
buttons.push(this.getBtn("play", "Continue simulation", this.props.onUnpause));
|
||||
} else {
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"pause"}`}> Pause simulation </Tooltip>} >
|
||||
<Button key={key} variant= 'light' size="lg" onClick={this.props.onPause} style={buttonStyle}>
|
||||
<Icon icon="pause" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
buttons.push(this.getBtn("pause", "Pause simulation", this.props.onPause));
|
||||
}
|
||||
|
||||
if (this.props.fullscreen !== true) {
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"file"}`}> Add, edit or delete files of scenario </Tooltip>}>
|
||||
<Button key={key} variant='light' size="lg" onClick={this.props.onEditFiles} style={buttonStyle}>
|
||||
<Icon icon="file" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'} overlay={<Tooltip id={`tooltip-${"file"}`}> Add, edit or delete input signals </Tooltip>}>
|
||||
<Button key={key} variant='light' size="lg" onClick={this.props.onEditInputSignals} style={buttonStyle}>
|
||||
<Icon icon="sign-in-alt" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"file"}`}> Add, edit or delete output signals </Tooltip>}>
|
||||
<Button key={key} variant='light' size="lg" onClick={this.props.onEditOutputSignals} style={buttonStyle}>
|
||||
<Icon icon="sign-out-alt" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
|
||||
buttons.push(
|
||||
<OverlayTrigger key={key++} placement={'bottom'}
|
||||
overlay={<Tooltip id={`tooltip-${"layout"}`}> Add widgets and edit layout </Tooltip>}>
|
||||
<Button key={key} variant='light' size="lg" onClick={this.props.onEdit} style={buttonStyle}>
|
||||
<Icon icon="pen" classname='icon-color' style={iconStyle}/>
|
||||
</Button>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,6 +137,14 @@ class DashboardTable extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const buttonStyle = {
|
||||
marginLeft: '10px',
|
||||
}
|
||||
|
||||
const iconStyle = {
|
||||
height: '30px',
|
||||
width: '30px'
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -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}
|
||||
/>
|
||||
<IconButton
|
||||
ikey={1}
|
||||
tooltip='Import Dashboard'
|
||||
onClick={() => this.setState({importDashboardModal: true})}
|
||||
icon='upload'
|
||||
disabled={this.props.locked}
|
||||
hidetooltip={this.props.locked}
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
</span>
|
||||
</h2>
|
||||
|
@ -198,6 +214,7 @@ class DashboardTable extends Component {
|
|||
})}
|
||||
onExport={index => this.exportDashboard(index)}
|
||||
onDuplicate={index => this.duplicateDashboard(index)}
|
||||
locked={this.props.locked}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
|
|
|
@ -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 <div className="section-title"> <span>{"Loading Dashboard..."}</span> </div>
|
||||
}
|
||||
|
||||
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 (<div className={boxClasses} >
|
||||
<div className='section-header box-header'>
|
||||
<div className="section-title">
|
||||
<h2>{this.state.dashboard.name}</h2>
|
||||
<h2>
|
||||
{this.state.dashboard.name}
|
||||
<span className='icon-button'>
|
||||
<IconToggleButton
|
||||
ikey={0}
|
||||
checked={this.state.locked}
|
||||
checkedIcon='lock'
|
||||
uncheckedIcon='lock-open'
|
||||
tooltipChecked='Dashboard is locked, cannot be edited'
|
||||
tooltipUnchecked='Dashboard is unlocked, can be edited'
|
||||
disabled={true}
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<DashboardButtonGroup
|
||||
locked={this.state.locked}
|
||||
editing={this.state.editing}
|
||||
onEdit={this.startEditing.bind(this)}
|
||||
fullscreen={this.props.isFullscreen}
|
||||
|
@ -578,6 +619,7 @@ class Dashboard extends Component {
|
|||
signals={this.state.signals}
|
||||
files={this.state.files}
|
||||
scenarioID={this.state.dashboard.scenarioID}
|
||||
locked={this.state.locked}
|
||||
/>
|
||||
|
||||
<EditSignalMappingDialog
|
||||
|
|
|
@ -106,10 +106,12 @@ class EditFilesDialog extends React.Component {
|
|||
marginTop: '-40px'
|
||||
};
|
||||
|
||||
let title = this.props.locked ? "View files of scenario" : "Edit Files of Scenario";
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
show={this.props.show}
|
||||
title="Edit Files of Scenario"
|
||||
title={title}
|
||||
buttonTitle="Close"
|
||||
onClose={() => 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}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
|
@ -146,13 +149,17 @@ class EditFilesDialog extends React.Component {
|
|||
<h5>Add file</h5>
|
||||
<Row>
|
||||
<Col xs lg="4">
|
||||
<Form.Control type='file' onChange={(event) => this.selectUploadFile(event)} />
|
||||
<Form.Control
|
||||
type='file'
|
||||
onChange={(event) => this.selectUploadFile(event)}
|
||||
disabled={this.props.locked}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs lg="2">
|
||||
<span className='solid-button'>
|
||||
<Button
|
||||
variant='secondary'
|
||||
disabled={this.state.uploadFile === null}
|
||||
disabled={this.state.uploadFile === null || this.props.locked}
|
||||
onClick={() => this.startFileUpload()}>
|
||||
Upload
|
||||
</Button>
|
||||
|
|
|
@ -154,19 +154,31 @@ class ResultTable extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const buttonStyle = {
|
||||
marginLeft: '10px',
|
||||
}
|
||||
|
||||
const iconStyle = {
|
||||
height: '30px',
|
||||
width: '30px'
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/*Result table*/}
|
||||
<h2 style={this.props.tableHeadingStyle}>Results
|
||||
<span className='icon-button'>
|
||||
<span className='icon-button'>
|
||||
<IconButton
|
||||
ikey={1}
|
||||
tooltip='Add Result'
|
||||
onClick={() => this.setState({ newResultModal: true })}
|
||||
icon='plus'
|
||||
disabled={this.props.locked}
|
||||
hidetooltip={this.props.locked}
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
<Table data={this.props.results}>
|
||||
|
@ -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}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
|
|
|
@ -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 (<Redirect to="/scenarios" />);
|
||||
}
|
||||
|
||||
const altButtonStyle = {
|
||||
marginLeft: '10px',
|
||||
}
|
||||
|
||||
const iconStyle = {
|
||||
height: '30px',
|
||||
width: '30px'
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/*Scenario Users table*/}
|
||||
|
@ -124,6 +115,7 @@ class ScenarioUsersTable extends Component {
|
|||
deleteUserName: this.props.scenario.users[index].username,
|
||||
modalUserIndex: index
|
||||
})}
|
||||
locked={this.props.locked}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
|
@ -141,13 +133,14 @@ class ScenarioUsersTable extends Component {
|
|||
/>
|
||||
<InputGroup.Append>
|
||||
<span className='icon-button'>
|
||||
<Button
|
||||
variant='light'
|
||||
type="submit"
|
||||
style={altButtonStyle}
|
||||
onClick={() => this.addUser()}>
|
||||
<Icon icon="plus" classname={'icon-color'} style={iconStyle} />
|
||||
</Button>
|
||||
<IconButton
|
||||
ikey={1}
|
||||
tooltip='Add User to Scenario'
|
||||
onClick={() => this.addUser()}
|
||||
icon='plus'
|
||||
disabled={this.props.locked}
|
||||
hidetooltip={this.props.locked}
|
||||
/>
|
||||
</span>
|
||||
</InputGroup.Append>
|
||||
</InputGroup>
|
||||
|
|
|
@ -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 <h1>Loading Scenario...</h1>;
|
||||
}
|
||||
|
||||
let tooltip = this.state.scenario.isLocked ? "View files of scenario" : "Add, edit or delete files of scenario";
|
||||
|
||||
return <div className='section'>
|
||||
<div className='section-buttons-group-right'>
|
||||
<IconButton
|
||||
ikey="0"
|
||||
tooltip="Add, edit or delete files of scenario"
|
||||
tooltip={tooltip}
|
||||
onClick={this.onEditFiles.bind(this)}
|
||||
icon="file"
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
</div>
|
||||
<h1>{this.state.scenario.name}</h1>
|
||||
<h1>
|
||||
{this.state.scenario.name}
|
||||
<span className='icon-button'>
|
||||
<IconToggleButton
|
||||
ikey={0}
|
||||
onChange={() => 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}
|
||||
/>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<EditFilesDialog
|
||||
sessionToken={this.state.sessionToken}
|
||||
|
@ -144,6 +187,7 @@ class Scenario extends React.Component {
|
|||
signals={this.state.signals}
|
||||
files={this.state.files}
|
||||
scenarioID={this.state.scenario.id}
|
||||
locked={this.state.scenario.isLocked}
|
||||
/>
|
||||
|
||||
<ConfigTable
|
||||
|
@ -155,6 +199,7 @@ class Scenario extends React.Component {
|
|||
sessionToken={this.state.sessionToken}
|
||||
currentUser={this.state.currentUser}
|
||||
tableHeadingStyle={tableHeadingStyle}
|
||||
locked={this.state.scenario.isLocked}
|
||||
/>
|
||||
|
||||
<DashboardTable
|
||||
|
@ -164,6 +209,7 @@ class Scenario extends React.Component {
|
|||
sessionToken={this.state.sessionToken}
|
||||
currentUser={this.state.currentUser}
|
||||
tableHeadingStyle={tableHeadingStyle}
|
||||
locked={this.state.scenario.isLocked}
|
||||
/>
|
||||
|
||||
<ResultTable
|
||||
|
@ -172,6 +218,7 @@ class Scenario extends React.Component {
|
|||
scenario={this.state.scenario}
|
||||
sessionToken={this.state.sessionToken}
|
||||
tableHeadingStyle={tableHeadingStyle}
|
||||
locked={this.state.scenario.isLocked}
|
||||
/>
|
||||
|
||||
<ScenarioUsersTable
|
||||
|
@ -179,6 +226,7 @@ class Scenario extends React.Component {
|
|||
currentUser={this.state.currentUser}
|
||||
sessionToken={this.state.sessionToken}
|
||||
tableHeadingStyle={tableHeadingStyle}
|
||||
locked={this.state.scenario.isLocked}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -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 <Icon icon={ running ? 'check' : 'times' } />
|
||||
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 <div className='section'>
|
||||
<h1>Scenarios
|
||||
<h1>Scenarios
|
||||
<span className='icon-button'>
|
||||
<IconButton
|
||||
ikey={0}
|
||||
tooltip='Add Scenario'
|
||||
onClick={() => this.setState({ newModal: true })}
|
||||
icon='plus'
|
||||
/>
|
||||
<IconButton
|
||||
ikey={1}
|
||||
tooltip='Import Scenario'
|
||||
onClick={() => this.setState({ importModal: true })}
|
||||
icon='upload'
|
||||
/>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<Table data={this.state.scenarios}>
|
||||
{this.state.currentUser.role === "Admin" ?
|
||||
<TableColumn
|
||||
title='ID'
|
||||
dataKey='id'
|
||||
/>
|
||||
: <></>
|
||||
}
|
||||
<TableColumn
|
||||
title='Name'
|
||||
dataKey='name'
|
||||
link='/scenarios/'
|
||||
linkKey='id'
|
||||
<IconButton
|
||||
ikey={0}
|
||||
tooltip='Add Scenario'
|
||||
onClick={() => this.setState({ newModal: true })}
|
||||
icon='plus'
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
<TableColumn
|
||||
title='Running'
|
||||
dataKey='running'
|
||||
modifier={(running) => this.modifyRunningColumn(running)}
|
||||
<IconButton
|
||||
ikey={1}
|
||||
tooltip='Import Scenario'
|
||||
onClick={() => this.setState({ importModal: true })}
|
||||
icon='upload'
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<Table data={this.state.scenarios}>
|
||||
{this.state.currentUser.role === "Admin" ?
|
||||
<TableColumn
|
||||
width='200'
|
||||
align='right'
|
||||
editButton
|
||||
deleteButton
|
||||
exportButton
|
||||
duplicateButton
|
||||
onEdit={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)}
|
||||
title='ID'
|
||||
dataKey='id'
|
||||
/>
|
||||
</Table>
|
||||
: <></>
|
||||
}
|
||||
<TableColumn
|
||||
title='Name'
|
||||
dataKey='name'
|
||||
link='/scenarios/'
|
||||
linkKey='id'
|
||||
/>
|
||||
{this.state.currentUser.role === "Admin" ?
|
||||
<TableColumn
|
||||
title='Locked'
|
||||
lockButton
|
||||
checkboxKey='isLocked'
|
||||
onChangeLock={(index, event) => this.onLock(index)}
|
||||
isLocked={index => this.isLocked(index)}
|
||||
/>
|
||||
: <></>
|
||||
}
|
||||
<TableColumn
|
||||
width='200'
|
||||
align='right'
|
||||
editButton
|
||||
deleteButton
|
||||
exportButton
|
||||
duplicateButton
|
||||
onEdit={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)}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
<NewScenarioDialog show={this.state.newModal} onClose={(data) => this.closeNewModal(data)} />
|
||||
<EditScenarioDialog show={this.state.editModal} onClose={(data) => this.closeEditModal(data)} scenario={this.state.modalScenario} />
|
||||
<ImportScenarioDialog show={this.state.importModal} onClose={data => this.closeImportModal(data)} nodes={this.state.nodes} />
|
||||
<NewScenarioDialog show={this.state.newModal} onClose={(data) => this.closeNewModal(data)} />
|
||||
<EditScenarioDialog show={this.state.editModal} onClose={(data) => this.closeEditModal(data)} scenario={this.state.modalScenario} />
|
||||
<ImportScenarioDialog show={this.state.importModal} onClose={data => this.closeImportModal(data)} nodes={this.state.nodes} />
|
||||
|
||||
<DeleteDialog title="scenario" name={this.state.modalScenario.name} show={this.state.deleteModal} onClose={(e) => this.closeDeleteModal(e)} />
|
||||
</div>;
|
||||
<DeleteDialog title="scenario" name={this.state.modalScenario.name} show={this.state.deleteModal} onClose={(e) => this.closeDeleteModal(e)} />
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue