From b720663f10f2baa34c18c531475656e67db87f3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 08:35:51 +0000 Subject: [PATCH 01/23] Bump rollup from 2.67.2 to 2.79.2 Bumps [rollup](https://github.com/rollup/rollup) from 2.67.2 to 2.79.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v2.67.2...v2.79.2) --- updated-dependencies: - dependency-name: rollup dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1da7b35..eb21b008 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14810,9 +14810,9 @@ } }, "node_modules/rollup": { - "version": "2.67.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", - "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "bin": { "rollup": "dist/bin/rollup" }, @@ -28451,9 +28451,9 @@ } }, "rollup": { - "version": "2.67.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", - "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "requires": { "fsevents": "~2.3.2" } From 6199bf375fc980f72148c629de3653ee823e9fa5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 13:53:15 +0000 Subject: [PATCH 02/23] Bump serve-static and express Bumps [serve-static](https://github.com/expressjs/serve-static) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `serve-static` from 1.15.0 to 1.16.2 - [Release notes](https://github.com/expressjs/serve-static/releases) - [Changelog](https://github.com/expressjs/serve-static/blob/v1.16.2/HISTORY.md) - [Commits](https://github.com/expressjs/serve-static/compare/v1.15.0...v1.16.2) Updates `express` from 4.19.2 to 4.21.0 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md) - [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0) --- updated-dependencies: - dependency-name: serve-static dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 452 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 318 insertions(+), 134 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb21b008..ac0d87ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5242,9 +5242,9 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -5254,7 +5254,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -5438,12 +5438,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6679,6 +6685,22 @@ "node": ">= 10" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -7042,9 +7064,9 @@ } }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "engines": { "node": ">= 0.8" } @@ -7173,6 +7195,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", @@ -7892,36 +7933,36 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -7959,9 +8000,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", @@ -8173,12 +8214,12 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -8454,9 +8495,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.4", @@ -8512,13 +8556,18 @@ "integrity": "sha1-SCG85m8cJMsDMWAr5strEsTwHEs=" }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8660,6 +8709,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -8722,11 +8782,22 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8757,6 +8828,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -11080,9 +11162,12 @@ "integrity": "sha512-QmpUu4KqDmX0plH4u+tf0riMc1KHE1+lw95cMrLlXQAFOx/xnBtwhZ52XJxd9X2O6kwKBqX32kmhbhlobD0cuw==" }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -11525,9 +11610,12 @@ } }, "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -13457,11 +13545,11 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -15015,9 +15103,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -15058,6 +15146,14 @@ "node": ">= 0.8" } }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -15134,19 +15230,35 @@ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -15197,13 +15309,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -21640,9 +21756,9 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -21652,7 +21768,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -21774,12 +21890,15 @@ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -22672,6 +22791,16 @@ "execa": "^5.0.0" } }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, "define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -22943,9 +23072,9 @@ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" }, "end-of-stream": { "version": "1.4.4", @@ -23053,6 +23182,19 @@ "unbox-primitive": "^1.0.1" } }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, "es-module-lexer": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", @@ -23572,36 +23714,36 @@ } }, "express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -23633,9 +23775,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, "safe-buffer": { "version": "5.2.1", @@ -23789,12 +23931,12 @@ } }, "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -23976,9 +24118,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "function.prototype.name": { "version": "1.1.4", @@ -24019,13 +24161,15 @@ "integrity": "sha1-SCG85m8cJMsDMWAr5strEsTwHEs=" }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-own-enumerable-property-symbols": { @@ -24124,6 +24268,14 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -24171,13 +24323,18 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "requires": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" } }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -24191,6 +24348,14 @@ "has-symbols": "^1.0.2" } }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -25900,9 +26065,9 @@ "integrity": "sha512-QmpUu4KqDmX0plH4u+tf0riMc1KHE1+lw95cMrLlXQAFOx/xnBtwhZ52XJxd9X2O6kwKBqX32kmhbhlobD0cuw==" }, "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" }, "merge-stream": { "version": "2.0.0", @@ -26195,9 +26360,9 @@ "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" }, "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" }, "object-is": { "version": "1.1.5", @@ -27466,11 +27631,11 @@ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "requires": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" } }, "querystringify": { @@ -28586,9 +28751,9 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" }, "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "requires": { "debug": "2.6.9", "depd": "2.0.0", @@ -28625,6 +28790,11 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -28696,14 +28866,27 @@ } }, "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "requires": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" + } + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" } }, "setimmediate": { @@ -28744,13 +28927,14 @@ "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" }, "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" } }, "signal-exit": { From 9fe01280e8d273e30869ef9dd01b8b2e98ec92b7 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Tue, 8 Oct 2024 12:53:48 +0200 Subject: [PATCH 03/23] [Upd] Update dependencies. --- package-lock.json | 74 +++++++++++++++++++++++++++------------- package.json | 8 ++--- src/store/TermItStore.ts | 4 +-- 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac0d87ce..808e74ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,11 +13,11 @@ "@formatjs/intl-relativetimeformat": "^11.2.4", "@fortawesome/fontawesome-free": "^6.4.0", "@opendata-mvcr/assembly-line-shared": "^0.3.2", - "apexcharts": "^3.41.0", - "axios": "^1.6.5", + "apexcharts": "^3.54.0", + "axios": "^1.7.7", "bootstrap": "4.6.2", "chart.js": "^3.9.1", - "classnames": "^2.3.2", + "classnames": "^2.5.1", "dom-serializer": "^1.3.2", "domhandler": "^4.3.1", "easymde": "2.18.0", @@ -82,7 +82,7 @@ "@types/react-highlight-words": "^0.16.4", "@types/react-router-dom": "^5.3.3", "@types/react-table": "^7.7.14", - "@types/redux-logger": "^3.0.9", + "@types/redux-logger": "^3.0.13", "@types/redux-mock-store": "^1.0.3", "@types/uuid": "^9.0.2", "@types/whatwg-mimetype": "^2.1.1", @@ -3882,14 +3882,20 @@ } }, "node_modules/@types/redux-logger": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/redux-logger/-/redux-logger-3.0.9.tgz", - "integrity": "sha512-cwYhVbYNgH01aepeMwhd0ABX6fhVB2rcQ9m80u8Fl50ZODhsZ8RhQArnLTkE7/Zrfq4Sz/taNoF7DQy9pCZSKg==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@types/redux-logger/-/redux-logger-3.0.13.tgz", + "integrity": "sha512-jylqZXQfMxahkuPcO8J12AKSSCQngdEWQrw7UiLUJzMBcv1r4Qg77P6mjGLjM27e5gFQDPD8vwUMJ9AyVxFSsg==", "dev": true, "dependencies": { - "redux": "^4.0.0" + "redux": "^5.0.0" } }, + "node_modules/@types/redux-logger/node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "dev": true + }, "node_modules/@types/redux-mock-store": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/redux-mock-store/-/redux-mock-store-1.0.3.tgz", @@ -4437,6 +4443,11 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "node_modules/@yr/monotone-cubic-spline": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", + "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==" + }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -4661,10 +4672,11 @@ } }, "node_modules/apexcharts": { - "version": "3.41.0", - "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.41.0.tgz", - "integrity": "sha512-FJXA7NVjxs1q+ptR3b1I+pN8K/gWuXn+qLZjFz8EHvJOokdgcuwa/HSe5aC465HW/LWnrjWLSTsOQejQbQ42hQ==", + "version": "3.54.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.54.0.tgz", + "integrity": "sha512-ZgI/seScffjLpwNRX/gAhIkAhpCNWiTNsdICv7qxnF0xisI23XSsaENUKIcMlyP1rbe8ECgvybDnp7plZld89A==", "dependencies": { + "@yr/monotone-cubic-spline": "^1.0.3", "svg.draggable.js": "^2.2.2", "svg.easing.js": "^2.0.0", "svg.filter.js": "^2.0.2", @@ -5711,9 +5723,9 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "node_modules/clean-css": { "version": "5.2.4", @@ -20733,12 +20745,20 @@ } }, "@types/redux-logger": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/redux-logger/-/redux-logger-3.0.9.tgz", - "integrity": "sha512-cwYhVbYNgH01aepeMwhd0ABX6fhVB2rcQ9m80u8Fl50ZODhsZ8RhQArnLTkE7/Zrfq4Sz/taNoF7DQy9pCZSKg==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@types/redux-logger/-/redux-logger-3.0.13.tgz", + "integrity": "sha512-jylqZXQfMxahkuPcO8J12AKSSCQngdEWQrw7UiLUJzMBcv1r4Qg77P6mjGLjM27e5gFQDPD8vwUMJ9AyVxFSsg==", "dev": true, "requires": { - "redux": "^4.0.0" + "redux": "^5.0.0" + }, + "dependencies": { + "redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "dev": true + } } }, "@types/redux-mock-store": { @@ -21165,6 +21185,11 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "@yr/monotone-cubic-spline": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", + "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==" + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -21323,10 +21348,11 @@ } }, "apexcharts": { - "version": "3.41.0", - "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.41.0.tgz", - "integrity": "sha512-FJXA7NVjxs1q+ptR3b1I+pN8K/gWuXn+qLZjFz8EHvJOokdgcuwa/HSe5aC465HW/LWnrjWLSTsOQejQbQ42hQ==", + "version": "3.54.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.54.0.tgz", + "integrity": "sha512-ZgI/seScffjLpwNRX/gAhIkAhpCNWiTNsdICv7qxnF0xisI23XSsaENUKIcMlyP1rbe8ECgvybDnp7plZld89A==", "requires": { + "@yr/monotone-cubic-spline": "^1.0.3", "svg.draggable.js": "^2.2.2", "svg.easing.js": "^2.0.0", "svg.filter.js": "^2.0.2", @@ -22078,9 +22104,9 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, "classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "clean-css": { "version": "5.2.4", diff --git a/package.json b/package.json index 602e01f1..df33063a 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,11 @@ "@formatjs/intl-relativetimeformat": "^11.2.4", "@fortawesome/fontawesome-free": "^6.4.0", "@opendata-mvcr/assembly-line-shared": "^0.3.2", - "apexcharts": "^3.41.0", - "axios": "^1.6.5", + "apexcharts": "^3.54.0", + "axios": "^1.7.7", "bootstrap": "4.6.2", "chart.js": "^3.9.1", - "classnames": "^2.3.2", + "classnames": "^2.5.1", "dom-serializer": "^1.3.2", "domhandler": "^4.3.1", "easymde": "2.18.0", @@ -92,7 +92,7 @@ "@types/react-highlight-words": "^0.16.4", "@types/react-router-dom": "^5.3.3", "@types/react-table": "^7.7.14", - "@types/redux-logger": "^3.0.9", + "@types/redux-logger": "^3.0.13", "@types/redux-mock-store": "^1.0.3", "@types/uuid": "^9.0.2", "@types/whatwg-mimetype": "^2.1.1", diff --git a/src/store/TermItStore.ts b/src/store/TermItStore.ts index eb73fbcf..9be8dd4e 100644 --- a/src/store/TermItStore.ts +++ b/src/store/TermItStore.ts @@ -10,10 +10,10 @@ const middlewares: Middleware[] = [thunk as ThunkMiddleware]; if (process.env.NODE_ENV === "development") { middlewares.push( createLogger({ - stateTransformer(state: TermItState): any { + stateTransformer: (state: TermItState) => { return TermItState.toLoggable(state); }, - }) + }) as Middleware ); } From be6d2f8937d2cdf97661bbeb8ec069074d221f50 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Tue, 8 Oct 2024 14:50:57 +0200 Subject: [PATCH 04/23] [Enhancement #528] Support opening a modeling tool from vocabulary detail. All relevant vocabularies are used together with the current vocabulary. --- .../vocabulary/VocabularyActions.tsx | 36 ++++++++++- .../modeling/OpenModelingToolDialog.tsx | 60 +++++++++++++++++++ src/i18n/cs.ts | 6 ++ src/i18n/en.ts | 6 ++ src/model/Configuration.ts | 2 + src/util/Utils.ts | 4 ++ 6 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 src/component/vocabulary/modeling/OpenModelingToolDialog.tsx diff --git a/src/component/vocabulary/VocabularyActions.tsx b/src/component/vocabulary/VocabularyActions.tsx index 368f4cc3..e4916d80 100644 --- a/src/component/vocabulary/VocabularyActions.tsx +++ b/src/component/vocabulary/VocabularyActions.tsx @@ -6,13 +6,23 @@ import { DropdownToggle, UncontrolledButtonDropdown, } from "reactstrap"; -import { GoClippy, GoCloudDownload, GoCloudUpload } from "react-icons/go"; +import { + GoClippy, + GoCloudDownload, + GoCloudUpload, + GoRepoForked, +} from "react-icons/go"; import ImportBackupOfVocabulary from "./importing/ImportBackupOfVocabulary"; import { FaCamera } from "react-icons/fa"; import Vocabulary from "../../model/Vocabulary"; import IfVocabularyActionAuthorized from "./authorization/IfVocabularyActionAuthorized"; import AccessLevel from "../../model/acl/AccessLevel"; import IfUserIsAdmin from "../authorization/IfUserIsAdmin"; +import If from "../misc/If"; +import { useSelector } from "react-redux"; +import TermItState from "../../model/TermItState"; +import Utils from "../../util/Utils"; +import OpenModelingToolDialog from "./modeling/OpenModelingToolDialog"; interface VocabularyActionsProps { vocabulary: Vocabulary; @@ -31,6 +41,8 @@ const VocabularyActions: React.FC = ({ }) => { const { i18n } = useI18n(); const [showImportDialog, setShowImportDialog] = React.useState(false); + const [showModelingDialog, setShowModelingDialog] = React.useState(false); + const config = useSelector((state: TermItState) => state.configuration); return ( <> @@ -39,6 +51,11 @@ const VocabularyActions: React.FC = ({ showDialog={showImportDialog} closeDialog={() => setShowImportDialog(false)} /> + setShowModelingDialog(false)} + vocabulary={vocabulary} + /> = ({ {i18n("vocabulary.snapshot.create.label")} + + + setShowModelingDialog(true)} + > + + {i18n("vocabulary.summary.model.label")} + + + diff --git a/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx b/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx new file mode 100644 index 00000000..74b1dc14 --- /dev/null +++ b/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx @@ -0,0 +1,60 @@ +import React from "react"; +import Vocabulary from "../../../model/Vocabulary"; +import { useI18n } from "../../hook/useI18n"; +import ConfirmCancelDialog from "../../misc/ConfirmCancelDialog"; +import { getLocalized } from "../../../model/MultilingualString"; +import { ThunkDispatch } from "../../../util/Types"; +import { useDispatch, useSelector } from "react-redux"; +import { loadRelatedVocabularies } from "../../../action/AsyncVocabularyActions"; +import VocabularyUtils from "../../../util/VocabularyUtils"; +import TermItState from "../../../model/TermItState"; + +interface OpenModelingToolDialogProps { + open: boolean; + onClose: () => void; + vocabulary: Vocabulary; +} + +const OpenModelingToolDialog: React.FC = ({ + open, + onClose, + vocabulary, +}) => { + const { formatMessage } = useI18n(); + const dispatch: ThunkDispatch = useDispatch(); + const [relatedVocabularies, setRelatedVocabularies] = React.useState< + string[] + >([]); + const modelingToolUrl = useSelector( + (state: TermItState) => state.configuration + ).modelingToolUrl; + React.useEffect(() => { + if (open) { + dispatch( + loadRelatedVocabularies(VocabularyUtils.create(vocabulary.iri)) + ).then((data) => setRelatedVocabularies(data)); + } + }, [open, vocabulary.iri, dispatch]); + const onOpen = () => { + const vocabularyList = [vocabulary.iri, ...relatedVocabularies]; + let params = vocabularyList + .map((v) => encodeURIComponent(v)) + .join("&vocabulary="); + window.location.href = modelingToolUrl + "?vocabulary=" + params; + }; + + return ( + + ); +}; + +export default OpenModelingToolDialog; diff --git a/src/i18n/cs.ts b/src/i18n/cs.ts index a99a857a..21db8a5e 100644 --- a/src/i18n/cs.ts +++ b/src/i18n/cs.ts @@ -335,6 +335,12 @@ const cs = { "Při zaškrtnutí tohoto políčka budou při importu identifikátory nahrazeny novými, pokud by kolidovaly s existujícími identifikátory.", "vocabulary.summary.startTextAnalysis.title": "Spustit textovou analýzu definic všech pojmů v tomto slovníku", + "vocabulary.summary.model.label": "Modelovat vztahy", + "vocabulary.summary.model.title": + "Modelovat vztahy mezi pojmy ve slovníku pomocí externího nástroje", + "vocabulary.summary.model.open": "Otevřít", + "vocabulary.summary.model.dialog.title": + "Modelovat vztahy pojmů slovníku {vocabulary}", "vocabulary.updated.message": "Slovník úspěšně uložen.", "vocabulary.created.message": "Slovník úspěšně vytvořen.", "vocabulary.detail.subtitle": "Vytvořen autorem {author} ", diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 00c1b1a3..a4c8dd64 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -327,6 +327,12 @@ const en = { "When ticked, identifiers colliding with existing ones will be replaced by new ones.", "vocabulary.summary.startTextAnalysis.title": "Start text analysis on definitions of all terms in this vocabulary", + "vocabulary.summary.model.label": "Model relationships", + "vocabulary.summary.model.title": + "Model relationships between terms in this vocabulary using an external tool", + "vocabulary.summary.model.open": "Open", + "vocabulary.summary.model.dialog.title": + "Model relationships of terms in {vocabulary}", "vocabulary.updated.message": "Vocabulary successfully updated.", "vocabulary.created.message": "Vocabulary successfully created.", "vocabulary.detail.subtitle": "Created by {author} on ", diff --git a/src/model/Configuration.ts b/src/model/Configuration.ts index 77169046..72459dd0 100644 --- a/src/model/Configuration.ts +++ b/src/model/Configuration.ts @@ -8,6 +8,7 @@ const ctx = { roles: `${VocabularyUtils.NS_TERMIT}má-uživatelskou-roli`, maxFileUploadSize: `${VocabularyUtils.NS_TERMIT}má-maximální-velikost-souboru`, versionSeparator: `${VocabularyUtils.NS_TERMIT}má-oddělovač-verze`, + modelingToolUrl: `${VocabularyUtils.NS_TERMIT}má-adresu-modelovacího-nástroje`, }; export const CONTEXT = Object.assign({}, USERROLE_CONTEXT, ctx); @@ -21,6 +22,7 @@ export interface Configuration { roles: UserRole[]; maxFileUploadSize: string; versionSeparator: string; + modelingToolUrl?: string; } export const DEFAULT_CONFIGURATION: Configuration = { diff --git a/src/util/Utils.ts b/src/util/Utils.ts index 4d89ec4c..45b54beb 100644 --- a/src/util/Utils.ts +++ b/src/util/Utils.ts @@ -363,6 +363,10 @@ const Utils = { } return true; }, + + notBlank(str?: string | null) { + return !!(str && str.trim().length > 0); + }, }; export default Utils; From 734079a25b57c4018a04d25f72d1c19678578b41 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Tue, 8 Oct 2024 17:45:40 +0200 Subject: [PATCH 05/23] [Enhancement #528] Allow user to select additional vocabularies to use to open for modeling --- src/component/misc/ConfirmCancelDialog.tsx | 4 +- .../modeling/OpenModelingToolDialog.scss | 9 +++ .../modeling/OpenModelingToolDialog.tsx | 74 +++++++++++++++++-- src/i18n/cs.ts | 2 + src/i18n/en.ts | 2 + 5 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 src/component/vocabulary/modeling/OpenModelingToolDialog.scss diff --git a/src/component/misc/ConfirmCancelDialog.tsx b/src/component/misc/ConfirmCancelDialog.tsx index 64923aa9..54732319 100644 --- a/src/component/misc/ConfirmCancelDialog.tsx +++ b/src/component/misc/ConfirmCancelDialog.tsx @@ -22,7 +22,8 @@ interface ConfirmCancelDialogProps { confirmDisabled?: boolean; cancelKey?: string; cancelColor?: string; - size?: string; + size?: "lg" | "sm"; + className?: string; } /** @@ -37,6 +38,7 @@ const ConfirmCancelDialog: React.FC = (props) => { isOpen={props.show} toggle={props.onClose} size={props.size} + className={props.className} > {props.title} {props.children} diff --git a/src/component/vocabulary/modeling/OpenModelingToolDialog.scss b/src/component/vocabulary/modeling/OpenModelingToolDialog.scss new file mode 100644 index 00000000..4735ad6f --- /dev/null +++ b/src/component/vocabulary/modeling/OpenModelingToolDialog.scss @@ -0,0 +1,9 @@ +.modeling-vocabulary-select-dialog { + max-width: 80%; +} + +input.vocabulary-checkbox { + position: relative; + margin-left: 0; + margin-right: 0.5rem; +} diff --git a/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx b/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx index 74b1dc14..cd7ffee4 100644 --- a/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx +++ b/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx @@ -8,6 +8,12 @@ import { useDispatch, useSelector } from "react-redux"; import { loadRelatedVocabularies } from "../../../action/AsyncVocabularyActions"; import VocabularyUtils from "../../../util/VocabularyUtils"; import TermItState from "../../../model/TermItState"; +import { loadVocabularies } from "../../../action/AsyncActions"; +import { Col, Input, Row } from "reactstrap"; +import { getShortLocale } from "../../../util/IntlUtil"; +import "./OpenModelingToolDialog.scss"; + +const COLUMN_COUNT = 3; interface OpenModelingToolDialogProps { open: boolean; @@ -20,29 +26,80 @@ const OpenModelingToolDialog: React.FC = ({ onClose, vocabulary, }) => { - const { formatMessage } = useI18n(); + const { formatMessage, i18n, locale } = useI18n(); const dispatch: ThunkDispatch = useDispatch(); const [relatedVocabularies, setRelatedVocabularies] = React.useState< string[] >([]); + const [selectedVocabularies, setSelectedVocabularies] = React.useState< + string[] + >([]); const modelingToolUrl = useSelector( (state: TermItState) => state.configuration ).modelingToolUrl; + const vocabularies = useSelector((state: TermItState) => state.vocabularies); + const vocabularyIris = Object.keys(vocabularies); React.useEffect(() => { if (open) { dispatch( loadRelatedVocabularies(VocabularyUtils.create(vocabulary.iri)) - ).then((data) => setRelatedVocabularies(data)); + ).then((data) => { + setRelatedVocabularies(data); + // The vocabulary is also among the related vocabularies loaded from the server + setSelectedVocabularies(data); + }); + if (Object.keys(vocabularies).length === 0) { + dispatch(loadVocabularies()); + } + } + }, [open, vocabulary.iri, vocabularies, dispatch]); + + const onSelect = (vIri: string) => { + if (selectedVocabularies.includes(vIri)) { + setSelectedVocabularies(selectedVocabularies.filter((v) => v !== vIri)); + } else { + setSelectedVocabularies([...selectedVocabularies, vIri]); } - }, [open, vocabulary.iri, dispatch]); + }; const onOpen = () => { - const vocabularyList = [vocabulary.iri, ...relatedVocabularies]; - let params = vocabularyList + let params = selectedVocabularies .map((v) => encodeURIComponent(v)) .join("&vocabulary="); window.location.href = modelingToolUrl + "?vocabulary=" + params; }; + const rowCount = Math.ceil(vocabularyIris.length / COLUMN_COUNT); + const rows = []; + for (let i = 0; i < rowCount; i++) { + const cols = []; + for (let j = 0; j < COLUMN_COUNT; j++) { + const index = i * COLUMN_COUNT + j; + if (index >= vocabularyIris.length) { + break; + } + cols.push( + + onSelect(vocabularyIris[index])} + className="vocabulary-checkbox" + /> + {getLocalized( + vocabularies[vocabularyIris[index]].label, + getShortLocale(locale) + )} + + ); + } + rows.push( + + {cols} + + ); + } + return ( = ({ title={formatMessage("vocabulary.summary.model.dialog.title", { vocabulary: getLocalized(vocabulary.label), })} - > + size="lg" + className="modeling-vocabulary-select-dialog" + > +

{i18n("vocabulary.summary.model.dialog.text")}

+ {rows} + ); }; diff --git a/src/i18n/cs.ts b/src/i18n/cs.ts index 21db8a5e..8211dd44 100644 --- a/src/i18n/cs.ts +++ b/src/i18n/cs.ts @@ -341,6 +341,8 @@ const cs = { "vocabulary.summary.model.open": "Otevřít", "vocabulary.summary.model.dialog.title": "Modelovat vztahy pojmů slovníku {vocabulary}", + "vocabulary.summary.model.dialog.text": + "Vyberte slovníky, které chcete pro modelování otevřít. Předvybrány jsou slovníky, které s otevíraným slovníkem souvisí a musí být v seznamy zahrnuty.", "vocabulary.updated.message": "Slovník úspěšně uložen.", "vocabulary.created.message": "Slovník úspěšně vytvořen.", "vocabulary.detail.subtitle": "Vytvořen autorem {author} ", diff --git a/src/i18n/en.ts b/src/i18n/en.ts index a4c8dd64..2ea8a26d 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -333,6 +333,8 @@ const en = { "vocabulary.summary.model.open": "Open", "vocabulary.summary.model.dialog.title": "Model relationships of terms in {vocabulary}", + "vocabulary.summary.model.dialog.text": + "Select vocabularies you want to open for modeling. Vocabularies related to the one being open are pre-selected as they are required by the modeling tool.", "vocabulary.updated.message": "Vocabulary successfully updated.", "vocabulary.created.message": "Vocabulary successfully created.", "vocabulary.detail.subtitle": "Created by {author} on ", From b3b4561bdc4c9d90056af736e4be3b9a56fdeb82 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Wed, 9 Oct 2024 08:41:26 +0200 Subject: [PATCH 06/23] [Enhancement #528] Load related vocabularies when vocabulary IRI changes. --- .../modeling/OpenModelingToolDialog.tsx | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx b/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx index cd7ffee4..2b198f73 100644 --- a/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx +++ b/src/component/vocabulary/modeling/OpenModelingToolDialog.tsx @@ -40,19 +40,17 @@ const OpenModelingToolDialog: React.FC = ({ const vocabularies = useSelector((state: TermItState) => state.vocabularies); const vocabularyIris = Object.keys(vocabularies); React.useEffect(() => { - if (open) { - dispatch( - loadRelatedVocabularies(VocabularyUtils.create(vocabulary.iri)) - ).then((data) => { - setRelatedVocabularies(data); - // The vocabulary is also among the related vocabularies loaded from the server - setSelectedVocabularies(data); - }); - if (Object.keys(vocabularies).length === 0) { - dispatch(loadVocabularies()); - } + dispatch( + loadRelatedVocabularies(VocabularyUtils.create(vocabulary.iri)) + ).then((data) => { + setRelatedVocabularies(data); + // The vocabulary is also among the related vocabularies loaded from the server + setSelectedVocabularies(data); + }); + if (Object.keys(vocabularies).length === 0) { + dispatch(loadVocabularies()); } - }, [open, vocabulary.iri, vocabularies, dispatch]); + }, [vocabulary.iri, vocabularies, dispatch]); const onSelect = (vIri: string) => { if (selectedVocabularies.includes(vIri)) { From b27f8267060277808db01301353f308e5f998606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Ka=C5=88ka?= Date: Wed, 2 Oct 2024 14:01:53 +0200 Subject: [PATCH 07/23] [Ref] fixing npm audit Resolves vulnerability in path-to-regexp --- package-lock.json | 227 ++++++++++++++++++---------------------------- 1 file changed, 89 insertions(+), 138 deletions(-) diff --git a/package-lock.json b/package-lock.json index 808e74ef..7e6a0932 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2052,7 +2052,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "devOptional": true, + "dev": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -2064,7 +2064,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "devOptional": true, + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -3472,25 +3472,25 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "devOptional": true + "dev": true }, "node_modules/@types/babel__core": { "version": "7.1.14", @@ -3820,7 +3820,7 @@ "version": "17.0.20", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.20.tgz", "integrity": "sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==", - "devOptional": true, + "dev": true, "dependencies": { "@types/react": "^17" } @@ -6144,7 +6144,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "devOptional": true + "dev": true }, "node_modules/cross-env": { "version": "7.0.3", @@ -6833,7 +6833,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.3.1" } @@ -9287,7 +9287,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", - "devOptional": true + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -10590,12 +10590,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "peer": true - }, "node_modules/js-cookie": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", @@ -11062,7 +11056,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "devOptional": true + "dev": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -12014,9 +12008,9 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dependencies": { "isarray": "0.0.1" } @@ -13256,6 +13250,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true, "bin": { "prettier": "bin-prettier.js" }, @@ -15001,7 +14996,7 @@ "version": "1.63.3", "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.3.tgz", "integrity": "sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==", - "devOptional": true, + "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -16452,7 +16447,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "devOptional": true, + "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -16495,7 +16490,7 @@ "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "devOptional": true, + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -16507,7 +16502,7 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "devOptional": true, + "dev": true, "dependencies": { "acorn": "^8.11.0" }, @@ -16519,7 +16514,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true + "dev": true }, "node_modules/tsconfig-paths": { "version": "3.14.1", @@ -16634,6 +16629,7 @@ "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -16960,7 +16956,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "devOptional": true + "dev": true }, "node_modules/v8-to-istanbul": { "version": "8.1.1", @@ -17956,7 +17952,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6" } @@ -19297,7 +19293,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "devOptional": true, + "dev": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -19306,7 +19302,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "devOptional": true, + "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -19470,8 +19466,7 @@ "@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", - "requires": {} + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==" }, "@emotion/utils": { "version": "1.2.1", @@ -20333,25 +20328,25 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "devOptional": true + "dev": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true + "dev": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true + "dev": true }, "@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "devOptional": true + "dev": true }, "@types/babel__core": { "version": "7.1.14", @@ -20683,7 +20678,7 @@ "version": "17.0.20", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.20.tgz", "integrity": "sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==", - "devOptional": true, + "dev": true, "requires": { "@types/react": "^17" } @@ -21229,8 +21224,7 @@ "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" }, "acorn-node": { "version": "1.8.2", @@ -21309,8 +21303,7 @@ "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" }, "ansi-escapes": { "version": "4.3.2", @@ -21625,8 +21618,7 @@ "babel-plugin-named-asset-import": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "requires": {} + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==" }, "babel-plugin-polyfill-corejs2": { "version": "0.3.1", @@ -21850,8 +21842,7 @@ "bootstrap": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", - "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==", - "requires": {} + "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==" }, "brace-expansion": { "version": "1.1.11", @@ -22433,7 +22424,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "devOptional": true + "dev": true }, "cross-env": { "version": "7.0.3", @@ -22579,8 +22570,7 @@ "css-prefers-color-scheme": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", - "requires": {} + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==" }, "css-select": { "version": "4.2.1", @@ -22679,8 +22669,7 @@ "cssnano-utils": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.2.tgz", - "integrity": "sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==", - "requires": {} + "integrity": "sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==" }, "csso": { "version": "4.2.0", @@ -22914,7 +22903,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "devOptional": true + "dev": true }, "diff-sequences": { "version": "27.5.1", @@ -23577,8 +23566,7 @@ "eslint-plugin-react-hooks": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", - "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", - "requires": {} + "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==" }, "eslint-plugin-testing-library": { "version": "5.3.1", @@ -24671,8 +24659,7 @@ "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "requires": {} + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" }, "idb": { "version": "6.1.5", @@ -24701,7 +24688,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", - "devOptional": true + "dev": true }, "import-fresh": { "version": "3.3.0", @@ -25401,8 +25388,7 @@ "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "requires": {} + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" }, "jest-react-hooks-shallow": { "version": "1.5.1", @@ -25645,12 +25631,6 @@ } } }, - "jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "peer": true - }, "js-cookie": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", @@ -26007,7 +25987,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "devOptional": true + "dev": true }, "makeerror": { "version": "1.0.12", @@ -26668,9 +26648,9 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "requires": { "isarray": "0.0.1" } @@ -26801,8 +26781,7 @@ "postcss-browser-comments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", - "requires": {} + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==" }, "postcss-calc": { "version": "8.2.4", @@ -26867,8 +26846,7 @@ "postcss-custom-media": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz", - "integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==", - "requires": {} + "integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==" }, "postcss-custom-properties": { "version": "12.1.4", @@ -26897,26 +26875,22 @@ "postcss-discard-comments": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.3.tgz", - "integrity": "sha512-6W5BemziRoqIdAKT+1QjM4bNcJAQ7z7zk073730NHg4cUXh3/rQHHj7pmYxUB9aGhuRhBiUf0pXvIHkRwhQP0Q==", - "requires": {} + "integrity": "sha512-6W5BemziRoqIdAKT+1QjM4bNcJAQ7z7zk073730NHg4cUXh3/rQHHj7pmYxUB9aGhuRhBiUf0pXvIHkRwhQP0Q==" }, "postcss-discard-duplicates": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.3.tgz", - "integrity": "sha512-vPtm1Mf+kp7iAENTG7jI1MN1lk+fBqL5y+qxyi4v3H+lzsXEdfS3dwUZD45KVhgzDEgduur8ycB4hMegyMTeRw==", - "requires": {} + "integrity": "sha512-vPtm1Mf+kp7iAENTG7jI1MN1lk+fBqL5y+qxyi4v3H+lzsXEdfS3dwUZD45KVhgzDEgduur8ycB4hMegyMTeRw==" }, "postcss-discard-empty": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.3.tgz", - "integrity": "sha512-xGJugpaXKakwKI7sSdZjUuN4V3zSzb2Y0LOlmTajFbNinEjTfVs9PFW2lmKBaC/E64WwYppfqLD03P8l9BuueA==", - "requires": {} + "integrity": "sha512-xGJugpaXKakwKI7sSdZjUuN4V3zSzb2Y0LOlmTajFbNinEjTfVs9PFW2lmKBaC/E64WwYppfqLD03P8l9BuueA==" }, "postcss-discard-overridden": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.4.tgz", - "integrity": "sha512-3j9QH0Qh1KkdxwiZOW82cId7zdwXVQv/gRXYDnwx5pBtR1sTkU4cXRK9lp5dSdiM0r0OICO/L8J6sV1/7m0kHg==", - "requires": {} + "integrity": "sha512-3j9QH0Qh1KkdxwiZOW82cId7zdwXVQv/gRXYDnwx5pBtR1sTkU4cXRK9lp5dSdiM0r0OICO/L8J6sV1/7m0kHg==" }, "postcss-double-position-gradients": { "version": "3.0.5", @@ -26937,8 +26911,7 @@ "postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", - "requires": {} + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==" }, "postcss-focus-visible": { "version": "6.0.4", @@ -26959,14 +26932,12 @@ "postcss-font-variant": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "requires": {} + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==" }, "postcss-gap-properties": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz", - "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==", - "requires": {} + "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==" }, "postcss-image-set-function": { "version": "4.0.6", @@ -26979,8 +26950,7 @@ "postcss-initial": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", - "requires": {} + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==" }, "postcss-js": { "version": "4.0.0", @@ -27042,14 +27012,12 @@ "postcss-logical": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", - "requires": {} + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==" }, "postcss-media-minmax": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", - "requires": {} + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==" }, "postcss-merge-longhand": { "version": "5.0.6", @@ -27110,8 +27078,7 @@ "postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "requires": {} + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -27168,8 +27135,7 @@ "postcss-normalize-charset": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.3.tgz", - "integrity": "sha512-iKEplDBco9EfH7sx4ut7R2r/dwTnUqyfACf62Unc9UiyFuI7uUqZZtY+u+qp7g8Qszl/U28HIfcsI3pEABWFfA==", - "requires": {} + "integrity": "sha512-iKEplDBco9EfH7sx4ut7R2r/dwTnUqyfACf62Unc9UiyFuI7uUqZZtY+u+qp7g8Qszl/U28HIfcsI3pEABWFfA==" }, "postcss-normalize-display-values": { "version": "5.0.3", @@ -27254,14 +27220,12 @@ "postcss-overflow-shorthand": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz", - "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==", - "requires": {} + "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==" }, "postcss-page-break": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "requires": {} + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==" }, "postcss-place": { "version": "7.0.4", @@ -27344,8 +27308,7 @@ "postcss-replace-overflow-wrap": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "requires": {} + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==" }, "postcss-selector-not": { "version": "5.0.0", @@ -27434,13 +27397,13 @@ "prettier": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", - "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==" + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true }, "prettier-plugin-tailwindcss": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.1.7.tgz", - "integrity": "sha512-tmBr45hCLuit2Cz9Pwow0/Jl1bGivYGsfcF29O+3sKcE++ybjz9dfie565S3ZsvAeV8uYer9SRMBWDsHPly2Lg==", - "requires": {} + "integrity": "sha512-tmBr45hCLuit2Cz9Pwow0/Jl1bGivYGsfcF29O+3sKcE++ybjz9dfie565S3ZsvAeV8uYer9SRMBWDsHPly2Lg==" }, "pretty-bytes": { "version": "5.6.0", @@ -27741,8 +27704,7 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/raw.macro/-/raw.macro-0.6.2.tgz", "integrity": "sha512-YWhyR420Xug/s6/7k+H8WTA0r84WULMPn0/o8Y5u5905tGjkvB72Fd/TvRXJcOiv7cSARUGzy+wCZPX9pr9YQA==", - "dev": true, - "requires": {} + "dev": true }, "rdf-canonize": { "version": "3.4.0", @@ -27945,8 +27907,7 @@ "react-icons": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.9.0.tgz", - "integrity": "sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==", - "requires": {} + "integrity": "sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==" }, "react-intl": { "version": "6.4.4", @@ -28019,8 +27980,7 @@ "react-promise-tracker": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/react-promise-tracker/-/react-promise-tracker-2.1.1.tgz", - "integrity": "sha512-NM7FrJ4y5aRN3FIeVtmeF8leIDQIdYni9pleHTvuX6Kz5zsIHMYSNERmvzTxvPuzei0iNiNiudsXySP63TXA8A==", - "requires": {} + "integrity": "sha512-NM7FrJ4y5aRN3FIeVtmeF8leIDQIdYni9pleHTvuX6Kz5zsIHMYSNERmvzTxvPuzei0iNiNiudsXySP63TXA8A==" }, "react-redux": { "version": "8.0.7", @@ -28246,8 +28206,7 @@ "react-side-effect": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz", - "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==", - "requires": {} + "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==" }, "react-simplemde-editor": { "version": "5.2.0", @@ -28260,8 +28219,7 @@ "react-spinners": { "version": "0.13.8", "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.13.8.tgz", - "integrity": "sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==", - "requires": {} + "integrity": "sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==" }, "react-stomp-hooks": { "version": "3.0.1", @@ -28276,8 +28234,7 @@ "react-table": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", - "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", - "requires": {} + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==" }, "react-test-renderer": { "version": "17.0.2", @@ -28406,8 +28363,7 @@ "redux-thunk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", - "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", - "requires": {} + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==" }, "regenerate": { "version": "1.4.2", @@ -28709,7 +28665,7 @@ "version": "1.63.3", "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.3.tgz", "integrity": "sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==", - "devOptional": true, + "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -29319,8 +29275,7 @@ "style-loader": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", - "requires": {} + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==" }, "style-to-object": { "version": "0.3.0", @@ -29812,7 +29767,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "devOptional": true, + "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -29833,13 +29788,13 @@ "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "devOptional": true + "dev": true }, "acorn-walk": { "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "devOptional": true, + "dev": true, "requires": { "acorn": "^8.11.0" } @@ -29848,7 +29803,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true + "dev": true } } }, @@ -29941,7 +29896,8 @@ "typescript": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==" + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true }, "typo-js": { "version": "1.2.1", @@ -30115,14 +30071,12 @@ "use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "requires": {} + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==" }, "use-sync-external-store": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz", - "integrity": "sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ==", - "requires": {} + "integrity": "sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ==" }, "util-deprecate": { "version": "1.0.2", @@ -30162,7 +30116,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "devOptional": true + "dev": true }, "v8-to-istanbul": { "version": "8.1.1", @@ -30308,8 +30262,7 @@ "acorn-import-attributes": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "requires": {} + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==" }, "eslint-scope": { "version": "5.1.1", @@ -30461,8 +30414,7 @@ "ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "requires": {} + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==" } } }, @@ -30892,8 +30844,7 @@ "ws": { "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "requires": {} + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==" }, "xml": { "version": "1.0.1", @@ -30935,7 +30886,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "devOptional": true + "dev": true }, "yocto-queue": { "version": "0.1.0", From 5fd2b748da249b256e5914b22b96d1e5c605079c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Ka=C5=88ka?= Date: Sun, 13 Oct 2024 12:34:34 +0200 Subject: [PATCH 08/23] [Enhancement kbss-cvut/termit-ui#519] Recent term history in vocabulary activity tab Displaying recent term changes in vocabulary detail in activity tab. --- src/action/AsyncVocabularyActions.ts | 39 ++++++++++- src/component/changetracking/PersistRow.tsx | 2 +- src/component/changetracking/UpdateRow.tsx | 2 +- .../VocabularyContentPersistRow.tsx | 35 ++++++++++ .../VocabularyContentUpdateRow.tsx | 36 ++++++++++ .../vocabulary/TermChangeFrequency.tsx | 38 +++++++++-- .../vocabulary/TermChangeFrequencyUI.tsx | 65 ++++++++++++++++--- src/util/Constants.ts | 2 + 8 files changed, 202 insertions(+), 17 deletions(-) create mode 100644 src/component/changetracking/VocabularyContentPersistRow.tsx create mode 100644 src/component/changetracking/VocabularyContentUpdateRow.tsx diff --git a/src/action/AsyncVocabularyActions.ts b/src/action/AsyncVocabularyActions.ts index 7a620f40..48e766d0 100644 --- a/src/action/AsyncVocabularyActions.ts +++ b/src/action/AsyncVocabularyActions.ts @@ -1,4 +1,4 @@ -import { GetStoreState, ThunkDispatch } from "../util/Types"; +import { GetStoreState, PageRequest, ThunkDispatch } from "../util/Types"; import * as SyncActions from "./SyncActions"; import { asyncActionFailure, @@ -27,6 +27,10 @@ import SnapshotData, { CONTEXT as SNAPSHOT_CONTEXT } from "../model/Snapshot"; import NotificationType from "../model/NotificationType"; import ExportConfig from "../model/local/ExportConfig"; import RDFStatement, { RDFSTATEMENT_CONTEXT } from "../model/RDFStatement"; +import ChangeRecord, { + CONTEXT as CHANGE_RECORD_CONTEXT, +} from "../model/changetracking/ChangeRecord"; +import AssetFactory from "../util/AssetFactory"; export function loadTermCount(vocabularyIri: IRI) { const action = { type: ActionType.LOAD_TERM_COUNT, vocabularyIri }; @@ -131,6 +135,39 @@ export function loadVocabularyContentChanges(vocabularyIri: IRI) { }; } +export function loadVocabularyContentDetailedChanges( + vocabularyIri: IRI, + pageReq: PageRequest +) { + const action = { + type: ActionType.LOAD_TERM_HISTORY, + }; + + return (dispatch: ThunkDispatch) => { + dispatch(asyncActionRequest(action, true)); + return Ajax.get( + `${Constants.API_PREFIX}/vocabularies/${vocabularyIri.fragment}/history-of-content/detail`, + param("namespace", vocabularyIri.namespace) + .param("page", pageReq.page?.toString()) + .param("size", pageReq.size?.toString()) + ) + .then((data) => + JsonLdUtils.compactAndResolveReferencesAsArray( + data, + CHANGE_RECORD_CONTEXT + ) + ) + .then((data: ChangeRecord[]) => { + dispatch(asyncActionSuccess(action)); + return data.map((r) => AssetFactory.createChangeRecord(r)); + }) + .catch((error: ErrorData) => { + dispatch(asyncActionFailure(action, error)); + return []; + }); + }; +} + export function loadRelatedVocabularies(vocabularyIri: IRI) { const action = { type: ActionType.LOAD_RELATED_VOCABULARIES, vocabularyIri }; return (dispatch: ThunkDispatch) => { diff --git a/src/component/changetracking/PersistRow.tsx b/src/component/changetracking/PersistRow.tsx index 122121ab..af965002 100644 --- a/src/component/changetracking/PersistRow.tsx +++ b/src/component/changetracking/PersistRow.tsx @@ -4,7 +4,7 @@ import PersistRecord from "../../model/changetracking/PersistRecord"; import { Badge } from "reactstrap"; import { useI18n } from "../hook/useI18n"; -interface PersistRowProps { +export interface PersistRowProps { record: PersistRecord; } diff --git a/src/component/changetracking/UpdateRow.tsx b/src/component/changetracking/UpdateRow.tsx index a284bfb0..8968b09e 100644 --- a/src/component/changetracking/UpdateRow.tsx +++ b/src/component/changetracking/UpdateRow.tsx @@ -9,7 +9,7 @@ import OutgoingLink from "../misc/OutgoingLink"; import { Badge, Label } from "reactstrap"; import { useI18n } from "../hook/useI18n"; -interface UpdateRowProps { +export interface UpdateRowProps { record: UpdateRecord; } diff --git a/src/component/changetracking/VocabularyContentPersistRow.tsx b/src/component/changetracking/VocabularyContentPersistRow.tsx new file mode 100644 index 00000000..6009cac5 --- /dev/null +++ b/src/component/changetracking/VocabularyContentPersistRow.tsx @@ -0,0 +1,35 @@ +import * as React from "react"; +import { FormattedDate, FormattedTime } from "react-intl"; +import { Badge } from "reactstrap"; +import { useI18n } from "../hook/useI18n"; +import { PersistRowProps } from "./PersistRow"; +import TermIriLink from "../term/TermIriLink"; + +export const VocabularyContentPersistRow: React.FC = ( + props +) => { + const { i18n } = useI18n(); + const record = props.record; + const created = new Date(Date.parse(record.timestamp)); + return ( + + +
+ +
+
+ {record.author.fullName} +
+ + + + + + {i18n(record.typeLabel)} + + + + ); +}; + +export default VocabularyContentPersistRow; diff --git a/src/component/changetracking/VocabularyContentUpdateRow.tsx b/src/component/changetracking/VocabularyContentUpdateRow.tsx new file mode 100644 index 00000000..85890e71 --- /dev/null +++ b/src/component/changetracking/VocabularyContentUpdateRow.tsx @@ -0,0 +1,36 @@ +import * as React from "react"; +import { FormattedDate, FormattedTime } from "react-intl"; +import AssetLabel from "../misc/AssetLabel"; +import { Badge } from "reactstrap"; +import { useI18n } from "../hook/useI18n"; +import { UpdateRowProps } from "./UpdateRow"; +import TermIriLink from "../term/TermIriLink"; + +export const VocabularyContentUpdateRow: React.FC = (props) => { + const { i18n } = useI18n(); + const record = props.record; + const created = new Date(Date.parse(record.timestamp)); + return ( + + +
+ +
+
+ {record.author.fullName} +
+ + + + + + {i18n(record.typeLabel)} + + + + + + ); +}; + +export default VocabularyContentUpdateRow; diff --git a/src/component/vocabulary/TermChangeFrequency.tsx b/src/component/vocabulary/TermChangeFrequency.tsx index 7bba6f33..d7fb18e2 100644 --- a/src/component/vocabulary/TermChangeFrequency.tsx +++ b/src/component/vocabulary/TermChangeFrequency.tsx @@ -9,36 +9,64 @@ import PromiseTrackingMask from "../misc/PromiseTrackingMask"; import { trackPromise } from "react-promise-tracker"; import { useI18n } from "../hook/useI18n"; import AggregatedChangeInfo from "../../model/changetracking/AggregatedChangeInfo"; -import { loadVocabularyContentChanges } from "../../action/AsyncVocabularyActions"; +import { + loadVocabularyContentChanges, + loadVocabularyContentDetailedChanges, +} from "../../action/AsyncVocabularyActions"; +import ChangeRecord from "../../model/changetracking/ChangeRecord"; interface TermChangeFrequencyProps { vocabulary: Vocabulary; } const TermChangeFrequency: React.FC = (props) => { - const [records, setRecords] = + const [aggregatedRecords, setAggregatedRecords] = React.useState(null); + const [changeRecords, setChangeRecords] = + React.useState(null); const { vocabulary } = props; const { i18n } = useI18n(); const dispatch: ThunkDispatch = useDispatch(); + const [page, setPage] = React.useState(0); React.useEffect(() => { if (vocabulary.iri !== Constants.EMPTY_ASSET_IRI) { trackPromise( dispatch( loadVocabularyContentChanges(VocabularyUtils.create(vocabulary.iri)) - ), + ).then((recs) => setAggregatedRecords(recs)), "term-change-frequency" - ).then((recs) => setRecords(recs)); + ); } }, [vocabulary.iri, dispatch]); + React.useEffect(() => { + if (vocabulary.iri !== Constants.EMPTY_ASSET_IRI) { + trackPromise( + dispatch( + loadVocabularyContentDetailedChanges( + VocabularyUtils.create(vocabulary.iri), + { page: page, size: Constants.VOCABULARY_CONTENT_HISTORY_LIMIT } + ) + ).then((changeRecords) => setChangeRecords(changeRecords)), + "term-change-frequency" + ); + } + }, [vocabulary.iri, dispatch, page]); + return ( <> - + ); }; diff --git a/src/component/vocabulary/TermChangeFrequencyUI.tsx b/src/component/vocabulary/TermChangeFrequencyUI.tsx index 7d1ec7d1..6235d1f3 100644 --- a/src/component/vocabulary/TermChangeFrequencyUI.tsx +++ b/src/component/vocabulary/TermChangeFrequencyUI.tsx @@ -1,12 +1,23 @@ import * as React from "react"; import Chart from "react-apexcharts"; -import { Col, Row } from "reactstrap"; +import { Col, Row, Table } from "reactstrap"; import { useI18n } from "../hook/useI18n"; import AggregatedChangeInfo from "../../model/changetracking/AggregatedChangeInfo"; import VocabularyUtils from "../../util/VocabularyUtils"; +import ChangeRecord from "../../model/changetracking/ChangeRecord"; +import { UpdateRecord } from "../../model/changetracking/UpdateRecord"; +import VocabularyContentPersistRow from "../changetracking/VocabularyContentPersistRow"; +import VocabularyContentUpdateRow from "../changetracking/VocabularyContentUpdateRow"; +import If from "../misc/If"; +import SimplePagination from "../dashboard/widget/lastcommented/SimplePagination"; interface TermChangeFrequencyUIProps { - records: AggregatedChangeInfo[] | null; + aggregatedRecords: AggregatedChangeInfo[] | null; + changeRecords: ChangeRecord[] | null; + page: number; + setPage: (page: number) => void; + pageSize: number; + itemCount: number; } /** @@ -48,14 +59,19 @@ const CZ_LOCALE = { }; const TermChangeFrequencyUI: React.FC = ({ - records, + aggregatedRecords, + changeRecords, + page, + setPage, + pageSize, + itemCount, }) => { const { i18n, locale } = useI18n(); - if (!records) { + if (!aggregatedRecords || !changeRecords) { return
 
; } - if (records.length === 0) { + if (aggregatedRecords.length === 0) { return (
= ({ ); } - const dates = Array.from(new Set(records.map((r) => r.getDate()))); - const termCreations = records.filter( + const dates = Array.from(new Set(aggregatedRecords.map((r) => r.getDate()))); + const termCreations = aggregatedRecords.filter( (r) => r.types.indexOf(VocabularyUtils.PERSIST_EVENT) !== -1 ); - const termUpdates = records.filter( + const termUpdates = aggregatedRecords.filter( (r) => r.types.indexOf(VocabularyUtils.UPDATE_EVENT) !== -1 ); @@ -131,9 +147,40 @@ const TermChangeFrequencyUI: React.FC = ({ ]; return ( - + + +
+ + + + + + + + + + + {changeRecords.map((r) => + r instanceof UpdateRecord ? ( + + ) : ( + + ) + )} + +
{i18n("history.whenwho")}{i18n("type.term")}{i18n("history.type")}{i18n("history.changedAttribute")}
+
+ 0}> + + +
); }; diff --git a/src/util/Constants.ts b/src/util/Constants.ts index 4e961678..3764ea2d 100644 --- a/src/util/Constants.ts +++ b/src/util/Constants.ts @@ -121,6 +121,8 @@ const constants = { // Size of page fetched from server DEFAULT_PAGE_SIZE: 100, + // size of the page for change records in vocabulary activity tab + VOCABULARY_CONTENT_HISTORY_LIMIT: 15, WEBSOCKET_ENDPOINT: { VOCABULARIES_VALIDATION: "/vocabularies/validation", From d96ba2acd99761e41cf3d4ee4806dd4d2780102a Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 14 Oct 2024 14:41:37 +0200 Subject: [PATCH 09/23] [Upd] Update dependencies, remove obsolete REST API mock code. --- doc/development.md | 11 +- package-lock.json | 275 ++++++++++++++++++++--------------- package.json | 8 +- src/util/Ajax.ts | 309 +--------------------------------------- src/util/ConfigParam.ts | 1 - 5 files changed, 170 insertions(+), 434 deletions(-) diff --git a/doc/development.md b/doc/development.md index 0ae5745e..1c2089ea 100644 --- a/doc/development.md +++ b/doc/development.md @@ -23,7 +23,7 @@ marking it as production-ready. ## Development Requirements -Unless you are using Docker to build the project, **Node.js 14** or later and **npm 7** or later (due to using lockfile v2) are required. Node.js 16 and npm 8 is recommended. +Unless you are using Docker to build the project, **Node.js 20** or later and **npm 8** or later are required. ## Tests @@ -124,15 +124,6 @@ tracking and the corresponding loading mask. See `TermChangeFrequency` for usage - Tests can be debugged directly in IDEA just like JUnit tests - IDEA is able to run singular tests. - The application can be debugged in IDEA as well, see the [JetBrains blog](https://blog.jetbrains.com/webstorm/2017/01/debugging-react-apps/). -## Mocking Server REST API - -It is possible to mock server REST API, so that the application can be developed and run without having to start the backend application. -To do so, use `npm run start-mock-rest`, which sets environment variables telling the app to mock the REST API. Now, the mock API is set up -in `src/util/Ajax`, function `mockRestApi`, we are using [Axios Mock Adapter](https://github.com/ctimmerm/axios-mock-adapter). The usage should be -fairly intuitive. Data should be kept in JSON files in `src/rest-mock` (has to be in `src`, otherwise webpack refuses to import the data). - -However, note that the current mocked API does not cover the actual backend REST API anymore, and it is recommended to run the backend (e.g. in Docker) for real and connect to it instead. - ## Adjusting Bootstrap Styles It is possible to adjust the styling of the application. We are using Bootstrap which provides SCSS definitions which can be overridden. Based on the diff --git a/package-lock.json b/package-lock.json index 7e6a0932..a6370641 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "redux-thunk": "^2.4.2", "resolve": "1.22.2", "simple-xpath-position": "^2.0.2", - "uuid": "^9.0.0", + "uuid": "^10.0.0", "whatwg-fetch": "3.6.2", "whatwg-mimetype": "3.0.0" }, @@ -73,7 +73,7 @@ "@types/enzyme": "^3.10.13", "@types/jest": "^27.4.1", "@types/js-cookie": "^3.0.3", - "@types/lodash": "^4.14.195", + "@types/lodash": "^4.17.10", "@types/luxon": "^3.3.0", "@types/node": "^18.11.17", "@types/react": "^17.0.61", @@ -84,10 +84,10 @@ "@types/react-table": "^7.7.14", "@types/redux-logger": "^3.0.13", "@types/redux-mock-store": "^1.0.3", - "@types/uuid": "^9.0.2", + "@types/uuid": "^10.0.0", "@types/whatwg-mimetype": "^2.1.1", "@wojtekmaj/enzyme-adapter-react-17": "^0.8.0", - "axios-mock-adapter": "^1.22.0", + "axios-mock-adapter": "^2.1.0", "babel-plugin-macros": "2.8.0", "cross-env": "^7.0.3", "enzyme": "^3.11.0", @@ -2052,7 +2052,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -2064,7 +2064,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -3472,25 +3472,25 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "devOptional": true }, "node_modules/@types/babel__core": { "version": "7.1.14", @@ -3728,9 +3728,9 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, "node_modules/@types/lodash": { - "version": "4.14.195", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", - "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", "dev": true }, "node_modules/@types/luxon": { @@ -3820,7 +3820,7 @@ "version": "17.0.20", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.20.tgz", "integrity": "sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==", - "dev": true, + "devOptional": true, "dependencies": { "@types/react": "^17" } @@ -3982,9 +3982,9 @@ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" }, "node_modules/@types/uuid": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", - "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", "dev": true }, "node_modules/@types/whatwg-mimetype": { @@ -4884,9 +4884,9 @@ } }, "node_modules/axios-mock-adapter": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.22.0.tgz", - "integrity": "sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-2.1.0.tgz", + "integrity": "sha512-AZUe4OjECGCNNssH8SOdtneiQELsqTsat3SQQCWLPjN436/H+L9AjWfV7bF+Zg/YL9cgbhrz5671hoh+Tbn98w==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", @@ -6144,7 +6144,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "node_modules/cross-env": { "version": "7.0.3", @@ -6833,7 +6833,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.3.1" } @@ -9287,7 +9287,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", - "dev": true + "devOptional": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -10590,6 +10590,12 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "peer": true + }, "node_modules/js-cookie": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", @@ -11056,7 +11062,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -13250,7 +13256,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", - "dev": true, "bin": { "prettier": "bin-prettier.js" }, @@ -14996,7 +15001,7 @@ "version": "1.63.3", "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.3.tgz", "integrity": "sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==", - "dev": true, + "devOptional": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -16447,7 +16452,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, + "devOptional": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -16490,7 +16495,7 @@ "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, + "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -16502,7 +16507,7 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, + "devOptional": true, "dependencies": { "acorn": "^8.11.0" }, @@ -16514,7 +16519,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true }, "node_modules/tsconfig-paths": { "version": "3.14.1", @@ -16629,7 +16634,6 @@ "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -16940,9 +16944,13 @@ } }, "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -16956,7 +16964,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "node_modules/v8-to-istanbul": { "version": "8.1.1", @@ -17952,7 +17960,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -19293,7 +19301,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -19302,7 +19310,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -19466,7 +19474,8 @@ "@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==" + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "requires": {} }, "@emotion/utils": { "version": "1.2.1", @@ -20328,25 +20337,25 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true + "devOptional": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "devOptional": true }, "@types/babel__core": { "version": "7.1.14", @@ -20586,9 +20595,9 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, "@types/lodash": { - "version": "4.14.195", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", - "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", "dev": true }, "@types/luxon": { @@ -20678,7 +20687,7 @@ "version": "17.0.20", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.20.tgz", "integrity": "sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==", - "dev": true, + "devOptional": true, "requires": { "@types/react": "^17" } @@ -20842,9 +20851,9 @@ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" }, "@types/uuid": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", - "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", "dev": true }, "@types/whatwg-mimetype": { @@ -21224,7 +21233,8 @@ "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "requires": {} }, "acorn-node": { "version": "1.8.2", @@ -21303,7 +21313,8 @@ "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} }, "ansi-escapes": { "version": "4.3.2", @@ -21503,9 +21514,9 @@ } }, "axios-mock-adapter": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.22.0.tgz", - "integrity": "sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-2.1.0.tgz", + "integrity": "sha512-AZUe4OjECGCNNssH8SOdtneiQELsqTsat3SQQCWLPjN436/H+L9AjWfV7bF+Zg/YL9cgbhrz5671hoh+Tbn98w==", "dev": true, "requires": { "fast-deep-equal": "^3.1.3", @@ -21618,7 +21629,8 @@ "babel-plugin-named-asset-import": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==" + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "requires": {} }, "babel-plugin-polyfill-corejs2": { "version": "0.3.1", @@ -21842,7 +21854,8 @@ "bootstrap": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", - "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==" + "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==", + "requires": {} }, "brace-expansion": { "version": "1.1.11", @@ -22424,7 +22437,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "cross-env": { "version": "7.0.3", @@ -22570,7 +22583,8 @@ "css-prefers-color-scheme": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==" + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "requires": {} }, "css-select": { "version": "4.2.1", @@ -22669,7 +22683,8 @@ "cssnano-utils": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.2.tgz", - "integrity": "sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==" + "integrity": "sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==", + "requires": {} }, "csso": { "version": "4.2.0", @@ -22903,7 +22918,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "devOptional": true }, "diff-sequences": { "version": "27.5.1", @@ -23566,7 +23581,8 @@ "eslint-plugin-react-hooks": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", - "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==" + "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", + "requires": {} }, "eslint-plugin-testing-library": { "version": "5.3.1", @@ -24659,7 +24675,8 @@ "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "requires": {} }, "idb": { "version": "6.1.5", @@ -24688,7 +24705,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", - "dev": true + "devOptional": true }, "import-fresh": { "version": "3.3.0", @@ -25388,7 +25405,8 @@ "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "requires": {} }, "jest-react-hooks-shallow": { "version": "1.5.1", @@ -25631,6 +25649,12 @@ } } }, + "jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "peer": true + }, "js-cookie": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", @@ -25987,7 +26011,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "makeerror": { "version": "1.0.12", @@ -26781,7 +26805,8 @@ "postcss-browser-comments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==" + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "requires": {} }, "postcss-calc": { "version": "8.2.4", @@ -26846,7 +26871,8 @@ "postcss-custom-media": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz", - "integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==" + "integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==", + "requires": {} }, "postcss-custom-properties": { "version": "12.1.4", @@ -26875,22 +26901,26 @@ "postcss-discard-comments": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.3.tgz", - "integrity": "sha512-6W5BemziRoqIdAKT+1QjM4bNcJAQ7z7zk073730NHg4cUXh3/rQHHj7pmYxUB9aGhuRhBiUf0pXvIHkRwhQP0Q==" + "integrity": "sha512-6W5BemziRoqIdAKT+1QjM4bNcJAQ7z7zk073730NHg4cUXh3/rQHHj7pmYxUB9aGhuRhBiUf0pXvIHkRwhQP0Q==", + "requires": {} }, "postcss-discard-duplicates": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.3.tgz", - "integrity": "sha512-vPtm1Mf+kp7iAENTG7jI1MN1lk+fBqL5y+qxyi4v3H+lzsXEdfS3dwUZD45KVhgzDEgduur8ycB4hMegyMTeRw==" + "integrity": "sha512-vPtm1Mf+kp7iAENTG7jI1MN1lk+fBqL5y+qxyi4v3H+lzsXEdfS3dwUZD45KVhgzDEgduur8ycB4hMegyMTeRw==", + "requires": {} }, "postcss-discard-empty": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.3.tgz", - "integrity": "sha512-xGJugpaXKakwKI7sSdZjUuN4V3zSzb2Y0LOlmTajFbNinEjTfVs9PFW2lmKBaC/E64WwYppfqLD03P8l9BuueA==" + "integrity": "sha512-xGJugpaXKakwKI7sSdZjUuN4V3zSzb2Y0LOlmTajFbNinEjTfVs9PFW2lmKBaC/E64WwYppfqLD03P8l9BuueA==", + "requires": {} }, "postcss-discard-overridden": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.4.tgz", - "integrity": "sha512-3j9QH0Qh1KkdxwiZOW82cId7zdwXVQv/gRXYDnwx5pBtR1sTkU4cXRK9lp5dSdiM0r0OICO/L8J6sV1/7m0kHg==" + "integrity": "sha512-3j9QH0Qh1KkdxwiZOW82cId7zdwXVQv/gRXYDnwx5pBtR1sTkU4cXRK9lp5dSdiM0r0OICO/L8J6sV1/7m0kHg==", + "requires": {} }, "postcss-double-position-gradients": { "version": "3.0.5", @@ -26911,7 +26941,8 @@ "postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==" + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "requires": {} }, "postcss-focus-visible": { "version": "6.0.4", @@ -26932,12 +26963,14 @@ "postcss-font-variant": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==" + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "requires": {} }, "postcss-gap-properties": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz", - "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==" + "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==", + "requires": {} }, "postcss-image-set-function": { "version": "4.0.6", @@ -26950,7 +26983,8 @@ "postcss-initial": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==" + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "requires": {} }, "postcss-js": { "version": "4.0.0", @@ -27012,12 +27046,14 @@ "postcss-logical": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==" + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "requires": {} }, "postcss-media-minmax": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==" + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "requires": {} }, "postcss-merge-longhand": { "version": "5.0.6", @@ -27078,7 +27114,8 @@ "postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -27135,7 +27172,8 @@ "postcss-normalize-charset": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.3.tgz", - "integrity": "sha512-iKEplDBco9EfH7sx4ut7R2r/dwTnUqyfACf62Unc9UiyFuI7uUqZZtY+u+qp7g8Qszl/U28HIfcsI3pEABWFfA==" + "integrity": "sha512-iKEplDBco9EfH7sx4ut7R2r/dwTnUqyfACf62Unc9UiyFuI7uUqZZtY+u+qp7g8Qszl/U28HIfcsI3pEABWFfA==", + "requires": {} }, "postcss-normalize-display-values": { "version": "5.0.3", @@ -27220,12 +27258,14 @@ "postcss-overflow-shorthand": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz", - "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==" + "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==", + "requires": {} }, "postcss-page-break": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==" + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "requires": {} }, "postcss-place": { "version": "7.0.4", @@ -27308,7 +27348,8 @@ "postcss-replace-overflow-wrap": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==" + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "requires": {} }, "postcss-selector-not": { "version": "5.0.0", @@ -27397,13 +27438,13 @@ "prettier": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", - "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", - "dev": true + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==" }, "prettier-plugin-tailwindcss": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.1.7.tgz", - "integrity": "sha512-tmBr45hCLuit2Cz9Pwow0/Jl1bGivYGsfcF29O+3sKcE++ybjz9dfie565S3ZsvAeV8uYer9SRMBWDsHPly2Lg==" + "integrity": "sha512-tmBr45hCLuit2Cz9Pwow0/Jl1bGivYGsfcF29O+3sKcE++ybjz9dfie565S3ZsvAeV8uYer9SRMBWDsHPly2Lg==", + "requires": {} }, "pretty-bytes": { "version": "5.6.0", @@ -27704,7 +27745,8 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/raw.macro/-/raw.macro-0.6.2.tgz", "integrity": "sha512-YWhyR420Xug/s6/7k+H8WTA0r84WULMPn0/o8Y5u5905tGjkvB72Fd/TvRXJcOiv7cSARUGzy+wCZPX9pr9YQA==", - "dev": true + "dev": true, + "requires": {} }, "rdf-canonize": { "version": "3.4.0", @@ -27907,7 +27949,8 @@ "react-icons": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.9.0.tgz", - "integrity": "sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==" + "integrity": "sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==", + "requires": {} }, "react-intl": { "version": "6.4.4", @@ -27980,7 +28023,8 @@ "react-promise-tracker": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/react-promise-tracker/-/react-promise-tracker-2.1.1.tgz", - "integrity": "sha512-NM7FrJ4y5aRN3FIeVtmeF8leIDQIdYni9pleHTvuX6Kz5zsIHMYSNERmvzTxvPuzei0iNiNiudsXySP63TXA8A==" + "integrity": "sha512-NM7FrJ4y5aRN3FIeVtmeF8leIDQIdYni9pleHTvuX6Kz5zsIHMYSNERmvzTxvPuzei0iNiNiudsXySP63TXA8A==", + "requires": {} }, "react-redux": { "version": "8.0.7", @@ -28206,7 +28250,8 @@ "react-side-effect": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz", - "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==" + "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==", + "requires": {} }, "react-simplemde-editor": { "version": "5.2.0", @@ -28219,7 +28264,8 @@ "react-spinners": { "version": "0.13.8", "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.13.8.tgz", - "integrity": "sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==" + "integrity": "sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==", + "requires": {} }, "react-stomp-hooks": { "version": "3.0.1", @@ -28234,7 +28280,8 @@ "react-table": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", - "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==" + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", + "requires": {} }, "react-test-renderer": { "version": "17.0.2", @@ -28363,7 +28410,8 @@ "redux-thunk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", - "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==" + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "requires": {} }, "regenerate": { "version": "1.4.2", @@ -28665,7 +28713,7 @@ "version": "1.63.3", "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.3.tgz", "integrity": "sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==", - "dev": true, + "devOptional": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -29275,7 +29323,8 @@ "style-loader": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==" + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "requires": {} }, "style-to-object": { "version": "0.3.0", @@ -29767,7 +29816,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, + "devOptional": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -29788,13 +29837,13 @@ "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true + "devOptional": true }, "acorn-walk": { "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, + "devOptional": true, "requires": { "acorn": "^8.11.0" } @@ -29803,7 +29852,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true } } }, @@ -29896,8 +29945,7 @@ "typescript": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==" }, "typo-js": { "version": "1.2.1", @@ -30071,12 +30119,14 @@ "use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==" + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "requires": {} }, "use-sync-external-store": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz", - "integrity": "sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ==" + "integrity": "sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ==", + "requires": {} }, "util-deprecate": { "version": "1.0.2", @@ -30103,9 +30153,9 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==" }, "v8-compile-cache": { "version": "2.3.0", @@ -30116,7 +30166,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "v8-to-istanbul": { "version": "8.1.1", @@ -30262,7 +30312,8 @@ "acorn-import-attributes": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==" + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "requires": {} }, "eslint-scope": { "version": "5.1.1", @@ -30414,7 +30465,8 @@ "ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==" + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "requires": {} } } }, @@ -30844,7 +30896,8 @@ "ws": { "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==" + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "requires": {} }, "xml": { "version": "1.0.1", @@ -30886,7 +30939,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "devOptional": true }, "yocto-queue": { "version": "0.1.0", diff --git a/package.json b/package.json index df33063a..1137b308 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "redux-thunk": "^2.4.2", "resolve": "1.22.2", "simple-xpath-position": "^2.0.2", - "uuid": "^9.0.0", + "uuid": "^10.0.0", "whatwg-fetch": "3.6.2", "whatwg-mimetype": "3.0.0" }, @@ -83,7 +83,7 @@ "@types/enzyme": "^3.10.13", "@types/jest": "^27.4.1", "@types/js-cookie": "^3.0.3", - "@types/lodash": "^4.14.195", + "@types/lodash": "^4.17.10", "@types/luxon": "^3.3.0", "@types/node": "^18.11.17", "@types/react": "^17.0.61", @@ -94,10 +94,10 @@ "@types/react-table": "^7.7.14", "@types/redux-logger": "^3.0.13", "@types/redux-mock-store": "^1.0.3", - "@types/uuid": "^9.0.2", + "@types/uuid": "^10.0.0", "@types/whatwg-mimetype": "^2.1.1", "@wojtekmaj/enzyme-adapter-react-17": "^0.8.0", - "axios-mock-adapter": "^1.22.0", + "axios-mock-adapter": "^2.1.0", "babel-plugin-macros": "2.8.0", "cross-env": "^7.0.3", "enzyme": "^3.11.0", diff --git a/src/util/Ajax.ts b/src/util/Ajax.ts index 05ba5fc1..0c001be7 100644 --- a/src/util/Ajax.ts +++ b/src/util/Ajax.ts @@ -1,15 +1,8 @@ -import axios, { - AxiosHeaders, - AxiosInstance, - AxiosRequestConfig, - ResponseType, -} from "axios"; +import axios, { AxiosHeaders, ResponseType } from "axios"; import Routing from "./Routing"; import Constants, { getEnv } from "./Constants"; import Routes from "./Routes"; -import MockAdapter from "axios-mock-adapter"; import SecurityUtils from "./SecurityUtils"; -import fileContent from "../rest-mock/file"; import ConfigParam from "./ConfigParam"; class RequestConfigBuilder { @@ -267,10 +260,6 @@ export class Ajax { } } ); - if (getEnv(ConfigParam.MOCK_REST_API, "") === true.toString()) { - // Mock backend REST API if the environment is configured to do so - mockRestApi(this.axiosInstance); - } } /** @@ -402,302 +391,6 @@ export class Ajax { } } -function mockRestApi(axiosInst: AxiosInstance): void { - const mock = new MockAdapter(axiosInst, { delayResponse: 500 }); - const respHeaders = {}; - respHeaders[Constants.Headers.AUTHORIZATION] = "12345"; - - // Mock term history - mock - .onGet(/\/rest\/terms\/.+\/history/) - .reply(200, require("../rest-mock/termHistory"), respHeaders); - // Mock current user data - mock - .onGet(Constants.API_PREFIX + "/users/current") - .reply(200, require("../rest-mock/current"), respHeaders); - // Mock login return value - mock.onPost("/j_spring_security_check").reply( - 200, - { - loggedIn: true, - success: true, - }, - respHeaders - ); - // Mock registration request - mock.onPost(Constants.API_PREFIX + "/users").reply(201); - // Mock users retrieval - mock - .onGet(Constants.API_PREFIX + "/users") - .reply(200, require("../rest-mock/users"), respHeaders); - // Mock username existence check - mock - .onGet(Constants.API_PREFIX + "/users/username") - .reply((config: AxiosRequestConfig) => { - if (config.params.username.charAt(0) === "a") { - return [200, true]; - } else { - return [200, false]; - } - }, respHeaders); - // Mock vocabulary IRI generator - mock - .onGet(Constants.API_PREFIX + "/vocabularies/identifier") - .reply( - 200, - "http://onto.fel.cvut.cz/ontologies/termit/vocabulary/test", - respHeaders - ); - // Mock get vocabularies - mock - .onGet(Constants.API_PREFIX + "/vocabularies") - .reply(200, require("../rest-mock/vocabularies"), respHeaders); - // Mock vocabulary create endpoint - mock.onPost(Constants.API_PREFIX + "/vocabularies").reply( - 201, - null, - Object.assign({}, respHeaders, { - location: - "http://kbss.felk.cvut.cz/termit/rest/vocabularies/metropolitan-plan", - }) - ); - // mock.onPost(Constants.API_PREFIX + "/vocabularies").reply(500, { - // message: "Unable to create vocabulary!" - // }); - // Mock term IRI generator - mock - .onGet(/\/rest\/vocabularies\/.+\/terms\/identifier/) - .reply( - 200, - "http://onto.fel.cvut.cz/ontologies/termit/vocabulary/test/term-one", - respHeaders - ); - // Mock getting subterms of a vocabulary term - mock - .onGet(/\/rest\/vocabularies\/.+\/terms\/.+\/subterms/) - .reply((config) => { - const url: string = config.url!; - if (url.indexOf("pojem-4")) { - return [200, require("../rest-mock/subterms"), respHeaders]; - } else { - return [200, [], respHeaders]; - } - }); - - // Mock getting term assignments - mock - .onGet(/\/rest\/vocabularies\/.+\/terms\/.+\/assignments/) - .reply((config) => { - const iri = config.url; - const head = Object.assign({}, respHeaders, { - "content-type": Constants.JSON_LD_MIME_TYPE, - }); - if (iri!.indexOf("pojem-1") !== -1 || iri!.indexOf("pojem-2") !== -1) { - return [200, require("../rest-mock/termAssignments.json"), head]; - } else { - return [200, [], head]; - } - }); - - // Mock term creation - mock.onPost(/\/rest\/vocabularies\/.+\/terms/).reply( - 201, - null, - Object.assign({}, respHeaders, { - location: - "http://kbss.felk.cvut.cz/termit/rest/vocabularies/metropolitan-plan/terms/test-term", - }) - ); - - // Mock getting vocabulary terms - mock - .onGet(/\/rest\/vocabularies\/.+\/terms\/roots/) - .reply(200, require("../rest-mock/terms"), respHeaders); - - // Mock term update - mock - .onPut(/\/rest\/vocabularies\/.+\/terms\/.+/) - .reply(204, null, respHeaders); - - // Mock getting vocabulary term - mock.onGet(/\/rest\/vocabularies\/.+\/terms\/.+/).reply((config) => { - const url: string = config.url!; - const termId = url.substring(url.lastIndexOf("/") + 1); - const terms = require("../rest-mock/terms"); - for (const t of terms) { - if (t["@id"].indexOf(termId) !== -1) { - return [200, t, respHeaders]; - } - } - return [404, undefined, respHeaders]; - }); - - // Mock term label uniqueness in vocabulary check - mock - .onGet(/\/rest\/vocabularies\/.+\/terms\/name/) - .reply((config: AxiosRequestConfig) => { - if (config.params.value === "test") { - return [200, true]; - } else { - return [200, false]; - } - }); - - // Mock vocabulary terms export - mock - .onGet(/\/rest\/vocabularies\/.+\/terms/) - .reply((config: AxiosRequestConfig) => { - if (config.headers!.Accept === Constants.CSV_MIME_TYPE) { - const exportData = - "IRI,Label,Comment,Types,Sources,SubTerms\nhttp://test.org,Test,Test comment,,,"; - const attachmentHeader = {}; - attachmentHeader[Constants.Headers.CONTENT_DISPOSITION] = - 'attachment; filename="export.csv"'; - return [ - 200, - exportData, - Object.assign({}, respHeaders, attachmentHeader), - ]; - } - return [415, null]; - }); - - // Mock vocabulary retrieval endpoint - mock.onGet(/\/rest\/vocabularies\/.+/).reply( - 200, - require("../rest-mock/vocabulary"), - Object.assign({}, respHeaders, { - "content-type": Constants.JSON_LD_MIME_TYPE, - }) - ); - - // Mock resource IRI generator - mock - .onGet(Constants.API_PREFIX + "/resources/identifier") - .reply( - 200, - "http://onto.fel.cvut.cz/ontologies/termit/resource/test-resource", - respHeaders - ); - - // Mock text analysis invocation - mock - .onPut(/\/rest\/resources\/.+\/text-analysis/) - .reply(204, null, respHeaders); - - // Mock getting file content - mock.onGet(/\/rest\/resources\/.+\/content/).reply( - 200, - fileContent, - Object.assign({}, respHeaders, { - "content-type": Constants.HTML_MIME_TYPE, - }) - ); - - // Mock update file content - mock.onPut(/\/rest\/resources\/.+\/content/).reply( - 204, - fileContent, - Object.assign({}, respHeaders, { - "content-type": Constants.HTML_MIME_TYPE, - }) - ); - - // Mock resource retrieval endpoint - mock.onGet(/\/rest\/resources\/.+/).reply((config) => { - if ( - config.params.namespace && - config.params.namespace.indexOf("document") !== -1 - ) { - return [ - 200, - require("../rest-mock/document"), - Object.assign({}, respHeaders, { - "content-type": Constants.JSON_LD_MIME_TYPE, - }), - ]; - } else { - return [ - 200, - require("../rest-mock/resource"), - Object.assign({}, respHeaders, { - "content-type": Constants.JSON_LD_MIME_TYPE, - }), - ]; - } - }); - // Mock resource creation - mock.onPost(Constants.API_PREFIX + "/resources").reply( - 201, - null, - Object.assign({}, respHeaders, { - location: - "http://onto.fel.cvut.cz/ontologies/application/termit/randomInstance-1529066498", - }) - ); - - // Mock resource tags update - mock.onPut("/rest/resources/resource/terms").reply(204, null, respHeaders); - - // Mock vocabulary update endpoint - mock.onPut(/\/rest\/vocabularies\/.+/).reply(204, undefined, respHeaders); - - mock.onGet(/\/rest\/query/).reply((config) => { - if (config.params.query.includes("?asset")) { - return [200, require("../rest-mock/assetCount"), respHeaders]; - } else if (config.params.query.includes("DISTINCT ?pojem")) { - return [200, require("../rest-mock/termFrequency"), respHeaders]; - } else if (config.params.query.includes("?typ")) { - return [200, require("../rest-mock/termTypeFrequency"), respHeaders]; - } else { - return [200, [], respHeaders]; - } - }); - - // Mock label search results - mock - .onGet(Constants.API_PREFIX + "/search/label") - .reply(200, require("../rest-mock/searchResults"), respHeaders); - - // Mock get types - mock - .onGet(/\/rest\/language\/types/) - .reply(200, require("../rest-mock/types"), respHeaders); - - // Mock get label - mock.onGet(Constants.API_PREFIX + "/data/label").reply((config) => { - const iri: string = config.params.iri; - if (iri.indexOf("#") !== -1) { - return [404, undefined, respHeaders]; - } - return [200, iri.substring(iri.lastIndexOf("/") + 1), respHeaders]; - }); - // Mock getting known properties - mock.onGet(Constants.API_PREFIX + "/data/properties").reply( - 200, - require("../rest-mock/properties"), - Object.assign({}, respHeaders, { - "content-type": Constants.JSON_LD_MIME_TYPE, - }) - ); - // Mock creating new property - mock.onPost(Constants.API_PREFIX + "/data/properties").reply( - 201, - undefined, - Object.assign({}, respHeaders, { - location: "http://kbss.felk.cvut.cz/termit/rest/data/properties", - }) - ); - // Mock getting last edited assets - mock.onGet(Constants.API_PREFIX + "/assets/last-edited").reply( - 200, - require("../rest-mock/lastEditedAssets"), - Object.assign({}, respHeaders, { - "content-type": Constants.JSON_LD_MIME_TYPE, - }) - ); -} - const instance = new Ajax(); export default instance; diff --git a/src/util/ConfigParam.ts b/src/util/ConfigParam.ts index 7f65eab8..b53da105 100644 --- a/src/util/ConfigParam.ts +++ b/src/util/ConfigParam.ts @@ -1,7 +1,6 @@ const ConfigParam = { ADMIN_REGISTRATION_ONLY: "ADMIN_REGISTRATION_ONLY", SHOW_PUBLIC_VIEW_ON_UNAUTHORIZED: "SHOW_PUBLIC_VIEW_ON_UNAUTHORIZED", - MOCK_REST_API: "MOCK_REST_API", AUTH_TYPE: "AUTHENTICATION", AUTH_SERVER_MANAGEMENT_URL: "AUTH_SERVER_MANAGEMENT", AUTH_SERVER_USER_PROFILE_URL: "AUTH_SERVER_USER_PROFILE", From c01fa90c7de4e3c71ad854c0cf42a5ea0e60ac0c Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 14 Oct 2024 16:07:09 +0200 Subject: [PATCH 10/23] [Enhancement #538] Allow downloading file without unconfirmed occurrences from annotator. --- src/action/AsyncActions.ts | 16 +++- src/component/annotator/Annotator.tsx | 5 ++ .../annotator/AnnotatorDownloadActions.tsx | 78 +++++++++++++++++++ .../resource/document/DocumentFiles.tsx | 4 +- src/i18n/cs.ts | 3 + src/i18n/en.ts | 3 + 6 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 src/component/annotator/AnnotatorDownloadActions.tsx diff --git a/src/action/AsyncActions.ts b/src/action/AsyncActions.ts index 17623ddc..21d99a98 100644 --- a/src/action/AsyncActions.ts +++ b/src/action/AsyncActions.ts @@ -1133,9 +1133,15 @@ export function loadLatestTextAnalysisRecord(resourceIri: IRI) { /** * Downloads the content of a file with the specified IRI (assuming it is stored on the server). * @param fileIri File identifier - * @param at Timestamp of the file version to download + * @param options File export options */ -export function exportFileContent(fileIri: IRI, at?: string) { +export function exportFileContent( + fileIri: IRI, + options: { + at?: string; + withoutUnconfirmedOccurrences?: boolean; + } = {} +) { const action = { type: ActionType.EXPORT_FILE_CONTENT, }; @@ -1147,7 +1153,11 @@ export function exportFileContent(fileIri: IRI, at?: string) { url, param("namespace", fileIri.namespace) .param("attachment", "true") - .param("at", at) + .param("at", options.at) + .param( + "withoutUnconfirmedOccurrences", + options.withoutUnconfirmedOccurrences?.toString() + ) .responseType("arraybuffer") ) .then((resp: AxiosResponse) => { diff --git a/src/component/annotator/Annotator.tsx b/src/component/annotator/Annotator.tsx index 2aae447f..d4cfa446 100644 --- a/src/component/annotator/Annotator.tsx +++ b/src/component/annotator/Annotator.tsx @@ -56,6 +56,7 @@ import { AnnotationClass, AnnotationOrigin, } from "../../model/AnnotatorLegendFilter"; +import AnnotatorDownloadActions from "./AnnotatorDownloadActions"; interface AnnotatorProps extends HasI18n { fileIri: IRI; @@ -657,6 +658,10 @@ export class Annotator extends React.Component { )} /> , + , , ]} /> diff --git a/src/component/annotator/AnnotatorDownloadActions.tsx b/src/component/annotator/AnnotatorDownloadActions.tsx new file mode 100644 index 00000000..f13bc4e5 --- /dev/null +++ b/src/component/annotator/AnnotatorDownloadActions.tsx @@ -0,0 +1,78 @@ +import React from "react"; +import { IRI } from "../../util/VocabularyUtils"; +import { useI18n } from "../hook/useI18n"; +import { + DropdownItem, + DropdownMenu, + DropdownToggle, + UncontrolledButtonDropdown, +} from "reactstrap"; +import { FaCloudDownloadAlt } from "react-icons/fa"; +import { useDispatch } from "react-redux"; +import { ThunkDispatch } from "../../util/Types"; +import { exportFileContent } from "../../action/AsyncActions"; +import { trackPromise } from "react-promise-tracker"; +import { DateTime } from "luxon"; +import Constants from "../../util/Constants"; + +const AnnotatorDownloadActions: React.FC<{ fileIri: IRI }> = ({ fileIri }) => { + const { i18n } = useI18n(); + const dispatch: ThunkDispatch = useDispatch(); + + const downloadCurrentFile = () => { + trackPromise(dispatch(exportFileContent(fileIri)), "annotator"); + }; + const downloadOriginalFile = () => { + const timestamp = DateTime.fromMillis(0).toFormat( + Constants.TIMESTAMP_PARAM_FORMAT + ); + trackPromise( + dispatch(exportFileContent(fileIri, { at: timestamp })), + "annotator" + ); + }; + const downloadWithoutUnconfirmed = () => { + trackPromise( + dispatch( + exportFileContent(fileIri, { withoutUnconfirmedOccurrences: true }) + ), + "annotator" + ); + }; + + return ( + + + + + {i18n("resource.metadata.file.content.download")} + + + + + {i18n("annotator.download.thisFile")} + + + {i18n("annotator.download.original")} + + + {i18n("annotator.download.withoutUnconfirmed")} + + + + ); +}; + +export default AnnotatorDownloadActions; diff --git a/src/component/resource/document/DocumentFiles.tsx b/src/component/resource/document/DocumentFiles.tsx index 8b6cf76b..ea2a6c88 100644 --- a/src/component/resource/document/DocumentFiles.tsx +++ b/src/component/resource/document/DocumentFiles.tsx @@ -71,7 +71,9 @@ export const DocumentFiles = (props: DocumentFilesProps) => { Constants.TIMESTAMP_PARAM_FORMAT ); dispatch( - exportFileContent(VocabularyUtils.create(termitFile.iri), timestamp) + exportFileContent(VocabularyUtils.create(termitFile.iri), { + at: timestamp, + }) ); }; diff --git a/src/i18n/cs.ts b/src/i18n/cs.ts index a99a857a..3df037b3 100644 --- a/src/i18n/cs.ts +++ b/src/i18n/cs.ts @@ -671,6 +671,9 @@ const cs = { annotator: "Anotátor", "annotator.content.loading": "Načítám obsah souboru...", + "annotator.download.thisFile": "Tento soubor", + "annotator.download.original": "Originál", + "annotator.download.withoutUnconfirmed": "Bez nepotvrzených výskytů", "annotator.vocabulary": "Používá pojmy ze slovníku", "annotator.selectionPurpose.dialog.title": "K čemu bude sloužit vybraný text?", diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 00c1b1a3..e4b33ab6 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -661,6 +661,9 @@ const en = { annotator: "Annotator", "annotator.content.loading": "Loading file content...", + "annotator.download.thisFile": "This file", + "annotator.download.original": "Original", + "annotator.download.withoutUnconfirmed": "Without unconfirmed occurrences", "annotator.vocabulary": "Uses terms from vocabulary", "annotator.selectionPurpose.dialog.title": "What do you want to do with the selected text?", From bedcc296a040e6fcc845146f68e9a19248327ec6 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 14 Oct 2024 16:16:46 +0200 Subject: [PATCH 11/23] [Ref] Move file download to AsyncResourceActions.ts --- src/action/AsyncActions.ts | 40 --------- src/action/AsyncResourceActions.ts | 42 ++++++++++ src/action/__tests__/AsyncActions.test.ts | 57 ------------- .../__tests__/AsyncResourceActions.test.ts | 84 +++++++++++++++++++ .../annotator/AnnotatorDownloadActions.tsx | 2 +- .../resource/document/DocumentFiles.tsx | 2 +- 6 files changed, 128 insertions(+), 99 deletions(-) create mode 100644 src/action/__tests__/AsyncResourceActions.test.ts diff --git a/src/action/AsyncActions.ts b/src/action/AsyncActions.ts index 21d99a98..6db20ef6 100644 --- a/src/action/AsyncActions.ts +++ b/src/action/AsyncActions.ts @@ -1130,46 +1130,6 @@ export function loadLatestTextAnalysisRecord(resourceIri: IRI) { }; } -/** - * Downloads the content of a file with the specified IRI (assuming it is stored on the server). - * @param fileIri File identifier - * @param options File export options - */ -export function exportFileContent( - fileIri: IRI, - options: { - at?: string; - withoutUnconfirmedOccurrences?: boolean; - } = {} -) { - const action = { - type: ActionType.EXPORT_FILE_CONTENT, - }; - return (dispatch: ThunkDispatch) => { - dispatch(asyncActionRequest(action)); - const url = - Constants.API_PREFIX + "/resources/" + fileIri.fragment + "/content"; - return Ajax.getRaw( - url, - param("namespace", fileIri.namespace) - .param("attachment", "true") - .param("at", options.at) - .param( - "withoutUnconfirmedOccurrences", - options.withoutUnconfirmedOccurrences?.toString() - ) - .responseType("arraybuffer") - ) - .then((resp: AxiosResponse) => { - const fileName = fileIri.fragment; - const mimeType = resp.headers["content-type"]; - Utils.fileDownload(resp.data, fileName, mimeType); - return dispatch(asyncActionSuccess(action)); - }) - .catch((error: ErrorData) => dispatch(asyncActionFailure(action, error))); - }; -} - export function loadHistory(asset: Asset) { const assetIri = VocabularyUtils.create(asset.iri); const historyConf = resolveHistoryLoadingParams(asset, assetIri); diff --git a/src/action/AsyncResourceActions.ts b/src/action/AsyncResourceActions.ts index b93b90bd..dfacc0e2 100644 --- a/src/action/AsyncResourceActions.ts +++ b/src/action/AsyncResourceActions.ts @@ -12,6 +12,8 @@ import JsonLdUtils from "../util/JsonLdUtils"; import File, { FileData } from "../model/File"; import { CONTEXT as DOCUMENT_CONTEXT } from "../model/Document"; import { ErrorData } from "../model/ErrorInfo"; +import { AxiosResponse } from "axios"; +import Utils from "../util/Utils"; export function loadFileMetadata(fileIri: IRI) { const action = { type: ActionType.LOAD_FILE_METADATA }; @@ -37,3 +39,43 @@ export function loadFileMetadata(fileIri: IRI) { }); }; } + +/** + * Downloads the content of a file with the specified IRI (assuming it is stored on the server). + * @param fileIri File identifier + * @param options File export options + */ +export function exportFileContent( + fileIri: IRI, + options: { + at?: string; + withoutUnconfirmedOccurrences?: boolean; + } = {} +) { + const action = { + type: ActionType.EXPORT_FILE_CONTENT, + }; + return (dispatch: ThunkDispatch) => { + dispatch(asyncActionRequest(action)); + const url = + Constants.API_PREFIX + "/resources/" + fileIri.fragment + "/content"; + return Ajax.getRaw( + url, + param("namespace", fileIri.namespace) + .param("attachment", "true") + .param("at", options.at) + .param( + "withoutUnconfirmedOccurrences", + options.withoutUnconfirmedOccurrences?.toString() + ) + .responseType("arraybuffer") + ) + .then((resp: AxiosResponse) => { + const fileName = fileIri.fragment; + const mimeType = resp.headers["content-type"]; + Utils.fileDownload(resp.data, fileName, mimeType); + return dispatch(asyncActionSuccess(action)); + }) + .catch((error: ErrorData) => dispatch(asyncActionFailure(action, error))); + }; +} diff --git a/src/action/__tests__/AsyncActions.test.ts b/src/action/__tests__/AsyncActions.test.ts index c62a062c..dfe20b61 100644 --- a/src/action/__tests__/AsyncActions.test.ts +++ b/src/action/__tests__/AsyncActions.test.ts @@ -5,7 +5,6 @@ import { createProperty, createVocabulary, executeFileTextAnalysis, - exportFileContent, getContentType, getLabel, getProperties, @@ -56,7 +55,6 @@ import RdfsResource, { } from "../../model/RdfsResource"; import TermItState from "../../model/TermItState"; import Resource from "../../model/Resource"; -import Utils from "../../util/Utils"; import AsyncActionStatus from "../AsyncActionStatus"; import fileContent from "../../rest-mock/file"; import TermItFile from "../../model/File"; @@ -1556,61 +1554,6 @@ describe("Async actions", () => { }); }); - describe("exportFileContent", () => { - const fileName = "test-file.html"; - const fileIri = VocabularyUtils.create( - "http://onto.fel.cvut.cz/ontologies/termit/resources/" + fileName - ); - - it("sends request asking for content as attachment", () => { - Ajax.getRaw = jest.fn().mockImplementation(() => - Promise.resolve({ - data: "test", - headers: { - "content-type": "text/html", - "content-disposition": 'attachment; filename="' + fileName + '"', - }, - }) - ); - Utils.fileDownload = jest.fn(); - return Promise.resolve( - (store.dispatch as ThunkDispatch)(exportFileContent(fileIri)) - ).then(() => { - expect(Ajax.getRaw).toHaveBeenCalled(); - const url = (Ajax.getRaw as jest.Mock).mock.calls[0][0]; - expect(url).toEqual( - Constants.API_PREFIX + "/resources/" + fileName + "/content" - ); - const config = (Ajax.getRaw as jest.Mock).mock.calls[0][1]; - expect(config.getParams().attachment).toEqual("true"); - expect(config.getParams().namespace).toEqual(fileIri.namespace); - }); - }); - - it("stores response attachment", () => { - const data = 'test'; - Ajax.getRaw = jest.fn().mockImplementation(() => - Promise.resolve({ - data, - headers: { - "content-type": "text/html", - "content-disposition": 'attachment; filename="' + fileName + '"', - }, - }) - ); - Utils.fileDownload = jest.fn(); - return Promise.resolve( - (store.dispatch as ThunkDispatch)(exportFileContent(fileIri)) - ).then(() => { - expect(Utils.fileDownload).toHaveBeenCalled(); - const args = (Utils.fileDownload as jest.Mock).mock.calls[0]; - expect(args[0]).toEqual(data); - expect(args[1]).toEqual(fileName); - expect(args[2]).toEqual("text/html"); - }); - }); - }); - describe("loadImportedVocabularies", () => { it("loads imported vocabularies for the specified vocabulary IRI", () => { const imports = [Generator.generateUri(), Generator.generateUri()]; diff --git a/src/action/__tests__/AsyncResourceActions.test.ts b/src/action/__tests__/AsyncResourceActions.test.ts new file mode 100644 index 00000000..be30f280 --- /dev/null +++ b/src/action/__tests__/AsyncResourceActions.test.ts @@ -0,0 +1,84 @@ +import configureMockStore, { MockStoreEnhanced } from "redux-mock-store"; +import TermItState from "../../model/TermItState"; +import thunk from "redux-thunk"; +import VocabularyUtils from "../../util/VocabularyUtils"; +import Utils from "../../util/Utils"; +import { ThunkDispatch } from "../../util/Types"; +import Constants from "../../util/Constants"; +import Ajax from "../../util/Ajax"; +import { exportFileContent } from "../AsyncResourceActions"; + +jest.mock("../../util/Routing"); +jest.mock("../../util/Ajax", () => { + const originalModule = jest.requireActual("../../util/Ajax"); + return { + ...originalModule, + default: jest.fn(), + }; +}); + +const mockStore = configureMockStore([thunk]); + +describe("AsyncResourceActions", () => { + let store: MockStoreEnhanced; + + beforeEach(() => { + jest.clearAllMocks(); + store = mockStore(new TermItState()); + }); + + describe("exportFileContent", () => { + const fileName = "test-file.html"; + const fileIri = VocabularyUtils.create( + "http://onto.fel.cvut.cz/ontologies/termit/resources/" + fileName + ); + + it("sends request asking for content as attachment", () => { + Ajax.getRaw = jest.fn().mockImplementation(() => + Promise.resolve({ + data: "test", + headers: { + "content-type": "text/html", + "content-disposition": 'attachment; filename="' + fileName + '"', + }, + }) + ); + Utils.fileDownload = jest.fn(); + return Promise.resolve( + (store.dispatch as ThunkDispatch)(exportFileContent(fileIri)) + ).then(() => { + expect(Ajax.getRaw).toHaveBeenCalled(); + const url = (Ajax.getRaw as jest.Mock).mock.calls[0][0]; + expect(url).toEqual( + Constants.API_PREFIX + "/resources/" + fileName + "/content" + ); + const config = (Ajax.getRaw as jest.Mock).mock.calls[0][1]; + expect(config.getParams().attachment).toEqual("true"); + expect(config.getParams().namespace).toEqual(fileIri.namespace); + }); + }); + + it("stores response attachment", () => { + const data = 'test'; + Ajax.getRaw = jest.fn().mockImplementation(() => + Promise.resolve({ + data, + headers: { + "content-type": "text/html", + "content-disposition": 'attachment; filename="' + fileName + '"', + }, + }) + ); + Utils.fileDownload = jest.fn(); + return Promise.resolve( + (store.dispatch as ThunkDispatch)(exportFileContent(fileIri)) + ).then(() => { + expect(Utils.fileDownload).toHaveBeenCalled(); + const args = (Utils.fileDownload as jest.Mock).mock.calls[0]; + expect(args[0]).toEqual(data); + expect(args[1]).toEqual(fileName); + expect(args[2]).toEqual("text/html"); + }); + }); + }); +}); diff --git a/src/component/annotator/AnnotatorDownloadActions.tsx b/src/component/annotator/AnnotatorDownloadActions.tsx index f13bc4e5..4c0c2542 100644 --- a/src/component/annotator/AnnotatorDownloadActions.tsx +++ b/src/component/annotator/AnnotatorDownloadActions.tsx @@ -10,10 +10,10 @@ import { import { FaCloudDownloadAlt } from "react-icons/fa"; import { useDispatch } from "react-redux"; import { ThunkDispatch } from "../../util/Types"; -import { exportFileContent } from "../../action/AsyncActions"; import { trackPromise } from "react-promise-tracker"; import { DateTime } from "luxon"; import Constants from "../../util/Constants"; +import { exportFileContent } from "../../action/AsyncResourceActions"; const AnnotatorDownloadActions: React.FC<{ fileIri: IRI }> = ({ fileIri }) => { const { i18n } = useI18n(); diff --git a/src/component/resource/document/DocumentFiles.tsx b/src/component/resource/document/DocumentFiles.tsx index ea2a6c88..8da3c5a0 100644 --- a/src/component/resource/document/DocumentFiles.tsx +++ b/src/component/resource/document/DocumentFiles.tsx @@ -4,11 +4,11 @@ import { ThunkDispatch } from "../../../util/Types"; import { useDispatch } from "react-redux"; import { createFileInDocument, - exportFileContent, removeFileFromDocument, updateResource, uploadFileContent, } from "../../../action/AsyncActions"; +import { exportFileContent } from "../../../action/AsyncResourceActions"; import VocabularyUtils from "../../../util/VocabularyUtils"; import Files from "./Files"; import NotificationType from "../../../model/NotificationType"; From 3c74c29e35953ff016e415c1f8f33872604b034e Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Thu, 17 Oct 2024 10:18:56 +0200 Subject: [PATCH 12/23] [Enhancement #544] Simplify FTS results rendering. Do not load full term for each result, support all newly added fields. --- src/component/search/label/SearchResults.tsx | 2 +- src/component/search/label/TermResultItem.tsx | 177 +++++------------- .../search/label/VocabularyResultItem.tsx | 135 +++++-------- .../label/__tests__/SearchResults.test.tsx | 15 +- src/model/search/SearchResult.ts | 4 + 5 files changed, 102 insertions(+), 231 deletions(-) diff --git a/src/component/search/label/SearchResults.tsx b/src/component/search/label/SearchResults.tsx index 31271910..ebecf583 100644 --- a/src/component/search/label/SearchResults.tsx +++ b/src/component/search/label/SearchResults.tsx @@ -51,7 +51,7 @@ export function mergeDuplicates( // If the match field is the same there is no need to update other attributes, as the match is already // marked in the snippet of the existing item if (existing.snippetField !== r.snippetField) { - if (r.snippetField === "label") { + if (r.snippetField === "prefLabel") { // Render label match first existing.snippets.unshift(r.snippetText); existing.snippetFields.unshift(r.snippetField); diff --git a/src/component/search/label/TermResultItem.tsx b/src/component/search/label/TermResultItem.tsx index ada31f8e..8c8f5181 100644 --- a/src/component/search/label/TermResultItem.tsx +++ b/src/component/search/label/TermResultItem.tsx @@ -1,12 +1,7 @@ import * as React from "react"; -import { injectIntl } from "react-intl"; -import withI18n, { HasI18n } from "../../hoc/withI18n"; -import VocabularyUtils, { IRI } from "../../../util/VocabularyUtils"; import AssetLink from "../../misc/AssetLink"; import Term from "../../../model/Term"; -import { connect } from "react-redux"; -import { ThunkDispatch } from "../../../util/Types"; -import { loadTermByIri } from "../../../action/AsyncActions"; +import { useSelector } from "react-redux"; import { SearchResultItem } from "./SearchResults"; import AssetLabel from "../../misc/AssetLabel"; import AssetFactory from "../../../util/AssetFactory"; @@ -14,137 +9,55 @@ import TermItState from "../../../model/TermItState"; import FTSMatch from "./FTSMatch"; import TermBadge from "../../badge/TermBadge"; import { getTermPath } from "../../term/TermLink"; -import User from "../../../model/User"; -import { getLocalized } from "../../../model/MultilingualString"; -import { getShortLocale } from "../../../util/IntlUtil"; import TermStateBadge from "../../term/state/TermStateBadge"; +import { useI18n } from "../../hook/useI18n"; +import { getResultDescription } from "./VocabularyResultItem"; -interface TermResultItemOwnProps { +interface TermResultItemProps { result: SearchResultItem; } -interface TermResultItemDispatchProps { - loadTerm: (termIri: IRI) => Promise; -} - -interface TermResultItemStateProps { - user: User; -} - -interface TermResultItemProps - extends TermResultItemOwnProps, - TermResultItemDispatchProps, - TermResultItemStateProps, - HasI18n {} - -interface TermResultItemState { - text: string | undefined; -} - -export class TermResultItem extends React.Component< - TermResultItemProps, - TermResultItemState -> { - constructor(props: TermResultItemProps) { - super(props); - this.state = { - text: undefined, - }; - } +const TermResultItem: React.FC = ({ result }) => { + const { i18n } = useI18n(); + const user = useSelector((state: TermItState) => state.user); - public componentDidMount(): void { - const indexOfDefinition = this.getIndexOf("definition"); - if (indexOfDefinition < 0) { - const iri = VocabularyUtils.create(this.props.result.iri); - this.props.loadTerm(iri).then((term) => { - if (term) { - this.setState({ - text: term!.definition - ? getLocalized( - term!.definition, - getShortLocale(this.props.locale) - ) - : getLocalized( - term!.scopeNote, - getShortLocale(this.props.locale) - ), - }); - } - }); - } - } - - private getIndexOf(field: string) { - return this.props.result.snippetFields.indexOf(field); - } - - public render() { - const i18n = this.props.i18n; - const result = this.props.result; - const t = { - iri: result.iri, - label: ( - <> - {result.label} -   - {this.props.result.vocabulary ? ( - <> - {i18n("search.results.vocabulary.from")}  - - - ) : ( - <> - )} - - ), - }; - - let text; - if (this.getIndexOf("definition") > -1) { - text = result.snippets[this.getIndexOf("definition")]; - } else { - text = this.state.text; - } - - if (text && text!.length > 200) { - text = text!.substring(0, 200) + " ..."; - } - - const asset = AssetFactory.createAsset(result); - return ( + const t = { + iri: result.iri, + label: ( <> - - - -
- - {this.getIndexOf("definition") > -1 ? ( - - ) : ( - text - )} - + {result.label} +   + {result.vocabulary ? ( + <> + {i18n("search.results.vocabulary.from")}  + + + ) : ( + <> + )} - ); - } -} - -export default connect< - TermResultItemStateProps, - TermResultItemDispatchProps, - TermResultItemOwnProps, - TermItState ->( - (state: TermItState) => { - return { user: state.user }; - }, - (dispatch: ThunkDispatch) => { - return { - loadTerm: (termIri: IRI) => dispatch(loadTermByIri(termIri)), - }; - } -)(injectIntl(withI18n(TermResultItem))); + ), + }; + const fields = ["definition", "scopeNote"]; + + const description = getResultDescription(result, fields); + + const asset = AssetFactory.createAsset(result); + return ( + <> + + + +
+ + + + + ); +}; + +export default TermResultItem; diff --git a/src/component/search/label/VocabularyResultItem.tsx b/src/component/search/label/VocabularyResultItem.tsx index 285791e7..26cbff1e 100644 --- a/src/component/search/label/VocabularyResultItem.tsx +++ b/src/component/search/label/VocabularyResultItem.tsx @@ -1,110 +1,65 @@ import * as React from "react"; -import { injectIntl } from "react-intl"; -import withI18n, { HasI18n } from "../../hoc/withI18n"; -import VocabularyUtils, { IRI } from "../../../util/VocabularyUtils"; -import { connect } from "react-redux"; -import { ThunkDispatch } from "../../../util/Types"; import { SearchResultItem } from "./SearchResults"; -import TermItState from "../../../model/TermItState"; import FTSMatch from "./FTSMatch"; -import { getRdfsResource } from "../../../action/AsyncActions"; -import RdfsResource from "../../../model/RdfsResource"; import Vocabulary from "../../../model/Vocabulary"; import VocabularyLink from "../../vocabulary/VocabularyLink"; import AssetFactory from "../../../util/AssetFactory"; import VocabularyBadge from "../../badge/VocabularyBadge"; -import { getLocalized } from "../../../model/MultilingualString"; -import { getShortLocale } from "../../../util/IntlUtil"; -interface VocabularyResultItemOwnProps { +interface VocabularyResultItemProps { result: SearchResultItem; } -interface VocabularyResultItemDispatchProps { - getResource: (iri: IRI) => Promise; +export function getSnippetFieldIndex( + result: SearchResultItem, + fieldName: string +) { + return result.snippetFields.indexOf(fieldName); } -interface VocabularyResultItemStateProps {} - -interface VocabularyResultItemProps - extends VocabularyResultItemOwnProps, - VocabularyResultItemDispatchProps, - VocabularyResultItemStateProps, - HasI18n {} - -interface VocabularyResultItemState { - comment?: string | null; -} - -export class VocabularyResultItem extends React.Component< - VocabularyResultItemProps, - VocabularyResultItemState -> { - constructor(props: VocabularyResultItemProps) { - super(props); - this.state = { - comment: null, - }; - } - - public componentDidMount(): void { - const indexOfComment = this.getIndexOf("comment"); - if (indexOfComment < 0) { - const iri = VocabularyUtils.create(this.props.result.iri); - this.props.getResource(iri).then((resource) => { - if (resource) { - this.setState({ - comment: getLocalized( - resource.comment, - getShortLocale(this.props.locale) - ), - }); - } - }); +export function getResultDescription( + result: SearchResultItem, + fieldNames: string[] +) { + let snippetFieldIndex = -1; + for (let i = 0; i < fieldNames.length; i++) { + snippetFieldIndex = getSnippetFieldIndex(result, fieldNames[i]); + if (snippetFieldIndex >= 0) { + break; } } - - private getIndexOf(field: string) { - return this.props.result.snippetFields.indexOf(field); + let text; + if (snippetFieldIndex >= 0) { + text = result.snippets[snippetFieldIndex]; + } else { + text = result.description; } - public render() { - let text; - if (this.getIndexOf("comment") > -1) { - text = this.props.result.snippets[this.getIndexOf("comment")]; - } else { - text = this.state.comment || ""; - } - - if (text && text!.length > 200) { - text = text!.substring(0, 200) + " ..."; - } - - const res = this.props.result; - return ( - <> - - - - -
- - - - - ); + if (text && text!.length > 200) { + text = text!.substring(0, 200) + " ..."; } + return text || ""; } -export default connect< - VocabularyResultItemStateProps, - VocabularyResultItemDispatchProps, - VocabularyResultItemOwnProps, - TermItState ->(undefined, (dispatch: ThunkDispatch) => { - return { - getResource: (iri: IRI) => dispatch(getRdfsResource(iri)), - }; -})(injectIntl(withI18n(VocabularyResultItem))); +const VocabularyResultItem: React.FC = ({ + result, +}) => { + const description = getResultDescription(result, ["description"]); + + return ( + <> + + + + +
+ + + + + ); +}; + +export default VocabularyResultItem; diff --git a/src/component/search/label/__tests__/SearchResults.test.tsx b/src/component/search/label/__tests__/SearchResults.test.tsx index 557467f6..bf76baa0 100644 --- a/src/component/search/label/__tests__/SearchResults.test.tsx +++ b/src/component/search/label/__tests__/SearchResults.test.tsx @@ -131,7 +131,7 @@ describe("SearchResults", () => { iri, label: "Test", snippetText: "Match and another match", - snippetField: "comment", + snippetField: "description", vocabulary: { iri: vocabularyIri }, types: [VocabularyUtils.VOCABULARY], }), @@ -139,7 +139,7 @@ describe("SearchResults", () => { iri, label: "Test", snippetText: "Match and another match", - snippetField: "comment", + snippetField: "description", vocabulary: { iri: vocabularyIri }, types: [VocabularyUtils.VOCABULARY], }), @@ -162,22 +162,21 @@ describe("SearchResults", () => { it("merges matches of multiple fields of one asset into one result row", () => { const iri = Generator.generateUri(); - const vocabularyIri = Generator.generateUri(); const results = [ new SearchResult({ iri, label: "Test", snippetText: "Match in label", - snippetField: "label", - vocabulary: { iri: vocabularyIri }, + description: "Vocabulary description", + snippetField: "title", types: [VocabularyUtils.VOCABULARY], }), new SearchResult({ iri, label: "Test", - snippetText: "Match in comment", - snippetField: "comment", - vocabulary: { iri: vocabularyIri }, + description: "Vocabulary description", + snippetText: "Match in description", + snippetField: "description", types: [VocabularyUtils.VOCABULARY], }), ]; diff --git a/src/model/search/SearchResult.ts b/src/model/search/SearchResult.ts index 302e6ce8..34e0245b 100644 --- a/src/model/search/SearchResult.ts +++ b/src/model/search/SearchResult.ts @@ -6,6 +6,7 @@ import Utils from "../../util/Utils"; export const CONTEXT = { iri: "@id", label: VocabularyUtils.RDFS_LABEL, + description: VocabularyUtils.DC_DESCRIPTION, vocabulary: VocabularyUtils.IS_TERM_FROM_VOCABULARY, state: VocabularyUtils.HAS_TERM_STATE, snippetText: @@ -19,6 +20,7 @@ export const CONTEXT = { export interface SearchResultData extends AssetData { iri: string; label: string; + description?: string; snippetText: string; snippetField: string; score?: number; @@ -30,6 +32,7 @@ export interface SearchResultData extends AssetData { export default class SearchResult implements AssetData { public readonly iri: string; public readonly label: string; + public readonly description?: string; public readonly snippetText: string; public readonly snippetField: string; public readonly score?: number; @@ -40,6 +43,7 @@ export default class SearchResult implements AssetData { constructor(data: SearchResultData) { this.iri = data.iri; this.label = data.label; + this.description = data.description; this.snippetField = data.snippetField; this.snippetText = data.snippetText; this.score = data.score; From 95af54693a527e35a157fc307347e9f3a8815f00 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 21 Oct 2024 10:40:41 +0200 Subject: [PATCH 13/23] [Enhancement #544] Show info about field in which FTS match was found. --- src/component/search/label/FTSMatch.tsx | 16 ++++----- src/component/search/label/MatchInfo.tsx | 36 +++++++++++++++++++ src/component/search/label/TermResultItem.tsx | 7 ++-- .../search/label/VocabularyResultItem.tsx | 5 +-- src/i18n/cs.ts | 8 ++--- src/i18n/en.ts | 2 +- src/util/Constants.ts | 1 + 7 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 src/component/search/label/MatchInfo.tsx diff --git a/src/component/search/label/FTSMatch.tsx b/src/component/search/label/FTSMatch.tsx index b82e7709..4f9a05c7 100644 --- a/src/component/search/label/FTSMatch.tsx +++ b/src/component/search/label/FTSMatch.tsx @@ -42,15 +42,13 @@ const processingInstructions: Instruction[] = [ export const FTSMatch: React.FC = (props: FTSMatchProps) => { const parser = new HtmlToReactParser(); return ( -
- - {parser.parseWithInstructions( - props.match, - isValidNode, - processingInstructions - )} - -
+ + {parser.parseWithInstructions( + props.match, + isValidNode, + processingInstructions + )} + ); }; diff --git a/src/component/search/label/MatchInfo.tsx b/src/component/search/label/MatchInfo.tsx new file mode 100644 index 00000000..4449f3d6 --- /dev/null +++ b/src/component/search/label/MatchInfo.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import SearchResult from "../../../model/search/SearchResult"; +import { useI18n } from "../../hook/useI18n"; +import FTSMatch from "./FTSMatch"; + +/** + * If the match is in one of these, it is not rendered by the result row by default + */ +const HIDDEN_FIELDS = ["altLabel", "hiddenLabel"]; + +const FIELD_NAME_MAPPING = { + prefLabel: "asset.label", + altLabel: "term.metadata.altLabels.label", + hiddenLabel: "term.metadata.hiddenLabels.label", + scopeNote: "term.metadata.comment", + definition: "term.metadata.definition", + description: "description", +}; + +const MatchInfo: React.FC<{ result: SearchResult }> = ({ result }) => { + const { i18n } = useI18n(); + return ( + + {i18n("search.results.field")}{" "} + {i18n(FIELD_NAME_MAPPING[result.snippetField])} + {HIDDEN_FIELDS.includes(result.snippetField) ? ( + <> +  ( + ) + + ) : null} + + ); +}; + +export default MatchInfo; diff --git a/src/component/search/label/TermResultItem.tsx b/src/component/search/label/TermResultItem.tsx index 8c8f5181..f7535da9 100644 --- a/src/component/search/label/TermResultItem.tsx +++ b/src/component/search/label/TermResultItem.tsx @@ -12,6 +12,7 @@ import { getTermPath } from "../../term/TermLink"; import TermStateBadge from "../../term/state/TermStateBadge"; import { useI18n } from "../../hook/useI18n"; import { getResultDescription } from "./VocabularyResultItem"; +import MatchInfo from "./MatchInfo"; interface TermResultItemProps { result: SearchResultItem; @@ -52,10 +53,10 @@ const TermResultItem: React.FC = ({ result }) => { path={getTermPath(asset as Term, user)} tooltip={i18n("asset.link.tooltip")} /> -
- +
- +
+ ); }; diff --git a/src/component/search/label/VocabularyResultItem.tsx b/src/component/search/label/VocabularyResultItem.tsx index 26cbff1e..d79bbd15 100644 --- a/src/component/search/label/VocabularyResultItem.tsx +++ b/src/component/search/label/VocabularyResultItem.tsx @@ -5,6 +5,7 @@ import Vocabulary from "../../../model/Vocabulary"; import VocabularyLink from "../../vocabulary/VocabularyLink"; import AssetFactory from "../../../util/AssetFactory"; import VocabularyBadge from "../../badge/VocabularyBadge"; +import Constants from "../../../util/Constants"; interface VocabularyResultItemProps { result: SearchResultItem; @@ -35,8 +36,8 @@ export function getResultDescription( text = result.description; } - if (text && text!.length > 200) { - text = text!.substring(0, 200) + " ..."; + if (text && text!.length > Constants.FTS_SNIPPET_TEXT_SIZE) { + text = text!.substring(0, Constants.FTS_SNIPPET_TEXT_SIZE) + " ..."; } return text || ""; } diff --git a/src/i18n/cs.ts b/src/i18n/cs.ts index 3df037b3..12e4b038 100644 --- a/src/i18n/cs.ts +++ b/src/i18n/cs.ts @@ -119,7 +119,7 @@ const cs = { "main.nav.search": "Vyhledávání", "main.nav.searchTerms": "Vyhledávání pojmů", "main.nav.searchVocabularies": "Vyhledávání slovníků", - "main.nav.facetedSearch": "Facetové vyhledávání", + "main.nav.facetedSearch": "Fasetové vyhledávání", "main.nav.admin": "Administrace", "main.nav.create-vocabulary": "Nový slovník", "main.nav.import-vocabulary": "Importovat slovník", @@ -130,7 +130,7 @@ const cs = { "main.search.count-info-and-link": "Zobrazeno {displayed} z {count} výsledků. Zobrazit všechny.", "main.search.no-results": - "Zadanému výrazu neodpovídá žádný výsledek. Kliknutím vyzkoušíte facetové hledání.", + "Zadanému výrazu neodpovídá žádný výsledek. Kliknutím vyzkoušíte fasetové hledání.", "main.lang-selector.tooltip": "Vyberte jazyk uživatelského rozhraní", "dashboard.widget.assetList.empty": @@ -635,7 +635,7 @@ const cs = { "search.tab.terms": "Pojmy", "search.tab.terms.filter.allVocabularies": "Všechny slovníky", "search.tab.vocabularies": "Slovníky", - "search.tab.facets": "Facetové vyhledávání pojmů", + "search.tab.facets": "Fasetové vyhledávání pojmů", "search.reset": "Vymazat vyhledávání", "search.results.title": "Výsledky vyhledávání „{searchString}“", "search.no-results": "Zadanému výrazu neodpovídá žádný výsledek.", @@ -645,7 +645,7 @@ const cs = { "search.results.table.label.tooltip": "Zobrazit detail objektu", "search.results.table.match": "Nalezená shoda", "search.results.table.score": "Skóre shody", - "search.results.field.badge.tooltip": "Shoda nalezena v tomto atributu", + "search.results.field": "Shoda nalezena v atributu:", "search.results.field.label": "Název", "search.results.field.comment": "Popis", "search.results.field.definition": "Definice", diff --git a/src/i18n/en.ts b/src/i18n/en.ts index e4b33ab6..70b9b485 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -635,7 +635,7 @@ const en = { "search.results.table.label.tooltip": "Open asset detail", "search.results.table.match": "Match", "search.results.table.score": "Match score", - "search.results.field.badge.tooltip": "Matched attribute", + "search.results.field": "Match found in attribute:", "search.results.field.label": "Label", "search.results.field.comment": "Comment", "search.results.field.definition": "Definition", diff --git a/src/util/Constants.ts b/src/util/Constants.ts index 3764ea2d..97d25075 100644 --- a/src/util/Constants.ts +++ b/src/util/Constants.ts @@ -118,6 +118,7 @@ const constants = { ANNOTATOR_TUTORIAL: {}, WORKSPACE_EDITABLE_CONTEXT_PARAM: "edit-context", TIMESTAMP_PARAM_FORMAT: "yyyyMMdd'T'HHmmss'Z'", + FTS_SNIPPET_TEXT_SIZE: 250, // Size of page fetched from server DEFAULT_PAGE_SIZE: 100, From d329deaa2f8d118c45c4d2c7f398d5c217c72533 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 21 Oct 2024 13:07:37 +0200 Subject: [PATCH 14/23] [Enhancement #544] Show info about field in which FTS match was found (vocabulary results). --- src/component/search/label/MatchInfo.tsx | 1 + src/component/search/label/VocabularyResultItem.tsx | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/component/search/label/MatchInfo.tsx b/src/component/search/label/MatchInfo.tsx index 4449f3d6..21f8962e 100644 --- a/src/component/search/label/MatchInfo.tsx +++ b/src/component/search/label/MatchInfo.tsx @@ -12,6 +12,7 @@ const FIELD_NAME_MAPPING = { prefLabel: "asset.label", altLabel: "term.metadata.altLabels.label", hiddenLabel: "term.metadata.hiddenLabels.label", + title: "asset.label", scopeNote: "term.metadata.comment", definition: "term.metadata.definition", description: "description", diff --git a/src/component/search/label/VocabularyResultItem.tsx b/src/component/search/label/VocabularyResultItem.tsx index d79bbd15..670e0e33 100644 --- a/src/component/search/label/VocabularyResultItem.tsx +++ b/src/component/search/label/VocabularyResultItem.tsx @@ -6,6 +6,7 @@ import VocabularyLink from "../../vocabulary/VocabularyLink"; import AssetFactory from "../../../util/AssetFactory"; import VocabularyBadge from "../../badge/VocabularyBadge"; import Constants from "../../../util/Constants"; +import MatchInfo from "./MatchInfo"; interface VocabularyResultItemProps { result: SearchResultItem; @@ -55,10 +56,10 @@ const VocabularyResultItem: React.FC = ({ vocabulary={AssetFactory.createAsset(result) as Vocabulary} />
-
- +
- +
+ ); }; From e98a767e5fac6f2227c567f76f339997d6fc81dd Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 21 Oct 2024 15:22:06 +0200 Subject: [PATCH 15/23] [Enhancement #536] Support search by examples in faceted search. --- src/component/search/facet/FacetedSearch.tsx | 37 ++++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/component/search/facet/FacetedSearch.tsx b/src/component/search/facet/FacetedSearch.tsx index a87eb96f..02b53734 100644 --- a/src/component/search/facet/FacetedSearch.tsx +++ b/src/component/search/facet/FacetedSearch.tsx @@ -36,6 +36,11 @@ INITIAL_STATE[VocabularyUtils.SKOS_NOTATION] = { value: [""], matchType: MatchType.EXACT_MATCH, }; +INITIAL_STATE[VocabularyUtils.SKOS_EXAMPLE] = { + property: VocabularyUtils.SKOS_EXAMPLE, + value: [""], + matchType: MatchType.SUBSTRING, +}; INITIAL_STATE[VocabularyUtils.RDF_TYPE] = { property: VocabularyUtils.RDF_TYPE, value: [], @@ -96,33 +101,43 @@ const FacetedSearch: React.FC = () => { - - - - + - + - + + + + + + + + + From 434f5da401e5e75500ea996fb655d65d46922f94 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 21 Oct 2024 15:25:24 +0200 Subject: [PATCH 16/23] [Enhancement #536] Update faceted search tests. --- .../search/facet/__tests__/FacetedSearch.test.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/component/search/facet/__tests__/FacetedSearch.test.tsx b/src/component/search/facet/__tests__/FacetedSearch.test.tsx index de676e67..83e464cc 100644 --- a/src/component/search/facet/__tests__/FacetedSearch.test.tsx +++ b/src/component/search/facet/__tests__/FacetedSearch.test.tsx @@ -46,7 +46,7 @@ describe("FacetedSearch", () => { matchType: MatchType.SUBSTRING, }; await act(async () => { - wrapper.find(TextFacet).prop("onChange")(firstNotationValue); + wrapper.find(TextFacet).at(0).prop("onChange")(firstNotationValue); }); wrapper.update(); act(() => { @@ -58,7 +58,7 @@ describe("FacetedSearch", () => { matchType: MatchType.SUBSTRING, }; await act(async () => { - wrapper.find(TextFacet).prop("onChange")(secondNotationValue); + wrapper.find(TextFacet).at(0).prop("onChange")(secondNotationValue); }); wrapper.update(); expect(wrapper.find(SimplePagination).prop("page")).toEqual(0); @@ -84,7 +84,7 @@ describe("FacetedSearch", () => { matchType: MatchType.SUBSTRING, }; await act(async () => { - wrapper.find(TextFacet).prop("onChange")(firstNotationValue); + wrapper.find(TextFacet).at(0).prop("onChange")(firstNotationValue); }); wrapper.update(); (SearchActions.executeFacetedTermSearch as jest.Mock).mockReset(); @@ -140,7 +140,7 @@ describe("FacetedSearch", () => { expect(wrapper.exists(FacetedSearchResults)).toBeFalsy(); expect(wrapper.exists(SimplePagination)).toBeFalsy(); await act(async () => { - wrapper.find(TextFacet).prop("onChange")(firstNotationValue); + wrapper.find(TextFacet).at(0).prop("onChange")(firstNotationValue); }); wrapper.update(); act(() => { @@ -155,7 +155,7 @@ describe("FacetedSearch", () => { matchType: MatchType.SUBSTRING, }; act(() => { - wrapper.find(TextFacet).prop("onChange")(secondNotationValue); + wrapper.find(TextFacet).at(0).prop("onChange")(secondNotationValue); }); await act(async () => { wrapper.update(); From bd1b22c7c8ade2522619b934cc728d8977e0e8e8 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 21 Oct 2024 16:53:30 +0200 Subject: [PATCH 17/23] [Enhancement #552] Implement text input debounce in faceted search. --- package-lock.json | 18 ++++++++ package.json | 1 + src/action/SearchActions.ts | 3 +- src/component/search/facet/FacetedSearch.tsx | 41 ++++++++++++------- .../facet/__tests__/FacetedSearch.test.tsx | 4 ++ src/util/Constants.ts | 2 + 6 files changed, 52 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index a6370641..7b63562a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,6 +63,7 @@ "redux-thunk": "^2.4.2", "resolve": "1.22.2", "simple-xpath-position": "^2.0.2", + "use-debounce": "^10.0.4", "uuid": "^10.0.0", "whatwg-fetch": "3.6.2", "whatwg-mimetype": "3.0.0" @@ -16895,6 +16896,17 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-debounce": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.4.tgz", + "integrity": "sha512-6Cf7Yr7Wk7Kdv77nnJMf6de4HuDE4dTxKij+RqE9rufDsI6zsbjyAxcH5y2ueJCQAnfgKbzXbZHYlkFwmBlWkw==", + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "react": "*" + } + }, "node_modules/use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", @@ -30116,6 +30128,12 @@ "requires-port": "^1.0.0" } }, + "use-debounce": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.4.tgz", + "integrity": "sha512-6Cf7Yr7Wk7Kdv77nnJMf6de4HuDE4dTxKij+RqE9rufDsI6zsbjyAxcH5y2ueJCQAnfgKbzXbZHYlkFwmBlWkw==", + "requires": {} + }, "use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", diff --git a/package.json b/package.json index 1137b308..20028869 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "redux-thunk": "^2.4.2", "resolve": "1.22.2", "simple-xpath-position": "^2.0.2", + "use-debounce": "^10.0.4", "uuid": "^10.0.0", "whatwg-fetch": "3.6.2", "whatwg-mimetype": "3.0.0" diff --git a/src/action/SearchActions.ts b/src/action/SearchActions.ts index ccd14ceb..ca661857 100644 --- a/src/action/SearchActions.ts +++ b/src/action/SearchActions.ts @@ -56,7 +56,6 @@ export function removeSearchListener() { * Timer to delay search requests as user is still typing. */ let updateSearchTimer: ReturnType | null = null; -const updateSearchDelay = 400; // ms /** * Change the search criteria and trigger a new search. @@ -85,7 +84,7 @@ export function updateSearchFilter(searchString: string) { updateSearchTimer = setTimeout(() => { updateSearchTimer = null; dispatch(searchEverything()); - }, updateSearchDelay); + }, Constants.SEARCH_DEBOUNCE_DELAY); return Promise.resolve(); } }; diff --git a/src/component/search/facet/FacetedSearch.tsx b/src/component/search/facet/FacetedSearch.tsx index 02b53734..fe6dfee9 100644 --- a/src/component/search/facet/FacetedSearch.tsx +++ b/src/component/search/facet/FacetedSearch.tsx @@ -19,6 +19,7 @@ import VocabularyFacet from "./VocabularyFacet"; import SimplePagination from "../../dashboard/widget/lastcommented/SimplePagination"; import Constants from "../../../util/Constants"; import TermStateFacet from "./TermStateFacet"; +import { useDebouncedCallback } from "use-debounce"; function aggregateSearchParams(params: { [key: string]: SearchParam }) { return Object.entries(params) @@ -62,19 +63,35 @@ const FacetedSearch: React.FC = () => { const dispatch: ThunkDispatch = useDispatch(); const [page, setPage] = useState(0); const [params, setParams] = useState(INITIAL_STATE); + const [results, setResults] = + React.useState(null); + const onChange = (value: SearchParam) => { const change = {}; change[value.property] = value; setParams({ ...params, ...change }); setPage(0); + if (value.matchType === MatchType.IRI || value.value[0].length === 0) { + runSearch({ ...params, ...change }, page); + } else { + debouncedSearch({ ...params, ...change }, page); + } + }; + const onPageChange = (page: number) => { + setPage(page); + runSearch(params, page); }; - const [results, setResults] = - React.useState(null); const runSearch = React.useCallback( - (params: SearchParam[]) => { + (params: {}, page: number) => { + const sp = aggregateSearchParams(params); + if (sp.length === 0) { + setPage(0); + setResults(null); + return; + } trackPromise( dispatch( - executeFacetedTermSearch(params, { + executeFacetedTermSearch(sp, { page, size: Constants.DEFAULT_PAGE_SIZE, }) @@ -82,17 +99,11 @@ const FacetedSearch: React.FC = () => { "faceted-search" ).then((res) => setResults(res)); }, - [page, dispatch, setResults] + [dispatch, setPage, setResults] ); - React.useEffect(() => { - const sp = aggregateSearchParams(params); - if (sp.length === 0) { - setPage(0); - setResults(null); - return; - } - runSearch(sp); - }, [params, runSearch]); + const debouncedSearch = useDebouncedCallback((params: {}, page: number) => { + runSearch(params, page); + }, Constants.SEARCH_DEBOUNCE_DELAY); return (