diff --git a/shell-ui/package-lock.json b/shell-ui/package-lock.json index 7c7a717d7d..a1821d87ef 100644 --- a/shell-ui/package-lock.json +++ b/shell-ui/package-lock.json @@ -8,20 +8,20 @@ "name": "shell-ui", "version": "1.0.0", "dependencies": { - "@scality/core-ui": "0.151.0", - "@scality/module-federation": "^1.3.4", + "@scality/core-ui": "git+https://github.com/scality/core-ui#bf0c36da657737f47dabe310bb1a20c136877970", + "@scality/module-federation": "git+https://github.com/scality/module-federation#c571388783a2a51ae3bf5d36ae66753c8b014bb5", "downshift": "^8.0.0", "jest-environment-jsdom": "^29.7.0", "oidc-client-ts": "^3.0.1", "oidc-react": "^3.2.2", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-error-boundary": "^4.0.2", "react-intl": "^5.15.3", "react-query": "^3.34.0", "react-router": "5.2.0", "react-router-dom": "5.2.0", - "styled-components": "^5.2.1", + "styled-components": "^5.3.11", "typescript": "^5.6.3" }, "devDependencies": { @@ -35,14 +35,15 @@ "@rspack/core": "^0.7.5", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^5.11.9", - "@testing-library/react": "^11.2.5", - "@testing-library/react-hooks": "^5.1.1", + "@testing-library/react": "^15.0.7", + "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "^13.0.10", - "@types/react": "^17.0.39", - "@types/react-dom": "^17.0.13", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", "@types/react-router": "^5.1.20", - "@types/react-router-dom": "^5.2.0", - "@types/styled-components": "^5.1.26", + "@types/react-router-dom": "^5.3.3", + "@types/react-test-renderer": "^18.3.0", + "@types/styled-components": "^5.1.34", "babel-jest": "^26.6.3", "babel-loader": "^8.2.2", "fs-extra": "^10.0.0", @@ -52,7 +53,7 @@ "jest-preview": "^0.3.1", "msw": "0.36.8", "node-fetch": "^2.6.1", - "react-test-renderer": "^17.0.2", + "react-test-renderer": "^18.3.1", "ts-node": "^10.9.2" } }, @@ -1864,19 +1865,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", - "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", - "dev": true, - "dependencies": { - "core-js-pure": "^3.30.2", - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", @@ -2043,8 +2031,7 @@ }, "node_modules/@emotion/is-prop-valid": { "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "license": "MIT", "optional": true, "dependencies": { "@emotion/memoize": "0.7.4" @@ -2052,8 +2039,7 @@ }, "node_modules/@emotion/memoize": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "license": "MIT", "optional": true }, "node_modules/@emotion/react": { @@ -4175,8 +4161,9 @@ }, "node_modules/@scality/core-ui": { "version": "0.151.0", - "resolved": "https://registry.npmjs.org/@scality/core-ui/-/core-ui-0.151.0.tgz", - "integrity": "sha512-OeAhs+uiOOBDSGqzZGpIka1iCtRrGJkjNhzdRJhJtLwxKDFU7iyPUPA3MbJ8DoGJQN0do8k3PTyei1fZEiMXJA==", + "resolved": "git+ssh://git@github.com/scality/core-ui.git#bf0c36da657737f47dabe310bb1a20c136877970", + "integrity": "sha512-dC/zNxvxU7DVgxhbyKHgwwVyM2CwWACrwyVbh1VP0/7KTcgTmoYR2hO9qAMi9t8yyNWidOi9AVVzKupes13wRw==", + "license": "SEE LICENSE IN LICENSE", "dependencies": { "@floating-ui/dom": "^1.6.3", "@fortawesome/fontawesome-free": "^5.10.2", @@ -4190,9 +4177,9 @@ "framer-motion": "^4.1.17", "polished": "3.4.1", "pretty-bytes": "^5.6.0", - "react": "^17.0.2", + "react": "^18.3.1", "react-debounce-input": "3.2.2", - "react-dom": "^17.0.2", + "react-dom": "^18.3.1", "react-dropzone": "^14.2.3", "react-hook-form": "^7.49.2", "react-query": "^3.34.0", @@ -4200,6 +4187,7 @@ "react-router-dom": "5.2.0", "react-select": "4.3.1", "react-table": "^7.7.0", + "react-test-renderer": "^18.3.1", "react-virtualized": "9.22.3", "react-virtualized-auto-sizer": "^1.0.24", "react-window": "^1.8.6", @@ -4238,11 +4226,12 @@ }, "node_modules/@scality/module-federation": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@scality/module-federation/-/module-federation-1.3.4.tgz", - "integrity": "sha512-Okmgh+s9UTM6ropLt5QIJhswaN3m0hGNjGI2w/al+a4H+fQs5x/rAYngzWhFnHxdox0RUSRwA7aOZH1fBAvnmA==", + "resolved": "git+ssh://git@github.com/scality/module-federation.git#c571388783a2a51ae3bf5d36ae66753c8b014bb5", + "integrity": "sha512-lrpXm7Skkq/CtGQRI563pSelewbeNaBBbs3J4zzCiheb0H2fSs6JF6lqQHQjL9A0HRVjfnArotXlF8E8JzVtnw==", + "license": "SEE LICENSE IN LICENSE", "peerDependencies": { - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.3.1", + "react-dom": "^18.3.1" } }, "node_modules/@sinclair/typebox": { @@ -4290,9 +4279,9 @@ "dev": true }, "node_modules/@storybook/preview-api": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.4.5.tgz", - "integrity": "sha512-MKIZ2jQO/3cUdsT57eq8jRgB6inALo9BxrQ88f7mqzltOkMvADvTAY6y8JZqTUoDzWTH/ny/8SGGdtpqlxRuiQ==", + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.4.4.tgz", + "integrity": "sha512-iZrWQcjRBqBHFdDXVxGpw6mHBZMCMYqhWXdyJ0d1S2y3PwcfOjkcXlQ1UiAenFHlA6dKrcYw8luKUQTL9bKReA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" @@ -4698,41 +4687,51 @@ } }, "node_modules/@testing-library/react": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.7.tgz", - "integrity": "sha512-tzRNp7pzd5QmbtXNG/mhdcl7Awfu/Iz1RaVHY75zTdOkmHCuzMhRL83gWHSgOAcjS3CCbyfwUHMZgRJb4kAfpA==", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.7.tgz", + "integrity": "sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^7.28.1" + "@testing-library/dom": "^10.0.0", + "@types/react-dom": "^18.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "peerDependencies": { - "react": "*", - "react-dom": "*" + "@types/react": "^18.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@testing-library/react-hooks": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-5.1.3.tgz", - "integrity": "sha512-UdEUtlQapQ579NEcXDAUE275u+KUsPtxW7NmFrNt0bE6lW8lqNCyxDK0RSuECmNZ/S0/fgP00W9RWRhVKO/hRg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz", + "integrity": "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", - "@types/react": ">=16.9.0", - "@types/react-dom": ">=16.9.0", - "@types/react-test-renderer": ">=16.9.0", - "filter-console": "^0.1.1", "react-error-boundary": "^3.1.0" }, + "engines": { + "node": ">=12" + }, "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0", - "react-test-renderer": ">=16.9.0" + "@types/react": "^16.9.0 || ^17.0.0", + "react": "^16.9.0 || ^17.0.0", + "react-dom": "^16.9.0 || ^17.0.0", + "react-test-renderer": "^16.9.0 || ^17.0.0" }, "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, "react-dom": { "optional": true }, @@ -4757,81 +4756,6 @@ "react": ">=16.13.1" } }, - "node_modules/@testing-library/react/node_modules/@testing-library/dom": { - "version": "7.31.2", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", - "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^4.2.2", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.6", - "lz-string": "^1.4.4", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@testing-library/react/node_modules/@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "dev": true - }, - "node_modules/@testing-library/react/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@testing-library/react/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/react/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@testing-library/react/node_modules/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==", - "dev": true - }, "node_modules/@testing-library/user-event": { "version": "13.5.0", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", @@ -4900,37 +4824,34 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.6.2", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "version": "7.4.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "version": "7.11.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "dev": true, "dependencies": { "@types/connect": "*", @@ -5011,9 +4932,9 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", "dev": true, "dependencies": { "@types/body-parser": "*", @@ -5023,9 +4944,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz", - "integrity": "sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA==", + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", "dev": true, "dependencies": { "@types/node": "*", @@ -5188,12 +5109,6 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true - }, "node_modules/@types/node": { "version": "22.9.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz", @@ -5222,34 +5137,33 @@ "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" }, "node_modules/@types/qs": { - "version": "6.9.17", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", - "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", "dev": true }, "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, "node_modules/@types/react": { - "version": "17.0.83", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.83.tgz", - "integrity": "sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw==", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "^0.16", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "17.0.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.25.tgz", - "integrity": "sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, "dependencies": { - "@types/react": "^17" + "@types/react": "*" } }, "node_modules/@types/react-router": { @@ -5288,11 +5202,6 @@ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" - }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -5303,6 +5212,12 @@ "@types/node": "*" } }, + "node_modules/@types/send/node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, "node_modules/@types/serve-index": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", @@ -5313,9 +5228,9 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", "dev": true, "dependencies": { "@types/http-errors": "*", @@ -7174,17 +7089,6 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/core-js-pure": { - "version": "3.39.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.39.0.tgz", - "integrity": "sha512-7fEcWwKI4rJinnK+wLTezeg2smbFFdSBP6E2kQZNbnzM2s1rpKQ6aaRteZSSg7FLU3P0HGGVo/gbpfanU36urg==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -8789,15 +8693,6 @@ "node": ">=8" } }, - "node_modules/filter-console": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/filter-console/-/filter-console-0.1.1.tgz", - "integrity": "sha512-zrXoV1Uaz52DqPs+qEwNJWJFAWZpYJ47UNmpN9q4j+/EYsz85uV0DC9k8tRND5kYmoVzL0W+Y75q4Rg8sRJCdg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -9361,9 +9256,8 @@ }, "node_modules/harmony-reflect": { "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", - "dev": true + "dev": true, + "license": "(Apache-2.0 OR MPL-1.1)" }, "node_modules/has-flag": { "version": "4.0.0", @@ -12898,9 +12792,8 @@ }, "node_modules/jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -14670,12 +14563,11 @@ } }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" @@ -14694,16 +14586,15 @@ } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.3.1" } }, "node_modules/react-dropzone": { @@ -14897,7 +14788,6 @@ "version": "16.15.0", "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", - "dev": true, "dependencies": { "object-assign": "^4.1.1", "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" @@ -14919,26 +14809,18 @@ } }, "node_modules/react-test-renderer": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz", - "integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==", - "dev": true, + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.3.1.tgz", + "integrity": "sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA==", "dependencies": { - "object-assign": "^4.1.1", - "react-is": "^17.0.2", - "react-shallow-renderer": "^16.13.1", - "scheduler": "^0.20.2" + "react-is": "^18.3.1", + "react-shallow-renderer": "^16.15.0", + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.3.1" } }, - "node_modules/react-test-renderer/node_modules/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==", - "dev": true - }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -15729,12 +15611,11 @@ } }, "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { @@ -16036,9 +15917,9 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", @@ -17247,10 +17128,9 @@ } }, "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "version": "2.0.0", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -17465,9 +17345,8 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", diff --git a/shell-ui/package.json b/shell-ui/package.json index d871b5156a..fef007e7f3 100644 --- a/shell-ui/package.json +++ b/shell-ui/package.json @@ -22,14 +22,15 @@ "@rspack/core": "^0.7.5", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^5.11.9", - "@testing-library/react": "^11.2.5", - "@testing-library/react-hooks": "^5.1.1", + "@testing-library/react": "^15.0.7", + "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "^13.0.10", - "@types/react": "^17.0.39", - "@types/react-dom": "^17.0.13", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", "@types/react-router": "^5.1.20", - "@types/react-router-dom": "^5.2.0", - "@types/styled-components": "^5.1.26", + "@types/react-router-dom": "^5.3.3", + "@types/react-test-renderer": "^18.3.0", + "@types/styled-components": "^5.1.34", "babel-jest": "^26.6.3", "babel-loader": "^8.2.2", "fs-extra": "^10.0.0", @@ -39,24 +40,24 @@ "jest-preview": "^0.3.1", "msw": "0.36.8", "node-fetch": "^2.6.1", - "react-test-renderer": "^17.0.2", + "react-test-renderer": "^18.3.1", "ts-node": "^10.9.2" }, "dependencies": { - "@scality/core-ui": "0.151.0", - "@scality/module-federation": "^1.3.4", + "@scality/core-ui": "git+https://github.com/scality/core-ui#bf0c36da657737f47dabe310bb1a20c136877970", + "@scality/module-federation": "git+https://github.com/scality/module-federation#c571388783a2a51ae3bf5d36ae66753c8b014bb5", "downshift": "^8.0.0", "jest-environment-jsdom": "^29.7.0", "oidc-client-ts": "^3.0.1", "oidc-react": "^3.2.2", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-error-boundary": "^4.0.2", "react-intl": "^5.15.3", "react-query": "^3.34.0", "react-router": "5.2.0", "react-router-dom": "5.2.0", - "styled-components": "^5.2.1", + "styled-components": "^5.3.11", "typescript": "^5.6.3" } } diff --git a/shell-ui/src/FederatedApp.tsx b/shell-ui/src/FederatedApp.tsx index cae930c6ab..60c7619353 100644 --- a/shell-ui/src/FederatedApp.tsx +++ b/shell-ui/src/FederatedApp.tsx @@ -1,5 +1,6 @@ import { CoreUiThemeProvider } from '@scality/core-ui/dist/components/coreuithemeprovider/CoreUiThemeProvider'; import { ErrorPage500 } from '@scality/core-ui/dist/components/error-pages/ErrorPage500.component'; +import { Loader } from '@scality/core-ui/dist/components/loader/Loader.component'; import { ScrollbarWrapper } from '@scality/core-ui/dist/components/scrollbarwrapper/ScrollbarWrapper.component'; import { ToastProvider } from '@scality/core-ui/dist/components/toast/ToastProvider'; import { @@ -12,61 +13,35 @@ import React, { useEffect, useMemo } from 'react'; import { ErrorBoundary } from 'react-error-boundary'; import { QueryClient, QueryClientProvider } from 'react-query'; import { Route, Router, Switch } from 'react-router-dom'; -import { Loader } from '@scality/core-ui/dist/components/loader/Loader.component'; -import NotificationCenterProvider, { - NotificationCenterContextType, -} from './NotificationCenterProvider'; +import { loadShare } from '@module-federation/enhanced/runtime'; +import { useQuery } from 'react-query'; +import NotificationCenterProvider from './NotificationCenterProvider'; import { AuthConfigProvider, useAuthConfig } from './auth/AuthConfigProvider'; import { AuthProvider, useAuth } from './auth/AuthProvider'; import { FirstTimeLoginProvider } from './auth/FirstTimeLoginProvider'; +import { + ShellAlerts, + shellAlerts, + ShellHooks, + shellHooks, +} from './hooks/useShellHooks'; import './index.css'; import { ConfigurationProvider, FederatedView, useConfigRetriever, - useConfig, useDiscoveredViews, - useLinkOpener, - BuildtimeWebFinger, - RuntimeWebFinger, } from './initFederation/ConfigurationProviders'; import { ShellConfigProvider, useShellConfig, } from './initFederation/ShellConfigProvider'; import { ShellHistoryProvider } from './initFederation/ShellHistoryProvider'; -import { - ShellThemeSelectorProvider, - useShellThemeSelector, -} from './initFederation/ShellThemeSelectorProvider'; -import { - UIListProvider, - useDeployedApps, -} from './initFederation/UIListProvider'; +import { ShellThemeSelectorProvider } from './initFederation/ShellThemeSelectorProvider'; +import { UIListProvider } from './initFederation/UIListProvider'; import { SolutionsNavbar } from './navbar'; import { LanguageProvider, useLanguage } from './navbar/lang'; -import AlertProvider from './alerts/AlertProvider'; -import { - getAlertingAlertSelectors, - getAuthenticationAlertSelectors, - getBootstrapAlertSelectors, - getDashboardingAlertSelectors, - getIngressControllerAlertSelectors, - getK8SMasterAlertSelectors, - getLoggingAlertSelectors, - getMonitoringAlertSelectors, - getNetworksAlertSelectors, - getNodesAlertSelectors, - getPlatformAlertSelectors, - getServicesAlertSelectors, - getVolumesAlertSelectors, - useAlerts, - useHighestSeverityAlerts, -} from './alerts'; -import { useHistory } from 'react-router'; -import { useQuery, UseQueryResult } from 'react-query'; -import { loadShare } from '@module-federation/enhanced/runtime'; /** * This is a mock function to replace the real loadShare function when running tests. @@ -86,95 +61,9 @@ const loadShareModule = export const queryClient = new QueryClient(); -export type ShellTypes = { - shellHooks: { - useAuthConfig: typeof useAuthConfig; - useAuth: typeof useAuth; - useConfigRetriever: typeof useConfigRetriever; - useDiscoveredViews: typeof useDiscoveredViews; - useShellConfig: typeof useShellConfig; - useLanguage: typeof useLanguage; - useConfig: typeof useConfig; - useLinkOpener: typeof useLinkOpener; - useDeployedApps: typeof useDeployedApps; - useShellThemeSelector: typeof useShellThemeSelector; - }; - shellAlerts: { - AlertsProvider: typeof AlertProvider; - hooks: { - useAlerts: typeof useAlerts; - useHighestSeverityAlerts: typeof useHighestSeverityAlerts; - }; - alertSelectors: { - getPlatformAlertSelectors: typeof getPlatformAlertSelectors; - getNodesAlertSelectors: typeof getNodesAlertSelectors; - getVolumesAlertSelectors: typeof getVolumesAlertSelectors; - getNetworksAlertSelectors: typeof getNetworksAlertSelectors; - getServicesAlertSelectors: typeof getServicesAlertSelectors; - getK8SMasterAlertSelectors: typeof getK8SMasterAlertSelectors; - getBootstrapAlertSelectors: typeof getBootstrapAlertSelectors; - getMonitoringAlertSelectors: typeof getMonitoringAlertSelectors; - getAlertingAlertSelectors: typeof getAlertingAlertSelectors; - getLoggingAlertSelectors: typeof getLoggingAlertSelectors; - getDashboardingAlertSelectors: typeof getDashboardingAlertSelectors; - getIngressControllerAlertSelectors: typeof getIngressControllerAlertSelectors; - getAuthenticationAlertSelectors: typeof getAuthenticationAlertSelectors; - }; - }; -}; - -declare global { - interface Window { - shellContexts: { - ShellHistoryContext: React.Context | null>; - NotificationContext: React.Context; - WebFingersContext: React.Context< - | null - | UseQueryResult< - BuildtimeWebFinger | RuntimeWebFinger>, - unknown - >[] - >; - }; - shellHooks: ShellTypes['shellHooks']; - shellAlerts: ShellTypes['shellAlerts']; - } -} - -window.shellHooks = { - useAuthConfig, - useAuth, - useConfigRetriever, - useDiscoveredViews, - useShellConfig, - useLanguage, - useConfig, - useLinkOpener: useLinkOpener, - useDeployedApps: useDeployedApps, - useShellThemeSelector: useShellThemeSelector, -}; - -window.shellAlerts = { - AlertsProvider: AlertProvider, - hooks: { - useAlerts: useAlerts, - useHighestSeverityAlerts: useHighestSeverityAlerts, - }, - alertSelectors: { - getPlatformAlertSelectors: getPlatformAlertSelectors, - getNodesAlertSelectors: getNodesAlertSelectors, - getVolumesAlertSelectors: getVolumesAlertSelectors, - getNetworksAlertSelectors: getNetworksAlertSelectors, - getServicesAlertSelectors: getServicesAlertSelectors, - getK8SMasterAlertSelectors: getK8SMasterAlertSelectors, - getBootstrapAlertSelectors: getBootstrapAlertSelectors, - getMonitoringAlertSelectors: getMonitoringAlertSelectors, - getAlertingAlertSelectors: getAlertingAlertSelectors, - getLoggingAlertSelectors: getLoggingAlertSelectors, - getDashboardingAlertSelectors: getDashboardingAlertSelectors, - getIngressControllerAlertSelectors: getIngressControllerAlertSelectors, - getAuthenticationAlertSelectors: getAuthenticationAlertSelectors, - }, +export type FederatedAppProps = { + shellHooks: ShellHooks; + shellAlerts: ShellAlerts; }; function FederatedRoute({ @@ -230,6 +119,11 @@ function ProtectedFederatedRoute({ const { userData } = useAuth(); const { retrieveConfiguration } = useConfigRetriever(); + const federatedAppProps: FederatedAppProps = { + shellHooks, + shellAlerts, + }; + if ( userData && (groups?.some((group) => userData.groups.includes(group)) ?? true) @@ -242,7 +136,7 @@ function ProtectedFederatedRoute({ diff --git a/shell-ui/src/NotificationCenterProvider.tsx b/shell-ui/src/NotificationCenterProvider.tsx index d1cd131136..63ed86ad38 100644 --- a/shell-ui/src/NotificationCenterProvider.tsx +++ b/shell-ui/src/NotificationCenterProvider.tsx @@ -1,4 +1,4 @@ -import React, { Dispatch, createContext, useReducer } from 'react'; +import { Dispatch, FC, ReactNode, createContext, useReducer } from 'react'; export type Notification = { id: string; @@ -18,16 +18,12 @@ export type NotificationCenterContextType = { dispatch: Dispatch; }; -if (!window.shellContexts) { - //@ts-ignore - window.shellContexts = {}; -} -if (!window.shellContexts.NotificationContext) { - window.shellContexts.NotificationContext = - createContext(null); -} export const NotificationCenterContext = - window.shellContexts.NotificationContext; + createContext(null); + +type NotificationCenterProviderProps = { + children: ReactNode; +}; export enum NotificationActionType { PUBLISH, @@ -50,7 +46,9 @@ export type NotificationCenterActions = const LOCAL_STORAGE_NOTIFICATION_PREFIX = 'notification-center__'; -const NotificationCenterProvider = ({ children }) => { +const NotificationCenterProvider: FC = ({ + children, +}) => { const notificationReducer = ( state: InternalNotification[], action: NotificationCenterActions, diff --git a/shell-ui/src/alerts/alertContext.ts b/shell-ui/src/alerts/alertContext.ts index fe8b222bf4..a1647e6fc4 100644 --- a/shell-ui/src/alerts/alertContext.ts +++ b/shell-ui/src/alerts/alertContext.ts @@ -1,15 +1,3 @@ import { createContext } from 'react'; -if (!window.shellContexts) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts = {}; -} - -// @ts-expect-error - FIXME when you are working on it -if (!window.shellContexts.AlertContext) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts.AlertContext = createContext(null); -} - -// @ts-expect-error - FIXME when you are working on it -export const AlertContext = window.shellContexts.AlertContext; +export const AlertContext = createContext(null); diff --git a/shell-ui/src/alerts/alertHooks.ts b/shell-ui/src/alerts/alertHooks.ts index 8393d6dd4d..6107f67d8a 100644 --- a/shell-ui/src/alerts/alertHooks.ts +++ b/shell-ui/src/alerts/alertHooks.ts @@ -90,7 +90,7 @@ export const useHighestSeverityAlerts = (filters: FilterLabels): Alert[] => { * * @returns react query result */ -export function useAlerts(filters: FilterLabels) { +export function useAlerts(filters?: FilterLabels) { const query = useContext(AlertContext); if (!query) { diff --git a/shell-ui/src/auth/useFirstTimeLogin.spec.tsx b/shell-ui/src/auth/useFirstTimeLogin.spec.tsx index f918b33d18..9eb73076ff 100644 --- a/shell-ui/src/auth/useFirstTimeLogin.spec.tsx +++ b/shell-ui/src/auth/useFirstTimeLogin.spec.tsx @@ -3,6 +3,7 @@ import { useFirstTimeLogin } from './FirstTimeLoginProvider'; import { wrapper } from '../navbar/index.spec'; import { configurationHandlers } from '../FederatedApp.spec'; import { setupServer } from 'msw/node'; +import { waitFor } from '@testing-library/react'; const server = setupServer(...configurationHandlers); @@ -28,14 +29,11 @@ describe('useFirstTimeLogin hook', () => { it('should return firstTimeLogin as true if the user is logging in for the first time', async () => { //S - const { result, waitForNextUpdate } = renderHook( - () => useFirstTimeLogin(), - { wrapper }, - ); - //E - await waitForNextUpdate(); + const { result } = renderHook(() => useFirstTimeLogin(), { wrapper }); //V - expect(result.current.firstTimeLogin).toEqual(true); + await waitFor(() => { + expect(result.current.firstTimeLogin).toEqual(true); + }); }); it('should return firstTimeLogin as false if the user is NOT logging in for the first time', async () => { diff --git a/shell-ui/src/hooks/useShellHooks.ts b/shell-ui/src/hooks/useShellHooks.ts new file mode 100644 index 0000000000..fc2643f590 --- /dev/null +++ b/shell-ui/src/hooks/useShellHooks.ts @@ -0,0 +1,102 @@ +import { + useAlerts, + getPlatformAlertSelectors, + getNodesAlertSelectors, + getVolumesAlertSelectors, + getNetworksAlertSelectors, + getServicesAlertSelectors, + getK8SMasterAlertSelectors, + getBootstrapAlertSelectors, + getMonitoringAlertSelectors, + getAlertingAlertSelectors, + getLoggingAlertSelectors, + getDashboardingAlertSelectors, + getIngressControllerAlertSelectors, + getAuthenticationAlertSelectors, + useHighestSeverityAlerts, +} from '../alerts'; +import AlertProvider from '../alerts/AlertProvider'; +import { useAuthConfig } from '../auth/AuthConfigProvider'; +import { useAuth } from '../auth/AuthProvider'; +import { + useConfig, + useConfigRetriever, + useDiscoveredViews, + useLinkOpener, +} from '../initFederation/ConfigurationProviders'; +import { useShellConfig } from '../initFederation/ShellConfigProvider'; +import { useShellThemeSelector } from '../initFederation/ShellThemeSelectorProvider'; +import { useDeployedApps } from '../initFederation/UIListProvider'; +import { useLanguage } from '../navbar/lang'; + +export type ShellHooks = { + useAuthConfig: typeof useAuthConfig; + useAuth: typeof useAuth; + useConfigRetriever: typeof useConfigRetriever; + useDiscoveredViews: typeof useDiscoveredViews; + useShellConfig: typeof useShellConfig; + useLanguage: typeof useLanguage; + useConfig: typeof useConfig; + useLinkOpener: typeof useLinkOpener; + useDeployedApps: typeof useDeployedApps; + useShellThemeSelector: typeof useShellThemeSelector; +}; + +export type ShellAlerts = { + AlertsProvider: typeof AlertProvider; + alertHooks: { + useAlerts: typeof useAlerts; + useHighestSeverityAlerts: typeof useHighestSeverityAlerts; + }; + alertSelectors: { + getPlatformAlertSelectors: typeof getPlatformAlertSelectors; + getNodesAlertSelectors: typeof getNodesAlertSelectors; + getVolumesAlertSelectors: typeof getVolumesAlertSelectors; + getNetworksAlertSelectors: typeof getNetworksAlertSelectors; + getServicesAlertSelectors: typeof getServicesAlertSelectors; + getK8SMasterAlertSelectors: typeof getK8SMasterAlertSelectors; + getBootstrapAlertSelectors: typeof getBootstrapAlertSelectors; + getMonitoringAlertSelectors: typeof getMonitoringAlertSelectors; + getAlertingAlertSelectors: typeof getAlertingAlertSelectors; + getLoggingAlertSelectors: typeof getLoggingAlertSelectors; + getDashboardingAlertSelectors: typeof getDashboardingAlertSelectors; + getIngressControllerAlertSelectors: typeof getIngressControllerAlertSelectors; + getAuthenticationAlertSelectors: typeof getAuthenticationAlertSelectors; + }; +}; + +export const shellHooks: ShellHooks = { + useAuthConfig, + useAuth, + useConfigRetriever, + useDiscoveredViews, + useShellConfig, + useLanguage, + useConfig, + useLinkOpener, + useDeployedApps, + useShellThemeSelector, +}; + +export const shellAlerts: ShellAlerts = { + AlertsProvider: AlertProvider, + alertHooks: { + useAlerts, + useHighestSeverityAlerts, + }, + alertSelectors: { + getPlatformAlertSelectors, + getNodesAlertSelectors, + getVolumesAlertSelectors, + getNetworksAlertSelectors, + getServicesAlertSelectors, + getK8SMasterAlertSelectors, + getBootstrapAlertSelectors, + getMonitoringAlertSelectors, + getAlertingAlertSelectors, + getLoggingAlertSelectors, + getDashboardingAlertSelectors, + getIngressControllerAlertSelectors, + getAuthenticationAlertSelectors, + }, +}; diff --git a/shell-ui/src/index.tsx b/shell-ui/src/index.tsx index fc4c4670b4..82892eb7bd 100644 --- a/shell-ui/src/index.tsx +++ b/shell-ui/src/index.tsx @@ -1,11 +1,9 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App, { ShellTypes } from './FederatedApp'; -import { NotificationCenterContextType } from './NotificationCenterProvider'; -import { History } from 'history'; -import { - BuildtimeWebFinger, - RuntimeWebFinger, -} from './initFederation/ConfigurationProviders'; +import { createRoot } from 'react-dom/client'; +import App from './FederatedApp'; -ReactDOM.render(, document.getElementById('app')); +const rootElement = document.getElementById('app'); + +if (rootElement) { + const root = createRoot(rootElement); + root.render(); +} diff --git a/shell-ui/src/initFederation/ConfigurationProviders.tsx b/shell-ui/src/initFederation/ConfigurationProviders.tsx index 33d1093b0f..ea8f0c0f87 100644 --- a/shell-ui/src/initFederation/ConfigurationProviders.tsx +++ b/shell-ui/src/initFederation/ConfigurationProviders.tsx @@ -2,27 +2,12 @@ import { ErrorPage500 } from '@scality/core-ui/dist/components/error-pages/Error import { IconName } from '@scality/core-ui/dist/components/icon/Icon.component'; import { Loader } from '@scality/core-ui/dist/components/loader/Loader.component'; import { SolutionUI } from '@scality/module-federation'; -import React, { createContext, useContext } from 'react'; +import React, { useMemo, useSyncExternalStore } from 'react'; import { useQueries, UseQueryResult } from 'react-query'; import { useShellConfig } from './ShellConfigProvider'; import { useShellHistory } from './ShellHistoryProvider'; import { useDeployedApps, useDeployedAppsRetriever } from './UIListProvider'; -if (!window.shellContexts) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts = {}; -} - -if (!window.shellContexts.WebFingersContext) { - window.shellContexts.WebFingersContext = createContext< - | null - | UseQueryResult< - BuildtimeWebFinger | RuntimeWebFinger>, - unknown - >[] - >(null); -} - export type OAuth2ProxyConfig = { kind: 'OAuth2Proxy'; //todo : add other entries }; @@ -85,10 +70,8 @@ export function useConfigRetriever(): { name: string; }) => (T extends 'build' ? BuildtimeWebFinger : RuntimeWebFinger) | null; } { + const { state: webFingerContextValue } = useWebFingersStore(); const { retrieveDeployedApps } = useDeployedAppsRetriever(); - const webFingerContextValue = useContext( - window.shellContexts.WebFingersContext, - ); if (!webFingerContextValue) { throw new Error( @@ -142,15 +125,18 @@ export function useConfig>({ configType: T extends 'build' ? 'build' : 'run'; name: string; }): null | T extends 'build' ? BuildtimeWebFinger : RuntimeWebFinger { + // Utiliser le nouveau hook useWebFingersStore + const { state: webFingerContextValue } = useWebFingersStore(); + + // Utiliser le retrieveConfiguration du hook useConfigRetriever const { retrieveConfiguration } = useConfigRetriever(); - const webFingerContextValue = useContext( - window.shellContexts.WebFingersContext, - ); - if (!webFingerContextValue) { + // Vérifier que le contexte est disponible + if (!webFingerContextValue || webFingerContextValue.length === 0) { throw new Error("Can't use useConfig outside of ConfigurationProvider"); } + // Récupérer et retourner la configuration return retrieveConfiguration({ configType, name, @@ -179,6 +165,72 @@ export type NonFederatedView = { icon?: IconName; }; export type ViewDefinition = FederatedView | NonFederatedView; + +// External store implementation +class WebFingersStore { + private listeners: Set<() => void> = new Set(); + private _state: UseQueryResult< + BuildtimeWebFinger | RuntimeWebFinger>, + unknown + >[] = []; + + subscribe = (listener: () => void) => { + this.listeners.add(listener); + return () => { + this.listeners.delete(listener); + }; + }; + + getState = () => { + return this._state; + }; + + private isStateEqual( + currentState: UseQueryResult< + BuildtimeWebFinger | RuntimeWebFinger>, + unknown + >[], + newState: UseQueryResult< + BuildtimeWebFinger | RuntimeWebFinger>, + unknown + >[], + ) { + return ( + currentState.length === newState.length && + currentState.every( + (item, index) => + JSON.stringify(item) === JSON.stringify(newState[index]), + ) + ); + } + + updateState = ( + newState: UseQueryResult< + BuildtimeWebFinger | RuntimeWebFinger>, + unknown + >[], + ) => { + if (!this.isStateEqual(this._state, newState)) { + this._state = newState; + this.listeners.forEach((listener) => listener()); + } + }; +} + +const webFingersStore = new WebFingersStore(); + +export function useWebFingersStore() { + const state = useSyncExternalStore( + webFingersStore.subscribe, + webFingersStore.getState, + ); + + return { + state, + updateWebFingersState: webFingersStore.updateState, + }; +} + export function useDiscoveredViews(): ViewDefinition[] { const { retrieveConfiguration } = useConfigRetriever(); const { retrieveDeployedApps } = useDeployedAppsRetriever(); @@ -286,6 +338,7 @@ export const ConfigurationProvider = ({ }: { children: React.ReactNode; }) => { + const { updateWebFingersState } = useWebFingersStore(); const deployedUIs = useDeployedApps(); const results = useQueries( deployedUIs.flatMap((ui) => [ @@ -323,6 +376,11 @@ export const ConfigurationProvider = ({ }, ]), ); + + useMemo(() => { + updateWebFingersState(results); + }, [results]); + const statuses = Array.from(new Set(results.map((result) => result.status))); const globalStatus = statuses.includes('error') ? 'error' @@ -333,13 +391,14 @@ export const ConfigurationProvider = ({ : statuses.includes('idle') && statuses.includes('success') ? 'loading' : 'success'; + return ( - + <> {(globalStatus === 'loading' || globalStatus === 'idle') && ( )} {globalStatus === 'error' && } {globalStatus === 'success' && children} - + ); }; diff --git a/shell-ui/src/initFederation/ShellConfigProvider.tsx b/shell-ui/src/initFederation/ShellConfigProvider.tsx index 486dcb9667..7d4b80546e 100644 --- a/shell-ui/src/initFederation/ShellConfigProvider.tsx +++ b/shell-ui/src/initFederation/ShellConfigProvider.tsx @@ -7,15 +7,7 @@ import { import React, { createContext, useContext } from 'react'; import { useQuery } from 'react-query'; -if (!window.shellContexts) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts = {}; -} -// @ts-expect-error - FIXME when you are working on it -if (!window.shellContexts.ShellConfigContext) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts.ShellConfigContext = createContext(null); -} +const ShellConfigContext = createContext(null); export type NavbarEntry = { groups?: string[]; @@ -78,10 +70,7 @@ export type ShellConfig = { }; export const useShellConfig = () => { - const contextValue = useContext( - // @ts-expect-error - FIXME when you are working on it - window.shellContexts.ShellConfigContext, - ); + const contextValue = useContext(ShellConfigContext); if (!contextValue) { throw new Error("useShellConfig can't be used outside ShellConfigProvider"); @@ -99,14 +88,13 @@ export const useShellConfig = () => { export const ShellConfigProvider = ({ shellConfigUrl, children }) => { const { data: config, status } = useQuery( 'getShellJSONConfigFile', - () => { - return fetch(shellConfigUrl).then((r) => { - if (r.ok) { - return r.json(); - } else { - return Promise.reject(); - } - }); + async () => { + const r = await fetch(shellConfigUrl); + if (r.ok) { + return r.json(); + } else { + return Promise.reject(); + } }, { refetchOnWindowFocus: false, @@ -114,8 +102,7 @@ export const ShellConfigProvider = ({ shellConfigUrl, children }) => { ); return ( - // @ts-expect-error - FIXME when you are working on it - { )} {status === 'error' && } {status === 'success' && children} - {/* @ts-expect-error - FIXME when you are working on it */} - + ); }; diff --git a/shell-ui/src/initFederation/ShellHistoryProvider.tsx b/shell-ui/src/initFederation/ShellHistoryProvider.tsx index 65ab8f9d9f..bbfb6f9e6a 100644 --- a/shell-ui/src/initFederation/ShellHistoryProvider.tsx +++ b/shell-ui/src/initFederation/ShellHistoryProvider.tsx @@ -4,19 +4,9 @@ import { useHistory } from 'react-router'; const ShellHistoryContext = createContext > | null>(null); -if (!window.shellContexts) { - window.shellContexts = { - ShellHistoryContext, - ...window.shellContexts, - }; -} - -if (!window.shellContexts.ShellHistoryContext) { - window.shellContexts.ShellHistoryContext = ShellHistoryContext; -} export const useShellHistory = () => { - const contextValue = useContext(window.shellContexts.ShellHistoryContext); + const contextValue = useContext(ShellHistoryContext); if (!contextValue) { throw new Error( @@ -29,8 +19,8 @@ export const useShellHistory = () => { export const ShellHistoryProvider = ({ children }) => { const history = useHistory(); return ( - + {children} - + ); }; diff --git a/shell-ui/src/initFederation/ShellThemeSelectorProvider.tsx b/shell-ui/src/initFederation/ShellThemeSelectorProvider.tsx index b69b9be5e9..e1e095677c 100644 --- a/shell-ui/src/initFederation/ShellThemeSelectorProvider.tsx +++ b/shell-ui/src/initFederation/ShellThemeSelectorProvider.tsx @@ -13,22 +13,10 @@ type ThemeContextValues = { assets: { logoPath: string }; }; -if (!window.shellContexts) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts = {}; -} -// @ts-expect-error - FIXME when you are working on it -if (!window.shellContexts.ShellThemeContext) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts.ShellThemeContext = - React.createContext(null); -} +const ShellThemeContext = React.createContext(null); export function useShellThemeSelector(): ThemeContextValues { - const themeContext: ThemeContextValues = useContext( - // @ts-expect-error - FIXME when you are working on it - window.shellContexts.ShellThemeContext, - ); + const themeContext: ThemeContextValues = useContext(ShellThemeContext); if (themeContext === null) { throw new Error( @@ -97,8 +85,7 @@ export function ShellThemeSelectorProvider({ }; return ( - // @ts-expect-error - FIXME when you are working on it - {children(selectedTheme, themeMode)} - {/* @ts-expect-error - FIXME when you are working on it */} - + ); } diff --git a/shell-ui/src/initFederation/UIListProvider.tsx b/shell-ui/src/initFederation/UIListProvider.tsx index 7b7839a885..28e1d45053 100644 --- a/shell-ui/src/initFederation/UIListProvider.tsx +++ b/shell-ui/src/initFederation/UIListProvider.tsx @@ -5,15 +5,7 @@ import { Loader } from '@scality/core-ui/dist/components/loader/Loader.component import { ErrorPage500 } from '@scality/core-ui/dist/components/error-pages/ErrorPage500.component'; import type { SolutionUI } from '@scality/module-federation'; -if (!window.shellContexts) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts = {}; -} -// @ts-expect-error - FIXME when you are working on it -if (!window.shellContexts.UIListContext) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts.UIListContext = createContext(null); -} +const UIListContext = createContext(null); export function useDeployedAppsRetriever(): { retrieveDeployedApps: (selectors?: { @@ -21,8 +13,7 @@ export function useDeployedAppsRetriever(): { name?: string; }) => SolutionUI[]; } { - // @ts-expect-error - FIXME when you are working on it - const uiListContext = useContext(window.shellContexts.UIListContext); + const uiListContext = useContext(UIListContext); if (!uiListContext) { throw new Error( @@ -32,9 +23,7 @@ export function useDeployedAppsRetriever(): { return { retrieveDeployedApps: (selectors) => { - // @ts-expect-error - FIXME when you are working on it if (selectors && uiListContext.uis) { - // @ts-expect-error - FIXME when you are working on it return uiListContext.uis.filter((ui) => { return ( ((selectors.kind && selectors.kind === ui.kind) || @@ -43,7 +32,6 @@ export function useDeployedAppsRetriever(): { ); }); } - // @ts-expect-error - FIXME when you are working on it return uiListContext.uis || []; }, }; @@ -52,8 +40,7 @@ export const useDeployedApps = (selectors?: { kind?: string; name?: string; }): SolutionUI[] => { - // @ts-expect-error - FIXME when you are working on it - const uiListContext = useContext(window.shellContexts.UIListContext); + const uiListContext = useContext(UIListContext); if (!uiListContext) { throw new Error("Can't use useDeployedApps outside of UIListProvider"); @@ -71,22 +58,20 @@ export const UIListProvider = ({ }) => { const { status, data } = useQuery( 'discoveredUIs', - () => { - return fetch(discoveryURL, { cache: 'no-cache' }).then((r) => { - if (r.ok) { - return r.json(); - } else { - return Promise.reject(); - } - }); + async () => { + const r = await fetch(discoveryURL, { cache: 'no-cache' }); + if (r.ok) { + return r.json(); + } else { + return Promise.reject(); + } }, { refetchOnWindowFocus: false, }, ); return ( - // @ts-expect-error - FIXME when you are working on it - } {status === 'success' && children} - {/* @ts-expect-error - FIXME when you are working on it */} - + ); }; diff --git a/shell-ui/src/navbar/__TESTS__/testMultipleHooks.tsx b/shell-ui/src/navbar/__TESTS__/testMultipleHooks.tsx index 2c68a5161d..b66220b6fb 100644 --- a/shell-ui/src/navbar/__TESTS__/testMultipleHooks.tsx +++ b/shell-ui/src/navbar/__TESTS__/testMultipleHooks.tsx @@ -24,7 +24,7 @@ export type RenderAdditionalHook = ( }; export function prepareRenderMultipleHooks(options: { - wrapper: FunctionComponent>>; + wrapper: FunctionComponent>>>; }): { renderAdditionalHook: RenderAdditionalHook; waitForWrapperToBeReady: () => Promise; diff --git a/shell-ui/src/navbar/index.spec.tsx b/shell-ui/src/navbar/index.spec.tsx index 812fead4ca..f25e4d74da 100644 --- a/shell-ui/src/navbar/index.spec.tsx +++ b/shell-ui/src/navbar/index.spec.tsx @@ -5,9 +5,8 @@ import React from 'react'; import { QueryClient, QueryClientProvider } from 'react-query'; import { MemoryRouter } from 'react-router'; -import { render, screen } from '@testing-library/react'; +import { render, screen, waitFor, act } from '@testing-library/react'; import { useAuth } from 'oidc-react'; -import { act } from 'react-test-renderer'; import { SolutionsNavbar } from '.'; import { WithInitFederationProviders } from '../FederatedApp'; import { configurationHandlers } from '../FederatedApp.spec'; @@ -128,77 +127,99 @@ describe('useNavbar', () => { }; it('should retrieve navbar configuration', async () => { //E - const { result, waitForNextUpdate } = renderHook(() => useNavbar(), { + const { result } = renderHook(() => useNavbar(), { wrapper, }); - await waitForNextUpdate(); - //V - expect(result.current.getLinks()).toStrictEqual(expectedDefaultNavbarLinks); + await waitFor(() => { + expect(result.current.getLinks()).toStrictEqual( + expectedDefaultNavbarLinks, + ); + }); }); it('should set main navbar links', async () => { //S - const { result, waitForNextUpdate } = renderHook(() => useNavbar(), { + const { result } = renderHook(() => useNavbar(), { wrapper, }); - await act(() => waitForNextUpdate()); + await waitFor(() => { + expect(result.current.setMainLinks).toBeDefined(); + }); + //E act(() => // @ts-expect-error - FIXME when you are working on it result.current.setMainLinks([expectedDefaultNavbarLinks.main[0]]), ); + //V - expect(result.current.getLinks()).toStrictEqual({ - ...expectedDefaultNavbarLinks, - main: [expectedDefaultNavbarLinks.main[0]], + await waitFor(() => { + expect(result.current.getLinks()).toStrictEqual({ + ...expectedDefaultNavbarLinks, + main: [expectedDefaultNavbarLinks.main[0]], + }); }); }); it('should set secondary navbar links', async () => { //S - const { result, waitForNextUpdate } = renderHook(() => useNavbar(), { + const { result } = renderHook(() => useNavbar(), { wrapper, }); - await waitForNextUpdate(); + + await waitFor(() => { + expect(result.current.setSecondaryLinks).toBeDefined(); + }); //E act(() => // @ts-expect-error - FIXME when you are working on it result.current.setSecondaryLinks([expectedDefaultNavbarLinks.main[0]]), ); //V - expect(result.current.getLinks()).toStrictEqual({ - ...expectedDefaultNavbarLinks, - secondary: [expectedDefaultNavbarLinks.main[0]], + await waitFor(() => { + expect(result.current.getLinks()).toStrictEqual({ + ...expectedDefaultNavbarLinks, + secondary: [expectedDefaultNavbarLinks.main[0]], + }); }); }); it('should set user dropdown links', async () => { //S - const { result, waitForNextUpdate } = renderHook(() => useNavbar(), { + const { result } = renderHook(() => useNavbar(), { wrapper, }); - await waitForNextUpdate(); //E + await waitFor(() => { + expect(result.current.setUserDropdownLinks).toBeDefined(); + }); act(() => // @ts-expect-error - FIXME when you are working on it result.current.setUserDropdownLinks([expectedDefaultNavbarLinks.main[0]]), ); //V - expect(result.current.getLinks()).toStrictEqual({ - ...expectedDefaultNavbarLinks, - userDropdown: [expectedDefaultNavbarLinks.main[0]], + await waitFor(() => { + expect(result.current.getLinks()).toStrictEqual({ + ...expectedDefaultNavbarLinks, + userDropdown: [expectedDefaultNavbarLinks.main[0]], + }); }); }); it('should set logo link', async () => { //S - const { result, waitForNextUpdate } = renderHook(() => useNavbar(), { + const { result } = renderHook(() => useNavbar(), { wrapper, }); - await waitForNextUpdate(); //E + await waitFor(() => { + expect(result.current.setLogoLink).toBeDefined(); + }); + act(() => result.current.setLogoLink('http://localhost:3000')); //V - expect(result.current.getLinks()).toStrictEqual({ - ...expectedDefaultNavbarLinks, - logoHref: 'http://localhost:3000', + await waitFor(() => { + expect(result.current.getLinks()).toStrictEqual({ + ...expectedDefaultNavbarLinks, + logoHref: 'http://localhost:3000', + }); }); }); it('should display the Notification Center for Platform Admin', async () => { diff --git a/shell-ui/src/navbar/lang.tsx b/shell-ui/src/navbar/lang.tsx index b51cea7f53..5da8ab569b 100644 --- a/shell-ui/src/navbar/lang.tsx +++ b/shell-ui/src/navbar/lang.tsx @@ -9,15 +9,7 @@ import translations_en from './translations/en.json'; import translations_fr from './translations/fr.json'; import { LANGUAGE_CHANGED_EVENT } from './events'; -if (!window.shellContexts) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts = {}; -} -// @ts-expect-error - FIXME when you are working on it -if (!window.shellContexts.LanguageContext) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts.LanguageContext = createContext(null); -} +const LanguageContext = createContext(null); type Language = 'en' | 'fr'; export const languages: Language[] = ['en', 'fr']; @@ -30,8 +22,7 @@ export function useLanguage(): { setLanguage: (language: Language) => void; unSelectedLanguages: Language[]; } { - // @ts-expect-error - FIXME when you are working on it - const languageContext = useContext(window.shellContexts.LanguageContext); + const languageContext = useContext(LanguageContext); if (languageContext === null) { throw new Error( @@ -40,12 +31,9 @@ export function useLanguage(): { } return { - // @ts-expect-error - FIXME when you are working on it language: languageContext.language, - // @ts-expect-error - FIXME when you are working on it setLanguage: languageContext.setLanguage, unSelectedLanguages: languages.filter( - // @ts-expect-error - FIXME when you are working on it (lang) => lang !== languageContext.language, ), }; @@ -81,8 +69,7 @@ export function LanguageProvider({ }; return ( - // @ts-expect-error - FIXME when you are working on it - {children} - {/* @ts-expect-error - FIXME when you are working on it */} - + ); } diff --git a/shell-ui/src/navbar/navbarContext.ts b/shell-ui/src/navbar/navbarContext.ts index 74865b34e9..018b9f1782 100644 --- a/shell-ui/src/navbar/navbarContext.ts +++ b/shell-ui/src/navbar/navbarContext.ts @@ -2,16 +2,4 @@ import { createContext } from 'react'; import type { Navbar } from './navbarHooks'; import './navbarHooks'; -if (!window.shellContexts) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts = {}; -} - -// @ts-expect-error - FIXME when you are working on it -if (!window.shellContexts.NavbarContext) { - // @ts-expect-error - FIXME when you are working on it - window.shellContexts.NavbarContext = createContext(null); -} - -// @ts-expect-error - FIXME when you are working on it -export const NavbarContext = window.shellContexts.NavbarContext; +export const NavbarContext = createContext(null); diff --git a/ui/package-lock.json b/ui/package-lock.json index 88fb780ef1..bd499a5475 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -12,8 +12,8 @@ "@hookform/resolvers": "^3.1.0", "@js-temporal/polyfill": "^0.4.4", "@kubernetes/client-node": "github:scality/kubernetes-client-javascript.git#browser-0.10.4-64-ge7c6721", - "@scality/core-ui": "0.151.0", - "@scality/module-federation": "^1.3.4", + "@scality/core-ui": "git+https://github.com/scality/core-ui#bf0c36da657737f47dabe310bb1a20c136877970", + "@scality/module-federation": "git+https://github.com/scality/module-federation#c571388783a2a51ae3bf5d36ae66753c8b014bb5", "axios": "^0.21.1", "formik": "2.2.5", "jsonpath": "^1.1.1", @@ -21,9 +21,9 @@ "lodash.isequal": "^4.5.0", "lodash.sortby": "^4.7.0", "luxon": "^2.1.1", - "react": "^17.0.1", - "react-dom": "^17.0.1", - "react-error-boundary": "^3.1.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-error-boundary": "^4.1.2", "react-hook-form": "^7.44.3", "react-intl": "^5.15.3", "react-json-view": "^1.21.3", @@ -34,7 +34,7 @@ "redux": "^4.0.1", "redux-saga": "^1.0.2", "reselect": "^2.5.4", - "styled-components": "^5.0.1", + "styled-components": "^5.3.11", "uuid": "3.3.2", "yup": "^0.32.9" }, @@ -50,7 +50,7 @@ "@rspack/core": "^0.7.5", "@testing-library/dom": "^9.3.1", "@testing-library/jest-dom": "^5.11.9", - "@testing-library/react": "^11.2.3", + "@testing-library/react": "^15.0.7", "@testing-library/react-hooks": "^3.4.2", "@testing-library/user-event": "^14.4.3", "@types/hapi__joi": "^17.1.9", @@ -58,10 +58,13 @@ "@types/lodash.isempty": "^4.4.7", "@types/lodash.isequal": "^4.5.6", "@types/lodash.sortby": "^4.7.7", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", "@types/react-redux": "^7.1.25", "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", - "@types/styled-components": "^5.1.26", + "@types/react-test-renderer": "^18.3.0", + "@types/styled-components": "^5.1.34", "@typescript-eslint/eslint-plugin": "^5.62.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.3", @@ -84,7 +87,7 @@ "jest-preview": "^0.3.1", "msw": "0.36.8", "oidc-client": "^1.8.0", - "react-test-renderer": "^17.0.1", + "react-test-renderer": "^18.3.1", "ts-node": "^10.9.2", "typescript": "^5.3.3" }, @@ -2637,13 +2640,15 @@ "node_modules/@emotion/is-prop-valid": { "version": "0.8.8", "license": "MIT", + "optional": true, "dependencies": { "@emotion/memoize": "0.7.4" } }, "node_modules/@emotion/memoize": { "version": "0.7.4", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/@emotion/react": { "version": "11.11.3", @@ -5532,8 +5537,9 @@ }, "node_modules/@scality/core-ui": { "version": "0.151.0", - "resolved": "https://registry.npmjs.org/@scality/core-ui/-/core-ui-0.151.0.tgz", - "integrity": "sha512-OeAhs+uiOOBDSGqzZGpIka1iCtRrGJkjNhzdRJhJtLwxKDFU7iyPUPA3MbJ8DoGJQN0do8k3PTyei1fZEiMXJA==", + "resolved": "git+ssh://git@github.com/scality/core-ui.git#bf0c36da657737f47dabe310bb1a20c136877970", + "integrity": "sha512-dC/zNxvxU7DVgxhbyKHgwwVyM2CwWACrwyVbh1VP0/7KTcgTmoYR2hO9qAMi9t8yyNWidOi9AVVzKupes13wRw==", + "license": "SEE LICENSE IN LICENSE", "dependencies": { "@floating-ui/dom": "^1.6.3", "@fortawesome/fontawesome-free": "^5.10.2", @@ -5547,9 +5553,9 @@ "framer-motion": "^4.1.17", "polished": "3.4.1", "pretty-bytes": "^5.6.0", - "react": "^17.0.2", + "react": "^18.3.1", "react-debounce-input": "3.2.2", - "react-dom": "^17.0.2", + "react-dom": "^18.3.1", "react-dropzone": "^14.2.3", "react-hook-form": "^7.49.2", "react-query": "^3.34.0", @@ -5557,6 +5563,7 @@ "react-router-dom": "5.2.0", "react-select": "4.3.1", "react-table": "^7.7.0", + "react-test-renderer": "^18.3.1", "react-virtualized": "9.22.3", "react-virtualized-auto-sizer": "^1.0.24", "react-window": "^1.8.6", @@ -5587,11 +5594,12 @@ }, "node_modules/@scality/module-federation": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@scality/module-federation/-/module-federation-1.3.4.tgz", - "integrity": "sha512-Okmgh+s9UTM6ropLt5QIJhswaN3m0hGNjGI2w/al+a4H+fQs5x/rAYngzWhFnHxdox0RUSRwA7aOZH1fBAvnmA==", + "resolved": "git+ssh://git@github.com/scality/module-federation.git#c571388783a2a51ae3bf5d36ae66753c8b014bb5", + "integrity": "sha512-lrpXm7Skkq/CtGQRI563pSelewbeNaBBbs3J4zzCiheb0H2fSs6JF6lqQHQjL9A0HRVjfnArotXlF8E8JzVtnw==", + "license": "SEE LICENSE IN LICENSE", "peerDependencies": { - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.3.1", + "react-dom": "^18.3.1" } }, "node_modules/@sinclair/typebox": { @@ -5628,9 +5636,9 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.4.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.4.4.tgz", - "integrity": "sha512-iZrWQcjRBqBHFdDXVxGpw6mHBZMCMYqhWXdyJ0d1S2y3PwcfOjkcXlQ1UiAenFHlA6dKrcYw8luKUQTL9bKReA==", + "version": "8.4.5", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.4.5.tgz", + "integrity": "sha512-MKIZ2jQO/3cUdsT57eq8jRgB6inALo9BxrQ88f7mqzltOkMvADvTAY6y8JZqTUoDzWTH/ny/8SGGdtpqlxRuiQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" @@ -6196,19 +6204,27 @@ } }, "node_modules/@testing-library/react": { - "version": "11.2.5", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.7.tgz", + "integrity": "sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^7.28.1" + "@testing-library/dom": "^10.0.0", + "@types/react-dom": "^18.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "peerDependencies": { - "react": "*", - "react-dom": "*" + "@types/react": "^18.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@testing-library/react-hooks": { @@ -6224,54 +6240,32 @@ "react-test-renderer": ">=16.9.0" } }, - "node_modules/@testing-library/react/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, "node_modules/@testing-library/react/node_modules/@testing-library/dom": { - "version": "7.31.2", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", - "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^4.2.2", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.6", - "lz-string": "^1.4.4", - "pretty-format": "^26.6.2" + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" }, "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/@testing-library/react/node_modules/@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "dev": true - }, - "node_modules/@testing-library/react/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "dequal": "^2.0.3" } }, "node_modules/@testing-library/react/node_modules/chalk": { @@ -6291,18 +6285,29 @@ } }, "node_modules/@testing-library/react/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "engines": { - "node": ">= 10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@testing-library/react/node_modules/react-is": { @@ -6739,14 +6744,23 @@ "dev": true }, "node_modules/@types/react": { - "version": "17.0.3", - "license": "MIT", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-redux": { "version": "7.1.25", "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz", @@ -6781,9 +6795,10 @@ } }, "node_modules/@types/react-test-renderer": { - "version": "17.0.1", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.3.0.tgz", + "integrity": "sha512-HW4MuEYxfDbOHQsVlY/XtOvNHftCVEPhJF2pQXXwcUiUF+Oyb0usgp48HSgpK5rt8m9KZb22yqOeZm+rrVG8gw==", "dev": true, - "license": "MIT", "dependencies": { "@types/react": "*" } @@ -6804,10 +6819,6 @@ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, - "node_modules/@types/scheduler": { - "version": "0.16.1", - "license": "MIT" - }, "node_modules/@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -6861,9 +6872,9 @@ } }, "node_modules/@types/styled-components": { - "version": "5.1.26", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", - "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", + "version": "5.1.34", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz", + "integrity": "sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==", "dev": true, "dependencies": { "@types/hoist-non-react-statics": "*", @@ -11968,6 +11979,15 @@ "deps-sort": "bin/cmd.js" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/des.js": { "version": "1.0.1", "license": "MIT", @@ -22939,12 +22959,11 @@ } }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" @@ -22973,16 +22992,15 @@ } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.3.1" } }, "node_modules/react-dropzone": { @@ -23002,15 +23020,12 @@ } }, "node_modules/react-error-boundary": { - "version": "3.1.1", - "license": "MIT", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.1.2.tgz", + "integrity": "sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==", "dependencies": { "@babel/runtime": "^7.12.5" }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, "peerDependencies": { "react": ">=16.13.1" } @@ -23219,15 +23234,15 @@ } }, "node_modules/react-shallow-renderer": { - "version": "16.14.1", - "dev": true, - "license": "MIT", + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", + "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", "dependencies": { "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0" + "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" }, "peerDependencies": { - "react": "^16.0.0 || ^17.0.0" + "react": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/react-table": { @@ -23243,23 +23258,22 @@ } }, "node_modules/react-test-renderer": { - "version": "17.0.1", - "dev": true, - "license": "MIT", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.3.1.tgz", + "integrity": "sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA==", "dependencies": { - "object-assign": "^4.1.1", - "react-is": "^17.0.1", - "react-shallow-renderer": "^16.13.1", - "scheduler": "^0.20.1" + "react-is": "^18.3.1", + "react-shallow-renderer": "^16.15.0", + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "17.0.1" + "react": "^18.3.1" } }, "node_modules/react-test-renderer/node_modules/react-is": { - "version": "17.0.1", - "dev": true, - "license": "MIT" + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/react-textarea-autosize": { "version": "8.3.2", @@ -24066,12 +24080,11 @@ } }, "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { @@ -25308,15 +25321,16 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/styled-components": { - "version": "5.2.1", - "license": "MIT", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", + "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", "dependencies": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", + "@emotion/is-prop-valid": "^1.1.0", "@emotion/stylis": "^0.8.4", "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1", + "babel-plugin-styled-components": ">= 1.12.0", "css-to-react-native": "^3.0.0", "hoist-non-react-statics": "^3.0.0", "shallowequal": "^1.1.0", @@ -25335,6 +25349,19 @@ "react-is": ">= 16.8.0" } }, + "node_modules/styled-components/node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/styled-components/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, "node_modules/styled-components/node_modules/has-flag": { "version": "3.0.0", "license": "MIT", @@ -29891,12 +29918,14 @@ }, "@emotion/is-prop-valid": { "version": "0.8.8", + "optional": true, "requires": { "@emotion/memoize": "0.7.4" } }, "@emotion/memoize": { - "version": "0.7.4" + "version": "0.7.4", + "optional": true }, "@emotion/react": { "version": "11.11.3", @@ -32152,9 +32181,9 @@ } }, "@scality/core-ui": { - "version": "0.151.0", - "resolved": "https://registry.npmjs.org/@scality/core-ui/-/core-ui-0.151.0.tgz", - "integrity": "sha512-OeAhs+uiOOBDSGqzZGpIka1iCtRrGJkjNhzdRJhJtLwxKDFU7iyPUPA3MbJ8DoGJQN0do8k3PTyei1fZEiMXJA==", + "version": "git+ssh://git@github.com/scality/core-ui.git#bf0c36da657737f47dabe310bb1a20c136877970", + "integrity": "sha512-dC/zNxvxU7DVgxhbyKHgwwVyM2CwWACrwyVbh1VP0/7KTcgTmoYR2hO9qAMi9t8yyNWidOi9AVVzKupes13wRw==", + "from": "@scality/core-ui@git+https://github.com/scality/core-ui#bf0c36da657737f47dabe310bb1a20c136877970", "requires": { "@floating-ui/dom": "^1.6.3", "@fortawesome/fontawesome-free": "^5.10.2", @@ -32168,9 +32197,9 @@ "framer-motion": "^4.1.17", "polished": "3.4.1", "pretty-bytes": "^5.6.0", - "react": "^17.0.2", + "react": "^18.3.1", "react-debounce-input": "3.2.2", - "react-dom": "^17.0.2", + "react-dom": "^18.3.1", "react-dropzone": "^14.2.3", "react-hook-form": "^7.49.2", "react-query": "^3.34.0", @@ -32178,6 +32207,7 @@ "react-router-dom": "5.2.0", "react-select": "4.3.1", "react-table": "^7.7.0", + "react-test-renderer": "^18.3.1", "react-virtualized": "9.22.3", "react-virtualized-auto-sizer": "^1.0.24", "react-window": "^1.8.6", @@ -32209,9 +32239,9 @@ } }, "@scality/module-federation": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@scality/module-federation/-/module-federation-1.3.4.tgz", - "integrity": "sha512-Okmgh+s9UTM6ropLt5QIJhswaN3m0hGNjGI2w/al+a4H+fQs5x/rAYngzWhFnHxdox0RUSRwA7aOZH1fBAvnmA==" + "version": "git+ssh://git@github.com/scality/module-federation.git#c571388783a2a51ae3bf5d36ae66753c8b014bb5", + "integrity": "sha512-lrpXm7Skkq/CtGQRI563pSelewbeNaBBbs3J4zzCiheb0H2fSs6JF6lqQHQjL9A0HRVjfnArotXlF8E8JzVtnw==", + "from": "@scality/module-federation@git+https://github.com/scality/module-federation#c571388783a2a51ae3bf5d36ae66753c8b014bb5" }, "@sinclair/typebox": { "version": "0.27.8", @@ -32246,9 +32276,9 @@ } }, "@storybook/preview-api": { - "version": "8.4.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.4.4.tgz", - "integrity": "sha512-iZrWQcjRBqBHFdDXVxGpw6mHBZMCMYqhWXdyJ0d1S2y3PwcfOjkcXlQ1UiAenFHlA6dKrcYw8luKUQTL9bKReA==" + "version": "8.4.5", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.4.5.tgz", + "integrity": "sha512-MKIZ2jQO/3cUdsT57eq8jRgB6inALo9BxrQ88f7mqzltOkMvADvTAY6y8JZqTUoDzWTH/ny/8SGGdtpqlxRuiQ==" }, "@styled-system/background": { "version": "5.1.2", @@ -32628,55 +32658,39 @@ } }, "@testing-library/react": { - "version": "11.2.5", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.7.tgz", + "integrity": "sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==", "dev": true, "requires": { "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^7.28.1" + "@testing-library/dom": "^10.0.0", + "@types/react-dom": "^18.0.0" }, "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, "@testing-library/dom": { - "version": "7.31.2", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", - "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^4.2.2", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.6", - "lz-string": "^1.4.4", - "pretty-format": "^26.6.2" + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" } }, - "@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "dev": true - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "dequal": "^2.0.3" } }, "chalk": { @@ -32690,15 +32704,22 @@ } }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, "react-is": { @@ -33104,13 +33125,23 @@ "dev": true }, "@types/react": { - "version": "17.0.3", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "requires": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, + "@types/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-redux": { "version": "7.1.25", "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz", @@ -33145,7 +33176,9 @@ } }, "@types/react-test-renderer": { - "version": "17.0.1", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.3.0.tgz", + "integrity": "sha512-HW4MuEYxfDbOHQsVlY/XtOvNHftCVEPhJF2pQXXwcUiUF+Oyb0usgp48HSgpK5rt8m9KZb22yqOeZm+rrVG8gw==", "dev": true, "requires": { "@types/react": "*" @@ -33166,9 +33199,6 @@ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, - "@types/scheduler": { - "version": "0.16.1" - }, "@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -33219,9 +33249,9 @@ } }, "@types/styled-components": { - "version": "5.1.26", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", - "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", + "version": "5.1.34", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz", + "integrity": "sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==", "dev": true, "requires": { "@types/hoist-non-react-statics": "*", @@ -36854,6 +36884,12 @@ "through2": "^2.0.0" } }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true + }, "des.js": { "version": "1.0.1", "optional": true, @@ -44850,12 +44886,11 @@ } }, "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "react-base16-styling": { @@ -44877,13 +44912,12 @@ } }, "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "requires": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" } }, "react-dropzone": { @@ -44897,7 +44931,9 @@ } }, "react-error-boundary": { - "version": "3.1.1", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.1.2.tgz", + "integrity": "sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==", "requires": { "@babel/runtime": "^7.12.5" } @@ -45026,11 +45062,12 @@ } }, "react-shallow-renderer": { - "version": "16.14.1", - "dev": true, + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", + "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", "requires": { "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0" + "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" } }, "react-table": { @@ -45039,18 +45076,19 @@ "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==" }, "react-test-renderer": { - "version": "17.0.1", - "dev": true, + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.3.1.tgz", + "integrity": "sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA==", "requires": { - "object-assign": "^4.1.1", - "react-is": "^17.0.1", - "react-shallow-renderer": "^16.13.1", - "scheduler": "^0.20.1" + "react-is": "^18.3.1", + "react-shallow-renderer": "^16.15.0", + "scheduler": "^0.23.2" }, "dependencies": { "react-is": { - "version": "17.0.1", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" } } }, @@ -45629,12 +45667,11 @@ } }, "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "schema-utils": { @@ -46592,20 +46629,35 @@ } }, "styled-components": { - "version": "5.2.1", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", + "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", + "@emotion/is-prop-valid": "^1.1.0", "@emotion/stylis": "^0.8.4", "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1", + "babel-plugin-styled-components": ">= 1.12.0", "css-to-react-native": "^3.0.0", "hoist-non-react-statics": "^3.0.0", "shallowequal": "^1.1.0", "supports-color": "^5.5.0" }, "dependencies": { + "@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "requires": { + "@emotion/memoize": "^0.9.0" + } + }, + "@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, "has-flag": { "version": "3.0.0" }, diff --git a/ui/package.json b/ui/package.json index fcdc2e4949..052a091fec 100644 --- a/ui/package.json +++ b/ui/package.json @@ -7,8 +7,8 @@ "@hookform/resolvers": "^3.1.0", "@js-temporal/polyfill": "^0.4.4", "@kubernetes/client-node": "github:scality/kubernetes-client-javascript.git#browser-0.10.4-64-ge7c6721", - "@scality/core-ui": "0.151.0", - "@scality/module-federation": "^1.3.4", + "@scality/core-ui": "git+https://github.com/scality/core-ui#bf0c36da657737f47dabe310bb1a20c136877970", + "@scality/module-federation": "git+https://github.com/scality/module-federation#c571388783a2a51ae3bf5d36ae66753c8b014bb5", "axios": "^0.21.1", "formik": "2.2.5", "jsonpath": "^1.1.1", @@ -16,9 +16,9 @@ "lodash.isequal": "^4.5.0", "lodash.sortby": "^4.7.0", "luxon": "^2.1.1", - "react": "^17.0.1", - "react-dom": "^17.0.1", - "react-error-boundary": "^3.1.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-error-boundary": "^4.1.2", "react-hook-form": "^7.44.3", "react-intl": "^5.15.3", "react-json-view": "^1.21.3", @@ -29,7 +29,7 @@ "redux": "^4.0.1", "redux-saga": "^1.0.2", "reselect": "^2.5.4", - "styled-components": "^5.0.1", + "styled-components": "^5.3.11", "uuid": "3.3.2", "yup": "^0.32.9" }, @@ -78,7 +78,7 @@ "@rspack/core": "^0.7.5", "@testing-library/dom": "^9.3.1", "@testing-library/jest-dom": "^5.11.9", - "@testing-library/react": "^11.2.3", + "@testing-library/react": "^15.0.7", "@testing-library/react-hooks": "^3.4.2", "@testing-library/user-event": "^14.4.3", "@types/hapi__joi": "^17.1.9", @@ -86,10 +86,13 @@ "@types/lodash.isempty": "^4.4.7", "@types/lodash.isequal": "^4.5.6", "@types/lodash.sortby": "^4.7.7", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", "@types/react-redux": "^7.1.25", "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", - "@types/styled-components": "^5.1.26", + "@types/react-test-renderer": "^18.3.0", + "@types/styled-components": "^5.1.34", "@typescript-eslint/eslint-plugin": "^5.62.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.3", @@ -112,7 +115,7 @@ "jest-preview": "^0.3.1", "msw": "0.36.8", "oidc-client": "^1.8.0", - "react-test-renderer": "^17.0.1", + "react-test-renderer": "^18.3.1", "ts-node": "^10.9.2", "typescript": "^5.3.3" }, diff --git a/ui/src/FederableApp.tsx b/ui/src/FederableApp.tsx index 43a6b68b1c..60003f3fb9 100644 --- a/ui/src/FederableApp.tsx +++ b/ui/src/FederableApp.tsx @@ -16,6 +16,7 @@ import { setHistory as setReduxHistory } from './ducks/history'; import { setApiConfigAction } from './ducks/config'; import { authErrorAction } from './ducks/app/authError'; import { AuthError } from './services/errorhandler'; +import { ShellHooksProvider, useShellHooks } from './ShellHooksContext'; const composeEnhancers = // @ts-expect-error - FIXME when you are working on it typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ @@ -87,7 +88,8 @@ type Config = { }; export const useConfig = () => { const { name } = useCurrentApp(); - const runtimeConfiguration = window.shellHooks.useConfig({ + const { useConfig } = useShellHooks(); + const runtimeConfiguration = useConfig({ configType: 'run', name, }); @@ -131,16 +133,21 @@ export const AppConfigProvider = ({ ); }; -export default function FederableApp() { +export default function FederableApp(props) { return ( - - - - - - - - - + + + + + + + + + + + ); } diff --git a/ui/src/ShellHooksContext.tsx b/ui/src/ShellHooksContext.tsx new file mode 100644 index 0000000000..13e72f3f0e --- /dev/null +++ b/ui/src/ShellHooksContext.tsx @@ -0,0 +1,99 @@ +import { FC, ReactNode, useMemo, useSyncExternalStore } from 'react'; +import { ShellTypes } from '../@mf-types/shell/compiled-types/src/FederatedApp'; + +export type ShellHooks = ShellTypes['shellHooks']; +export type ShellAlerts = ShellTypes['shellAlerts']; + +type Listener = () => void; + +const createShellHooksStore = () => { + let shellHooks: ShellHooks | null = null; + + const listeners: Set = new Set(); + + return { + getShellHooks: () => shellHooks, + + subscribe: (listener: Listener) => { + listeners.add(listener); + return () => { + listeners.delete(listener); + }; + }, + + setShellHooks: (newHooks: ShellHooks) => { + if (shellHooks !== newHooks) { + shellHooks = newHooks; + listeners.forEach((listener) => listener()); + } + }, + }; +}; + +const createShellAlertsStore = () => { + let shellAlerts: ShellAlerts | null = null; + const listeners: Set = new Set(); + + return { + getShellAlerts: () => shellAlerts, + + subscribe: (listener: Listener) => { + listeners.add(listener); + return () => { + listeners.delete(listener); + }; + }, + + setShellAlerts: (newAlerts: ShellAlerts) => { + if (shellAlerts !== newAlerts) { + shellAlerts = newAlerts; + listeners.forEach((listener) => listener()); + } + }, + }; +}; + +export const shellHooksStore = createShellHooksStore(); +export const shellAlertsStore = createShellAlertsStore(); + +export const useShellHooks = (): ShellHooks => { + const hooks = useSyncExternalStore( + shellHooksStore.subscribe, + shellHooksStore.getShellHooks, + ); + + if (!hooks) { + throw new Error( + 'useShellHooks must be used within a ShellHooksProvider and initialized with valid hooks.', + ); + } + + return hooks; +}; + +export const useShellAlerts = (): ShellAlerts => { + const alerts = useSyncExternalStore( + shellAlertsStore.subscribe, + shellAlertsStore.getShellAlerts, + ); + + if (!alerts) { + throw new Error( + 'useShellAlerts must be used within a ShellHooksProvider and initialized with valid alerts.', + ); + } + + return alerts; +}; + +export const ShellHooksProvider: FC<{ + shellHooks: ShellHooks; + shellAlerts: ShellAlerts; + children: ReactNode; +}> = ({ shellHooks, shellAlerts, children }) => { + useMemo(() => { + shellHooksStore.setShellHooks(shellHooks); + shellAlertsStore.setShellAlerts(shellAlerts); + }, [shellHooks, shellAlerts]); + return <>{children}; +}; diff --git a/ui/src/components/DashboardInventory.tsx b/ui/src/components/DashboardInventory.tsx index 5b6a585053..d0e70a582f 100644 --- a/ui/src/components/DashboardInventory.tsx +++ b/ui/src/components/DashboardInventory.tsx @@ -73,6 +73,7 @@ const DashboardInventory = () => { getNodesCountQuery(config || '', getToken), ); const history = useHistory(); + return ( @@ -108,7 +109,7 @@ const DashboardInventory = () => { - {nodesCount} + {nodesCount as number} @@ -143,7 +144,7 @@ const DashboardInventory = () => { - {volumesCount} + {volumesCount as number} diff --git a/ui/src/containers/AlertProvider.tsx b/ui/src/containers/AlertProvider.tsx index 8893a8227d..940edabd2e 100644 --- a/ui/src/containers/AlertProvider.tsx +++ b/ui/src/containers/AlertProvider.tsx @@ -1,20 +1,24 @@ import React from 'react'; -import type { FilterLabels, Alert } from '../services/alertUtils'; +import { QueryObserverResult } from 'react-query'; import { STATUS_HEALTH } from '../constants'; import { useConfig } from '../FederableApp'; -import { QueryObserverResult } from 'react-query'; +import type { Alert, FilterLabels } from '../services/alertUtils'; +import { useShellAlerts } from '../ShellHooksContext'; export type Status = 'healthy' | 'warning' | 'critical'; export const useAlerts = ( - filters: FilterLabels, + filters?: FilterLabels, ): Omit, 'data'> & { alerts?: Alert[] } => { - return window.shellAlerts.hooks.useAlerts(filters); + const { hooks } = useShellAlerts(); + return hooks.useAlerts(filters); }; export const useHighestSeverityAlerts = (filters: FilterLabels) => { - return window.shellAlerts.hooks.useHighestSeverityAlerts(filters); + const { hooks } = useShellAlerts(); + return hooks.useHighestSeverityAlerts(filters); }; export const useAlertLibrary = () => { - return window.shellAlerts.alertSelectors; + const { alertSelectors } = useShellAlerts(); + return alertSelectors; }; export const highestAlertToStatus = (alerts?: Alert[]): Status => { @@ -34,10 +38,11 @@ export const highestAlertToStatus = (alerts?: Alert[]): Status => { const AlertProvider = ({ children }: { children: React.ReactNode }) => { const { url_alertmanager } = useConfig(); + const alerts = useShellAlerts(); return ( - + {children} - + ); }; diff --git a/ui/src/containers/ConfigProvider.tsx b/ui/src/containers/ConfigProvider.tsx index 919fbf24d4..9cdab20c42 100644 --- a/ui/src/containers/ConfigProvider.tsx +++ b/ui/src/containers/ConfigProvider.tsx @@ -1,6 +1,10 @@ +import { useShellHooks } from '../ShellHooksContext'; + export function useLinkOpener() { - return window.shellHooks.useLinkOpener(); + const { useLinkOpener } = useShellHooks(); + return useLinkOpener(); } export function useDiscoveredViews() { - return window.shellHooks.useDiscoveredViews(); + const { useDiscoveredViews } = useShellHooks(); + return useDiscoveredViews(); } diff --git a/ui/src/containers/IntlProvider.tsx b/ui/src/containers/IntlProvider.tsx index d682b801ef..0bb19af5b0 100644 --- a/ui/src/containers/IntlProvider.tsx +++ b/ui/src/containers/IntlProvider.tsx @@ -2,13 +2,15 @@ import React from 'react'; import { IntlProvider } from 'react-intl'; import translations_en from '../translations/en.json'; import translations_fr from '../translations/fr.json'; +import { useShellHooks } from '../ShellHooksContext'; const messages = { EN: translations_en, FR: translations_fr, }; const FederatedIntlProvider = ({ children }: { children: React.ReactNode }) => { - const { language } = window.shellHooks.useLanguage(); + const { useLanguage } = useShellHooks(); + const { language } = useLanguage(); return ( {children} diff --git a/ui/src/containers/NodePage.tsx b/ui/src/containers/NodePage.tsx index c4728a2d16..da7df13dab 100644 --- a/ui/src/containers/NodePage.tsx +++ b/ui/src/containers/NodePage.tsx @@ -10,7 +10,6 @@ import { useTypedSelector } from '../hooks'; const NodePage = (props) => { useRefreshEffect(refreshNodesAction, stopRefreshNodesAction); - // @ts-expect-error - FIXME when you are working on it const { alerts } = useAlerts(); const theme = useTheme(); const nodeTableData = useSelector( diff --git a/ui/src/containers/PrivateRoute.tsx b/ui/src/containers/PrivateRoute.tsx index 5bf1939d4e..03207264da 100644 --- a/ui/src/containers/PrivateRoute.tsx +++ b/ui/src/containers/PrivateRoute.tsx @@ -11,13 +11,16 @@ import { useUserAccessRight, useUserRoles, } from '../hooks'; +import { useShellHooks } from '../ShellHooksContext'; export const useAuth = () => { - return window.shellHooks.useAuth(); + const { useAuth } = useShellHooks(); + return useAuth(); }; export const useShellConfig = () => { - return window.shellHooks.useShellConfig(); + const { useShellConfig } = useShellHooks(); + return useShellConfig(); }; const AccessRouteGuard = ({ component, ...rest }) => { @@ -39,7 +42,8 @@ const PrivateRoute = ({ component, ...rest }: PrivateRouteProps) => { (left, right) => left.isAuthError === right.isAuthError, ); const url_support = api?.url_support; - const { userData } = window.shellHooks.useAuth(); + const { useAuth } = useShellHooks(); + const { userData } = useAuth(); const dispatch = useDispatch(); const history = useHistory(); diff --git a/ui/src/hooks.tsx b/ui/src/hooks.tsx index cb63d88e7e..c810c21681 100644 --- a/ui/src/hooks.tsx +++ b/ui/src/hooks.tsx @@ -115,7 +115,6 @@ export const MetricsTimeSpanProvider = ({ ); }; export const useVolumesWithAlerts = (nodeName?: string) => { - // @ts-expect-error - FIXME when you are working on it const { alerts } = useAlerts(); const volumeListData = useTypedSelector((state) => // @ts-expect-error - FIXME when you are working on it