diff --git a/README.md b/README.md index 996b13f5..9ec7e816 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ This readme file is used mostly to document project dependencies and conventions - react-toastify - react-tabs - react-intl - - react-select - react-error-boundary - react-tooltip - react-zoom-pan-pinch diff --git a/TODO.txt b/TODO.txt index 7dd38da3..1f9e13a6 100644 --- a/TODO.txt +++ b/TODO.txt @@ -31,11 +31,9 @@ User profile: - Sitemap for better SEO and crawler optimization [Functionality - CANCELED] -- User notifications on edit - consider spam prevention and change aggregation - Integrate socials and feedback - Content based search in Library - Private projects. Consider cooperative editing -- OSS: synthesis table: auto substitution for diamond synthesis [Tech] diff --git a/rsconcept/frontend/package-lock.json b/rsconcept/frontend/package-lock.json index b8f9c894..bb4e5c24 100644 --- a/rsconcept/frontend/package-lock.json +++ b/rsconcept/frontend/package-lock.json @@ -34,7 +34,6 @@ "react-intl": "^7.1.10", "react-router": "^7.5.0", "react-scan": "^0.3.3", - "react-select": "^5.10.1", "react-tabs": "^6.1.0", "react-toastify": "^11.0.5", "react-tooltip": "^5.28.1", @@ -987,135 +986,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/@emotion/babel-plugin": { - "version": "11.13.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", - "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.3.3", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "license": "MIT" - }, - "node_modules/@emotion/babel-plugin/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", - "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "^0.9.0", - "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.2", - "@emotion/weak-memoize": "^0.4.0", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", - "license": "MIT" - }, - "node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", - "license": "MIT" - }, - "node_modules/@emotion/react": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", - "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.13.5", - "@emotion/cache": "^11.14.0", - "@emotion/serialize": "^1.3.3", - "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", - "@emotion/utils": "^1.4.2", - "@emotion/weak-memoize": "^0.4.0", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", - "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", - "license": "MIT", - "dependencies": { - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.10.0", - "@emotion/utils": "^1.4.2", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", - "license": "MIT" - }, - "node_modules/@emotion/unitless": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", - "license": "MIT" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", - "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", - "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", - "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", - "license": "MIT" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", - "license": "MIT" - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", @@ -4434,7 +4304,10 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@types/react": { "version": "19.1.1", @@ -4464,15 +4337,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.12", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", - "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*" - } - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -5211,7 +5075,10 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -5500,6 +5367,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5747,7 +5615,10 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -5763,7 +5634,10 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">= 6" } @@ -6175,16 +6049,6 @@ "node": ">=0.10.0" } }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, "node_modules/dom-walk": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", @@ -6274,6 +6138,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -6502,6 +6367,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -7240,12 +7106,6 @@ "node": ">=8" } }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "license": "MIT" - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -7903,6 +7763,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -8020,6 +7881,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, "license": "MIT" }, "node_modules/is-async-function": { @@ -8092,6 +7954,7 @@ "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -9211,6 +9074,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { @@ -9559,6 +9423,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, "license": "MIT" }, "node_modules/locate-path": { @@ -9688,12 +9553,6 @@ "dev": true, "license": "CC0-1.0" }, - "node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "license": "MIT" - }, "node_modules/meow": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", @@ -10110,6 +9969,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -10122,6 +9982,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -10170,12 +10031,14 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10816,27 +10679,6 @@ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "license": "MIT" }, - "node_modules/react-select": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.10.1.tgz", - "integrity": "sha512-roPEZUL4aRZDx6DcsD+ZNreVl+fM8VsKn0Wtex1v4IazH60ILp5xhdlp464IsEAlJdXeD+BhDAFsBVMfvLQueA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.0", - "@emotion/cache": "^11.4.0", - "@emotion/react": "^11.8.1", - "@floating-ui/dom": "^1.0.1", - "@types/react-transition-group": "^4.4.0", - "memoize-one": "^6.0.0", - "prop-types": "^15.6.0", - "react-transition-group": "^4.3.0", - "use-isomorphic-layout-effect": "^1.2.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/react-style-singleton": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", @@ -10899,22 +10741,6 @@ "react-dom": ">=16.14.0" } }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "license": "BSD-3-Clause", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, "node_modules/react-zoom-pan-pinch": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.7.0.tgz", @@ -11021,6 +10847,7 @@ "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.16.0", @@ -11064,6 +10891,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -11898,12 +11726,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", - "license": "MIT" - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11938,6 +11760,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -12935,20 +12758,6 @@ "react": "*" } }, - "node_modules/use-isomorphic-layout-effect": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", - "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/use-sidecar": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", diff --git a/rsconcept/frontend/package.json b/rsconcept/frontend/package.json index f1fe922d..ee6d36d2 100644 --- a/rsconcept/frontend/package.json +++ b/rsconcept/frontend/package.json @@ -40,7 +40,6 @@ "react-intl": "^7.1.10", "react-router": "^7.5.0", "react-scan": "^0.3.3", - "react-select": "^5.10.1", "react-tabs": "^6.1.0", "react-toastify": "^11.0.5", "react-tooltip": "^5.28.1", diff --git a/rsconcept/frontend/src/components/input/index.tsx b/rsconcept/frontend/src/components/input/index.tsx index c6e9d37f..e8374ebe 100644 --- a/rsconcept/frontend/src/components/input/index.tsx +++ b/rsconcept/frontend/src/components/input/index.tsx @@ -4,7 +4,6 @@ export { ErrorField } from './error-field'; export { FileInput } from './file-input'; export { Label } from './label'; export { SearchBar } from './search-bar'; -export { SelectMulti, type SelectMultiProps } from './select-multi'; export { SelectTree } from './select-tree'; export { TextArea } from './text-area'; export { TextInput } from './text-input'; diff --git a/rsconcept/frontend/src/components/input/select-multi.tsx b/rsconcept/frontend/src/components/input/select-multi.tsx deleted file mode 100644 index 3ef4009d..00000000 --- a/rsconcept/frontend/src/components/input/select-multi.tsx +++ /dev/null @@ -1,128 +0,0 @@ -'use client'; - -import Select, { - type ClearIndicatorProps, - components, - type DropdownIndicatorProps, - type GroupBase, - type Props, - type StylesConfig -} from 'react-select'; - -import { useWindowSize } from '@/hooks/use-window-size'; -import { APP_COLORS, SELECT_THEME } from '@/styling/colors'; - -import { IconClose, IconDropArrow, IconDropArrowUp } from '../icons'; - -function DropdownIndicator = GroupBase>( - props: DropdownIndicatorProps -) { - return ( - components.DropdownIndicator && ( - - {props.selectProps.menuIsOpen ? : } - - ) - ); -} - -function ClearIndicator = GroupBase>( - props: ClearIndicatorProps -) { - return ( - components.ClearIndicator && ( - - - - ) - ); -} - -export interface SelectMultiProps = GroupBase> - extends Omit, 'theme' | 'menuPortalTarget'> { - noPortal?: boolean; -} - -/** - * Displays a multi-select component. - */ -export function SelectMulti = GroupBase>({ - noPortal, - ...restProps -}: SelectMultiProps) { - const size = useWindowSize(); - - const adjustedStyles: StylesConfig = { - container: defaultStyles => ({ - ...defaultStyles, - borderRadius: '0.25rem' - }), - control: (styles, { isDisabled }) => ({ - ...styles, - borderRadius: '0.25rem', - cursor: isDisabled ? 'not-allowed' : 'pointer', - boxShadow: 'none' - }), - option: (styles, { isSelected }) => ({ - ...styles, - padding: '0.25rem 0.75rem', - fontSize: '0.875rem', - lineHeight: '1.25rem', - backgroundColor: isSelected ? APP_COLORS.bgSelected : styles.backgroundColor, - color: isSelected ? APP_COLORS.fgSelected : styles.color, - borderWidth: '1px', - borderColor: APP_COLORS.border - }), - menuPortal: styles => ({ - ...styles, - zIndex: 9999 - }), - menuList: styles => ({ - ...styles, - padding: 0 - }), - input: styles => ({ ...styles }), - placeholder: styles => ({ ...styles }), - multiValue: styles => ({ - ...styles, - borderRadius: '0.5rem', - backgroundColor: APP_COLORS.bgSelected - }), - dropdownIndicator: base => ({ - ...base, - paddingTop: 0, - paddingBottom: 0 - }), - clearIndicator: base => ({ - ...base, - paddingTop: 0, - paddingBottom: 0 - }) - }; - - return ( - 'Список пуст'} - components={{ DropdownIndicator, ClearIndicator }} - theme={theme => ({ - ...theme, - borderRadius: 0, - spacing: { - ...theme.spacing, - baseUnit: size.isSmall ? 2 : 4, - menuGutter: size.isSmall ? 4 : 8, - controlHeight: size.isSmall ? 28 : 38 - }, - colors: { - ...theme.colors, - ...SELECT_THEME - } - })} - menuPortalTarget={!noPortal ? document.body : null} - styles={adjustedStyles} - classNames={{ container: () => 'focus-frame' }} - {...restProps} - /> - ); -} diff --git a/rsconcept/frontend/src/components/ui/combo-multi.tsx b/rsconcept/frontend/src/components/ui/combo-multi.tsx new file mode 100644 index 00000000..1aa332e6 --- /dev/null +++ b/rsconcept/frontend/src/components/ui/combo-multi.tsx @@ -0,0 +1,150 @@ +'use client'; + +import { useEffect, useRef, useState } from 'react'; +import clsx from 'clsx'; +import { ChevronDownIcon } from 'lucide-react'; + +import { IconRemove } from '../icons'; +import { type Styling } from '../props'; +import { cn } from '../utils'; + +import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from './command'; +import { Popover, PopoverContent, PopoverTrigger } from './popover'; + +interface ComboMultiProps extends Styling { + id?: string; + items?: Option[]; + value: Option[]; + onChange: (newValue: Option[]) => void; + + idFunc: (item: Option) => string; + labelValueFunc: (item: Option) => string; + labelOptionFunc: (item: Option) => string; + + placeholder?: string; + noSearch?: boolean; +} + +/** + * Displays a combo-box component with multiple selection. + */ +export function ComboMulti({ + id, + items, + value, + onChange, + labelValueFunc, + labelOptionFunc, + idFunc, + placeholder, + className, + style, + noSearch +}: ComboMultiProps) { + const [open, setOpen] = useState(false); + const [popoverWidth, setPopoverWidth] = useState(undefined); + const triggerRef = useRef(null); + + useEffect(() => { + if (triggerRef.current) { + setPopoverWidth(triggerRef.current.offsetWidth); + } + }, [open]); + + function handleAddValue(newValue: Option) { + if (value.includes(newValue)) { + handleRemoveValue(newValue); + } else { + onChange([...value, newValue]); + setOpen(false); + } + } + + function handleRemoveValue(delValue: Option) { + onChange(value.filter(v => v !== delValue)); + setOpen(false); + } + + function handleClear(event: React.MouseEvent) { + event.stopPropagation(); + onChange([]); + setOpen(false); + } + + return ( + + + + + {value.length === 0 ? {placeholder} : null} + {value.map(item => ( + + {labelValueFunc(item)} + { + event.stopPropagation(); + handleRemoveValue(item); + }} + /> + + ))} + + + + {!!value ? ( + + ) : null} + + + + + {!noSearch ? : null} + + Список пуст + + {items?.map(item => ( + handleAddValue(item)} + className={cn(value === item && 'bg-selected text-selected-foreground')} + > + {labelOptionFunc(item)} + + ))} + + + + + + ); +} diff --git a/rsconcept/frontend/src/features/rsform/components/select-multi-grammeme.tsx b/rsconcept/frontend/src/features/rsform/components/select-multi-grammeme.tsx index 4a680eb9..8cd76079 100644 --- a/rsconcept/frontend/src/features/rsform/components/select-multi-grammeme.tsx +++ b/rsconcept/frontend/src/features/rsform/components/select-multi-grammeme.tsx @@ -1,27 +1,30 @@ -import { SelectMulti, type SelectMultiProps } from '@/components/input'; import { type Styling } from '@/components/props'; +import { ComboMulti } from '@/components/ui/combo-multi'; -import { Grammeme, type IGrammemeOption } from '../models/language'; -import { getCompatibleGrams, grammemeCompare, supportedGrammeOptions } from '../models/language-api'; +import { labelGrammeme } from '../labels'; +import { type Grammeme, supportedGrammemes } from '../models/language'; +import { getCompatibleGrams } from '../models/language-api'; -interface SelectMultiGrammemeProps extends Omit, 'value' | 'onChange'>, Styling { - value: IGrammemeOption[]; - onChange: (newValue: IGrammemeOption[]) => void; +interface SelectMultiGrammemeProps extends Styling { + id?: string; + value: Grammeme[]; + onChange: (newValue: Grammeme[]) => void; placeholder?: string; } export function SelectMultiGrammeme({ value, onChange, ...restProps }: SelectMultiGrammemeProps) { - const compatible = getCompatibleGrams( - value.filter(data => Object.values(Grammeme).includes(data.value)).map(data => data.value) - ); - const options = supportedGrammeOptions.filter(({ value }) => compatible.includes(value)); + const compatible = getCompatibleGrams(value); + const items: Grammeme[] = [...supportedGrammemes.filter(gram => compatible.includes(gram))]; return ( - onChange([...newValue].sort((left, right) => grammemeCompare(left.value, right.value)))} + onChange={onChange} + idFunc={gram => gram} + labelOptionFunc={gram => labelGrammeme(gram)} + labelValueFunc={gram => labelGrammeme(gram)} {...restProps} /> ); diff --git a/rsconcept/frontend/src/features/rsform/components/select-word-form.tsx b/rsconcept/frontend/src/features/rsform/components/select-word-form.tsx index 955adb06..4e33a1d2 100644 --- a/rsconcept/frontend/src/features/rsform/components/select-word-form.tsx +++ b/rsconcept/frontend/src/features/rsform/components/select-word-form.tsx @@ -5,8 +5,7 @@ import clsx from 'clsx'; import { type Styling } from '@/components/props'; import { prefixes } from '@/utils/constants'; -import { Grammeme, type IGrammemeOption } from '../models/language'; -import { supportedGrammeOptions } from '../models/language-api'; +import { Grammeme, supportedGrammemes } from '../models/language'; import { WordformButton } from './wordform-button'; @@ -30,13 +29,13 @@ const DefaultWordForms = [ ] as const; interface SelectWordFormProps extends Styling { - value: IGrammemeOption[]; - onChange: React.Dispatch>; + value: Grammeme[]; + onChange: React.Dispatch>; } export function SelectWordForm({ value, onChange, className, ...restProps }: SelectWordFormProps) { function handleSelect(grams: Grammeme[]) { - onChange(supportedGrammeOptions.filter(({ value }) => grams.includes(value))); + onChange(supportedGrammemes.filter(value => grams.includes(value))); } return ( @@ -47,7 +46,7 @@ export function SelectWordForm({ value, onChange, className, ...restProps }: Sel text={data.text} example={data.example} grams={data.grams} - isSelected={data.grams.every(gram => value.find(item => item.value === gram))} + isSelected={data.grams.every(gram => value.find(item => item === gram))} onSelectGrams={handleSelect} /> ))} diff --git a/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-reference/dlg-edit-reference.tsx b/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-reference/dlg-edit-reference.tsx index 60067ebc..f88bc6a4 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-reference/dlg-edit-reference.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-reference/dlg-edit-reference.tsx @@ -12,13 +12,14 @@ import { TabLabel, TabList, TabPanel, Tabs } from '@/components/tabs'; import { useDialogsStore } from '@/stores/dialogs'; import { labelReferenceType } from '../../labels'; -import { type IReference, ReferenceType, schemaGrammemeOption, schemaReferenceType } from '../../models/language'; import { - parseEntityReference, - parseGrammemes, - parseSyntacticReference, - supportedGrammeOptions -} from '../../models/language-api'; + type IReference, + ReferenceType, + schemaGrammeme, + schemaReferenceType, + supportedGrammemes +} from '../../models/language'; +import { parseEntityReference, parseGrammemes, parseSyntacticReference } from '../../models/language-api'; import { type IRSForm } from '../../models/rsform'; import { TabEntityReference } from './tab-entity-reference'; @@ -37,7 +38,7 @@ const schemaEditReferenceState = z type: schemaReferenceType, entity: z.strictObject({ entity: z.string(), - grams: z.array(schemaGrammemeOption) + grams: z.array(schemaGrammeme) }), syntactic: z.strictObject({ offset: z.coerce.number(), nominal: z.string() }) }) @@ -82,7 +83,7 @@ export function DlgEditReference() { type: data.type, data: { entity: data.entity.entity, - form: data.entity.grams.map(gram => gram.value).join(',') + form: data.entity.grams.join(',') } }); } else { @@ -138,7 +139,7 @@ function initEntityReference(initial: IReferenceInputState) { } else { const ref = parseEntityReference(initial.refRaw); const grams = parseGrammemes(ref.form); - const supported = supportedGrammeOptions.filter(data => grams.includes(data.value)); + const supported = supportedGrammemes.filter(data => grams.includes(data)); return { entity: ref.entity, grams: supported diff --git a/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-reference/tab-entity-reference.tsx b/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-reference/tab-entity-reference.tsx index 5bac2267..14d30f9c 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-reference/tab-entity-reference.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-reference/tab-entity-reference.tsx @@ -77,7 +77,6 @@ export function TabEntityReference() { id='dlg_reference_grammemes' placeholder='Выберите граммемы' className='grow' - menuPlacement='top' value={field.value} onChange={field.onChange} /> diff --git a/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-word-forms/dlg-edit-word-forms.tsx b/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-word-forms/dlg-edit-word-forms.tsx index 42d76dce..dde4f1ef 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-word-forms/dlg-edit-word-forms.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/dlg-edit-word-forms/dlg-edit-word-forms.tsx @@ -17,8 +17,8 @@ import { useIsProcessingCctext } from '../../backend/cctext/use-is-processing-cc import { useParseText } from '../../backend/cctext/use-parse-text'; import { useCstUpdate } from '../../backend/use-cst-update'; import { SelectMultiGrammeme } from '../../components/select-multi-grammeme'; -import { type IGrammemeOption, type IWordForm, supportedGrammemes } from '../../models/language'; -import { parseGrammemes, supportedGrammeOptions, wordFormEquals } from '../../models/language-api'; +import { type Grammeme, type IWordForm, supportedGrammemes } from '../../models/language'; +import { parseGrammemes, wordFormEquals } from '../../models/language-api'; import { type IConstituenta } from '../../models/rsform'; import { TableWordForms } from './table-word-forms'; @@ -38,7 +38,7 @@ export function DlgEditWordForms() { const { generateLexeme } = useGenerateLexeme(); const [inputText, setInputText] = useState(target.term_resolved); - const [inputGrams, setInputGrams] = useState([]); + const [inputGrams, setInputGrams] = useState([]); const [forms, setForms] = useState( target.term_forms.map(term => ({ @@ -65,27 +65,27 @@ export function DlgEditWordForms() { function handleAddForm() { const newForm: IWordForm = { text: inputText, - grams: inputGrams.map(item => item.value) + grams: inputGrams }; setForms(forms => [newForm, ...forms.filter(value => !wordFormEquals(value, newForm))]); } function handleSelectForm(form: IWordForm) { setInputText(form.text); - setInputGrams(supportedGrammeOptions.filter(gram => form.grams.find(test => test === gram.value))); + setInputGrams(supportedGrammemes.filter(gram => form.grams.find(test => test === gram))); } function handleInflect() { void inflectText({ text: target.term_resolved, - grams: inputGrams.map(gram => gram.value).join(',') + grams: inputGrams.join(',') }).then(response => setInputText(response.result)); } function handleParse() { void parseText({ text: inputText }).then(response => { const grams = parseGrammemes(response.result); - setInputGrams(supportedGrammeOptions.filter(gram => grams.find(test => test === gram.value))); + setInputGrams(supportedGrammemes.filter(gram => grams.find(test => test === gram))); }); } @@ -159,7 +159,7 @@ export function DlgEditWordForms() { diff --git a/rsconcept/frontend/src/features/rsform/models/language-api.ts b/rsconcept/frontend/src/features/rsform/models/language-api.ts index e9968580..c29fbabe 100644 --- a/rsconcept/frontend/src/features/rsform/models/language-api.ts +++ b/rsconcept/frontend/src/features/rsform/models/language-api.ts @@ -2,19 +2,15 @@ * Module: Natural language model API. */ -import { labelGrammeme } from '../labels'; - import { Grammeme, GrammemeGroups, type IEntityReference, - type IGrammemeOption, type IReference, type ISyntacticReference, type IWordForm, NounGrams, ReferenceType, - supportedGrammemes, VerbGrams } from './language'; @@ -122,14 +118,6 @@ export function parseSyntacticReference(text: string): ISyntacticReference { }; } -/** - * Represents options for {@link Grammeme} selector. - */ -export const supportedGrammeOptions: IGrammemeOption[] = supportedGrammemes.map(gram => ({ - value: gram, - label: labelGrammeme(gram) -})); - /** * Transforms {@link IReference} to string representation. */ diff --git a/rsconcept/frontend/src/features/rsform/models/language.ts b/rsconcept/frontend/src/features/rsform/models/language.ts index 5d061925..2d463266 100644 --- a/rsconcept/frontend/src/features/rsform/models/language.ts +++ b/rsconcept/frontend/src/features/rsform/models/language.ts @@ -230,13 +230,6 @@ export const supportedGrammemes = [ Grammeme.accs, Grammeme.ablt, Grammeme.loct, ] as const; -export const schemaGrammemeOption = z.strictObject({ - value: schemaGrammeme, - label: z.string() -}); - -export type IGrammemeOption = z.infer; - // ====== Reference resolution ===== /** Represents text reference type. */ diff --git a/rsconcept/frontend/src/styling/colors.ts b/rsconcept/frontend/src/styling/colors.ts index 081cb278..c209f64d 100644 --- a/rsconcept/frontend/src/styling/colors.ts +++ b/rsconcept/frontend/src/styling/colors.ts @@ -19,7 +19,7 @@ export const APP_COLORS = { fgDefault: 'var(--clr-prim-999)', fgSelected: 'var(--clr-prim-999)', - fgDisabled: 'var(--clr-prim-800)', + fgMuted: 'var(--clr-prim-600)', fgWarning: 'var(--clr-warn-600)', bgRed: 'var(--acc-bg-red)', @@ -40,26 +40,3 @@ export const APP_COLORS = { fgTeal: 'var(--acc-fg-teal)', fgOrange: 'var(--acc-fg-orange)' } - -/** Represents Select component theme. */ -export const SELECT_THEME = { - primary: APP_COLORS.bgPrimary, - primary75: APP_COLORS.bgSelected, - primary50: APP_COLORS.bgHover, - primary25: APP_COLORS.bgHover, - - danger: APP_COLORS.fgWarning, - dangerLight: APP_COLORS.bgWarning, - - neutral0: APP_COLORS.bgInput, - neutral5: APP_COLORS.bgDefault, - neutral10: APP_COLORS.border, - neutral20: APP_COLORS.border, - neutral30: APP_COLORS.border, - neutral40: APP_COLORS.fgDisabled, - neutral50: APP_COLORS.fgDisabled, // placeholder - neutral60: APP_COLORS.fgDefault, - neutral70: APP_COLORS.fgWarning, - neutral80: APP_COLORS.fgDefault, - neutral90: APP_COLORS.fgWarning -};