From cb5344090a99a19684c743246583e294d9729976 Mon Sep 17 00:00:00 2001 From: lirazyehezkel <61656597+lirazyehezkel@users.noreply.github.com> Date: Thu, 6 Jan 2022 14:50:50 +0200 Subject: [PATCH] TRA-4089 Mizu enterprise frame (#594) * ent app * mizu ent frame * apis * design settings modal by Javier * fix warnings * fix warnings * text change * redirect after logout * cr fixes --- ui/package-lock.json | 405 ++++++++++++++++++ ui/package.json | 1 + ui/src/App.sass | 19 - ui/src/App.tsx | 110 +---- ui/src/EntApp.tsx | 107 +++++ ui/src/components/Filters.tsx | 7 +- ui/src/components/Header/EntHeader.tsx | 78 ++++ ui/src/components/Header/Header.sass | 23 + ui/src/components/Header/Header.tsx | 1 + ui/src/components/InstallPage.tsx | 9 +- ui/src/components/LoadingOverlay.tsx | 10 +- ui/src/components/LoginPage.tsx | 2 +- .../components/SettingsModal/SettingModal.tsx | 150 +++++++ .../SettingsModal/SettingsModal.sass | 61 +++ ui/src/components/TLSWarning/TLSWarning.tsx | 2 +- ui/src/components/TrafficPage.tsx | 14 +- ui/src/components/UI/Checkbox.tsx | 4 +- ui/src/components/assets/MizuEntLogo.svg | 11 + ui/src/components/assets/logout.png | Bin 0 -> 7623 bytes ui/src/components/assets/settings.svg | 3 + ui/src/components/assets/user-circle.svg | 4 + ui/src/helpers/api.js | 15 +- ui/src/helpers/commonStyle.ts | 30 ++ ui/src/index.sass | 1 - ui/src/index.tsx | 18 +- ui/src/variables.module.scss | 2 + 26 files changed, 948 insertions(+), 139 deletions(-) create mode 100644 ui/src/EntApp.tsx create mode 100644 ui/src/components/Header/EntHeader.tsx create mode 100644 ui/src/components/Header/Header.sass create mode 100644 ui/src/components/SettingsModal/SettingModal.tsx create mode 100644 ui/src/components/SettingsModal/SettingsModal.sass create mode 100644 ui/src/components/assets/MizuEntLogo.svg create mode 100644 ui/src/components/assets/logout.png create mode 100644 ui/src/components/assets/settings.svg create mode 100644 ui/src/components/assets/user-circle.svg create mode 100644 ui/src/helpers/commonStyle.ts diff --git a/ui/package-lock.json b/ui/package-lock.json index 085ebaf6a..08d70cc0d 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1161,11 +1161,51 @@ "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" }, + "@emotion/cache": { + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz", + "integrity": "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==", + "requires": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.1.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "4.0.13" + } + }, "@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, + "@emotion/is-prop-valid": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.1.tgz", + "integrity": "sha512-bW1Tos67CZkOURLc0OalnfxtSXQJMrAMV0jZTVGJUPSOd4qgjF3+tTD5CwJM13PHA8cltGW1WGbbvV9NpvUZPw==", + "requires": { + "@emotion/memoize": "^0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", + "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + }, + "@emotion/sheet": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", + "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" + }, + "@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + }, + "@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, "@eslint/eslintrc": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", @@ -1898,6 +1938,335 @@ "react-is": "^16.8.0 || ^17.0.0" } }, + "@mui/base": { + "version": "5.0.0-alpha.62", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.62.tgz", + "integrity": "sha512-ItmdSZwHKQbLbAsS3sWguR7OHqYqh2cYWahoVmHb13Kc6bMdmVUTY4x57IlDSU712B0yuA0Q/gPTq7xADKnFow==", + "requires": { + "@babel/runtime": "^7.16.3", + "@emotion/is-prop-valid": "^1.1.1", + "@mui/utils": "^5.2.3", + "@popperjs/core": "^2.4.4", + "clsx": "^1.1.1", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } + } + }, + "@mui/icons-material": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.2.5.tgz", + "integrity": "sha512-uQiUz+l0xy+2jExyKyU19MkMAR2F7bQFcsQ5hdqAtsB14Jw2zlmIAD55mV6f0NxKCut7Rx6cA3ZpfzlzAfoK8Q==", + "requires": { + "@babel/runtime": "^7.16.3" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + } + } + }, + "@mui/material": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.2.6.tgz", + "integrity": "sha512-yF2bRqyJMo6bYXT7TPA9IU/XLaXHi47Xvmj8duQa5ha3bCpFMXLfGoZcAUl6ZDjjGEz1nCFS+c1qx219xD/aeQ==", + "requires": { + "@babel/runtime": "^7.16.3", + "@mui/base": "5.0.0-alpha.62", + "@mui/system": "^5.2.6", + "@mui/types": "^7.1.0", + "@mui/utils": "^5.2.3", + "@types/react-transition-group": "^4.4.4", + "clsx": "^1.1.1", + "csstype": "^3.0.10", + "hoist-non-react-statics": "^3.3.2", + "prop-types": "^15.7.2", + "react-is": "^17.0.2", + "react-transition-group": "^4.4.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@types/react-transition-group": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", + "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", + "requires": { + "@types/react": "*" + } + }, + "csstype": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz", + "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + } + } + }, + "@mui/private-theming": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.2.3.tgz", + "integrity": "sha512-Lc1Cmu8lSsYZiXADi9PBb17Ho82ZbseHQujUFAcp6bCJ5x/d+87JYCIpCBMagPu/isRlFCwbziuXPmz7WOzJPQ==", + "requires": { + "@babel/runtime": "^7.16.3", + "@mui/utils": "^5.2.3", + "prop-types": "^15.7.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + } + } + }, + "@mui/styled-engine": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.2.6.tgz", + "integrity": "sha512-bqAhli8eGS6v2qxivy2/4K0Ag8o//jsu1G2G6QcieFiT6y7oIF/nd/6Tvw6OSm3roOTifVQWNKwkt1yFWhGS+w==", + "requires": { + "@babel/runtime": "^7.16.3", + "@emotion/cache": "^11.7.1", + "prop-types": "^15.7.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + } + } + }, + "@mui/styles": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@mui/styles/-/styles-5.2.3.tgz", + "integrity": "sha512-Art4qjlEI9H2h34mLL8s+CE9nWZWZbuJLbNpievaIM6DGuayz3DYkJHcH5mXJYFPhTNoe9IQYbpyKofjE0YVag==", + "requires": { + "@babel/runtime": "^7.16.3", + "@emotion/hash": "^0.8.0", + "@mui/private-theming": "^5.2.3", + "@mui/types": "^7.1.0", + "@mui/utils": "^5.2.3", + "clsx": "^1.1.1", + "csstype": "^3.0.10", + "hoist-non-react-statics": "^3.3.2", + "jss": "^10.8.2", + "jss-plugin-camel-case": "^10.8.2", + "jss-plugin-default-unit": "^10.8.2", + "jss-plugin-global": "^10.8.2", + "jss-plugin-nested": "^10.8.2", + "jss-plugin-props-sort": "^10.8.2", + "jss-plugin-rule-value-function": "^10.8.2", + "jss-plugin-vendor-prefixer": "^10.8.2", + "prop-types": "^15.7.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "csstype": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz", + "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" + }, + "jss": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.9.0.tgz", + "integrity": "sha512-YpzpreB6kUunQBbrlArlsMpXYyndt9JATbt95tajx0t4MTJJcCJdd4hdNpHmOIDiUJrF/oX5wtVFrS3uofWfGw==", + "requires": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-camel-case": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.9.0.tgz", + "integrity": "sha512-UH6uPpnDk413/r/2Olmw4+y54yEF2lRIV8XIZyuYpgPYTITLlPOsq6XB9qeqv+75SQSg3KLocq5jUBXW8qWWww==", + "requires": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.9.0" + } + }, + "jss-plugin-default-unit": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.9.0.tgz", + "integrity": "sha512-7Ju4Q9wJ/MZPsxfu4T84mzdn7pLHWeqoGd/D8O3eDNNJ93Xc8PxnLmV8s8ZPNRYkLdxZqKtm1nPQ0BM4JRlq2w==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "jss-plugin-global": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.9.0.tgz", + "integrity": "sha512-4G8PHNJ0x6nwAFsEzcuVDiBlyMsj2y3VjmFAx/uHk/R/gzJV+yRHICjT4MKGGu1cJq2hfowFWCyrr/Gg37FbgQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "jss-plugin-nested": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.9.0.tgz", + "integrity": "sha512-2UJnDrfCZpMYcpPYR16oZB7VAC6b/1QLsRiAutOt7wJaaqwCBvNsosLEu/fUyKNQNGdvg2PPJFDO5AX7dwxtoA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-props-sort": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.9.0.tgz", + "integrity": "sha512-7A76HI8bzwqrsMOJTWKx/uD5v+U8piLnp5bvru7g/3ZEQOu1+PjHvv7bFdNO3DwNPC9oM0a//KwIJsIcDCjDzw==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "jss-plugin-rule-value-function": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.9.0.tgz", + "integrity": "sha512-IHJv6YrEf8pRzkY207cPmdbBstBaE+z8pazhPShfz0tZSDtRdQua5jjg6NMz3IbTasVx9FdnmptxPqSWL5tyJg==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-vendor-prefixer": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.9.0.tgz", + "integrity": "sha512-MbvsaXP7iiVdYVSEoi+blrW+AYnTDvHTW6I6zqi7JcwXdc6I9Kbm234nEblayhF38EftoenbM+5218pidmC5gA==", + "requires": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.9.0" + } + } + } + }, + "@mui/system": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.2.6.tgz", + "integrity": "sha512-PZ7bmpWOLikWgqn2zWv9/Xa7lxnRBOmfjoMH7c/IVYJs78W3971brXJ3xV9MEWWQcoqiYQeXzUJaNf4rFbKCBA==", + "requires": { + "@babel/runtime": "^7.16.3", + "@mui/private-theming": "^5.2.3", + "@mui/styled-engine": "^5.2.6", + "@mui/types": "^7.1.0", + "@mui/utils": "^5.2.3", + "clsx": "^1.1.1", + "csstype": "^3.0.10", + "prop-types": "^15.7.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "csstype": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz", + "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" + } + } + }, + "@mui/types": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.0.tgz", + "integrity": "sha512-Hh7ALdq/GjfIwLvqH3XftuY3bcKhupktTm+S6qRIDGOtPtRuq2L21VWzOK4p7kblirK0XgGVH5BLwa6u8z/6QQ==" + }, + "@mui/utils": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.2.3.tgz", + "integrity": "sha512-sQujlajIS0zQKcGIS6tZR0L1R+ib26B6UtuEn+cZqwKHsPo3feuS+SkdscYBdcCdMbrZs4gj8WIJHl2z6tbSzQ==", + "requires": { + "@babel/runtime": "^7.16.3", + "@types/prop-types": "^15.7.4", + "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", @@ -1957,6 +2326,11 @@ } } }, + "@popperjs/core": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz", + "integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==" + }, "@rollup/plugin-node-resolve": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", @@ -2479,6 +2853,14 @@ "@types/react": "*" } }, + "@types/react-is": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", + "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "requires": { + "@types/react": "*" + } + }, "@types/react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -4355,6 +4737,11 @@ } } }, + "classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, "clean-css": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", @@ -10689,6 +11076,19 @@ "object-visit": "^1.0.0" } }, + "material-ui-popup-state": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/material-ui-popup-state/-/material-ui-popup-state-2.0.0.tgz", + "integrity": "sha512-1sbb9xpMs7OxG0SOGfGO0ZnwiLtqZSoXda0/AqqJkpouT4e0nADXutQtDJFMa9GUMNAODVDlYnNmfqM+MhFjsg==", + "requires": { + "@babel/runtime": "^7.12.5", + "@mui/icons-material": "^5.0.0", + "@mui/material": "^5.0.0", + "@mui/styles": "^5.0.0", + "classnames": "^2.2.6", + "prop-types": "^15.7.2" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -15733,6 +16133,11 @@ } } }, + "stylis": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/ui/package.json b/ui/package.json index 71b1ed470..64763c557 100644 --- a/ui/package.json +++ b/ui/package.json @@ -18,6 +18,7 @@ "highlight.js": "^11.3.1", "json-beautify": "^1.1.1", "jsonpath": "^1.1.1", + "material-ui-popup-state": "^2.0.0", "moment": "^2.29.1", "node-sass": "^5.0.0", "numeral": "^2.0.6", diff --git a/ui/src/App.sass b/ui/src/App.sass index 47ecb56ef..44fe3e268 100644 --- a/ui/src/App.sass +++ b/ui/src/App.sass @@ -7,25 +7,6 @@ body color: $font-color width: 100% - .header - height: 60px - display: flex - align-items: center - padding: 5px 24px - justify-content: space-between - - .title - letter-spacing: 2px - - img - height: 45px - - .description - margin-left: 10px - font-size: 11px - font-weight: bold - color: $light-blue-color - .centeredForm max-width: 500px text-align: center diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 7371e18b9..65b8a7aff 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -1,71 +1,16 @@ -import React, {useEffect, useState} from 'react'; +import React, {useState} from 'react'; import './App.sass'; -import {TrafficPage} from "./components/TrafficPage"; import {TLSWarning} from "./components/TLSWarning/TLSWarning"; import {Header} from "./components/Header/Header"; -import { ToastContainer, toast } from 'react-toastify'; -import 'react-toastify/dist/ReactToastify.css'; -import Api from "./helpers/api"; -import LoadingOverlay from './components/LoadingOverlay'; -import LoginPage from './components/LoginPage'; -import InstallPage from './components/InstallPage'; - -const api = Api.getInstance(); - - // TODO: move to state management -export enum Page { - Traffic, - Setup, - Login -} - -// TODO: move to state management -export interface MizuContextModel { - page: Page; - setPage: (page: Page) => void; -} - -// TODO: move to state management -export const MizuContext = React.createContext(null); +import {TrafficPage} from "./components/TrafficPage"; const App = () => { - const [isLoading, setIsLoading] = useState(true); + const [analyzeStatus, setAnalyzeStatus] = useState(null); const [showTLSWarning, setShowTLSWarning] = useState(false); const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false); const [addressesWithTLS, setAddressesWithTLS] = useState(new Set()); - const [page, setPage] = useState(Page.Traffic); // TODO: move to state management - - const determinePage = async () => { // TODO: move to state management - if (window['isEnt'] !== true) { - setPage(Page.Traffic); - setIsLoading(false); - return; - } - - try { - const isInstallNeeded = await api.isInstallNeeded(); - if (isInstallNeeded) { - setPage(Page.Setup); - } else { - const isAuthNeeded = await api.isAuthenticationNeeded(); - if(isAuthNeeded) { - setPage(Page.Login); - } - } - } catch (e) { - toast.error("Error occured while checking Mizu API status, see console for mode details"); - console.error(e); - } finally { - setIsLoading(false); - } - } - - useEffect(() => { - determinePage(); - }, []); - const onTLSDetected = (destAddress: string) => { addressesWithTLS.add(destAddress); setAddressesWithTLS(new Set(addressesWithTLS)); @@ -75,49 +20,16 @@ const App = () => { } }; - let pageComponent: any; - - switch (page) { // TODO: move to state management / proper routing - case Page.Traffic: - pageComponent = ; - break; - case Page.Setup: - pageComponent = ; - break; - case Page.Login: - pageComponent = ; - break; - default: - pageComponent =
Unknown Error
; - } - - if (isLoading) { - return ; - } - return (
- -
- {pageComponent} - - - +
+ +
); } diff --git a/ui/src/EntApp.tsx b/ui/src/EntApp.tsx new file mode 100644 index 000000000..1103367cb --- /dev/null +++ b/ui/src/EntApp.tsx @@ -0,0 +1,107 @@ +import React, {useEffect, useState} from 'react'; +import './App.sass'; +import {TrafficPage} from "./components/TrafficPage"; +import {TLSWarning} from "./components/TLSWarning/TLSWarning"; +import {EntHeader} from "./components/Header/EntHeader"; +import Api from "./helpers/api"; +import {toast} from "react-toastify"; +import InstallPage from "./components/InstallPage"; +import LoginPage from "./components/LoginPage"; +import LoadingOverlay from "./components/LoadingOverlay"; + +const api = Api.getInstance(); + +// TODO: move to state management +export enum Page { + Traffic, + Setup, + Login +} + +// TODO: move to state management +export interface MizuContextModel { + page: Page; + setPage: (page: Page) => void; +} + +// TODO: move to state management +export const MizuContext = React.createContext(null); + +const EntApp = () => { + + const [isLoading, setIsLoading] = useState(true); + const [showTLSWarning, setShowTLSWarning] = useState(false); + const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false); + const [addressesWithTLS, setAddressesWithTLS] = useState(new Set()); + const [page, setPage] = useState(Page.Traffic); // TODO: move to state management + const [isFirstLogin, setIsFirstLogin] = useState(false); + + const determinePage = async () => { // TODO: move to state management + try { + const isInstallNeeded = await api.isInstallNeeded(); + if (isInstallNeeded) { + setPage(Page.Setup); + } else { + const isAuthNeeded = await api.isAuthenticationNeeded(); + if(isAuthNeeded) { + setPage(Page.Login); + } + } + } catch (e) { + toast.error("Error occured while checking Mizu API status, see console for mode details"); + console.error(e); + } finally { + setIsLoading(false); + } + } + + useEffect(() => { + determinePage(); + }, []); + + const onTLSDetected = (destAddress: string) => { + addressesWithTLS.add(destAddress); + setAddressesWithTLS(new Set(addressesWithTLS)); + + if (!userDismissedTLSWarning) { + setShowTLSWarning(true); + } + }; + + let pageComponent: any; + + switch (page) { // TODO: move to state management / proper routing + case Page.Traffic: + pageComponent = ; + break; + case Page.Setup: + pageComponent = setIsFirstLogin(true)}/>; + break; + case Page.Login: + pageComponent = ; + break; + default: + pageComponent =
Unknown Error
; + } + + if (isLoading) { + return ; + } + + return ( +
+ + {page === Page.Traffic && } + {pageComponent} + {page === Page.Traffic && } + +
+ ); +} + +export default EntApp; diff --git a/ui/src/components/Filters.tsx b/ui/src/components/Filters.tsx index 9e281c9b6..94ff6cb96 100644 --- a/ui/src/components/Filters.tsx +++ b/ui/src/components/Filters.tsx @@ -36,7 +36,7 @@ interface QueryFormProps { openWebSocket: (query: string, resetEntries: boolean) => void; } -const style = { +export const modalStyle = { position: 'absolute', top: '10%', left: '50%', @@ -45,6 +45,7 @@ const style = { bgcolor: 'background.paper', borderRadius: '5px', boxShadow: 24, + outline: "none", p: 4, color: '#000', }; @@ -153,11 +154,11 @@ export const QueryForm: React.FC = ({query, setQuery, background style={{overflow: 'auto'}} > - + Filtering Guide (Cheatsheet) - +

Mizu has a rich filtering syntax that let's you query the results both flexibly and efficiently.

Here are some examples that you can try;

diff --git a/ui/src/components/Header/EntHeader.tsx b/ui/src/components/Header/EntHeader.tsx new file mode 100644 index 000000000..d331ef144 --- /dev/null +++ b/ui/src/components/Header/EntHeader.tsx @@ -0,0 +1,78 @@ +import React, {useContext, useEffect, useState} from "react"; +import logo from '../assets/MizuEntLogo.svg'; +import './Header.sass'; +import userImg from '../assets/user-circle.svg'; +import settingImg from '../assets/settings.svg'; +import {Menu, MenuItem} from "@material-ui/core"; +import PopupState, {bindMenu, bindTrigger} from "material-ui-popup-state"; +import logoutIcon from '../assets/logout.png'; +import {SettingsModal} from "../SettingsModal/SettingModal"; +import Api from "../../helpers/api"; +import {toast} from "react-toastify"; +import {MizuContext, Page} from "../../EntApp"; + +const api = Api.getInstance(); + +interface EntHeaderProps { + isFirstLogin: boolean; + setIsFirstLogin: (flag: boolean) => void +} + +export const EntHeader: React.FC = ({isFirstLogin, setIsFirstLogin}) => { + + const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); + + useEffect(() => { + if(isFirstLogin) { + setIsSettingsModalOpen(true) + } + }, [isFirstLogin]) + + const onSettingsModalClose = () => { + setIsSettingsModalOpen(false); + setIsFirstLogin(false); + } + + return
+
+
+ logo +
+
+
+ settings setIsSettingsModalOpen(true)}/> + +
+ +
; +} + +const ProfileButton = () => { + + const {setPage} = useContext(MizuContext); + + const logout = async (popupState) => { + try { + await api.logout(); + setPage(Page.Login); + } catch (e) { + toast.error("Something went wrong, please check the console"); + console.error(e); + } + popupState.close(); + } + + return ( + {(popupState) => ( + + user + + logout(popupState)}> + logout + Log Out + + + + )} + ); +} diff --git a/ui/src/components/Header/Header.sass b/ui/src/components/Header/Header.sass new file mode 100644 index 000000000..dfc2c4cad --- /dev/null +++ b/ui/src/components/Header/Header.sass @@ -0,0 +1,23 @@ +@import '../../variables.module' + +.header + height: 60px + display: flex + align-items: center + padding: 5px 24px + justify-content: space-between + + .title + letter-spacing: 2px + + img + height: 45px + + .description + margin-left: 10px + font-size: 11px + font-weight: bold + color: $light-blue-color + + .headerIcon + cursor: pointer diff --git a/ui/src/components/Header/Header.tsx b/ui/src/components/Header/Header.tsx index 84a119d28..84f0ccd3c 100644 --- a/ui/src/components/Header/Header.tsx +++ b/ui/src/components/Header/Header.tsx @@ -2,6 +2,7 @@ import React from "react"; import {AuthPresentation} from "../AuthPresentation/AuthPresentation"; import {AnalyzeButton} from "../AnalyzeButton/AnalyzeButton"; import logo from '../assets/Mizu-logo.svg'; +import './Header.sass'; interface HeaderProps { analyzeStatus: any diff --git a/ui/src/components/InstallPage.tsx b/ui/src/components/InstallPage.tsx index 1606d319f..65840b96e 100644 --- a/ui/src/components/InstallPage.tsx +++ b/ui/src/components/InstallPage.tsx @@ -1,6 +1,6 @@ import { Button, TextField } from "@material-ui/core"; import React, { useContext, useState } from "react"; -import { MizuContext, Page } from "../App"; +import { MizuContext, Page } from "../EntApp"; import { adminUsername } from "../consts"; import Api, { FormValidationErrorType } from "../helpers/api"; import { toast } from 'react-toastify'; @@ -8,7 +8,11 @@ import LoadingOverlay from "./LoadingOverlay"; const api = Api.getInstance(); -export const InstallPage: React.FC = () => { +interface InstallPageProps { + onFirstLogin: () => void; +} + +export const InstallPage: React.FC = ({onFirstLogin}) => { const [isLoading, setIsLoading] = useState(false); const [password, setPassword] = useState(""); @@ -31,6 +35,7 @@ export const InstallPage: React.FC = () => { if (!await api.isAuthenticationNeeded()) { toast.success("admin user created successfully"); setPage(Page.Traffic); + onFirstLogin(); } } catch (e) { if (e.type === FormValidationErrorType) { diff --git a/ui/src/components/LoadingOverlay.tsx b/ui/src/components/LoadingOverlay.tsx index b0802ebaf..27dcc2a02 100644 --- a/ui/src/components/LoadingOverlay.tsx +++ b/ui/src/components/LoadingOverlay.tsx @@ -11,11 +11,17 @@ const LoadingOverlay: React.FC = ({delay}) => { const [isVisible, setIsVisible] = useState(false); + // @ts-ignore useEffect(() => { + let isRelevant = true; + setTimeout(() => { - setIsVisible(true); + if(isRelevant) + setIsVisible(true); }, delay ?? SpinnerShowDelayMs); - }, []); + + return () => isRelevant = false; + }, [delay]); return