diff --git a/package-lock.json b/package-lock.json index d40ae21a2..27208b121 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,16 +54,16 @@ "eslint-config-next": "^14.2.15", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.30.0", - "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-react": "^7.36.1", - "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-hooks": "^5.1.0", "jest": "^29.7.0", "jest-canvas-mock": "^2.5.2", "jest-environment-jsdom": "^29.7.0", "lerna": "^8.1.8", "nx": "19.4.3 ", - "oxlint": "^0.9.8", + "oxlint": "^0.15.8", "postcss-import": "^16.1.0", "postcss-modules": "^6.0.0", "postcss-preset-mantine": "^1.17.0", @@ -5543,12 +5543,6 @@ "node": ">= 10" } }, - "node_modules/@next/env": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.23.tgz", - "integrity": "sha512-CysUC9IO+2Bh0omJ3qrb47S8DtsTKbFidGm6ow4gXIG6reZybqxbkH2nhdEm1tC8SmgzDdpq3BIML0PWsmyUYA==", - "license": "MIT" - }, "node_modules/@next/eslint-plugin-next": { "version": "14.2.23", "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.23.tgz", @@ -5580,150 +5574,6 @@ } } }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.23.tgz", - "integrity": "sha512-WhtEntt6NcbABA8ypEoFd3uzq5iAnrl9AnZt9dXdO+PZLACE32z3a3qA5OoV20JrbJfSJ6Sd6EqGZTrlRnGxQQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.23.tgz", - "integrity": "sha512-vwLw0HN2gVclT/ikO6EcE+LcIN+0mddJ53yG4eZd0rXkuEr/RnOaMH8wg/sYl5iz5AYYRo/l6XX7FIo6kwbw1Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.23.tgz", - "integrity": "sha512-uuAYwD3At2fu5CH1wD7FpP87mnjAv4+DNvLaR9kiIi8DLStWSW304kF09p1EQfhcbUI1Py2vZlBO2VaVqMRtpg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.23.tgz", - "integrity": "sha512-Mm5KHd7nGgeJ4EETvVgFuqKOyDh+UMXHXxye6wRRFDr4FdVRI6YTxajoV2aHE8jqC14xeAMVZvLqYqS7isHL+g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.23.tgz", - "integrity": "sha512-Ybfqlyzm4sMSEQO6lDksggAIxnvWSG2cDWnG2jgd+MLbHYn2pvFA8DQ4pT2Vjk3Cwrv+HIg7vXJ8lCiLz79qoQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.23.tgz", - "integrity": "sha512-OSQX94sxd1gOUz3jhhdocnKsy4/peG8zV1HVaW6DLEbEmRRtUCUQZcKxUD9atLYa3RZA+YJx+WZdOnTkDuNDNA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.23.tgz", - "integrity": "sha512-ezmbgZy++XpIMTcTNd0L4k7+cNI4ET5vMv/oqNfTuSXkZtSA9BURElPFyarjjGtRgZ9/zuKDHoMdZwDZIY3ehQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.23.tgz", - "integrity": "sha512-zfHZOGguFCqAJ7zldTKg4tJHPJyJCOFhpoJcVxKL9BSUHScVDnMdDuOU1zPPGdOzr/GWxbhYTjyiEgLEpAoFPA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.23.tgz", - "integrity": "sha512-xCtq5BD553SzOgSZ7UH5LH+OATQihydObTrCTvVzOro8QiWYKdBVwcB2Mn2MLMo6DGW9yH1LSPw7jS7HhgJgjw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7159,9 +7009,9 @@ } }, "node_modules/@oxlint/darwin-arm64": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-0.9.10.tgz", - "integrity": "sha512-eOXKZYq5bnCSgDefgM5bzAg+4Fc//Rc4yjgKN8iDWUARweCaChiQXb6TXX8MfEfs6qayEMy6yVj0pqoFz0B1aw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-0.15.10.tgz", + "integrity": "sha512-nGuKO+lZh4vS2Lb9lceePSQkXLhKcBPIAlux8BY+ewk2LnNNWsCbHhoslBwLF2h0MB8HiqOIk8WzRwllCY8sBg==", "cpu": [ "arm64" ], @@ -7173,9 +7023,9 @@ ] }, "node_modules/@oxlint/darwin-x64": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-0.9.10.tgz", - "integrity": "sha512-UeYICDvLUaUOcY+0ugZUEmBMRLP+x8iTgL7TeY6BlpGw2ahbtUOTbyIIRWtr/0O++TnjZ+v8TzhJ9crw6Ij6dg==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-0.15.10.tgz", + "integrity": "sha512-Xpyk8PiNKIrxYuundViBsxLcltYPGy+M5w/mO7EI9eeqSizMvWNimQgfPzK5fgh3V0gv8bJG0IyPZJVN0uEE9A==", "cpu": [ "x64" ], @@ -7187,9 +7037,9 @@ ] }, "node_modules/@oxlint/linux-arm64-gnu": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-0.9.10.tgz", - "integrity": "sha512-0Zn+vqHhrZyufFBfq9WOgiIool0gCR14BLsdS+0Dwd9o+kNxPGA5q7erQFkiC4rpkxtfBHeD3iIKMMt7d29Kyw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-0.15.10.tgz", + "integrity": "sha512-fUxOOYlQBXc6Cz7d40zE2G6VG4yhR9vz+P1M8T1NhTe6yFUzfCCWV+zmHxpUPEy9dgGZPIvodIx7bP+kOPEmuA==", "cpu": [ "arm64" ], @@ -7201,9 +7051,9 @@ ] }, "node_modules/@oxlint/linux-arm64-musl": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-0.9.10.tgz", - "integrity": "sha512-tkQcWpYwF42bA/uRaV2iMFePHkBjTTgomOgeEaiw6XOSJX4nBEqGIIboqqLBWT4JnKCf/L+IG3y/e1MflhKByw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-0.15.10.tgz", + "integrity": "sha512-JESSO73nplnTftaBpWdgjsOtuSfl7Jeg3I37qJYVtHIxxyJMtHuuUd9g0K0MLbwcue2K7DFCnzlDNlxer2yrgQ==", "cpu": [ "arm64" ], @@ -7215,9 +7065,9 @@ ] }, "node_modules/@oxlint/linux-x64-gnu": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-0.9.10.tgz", - "integrity": "sha512-JHbkMUnibqaSMBvLHyqTL5cWxcGW+jw+Ppt2baLISpvo34a6fBR+PI7v/A92sEDWe0W1rPhypzCwA8mKpkQ3DA==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-0.15.10.tgz", + "integrity": "sha512-NS4joBtL8Hg7zPBlPxSzrSRqkxtZfABf+fAY8vNxwYMsG8I8VoQZQdhz7+0p6ecg0+jH3CmIpDQfo73eaUBwoA==", "cpu": [ "x64" ], @@ -7229,9 +7079,9 @@ ] }, "node_modules/@oxlint/linux-x64-musl": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-0.9.10.tgz", - "integrity": "sha512-aBBwN7bQzidwHwEXr7BAdVvMTLWstCy5gikerjLnGDeCSXX9r+o6+yUzTOqZvOo66E+XBgOJaVbY8rsL1MLE0g==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-0.15.10.tgz", + "integrity": "sha512-zC2eEEe4scfsoUV87YsZFOSfPutxeaAmCI9Ys2G1lQoTyZ+9G9nuxTzBMla/yspX6mQGxonXPxLxYbIlDT24vA==", "cpu": [ "x64" ], @@ -7243,9 +7093,9 @@ ] }, "node_modules/@oxlint/win32-arm64": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-0.9.10.tgz", - "integrity": "sha512-LXDnk7vKHT3IY6G1jq0O7+XMhtcHOYuxLGIx4KP+4xS6vKgBY+Bsq4xV3AtmtKlvnXkP5FxHpfLmcEtm5AWysA==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-0.15.10.tgz", + "integrity": "sha512-u8nHap9L96zTQvwHYqn1ZcoiHzLR24ifuKDBIwlmwEVYucUgE55tUc+ea8kPUUB4uvfOv0HtAxNFuKr43biPzg==", "cpu": [ "arm64" ], @@ -7257,9 +7107,9 @@ ] }, "node_modules/@oxlint/win32-x64": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-0.9.10.tgz", - "integrity": "sha512-w5XRAV4bhgwenjjpGYZGglqzG9Wv/sI+cjQWJBQsvfDXsr2w4vOBXzt1j3/Z3EcSqf4KtkCa/IIuAhQyeShUbA==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-0.15.10.tgz", + "integrity": "sha512-OvG4lRw2AnTDJnCb1Jm1bzE2KuRvJLE+fQ6TDSj0UQSmTGHLXIZLc+Y8HMxntCx0p850FVBtYixdg2sHkv+i3g==", "cpu": [ "x64" ], @@ -9009,6 +8859,8 @@ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "@swc/counter": "^0.1.3", "tslib": "^2.4.0" @@ -14686,6 +14538,19 @@ } } }, + "node_modules/eslint-config-next/node_modules/eslint-plugin-react-hooks": { + "version": "5.0.0-canary-7118f5dd7-20230705", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", + "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, "node_modules/eslint-config-prettier": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", @@ -15012,16 +14877,16 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", + "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { @@ -27865,56 +27730,6 @@ "node": ">=0.10.0" } }, - "node_modules/next": { - "version": "14.2.23", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.23.tgz", - "integrity": "sha512-mjN3fE6u/tynneLiEg56XnthzuYw+kD7mCujgVqioxyPqbmiotUCGJpIZGS/VaPg3ZDT1tvWxiVyRzeqJFm/kw==", - "license": "MIT", - "dependencies": { - "@next/env": "14.2.23", - "@swc/helpers": "0.5.5", - "busboy": "1.6.0", - "caniuse-lite": "^1.0.30001579", - "graceful-fs": "^4.2.11", - "postcss": "8.4.31", - "styled-jsx": "5.1.1" - }, - "bin": { - "next": "dist/bin/next" - }, - "engines": { - "node": ">=18.17.0" - }, - "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.23", - "@next/swc-darwin-x64": "14.2.23", - "@next/swc-linux-arm64-gnu": "14.2.23", - "@next/swc-linux-arm64-musl": "14.2.23", - "@next/swc-linux-x64-gnu": "14.2.23", - "@next/swc-linux-x64-musl": "14.2.23", - "@next/swc-win32-arm64-msvc": "14.2.23", - "@next/swc-win32-ia32-msvc": "14.2.23", - "@next/swc-win32-x64-msvc": "14.2.23" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "@playwright/test": "^1.41.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@playwright/test": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, "node_modules/next-compose-plugins": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/next-compose-plugins/-/next-compose-plugins-2.2.1.tgz", @@ -27934,34 +27749,6 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -28808,9 +28595,9 @@ } }, "node_modules/oxlint": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-0.9.10.tgz", - "integrity": "sha512-bKiiFN7Hnoaist/rditTRBXz+GXKYuLd53/NB7Q6zHB/bifELJarSoRLkAUGElIJKl4PSr3lTh1g6zehh+rX0g==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-0.15.10.tgz", + "integrity": "sha512-962UBhpbd041fnx1GjQIY7uGIAXcAl/t45Xd6IZi11PyXVRHz7TjC4qpndrwp98Lfg7HuDaMXoOWOaNsgtEgag==", "dev": true, "license": "MIT", "bin": { @@ -28818,20 +28605,20 @@ "oxlint": "bin/oxlint" }, "engines": { - "node": ">=14.*" + "node": ">=8.*" }, "funding": { "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxlint/darwin-arm64": "0.9.10", - "@oxlint/darwin-x64": "0.9.10", - "@oxlint/linux-arm64-gnu": "0.9.10", - "@oxlint/linux-arm64-musl": "0.9.10", - "@oxlint/linux-x64-gnu": "0.9.10", - "@oxlint/linux-x64-musl": "0.9.10", - "@oxlint/win32-arm64": "0.9.10", - "@oxlint/win32-x64": "0.9.10" + "@oxlint/darwin-arm64": "0.15.10", + "@oxlint/darwin-x64": "0.15.10", + "@oxlint/linux-arm64-gnu": "0.15.10", + "@oxlint/linux-arm64-musl": "0.15.10", + "@oxlint/linux-x64-gnu": "0.15.10", + "@oxlint/linux-x64-musl": "0.15.10", + "@oxlint/win32-arm64": "0.15.10", + "@oxlint/win32-x64": "0.15.10" } }, "node_modules/p-cancelable": { @@ -36772,29 +36559,6 @@ "tslib": "^2.1.0" } }, - "node_modules/styled-jsx": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", - "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", - "license": "MIT", - "dependencies": { - "client-only": "0.0.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "babel-plugin-macros": { - "optional": true - } - } - }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", @@ -40392,7 +40156,7 @@ "mantine-react-table": "^2.0.0-beta.8", "mathjs": "^13.1.1", "minisearch": "^6.3.0", - "next": "^14.2.23", + "next": "^15.1.6", "next-compose-plugins": "^2.2.1", "next-images": "^1.8.5", "node-json-db": "^2.3.0", @@ -40460,6 +40224,149 @@ "tailwindcss": "^3.4.16" } }, + "packages/frontend/node_modules/@next/env": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.6.tgz", + "integrity": "sha512-d9AFQVPEYNr+aqokIiPLNK/MTyt3DWa/dpKveiAaVccUadFbhFEvY6FXYX2LJO2Hv7PHnLBu2oWwB4uBuHjr/w==", + "license": "MIT" + }, + "packages/frontend/node_modules/@next/swc-darwin-arm64": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.6.tgz", + "integrity": "sha512-u7lg4Mpl9qWpKgy6NzEkz/w0/keEHtOybmIl0ykgItBxEM5mYotS5PmqTpo+Rhg8FiOiWgwr8USxmKQkqLBCrw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/frontend/node_modules/@next/swc-darwin-x64": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.6.tgz", + "integrity": "sha512-x1jGpbHbZoZ69nRuogGL2MYPLqohlhnT9OCU6E6QFewwup+z+M6r8oU47BTeJcWsF2sdBahp5cKiAcDbwwK/lg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/frontend/node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.6.tgz", + "integrity": "sha512-jar9sFw0XewXsBzPf9runGzoivajeWJUc/JkfbLTC4it9EhU8v7tCRLH7l5Y1ReTMN6zKJO0kKAGqDk8YSO2bg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/frontend/node_modules/@next/swc-linux-arm64-musl": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.6.tgz", + "integrity": "sha512-+n3u//bfsrIaZch4cgOJ3tXCTbSxz0s6brJtU3SzLOvkJlPQMJ+eHVRi6qM2kKKKLuMY+tcau8XD9CJ1OjeSQQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/frontend/node_modules/@next/swc-linux-x64-gnu": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.6.tgz", + "integrity": "sha512-SpuDEXixM3PycniL4iVCLyUyvcl6Lt0mtv3am08sucskpG0tYkW1KlRhTgj4LI5ehyxriVVcfdoxuuP8csi3kQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/frontend/node_modules/@next/swc-linux-x64-musl": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.6.tgz", + "integrity": "sha512-L4druWmdFSZIIRhF+G60API5sFB7suTbDRhYWSjiw0RbE+15igQvE2g2+S973pMGvwN3guw7cJUjA/TmbPWTHQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/frontend/node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.6.tgz", + "integrity": "sha512-s8w6EeqNmi6gdvM19tqKKWbCyOBvXFbndkGHl+c9YrzsLARRdCHsD9S1fMj8gsXm9v8vhC8s3N8rjuC/XrtkEg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/frontend/node_modules/@next/swc-win32-x64-msvc": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.6.tgz", + "integrity": "sha512-6xomMuu54FAFxttYr5PJbEfu96godcxBTRk1OhAvJq0/EnmFU/Ybiax30Snis4vdWZ9LGpf7Roy5fSs7v/5ROQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/frontend/node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "packages/frontend/node_modules/@types/node": { "version": "18.15.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz", @@ -40467,6 +40374,111 @@ "dev": true, "license": "MIT" }, + "packages/frontend/node_modules/next": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/next/-/next-15.1.6.tgz", + "integrity": "sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==", + "license": "MIT", + "dependencies": { + "@next/env": "15.1.6", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.1.6", + "@next/swc-darwin-x64": "15.1.6", + "@next/swc-linux-arm64-gnu": "15.1.6", + "@next/swc-linux-arm64-musl": "15.1.6", + "@next/swc-linux-x64-gnu": "15.1.6", + "@next/swc-linux-x64-musl": "15.1.6", + "@next/swc-win32-arm64-msvc": "15.1.6", + "@next/swc-win32-x64-msvc": "15.1.6", + "sharp": "^0.33.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "packages/frontend/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "packages/frontend/node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, "packages/sampleCommons": { "name": "@gen3/samplecommons", "version": "0.10.79", @@ -40494,7 +40506,7 @@ }, "devDependencies": { "@gen3/toolsff": "file:../tools", - "@next/mdx": "^14.2.15", + "@next/mdx": "^14.2.23", "@types/mdx": "^2.0.13", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", @@ -40568,6 +40580,171 @@ "url": "https://opencollective.com/unified" } }, + "packages/sampleCommons/node_modules/@next/env": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.6.tgz", + "integrity": "sha512-d9AFQVPEYNr+aqokIiPLNK/MTyt3DWa/dpKveiAaVccUadFbhFEvY6FXYX2LJO2Hv7PHnLBu2oWwB4uBuHjr/w==", + "license": "MIT" + }, + "packages/sampleCommons/node_modules/@next/mdx": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/mdx/-/mdx-15.1.6.tgz", + "integrity": "sha512-jt9b9ayY8z3F/oQa2YCK7NugxY6ttAiJ8Eu29OTwwW5rcYMjXohIRaqsSrgFWhCFkJA6/EccKO+1ApocCZnn5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "^0.7.0" + }, + "peerDependencies": { + "@mdx-js/loader": ">=0.15.0", + "@mdx-js/react": ">=0.15.0" + }, + "peerDependenciesMeta": { + "@mdx-js/loader": { + "optional": true + }, + "@mdx-js/react": { + "optional": true + } + } + }, + "packages/sampleCommons/node_modules/@next/swc-darwin-arm64": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.6.tgz", + "integrity": "sha512-u7lg4Mpl9qWpKgy6NzEkz/w0/keEHtOybmIl0ykgItBxEM5mYotS5PmqTpo+Rhg8FiOiWgwr8USxmKQkqLBCrw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/sampleCommons/node_modules/@next/swc-darwin-x64": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.6.tgz", + "integrity": "sha512-x1jGpbHbZoZ69nRuogGL2MYPLqohlhnT9OCU6E6QFewwup+z+M6r8oU47BTeJcWsF2sdBahp5cKiAcDbwwK/lg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/sampleCommons/node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.6.tgz", + "integrity": "sha512-jar9sFw0XewXsBzPf9runGzoivajeWJUc/JkfbLTC4it9EhU8v7tCRLH7l5Y1ReTMN6zKJO0kKAGqDk8YSO2bg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/sampleCommons/node_modules/@next/swc-linux-arm64-musl": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.6.tgz", + "integrity": "sha512-+n3u//bfsrIaZch4cgOJ3tXCTbSxz0s6brJtU3SzLOvkJlPQMJ+eHVRi6qM2kKKKLuMY+tcau8XD9CJ1OjeSQQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/sampleCommons/node_modules/@next/swc-linux-x64-gnu": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.6.tgz", + "integrity": "sha512-SpuDEXixM3PycniL4iVCLyUyvcl6Lt0mtv3am08sucskpG0tYkW1KlRhTgj4LI5ehyxriVVcfdoxuuP8csi3kQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/sampleCommons/node_modules/@next/swc-linux-x64-musl": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.6.tgz", + "integrity": "sha512-L4druWmdFSZIIRhF+G60API5sFB7suTbDRhYWSjiw0RbE+15igQvE2g2+S973pMGvwN3guw7cJUjA/TmbPWTHQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/sampleCommons/node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.6.tgz", + "integrity": "sha512-s8w6EeqNmi6gdvM19tqKKWbCyOBvXFbndkGHl+c9YrzsLARRdCHsD9S1fMj8gsXm9v8vhC8s3N8rjuC/XrtkEg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/sampleCommons/node_modules/@next/swc-win32-x64-msvc": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.6.tgz", + "integrity": "sha512-6xomMuu54FAFxttYr5PJbEfu96godcxBTRk1OhAvJq0/EnmFU/Ybiax30Snis4vdWZ9LGpf7Roy5fSs7v/5ROQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "packages/sampleCommons/node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "packages/sampleCommons/node_modules/@types/hast": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", @@ -41363,6 +41540,88 @@ ], "license": "MIT" }, + "packages/sampleCommons/node_modules/next": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/next/-/next-15.1.6.tgz", + "integrity": "sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==", + "license": "MIT", + "dependencies": { + "@next/env": "15.1.6", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.1.6", + "@next/swc-darwin-x64": "15.1.6", + "@next/swc-linux-arm64-gnu": "15.1.6", + "@next/swc-linux-arm64-musl": "15.1.6", + "@next/swc-linux-x64-gnu": "15.1.6", + "@next/swc-linux-x64-musl": "15.1.6", + "@next/swc-win32-arm64-msvc": "15.1.6", + "@next/swc-win32-x64-msvc": "15.1.6", + "sharp": "^0.33.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "packages/sampleCommons/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "packages/sampleCommons/node_modules/remark-mdx": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", @@ -41410,6 +41669,29 @@ "url": "https://opencollective.com/unified" } }, + "packages/sampleCommons/node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, "packages/sampleCommons/node_modules/unified": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", diff --git a/package.json b/package.json index 914a49988..94c1e23ae 100644 --- a/package.json +++ b/package.json @@ -73,16 +73,16 @@ "eslint-config-next": "^14.2.15", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.30.0", - "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-react": "^7.36.1", - "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-hooks": "^5.1.0", "jest": "^29.7.0", "jest-canvas-mock": "^2.5.2", "jest-environment-jsdom": "^29.7.0", "lerna": "^8.1.8", "nx": "19.4.3 ", - "oxlint": "^0.9.8", + "oxlint": "^0.15.8", "postcss-import": "^16.1.0", "postcss-modules": "^6.0.0", "postcss-preset-mantine": "^1.17.0", diff --git a/packages/core/src/features/user/hooks.ts b/packages/core/src/features/user/hooks.ts index bfcaa9ad4..90d519490 100644 --- a/packages/core/src/features/user/hooks.ts +++ b/packages/core/src/features/user/hooks.ts @@ -1,5 +1,6 @@ +import { useEffect, useState } from 'react'; import { useGetExternalLoginsQuery } from './externalLoginsSlice'; -import { FileMetadata } from './types'; +import { ExternalProvider, FileMetadata } from './types'; import { GUID_PREFIX_PATTERN } from '../../constants'; import { resolveDRSObjectId } from '../drsResolver/utils'; @@ -91,7 +92,7 @@ interface FederatedLoginStatusParams { selectedFiles: ReadonlyArray; } -const useGetFederatedLoginStatus = async ({ +const useGetFederatedLoginStatus = ({ selectedFiles, }: FederatedLoginStatusParams) => { const { @@ -100,44 +101,71 @@ const useGetFederatedLoginStatus = async ({ error: wtsError, } = useGetExternalLoginsQuery(); - if (wtsError || wtsResults === undefined) { - return { error: wtsError }; - } + // State to manage the asynchronous results + const [result, setResult] = useState<{ + providersToAuthenticate?: ExternalProvider[]; + missingProviders?: ExternalProvider[]; + error?: Error; + } | null>(null); - const providers = wtsResults.providers ?? []; - - const unauthenticatedProviders = providers.filter( - (provider) => !provider.refresh_token_expiration, - ); - - const guidResolutions = await resolveGUIDsInSelectedFiles(selectedFiles); - const providersToAuthenticate = unauthenticatedProviders.filter( - (unauthenticatedProvider) => - Object(guidResolutions.externalHosts) - .values() - .includes(new URL(unauthenticatedProvider.base_url).hostname), - ); - - const missingProviders = providersToAuthenticate.filter( - (provider) => - !Object(guidResolutions.externalHosts) - .values() - .includes(new URL(provider.base_url).hostname), - ); - if (missingProviders.length > 0) { - throw new Error( - `Could not find DRS server hostname for providers: ${missingProviders - .map((provider) => provider.name) - .join(', ')}`, - ); - } + useEffect(() => { + const fetchData = async () => { + if (wtsError || !wtsResults) { + if (wtsError instanceof Error) setResult({ error: wtsError }); + else setResult({ error: new Error('Unknown error') }); + return; + } + + const providers = wtsResults.providers ?? []; + const unauthenticatedProviders = providers.filter( + (provider) => !provider.refresh_token_expiration, + ); + + try { + const guidResolutions = + await resolveGUIDsInSelectedFiles(selectedFiles); + const providersToAuthenticate = unauthenticatedProviders.filter( + (unauthenticatedProvider) => + Object.values(guidResolutions.externalHosts).includes( + new URL(unauthenticatedProvider.base_url).hostname, + ), + ); + + const missingProviders = providersToAuthenticate.filter( + (provider) => + !Object.values(guidResolutions.externalHosts).includes( + new URL(provider.base_url).hostname, + ), + ); + + if (missingProviders.length > 0) { + throw new Error( + `Could not find DRS server hostname for providers: ${missingProviders + .map((provider) => provider.name) + .join(', ')}`, + ); + } + + setResult({ + providersToAuthenticate, + missingProviders, + }); + } catch (error: unknown) { + if (error instanceof Error) setResult({ error }); + else setResult({ error: new Error('Unknown error') }); + } + }; + + // Only run if there's data to act on + if (!wstIsLoading && wtsResults) { + fetchData(); + } + }, [selectedFiles, wstIsLoading, wtsError, wtsResults]); return { - data: wtsResults, isLoading: wstIsLoading, - error: wtsError, - providersToAuthenticate: providersToAuthenticate, - missingProviders: missingProviders, + data: result, + error: result?.error || wtsError, }; }; diff --git a/packages/core/src/features/user/userSliceRTK.ts b/packages/core/src/features/user/userSliceRTK.ts index 6c254db5b..8103d8e3b 100644 --- a/packages/core/src/features/user/userSliceRTK.ts +++ b/packages/core/src/features/user/userSliceRTK.ts @@ -42,7 +42,8 @@ export const userAuthApi = createApi({ try { results = await fetchFence({ endpoint, headers }); - } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (_e: unknown) { /* Because an "error" response is valid for the auth requests we don't want to put the request in an error state, or it will attempt the request over and over again diff --git a/packages/core/src/utils/extractvalues.ts b/packages/core/src/utils/extractvalues.ts index da722aac4..03f529fec 100644 --- a/packages/core/src/utils/extractvalues.ts +++ b/packages/core/src/utils/extractvalues.ts @@ -8,10 +8,16 @@ export type JSONValue = string | number | boolean | JSONValue[] | JSONObject; import { JSONPath } from 'jsonpath-plus'; -export const extractValuesFromObject = (jsonPathMappings: JsonPathMapping, obj: JSONObject): JSONObject =>{ +export const extractValuesFromObject = ( + jsonPathMappings: JsonPathMapping, + obj: JSONObject, +): JSONObject => { const result: { [key: string]: any } = {}; - const extractObjectValue = (jsonPath: string, obj: JSONObject): JSONValue | undefined => { + const extractObjectValue = ( + jsonPath: string, + obj: JSONObject, + ): JSONValue | undefined => { const extractedValues = JSONPath({ path: jsonPath, json: obj }); return extractedValues.length > 0 ? extractedValues[0] : undefined; }; diff --git a/packages/frontend/package.json b/packages/frontend/package.json index f63315ec7..0eeec995c 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -26,7 +26,7 @@ "copy-tailwind": "cp src/tailwind.cjs dist/tailwind.cjs", "build": "npm run compile && npm run types && npm run rollup", "build:clean": "npm run clean && npm run build", - "build:watch": "npm run rollup -- --watch", + "build:watch": "npm run compile && npm run rollup -- --watch", "dev": "npm run build:watch" }, "exports": { @@ -88,7 +88,7 @@ "mantine-react-table": "^2.0.0-beta.8", "mathjs": "^13.1.1", "minisearch": "^6.3.0", - "next": "^14.2.23", + "next": "^15.1.6", "next-compose-plugins": "^2.2.1", "next-images": "^1.8.5", "node-json-db": "^2.3.0", diff --git a/packages/frontend/src/components/Profile/CredentialsTable.tsx b/packages/frontend/src/components/Profile/CredentialsTable.tsx index ccc5a2a30..aaa8e4470 100644 --- a/packages/frontend/src/components/Profile/CredentialsTable.tsx +++ b/packages/frontend/src/components/Profile/CredentialsTable.tsx @@ -67,23 +67,16 @@ const CredentialsTable = () => { header: 'Actions', Cell: ({ row }: MRT_Cell) => (
- {row.original.actions === 'delete' ? ( - - removeCredential({ - csrfToken: csrfToken?.csrfToken, - id: row.original.key, - }) - } - > - - - ) : ( - - {' '} - - - )} + + removeCredential({ + csrfToken: csrfToken?.csrfToken, + id: row.original.key, + }) + } + > + +
), }, diff --git a/packages/frontend/src/components/Profile/ExternalProviderCard.tsx b/packages/frontend/src/components/Profile/ExternalProviderCard.tsx index be9351a6d..a86de0a24 100644 --- a/packages/frontend/src/components/Profile/ExternalProviderCard.tsx +++ b/packages/frontend/src/components/Profile/ExternalProviderCard.tsx @@ -7,40 +7,37 @@ import { } from 'react-icons/io'; import Link from 'next/link'; import { useDisclosure } from '@mantine/hooks'; +import { + QueryActionCreatorResult, + QueryDefinition, +} from '@reduxjs/toolkit/query'; /** * Open a new window for authentication. * @param url - URL to open * @param title - Title of the window + * @param refetch - refetch the external status if successful */ -const openAuthWindow = (url: string, title: string): Promise => { +const openAuthWindow = ( + url: string, + title: string, + refetch: () => QueryActionCreatorResult< + QueryDefinition + >, +): Promise => { const pollInterval = 500; return new Promise((resolve, reject) => { if (window.navigator.cookieEnabled) { + const width = Math.max(1024, window.innerWidth / 2); + const height = Math.max(1024, window.innerHeight / 2); const dualScreenLeft = window.screenLeft ?? window.screenX; const dualScreenTop = window.screenTop ?? window.screenY; - - const width = - window.innerWidth ?? - document.documentElement.clientWidth ?? - screen.width; - - const height = - window.innerHeight ?? - document.documentElement.clientHeight ?? - screen.height; - - const systemZoom = width / window.screen.availWidth; - - const left = (width - 500) / 2 / systemZoom + dualScreenLeft; - const top = (height - 550) / 2 / systemZoom + dualScreenTop; - + const left = dualScreenLeft + (window.innerWidth - width) / 2; + const top = dualScreenTop + (window.innerHeight - height) / 2; const win = window.open( url, title, - `width=${500 / systemZoom},height=${ - 550 / systemZoom - },top=${top},left=${left}`, + `width=${width},height=${height},left=${left},top=${top}`, ); if (!win) { @@ -65,9 +62,11 @@ const openAuthWindow = (url: string, title: string): Promise => { reject('login_error'); return; } + refetch(); resolve('success'); } - } catch (err) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (_err: unknown) { // We just want to catch it and not reject it. Rejecting the promise leads to unexpected behavior // where the logged-in status isn't reflected immediately as the program moves ahead w/o users // having a chance to log in, requiring a manual screen refresh to update. By catching errors @@ -85,11 +84,14 @@ const openAuthWindow = (url: string, title: string): Promise => { interface ExternalProviderCardProps extends HTMLAttributes { provider: ExternalProvider; + refetch: () => QueryActionCreatorResult< + QueryDefinition + >; } const ExternalProviderCard: React.FunctionComponent< ExternalProviderCardProps -> = ({ provider }) => { +> = ({ provider, refetch }) => { const [loading, handler] = useDisclosure(); return ( @@ -141,6 +143,7 @@ const ExternalProviderCard: React.FunctionComponent< openAuthWindow( `${providerUrl.url}${queryChar}redirect=${window.location.pathname}`, provider.name, + refetch, ).finally(() => { handler.close(); }); diff --git a/packages/frontend/src/components/Profile/ExternalProvidersPanel.tsx b/packages/frontend/src/components/Profile/ExternalProvidersPanel.tsx index 9bf5eceee..97f097b52 100644 --- a/packages/frontend/src/components/Profile/ExternalProvidersPanel.tsx +++ b/packages/frontend/src/components/Profile/ExternalProvidersPanel.tsx @@ -10,13 +10,18 @@ const ExternalProvidersPanel = () => { isLoading, isError, isSuccess, + refetch, } = useGetExternalLoginsQuery(); const providerCards = useMemo( () => externalProviders ? externalProviders.providers.map((provider: ExternalProvider) => ( - + )) : null, [externalProviders], diff --git a/packages/frontend/src/components/facets/FacetEnumList.tsx b/packages/frontend/src/components/facets/FacetEnumList.tsx index 7aebe449f..a700866ea 100644 --- a/packages/frontend/src/components/facets/FacetEnumList.tsx +++ b/packages/frontend/src/components/facets/FacetEnumList.tsx @@ -12,6 +12,36 @@ import { SortType } from './types'; import { updateFacetEnum } from './utils'; import { useDeepCompareCallback, useDeepCompareEffect } from 'use-deep-compare'; +const compareKeysAscending = ( + a: string | number, + b: string | number, +): number => { + if (typeof a === 'number' && typeof b === 'number') { + return a - b; + } + // If only one value is a number, move numbers to one end + // (in this case, numbers will come before strings) + if (typeof a === 'number') return -1; + if (typeof b === 'number') return 1; + // If both are strings, sort alphabetically + return a.localeCompare(b); +}; + +const compareKeysDescending = ( + a: string | number, + b: string | number, +): number => { + if (typeof a === 'number' && typeof b === 'number') { + return b - a; + } + // If only one value is a number, move numbers to one end + // (in this case, numbers will come before strings) + if (typeof a === 'number') return 1; + if (typeof b === 'number') return -1; + // If both are strings, sort alphabetically + return b.localeCompare(a); +}; + interface FacetEnumListProps { field: string; facetName?: string; @@ -47,9 +77,9 @@ const FacetEnumList: React.FC = ({ const isFilterExpanded = hooks?.useFilterExpanded && hooks.useFilterExpanded(field); const showFilters = isFilterExpanded === undefined || isFilterExpanded; - const [sortedData, setSortedData] = useState>( - {}, - ); + const [sortedData, setSortedData] = useState< + Array<[string | number, number]> + >([]); const [sortType, setSortType] = useState({ type: 'alpha', direction: 'asc', @@ -202,65 +232,16 @@ const FacetEnumList: React.FC = ({ useDeepCompareEffect(() => { if (facetChartData.filteredData && facetChartData.filteredData.length > 0) { - const compareValuesAscending = ( - [, a]: [string | number, number], - [, b]: [string | number, number], - ): number => a - b; - const compareValuesDescending = ( - [, a]: [string | number, number], - [, b]: [string | number, number], - ): number => b - a; - const compareKeysAscending = ( - [a]: [string | number, number], - [b]: [string | number, number], - ): number => - typeof a === 'string' && typeof b === 'string' - ? a.localeCompare(b) - : typeof a === 'number' && typeof b === 'number' - ? a - b - : 0; - - const compareKeysDescending = ( - [a]: [string | number, number], - [b]: [string | number, number], - ): number => - typeof a === 'string' && typeof b === 'string' - ? b.localeCompare(a) - : typeof a === 'number' && typeof b === 'number' - ? b - a - : 0; - - let comparisonFn; - - if (sortType.type === 'value') { - comparisonFn = - sortType.direction === 'dsc' - ? compareValuesDescending - : compareValuesAscending; - } else { - comparisonFn = - sortType.direction === 'dsc' - ? compareKeysDescending - : compareKeysAscending; - } - const obj = [...facetChartData.filteredData] - .sort(comparisonFn) - .slice(0, !isGroupExpanded ? maxValuesToDisplay : undefined) - .reduce( - (acc, [key, value]) => { - acc[key] = value; - return acc; - }, - {} as Record, - ); - - const val = Object.fromEntries( - [...facetChartData.filteredData] - .sort(comparisonFn) - .slice(0, !isGroupExpanded ? maxValuesToDisplay : undefined), - ); - + .sort( + sortType.type === 'value' + ? ([, a], [, b]) => (sortType.direction === 'dsc' ? b - a : a - b) + : ([a], [b]) => + sortType.direction === 'dsc' + ? compareKeysDescending(a, b) + : compareKeysAscending(a, b), + ) + .slice(0, !isGroupExpanded ? maxValuesToDisplay : undefined); setSortedData(obj); } }, [ @@ -345,10 +326,10 @@ const FacetEnumList: React.FC = ({ {BAD_DATA_MESSAGE} ) : isSuccess ? ( - !sortedData || Object.entries(sortedData).length === 0 ? ( + !sortedData || sortedData.length === 0 ? (
No results found
) : ( - Object.entries(sortedData ?? {}).map(([value, count]) => { + sortedData.map(([value, count]) => { return (
= ({ } />
- + {value} diff --git a/packages/frontend/src/components/facets/MultiSelectValueFacet.tsx b/packages/frontend/src/components/facets/MultiSelectValueFacet.tsx index 86d8445e0..6459cc47c 100644 --- a/packages/frontend/src/components/facets/MultiSelectValueFacet.tsx +++ b/packages/frontend/src/components/facets/MultiSelectValueFacet.tsx @@ -1,6 +1,6 @@ import React, { useState, useMemo } from 'react'; import { EnumFacetResponse, FacetCardProps, FacetDataHooks } from './types'; -import { ActionIcon, Group, MultiSelect, Tooltip } from '@mantine/core'; +import { MultiSelect, Tooltip } from '@mantine/core'; import { controlsIconStyle, FacetIconButton, @@ -16,6 +16,7 @@ import { trimFirstFieldNameToTitle, } from '@gen3/core'; import { useDeepCompareEffect } from 'use-deep-compare'; +import { updateFacetEnum } from './utils'; type ExactValueProps = Omit< FacetCardProps, @@ -25,6 +26,23 @@ type ExactValueProps = Omit< const instanceOfIncludesExcludes = (op: Operation): op is Includes | Excludes => ['in'].includes(op.operator); // TODO: Guppy does not support excludes +interface OperandsObject { + operands: unknown[]; +} + +const isOperandsObject = (obj: unknown): obj is OperandsObject => { + return ( + !!obj && // Ensure obj is not null or undefined + typeof obj === 'object' && + 'operands' in obj && + Array.isArray((obj as OperandsObject).operands) + ); +}; + +const isFacetEmpty = (op: object | null): boolean => { + return isOperandsObject(op) && op.operands.length === 0; +}; + /** * Extracts the operands if the operation isIncludes or Excludes. Returns an empty Array * if filter is not the correct type. @@ -79,7 +97,7 @@ const MultiSelectValueFacet: React.FC = ({ }, [facetDataValues?.data]); useDeepCompareEffect(() => { - if (!facetValue) { + if (!facetValue || isFacetEmpty(facetValue)) { setSelectedValues([]); } else if (instanceOfIncludesExcludes(facetValue)) { const filters = facetValue.operands.map((x: number | string) => @@ -91,29 +109,10 @@ const MultiSelectValueFacet: React.FC = ({ useDeepCompareEffect(() => { const setValues = (values: string[]) => { - if (values.length > 0) { - if (facetValue && instanceOfIncludesExcludes(facetValue)) { - // updating facet value - updateFacetFilters(field, { - ...facetValue, - operands: values, - }); - } - if (facetValue === undefined) { - // TODO: Assuming Includes by default but this might change to Include|Excludes - updateFacetFilters(field, { - operator: 'in', - field: field, - operands: values, - }); - } - } - // no values remove the filter - else { - clearFilters(field); - } + updateFacetEnum(field, values, updateFacetFilters, clearFilters); }; + console.log('selectedValues: ', selectedValues); setValues(selectedValues); }, [selectedValues]); @@ -162,14 +161,18 @@ const MultiSelectValueFacet: React.FC = ({ diff --git a/packages/frontend/src/features/CohortBuilder/CohortPanel.tsx b/packages/frontend/src/features/CohortBuilder/CohortPanel.tsx index a8e03b11b..dfddb3203 100644 --- a/packages/frontend/src/features/CohortBuilder/CohortPanel.tsx +++ b/packages/frontend/src/features/CohortBuilder/CohortPanel.tsx @@ -1,5 +1,5 @@ import React, { useMemo, useState } from 'react'; -import { Tabs } from '@mantine/core'; +import { LoadingOverlay, Tabs } from '@mantine/core'; import { partial } from 'lodash'; import { type FacetDefinition, @@ -166,6 +166,7 @@ export const CohortPanel = ({ const { data, isSuccess, + isFetching: isAggsQueryFetching, isError: isAggsQueryError, } = useGetAggsQuery({ type: index, @@ -298,6 +299,7 @@ export const CohortPanel = ({ return (
+
{filters?.tabs === undefined ? null : filters?.tabs.length > 1 ? ( diff --git a/packages/sampleCommons/next.config.js b/packages/sampleCommons/next.config.js index d2e47481a..d83b7c6ce 100644 --- a/packages/sampleCommons/next.config.js +++ b/packages/sampleCommons/next.config.js @@ -22,19 +22,19 @@ const withMDX = require('@next/mdx')({ // Next configuration with support for rewriting API to existing common services const nextConfig = { reactStrictMode: true, + eslint: { + ignoreDuringBuilds: true, + }, productionBrowserSourceMaps: true, experimental: { - esmExternals: true, instrumentationHook: true, }, pageExtensions: ['mdx', 'md', 'jsx', 'js', 'tsx', 'ts'], - transpilePackages: ['@gen3/core', '@gen3/frontend'], basePath: basePath, webpack: (config) => { config.infrastructureLogging = { level: 'error', }; - return config; }, async headers() { diff --git a/packages/sampleCommons/package.json b/packages/sampleCommons/package.json index 066fce137..83ab77226 100644 --- a/packages/sampleCommons/package.json +++ b/packages/sampleCommons/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "lint": "next lint", - "dev": "next dev", + "dev": "NODE_OPTIONS='--inspect' next dev", "clean": "rm -rf .next && rm -rf out", "build": "next build", "start": "next start", @@ -38,7 +38,7 @@ }, "devDependencies": { "@gen3/toolsff": "file:../tools", - "@next/mdx": "^14.2.15", + "@next/mdx": "^14.2.23", "@types/mdx": "^2.0.13", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5",