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
This commit is contained in:
lirazyehezkel 2022-01-06 14:50:50 +02:00 committed by GitHub
parent 2110afc514
commit cb5344090a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 948 additions and 139 deletions

405
ui/package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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

View File

@ -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<MizuContextModel>(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<string>());
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 = <TrafficPage setAnalyzeStatus={setAnalyzeStatus} onTLSDetected={onTLSDetected}/>;
break;
case Page.Setup:
pageComponent = <InstallPage/>;
break;
case Page.Login:
pageComponent = <LoginPage/>;
break;
default:
pageComponent = <div>Unknown Error</div>;
}
if (isLoading) {
return <LoadingOverlay/>;
}
return (
<div className="mizuApp">
<MizuContext.Provider value={{page, setPage}}>
<Header analyzeStatus={analyzeStatus}/>
{pageComponent}
<TLSWarning showTLSWarning={showTLSWarning}
setShowTLSWarning={setShowTLSWarning}
addressesWithTLS={addressesWithTLS}
setAddressesWithTLS={setAddressesWithTLS}
userDismissedTLSWarning={userDismissedTLSWarning}
setUserDismissedTLSWarning={setUserDismissedTLSWarning}/>
</MizuContext.Provider>
<ToastContainer
position="bottom-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
<Header analyzeStatus={analyzeStatus}/>
<TrafficPage setAnalyzeStatus={setAnalyzeStatus} onTLSDetected={onTLSDetected}/>
<TLSWarning showTLSWarning={showTLSWarning}
setShowTLSWarning={setShowTLSWarning}
addressesWithTLS={addressesWithTLS}
setAddressesWithTLS={setAddressesWithTLS}
userDismissedTLSWarning={userDismissedTLSWarning}
setUserDismissedTLSWarning={setUserDismissedTLSWarning}/>
</div>
);
}

107
ui/src/EntApp.tsx Normal file
View File

@ -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<MizuContextModel>(null);
const EntApp = () => {
const [isLoading, setIsLoading] = useState(true);
const [showTLSWarning, setShowTLSWarning] = useState(false);
const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false);
const [addressesWithTLS, setAddressesWithTLS] = useState(new Set<string>());
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 = <TrafficPage onTLSDetected={onTLSDetected}/>;
break;
case Page.Setup:
pageComponent = <InstallPage onFirstLogin={() => setIsFirstLogin(true)}/>;
break;
case Page.Login:
pageComponent = <LoginPage/>;
break;
default:
pageComponent = <div>Unknown Error</div>;
}
if (isLoading) {
return <LoadingOverlay/>;
}
return (
<div className="mizuApp">
<MizuContext.Provider value={{page, setPage}}>
{page === Page.Traffic && <EntHeader isFirstLogin={isFirstLogin} setIsFirstLogin={setIsFirstLogin}/>}
{pageComponent}
{page === Page.Traffic && <TLSWarning showTLSWarning={showTLSWarning}
setShowTLSWarning={setShowTLSWarning}
addressesWithTLS={addressesWithTLS}
setAddressesWithTLS={setAddressesWithTLS}
userDismissedTLSWarning={userDismissedTLSWarning}
setUserDismissedTLSWarning={setUserDismissedTLSWarning}/>}
</MizuContext.Provider>
</div>
);
}
export default EntApp;

View File

@ -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<QueryFormProps> = ({query, setQuery, background
style={{overflow: 'auto'}}
>
<Fade in={openModal}>
<Box sx={style}>
<Box sx={modalStyle}>
<Typography id="modal-modal-title" variant="h5" component="h2" style={{textAlign: 'center'}}>
Filtering Guide (Cheatsheet)
</Typography>
<Typography id="modal-modal-description">
<Typography component={'span'} id="modal-modal-description">
<p>Mizu has a rich filtering syntax that let's you query the results both flexibly and efficiently.</p>
<p>Here are some examples that you can try;</p>
</Typography>

View File

@ -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<EntHeaderProps> = ({isFirstLogin, setIsFirstLogin}) => {
const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false);
useEffect(() => {
if(isFirstLogin) {
setIsSettingsModalOpen(true)
}
}, [isFirstLogin])
const onSettingsModalClose = () => {
setIsSettingsModalOpen(false);
setIsFirstLogin(false);
}
return <div className="header">
<div>
<div className="title">
<img style={{height: 55}} src={logo} alt="logo"/>
</div>
</div>
<div style={{display: "flex", alignItems: "center"}}>
<img className="headerIcon" alt="settings" src={settingImg} style={{marginRight: 25}} onClick={() => setIsSettingsModalOpen(true)}/>
<ProfileButton/>
</div>
<SettingsModal isOpen={isSettingsModalOpen} onClose={onSettingsModalClose} isFirstLogin={isFirstLogin}/>
</div>;
}
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 variant="popover" popupId="demo-popup-menu">
{(popupState) => (
<React.Fragment>
<img className="headerIcon" alt="user" src={userImg} {...bindTrigger(popupState)}/>
<Menu {...bindMenu(popupState)}>
<MenuItem style={{fontSize: 12, fontWeight: 600}} onClick={() => logout(popupState)}>
<img alt="logout" src={logoutIcon} style={{marginRight: 5, height: 16}}/>
Log Out
</MenuItem>
</Menu>
</React.Fragment>
)}
</PopupState>);
}

