diff --git a/.github/actions/bastion-ui-tests/action.yaml b/.github/actions/bastion-ui-tests/action.yaml index 9d500a28d4..bb106200fc 100644 --- a/.github/actions/bastion-ui-tests/action.yaml +++ b/.github/actions/bastion-ui-tests/action.yaml @@ -5,7 +5,7 @@ inputs: TEST_FILTERS: description: "The test filter to use" required: false - default: "e2e" + default: "integration" TARGET_URL: description: "The URL to reach the UI" required: false diff --git a/.github/workflows/pre-merge.yaml b/.github/workflows/pre-merge.yaml index 1730ae3ace..863354df32 100644 --- a/.github/workflows/pre-merge.yaml +++ b/.github/workflows/pre-merge.yaml @@ -420,7 +420,7 @@ jobs: tags: ghcr.io/${{ github.repository_owner }}/metalk8s-nginx-integration-tests:${{ github.sha }} integration_tests_ui: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04-8core needs: - build_integration_container_nginx - changed-files @@ -456,7 +456,7 @@ jobs: - name: Install Cypress and its dependencies run: | cd ui - PKGS="har-validator cypress cypress-cucumber-preprocessor cypress-wait-until @testing-library/cypress" + PKGS="har-validator cypress cypress-wait-until @testing-library/cypress querystring" for pkg in $PKGS; do npm install --no-save --no-package-lock --legacy-peer-deps $pkg@$(node -p \ -e "require('./package-lock.json').dependencies['$pkg'].version" \ diff --git a/buildchain/buildchain/versions.py b/buildchain/buildchain/versions.py index a8b5d1df27..a1e95d00c9 100644 --- a/buildchain/buildchain/versions.py +++ b/buildchain/buildchain/versions.py @@ -83,7 +83,7 @@ def load_version_information() -> None: ETCD_VERSION: str = "3.5.15" ETCD_IMAGE_VERSION: str = f"{ETCD_VERSION}-0" NGINX_IMAGE_VERSION: str = "1.27.2-alpine" -NODEJS_IMAGE_VERSION: str = "16.14.0" +NODEJS_IMAGE_VERSION: str = "20.11.1" KEEPALIVED_VERSION: str = "2.3.1" CERT_MANAGER_VERSION: str = "1.16.1" diff --git a/shell-ui/package-lock.json b/shell-ui/package-lock.json index 77a68577ca..b46e2ff0d1 100644 --- a/shell-ui/package-lock.json +++ b/shell-ui/package-lock.json @@ -8,20 +8,21 @@ "name": "shell-ui", "version": "1.0.0", "dependencies": { - "@scality/core-ui": "0.151.0", - "@scality/module-federation": "^1.3.4", + "@scality/core-ui": "0.155.0", + "@scality/module-federation": "^1.4.0", "downshift": "^8.0.0", + "history": "^5.3.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", + "react-query": "^3.34.0", + "react-router": "^7.0.1", + "react-router-dom": "^7.0.1", + "styled-components": "^5.3.11", "typescript": "^5.6.3" }, "devDependencies": { @@ -35,14 +36,16 @@ "@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/history": "^5.0.0", + "@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 +55,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 +1867,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 +2033,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 +2041,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": { @@ -2146,6 +2134,32 @@ "@floating-ui/utils": "^0.2.8" } }, + "node_modules/@floating-ui/react": { + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@floating-ui/utils": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", @@ -4174,11 +4188,12 @@ } }, "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==", + "version": "0.155.0", + "resolved": "https://registry.npmjs.org/@scality/core-ui/-/core-ui-0.155.0.tgz", + "integrity": "sha512-XvkkdOkC2rDX5hAAGtSuLPwmJn+FKg4PmKn9gL8K6CaPyNTpo1y8Itjn96GTdFSvL0McuSwCWJoR3BgGDYVmdQ==", "dependencies": { "@floating-ui/dom": "^1.6.3", + "@floating-ui/react": "^0.26.28", "@fortawesome/fontawesome-free": "^5.10.2", "@fortawesome/fontawesome-svg-core": "^1.2.35", "@fortawesome/free-regular-svg-icons": "^5.15.3", @@ -4190,16 +4205,17 @@ "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", - "react-router": "5.2.0", - "react-router-dom": "5.2.0", + "react-router": "7.0.1", + "react-router-dom": "7.0.1", "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", @@ -4237,12 +4253,15 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "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==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scality/module-federation/-/module-federation-1.4.0.tgz", + "integrity": "sha512-oG2ga13gsW3HPj9rxWgMApj0HC2zAmzW1+vVHtXCOKCGRNfHPyyAXjVOAAfyF87915PE4XLyZt5XGI5dB3nEig==", + "dependencies": { + "react-router": "^7.0.1" + }, "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 +4309,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 +4717,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 +4786,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 +4854,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 +4962,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 +4974,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": "*", @@ -5070,10 +5021,14 @@ } }, "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/history/-/history-5.0.0.tgz", + "integrity": "sha512-hy8b7Y1J8OGe6LbAjj3xniQrj3v6lsivCcrmf4TzSgPzLkhIeKgc5IZnT7ReIqmEuodjfO8EYAuoFvIrHi/+jQ==", + "deprecated": "This is a stub types definition. history provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "history": "*" + } }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.5", @@ -5188,12 +5143,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 +5171,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": { @@ -5273,6 +5221,18 @@ "@types/react-router": "*" } }, + "node_modules/@types/react-router-dom/node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "dev": true + }, + "node_modules/@types/react-router/node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "dev": true + }, "node_modules/@types/react-test-renderer": { "version": "18.3.0", "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.3.0.tgz", @@ -5288,11 +5248,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 +5258,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 +5274,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 +7135,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 +8739,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 +9302,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", @@ -9519,16 +9459,11 @@ "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" }, "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" + "@babel/runtime": "^7.7.6" } }, "node_modules/hoist-non-react-statics": { @@ -12898,9 +12833,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" }, @@ -13459,20 +13393,6 @@ "node": ">=4" } }, - "node_modules/mini-create-react-context": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", - "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dependencies": { - "@babel/runtime": "^7.12.1", - "tiny-warning": "^1.0.3" - }, - "peerDependencies": { - "prop-types": "^15.0.0", - "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -14670,12 +14590,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 +14613,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": { @@ -14822,60 +14740,56 @@ } }, "node_modules/react-router": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", - "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", - "dependencies": { - "@babel/runtime": "^7.1.2", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "mini-create-react-context": "^0.4.0", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.0.1.tgz", + "integrity": "sha512-WVAhv9oWCNsja5AkK6KLpXJDSJCQizOIyOd4vvB/+eHGbYx5vkhcmcmwWjQ9yqkRClogi+xjEg9fNEOd5EX/tw==", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + }, + "engines": { + "node": ">=20.0.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } } }, "node_modules/react-router-dom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", - "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.0.1.tgz", + "integrity": "sha512-duBzwAAiIabhFPZfDjcYpJ+f08TMbPMETgq254GWne2NW1ZwRHhZLj7tpSp8KGb7JvZzlLcjGUnqLxpZQVEPng==", "dependencies": { - "@babel/runtime": "^7.1.2", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.2.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "react-router": "7.0.1" + }, + "engines": { + "node": ">=20.0.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=18", + "react-dom": ">=18" } }, - "node_modules/react-router/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + "node_modules/react-router/node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" }, - "node_modules/react-router/node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "dependencies": { - "isarray": "0.0.1" + "node_modules/react-router/node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "engines": { + "node": ">=18" } }, - "node_modules/react-router/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, "node_modules/react-select": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz", @@ -14898,7 +14812,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" @@ -14920,26 +14833,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", @@ -15262,11 +15167,6 @@ "node": ">=8" } }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, "node_modules/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -15730,12 +15630,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": { @@ -15939,8 +15838,7 @@ "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", - "dev": true + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" }, "node_modules/set-function-length": { "version": "1.2.2", @@ -16037,9 +15935,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", @@ -16739,6 +16637,11 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -16898,16 +16801,6 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -17111,6 +17004,11 @@ "node": ">=0.6.x" } }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" + }, "node_modules/type-detect": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", @@ -17248,10 +17146,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" } @@ -17466,9 +17363,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", @@ -17508,11 +17404,6 @@ "node": ">=10.12.0" } }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/shell-ui/package.json b/shell-ui/package.json index 2afc559466..91f3899da2 100644 --- a/shell-ui/package.json +++ b/shell-ui/package.json @@ -22,14 +22,16 @@ "@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/history": "^5.0.0", + "@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 +41,25 @@ "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": "0.155.0", + "@scality/module-federation": "^1.4.0", "downshift": "^8.0.0", + "history": "^5.3.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", + "react-query": "^3.34.0", + "react-router": "^7.0.1", + "react-router-dom": "^7.0.1", + "styled-components": "^5.3.11", "typescript": "^5.6.3" } } diff --git a/shell-ui/src/FederatedApp.spec.tsx b/shell-ui/src/FederatedApp.spec.tsx index 27391a74b3..7f6403ab98 100644 --- a/shell-ui/src/FederatedApp.spec.tsx +++ b/shell-ui/src/FederatedApp.spec.tsx @@ -1,10 +1,11 @@ -import { setupServer } from 'msw/node'; -import { rest } from 'msw'; -import { screen, render, within, waitFor } from '@testing-library/react'; -import './navbar/index'; -import { waitForLoadingToFinish } from './navbar/__TESTS__/utils'; import { jest } from '@jest/globals'; +import { render, screen, waitFor, within } from '@testing-library/react'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; import App, { queryClient } from './FederatedApp'; +import { waitForLoadingToFinish } from './navbar/__TESTS__/utils'; +import './navbar/index'; + export const configurationHandlers = [ rest.get( 'http://localhost:3000/.well-known/micro-app-configuration', @@ -245,11 +246,20 @@ describe('FederatedApp', () => { expect(screen.getByRole('navigation')).toBeInTheDocument(), ); //V - const navbar = screen.getByRole('navigation'); + let navbar = screen.getByRole('navigation'); expect(navbar).toBeInTheDocument(); - await waitFor(() => - expect(within(navbar).getByText(/Platform/i)).toBeInTheDocument(), + + await waitFor( + () => { + navbar = screen.getByRole('navigation'); + + return expect( + within(navbar).getByText(/Platform/i), + ).toBeInTheDocument(); + }, + { timeout: 5000 }, ); + expect(within(navbar).getByText(/Platform/i)).toBeInTheDocument(); expect(within(navbar).getByText(/Alerts/i)).toBeInTheDocument(); }); diff --git a/shell-ui/src/FederatedApp.tsx b/shell-ui/src/FederatedApp.tsx index cae930c6ab..ef819f23ac 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 { @@ -7,66 +8,40 @@ import { FederatedComponentProps, SolutionUI, } from '@scality/module-federation'; -import { createBrowserHistory } from 'history'; 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 { QueryClient } from 'react-query'; +import { BrowserRouter, Route, Routes } from 'react-router-dom'; -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'; +import { QueryClientProvider } from './QueryClientProvider'; /** * 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({ @@ -255,6 +149,7 @@ function ProtectedFederatedRoute({ function InternalRouter() { const discoveredViews = useDiscoveredViews(); const { retrieveConfiguration } = useConfigRetriever(); + const routes = useMemo( () => ( @@ -284,55 +179,43 @@ function InternalRouter() { .map(({ app, view, groups }) => ({ path: app.appHistoryBasePath + view.path, + basename: app.appHistoryBasePath, exact: view.exact, strict: view.strict, sensitive: view.sensitive, - component: () => { - const federatedAppHistory = useMemo( - () => - createBrowserHistory({ - basename: app.appHistoryBasePath, - }), - [], - ); - return ( - - ({ - configType: 'build', - name: app.name, - })?.spec.remoteEntryPath - } - module={view.module} - scope={view.scope} - app={app} - groups={groups} - /> - - ); - }, + element: ( + ({ + configType: 'build', + name: app.name, + })?.spec.remoteEntryPath + } + module={view.module} + scope={view.scope} + app={app} + groups={groups} + /> + ), })), [JSON.stringify(discoveredViews)], ); + return ( - <> - - {routes.map((route) => ( - - ))} - - + + {routes.map((route) => ( + + ))} + ); } function InternalApp() { - const history = useMemo(() => { - const history = createBrowserHistory({}); - return history; - }, []); - const { status } = useQuery({ queryKey: ['load-share-deps'], queryFn: async () => { @@ -349,7 +232,7 @@ function InternalApp() { }); return ( - + @@ -365,7 +248,7 @@ function InternalApp() { - + ); } 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/QueryClientProvider.tsx b/shell-ui/src/QueryClientProvider.tsx new file mode 100644 index 0000000000..915ba3a36c --- /dev/null +++ b/shell-ui/src/QueryClientProvider.tsx @@ -0,0 +1,11 @@ +import { + QueryClient, + QueryClientProvider as BaseQueryClientProvider, +} from 'react-query'; + +export const QueryClientProvider = + BaseQueryClientProvider as React.ComponentType<{ + client: QueryClient; + contextSharing?: boolean; + children?: React.ReactNode; + }>; diff --git a/shell-ui/src/alerts/Alerts.spec.tsx b/shell-ui/src/alerts/Alerts.spec.tsx index d39000c011..48af353ca4 100644 --- a/shell-ui/src/alerts/Alerts.spec.tsx +++ b/shell-ui/src/alerts/Alerts.spec.tsx @@ -2,7 +2,7 @@ import './index'; import packageJson from '../../package.json'; const { version } = packageJson; import { render } from '@testing-library/react'; -import { QueryClientProvider, QueryClient } from 'react-query'; +import { QueryClient } from 'react-query'; import { renderHook } from '@testing-library/react-hooks'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; @@ -11,6 +11,7 @@ import { createContext, useContext } from 'react'; import { useQuery } from 'react-query'; import AlertProvider from './AlertProvider'; import { useAlerts } from './alertHooks'; +import { QueryClientProvider } from '../QueryClientProvider'; const testService = 'http://10.0.0.1/api/alertmanager'; const alerts = [ { @@ -135,7 +136,6 @@ describe('alerts', () => { ); //E - // @ts-expect-error - FIXME when you are working on it const { result, waitForNextUpdate } = renderHook(() => useAlerts(), { wrapper, }); 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.test.tsx b/shell-ui/src/alerts/alertHooks.test.tsx index 3bf3ed5587..45f81611a4 100644 --- a/shell-ui/src/alerts/alertHooks.test.tsx +++ b/shell-ui/src/alerts/alertHooks.test.tsx @@ -2,10 +2,11 @@ import React from 'react'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { renderHook } from '@testing-library/react-hooks'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient } from 'react-query'; import AlertProvider from './AlertProvider'; import { useHighestSeverityAlerts } from './alertHooks'; import { afterAll, beforeAll, jest } from '@jest/globals'; +import { QueryClientProvider } from '../QueryClientProvider'; const testService = 'http://10.0.0.1/api/alertmanager'; const VOLUME_DEGRADED_ALERT = { diff --git a/shell-ui/src/alerts/alertHooks.ts b/shell-ui/src/alerts/alertHooks.ts index 8393d6dd4d..0790969b15 100644 --- a/shell-ui/src/alerts/alertHooks.ts +++ b/shell-ui/src/alerts/alertHooks.ts @@ -90,16 +90,14 @@ 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) { throw new Error( 'The useAlerts hook can only be used within AlertProvider.', ); - // @ts-expect-error - FIXME when you are working on it } else if (query.status === 'success') { - // @ts-expect-error - FIXME when you are working on it const newQuery = { ...query, alerts: filterAlerts(query.data, filters) }; delete newQuery.data; return newQuery; diff --git a/shell-ui/src/auth/useFirstTimeLogin.spec.tsx b/shell-ui/src/auth/useFirstTimeLogin.spec.tsx index f918b33d18..9ea7286ef8 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,28 +29,21 @@ 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 () => { //E - const { waitForNextUpdate: waitForNextUpdateFirstRender } = renderHook( - () => useFirstTimeLogin(), - { wrapper }, - ); - await waitForNextUpdateFirstRender(); - const { result, waitForNextUpdate } = renderHook( - () => useFirstTimeLogin(), - { wrapper }, - ); - await waitForNextUpdate(); + renderHook(() => useFirstTimeLogin(), { wrapper }); + const { result } = renderHook(() => useFirstTimeLogin(), { wrapper }); + + await waitFor(() => { + expect(result.current.firstTimeLogin).toBeDefined(); + }); //V expect(result.current.firstTimeLogin).toEqual(false); }); diff --git a/shell-ui/src/hooks/useShellHooks.ts b/shell-ui/src/hooks/useShellHooks.ts new file mode 100644 index 0000000000..d2e79555a4 --- /dev/null +++ b/shell-ui/src/hooks/useShellHooks.ts @@ -0,0 +1,105 @@ +import { useNotificationCenter } from '../useNotificationCenter'; +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; + useNotificationCenter: typeof useNotificationCenter; +}; + +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, + useNotificationCenter, +}; + +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..fadaf605fe 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(); @@ -249,7 +301,7 @@ export function useDiscoveredViews(): ViewDefinition[] { return discoveredViews; } export const useLinkOpener = () => { - const history = useShellHistory(); + const navigate = useShellHistory(); return { openLink: ( to: @@ -273,7 +325,7 @@ export const useLinkOpener = () => { window.open(to.url, '_blank'); } } else if (to.isFederated) { - history.push(to.app.appHistoryBasePath + to.view.path); + navigate(to.app.appHistoryBasePath + to.view.path); } else { // @ts-expect-error - FIXME when you are working on it window.location.href = to.url; @@ -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..f37ae58754 100644 --- a/shell-ui/src/initFederation/ShellHistoryProvider.tsx +++ b/shell-ui/src/initFederation/ShellHistoryProvider.tsx @@ -1,22 +1,12 @@ import { createContext, useContext } from 'react'; -import { useHistory } from 'react-router'; +import { useNavigate } from 'react-router'; const ShellHistoryContext = createContext + typeof useNavigate > | 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( @@ -27,10 +17,10 @@ export const useShellHistory = () => { return contextValue; }; export const ShellHistoryProvider = ({ children }) => { - const history = useHistory(); + const history = useNavigate(); 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.spec.tsx b/shell-ui/src/initFederation/UIListProvider.spec.tsx index 3e35202098..dd509e41a5 100644 --- a/shell-ui/src/initFederation/UIListProvider.spec.tsx +++ b/shell-ui/src/initFederation/UIListProvider.spec.tsx @@ -1,8 +1,9 @@ import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { renderHook } from '@testing-library/react-hooks'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient } from 'react-query'; import { UIListProvider, useDeployedApps } from './UIListProvider'; +import { QueryClientProvider } from '../QueryClientProvider'; const testService = 'http://10.0.0.1/uilist.json'; const testLocalUI = { kind: 'test-ui', @@ -124,4 +125,4 @@ describe('useDeployedApps', () => { afterAll(() => { server.close(); }); -}); \ No newline at end of file +}); 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/InstanceName.spec.tsx b/shell-ui/src/navbar/InstanceName.spec.tsx index 0137d1f842..11b0610b08 100644 --- a/shell-ui/src/navbar/InstanceName.spec.tsx +++ b/shell-ui/src/navbar/InstanceName.spec.tsx @@ -9,9 +9,10 @@ import { } from '@testing-library/react'; import { jest } from '@jest/globals'; import userEvent from '@testing-library/user-event'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient } from 'react-query'; import { ToastProvider } from '@scality/core-ui/dist/components/toast/ToastProvider'; import { UserData } from '../auth/AuthProvider'; +import { QueryClientProvider } from '../QueryClientProvider'; jest.mock('../initFederation/ConfigurationProviders', () => ({ useConfigRetriever: () => ({ diff --git a/shell-ui/src/navbar/NavBar.tsx b/shell-ui/src/navbar/NavBar.tsx index 2dad490330..0b21d7a4a6 100644 --- a/shell-ui/src/navbar/NavBar.tsx +++ b/shell-ui/src/navbar/NavBar.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useMemo } from 'react'; -import { RouteProps, matchPath, useHistory } from 'react-router'; +import { RouteProps, matchPath, useNavigate } from 'react-router'; import { useLocation } from 'react-router-dom'; import styled, { createGlobalStyle } from 'styled-components'; @@ -155,7 +155,7 @@ export const useNavbarLinksToActions = ( const location = useLocation(); const doesRouteMatch = useCallback( (path: RouteProps) => { - return matchPath(location.pathname, path); + return matchPath(path.path + '*', location.pathname); }, [location], ); @@ -188,9 +188,6 @@ export const useNavbarLinksToActions = ( 'i', ).toString() : link.view.app.appHistoryBasePath + link.view.view.path, - exact: link.view.view.exact, - strict: link.view.view.strict, - sensitive: link.view.view.sensitive, }) : normalizePath((link.view as NonFederatedView).url) === window.location.origin + window.location.pathname, @@ -261,7 +258,7 @@ export const Navbar = ({ const { openLink } = useLinkOpener(); const { logOut } = useLogOut(); const { getLinks } = useNavbar(); - const history = useHistory(); + const navigate = useNavigate(); const navbarLinks = useMemo(() => getLinks(), [getLinks]); const navbarMainActions = useNavbarLinksToActions(navbarLinks.main); const navbarSecondaryActions = useNavbarLinksToActions(navbarLinks.secondary); @@ -303,7 +300,8 @@ export const Navbar = ({ const url = link.view.isFederated ? link.view.app.appHistoryBasePath + link.view.view.path : (link.view as NonFederatedView).url; - history.replace(url); + + navigate(url, { replace: true }); } }, [navbarMainActions]); diff --git a/shell-ui/src/navbar/NotificationCenter.spec.tsx b/shell-ui/src/navbar/NotificationCenter.spec.tsx index 5b4d385399..12aff93045 100644 --- a/shell-ui/src/navbar/NotificationCenter.spec.tsx +++ b/shell-ui/src/navbar/NotificationCenter.spec.tsx @@ -6,11 +6,12 @@ import NotificationCenterProvider, { } from '../NotificationCenterProvider'; import NotificationCenter from './NotificationCenter'; import userEvent from '@testing-library/user-event'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient } from 'react-query'; import { prepareRenderMultipleHooks } from './__TESTS__/testMultipleHooks'; -import { MemoryRouter, Route, Switch } from 'react-router-dom'; +import { MemoryRouter, Route, Routes } from 'react-router-dom'; import { ShellHistoryProvider } from '../initFederation/ShellHistoryProvider'; import { useNotificationCenter } from '../useNotificationCenter'; +import { QueryClientProvider } from '../QueryClientProvider'; export const notificationCenterSelectors = { notificationCenterButton: () => @@ -24,6 +25,7 @@ export const notificationCenterSelectors = { notificationCenterComboBox: () => screen.getByRole('combobox', { name: /notification center/i }), }; + describe('NotificationCenter', () => { const wrapper = ({ children }: PropsWithChildren>) => { return ( @@ -33,14 +35,12 @@ describe('NotificationCenter', () => {
{children}
- - - Home page - - Alert page - License page - New version page - + + Home page} /> + Alert page} /> + License page} /> + New version page} /> +
diff --git a/shell-ui/src/navbar/NotificationCenter.tsx b/shell-ui/src/navbar/NotificationCenter.tsx index dfc5e033fc..36d0ecb336 100644 --- a/shell-ui/src/navbar/NotificationCenter.tsx +++ b/shell-ui/src/navbar/NotificationCenter.tsx @@ -103,14 +103,14 @@ const NotificationCenter = () => { if (!selectedItem) { return; } - history.push(selectedItem.redirectUrl); + navigate(selectedItem.redirectUrl); readAllNotifications(); }, }); const isAtLeastOneNotificationUnread = notifications.some( (notification) => !notification.readOn, ); - const history = useShellHistory(); + const navigate = useShellHistory(); return (
( key: string, @@ -24,7 +24,9 @@ export type RenderAdditionalHook = ( }; export function prepareRenderMultipleHooks(options: { - wrapper: FunctionComponent>>; + wrapper: FunctionComponent< + React.PropsWithChildren>> + >; }): { renderAdditionalHook: RenderAdditionalHook; waitForWrapperToBeReady: () => Promise; diff --git a/shell-ui/src/navbar/index.spec.tsx b/shell-ui/src/navbar/index.spec.tsx index 812fead4ca..0fa12aa77e 100644 --- a/shell-ui/src/navbar/index.spec.tsx +++ b/shell-ui/src/navbar/index.spec.tsx @@ -2,12 +2,11 @@ import { CoreUiThemeProvider } from '@scality/core-ui/dist/components/coreuithem import { renderHook } from '@testing-library/react-hooks'; import { setupServer } from 'msw/node'; import React from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient } 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'; @@ -19,6 +18,7 @@ import { ShellThemeSelectorProvider } from '../initFederation/ShellThemeSelector import { waitForLoadingToFinish } from './__TESTS__/utils'; import { LanguageProvider } from './lang'; import { useNavbar } from './navbarHooks'; +import { QueryClientProvider } from '../QueryClientProvider'; const queryClient = new QueryClient({ defaultOptions: { @@ -128,77 +128,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/shell-ui/src/navbar/navbarHooks.ts b/shell-ui/src/navbar/navbarHooks.ts index a1a86305d4..f30556fecc 100644 --- a/shell-ui/src/navbar/navbarHooks.ts +++ b/shell-ui/src/navbar/navbarHooks.ts @@ -27,6 +27,5 @@ export const useNavbar = (): Navbar => { throw new Error("Can't use useNavbar outside of NavbarConfigProvider"); } - // @ts-expect-error - FIXME when you are working on it return navbar; }; diff --git a/shell-ui/src/platform/service/k8s.spec.tsx b/shell-ui/src/platform/service/k8s.spec.tsx index c5bbb421aa..eb735aa911 100644 --- a/shell-ui/src/platform/service/k8s.spec.tsx +++ b/shell-ui/src/platform/service/k8s.spec.tsx @@ -2,9 +2,10 @@ import { afterAll, beforeAll, jest } from '@jest/globals'; import { renderHook } from '@testing-library/react-hooks'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { QueryClient, QueryClientProvider, useQuery } from 'react-query'; +import { QueryClient, useQuery } from 'react-query'; import '../library'; import { getNodesCountQuery, getVolumesCountQuery } from './k8s'; +import { QueryClientProvider } from '../../QueryClientProvider'; const k8sUrl = 'https://10.0.0.1:8443/api/kubernetes'; const nodes = { kind: 'NodeList', diff --git a/shell-ui/src/setupTests.ts b/shell-ui/src/setupTests.ts index 0ee4519cba..acb0d55de9 100644 --- a/shell-ui/src/setupTests.ts +++ b/shell-ui/src/setupTests.ts @@ -2,6 +2,7 @@ import fetch from 'node-fetch'; import 'regenerator-runtime/runtime'; import '@testing-library/jest-dom/extend-expect'; import 'jest-localstorage-mock'; +import { TextEncoder, TextDecoder } from 'util'; const nodeCrypto = require('crypto'); @@ -11,20 +12,21 @@ window.crypto = { return nodeCrypto.randomFillSync(buffer); }, }; +Object.defineProperty(window, 'location', { + value: { + reload: jest.fn(), + origin: 'http://localhost', + href: 'http://localhost', + hash: '', + assign: jest.fn(), + replace: jest.fn(), + }, +}); window.fetch = (url, ...rest) => // @ts-expect-error - FIXME when you are working on it fetch(/^https?:/.test(url) ? url : new URL(url, 'http://localhost'), ...rest); -delete window.location; -//@ts-expect-error -window.location = { - assign: jest.fn(), - reload: jest.fn(), - replace: jest.fn(), - hash: '', -}; - const DOMRect = jest.fn(() => ({ x: 1796.453125, y: 0, @@ -89,3 +91,6 @@ jest.mock('@scality/module-federation', () => { FederatedComponent: () => '', }; }); + +global.TextEncoder = TextEncoder; +global.TextDecoder = TextDecoder; diff --git a/ui/@mf-types/shell/compiled-types/src/FederatedApp.d.ts b/ui/@mf-types/shell/compiled-types/src/FederatedApp.d.ts index ddcf5462a5..0c3b50b4cb 100644 --- a/ui/@mf-types/shell/compiled-types/src/FederatedApp.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/FederatedApp.d.ts @@ -1,67 +1,13 @@ import React from 'react'; import { QueryClient } from 'react-query'; -import { NotificationCenterContextType } from './NotificationCenterProvider'; -import { useAuthConfig } from './auth/AuthConfigProvider'; -import { useAuth } from './auth/AuthProvider'; +import { ShellAlerts, ShellHooks } from './hooks/useShellHooks'; import './index.css'; -import { useConfigRetriever, useConfig, useDiscoveredViews, useLinkOpener, BuildtimeWebFinger, RuntimeWebFinger } from './initFederation/ConfigurationProviders'; -import { useShellConfig } from './initFederation/ShellConfigProvider'; -import { useShellThemeSelector } from './initFederation/ShellThemeSelectorProvider'; -import { useDeployedApps } from './initFederation/UIListProvider'; -import { 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 { UseQueryResult } from 'react-query'; export declare const queryClient: 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; - }; - }; +export type FederatedAppProps = { + shellHooks: ShellHooks; + shellAlerts: ShellAlerts; }; -declare global { - interface Window { - shellContexts: { - ShellHistoryContext: React.Context | null>; - NotificationContext: React.Context; - WebFingersContext: React.Context>, unknown>[]>; - }; - shellHooks: ShellTypes['shellHooks']; - shellAlerts: ShellTypes['shellAlerts']; - } -} export declare function WithInitFederationProviders({ children, }: { children: React.ReactNode; -}): JSX.Element; -export default function App(): JSX.Element; +}): import("react/jsx-runtime").JSX.Element; +export default function App(): import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/NotificationCenterProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/NotificationCenterProvider.d.ts index 1ffbc0d8d8..e85a158884 100644 --- a/ui/@mf-types/shell/compiled-types/src/NotificationCenterProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/NotificationCenterProvider.d.ts @@ -1,4 +1,4 @@ -import React, { Dispatch } from 'react'; +import { Dispatch, FC, ReactNode } from 'react'; export type Notification = { id: string; title: string; @@ -14,7 +14,10 @@ export type NotificationCenterContextType = { notifications: InternalNotification[]; dispatch: Dispatch; }; -export declare const NotificationCenterContext: React.Context; +export declare const NotificationCenterContext: import("react").Context; +type NotificationCenterProviderProps = { + children: ReactNode; +}; export declare enum NotificationActionType { PUBLISH = 0, UNPUBLISH = 1, @@ -29,7 +32,5 @@ export type NotificationCenterActions = { } | { type: NotificationActionType.READ_ALL; }; -declare const NotificationCenterProvider: ({ children }: { - children: any; -}) => JSX.Element; +declare const NotificationCenterProvider: FC; export default NotificationCenterProvider; diff --git a/ui/@mf-types/shell/compiled-types/src/alerts/AlertProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/alerts/AlertProvider.d.ts index dd4bb2ac29..6baaae9453 100644 --- a/ui/@mf-types/shell/compiled-types/src/alerts/AlertProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/alerts/AlertProvider.d.ts @@ -9,4 +9,4 @@ import React from 'react'; export default function AlertProvider({ alertManagerUrl, children, }: { alertManagerUrl: string; children: React.ReactNode; -}): JSX.Element; +}): import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/alerts/alertContext.d.ts b/ui/@mf-types/shell/compiled-types/src/alerts/alertContext.d.ts index acbffad943..80fd911ae6 100644 --- a/ui/@mf-types/shell/compiled-types/src/alerts/alertContext.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/alerts/alertContext.d.ts @@ -1 +1 @@ -export declare const AlertContext: any; +export declare const AlertContext: import("react").Context; diff --git a/ui/@mf-types/shell/compiled-types/src/alerts/alertHooks.d.ts b/ui/@mf-types/shell/compiled-types/src/alerts/alertHooks.d.ts index 64f13b1b0f..927c5621a9 100644 --- a/ui/@mf-types/shell/compiled-types/src/alerts/alertHooks.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/alerts/alertHooks.d.ts @@ -23,4 +23,4 @@ export declare const useHighestSeverityAlerts: (filters: FilterLabels) => Alert[ * * @returns react query result */ -export declare function useAlerts(filters: FilterLabels): any; +export declare function useAlerts(filters?: FilterLabels): any; diff --git a/ui/@mf-types/shell/compiled-types/src/auth/AuthConfigProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/auth/AuthConfigProvider.d.ts index f25260610c..cbfa514244 100644 --- a/ui/@mf-types/shell/compiled-types/src/auth/AuthConfigProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/auth/AuthConfigProvider.d.ts @@ -6,4 +6,4 @@ export declare const useAuthConfig: () => { }; export declare function AuthConfigProvider({ children, }: { children: React.ReactNode; -}): JSX.Element; +}): import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/auth/AuthProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/auth/AuthProvider.d.ts index 649a81a82d..cfd994b938 100644 --- a/ui/@mf-types/shell/compiled-types/src/auth/AuthProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/auth/AuthProvider.d.ts @@ -2,7 +2,7 @@ import { User } from 'oidc-client-ts'; import React from 'react'; export declare function AuthProvider({ children }: { children: React.ReactNode; -}): JSX.Element; +}): import("react/jsx-runtime").JSX.Element; export type UserData = { token: string; username: string; diff --git a/ui/@mf-types/shell/compiled-types/src/auth/FirstTimeLoginProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/auth/FirstTimeLoginProvider.d.ts index d2926004da..67f62dee9d 100644 --- a/ui/@mf-types/shell/compiled-types/src/auth/FirstTimeLoginProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/auth/FirstTimeLoginProvider.d.ts @@ -4,4 +4,4 @@ export declare const useFirstTimeLogin: () => { }; export declare function FirstTimeLoginProvider({ children, }: { children: React.ReactNode; -}): JSX.Element; +}): import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/hooks/useShellHooks.d.ts b/ui/@mf-types/shell/compiled-types/src/hooks/useShellHooks.d.ts new file mode 100644 index 0000000000..9c94c0ad9c --- /dev/null +++ b/ui/@mf-types/shell/compiled-types/src/hooks/useShellHooks.d.ts @@ -0,0 +1,47 @@ +import { useNotificationCenter } from '../useNotificationCenter'; +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; + useNotificationCenter: typeof useNotificationCenter; +}; +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 declare const shellHooks: ShellHooks; +export declare const shellAlerts: ShellAlerts; diff --git a/ui/@mf-types/shell/compiled-types/src/initFederation/ConfigurationProviders.d.ts b/ui/@mf-types/shell/compiled-types/src/initFederation/ConfigurationProviders.d.ts index 0489af918e..ec634d2286 100644 --- a/ui/@mf-types/shell/compiled-types/src/initFederation/ConfigurationProviders.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/initFederation/ConfigurationProviders.d.ts @@ -1,6 +1,7 @@ import { IconName } from '@scality/core-ui/dist/components/icon/Icon.component'; import { SolutionUI } from '@scality/module-federation'; import React from 'react'; +import { UseQueryResult } from 'react-query'; export type OAuth2ProxyConfig = { kind: 'OAuth2Proxy'; }; @@ -90,6 +91,10 @@ export type NonFederatedView = { icon?: IconName; }; export type ViewDefinition = FederatedView | NonFederatedView; +export declare function useWebFingersStore(): { + state: UseQueryResult>, unknown>[]; + updateWebFingersState: (newState: UseQueryResult>, unknown>[]) => void; +}; export declare function useDiscoveredViews(): ViewDefinition[]; export declare const useLinkOpener: () => { openLink: (to: { @@ -105,4 +110,4 @@ export declare const useLinkOpener: () => { }; export declare const ConfigurationProvider: ({ children, }: { children: React.ReactNode; -}) => JSX.Element; +}) => import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/initFederation/ShellConfigProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/initFederation/ShellConfigProvider.d.ts index c44bf025d8..784f27cbdc 100644 --- a/ui/@mf-types/shell/compiled-types/src/initFederation/ShellConfigProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/initFederation/ShellConfigProvider.d.ts @@ -51,5 +51,5 @@ export declare const useShellConfig: () => ShellConfig; export declare const ShellConfigProvider: ({ shellConfigUrl, children }: { shellConfigUrl: any; children: any; -}) => JSX.Element; +}) => import("react/jsx-runtime").JSX.Element; export {}; diff --git a/ui/@mf-types/shell/compiled-types/src/initFederation/ShellHistoryProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/initFederation/ShellHistoryProvider.d.ts index aef67d63cd..1fd36032b9 100644 --- a/ui/@mf-types/shell/compiled-types/src/initFederation/ShellHistoryProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/initFederation/ShellHistoryProvider.d.ts @@ -1,4 +1,4 @@ -export declare const useShellHistory: () => import("history").History; +export declare const useShellHistory: () => import("react-router").NavigateFunction; export declare const ShellHistoryProvider: ({ children }: { children: any; -}) => JSX.Element; +}) => import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/initFederation/ShellThemeSelectorProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/initFederation/ShellThemeSelectorProvider.d.ts index b7310e8060..2d8a113dd2 100644 --- a/ui/@mf-types/shell/compiled-types/src/initFederation/ShellThemeSelectorProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/initFederation/ShellThemeSelectorProvider.d.ts @@ -13,5 +13,5 @@ export declare function useShellThemeSelector(): ThemeContextValues; export declare function ShellThemeSelectorProvider({ children, }: { children: (theme: CoreUITheme, themeName: ThemeMode) => React.ReactNode; onThemeChanged?: (evt: CustomEvent) => void; -}): JSX.Element; +}): import("react/jsx-runtime").JSX.Element; export {}; diff --git a/ui/@mf-types/shell/compiled-types/src/initFederation/UIListProvider.d.ts b/ui/@mf-types/shell/compiled-types/src/initFederation/UIListProvider.d.ts index 34e350cc2b..e3dd0a222e 100644 --- a/ui/@mf-types/shell/compiled-types/src/initFederation/UIListProvider.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/initFederation/UIListProvider.d.ts @@ -13,4 +13,4 @@ export declare const useDeployedApps: (selectors?: { export declare const UIListProvider: ({ children, discoveryURL, }: { children: React.ReactNode; discoveryURL: string; -}) => JSX.Element; +}) => import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/navbar/InstanceName.d.ts b/ui/@mf-types/shell/compiled-types/src/navbar/InstanceName.d.ts index 4755ebda55..175ae50f4d 100644 --- a/ui/@mf-types/shell/compiled-types/src/navbar/InstanceName.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/navbar/InstanceName.d.ts @@ -1,6 +1,6 @@ import { PropsWithChildren } from 'react'; import { UserData } from '../auth/AuthProvider'; -export declare const InstanceNameProvider: ({ children }: PropsWithChildren<{}>) => JSX.Element; +export declare const InstanceNameProvider: ({ children }: PropsWithChildren<{}>) => import("react/jsx-runtime").JSX.Element; export declare const useInstanceName: () => string; export declare const useInstanceNameAdapter: () => { remoteEntryUrl: string; @@ -14,5 +14,5 @@ export declare const _InternalInstanceName: ({ moduleExports, }: { setInstanceName: (userData: UserData | undefined, name: string) => Promise; }; }; -}) => JSX.Element; -export declare const InstanceName: () => JSX.Element; +}) => import("react/jsx-runtime").JSX.Element; +export declare const InstanceName: () => import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/navbar/NavBar.d.ts b/ui/@mf-types/shell/compiled-types/src/navbar/NavBar.d.ts index 467aac4b73..061a4f19a0 100644 --- a/ui/@mf-types/shell/compiled-types/src/navbar/NavBar.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/navbar/NavBar.d.ts @@ -3,7 +3,7 @@ import { ViewDefinition } from '../initFederation/ConfigurationProviders'; import type { Link as TypeLink } from './navbarHooks'; export declare const LoadingNavbar: ({ logo }: { logo: string; -}) => JSX.Element; +}) => import("react/jsx-runtime").JSX.Element; export declare const useNavbarLinksToActions: (links: TypeLink[]) => { link: TypeLink; selected: boolean; @@ -17,4 +17,4 @@ export declare const Navbar: ({ logo, canChangeLanguage, canChangeTheme, childre canChangeTheme?: boolean; providerLogout?: boolean; children?: React.ReactNode; -}) => JSX.Element; +}) => import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/navbar/NavbarUpdaterComponents.d.ts b/ui/@mf-types/shell/compiled-types/src/navbar/NavbarUpdaterComponents.d.ts deleted file mode 100644 index 42dc4eb2bd..0000000000 --- a/ui/@mf-types/shell/compiled-types/src/navbar/NavbarUpdaterComponents.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare const NavbarUpdaterComponents: () => JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/navbar/NotificationCenter.d.ts b/ui/@mf-types/shell/compiled-types/src/navbar/NotificationCenter.d.ts deleted file mode 100644 index 4ff737f314..0000000000 --- a/ui/@mf-types/shell/compiled-types/src/navbar/NotificationCenter.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const NotificationCenter: () => JSX.Element; -export default NotificationCenter; diff --git a/ui/@mf-types/shell/compiled-types/src/navbar/SleepingNotificationBell.d.ts b/ui/@mf-types/shell/compiled-types/src/navbar/SleepingNotificationBell.d.ts deleted file mode 100644 index befb9a0f32..0000000000 --- a/ui/@mf-types/shell/compiled-types/src/navbar/SleepingNotificationBell.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare const SleepingNotificationBell: () => JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/navbar/index.d.ts b/ui/@mf-types/shell/compiled-types/src/navbar/index.d.ts index 018f0a83e2..fbaed5d7b9 100644 --- a/ui/@mf-types/shell/compiled-types/src/navbar/index.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/navbar/index.d.ts @@ -3,4 +3,4 @@ import './library'; export type SolutionsNavbarProps = { children?: React.ReactNode; }; -export declare const SolutionsNavbar: ({ children }: SolutionsNavbarProps) => JSX.Element; +export declare const SolutionsNavbar: ({ children }: SolutionsNavbarProps) => import("react/jsx-runtime").JSX.Element; diff --git a/ui/@mf-types/shell/compiled-types/src/navbar/lang.d.ts b/ui/@mf-types/shell/compiled-types/src/navbar/lang.d.ts index 06bf0b7d6d..c74429cb40 100644 --- a/ui/@mf-types/shell/compiled-types/src/navbar/lang.d.ts +++ b/ui/@mf-types/shell/compiled-types/src/navbar/lang.d.ts @@ -10,5 +10,5 @@ export declare function LanguageProvider({ children, canChangeLanguage, onLangua children: React.ReactNode; canChangeLanguage?: boolean; onLanguageChanged?: (evt: CustomEvent) => void; -}): JSX.Element; +}): import("react/jsx-runtime").JSX.Element; export {}; diff --git a/ui/@mf-types/shell/compiled-types/src/navbar/navbarContext.d.ts b/ui/@mf-types/shell/compiled-types/src/navbar/navbarContext.d.ts deleted file mode 100644 index edf40338ec..0000000000 --- a/ui/@mf-types/shell/compiled-types/src/navbar/navbarContext.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './navbarHooks'; -export declare const NavbarContext: any; diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/IconHelper.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/IconHelper.d.ts deleted file mode 100644 index 1150727e01..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/IconHelper.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { CSSProperties, ReactNode } from 'react'; -import { Position } from './tooltip/Tooltip.component'; -type IconHelpProps = { - tooltipMessage: ReactNode; - placement?: Position; - overlayStyle?: CSSProperties; -}; -export declare const IconHelp: ({ tooltipMessage, overlayStyle, placement, }: IconHelpProps) => import("react/jsx-runtime").JSX.Element; -export {}; -//# sourceMappingURL=IconHelper.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/dropdown/Dropdown.component.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/dropdown/Dropdown.component.d.ts deleted file mode 100644 index 389d49b389..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/dropdown/Dropdown.component.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -export type Item = { - label: string; - name?: string; - selected?: boolean; - onClick: (arg0: any) => void; -}; -type Items = Array; -type Props = { - text?: string; - size?: string; - variant?: string; - title?: string; - items: Items; - icon?: JSX.Element; - caret?: boolean; -}; -declare function Dropdown({ items, text, icon, size, variant, title, caret, ...rest }: Props): import("react/jsx-runtime").JSX.Element; -export { Dropdown }; -//# sourceMappingURL=Dropdown.component.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/icon/Icon.component.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/icon/Icon.component.d.ts deleted file mode 100644 index b85b36bdea..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/icon/Icon.component.d.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { CSSProperties } from 'react'; -import { CoreUITheme } from '../../style/theme'; -import { SizeProp } from '@fortawesome/fontawesome-svg-core'; -export declare const iconTable: { - Account: string; - Backend: string; - Tape: string; - 'Node-backend': string; - 'Volume-backend': string; - 'Node-pdf': string; - 'Volume-pdf': string; - Network: string; - Bucket: string; - 'Cloud-backend': string; - Datacenter: string; - 'Simple-user': string; - User: string; - Group: string; - Alert: string; - Bell: string; - 'Lat-menu': string; - Dashboard: string; - Workflow: string; - Expiration: string; - Replication: string; - Transition: string; - Discovery: string; - Metrics: string; - Edit: string; - Logs: string; - Lock: string; - 'Lock-open': string; - 'Create-add': string; - Delete: string; - Save: string; - 'External-link': string; - Link: string; - Unlink: string; - Close: string; - 'Dropdown-down': string; - 'Dropdown-up': string; - Search: string; - More: string; - Info: string; - Sync: string; - Export: string; - Copy: string; - 'Simple-upload': string; - Upload: string; - 'Add-plus': string; - Minus: string; - 'Remove-minus': string; - Sort: string; - 'Sort-up': string; - 'Sort-down': string; - Calendar: string; - 'Calendar-minus': string; - 'Arrow-up': string; - 'Arrow-down': string; - 'Arrow-right': string; - 'Arrow-left': string; - 'Arrow-alt-circle-up': string; - Folder: string; - File: string; - 'File-invoice': string; - License: string; - 'Deletion-marker': string; - 'Map-marker': string; - Location: string; - 'Info-circle': string; - 'Exclamation-triangle': string; - 'Exclamation-circle': string; - Exclamation: string; - Check: string; - Protected: string; - 'Chevron-left': string; - 'Chevron-right': string; - 'Chevron-down': string; - 'Chevron-up': string; - 'Angle-right': string; - 'Angle-double-right': string; - Language: string; - Theme: string; - Documentation: string; - Support: string; - EULA: string; - 'Log-out': string; - Hourglass: string; - Pause: string; - 'Pause-circle': string; - 'Play-circle': string; - Upgrade: string; - Expansion: string; - Rebalance: string; - Maintenance: string; - Role: string; - 'Change-erasure': string; - 'Circle-health': string; - 'Circle-empty': string; - 'Dot-circle': string; - 'Check-circle': string; - 'Times-circle': string; - Toolbox: string; - Cubes: string; - Policy: string; - Pen: string; - Pencil: string; - Eye: string; - EyeSlash: string; - Snowflake: string; - Key: string; - Filter: string; - Download: string; - Certificate: string; - Redo: string; - Eraser: string; - 'ID-card': string; - Setting: string; - Desktop: string; - Globe: string; - Satellite: string; - LightMode: string; - DarkMode: string; - News: string; - Ring: string; - Stop: string; - Play: string; -}; -export declare const customIcons: { - 'Remote-user': ({ ariaLabel, color, size }: { - ariaLabel: any; - color: any; - size: any; - }) => import("react/jsx-runtime").JSX.Element; - 'Remote-group': ({ ariaLabel, color, size }: { - ariaLabel: any; - color: any; - size: any; - }) => import("react/jsx-runtime").JSX.Element; -}; -export type IconName = keyof typeof iconTable | keyof typeof customIcons; -export type IconColor = keyof CoreUITheme; -type Props = { - name: IconName; - size?: SizeProp; - color?: IconColor | CSSProperties['color']; - ariaLabel?: string; - withWrapper?: boolean; - style?: CSSProperties; - onClick?: (event: MouseEvent) => void; -}; -export declare const IconWrapper: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, { - size: SizeProp; -}, never>; -declare function Icon({ withWrapper, ...props }: Props): import("react/jsx-runtime").JSX.Element; -export { Icon }; -//# sourceMappingURL=Icon.component.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/inputlist/InputList.component.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/inputlist/InputList.component.d.ts deleted file mode 100644 index c403298c75..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/inputlist/InputList.component.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { HTMLProps } from 'react'; -import { RefCallBack } from 'react-hook-form'; -export type InputListProps = Omit, 'size'> & { - ref: RefCallBack; - min?: string | number; - max?: string | number; - maxLength?: number; - minLength?: number; - pattern?: string; - required?: boolean; - disabled?: boolean; - maxItems?: number; - value: T[]; -}; -export declare const InputList: import("react").ForwardRefExoticComponent, "size"> & { - ref: RefCallBack; - min?: string | number; - max?: string | number; - maxLength?: number; - minLength?: number; - pattern?: string; - required?: boolean; - disabled?: boolean; - maxItems?: number; - value: (string | number | readonly string[] | undefined)[]; -}, "ref"> & import("react").RefAttributes>; -//# sourceMappingURL=InputList.component.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/linetemporalchart/MetricTimespanProvider.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/linetemporalchart/MetricTimespanProvider.d.ts deleted file mode 100644 index 239fade2bc..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/linetemporalchart/MetricTimespanProvider.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react'; -import { QueryTimeSpan } from '../constants'; -export declare const MetricsTimeSpanContext: React.Context; -export declare const MetricsTimeSpanProvider: ({ children, }: { - children: JSX.Element; -}) => import("react/jsx-runtime").JSX.Element; -export declare const useMetricsTimeSpan: () => QueryTimeSpan; -//# sourceMappingURL=MetricTimespanProvider.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tablev2/TableCommon.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tablev2/TableCommon.d.ts deleted file mode 100644 index d8e90151e3..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tablev2/TableCommon.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import React, { ComponentType, LegacyRef } from 'react'; -import { Row } from 'react-table'; -import { FixedSizeList, ListChildComponentProps, ListItemKeySelector } from 'react-window'; -import { TableHeightKeyType, TableLocalType } from './TableUtils'; -import { CSSProperties } from 'styled-components'; -type VirtualizedRowsType = Record> = { - rows: Row[]; - RenderRow: ComponentType[]>>; - rowHeight: TableHeightKeyType; - setHasScrollbar: React.Dispatch>; - hasScrollbar?: boolean; - itemKey?: ListItemKeySelector[]>; - onBottom?: (rowLength: number) => void; - onBottomOffset?: number; - listRef?: LegacyRef[]>>; -}; -export declare const VirtualizedRows: = Record>({ rows, rowHeight, setHasScrollbar, onBottom, onBottomOffset, RenderRow, listRef, itemKey, }: VirtualizedRowsType) => import("react/jsx-runtime").JSX.Element; -export declare const useTableScrollbar: () => { - hasScrollbar: boolean | undefined; - setHasScrollbar: React.Dispatch>; - scrollBarWidth: number; - handleScrollbarWidth: (node: any) => void; -}; -export type RenderRowType = { - index: number; - style: CSSProperties; -}; -type TableRowsProps = Record> = { - locale?: TableLocalType; - children?: (children: JSX.Element) => JSX.Element; - customItemKey?: (index: number, data: DATA_ROW) => string; - RenderRow: React.MemoExoticComponent<({ index, style }: RenderRowType) => JSX.Element>; -}; -export declare function TableRows = Record>({ locale, children, customItemKey, RenderRow }: TableRowsProps): import("react/jsx-runtime").JSX.Element | null; -export {}; -//# sourceMappingURL=TableCommon.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tablev2/TableUtils.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tablev2/TableUtils.d.ts deleted file mode 100644 index 0797ab79d6..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tablev2/TableUtils.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -declare const STATUS_CRITICAL = "critical"; -declare const STATUS_WARNING = "warning"; -declare const STATUS_NONE = "none"; -declare const STATUS_HEALTH = "healthy"; -type StatusType = typeof STATUS_CRITICAL | typeof STATUS_WARNING | typeof STATUS_NONE | typeof STATUS_HEALTH; -export declare function compareHealth(status1: StatusType, status2: StatusType): number | undefined; -export declare function convertRemToPixels(rem: any): number; -export type TableLocalType = 'en' | 'fr'; -export type TableHeightKeyType = 'h32' | 'h40' | 'h48' | 'h64'; -export type TableVariantType = 'backgroundLevel1' | 'backgroundLevel2' | 'backgroundLevel3' | 'backgroundLevel4'; -export declare const tableRowHeight: { - h32: string; - h40: string; - h48: string; - h64: string; -}; -type TableMessagesType = 'error' | 'loading' | 'idle' | 'noResult'; -export declare const translatedMessages: (type: TableMessagesType, entityName?: { - en: { - singular: string; - plural: string; - }; - fr?: { - singular: string; - plural: string; - }; -}, locale?: TableLocalType) => string; -export {}; -//# sourceMappingURL=TableUtils.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tabsv2/Tabsv2.component.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tabsv2/Tabsv2.component.d.ts deleted file mode 100644 index c74068321e..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/tabsv2/Tabsv2.component.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import React, { ReactElement } from 'react'; -import { Tab } from './Tab'; -import { TabProps } from './Tab'; -type TabsProps = { - activeTabColor?: string; - activeTabSeparator?: string; - tabLineColor?: string; - inactiveTabColor?: string; - tabContentColor?: string; - separatorColor?: string; - tabHoverColor?: string; - children: ReactElement[]; - className?: string; -}; -export declare const TabsContext: React.Context; -declare function Tabs({ activeTabColor, activeTabSeparator, tabLineColor, inactiveTabColor, tabContentColor, separatorColor, tabHoverColor, children, className, ...rest }: TabsProps): import("react/jsx-runtime").JSX.Element; -declare namespace Tabs { - var Tab: typeof import("./Tab").Tab; -} -export { Tabs, Tab }; -//# sourceMappingURL=Tabsv2.component.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/toast/ToastProvider.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/toast/ToastProvider.d.ts deleted file mode 100644 index 28507fa049..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/components/toast/ToastProvider.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ReactNode } from 'react'; -import { ToastProps } from './Toast.component'; -export type ToastContextState = Omit; -export interface ToastContextType { - showToast: (toastProps: ToastContextState) => void; -} -export declare const ToastContext: import("react").Context; -interface ToastProviderProps { - children: ReactNode; -} -export declare const ToastProvider: React.FC; -export declare const useToast: () => ToastContextType; -export {}; -//# sourceMappingURL=ToastProvider.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/index.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/index.d.ts deleted file mode 100644 index 4af01473e2..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/index.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -export { Banner } from './components/banner/Banner.component'; -export { Breadcrumb } from './components/breadcrumb/Breadcrumb.component'; -export { Button } from './components/button/Button.component'; -export { Checkbox } from './components/checkbox/Checkbox.component'; -export { Chips } from './components/chips/Chips.component'; -export { Dropdown } from './components/dropdown/Dropdown.component'; -export { LOADER_SIZE, STATUS_CRITICAL, STATUS_WARNING, STATUS_SUCCESS, STATUS_HEALTHY, STATUS_INFO, STATUS_UNKNOWN, STATUS_NONE, Status, } from './components/constants'; -export { Layout } from './components/layout/Layout.component'; -export { Loader } from './components/loader/Loader.component'; -export { Modal } from './components/modal/Modal.component'; -export { Navbar } from './components/navbar/Navbar.component'; -export { Notifications } from './components/notifications/Notifications.component'; -export { SearchInput } from './components/searchinput/SearchInput.component'; -export { Select } from './components/select/Select.component'; -export { Sidebar } from './components/sidebar/Sidebar.component'; -export { Steppers } from './components/steppers/Steppers.component'; -export { Toggle } from './components/toggle/Toggle.component'; -export { Tooltip } from './components/tooltip/Tooltip.component'; -export { MultiSelect } from './components/multiselect/MultiSelect.component'; -export { VegaChart } from './components/vegachart/VegaChart.component'; -export { LineChart } from './components/linechart/LineChart.component'; -export { ProgressBar } from './components/progressbar/ProgressBar.component'; -export { TextArea } from './components/textarea/TextArea.component'; -export { CloudProgressBar } from './components/cloudprogressbar/CloudProgressBar.component'; -export { Sparkline } from './components/sparkline/SparkLine.component'; -export { BarChart } from './components/barchart/BarChart.component'; -export { CircularProgressBar } from './components/circularprogressbar/CircularProgressBar.component'; -export { AreaChart } from './components/areachart/AreaChart.component'; -export { CollapsiblePanel } from './components/collapsiblepanel/CollapsiblePanel.component'; -export { LateralNavbarLayout } from './components/lateralnavbarlayout/LateralNavbarLayout.component'; -export { GlobalHealthBar } from './components/globalhealthbar/GlobalHealthBar.component'; -export { ConstrainedText } from './components/constrainedtext/Constrainedtext.component'; -export { EmptyState } from './components/emptystate/Emptystate.component'; -export { EmptyTable } from './components/emptytable/Emptytable.component'; -export { ScrollbarWrapper } from './components/scrollbarwrapper/ScrollbarWrapper.component'; -export { ErrorPage401 } from './components/error-pages/ErrorPage401.component'; -export { ErrorPage404 } from './components/error-pages/ErrorPage404.component'; -export { ErrorPage500 } from './components/error-pages/ErrorPage500.component'; -export { ErrorPageAuth } from './components/error-pages/ErrorPageAuth.component'; -export { TextBadge } from './components/textbadge/TextBadge.component'; -export { SpacedBox } from './components/spacedbox/SpacedBox'; -export { Layout as Layout2 } from './components/layout/v2'; -export { TwoPanelLayout } from './components/layout/v2/panels'; -export { AppContainer } from './components/layout/v2/AppContainer'; -export { BasicText, SecondaryText, LargerText, EmphaseText, StatusText, LargeText, SmallerText, ChartTitleText, Text, Link, } from './components/text/Text.component'; -export { Card } from './components/card/Card.component'; -export { PrettyBytes } from './components/prettybytes/PrettyBytes.component'; -export { Icon } from './components/icon/Icon.component'; -export { StatusWrapper } from './components/statuswrapper/Statuswrapper.component'; -export { Stack, Wrap, spacing } from './spacing'; -export { Form, FormSection, FormGroup } from './components/form/Form.component'; -export { FormattedDateTime } from './components/date/FormattedDateTime'; -export { getDateDaysDiff } from './components/date/dateDiffer'; -export { IconHelp } from './components/IconHelper'; -export { Dropzone } from './components/dropzone/Dropzone'; -export { Toast } from './components/toast/Toast.component'; -export { ToastProvider, useToast } from './components/toast/ToastProvider'; -export { useMutationsHandler } from './components/toast/useMutationsHandler'; -export { Stepper } from './components/steppers/Stepper.component'; -export { InfoMessage } from './components/infomessage/InfoMessage.component'; -export { InputList } from './components/inputlist/InputList.component'; -export { InlineInput } from './components/inlineinput/InlineInput'; -export { UnsuccessfulResult } from './components/UnsuccessfulResult.component'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/organisms/attachments/AttachmentConfirmationModal.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/organisms/attachments/AttachmentConfirmationModal.d.ts deleted file mode 100644 index e2825a50f6..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/dist/organisms/attachments/AttachmentConfirmationModal.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentType } from 'react'; -import { UseMutationOptions } from 'react-query'; -import { AttachmentOperation, AttachmentAction } from './AttachmentTypes'; -export declare function AttachmentConfirmationModal = Record>({ attachmentOperations, getAttachmentMutationOptions, resourceType, resourceName, redirectUrl, EntityIcon, cancelButtonDisabled, onCancel, onExit, }: { - attachmentOperations: AttachmentOperation[]; - getAttachmentMutationOptions: () => UseMutationOptions; - resourceName: string; - resourceType: RESOURCE_TYPE; - redirectUrl: string; - EntityIcon: ComponentType<{ - type: ENTITY_TYPE | RESOURCE_TYPE; - }>; - cancelButtonDisabled?: boolean; - onCancel?: () => void; - onExit?: (successfullOperations: AttachmentOperation[], failedOperations: AttachmentOperation[]) => void; -}): import("react/jsx-runtime").JSX.Element; -//# sourceMappingURL=AttachmentConfirmationModal.d.ts.map \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/package.json b/ui/@mf-types/shell/node_modules/@scality/core-ui/package.json deleted file mode 100644 index 64b897d83f..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/package.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "name": "@scality/core-ui", - "version": "0.151.0", - "description": "Scality common React component library", - "author": "Scality Engineering", - "license": "SEE LICENSE IN LICENSE", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "mainSrc": "src/lib/index.js", - "sideEffects": false, - "scripts": { - "analyze": "source-map-explorer 'dist/*.js'", - "build": "rimraf dist && tsc", - "copy-files": "copyfiles -u 2 src/lib/style/fonts/* dist && copyfiles -u 2 src/lib/*.css dist", - "lint": "eslint src/* --ext .js --no-error-on-unmatched-pattern", - "prepare": "npm run build", - "postbuild": "npm run copy-files", - "plop": "plop", - "test": "jest", - "storybook": "storybook dev -p 3000", - "build-storybook": "storybook build", - "storybook:deploy": "storybook-to-ghpages", - "preview": "jest-preview" - }, - "keywords": [], - "browserslist": [ - ">0.2%", - "not dead", - "not ie <= 11", - "not op_mini all" - ], - "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.16.7", - "@babel/preset-typescript": "^7.16.7", - "@chromatic-com/storybook": "^1.9.0", - "@storybook/addon-actions": "^8.3.6", - "@storybook/addon-essentials": "^8.3.6", - "@storybook/addon-links": "^8.3.6", - "@storybook/addon-mdx-gfm": "^8.3.6", - "@storybook/addon-storysource": "^8.3.6", - "@storybook/addon-webpack5-compiler-swc": "^1.0.5", - "@storybook/blocks": "^8.3.6", - "@storybook/manager-api": "^8.3.6", - "@storybook/react": "^8.3.6", - "@storybook/react-webpack5": "^8.3.6", - "@storybook/storybook-deployer": "^2.8.16", - "@storybook/theming": "^8.3.6", - "@testing-library/jest-dom": "^5.14.1", - "@testing-library/react": "^11.2.7", - "@testing-library/react-hooks": "^8.0.1", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.0", - "@types/react": "^17.0.39", - "@types/react-dom": "^17.0.11", - "@types/react-router": "^5.1.20", - "@types/react-router-dom": "^5.3.3", - "@types/react-table": "^7.7.11", - "@types/react-virtualized-auto-sizer": "^1.0.1", - "@types/react-window": "^1.8.5", - "@types/styled-components": "^5.1.25", - "@types/styled-system": "^5.1.15", - "@typescript-eslint/eslint-plugin": "^6.12.0", - "@typescript-eslint/parser": "^6.12.0", - "copyfiles": "^2.4.1", - "cross-env": "^7.0.3", - "csstype": "^3.1.0", - "eslint": "^8.15.0", - "eslint-config-react-app": "^7.0.1", - "eslint-plugin-storybook": "^0.10.1", - "husky": "^3.0.5", - "identity-obj-proxy": "^3.0.0", - "jest": "^26.6.3", - "jest-canvas-mock": "^2.3.1", - "jest-preview": "^0.3.1", - "plop": "^2.4.0", - "regenerator-runtime": "^0.13.7", - "rimraf": "^3.0.0", - "source-map-explorer": "^2.0.1", - "storybook": "^8.3.6", - "typescript": "^5.3.2" - }, - "husky": { - "hooks": { - "pre-commit": "npm run lint" - } - }, - "jest": { - "setupFiles": [ - "jest-canvas-mock" - ], - "transform": { - "^.+\\.[tj]sx?$": "babel-jest", - "^.+\\.mdx?$": "@storybook/addon-docs/jest-transform-mdx" - } - }, - "dependencies": { - "@floating-ui/dom": "^1.6.3", - "@fortawesome/fontawesome-free": "^5.10.2", - "@fortawesome/fontawesome-svg-core": "^1.2.35", - "@fortawesome/free-regular-svg-icons": "^5.15.3", - "@fortawesome/free-solid-svg-icons": "^5.15.3", - "@fortawesome/react-fontawesome": "^0.1.14", - "@js-temporal/polyfill": "^0.4.4", - "@storybook/preview-api": "^8.3.6", - "downshift": "^7.0.5", - "framer-motion": "^4.1.17", - "polished": "3.4.1", - "pretty-bytes": "^5.6.0", - "react": "^17.0.2", - "react-debounce-input": "3.2.2", - "react-dom": "^17.0.2", - "react-dropzone": "^14.2.3", - "react-hook-form": "^7.49.2", - "react-query": "^3.34.0", - "react-router": "5.2.0", - "react-router-dom": "5.2.0", - "react-select": "4.3.1", - "react-table": "^7.7.0", - "react-virtualized": "9.22.3", - "react-virtualized-auto-sizer": "^1.0.24", - "react-window": "^1.8.6", - "styled-components": "^5.2.1", - "styled-system": "^5.1.5", - "vega": "^5.17.3", - "vega-embed": "6.0.0", - "vega-lite": "5.0.0", - "vega-tooltip": "0.27.0" - }, - "homepage": "https://scality.github.io/core-ui/", - "publishConfig": { - "access": "public" - }, - "repository": "https://github.com/scality/core-ui.git" -} diff --git a/ui/@mf-types/shell/node_modules/@scality/core-ui/types/styled.d.ts b/ui/@mf-types/shell/node_modules/@scality/core-ui/types/styled.d.ts deleted file mode 100644 index 2d9c50c07f..0000000000 --- a/ui/@mf-types/shell/node_modules/@scality/core-ui/types/styled.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import 'styled-components'; -import { CoreUITheme } from '../src/lib/style/theme'; - -declare module 'styled-components' { - export interface DefaultTheme extends CoreUITheme {} -} diff --git a/ui/@mf-types/shell/node_modules/@types/history/DOMUtils.d.ts b/ui/@mf-types/shell/node_modules/@types/history/DOMUtils.d.ts deleted file mode 100644 index 2b0a597cea..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/DOMUtils.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -declare global { - // Some users of this package are don't use "dom" libs - interface EventTarget {} - interface EventListener {} - interface EventListenerObject {} -} - -export const isExtraneousPopstateEvent: boolean; -export function addEventListener(node: EventTarget, event: string, listener: EventListener | EventListenerObject): void; -export function removeEventListener( - node: EventTarget, - event: string, - listener: EventListener | EventListenerObject, -): void; -export function getConfirmation(message: string, callback: (result: boolean) => void): void; -export function supportsHistory(): boolean; -export function supportsGoWithoutReloadUsingHash(): boolean; diff --git a/ui/@mf-types/shell/node_modules/@types/history/ExecutionEnvironment.d.ts b/ui/@mf-types/shell/node_modules/@types/history/ExecutionEnvironment.d.ts deleted file mode 100644 index ac15888726..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/ExecutionEnvironment.d.ts +++ /dev/null @@ -1 +0,0 @@ -export const canUseDOM: boolean; diff --git a/ui/@mf-types/shell/node_modules/@types/history/LocationUtils.d.ts b/ui/@mf-types/shell/node_modules/@types/history/LocationUtils.d.ts deleted file mode 100644 index 26e9324b62..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/LocationUtils.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Path, LocationState, LocationKey, Location, LocationDescriptor } from './index'; - -export function locationsAreEqual(lv: LocationDescriptor, rv: LocationDescriptor): boolean; -export function createLocation( - path: LocationDescriptor, - state?: S, - key?: LocationKey, - currentLocation?: Location, -): Location; diff --git a/ui/@mf-types/shell/node_modules/@types/history/PathUtils.d.ts b/ui/@mf-types/shell/node_modules/@types/history/PathUtils.d.ts deleted file mode 100644 index 18952a2b3e..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/PathUtils.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Path, Location, LocationDescriptorObject } from './index'; - -export function addLeadingSlash(path: Path): Path; -export function stripLeadingSlash(path: Path): Path; -export function hasBasename(path: Path): boolean; -export function stripBasename(path: Path, prefix: string): Path; -export function stripTrailingSlash(path: Path): Path; -export function parsePath(path: Path): Location; -export function createPath(location: LocationDescriptorObject): Path; diff --git a/ui/@mf-types/shell/node_modules/@types/history/createBrowserHistory.d.ts b/ui/@mf-types/shell/node_modules/@types/history/createBrowserHistory.d.ts deleted file mode 100644 index 09910bd8cd..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/createBrowserHistory.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { History, LocationState } from './index'; -import { getConfirmation } from './DOMUtils'; - -export interface BrowserHistoryBuildOptions { - basename?: string | undefined; - forceRefresh?: boolean | undefined; - getUserConfirmation?: typeof getConfirmation | undefined; - keyLength?: number | undefined; -} - -export default function createBrowserHistory(options?: BrowserHistoryBuildOptions): History; diff --git a/ui/@mf-types/shell/node_modules/@types/history/createHashHistory.d.ts b/ui/@mf-types/shell/node_modules/@types/history/createHashHistory.d.ts deleted file mode 100644 index 4351a48450..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/createHashHistory.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { History, LocationState } from './index'; -import { getConfirmation } from './DOMUtils'; - -export type HashType = 'hashbang' | 'noslash' | 'slash'; - -export interface HashHistoryBuildOptions { - basename?: string | undefined; - hashType?: HashType | undefined; - getUserConfirmation?: typeof getConfirmation | undefined; -} - -export default function createHashHistory(options?: HashHistoryBuildOptions): History; diff --git a/ui/@mf-types/shell/node_modules/@types/history/createMemoryHistory.d.ts b/ui/@mf-types/shell/node_modules/@types/history/createMemoryHistory.d.ts deleted file mode 100644 index fea27d940d..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/createMemoryHistory.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { History, Location, LocationState } from './index'; -import { getConfirmation } from './DOMUtils'; - -export type InitialEntry = string | Partial; - -export interface MemoryHistoryBuildOptions { - getUserConfirmation?: typeof getConfirmation | undefined; - initialEntries?: InitialEntry[] | undefined; - initialIndex?: number | undefined; - keyLength?: number | undefined; -} - -export interface MemoryHistory extends History { - index: number; - entries: Location[]; - canGo(n: number): boolean; -} - -export default function createMemoryHistory(options?: MemoryHistoryBuildOptions): MemoryHistory; diff --git a/ui/@mf-types/shell/node_modules/@types/history/createTransitionManager.d.ts b/ui/@mf-types/shell/node_modules/@types/history/createTransitionManager.d.ts deleted file mode 100644 index 135ee54f0e..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/createTransitionManager.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Location, Action, LocationListener, LocationState, UnregisterCallback } from './index'; -import { getConfirmation } from './DOMUtils'; - -export type PromptFunction = (location: Location, action: Action) => any; - -export type Prompt = PromptFunction | boolean; - -export interface TransitionManager { - setPrompt(nextPrompt?: Prompt): UnregisterCallback; - appendListener(listener: LocationListener): UnregisterCallback; - notifyListeners(location: Location, action: Action): void; - confirmTransitionTo( - location: Location, - action: Action, - getUserConfirmation: typeof getConfirmation, - callback: (result: boolean) => void, - ): void; -} - -export default function createTransitionManager(): TransitionManager; diff --git a/ui/@mf-types/shell/node_modules/@types/history/index.d.ts b/ui/@mf-types/shell/node_modules/@types/history/index.d.ts deleted file mode 100644 index c7fb53ec91..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/index.d.ts +++ /dev/null @@ -1,95 +0,0 @@ -// Type definitions for history 4.7.2 -// Project: https://github.com/mjackson/history -// Definitions by: Sergey Buturlakin , Nathan Brown , Young Rok Kim , Daniel Nixon -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.3 -export as namespace History; - -export type Action = 'PUSH' | 'POP' | 'REPLACE'; -export type UnregisterCallback = () => void; - -export interface History { - length: number; - action: Action; - location: Location; - push(location: Path | LocationDescriptor, state?: HistoryLocationState): void; - replace(location: Path | LocationDescriptor, state?: HistoryLocationState): void; - go(n: number): void; - goBack(): void; - goForward(): void; - block(prompt?: boolean | string | TransitionPromptHook): UnregisterCallback; - listen(listener: LocationListener): UnregisterCallback; - createHref(location: LocationDescriptorObject): Href; -} - -export interface Location { - pathname: Pathname; - search: Search; - state: S; - hash: Hash; - key?: LocationKey | undefined; -} - -export interface LocationDescriptorObject { - pathname?: Pathname | undefined; - search?: Search | undefined; - state?: S | undefined; - hash?: Hash | undefined; - key?: LocationKey | undefined; -} - -export namespace History { - export type LocationDescriptor = Path | LocationDescriptorObject; - export type LocationKey = string; - export type LocationListener = (location: Location, action: Action) => void; - - export type LocationState = unknown; - export type Path = string; - export type Pathname = string; - export type Search = string; - export type TransitionHook = (location: Location, callback: (result: any) => void) => any; - export type TransitionPromptHook = ( - location: Location, - action: Action, - ) => string | false | void; - export type Hash = string; - export type Href = string; -} - -export type LocationDescriptor = History.LocationDescriptor; -export type LocationKey = History.LocationKey; -export type LocationListener = History.LocationListener; -export type LocationState = History.LocationState; -export type Path = History.Path; -export type Pathname = History.Pathname; -export type Search = History.Search; -export type TransitionHook = History.TransitionHook; -export type TransitionPromptHook = History.TransitionPromptHook; -export type Hash = History.Hash; -export type Href = History.Href; - -import { default as createBrowserHistory } from './createBrowserHistory'; -import { default as createHashHistory } from './createHashHistory'; -import { default as createMemoryHistory } from './createMemoryHistory'; -import { createLocation, locationsAreEqual } from './LocationUtils'; -import { parsePath, createPath } from './PathUtils'; - -// Global usage, without modules, needs the small trick, because lib.d.ts -// already has `history` and `History` global definitions: -// var createHistory = ((window as any).History as HistoryModule.Module).createHistory; -export interface Module { - createBrowserHistory: typeof createBrowserHistory; - createHashHistory: typeof createHashHistory; - createMemoryHistory: typeof createMemoryHistory; - createLocation: typeof createLocation; - locationsAreEqual: typeof locationsAreEqual; - parsePath: typeof parsePath; - createPath: typeof createPath; -} - -export * from './createBrowserHistory'; -export * from './createHashHistory'; -export * from './createMemoryHistory'; -export { createLocation, locationsAreEqual } from './LocationUtils'; -export { parsePath, createPath } from './PathUtils'; -export { createBrowserHistory, createHashHistory, createMemoryHistory }; diff --git a/ui/@mf-types/shell/node_modules/@types/history/package.json b/ui/@mf-types/shell/node_modules/@types/history/package.json deleted file mode 100644 index bfa4663363..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/history/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@types/history", - "version": "4.7.11", - "description": "TypeScript definitions for history", - "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/history", - "license": "MIT", - "contributors": [ - { - "name": "Sergey Buturlakin", - "url": "https://github.com/sergey-buturlakin", - "githubUsername": "sergey-buturlakin" - }, - { - "name": "Nathan Brown", - "url": "https://github.com/ngbrown", - "githubUsername": "ngbrown" - }, - { - "name": "Young Rok Kim", - "url": "https://github.com/rokoroku", - "githubUsername": "rokoroku" - }, - { - "name": "Daniel Nixon", - "url": "https://github.com/danielnixon", - "githubUsername": "danielnixon" - } - ], - "main": "", - "types": "index.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", - "directory": "types/history" - }, - "scripts": {}, - "dependencies": {}, - "typesPublisherContentHash": "141516ba36ab9f2b221dc957cba4ac21d9a06776c05786e6773c5581f8cf7455", - "typeScriptVersion": "3.8" -} \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@types/react-router/index.d.ts b/ui/@mf-types/shell/node_modules/@types/react-router/index.d.ts deleted file mode 100644 index a19c916f1d..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/react-router/index.d.ts +++ /dev/null @@ -1,198 +0,0 @@ -// Type definitions for React Router 5.1 -// Project: https://github.com/ReactTraining/react-router -// Definitions by: Sergey Buturlakin -// Yuichi Murata -// Václav Ostrožlík -// Nathan Brown -// Alex Wendland -// Kostya Esmukov -// John Reilly -// Karol Janyst -// Dovydas Navickas -// Huy Nguyen -// Jérémy Fauvel -// Daniel Roth -// Egor Shulga -// Rahul Raina -// Duong Tran -// Ben Smith -// Wesley Tsai -// Sebastian Silbermann -// Nicholas Hehr -// Pawel Fajfer -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.8 - -import * as React from 'react'; -import * as H from 'history'; - -// This is the type of the context object that will be passed down to all children of -// a `Router` component: -export interface RouterChildContext { - router: { - history: H.History; - route: { - location: H.Location; - match: match; - }; - }; -} -export interface MemoryRouterProps { - children?: React.ReactNode; - initialEntries?: H.LocationDescriptor[] | undefined; - initialIndex?: number | undefined; - getUserConfirmation?: ((message: string, callback: (ok: boolean) => void) => void) | undefined; - keyLength?: number | undefined; -} - -export class MemoryRouter extends React.Component {} - -export interface PromptProps { - message: string | ((location: H.Location, action: H.Action) => string | boolean); - when?: boolean | undefined; -} -export class Prompt extends React.Component {} - -export interface RedirectProps { - to: H.LocationDescriptor; - push?: boolean | undefined; - from?: string | undefined; - path?: string | undefined; - exact?: boolean | undefined; - strict?: boolean | undefined; -} -export class Redirect extends React.Component {} - -export interface StaticContext { - statusCode?: number | undefined; -} - -export interface RouteComponentProps< - Params extends { [K in keyof Params]?: string } = {}, - C extends StaticContext = StaticContext, - S = H.LocationState, -> { - history: H.History; - location: H.Location; - match: match; - staticContext?: C | undefined; -} - -export interface RouteChildrenProps { - history: H.History; - location: H.Location; - match: match | null; -} - -export interface RouteProps< - Path extends string = string, - Params extends { [K: string]: string | undefined } = ExtractRouteParams, -> { - location?: H.Location | undefined; - component?: React.ComponentType> | React.ComponentType | undefined; - render?: ((props: RouteComponentProps) => React.ReactNode) | undefined; - children?: ((props: RouteChildrenProps) => React.ReactNode) | React.ReactNode | undefined; - path?: Path | readonly Path[] | undefined; - exact?: boolean | undefined; - sensitive?: boolean | undefined; - strict?: boolean | undefined; -} -export class Route extends React.Component< - RouteProps & OmitNative, - any -> {} - -export interface RouterProps { - children?: React.ReactNode; - history: H.History; -} -export class Router extends React.Component {} - -export interface StaticRouterContext extends StaticContext { - url?: string | undefined; - action?: 'PUSH' | 'REPLACE' | undefined; - location?: object | undefined; -} -export interface StaticRouterProps { - basename?: string | undefined; - children?: React.ReactNode; - location?: string | object | undefined; - context?: StaticRouterContext | undefined; -} - -export class StaticRouter extends React.Component {} -export interface SwitchProps { - children?: React.ReactNode | undefined; - location?: H.Location | undefined; -} -export class Switch extends React.Component {} - -export interface match { - params: Params; - isExact: boolean; - path: string; - url: string; -} - -// Omit taken from https://github.com/Microsoft/TypeScript/issues/28339#issuecomment-467220238 -export type Omit = T extends any ? Pick> : never; - -// Newer Omit type: as the previous one is being exported, removing it would be a breaking change -export type OmitNative = { [P in Exclude]: T[P] }; - -export function matchPath( - pathname: string, - props: string | string[] | RouteProps, - parent?: match | null, -): match | null; - -export type ExtractRouteOptionalParam = T extends `${infer Param}?` - ? { [k in Param]?: U } - : T extends `${infer Param}*` - ? { [k in Param]?: U } - : T extends `${infer Param}+` - ? { [k in Param]: U } - : { [k in T]: U }; - -export type ExtractRouteParams = string extends T - ? { [k in string]?: U } - : T extends `${infer _Start}:${infer ParamWithOptionalRegExp}/${infer Rest}` - ? ParamWithOptionalRegExp extends `${infer Param}(${infer _RegExp})${infer Modifier extends '?' | '+' | '*' | ''}` - ? ExtractRouteOptionalParam<`${Param}${Modifier}`, U> & ExtractRouteParams - : ExtractRouteOptionalParam & ExtractRouteParams - : T extends `${infer _Start}:${infer ParamWithOptionalRegExp}` - ? ParamWithOptionalRegExp extends `${infer Param}(${infer _RegExp})${infer Modifier extends '?' | '+' | '*' | ''}` - ? ExtractRouteOptionalParam<`${Param}${Modifier}`, U> - : ExtractRouteOptionalParam - : {}; - -export function generatePath(path: S, params?: ExtractRouteParams): string; - -export type WithRouterProps> = C extends React.ComponentClass - ? { wrappedComponentRef?: React.Ref> | undefined } - : {}; - -export interface WithRouterStatics> { - WrappedComponent: C; -} - -// There is a known issue in TypeScript, which doesn't allow decorators to change the signature of the classes -// they are decorating. Due to this, if you are using @withRouter decorator in your code, -// you will see a bunch of errors from TypeScript. The current workaround is to use withRouter() as a function call -// on a separate line instead of as a decorator. -export function withRouter

, C extends React.ComponentType

>( - component: C & React.ComponentType

, -): React.ComponentClass> & WithRouterProps> & WithRouterStatics; - -export const __RouterContext: React.Context; - -export function useHistory(): H.History; - -export function useLocation(): H.Location; - -export function useParams(): Params; - -export function useRouteMatch(): match; -export function useRouteMatch( - path: string | string[] | RouteProps, -): match | null; diff --git a/ui/@mf-types/shell/node_modules/@types/react-router/package.json b/ui/@mf-types/shell/node_modules/@types/react-router/package.json deleted file mode 100644 index 62529f517a..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/react-router/package.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "name": "@types/react-router", - "version": "5.1.20", - "description": "TypeScript definitions for React Router", - "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-router", - "license": "MIT", - "contributors": [ - { - "name": "Sergey Buturlakin", - "url": "https://github.com/sergey-buturlakin", - "githubUsername": "sergey-buturlakin" - }, - { - "name": "Yuichi Murata", - "url": "https://github.com/mrk21", - "githubUsername": "mrk21" - }, - { - "name": "Václav Ostrožlík", - "url": "https://github.com/vasek17", - "githubUsername": "vasek17" - }, - { - "name": "Nathan Brown", - "url": "https://github.com/ngbrown", - "githubUsername": "ngbrown" - }, - { - "name": "Alex Wendland", - "url": "https://github.com/awendland", - "githubUsername": "awendland" - }, - { - "name": "Kostya Esmukov", - "url": "https://github.com/KostyaEsmukov", - "githubUsername": "KostyaEsmukov" - }, - { - "name": "John Reilly", - "url": "https://github.com/johnnyreilly", - "githubUsername": "johnnyreilly" - }, - { - "name": "Karol Janyst", - "url": "https://github.com/LKay", - "githubUsername": "LKay" - }, - { - "name": "Dovydas Navickas", - "url": "https://github.com/DovydasNavickas", - "githubUsername": "DovydasNavickas" - }, - { - "name": "Huy Nguyen", - "url": "https://github.com/huy-nguyen", - "githubUsername": "huy-nguyen" - }, - { - "name": "Jérémy Fauvel", - "url": "https://github.com/grmiade", - "githubUsername": "grmiade" - }, - { - "name": "Daniel Roth", - "url": "https://github.com/DaIgeb", - "githubUsername": "DaIgeb" - }, - { - "name": "Egor Shulga", - "url": "https://github.com/egorshulga", - "githubUsername": "egorshulga" - }, - { - "name": "Rahul Raina", - "url": "https://github.com/rraina", - "githubUsername": "rraina" - }, - { - "name": "Duong Tran", - "url": "https://github.com/t49tran", - "githubUsername": "t49tran" - }, - { - "name": "Ben Smith", - "url": "https://github.com/8enSmith", - "githubUsername": "8enSmith" - }, - { - "name": "Wesley Tsai", - "url": "https://github.com/wezleytsai", - "githubUsername": "wezleytsai" - }, - { - "name": "Sebastian Silbermann", - "url": "https://github.com/eps1lon", - "githubUsername": "eps1lon" - }, - { - "name": "Nicholas Hehr", - "url": "https://github.com/HipsterBrown", - "githubUsername": "HipsterBrown" - }, - { - "name": "Pawel Fajfer", - "url": "https://github.com/pawfa", - "githubUsername": "pawfa" - } - ], - "main": "", - "types": "index.d.ts", - "typesVersions": { - "<=4.6": { - "*": [ - "ts4.6/*" - ] - } - }, - "repository": { - "type": "git", - "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", - "directory": "types/react-router" - }, - "scripts": {}, - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - }, - "typesPublisherContentHash": "471509be13705fc944e92092c64b94ac19712efd46cd3b0bfe38faefb539955f", - "typeScriptVersion": "4.2" -} \ No newline at end of file diff --git a/ui/@mf-types/shell/node_modules/@types/react-router/ts4.6/index.d.ts b/ui/@mf-types/shell/node_modules/@types/react-router/ts4.6/index.d.ts deleted file mode 100644 index 88c2bfe1f6..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/react-router/ts4.6/index.d.ts +++ /dev/null @@ -1,173 +0,0 @@ -import * as React from 'react'; -import * as H from 'history'; - -// This is the type of the context object that will be passed down to all children of -// a `Router` component: -export interface RouterChildContext { - router: { - history: H.History; - route: { - location: H.Location; - match: match; - }; - }; -} -export interface MemoryRouterProps { - children?: React.ReactNode; - initialEntries?: H.LocationDescriptor[] | undefined; - initialIndex?: number | undefined; - getUserConfirmation?: ((message: string, callback: (ok: boolean) => void) => void) | undefined; - keyLength?: number | undefined; -} - -export class MemoryRouter extends React.Component {} - -export interface PromptProps { - message: string | ((location: H.Location, action: H.Action) => string | boolean); - when?: boolean | undefined; -} -export class Prompt extends React.Component {} - -export interface RedirectProps { - to: H.LocationDescriptor; - push?: boolean | undefined; - from?: string | undefined; - path?: string | undefined; - exact?: boolean | undefined; - strict?: boolean | undefined; -} -export class Redirect extends React.Component {} - -export interface StaticContext { - statusCode?: number | undefined; -} - -export interface RouteComponentProps< - Params extends { [K in keyof Params]?: string } = {}, - C extends StaticContext = StaticContext, - S = H.LocationState, -> { - history: H.History; - location: H.Location; - match: match; - staticContext?: C | undefined; -} - -export interface RouteChildrenProps { - history: H.History; - location: H.Location; - match: match | null; -} - -export interface RouteProps< - Path extends string = string, - Params extends { [K: string]: string | undefined } = ExtractRouteParams, -> { - location?: H.Location | undefined; - component?: React.ComponentType> | React.ComponentType | undefined; - render?: ((props: RouteComponentProps) => React.ReactNode) | undefined; - children?: ((props: RouteChildrenProps) => React.ReactNode) | React.ReactNode | undefined; - path?: Path | readonly Path[] | undefined; - exact?: boolean | undefined; - sensitive?: boolean | undefined; - strict?: boolean | undefined; -} -export class Route extends React.Component< - RouteProps & OmitNative, - any -> {} - -export interface RouterProps { - children?: React.ReactNode; - history: H.History; -} -export class Router extends React.Component {} - -export interface StaticRouterContext extends StaticContext { - url?: string | undefined; - action?: 'PUSH' | 'REPLACE' | undefined; - location?: object | undefined; -} -export interface StaticRouterProps { - basename?: string | undefined; - children?: React.ReactNode; - location?: string | object | undefined; - context?: StaticRouterContext | undefined; -} - -export class StaticRouter extends React.Component {} -export interface SwitchProps { - children?: React.ReactNode | undefined; - location?: H.Location | undefined; -} -export class Switch extends React.Component {} - -export interface match { - params: Params; - isExact: boolean; - path: string; - url: string; -} - -// Omit taken from https://github.com/Microsoft/TypeScript/issues/28339#issuecomment-467220238 -export type Omit = T extends any ? Pick> : never; - -// Newer Omit type: as the previous one is being exported, removing it would be a breaking change -export type OmitNative = { [P in Exclude]: T[P] }; - -export function matchPath( - pathname: string, - props: string | string[] | RouteProps, - parent?: match | null, -): match | null; - -export type ExtractRouteOptionalParam = T extends `${infer Param}?` - ? { [k in Param]?: U } - : T extends `${infer Param}*` - ? { [k in Param]?: U } - : T extends `${infer Param}+` - ? { [k in Param]: U } - : { [k in T]: U }; - -export type ExtractRouteParams = string extends T - ? { [k in string]?: U } - : T extends `${infer _Start}:${infer ParamWithOptionalRegExp}/${infer Rest}` - ? ParamWithOptionalRegExp extends `${infer Param}(${infer _RegExp})` - ? ExtractRouteOptionalParam & ExtractRouteParams - : ExtractRouteOptionalParam & ExtractRouteParams - : T extends `${infer _Start}:${infer ParamWithOptionalRegExp}` - ? ParamWithOptionalRegExp extends `${infer Param}(${infer _RegExp})` - ? ExtractRouteOptionalParam - : ExtractRouteOptionalParam - : {}; - -export function generatePath(path: S, params?: ExtractRouteParams): string; - -export type WithRouterProps> = C extends React.ComponentClass - ? { wrappedComponentRef?: React.Ref> | undefined } - : {}; - -export interface WithRouterStatics> { - WrappedComponent: C; -} - -// There is a known issue in TypeScript, which doesn't allow decorators to change the signature of the classes -// they are decorating. Due to this, if you are using @withRouter decorator in your code, -// you will see a bunch of errors from TypeScript. The current workaround is to use withRouter() as a function call -// on a separate line instead of as a decorator. -export function withRouter

, C extends React.ComponentType

>( - component: C & React.ComponentType

, -): React.ComponentClass> & WithRouterProps> & WithRouterStatics; - -export const __RouterContext: React.Context; - -export function useHistory(): H.History; - -export function useLocation(): H.Location; - -export function useParams(): Params; - -export function useRouteMatch(): match; -export function useRouteMatch( - path: string | string[] | RouteProps, -): match | null; diff --git a/ui/@mf-types/shell/node_modules/@types/react/experimental.d.ts b/ui/@mf-types/shell/node_modules/@types/react/experimental.d.ts deleted file mode 100644 index 7fb22dbda0..0000000000 --- a/ui/@mf-types/shell/node_modules/@types/react/experimental.d.ts +++ /dev/null @@ -1,192 +0,0 @@ -/** - * These are types for things that are present in the `experimental` builds of React but not yet - * on a stable build. - * - * Once they are promoted to stable they can just be moved to the main index file. - * - * To load the types declared here in an actual project, there are three ways. The easiest one, - * if your `tsconfig.json` already has a `"types"` array in the `"compilerOptions"` section, - * is to add `"react/experimental"` to the `"types"` array. - * - * Alternatively, a specific import syntax can to be used from a typescript file. - * This module does not exist in reality, which is why the {} is important: - * - * ```ts - * import {} from 'react/experimental' - * ``` - * - * It is also possible to include it through a triple-slash reference: - * - * ```ts - * /// - * ``` - * - * Either the import or the reference only needs to appear once, anywhere in the project. - */ - -// See https://github.com/facebook/react/blob/master/packages/react/src/React.js to see how the exports are declared, -// and https://github.com/facebook/react/blob/master/packages/shared/ReactFeatureFlags.js to verify which APIs are -// flagged experimental or not. Experimental APIs will be tagged with `__EXPERIMENTAL__`. -// -// For the inputs of types exported as simply a fiber tag, the `beginWork` function of ReactFiberBeginWork.js -// is a good place to start looking for details; it generally calls prop validation functions or delegates -// all tasks done as part of the render phase (the concurrent part of the React update cycle). -// -// Suspense-related handling can be found in ReactFiberThrow.js. - -import React = require('.'); - -export {}; - -declare const UNDEFINED_VOID_ONLY: unique symbol; -type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never }; - -declare module '.' { - export interface SuspenseProps { - /** - * The presence of this prop indicates that the content is computationally expensive to render. - * In other words, the tree is CPU bound and not I/O bound (e.g. due to fetching data). - * @see {@link https://github.com/facebook/react/pull/19936} - */ - unstable_expectedLoadTime?: number; - } - - export type SuspenseListRevealOrder = 'forwards' | 'backwards' | 'together'; - export type SuspenseListTailMode = 'collapsed' | 'hidden'; - - export interface SuspenseListCommonProps { - /** - * Note that SuspenseList require more than one child; - * it is a runtime warning to provide only a single child. - * - * It does, however, allow those children to be wrapped inside a single - * level of ``. - */ - children: ReactElement | Iterable; - } - - interface DirectionalSuspenseListProps extends SuspenseListCommonProps { - /** - * Defines the order in which the `SuspenseList` children should be revealed. - */ - revealOrder: 'forwards' | 'backwards'; - /** - * Dictates how unloaded items in a SuspenseList is shown. - * - * - By default, `SuspenseList` will show all fallbacks in the list. - * - `collapsed` shows only the next fallback in the list. - * - `hidden` doesn’t show any unloaded items. - */ - tail?: SuspenseListTailMode; - } - - interface NonDirectionalSuspenseListProps extends SuspenseListCommonProps { - /** - * Defines the order in which the `SuspenseList` children should be revealed. - */ - revealOrder?: Exclude; - /** - * The tail property is invalid when not using the `forwards` or `backwards` reveal orders. - */ - tail?: never; - } - - export type SuspenseListProps = DirectionalSuspenseListProps | NonDirectionalSuspenseListProps; - - /** - * `SuspenseList` helps coordinate many components that can suspend by orchestrating the order - * in which these components are revealed to the user. - * - * When multiple components need to fetch data, this data may arrive in an unpredictable order. - * However, if you wrap these items in a `SuspenseList`, React will not show an item in the list - * until previous items have been displayed (this behavior is adjustable). - * - * @see https://reactjs.org/docs/concurrent-mode-reference.html#suspenselist - * @see https://reactjs.org/docs/concurrent-mode-patterns.html#suspenselist - */ - export const unstable_SuspenseList: ExoticComponent; - - export interface SuspenseConfig { - busyDelayMs?: number; - busyMinDurationMs?: number; - } - - // undocumented, considered for removal - export function unstable_withSuspenseConfig( - scope: () => VoidOrUndefinedOnly, - config: SuspenseConfig | null | undefined, - ): void; - - // must be synchronous - export type TransitionFunction = () => VoidOrUndefinedOnly; - // strange definition to allow vscode to show documentation on the invocation - export interface TransitionStartFunction { - /** - * State updates caused inside the callback are allowed to be deferred. - * - * **If some state update causes a component to suspend, that state update should be wrapped in a transition.** - * - * @param callback A _synchronous_ function which causes state updates that can be deferred. - */ - (callback: TransitionFunction): void; - } - - /** - * Returns a deferred version of the value that may “lag behind” it for at most `timeoutMs`. - * - * This is commonly used to keep the interface responsive when you have something that renders immediately - * based on user input and something that needs to wait for a data fetch. - * - * A good example of this is a text input. - * - * @param value The value that is going to be deferred - * - * @see https://reactjs.org/docs/concurrent-mode-reference.html#usedeferredvalue - */ - export function unstable_useDeferredValue(value: T): T; - - /** - * Allows components to avoid undesirable loading states by waiting for content to load - * before transitioning to the next screen. It also allows components to defer slower, - * data fetching updates until subsequent renders so that more crucial updates can be - * rendered immediately. - * - * The `useTransition` hook returns two values in an array. - * - * The first is a function that takes a callback. We can use it to tell React which state we want to defer. - * The seconda boolean. It’s React’s way of informing us whether we’re waiting for the transition to finish. - * - * **If some state update causes a component to suspend, that state update should be wrapped in a transition.** - * - * @param config An optional object with `timeoutMs` - * - * @see https://reactjs.org/docs/concurrent-mode-reference.html#usetransition - */ - export function unstable_useTransition(config?: SuspenseConfig | null): [TransitionStartFunction, boolean]; - - const opaqueIdentifierBranding: unique symbol; - /** - * WARNING: Don't use this as a `string`. - * - * This is an opaque type that is not supposed to type-check structurally. - * It is only valid if returned from React methods and passed to React e.g. `

} /> + } /> + , ); @@ -259,6 +255,13 @@ describe('', () => { await act(async () => { await userEvent.click(selectors.authSelect.authClick()); + }); + + await waitFor(() => { + expect(selectors.authSelect.optionCramMd5()).toBeInTheDocument(); + }); + + await act(async () => { await userEvent.click(selectors.authSelect.optionCramMd5()); }); @@ -268,6 +271,13 @@ describe('', () => { await act(async () => { await userEvent.click(selectors.authSelect.authClick()); + }); + + await waitFor(() => { + expect(selectors.authSelect.optionPlain()).toBeInTheDocument(); + }); + + await act(async () => { await userEvent.click(selectors.authSelect.optionPlain()); }); @@ -355,8 +365,18 @@ describe('', () => { it('show errors on submit with not all required field', async () => { await commonSetup(); + await waitFor(() => { + expect(selectors.enableConfiguration()).toBeInTheDocument(); + }); await act(async () => { await userEvent.click(selectors.enableConfiguration()); + }); + + await waitFor(() => { + expect(selectors.saveButton()).toBeInTheDocument(); + }); + + await act(async () => { await userEvent.click(selectors.saveButton()); }); @@ -403,7 +423,13 @@ describe('', () => { selectors.recipient(), 'user1@test.com, user2@test.com', ); + }); + + await waitFor(() => { + expect(selectors.saveButton()).toBeInTheDocument(); + }); + await act(async () => { await userEvent.click(selectors.saveButton()); }); @@ -460,19 +486,38 @@ spec: ); await userEvent.clear(selectors.port()); await userEvent.type(selectors.port(), '22'); + }); + await waitFor(() => { + expect(selectors.authSelect.authClick()).toBeInTheDocument(); + }); + + await act(async () => { await userEvent.click(selectors.authSelect.authClick()); + }); + + await waitFor(() => { + expect(selectors.authSelect.optionNoAuth()).toBeInTheDocument(); + }); + + await act(async () => { await userEvent.click(selectors.authSelect.optionNoAuth()); + }); - await userEvent.clear(selectors.sender()); - await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); + await userEvent.clear(selectors.sender()); + await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); - await userEvent.clear(selectors.recipient()); - await userEvent.type( - selectors.recipient(), - 'user1@test.com, user2@test.com', - ); + await userEvent.clear(selectors.recipient()); + await userEvent.type( + selectors.recipient(), + 'user1@test.com, user2@test.com', + ); + await waitFor(() => { + expect(selectors.saveButton()).toBeInTheDocument(); + }); + + await act(async () => { await userEvent.click(selectors.saveButton()); }); @@ -542,7 +587,13 @@ spec: selectors.recipient(), 'user1@test.com, user2@test.com', ); + }); + await waitFor(() => { + expect(selectors.saveButton()).toBeInTheDocument(); + }); + + await act(async () => { await userEvent.click(selectors.saveButton()); }); @@ -602,21 +653,21 @@ spec: 'smtp4dev.default.svc.cluster.local', ); await userEvent.type(selectors.port(), '42'); + }); - await userEvent.click(selectors.authSelect.authClick()); - await userEvent.click(selectors.authSelect.optionLogin()); + await userEvent.click(selectors.authSelect.authClick()); + await userEvent.click(selectors.authSelect.optionLogin()); - await userEvent.type(selectors.username(), 'Renard'); - await userEvent.type(selectors.password(), 'Renard Password'); + await userEvent.type(selectors.username(), 'Renard'); + await userEvent.type(selectors.password(), 'Renard Password'); - await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); - await userEvent.type( - selectors.recipient(), - 'user1@test.com, user2@test.com', - ); + await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); + await userEvent.type( + selectors.recipient(), + 'user1@test.com, user2@test.com', + ); - await userEvent.click(selectors.saveButton()); - }); + await userEvent.click(selectors.saveButton()); await waitForElementToBeRemoved(() => { return screen.getByText(/Saving\.\.\./); @@ -670,21 +721,21 @@ spec: 'smtp4dev.default.svc.cluster.local', ); await userEvent.type(selectors.port(), '42'); + }); - await userEvent.click(selectors.authSelect.authClick()); - await userEvent.click(selectors.authSelect.optionCramMd5()); + await userEvent.click(selectors.authSelect.authClick()); + await userEvent.click(selectors.authSelect.optionCramMd5()); - await userEvent.type(selectors.username(), 'Renard'); - await userEvent.type(selectors.secret(), 'xxxyyyzzz-secret'); + await userEvent.type(selectors.username(), 'Renard'); + await userEvent.type(selectors.secret(), 'xxxyyyzzz-secret'); - await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); - await userEvent.type( - selectors.recipient(), - 'user1@test.com, user2@test.com', - ); + await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); + await userEvent.type( + selectors.recipient(), + 'user1@test.com, user2@test.com', + ); - await userEvent.click(selectors.saveButton()); - }); + await userEvent.click(selectors.saveButton()); await waitForElementToBeRemoved(() => { return screen.getByText(/Saving\.\.\./); @@ -738,22 +789,21 @@ spec: 'smtp4dev.default.svc.cluster.local', ); await userEvent.type(selectors.port(), '42'); + }); + await userEvent.click(selectors.authSelect.authClick()); + await userEvent.click(selectors.authSelect.optionPlain()); - await userEvent.click(selectors.authSelect.authClick()); - await userEvent.click(selectors.authSelect.optionPlain()); - - await userEvent.type(selectors.identity(), 'RenardID'); - await userEvent.type(selectors.username(), 'Renard'); - await userEvent.type(selectors.password(), 'xxxyyyzzz-password'); + await userEvent.type(selectors.identity(), 'RenardID'); + await userEvent.type(selectors.username(), 'Renard'); + await userEvent.type(selectors.password(), 'xxxyyyzzz-password'); - await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); - await userEvent.type( - selectors.recipient(), - 'user1@test.com, user2@test.com', - ); + await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); + await userEvent.type( + selectors.recipient(), + 'user1@test.com, user2@test.com', + ); - await userEvent.click(selectors.saveButton()); - }); + await userEvent.click(selectors.saveButton()); await waitForElementToBeRemoved(() => { return screen.getByText(/Saving\.\.\./); @@ -876,21 +926,20 @@ spec: 'smtp4dev.default.svc.cluster.local', ); await userEvent.type(selectors.port(), '42'); + }); + await userEvent.click(selectors.authSelect.authClick()); + await userEvent.click(selectors.authSelect.optionLogin()); - await userEvent.click(selectors.authSelect.authClick()); - await userEvent.click(selectors.authSelect.optionLogin()); - - await userEvent.type(selectors.username(), 'Renard'); - await userEvent.type(selectors.password(), 'Renard Password'); + await userEvent.type(selectors.username(), 'Renard'); + await userEvent.type(selectors.password(), 'Renard Password'); - await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); - await userEvent.type( - selectors.recipient(), - 'user1@test.com, user2@test.com', - ); + await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); + await userEvent.type( + selectors.recipient(), + 'user1@test.com, user2@test.com', + ); - await userEvent.click(selectors.sendTestingEmailButton()); - }); + await userEvent.click(selectors.sendTestingEmailButton()); expect(selectors.sendTestingEmailButton()).toBeDisabled(); await waitForElementToBeRemoved(() => { @@ -950,22 +999,22 @@ spec: 'smtp4dev.default.svc.cluster.local', ); await userEvent.type(selectors.port(), '42'); + }); - await userEvent.click(selectors.authSelect.authClick()); - await userEvent.click(selectors.authSelect.optionPlain()); + await userEvent.click(selectors.authSelect.authClick()); + await userEvent.click(selectors.authSelect.optionPlain()); - await userEvent.type(selectors.identity(), 'Renard ID'); - await userEvent.type(selectors.username(), 'Renard'); - await userEvent.type(selectors.password(), 'Renard Password'); + await userEvent.type(selectors.identity(), 'Renard ID'); + await userEvent.type(selectors.username(), 'Renard'); + await userEvent.type(selectors.password(), 'Renard Password'); - await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); - await userEvent.type( - selectors.recipient(), - 'user1@test.com, user2@test.com', - ); + await userEvent.type(selectors.sender(), 'renard.admin@scality.com'); + await userEvent.type( + selectors.recipient(), + 'user1@test.com, user2@test.com', + ); - await userEvent.click(selectors.sendTestingEmailButton()); - }); + await userEvent.click(selectors.sendTestingEmailButton()); expect(selectors.sendTestingEmailButton()).toBeDisabled(); await waitForElementToBeRemoved(() => { diff --git a/ui/src/alert-configuration/ConfigureAlerting.tsx b/ui/src/alert-configuration/ConfigureAlerting.tsx index 4b8322b310..84bad31319 100644 --- a/ui/src/alert-configuration/ConfigureAlerting.tsx +++ b/ui/src/alert-configuration/ConfigureAlerting.tsx @@ -18,7 +18,6 @@ import { Box, Button, Input, Select } from '@scality/core-ui/dist/next'; import { useEffect, useRef } from 'react'; import { Controller, useForm } from 'react-hook-form'; import { useDispatch } from 'react-redux'; -import { useHistory } from 'react-router'; import { useTheme } from 'styled-components'; import { useAuth } from '../containers/PrivateRoute'; @@ -33,6 +32,7 @@ import { useTestAlertConfiguration, } from './domain/AlertConfigurationDomain'; import { Metalk8sCSCAlertConfigurationStore } from './infrastructure/Metalk8sCSCAlertConfigurationStore'; +import { useBasenameRelativeNavigate } from '@scality/module-federation'; const LogsBanner = ({ logs }: { logs: PromiseResult }) => { const firstLog = @@ -116,7 +116,7 @@ const schema = Joi.object({ export default function ConfigureAlerting() { const theme = useTheme(); - const history = useHistory(); + const navigate = useBasenameRelativeNavigate(); const dispatch = useDispatch(); const { register, @@ -165,7 +165,7 @@ export default function ConfigureAlerting() { message: 'The email notification configuration has been saved', }), ); - history.push('/alerts'); + navigate('/alerts'); } }, [editAlertMutation.status]); @@ -215,7 +215,7 @@ export default function ConfigureAlerting() {