diff --git a/webapp/package-lock.json b/webapp/package-lock.json index c85c284dcc..1f4465e50a 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -27,10 +27,10 @@ "mattermost-redux": "10.9.0", "parse-duration": "2.1.4", "qs": "6.10.5", - "react": "^17.0.2", + "react": "^18.0.0", "react-chartjs-2": "4.3.1", "react-custom-scrollbars": "4.2.1", - "react-dom": "^17.0.2", + "react-dom": "^18.0.0", "react-infinite-scroll-component": "^6.1.0", "react-infinite-scroller": "1.2.6", "react-intl": "7.1.11", @@ -60,17 +60,16 @@ "@types/lodash": "4.14.178", "@types/luxon": "3.6.2", "@types/qs": "6.9.7", - "@types/react": "^17.0.2", + "@types/react": "^18.0.0", "@types/react-beautiful-dnd": "13.1.2", - "@types/react-bootstrap": "1.0.1", "@types/react-custom-scrollbars": "4.0.10", - "@types/react-dom": "^17.0.2", + "@types/react-dom": "^18.0.0", "@types/react-infinite-scroller": "1.2.3", "@types/react-redux": "7.1.21", "@types/react-router-dom": "5.3.3", "@types/react-router-hash-link": "2.4.5", "@types/react-select": "3.1.2", - "@types/react-test-renderer": "17.0.1", + "@types/react-test-renderer": "18.0.0", "@types/redux-mock-store": "1.0.3", "@types/shallow-equals": "1.0.0", "@types/styled-components": "5.1.26", @@ -105,9 +104,8 @@ "postcss-styled-syntax": "0.7.1", "process": "0.11.10", "react-beautiful-dnd": "13.1.0", - "react-bootstrap": "1.6.1", "react-refresh": "0.11.0", - "react-test-renderer": "17.0.2", + "react-test-renderer": "18.0.0", "redux-mock-store": "1.5.4", "redux-thunk": "2.4.1", "sass": "1.46.0", @@ -5345,25 +5343,6 @@ "integrity": "sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==", "dev": true }, - "node_modules/@restart/context": { - "version": "2.1.4", - "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", - "dev": true, - "peerDependencies": { - "react": ">=16.3.2" - } - }, - "node_modules/@restart/hooks": { - "version": "0.3.27", - "integrity": "sha512-s984xV/EapUIfkjlf8wz9weP2O9TNKR96C68FfMEy2bE69+H4cNv3RD4Mf97lW7Htt7PjZrYTjSC8f3SB9VCXw==", - "dev": true, - "dependencies": { - "dequal": "^2.0.2" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -5732,11 +5711,6 @@ "@types/node": "*" } }, - "node_modules/@types/invariant": { - "version": "2.2.35", - "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==", - "dev": true - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -5871,12 +5845,11 @@ "dev": true }, "node_modules/@types/react": { - "version": "17.0.52", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", - "integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", + "version": "18.3.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.26.tgz", + "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, @@ -5888,11 +5861,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-bootstrap": { - "version": "1.0.1", - "integrity": "sha512-n68SeFrpOFWiSN2DCpyn17ZwTZzY8+mio8E9oCrl7abHytUz3r7ZYIKPxaETHYQxCi8oxF3NultpMAyBxFIjhg==", - "dev": true - }, "node_modules/@types/react-custom-scrollbars": { "version": "4.0.10", "integrity": "sha512-1T430E+usndUjymkXB8k/zGpWehggircq/QaQMuFLMJceccAcD9vcmbUXF1LjeVP/+P4wI/bad6BF1E+7IGlqA==", @@ -5902,12 +5870,12 @@ } }, "node_modules/@types/react-dom": { - "version": "17.0.18", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.18.tgz", - "integrity": "sha512-rLVtIfbwyur2iFKykP2w0pl/1unw26b5td16d5xMgp7/yjTHomkyxPYChFoCr/FtEX1lN9wY6lFj1qvKdS5kDw==", + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "dev": true, - "dependencies": { - "@types/react": "^17" + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@types/react-infinite-scroller": { @@ -5984,8 +5952,9 @@ } }, "node_modules/@types/react-test-renderer": { - "version": "17.0.1", - "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz", + "integrity": "sha512-C7/5FBJ3g3sqUahguGi03O79b8afNeSD6T8/GU50oQrJCU0bVCCGQHaGKUbg2Ce8VQEEqTw8/HiS6lXHHdgkdQ==", "dev": true, "dependencies": { "@types/react": "*" @@ -6012,10 +5981,6 @@ "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", "dev": true }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, "node_modules/@types/semver": { "version": "7.7.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", @@ -6075,11 +6040,6 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "dev": true }, - "node_modules/@types/warning": { - "version": "3.0.0", - "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=", - "dev": true - }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", @@ -8901,14 +8861,6 @@ "node": ">= 0.6.0" } }, - "node_modules/dequal": { - "version": "2.0.2", - "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -16750,18 +16702,6 @@ "react-is": "^16.13.1" } }, - "node_modules/prop-types-extra": { - "version": "1.1.1", - "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", - "dev": true, - "dependencies": { - "react-is": "^16.3.2", - "warning": "^4.0.0" - }, - "peerDependencies": { - "react": ">=0.14.0" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -16934,12 +16874,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" @@ -16963,53 +16902,6 @@ "react-dom": "^16.8.5 || ^17.0.0" } }, - "node_modules/react-bootstrap": { - "version": "1.6.1", - "integrity": "sha512-ojEPQ6OtyIMdLg0Smofk+85PKN6MLKQX3bU0Vwmok/4yNa8DQ2vCGhO2IgHJvT+ERQZ4X+gAQcdn6msAHSwLBg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.14.0", - "@restart/context": "^2.1.4", - "@restart/hooks": "^0.3.26", - "@types/invariant": "^2.2.33", - "@types/prop-types": "^15.7.3", - "@types/react": ">=16.14.8", - "@types/react-transition-group": "^4.4.1", - "@types/warning": "^3.0.0", - "classnames": "^2.3.1", - "dom-helpers": "^5.2.1", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "prop-types-extra": "^1.1.0", - "react-overlays": "^5.0.1", - "react-transition-group": "^4.4.1", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/react-bootstrap/node_modules/react-overlays": { - "version": "5.1.1", - "integrity": "sha512-eCN2s2/+GVZzpnId4XVWtvDPYYBD2EtOGP74hE+8yDskPzFy9+pV1H3ZZihxuRdEbQzzacySaaDkR7xE0ydl4Q==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.8", - "@popperjs/core": "^2.8.6", - "@restart/hooks": "^0.3.26", - "@types/warning": "^3.0.0", - "dom-helpers": "^5.2.0", - "prop-types": "^15.7.2", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - }, - "peerDependencies": { - "react": ">=16.3.0", - "react-dom": ">=16.3.0" - } - }, "node_modules/react-chartjs-2": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz", @@ -17034,16 +16926,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-error-boundary": { @@ -17165,11 +17056,6 @@ "version": "16.13.1", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", - "dev": true - }, "node_modules/react-redux": { "version": "7.2.6", "integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==", @@ -17284,24 +17170,34 @@ } }, "node_modules/react-test-renderer": { - "version": "17.0.2", - "integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.0.0.tgz", + "integrity": "sha512-SyZTP/FSkwfiKOZuTZiISzsrC8A80KNlQ8PyyoGoOq+VzMAab6Em1POK/CiX3+XyXG6oiJa1C53zYDbdrJu9fw==", "dev": true, "dependencies": { - "object-assign": "^4.1.1", - "react-is": "^17.0.2", + "react-is": "^18.0.0", "react-shallow-renderer": "^16.13.1", - "scheduler": "^0.20.2" + "scheduler": "^0.21.0" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.0.0" } }, "node_modules/react-test-renderer/node_modules/react-is": { - "version": "17.0.2", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, + "node_modules/react-test-renderer/node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.2", "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", @@ -17882,12 +17778,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": { @@ -19833,20 +19728,6 @@ "node": ">=0.10.0" } }, - "node_modules/uncontrollable": { - "version": "7.2.1", - "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.6.3", - "@types/react": ">=16.9.11", - "invariant": "^2.2.4", - "react-lifecycles-compat": "^3.0.4" - }, - "peerDependencies": { - "react": ">=15.0.0" - } - }, "node_modules/undici": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/undici/-/undici-5.12.0.tgz", @@ -20125,14 +20006,6 @@ "makeerror": "1.0.12" } }, - "node_modules/warning": { - "version": "4.0.3", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/watchpack": { "version": "2.3.1", "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", @@ -24825,19 +24698,6 @@ "integrity": "sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==", "dev": true }, - "@restart/context": { - "version": "2.1.4", - "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", - "dev": true - }, - "@restart/hooks": { - "version": "0.3.27", - "integrity": "sha512-s984xV/EapUIfkjlf8wz9weP2O9TNKR96C68FfMEy2bE69+H4cNv3RD4Mf97lW7Htt7PjZrYTjSC8f3SB9VCXw==", - "dev": true, - "requires": { - "dequal": "^2.0.2" - } - }, "@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -25139,11 +24999,6 @@ "@types/node": "*" } }, - "@types/invariant": { - "version": "2.2.35", - "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==", - "dev": true - }, "@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -25278,12 +25133,11 @@ "dev": true }, "@types/react": { - "version": "17.0.52", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", - "integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", + "version": "18.3.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.26.tgz", + "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==", "requires": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, @@ -25295,11 +25149,6 @@ "@types/react": "*" } }, - "@types/react-bootstrap": { - "version": "1.0.1", - "integrity": "sha512-n68SeFrpOFWiSN2DCpyn17ZwTZzY8+mio8E9oCrl7abHytUz3r7ZYIKPxaETHYQxCi8oxF3NultpMAyBxFIjhg==", - "dev": true - }, "@types/react-custom-scrollbars": { "version": "4.0.10", "integrity": "sha512-1T430E+usndUjymkXB8k/zGpWehggircq/QaQMuFLMJceccAcD9vcmbUXF1LjeVP/+P4wI/bad6BF1E+7IGlqA==", @@ -25309,13 +25158,10 @@ } }, "@types/react-dom": { - "version": "17.0.18", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.18.tgz", - "integrity": "sha512-rLVtIfbwyur2iFKykP2w0pl/1unw26b5td16d5xMgp7/yjTHomkyxPYChFoCr/FtEX1lN9wY6lFj1qvKdS5kDw==", - "dev": true, - "requires": { - "@types/react": "^17" - } + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true }, "@types/react-infinite-scroller": { "version": "1.2.3", @@ -25395,8 +25241,9 @@ } }, "@types/react-test-renderer": { - "version": "17.0.1", - "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz", + "integrity": "sha512-C7/5FBJ3g3sqUahguGi03O79b8afNeSD6T8/GU50oQrJCU0bVCCGQHaGKUbg2Ce8VQEEqTw8/HiS6lXHHdgkdQ==", "dev": true, "requires": { "@types/react": "*" @@ -25423,10 +25270,6 @@ "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", "dev": true }, - "@types/scheduler": { - "version": "0.16.2", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, "@types/semver": { "version": "7.7.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", @@ -25486,11 +25329,6 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "dev": true }, - "@types/warning": { - "version": "3.0.0", - "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=", - "dev": true - }, "@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", @@ -27613,11 +27451,6 @@ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true }, - "dequal": { - "version": "2.0.2", - "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==", - "dev": true - }, "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -33503,15 +33336,6 @@ "react-is": "^16.13.1" } }, - "prop-types-extra": { - "version": "1.1.1", - "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", - "dev": true, - "requires": { - "react-is": "^16.3.2", - "warning": "^4.0.0" - } - }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -33633,12 +33457,11 @@ } }, "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "react-beautiful-dnd": { @@ -33655,47 +33478,6 @@ "use-memo-one": "^1.1.1" } }, - "react-bootstrap": { - "version": "1.6.1", - "integrity": "sha512-ojEPQ6OtyIMdLg0Smofk+85PKN6MLKQX3bU0Vwmok/4yNa8DQ2vCGhO2IgHJvT+ERQZ4X+gAQcdn6msAHSwLBg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.14.0", - "@restart/context": "^2.1.4", - "@restart/hooks": "^0.3.26", - "@types/invariant": "^2.2.33", - "@types/prop-types": "^15.7.3", - "@types/react": ">=16.14.8", - "@types/react-transition-group": "^4.4.1", - "@types/warning": "^3.0.0", - "classnames": "^2.3.1", - "dom-helpers": "^5.2.1", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "prop-types-extra": "^1.1.0", - "react-overlays": "^5.0.1", - "react-transition-group": "^4.4.1", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - }, - "dependencies": { - "react-overlays": { - "version": "5.1.1", - "integrity": "sha512-eCN2s2/+GVZzpnId4XVWtvDPYYBD2EtOGP74hE+8yDskPzFy9+pV1H3ZZihxuRdEbQzzacySaaDkR7xE0ydl4Q==", - "dev": true, - "requires": { - "@babel/runtime": "^7.13.8", - "@popperjs/core": "^2.8.6", - "@restart/hooks": "^0.3.26", - "@types/warning": "^3.0.0", - "dom-helpers": "^5.2.0", - "prop-types": "^15.7.2", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - } - } - } - }, "react-chartjs-2": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz", @@ -33712,13 +33494,12 @@ } }, "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "requires": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" } }, "react-error-boundary": { @@ -33817,11 +33598,6 @@ "version": "16.13.1", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "react-lifecycles-compat": { - "version": "3.0.4", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", - "dev": true - }, "react-redux": { "version": "7.2.6", "integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==", @@ -33907,20 +33683,30 @@ } }, "react-test-renderer": { - "version": "17.0.2", - "integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.0.0.tgz", + "integrity": "sha512-SyZTP/FSkwfiKOZuTZiISzsrC8A80KNlQ8PyyoGoOq+VzMAab6Em1POK/CiX3+XyXG6oiJa1C53zYDbdrJu9fw==", "dev": true, "requires": { - "object-assign": "^4.1.1", - "react-is": "^17.0.2", + "react-is": "^18.0.0", "react-shallow-renderer": "^16.13.1", - "scheduler": "^0.20.2" + "scheduler": "^0.21.0" }, "dependencies": { "react-is": { - "version": "17.0.2", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true + }, + "scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0" + } } } }, @@ -34344,12 +34130,11 @@ } }, "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "schema-utils": { @@ -35781,17 +35566,6 @@ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "dev": true }, - "uncontrollable": { - "version": "7.2.1", - "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.6.3", - "@types/react": ">=16.9.11", - "invariant": "^2.2.4", - "react-lifecycles-compat": "^3.0.4" - } - }, "undici": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/undici/-/undici-5.12.0.tgz", @@ -36006,14 +35780,6 @@ "makeerror": "1.0.12" } }, - "warning": { - "version": "4.0.3", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "watchpack": { "version": "2.3.1", "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", diff --git a/webapp/package.json b/webapp/package.json index 703d58c657..7e90821e49 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -27,10 +27,10 @@ "mattermost-redux": "10.9.0", "parse-duration": "2.1.4", "qs": "6.10.5", - "react": "^17.0.2", + "react": "^18.0.0", "react-chartjs-2": "4.3.1", "react-custom-scrollbars": "4.2.1", - "react-dom": "^17.0.2", + "react-dom": "^18.0.0", "react-infinite-scroll-component": "^6.1.0", "react-infinite-scroller": "1.2.6", "react-intl": "7.1.11", @@ -60,17 +60,16 @@ "@types/lodash": "4.14.178", "@types/luxon": "3.6.2", "@types/qs": "6.9.7", - "@types/react": "^17.0.2", + "@types/react": "^18.0.0", "@types/react-beautiful-dnd": "13.1.2", - "@types/react-bootstrap": "1.0.1", "@types/react-custom-scrollbars": "4.0.10", - "@types/react-dom": "^17.0.2", + "@types/react-dom": "^18.0.0", "@types/react-infinite-scroller": "1.2.3", "@types/react-redux": "7.1.21", "@types/react-router-dom": "5.3.3", "@types/react-router-hash-link": "2.4.5", "@types/react-select": "3.1.2", - "@types/react-test-renderer": "17.0.1", + "@types/react-test-renderer": "18.0.0", "@types/redux-mock-store": "1.0.3", "@types/shallow-equals": "1.0.0", "@types/styled-components": "5.1.26", @@ -105,9 +104,8 @@ "postcss-styled-syntax": "0.7.1", "process": "0.11.10", "react-beautiful-dnd": "13.1.0", - "react-bootstrap": "1.6.1", "react-refresh": "0.11.0", - "react-test-renderer": "17.0.2", + "react-test-renderer": "18.0.0", "redux-mock-store": "1.5.4", "redux-thunk": "2.4.1", "sass": "1.46.0", @@ -123,8 +121,8 @@ }, "overrides": { "react-custom-scrollbars": { - "react": "17.0.2", - "react-dom": "17.0.2" + "react": "18.0.0", + "react-dom": "18.0.0" } }, "scripts": { @@ -190,6 +188,9 @@ "setupFiles": [ "jest-canvas-mock" ], + "setupFilesAfterEnv": [ + "/src/setupTests.ts" + ], "testEnvironmentOptions": { "url": "http://localhost:8065" } diff --git a/webapp/src/components/actions_modal.tsx b/webapp/src/components/actions_modal.tsx index 6b3695663a..a859aa6fc2 100644 --- a/webapp/src/components/actions_modal.tsx +++ b/webapp/src/components/actions_modal.tsx @@ -3,12 +3,13 @@ import React from 'react'; import {useIntl} from 'react-intl'; -import {Modal} from 'react-bootstrap'; import styled from 'styled-components'; import {LightningBoltOutlineIcon} from '@mattermost/compass-icons/components'; +import {Modal} from 'src/externals/react-bootstrap'; + import GenericModal, {DefaultFooterContainer, ModalSubheading} from 'src/components/widgets/generic_modal'; interface Props { diff --git a/webapp/src/components/backstage/playbook_edit/automation/menu_list.tsx b/webapp/src/components/backstage/playbook_edit/automation/menu_list.tsx index a7ac51f6d7..b6b6bbbd84 100644 --- a/webapp/src/components/backstage/playbook_edit/automation/menu_list.tsx +++ b/webapp/src/components/backstage/playbook_edit/automation/menu_list.tsx @@ -28,7 +28,7 @@ const ThumbVertical = styled.div` `; const MenuList = (props: MenuListComponentProps) => { - const renderThumbVertical = useCallback((thumbProps) => { + const renderThumbVertical = useCallback((thumbProps: any) => { const thumbPropsWithoutStyle = {...thumbProps}; Reflect.deleteProperty(thumbPropsWithoutStyle, 'style'); return ; diff --git a/webapp/src/components/backstage/playbook_editor/controls.tsx b/webapp/src/components/backstage/playbook_editor/controls.tsx index a5148e70f4..bf28cd0f04 100644 --- a/webapp/src/components/backstage/playbook_editor/controls.tsx +++ b/webapp/src/components/backstage/playbook_editor/controls.tsx @@ -22,8 +22,6 @@ import { StarOutlineIcon, } from '@mattermost/compass-icons/components'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; - import {getTeam} from 'mattermost-redux/selectors/entities/teams'; import {Team} from '@mattermost/types/teams'; import {GlobalState} from '@mattermost/types/store'; @@ -31,6 +29,8 @@ import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; import {FormattedMessage, FormattedNumber, useIntl} from 'react-intl'; import {createGlobalState} from 'react-use'; +import {OverlayTrigger, Tooltip} from 'src/externals/react-bootstrap'; + import {navigateToPluginUrl, pluginUrl} from 'src/browser_routing'; import { PlaybookPermissionsMember, diff --git a/webapp/src/components/backstage/playbook_runs/playbook_run/add_participant_modal.tsx b/webapp/src/components/backstage/playbook_runs/playbook_run/add_participant_modal.tsx index bbbbe69331..4ccb61286c 100644 --- a/webapp/src/components/backstage/playbook_runs/playbook_run/add_participant_modal.tsx +++ b/webapp/src/components/backstage/playbook_runs/playbook_run/add_participant_modal.tsx @@ -3,7 +3,7 @@ import React, {useState} from 'react'; import {useIntl} from 'react-intl'; -import {Modal} from 'react-bootstrap'; + import styled from 'styled-components'; import {useDispatch, useSelector} from 'react-redux'; import {searchProfiles} from 'mattermost-redux/actions/users'; @@ -12,6 +12,8 @@ import {LightningBoltOutlineIcon} from '@mattermost/compass-icons/components'; import {OptionTypeBase, StylesConfig} from 'react-select'; import {General} from 'mattermost-redux/constants'; +import {Modal} from 'src/externals/react-bootstrap'; + import GenericModal from 'src/components/widgets/generic_modal'; import {PlaybookRun} from 'src/types/playbook_run'; import {useManageRunMembership} from 'src/graphql/hooks'; diff --git a/webapp/src/components/backstage/playbook_runs/playbook_run/header_button.tsx b/webapp/src/components/backstage/playbook_runs/playbook_run/header_button.tsx index 685c5ecd38..039d906619 100644 --- a/webapp/src/components/backstage/playbook_runs/playbook_run/header_button.tsx +++ b/webapp/src/components/backstage/playbook_runs/playbook_run/header_button.tsx @@ -7,11 +7,7 @@ import React from 'react'; import Tooltip from 'src/components/widgets/tooltip'; import {CompassIcon} from 'src/types/compass'; -declare module 'react-bootstrap/esm/OverlayTrigger' { - interface OverlayTriggerProps { - shouldUpdatePosition?: boolean; - } -} +// OverlayTrigger props are now handled by the external react-bootstrap interface HeaderButtonProps { tooltipId: string; diff --git a/webapp/src/components/checklist_item/duedate.tsx b/webapp/src/components/checklist_item/duedate.tsx index 0033514e92..20e6a8d3e4 100644 --- a/webapp/src/components/checklist_item/duedate.tsx +++ b/webapp/src/components/checklist_item/duedate.tsx @@ -11,10 +11,11 @@ import { Duration, DurationLikeObject, } from 'luxon'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; import {Placement} from '@floating-ui/react'; +import {OverlayTrigger, Tooltip} from 'src/externals/react-bootstrap'; + import DateTimeSelector, {DateTimeOption, optionFromMillis} from 'src/components/datetime_selector'; import { Mode, diff --git a/webapp/src/components/give_feedback_button.tsx b/webapp/src/components/give_feedback_button.tsx index 47e173728a..37e35d2800 100644 --- a/webapp/src/components/give_feedback_button.tsx +++ b/webapp/src/components/give_feedback_button.tsx @@ -3,11 +3,13 @@ import React from 'react'; import {useSelector} from 'react-redux'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; + import {useIntl} from 'react-intl'; import {Placement} from '@floating-ui/react'; import {GlobalState} from '@mattermost/types/store'; +import {OverlayTrigger, Tooltip} from 'src/externals/react-bootstrap'; + import {OVERLAY_DELAY} from 'src/constants'; import {InvertedTertiaryButton} from 'src/components/assets/buttons'; diff --git a/webapp/src/components/global_header_right.tsx b/webapp/src/components/global_header_right.tsx index 0328707464..1e4af4291a 100644 --- a/webapp/src/components/global_header_right.tsx +++ b/webapp/src/components/global_header_right.tsx @@ -2,12 +2,14 @@ // See LICENSE.txt for license information. import React from 'react'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; + import {useIntl} from 'react-intl'; import {useDispatch, useSelector} from 'react-redux'; import styled, {css} from 'styled-components'; import {CheckboxMultipleMarkedOutlineIcon} from '@mattermost/compass-icons/components'; +import {OverlayTrigger, Tooltip} from 'src/externals/react-bootstrap'; + import GiveFeedbackButton from 'src/components/give_feedback_button'; import {closeBackstageRHS, openBackstageRHS} from 'src/actions'; import {BackstageRHSSection, BackstageRHSViewMode} from 'src/types/backstage_rhs'; diff --git a/webapp/src/components/modals/update_run_status_modal.tsx b/webapp/src/components/modals/update_run_status_modal.tsx index b033140c36..cac8949168 100644 --- a/webapp/src/components/modals/update_run_status_modal.tsx +++ b/webapp/src/components/modals/update_run_status_modal.tsx @@ -210,7 +210,7 @@ const UpdateRunStatusModal = ({ } const followersChannelCount = run?.followers?.length ?? 0; - const OverviewLink = (...chunks: string[]): ReactNode => ( + const OverviewLink = (chunks: ReactNode): ReactNode => ( {runName} will be broadcasted to {hasChannels, select, true {{broadcastChannelCount, plural, =1 {one channel} other {{broadcastChannelCount, number} channels}}} other {}}{hasFollowersAndChannels, select, true { and } other {}}{hasFollowers, select, true {{followersChannelCount, plural, =1 {one direct message} other {{followersChannelCount, number} direct messages}}} other {}}.', }, { OverviewLink, - ChannelsTooltip: (...chunks) => ( + ChannelsTooltip: (chunks: ReactNode) => ( {chunks} ), - FollowersTooltip: (...chunks) => ( + FollowersTooltip: (chunks: ReactNode) => ( { - const {locale} = useIntl(); const makeOption = useMakeOption(Mode.DurationValue); const defaults = useMemo(() => { @@ -447,7 +446,7 @@ const useReminderTimerOption = ( options.sort((a, b) => ms(a.value) - ms(b.value)); return {options, value}; - }, [run, preselectedValue, locale]); + }, [run, preselectedValue, makeOption]); const {input, value} = useDateTimeInput({ mode: Mode.DateTimeValue, diff --git a/webapp/src/components/rhs/rhs_participant.tsx b/webapp/src/components/rhs/rhs_participant.tsx index 75e8c2a2ab..9f78f95f98 100644 --- a/webapp/src/components/rhs/rhs_participant.tsx +++ b/webapp/src/components/rhs/rhs_participant.tsx @@ -3,7 +3,8 @@ import React from 'react'; import styled, {css} from 'styled-components'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; + +import {OverlayTrigger, Tooltip} from 'src/externals/react-bootstrap'; import Profile from 'src/components/profile/profile'; diff --git a/webapp/src/components/rhs/rhs_run_details_title.tsx b/webapp/src/components/rhs/rhs_run_details_title.tsx index 5be56f484d..7e08aa8ff7 100644 --- a/webapp/src/components/rhs/rhs_run_details_title.tsx +++ b/webapp/src/components/rhs/rhs_run_details_title.tsx @@ -3,9 +3,11 @@ import React from 'react'; import styled from 'styled-components'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; + import {useIntl} from 'react-intl'; +import {OverlayTrigger, Tooltip} from 'src/externals/react-bootstrap'; + import {useRunFollowers, useRunMetadata} from 'src/hooks'; import LeftChevron from 'src/components/assets/icons/left_chevron'; import FollowButton from 'src/components/backstage/follow_button'; diff --git a/webapp/src/components/rhs/rhs_run_participants_title.tsx b/webapp/src/components/rhs/rhs_run_participants_title.tsx index ab14da25b1..b3591ce853 100644 --- a/webapp/src/components/rhs/rhs_run_participants_title.tsx +++ b/webapp/src/components/rhs/rhs_run_participants_title.tsx @@ -2,9 +2,11 @@ // See LICENSE.txt for license information. import React from 'react'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; + import {useIntl} from 'react-intl'; +import {OverlayTrigger, Tooltip} from 'src/externals/react-bootstrap'; + import LeftChevron from 'src/components/assets/icons/left_chevron'; import {OVERLAY_DELAY} from 'src/constants'; import {HeaderSubtitle, HeaderVerticalDivider} from 'src/components/backstage/playbook_runs/playbook_run/rhs'; diff --git a/webapp/src/components/sidebar/create_playbook_dropdown.tsx b/webapp/src/components/sidebar/create_playbook_dropdown.tsx index 627fc356d7..a345ec25aa 100644 --- a/webapp/src/components/sidebar/create_playbook_dropdown.tsx +++ b/webapp/src/components/sidebar/create_playbook_dropdown.tsx @@ -4,7 +4,7 @@ import React from 'react'; import styled from 'styled-components'; import {useDispatch, useSelector} from 'react-redux'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; + import {useIntl} from 'react-intl'; import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams'; import { @@ -14,6 +14,8 @@ import { PlusIcon, } from '@mattermost/compass-icons/components'; +import {OverlayTrigger, Tooltip} from 'src/externals/react-bootstrap'; + import {displayPlaybookCreateModal} from 'src/actions'; import {useImportPlaybook} from 'src/components/backstage/import_playbook'; import {navigateToPluginUrl} from 'src/browser_routing'; diff --git a/webapp/src/components/widgets/confirmation_modal.tsx b/webapp/src/components/widgets/confirmation_modal.tsx index 71d42e0582..b66ef656bf 100644 --- a/webapp/src/components/widgets/confirmation_modal.tsx +++ b/webapp/src/components/widgets/confirmation_modal.tsx @@ -2,9 +2,11 @@ // See LICENSE.txt for license information. import React, {useState} from 'react'; -import {Modal} from 'react-bootstrap'; + import {FormattedMessage} from 'react-intl'; +import {Modal} from 'src/externals/react-bootstrap'; + import {PrimaryButton, TertiaryButton} from 'src/components/assets/buttons'; import { @@ -235,6 +237,8 @@ export default class ConfirmModal extends React.Component { {this.props.title} diff --git a/webapp/src/components/widgets/confirmation_modal_light.tsx b/webapp/src/components/widgets/confirmation_modal_light.tsx index c1b62742b0..a8ff163ff8 100644 --- a/webapp/src/components/widgets/confirmation_modal_light.tsx +++ b/webapp/src/components/widgets/confirmation_modal_light.tsx @@ -3,7 +3,8 @@ import React from 'react'; import styled from 'styled-components'; -import {Modal} from 'react-bootstrap'; + +import {Modal} from 'src/externals/react-bootstrap'; import GenericModal, {DefaultFooterContainer} from 'src/components/widgets/generic_modal'; diff --git a/webapp/src/components/widgets/generic_modal.tsx b/webapp/src/components/widgets/generic_modal.tsx index b327993fd3..587e378462 100644 --- a/webapp/src/components/widgets/generic_modal.tsx +++ b/webapp/src/components/widgets/generic_modal.tsx @@ -4,9 +4,11 @@ import styled from 'styled-components'; import classNames from 'classnames'; import React, {ComponentType} from 'react'; -import {Modal} from 'react-bootstrap'; + import {FormattedMessage} from 'react-intl'; +import {Modal} from 'src/externals/react-bootstrap'; + import {DestructiveButton, PrimaryButton, TertiaryButton} from 'src/components/assets/buttons'; type Props = { @@ -139,6 +141,8 @@ export default class GenericModal extends React.PureComponent {
{Boolean(this.props.modalHeaderText) && ( {this.props.modalHeaderText} diff --git a/webapp/src/components/widgets/text_with_tooltip.tsx b/webapp/src/components/widgets/text_with_tooltip.tsx index dd27b1ed03..8687b92e6e 100644 --- a/webapp/src/components/widgets/text_with_tooltip.tsx +++ b/webapp/src/components/widgets/text_with_tooltip.tsx @@ -40,16 +40,16 @@ const TextWithTooltip = (props: Props) => { return () => { window.removeEventListener('resize', resizeListener); }; - }, []); + }, [resizeListener]); useEffect(() => { resizeListener(); }); - const setRef = useCallback((node) => { + const setRef = useCallback((node: HTMLAnchorElement | null) => { ref.current = node; resizeListener(); - }, []); + }, [resizeListener]); const text = ( { + // Try to get ReactBootstrap from global scope (provided by Mattermost webapp) + if (typeof window !== 'undefined' && (window as any).ReactBootstrap) { + return (window as any).ReactBootstrap; + } + + // Try to get ReactBootstrap from global scope (alternative access) + if (typeof ReactBootstrap !== 'undefined') { + return ReactBootstrap; + } + + // Try to get ReactBootstrap from global scope (Node.js test environment) + if (typeof global !== 'undefined' && (global as any).ReactBootstrap) { + return (global as any).ReactBootstrap; + } + + // Throw an error if ReactBootstrap is not available + throw new Error('ReactBootstrap is not available. Make sure it is loaded in the environment.'); +}; + +const ReactBootstrapComponents = getReactBootstrap(); + +export const Modal = ReactBootstrapComponents.Modal; +export const Button = ReactBootstrapComponents.Button; +export const Form = ReactBootstrapComponents.Form; +export const InputGroup = ReactBootstrapComponents.InputGroup; +export const FormControl = ReactBootstrapComponents.FormControl; +export const Dropdown = ReactBootstrapComponents.Dropdown; +export const DropdownButton = ReactBootstrapComponents.DropdownButton; +export const DropdownToggle = ReactBootstrapComponents.DropdownToggle; +export const DropdownMenu = ReactBootstrapComponents.DropdownMenu; +export const DropdownItem = ReactBootstrapComponents.DropdownItem; +export const Nav = ReactBootstrapComponents.Nav; +export const NavItem = ReactBootstrapComponents.NavItem; +export const NavLink = ReactBootstrapComponents.NavLink; +export const NavDropdown = ReactBootstrapComponents.NavDropdown; +export const Tabs = ReactBootstrapComponents.Tabs; +export const Tab = ReactBootstrapComponents.Tab; +export const Row = ReactBootstrapComponents.Row; +export const Col = ReactBootstrapComponents.Col; +export const Container = ReactBootstrapComponents.Container; +export const Card = ReactBootstrapComponents.Card; +export const CardHeader = ReactBootstrapComponents.CardHeader; +export const CardBody = ReactBootstrapComponents.CardBody; +export const CardFooter = ReactBootstrapComponents.CardFooter; +export const Badge = ReactBootstrapComponents.Badge; +export const Alert = ReactBootstrapComponents.Alert; +export const Spinner = ReactBootstrapComponents.Spinner; +export const OverlayTrigger = ReactBootstrapComponents.OverlayTrigger; +export const Tooltip = ReactBootstrapComponents.Tooltip; +export const Popover = ReactBootstrapComponents.Popover; + diff --git a/webapp/src/hooks/general.ts b/webapp/src/hooks/general.ts index a9ba5090bf..9a29dd79d4 100644 --- a/webapp/src/hooks/general.ts +++ b/webapp/src/hooks/general.ts @@ -152,7 +152,7 @@ export function useTimeout(callback: () => void, delay: number | null) { export function useClientRect() { const [rect, setRect] = useState(new DOMRect()); - const ref = useCallback((node) => { + const ref = useCallback((node: HTMLElement | null) => { if (node !== null) { setRect(node.getBoundingClientRect()); } diff --git a/webapp/src/index.tsx b/webapp/src/index.tsx index c942e73dd2..803bfa291c 100644 --- a/webapp/src/index.tsx +++ b/webapp/src/index.tsx @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import React from 'react'; -import {render, unmountComponentAtNode} from 'react-dom'; +import {Root, createRoot} from 'react-dom/client'; import {Store, Unsubscribe} from 'redux'; import {Redirect, useLocation, useRouteMatch} from 'react-router-dom'; import {GlobalState} from '@mattermost/types/store'; @@ -139,13 +139,14 @@ export default class Plugin { activityFunc?: () => void; stylesContainer?: Element; + stylesRoot?: Root; doRegistrations(registry: any, store: Store, graphqlClient: ApolloClient): void { registry.registerReducer(reducer); registry.registerTranslations((locale: string) => { try { - // eslint-disable-next-line global-require, @typescript-eslint/no-require-imports + // eslint-disable-next-line global-require, @typescript-eslint/no-require-imports, no-warning-comments return require(`../i18n/${locale}.json`); // TODO make async, this increases bundle size exponentially } catch { return {}; @@ -299,7 +300,8 @@ export default class Plugin { public initialize(registry: any, store: Store): void { this.stylesContainer = document.createElement('div'); document.body.appendChild(this.stylesContainer); - render(<>, this.stylesContainer); + this.stylesRoot = createRoot(this.stylesContainer); + this.stylesRoot.render(<>); // Consume the SiteURL so that the client is subpath aware. We also do this for Client4 // in our version of the mattermost-redux, since webapp only does it in its copy. @@ -349,8 +351,13 @@ export default class Plugin { document.removeEventListener('click', this.activityFunc); delete this.activityFunc; } + if (this.stylesRoot) { + this.stylesRoot.unmount(); + delete this.stylesRoot; + } if (this.stylesContainer) { - unmountComponentAtNode(this.stylesContainer); + document.body.removeChild(this.stylesContainer); + delete this.stylesContainer; } } } diff --git a/webapp/src/setupTests.ts b/webapp/src/setupTests.ts new file mode 100644 index 0000000000..0f5b146858 --- /dev/null +++ b/webapp/src/setupTests.ts @@ -0,0 +1,43 @@ +// Copyright (c) 2020-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// Mock ReactBootstrap for Jest tests +const mockComponent = () => null; + +(global as any).ReactBootstrap = { + Modal: Object.assign(mockComponent, { + Header: mockComponent, + Body: mockComponent, + Footer: mockComponent, + Title: mockComponent, + Dialog: mockComponent, + }), + Button: mockComponent, + Form: mockComponent, + InputGroup: mockComponent, + FormControl: mockComponent, + Dropdown: mockComponent, + DropdownButton: mockComponent, + DropdownToggle: mockComponent, + DropdownMenu: mockComponent, + DropdownItem: mockComponent, + Nav: mockComponent, + NavItem: mockComponent, + NavLink: mockComponent, + NavDropdown: mockComponent, + Tabs: mockComponent, + Tab: mockComponent, + Row: mockComponent, + Col: mockComponent, + Container: mockComponent, + Card: mockComponent, + CardHeader: mockComponent, + CardBody: mockComponent, + CardFooter: mockComponent, + Badge: mockComponent, + Alert: mockComponent, + Spinner: mockComponent, + OverlayTrigger: mockComponent, + Tooltip: mockComponent, + Popover: mockComponent, +}; diff --git a/webapp/src/types/react-bootstrap.d.ts b/webapp/src/types/react-bootstrap.d.ts new file mode 100644 index 0000000000..71346eda75 --- /dev/null +++ b/webapp/src/types/react-bootstrap.d.ts @@ -0,0 +1,135 @@ +// Copyright (c) 2020-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// Type declarations for react-bootstrap when used as external dependency +declare module 'react-bootstrap' { + import {ComponentType} from 'react'; + + export const Modal: ComponentType & { + Header: ComponentType; + Body: ComponentType; + Footer: ComponentType; + Title: ComponentType; + Dialog: ComponentType; + }; + export const Button: ComponentType; + export const Form: ComponentType; + export const FormControl: ComponentType; + export const FormGroup: ComponentType; + export const FormLabel: ComponentType; + export const FormText: ComponentType; + export const FormCheck: ComponentType; + export const FormCheckInput: ComponentType; + export const FormCheckLabel: ComponentType; + export const FormFile: ComponentType; + export const FormFileInput: ComponentType; + export const FormFileLabel: ComponentType; + export const InputGroup: ComponentType; + export const InputGroupText: ComponentType; + export const InputGroupPrepend: ComponentType; + export const InputGroupAppend: ComponentType; + export const Dropdown: ComponentType; + export const DropdownButton: ComponentType; + export const DropdownToggle: ComponentType; + export const DropdownMenu: ComponentType; + export const DropdownItem: ComponentType; + export const Nav: ComponentType; + export const NavItem: ComponentType; + export const NavLink: ComponentType; + export const NavDropdown: ComponentType; + export const Navbar: ComponentType; + export const NavbarBrand: ComponentType; + export const NavbarToggle: ComponentType; + export const NavbarCollapse: ComponentType; + export const NavbarText: ComponentType; + export const Card: ComponentType; + export const CardHeader: ComponentType; + export const CardBody: ComponentType; + export const CardFooter: ComponentType; + export const CardTitle: ComponentType; + export const CardText: ComponentType; + export const CardImg: ComponentType; + export const CardImgOverlay: ComponentType; + export const CardGroup: ComponentType; + export const CardDeck: ComponentType; + export const CardColumns: ComponentType; + export const ListGroup: ComponentType; + export const ListGroupItem: ComponentType; + export const Table: ComponentType; + export const Container: ComponentType; + export const Row: ComponentType; + export const Col: ComponentType; + export const Alert: ComponentType; + export const Badge: ComponentType; + export const Breadcrumb: ComponentType; + export const BreadcrumbItem: ComponentType; + export const ButtonGroup: ComponentType; + export const ButtonToolbar: ComponentType; + export const ToggleButton: ComponentType; + export const ToggleButtonGroup: ComponentType; + export const SplitButton: ComponentType; + export const CloseButton: ComponentType; + export const Spinner: ComponentType; + export const ProgressBar: ComponentType; + export const Carousel: ComponentType; + export const CarouselItem: ComponentType; + export const CarouselCaption: ComponentType; + export const Image: ComponentType; + export const Figure: ComponentType; + export const FigureImage: ComponentType; + export const FigureCaption: ComponentType; + export const Media: ComponentType; + export const Jumbotron: ComponentType; + export const ResponsiveEmbed: ComponentType; + export const Pagination: ComponentType; + export const PageItem: ComponentType; + export const Pager: ComponentType; + export const Popover: ComponentType; + export const PopoverHeader: ComponentType; + export const PopoverBody: ComponentType; + export const PopoverTitle: ComponentType; + export const PopoverContent: ComponentType; + export const Tooltip: ComponentType; + export const OverlayTrigger: ComponentType; + export const Overlay: ComponentType; + export const Fade: ComponentType; + export const Collapse: ComponentType; + export const Accordion: ComponentType; + export const AccordionToggle: ComponentType; + export const AccordionCollapse: ComponentType; + export const Tab: ComponentType; + export const Tabs: ComponentType; + export const TabContainer: ComponentType; + export const TabContent: ComponentType; + export const TabPane: ComponentType; + export const Toast: ComponentType; + export const ToastHeader: ComponentType; + export const ToastBody: ComponentType; + export const Switch: ComponentType; + export const ElementChildren: ComponentType; + export const AbstractNav: ComponentType; + export const AbstractNavItem: ComponentType; + export const NavContext: ComponentType; + export const SelectableContext: ComponentType; + export const TabContext: ComponentType; + export const ToggleContext: ComponentType; + export const ModalContext: ComponentType; + export const AccordionContext: ComponentType; + export const NavbarContext: ComponentType; + export const CardContext: ComponentType; + export const FormContext: ComponentType; + export const ThemeProvider: ComponentType; + export const BootstrapModalManager: ComponentType; + export const SafeAnchor: ComponentType; + export const createChainedFunction: (...funcs: any[]) => any; + export const createWithBsPrefix: (prefix: string) => ComponentType; + export const divWithClassName: (className: string) => ComponentType; + export const useWrappedRefWithWarning: (ref: any, componentName: string) => any; + export const usePopperMarginModifiers: (overlay: any) => any; + export const transitionEndListener: (element: any, handler: any) => any; + export const triggerBrowserReflow: (node: any) => any; +} + +declare module 'react-bootstrap/esm/OverlayTrigger' { + export const OverlayTrigger: ComponentType; +}