Compare commits

..

No commits in common. "90be3b5aa77c51b8109b3f25859627e17ae8a0aa" and "7792a82bf7216cbec214200c7c3d683b8011e508" have entirely different histories.

486 changed files with 6884 additions and 6658 deletions

View File

@ -620,8 +620,6 @@ def inline_synthesis(request: Request) -> HttpResponse:
receiver = m.RSForm(serializer.validated_data['receiver']) receiver = m.RSForm(serializer.validated_data['receiver'])
items = cast(list[m.Constituenta], serializer.validated_data['items']) items = cast(list[m.Constituenta], serializer.validated_data['items'])
if len(items) == 0:
items = list(m.RSForm(serializer.validated_data['source']).constituents().order_by('order'))
with transaction.atomic(): with transaction.atomic():
new_items = receiver.insert_copy(items) new_items = receiver.insert_copy(items)

View File

@ -11,11 +11,11 @@
"@dagrejs/dagre": "^1.1.4", "@dagrejs/dagre": "^1.1.4",
"@hookform/resolvers": "^3.10.0", "@hookform/resolvers": "^3.10.0",
"@lezer/lr": "^1.4.2", "@lezer/lr": "^1.4.2",
"@tanstack/react-query": "^5.66.0", "@tanstack/react-query": "^5.64.2",
"@tanstack/react-query-devtools": "^5.66.0", "@tanstack/react-query-devtools": "^5.64.2",
"@tanstack/react-table": "^8.20.6", "@tanstack/react-table": "^8.20.6",
"@uiw/codemirror-themes": "^4.23.8", "@uiw/codemirror-themes": "^4.23.7",
"@uiw/react-codemirror": "^4.23.8", "@uiw/react-codemirror": "^4.23.7",
"axios": "^1.7.9", "axios": "^1.7.9",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"html-to-image": "^1.11.11", "html-to-image": "^1.11.11",
@ -27,12 +27,12 @@
"react-hook-form": "^7.54.2", "react-hook-form": "^7.54.2",
"react-icons": "^5.4.0", "react-icons": "^5.4.0",
"react-intl": "^7.1.5", "react-intl": "^7.1.5",
"react-router": "^7.1.5", "react-router": "^7.1.3",
"react-select": "^5.10.0", "react-select": "^5.10.0",
"react-tabs": "^6.1.0", "react-tabs": "^6.1.0",
"react-toastify": "^11.0.3", "react-toastify": "^11.0.3",
"react-tooltip": "^5.28.0", "react-tooltip": "^5.28.0",
"react-zoom-pan-pinch": "^3.7.0", "react-zoom-pan-pinch": "^3.6.1",
"reactflow": "^11.11.4", "reactflow": "^11.11.4",
"use-debounce": "^10.0.4", "use-debounce": "^10.0.4",
"zod": "^3.24.1", "zod": "^3.24.1",
@ -40,9 +40,9 @@
}, },
"devDependencies": { "devDependencies": {
"@lezer/generator": "^1.7.2", "@lezer/generator": "^1.7.2",
"@playwright/test": "^1.50.1", "@playwright/test": "^1.50.0",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"@types/node": "^22.13.1", "@types/node": "^22.10.10",
"@types/react": "^19.0.8", "@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3", "@types/react-dom": "^19.0.3",
"@typescript-eslint/eslint-plugin": "^8.0.1", "@typescript-eslint/eslint-plugin": "^8.0.1",
@ -61,8 +61,8 @@
"tailwindcss": "^3.4.17", "tailwindcss": "^3.4.17",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
"typescript": "^5.7.3", "typescript": "^5.7.3",
"typescript-eslint": "^8.23.0", "typescript-eslint": "^8.21.0",
"vite": "^6.1.0" "vite": "^6.0.11"
} }
}, },
"node_modules/@alloc/quick-lru": { "node_modules/@alloc/quick-lru": {
@ -825,9 +825,9 @@
} }
}, },
"node_modules/@codemirror/state": { "node_modules/@codemirror/state": {
"version": "6.5.2", "version": "6.5.1",
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.1.tgz",
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", "integrity": "sha512-3rA9lcwciEB47ZevqvD8qgbzhM9qMb8vCcQCNmDfVRPQG4JT9mSb0Jg8H7YjKGGQcFnLN323fj9jdnG59Kx6bg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@marijn/find-cluster-break": "^1.0.0" "@marijn/find-cluster-break": "^1.0.0"
@ -1458,13 +1458,13 @@
} }
}, },
"node_modules/@eslint/config-array": { "node_modules/@eslint/config-array": {
"version": "0.19.2", "version": "0.19.1",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz",
"integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@eslint/object-schema": "^2.1.6", "@eslint/object-schema": "^2.1.5",
"debug": "^4.3.1", "debug": "^4.3.1",
"minimatch": "^3.1.2" "minimatch": "^3.1.2"
}, },
@ -1581,9 +1581,9 @@
} }
}, },
"node_modules/@eslint/object-schema": { "node_modules/@eslint/object-schema": {
"version": "2.1.6", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz",
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
@ -2430,13 +2430,13 @@
} }
}, },
"node_modules/@playwright/test": { "node_modules/@playwright/test": {
"version": "1.50.1", "version": "1.50.0",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.50.1.tgz", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.50.0.tgz",
"integrity": "sha512-Jii3aBg+CEDpgnuDxEp/h7BimHcUTDlpEtce89xEumlJ5ef2hqepZ+PWp1DDpYC/VO9fmWVI1IlEaoI5fK9FXQ==", "integrity": "sha512-ZGNXbt+d65EGjBORQHuYKj+XhCewlwpnSd/EDuLPZGSiEWmgOJB5RmMCCYGy5aMfTs9wx61RivfDKi8H/hcMvw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"playwright": "1.50.1" "playwright": "1.50.0"
}, },
"bin": { "bin": {
"playwright": "cli.js" "playwright": "cli.js"
@ -2716,9 +2716,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.0.tgz",
"integrity": "sha512-gGi5adZWvjtJU7Axs//CWaQbQd/vGy8KGcnEaCWiyCqxWYDxwIlAHFuSe6Guoxtd0SRvSfVTDMPd5H+4KE2kKA==", "integrity": "sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2730,9 +2730,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.0.tgz",
"integrity": "sha512-1aRlh1gqtF7vNPMnlf1vJKk72Yshw5zknR/ZAVh7zycRAGF2XBMVDAHmFQz/Zws5k++nux3LOq/Ejj1WrDR6xg==", "integrity": "sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2744,9 +2744,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.0.tgz",
"integrity": "sha512-drHl+4qhFj+PV/jrQ78p9ch6A0MfNVZScl/nBps5a7u01aGf/GuBRrHnRegA9bP222CBDfjYbFdjkIJ/FurvSQ==", "integrity": "sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2758,9 +2758,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.0.tgz",
"integrity": "sha512-hQqq/8QALU6t1+fbNmm6dwYsa0PDD4L5r3TpHx9dNl+aSEMnIksHZkSO3AVH+hBMvZhpumIGrTFj8XCOGuIXjw==", "integrity": "sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2772,9 +2772,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.0.tgz",
"integrity": "sha512-/L0LixBmbefkec1JTeAQJP0ETzGjFtNml2gpQXA8rpLo7Md+iXQzo9kwEgzyat5Q+OG/C//2B9Fx52UxsOXbzw==", "integrity": "sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2786,9 +2786,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.0.tgz",
"integrity": "sha512-6Rk3PLRK+b8L/M6m/x6Mfj60LhAUcLJ34oPaxufA+CfqkUrDoUPQYFdRrhqyOvtOKXLJZJwxlOLbQjNYQcRQfw==", "integrity": "sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2800,9 +2800,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.0.tgz",
"integrity": "sha512-kmT3x0IPRuXY/tNoABp2nDvI9EvdiS2JZsd4I9yOcLCCViKsP0gB38mVHOhluzx+SSVnM1KNn9k6osyXZhLoCA==", "integrity": "sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2814,9 +2814,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.0.tgz",
"integrity": "sha512-3iSA9tx+4PZcJH/Wnwsvx/BY4qHpit/u2YoZoXugWVfc36/4mRkgGEoRbRV7nzNBSCOgbWMeuQ27IQWgJ7tRzw==", "integrity": "sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -2828,9 +2828,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.0.tgz",
"integrity": "sha512-7CwSJW+sEhM9sESEk+pEREF2JL0BmyCro8UyTq0Kyh0nu1v0QPNY3yfLPFKChzVoUmaKj8zbdgBxUhBRR+xGxg==", "integrity": "sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2842,9 +2842,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.0.tgz",
"integrity": "sha512-GZdafB41/4s12j8Ss2izofjeFXRAAM7sHCb+S4JsI9vaONX/zQ8cXd87B9MRU/igGAJkKvmFmJJBeeT9jJ5Cbw==", "integrity": "sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2856,9 +2856,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loongarch64-gnu": { "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.0.tgz",
"integrity": "sha512-uuphLuw1X6ur11675c2twC6YxbzyLSpWggvdawTUamlsoUv81aAXRMPBC1uvQllnBGls0Qt5Siw8reSIBnbdqQ==", "integrity": "sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@ -2870,9 +2870,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.0.tgz",
"integrity": "sha512-KvLEw1os2gSmD6k6QPCQMm2T9P2GYvsMZMRpMz78QpSoEevHbV/KOUbI/46/JRalhtSAYZBYLAnT9YE4i/l4vg==", "integrity": "sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -2884,9 +2884,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.0.tgz",
"integrity": "sha512-wcpCLHGM9yv+3Dql/CI4zrY2mpQ4WFergD3c9cpRowltEh5I84pRT/EuHZsG0In4eBPPYthXnuR++HrFkeqwkA==", "integrity": "sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -2898,9 +2898,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.0.tgz",
"integrity": "sha512-nLbfQp2lbJYU8obhRQusXKbuiqm4jSJteLwfjnunDT5ugBKdxqw1X9KWwk8xp1OMC6P5d0WbzxzhWoznuVK6XA==", "integrity": "sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -2912,9 +2912,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.0.tgz",
"integrity": "sha512-JGejzEfVzqc/XNiCKZj14eb6s5w8DdWlnQ5tWUbs99kkdvfq9btxxVX97AaxiUX7xJTKFA0LwoS0KU8C2faZRg==", "integrity": "sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2926,9 +2926,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.0.tgz",
"integrity": "sha512-/iFIbhzeyZZy49ozAWJ1ZR2KW6ZdYUbQXLT4O5n1cRZRoTpwExnHLjlurDXXPKEGxiAg0ujaR9JDYKljpr2fDg==", "integrity": "sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2940,9 +2940,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.0.tgz",
"integrity": "sha512-qORc3UzoD5UUTneiP2Afg5n5Ti1GAW9Gp5vHPxzvAFFA3FBaum9WqGvYXGf+c7beFdOKNos31/41PRMUwh1tpA==", "integrity": "sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -2954,9 +2954,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.0.tgz",
"integrity": "sha512-5g7E2PHNK2uvoD5bASBD9aelm44nf1w4I5FEI7MPHLWcCSrR8JragXZWgKPXk5i2FU3JFfa6CGZLw2RrGBHs2Q==", "integrity": "sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -2968,9 +2968,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.4.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.0.tgz",
"integrity": "sha512-p0scwGkR4kZ242xLPBuhSckrJ734frz6v9xZzD+kHVYRAkSUmdSLCIJRfql6H5//aF8Q10K+i7q8DiPfZp0b7A==", "integrity": "sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -3009,9 +3009,9 @@
} }
}, },
"node_modules/@tanstack/query-core": { "node_modules/@tanstack/query-core": {
"version": "5.66.0", "version": "5.64.2",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.0.tgz", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.64.2.tgz",
"integrity": "sha512-J+JeBtthiKxrpzUu7rfIPDzhscXF2p5zE/hVdrqkACBP8Yu0M96mwJ5m/8cPPYQE9aRNvXztXHlNwIh4FEeMZw==", "integrity": "sha512-hdO8SZpWXoADNTWXV9We8CwTkXU88OVWRBcsiFrk7xJQnhm6WRlweDzMD+uH+GnuieTBVSML6xFa17C2cNV8+g==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"type": "github", "type": "github",
@ -3019,9 +3019,9 @@
} }
}, },
"node_modules/@tanstack/query-devtools": { "node_modules/@tanstack/query-devtools": {
"version": "5.65.0", "version": "5.64.2",
"resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.65.0.tgz", "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.64.2.tgz",
"integrity": "sha512-g5y7zc07U9D3esMdqUfTEVu9kMHoIaVBsD0+M3LPdAdD710RpTcLiNvJY1JkYXqkq9+NV+CQoemVNpQPBXVsJg==", "integrity": "sha512-3DautR5UpVZdk/qNIhioZVF7g8fdQZ1U98sBEEk4Tzz3tihSBNMPgwlP40nzgbPEDBIrn/j/oyyvNBVSo083Vw==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"type": "github", "type": "github",
@ -3029,12 +3029,12 @@
} }
}, },
"node_modules/@tanstack/react-query": { "node_modules/@tanstack/react-query": {
"version": "5.66.0", "version": "5.64.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.66.0.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.64.2.tgz",
"integrity": "sha512-z3sYixFQJe8hndFnXgWu7C79ctL+pI0KAelYyW+khaNJ1m22lWrhJU2QrsTcRKMuVPtoZvfBYrTStIdKo+x0Xw==", "integrity": "sha512-3pakNscZNm8KJkxmovvtZ4RaXLyiYYobwleTMvpIGUoKRa8j8VlrQKNl5W8VUEfVfZKkikvXVddLuWMbcSCA1Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@tanstack/query-core": "5.66.0" "@tanstack/query-core": "5.64.2"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
@ -3045,19 +3045,19 @@
} }
}, },
"node_modules/@tanstack/react-query-devtools": { "node_modules/@tanstack/react-query-devtools": {
"version": "5.66.0", "version": "5.64.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.66.0.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.64.2.tgz",
"integrity": "sha512-uB57wA2YZaQ2fPcFW0E9O1zAGDGSbRKRx84uMk/86VyU9jWVxvJ3Uzp+zNm+nZJYsuekCIo2opTdgNuvM3cKgA==", "integrity": "sha512-+ZjJVnPzc8BUV/Eklu2k9T/IAyAyvwoCHqOaOrk2sbU33LFhM52BpX4eyENXn0bx5LwV3DJZgEQlIzucoemfGQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@tanstack/query-devtools": "5.65.0" "@tanstack/query-devtools": "5.64.2"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
"url": "https://github.com/sponsors/tannerlinsley" "url": "https://github.com/sponsors/tannerlinsley"
}, },
"peerDependencies": { "peerDependencies": {
"@tanstack/react-query": "^5.66.0", "@tanstack/react-query": "^5.64.2",
"react": "^18 || ^19" "react": "^18 || ^19"
} }
}, },
@ -3308,9 +3308,9 @@
} }
}, },
"node_modules/@types/d3-path": { "node_modules/@types/d3-path": {
"version": "3.1.1", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz",
"integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/d3-polygon": { "node_modules/@types/d3-polygon": {
@ -3332,9 +3332,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/d3-scale": { "node_modules/@types/d3-scale": {
"version": "4.0.9", "version": "4.0.8",
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
"integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/d3-time": "*" "@types/d3-time": "*"
@ -3477,9 +3477,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.13.1", "version": "22.10.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.10.tgz",
"integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", "integrity": "sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -3545,21 +3545,21 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.21.0.tgz",
"integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==", "integrity": "sha512-eTH+UOR4I7WbdQnG4Z48ebIA6Bgi7WO8HvFEneeYBxG8qCOYgTOFPSg6ek9ITIDvGjDQzWHcoWHCDO2biByNzA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.10.0", "@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/scope-manager": "8.21.0",
"@typescript-eslint/type-utils": "8.23.0", "@typescript-eslint/type-utils": "8.21.0",
"@typescript-eslint/utils": "8.23.0", "@typescript-eslint/utils": "8.21.0",
"@typescript-eslint/visitor-keys": "8.23.0", "@typescript-eslint/visitor-keys": "8.21.0",
"graphemer": "^1.4.0", "graphemer": "^1.4.0",
"ignore": "^5.3.1", "ignore": "^5.3.1",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
"ts-api-utils": "^2.0.1" "ts-api-utils": "^2.0.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3575,16 +3575,16 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.21.0.tgz",
"integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==", "integrity": "sha512-Wy+/sdEH9kI3w9civgACwabHbKl+qIOu0uFZ9IMKzX3Jpv9og0ZBJrZExGrPpFAY7rWsXuxs5e7CPPP17A4eYA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/scope-manager": "8.21.0",
"@typescript-eslint/types": "8.23.0", "@typescript-eslint/types": "8.21.0",
"@typescript-eslint/typescript-estree": "8.23.0", "@typescript-eslint/typescript-estree": "8.21.0",
"@typescript-eslint/visitor-keys": "8.23.0", "@typescript-eslint/visitor-keys": "8.21.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -3600,14 +3600,14 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.21.0.tgz",
"integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==", "integrity": "sha512-G3IBKz0/0IPfdeGRMbp+4rbjfSSdnGkXsM/pFZA8zM9t9klXDnB/YnKOBQ0GoPmoROa4bCq2NeHgJa5ydsQ4mA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.23.0", "@typescript-eslint/types": "8.21.0",
"@typescript-eslint/visitor-keys": "8.23.0" "@typescript-eslint/visitor-keys": "8.21.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3618,16 +3618,16 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.21.0.tgz",
"integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==", "integrity": "sha512-95OsL6J2BtzoBxHicoXHxgk3z+9P3BEcQTpBKriqiYzLKnM2DeSqs+sndMKdamU8FosiadQFT3D+BSL9EKnAJQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.23.0", "@typescript-eslint/typescript-estree": "8.21.0",
"@typescript-eslint/utils": "8.23.0", "@typescript-eslint/utils": "8.21.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^2.0.1" "ts-api-utils": "^2.0.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3642,9 +3642,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.21.0.tgz",
"integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", "integrity": "sha512-PAL6LUuQwotLW2a8VsySDBwYMm129vFm4tMVlylzdoTybTHaAi0oBp7Ac6LhSrHHOdLM3efH+nAR6hAWoMF89A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -3656,20 +3656,20 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.21.0.tgz",
"integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", "integrity": "sha512-x+aeKh/AjAArSauz0GiQZsjT8ciadNMHdkUSwBB9Z6PrKc/4knM4g3UfHml6oDJmKC88a6//cdxnO/+P2LkMcg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.23.0", "@typescript-eslint/types": "8.21.0",
"@typescript-eslint/visitor-keys": "8.23.0", "@typescript-eslint/visitor-keys": "8.21.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
"minimatch": "^9.0.4", "minimatch": "^9.0.4",
"semver": "^7.6.0", "semver": "^7.6.0",
"ts-api-utils": "^2.0.1" "ts-api-utils": "^2.0.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3683,16 +3683,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.21.0.tgz",
"integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==", "integrity": "sha512-xcXBfcq0Kaxgj7dwejMbFyq7IOHgpNMtVuDveK7w3ZGwG9owKzhALVwKpTF2yrZmEwl9SWdetf3fxNzJQaVuxw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/scope-manager": "8.21.0",
"@typescript-eslint/types": "8.23.0", "@typescript-eslint/types": "8.21.0",
"@typescript-eslint/typescript-estree": "8.23.0" "@typescript-eslint/typescript-estree": "8.21.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -3707,13 +3707,13 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.21.0.tgz",
"integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", "integrity": "sha512-BkLMNpdV6prozk8LlyK/SOoWLmUFi+ZD+pcqti9ILCbVvHGk1ui1g4jJOc2WDLaeExz2qWwojxlPce5PljcT3w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.23.0", "@typescript-eslint/types": "8.21.0",
"eslint-visitor-keys": "^4.2.0" "eslint-visitor-keys": "^4.2.0"
}, },
"engines": { "engines": {
@ -3738,9 +3738,9 @@
} }
}, },
"node_modules/@uiw/codemirror-extensions-basic-setup": { "node_modules/@uiw/codemirror-extensions-basic-setup": {
"version": "4.23.8", "version": "4.23.7",
"resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.8.tgz", "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.7.tgz",
"integrity": "sha512-XJR/8AEVcE7ufy1BhW2nCN9qSVDYEdCtYLfvhaMwl6Q3qcaYYCGE2K5QbFCy7LsdP/3uZKvc1OskuqatoOPdhQ==", "integrity": "sha512-9/2EUa1Lck4kFKkR2BkxlZPpgD/EWuKHnOlysf1yHKZGraaZmZEaUw+utDK4QcuJc8Iz097vsLz4f4th5EU27g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@codemirror/autocomplete": "^6.0.0", "@codemirror/autocomplete": "^6.0.0",
@ -3765,9 +3765,9 @@
} }
}, },
"node_modules/@uiw/codemirror-themes": { "node_modules/@uiw/codemirror-themes": {
"version": "4.23.8", "version": "4.23.7",
"resolved": "https://registry.npmjs.org/@uiw/codemirror-themes/-/codemirror-themes-4.23.8.tgz", "resolved": "https://registry.npmjs.org/@uiw/codemirror-themes/-/codemirror-themes-4.23.7.tgz",
"integrity": "sha512-PZmJBZxWMuZ48p/2D5aRPl8zTlBq1d/+NeRqyyH6P6k6yWDF6h71m0Dt+fjslgPE7KmWXux2hbejXXXoRLZO9Q==", "integrity": "sha512-UNf1XOx1hG9OmJnrtT86PxKcdcwhaNhbrcD+nsk8WxRJ3n5c8nH6euDvgVPdVLPwbizsaQcZTILACgA/FjRpVg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@codemirror/language": "^6.0.0", "@codemirror/language": "^6.0.0",
@ -3784,16 +3784,16 @@
} }
}, },
"node_modules/@uiw/react-codemirror": { "node_modules/@uiw/react-codemirror": {
"version": "4.23.8", "version": "4.23.7",
"resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.8.tgz", "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.7.tgz",
"integrity": "sha512-/NA5Pj4MmXkLSlmlUm4yfEmRLntrNq5TkQKBSINn7TukXQ4fc+C6Bk0U60Qa4rkvCSgwzZdQ2exyP0t0+2GtqA==", "integrity": "sha512-Nh/0P6W+kWta+ARp9YpnKPD9ick5teEnwmtNoPQnyd6NPv0EQP3Ui4YmRVNj1nkUEo+QjrAUaEfcejJ2up/HZA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.18.6", "@babel/runtime": "^7.18.6",
"@codemirror/commands": "^6.1.0", "@codemirror/commands": "^6.1.0",
"@codemirror/state": "^6.1.1", "@codemirror/state": "^6.1.1",
"@codemirror/theme-one-dark": "^6.0.0", "@codemirror/theme-one-dark": "^6.0.0",
"@uiw/codemirror-extensions-basic-setup": "4.23.8", "@uiw/codemirror-extensions-basic-setup": "4.23.7",
"codemirror": "^6.0.0" "codemirror": "^6.0.0"
}, },
"funding": { "funding": {
@ -4288,9 +4288,9 @@
} }
}, },
"node_modules/babel-plugin-react-compiler": { "node_modules/babel-plugin-react-compiler": {
"version": "19.0.0-beta-714736e-20250131", "version": "19.0.0-beta-e552027-20250112",
"resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-19.0.0-beta-714736e-20250131.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-19.0.0-beta-e552027-20250112.tgz",
"integrity": "sha512-frj2l6fRWVi26iw9WthFKyFyE4u5ZSHH3KdKiscOOwpz210seTtwnp0QbJmi8Zoa5HK7Fk2fH40JffN2y8GvLg==", "integrity": "sha512-pUTT0mAZ4XLewC6bvqVeX015nVRLVultcSQlkzGdC10G6YV6K2h4E7cwGlLAuLKWTj3Z08mTO9uTnPP/opUBsg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -4527,9 +4527,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001697", "version": "1.0.30001695",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001695.tgz",
"integrity": "sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==", "integrity": "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -4629,9 +4629,9 @@
} }
}, },
"node_modules/cjs-module-lexer": { "node_modules/cjs-module-lexer": {
"version": "1.4.3", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz",
"integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -5211,9 +5211,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.93", "version": "1.5.88",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.93.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.88.tgz",
"integrity": "sha512-M+29jTcfNNoR9NV7la4SwUqzWAxEwnc7ThA5e1m6LRSotmpfpCpLcIfgtSCVL+MllNLgAyM/5ru86iMRemPzDQ==", "integrity": "sha512-K3C2qf1o+bGzbilTDCTBhTQcMS9KW60yTAaTeeXsfvQuTDDwlokLam/AdqlqcSy9u4UainDgsHV23ksXAOgamw==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
@ -5574,9 +5574,9 @@
} }
}, },
"node_modules/eslint-plugin-react-compiler": { "node_modules/eslint-plugin-react-compiler": {
"version": "19.0.0-beta-714736e-20250131", "version": "19.0.0-beta-e552027-20250112",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-compiler/-/eslint-plugin-react-compiler-19.0.0-beta-714736e-20250131.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-react-compiler/-/eslint-plugin-react-compiler-19.0.0-beta-e552027-20250112.tgz",
"integrity": "sha512-iTPUaHzvBejGqicSwZLCDBgWBxLzU1Dvqjs31loNoOPRnsey5dcOupaZajECKVvXmB1wcbIWNp6/VR5+dM9d6w==", "integrity": "sha512-VjkIXHouCYyJHgk5HmZ1LH+fAK5CX+ULRX9iNYtwYJ+ljbivFhIT+JJyxNT/USQpCeS2Dt5ahjFeeMv0RRwTww==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5911,9 +5911,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/fastq": { "node_modules/fastq": {
"version": "1.19.0", "version": "1.18.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz",
"integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
@ -6554,9 +6554,9 @@
} }
}, },
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "3.3.1", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"parent-module": "^1.0.0", "parent-module": "^1.0.0",
@ -6719,13 +6719,13 @@
} }
}, },
"node_modules/is-boolean-object": { "node_modules/is-boolean-object": {
"version": "1.2.2", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
"integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bound": "^1.0.3", "call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2" "has-tostringtag": "^1.0.2"
}, },
"engines": { "engines": {
@ -7042,13 +7042,13 @@
} }
}, },
"node_modules/is-weakref": { "node_modules/is-weakref": {
"version": "1.1.1", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
"integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bound": "^1.0.3" "call-bound": "^1.0.2"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -8306,9 +8306,9 @@
} }
}, },
"node_modules/object-inspect": { "node_modules/object-inspect": {
"version": "1.13.4", "version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -8721,13 +8721,13 @@
} }
}, },
"node_modules/playwright": { "node_modules/playwright": {
"version": "1.50.1", "version": "1.50.0",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.1.tgz", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.0.tgz",
"integrity": "sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==", "integrity": "sha512-+GinGfGTrd2IfX1TA4N2gNmeIksSb+IAe589ZH+FlmpV3MYTx6+buChGIuDLQwrGNCw2lWibqV50fU510N7S+w==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"playwright-core": "1.50.1" "playwright-core": "1.50.0"
}, },
"bin": { "bin": {
"playwright": "cli.js" "playwright": "cli.js"
@ -8740,9 +8740,9 @@
} }
}, },
"node_modules/playwright-core": { "node_modules/playwright-core": {
"version": "1.50.1", "version": "1.50.0",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.1.tgz", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.0.tgz",
"integrity": "sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==", "integrity": "sha512-CXkSSlr4JaZs2tZHI40DsZUN/NIwgaUPsyLuOAaIZp2CyF2sN5MM5NJsyB188lFSSozFxQ5fPT4qM+f0tH/6wQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
@ -9181,9 +9181,9 @@
} }
}, },
"node_modules/react-router": { "node_modules/react-router": {
"version": "7.1.5", "version": "7.1.3",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.3.tgz",
"integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==", "integrity": "sha512-EezYymLY6Guk/zLQ2vRA8WvdUhWFEj5fcE3RfWihhxXBW7+cd1LsIiA3lmx+KCmneAGQuyBv820o44L2+TtkSA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/cookie": "^0.6.0", "@types/cookie": "^0.6.0",
@ -9282,9 +9282,9 @@
} }
}, },
"node_modules/react-zoom-pan-pinch": { "node_modules/react-zoom-pan-pinch": {
"version": "3.7.0", "version": "3.6.1",
"resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.7.0.tgz", "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.6.1.tgz",
"integrity": "sha512-UmReVZ0TxlKzxSbYiAj+LeGRW8s8LraAFTXRAxzMYnNRgGPsxCudwZKVkjvGmjtx7SW/hZamt69NUmGf4xrkXA==", "integrity": "sha512-SdPqdk7QDSV7u/WulkFOi+cnza8rEZ0XX4ZpeH7vx3UZEg7DoyuAy3MCmm+BWv/idPQL2Oe73VoC0EhfCN+sZQ==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=8", "node": ">=8",
@ -9468,9 +9468,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.34.4", "version": "4.32.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.4.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.0.tgz",
"integrity": "sha512-spF66xoyD7rz3o08sHP7wogp1gZ6itSq22SGa/IZTcUDXDlOyrShwMwkVSB+BUxFRZZCUYqdb3KWDEOMVQZxuw==", "integrity": "sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -9484,25 +9484,25 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.34.4", "@rollup/rollup-android-arm-eabi": "4.32.0",
"@rollup/rollup-android-arm64": "4.34.4", "@rollup/rollup-android-arm64": "4.32.0",
"@rollup/rollup-darwin-arm64": "4.34.4", "@rollup/rollup-darwin-arm64": "4.32.0",
"@rollup/rollup-darwin-x64": "4.34.4", "@rollup/rollup-darwin-x64": "4.32.0",
"@rollup/rollup-freebsd-arm64": "4.34.4", "@rollup/rollup-freebsd-arm64": "4.32.0",
"@rollup/rollup-freebsd-x64": "4.34.4", "@rollup/rollup-freebsd-x64": "4.32.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.34.4", "@rollup/rollup-linux-arm-gnueabihf": "4.32.0",
"@rollup/rollup-linux-arm-musleabihf": "4.34.4", "@rollup/rollup-linux-arm-musleabihf": "4.32.0",
"@rollup/rollup-linux-arm64-gnu": "4.34.4", "@rollup/rollup-linux-arm64-gnu": "4.32.0",
"@rollup/rollup-linux-arm64-musl": "4.34.4", "@rollup/rollup-linux-arm64-musl": "4.32.0",
"@rollup/rollup-linux-loongarch64-gnu": "4.34.4", "@rollup/rollup-linux-loongarch64-gnu": "4.32.0",
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.4", "@rollup/rollup-linux-powerpc64le-gnu": "4.32.0",
"@rollup/rollup-linux-riscv64-gnu": "4.34.4", "@rollup/rollup-linux-riscv64-gnu": "4.32.0",
"@rollup/rollup-linux-s390x-gnu": "4.34.4", "@rollup/rollup-linux-s390x-gnu": "4.32.0",
"@rollup/rollup-linux-x64-gnu": "4.34.4", "@rollup/rollup-linux-x64-gnu": "4.32.0",
"@rollup/rollup-linux-x64-musl": "4.34.4", "@rollup/rollup-linux-x64-musl": "4.32.0",
"@rollup/rollup-win32-arm64-msvc": "4.34.4", "@rollup/rollup-win32-arm64-msvc": "4.32.0",
"@rollup/rollup-win32-ia32-msvc": "4.34.4", "@rollup/rollup-win32-ia32-msvc": "4.32.0",
"@rollup/rollup-win32-x64-msvc": "4.34.4", "@rollup/rollup-win32-x64-msvc": "4.32.0",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
@ -9592,9 +9592,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/semver": { "node_modules/semver": {
"version": "7.7.1", "version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"bin": { "bin": {
@ -10269,9 +10269,9 @@
} }
}, },
"node_modules/ts-api-utils": { "node_modules/ts-api-utils": {
"version": "2.0.1", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz",
"integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -10478,15 +10478,15 @@
} }
}, },
"node_modules/typescript-eslint": { "node_modules/typescript-eslint": {
"version": "8.23.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.23.0.tgz", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.21.0.tgz",
"integrity": "sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ==", "integrity": "sha512-txEKYY4XMKwPXxNkN8+AxAdX6iIJAPiJbHE/FpQccs/sxw8Lf26kqwC3cn0xkHlW8kEbLhkhCsjWuMveaY9Rxw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/eslint-plugin": "8.23.0", "@typescript-eslint/eslint-plugin": "8.21.0",
"@typescript-eslint/parser": "8.23.0", "@typescript-eslint/parser": "8.21.0",
"@typescript-eslint/utils": "8.23.0" "@typescript-eslint/utils": "8.21.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -10625,15 +10625,15 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "6.1.0", "version": "6.0.11",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz",
"integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==", "integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"esbuild": "^0.24.2", "esbuild": "^0.24.2",
"postcss": "^8.5.1", "postcss": "^8.4.49",
"rollup": "^4.30.1" "rollup": "^4.23.0"
}, },
"bin": { "bin": {
"vite": "bin/vite.js" "vite": "bin/vite.js"

View File

@ -15,11 +15,11 @@
"@dagrejs/dagre": "^1.1.4", "@dagrejs/dagre": "^1.1.4",
"@hookform/resolvers": "^3.10.0", "@hookform/resolvers": "^3.10.0",
"@lezer/lr": "^1.4.2", "@lezer/lr": "^1.4.2",
"@tanstack/react-query": "^5.66.0", "@tanstack/react-query": "^5.64.2",
"@tanstack/react-query-devtools": "^5.66.0", "@tanstack/react-query-devtools": "^5.64.2",
"@tanstack/react-table": "^8.20.6", "@tanstack/react-table": "^8.20.6",
"@uiw/codemirror-themes": "^4.23.8", "@uiw/codemirror-themes": "^4.23.7",
"@uiw/react-codemirror": "^4.23.8", "@uiw/react-codemirror": "^4.23.7",
"axios": "^1.7.9", "axios": "^1.7.9",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"html-to-image": "^1.11.11", "html-to-image": "^1.11.11",
@ -31,12 +31,12 @@
"react-hook-form": "^7.54.2", "react-hook-form": "^7.54.2",
"react-icons": "^5.4.0", "react-icons": "^5.4.0",
"react-intl": "^7.1.5", "react-intl": "^7.1.5",
"react-router": "^7.1.5", "react-router": "^7.1.3",
"react-select": "^5.10.0", "react-select": "^5.10.0",
"react-tabs": "^6.1.0", "react-tabs": "^6.1.0",
"react-toastify": "^11.0.3", "react-toastify": "^11.0.3",
"react-tooltip": "^5.28.0", "react-tooltip": "^5.28.0",
"react-zoom-pan-pinch": "^3.7.0", "react-zoom-pan-pinch": "^3.6.1",
"reactflow": "^11.11.4", "reactflow": "^11.11.4",
"use-debounce": "^10.0.4", "use-debounce": "^10.0.4",
"zod": "^3.24.1", "zod": "^3.24.1",
@ -44,9 +44,9 @@
}, },
"devDependencies": { "devDependencies": {
"@lezer/generator": "^1.7.2", "@lezer/generator": "^1.7.2",
"@playwright/test": "^1.50.1", "@playwright/test": "^1.50.0",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"@types/node": "^22.13.1", "@types/node": "^22.10.10",
"@types/react": "^19.0.8", "@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3", "@types/react-dom": "^19.0.3",
"@typescript-eslint/eslint-plugin": "^8.0.1", "@typescript-eslint/eslint-plugin": "^8.0.1",
@ -65,8 +65,8 @@
"tailwindcss": "^3.4.17", "tailwindcss": "^3.4.17",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
"typescript": "^5.7.3", "typescript": "^5.7.3",
"typescript-eslint": "^8.23.0", "typescript-eslint": "^8.21.0",
"vite": "^6.1.0" "vite": "^6.0.11"
}, },
"overrides": { "overrides": {
"react": "^19.0.0" "react": "^19.0.0"

View File

@ -1,16 +1,16 @@
import { Suspense } from 'react'; import { Suspense } from 'react';
import { Outlet } from 'react-router'; import { Outlet } from 'react-router';
import { Loader } from '@/components/Loader'; import ConceptToaster from '@/app/ConceptToaster';
import { ModalLoader } from '@/components/Modal'; import Footer from '@/app/Footer';
import Navigation from '@/app/Navigation';
import Loader from '@/components/ui/Loader';
import ModalLoader from '@/components/ui/ModalLoader';
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/appLayout'; import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/appLayout';
import { globals } from '@/utils/constants'; import { globals } from '@/utils/constants';
import { Footer } from './Footer';
import { GlobalDialogs } from './GlobalDialogs'; import { GlobalDialogs } from './GlobalDialogs';
import ConceptToaster from './GlobalToaster';
import { GlobalTooltips } from './GlobalTooltips'; import { GlobalTooltips } from './GlobalTooltips';
import { Navigation } from './Navigation';
import { NavigationState } from './Navigation/NavigationContext'; import { NavigationState } from './Navigation/NavigationContext';
function ApplicationLayout() { function ApplicationLayout() {

View File

@ -6,6 +6,7 @@ interface ToasterThemedProps extends Omit<ToastContainerProps, 'theme'> {}
function ToasterThemed(props: ToasterThemedProps) { function ToasterThemed(props: ToasterThemedProps) {
const darkMode = usePreferencesStore(state => state.darkMode); const darkMode = usePreferencesStore(state => state.darkMode);
return <ToastContainer theme={darkMode ? 'dark' : 'light'} {...props} />; return <ToastContainer theme={darkMode ? 'dark' : 'light'} {...props} />;
} }

View File

@ -1,9 +1,9 @@
import { useNavigate, useRouteError } from 'react-router'; import { useNavigate, useRouteError } from 'react-router';
import { Button } from '@/components/Control'; import InfoError from '@/components/info/InfoError';
import { InfoError } from '@/components/InfoError'; import Button from '@/components/ui/Button';
export function ErrorFallback() { function ErrorFallback() {
const error = useRouteError(); const error = useRouteError();
const router = useNavigate(); const router = useNavigate();
@ -18,3 +18,5 @@ export function ErrorFallback() {
</div> </div>
); );
} }
export default ErrorFallback;

View File

@ -1,9 +1,9 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { TextURL } from '@/components/Control'; import TextURL from '@/components/ui/TextURL';
import { external_urls } from '@/utils/constants'; import { external_urls } from '@/utils/constants';
export function Footer() { function Footer() {
return ( return (
<footer <footer
className={clsx( className={clsx(
@ -25,3 +25,5 @@ export function Footer() {
</footer> </footer>
); );
} }
export default Footer;

View File

@ -2,31 +2,32 @@
import React from 'react'; import React from 'react';
import { DialogType, useDialogsStore } from '@/stores/dialogs'; import { DialogType } from '@/models/miscellaneous';
import { useDialogsStore } from '@/stores/dialogs';
const DlgChangeInputSchema = React.lazy(() => import('@/features/oss/dialogs/DlgChangeInputSchema')); const DlgChangeInputSchema = React.lazy(() => import('@/dialogs/DlgChangeInputSchema'));
const DlgChangeLocation = React.lazy(() => import('@/features/library/dialogs/DlgChangeLocation')); const DlgChangeLocation = React.lazy(() => import('@/dialogs/DlgChangeLocation'));
const DlgCloneLibraryItem = React.lazy(() => import('@/features/rsform/dialogs/DlgCloneLibraryItem')); const DlgCloneLibraryItem = React.lazy(() => import('@/dialogs/DlgCloneLibraryItem'));
const DlgCreateCst = React.lazy(() => import('@/features/rsform/dialogs/DlgCreateCst')); const DlgCreateCst = React.lazy(() => import('@/dialogs/DlgCreateCst'));
const DlgCreateOperation = React.lazy(() => import('@/features/oss/dialogs/DlgCreateOperation')); const DlgCreateOperation = React.lazy(() => import('@/dialogs/DlgCreateOperation'));
const DlgCreateVersion = React.lazy(() => import('@/features/rsform/dialogs/DlgCreateVersion')); const DlgCreateVersion = React.lazy(() => import('@/dialogs/DlgCreateVersion'));
const DlgCstTemplate = React.lazy(() => import('@/features/rsform/dialogs/DlgCstTemplate')); const DlgCstTemplate = React.lazy(() => import('@/dialogs/DlgCstTemplate'));
const DlgDeleteCst = React.lazy(() => import('@/features/rsform/dialogs/DlgDeleteCst')); const DlgDeleteCst = React.lazy(() => import('@/dialogs/DlgDeleteCst'));
const DlgDeleteOperation = React.lazy(() => import('@/features/oss/dialogs/DlgDeleteOperation')); const DlgDeleteOperation = React.lazy(() => import('@/dialogs/DlgDeleteOperation'));
const DlgEditEditors = React.lazy(() => import('@/features/library/dialogs/DlgEditEditors')); const DlgEditEditors = React.lazy(() => import('@/dialogs/DlgEditEditors'));
const DlgEditOperation = React.lazy(() => import('@/features/oss/dialogs/DlgEditOperation')); const DlgEditOperation = React.lazy(() => import('@/dialogs/DlgEditOperation'));
const DlgEditReference = React.lazy(() => import('@/features/rsform/dialogs/DlgEditReference')); const DlgEditReference = React.lazy(() => import('@/dialogs/DlgEditReference'));
const DlgEditVersions = React.lazy(() => import('@/features/rsform/dialogs/DlgEditVersions')); const DlgEditVersions = React.lazy(() => import('@/dialogs/DlgEditVersions'));
const DlgEditWordForms = React.lazy(() => import('@/features/rsform/dialogs/DlgEditWordForms')); const DlgEditWordForms = React.lazy(() => import('@/dialogs/DlgEditWordForms'));
const DlgGraphParams = React.lazy(() => import('@/features/rsform/dialogs/DlgGraphParams')); const DlgGraphParams = React.lazy(() => import('@/dialogs/DlgGraphParams'));
const DlgInlineSynthesis = React.lazy(() => import('@/features/rsform/dialogs/DlgInlineSynthesis')); const DlgInlineSynthesis = React.lazy(() => import('@/dialogs/DlgInlineSynthesis'));
const DlgRelocateConstituents = React.lazy(() => import('@/features/oss/dialogs/DlgRelocateConstituents')); const DlgRelocateConstituents = React.lazy(() => import('@/dialogs/DlgRelocateConstituents'));
const DlgRenameCst = React.lazy(() => import('@/features/rsform/dialogs/DlgRenameCst')); const DlgRenameCst = React.lazy(() => import('@/dialogs/DlgRenameCst'));
const DlgShowAST = React.lazy(() => import('@/features/rsform/dialogs/DlgShowAST')); const DlgShowAST = React.lazy(() => import('@/dialogs/DlgShowAST'));
const DlgShowQR = React.lazy(() => import('@/features/rsform/dialogs/DlgShowQR')); const DlgShowQR = React.lazy(() => import('@/dialogs/DlgShowQR'));
const DlgShowTypeGraph = React.lazy(() => import('@/features/rsform/dialogs/DlgShowTypeGraph')); const DlgShowTypeGraph = React.lazy(() => import('@/dialogs/DlgShowTypeGraph'));
const DlgSubstituteCst = React.lazy(() => import('@/features/rsform/dialogs/DlgSubstituteCst')); const DlgSubstituteCst = React.lazy(() => import('@/dialogs/DlgSubstituteCst'));
const DlgUploadRSForm = React.lazy(() => import('@/features/rsform/dialogs/DlgUploadRSForm')); const DlgUploadRSForm = React.lazy(() => import('@/dialogs/DlgUploadRSForm'));
export const GlobalDialogs = () => { export const GlobalDialogs = () => {
const active = useDialogsStore(state => state.active); const active = useDialogsStore(state => state.active);

View File

@ -1,8 +1,8 @@
'use client'; 'use client';
import { Tooltip } from '@/components/Container'; import InfoConstituenta from '@/components/info/InfoConstituenta';
import { Loader } from '@/components/Loader'; import Loader from '@/components/ui/Loader';
import InfoConstituenta from '@/features/rsform/components/InfoConstituenta'; import Tooltip from '@/components/ui/Tooltip';
import { useTooltipsStore } from '@/stores/tooltips'; import { useTooltipsStore } from '@/stores/tooltips';
import { globals } from '@/utils/constants'; import { globals } from '@/utils/constants';

View File

@ -1,5 +1,6 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
import { IconLibrary2, IconManuals, IconNewItem2 } from '@/components/Icons'; import { IconLibrary2, IconManuals, IconNewItem2 } from '@/components/Icons';
import { CProps } from '@/components/props'; import { CProps } from '@/components/props';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
@ -9,11 +10,10 @@ import { PARAMETER } from '@/utils/constants';
import { urls } from '../urls'; import { urls } from '../urls';
import Logo from './Logo'; import Logo from './Logo';
import NavigationButton from './NavigationButton'; import NavigationButton from './NavigationButton';
import { useConceptNavigation } from './NavigationContext';
import ToggleNavigation from './ToggleNavigation'; import ToggleNavigation from './ToggleNavigation';
import UserMenu from './UserMenu'; import UserMenu from './UserMenu';
export function Navigation() { function Navigation() {
const router = useConceptNavigation(); const router = useConceptNavigation();
const size = useWindowSize(); const size = useWindowSize();
const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation); const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation);
@ -65,3 +65,5 @@ export function Navigation() {
</nav> </nav>
); );
} }
export default Navigation;

View File

@ -1,5 +1,5 @@
import { useAuthSuspense } from '@/backend/auth/useAuth';
import { IconLogin, IconUser2 } from '@/components/Icons'; import { IconLogin, IconUser2 } from '@/components/Icons';
import { useAuthSuspense } from '@/features/auth/backend/useAuth';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';
import NavigationButton from './NavigationButton'; import NavigationButton from './NavigationButton';

View File

@ -1,4 +1,6 @@
import { Dropdown, DropdownButton } from '@/components/Dropdown'; import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
import { useAuthSuspense } from '@/backend/auth/useAuth';
import { useLogout } from '@/backend/auth/useLogout';
import { import {
IconAdmin, IconAdmin,
IconAdminOff, IconAdminOff,
@ -14,12 +16,11 @@ import {
IconUser IconUser
} from '@/components/Icons'; } from '@/components/Icons';
import { CProps } from '@/components/props'; import { CProps } from '@/components/props';
import { useAuthSuspense } from '@/features/auth/backend/useAuth'; import Dropdown from '@/components/ui/Dropdown';
import { useLogout } from '@/features/auth/backend/useLogout'; import DropdownButton from '@/components/ui/DropdownButton';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';
import { urls } from '../urls'; import { urls } from '../urls';
import { useConceptNavigation } from './NavigationContext';
interface UserDropdownProps { interface UserDropdownProps {
isOpen: boolean; isOpen: boolean;
@ -45,12 +46,12 @@ function UserDropdown({ isOpen, hideDropdown }: UserDropdownProps) {
function logoutAndRedirect() { function logoutAndRedirect() {
hideDropdown(); hideDropdown();
void logout().then(() => router.push(urls.login)); logout(() => router.push(urls.login));
} }
function gotoAdmin() { function gotoAdmin() {
hideDropdown(); hideDropdown();
void logout().then(() => router.push(urls.admin, true)); logout(() => router.push(urls.admin, true));
} }
function gotoIcons(event: CProps.EventMouse) { function gotoIcons(event: CProps.EventMouse) {

View File

@ -1,10 +1,10 @@
import { Suspense } from 'react'; import { Suspense } from 'react';
import { useDropdown } from '@/components/Dropdown'; import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
import { Loader } from '@/components/Loader'; import Loader from '@/components/ui/Loader';
import useDropdown from '@/hooks/useDropdown';
import { urls } from '../urls'; import { urls } from '../urls';
import { useConceptNavigation } from './NavigationContext';
import UserButton from './UserButton'; import UserButton from './UserButton';
import UserDropdown from './UserDropdown'; import UserDropdown from './UserDropdown';

View File

@ -1 +1 @@
export { Navigation } from './Navigation'; export { default } from './Navigation';

View File

@ -1,19 +1,19 @@
import { createBrowserRouter } from 'react-router'; import { createBrowserRouter } from 'react-router';
import { Loader } from '@/components/Loader'; import { prefetchAuth } from '@/backend/auth/useAuth';
import { prefetchAuth } from '@/features/auth/backend/useAuth'; import { prefetchLibrary } from '@/backend/library/useLibrary';
import LoginPage from '@/features/auth/pages/LoginPage'; import { prefetchOSS } from '@/backend/oss/useOSS';
import HomePage from '@/features/home/HomePage'; import { prefetchRSForm } from '@/backend/rsform/useRSForm';
import NotFoundPage from '@/features/home/NotFoundPage'; import { prefetchProfile } from '@/backend/users/useProfile';
import { prefetchLibrary } from '@/features/library/backend/useLibrary'; import { prefetchUsers } from '@/backend/users/useUsers';
import CreateItemPage from '@/features/library/pages/CreateItemPage'; import Loader from '@/components/ui/Loader';
import { prefetchOSS } from '@/features/oss/backend/useOSS'; import CreateItemPage from '@/pages/CreateItemPage';
import { prefetchRSForm } from '@/features/rsform/backend/useRSForm'; import HomePage from '@/pages/HomePage';
import { prefetchProfile } from '@/features/users/backend/useProfile'; import LoginPage from '@/pages/LoginPage';
import { prefetchUsers } from '@/features/users/backend/useUsers'; import NotFoundPage from '@/pages/NotFoundPage';
import ApplicationLayout from './ApplicationLayout'; import ApplicationLayout from './ApplicationLayout';
import { ErrorFallback } from './ErrorFallback'; import ErrorFallback from './ErrorFallback';
import { routes } from './urls'; import { routes } from './urls';
export const Router = createBrowserRouter([ export const Router = createBrowserRouter([
@ -38,25 +38,25 @@ export const Router = createBrowserRouter([
}, },
{ {
path: routes.signup, path: routes.signup,
lazy: () => import('@/features/users/pages/RegisterPage') lazy: () => import('@/pages/RegisterPage')
}, },
{ {
path: routes.profile, path: routes.profile,
loader: prefetchProfile, loader: prefetchProfile,
lazy: () => import('@/features/users/pages/UserProfilePage') lazy: () => import('@/pages/UserProfilePage')
}, },
{ {
path: routes.restore_password, path: routes.restore_password,
lazy: () => import('@/features/auth/pages/RestorePasswordPage') lazy: () => import('@/pages/RestorePasswordPage')
}, },
{ {
path: routes.password_change, path: routes.password_change,
lazy: () => import('@/features/auth/pages/PasswordChangePage') lazy: () => import('@/pages/PasswordChangePage')
}, },
{ {
path: routes.library, path: routes.library,
loader: () => Promise.allSettled([prefetchLibrary(), prefetchUsers()]), loader: () => Promise.allSettled([prefetchLibrary(), prefetchUsers()]),
lazy: () => import('@/features/library/pages/LibraryPage') lazy: () => import('@/pages/LibraryPage')
}, },
{ {
path: routes.create_schema, path: routes.create_schema,
@ -65,24 +65,24 @@ export const Router = createBrowserRouter([
{ {
path: `${routes.rsforms}/:id`, path: `${routes.rsforms}/:id`,
loader: data => prefetchRSForm(parseRSFormURL(data.params.id, data.request.url)), loader: data => prefetchRSForm(parseRSFormURL(data.params.id, data.request.url)),
lazy: () => import('@/features/rsform/pages/RSFormPage') lazy: () => import('@/pages/RSFormPage')
}, },
{ {
path: `${routes.oss}/:id`, path: `${routes.oss}/:id`,
loader: data => prefetchOSS(parseOssURL(data.params.id)), loader: data => prefetchOSS(parseOssURL(data.params.id)),
lazy: () => import('@/features/oss/pages/OssPage') lazy: () => import('@/pages/OssPage')
}, },
{ {
path: routes.manuals, path: routes.manuals,
lazy: () => import('@/features/help/pages/ManualsPage') lazy: () => import('@/pages/ManualsPage')
}, },
{ {
path: `${routes.icons}`, path: `${routes.icons}`,
lazy: () => import('@/features/home/IconsPage') lazy: () => import('@/pages/IconsPage')
}, },
{ {
path: `${routes.database_schema}`, path: `${routes.database_schema}`,
lazy: () => import('@/features/home/DatabaseSchemaPage') lazy: () => import('@/pages/DatabaseSchemaPage')
} }
] ]
} }

View File

@ -1,6 +1,3 @@
export { useConceptNavigation } from './Navigation/NavigationContext';
export { useBlockNavigation } from './Navigation/NavigationContext';
export { urls } from './urls';
import { RouterProvider } from 'react-router'; import { RouterProvider } from 'react-router';
import { Router } from './Router'; import { Router } from './Router';

View File

@ -1,15 +1,13 @@
/** /**
* Module: generic API for backend REST communications using axios library. * Module: generic API for backend REST communications using axios library.
*/ */
import axios, { AxiosError, AxiosRequestConfig } from 'axios'; import axios from 'axios';
import { AxiosError, AxiosRequestConfig } from 'axios';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { buildConstants } from '@/utils/buildConstants'; import { buildConstants } from '@/utils/buildConstants';
import { extractErrorMessage } from '@/utils/utils'; import { extractErrorMessage } from '@/utils/utils';
export { AxiosError } from 'axios';
export const isAxiosError = axios.isAxiosError;
const defaultOptions = { const defaultOptions = {
xsrfCookieName: 'csrftoken', xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'x-csrftoken', xsrfHeaderName: 'x-csrftoken',

View File

@ -3,53 +3,44 @@ import { z } from 'zod';
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { errorMsg, infoMsg } from '@/utils/labels'; import { ICurrentUser } from '@/models/user';
import { errors, information } from '@/utils/labels';
/**
* Represents CurrentUser information.
*/
export interface ICurrentUser {
id: number | null;
username: string;
is_staff: boolean;
editor: number[];
}
/** /**
* Represents login data, used to authenticate users. * Represents login data, used to authenticate users.
*/ */
export const schemaUserLogin = z.object({ export const UserLoginSchema = z.object({
username: z.string().nonempty(errorMsg.requiredField), username: z.string().nonempty(errors.requiredField),
password: z.string().nonempty(errorMsg.requiredField) password: z.string().nonempty(errors.requiredField)
}); });
/** /**
* Represents login data, used to authenticate users. * Represents login data, used to authenticate users.
*/ */
export type IUserLoginDTO = z.infer<typeof schemaUserLogin>; export type IUserLoginDTO = z.infer<typeof UserLoginSchema>;
/** /**
* Represents data needed to update password for current user. * Represents data needed to update password for current user.
*/ */
export const schemaChangePassword = z export const ChangePasswordSchema = z
.object({ .object({
old_password: z.string().nonempty(errorMsg.requiredField), old_password: z.string().nonempty(errors.requiredField),
new_password: z.string().nonempty(errorMsg.requiredField), new_password: z.string().nonempty(errors.requiredField),
new_password2: z.string().nonempty(errorMsg.requiredField) new_password2: z.string().nonempty(errors.requiredField)
}) })
.refine(schema => schema.new_password === schema.new_password2, { .refine(schema => schema.new_password === schema.new_password2, {
path: ['new_password2'], path: ['new_password2'],
message: errorMsg.passwordsMismatch message: errors.passwordsMismatch
}) })
.refine(schema => schema.old_password !== schema.new_password, { .refine(schema => schema.old_password !== schema.new_password, {
path: ['new_password'], path: ['new_password'],
message: errorMsg.passwordsSame message: errors.passwordsSame
}); });
/** /**
* Represents data needed to update password for current user. * Represents data needed to update password for current user.
*/ */
export type IChangePasswordDTO = z.infer<typeof schemaChangePassword>; export type IChangePasswordDTO = z.infer<typeof ChangePasswordSchema>;
/** /**
* Represents password reset request data. * Represents password reset request data.
@ -103,7 +94,7 @@ export const authApi = {
endpoint: '/users/api/change-password', endpoint: '/users/api/change-password',
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
requestPasswordReset: (data: IRequestPasswordDTO) => requestPasswordReset: (data: IRequestPasswordDTO) =>

View File

@ -1,7 +1,6 @@
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
import { queryClient } from '@/backend/queryClient'; import { queryClient } from '../queryClient';
import { authApi } from './api'; import { authApi } from './api';
export function useAuth() { export function useAuth() {

View File

@ -10,7 +10,10 @@ export const useChangePassword = () => {
onSettled: () => client.invalidateQueries({ queryKey: [authApi.baseKey] }) onSettled: () => client.invalidateQueries({ queryKey: [authApi.baseKey] })
}); });
return { return {
changePassword: (data: IChangePasswordDTO) => mutation.mutateAsync(data), changePassword: (
data: IChangePasswordDTO, //
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess }),
isPending: mutation.isPending, isPending: mutation.isPending,
error: mutation.error, error: mutation.error,
reset: mutation.reset reset: mutation.reset

View File

@ -11,7 +11,7 @@ export const useLogin = () => {
onSuccess: () => client.resetQueries() onSuccess: () => client.resetQueries()
}); });
return { return {
login: (data: IUserLoginDTO) => mutation.mutateAsync(data), login: (data: IUserLoginDTO, onSuccess?: () => void) => mutation.mutate(data, { onSuccess }),
isPending: mutation.isPending, isPending: mutation.isPending,
error: mutation.error, error: mutation.error,
reset: mutation.reset reset: mutation.reset

View File

@ -9,5 +9,5 @@ export const useLogout = () => {
mutationFn: authApi.logout, mutationFn: authApi.logout,
onSuccess: () => client.resetQueries() onSuccess: () => client.resetQueries()
}); });
return { logout: () => mutation.mutateAsync() }; return { logout: (onSuccess?: () => void) => mutation.mutate(undefined, { onSuccess }) };
}; };

View File

@ -8,7 +8,10 @@ export const useRequestPasswordReset = () => {
mutationFn: authApi.requestPasswordReset mutationFn: authApi.requestPasswordReset
}); });
return { return {
requestPasswordReset: (data: IRequestPasswordDTO) => mutation.mutateAsync(data), requestPasswordReset: (
data: IRequestPasswordDTO, //
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess }),
isPending: mutation.isPending, isPending: mutation.isPending,
error: mutation.error, error: mutation.error,
reset: mutation.reset reset: mutation.reset

View File

@ -12,8 +12,14 @@ export const useResetPassword = () => {
mutationFn: authApi.resetPassword mutationFn: authApi.resetPassword
}); });
return { return {
validateToken: (data: IPasswordTokenDTO) => validateMutation.mutateAsync(data), validateToken: (
resetPassword: (data: IResetPasswordDTO) => resetMutation.mutateAsync(data), data: IPasswordTokenDTO, //
onSuccess?: () => void
) => validateMutation.mutate(data, { onSuccess }),
resetPassword: (
data: IResetPasswordDTO, //
onSuccess?: () => void
) => resetMutation.mutate(data, { onSuccess }),
isPending: resetMutation.isPending || validateMutation.isPending, isPending: resetMutation.isPending || validateMutation.isPending,
error: resetMutation.error ?? validateMutation.error, error: resetMutation.error ?? validateMutation.error,
reset: resetMutation.reset reset: resetMutation.reset

View File

@ -0,0 +1,18 @@
import { useMutation } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport';
import { cctextApi, ILexemeResponse } from './api';
export const useGenerateLexeme = () => {
const mutation = useMutation({
mutationKey: [cctextApi.baseKey, 'generate-lexeme'],
mutationFn: cctextApi.generateLexeme
});
return {
generateLexeme: (
data: { text: string }, //
onSuccess?: DataCallback<ILexemeResponse>
) => mutation.mutate(data, { onSuccess })
};
};

View File

@ -0,0 +1,18 @@
import { useMutation } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport';
import { cctextApi, ITextResult, IWordFormDTO } from './api';
export const useInflectText = () => {
const mutation = useMutation({
mutationKey: [cctextApi.baseKey, 'inflect-text'],
mutationFn: cctextApi.inflectText
});
return {
inflectText: (
data: IWordFormDTO, //
onSuccess?: DataCallback<ITextResult>
) => mutation.mutate(data, { onSuccess })
};
};

View File

@ -0,0 +1,18 @@
import { useMutation } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport';
import { cctextApi, ITextResult } from './api';
export const useParseText = () => {
const mutation = useMutation({
mutationKey: [cctextApi.baseKey, 'parse-text'],
mutationFn: cctextApi.parseText
});
return {
parseText: (
data: { text: string }, //
onSuccess?: DataCallback<ITextResult>
) => mutation.mutate(data, { onSuccess })
};
};

View File

@ -3,12 +3,21 @@ import { z } from 'zod';
import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/backend/oss/api';
import { IRSFormDTO, rsformsApi } from '@/features/rsform/backend/api'; import { IRSFormDTO, rsformsApi } from '@/backend/rsform/api';
import { errorMsg, infoMsg } from '@/utils/labels'; import {
AccessPolicy,
import { AccessPolicy, ILibraryItem, IVersionInfo, LibraryItemID, LibraryItemType, VersionID } from '../models/library'; ILibraryItem,
import { validateLocation } from '../models/libraryAPI'; IVersionData,
IVersionInfo,
LibraryItemID,
LibraryItemType,
VersionID
} from '@/models/library';
import { validateLocation } from '@/models/libraryAPI';
import { ConstituentaID } from '@/models/rsform';
import { UserID } from '@/models/user';
import { errors, information } from '@/utils/labels';
/** /**
* Represents update data for renaming Location. * Represents update data for renaming Location.
@ -21,29 +30,14 @@ export interface IRenameLocationDTO {
/** /**
* Represents data, used for cloning {@link IRSForm}. * Represents data, used for cloning {@link IRSForm}.
*/ */
export const schemaCloneLibraryItem = z.object({ export interface IRCloneLibraryItemDTO extends Omit<ILibraryItem, 'time_create' | 'time_update' | 'owner'> {
id: z.number(), items?: ConstituentaID[];
item_type: z.nativeEnum(LibraryItemType), }
title: z.string().nonempty(errorMsg.requiredField),
alias: z.string().nonempty(errorMsg.requiredField),
comment: z.string(),
visible: z.boolean(),
read_only: z.boolean(),
location: z.string().refine(data => validateLocation(data), { message: errorMsg.invalidLocation }),
access_policy: z.nativeEnum(AccessPolicy),
items: z.array(z.number()).optional()
});
/**
* Represents data, used for cloning {@link IRSForm}.
*/
export type ICloneLibraryItemDTO = z.infer<typeof schemaCloneLibraryItem>;
/** /**
* Represents data, used for creating {@link IRSForm}. * Represents data, used for creating {@link IRSForm}.
*/ */
export const schemaCreateLibraryItem = z export const CreateLibraryItemSchema = z
.object({ .object({
item_type: z.nativeEnum(LibraryItemType), item_type: z.nativeEnum(LibraryItemType),
title: z.string().optional(), title: z.string().optional(),
@ -51,57 +45,44 @@ export const schemaCreateLibraryItem = z
comment: z.string(), comment: z.string(),
visible: z.boolean(), visible: z.boolean(),
read_only: z.boolean(), read_only: z.boolean(),
location: z.string().refine(data => validateLocation(data), { message: errorMsg.invalidLocation }), location: z.string(),
access_policy: z.nativeEnum(AccessPolicy), access_policy: z.nativeEnum(AccessPolicy),
file: z.instanceof(File).optional(), file: z.instanceof(File).optional(),
fileName: z.string().optional() fileName: z.string().optional()
}) })
.refine(data => validateLocation(data.location), {
path: ['location'],
message: errors.invalidLocation
})
.refine(data => !!data.file || !!data.title, { .refine(data => !!data.file || !!data.title, {
path: ['title'], path: ['title'],
message: errorMsg.requiredField message: errors.requiredField
}) })
.refine(data => !!data.file || !!data.alias, { .refine(data => !!data.file || !!data.alias, {
path: ['alias'], path: ['alias'],
message: errorMsg.requiredField message: errors.requiredField
}); });
/** /**
* Represents data, used for creating {@link IRSForm}. * Represents data, used for creating {@link IRSForm}.
*/ */
export type ICreateLibraryItemDTO = z.infer<typeof schemaCreateLibraryItem>; export type ICreateLibraryItemDTO = z.infer<typeof CreateLibraryItemSchema>;
/** /**
* Represents update data for editing {@link ILibraryItem}. * Represents update data for editing {@link ILibraryItem}.
*/ */
export const schemaUpdateLibraryItem = z.object({ export interface IUpdateLibraryItemDTO
id: z.number(), extends Omit<ILibraryItem, 'time_create' | 'time_update' | 'access_policy' | 'location' | 'owner'> {}
item_type: z.nativeEnum(LibraryItemType),
title: z.string().nonempty(errorMsg.requiredField),
alias: z.string().nonempty(errorMsg.requiredField),
comment: z.string(),
visible: z.boolean(),
read_only: z.boolean()
});
/**
* Represents update data for editing {@link ILibraryItem}.
*/
export type IUpdateLibraryItemDTO = z.infer<typeof schemaUpdateLibraryItem>;
/** /**
* Create version metadata in persistent storage. * Create version metadata in persistent storage.
*/ */
export const schemaVersionCreate = z.object({ export interface IVersionCreateDTO {
version: z.string(), version: string;
description: z.string(), description: string;
items: z.array(z.number()).optional() items?: ConstituentaID[];
}); }
/**
* Create version metadata in persistent storage.
*/
export type IVersionCreateDTO = z.infer<typeof schemaVersionCreate>;
/** /**
* Represents data response when creating {@link IVersionInfo}. * Represents data response when creating {@link IVersionInfo}.
@ -111,20 +92,6 @@ export interface IVersionCreatedResponse {
schema: IRSFormDTO; schema: IRSFormDTO;
} }
/**
* Represents version data, intended to update version metadata in persistent storage.
*/
export const schemaVersionUpdate = z.object({
id: z.number(),
version: z.string().nonempty(errorMsg.requiredField),
description: z.string()
});
/**
* Represents version data, intended to update version metadata in persistent storage.
*/
export type IVersionUpdateDTO = z.infer<typeof schemaVersionUpdate>;
export const libraryApi = { export const libraryApi = {
baseKey: 'library', baseKey: 'library',
libraryListKey: ['library', 'list'], libraryListKey: ['library', 'list'],
@ -160,7 +127,7 @@ export const libraryApi = {
endpoint: !data.file ? '/api/library' : '/api/rsforms/create-detailed', endpoint: !data.file ? '/api/library' : '/api/rsforms/create-detailed',
request: { request: {
data: data, data: data,
successMessage: infoMsg.newLibraryItem successMessage: information.newLibraryItem
}, },
options: !data.file options: !data.file
? undefined ? undefined
@ -175,15 +142,15 @@ export const libraryApi = {
endpoint: `/api/library/${data.id}`, endpoint: `/api/library/${data.id}`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
setOwner: ({ itemID, owner }: { itemID: LibraryItemID; owner: number }) => setOwner: ({ itemID, owner }: { itemID: LibraryItemID; owner: UserID }) =>
axiosPatch({ axiosPatch({
endpoint: `/api/library/${itemID}/set-owner`, endpoint: `/api/library/${itemID}/set-owner`,
request: { request: {
data: { user: owner }, data: { user: owner },
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
setLocation: ({ itemID, location }: { itemID: LibraryItemID; location: string }) => setLocation: ({ itemID, location }: { itemID: LibraryItemID; location: string }) =>
@ -191,7 +158,7 @@ export const libraryApi = {
endpoint: `/api/library/${itemID}/set-location`, endpoint: `/api/library/${itemID}/set-location`,
request: { request: {
data: { location: location }, data: { location: location },
successMessage: infoMsg.moveComplete successMessage: information.moveComplete
} }
}), }),
setAccessPolicy: ({ itemID, policy }: { itemID: LibraryItemID; policy: AccessPolicy }) => setAccessPolicy: ({ itemID, policy }: { itemID: LibraryItemID; policy: AccessPolicy }) =>
@ -199,15 +166,15 @@ export const libraryApi = {
endpoint: `/api/library/${itemID}/set-access-policy`, endpoint: `/api/library/${itemID}/set-access-policy`,
request: { request: {
data: { access_policy: policy }, data: { access_policy: policy },
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
setEditors: ({ itemID, editors }: { itemID: LibraryItemID; editors: number[] }) => setEditors: ({ itemID, editors }: { itemID: LibraryItemID; editors: UserID[] }) =>
axiosPatch({ axiosPatch({
endpoint: `/api/library/${itemID}/set-editors`, endpoint: `/api/library/${itemID}/set-editors`,
request: { request: {
data: { users: editors }, data: { users: editors },
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
@ -215,15 +182,15 @@ export const libraryApi = {
axiosDelete({ axiosDelete({
endpoint: `/api/library/${target}`, endpoint: `/api/library/${target}`,
request: { request: {
successMessage: infoMsg.itemDestroyed successMessage: information.itemDestroyed
} }
}), }),
cloneItem: (data: ICloneLibraryItemDTO) => cloneItem: (data: IRCloneLibraryItemDTO) =>
axiosPost<ICloneLibraryItemDTO, IRSFormDTO>({ axiosPost<IRCloneLibraryItemDTO, IRSFormDTO>({
endpoint: `/api/library/${data.id}/clone`, endpoint: `/api/library/${data.id}/clone`,
request: { request: {
data: data, data: data,
successMessage: newSchema => infoMsg.cloneComplete(newSchema.alias) successMessage: newSchema => information.cloneComplete(newSchema.alias)
} }
}), }),
renameLocation: (data: IRenameLocationDTO) => renameLocation: (data: IRenameLocationDTO) =>
@ -231,38 +198,38 @@ export const libraryApi = {
endpoint: '/api/library/rename-location', endpoint: '/api/library/rename-location',
request: { request: {
data: data, data: data,
successMessage: infoMsg.locationRenamed successMessage: information.locationRenamed
} }
}), }),
versionCreate: ({ itemID, data }: { itemID: LibraryItemID; data: IVersionCreateDTO }) => versionCreate: ({ itemID, data }: { itemID: LibraryItemID; data: IVersionData }) =>
axiosPost<IVersionCreateDTO, IVersionCreatedResponse>({ axiosPost<IVersionData, IVersionCreatedResponse>({
endpoint: `/api/library/${itemID}/create-version`, endpoint: `/api/library/${itemID}/create-version`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.newVersion(data.version) successMessage: information.newVersion(data.version)
} }
}), }),
versionRestore: ({ versionID }: { versionID: VersionID }) => versionRestore: ({ versionID }: { versionID: VersionID }) =>
axiosPatch<undefined, IRSFormDTO>({ axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/versions/${versionID}/restore`, endpoint: `/api/versions/${versionID}/restore`,
request: { request: {
successMessage: infoMsg.versionRestored successMessage: information.versionRestored
} }
}), }),
versionUpdate: (data: IVersionUpdateDTO) => versionUpdate: ({ versionID, data }: { versionID: VersionID; data: IVersionData }) =>
axiosPatch<IVersionUpdateDTO, IVersionInfo>({ axiosPatch<IVersionData, IVersionInfo>({
endpoint: `/api/versions/${data.id}`, endpoint: `/api/versions/${versionID}`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
versionDelete: (data: { itemID: LibraryItemID; versionID: VersionID }) => versionDelete: (data: { itemID: LibraryItemID; versionID: VersionID }) =>
axiosDelete({ axiosDelete({
endpoint: `/api/versions/${data.versionID}`, endpoint: `/api/versions/${data.versionID}`,
request: { request: {
successMessage: infoMsg.versionDestroyed successMessage: information.versionDestroyed
} }
}) })
}; };

View File

@ -1,7 +1,7 @@
import { useAuthSuspense } from '@/features/auth/backend/useAuth'; import { useAuthSuspense } from '@/backend/auth/useAuth';
import { matchLibraryItem, matchLibraryItemLocation } from '@/models/libraryAPI';
import { ILibraryFilter } from '@/models/miscellaneous';
import { ILibraryFilter } from '../models/library';
import { matchLibraryItem, matchLibraryItemLocation } from '../models/libraryAPI';
import { useLibrary } from './useLibrary'; import { useLibrary } from './useLibrary';
export function useApplyLibraryFilter(filter: ILibraryFilter) { export function useApplyLibraryFilter(filter: ILibraryFilter) {

View File

@ -1,6 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ICloneLibraryItemDTO, libraryApi } from './api'; import { DataCallback } from '@/backend/apiTransport';
import { IRSFormDTO } from '../rsform/api';
import { IRCloneLibraryItemDTO, libraryApi } from './api';
export const useCloneItem = () => { export const useCloneItem = () => {
const client = useQueryClient(); const client = useQueryClient();
@ -10,6 +13,9 @@ export const useCloneItem = () => {
onSuccess: () => client.invalidateQueries({ queryKey: [libraryApi.baseKey] }) onSuccess: () => client.invalidateQueries({ queryKey: [libraryApi.baseKey] })
}); });
return { return {
cloneItem: (data: ICloneLibraryItemDTO) => mutation.mutateAsync(data) cloneItem: (
data: IRCloneLibraryItemDTO, //
onSuccess?: DataCallback<IRSFormDTO>
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,5 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport';
import { ILibraryItem } from '@/models/library';
import { ICreateLibraryItemDTO, libraryApi } from './api'; import { ICreateLibraryItemDTO, libraryApi } from './api';
export const useCreateItem = () => { export const useCreateItem = () => {
@ -10,7 +13,10 @@ export const useCreateItem = () => {
onSuccess: () => client.invalidateQueries({ queryKey: [libraryApi.baseKey] }) onSuccess: () => client.invalidateQueries({ queryKey: [libraryApi.baseKey] })
}); });
return { return {
createItem: (data: ICreateLibraryItemDTO) => mutation.mutateAsync(data), createItem: (
data: ICreateLibraryItemDTO, //
onSuccess?: DataCallback<ILibraryItem>
) => mutation.mutate(data, { onSuccess }),
isPending: mutation.isPending, isPending: mutation.isPending,
error: mutation.error, error: mutation.error,
reset: mutation.reset reset: mutation.reset

View File

@ -1,10 +1,10 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { LibraryItemID } from '@/models/library';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
import { LibraryItemID } from '../models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export const useDeleteItem = () => { export const useDeleteItem = () => {
@ -26,7 +26,10 @@ export const useDeleteItem = () => {
} }
}); });
return { return {
deleteItem: (target: LibraryItemID) => mutation.mutateAsync(target), deleteItem: (
target: LibraryItemID, //
onSuccess?: () => void
) => mutation.mutate(target, { onSuccess }),
isPending: mutation.isPending isPending: mutation.isPending
}; };
}; };

View File

@ -1,6 +1,6 @@
import { FolderTree } from '@/features/library/models/FolderTree'; import { FolderTree } from '@/models/FolderTree';
import { LocationHead } from '@/models/library';
import { LocationHead } from '../models/library';
import { useLibrary } from './useLibrary'; import { useLibrary } from './useLibrary';
export function useFolders() { export function useFolders() {

View File

@ -1,7 +1,7 @@
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
import { useAuthSuspense } from '@/backend/auth/useAuth';
import { queryClient } from '@/backend/queryClient'; import { queryClient } from '@/backend/queryClient';
import { useAuthSuspense } from '@/features/auth/backend/useAuth';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';
import { libraryApi } from './api'; import { libraryApi } from './api';

View File

@ -1,7 +1,7 @@
import { useIsMutating } from '@tanstack/react-query'; import { useIsMutating } from '@tanstack/react-query';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { libraryApi } from './api'; import { libraryApi } from './api';

View File

@ -1,7 +1,7 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { IRenameLocationDTO, libraryApi } from './api'; import { IRenameLocationDTO, libraryApi } from './api';
@ -18,6 +18,9 @@ export const useRenameLocation = () => {
]) ])
}); });
return { return {
renameLocation: (data: IRenameLocationDTO) => mutation.mutateAsync(data) renameLocation: (
data: IRenameLocationDTO, //
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,9 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IOperationSchemaDTO, ossApi } from '@/features/oss/backend/api'; import { IOperationSchemaDTO, ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { AccessPolicy, ILibraryItem, LibraryItemID } from '@/models/library';
import { AccessPolicy, ILibraryItem, LibraryItemID } from '../models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export const useSetAccessPolicy = () => { export const useSetAccessPolicy = () => {
@ -39,6 +39,6 @@ export const useSetAccessPolicy = () => {
}); });
return { return {
setAccessPolicy: (data: { itemID: LibraryItemID; policy: AccessPolicy }) => mutation.mutateAsync(data) setAccessPolicy: (data: { itemID: LibraryItemID; policy: AccessPolicy }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,7 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { LibraryItemID } from '@/models/library';
import { UserID } from '@/models/user';
import { libraryApi } from './api'; import { libraryApi } from './api';
@ -34,6 +36,6 @@ export const useSetEditors = () => {
}); });
return { return {
setEditors: (data: { itemID: number; editors: number[] }) => mutation.mutateAsync(data) setEditors: (data: { itemID: LibraryItemID; editors: UserID[] }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,9 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IOperationSchemaDTO, ossApi } from '@/features/oss/backend/api'; import { IOperationSchemaDTO, ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { ILibraryItem, LibraryItemID } from '@/models/library';
import { ILibraryItem, LibraryItemID } from '../models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export const useSetLocation = () => { export const useSetLocation = () => {
@ -39,6 +39,12 @@ export const useSetLocation = () => {
}); });
return { return {
setLocation: (data: { itemID: LibraryItemID; location: string }) => mutation.mutateAsync(data) setLocation: (
data: {
itemID: LibraryItemID; //
location: string;
},
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,9 +1,10 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IOperationSchemaDTO, ossApi } from '@/features/oss/backend/api'; import { IOperationSchemaDTO, ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { ILibraryItem, LibraryItemID } from '@/models/library';
import { UserID } from '@/models/user';
import { ILibraryItem } from '../models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export const useSetOwner = () => { export const useSetOwner = () => {
@ -39,6 +40,6 @@ export const useSetOwner = () => {
}); });
return { return {
setOwner: (data: { itemID: number; owner: number }) => mutation.mutateAsync(data) setOwner: (data: { itemID: LibraryItemID; owner: UserID }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,9 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IOperationSchemaDTO, ossApi } from '@/features/oss/backend/api'; import { IOperationSchemaDTO, ossApi } from '@/backend/oss/api';
import { IRSFormDTO } from '@/features/rsform/backend/api'; import { ILibraryItem, LibraryItemType } from '@/models/library';
import { ILibraryItem, LibraryItemType } from '../models/library'; import { IRSFormDTO } from '../rsform/api';
import { IUpdateLibraryItemDTO, libraryApi } from './api'; import { IUpdateLibraryItemDTO, libraryApi } from './api';
export const useUpdateItem = () => { export const useUpdateItem = () => {
@ -32,6 +32,6 @@ export const useUpdateItem = () => {
} }
}); });
return { return {
updateItem: (data: IUpdateLibraryItemDTO) => mutation.mutateAsync(data) updateItem: (data: IUpdateLibraryItemDTO) => mutation.mutate(data)
}; };
}; };

View File

@ -1,6 +1,7 @@
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { ILibraryItem, LibraryItemID } from '../models/library'; import { ILibraryItem, LibraryItemID } from '@/models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export function useUpdateTimestamp() { export function useUpdateTimestamp() {

View File

@ -1,10 +1,11 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { rsformsApi } from '@/features/rsform/backend/api'; import { DataCallback } from '@/backend/apiTransport';
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { rsformsApi } from '@/backend/rsform/api';
import { IVersionData, LibraryItemID, VersionID } from '@/models/library';
import { LibraryItemID } from '../models/library'; import { libraryApi } from './api';
import { IVersionCreateDTO, libraryApi } from './api';
import { useUpdateTimestamp } from './useUpdateTimestamp';
export const useVersionCreate = () => { export const useVersionCreate = () => {
const client = useQueryClient(); const client = useQueryClient();
@ -18,7 +19,12 @@ export const useVersionCreate = () => {
} }
}); });
return { return {
versionCreate: (data: { itemID: LibraryItemID; data: IVersionCreateDTO }) => versionCreate: (
mutation.mutateAsync(data).then(response => response.version) data: {
itemID: LibraryItemID; //
data: IVersionData;
},
onSuccess?: DataCallback<VersionID>
) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.version) })
}; };
}; };

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IRSFormDTO, rsformsApi } from '@/features/rsform/backend/api'; import { IRSFormDTO, rsformsApi } from '@/backend/rsform/api';
import { LibraryItemID, VersionID } from '@/models/library';
import { LibraryItemID, VersionID } from '../models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export const useVersionDelete = () => { export const useVersionDelete = () => {
@ -24,6 +24,12 @@ export const useVersionDelete = () => {
} }
}); });
return { return {
versionDelete: (data: { itemID: LibraryItemID; versionID: VersionID }) => mutation.mutateAsync(data) versionDelete: (
data: {
itemID: LibraryItemID; //
versionID: VersionID;
},
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { VersionID } from '@/models/library';
import { VersionID } from '../models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export const useVersionRestore = () => { export const useVersionRestore = () => {
@ -16,6 +16,6 @@ export const useVersionRestore = () => {
} }
}); });
return { return {
versionRestore: (data: { versionID: VersionID }) => mutation.mutateAsync(data) versionRestore: (data: { versionID: VersionID }, onSuccess?: () => void) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,8 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IRSFormDTO, rsformsApi } from '@/features/rsform/backend/api'; import { IRSFormDTO, rsformsApi } from '@/backend/rsform/api';
import { IVersionData, VersionID } from '@/models/library';
import { IVersionUpdateDTO, libraryApi } from './api'; import { libraryApi } from './api';
export const useVersionUpdate = () => { export const useVersionUpdate = () => {
const client = useQueryClient(); const client = useQueryClient();
@ -27,6 +28,6 @@ export const useVersionUpdate = () => {
} }
}); });
return { return {
versionUpdate: (data: IVersionUpdateDTO) => mutation.mutateAsync(data) versionUpdate: (data: { versionID: VersionID; data: IVersionData }) => mutation.mutate(data)
}; };
}; };

View File

@ -2,15 +2,9 @@
* Module: OSS data loading and processing. * Module: OSS data loading and processing.
*/ */
import { ILibraryItem, LibraryItemID } from '@/features/library/models/library';
import {
IOperation,
IOperationSchema,
IOperationSchemaStats,
OperationID,
OperationType
} from '@/features/oss/models/oss';
import { Graph } from '@/models/Graph'; import { Graph } from '@/models/Graph';
import { ILibraryItem, LibraryItemID } from '@/models/library';
import { IOperation, IOperationSchema, IOperationSchemaStats, OperationID, OperationType } from '@/models/oss';
import { IOperationSchemaDTO } from './api'; import { IOperationSchemaDTO } from './api';

View File

@ -1,13 +1,19 @@
import { queryOptions } from '@tanstack/react-query'; import { queryOptions } from '@tanstack/react-query';
import { z } from 'zod';
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { ILibraryItem, ILibraryItemData, LibraryItemID } from '@/features/library/models/library'; import { ILibraryItem, ILibraryItemData, LibraryItemID } from '@/models/library';
import { IArgument, ICstSubstituteEx, IOperation, OperationID, OperationType } from '@/features/oss/models/oss'; import {
import { schemaCstSubstitute } from '@/features/rsform/backend/api'; IArgument,
import { IConstituentaReference, ITargetCst } from '@/features/rsform/models/rsform'; ICstSubstitute,
import { infoMsg } from '@/utils/labels'; ICstSubstituteEx,
IOperation,
IOperationPosition,
OperationID,
OperationType
} from '@/models/oss';
import { ConstituentaID, IConstituentaReference, ITargetCst } from '@/models/rsform';
import { information } from '@/utils/labels';
/** /**
* Represents {@link IOperation} data from server. * Represents {@link IOperation} data from server.
@ -23,42 +29,23 @@ export interface IOperationSchemaDTO extends ILibraryItemData {
substitutions: ICstSubstituteEx[]; substitutions: ICstSubstituteEx[];
} }
/**
* Represents {@link IOperation} position.
*/
export const schemaOperationPosition = z.object({
id: z.number(),
position_x: z.number(),
position_y: z.number()
});
/**
* Represents {@link IOperation} position.
*/
export type IOperationPosition = z.infer<typeof schemaOperationPosition>;
/** /**
* Represents {@link IOperation} data, used in creation process. * Represents {@link IOperation} data, used in creation process.
*/ */
export const schemaOperationCreate = z.object({ export interface IOperationCreateDTO {
positions: z.array(schemaOperationPosition), positions: IOperationPosition[];
item_data: z.object({ item_data: {
alias: z.string().nonempty(), alias: string;
operation_type: z.nativeEnum(OperationType), operation_type: OperationType;
title: z.string(), title: string;
comment: z.string(), comment: string;
position_x: z.number(), position_x: number;
position_y: z.number(), position_y: number;
result: z.number().nullable() result: LibraryItemID | null;
}), };
arguments: z.array(z.number()), arguments: OperationID[] | undefined;
create_schema: z.boolean() create_schema: boolean;
}); }
/**
* Represents {@link IOperation} data, used in creation process.
*/
export type IOperationCreateDTO = z.infer<typeof schemaOperationCreate>;
/** /**
* Represents data response when creating {@link IOperation}. * Represents data response when creating {@link IOperation}.
@ -79,17 +66,10 @@ export interface ITargetOperation {
/** /**
* Represents {@link IOperation} data, used in destruction process. * Represents {@link IOperation} data, used in destruction process.
*/ */
export const schemaOperationDelete = z.object({ export interface IOperationDeleteDTO extends ITargetOperation {
target: z.number(), keep_constituents: boolean;
positions: z.array(schemaOperationPosition), delete_schema: boolean;
keep_constituents: z.boolean(), }
delete_schema: z.boolean()
});
/**
* Represents {@link IOperation} data, used in destruction process.
*/
export type IOperationDeleteDTO = z.infer<typeof schemaOperationDelete>;
/** /**
* Represents data response when creating {@link IRSForm} for Input {@link IOperation}. * Represents data response when creating {@link IRSForm} for Input {@link IOperation}.
@ -102,49 +82,30 @@ export interface IInputCreatedResponse {
/** /**
* Represents {@link IOperation} data, used in setInput process. * Represents {@link IOperation} data, used in setInput process.
*/ */
export const schemaInputUpdate = z.object({ export interface IInputUpdateDTO extends ITargetOperation {
target: z.number(), input: LibraryItemID | null;
positions: z.array(schemaOperationPosition), }
input: z.number().nullable()
});
/**
* Represents {@link IOperation} data, used in setInput process.
*/
export type IInputUpdateDTO = z.infer<typeof schemaInputUpdate>;
/** /**
* Represents {@link IOperation} data, used in update process. * Represents {@link IOperation} data, used in update process.
*/ */
export const schemaOperationUpdate = z.object({ export interface IOperationUpdateDTO extends ITargetOperation {
target: z.number(), item_data: {
positions: z.array(schemaOperationPosition), alias: string;
item_data: z.object({ title: string;
alias: z.string().nonempty(), comment: string;
title: z.string(), };
comment: z.string() arguments: OperationID[] | undefined;
}), substitutions: ICstSubstitute[] | undefined;
arguments: z.array(z.number()), }
substitutions: z.array(schemaCstSubstitute)
});
/**
* Represents {@link IOperation} data, used in update process.
*/
export type IOperationUpdateDTO = z.infer<typeof schemaOperationUpdate>;
/** /**
* Represents data, used relocating {@link IConstituenta}s between {@link ILibraryItem}s. * Represents data, used relocating {@link IConstituenta}s between {@link ILibraryItem}s.
*/ */
export const schemaCstRelocate = z.object({ export interface ICstRelocateDTO {
destination: z.number(), destination: LibraryItemID;
items: z.array(z.number()).refine(data => data.length > 0) items: ConstituentaID[];
}); }
/**
* Represents data, used relocating {@link IConstituenta}s between {@link ILibraryItem}s.
*/
export type ICstRelocateDTO = z.infer<typeof schemaCstRelocate>;
export const ossApi = { export const ossApi = {
baseKey: 'oss', baseKey: 'oss',
@ -176,7 +137,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/update-positions`, endpoint: `/api/oss/${itemID}/update-positions`,
request: { request: {
data: { positions: positions }, data: { positions: positions },
successMessage: isSilent ? undefined : infoMsg.changesSaved successMessage: isSilent ? undefined : information.changesSaved
} }
}), }),
@ -185,15 +146,15 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/create-operation`, endpoint: `/api/oss/${itemID}/create-operation`,
request: { request: {
data: data, data: data,
successMessage: response => infoMsg.newOperation(response.new_operation.alias) successMessage: response => information.newOperation(response.new_operation.alias)
} }
}), }),
operationDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationDeleteDTO }) => operationDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationDeleteDTO }) =>
axiosPatch<IOperationDeleteDTO, IOperationSchemaDTO>({ axiosDelete<IOperationDeleteDTO, IOperationSchemaDTO>({
endpoint: `/api/oss/${itemID}/delete-operation`, endpoint: `/api/oss/${itemID}/delete-operation`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.operationDestroyed successMessage: information.operationDestroyed
} }
}), }),
inputCreate: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetOperation }) => inputCreate: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetOperation }) =>
@ -201,7 +162,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/create-input`, endpoint: `/api/oss/${itemID}/create-input`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.newLibraryItem successMessage: information.newLibraryItem
} }
}), }),
inputUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IInputUpdateDTO }) => inputUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IInputUpdateDTO }) =>
@ -209,7 +170,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/set-input`, endpoint: `/api/oss/${itemID}/set-input`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
operationUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationUpdateDTO }) => operationUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationUpdateDTO }) =>
@ -217,7 +178,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/update-operation`, endpoint: `/api/oss/${itemID}/update-operation`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
operationExecute: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetOperation }) => operationExecute: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetOperation }) =>
@ -225,16 +186,16 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/execute-operation`, endpoint: `/api/oss/${itemID}/execute-operation`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.operationExecuted successMessage: information.operationExecuted
} }
}), }),
relocateConstituents: (data: ICstRelocateDTO) => relocateConstituents: ({ itemID, data }: { itemID: LibraryItemID; data: ICstRelocateDTO }) =>
axiosPost<ICstRelocateDTO, IOperationSchemaDTO>({ axiosPost<ICstRelocateDTO, IOperationSchemaDTO>({
endpoint: `/api/oss/relocate-constituents`, endpoint: `/api/oss/${itemID}/relocate-constituents`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
getPredecessor: (data: ITargetCst) => getPredecessor: (data: ITargetCst) =>

View File

@ -1,6 +1,7 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { ITargetCst } from '@/features/rsform/models/rsform'; import { DataCallback } from '@/backend/apiTransport';
import { IConstituentaReference, ITargetCst } from '@/models/rsform';
import { ossApi } from './api'; import { ossApi } from './api';
@ -10,6 +11,9 @@ export const useFindPredecessor = () => {
mutationFn: ossApi.getPredecessor mutationFn: ossApi.getPredecessor
}); });
return { return {
findPredecessor: (data: ITargetCst) => mutation.mutateAsync(data) findPredecessor: (
data: ITargetCst, //
onSuccess?: DataCallback<IConstituentaReference>
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,8 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { DataCallback } from '@/backend/apiTransport';
import { LibraryItemID } from '@/features/library/models/library'; import { libraryApi } from '@/backend/library/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { ILibraryItem, LibraryItemID } from '@/models/library';
import { ITargetOperation, ossApi } from './api'; import { ITargetOperation, ossApi } from './api';
@ -20,7 +21,12 @@ export const useInputCreate = () => {
} }
}); });
return { return {
inputCreate: (data: { itemID: LibraryItemID; data: ITargetOperation }) => inputCreate: (
mutation.mutateAsync(data).then(response => response.new_schema) data: {
itemID: LibraryItemID; //
data: ITargetOperation;
},
onSuccess?: DataCallback<ILibraryItem>
) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.new_schema) })
}; };
}; };

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { libraryApi } from '@/backend/library/api';
import { LibraryItemID } from '@/features/library/models/library'; import { rsformsApi } from '@/backend/rsform/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { LibraryItemID } from '@/models/library';
import { IInputUpdateDTO, ossApi } from './api'; import { IInputUpdateDTO, ossApi } from './api';
@ -20,6 +20,6 @@ export const useInputUpdate = () => {
} }
}); });
return { return {
inputUpdate: (data: { itemID: LibraryItemID; data: IInputUpdateDTO }) => mutation.mutateAsync(data) inputUpdate: (data: { itemID: LibraryItemID; data: IInputUpdateDTO }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,6 +1,6 @@
import { useIsMutating } from '@tanstack/react-query'; import { useIsMutating } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { libraryApi } from '@/backend/library/api';
import { ossApi } from './api'; import { ossApi } from './api';

View File

@ -1,10 +1,10 @@
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
import { useLibrary, useLibrarySuspense } from '@/features/library/backend/useLibrary'; import { useLibrary, useLibrarySuspense } from '@/backend/library/useLibrary';
import { LibraryItemID } from '@/features/library/models/library'; import { OssLoader } from '@/backend/oss/OssLoader';
import { OssLoader } from '@/features/oss/backend/OssLoader'; import { LibraryItemID } from '@/models/library';
import { queryClient } from '../../../backend/queryClient'; import { queryClient } from '../queryClient';
import { ossApi } from './api'; import { ossApi } from './api';
export function useOss({ itemID }: { itemID?: LibraryItemID }) { export function useOss({ itemID }: { itemID?: LibraryItemID }) {

View File

@ -0,0 +1,29 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport';
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/models/library';
import { IOperationCreateDTO, IOperationDTO, ossApi } from './api';
export const useOperationCreate = () => {
const client = useQueryClient();
const { updateTimestamp } = useUpdateTimestamp();
const mutation = useMutation({
mutationKey: [ossApi.baseKey, 'operation-create'],
mutationFn: ossApi.operationCreate,
onSuccess: data => {
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.oss.id }).queryKey, data.oss);
updateTimestamp(data.oss.id);
}
});
return {
operationCreate: (
data: {
itemID: LibraryItemID; //
data: IOperationCreateDTO;
},
onSuccess?: DataCallback<IOperationDTO>
) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.new_operation) })
};
};

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { libraryApi } from '@/backend/library/api';
import { LibraryItemID } from '@/features/library/models/library'; import { rsformsApi } from '@/backend/rsform/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { LibraryItemID } from '@/models/library';
import { IOperationDeleteDTO, ossApi } from './api'; import { IOperationDeleteDTO, ossApi } from './api';
@ -20,6 +20,6 @@ export const useOperationDelete = () => {
} }
}); });
return { return {
operationDelete: (data: { itemID: LibraryItemID; data: IOperationDeleteDTO }) => mutation.mutateAsync(data) operationDelete: (data: { itemID: LibraryItemID; data: IOperationDeleteDTO }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { libraryApi } from '@/backend/library/api';
import { LibraryItemID } from '@/features/library/models/library'; import { rsformsApi } from '@/backend/rsform/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { LibraryItemID } from '@/models/library';
import { ITargetOperation, ossApi } from './api'; import { ITargetOperation, ossApi } from './api';
@ -20,6 +20,6 @@ export const useOperationExecute = () => {
} }
}); });
return { return {
operationExecute: (data: { itemID: LibraryItemID; data: ITargetOperation }) => mutation.mutateAsync(data) operationExecute: (data: { itemID: LibraryItemID; data: ITargetOperation }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { libraryApi } from '@/backend/library/api';
import { ILibraryItem, LibraryItemID } from '@/features/library/models/library'; import { rsformsApi } from '@/backend/rsform/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { ILibraryItem, LibraryItemID } from '@/models/library';
import { IOperationUpdateDTO, ossApi } from './api'; import { IOperationUpdateDTO, ossApi } from './api';
@ -30,6 +30,6 @@ export const useOperationUpdate = () => {
} }
}); });
return { return {
operationUpdate: (data: { itemID: LibraryItemID; data: IOperationUpdateDTO }) => mutation.mutateAsync(data) operationUpdate: (data: { itemID: LibraryItemID; data: IOperationUpdateDTO }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,7 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { libraryApi } from '@/backend/library/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/backend/rsform/api';
import { LibraryItemID } from '@/models/library';
import { ICstRelocateDTO, ossApi } from './api'; import { ICstRelocateDTO, ossApi } from './api';
@ -19,6 +20,6 @@ export const useRelocateConstituents = () => {
} }
}); });
return { return {
relocateConstituents: (data: ICstRelocateDTO) => mutation.mutateAsync(data) relocateConstituents: (data: { itemID: LibraryItemID; data: ICstRelocateDTO }) => mutation.mutate(data)
}; };
}; };

View File

@ -0,0 +1,26 @@
import { useMutation } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/models/library';
import { IOperationPosition } from '@/models/oss';
import { ossApi } from './api';
export const useUpdatePositions = () => {
const { updateTimestamp } = useUpdateTimestamp();
const mutation = useMutation({
mutationKey: [ossApi.baseKey, 'update-positions'],
mutationFn: ossApi.updatePositions,
onSuccess: (_, variables) => updateTimestamp(variables.itemID)
});
return {
updatePositions: (
data: {
itemID: LibraryItemID; //
positions: IOperationPosition[];
isSilent?: boolean;
},
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess })
};
};

View File

@ -1,6 +1,6 @@
import { QueryClient } from '@tanstack/react-query'; import { QueryClient } from '@tanstack/react-query';
import { AxiosError } from 'axios';
import { AxiosError } from './apiTransport';
import { DELAYS } from './configuration'; import { DELAYS } from './configuration';
declare module '@tanstack/react-query' { declare module '@tanstack/react-query' {

View File

@ -2,13 +2,13 @@
* Module: RSForm data loading and processing. * Module: RSForm data loading and processing.
*/ */
import { LibraryItemID } from '@/features/library/models/library';
import { Graph } from '@/models/Graph'; import { Graph } from '@/models/Graph';
import { LibraryItemID } from '@/models/library';
import { ConstituentaID, CstType, IConstituenta, IRSForm, IRSFormStats } from '@/models/rsform';
import { inferClass, inferStatus, inferTemplate, isBaseSet, isFunctional } from '@/models/rsformAPI';
import { ParsingStatus, ValueClass } from '@/models/rslang';
import { extractGlobals, isSimpleExpression, splitTemplateDefinition } from '@/models/rslangAPI';
import { ConstituentaID, CstType, IConstituenta, IRSForm, IRSFormStats } from '../models/rsform';
import { inferClass, inferStatus, inferTemplate, isBaseSet, isFunctional } from '../models/rsformAPI';
import { ParsingStatus, ValueClass } from '../models/rslang';
import { extractGlobals, isSimpleExpression, splitTemplateDefinition } from '../models/rslangAPI';
import { IRSFormDTO } from './api'; import { IRSFormDTO } from './api';
/** /**

View File

@ -1,16 +1,9 @@
import { queryOptions } from '@tanstack/react-query'; import { queryOptions } from '@tanstack/react-query';
import { z } from 'zod';
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { import { ILibraryItemReference, ILibraryItemVersioned, LibraryItemID, VersionID } from '@/models/library';
ILibraryItemReference, import { ICstSubstitute, ICstSubstitutions } from '@/models/oss';
ILibraryItemVersioned,
LibraryItemID,
VersionID
} from '@/features/library/models/library';
import { errorMsg, infoMsg } from '@/utils/labels';
import { import {
ConstituentaID, ConstituentaID,
CstType, CstType,
@ -19,8 +12,9 @@ import {
IInheritanceInfo, IInheritanceInfo,
ITargetCst, ITargetCst,
TermForm TermForm
} from '../models/rsform'; } from '@/models/rsform';
import { IArgumentInfo, IExpressionParse, ParsingStatus, ValueClass } from '../models/rslang'; import { IArgumentInfo, IExpressionParse, ParsingStatus, ValueClass } from '@/models/rslang';
import { information } from '@/utils/labels';
/** /**
* Represents {@link IConstituenta} data from server. * Represents {@link IConstituenta} data from server.
@ -80,35 +74,25 @@ export interface ICstCreatedResponse {
/** /**
* Represents data, used in updating persistent attributes in {@link IConstituenta}. * Represents data, used in updating persistent attributes in {@link IConstituenta}.
*/ */
export const schemaCstUpdate = z.object({ export interface ICstUpdateDTO {
target: z.number(), target: ConstituentaID;
item_data: z.object({ item_data: {
convention: z.string().optional(), convention?: string;
definition_formal: z.string().optional(), definition_formal?: string;
definition_raw: z.string().optional(), definition_raw?: string;
term_raw: z.string().optional(), term_raw?: string;
term_forms: z.array(z.object({ text: z.string(), tags: z.string() })).optional() term_forms?: TermForm[];
}) };
}); }
/**
* Represents data, used in updating persistent attributes in {@link IConstituenta}.
*/
export type ICstUpdateDTO = z.infer<typeof schemaCstUpdate>;
/** /**
* Represents data, used in renaming {@link IConstituenta}. * Represents data, used in renaming {@link IConstituenta}.
*/ */
export const schemaCstRename = z.object({ export interface ICstRenameDTO {
target: z.number(), alias: string;
alias: z.string(), cst_type: CstType;
cst_type: z.nativeEnum(CstType) target: ConstituentaID;
}); }
/**
* Represents data, used in renaming {@link IConstituenta}.
*/
export type ICstRenameDTO = z.infer<typeof schemaCstRename>;
/** /**
* Represents data, used in ordering a list of {@link IConstituenta}. * Represents data, used in ordering a list of {@link IConstituenta}.
@ -126,33 +110,15 @@ export interface IProduceStructureResponse {
schema: IRSFormDTO; schema: IRSFormDTO;
} }
/**
* Represents data, used in merging single {@link IConstituenta}.
*/
export const schemaCstSubstitute = z.object({
original: z.number(),
substitution: z.number()
});
/**
* Represents data, used in merging single {@link IConstituenta}.
*/
export type ICstSubstitute = z.infer<typeof schemaCstSubstitute>;
/** /**
* Represents input data for inline synthesis. * Represents input data for inline synthesis.
*/ */
export const schemaInlineSynthesis = z.object({ export interface IInlineSynthesisDTO {
receiver: z.number(), receiver: LibraryItemID;
source: z.number().nullable(), source: LibraryItemID;
items: z.array(z.number()), items: ConstituentaID[];
substitutions: z.array(schemaCstSubstitute) substitutions: ICstSubstitute[];
}); }
/**
* Represents input data for inline synthesis.
*/
export type IInlineSynthesisDTO = z.infer<typeof schemaInlineSynthesis>;
/** /**
* Represents {@link IConstituenta} data, used for checking expression. * Represents {@link IConstituenta} data, used for checking expression.
@ -163,18 +129,6 @@ export interface ICheckConstituentaDTO {
definition_formal: string; definition_formal: string;
} }
/**
* Represents data, used in renaming {@link IConstituenta}.
*/
export const schemaCstSubstitutions = z.object({
substitutions: z.array(schemaCstSubstitute).min(1, { message: errorMsg.emptySubstitutions })
});
/**
* Represents data, used in merging multiple {@link IConstituenta}.
*/
export type ICstSubstitutionsDTO = z.infer<typeof schemaCstSubstitutions>;
export const rsformsApi = { export const rsformsApi = {
baseKey: 'rsform', baseKey: 'rsform',
@ -202,7 +156,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${data.itemID}/load-trs`, endpoint: `/api/rsforms/${data.itemID}/load-trs`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.uploadSuccess successMessage: information.uploadSuccess
}, },
options: { options: {
headers: { headers: {
@ -216,7 +170,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/create-cst`, endpoint: `/api/rsforms/${itemID}/create-cst`,
request: { request: {
data: data, data: data,
successMessage: response => infoMsg.newConstituent(response.new_cst.alias) successMessage: response => information.newConstituent(response.new_cst.alias)
} }
}), }),
cstUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: ICstUpdateDTO }) => cstUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: ICstUpdateDTO }) =>
@ -224,15 +178,15 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/update-cst`, endpoint: `/api/rsforms/${itemID}/update-cst`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
cstDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IConstituentaList }) => cstDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IConstituentaList }) =>
axiosPatch<IConstituentaList, IRSFormDTO>({ axiosDelete<IConstituentaList, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/delete-multiple-cst`, endpoint: `/api/rsforms/${itemID}/delete-multiple-cst`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.constituentsDestroyed(data.items.length) successMessage: information.constituentsDestroyed(data.items.length)
} }
}), }),
cstRename: ({ itemID, data }: { itemID: LibraryItemID; data: ICstRenameDTO }) => cstRename: ({ itemID, data }: { itemID: LibraryItemID; data: ICstRenameDTO }) =>
@ -240,15 +194,15 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/rename-cst`, endpoint: `/api/rsforms/${itemID}/rename-cst`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}), }),
cstSubstitute: ({ itemID, data }: { itemID: LibraryItemID; data: ICstSubstitutionsDTO }) => cstSubstitute: ({ itemID, data }: { itemID: LibraryItemID; data: ICstSubstitutions }) =>
axiosPatch<ICstSubstitutionsDTO, IRSFormDTO>({ axiosPatch<ICstSubstitutions, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/substitute`, endpoint: `/api/rsforms/${itemID}/substitute`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.substituteSingle successMessage: information.substituteSingle
} }
}), }),
cstMove: ({ itemID, data }: { itemID: LibraryItemID; data: ICstMoveDTO }) => cstMove: ({ itemID, data }: { itemID: LibraryItemID; data: ICstMoveDTO }) =>
@ -258,30 +212,30 @@ export const rsformsApi = {
}), }),
produceStructure: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetCst }) => produceStructure: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetCst }) =>
axiosPatch<ITargetCst, IProduceStructureResponse>({ axiosPost<ITargetCst, IProduceStructureResponse>({
endpoint: `/api/rsforms/${itemID}/produce-structure`, endpoint: `/api/rsforms/${itemID}/produce-structure`,
request: { request: {
data: data, data: data,
successMessage: response => infoMsg.addedConstituents(response.cst_list.length) successMessage: response => information.addedConstituents(response.cst_list.length)
} }
}), }),
inlineSynthesis: (data: IInlineSynthesisDTO) => inlineSynthesis: ({ itemID, data }: { itemID: LibraryItemID; data: IInlineSynthesisDTO }) =>
axiosPatch<IInlineSynthesisDTO, IRSFormDTO>({ axiosPost<IInlineSynthesisDTO, IRSFormDTO>({
endpoint: `/api/rsforms/inline-synthesis`, endpoint: `/api/rsforms/${itemID}/inline-synthesis`,
request: { request: {
data: data, data: data,
successMessage: infoMsg.inlineSynthesisComplete successMessage: information.inlineSynthesisComplete
} }
}), }),
restoreOrder: ({ itemID }: { itemID: LibraryItemID }) => restoreOrder: ({ itemID }: { itemID: LibraryItemID }) =>
axiosPatch<undefined, IRSFormDTO>({ axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/restore-order`, endpoint: `/api/rsforms/${itemID}/restore-order`,
request: { successMessage: infoMsg.reorderComplete } request: { successMessage: information.reorderComplete }
}), }),
resetAliases: ({ itemID }: { itemID: LibraryItemID }) => resetAliases: ({ itemID }: { itemID: LibraryItemID }) =>
axiosPatch<undefined, IRSFormDTO>({ axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/reset-aliases`, endpoint: `/api/rsforms/${itemID}/reset-aliases`,
request: { successMessage: infoMsg.reindexComplete } request: { successMessage: information.reindexComplete }
}), }),
checkConstituenta: ({ itemID, data }: { itemID: LibraryItemID; data: ICheckConstituentaDTO }) => checkConstituenta: ({ itemID, data }: { itemID: LibraryItemID; data: ICheckConstituentaDTO }) =>

View File

@ -0,0 +1,25 @@
import { useMutation } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport';
import { LibraryItemID } from '@/models/library';
import { IExpressionParse } from '@/models/rslang';
import { ICheckConstituentaDTO, rsformsApi } from './api';
export const useCheckConstituenta = () => {
const mutation = useMutation({
mutationKey: [rsformsApi.baseKey, 'check-constituenta'],
mutationFn: rsformsApi.checkConstituenta
});
return {
checkConstituenta: (
data: {
itemID: LibraryItemID; //
data: ICheckConstituentaDTO;
},
onSuccess?: DataCallback<IExpressionParse>
) => mutation.mutate(data, { onSuccess }),
isPending: mutation.isPending,
error: mutation.error
};
};

View File

@ -1,8 +1,10 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { DataCallback } from '@/backend/apiTransport';
import { LibraryItemID } from '@/features/library/models/library'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/backend/oss/api';
import { LibraryItemID } from '@/models/library';
import { IConstituentaMeta } from '@/models/rsform';
import { ICstCreateDTO, rsformsApi } from './api'; import { ICstCreateDTO, rsformsApi } from './api';
@ -26,7 +28,12 @@ export const useCstCreate = () => {
} }
}); });
return { return {
cstCreate: (data: { itemID: LibraryItemID; data: ICstCreateDTO }) => cstCreate: (
mutation.mutateAsync(data).then(response => response.new_cst) data: {
itemID: LibraryItemID; //
data: ICstCreateDTO;
},
onSuccess?: DataCallback<IConstituentaMeta>
) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.new_cst) })
}; };
}; };

View File

@ -1,10 +1,10 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/features/library/models/library'; import { ossApi } from '@/backend/oss/api';
import { ossApi } from '@/features/oss/backend/api'; import { LibraryItemID } from '@/models/library';
import { IConstituentaList } from '@/models/rsform';
import { IConstituentaList } from '../models/rsform';
import { rsformsApi } from './api'; import { rsformsApi } from './api';
export const useCstDelete = () => { export const useCstDelete = () => {
@ -27,6 +27,12 @@ export const useCstDelete = () => {
} }
}); });
return { return {
cstDelete: (data: { itemID: LibraryItemID; data: IConstituentaList }) => mutation.mutateAsync(data) cstDelete: (
data: {
itemID: LibraryItemID; //
data: IConstituentaList;
},
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,7 +1,7 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/features/library/models/library'; import { LibraryItemID } from '@/models/library';
import { ICstMoveDTO, rsformsApi } from './api'; import { ICstMoveDTO, rsformsApi } from './api';
@ -17,6 +17,12 @@ export const useCstMove = () => {
} }
}); });
return { return {
cstMove: (data: { itemID: LibraryItemID; data: ICstMoveDTO }) => mutation.mutateAsync(data) cstMove: (
data: {
itemID: LibraryItemID; //
data: ICstMoveDTO;
},
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/features/library/models/library'; import { ossApi } from '@/backend/oss/api';
import { ossApi } from '@/features/oss/backend/api'; import { LibraryItemID } from '@/models/library';
import { ICstRenameDTO, rsformsApi } from './api'; import { ICstRenameDTO, rsformsApi } from './api';
@ -26,6 +26,6 @@ export const useCstRename = () => {
} }
}); });
return { return {
cstRename: (data: { itemID: LibraryItemID; data: ICstRenameDTO }) => mutation.mutateAsync(data) cstRename: (data: { itemID: LibraryItemID; data: ICstRenameDTO }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,10 +1,11 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/features/library/models/library'; import { ossApi } from '@/backend/oss/api';
import { ossApi } from '@/features/oss/backend/api'; import { LibraryItemID } from '@/models/library';
import { ICstSubstitutions } from '@/models/oss';
import { ICstSubstitutionsDTO, rsformsApi } from './api'; import { rsformsApi } from './api';
export const useCstSubstitute = () => { export const useCstSubstitute = () => {
const client = useQueryClient(); const client = useQueryClient();
@ -26,6 +27,12 @@ export const useCstSubstitute = () => {
} }
}); });
return { return {
cstSubstitute: (data: { itemID: LibraryItemID; data: ICstSubstitutionsDTO }) => mutation.mutateAsync(data) cstSubstitute: (
data: {
itemID: LibraryItemID; //
data: ICstSubstitutions;
},
onSuccess?: () => void
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -0,0 +1,38 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { ossApi } from '@/backend/oss/api';
import { LibraryItemID } from '@/models/library';
import { ICstUpdateDTO, rsformsApi } from './api';
export const useCstUpdate = () => {
const client = useQueryClient();
const { updateTimestamp } = useUpdateTimestamp();
const mutation = useMutation({
mutationKey: [rsformsApi.baseKey, 'update-cst'],
mutationFn: rsformsApi.cstUpdate,
onSuccess: (newCst, variables) => {
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey, prev =>
!prev
? undefined
: {
...prev,
items: prev.items.map(item => (item.id === newCst.id ? { ...item, ...newCst } : item))
}
);
updateTimestamp(variables.itemID);
return Promise.allSettled([
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
client.invalidateQueries({
queryKey: [rsformsApi.baseKey],
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== variables.itemID
})
]);
}
});
return {
cstUpdate: (data: { itemID: LibraryItemID; data: ICstUpdateDTO }) => mutation.mutate(data)
};
};

View File

@ -1,6 +1,6 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { LibraryItemID, VersionID } from '@/features/library/models/library'; import { LibraryItemID, VersionID } from '@/models/library';
import { rsformsApi } from './api'; import { rsformsApi } from './api';
@ -10,6 +10,12 @@ export const useDownloadRSForm = () => {
mutationFn: rsformsApi.download mutationFn: rsformsApi.download
}); });
return { return {
download: (data: { itemID: LibraryItemID; version?: VersionID }) => mutation.mutateAsync(data) download: (
data: {
itemID: LibraryItemID; //
version?: VersionID;
},
onSuccess?: (data: Blob) => void
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,9 +1,11 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { DataCallback } from '@/backend/apiTransport';
import { ossApi } from '@/features/oss/backend/api'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { ossApi } from '@/backend/oss/api';
import { LibraryItemID } from '@/models/library';
import { IInlineSynthesisDTO, rsformsApi } from './api'; import { IInlineSynthesisDTO, IRSFormDTO, rsformsApi } from './api';
export const useInlineSynthesis = () => { export const useInlineSynthesis = () => {
const client = useQueryClient(); const client = useQueryClient();
@ -25,6 +27,12 @@ export const useInlineSynthesis = () => {
} }
}); });
return { return {
inlineSynthesis: (data: IInlineSynthesisDTO) => mutation.mutateAsync(data) inlineSynthesis: (
data: {
itemID: LibraryItemID; //
data: IInlineSynthesisDTO;
},
onSuccess?: DataCallback<IRSFormDTO>
) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,6 +1,6 @@
import { useIsMutating } from '@tanstack/react-query'; import { useIsMutating } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { libraryApi } from '@/backend/library/api';
import { rsformsApi } from './api'; import { rsformsApi } from './api';

View File

@ -1,10 +1,11 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { DataCallback } from '@/backend/apiTransport';
import { LibraryItemID } from '@/features/library/models/library'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/backend/oss/api';
import { LibraryItemID } from '@/models/library';
import { ConstituentaID, ITargetCst } from '@/models/rsform';
import { ITargetCst } from '../models/rsform';
import { rsformsApi } from './api'; import { rsformsApi } from './api';
export const useProduceStructure = () => { export const useProduceStructure = () => {
@ -27,7 +28,12 @@ export const useProduceStructure = () => {
} }
}); });
return { return {
produceStructure: (data: { itemID: LibraryItemID; data: ITargetCst }) => produceStructure: (
mutation.mutateAsync(data).then(response => response.cst_list) data: {
itemID: LibraryItemID; //
data: ITargetCst;
},
onSuccess?: DataCallback<ConstituentaID[]>
) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.cst_list) })
}; };
}; };

View File

@ -1,10 +1,10 @@
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
import { LibraryItemID, VersionID } from '@/features/library/models/library'; import { RSFormLoader } from '@/backend/rsform/RSFormLoader';
import { LibraryItemID, VersionID } from '@/models/library';
import { queryClient } from '../../../backend/queryClient'; import { queryClient } from '../queryClient';
import { rsformsApi } from './api'; import { rsformsApi } from './api';
import { RSFormLoader } from './RSFormLoader';
export function useRSForm({ itemID, version }: { itemID?: LibraryItemID; version?: VersionID }) { export function useRSForm({ itemID, version }: { itemID?: LibraryItemID; version?: VersionID }) {
const { data, isLoading, error } = useQuery({ const { data, isLoading, error } = useQuery({

View File

@ -1,13 +1,13 @@
import { useSuspenseQueries } from '@tanstack/react-query'; import { useQueries } from '@tanstack/react-query';
import { LibraryItemID } from '@/features/library/models/library'; import { RSFormLoader } from '@/backend/rsform/RSFormLoader';
import { LibraryItemID } from '@/models/library';
import { DELAYS } from '../../../backend/configuration'; import { DELAYS } from '../configuration';
import { rsformsApi } from './api'; import { rsformsApi } from './api';
import { RSFormLoader } from './RSFormLoader';
export function useRSForms(itemIDs: LibraryItemID[]) { export function useRSForms(itemIDs: LibraryItemID[]) {
const results = useSuspenseQueries({ const results = useQueries({
queries: itemIDs.map(itemID => ({ queries: itemIDs.map(itemID => ({
...rsformsApi.getRSFormQueryOptions({ itemID }), ...rsformsApi.getRSFormQueryOptions({ itemID }),
enabled: itemIDs.length > 0, enabled: itemIDs.length > 0,

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/features/library/models/library'; import { ossApi } from '@/backend/oss/api';
import { ossApi } from '@/features/oss/backend/api'; import { LibraryItemID } from '@/models/library';
import { rsformsApi } from './api'; import { rsformsApi } from './api';
@ -26,6 +26,6 @@ export const useResetAliases = () => {
} }
}); });
return { return {
resetAliases: (data: { itemID: LibraryItemID }) => mutation.mutateAsync(data) resetAliases: (data: { itemID: LibraryItemID }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,7 +1,7 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/features/library/models/library'; import { LibraryItemID } from '@/models/library';
import { rsformsApi } from './api'; import { rsformsApi } from './api';
@ -17,6 +17,6 @@ export const useRestoreOrder = () => {
} }
}); });
return { return {
restoreOrder: (data: { itemID: LibraryItemID }) => mutation.mutateAsync(data) restoreOrder: (data: { itemID: LibraryItemID }) => mutation.mutate(data)
}; };
}; };

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { libraryApi } from '@/features/library/backend/api'; import { libraryApi } from '@/backend/library/api';
import { ILibraryItem } from '@/features/library/models/library'; import { ossApi } from '@/backend/oss/api';
import { ossApi } from '@/features/oss/backend/api'; import { ILibraryItem } from '@/models/library';
import { IRSFormUploadDTO, rsformsApi } from './api'; import { IRSFormUploadDTO, rsformsApi } from './api';
@ -27,6 +27,6 @@ export const useUploadTRS = () => {
} }
}); });
return { return {
upload: (data: IRSFormUploadDTO) => mutation.mutateAsync(data) upload: (data: IRSFormUploadDTO) => mutation.mutate(data)
}; };
}; };

View File

@ -3,36 +3,35 @@ import { z } from 'zod';
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { IUserInfo, IUserProfile } from '@/models/user';
import { patterns } from '@/utils/constants'; import { patterns } from '@/utils/constants';
import { errorMsg, infoMsg } from '@/utils/labels'; import { errors, information } from '@/utils/labels';
import { IUserInfo, IUserProfile } from '../models/user';
/** /**
* Represents signup data, used to create new users. * Represents signup data, used to create new users.
*/ */
export const schemaUserSignup = z export const UserSignupSchema = z
.object({ .object({
username: z.string().nonempty(errorMsg.requiredField).regex(RegExp(patterns.login), errorMsg.loginFormat), username: z.string().nonempty(errors.requiredField).regex(RegExp(patterns.login), errors.loginFormat),
email: z.string().email(errorMsg.emailField), email: z.string().email(errors.emailField),
first_name: z.string(), first_name: z.string(),
last_name: z.string(), last_name: z.string(),
password: z.string().nonempty(errorMsg.requiredField), password: z.string().nonempty(errors.requiredField),
password2: z.string().nonempty(errorMsg.requiredField) password2: z.string().nonempty(errors.requiredField)
}) })
.refine(schema => schema.password === schema.password2, { path: ['password2'], message: errorMsg.passwordsMismatch }); .refine(schema => schema.password === schema.password2, { path: ['password2'], message: errors.passwordsMismatch });
/** /**
* Represents signup data, used to create new users. * Represents signup data, used to create new users.
*/ */
export type IUserSignupDTO = z.infer<typeof schemaUserSignup>; export type IUserSignupDTO = z.infer<typeof UserSignupSchema>;
/** /**
* Represents user data, intended to update user profile in persistent storage. * Represents user data, intended to update user profile in persistent storage.
*/ */
export const schemaUpdateProfile = z.object({ export const UpdateProfileSchema = z.object({
email: z.string().email(errorMsg.emailField), email: z.string().email(errors.emailField),
first_name: z.string(), first_name: z.string(),
last_name: z.string() last_name: z.string()
}); });
@ -40,7 +39,7 @@ export const schemaUpdateProfile = z.object({
/** /**
* Represents user data, intended to update user profile in persistent storage. * Represents user data, intended to update user profile in persistent storage.
*/ */
export type IUpdateProfileDTO = z.infer<typeof schemaUpdateProfile>; export type IUpdateProfileDTO = z.infer<typeof UpdateProfileSchema>;
export const usersApi = { export const usersApi = {
baseKey: 'users', baseKey: 'users',
@ -70,7 +69,7 @@ export const usersApi = {
endpoint: '/users/api/signup', endpoint: '/users/api/signup',
request: { request: {
data: data, data: data,
successMessage: createdUser => infoMsg.newUser(createdUser.username) successMessage: createdUser => information.newUser(createdUser.username)
} }
}), }),
@ -79,7 +78,7 @@ export const usersApi = {
endpoint: '/users/api/profile', endpoint: '/users/api/profile',
request: { request: {
data: data, data: data,
successMessage: infoMsg.changesSaved successMessage: information.changesSaved
} }
}) })
}; };

View File

@ -1,6 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IUserSignupDTO, usersApi } from './api'; import { DataCallback } from '@/backend/apiTransport';
import { IUserSignupDTO, usersApi } from '@/backend/users/api';
import { IUserProfile } from '@/models/user';
export const useSignup = () => { export const useSignup = () => {
const client = useQueryClient(); const client = useQueryClient();
@ -10,7 +12,10 @@ export const useSignup = () => {
onSuccess: () => client.invalidateQueries({ queryKey: usersApi.getUsersQueryOptions().queryKey }) onSuccess: () => client.invalidateQueries({ queryKey: usersApi.getUsersQueryOptions().queryKey })
}); });
return { return {
signup: (data: IUserSignupDTO) => mutation.mutateAsync(data), signup: (
data: IUserSignupDTO, //
onSuccess?: DataCallback<IUserProfile>
) => mutation.mutate(data, { onSuccess }),
isPending: mutation.isPending, isPending: mutation.isPending,
error: mutation.error, error: mutation.error,
reset: mutation.reset reset: mutation.reset

View File

@ -1,5 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IUserProfile } from '@/models/user';
import { DataCallback } from '../apiTransport';
import { IUpdateProfileDTO, usersApi } from './api'; import { IUpdateProfileDTO, usersApi } from './api';
export const useUpdateProfile = () => { export const useUpdateProfile = () => {
@ -13,7 +16,8 @@ export const useUpdateProfile = () => {
} }
}); });
return { return {
updateProfile: (data: IUpdateProfileDTO) => mutation.mutateAsync(data), updateProfile: (data: IUpdateProfileDTO, onSuccess?: DataCallback<IUserProfile>) =>
mutation.mutate(data, { onSuccess }),
isPending: mutation.isPending, isPending: mutation.isPending,
error: mutation.error, error: mutation.error,
reset: mutation.reset reset: mutation.reset

View File

@ -1,4 +0,0 @@
export { Divider } from './Divider';
export { FlexColumn } from './FlexColumn';
export { Overlay } from './Overlay';
export { type PlacesType, Tooltip } from './Tooltip';

View File

@ -1,5 +0,0 @@
export { Button } from './Button';
export { MiniButton } from './MiniButton';
export { SelectorButton } from './SelectorButton';
export { SubmitButton } from './SubmitButton';
export { TextURL } from './TextURL';

View File

@ -1,6 +1,6 @@
import { AccessPolicy, LibraryItemType, LocationHead } from '@/features/library/models/library'; import { AccessPolicy, LibraryItemType, LocationHead } from '@/models/library';
import { CstType, ExpressionStatus } from '@/features/rsform/models/rsform'; import { CstMatchMode, DependencyMode } from '@/models/miscellaneous';
import { CstMatchMode, DependencyMode } from '@/features/rsform/stores/cstSearch'; import { CstType, ExpressionStatus } from '@/models/rsform';
import { import {
IconAlias, IconAlias,

View File

@ -1,4 +0,0 @@
export { Dropdown } from './Dropdown';
export { DropdownButton } from './DropdownButton';
export { DropdownCheckbox } from './DropdownCheckbox';
export { useDropdown } from './useDropdown';

View File

@ -1,8 +1,8 @@
import { urls, useConceptNavigation } from '@/app'; import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
import { TextURL } from '@/components/Control'; import { urls } from '@/app/urls';
import { useAuthSuspense } from '@/backend/auth/useAuth';
import { useAuthSuspense } from '../backend/useAuth'; import { useLogout } from '@/backend/auth/useLogout';
import { useLogout } from '../backend/useLogout'; import TextURL from '@/components/ui/TextURL';
function ExpectedAnonymous() { function ExpectedAnonymous() {
const { user } = useAuthSuspense(); const { user } = useAuthSuspense();
@ -10,7 +10,7 @@ function ExpectedAnonymous() {
const router = useConceptNavigation(); const router = useConceptNavigation();
function logoutAndRedirect() { function logoutAndRedirect() {
void logout().then(() => router.push(urls.login)); logout(() => router.push(urls.login));
} }
return ( return (

View File

@ -1,10 +0,0 @@
export { Checkbox, type CheckboxProps } from './Checkbox';
export { CheckboxTristate } from './CheckboxTristate';
export { ErrorField } from './ErrorField';
export { FileInput } from './FileInput';
export { Label } from './Label';
export { SelectMulti, type SelectMultiProps } from './SelectMulti';
export { SelectSingle, type SelectSingleProps } from './SelectSingle';
export { SelectTree } from './SelectTree';
export { TextArea } from './TextArea';
export { TextInput } from './TextInput';

View File

@ -1,19 +0,0 @@
'use client';
import clsx from 'clsx';
interface ModalBackdropProps {
onHide: () => void;
}
export function ModalBackdrop({ onHide }: ModalBackdropProps) {
return (
<>
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
<div
className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')}
onClick={onHide}
/>
</>
);
}

View File

@ -1,79 +0,0 @@
'use client';
import clsx from 'clsx';
import useEscapeKey from '@/hooks/useEscapeKey';
import { useDialogsStore } from '@/stores/dialogs';
import { PARAMETER } from '@/utils/constants';
import { prepareTooltip } from '@/utils/utils';
import { Button, MiniButton } from '../Control';
import { IconClose } from '../Icons';
import { BadgeHelp } from '../shared/BadgeHelp';
import { ModalBackdrop } from './ModalBackdrop';
import { ModalProps } from './ModalForm';
interface ModalViewProps extends ModalProps {}
/**
* Displays a customizable modal window with submit form.
*/
export function ModalView({
children,
className,
header,
overflowVisible,
helpTopic,
hideHelpWhen,
...restProps
}: React.PropsWithChildren<ModalViewProps>) {
const hideDialog = useDialogsStore(state => state.hideDialog);
useEscapeKey(hideDialog);
return (
<div className='fixed top-0 left-0 w-full h-full z-modal cursor-default'>
<ModalBackdrop onHide={hideDialog} />
<div
className={clsx(
'cc-animate-modal',
'z-modal absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
'border rounded-xl bg-prim-100'
)}
>
{helpTopic && !hideHelpWhen?.() ? (
<div className='float-left mt-2 ml-2'>
<BadgeHelp topic={helpTopic} className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')} padding='p-0' />
</div>
) : null}
<MiniButton
noPadding
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
icon={<IconClose size='1.25rem' />}
className='float-right mt-2 mr-2'
onClick={hideDialog}
/>
{header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null}
<div
className={clsx(
'overscroll-contain max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)] outline-none',
{
'overflow-auto': !overflowVisible,
'overflow-visible': overflowVisible
},
className
)}
{...restProps}
>
{children}
</div>
<div className='z-modalControls my-2 flex gap-12 justify-center text-sm'>
<Button text='Закрыть' className='min-w-[7rem]' onClick={hideDialog} />
</div>
</div>
</div>
);
}

View File

@ -1,3 +0,0 @@
export { ModalForm } from './ModalForm';
export { ModalLoader } from './ModalLoader';
export { ModalView } from './ModalView';

View File

@ -8,13 +8,13 @@ import clsx from 'clsx';
import { EditorView } from 'codemirror'; import { EditorView } from 'codemirror';
import { forwardRef, useRef } from 'react'; import { forwardRef, useRef } from 'react';
import { Label } from '@/components/Input'; import Label from '@/components/ui/Label';
import { ConstituentaID, IRSForm } from '@/models/rsform';
import { generateAlias, getCstTypePrefix, guessCstType } from '@/models/rsformAPI';
import { extractGlobals } from '@/models/rslangAPI';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';
import { APP_COLORS } from '@/styling/colors'; import { APP_COLORS } from '@/styling/color';
import { ConstituentaID, IRSForm } from '../../models/rsform';
import { generateAlias, getCstTypePrefix, guessCstType } from '../../models/rsformAPI';
import { extractGlobals } from '../../models/rslangAPI';
import { ccBracketMatching } from './bracketMatching'; import { ccBracketMatching } from './bracketMatching';
import { rsNavigation } from './clickNavigation'; import { rsNavigation } from './clickNavigation';
import { RSLanguage } from './rslang'; import { RSLanguage } from './rslang';

View File

@ -1,7 +1,7 @@
import { bracketMatching, MatchResult } from '@codemirror/language'; import { bracketMatching, MatchResult } from '@codemirror/language';
import { Decoration, EditorView } from '@codemirror/view'; import { Decoration, EditorView } from '@codemirror/view';
import { BRACKETS_THEME } from '../../colors'; import { BRACKETS_THEME } from '@/styling/color';
const matchingMark = Decoration.mark({ class: 'cc-matchingBracket' }); const matchingMark = Decoration.mark({ class: 'cc-matchingBracket' });
const nonMatchingMark = Decoration.mark({ class: 'cc-nonmatchingBracket' }); const nonMatchingMark = Decoration.mark({ class: 'cc-nonmatchingBracket' });

View File

@ -1,10 +1,9 @@
import { Extension } from '@codemirror/state'; import { Extension } from '@codemirror/state';
import { EditorView } from '@uiw/react-codemirror'; import { EditorView } from '@uiw/react-codemirror';
import { ConstituentaID, IRSForm } from '@/models/rsform';
import { findAliasAt } from '@/utils/codemirror'; import { findAliasAt } from '@/utils/codemirror';
import { ConstituentaID, IRSForm } from '../../models/rsform';
const navigationProducer = (schema: IRSForm, onOpenEdit: (cstID: ConstituentaID) => void) => { const navigationProducer = (schema: IRSForm, onOpenEdit: (cstID: ConstituentaID) => void) => {
return EditorView.domEventHandlers({ return EditorView.domEventHandlers({
click: (event: MouseEvent, view: EditorView) => { click: (event: MouseEvent, view: EditorView) => {

Some files were not shown because too many files have changed in this diff Show More