From 6cbdfd263107f796f2dd584d46cfdd6557721260 Mon Sep 17 00:00:00 2001 From: Sergio Betanzos Date: Mon, 7 Jun 2021 13:27:38 +0200 Subject: [PATCH] M #~: Add sockets to listen global events (#1280) --- src/fireedge/package-lock.json | 171 ++++---- src/fireedge/package.json | 4 +- src/fireedge/src/client/actions/general.js | 82 ---- src/fireedge/src/client/actions/pool.js | 139 ------ src/fireedge/src/client/actions/user.js | 54 --- .../client/components/Cards/ProvisionCard.js | 7 +- .../components/Cards/ProvisionTemplateCard.js | 7 +- .../components/Cards/VirtualMachineCard.js | 60 +++ .../src/client/components/Cards/index.js | 2 + .../src/client/components/DebugLog/index.js | 11 +- .../components/Sidebar/SidebarCollapseItem.js | 2 +- src/fireedge/src/client/constants/color.js | 2 +- src/fireedge/src/client/constants/index.js | 8 +- src/fireedge/src/client/constants/states.js | 114 ++++- src/fireedge/src/client/constants/vm.js | 413 ++++++++++++++++++ .../containers/ApplicationsTemplates/index.js | 2 +- .../containers/Providers/Sections/info.js | 3 +- .../Provisions/DialogInfo/datastores.js | 3 +- .../containers/Provisions/DialogInfo/hosts.js | 3 +- .../containers/Provisions/DialogInfo/index.js | 4 +- .../containers/Provisions/DialogInfo/info.js | 8 +- .../containers/Provisions/DialogInfo/log.js | 7 +- .../Provisions/DialogInfo/networks.js | 3 +- .../Provisions/Form/Create/index.js | 4 +- .../VirtualMachines/Sections/info.js | 159 +++++++ .../VirtualMachines/Sections/styles.js | 32 ++ .../containers/VirtualMachines/index.js | 78 ++++ .../src/client/containers/WebConsole/index.js | 8 +- src/fireedge/src/client/dev/index.js | 5 +- .../src/client/features/General/actions.js | 8 +- .../src/client/features/General/hooks.js | 23 +- .../src/client/features/General/slice.js | 9 +- src/fireedge/src/client/features/One/slice.js | 6 + .../src/client/features/One/socket/actions.js | 138 ++++++ .../src/client/features/One/vm/actions.js | 11 + .../src/client/features/One/vm/hooks.js | 3 +- .../src/client/features/One/vm/services.js | 23 +- src/fireedge/src/client/hooks/index.js | 2 - src/fireedge/src/client/hooks/useGeneral.js | 54 --- src/fireedge/src/client/hooks/useSocket.js | 22 +- .../src/client/models/VirtualMachine.js | 10 + .../src/client/providers/notistackProvider.js | 8 +- .../src/client/providers/socketProvider.js | 27 +- src/fireedge/src/client/reducers/auth.js | 99 ----- src/fireedge/src/client/reducers/general.js | 75 ---- src/fireedge/src/client/reducers/index.js | 30 -- .../src/client/reducers/opennebula.js | 57 --- src/fireedge/src/client/reducers/zendesk.js | 37 -- src/fireedge/src/client/router/dev.js | 14 +- .../src/client/{store.js => store/index.js} | 11 +- src/fireedge/src/client/store/reducers.js | 12 + src/fireedge/src/client/types/provision.js | 166 ------- src/fireedge/src/client/utils/helpers.js | 2 + .../src/server/routes/entrypoints/App.js | 4 +- .../src/server/routes/websockets/index.js | 3 +- 55 files changed, 1227 insertions(+), 1022 deletions(-) delete mode 100644 src/fireedge/src/client/actions/general.js delete mode 100644 src/fireedge/src/client/actions/pool.js delete mode 100644 src/fireedge/src/client/actions/user.js create mode 100644 src/fireedge/src/client/components/Cards/VirtualMachineCard.js create mode 100644 src/fireedge/src/client/constants/vm.js create mode 100644 src/fireedge/src/client/containers/VirtualMachines/Sections/info.js create mode 100644 src/fireedge/src/client/containers/VirtualMachines/Sections/styles.js create mode 100644 src/fireedge/src/client/containers/VirtualMachines/index.js create mode 100644 src/fireedge/src/client/features/One/socket/actions.js delete mode 100644 src/fireedge/src/client/hooks/useGeneral.js create mode 100644 src/fireedge/src/client/models/VirtualMachine.js delete mode 100644 src/fireedge/src/client/reducers/auth.js delete mode 100644 src/fireedge/src/client/reducers/general.js delete mode 100644 src/fireedge/src/client/reducers/index.js delete mode 100644 src/fireedge/src/client/reducers/opennebula.js delete mode 100644 src/fireedge/src/client/reducers/zendesk.js rename src/fireedge/src/client/{store.js => store/index.js} (69%) create mode 100644 src/fireedge/src/client/store/reducers.js delete mode 100644 src/fireedge/src/client/types/provision.js diff --git a/src/fireedge/package-lock.json b/src/fireedge/package-lock.json index 848219de79..2aaa0f45c6 100644 --- a/src/fireedge/package-lock.json +++ b/src/fireedge/package-lock.json @@ -49,7 +49,7 @@ "http": "0.0.1-security", "http-proxy-middleware": "1.0.5", "https": "1.0.0", - "iconoir-react": "^1.1.0", + "iconoir-react": "1.1.0", "immutable": "4.0.0-rc.12", "intersection-observer": "0.11.0", "jsonschema": "1.2.7", @@ -59,7 +59,7 @@ "luxon": "1.25.0", "marked": "2.0.0", "morgan": "1.10.0", - "notistack": "1.0.1", + "notistack": "1.0.9", "opennebula-guacamole": "1.0.0", "path": "0.12.7", "prop-types": "15.7.2", @@ -1675,11 +1675,11 @@ } }, "node_modules/@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dependencies": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { @@ -1687,19 +1687,19 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", "dependencies": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { @@ -1780,9 +1780,9 @@ "integrity": "sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==" }, "node_modules/@types/node": { - "version": "15.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz", - "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==" + "version": "15.12.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.1.tgz", + "integrity": "sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw==" }, "node_modules/@types/prop-types": { "version": "15.7.3", @@ -1790,9 +1790,9 @@ "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "node_modules/@types/react": { - "version": "17.0.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.8.tgz", - "integrity": "sha512-3sx4c0PbXujrYAKwXxNONXUtRp9C+hE2di0IuxFyf5BELD+B+AXL8G7QrmSKhVwKZDbv0igiAjQAMhXj8Yg3aw==", + "version": "17.0.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.9.tgz", + "integrity": "sha512-2Cw7FvevpJxQrCb+k5t6GH1KIvmadj5uBbjPaLlJB/nZWUj56e1ZqcD6zsoMFB47MsJUTFl9RJ132A7hb3QFJA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -2956,9 +2956,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001232", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz", - "integrity": "sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg==", + "version": "1.0.30001234", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001234.tgz", + "integrity": "sha512-a3gjUVKkmwLdNysa1xkUAwN2VfJUJyVW47rsi3aCbkRCtbHAfo+rOsCqVw29G6coQ8gzAPb5XBXwiGHwme3isA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/browserslist" @@ -3662,9 +3662,9 @@ } }, "node_modules/core-js": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.13.1.tgz", - "integrity": "sha512-JqveUc4igkqwStL2RTRn/EPFGBOfEZHxJl/8ej1mXJR75V3go2mFF4bmUYkEIT1rveHKnkUlcJX/c+f1TyIovQ==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.14.0.tgz", + "integrity": "sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -3672,9 +3672,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.13.1.tgz", - "integrity": "sha512-mdrcxc0WznfRd8ZicEZh1qVeJ2mu6bwQFh8YVUK48friy/FOwFV5EJj9/dlh+nMQ74YusdVfBFDuomKgUspxWQ==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.14.0.tgz", + "integrity": "sha512-R4NS2eupxtiJU+VwgkF9WTpnSfZW4pogwKHd8bclWU2sp93Pr5S1uYJI84cMOubJRou7bcfL0vmwtLslWN5p3A==", "dependencies": { "browserslist": "^4.16.6", "semver": "7.0.0" @@ -4158,9 +4158,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.3.743", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.743.tgz", - "integrity": "sha512-K2wXfo9iZQzNJNx67+Pld0DRF+9bYinj62gXCdgPhcu1vidwVuLPHQPPFnCdO55njWigXXpfBiT90jGUPbw8Zg==" + "version": "1.3.749", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz", + "integrity": "sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -6304,7 +6304,8 @@ "node_modules/https": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", - "integrity": "sha1-PDfHrhqO65ZpBKKtHpdaGUt+06Q=" + "integrity": "sha1-PDfHrhqO65ZpBKKtHpdaGUt+06Q=", + "license": "ISC" }, "node_modules/https-browserify": { "version": "1.0.0", @@ -6320,6 +6321,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/iconoir-react/-/iconoir-react-1.1.0.tgz", "integrity": "sha512-eVlXhKtRJOHsqqNNazM8j5eAZxPaISSrNoN4VnqwWzZw5SnLvHi5Qp2kuKKznnx2vEIv4zcB4iqBQmmRW0vJ0A==", + "license": "MIT", "dependencies": { "prop-types": "^15.7.2" }, @@ -7441,24 +7443,16 @@ } }, "node_modules/mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "dependencies": { - "mime-db": "1.47.0" + "mime-db": "1.48.0" }, "engines": { "node": ">= 0.6" } }, - "node_modules/mime-types/node_modules/mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", @@ -7865,9 +7859,9 @@ } }, "node_modules/notistack": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/notistack/-/notistack-1.0.1.tgz", - "integrity": "sha512-2T1WkokzRCM8N9EdueaXja160IMFIMHVhRu0fGkDje7qCzwBHlTMZY2NULQzB2GFOO6iGVzl5GCX2XrJIzI8bw==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-1.0.9.tgz", + "integrity": "sha512-Dal2HtTpWrdYCZ3t0HhJt47NJZwVSPee36WzORRbqUkFR0k9pxFszxBuPSWshBLwF6Av8s86XPP+ED5zRz0CGw==", "dependencies": { "clsx": "^1.1.0", "hoist-non-react-statics": "^3.3.0" @@ -7878,8 +7872,8 @@ }, "peerDependencies": { "@material-ui/core": "^4.0.0", - "react": "^16.8.0", - "react-dom": "^16.8.0" + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" } }, "node_modules/npmlog": { @@ -13203,25 +13197,25 @@ } }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "requires": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -13292,9 +13286,9 @@ "integrity": "sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==" }, "@types/node": { - "version": "15.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz", - "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==" + "version": "15.12.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.1.tgz", + "integrity": "sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw==" }, "@types/prop-types": { "version": "15.7.3", @@ -13302,9 +13296,9 @@ "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/react": { - "version": "17.0.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.8.tgz", - "integrity": "sha512-3sx4c0PbXujrYAKwXxNONXUtRp9C+hE2di0IuxFyf5BELD+B+AXL8G7QrmSKhVwKZDbv0igiAjQAMhXj8Yg3aw==", + "version": "17.0.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.9.tgz", + "integrity": "sha512-2Cw7FvevpJxQrCb+k5t6GH1KIvmadj5uBbjPaLlJB/nZWUj56e1ZqcD6zsoMFB47MsJUTFl9RJ132A7hb3QFJA==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -14262,9 +14256,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001232", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz", - "integrity": "sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg==" + "version": "1.0.30001234", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001234.tgz", + "integrity": "sha512-a3gjUVKkmwLdNysa1xkUAwN2VfJUJyVW47rsi3aCbkRCtbHAfo+rOsCqVw29G6coQ8gzAPb5XBXwiGHwme3isA==" }, "chalk": { "version": "2.4.2", @@ -14811,14 +14805,14 @@ } }, "core-js": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.13.1.tgz", - "integrity": "sha512-JqveUc4igkqwStL2RTRn/EPFGBOfEZHxJl/8ej1mXJR75V3go2mFF4bmUYkEIT1rveHKnkUlcJX/c+f1TyIovQ==" + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.14.0.tgz", + "integrity": "sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA==" }, "core-js-compat": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.13.1.tgz", - "integrity": "sha512-mdrcxc0WznfRd8ZicEZh1qVeJ2mu6bwQFh8YVUK48friy/FOwFV5EJj9/dlh+nMQ74YusdVfBFDuomKgUspxWQ==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.14.0.tgz", + "integrity": "sha512-R4NS2eupxtiJU+VwgkF9WTpnSfZW4pogwKHd8bclWU2sp93Pr5S1uYJI84cMOubJRou7bcfL0vmwtLslWN5p3A==", "requires": { "browserslist": "^4.16.6", "semver": "7.0.0" @@ -15230,9 +15224,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.743", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.743.tgz", - "integrity": "sha512-K2wXfo9iZQzNJNx67+Pld0DRF+9bYinj62gXCdgPhcu1vidwVuLPHQPPFnCdO55njWigXXpfBiT90jGUPbw8Zg==" + "version": "1.3.749", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz", + "integrity": "sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==" }, "elliptic": { "version": "6.5.4", @@ -17775,18 +17769,11 @@ "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" }, "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "requires": { - "mime-db": "1.47.0" - }, - "dependencies": { - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - } + "mime-db": "1.48.0" } }, "mimic-response": { @@ -18136,9 +18123,9 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "notistack": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/notistack/-/notistack-1.0.1.tgz", - "integrity": "sha512-2T1WkokzRCM8N9EdueaXja160IMFIMHVhRu0fGkDje7qCzwBHlTMZY2NULQzB2GFOO6iGVzl5GCX2XrJIzI8bw==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-1.0.9.tgz", + "integrity": "sha512-Dal2HtTpWrdYCZ3t0HhJt47NJZwVSPee36WzORRbqUkFR0k9pxFszxBuPSWshBLwF6Av8s86XPP+ED5zRz0CGw==", "requires": { "clsx": "^1.1.0", "hoist-non-react-statics": "^3.3.0" diff --git a/src/fireedge/package.json b/src/fireedge/package.json index 1fb8830631..d96e7e54e2 100644 --- a/src/fireedge/package.json +++ b/src/fireedge/package.json @@ -93,7 +93,7 @@ "luxon": "1.25.0", "marked": "2.0.0", "morgan": "1.10.0", - "notistack": "1.0.1", + "notistack": "1.0.9", "opennebula-guacamole": "1.0.0", "path": "0.12.7", "prop-types": "15.7.2", @@ -129,4 +129,4 @@ "yup": "0.32.9", "zeromq": "5.2.0" } -} \ No newline at end of file +} diff --git a/src/fireedge/src/client/actions/general.js b/src/fireedge/src/client/actions/general.js deleted file mode 100644 index 48d3caa0c6..0000000000 --- a/src/fireedge/src/client/actions/general.js +++ /dev/null @@ -1,82 +0,0 @@ -const CHANGE_ZONE = 'CHANGE_ZONE' -const CHANGE_LOADING = 'CHANGE_LOADING' -const TOGGLE_MENU = 'TOGGLE_MENU' -const FIX_MENU = 'FIX_MENU' - -const ENQUEUE_SNACKBAR = 'ENQUEUE_SNACKBAR' -const CLOSE_SNACKBAR = 'CLOSE_SNACKBAR' -const REMOVE_SNACKBAR = 'REMOVE_SNACKBAR' - -const Actions = { - CHANGE_ZONE, - CHANGE_LOADING, - TOGGLE_MENU, - FIX_MENU, - ENQUEUE_SNACKBAR, - CLOSE_SNACKBAR, - REMOVE_SNACKBAR -} - -module.exports = { - Actions, - changeZone: zone => ({ - type: CHANGE_ZONE, - payload: { zone } - }), - changeLoading: isLoading => ({ - type: CHANGE_LOADING, - payload: { isLoading } - }), - openMenu: isOpen => ({ - type: TOGGLE_MENU, - isOpen - }), - fixMenu: isFixed => ({ - type: FIX_MENU, - isFixed - }), - enqueueSnackbar: notification => { - const key = notification.options && notification.options.key - - return { - type: ENQUEUE_SNACKBAR, - notification: { - ...notification, - key: key || new Date().getTime() + Math.random() - } - } - }, - enqueueError: message => ({ - type: ENQUEUE_SNACKBAR, - notification: { - key: new Date().getTime() + Math.random(), - message, - options: { variant: 'error' } - } - }), - enqueueSuccess: message => ({ - type: ENQUEUE_SNACKBAR, - notification: { - key: new Date().getTime() + Math.random(), - message, - options: { variant: 'success' } - } - }), - enqueueInfo: message => ({ - type: ENQUEUE_SNACKBAR, - notification: { - key: new Date().getTime() + Math.random(), - message, - options: { variant: 'info' } - } - }), - closeSnackbar: key => ({ - type: CLOSE_SNACKBAR, - dismissAll: !key, // dismiss all if no key has been defined - key - }), - removeSnackbar: key => ({ - type: REMOVE_SNACKBAR, - key - }) -} diff --git a/src/fireedge/src/client/actions/pool.js b/src/fireedge/src/client/actions/pool.js deleted file mode 100644 index e194cac17b..0000000000 --- a/src/fireedge/src/client/actions/pool.js +++ /dev/null @@ -1,139 +0,0 @@ -const START_ONE_REQUEST = 'START_ONE_REQUEST' -const SUCCESS_ONE_REQUEST = 'SUCCESS_ONE_REQUEST' -const FAILURE_ONE_REQUEST = 'FAILURE_ONE_REQUEST' - -const Actions = { - START_ONE_REQUEST, - SUCCESS_ONE_REQUEST, - FAILURE_ONE_REQUEST -} - -module.exports = { - Actions, - - // -------------------------------------------- - // ONE - // -------------------------------------------- - - setVms: vms => ({ - type: SUCCESS_ONE_REQUEST, - payload: { vms } - }), - setTemplates: templates => ({ - type: SUCCESS_ONE_REQUEST, - payload: { templates } - }), - setDatastores: datastores => ({ - type: SUCCESS_ONE_REQUEST, - payload: { datastores } - }), - setVRouters: virtualRouters => ({ - type: SUCCESS_ONE_REQUEST, - payload: { virtualRouters } - }), - setVmGroups: vmGroups => ({ - type: SUCCESS_ONE_REQUEST, - payload: { vmGroups } - }), - setImages: images => ({ - type: SUCCESS_ONE_REQUEST, - payload: { images } - }), - setFiles: files => ({ - type: SUCCESS_ONE_REQUEST, - payload: { files } - }), - setMarketplaces: marketplaces => ({ - type: SUCCESS_ONE_REQUEST, - payload: { marketplaces } - }), - setApps: apps => ({ - type: SUCCESS_ONE_REQUEST, - payload: { apps } - }), - setVNetworks: vNetworks => ({ - type: SUCCESS_ONE_REQUEST, - payload: { vNetworks } - }), - setVNetworksTemplates: vNetworksTemplates => ({ - type: SUCCESS_ONE_REQUEST, - payload: { vNetworksTemplates } - }), - setSecGroups: securityGroups => ({ - type: SUCCESS_ONE_REQUEST, - payload: { securityGroups } - }), - setClusters: clusters => ({ - type: SUCCESS_ONE_REQUEST, - payload: { clusters } - }), - setHosts: hosts => ({ - type: SUCCESS_ONE_REQUEST, - payload: { hosts } - }), - setZones: zones => ({ - type: SUCCESS_ONE_REQUEST, - payload: { zones } - }), - setUsers: users => ({ - type: SUCCESS_ONE_REQUEST, - payload: { users } - }), - setGroups: groups => ({ - type: SUCCESS_ONE_REQUEST, - payload: { groups } - }), - setVdc: vdc => ({ - type: SUCCESS_ONE_REQUEST, - payload: { vdc } - }), - setAcl: acl => ({ - type: SUCCESS_ONE_REQUEST, - payload: { acl } - }), - - // -------------------------------------------- - // ONE FLOW - // -------------------------------------------- - - setApplications: applications => ({ - type: SUCCESS_ONE_REQUEST, - payload: { applications } - }), - setApplicationsTemplates: applicationsTemplates => ({ - type: SUCCESS_ONE_REQUEST, - payload: { applicationsTemplates } - }), - - // -------------------------------------------- - // ONE PROVISION - // -------------------------------------------- - - setProvisionsTemplates: provisionsTemplates => ({ - type: SUCCESS_ONE_REQUEST, - payload: { provisionsTemplates } - }), - setProviders: providers => ({ - type: SUCCESS_ONE_REQUEST, - payload: { providers } - }), - setProvisions: provisions => ({ - type: SUCCESS_ONE_REQUEST, - payload: { provisions } - }), - - // -------------------------------------------- - // ONE REQUEST - // -------------------------------------------- - - startOneRequest: () => ({ - type: START_ONE_REQUEST - }), - successOneRequest: () => ({ - type: SUCCESS_ONE_REQUEST - }), - failureOneRequest: error => ({ - type: FAILURE_ONE_REQUEST, - payload: { error } - }) -} diff --git a/src/fireedge/src/client/actions/user.js b/src/fireedge/src/client/actions/user.js deleted file mode 100644 index 8da8ab3367..0000000000 --- a/src/fireedge/src/client/actions/user.js +++ /dev/null @@ -1,54 +0,0 @@ -const START_AUTH = 'START_AUTH' -const SELECT_FILTER_GROUP = 'SELECT_FILTER_GROUP' -const CHANGE_SETTINGS = 'CHANGE_SETTINGS' -const SUCCESS_AUTH = 'SUCCESS_AUTH' -const FAILURE_AUTH = 'FAILURE_AUTH' -const LOGOUT = 'LOGOUT' - -const Actions = { - START_AUTH, - SELECT_FILTER_GROUP, - CHANGE_SETTINGS, - SUCCESS_AUTH, - FAILURE_AUTH, - LOGOUT -} - -module.exports = { - Actions, - startAuth: () => ({ - type: START_AUTH - }), - updateSetting: (dispatch, getState) => { - const current = getState() - - const userSetting = current.Authenticated?.user?.TEMPLATE?.FIREEDGE - - if (!userSetting) return - - const mapSetting = Object.entries(userSetting) - .reduce((res, [key, value]) => - ({ ...res, [String(key).toLowerCase()]: value }) - , {}) - - dispatch(({ - type: CHANGE_SETTINGS, - payload: mapSetting - })) - }, - selectFilterGroup: payload => ({ - type: SELECT_FILTER_GROUP, - payload - }), - successAuth: payload => ({ - type: SUCCESS_AUTH, - payload - }), - failureAuth: payload => ({ - type: FAILURE_AUTH, - payload - }), - logout: () => ({ - type: LOGOUT - }) -} diff --git a/src/fireedge/src/client/components/Cards/ProvisionCard.js b/src/fireedge/src/client/components/Cards/ProvisionCard.js index 059d1d2dc3..a58563f05d 100644 --- a/src/fireedge/src/client/components/Cards/ProvisionCard.js +++ b/src/fireedge/src/client/components/Cards/ProvisionCard.js @@ -6,8 +6,8 @@ import { Db as ProviderIcon, Cloud as ProvisionIcon } from 'iconoir-react' import SelectCard, { Action } from 'client/components/Cards/SelectCard' import { StatusBadge } from 'client/components/Status' import Image from 'client/components/Image' + import { isExternalURL } from 'client/utils' -import * as Types from 'client/types/provision' import { PROVISIONS_STATES, PROVIDER_IMAGES_URL, @@ -65,10 +65,7 @@ const ProvisionCard = memo( ) ProvisionCard.propTypes = { - value: PropTypes.oneOfType([ - Types.Provider, - Types.Provision - ]), + value: PropTypes.object, isSelected: PropTypes.bool, handleClick: PropTypes.func, isProvider: PropTypes.bool, diff --git a/src/fireedge/src/client/components/Cards/ProvisionTemplateCard.js b/src/fireedge/src/client/components/Cards/ProvisionTemplateCard.js index 403aaf100e..2c346cddc9 100644 --- a/src/fireedge/src/client/components/Cards/ProvisionTemplateCard.js +++ b/src/fireedge/src/client/components/Cards/ProvisionTemplateCard.js @@ -3,9 +3,7 @@ import PropTypes from 'prop-types' import { Db as ProviderIcon, SettingsCloud as ProvisionIcon } from 'iconoir-react' -import * as Types from 'client/types/provision' import { SelectCard } from 'client/components/Cards' - import Image from 'client/components/Image' import { isExternalURL } from 'client/utils' import { PROVIDER_IMAGES_URL, PROVISION_IMAGES_URL } from 'client/constants' @@ -49,10 +47,7 @@ ProvisionTemplateCard.propTypes = { isProvider: PropTypes.bool, isSelected: PropTypes.bool, isValid: PropTypes.bool, - value: PropTypes.oneOfType([ - Types.ProviderTemplate, - Types.ProvisionTemplate - ]) + value: PropTypes.object } ProvisionTemplateCard.defaultProps = { diff --git a/src/fireedge/src/client/components/Cards/VirtualMachineCard.js b/src/fireedge/src/client/components/Cards/VirtualMachineCard.js new file mode 100644 index 0000000000..d5da561cf2 --- /dev/null +++ b/src/fireedge/src/client/components/Cards/VirtualMachineCard.js @@ -0,0 +1,60 @@ +import React, { memo } from 'react' +import PropTypes from 'prop-types' +import { ViewGrid as VmIcon } from 'iconoir-react' + +import SelectCard, { Action } from 'client/components/Cards/SelectCard' +import { StatusBadge } from 'client/components/Status' +import { getState } from 'client/models/VirtualMachine' + +const VirtualMachineCard = memo( + ({ value, isSelected, handleClick, actions }) => { + const { ID, NAME } = value + const { color, name } = getState(value) ?? {} + + return ( + + + )} + dataCy={`vm-${ID}`} + handleClick={handleClick} + icon={( + + + + )} + isSelected={isSelected} + subheader={`#${ID}`} + title={NAME} + /> + ) + }, + (prev, next) => + prev.isSelected === next.isSelected && + prev.value.STATE === next.value.STATE && + prev.value?.LCM_STATE === next.value?.LCM_STATE +) + +VirtualMachineCard.propTypes = { + handleClick: PropTypes.func, + isSelected: PropTypes.bool, + value: PropTypes.object, + actions: PropTypes.arrayOf( + PropTypes.shape({ + handleClick: PropTypes.func.isRequired, + icon: PropTypes.object.isRequired, + cy: PropTypes.string + }) + ) +} + +VirtualMachineCard.defaultProps = { + handleClick: undefined, + isSelected: false, + value: {}, + actions: undefined +} + +VirtualMachineCard.displayName = 'VirtualMachineCard' + +export default VirtualMachineCard diff --git a/src/fireedge/src/client/components/Cards/index.js b/src/fireedge/src/client/components/Cards/index.js index aeacc4a299..d447d905b0 100644 --- a/src/fireedge/src/client/components/Cards/index.js +++ b/src/fireedge/src/client/components/Cards/index.js @@ -11,6 +11,7 @@ import ProvisionCard from 'client/components/Cards/ProvisionCard' import ProvisionTemplateCard from 'client/components/Cards/ProvisionTemplateCard' import SelectCard from 'client/components/Cards/SelectCard' import TierCard from 'client/components/Cards/TierCard' +import VirtualMachineCard from 'client/components/Cards/VirtualMachineCard' import WavesCard from 'client/components/Cards/WavesCard' export { @@ -27,5 +28,6 @@ export { ProvisionTemplateCard, SelectCard, TierCard, + VirtualMachineCard, WavesCard } diff --git a/src/fireedge/src/client/components/DebugLog/index.js b/src/fireedge/src/client/components/DebugLog/index.js index b5f2ef6454..9f12071ef8 100644 --- a/src/fireedge/src/client/components/DebugLog/index.js +++ b/src/fireedge/src/client/components/DebugLog/index.js @@ -44,11 +44,13 @@ const DebugLog = memo(({ uuid, socket, logDefault, title }) => { })) useEffect(() => { - uuid && socket?.on((socketData = {}) => { + const { on, off } = socket((socketData = {}) => { socketData.id === uuid && setLog(prevLog => LogUtils.concatNewMessageToLog(prevLog, socketData)) }) - return () => uuid && socket?.off() + + uuid && on() + return off }, []) return ( @@ -68,10 +70,7 @@ const DebugLog = memo(({ uuid, socket, logDefault, title }) => { DebugLog.propTypes = { uuid: PropTypes.string, - socket: PropTypes.shape({ - on: PropTypes.func.isRequired, - off: PropTypes.func.isRequired - }).isRequired, + socket: PropTypes.func.isRequired, logDefault: PropTypes.object, title: PropTypes.oneOfType([ PropTypes.element, diff --git a/src/fireedge/src/client/components/Sidebar/SidebarCollapseItem.js b/src/fireedge/src/client/components/Sidebar/SidebarCollapseItem.js index 15a5791d7e..3ebd7fc87d 100644 --- a/src/fireedge/src/client/components/Sidebar/SidebarCollapseItem.js +++ b/src/fireedge/src/client/components/Sidebar/SidebarCollapseItem.js @@ -12,7 +12,7 @@ import { } from '@material-ui/core' import { NavArrowRight as CollapseIcon, NavArrowDown as ExpandMoreIcon } from 'iconoir-react' -import { useGeneral } from 'client/hooks' +import { useGeneral } from 'client/features/General' import SidebarLink from 'client/components/Sidebar/SidebarLink' import sidebarStyles from 'client/components/Sidebar/styles' diff --git a/src/fireedge/src/client/constants/color.js b/src/fireedge/src/client/constants/color.js index a4ddde7023..d1dceb96d1 100644 --- a/src/fireedge/src/client/constants/color.js +++ b/src/fireedge/src/client/constants/color.js @@ -21,7 +21,7 @@ export default { light: '#3adb76', main: '#4caf50', dark: '#388e3c', - contrastText: 'rgba(0, 0, 0, 0.87)' + contrastText: '#fff' }, debug: { light: '#7f7f7f', diff --git a/src/fireedge/src/client/constants/index.js b/src/fireedge/src/client/constants/index.js index eb86da0b77..5bd6bce324 100644 --- a/src/fireedge/src/client/constants/index.js +++ b/src/fireedge/src/client/constants/index.js @@ -72,7 +72,13 @@ export const DEBUG_LEVEL = { DEBUG: 'DEBUG' } +export const SOCKETS = { + hooks: 'hooks', + provision: 'provision' +} + export * as T from 'client/constants/translates' +export * as STATES from 'client/constants/states' export * from 'client/constants/flow' -export * from 'client/constants/states' export * from 'client/constants/provision' +export * from 'client/constants/vm' diff --git a/src/fireedge/src/client/constants/states.js b/src/fireedge/src/client/constants/states.js index 6cdfc861b2..77f14da6d2 100644 --- a/src/fireedge/src/client/constants/states.js +++ b/src/fireedge/src/client/constants/states.js @@ -1,26 +1,100 @@ -export const PENDING = 'PENDING' -export const DEPLOYING = 'DEPLOYING' -export const RUNNING = 'RUNNING' -export const UNDEPLOYING = 'UNDEPLOYING' -export const WARNING = 'WARNING' -export const DONE = 'DONE' -export const FAILED_UNDEPLOYING = 'FAILED_UNDEPLOYING' -export const FAILED_DEPLOYING = 'FAILED_DEPLOYING' -export const SCALING = 'SCALING' -export const FAILED_SCALING = 'FAILED_SCALING' +export const ACTIVE = 'ACTIVE' +export const BOOT = 'BOOT' +export const BOOT_FAILURE = 'BOOT_FAILURE' +export const BOOT_MIGRATE = 'BOOT_MIGRATE' +export const BOOT_MIGRATE_FAILURE = 'BOOT_MIGRATE_FAILURE' +export const BOOT_POWEROFF = 'BOOT_POWEROFF' +export const BOOT_STOPPED = 'BOOT_STOPPED' +export const BOOT_STOPPED_FAILURE = 'BOOT_STOPPED_FAILURE' +export const BOOT_SUSPENDED = 'BOOT_SUSPENDED' +export const BOOT_UNDEPLOY = 'BOOT_UNDEPLOY' +export const BOOT_UNDEPLOY_FAILURE = 'BOOT_UNDEPLOY_FAILURE' +export const BOOT_UNKNOWN = 'BOOT_UNKNOWN' +export const CANCEL = 'CANCEL' +export const CLEANUP_DELETE = 'CLEANUP_DELETE' +export const CLEANUP_RESUBMIT = 'CLEANUP_RESUBMIT' +export const CLONING = 'CLONING' +export const CLONING_FAILURE = 'CLONING_FAILURE' +export const CONFIGURING = 'CONFIGURING' export const COOLDOWN = 'COOLDOWN' - +export const DELETING = 'DELETING' +export const DEPLOYING = 'DEPLOYING' +export const DISABLED = 'DISABLED' +export const DISK_RESIZE = 'DISK_RESIZE' +export const DISK_RESIZE_POWEROFF = 'DISK_RESIZE_POWEROFF' +export const DISK_RESIZE_UNDEPLOYED = 'DISK_RESIZE_UNDEPLOYED' +export const DISK_SNAPSHOT = 'DISK_SNAPSHOT' +export const DISK_SNAPSHOT_DELETE = 'DISK_SNAPSHOT_DELETE' +export const DISK_SNAPSHOT_DELETE_POWEROFF = 'DISK_SNAPSHOT_DELETE_POWEROFF' +export const DISK_SNAPSHOT_DELETE_SUSPENDED = 'DISK_SNAPSHOT_DELETE_SUSPENDED' +export const DISK_SNAPSHOT_POWEROFF = 'DISK_SNAPSHOT_POWEROFF' +export const DISK_SNAPSHOT_REVERT = 'DISK_SNAPSHOT_REVERT' +export const DISK_SNAPSHOT_REVERT_POWEROFF = 'DISK_SNAPSHOT_REVERT_POWEROFF' +export const DISK_SNAPSHOT_REVERT_SUSPENDED = 'DISK_SNAPSHOT_REVERT_SUSPENDED' +export const DISK_SNAPSHOT_SUSPENDED = 'DISK_SNAPSHOT_SUSPENDED' +export const DONE = 'DONE' +export const EPILOG = 'EPILOG' +export const EPILOG_FAILURE = 'EPILOG_FAILURE' +export const EPILOG_STOP = 'EPILOG_STOP' +export const EPILOG_STOP_FAILURE = 'EPILOG_STOP_FAILURE' +export const EPILOG_UNDEPLOY = 'EPILOG_UNDEPLOY' +export const EPILOG_UNDEPLOY_FAILURE = 'EPILOG_UNDEPLOY_FAILURE' +export const ERROR = 'ERROR' +export const FAILED = 'FAILED' +export const FAILED_DEPLOYING = 'FAILED_DEPLOYING' +export const FAILED_SCALING = 'FAILED_SCALING' +export const FAILED_UNDEPLOYING = 'FAILED_UNDEPLOYING' +export const FAILURE = 'FAILURE' +export const HOLD = 'HOLD' +export const HOTPLUG = 'HOTPLUG' +export const HOTPLUG_EPILOG_POWEROFF = 'HOTPLUG_EPILOG_POWEROFF' +export const HOTPLUG_NIC = 'HOTPLUG_NIC' +export const HOTPLUG_NIC_POWEROFF = 'HOTPLUG_NIC_POWEROFF' +export const HOTPLUG_PROLOG_POWEROFF = 'HOTPLUG_PROLOG_POWEROFF' +export const HOTPLUG_RESIZE = 'HOTPLUG_RESIZE' +export const HOTPLUG_SAVEAS = 'HOTPLUG_SAVEAS' +export const HOTPLUG_SAVEAS_POWEROFF = 'HOTPLUG_SAVEAS_POWEROFF' +export const HOTPLUG_SAVEAS_STOPPED = 'HOTPLUG_SAVEAS_STOPPED' +export const HOTPLUG_SAVEAS_SUSPENDED = 'HOTPLUG_SAVEAS_SUSPENDED' +export const HOTPLUG_SAVEAS_UNDEPLOYED = 'HOTPLUG_SAVEAS_UNDEPLOYED' +export const HOTPLUG_SNAPSHOT = 'HOTPLUG_SNAPSHOT' export const INIT = 'INIT' -export const OFFLINE = 'OFFLINE' +export const LCM_INIT = 'LCM_INIT' +export const MIGRATE = 'MIGRATE' export const MONITORED = 'MONITORED' -export const MONITORING_MONITORED = 'MONITORING_MONITORED' +export const MONITORING_DISABLED = 'MONITORING_DISABLED' export const MONITORING_ERROR = 'MONITORING_ERROR' export const MONITORING_INIT = 'MONITORING_INIT' -export const MONITORING_DISABLED = 'MONITORING_DISABLED' - +export const MONITORING_MONITORED = 'MONITORING_MONITORED' +export const OFFLINE = 'OFFLINE' +export const PENDING = 'PENDING' +export const POWEROFF = 'POWEROFF' +export const PROLOG = 'PROLOG' +export const PROLOG_FAILURE = 'PROLOG_FAILURE' +export const PROLOG_MIGRATE = 'PROLOG_MIGRATE' +export const PROLOG_MIGRATE_FAILURE = 'PROLOG_MIGRATE_FAILURE' +export const PROLOG_MIGRATE_POWEROFF = 'PROLOG_MIGRATE_POWEROFF' +export const PROLOG_MIGRATE_POWEROFF_FAILURE = 'PROLOG_MIGRATE_POWEROFF_FAILURE' +export const PROLOG_MIGRATE_SUSPEND = 'PROLOG_MIGRATE_SUSPEND' +export const PROLOG_MIGRATE_SUSPEND_FAILURE = 'PROLOG_MIGRATE_SUSPEND_FAILURE' +export const PROLOG_MIGRATE_UNKNOWN = 'PROLOG_MIGRATE_UNKNOWN' +export const PROLOG_MIGRATE_UNKNOWN_FAILURE = 'PROLOG_MIGRATE_UNKNOWN_FAILURE' +export const PROLOG_RESUME = 'PROLOG_RESUME' +export const PROLOG_RESUME_FAILURE = 'PROLOG_RESUME_FAILURE' +export const PROLOG_UNDEPLOY = 'PROLOG_UNDEPLOY' +export const PROLOG_UNDEPLOY_FAILURE = 'PROLOG_UNDEPLOY_FAILURE' export const READY = 'READY' -export const DISABLED = 'DISABLED' - -export const CONFIGURING = 'CONFIGURING' -export const ERROR = 'ERROR' -export const DELETING = 'DELETING' +export const RUNNING = 'RUNNING' +export const SAVE_MIGRATE = 'SAVE_MIGRATE' +export const SAVE_STOP = 'SAVE_STOP' +export const SAVE_SUSPEND = 'SAVE_SUSPEND' +export const SCALING = 'SCALING' +export const SHUTDOWN = 'SHUTDOWN' +export const SHUTDOWN_POWEROFF = 'SHUTDOWN_POWEROFF' +export const SHUTDOWN_UNDEPLOY = 'SHUTDOWN_UNDEPLOY' +export const STOPPED = 'STOPPED' +export const SUSPENDED = 'SUSPENDED' +export const UNKNOWN = 'UNKNOWN' +export const UNDEPLOYED = 'UNDEPLOYED' +export const UNDEPLOYING = 'UNDEPLOYING' +export const WARNING = 'WARNING' diff --git a/src/fireedge/src/client/constants/vm.js b/src/fireedge/src/client/constants/vm.js new file mode 100644 index 0000000000..421501c756 --- /dev/null +++ b/src/fireedge/src/client/constants/vm.js @@ -0,0 +1,413 @@ +import * as STATES from 'client/constants/states' +import COLOR from 'client/constants/color' + +export const VM_STATES = [ + { // 0 + name: STATES.INIT, + color: COLOR.info.main, + meaning: '' + }, + { // 1 + name: STATES.PENDING, + color: COLOR.info.main, + meaning: '' + }, + { // 2 + name: STATES.HOLD, + color: COLOR.info.main, + meaning: '' + }, + { // 3 + name: STATES.ACTIVE, + color: COLOR.info.main, + meaning: '' + }, + { // 4 + name: STATES.STOPPED, + color: COLOR.info.main, + meaning: '' + }, + { // 5 + name: STATES.SUSPENDED, + color: COLOR.info.main, + meaning: '' + }, + { // 6 + name: STATES.DONE, + color: COLOR.debug.main, + meaning: '' + }, + { // 7 + name: STATES.FAILED, + color: COLOR.info.main, + meaning: '' + }, + { // 8 + name: STATES.POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 9 + name: STATES.UNDEPLOYED, + color: COLOR.info.main, + meaning: '' + }, + { // 10 + name: STATES.CLONING, + color: COLOR.info.main, + meaning: '' + }, + { // 11 + name: STATES.CLONING_FAILURE, + color: COLOR.info.main, + meaning: '' + } +] + +export const VM_LCM_STATES = [ + { // 0 + name: STATES.LCM_INIT, + color: COLOR.info.main, + meaning: '' + }, + { // 1 + name: STATES.PROLOG, + color: COLOR.info.main, + meaning: '' + }, + { // 2 + name: STATES.BOOT, + color: COLOR.info.main, + meaning: '' + }, + { // 3 + name: STATES.RUNNING, + color: COLOR.success.main, + meaning: '' + }, + { // 4 + name: STATES.MIGRATE, + color: COLOR.info.main, + meaning: '' + }, + { // 5 + name: STATES.SAVE_STOP, + color: COLOR.info.main, + meaning: '' + }, + { // 6 + name: STATES.SAVE_SUSPEND, + color: COLOR.info.main, + meaning: '' + }, + { // 7 + name: STATES.SAVE_MIGRATE, + color: COLOR.info.main, + meaning: '' + }, + { // 8 + name: STATES.PROLOG_MIGRATE, + color: COLOR.info.main, + meaning: '' + }, + { // 9 + name: STATES.PROLOG_RESUME, + color: COLOR.info.main, + meaning: '' + }, + { // 10 + name: STATES.EPILOG_STOP, + color: COLOR.info.main, + meaning: '' + }, + { // 11 + name: STATES.EPILOG, + color: COLOR.info.main, + meaning: '' + }, + { // 12 + name: STATES.SHUTDOWN, + color: COLOR.info.main, + meaning: '' + }, + { // 13 + name: STATES.CANCEL, + color: COLOR.info.main, + meaning: '' + }, + { // 14 + name: STATES.FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 15 + name: STATES.CLEANUP_RESUBMIT, + color: COLOR.info.main, + meaning: '' + }, + { // 16 + name: STATES.UNKNOWN, + color: COLOR.info.main, + meaning: '' + }, + { // 17 + name: STATES.HOTPLUG, + color: COLOR.info.main, + meaning: '' + }, + { // 18 + name: STATES.SHUTDOWN_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 19 + name: STATES.BOOT_UNKNOWN, + color: COLOR.info.main, + meaning: '' + }, + { // 20 + name: STATES.BOOT_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 21 + name: STATES.BOOT_SUSPENDED, + color: COLOR.info.main, + meaning: '' + }, + { // 22 + name: STATES.BOOT_STOPPED, + color: COLOR.info.main, + meaning: '' + }, + { // 23 + name: STATES.CLEANUP_DELETE, + color: COLOR.info.main, + meaning: '' + }, + { // 24 + name: STATES.HOTPLUG_SNAPSHOT, + color: COLOR.info.main, + meaning: '' + }, + { // 25 + name: STATES.HOTPLUG_NIC, + color: COLOR.info.main, + meaning: '' + }, + { // 26 + name: STATES.HOTPLUG_SAVEAS, + color: COLOR.info.main, + meaning: '' + }, + { // 27 + name: STATES.HOTPLUG_SAVEAS_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 28 + name: STATES.HOTPLUG_SAVEAS_SUSPENDED, + color: COLOR.info.main, + meaning: '' + }, + { // 29 + name: STATES.SHUTDOWN_UNDEPLOY, + color: COLOR.info.main, + meaning: '' + }, + { // 30 + name: STATES.EPILOG_UNDEPLOY, + color: COLOR.info.main, + meaning: '' + }, + { // 31 + name: STATES.PROLOG_UNDEPLOY, + color: COLOR.info.main, + meaning: '' + }, + { // 32 + name: STATES.BOOT_UNDEPLOY, + color: COLOR.info.main, + meaning: '' + }, + { // 33 + name: STATES.HOTPLUG_PROLOG_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 34 + name: STATES.HOTPLUG_EPILOG_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 35 + name: STATES.BOOT_MIGRATE, + color: COLOR.info.main, + meaning: '' + }, + { // 36 + name: STATES.BOOT_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 37 + name: STATES.BOOT_MIGRATE_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 38 + name: STATES.PROLOG_MIGRATE_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 39 + name: STATES.PROLOG_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 40 + name: STATES.EPILOG_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 41 + name: STATES.EPILOG_STOP_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 42 + name: STATES.EPILOG_UNDEPLOY_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 43 + name: STATES.PROLOG_MIGRATE_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 44 + name: STATES.PROLOG_MIGRATE_POWEROFF_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 45 + name: STATES.PROLOG_MIGRATE_SUSPEND, + color: COLOR.info.main, + meaning: '' + }, + { // 46 + name: STATES.PROLOG_MIGRATE_SUSPEND_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 47 + name: STATES.BOOT_UNDEPLOY_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 48 + name: STATES.BOOT_STOPPED_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 49 + name: STATES.PROLOG_RESUME_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 50 + name: STATES.PROLOG_UNDEPLOY_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 51 + name: STATES.DISK_SNAPSHOT_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 52 + name: STATES.DISK_SNAPSHOT_REVERT_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 53 + name: STATES.DISK_SNAPSHOT_DELETE_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 54 + name: STATES.DISK_SNAPSHOT_SUSPENDED, + color: COLOR.info.main, + meaning: '' + }, + { // 55 + name: STATES.DISK_SNAPSHOT_REVERT_SUSPENDED, + color: COLOR.info.main, + meaning: '' + }, + { // 56 + name: STATES.DISK_SNAPSHOT_DELETE_SUSPENDED, + color: COLOR.info.main, + meaning: '' + }, + { // 57 + name: STATES.DISK_SNAPSHOT, + color: COLOR.info.main, + meaning: '' + }, + { // 58 + name: STATES.DISK_SNAPSHOT_REVERT, + color: COLOR.info.main, + meaning: '' + }, + { // 59 + name: STATES.DISK_SNAPSHOT_DELETE, + color: COLOR.info.main, + meaning: '' + }, + { // 60 + name: STATES.PROLOG_MIGRATE_UNKNOWN, + color: COLOR.info.main, + meaning: '' + }, + { // 61 + name: STATES.PROLOG_MIGRATE_UNKNOWN_FAILURE, + color: COLOR.warning.main, + meaning: '' + }, + { // 62 + name: STATES.DISK_RESIZE, + color: COLOR.info.main, + meaning: '' + }, + { // 63 + name: STATES.DISK_RESIZE_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 64 + name: STATES.DISK_RESIZE_UNDEPLOYED, + color: COLOR.info.main, + meaning: '' + }, + { // 65 + name: STATES.HOTPLUG_NIC_POWEROFF, + color: COLOR.info.main, + meaning: '' + }, + { // 66 + name: STATES.HOTPLUG_RESIZE, + color: COLOR.info.main, + meaning: '' + }, + { // 67 + name: STATES.HOTPLUG_SAVEAS_UNDEPLOYED, + color: COLOR.info.main, + meaning: '' + }, + { // 68 + name: STATES.HOTPLUG_SAVEAS_STOPPED, + color: COLOR.info.main, + meaning: '' + } +] diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/index.js index e453986bf3..31e3047b18 100644 --- a/src/fireedge/src/client/containers/ApplicationsTemplates/index.js +++ b/src/fireedge/src/client/containers/ApplicationsTemplates/index.js @@ -21,7 +21,7 @@ function ApplicationsTemplates () { const { getApplicationsTemplates } = useApplicationTemplateApi() const { error, fetchRequest, loading, reloading } = useFetch(getApplicationsTemplates) - console.log({ error }) + useEffect(() => { fetchRequest() }, []) return ( diff --git a/src/fireedge/src/client/containers/Providers/Sections/info.js b/src/fireedge/src/client/containers/Providers/Sections/info.js index acd5c67125..3e6a5dda7d 100644 --- a/src/fireedge/src/client/containers/Providers/Sections/info.js +++ b/src/fireedge/src/client/containers/Providers/Sections/info.js @@ -14,7 +14,6 @@ import { Action } from 'client/components/Cards/SelectCard' import { Tr } from 'client/components/HOC' import { T } from 'client/constants' -import * as Types from 'client/types/provision' import useStyles from 'client/containers/Providers/Sections/styles' const Info = memo(({ fetchProps }) => { @@ -153,7 +152,7 @@ const Info = memo(({ fetchProps }) => { Info.propTypes = { fetchProps: PropTypes.shape({ - data: Types.Provision.isRequired + data: PropTypes.object.isRequired }).isRequired } diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/datastores.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/datastores.js index 90efee683b..d0f994e044 100644 --- a/src/fireedge/src/client/containers/Provisions/DialogInfo/datastores.js +++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/datastores.js @@ -8,7 +8,6 @@ import { useDatastoreApi, useProvisionApi } from 'client/features/One' import { useGeneralApi } from 'client/features/General' import { ListCards } from 'client/components/List' import { DatastoreCard } from 'client/components/Cards' -import * as Types from 'client/types/provision' const Datastores = memo( ({ hidden, data, reloading, refetchProvision, disableAllActions }) => { @@ -54,7 +53,7 @@ const Datastores = memo( ) Datastores.propTypes = { - data: Types.Provision.isRequired, + data: PropTypes.object.isRequired, hidden: PropTypes.bool, refetchProvision: PropTypes.func, reloading: PropTypes.bool, diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js index 0ad868dd7e..1ec5465af9 100644 --- a/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js +++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js @@ -8,7 +8,6 @@ import { useHostApi, useProvisionApi } from 'client/features/One' import { useGeneralApi } from 'client/features/General' import { ListCards } from 'client/components/List' import { HostCard } from 'client/components/Cards' -import * as Types from 'client/types/provision' const Hosts = memo( ({ hidden, data, reloading, refetchProvision, disableAllActions }) => { @@ -62,7 +61,7 @@ const Hosts = memo( prev.hidden === next.hidden && prev.reloading === next.reloading) Hosts.propTypes = { - data: Types.Provision.isRequired, + data: PropTypes.object.isRequired, hidden: PropTypes.bool, refetchProvision: PropTypes.func, reloading: PropTypes.bool, diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/index.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/index.js index 4ec1695acf..70976a3b3b 100644 --- a/src/fireedge/src/client/containers/Provisions/DialogInfo/index.js +++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/index.js @@ -16,8 +16,6 @@ import NetworksTab from 'client/containers/Provisions/DialogInfo/networks' import HostsTab from 'client/containers/Provisions/DialogInfo/hosts' import LogTab from 'client/containers/Provisions/DialogInfo/log' -import * as Types from 'client/types/provision' - const TABS = [ { name: 'info', icon: InfoIcon, content: InfoTab }, { name: 'datastores', icon: DatastoreIcon, content: DatastoresTab }, @@ -78,7 +76,7 @@ const DialogInfo = ({ disableAllActions, fetchProps }) => { DialogInfo.propTypes = { disableAllActions: PropTypes.bool, fetchProps: PropTypes.shape({ - data: Types.Provision.isRequired, + data: PropTypes.object.isRequired, fetchRequest: PropTypes.func, reloading: PropTypes.bool }).isRequired diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/info.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/info.js index cc277b4a31..184378812b 100644 --- a/src/fireedge/src/client/containers/Provisions/DialogInfo/info.js +++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/info.js @@ -1,4 +1,5 @@ import React, { memo } from 'react' +import PropTypes from 'prop-types' import clsx from 'clsx' import { List, ListItem, Typography, Grid, Paper, Divider } from '@material-ui/core' @@ -7,10 +8,9 @@ import { Check as CheckIcon, Square as BlankSquareIcon } from 'iconoir-react' import useStyles from 'client/containers/Provisions/DialogInfo/styles' import { StatusChip } from 'client/components/Status' import { Tr } from 'client/components/HOC' -import * as Types from 'client/types/provision' import { T, PROVISIONS_STATES } from 'client/constants' -const Info = memo(({ data }) => { +const Info = memo(({ data = {} }) => { const classes = useStyles() const { ID, GNAME, UNAME, PERMISSIONS, TEMPLATE } = data const { @@ -124,11 +124,11 @@ const Info = memo(({ data }) => { }) Info.propTypes = { - data: Types.Provision.isRequired + data: PropTypes.object.isRequired } Info.defaultProps = { - data: {} + data: undefined } Info.displayName = 'Info' diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/log.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/log.js index 4f7deb6d8c..29ee1998d0 100644 --- a/src/fireedge/src/client/containers/Provisions/DialogInfo/log.js +++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/log.js @@ -6,10 +6,9 @@ import { LinearProgress } from '@material-ui/core' import { useFetch, useSocket } from 'client/hooks' import { useProvisionApi } from 'client/features/One' import DebugLog, { LogUtils } from 'client/components/DebugLog' -import * as Types from 'client/types/provision' const Log = React.memo(({ hidden, data: { ID } }) => { - const { getProvision } = useSocket() + const { getProvisionSocket } = useSocket() const { getProvisionLog } = useProvisionApi() const { @@ -33,14 +32,14 @@ const Log = React.memo(({ hidden, data: { ID } }) => { return loading ? ( ) : ( - + ) }, (prev, next) => prev.hidden === next.hidden && prev.reloading === next.reloading ) Log.propTypes = { - data: Types.Provision.isRequired, + data: PropTypes.object.isRequired, hidden: PropTypes.bool, fetchRequest: PropTypes.func } diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js index 15b9a8218e..c64229888a 100644 --- a/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js +++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js @@ -8,7 +8,6 @@ import { useVNetworkApi, useProvisionApi } from 'client/features/One' import { useGeneralApi } from 'client/features/General' import { ListCards } from 'client/components/List' import { NetworkCard } from 'client/components/Cards' -import * as Types from 'client/types/provision' const Networks = memo( ({ hidden, data, reloading, refetchProvision, disableAllActions }) => { @@ -54,7 +53,7 @@ const Networks = memo( ) Networks.propTypes = { - data: Types.Provision.isRequired, + data: PropTypes.object.isRequired, hidden: PropTypes.bool, refetchProvision: PropTypes.func, reloading: PropTypes.bool, diff --git a/src/fireedge/src/client/containers/Provisions/Form/Create/index.js b/src/fireedge/src/client/containers/Provisions/Form/Create/index.js index 0fcf63c496..fbc80456ad 100644 --- a/src/fireedge/src/client/containers/Provisions/Form/Create/index.js +++ b/src/fireedge/src/client/containers/Provisions/Form/Create/index.js @@ -27,7 +27,7 @@ function ProvisionCreateForm () { const [uuid, setUuid] = useState(undefined) - const { getProvision } = useSocket() + const { getProvisionSocket } = useSocket() const { getProviders } = useProviderApi() const { createProvision } = useProvisionApi() const { enqueueInfo } = useGeneralApi() @@ -80,7 +80,7 @@ function ProvisionCreateForm () { return ( { + const classes = useStyles() + const { getProviderConnection } = useProviderApi() + + const [showConnection, setShowConnection] = useState(undefined) + + const { ID, NAME, GNAME, UNAME, PERMISSIONS, TEMPLATE } = data + const { + connection, + description, + provider: providerName, + registration_time: time + } = TEMPLATE?.PROVISION_BODY + + const hasConnection = connection && Object.keys(connection).length > 0 + + const isChecked = checked => + checked === '1' ? : + + const ConnectionButton = () => ( + } + cy='provider-connection' + handleClick={() => getProviderConnection(ID).then(setShowConnection)} + /> + ) + + return ( + + + + + + {Tr(T.Information)} + + + + {'ID'} + {ID} + + + {Tr(T.Name)} + {NAME} + + + {Tr(T.Description)} + {description} + + + {Tr(T.Provider)} + {providerName} + + + {Tr(T.RegistrationTime)} + + {new Date(time * 1000).toLocaleString()} + + + + + {hasConnection && ( + + + + {Tr(T.Credentials)} + + {!showConnection && } + + + + {Object.entries(connection)?.map(([key, value]) => + typeof value === 'string' && ( + + {key} + + {showConnection?.[key] ?? value} + + + ))} + + + )} + + + + + + {Tr(T.Permissions)} + {Tr(T.Use)} + {Tr(T.Manage)} + {Tr(T.Admin)} + + + + {Tr(T.Owner)} + {isChecked(PERMISSIONS.OWNER_U)} + {isChecked(PERMISSIONS.OWNER_M)} + {isChecked(PERMISSIONS.OWNER_A)} + + + {Tr(T.Group)} + {isChecked(PERMISSIONS.GROUP_U)} + {isChecked(PERMISSIONS.GROUP_M)} + {isChecked(PERMISSIONS.GROUP_A)} + + + {Tr(T.Other)} + {isChecked(PERMISSIONS.OTHER_U)} + {isChecked(PERMISSIONS.OTHER_M)} + {isChecked(PERMISSIONS.OTHER_A)} + + + + + + + {Tr(T.Ownership)} + + + + {Tr(T.Owner)} + {UNAME} + + + {Tr(T.Group)} + {GNAME} + + + + + + ) +}) + +Info.propTypes = { + data: PropTypes.object.isRequired +} + +Info.defaultProps = { + data: {} +} + +Info.displayName = 'Info' + +export default Info diff --git a/src/fireedge/src/client/containers/VirtualMachines/Sections/styles.js b/src/fireedge/src/client/containers/VirtualMachines/Sections/styles.js new file mode 100644 index 0000000000..8462b9b88f --- /dev/null +++ b/src/fireedge/src/client/containers/VirtualMachines/Sections/styles.js @@ -0,0 +1,32 @@ +import { makeStyles } from '@material-ui/core' + +export default makeStyles(theme => ({ + marginBottom: { + marginBottom: theme.spacing(2) + }, + list: { + '& p': { + ...theme.typography.body2, + overflow: 'hidden', + textOverflow: 'ellipsis' + }, + '&.w-50 > *': { + '& > p, & > span': { + width: '50%' + } + }, + '&.w-25 > *': { + '& > p, & > span': { + width: '25%' + } + } + }, + title: { + '& p.bold': { + fontWeight: theme.typography.fontWeightBold + } + }, + alignToRight: { + textAlign: 'right' + } +})) diff --git a/src/fireedge/src/client/containers/VirtualMachines/index.js b/src/fireedge/src/client/containers/VirtualMachines/index.js new file mode 100644 index 0000000000..67f67c421c --- /dev/null +++ b/src/fireedge/src/client/containers/VirtualMachines/index.js @@ -0,0 +1,78 @@ +import React, { useEffect } from 'react' + +import { Container, Box } from '@material-ui/core' +import { Trash as DeleteIcon } from 'iconoir-react' + +import { useAuth } from 'client/features/Auth' +import { useVm, useVmApi } from 'client/features/One' +import { useGeneralApi } from 'client/features/General' +import { useFetch, useSearch } from 'client/hooks' + +import { ListHeader, ListCards } from 'client/components/List' +import { VirtualMachineCard } from 'client/components/Cards' +// import { DialogRequest } from 'client/components/Dialogs' +// import Information from 'client/containers/VirtualMachines/Sections/info' +import { T } from 'client/constants' +import { filterDoneVms } from 'client/models/VirtualMachine' + +function VirtualMachines () { + // const [showDialog, setShowDialog] = useState(false) + + const vms = useVm() + const { getVm, getVms, terminateVm } = useVmApi() + const { filterPool } = useAuth() + + const { enqueueSuccess } = useGeneralApi() + + const { fetchRequest, loading, reloading } = useFetch(getVms) + const { result, handleChange } = useSearch({ + list: vms, + listOptions: { shouldSort: true, keys: ['ID', 'NAME'] } + }) + + useEffect(() => { fetchRequest() }, [filterPool]) + + // const handleCancel = () => setShowDialog(false) + + return ( + + fetchRequest(undefined, { reload: true }), + isSubmitting: Boolean(loading || reloading) + }} + searchProps={{ handleChange }} + /> + + ({ + actions: [ + { + handleClick: () => terminateVm(ID) + .then(() => enqueueSuccess(`VM terminate - ID: ${ID}`)) + .then(() => fetchRequest(undefined, { reload: true })), + icon: , + cy: 'vm-delete' + } + ] + })} + /> + + {/* {showDialog !== false && ( + getVm(showDialog.id)} + dialogProps={{ handleCancel, ...showDialog }} + > + {({ data }) => } + + )} */} + + ) +} + +export default VirtualMachines diff --git a/src/fireedge/src/client/containers/WebConsole/index.js b/src/fireedge/src/client/containers/WebConsole/index.js index 149b828958..331f52c309 100644 --- a/src/fireedge/src/client/containers/WebConsole/index.js +++ b/src/fireedge/src/client/containers/WebConsole/index.js @@ -50,16 +50,12 @@ const Webconsole = () => { const classes = useStyles() const [listening, setListening] = useState(false) const [response, setResponse] = useState([]) - const { getHooks } = useSocket() + const { getHooksSocket } = useSocket() const toggleListening = () => setListening(list => !list) useEffect(() => { - listening - ? getHooks.on(data => setResponse(prev => [...prev, data])) - : getHooks.off() - - return getHooks.off + listening && getHooksSocket(data => setResponse(prev => [...prev, data])) }, [listening]) return ( diff --git a/src/fireedge/src/client/dev/index.js b/src/fireedge/src/client/dev/index.js index 1a3310f7b0..aa445c5660 100644 --- a/src/fireedge/src/client/dev/index.js +++ b/src/fireedge/src/client/dev/index.js @@ -17,6 +17,7 @@ import * as React from 'react' import { render } from 'react-dom' import { createStore } from 'client/store' +import rootReducer from 'client/store/reducers' import App from 'client/dev/_app' const { store } = createStore({ initState: window.REDUX_DATA }) @@ -29,7 +30,5 @@ if (process.env.NODE_ENV === 'development' && module.hot) { render(, document.getElementById('root')) }) - module.hot.accept('../reducers', () => { - store.replaceReducer(require('../reducers').default) - }) + module.hot.accept('../store/reducers', () => store.replaceReducer(rootReducer)) } diff --git a/src/fireedge/src/client/features/General/actions.js b/src/fireedge/src/client/features/General/actions.js index 030fae73e0..8825ff2933 100644 --- a/src/fireedge/src/client/features/General/actions.js +++ b/src/fireedge/src/client/features/General/actions.js @@ -5,6 +5,12 @@ export const changeZone = createAction('Change zone') export const changeLoading = createAction('Change loading') export const changeTitle = createAction('Change title') -export const enqueueSnackbar = createAction('Enqueue snackbar') export const dismissSnackbar = createAction('Dismiss snackbar') export const deleteSnackbar = createAction('Delete snackbar') + +export const enqueueSnackbar = createAction( + 'Enqueue snackbar', + (payload = {}) => { + if (payload?.message?.length > 0) return { payload } + } +) diff --git a/src/fireedge/src/client/features/General/hooks.js b/src/fireedge/src/client/features/General/hooks.js index 679919872d..7de4b41860 100644 --- a/src/fireedge/src/client/features/General/hooks.js +++ b/src/fireedge/src/client/features/General/hooks.js @@ -1,8 +1,7 @@ import { useDispatch, useSelector } from 'react-redux' import * as actions from 'client/features/General/actions' - -const generateKey = () => new Date().getTime() + Math.random() +import { generateKey } from 'client/utils' export const useGeneral = () => ( useSelector(state => state.general) @@ -17,15 +16,6 @@ export const useGeneralApi = () => { changeTitle: title => dispatch(actions.changeTitle(title)), changeZone: zone => dispatch(actions.changeZone(zone)), - enqueueSnackbar: notification => { - const key = notification.options && notification.options.key - - return dispatch(actions.enqueueSnackbar({ - key: key || generateKey(), - message: String(notification.message) || '', - options: notification.options || {} - })) - }, // dismiss all if no key has been defined dismissSnackbar: key => dispatch( actions.dismissSnackbar({ key, dismissAll: !key }) @@ -34,6 +24,13 @@ export const useGeneralApi = () => { actions.deleteSnackbar({ key }) ), + enqueueSnackbar: ({ message, options = {} } = {}) => dispatch( + actions.enqueueSnackbar({ + key: generateKey(), + message, + options + }) + ), enqueueSuccess: message => dispatch( actions.enqueueSnackbar({ key: generateKey(), @@ -45,14 +42,14 @@ export const useGeneralApi = () => { actions.enqueueSnackbar({ key: generateKey(), message, - options: { variant: 'success' } + options: { variant: 'error' } }) ), enqueueInfo: message => dispatch( actions.enqueueSnackbar({ key: generateKey(), message, - options: { variant: 'success' } + options: { variant: 'info' } }) ) } diff --git a/src/fireedge/src/client/features/General/slice.js b/src/fireedge/src/client/features/General/slice.js index 4efe9986ee..2b32c69e7a 100644 --- a/src/fireedge/src/client/features/General/slice.js +++ b/src/fireedge/src/client/features/General/slice.js @@ -1,6 +1,7 @@ import { createSlice } from '@reduxjs/toolkit' import * as actions from 'client/features/General/actions' +import { generateKey } from 'client/utils' const initial = { zone: 0, @@ -84,12 +85,12 @@ const { reducer } = createSlice({ isLoading: false, notifications: [ ...state.notifications, - { - key: new Date().getTime() + Math.random(), + (payload?.length > 0 && { + key: generateKey(), message: payload, options: { variant: 'error' } - } - ] + }) + ].filter(Boolean) }) ) } diff --git a/src/fireedge/src/client/features/One/slice.js b/src/fireedge/src/client/features/One/slice.js index 99291d492f..124138d5e6 100644 --- a/src/fireedge/src/client/features/One/slice.js +++ b/src/fireedge/src/client/features/One/slice.js @@ -1,5 +1,7 @@ import { createSlice } from '@reduxjs/toolkit' +import { socketEventState } from 'client/features/One/socket/actions' + const initial = { requests: {}, @@ -35,6 +37,10 @@ const { actions, reducer } = createSlice({ extraReducers: builder => { builder .addCase('logout', () => initial) + .addCase( + socketEventState.fulfilled, + (state, { payload }) => ({ ...state, ...payload }) + ) .addMatcher( ({ type }) => type.includes('/pool') && type.endsWith('/pending'), (state, { meta, type }) => { diff --git a/src/fireedge/src/client/features/One/socket/actions.js b/src/fireedge/src/client/features/One/socket/actions.js new file mode 100644 index 0000000000..560209b637 --- /dev/null +++ b/src/fireedge/src/client/features/One/socket/actions.js @@ -0,0 +1,138 @@ +import { createAsyncThunk } from '@reduxjs/toolkit' + +import * as actions from 'client/features/General/actions' +import { generateKey } from 'client/utils' + +const MESSAGE_PROVISION_SUCCESS_CREATED = 'Provision successfully created' + +const COMMANDS = { + create: 'create', + update: 'update', + delete: 'delete' +} + +const RESOURCES = { + acl: 'acl', + app: 'apps', + cluster: 'clusters', + datastore: 'datastores', + file: 'files', + group: 'groups', + host: 'hosts', + image: 'images', + marketplace: 'marketplaces', + secgroups: 'securityGroups', + template: 'templates', + user: 'users', + vdc: 'vdc', + vm: 'vms', + vmgroup: 'vmGroups', + vn: 'vNetworks', + vntemplate: 'vNetworksTemplates', + zone: 'zones', + document: { + 100: 'applications', + 101: 'applicationsTemplates', + 102: 'providers', + 103: 'provisions' + } +} + +const getResourceFromEventApi = (eventApi = {}) => { + const { CALL: command = '', CALL_INFO: info = {} } = eventApi?.HOOK_MESSAGE + const { EXTRA: extra, RESULT: result, PARAMETERS } = info + + // command: 'one.resourceName.action' + const [, resourceName, action] = command.split('.') + + // success: 1 || error: 0 + const success = result === '1' + + const value = extra?.[String(resourceName).toUpperCase()] + + const resource = RESOURCES[resourceName] + const name = resource?.[value?.TYPE] ?? resource + + const [, { VALUE: output }] = PARAMETERS?.PARAMETER + ?.filter(({ TYPE }) => TYPE === 'OUT') + + return { + action, + name, + value, + success, + output + } +} + +export const socketEventApi = createAsyncThunk( + 'socket/event-api', + ({ data }) => { + const { action, name, value, success, output } = getResourceFromEventApi(data) + + // console.log({ action, name, value, success, output }) + + return (success && value && action !== COMMANDS.delete) ? { [name]: value } : {} + }, + { + condition: payload => payload?.data?.HOOK_MESSAGE?.HOOK_TYPE === 'API' + } +) + +export const socketEventState = createAsyncThunk( + 'socket/event-state', + ({ data }, { getState }) => { + // possible hook objects: VM, IMAGE, HOST + const { RESOURCE_ID, HOOK_OBJECT: name, [name]: value } = data?.HOOK_MESSAGE + + // update the list if event returns resource value + if (!value || value === '') return + + const { NAME, STATE, LCM_STATE } = value + + // this won't be a document resource never + const resource = RESOURCES[String(name).toLowerCase()] + + const currentList = getState()?.one?.[resource] ?? [] + + const exists = currentList.some(({ ID }) => ID === RESOURCE_ID) + + // update if exists in current list, if not add it + const updatedList = exists + ? currentList?.map(item => ({ + ...item, + ...(item?.ID === RESOURCE_ID && { + NAME, + STATE, + ...(item?.LCM_STATE && { LCM_STATE }) + }) + })) + : [value, ...currentList] + + return { [resource]: updatedList } + }, + { + condition: payload => payload?.data?.HOOK_MESSAGE?.HOOK_TYPE === 'STATE' + } +) + +export const socketCreateProvision = createAsyncThunk( + 'socket/create-provision', + (_, { dispatch }) => { + dispatch(actions.enqueueSnackbar({ + key: generateKey(), + message: MESSAGE_PROVISION_SUCCESS_CREATED, + options: { variant: 'success' } + })) + }, + { + condition: (payload = {}) => { + const { command, data } = payload + + return ( + command === 'create' && + data === MESSAGE_PROVISION_SUCCESS_CREATED + ) + } + } +) diff --git a/src/fireedge/src/client/features/One/vm/actions.js b/src/fireedge/src/client/features/One/vm/actions.js index 3e59a99525..d1cbe59200 100644 --- a/src/fireedge/src/client/features/One/vm/actions.js +++ b/src/fireedge/src/client/features/One/vm/actions.js @@ -8,3 +8,14 @@ export const getVms = createAction( vmService.getVms, response => ({ vms: response }) ) + +export const terminateVm = createAction( + 'provider/delete', + payload => vmService.actionVm({ + ...payload, + action: { + params: { hard: false }, + perform: 'terminate' + } + }) +) diff --git a/src/fireedge/src/client/features/One/vm/hooks.js b/src/fireedge/src/client/features/One/vm/hooks.js index d8cf3ff39d..d42587bda8 100644 --- a/src/fireedge/src/client/features/One/vm/hooks.js +++ b/src/fireedge/src/client/features/One/vm/hooks.js @@ -18,6 +18,7 @@ export const useVmApi = () => { return { getVm: id => unwrapDispatch(actions.getVm({ id })), - getVms: () => unwrapDispatch(actions.getVms()) + getVms: () => unwrapDispatch(actions.getVms()), + terminateVm: id => unwrapDispatch(actions.terminateVm({ id })) } } diff --git a/src/fireedge/src/client/features/One/vm/services.js b/src/fireedge/src/client/features/One/vm/services.js index b3655381c8..1e7c9d90be 100644 --- a/src/fireedge/src/client/features/One/vm/services.js +++ b/src/fireedge/src/client/features/One/vm/services.js @@ -4,22 +4,35 @@ import { requestParams, RestClient } from 'client/utils' import { poolRequest } from 'client/features/One/utils' export const vmService = ({ - getVm: ({ filter, id }) => { + getVm: async ({ filter, id }) => { const name = Actions.VM_INFO const { url, options } = requestParams( { filter, id }, { name, ...Commands[name] } ) - return RestClient.get(url, options).then(res => { - if (!res?.id || res?.id !== httpCodes.ok.id) throw res + const res = await RestClient.get(url, options) - return res?.data?.VM ?? {} - }) + if (!res?.id || res?.id !== httpCodes.ok.id) throw res + + return res?.data?.VM ?? {} }, getVms: data => { const name = Actions.VM_POOL_INFO const command = { name, ...Commands[name] } return poolRequest(data, command, 'VM') + }, + actionVm: async ({ action, id }) => { + const name = Actions.VM_ACTION + const { url, options } = requestParams( + { action, id }, + { name, ...Commands[name] } + ) + + const res = await RestClient.put(url, options) + + if (!res?.id || res?.id !== httpCodes.ok.id) throw res + + return res?.data?.VM ?? {} } }) diff --git a/src/fireedge/src/client/hooks/index.js b/src/fireedge/src/client/hooks/index.js index 8cd0f2304f..041304751f 100644 --- a/src/fireedge/src/client/hooks/index.js +++ b/src/fireedge/src/client/hooks/index.js @@ -1,6 +1,5 @@ import useFetch from 'client/hooks/useFetch' import useFetchAll from 'client/hooks/useFetchAll' -import useGeneral from 'client/hooks/useGeneral' import useList from 'client/hooks/useList' import useListForm from 'client/hooks/useListForm' import useNearScreen from 'client/hooks/useNearScreen' @@ -10,7 +9,6 @@ import useSocket from 'client/hooks/useSocket' export { useFetch, useFetchAll, - useGeneral, useList, useListForm, useNearScreen, diff --git a/src/fireedge/src/client/hooks/useGeneral.js b/src/fireedge/src/client/hooks/useGeneral.js deleted file mode 100644 index 273a910cad..0000000000 --- a/src/fireedge/src/client/hooks/useGeneral.js +++ /dev/null @@ -1,54 +0,0 @@ -import { useCallback } from 'react' -import { useSelector, useDispatch, shallowEqual } from 'react-redux' - -import * as actions from 'client/actions/general' - -export default function useGeneral () { - const { - zone, - isLoading, - isOpenMenu, - isFixMenu - } = useSelector(state => state?.General, shallowEqual) - const dispatch = useDispatch() - - const fixMenu = useCallback(isFixed => dispatch(actions.fixMenu(isFixed)), [ - dispatch - ]) - - const openMenu = useCallback(isOpen => dispatch(actions.openMenu(isOpen)), [ - dispatch - ]) - - const changeZone = useCallback(zone => dispatch(actions.changeZone(zone)), [ - dispatch - ]) - - const changeLoading = useCallback( - loading => dispatch(actions.changeLoading(loading)), - [dispatch] - ) - - const showSuccess = useCallback( - ({ message }) => dispatch(actions.enqueueSuccess(message)), - [dispatch] - ) - - const showError = useCallback( - ({ message }) => dispatch(actions.enqueueError(message)), - [dispatch] - ) - - return { - isFixMenu, - isLoading, - isOpenMenu, - zone, - changeZone, - openMenu, - fixMenu, - changeLoading, - showSuccess, - showError - } -} diff --git a/src/fireedge/src/client/hooks/useSocket.js b/src/fireedge/src/client/hooks/useSocket.js index 137ed2973a..ed6506de0f 100644 --- a/src/fireedge/src/client/hooks/useSocket.js +++ b/src/fireedge/src/client/hooks/useSocket.js @@ -1,24 +1,20 @@ -import { useContext, useMemo } from 'react' +import { useContext, useCallback } from 'react' +import { SOCKETS } from 'client/constants' import { SocketContext } from 'client/providers/socketProvider' -const SOCKETS = { - hooks: 'hooks', - provision: 'provision' -} - export default function useSocket () { const { socket, isConnected } = useContext(SocketContext) - const getHooks = useMemo(() => ({ - on: (func) => isConnected && socket.on(SOCKETS.hooks, func), - off: () => isConnected && socket.off() + const getHooksSocket = useCallback(func => ({ + on: () => isConnected && socket.on(SOCKETS.hooks, func), + off: () => isConnected && socket.off(SOCKETS.hooks, func) }), [socket, isConnected]) - const getProvision = useMemo(() => ({ - on: (func) => isConnected && socket.on(SOCKETS.provision, func), - off: () => isConnected && socket.off() + const getProvisionSocket = useCallback(func => ({ + on: () => isConnected && socket.on(SOCKETS.provision, func), + off: () => isConnected && socket.off(SOCKETS.provision, func) }), [socket, isConnected]) - return { isConnected, getHooks, getProvision } + return { isConnected, getHooksSocket, getProvisionSocket } } diff --git a/src/fireedge/src/client/models/VirtualMachine.js b/src/fireedge/src/client/models/VirtualMachine.js new file mode 100644 index 0000000000..8275299161 --- /dev/null +++ b/src/fireedge/src/client/models/VirtualMachine.js @@ -0,0 +1,10 @@ +import { STATES, VM_STATES, VM_LCM_STATES } from 'client/constants' + +export const filterDoneVms = (vms = []) => + vms.filter(({ STATE }) => VM_STATES[STATE]?.name !== STATES.DONE) + +export const getState = ({ STATE, LCM_STATE } = {}) => { + const state = VM_STATES[+STATE] + + return state?.name === STATES.ACTIVE ? VM_LCM_STATES[+LCM_STATE] : state +} diff --git a/src/fireedge/src/client/providers/notistackProvider.js b/src/fireedge/src/client/providers/notistackProvider.js index 7870b97d03..2b7215d17b 100644 --- a/src/fireedge/src/client/providers/notistackProvider.js +++ b/src/fireedge/src/client/providers/notistackProvider.js @@ -10,19 +10,19 @@ const useStyles = makeStyles(({ palette }) => ({ wordBreak: 'break-all' }, variantSuccess: { - backgroundColor: `${palette.success.main} !important`, + backgroundColor: palette.success.main, color: palette.success.contrastText }, variantError: { - backgroundColor: `${palette.error.main} !important`, + backgroundColor: palette.error.main, color: palette.error.contrastText }, variantInfo: { - backgroundColor: `${palette.debug.main} !important`, + backgroundColor: palette.debug.main, color: palette.debug.contrastText }, variantWarning: { - backgroundColor: `${palette.warning.main} !important`, + backgroundColor: palette.warning.main, color: palette.warning.contrastText } })) diff --git a/src/fireedge/src/client/providers/socketProvider.js b/src/fireedge/src/client/providers/socketProvider.js index ed3bd81dae..dfcfd6ddf5 100644 --- a/src/fireedge/src/client/providers/socketProvider.js +++ b/src/fireedge/src/client/providers/socketProvider.js @@ -1,11 +1,13 @@ import React, { createContext, useEffect, useState } from 'react' import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import io from 'socket.io-client' -import { WEBSOCKET_URL } from 'client/constants' +import socketIO from 'socket.io-client' +import { useSelector, useDispatch } from 'react-redux' -const websocket = query => io({ path: WEBSOCKET_URL, query }) +import { WEBSOCKET_URL, SOCKETS } from 'client/constants' +import * as sockets from 'client/features/One/socket/actions' + +const createWebsocket = query => socketIO({ path: WEBSOCKET_URL, query }) const CONNECT = 'connect' const DISCONNECT = 'disconnect' @@ -15,6 +17,8 @@ export const SocketContext = createContext(null) const SocketProvider = ({ children }) => { const [socket, setSocket] = useState({}) const [isConnected, setConnected] = useState(false) + + const dispatch = useDispatch() const { jwt, zone } = useSelector(state => ({ zone: state?.general?.zone, jwt: state?.auth?.jwt @@ -23,14 +27,23 @@ const SocketProvider = ({ children }) => { useEffect(() => { if (!jwt) return - const client = websocket({ token: jwt, zone }) + const client = createWebsocket({ token: jwt, zone }) + setSocket(client) + client.on(CONNECT, () => setConnected(true)) client.on(DISCONNECT, () => setConnected(false)) - setSocket(client) + + client.on(SOCKETS.hooks, data => { + dispatch(sockets.socketEventState(data)) + }) + + client.on(SOCKETS.provision, data => { + dispatch(sockets.socketCreateProvision(data)) + }) return () => { setSocket(null) - return client.disconnect() + client?.disconnect() } }, [jwt, zone]) diff --git a/src/fireedge/src/client/reducers/auth.js b/src/fireedge/src/client/reducers/auth.js deleted file mode 100644 index a86f12c5d8..0000000000 --- a/src/fireedge/src/client/reducers/auth.js +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - -const { Actions: UserActions } = require('../actions/user') -const { - JWT_NAME, - FILTER_POOL, - DEFAULT_LANGUAGE, - DEFAULT_SCHEME -} = require('client/constants') - -const jwt = - typeof window !== 'undefined' - ? window.localStorage.getItem(JWT_NAME) ?? - window.sessionStorage.getItem(JWT_NAME) ?? - null - : null - -const initial = { - jwt, - user: null, - group: null, - error: null, - filterPool: FILTER_POOL.ALL_RESOURCES, - settings: { - scheme: DEFAULT_SCHEME, - lang: DEFAULT_LANGUAGE, - disableanimations: 'YES' - }, - isLoginInProcess: false, - isLoading: false, - firstRender: true -} - -const authentication = (state = initial, action) => { - switch (action.type) { - case UserActions.START_AUTH: - return { - ...state, - error: null, - firstRender: false, - isLoading: true - } - case UserActions.SUCCESS_AUTH: - return { - ...state, - error: null, - firstRender: false, - isLoading: false, - ...action.payload - } - case UserActions.SELECT_FILTER_GROUP: - return { - ...state, - isLoading: false, - isLoginInProcess: false, - ...action.payload - } - case UserActions.CHANGE_SETTINGS: - return { - ...state, - settings: { - ...initial.settings, - ...action.payload - } - } - case UserActions.FAILURE_AUTH: - return { - ...state, - jwt: null, - firstRender: false, - isLoading: false, - isLoginInProcess: false, - ...action.payload - } - case UserActions.LOGOUT: - return { - ...initial, - jwt: null, - firstRender: false - } - default: - return state - } -} - -module.exports = authentication diff --git a/src/fireedge/src/client/reducers/general.js b/src/fireedge/src/client/reducers/general.js deleted file mode 100644 index 86708f6f29..0000000000 --- a/src/fireedge/src/client/reducers/general.js +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - -const { Actions: PoolActions } = require('../actions/pool') -const { Actions: UserActions } = require('../actions/user') -const { Actions: GeneralActions } = require('../actions/general') - -const initial = { - zone: 0, - notifications: [], - isLoading: false, - isOpenMenu: false, - isFixMenu: false -} - -const General = (state = initial, action) => { - switch (action.type) { - case PoolActions.START_ONE_REQUEST: - return { ...state, isLoading: true } - case PoolActions.SUCCESS_ONE_REQUEST: - return { ...state, isLoading: false } - case PoolActions.FAILURE_ONE_REQUEST: - return { ...state, isLoading: false } - case GeneralActions.ENQUEUE_SNACKBAR: - return { - ...state, - notifications: [ - ...state.notifications, - { key: action.key, ...action.notification } - ] - } - case GeneralActions.CLOSE_SNACKBAR: - return { - ...state, - notifications: state.notifications.map(notification => - action.dismissAll || notification.key === action.key - ? { ...notification, dismissed: true } - : { ...notification } - ) - } - case GeneralActions.REMOVE_SNACKBAR: - return { - ...state, - notifications: state.notifications.filter( - notification => notification.key !== action.key - ) - } - case GeneralActions.CHANGE_LOADING: - return { ...state, ...action.payload } - case GeneralActions.CHANGE_ZONE: - return { ...state, ...action.payload } - case GeneralActions.TOGGLE_MENU: - return { ...state, isOpenMenu: action.isOpen } - case GeneralActions.FIX_MENU: - return { ...state, isFixMenu: action.isFixed } - case UserActions.LOGOUT: - return { ...initial } - default: - return state - } -} - -module.exports = General diff --git a/src/fireedge/src/client/reducers/index.js b/src/fireedge/src/client/reducers/index.js deleted file mode 100644 index a9bcf4c81f..0000000000 --- a/src/fireedge/src/client/reducers/index.js +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - -const { combineReducers } = require('redux') -const Opennebula = require('./opennebula') -const Zendesk = require('./zendesk') -const General = require('./general') -const Authenticated = require('./auth') - -const rootReducers = () => - combineReducers({ - Authenticated, - Opennebula, - Zendesk, - General - }) - -module.exports = rootReducers diff --git a/src/fireedge/src/client/reducers/opennebula.js b/src/fireedge/src/client/reducers/opennebula.js deleted file mode 100644 index ff3bebc512..0000000000 --- a/src/fireedge/src/client/reducers/opennebula.js +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - -const { Actions: PoolActions } = require('../actions/pool') -const { Actions: UserActions } = require('../actions/user') - -const initial = { - vm: [], - templates: [], - applications: [], - applicationsTemplates: [], - datastores: [], - virtualRouters: [], - vmGroups: [], - images: [], - files: [], - marketplaces: [], - apps: [], - vNetworks: [], - vNetworksTemplates: [], - securityGroups: [], - clusters: [], - hosts: [], - zones: [], - users: [], - groups: [], - vdc: [], - acl: [], - provisionsTemplates: [], - providers: [], - provisions: [] -} - -const Opennebula = (state = initial, action) => { - switch (action.type) { - case PoolActions.SUCCESS_ONE_REQUEST: - return { ...state, ...action.payload } - case UserActions.LOGOUT: - return { ...initial } - default: - return state - } -} - -module.exports = Opennebula diff --git a/src/fireedge/src/client/reducers/zendesk.js b/src/fireedge/src/client/reducers/zendesk.js deleted file mode 100644 index d935809e65..0000000000 --- a/src/fireedge/src/client/reducers/zendesk.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - -const initial = { - user: { - name: '' - }, - tickets: [] -} - -const Zendesk = (state = initial, action) => { - switch (action.type) { - case 'SETTICKET': { - const { tickets } = state - return { - ...state, - tickets - } - } - default: - return state - } -} - -module.exports = Zendesk diff --git a/src/fireedge/src/client/router/dev.js b/src/fireedge/src/client/router/dev.js index 13b1d4508c..0d36acdfed 100644 --- a/src/fireedge/src/client/router/dev.js +++ b/src/fireedge/src/client/router/dev.js @@ -1,6 +1,10 @@ import loadable from '@loadable/component' -import { Code as DevIcon } from 'iconoir-react' +import { + Code as DevIcon, + ViewGrid as VmIcon +} from 'iconoir-react' +const VirtualMachines = loadable(() => import('client/containers/VirtualMachines'), { ssr: false }) const TestApi = loadable(() => import('client/containers/TestApi'), { ssr: false }) const WebConsole = loadable(() => import('client/containers/WebConsole'), { ssr: false }) @@ -11,6 +15,14 @@ export const PATH = { } export const ENDPOINTS = [ + { + label: 'VMs', + path: PATH.VIRTUAL_MACHINES, + devMode: true, + sidebar: true, + icon: VmIcon, + Component: VirtualMachines + }, { label: 'Test API', path: PATH.TEST_API, diff --git a/src/fireedge/src/client/store.js b/src/fireedge/src/client/store/index.js similarity index 69% rename from src/fireedge/src/client/store.js rename to src/fireedge/src/client/store/index.js index fd56ae3d28..f4897685c8 100644 --- a/src/fireedge/src/client/store.js +++ b/src/fireedge/src/client/store/index.js @@ -2,10 +2,7 @@ import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit' import thunkMiddleware from 'redux-thunk' -import * as General from 'client/features/General' -import * as Auth from 'client/features/Auth' -import * as One from 'client/features/One' - +import rootReducer from 'client/store/reducers' import { isDevelopment } from 'client/utils' export const createStore = ({ initState = {}, services }) => { @@ -18,11 +15,7 @@ export const createStore = ({ initState = {}, services }) => { middleware.push(thunkMiddleware.withExtraArgument({ services })) const store = configureStore({ - reducer: { - general: General.reducer, - auth: Auth.reducer, - one: One.reducer - }, + reducer: rootReducer, devTools: isDevelopment(), middleware, preloadedState: initState diff --git a/src/fireedge/src/client/store/reducers.js b/src/fireedge/src/client/store/reducers.js new file mode 100644 index 0000000000..06cd3958a2 --- /dev/null +++ b/src/fireedge/src/client/store/reducers.js @@ -0,0 +1,12 @@ +const { combineReducers } = require('redux') +const General = require('client/features/General') +const Auth = require('client/features/Auth') +const One = require('client/features/One') + +const rootReducer = combineReducers({ + general: General.reducer, + auth: Auth.reducer, + one: One.reducer +}) + +module.exports = rootReducer diff --git a/src/fireedge/src/client/types/provision.js b/src/fireedge/src/client/types/provision.js deleted file mode 100644 index 11fccdd78f..0000000000 --- a/src/fireedge/src/client/types/provision.js +++ /dev/null @@ -1,166 +0,0 @@ -import PropTypes from 'prop-types' -import { PROVIDERS_TYPES, PROVISIONS_TYPES } from 'client/constants' - -const providerTypes = Object.values(PROVIDERS_TYPES).map(({ id }) => id) -const provisionTypes = Object.values(PROVISIONS_TYPES).map(({ id }) => id) - -export const UserInput = PropTypes.shape({ - name: PropTypes.string.isRequired, - description: PropTypes.string, - type: PropTypes.oneOf([ - 'text', - 'text64', - 'password', - 'number', - 'number-float', - 'range', - 'range-float', - 'boolean', - 'list', - 'array', - 'list-multiple' - ]).isRequired, - options: PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.string, PropTypes.number]) - ), - min_value: PropTypes.number, - max_value: PropTypes.number, - default: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]) -}) - -export const ProviderType = PropTypes.oneOf(providerTypes) - -export const ProvisionType = PropTypes.oneOf(provisionTypes) - -export const ProvisionHost = PropTypes.shape({ - im_mad: PropTypes.string.isRequired, - vm_mad: PropTypes.string.isRequired, - provision: PropTypes.shape({ - count: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]), - hostname: PropTypes.string - }) -}) - -export const ProviderPlainInfo = PropTypes.shape({ - image: PropTypes.string, - location_key: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string) - ]), - provision_type: ProvisionType.isRequired -}) - -export const ProviderTemplate = PropTypes.shape({ - name: PropTypes.string.isRequired, - description: PropTypes.string, - provider: ProviderType.isRequired, - plain: ProviderPlainInfo.isRequired, - connection: PropTypes.objectOf(PropTypes.string), - inputs: PropTypes.arrayOf(UserInput) -}) - -export const ProvisionTemplate = PropTypes.shape({ - name: PropTypes.string.isRequired, - description: PropTypes.string, - provider: ProviderType.isRequired, - provision_type: ProvisionType.isRequired, - defaults: PropTypes.shape({ - provision: PropTypes.shape({ - provider_name: PropTypes.string - }) - }).isRequired, - hosts: PropTypes.arrayOf(ProvisionHost), - inputs: PropTypes.arrayOf(UserInput) -}) - -export const Provider = PropTypes.shape({ - ID: PropTypes.string.isRequired, - UID: PropTypes.string.isRequired, - GID: PropTypes.string.isRequired, - UNAME: PropTypes.string.isRequired, - GNAME: PropTypes.string.isRequired, - NAME: PropTypes.string.isRequired, - TYPE: PropTypes.string.isRequired, - PERMISSIONS: PropTypes.shape({ - OWNER_U: PropTypes.oneOf(['0', '1']).isRequired, - OWNER_M: PropTypes.oneOf(['0', '1']).isRequired, - OWNER_A: PropTypes.oneOf(['0', '1']).isRequired, - GROUP_U: PropTypes.oneOf(['0', '1']).isRequired, - GROUP_M: PropTypes.oneOf(['0', '1']).isRequired, - GROUP_A: PropTypes.oneOf(['0', '1']).isRequired, - OTHER_U: PropTypes.oneOf(['0', '1']).isRequired, - OTHER_M: PropTypes.oneOf(['0', '1']).isRequired, - OTHER_A: PropTypes.oneOf(['0', '1']).isRequired - }).isRequired, - TEMPLATE: PropTypes.shape({ - PLAIN: ProviderPlainInfo, - PROVISION_BODY: PropTypes.oneOfType([ - // encrypted - PropTypes.string, - PropTypes.shape({ - provider: ProviderType, - connection: PropTypes.objectOf(PropTypes.string), - registration_time: PropTypes.number, - description: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]), - inputs: PropTypes.arrayOf(UserInput) - }).isRequired - ]) - }) -}) - -const ProvisionInfrastructure = PropTypes.shape({ - id: PropTypes.number.isRequired, - name: PropTypes.string.isRequired -}) - -export const Provision = PropTypes.shape({ - ID: PropTypes.string.isRequired, - UID: PropTypes.string.isRequired, - GID: PropTypes.string.isRequired, - UNAME: PropTypes.string.isRequired, - GNAME: PropTypes.string.isRequired, - NAME: PropTypes.string.isRequired, - TYPE: PropTypes.string.isRequired, - PERMISSIONS: PropTypes.shape({ - OWNER_U: PropTypes.oneOf(['0', '1']).isRequired, - OWNER_M: PropTypes.oneOf(['0', '1']).isRequired, - OWNER_A: PropTypes.oneOf(['0', '1']).isRequired, - GROUP_U: PropTypes.oneOf(['0', '1']).isRequired, - GROUP_M: PropTypes.oneOf(['0', '1']).isRequired, - GROUP_A: PropTypes.oneOf(['0', '1']).isRequired, - OTHER_U: PropTypes.oneOf(['0', '1']).isRequired, - OTHER_M: PropTypes.oneOf(['0', '1']).isRequired, - OTHER_A: PropTypes.oneOf(['0', '1']).isRequired - }).isRequired, - TEMPLATE: PropTypes.shape({ - BODY: PropTypes.shape({ - name: PropTypes.string, - description: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]), - start_time: PropTypes.number, - state: PropTypes.number, - provider: PropTypes.string, - provision: PropTypes.shape({ - infrastructure: PropTypes.shape({ - clusters: PropTypes.arrayOf(ProvisionInfrastructure), - datastores: PropTypes.arrayOf(ProvisionInfrastructure), - networks: PropTypes.arrayOf(ProvisionInfrastructure) - }), - resource: PropTypes.object - }), - image: PropTypes.string, - provision_type: ProvisionType - }).isRequired - }) -}) diff --git a/src/fireedge/src/client/utils/helpers.js b/src/fireedge/src/client/utils/helpers.js index 2453fefa81..a7449b7eac 100644 --- a/src/fireedge/src/client/utils/helpers.js +++ b/src/fireedge/src/client/utils/helpers.js @@ -4,6 +4,8 @@ export const fakeDelay = ms => new Promise(resolve => setTimeout(resolve, ms)) export const isExternalURL = url => RegExp(/^(http|https):/g).test(url) +export const generateKey = () => new Date().getTime() + Math.random() + export function sanitize (strings, ...values) { const dirty = strings.reduce((prev, next, i) => `${prev}${next}${values[i] || ''}`, '') diff --git a/src/fireedge/src/server/routes/entrypoints/App.js b/src/fireedge/src/server/routes/entrypoints/App.js index bc2b2e8070..f02e6085b3 100644 --- a/src/fireedge/src/server/routes/entrypoints/App.js +++ b/src/fireedge/src/server/routes/entrypoints/App.js @@ -8,7 +8,7 @@ const { createStore, compose, applyMiddleware } = require('redux') const thunk = require('redux-thunk').default const { ServerStyleSheets } = require('@material-ui/core/styles') const { ChunkExtractor } = require('@loadable/server') -const rootReducer = require('client/reducers') +const rootReducer = require('client/store/reducers') const { getConfig } = require('server/utils/yml') const { availableLanguages, defaultWebpackMode, defaultApps, defaultFileStats @@ -59,7 +59,7 @@ router.get('*', (req, res) => { const extractor = new ChunkExtractor({ statsFile }) // SSR redux store - store = createStore(rootReducer(), composeEnhancer(applyMiddleware(thunk))) + store = createStore(rootReducer, composeEnhancer(applyMiddleware(thunk))) storeRender = `` diff --git a/src/fireedge/src/server/routes/websockets/index.js b/src/fireedge/src/server/routes/websockets/index.js index b33c1830ae..0e5ba5a1bd 100644 --- a/src/fireedge/src/server/routes/websockets/index.js +++ b/src/fireedge/src/server/routes/websockets/index.js @@ -41,7 +41,6 @@ const websockets = (appServer = {}) => { } } ).listen(appServer) - defaultFilesWebsockets.forEach(file => { try { // eslint-disable-next-line global-require @@ -51,7 +50,7 @@ const websockets = (appServer = {}) => { fileInfo.main(io) } } catch (error) { - if (error instanceof Error && error.code === 'MODULE_NOT_FOUND') { + if (error instanceof Error) { const config = defaultConfigErrorMessage config.type = error.message messageTerminal(config)