diff --git a/src/frontend/static/frontend/package-lock.json b/src/frontend/static/frontend/package-lock.json index 9e29f6d6..834d2b8e 100644 --- a/src/frontend/static/frontend/package-lock.json +++ b/src/frontend/static/frontend/package-lock.json @@ -28,6 +28,7 @@ "react-avatar": "^5.0.3", "react-colorful": "^5.6.1", "react-dom": "^18.3.1", + "react-intl": "^7.1.14", "react-virtualized": "^9.22.6", "recharts": "^2.15.1", "semantic-ui-react": "^2.1.5", @@ -2542,6 +2543,102 @@ "react-dom": "^16.8.0 || ^17 || ^18" } }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz", + "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==", + "dependencies": { + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/intl-localematcher": "0.6.2", + "decimal.js": "^10.4.3", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/ecma402-abstract/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz", + "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/fast-memoize/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz", + "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/icu-skeleton-parser": "1.8.16", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz", + "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@formatjs/intl": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-3.1.8.tgz", + "integrity": "sha512-LWXgwI5zTMatvR8w8kCNh/priDTOF/ZssokMBHJ7ZWXFoYLVOYo0EJERD9Eajv+xsfQO1QkuAt77KWQ1OI4mOQ==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/icu-messageformat-parser": "2.11.4", + "intl-messageformat": "10.7.18", + "tslib": "^2.8.0" + }, + "peerDependencies": { + "typescript": "^5.6.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz", + "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/intl-localematcher/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@formatjs/intl/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, "node_modules/@gamestdio/websocket": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@gamestdio/websocket/-/websocket-0.3.2.tgz", @@ -4878,25 +4975,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "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==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@swc/helpers/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -5263,9 +5341,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" }, "node_modules/@types/express": { "version": "4.17.21", @@ -5325,6 +5403,17 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz", + "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==", + "dependencies": { + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@types/html-minifier-terser": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz", @@ -6812,9 +6901,9 @@ } }, "node_modules/apexcharts": { - "version": "3.52.0", - "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.52.0.tgz", - "integrity": "sha512-7dg0ADKs8AA89iYMZMe2sFDG0XK5PfqllKV9N+i3hKHm3vEtdhwz8AlXGm+/b0nJ6jKiaXsqci5LfVxNhtB+dA==", + "version": "3.54.1", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.54.1.tgz", + "integrity": "sha512-E4et0h/J1U3r3EwS/WlqJCQIbepKbp6wGUmaAwJOMjHUP4Ci0gxanLa7FR3okx6p9coi4st6J853/Cb1NP0vpA==", "dependencies": { "@yr/monotone-cubic-spline": "^1.0.3", "svg.draggable.js": "^2.2.2", @@ -7717,6 +7806,14 @@ } ] }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.20.tgz", + "integrity": "sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -8020,9 +8117,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", "funding": [ { "type": "opencollective", @@ -8037,12 +8134,12 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" @@ -8317,9 +8414,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", "funding": [ { "type": "opencollective", @@ -8333,8 +8430,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/capture-exit": { "version": "2.0.0", @@ -8870,10 +8966,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.2.tgz", - "integrity": "sha512-t6u7H4Ff/yZNk+zqTr74UjCcZ3k8ApBryeLLV4rYQd9aF3gqmjjGjjR44ENfeBMH8VVvSynIjAJ0mUuFhzQtrA==", - "deprecated": "core-js-pure@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js-pure.", + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.46.0.tgz", + "integrity": "sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw==", "hasInstallScript": true, "peer": true, "funding": { @@ -10720,10 +10815,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.188", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.188.tgz", - "integrity": "sha512-pfEx5CBFAocOKNrc+i5fSvhDaI1Vr9R9aT5uX1IzM3hhdL6k649wfuUcdUd9EZnmbE1xdfA51CwqQ61CO3Xl3g==", - "license": "ISC" + "version": "1.5.240", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.240.tgz", + "integrity": "sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==" }, "node_modules/elliptic": { "version": "6.6.1", @@ -13609,6 +13703,14 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -14249,6 +14351,22 @@ "node": ">=10.13.0" } }, + "node_modules/intl-messageformat": { + "version": "10.7.18", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.18.tgz", + "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/icu-messageformat-parser": "2.11.4", + "tslib": "^2.8.0" + } + }, + "node_modules/intl-messageformat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, "node_modules/ip": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", @@ -17402,16 +17520,6 @@ "node": ">=8" } }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "optional": true, - "peer": true, - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, "node_modules/jquery": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", @@ -20757,9 +20865,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", + "integrity": "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==" }, "node_modules/normalize-package-data": { "version": "3.0.3", @@ -23626,6 +23734,35 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, + "node_modules/react-intl": { + "version": "7.1.14", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-7.1.14.tgz", + "integrity": "sha512-VE/0Wi/lHJlBC7APQpCzLUdIt3GB5B0GZrRW8Q+ACbkHI4j+Wwgg9J1TniN6zmLHmPH5gxXcMy+fkSPfw5p1WQ==", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/icu-messageformat-parser": "2.11.4", + "@formatjs/intl": "3.1.8", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/react": "16 || 17 || 18 || 19", + "hoist-non-react-statics": "^3.3.2", + "intl-messageformat": "10.7.18", + "tslib": "^2.8.0" + }, + "peerDependencies": { + "react": "16 || 17 || 18 || 19", + "typescript": "^5.6.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/react-intl/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -26534,9 +26671,9 @@ } }, "node_modules/terser-webpack-plugin/node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "peer": true, "bin": { "acorn": "bin/acorn" @@ -26609,9 +26746,9 @@ "peer": true }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", @@ -26652,13 +26789,13 @@ } }, "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.39.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", - "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -27187,19 +27324,6 @@ "node": ">=4" } }, - "node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -27553,9 +27677,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "funding": [ { "type": "opencollective", @@ -28207,22 +28331,22 @@ } }, "node_modules/webpack": { - "version": "5.99.8", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.8.tgz", - "integrity": "sha512-lQ3CPiSTpfOnrEGeXDwoq5hIGzSjmwD72GdfVzF7CQAI7t47rJG9eDWvcEkEn3CUQymAElVvDg3YNTlCYj+qUQ==", - "license": "MIT", + "version": "5.102.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", + "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", + "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", - "browserslist": "^4.24.0", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.26.3", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", + "enhanced-resolve": "^5.17.3", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -28232,11 +28356,11 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.2", - "tapable": "^2.1.1", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -29224,9 +29348,9 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "peer": true, "bin": { "acorn": "bin/acorn" @@ -29235,11 +29359,22 @@ "node": ">=0.4.0" } }, + "node_modules/webpack/node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "peer": true, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/webpack/node_modules/ajv": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", @@ -29256,7 +29391,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "license": "MIT", "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3" @@ -29266,9 +29400,9 @@ } }, "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "peer": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -29282,23 +29416,25 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT", "peer": true }, "node_modules/webpack/node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "peer": true, "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/webpack/node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", - "license": "MIT", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", @@ -29315,18 +29451,22 @@ } }, "node_modules/webpack/node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "peer": true, "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/webpack/node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -29337,9 +29477,9 @@ } }, "node_modules/webpack/node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "peer": true, "engines": { "node": ">=10.13.0" diff --git a/src/frontend/static/frontend/package.json b/src/frontend/static/frontend/package.json index b3c8a873..ebd009d0 100644 --- a/src/frontend/static/frontend/package.json +++ b/src/frontend/static/frontend/package.json @@ -22,11 +22,6 @@ "@babel/preset-env": "^7.27.2", "@babel/preset-react": "^7.27.1", "@babel/preset-typescript": "^7.27.1", - "babel-loader": "^10.0.0", - "babel-plugin-react-compiler": "^19.1.0-rc.2", - "eslint-plugin-react-compiler": "^19.1.0-rc.2", - "react-compiler-runtime": "^19.1.0-rc.2", - "@eslint/compat": "^1.2.8", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.27.0", @@ -37,13 +32,17 @@ "@types/react-dom": "^18.3.5", "@types/react-virtualized": "^9.22.2", "@types/validator": "^13.12.3", + "babel-loader": "^10.0.0", + "babel-plugin-react-compiler": "^19.1.0-rc.2", "css-loader": "^7.1.2", "eslint": "^9.27.0", "eslint-plugin-jsdoc": "^50.6.9", "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-compiler": "^19.1.0-rc.2", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", "neostandard": "^0.12.1", + "react-compiler-runtime": "^19.1.0-rc.2", "style-loader": "^4.0.0", "ts-checker-rspack-plugin": "^1.1.1", "ts-loader": "^9.5.2", @@ -72,6 +71,7 @@ "react-avatar": "^5.0.3", "react-colorful": "^5.6.1", "react-dom": "^18.3.1", + "react-intl": "^7.1.14", "react-virtualized": "^9.22.6", "recharts": "^2.15.1", "semantic-ui-react": "^2.1.5", diff --git a/src/frontend/static/frontend/rspack.common.js b/src/frontend/static/frontend/rspack.common.js index df78ea52..e8132aa9 100644 --- a/src/frontend/static/frontend/rspack.common.js +++ b/src/frontend/static/frontend/rspack.common.js @@ -25,7 +25,8 @@ export const common = { survival: `${PATHS.src}/survival.tsx`, aboutUs: `${PATHS.src}/about-us.tsx`, openSource: `${PATHS.src}/open-source.tsx`, - sitePolicy: `${PATHS.src}/site-policy.tsx` + sitePolicy: `${PATHS.src}/site-policy.tsx`, + faq: `${PATHS.src}/faq.tsx` }, output: { path: PATHS.output, diff --git a/src/frontend/static/frontend/src/components/MainNavbar.tsx b/src/frontend/static/frontend/src/components/MainNavbar.tsx index a40b1e8f..6dfba492 100644 --- a/src/frontend/static/frontend/src/components/MainNavbar.tsx +++ b/src/frontend/static/frontend/src/components/MainNavbar.tsx @@ -149,7 +149,7 @@ const LogInLogOutPanel = (props: LogInLogOutPanelProps) => { ) } -type ActiveItemOptions = 'home' | 'pipeline' | 'files' | 'cgds' | 'survival' | 'institutions' | 'about-us' | 'biomarkers' | 'open-source' +type ActiveItemOptions = 'home' | 'pipeline' | 'files' | 'cgds' | 'survival' | 'institutions' | 'about-us' | 'biomarkers' | 'open-source' | 'faq' interface MainNavbarProps { activeItem?: ActiveItemOptions, @@ -289,6 +289,17 @@ const MainNavbar = (props: MainNavbarProps) => { + + + FAQ + + + Open source diff --git a/src/frontend/static/frontend/src/components/about-us/AboutUs.tsx b/src/frontend/static/frontend/src/components/about-us/AboutUs.tsx index 6e26bbb3..c978f099 100644 --- a/src/frontend/static/frontend/src/components/about-us/AboutUs.tsx +++ b/src/frontend/static/frontend/src/components/about-us/AboutUs.tsx @@ -1,6 +1,7 @@ import React from 'react' import { Container, Divider, Grid, Header, Image, List } from 'semantic-ui-react' import { Base } from '../Base' +import { useIntl } from 'react-intl' const EMAILS: string[] = [ 'mcabba@gmail.com', @@ -13,6 +14,7 @@ const EMAILS: string[] = [ * @returns Component */ export const AboutUs = () => { + const intl = useIntl() return (
@@ -34,13 +36,13 @@ export const AboutUs = () => {
- Multiomix is the result of interdisciplinary work between members of the following scientific institutions: + {intl.formatMessage({ id: 'about.description' })}
- - - + + +
@@ -51,7 +53,7 @@ export const AboutUs = () => {
- Project coordination: + {intl.formatMessage({ id: 'about.coordination' })}
@@ -67,15 +69,17 @@ export const AboutUs = () => {
- Project members + {intl.formatMessage({ id: 'about.members.title' })} +
- Main contributor: B.Comp.Sc. Genaro Camele + {intl.formatMessage({ id: 'about.members.main' })} B.Comp.Sc. Genaro Camele
- Collaborators: Esp. Hernán Chanfreau, Dr. Sebastián Menazzi, St. Agustín Marraco, B.Comp.Sc. Julián Muhlberger, St. Ramiro Lasorsa, PhD. Waldo Hasperué + {intl.formatMessage({ id: 'about.members.collaborators' })} Esp. Hernán Chanfreau, Dr. Sebastián Menazzi, St. Agustín Marraco, B.Comp.Sc. Julián Muhlberger, St. Ramiro Lasorsa, PhD. Waldo Hasperué +
@@ -87,10 +91,10 @@ export const AboutUs = () => { {/* Contact */}
- Contact: + {intl.formatMessage({ id: 'about.contact.title' })}
-

For questions or suggestions please contact us:

+

{intl.formatMessage({ id: 'about.contact.questions' })}

{EMAILS.map((email) => (

@@ -98,7 +102,7 @@ export const AboutUs = () => {

))} -

You can also contact us for creating your research institution. It will let researchers share datasets inside Multiomix.

+

{intl.formatMessage({ id: 'about.contact.institutions' })}

diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/BiomarkerInferenceExperimentsPanel.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/BiomarkerInferenceExperimentsPanel.tsx index 3c43ab0a..d4c6bf22 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/BiomarkerInferenceExperimentsPanel.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/BiomarkerInferenceExperimentsPanel.tsx @@ -7,6 +7,7 @@ import { NewInferenceExperimentModal } from './NewInferenceExperimentModal' import { InferenceExperimentResultModal } from './InferenceExperimentResultModal' import ky from 'ky' import { alertGeneralError } from '../../../../utils/util_functions' +import { useIntl } from 'react-intl' declare const urlBiomarkerInferenceExperimentsDetails: string @@ -23,7 +24,7 @@ interface BiomarkerInferenceExperimentsPanelProps { */ export const BiomarkerInferenceExperimentsPanel = (props: BiomarkerInferenceExperimentsPanelProps) => { const abortController = useRef(new AbortController()) - + const intl = useIntl() const [openModalNewInferenceExperiment, setOpenModalNewInferenceExperiment] = useState(false) const [openModalResultInferenceExperiment, setOpenModalResultInferenceExperiment] = useState(false) const [selectedInferenceExperiment, setSelectedInferenceExperiment] = useState>(null) @@ -92,7 +93,7 @@ export const BiomarkerInferenceExperimentsPanel = (props: BiomarkerInferenceExpe return ( } + closeIcon={} closeOnEscape={false} centered={false} closeOnDimmerClick={false} @@ -100,7 +101,7 @@ export const BiomarkerInferenceExperimentsPanel = (props: BiomarkerInferenceExpe onClose={closeStatResult} open={openModalResultInferenceExperiment} > -
+
diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentClinicalAttributeSelect.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentClinicalAttributeSelect.tsx index 1ddc75a9..7b5c4baa 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentClinicalAttributeSelect.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentClinicalAttributeSelect.tsx @@ -67,7 +67,7 @@ export const InferenceExperimentClinicalAttributeSelect = (props: InferenceExper }, [props.selectedInferenceExperiment.id]) return ( <> - + { props.setSelectedClinicalAttribute(value as string) }} - placeholder='Clinical attribute to group by' + placeholder='inference.clinicalAttribute.placeholder' disabled={clinicalAttributesOptions.length === 0} /> diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentResultMetrics.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentResultMetrics.tsx index 405c5d1f..2d74c9bf 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentResultMetrics.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentResultMetrics.tsx @@ -2,6 +2,7 @@ import React from 'react' import { Header, Segment } from 'semantic-ui-react' import { InferenceExperimentForTable } from '../../types' import { ModelDetailsPanel } from '../ModelDetailsPanels' +import { useIntl } from 'react-intl' // declare const urlInferenceExperimentMetrics: string @@ -17,15 +18,16 @@ interface InferenceExperimentResultMetricsProps { * @returns Component */ export const InferenceExperimentResultMetrics = (props: InferenceExperimentResultMetricsProps) => { + const intl = useIntl() return ( <>
- "{props.selectedInferenceExperiment.name}" metrics + {intl.formatMessage({ id: 'inference.metrics.title' }, { name: props.selectedInferenceExperiment.name })}
{/* Model details. */} -
Model details
+
{intl.formatMessage({ id: 'inference.model.details' })}
{props.selectedInferenceExperiment.trained_model !== null && } diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentsTable.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentsTable.tsx index 1cbb1fbd..9d581863 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentsTable.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentsTable.tsx @@ -11,6 +11,7 @@ import { Nullable } from '../../../../utils/interfaces' import { StopExperimentButton } from '../../../pipeline/all-experiments-view/StopExperimentButton' import { DeleteButton } from '../../../common/DeleteButton' import { TableCellSources } from '../../../common/TableCellSources' +import { useIntl } from 'react-intl' declare const urlBiomarkerInferenceExperiments: string declare const urlStopInferenceExperiment: string @@ -31,6 +32,7 @@ interface InferenceExperimentsTableProps { * @returns Component. */ export const InferenceExperimentsTable = (props: InferenceExperimentsTableProps) => { + const intl = useIntl() const [stoppingInferenceExperiment, setStoppingInferenceExperiment] = useState(false) const [inferenceExperimentToStop, setInferenceExperimentToStop] = useState>(null) @@ -109,13 +111,13 @@ export const InferenceExperimentsTable = (props: InferenceExperimentsTableProps) return ( -
+
- Are you sure you want to stop the inference experiment {inferenceExperimentToStop.name}? + {intl.formatMessage({ id: 'inference.stop.confirm' }, { name: inferenceExperimentToStop.name })} @@ -141,16 +143,16 @@ export const InferenceExperimentsTable = (props: InferenceExperimentsTableProps) return ( -
+
- Are you sure you want to delete the inference experiment {inferenceExperimentToRemove.name}? + {intl.formatMessage({ id: 'inference.delete.confirm' }, { name: inferenceExperimentToRemove.name })} @@ -165,24 +167,25 @@ export const InferenceExperimentsTable = (props: InferenceExperimentsTableProps) {/* Modal to confirm deleting the InferenceExperiment */} {getDeletionConfirmModal()} - headerTitle='Inference experiments' + headerTitle={intl.formatMessage({ id: 'inference.experiments.table.title' })} headers={[ - { name: 'Name', serverCodeToSort: 'name', width: 3 }, - { name: 'Description', serverCodeToSort: 'description', width: 4 }, - { name: 'State', serverCodeToSort: 'state', textAlign: 'center' }, - { name: 'Model', serverCodeToSort: 'model', width: 1 }, - { name: 'Date', serverCodeToSort: 'created' }, - { name: 'Datasets' }, - { name: 'Actions' } + { name: intl.formatMessage({ id: 'common.name' }), serverCodeToSort: 'name', width: 3 }, + { name: intl.formatMessage({ id: 'common.description' }), serverCodeToSort: 'description', width: 4 }, + { name: intl.formatMessage({ id: 'inference.table.columns.state' }), serverCodeToSort: 'state', textAlign: 'center' }, + { name: intl.formatMessage({ id: 'inference.table.columns.model' }), serverCodeToSort: 'model', width: 1 }, + { name: intl.formatMessage({ id: 'inference.table.columns.date' }), serverCodeToSort: 'created' }, + { name: intl.formatMessage({ id: 'inference.table.columns.dataset' }) }, + { name: intl.formatMessage({ id: 'common.actions' }) } + ]} queryParams={{ biomarker_pk: props.selectedBiomarker.id }} defaultSortProp={{ sortField: 'created', sortOrderAscendant: false }} showSearchInput - searchLabel='Name' - searchPlaceholder='Search by name or description' + searchLabel={intl.formatMessage({ id: 'common.name' })} + searchPlaceholder={intl.formatMessage({ id: 'inference.search.placeholder' })} urlToRetrieveData={urlBiomarkerInferenceExperiments} customElements={[ - + @@ -219,14 +222,15 @@ export const InferenceExperimentsTable = (props: InferenceExperimentsTableProps) onClick={() => { props.openInferenceResult(inferenceExperiment) }} className='clickable' color='blue' - title='See results' + title={intl.formatMessage({ id: 'inference.results.tooltip' })} + /> )} {/* Stop button */} {isInProcess && ( setInferenceExperimentToStop(inferenceExperiment)} /> )} @@ -235,7 +239,7 @@ export const InferenceExperimentsTable = (props: InferenceExperimentsTableProps) {/* Todo: Revisar ownerid */} {!isInProcess && ( setInferenceExperimentToRemove(inferenceExperiment)} ownerId={null} /> diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/NewInferenceExperimentModal.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/NewInferenceExperimentModal.tsx index 22ddb004..1ff3afb7 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/NewInferenceExperimentModal.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/NewInferenceExperimentModal.tsx @@ -7,6 +7,7 @@ import { SourceSelectors } from '../../../common/SourceSelectors' import { DjangoCGDSStudy, DjangoUserFile } from '../../../../utils/django_interfaces' import { BiomarkerTrainedModelsTable } from '../BiomarkerTrainedModelsTable' import ky from 'ky' +import { useIntl } from 'react-intl' declare const urlSubmitInferenceExperiment: string @@ -56,6 +57,7 @@ const getDefaultNewInferenceExperimentData = (): NewInferenceExperimentData => ( * @returns Component */ export const NewInferenceExperimentModal = (props: NewInferenceExperimentModalProps) => { + const intl = useIntl() const [form, setForm] = useState(getDefaultNewInferenceExperimentData()) const [currentStep, setCurrentStep] = useState(1) const [sendingData, setSendingData] = useState(false) @@ -292,7 +294,7 @@ export const NewInferenceExperimentModal = (props: NewInferenceExperimentModalPr return ( } + closeIcon={} closeOnEscape={false} centered={false} closeOnDimmerClick={false} @@ -302,7 +304,7 @@ export const NewInferenceExperimentModal = (props: NewInferenceExperimentModalPr > - Create new inference experiment + {intl.formatMessage({ id: 'inference.new.title' })} @@ -311,27 +313,30 @@ export const NewInferenceExperimentModal = (props: NewInferenceExperimentModalPr {/* Basic data */} -
Basic data
+
+ {intl.formatMessage({ id: 'inference.new.basicData' })} +
- Required field + {intl.formatMessage({ id: 'inference.new.requiredField' })} +
@@ -341,7 +346,7 @@ export const NewInferenceExperimentModal = (props: NewInferenceExperimentModalPr 1} link onClick={() => { setCurrentStep(1) }}> - Step 1: Trained model + {intl.formatMessage({ id: 'inference.new.step1' })} - Step 2: molecules datasets + {intl.formatMessage({ id: 'inference.new.step2' })} @@ -378,7 +383,7 @@ export const NewInferenceExperimentModal = (props: NewInferenceExperimentModalPr color='red' onClick={() => setCurrentStep(currentStep - 1)} > - Go back + {intl.formatMessage({ id: 'common.goBack' })} )} @@ -392,7 +397,7 @@ export const NewInferenceExperimentModal = (props: NewInferenceExperimentModalPr }} disabled={!selectedTrainedModelIsValid} > - Continue + {intl.formatMessage({ id: 'inference.new.continue' })} )} @@ -406,7 +411,7 @@ export const NewInferenceExperimentModal = (props: NewInferenceExperimentModalPr }} disabled={!formIsValid()} > - Confirm + {intl.formatMessage({ id: 'common.confirm' })} )} diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndGroupsInferenceTable.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndGroupsInferenceTable.tsx index 5a763c07..d915da4e 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndGroupsInferenceTable.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndGroupsInferenceTable.tsx @@ -5,6 +5,7 @@ import { PaginatedTable } from '../../../common/PaginatedTable' import { TableCellWithTitle } from '../../../common/TableCellWithTitle' import { ClusterLabelsSetSelect } from '../../../common/cluster-labels/ClusterLabelsSetSelect' import { NewClusterLabelsSetModal } from '../../../common/cluster-labels/NewClusterLabelsSetModal' +import { useIntl } from 'react-intl' declare const urlInferenceExperimentSamplesAndClusters: string declare const urlInferenceExperimentSamplesAndClustersDownload: string @@ -22,6 +23,7 @@ interface SamplesAndGroupsInferenceTableProps { * @returns Component. */ export const SamplesAndGroupsInferenceTable = (props: SamplesAndGroupsInferenceTableProps) => { + const intl = useIntl() const [selectedClusterSetPk, setSelectedClusterSetPk] = useState(undefined) const [openClusterLabelsSetModal, setOpenClusterLabelsSetModal] = useState(false) @@ -47,15 +49,16 @@ export const SamplesAndGroupsInferenceTable = (props: SamplesAndGroupsInferenceT headers={[ - { name: 'Sample', serverCodeToSort: 'sample', width: 3, textAlign: 'center' }, - { name: 'Cluster', serverCodeToSort: 'cluster', width: 2, textAlign: 'center' } + { name: intl.formatMessage({ id: 'common.sample' }), serverCodeToSort: 'sample', width: 3, textAlign: 'center' }, + { name: intl.formatMessage({ id: 'inference.table.columns.cluster' }), serverCodeToSort: 'cluster', width: 2, textAlign: 'center' } + ]} queryParams={{ inference_experiment_pk: props.selectedInferenceExperiment.id, ...extraQueryParams }} customElements={[ - + @@ -63,10 +66,10 @@ export const SamplesAndGroupsInferenceTable = (props: SamplesAndGroupsInferenceT ]} customFilters={[ { - label: 'Cluster', + label: intl.formatMessage({ id: 'common.sample' }), keyForServer: 'cluster', defaultValue: '', - placeholder: 'Filter by cluster', + placeholder: intl.formatMessage({ id: 'inference.table.filter.cluster.placeholder' }), allowZero: true, urlToRetrieveOptions: `${urlClustersUniqueInferenceExperiment}/${props.selectedInferenceExperiment.id}/` } @@ -74,8 +77,8 @@ export const SamplesAndGroupsInferenceTable = (props: SamplesAndGroupsInferenceT defaultSortProp={{ sortField: 'sample', sortOrderAscendant: false }} showSearchInput defaultPageSize={25} - searchLabel='Sample' - searchPlaceholder='Search by sample' + searchLabel={intl.formatMessage({ id: 'common.sample' })} + searchPlaceholder={intl.formatMessage({ id: 'common.search' })} urlToRetrieveData={urlInferenceExperimentSamplesAndClusters} mapFunction={(sampleAndCluster: SampleAndCluster) => { return ( @@ -88,7 +91,7 @@ export const SamplesAndGroupsInferenceTable = (props: SamplesAndGroupsInferenceT /> - {selectedTrainedModelPk !== null && ( + {selectedTrainedModelPk !== null && ( <> - - + + )} diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndTimeInferenceCharts.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndTimeInferenceCharts.tsx index c91dd401..0c60893a 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndTimeInferenceCharts.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndTimeInferenceCharts.tsx @@ -8,6 +8,7 @@ import { alertGeneralError } from '../../../../utils/util_functions' import { ResultPlaceholder } from '../stat-validations/result/ResultPlaceholder' import { BoxPlotChart } from '../../../pipeline/experiment-result/gene-gem-details/stats/BoxPlotChart' import { COLOR_YELLOW_FILL, COLOR_YELLOW_STROKE } from '../../../../utils/constants' +import { useIntl } from 'react-intl' declare const urlClinicalSourceAddOrEditInferenceExperiment: string declare const urlUnlinkClinicalSourceInferenceExperiment: string @@ -36,6 +37,7 @@ interface SamplesAndTimeInferenceChartsProps { * @returns Component. */ export const SamplesAndTimeInferenceCharts = (props: SamplesAndTimeInferenceChartsProps) => { + const intl = useIntl() const abortController = useRef(new AbortController()) const [loadingChartData, setLoadingChartData] = useState(false) const [chartData, setChartData] = useState([]) @@ -80,10 +82,10 @@ export const SamplesAndTimeInferenceCharts = (props: SamplesAndTimeInferenceChar
- No clinical attribute selected + {intl.formatMessage({ id: 'inference.charts.noAttribute' })} - Please, select one in the right Select. + {intl.formatMessage({ id: 'inference.charts.selectAttribute' })}
) diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndTimeInferenceTable.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndTimeInferenceTable.tsx index de57c85c..32956d34 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndTimeInferenceTable.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/SamplesAndTimeInferenceTable.tsx @@ -9,6 +9,7 @@ import { InfoPopup } from '../../../pipeline/experiment-result/gene-gem-details/ import { SamplesAndTimeInferenceCharts } from './SamplesAndTimeInferenceCharts' import { InferenceExperimentClinicalAttributeSelect } from './InferenceExperimentClinicalAttributeSelect' import { ClinicalSourcePopup } from '../../../pipeline/all-experiments-view/ClinicalSourcePopup' +import { useIntl } from 'react-intl' declare const urlInferenceExperimentSamplesAndTime: string declare const urlClinicalSourceAddOrEditInferenceExperiment: string @@ -28,6 +29,7 @@ interface SamplesAndTimeInferenceTableProps { * @returns Component. */ export const SamplesAndTimeInferenceTable = (props: SamplesAndTimeInferenceTableProps) => { + const intl = useIntl() const [activeMenuItem, setActiveMenuItem] = useState<'table' | 'charts'>('charts') // TODO: change to 'table' const [selectedRangeSetPk, setSelectedClusterSetPk] = useState(undefined) const [openRangeLabelsSetModal, setOpenRangeLabelsSetModal] = useState(false) @@ -48,8 +50,9 @@ export const SamplesAndTimeInferenceTable = (props: SamplesAndTimeInferenceTable return ( headers={[ - { name: 'Sample', serverCodeToSort: 'sample', width: 3, textAlign: 'center' }, - { name: 'Predicted time', serverCodeToSort: 'prediction', width: 2, textAlign: 'center' } + { name: intl.formatMessage({ id: 'common.sample' }), serverCodeToSort: 'sample', width: 3, textAlign: 'center' }, + { name: intl.formatMessage({ id: 'inference.timeTable.columns.predictedTime' }), serverCodeToSort: 'prediction', width: 2, textAlign: 'center' } + ]} queryParams={{ inference_experiment_pk: props.selectedInferenceExperiment.id, @@ -57,18 +60,18 @@ export const SamplesAndTimeInferenceTable = (props: SamplesAndTimeInferenceTable }} customFilters={[ { - label: 'Range', + label: intl.formatMessage({ id: 'inference.timeTable.filter.range.label' }), keyForServer: 'prediction', defaultValue: '', - placeholder: 'Filter by range', + placeholder: intl.formatMessage({ id: 'inference.timeTable.filter.range.placeholder' }), disabledFunction: () => selectedRangeSetPk === undefined } ]} defaultSortProp={{ sortField: 'sample', sortOrderAscendant: false }} showSearchInput defaultPageSize={25} - searchLabel='Sample' - searchPlaceholder='Search by sample' + searchLabel={intl.formatMessage({ id: 'common.sample' })} + searchPlaceholder={intl.formatMessage({ id: 'common.search' })} searchWidth={5} entriesSelectWidth={3} urlToRetrieveData={urlInferenceExperimentSamplesAndTime} @@ -116,10 +119,10 @@ export const SamplesAndTimeInferenceTable = (props: SamplesAndTimeInferenceTable active={activeMenuItem === 'charts'} onClick={() => setActiveMenuItem('charts')} > - Charts + {intl.formatMessage({ id: 'inference.timeTable.menu.table' })} - {selectedTrainedModelPk !== null && ( + {selectedTrainedModelPk !== null && ( <> {/* Clinical attribute select */} - {(activeMenuItem === 'charts' && props.selectedInferenceExperiment.clinical_source_id) && ( + {(activeMenuItem === 'charts' && props.selectedInferenceExperiment.clinical_source_id) && ( <> - + )} {/* Range Select */} @@ -176,8 +179,8 @@ export const SamplesAndTimeInferenceTable = (props: SamplesAndTimeInferenceTable setSelectedClusterSetPk={setSelectedClusterSetPk} /> - - + + )} diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/CurrentMoleculeDetails.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/CurrentMoleculeDetails.tsx index 4f463eeb..50231679 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/CurrentMoleculeDetails.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/CurrentMoleculeDetails.tsx @@ -11,6 +11,7 @@ import { GeneAssociationsNetworkPanel } from './genes/GeneAssociationsNetworkPan import { MiRNADrugsPanel } from '../../../pipeline/experiment-result/gene-gem-details/MiRNADrugsPanel' import { MiRNADiseasesPanel } from '../../../pipeline/experiment-result/gene-gem-details/MiRNADiseasesPanel' import { ActionableCancerGenesPanel } from './genes/ActionableCancerGenesPanel' +import { useIntl } from 'react-intl' // const MENU_DEFAULT: ActiveBiomarkerMoleculeItemMenu = ActiveBiomarkerMoleculeItemMenu.DETAILS // TODO: use this const MENU_DEFAULT: ActiveBiomarkerMoleculeItemMenu = ActiveBiomarkerMoleculeItemMenu.DETAILS @@ -31,6 +32,7 @@ interface CurrentMoleculeDetailsProps { */ export const CurrentMoleculeDetails = (props: CurrentMoleculeDetailsProps) => { const [activeItem, setActiveItem] = useState(MENU_DEFAULT) + const intl = useIntl() /** Effect to set the active item to DETAILS when the selected molecule changes. */ useEffect(() => { @@ -98,10 +100,10 @@ export const CurrentMoleculeDetails = (props: CurrentMoleculeDetailsProps) => {
- No molecule selected + {intl.formatMessage({ id: 'currentMoleculeDetails.noSelection' })} - Select one in the left panel + {intl.formatMessage({ id: 'currentMoleculeDetails.selectOne' })}
) diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/MoleculesDetailsMenu.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/MoleculesDetailsMenu.tsx index 5a98008b..d41a8bfe 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/MoleculesDetailsMenu.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/MoleculesDetailsMenu.tsx @@ -3,6 +3,7 @@ import { Menu } from 'semantic-ui-react' import { InfoPopup } from '../../../pipeline/experiment-result/gene-gem-details/InfoPopup' import { ActiveBiomarkerMoleculeItemMenu, BiomarkerMolecule } from '../../types' import { MoleculeType } from '../../../../utils/interfaces' +import { useIntl } from 'react-intl' /** MoleculesDetailsMenu props. */ interface MoleculesDetailsMenuProps { @@ -29,13 +30,13 @@ interface ItemMenuProp { */ export const MoleculesDetailsMenu = (props: MoleculesDetailsMenuProps) => { const isGene = [MoleculeType.MRNA, MoleculeType.CNA].includes(props.selectedMolecule.type) - + const intl = useIntl() /** * Array with all the items and conditions */ const items: ItemMenuProp[] = [ { - name: 'Details', + name: intl.formatMessage({ id: 'common.details' }), onClick: () => props.setActiveItem(ActiveBiomarkerMoleculeItemMenu.DETAILS), isActive: props.activeItem === ActiveBiomarkerMoleculeItemMenu.DETAILS, popupInfo: `Details of ${props.selectedMolecule.identifier} obtained from different standardized sources`, @@ -50,14 +51,14 @@ export const MoleculesDetailsMenu = (props: MoleculesDetailsMenuProps) => { // isVisible: isGene // }, { - name: 'Gene associations network', + name: intl.formatMessage({ id: 'moleculesDetailsMenu.geneAssociations' }), onClick: () => props.setActiveItem(ActiveBiomarkerMoleculeItemMenu.GENE_ASSOCIATIONS_NETWORK), isActive: props.activeItem === ActiveBiomarkerMoleculeItemMenu.GENE_ASSOCIATIONS_NETWORK, popupInfo: 'It shows the network of gene associations of the genes of this biomarker', isVisible: isGene }, { - name: 'Gene Ontology', + name: intl.formatMessage({ id: 'moleculesDetailsMenu.geneOntology' }), onClick: () => props.setActiveItem(ActiveBiomarkerMoleculeItemMenu.GENE_ONTOLOGY), isActive: props.activeItem === ActiveBiomarkerMoleculeItemMenu.GENE_ONTOLOGY, popupInfo: 'Gene Ontology (GO) is a powerful tool for understanding the biological processes, molecular functions, and cellular components associated with a gene', @@ -72,21 +73,21 @@ export const MoleculesDetailsMenu = (props: MoleculesDetailsMenuProps) => { // isVisible: isGene // }, { - name: 'Diseases', + name: intl.formatMessage({ id: 'moleculesDetailsMenu.diseases' }), onClick: () => props.setActiveItem(ActiveBiomarkerMoleculeItemMenu.DISEASES), isActive: props.activeItem === ActiveBiomarkerMoleculeItemMenu.DISEASES, popupInfo: 'Interactions of the molecule with diseases that have been reported in the literature', isVisible: [MoleculeType.MIRNA].includes(props.selectedMolecule.type) }, { - name: 'Drugs', + name: intl.formatMessage({ id: 'moleculesDetailsMenu.drugs' }), onClick: () => props.setActiveItem(ActiveBiomarkerMoleculeItemMenu.DRUGS), isActive: props.activeItem === ActiveBiomarkerMoleculeItemMenu.DRUGS, popupInfo: 'Interactions of the molecule with drugs that have been reported in the literature', isVisible: [MoleculeType.MIRNA].includes(props.selectedMolecule.type) }, { - name: 'miRNA-Gene interactions', + name: intl.formatMessage({ id: 'moleculesDetailsMenu.miRNAGeneInteractions' }), onClick: () => props.setActiveItem(ActiveBiomarkerMoleculeItemMenu.MIRNA_GENE_INTERACTIONS), isActive: props.activeItem === ActiveBiomarkerMoleculeItemMenu.MIRNA_GENE_INTERACTIONS, popupInfo: 'Different miRNA-Gene interactions that have been reported in the literature along with the associated mirDIP score and Pubmed sources', diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/MoleculesTable.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/MoleculesTable.tsx index dc1b9d23..e19784ab 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/MoleculesTable.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/MoleculesTable.tsx @@ -5,6 +5,7 @@ import { PaginatedTable } from '../../../common/PaginatedTable' import { TableCellWithTitle } from '../../../common/TableCellWithTitle' import { MoleculeTypeLabel } from '../../labels/MoleculeTypeLabel' import { MoleculeType, Nullable } from '../../../../utils/interfaces' +import { useIntl } from 'react-intl' declare const urlBiomarkerMolecules: string @@ -18,35 +19,35 @@ interface MoleculesTableProps { openMoleculeDetails: (molecule: BiomarkerMolecule) => void } -const moleculesTypesOptions: DropdownItemProps[] = [ - { key: MoleculeType.MRNA, text: 'mRNA', value: MoleculeType.MRNA }, - { key: MoleculeType.MIRNA, text: 'miRNA', value: MoleculeType.MIRNA }, - { key: MoleculeType.CNA, text: 'CNA', value: MoleculeType.CNA }, - { key: MoleculeType.METHYLATION, text: 'Methylation', value: MoleculeType.METHYLATION } -] - /** * Renders a Table with the samples and the cluster where they belong. * @param props Component props. * @returns Component. */ export const MoleculesTable = (props: MoleculesTableProps) => { + const intl = useIntl() + const moleculesTypesOptions: DropdownItemProps[] = [ + { key: MoleculeType.MRNA, text: intl.formatMessage({ id: 'moleculesTable.type.mrna' }), value: MoleculeType.MRNA }, + { key: MoleculeType.MIRNA, text: intl.formatMessage({ id: 'moleculesTable.type.mirna' }), value: MoleculeType.MIRNA }, + { key: MoleculeType.CNA, text: intl.formatMessage({ id: 'moleculesTable.type.cna' }), value: MoleculeType.CNA }, + { key: MoleculeType.METHYLATION, text: intl.formatMessage({ id: 'moleculesTable.type.methylation' }), value: MoleculeType.METHYLATION } + ] return ( headers={[ - { name: 'Identifier', serverCodeToSort: 'identifier', width: 3 }, - { name: 'Type', serverCodeToSort: 'type', width: 2 }, - { name: 'Actions' } + { name: intl.formatMessage({ id: 'moleculesTable.header.identifier' }), serverCodeToSort: 'identifier', width: 3 }, + { name: intl.formatMessage({ id: 'moleculesTable.header.type' }), serverCodeToSort: 'type', width: 2 }, + { name: intl.formatMessage({ id: 'moleculesTable.header.actions' }) } ]} queryParams={{ biomarker_pk: props.selectedBiomarker.id }} customFilters={[ - { label: 'Type', keyForServer: 'type', defaultValue: '', options: moleculesTypesOptions, width: 6 } + { label: intl.formatMessage({ id: 'moleculesTable.header.type' }), keyForServer: 'type', defaultValue: '', options: moleculesTypesOptions, width: 6 } ]} defaultSortProp={{ sortField: 'identifier', sortOrderAscendant: true }} showSearchInput defaultPageSize={25} - searchLabel='Sample' - searchPlaceholder='Search by identifier' + searchLabel={intl.formatMessage({ id: 'common.sample' })} + searchPlaceholder={intl.formatMessage({ id: 'common.search' }) + ' ' + intl.formatMessage({ id: 'moleculesTable.header.identifier' })} urlToRetrieveData={urlBiomarkerMolecules} searchWidth={6} entriesSelectWidth={3} @@ -61,7 +62,7 @@ export const MoleculesTable = (props: MoleculesTableProps) => { name='chart bar' className='clickable' color='blue' - title='Details' + title={intl.formatMessage({ id: 'common.details' })} onClick={() => props.openMoleculeDetails(molecule)} /> diff --git a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/gene-ontology/GeneOntologyCytoscapeChart.tsx b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/gene-ontology/GeneOntologyCytoscapeChart.tsx index 9b277bba..429c6a37 100644 --- a/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/gene-ontology/GeneOntologyCytoscapeChart.tsx +++ b/src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/molecules/gene-ontology/GeneOntologyCytoscapeChart.tsx @@ -6,6 +6,7 @@ import { alertGeneralError } from '../../../../../utils/util_functions' import { OntologyRelationTermToTermFilter, CytoscapeElements, OntologyType, GoTermToTermSearchParams, GoTermToTermForm } from './types' import { Button, Form, Grid } from 'semantic-ui-react' import '../../../../../css/cytoscape.css' +import { useIntl } from 'react-intl' declare const urlGOTermToTerms: string @@ -20,18 +21,27 @@ const COLORS_BY_ONTOLOGY_RELATION = { * Renders the legends for the Cytoscape instance. * @returns Component. */ -const CytoscapeLegends = () => ( -
-
Relations
-
-
    - {Object.entries(COLORS_BY_ONTOLOGY_RELATION).map(([_, [relationDescription, color]]) => ( -
  • {relationDescription}
  • - ))} -
+const CytoscapeLegends = () => { + const intl = useIntl() + + return ( +
+
+ {intl.formatMessage({ id: 'geneOntology.legend.relations' })} +
+
+
    + {Object.entries(COLORS_BY_ONTOLOGY_RELATION).map(([_, [relationDescription, color]]) => ( +
  • + + {relationDescription} +
  • + ))} +
+
-
-) + ) +} /** GeneOntologyCytoscapeChart props. */ interface GeneOntologyCytoscapeChartProps { @@ -47,6 +57,7 @@ interface GeneOntologyCytoscapeChartProps { * @returns Component. */ export const GeneOntologyCytoscapeChart = (props: GeneOntologyCytoscapeChartProps) => { + const intl = useIntl() const abortControllerTerm = useRef(new AbortController()) const [termsRelatedToTermForm, setTermsRelatedToTermForm] = useState({ relations: [OntologyRelationTermToTermFilter.PART_OF, OntologyRelationTermToTermFilter.REGULATES, OntologyRelationTermToTermFilter.HAS_PART], @@ -188,12 +199,12 @@ export const GeneOntologyCytoscapeChart = (props: GeneOntologyCytoscapeChartProp {/* Go back button. */} -