View File

@ -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

View File

@ -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

View File

@ -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<InstallPageProps> = ({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) {

View File

@ -11,11 +11,17 @@ const LoadingOverlay: React.FC<LoadingOverlayProps> = ({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 <div className="loading-overlay-container" hidden={!isVisible}>
<div className="loading-overlay-spinner"/>

View File

@ -1,7 +1,7 @@
import { Button, TextField } from "@material-ui/core";
import React, { useContext, useState } from "react";
import { toast } from "react-toastify";
import { MizuContext, Page } from "../App";
import { MizuContext, Page } from "../EntApp";
import Api from "../helpers/api";
import LoadingOverlay from "./LoadingOverlay";

View File

@ -0,0 +1,150 @@
import React, {useEffect, useMemo, useState} from "react";
import {Modal, Backdrop, Fade, Box, Button} from "@material-ui/core";
import {modalStyle} from "../Filters";
import Checkbox from "../UI/Checkbox";
import './SettingsModal.sass';
import Api from "../../helpers/api";
import spinner from "../assets/spinner.svg";
import {useCommonStyles} from "../../helpers/commonStyle";
import {toast} from "react-toastify";
interface SettingsModalProps {
isOpen: boolean
onClose: () => void
isFirstLogin: boolean
}
const api = Api.getInstance();
export const SettingsModal: React.FC<SettingsModalProps> = ({isOpen, onClose, isFirstLogin}) => {
const classes = useCommonStyles();
const [namespaces, setNamespaces] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [searchValue, setSearchValue] = useState("");
useEffect(() => {
(async () => {
try {
setIsLoading(true);
const tapConfig = await api.getTapConfig()
if(isFirstLogin) {
const namespacesObj = {...tapConfig?.tappedNamespaces}
Object.keys(tapConfig?.tappedNamespaces ?? {}).forEach(namespace => {
namespacesObj[namespace] = true;
})
setNamespaces(namespacesObj);
} else {
setNamespaces(tapConfig?.tappedNamespaces);
}
} catch (e) {
console.error(e);
} finally {
setIsLoading(false);
}
})()
}, [isFirstLogin])
const setAllNamespacesTappedValue = (isTap: boolean) => {
const newNamespaces = {};
Object.keys(namespaces).forEach(key => {
newNamespaces[key] = isTap;
})
setNamespaces(newNamespaces);
}
const updateTappingSettings = async () => {
try {
await api.setTapConfig(namespaces);
onClose();
toast.success("Saved successfully");
} catch (e) {
console.error(e);
toast.error("Something went wrong, changes may not have been saved.")
}
}
const toggleTapNamespace = (namespace) => {
const newNamespaces = {...namespaces};
newNamespaces[namespace] = !namespaces[namespace]
setNamespaces(newNamespaces);
}
const toggleAll = () => {
const isChecked = Object.values(namespaces).every(tap => tap === true);
setAllNamespacesTappedValue(!isChecked);
}
const filteredNamespaces = useMemo(() => {
return Object.keys(namespaces).filter((namespace) => namespace.includes(searchValue));
},[namespaces, searchValue])
const buildNamespacesTable = () => {
return <table cellPadding={5} style={{borderCollapse: "collapse"}}>
<thead>
<tr style={{borderBottomWidth: "2px"}}>
<th style={{width: 50}}><Checkbox checked={Object.values(namespaces).every(tap => tap === true)}
onToggle={toggleAll}/></th>
<th>Namespace</th>
</tr>
</thead>
<tbody>
{filteredNamespaces?.map(namespace => {
return <tr key={namespace}>
<td style={{width: 50}}>
<Checkbox checked={namespaces[namespace]} onToggle={() => toggleTapNamespace(namespace)}/>
</td>
<td>{namespace}</td>
</tr>
}
)}
</tbody>
</table>
}
const onModalClose = (reason) => {
if(reason === 'backdropClick' && isFirstLogin) return;
onClose();
}
return <Modal
open={isOpen}
onClose={(event, reason) => onModalClose(reason)}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
style={{overflow: 'auto'}}
>
<Fade in={isOpen}>
<Box sx={modalStyle} style={{width: "40vw", maxWidth: 600, height: "70vh", padding: 0, display: "flex", justifyContent: "space-between", flexDirection: "column"}}>
<div style={{padding: 32, paddingBottom: 0}}>
<div className="settingsTitle">Tapping Settings</div>
<div className="settingsSubtitle" style={{marginTop: 20}}>
Please choose from below the namespaces for tapping, traffic for namespaces selected will be displayed
</div>
{isLoading ? <div style={{textAlign: "center", padding: 20}}>
<img alt="spinner" src={spinner} style={{height: 35}}/>
</div> : <>
<div className="namespacesSettingsContainer">
<div style={{margin: "10px 0"}}>
<input className="searchNamespace" placeholder="Search" value={searchValue}
onChange={(event) => setSearchValue(event.target.value)}/></div>
<div className="namespacesTable">
{buildNamespacesTable()}
</div>
</div>
</>}
</div>
<div className="settingsActionsContainer">
{!isFirstLogin &&
<Button style={{width: 100}} className={classes.outlinedButton} size={"small"}
onClick={onClose} variant='outlined'>Cancel</Button>}
<Button style={{width: 100, marginLeft: 20}} className={classes.button} size={"small"}
onClick={updateTappingSettings}>OK</Button>
</div>
</Box>
</Fade>
</Modal>
}

View File

@ -0,0 +1,61 @@
@import "../../variables.module"
.settingsTitle
font-size: 28px
color: $blue-gray
font-weight: 600
.settingsSubtitle
font-size: 14px
color: $light-gray
margin-top: 20px
line-height: 20px
.namespacesSettingsContainer
border-radius: 4px
padding: 20px 0
.searchNamespace
outline: 0
background: white
border-radius: 4px
width: 300px
max-width: calc(40vw - 85px)
padding: 8px 10px
border: 1px #9D9D9D solid
font-size: 14px
color: #494677
.settingsActionsContainer
display: flex
justify-content: flex-end
padding: 20px
border-top: 2px $data-background-color solid
.namespacesTable
table
width: 100%
margin-top: 20px
tbody
max-height: calc(70vh - 355px)
overflow-y: auto
display: block
th
color: $blue-gray
text-align: left
padding: 10px
tr
border-bottom-width: 1px
border-bottom-color: $data-background-color
border-bottom-style: solid
display: table
table-layout: fixed
width: 100%
td
color: $light-gray
padding: 10px
font-size: 16px

View File

@ -29,7 +29,7 @@ export const TLSWarning: React.FC<TLSWarningProps> = ({showTLSWarning, setShowT
console.error(e);
}
})();
}, []);
}, [setShowTLSWarning, setAddressesWithTLS]);
return (<Snackbar open={showTLSWarning && !userDismissedTLSWarning}>
<MuiAlert classes={{filledWarning: 'customWarningStyle'}} elevation={6} variant="filled"

View File

@ -11,7 +11,6 @@ import variables from '../variables.module.scss';
import {StatusBar} from "./UI/StatusBar";
import Api, {MizuWebsocketURL} from "../helpers/api";
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import debounce from 'lodash/debounce';
const useLayoutStyles = makeStyles(() => ({
@ -40,13 +39,13 @@ enum ConnectionStatus {
}
interface TrafficPageProps {
setAnalyzeStatus: (status: any) => void;
onTLSDetected: (destAddress: string) => void;
setAnalyzeStatus?: (status: any) => void;
}
const api = Api.getInstance();
export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLSDetected}) => {
export const TrafficPage: React.FC<TrafficPageProps> = ({onTLSDetected, setAnalyzeStatus}) => {
const classes = useLayoutStyles();
@ -152,7 +151,8 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
setTappingStatus(message.tappingStatus);
break
case "analyzeStatus":
setAnalyzeStatus(message.analyzeStatus);
if(setAnalyzeStatus)
setAnalyzeStatus(message.analyzeStatus);
break
case "outboundLink":
onTLSDetected(message.Data.DstIP);
@ -193,8 +193,10 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
try{
const tapStatusResponse = await api.tapStatus();
setTappingStatus(tapStatusResponse);
const analyzeStatusResponse = await api.analyzeStatus();
setAnalyzeStatus(analyzeStatusResponse);
if(setAnalyzeStatus) {
const analyzeStatusResponse = await api.analyzeStatus();
setAnalyzeStatus(analyzeStatusResponse);
}
} catch (error) {
console.error(error);
}

View File

@ -8,8 +8,8 @@ export interface Props {
const Checkbox: React.FC<Props> = ({checked, onToggle}) => {
return (
<div className="checkboxWrapper">
<input type="checkbox" className="checkbox" checked={checked} onChange={(event) => onToggle(event.target.checked)}/>
<div>
<input style={{cursor: "pointer"}} type="checkbox" checked={checked} onChange={(event) => onToggle(event.target.checked)}/>
</div>
);
};

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.8199 22H10.1799C9.95182 22 9.73059 21.9221 9.55289 21.7792C9.37519 21.6362 9.25169 21.4368 9.20288 21.214L8.79588 19.33C8.25294 19.0921 7.73812 18.7946 7.26088 18.443L5.42388 19.028C5.20645 19.0973 4.97183 19.0902 4.759 19.0078C4.54617 18.9254 4.36794 18.7727 4.25388 18.575L2.42988 15.424C2.31703 15.2261 2.27467 14.9958 2.30973 14.7708C2.34479 14.5457 2.45519 14.3392 2.62288 14.185L4.04788 12.885C3.98308 12.2961 3.98308 11.7019 4.04788 11.113L2.62288 9.816C2.45496 9.66177 2.3444 9.45507 2.30933 9.22978C2.27427 9.00449 2.31677 8.77397 2.42988 8.576L4.24988 5.423C4.36394 5.22532 4.54218 5.07259 4.755 4.99019C4.96783 4.90778 5.20245 4.90066 5.41988 4.97L7.25688 5.555C7.50088 5.375 7.75488 5.207 8.01688 5.055C8.26988 4.913 8.52988 4.784 8.79588 4.669L9.20388 2.787C9.25246 2.5642 9.37572 2.36469 9.55323 2.22155C9.73074 2.07841 9.95185 2.00024 10.1799 2H13.8199C14.0479 2.00024 14.269 2.07841 14.4465 2.22155C14.6241 2.36469 14.7473 2.5642 14.7959 2.787L15.2079 4.67C15.7505 4.9079 16.265 5.20539 16.7419 5.557L18.5799 4.972C18.7972 4.90292 19.0316 4.91017 19.2442 4.99256C19.4568 5.07495 19.6349 5.22753 19.7489 5.425L21.5689 8.578C21.8009 8.985 21.7209 9.5 21.3759 9.817L19.9509 11.117C20.0157 11.7059 20.0157 12.3001 19.9509 12.889L21.3759 14.189C21.7209 14.507 21.8009 15.021 21.5689 15.428L19.7489 18.581C19.6348 18.7787 19.4566 18.9314 19.2438 19.0138C19.0309 19.0962 18.7963 19.1033 18.5789 19.034L16.7419 18.449C16.265 18.8003 15.7505 19.0975 15.2079 19.335L14.7959 21.214C14.7471 21.4366 14.6238 21.6359 14.4463 21.7788C14.2688 21.9218 14.0478 21.9998 13.8199 22ZM7.61988 16.229L8.43988 16.829C8.62488 16.965 8.81688 17.09 9.01688 17.204C9.20488 17.313 9.39688 17.411 9.59588 17.5L10.5289 17.909L10.9859 20H13.0159L13.4729 17.908L14.4059 17.499C14.8129 17.319 15.1999 17.096 15.5589 16.833L16.3789 16.233L18.4209 16.883L19.4359 15.125L17.8529 13.682L17.9649 12.67C18.0149 12.227 18.0149 11.78 17.9649 11.338L17.8529 10.326L19.4369 8.88L18.4209 7.121L16.3799 7.771L15.5589 7.171C15.1997 6.90669 14.8131 6.68173 14.4059 6.5L13.4729 6.091L13.0159 4H10.9859L10.5259 6.092L9.59588 6.5C9.18807 6.67861 8.80136 6.90198 8.44288 7.166L7.62188 7.766L5.58188 7.116L4.56488 8.88L6.14788 10.321L6.03588 11.334C5.98588 11.777 5.98588 12.224 6.03588 12.666L6.14788 13.678L4.56488 15.121L5.57988 16.879L7.61988 16.229ZM11.9959 16C10.935 16 9.9176 15.5786 9.16746 14.8284C8.41731 14.0783 7.99588 13.0609 7.99588 12C7.99588 10.9391 8.41731 9.92172 9.16746 9.17157C9.9176 8.42143 10.935 8 11.9959 8C13.0568 8 14.0742 8.42143 14.8243 9.17157C15.5745 9.92172 15.9959 10.9391 15.9959 12C15.9959 13.0609 15.5745 14.0783 14.8243 14.8284C14.0742 15.5786 13.0568 16 11.9959 16ZM11.9959 10C11.6042 10.0004 11.2213 10.1158 10.8947 10.3318C10.568 10.5479 10.3119 10.855 10.1583 11.2153C10.0046 11.5755 9.9601 11.9729 10.0303 12.3583C10.1004 12.7436 10.2822 13.0998 10.5529 13.3828C10.8237 13.6657 11.1716 13.863 11.5534 13.95C11.9353 14.037 12.3343 14.01 12.7009 13.8724C13.0676 13.7347 13.3858 13.4924 13.616 13.1756C13.8462 12.8587 13.9783 12.4812 13.9959 12.09V12.49V12C13.9959 11.4696 13.7852 10.9609 13.4101 10.5858C13.035 10.2107 12.5263 10 11.9959 10Z" fill="#627EF7"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C9.35831 2.03369 6.8343 3.09807 4.96618 4.96618C3.09807 6.8343 2.03369 9.35831 2 12C2.01235 13.5389 2.37972 15.0542 3.07351 16.4279C3.7673 17.8016 4.76879 18.9967 6 19.92V20H6.1C7.79318 21.2975 9.86685 22.0006 12 22.0006C14.1332 22.0006 16.2068 21.2975 17.9 20H18V19.92C19.2312 18.9967 20.2327 17.8016 20.9265 16.4279C21.6203 15.0542 21.9877 13.5389 22 12C21.9663 9.35831 20.9019 6.8343 19.0338 4.96618C17.1657 3.09807 14.6417 2.03369 12 2ZM8.07 18.93C8.21599 18.2614 8.58615 17.6629 9.11908 17.2336C9.65202 16.8044 10.3157 16.5702 11 16.57H13C13.6843 16.5702 14.348 16.8044 14.8809 17.2336C15.4138 17.6629 15.784 18.2614 15.93 18.93C14.7389 19.6308 13.382 20.0004 12 20.0004C10.618 20.0004 9.26113 19.6308 8.07 18.93ZM17.61 17.64C17.2296 16.7309 16.5891 15.9546 15.7689 15.4084C14.9487 14.8622 13.9854 14.5705 13 14.57H11C10.0146 14.5705 9.05127 14.8622 8.23108 15.4084C7.41088 15.9546 6.77037 16.7309 6.39 17.64C5.64066 16.903 5.0439 16.0255 4.63381 15.0578C4.22373 14.0901 4.00835 13.051 4 12C4.02594 9.88633 4.87712 7.86653 6.37183 6.37183C7.86653 4.87712 9.88633 4.02594 12 4C14.1137 4.02594 16.1335 4.87712 17.6282 6.37183C19.1229 7.86653 19.9741 9.88633 20 12C19.9916 13.051 19.7763 14.0901 19.3662 15.0578C18.9561 16.0255 18.3593 16.903 17.61 17.64Z" fill="#627EF7"/>
<path d="M12 6.00002C11.4714 5.98771 10.9457 6.08275 10.4548 6.27941C9.96397 6.47607 9.51809 6.77026 9.14417 7.14418C8.77026 7.51809 8.47607 7.96397 8.27941 8.45484C8.08275 8.94571 7.98771 9.47137 8.00002 10C7.98771 10.5287 8.08275 11.0543 8.27941 11.5452C8.47607 12.0361 8.77026 12.482 9.14417 12.8559C9.51809 13.2298 9.96397 13.524 10.4548 13.7206C10.9457 13.9173 11.4714 14.0123 12 14C12.5287 14.0123 13.0543 13.9173 13.5452 13.7206C14.0361 13.524 14.482 13.2298 14.8559 12.8559C15.2298 12.482 15.524 12.0361 15.7206 11.5452C15.9173 11.0543 16.0123 10.5287 16 10C16.0123 9.47137 15.9173 8.94571 15.7206 8.45484C15.524 7.96397 15.2298 7.51809 14.8559 7.14418C14.482 6.77026 14.0361 6.47607 13.5452 6.27941C13.0543 6.08275 12.5287 5.98771 12 6.00002ZM12 12C11.734 12.0129 11.4682 11.97 11.2197 11.874C10.9712 11.778 10.7456 11.6312 10.5572 11.4428C10.3689 11.2545 10.222 11.0288 10.126 10.7803C10.0301 10.5319 9.98716 10.2661 10 10C9.98716 9.73397 10.0301 9.46817 10.126 9.2197C10.222 8.97122 10.3689 8.74557 10.5572 8.55722C10.7456 8.36888 10.9712 8.22201 11.2197 8.12605C11.4682 8.03009 11.734 7.98716 12 8.00002C12.2661 7.98716 12.5319 8.03009 12.7803 8.12605C13.0288 8.22201 13.2545 8.36888 13.4428 8.55722C13.6312 8.74557 13.778 8.97122 13.874 9.2197C13.97 9.46817 14.0129 9.73397 14 10C14.0129 10.2661 13.97 10.5319 13.874 10.7803C13.778 11.0288 13.6312 11.2545 13.4428 11.4428C13.2545 11.6312 13.0288 11.778 12.7803 11.874C12.5319 11.97 12.2661 12.0129 12 12Z" fill="#627EF7"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -84,6 +84,16 @@ export default class Api {
return response.data;
}
getTapConfig = async () => {
const response = await this.client.get("/config/tapConfig");
return response.data;
}
setTapConfig = async (config) => {
const response = await this.client.post("/config/tapConfig", {tappedNamespaces: config});
return response.data;
}
isInstallNeeded = async () => {
const response = await this.client.get("/install/isNeeded");
return response.data;
@ -94,7 +104,7 @@ export default class Api {
await this.client.get("/status/tap");
return false;
} catch (e) {
if (e.response.status == 401) {
if (e.response.status === 401) {
return true;
}
throw e;
@ -112,10 +122,11 @@ export default class Api {
return response;
} catch (e) {
if (e.response.status === 400) {
throw {
const error = {
'type': FormValidationErrorType,
'messages': e.response.data
};
throw error;
} else {
throw e;
}

View File

@ -0,0 +1,30 @@
import {makeStyles} from "@material-ui/core";
// @ts-ignore
export const useCommonStyles = makeStyles(() => ({
button: {
backgroundColor: "#205cf5",
color: "white",
fontWeight: "600 !important",
fontSize: 12,
padding: "8px 12px",
borderRadius: "6px ! important",
"&:hover": {
backgroundColor: "#205cf5",
},
},
outlinedButton: {
backgroundColor: "transparent",
color: "#205cf5",
fontWeight: "600 !important",
fontSize: 12,
padding: "8px 12px",
border: "1px #205cf5 solid",
borderRadius: "6px ! important",
"&:hover": {
backgroundColor: "transparent",
},
}
}));

View File

@ -146,4 +146,3 @@ button
::-webkit-scrollbar-corner
display: none

View File

@ -2,10 +2,26 @@ import React from 'react';
import ReactDOM from 'react-dom';
import './index.sass';
import App from './App';
import EntApp from "./EntApp";
import {ToastContainer} from "react-toastify";
import 'react-toastify/dist/ReactToastify.css';
ReactDOM.render(
<React.StrictMode>
<App />
<>
{window["isEnt"] ? <EntApp/> : <App/>}
<ToastContainer
position="bottom-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</>
</React.StrictMode>,
document.getElementById('root')
);

View File

@ -8,6 +8,7 @@ $light-blue-color: #BCCEFD;
$success-color: #27AE60;
$failure-color: #EB5757;
$blue-gray: #494677;
$light-gray: #8F9BB2;
:export {
mainBackgroundColor: $main-background-color;
@ -19,4 +20,5 @@ $blue-gray: #494677;
successColor: $success-color;
failureColor: $failure-color;
blueGray: $blue-gray;
lightGray: $light-gray;
}