From f7f52f8201f8100898c124cf4f6b1e61ce825de7 Mon Sep 17 00:00:00 2001 From: Milo Thurston Date: Wed, 22 Jul 2026 16:24:31 +0100 Subject: [PATCH 01/12] Added page, fixed tests. #2839 --- package-lock.json | 547 +++++++----------- package.json | 6 +- src/router/index.js | 6 + src/router/routes.js | 1 + .../Static/Documentation/Documentation.vue | 90 +++ tests/setup.js | 12 +- .../unit/components/ChatBot/FionaChat.spec.js | 3 + .../CuratorSummaryStatistics.spec.js | 4 +- .../RecordEditsByMonth.spec.js | 8 +- .../RecordsCreatedByMonth.spec.js | 8 +- .../RecordsNeedingReview.spec.js | 4 +- .../RecordsWithoutDois.spec.js | 8 +- .../Curators/MaintenanceRequests.spec.js | 8 +- .../UserRecordsAwaitingApproval.spec.js | 13 +- .../Editor/DataAccess/EditDataAccess.spec.js | 2 + .../unit/components/Navigation/Header.spec.js | 5 + .../Record/GeneralInfo/DOITitle.spec.js | 4 +- .../Record/GeneralInfo/SavedSearches.spec.js | 8 +- .../SaveSearch/SaveSearchStepper.spec.js | 8 +- .../StepperComponents/PolicyStepper.spec.js | 3 + .../Private/ViewSavedSearchesTable.spec.js | 10 +- tests/unit/utils/generalUtils.spec.js | 4 +- .../views/Organisations/Organisation.spec.js | 64 +- .../views/Users/EditPublicProfile.spec.js | 13 +- 24 files changed, 430 insertions(+), 409 deletions(-) create mode 100644 src/views/Static/Documentation/Documentation.vue diff --git a/package-lock.json b/package-lock.json index 4442a0bbe9..3456a820d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,8 +64,8 @@ "@fortawesome/free-solid-svg-icons": "^6.6.0", "@vitejs/plugin-legacy": "^8.0.2", "@vitejs/plugin-vue": "^6.0.6", - "@vitest/coverage-v8": "^3.2.4", - "@vitest/ui": "^3.2.4", + "@vitest/coverage-v8": "^4.1.10", + "@vitest/ui": "^4.1.10", "@vue/babel-preset-app": "^5.0.8", "@vue/test-utils": "^2.4.6", "autoprefixer": "^10.4.20", @@ -103,7 +103,7 @@ "vite-plugin-compression2": "^2.5.3", "vite-plugin-eslint": "^1.8.1", "vite-plugin-vuetify": "^2.1.3", - "vitest": "^3.2.4", + "vitest": "^4.1.10", "vue-3-linkify": "^1.1.0", "yaml": "^2.8.3" }, @@ -111,20 +111,6 @@ "fsevents": "^2.3.2" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -153,6 +139,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -1858,6 +1845,7 @@ "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@keyv/serialize": "^1.1.1" } @@ -1899,6 +1887,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -1947,6 +1936,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -2002,7 +1992,6 @@ "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" @@ -2013,8 +2002,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD", - "optional": true, - "peer": true + "optional": true }, "node_modules/@emnapi/runtime": { "version": "1.11.1", @@ -2022,7 +2010,6 @@ "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -2032,8 +2019,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD", - "optional": true, - "peer": true + "optional": true }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.2", @@ -2041,7 +2027,6 @@ "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -2051,8 +2036,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD", - "optional": true, - "peer": true + "optional": true }, "node_modules/@epic-web/invariant": { "version": "1.0.0", @@ -2560,6 +2544,7 @@ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", "license": "MIT", + "peer": true, "dependencies": { "@fortawesome/fontawesome-common-types": "6.7.2" }, @@ -2685,16 +2670,6 @@ "node": ">=18.0.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", - "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -4351,6 +4326,13 @@ "node": ">=4" } }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, "node_modules/@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -5066,8 +5048,7 @@ "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.9", @@ -5122,6 +5103,7 @@ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -5415,32 +5397,30 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.6.tgz", - "integrity": "sha512-LsAdmUapA0qSN306d8+zOyawM0hFm2m2Hg9IwVNIKBm+qJV8cijiq2c+gxKZcB1HCfIWAy+0qEZDCUQA58A1cw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", + "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@ampproject/remapping": "^2.3.0", "@bcoe/v8-coverage": "^1.0.2", - "ast-v8-to-istanbul": "^0.3.3", - "debug": "^4.4.1", + "@vitest/utils": "4.1.10", + "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^5.0.6", - "istanbul-reports": "^3.1.7", - "magic-string": "^0.30.17", - "magicast": "^0.3.5", - "std-env": "^3.9.0", - "test-exclude": "^7.0.1", - "tinyrainbow": "^2.0.0" + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.2", + "obug": "^2.1.1", + "std-env": "^4.0.0-rc.1", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "3.2.6", - "vitest": "3.2.6" + "@vitest/browser": "4.1.10", + "vitest": "4.1.10" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -5449,39 +5429,40 @@ } }, "node_modules/@vitest/expect": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.6.tgz", - "integrity": "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", "dev": true, "license": "MIT", "dependencies": { + "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.6.tgz", - "integrity": "sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.6", + "@vitest/spy": "4.1.10", "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" + "magic-string": "^0.30.21" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -5503,42 +5484,42 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz", - "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^2.0.0" + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.6.tgz", - "integrity": "sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.6", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.6.tgz", - "integrity": "sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", - "magic-string": "^0.30.17", + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", "pathe": "^2.0.3" }, "funding": { @@ -5546,50 +5527,48 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.6.tgz", - "integrity": "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", "dev": true, "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/ui": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.2.6.tgz", - "integrity": "sha512-mATfG3zVdhobE9U1rIpvtYD3DGuSSxqZ3Aj/8ityGqKXy8YDJ9BoAjZmAz6dZ1IZ1xI5V+MerkCczvVa+3QK9Q==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.1.10.tgz", + "integrity": "sha512-EOUqfXHTXtpSHsyLHH40ts3Ue+hRhSGwzwzMlK0dTEOLSDYyOXLyr5JDGmHQWhN2DYI30gw6dVx3cdgM9FZl+Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@vitest/utils": "3.2.6", + "@vitest/utils": "4.1.10", "fflate": "^0.8.2", - "flatted": "^3.3.3", + "flatted": "^3.4.2", "pathe": "^2.0.3", - "sirv": "^3.0.1", - "tinyglobby": "^0.2.14", - "tinyrainbow": "^2.0.0" + "sirv": "^3.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "3.2.6" + "vitest": "4.1.10" } }, "node_modules/@vitest/utils": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.6.tgz", - "integrity": "sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -5853,6 +5832,7 @@ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.38.tgz", "integrity": "sha512-JTqp25l8aFfJYF7/KmsXZjAxJz7T+SjmTJLoXVjHtc2BrSgSiW2n9Aem/cWq1OPe68A8JL06B3eVdhlP0H4TVw==", "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-core": "3.5.38", "@vue/shared": "3.5.38" @@ -5863,6 +5843,7 @@ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.38.tgz", "integrity": "sha512-DuA2GiZawSEW442iw/9+Fkol8hTgb4Ke5KkhmSry65QA7YuyMbIdy8p0XZRMvNwJdgRz307W8g1CSzdvS4nuNg==", "license": "MIT", + "peer": true, "dependencies": { "@babel/parser": "^7.29.7", "@vue/compiler-core": "3.5.38", @@ -5927,6 +5908,7 @@ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.38.tgz", "integrity": "sha512-vue8vbf2QlV4quHqzwmJy6dWfmRhP1J8l4wtZg60CL6VoKqcPY2oe7may3+1d9qfpedjK5PRLFqd5k3Isj9mUw==", "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-ssr": "3.5.38", "@vue/shared": "3.5.38" @@ -5996,6 +5978,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6220,9 +6203,9 @@ } }, "node_modules/ast-v8-to-istanbul": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz", - "integrity": "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.5.tgz", + "integrity": "sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA==", "dev": true, "license": "MIT", "dependencies": { @@ -6761,6 +6744,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.38", "caniuse-lite": "^1.0.30001799", @@ -7200,18 +7184,11 @@ } }, "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, "engines": { "node": ">=18" } @@ -7259,16 +7236,6 @@ "dev": true, "license": "MIT" }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/chokidar": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", @@ -7946,6 +7913,7 @@ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" @@ -8067,16 +8035,6 @@ "dev": true, "license": "MIT" }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -9001,6 +8959,7 @@ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -9163,7 +9122,6 @@ "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@types/esrecurse": "^4.3.1", "@types/estree": "^1.0.8", @@ -9183,7 +9141,6 @@ "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" }, @@ -9197,7 +9154,6 @@ "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", @@ -9431,9 +9387,9 @@ } }, "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -10350,6 +10306,7 @@ "integrity": "sha512-6QD0ilzDDt93tX44y8tbmZdAcdTRYDhUP+Asgi6pC8Pp5IA3cvaZGyoVN/EGtlq9ziT65iPuBBn3ASLr6hCgVw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", @@ -10577,7 +10534,8 @@ "version": "12.1.2", "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-12.1.2.tgz", "integrity": "sha512-paZ72q1um0zZT1sS+O/3JfXVSOLPmZ0zlo8SgRc0rEplPFPQUPc4VpkgQS8IUTueeOBgIWwVpAWyC9tBYbQ0kg==", - "license": "https://www.highcharts.com/license" + "license": "https://www.highcharts.com/license", + "peer": true }, "node_modules/highcharts-vue": { "version": "2.0.1", @@ -11544,21 +11502,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/istanbul-reports": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", @@ -11611,7 +11554,8 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/js-beautify": { "version": "1.15.4", @@ -12168,7 +12112,8 @@ "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-3.0.5.tgz", "integrity": "sha512-1Y9XQH65eQKA9p2xtk+zxvnTeQBG7rdAXSkUG97DmuI/Xhji9uaUzaWxRj6rf9YC0v8KKHkxav7tnLX82Sz5Fg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lint-staged": { "version": "9.5.0", @@ -12806,13 +12751,6 @@ "node": ">=4" } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -12866,15 +12804,15 @@ } }, "node_modules/magicast": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", - "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", + "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.25.4", - "@babel/types": "^7.25.4", - "source-map-js": "^1.2.0" + "@babel/parser": "^7.29.3", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" } }, "node_modules/make-dir": { @@ -13998,6 +13936,20 @@ "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", "license": "MIT" }, + "node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -14172,6 +14124,7 @@ "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.104.0.tgz", "integrity": "sha512-sIEpobLwe7KhW1JdTvBJkNDgjJarHNsx+Q37iRNyASvmlDOD+f8Qirvwp6nFNz7Q5q3JcsJ1dpKM+oMPTDF/dw==", "license": "MIT", + "peer": true, "dependencies": { "@oxc-project/types": "^0.104.0" }, @@ -14502,16 +14455,6 @@ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "license": "MIT" }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, "node_modules/pbkdf2": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.6.tgz", @@ -14656,6 +14599,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", @@ -15786,6 +15730,7 @@ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", "license": "MIT", + "peer": true, "dependencies": { "@oxc-project/types": "=0.133.0", "@rolldown/pluginutils": "^1.0.0" @@ -15829,6 +15774,7 @@ "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.9" }, @@ -16135,6 +16081,7 @@ "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "chokidar": "^5.0.0", "immutable": "^5.1.5", @@ -16642,9 +16589,9 @@ "license": "MIT" }, "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", "dev": true, "license": "MIT" }, @@ -16862,26 +16809,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "license": "MIT" - }, "node_modules/stylelint": { "version": "16.26.1", "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.26.1.tgz", @@ -17148,6 +17075,7 @@ "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -17374,6 +17302,7 @@ "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==", "devOptional": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", @@ -17394,60 +17323,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/test-exclude": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz", - "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^10.4.1", - "minimatch": "^10.2.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/test-exclude/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -17489,11 +17364,14 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { "version": "0.2.17", @@ -17511,30 +17389,10 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { @@ -18150,6 +18008,7 @@ "resolved": "https://registry.npmjs.org/vike/-/vike-0.4.259.tgz", "integrity": "sha512-5S+rgfLYfozCqXTlyZzr6P4FXOIoPcsSbqYO32keBK2Jun4AKR5BI/sQiP3w09Zq/WZkywEu0ofHFAAxtaIdSg==", "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "^7.28.5", "@babel/types": "^7.28.5", @@ -18199,6 +18058,7 @@ "resolved": "https://registry.npmjs.org/vike-vue/-/vike-vue-0.9.11.tgz", "integrity": "sha512-Ujcu7NG/ZFsiAgEomA0PtuHFg0J/BMcol/QHiDzaIlov2JSiDfapyBLidrPVTrHwLHvmeCnxa4ruVqG+/Vj1XA==", "license": "MIT", + "peer": true, "dependencies": { "magic-string": "^0.30.21", "oxc-parser": "^0.104.0", @@ -18226,6 +18086,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", "license": "MIT", + "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", @@ -18298,29 +18159,6 @@ } } }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/vite-plugin-cjs-interop": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/vite-plugin-cjs-interop/-/vite-plugin-cjs-interop-4.0.3.tgz", @@ -18795,6 +18633,7 @@ "resolved": "https://registry.npmjs.org/vite-plugin-vuetify/-/vite-plugin-vuetify-2.1.3.tgz", "integrity": "sha512-Q4SC/4TqbNvaZIFb9YsfBqkGlYHbJJJ6uU3CnRBZqLUF3s5eCMVZAaV4GkTbehIH/bhSj42lMXztOwc71u6rVw==", "license": "MIT", + "peer": true, "dependencies": { "@vuetify/loader-shared": "^2.1.2", "debug": "^4.3.3", @@ -18819,65 +18658,80 @@ } }, "node_modules/vitest": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.6.tgz", - "integrity": "sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.6", - "@vitest/mocker": "3.2.6", - "@vitest/pretty-format": "^3.2.6", - "@vitest/runner": "3.2.6", - "@vitest/snapshot": "3.2.6", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.6", - "@vitest/ui": "3.2.6", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { "optional": true }, "@vitest/ui": { @@ -18888,9 +18742,19 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, + "node_modules/vitest/node_modules/es-module-lexer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "dev": true, + "license": "MIT" + }, "node_modules/vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -18903,6 +18767,7 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.38.tgz", "integrity": "sha512-vAMKHfImQlYSy0C+PBue4s3ERZ2xGKfgZg5GXAsLInq1dyh2H78ILVP5sK0KPFPVW4kv+OGCIvBEondcjpZp7A==", "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.38", "@vue/compiler-sfc": "3.5.38", @@ -19147,6 +19012,7 @@ "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.12.8.tgz", "integrity": "sha512-gvmOWeLd6CG7LVh2Qonft5YrIb7MpbKZglRjg0ItEloSbu6hfUII2RZmRSVxGKYdiXTf7J1hI3BRSHr8J9LkxA==", "license": "MIT", + "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/johnleider" @@ -19545,6 +19411,7 @@ "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "devOptional": true, "license": "ISC", + "peer": true, "bin": { "yaml": "bin.mjs" }, diff --git a/package.json b/package.json index d329308d33..7a83f920c1 100644 --- a/package.json +++ b/package.json @@ -74,8 +74,8 @@ "@fortawesome/free-solid-svg-icons": "^6.6.0", "@vitejs/plugin-legacy": "^8.0.2", "@vitejs/plugin-vue": "^6.0.6", - "@vitest/coverage-v8": "^3.2.4", - "@vitest/ui": "^3.2.4", + "@vitest/coverage-v8": "^4.1.10", + "@vitest/ui": "^4.1.10", "@vue/babel-preset-app": "^5.0.8", "@vue/test-utils": "^2.4.6", "autoprefixer": "^10.4.20", @@ -113,7 +113,7 @@ "vite-plugin-compression2": "^2.5.3", "vite-plugin-eslint": "^1.8.1", "vite-plugin-vuetify": "^2.1.3", - "vitest": "^3.2.4", + "vitest": "^4.1.10", "vue-3-linkify": "^1.1.0", "yaml": "^2.8.3" }, diff --git a/src/router/index.js b/src/router/index.js index a42f967d6b..e8029f5f18 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -16,6 +16,7 @@ import { Educational, Graph, Home, + Documentation, Licence, Login, LoginFailure, @@ -91,6 +92,11 @@ export function createMyRouter(store) { path: "/", component: Home, }, + { + name: "Documentation", + path: "/documentation", + component: Documentation, + }, { name: "Graph", path: "/graph/:id", diff --git a/src/router/routes.js b/src/router/routes.js index b816af2443..2c11a1067a 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -1,3 +1,4 @@ +export const Documentation = () => import("@/views/Static/Documentation/Documentation.vue"); export const Home = () => import("@/views/Home/Home.vue"); export const NotFound = () => import("@/views/Errors/404"); export const ServerError = () => import("@/views/Errors/500"); diff --git a/src/views/Static/Documentation/Documentation.vue b/src/views/Static/Documentation/Documentation.vue new file mode 100644 index 0000000000..5c59d6fd73 --- /dev/null +++ b/src/views/Static/Documentation/Documentation.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/tests/setup.js b/tests/setup.js index c160aa508f..5c083714cb 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -224,14 +224,16 @@ if (!Object.groupBy) { }; } -// Prevent accidental network access to local API endpoints in unit tests. +// Prevent unit tests from reaching API and embedded-service endpoints. const nativeFetch = globalThis.fetch ? globalThis.fetch.bind(globalThis) : null; const mockedFetch = async (input, init) => { const url = typeof input === "string" ? input : (input && input.url) || ""; if ( url.includes("localhost:3000") || url.includes("127.0.0.1:3000") || - url.includes("undefined/graphql") + url.includes("undefined/graphql") || + url.includes("dev-api.fairsharing.org") || + url.includes("aicc.uksouth.cloudapp.azure.com") ) { return new Response(JSON.stringify({}), { status: 200, @@ -246,14 +248,15 @@ if (typeof window !== "undefined") { window.fetch = globalThis.fetch; } -// Short-circuit GraphQL requests that would otherwise target localhost in tests. +// Short-circuit GraphQL requests to configured development endpoints in tests. const originalGetData = GraphQLClient.prototype.getData; GraphQLClient.prototype.getData = async function (queryString) { const url = this.url || ""; if ( url.includes("localhost:3000") || url.includes("127.0.0.1:3000") || - url.includes("undefined/graphql") + url.includes("undefined/graphql") || + url.includes("dev-api.fairsharing.org") ) { return { data: { data: {} } }; } @@ -266,6 +269,7 @@ RESTClient.prototype.executeQuery = async function (query) { if ( url.includes("localhost:3000") || url.includes("127.0.0.1:3000") || + url.includes("dev-api.fairsharing.org") || url.startsWith("undefined") || url.includes("/undefined/") ) { diff --git a/tests/unit/components/ChatBot/FionaChat.spec.js b/tests/unit/components/ChatBot/FionaChat.spec.js index 926e6f9911..80d4aa1c2e 100644 --- a/tests/unit/components/ChatBot/FionaChat.spec.js +++ b/tests/unit/components/ChatBot/FionaChat.spec.js @@ -12,6 +12,9 @@ describe("FionaChat", () => { document.body.innerHTML = '
'; wrapper = mount(FionaChat, { attachTo: "#app", + data: () => ({ + chatUrl: "about:blank#", + }), global: { stubs: { VBtn: { diff --git a/tests/unit/components/Curators/DownLoadRecordComponents/CuratorSummaryStatistics.spec.js b/tests/unit/components/Curators/DownLoadRecordComponents/CuratorSummaryStatistics.spec.js index c149ffa408..8df7f01867 100644 --- a/tests/unit/components/Curators/DownLoadRecordComponents/CuratorSummaryStatistics.spec.js +++ b/tests/unit/components/Curators/DownLoadRecordComponents/CuratorSummaryStatistics.spec.js @@ -15,7 +15,9 @@ const { mockClientInstance } = vi.hoisted(() => { vi.mock("@/lib/GraphClient/GraphClient", () => { return { - default: vi.fn().mockImplementation(() => mockClientInstance), + default: vi.fn(function () { + return mockClientInstance; + }), }; }); diff --git a/tests/unit/components/Curators/DownLoadRecordComponents/RecordEditsByMonth.spec.js b/tests/unit/components/Curators/DownLoadRecordComponents/RecordEditsByMonth.spec.js index f4eb14cbcc..f2c70c5e98 100644 --- a/tests/unit/components/Curators/DownLoadRecordComponents/RecordEditsByMonth.spec.js +++ b/tests/unit/components/Curators/DownLoadRecordComponents/RecordEditsByMonth.spec.js @@ -10,9 +10,11 @@ const { mockGetEditByMonth } = vi.hoisted(() => ({ // 2. Mock RestClient vi.mock("@/lib/Client/RESTClient", () => { return { - default: vi.fn().mockImplementation(() => ({ - getEditByMonth: mockGetEditByMonth, - })), + default: vi.fn(function () { + return { + getEditByMonth: mockGetEditByMonth, + }; + }), }; }); diff --git a/tests/unit/components/Curators/DownLoadRecordComponents/RecordsCreatedByMonth.spec.js b/tests/unit/components/Curators/DownLoadRecordComponents/RecordsCreatedByMonth.spec.js index f169466e4e..9746ded3d1 100644 --- a/tests/unit/components/Curators/DownLoadRecordComponents/RecordsCreatedByMonth.spec.js +++ b/tests/unit/components/Curators/DownLoadRecordComponents/RecordsCreatedByMonth.spec.js @@ -9,9 +9,11 @@ const { mockGetRecordCreatedByMonth } = vi.hoisted(() => ({ vi.mock("@/lib/Client/RESTClient", () => { return { - default: vi.fn().mockImplementation(() => ({ - getRecordCreatedByMonth: mockGetRecordCreatedByMonth, - })), + default: vi.fn(function () { + return { + getRecordCreatedByMonth: mockGetRecordCreatedByMonth, + }; + }), }; }); diff --git a/tests/unit/components/Curators/DownLoadRecordComponents/RecordsNeedingReview.spec.js b/tests/unit/components/Curators/DownLoadRecordComponents/RecordsNeedingReview.spec.js index f5970fba10..3b363a0d9c 100644 --- a/tests/unit/components/Curators/DownLoadRecordComponents/RecordsNeedingReview.spec.js +++ b/tests/unit/components/Curators/DownLoadRecordComponents/RecordsNeedingReview.spec.js @@ -13,7 +13,9 @@ const { mockClientInstance } = vi.hoisted(() => ({ vi.mock("@/lib/GraphClient/GraphClient", () => { return { - default: vi.fn().mockImplementation(() => mockClientInstance), + default: vi.fn(function () { + return mockClientInstance; + }), }; }); diff --git a/tests/unit/components/Curators/DownLoadRecordComponents/RecordsWithoutDois.spec.js b/tests/unit/components/Curators/DownLoadRecordComponents/RecordsWithoutDois.spec.js index 1736be80fc..858e322d52 100644 --- a/tests/unit/components/Curators/DownLoadRecordComponents/RecordsWithoutDois.spec.js +++ b/tests/unit/components/Curators/DownLoadRecordComponents/RecordsWithoutDois.spec.js @@ -9,9 +9,11 @@ const { mockGetRecordsWoDOIs } = vi.hoisted(() => ({ vi.mock("@/lib/Client/RESTClient", () => { return { - default: vi.fn().mockImplementation(() => ({ - getRecordsWoDOIs: mockGetRecordsWoDOIs, - })), + default: vi.fn(function () { + return { + getRecordsWoDOIs: mockGetRecordsWoDOIs, + }; + }), }; }); diff --git a/tests/unit/components/Curators/MaintenanceRequests.spec.js b/tests/unit/components/Curators/MaintenanceRequests.spec.js index 9f065d5fce..5635086f63 100644 --- a/tests/unit/components/Curators/MaintenanceRequests.spec.js +++ b/tests/unit/components/Curators/MaintenanceRequests.spec.js @@ -24,13 +24,17 @@ const restClientMock = vi.hoisted(() => ({ // Mock RESTClient and GraphClient classes vi.mock("@/lib/Client/RESTClient.js", () => { return { - default: vi.fn().mockImplementation(() => restClientMock), + default: vi.fn(function () { + return restClientMock; + }), }; }); vi.mock("@/lib/GraphClient/GraphClient", () => { return { - default: vi.fn().mockImplementation(() => graphClientMock), + default: vi.fn(function () { + return graphClientMock; + }), }; }); diff --git a/tests/unit/components/Curators/UserRecordsAwaitingApproval.spec.js b/tests/unit/components/Curators/UserRecordsAwaitingApproval.spec.js index 37d758281f..53849f3769 100644 --- a/tests/unit/components/Curators/UserRecordsAwaitingApproval.spec.js +++ b/tests/unit/components/Curators/UserRecordsAwaitingApproval.spec.js @@ -1,4 +1,4 @@ -import { afterEach, beforeAll, describe, expect, it, vi } from "vitest"; +import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; import { shallowMount } from "@vue/test-utils"; import sinon from "sinon"; import Vuex from "vuex"; @@ -119,7 +119,7 @@ describe("Curator -> UserRecordsAwaitingApproval.vue", () => { }); }); - afterEach(() => { + afterAll(() => { graphStub.restore(); restStub.restore(); }); @@ -168,7 +168,6 @@ describe("Curator -> UserRecordsAwaitingApproval.vue", () => { expect(wrapper.vm.approvalRequiredProcessed[0].curator).toMatch("Michae"); // TODO: Check that the curator are updated in the record - restStub = sinon.stub(Client.prototype, "executeQuery"); restStub.returns({ data: { error: { response: "Im an error" } } }); await wrapper.vm.assignCurator(11, 1, "Michael Smith"); expect(wrapper.vm.error.recordID).toBe(11); @@ -179,7 +178,6 @@ describe("Curator -> UserRecordsAwaitingApproval.vue", () => { it("can approve a record", async () => { //Correct approval wrapper.vm.dialogs.recordID = 100; - restStub = sinon.stub(Client.prototype, "executeQuery"); restStub.returns({ data: { error: false } }); await wrapper.vm.confirmApproval(); expect(wrapper.vm.approvalRequiredProcessed.length).toBe(2); @@ -193,9 +191,7 @@ describe("Curator -> UserRecordsAwaitingApproval.vue", () => { expect(wrapper.vm.dialogs.approveChanges).toBe(false); expect(wrapper.vm.approvalRequiredProcessed[0].id).toBe(11); //There is an error in the Client query - restStub.restore(); wrapper.vm.dialogs.recordID = 101; - restStub = sinon.stub(Client.prototype, "executeQuery"); restStub.returns({ data: { error: { response: { data: "error" } } } }); await wrapper.vm.confirmApproval(); expect(wrapper.vm.approvalRequiredProcessed.length).toBe(1); @@ -208,9 +204,7 @@ describe("Curator -> UserRecordsAwaitingApproval.vue", () => { expect(wrapper.vm.approvalRequiredProcessed.length).toBe(1); expect(wrapper.vm.dialogs.approveChanges).toBe(false); - restStub.restore(); wrapper.vm.dialogs.recordID = 102; - restStub = sinon.stub(Client.prototype, "executeQuery"); restStub.returns({ data: { error: { response: { data: "error" } } } }); await wrapper.vm.confirmApproval(); expect(wrapper.vm.approvalRequiredProcessed.length).toBe(1); @@ -220,7 +214,6 @@ describe("Curator -> UserRecordsAwaitingApproval.vue", () => { it("can delete a record", async () => { //There is an error in the Client query wrapper.vm.dialogs.recordID = 102; - restStub = sinon.stub(Client.prototype, "executeQuery"); restStub.returns({ data: { error: { response: { data: "error" } } } }); await wrapper.vm.confirmDelete(); expect(wrapper.vm.approvalRequiredProcessed.length).toBe(1); @@ -230,8 +223,6 @@ describe("Curator -> UserRecordsAwaitingApproval.vue", () => { //Correct deleted wrapper.vm.dialogs.recordID = 102; - restStub.restore(); - restStub = sinon.stub(Client.prototype, "executeQuery"); restStub.returns({ data: { error: false } }); await wrapper.vm.confirmDelete(); expect(wrapper.vm.approvalRequiredProcessed.length).toBe(0); diff --git a/tests/unit/components/Editor/DataAccess/EditDataAccess.spec.js b/tests/unit/components/Editor/DataAccess/EditDataAccess.spec.js index 8f484e8eab..39a119533f 100644 --- a/tests/unit/components/Editor/DataAccess/EditDataAccess.spec.js +++ b/tests/unit/components/Editor/DataAccess/EditDataAccess.spec.js @@ -165,6 +165,8 @@ describe("Edit -> DataAccess.vue", function () { it("handles save and exit with redirect", async () => { const btn = { textContent: "Save and exit" }; const pushCalls = $router.push.mock.calls.length; + restStub = sinon.stub(RestClient.prototype, "executeQuery"); + restStub.returns({ data: "GG!" }); await wrapper.vm.saveRecord(true, btn); expect($router.push).toHaveBeenCalledTimes(pushCalls + 1); }); diff --git a/tests/unit/components/Navigation/Header.spec.js b/tests/unit/components/Navigation/Header.spec.js index 5a587035a9..fa97f0dad7 100644 --- a/tests/unit/components/Navigation/Header.spec.js +++ b/tests/unit/components/Navigation/Header.spec.js @@ -4,6 +4,7 @@ import {createVuetify} from "vuetify"; import Vuex from "vuex"; import Header from "@/components/Navigation/Header.vue"; +import RESTClient from "@/lib/Client/RESTClient.js"; import uiControllerStore from "@/store/uiController.js"; import usersStore from "@/store/users.js"; @@ -120,6 +121,9 @@ describe("Header.vue", function () { it("logs out and redirects to Login", async () => { const push = vi.fn(); + const logoutSpy = vi + .spyOn(RESTClient.prototype, "logout") + .mockResolvedValue({ error: false }); const localStore = new Vuex.Store({ modules: { @@ -143,5 +147,6 @@ describe("Header.vue", function () { await localWrapper.vm.logoutUser(); expect(push).toHaveBeenCalledWith({ name: "Login" }); + logoutSpy.mockRestore(); }); }); diff --git a/tests/unit/components/Records/Record/GeneralInfo/DOITitle.spec.js b/tests/unit/components/Records/Record/GeneralInfo/DOITitle.spec.js index 9ab6ff76ff..29fe04f424 100644 --- a/tests/unit/components/Records/Record/GeneralInfo/DOITitle.spec.js +++ b/tests/unit/components/Records/Record/GeneralInfo/DOITitle.spec.js @@ -37,7 +37,9 @@ describe("DOITitle.vue", function () { readAsDataURL, target: fileContents, }; - window.Image = vi.fn(() => dummyFileReader); + window.Image = vi.fn(function () { + return dummyFileReader; + }); }); it("can be instantiated", async () => { diff --git a/tests/unit/components/Records/Record/GeneralInfo/SavedSearches.spec.js b/tests/unit/components/Records/Record/GeneralInfo/SavedSearches.spec.js index 4afdcd90ec..4d66d1e09c 100644 --- a/tests/unit/components/Records/Record/GeneralInfo/SavedSearches.spec.js +++ b/tests/unit/components/Records/Record/GeneralInfo/SavedSearches.spec.js @@ -33,9 +33,11 @@ const { mockUpdateSaveSearch } = vi.hoisted(() => { // Now Vitest can safely use it here! vi.mock("@/lib/Client/RESTClient.js", () => ({ - default: vi.fn().mockImplementation(() => ({ - updateSaveSearch: mockUpdateSaveSearch, - })), + default: vi.fn(function () { + return { + updateSaveSearch: mockUpdateSaveSearch, + }; + }), })); describe("SavedSearches.vue", () => { diff --git a/tests/unit/components/Records/Search/SaveSearch/SaveSearchStepper.spec.js b/tests/unit/components/Records/Search/SaveSearch/SaveSearchStepper.spec.js index 74507fdc0c..b6f1f75b6f 100644 --- a/tests/unit/components/Records/Search/SaveSearch/SaveSearchStepper.spec.js +++ b/tests/unit/components/Records/Search/SaveSearch/SaveSearchStepper.spec.js @@ -11,9 +11,11 @@ const { mockSaveSearchAPI } = vi.hoisted(() => ({ vi.mock("@/lib/Client/RESTClient", () => { return { - default: vi.fn(() => ({ - saveSearch: mockSaveSearchAPI, - })), + default: vi.fn(function () { + return { + saveSearch: mockSaveSearchAPI, + }; + }), }; }); diff --git a/tests/unit/components/Records/Search/SaveSearch/StepperComponents/PolicyStepper.spec.js b/tests/unit/components/Records/Search/SaveSearch/StepperComponents/PolicyStepper.spec.js index 1c4a5c7791..7e9c10633f 100644 --- a/tests/unit/components/Records/Search/SaveSearch/StepperComponents/PolicyStepper.spec.js +++ b/tests/unit/components/Records/Search/SaveSearch/StepperComponents/PolicyStepper.spec.js @@ -48,6 +48,9 @@ describe("PolicyStepper.vue", () => { }, saveSearch: { namespaced: true, + mutations: { + setPolicySelected: vi.fn(), + }, getters: { getPolicyRecords: getters.getPolicyRecords, getLoadingStatus: getters.getLoadingStatus, diff --git a/tests/unit/components/Users/Profiles/Private/ViewSavedSearchesTable.spec.js b/tests/unit/components/Users/Profiles/Private/ViewSavedSearchesTable.spec.js index 764784a4f3..724d153c46 100644 --- a/tests/unit/components/Users/Profiles/Private/ViewSavedSearchesTable.spec.js +++ b/tests/unit/components/Users/Profiles/Private/ViewSavedSearchesTable.spec.js @@ -13,10 +13,12 @@ const { mockDelete, mockUpdate } = vi.hoisted(() => { vi.mock("@/lib/Client/RESTClient", () => { return { - default: vi.fn(() => ({ - deleteSavedSearch: mockDelete, - updateSaveSearch: mockUpdate, - })), + default: vi.fn(function () { + return { + deleteSavedSearch: mockDelete, + updateSaveSearch: mockUpdate, + }; + }), }; }); diff --git a/tests/unit/utils/generalUtils.spec.js b/tests/unit/utils/generalUtils.spec.js index b925f4f791..0fde070b75 100644 --- a/tests/unit/utils/generalUtils.spec.js +++ b/tests/unit/utils/generalUtils.spec.js @@ -94,7 +94,9 @@ describe("generalUtils.js", function () { }), result: "vv", }; - window.FileReader = vi.fn(() => dummy); + window.FileReader = vi.fn(function () { + return dummy; + }); toBase64(mFile); dummy.onload(); dummy.onerror("a"); diff --git a/tests/unit/views/Organisations/Organisation.spec.js b/tests/unit/views/Organisations/Organisation.spec.js index 490da41e47..934186ca47 100644 --- a/tests/unit/views/Organisations/Organisation.spec.js +++ b/tests/unit/views/Organisations/Organisation.spec.js @@ -13,36 +13,44 @@ const { mockDeleteOrganisation, mockEditOrganisation, mockUpdateSaveSearch } = vi.mock("@/lib/GraphClient/GraphClient.js", () => { return { - default: vi.fn().mockImplementation(() => ({ - executeQuery: vi.fn().mockResolvedValue({ - organisation: { - id: 1, - name: "Test Org", - homepage: "https://test.org", - rorLink: "https://ror.org/test", - urlForLogo: "/media/logo.png", - alternativeNames: ["Alt1", "Alt2"], - types: ["Institute"], - users: [ - { id: 1, username: "testuser", orcid: "0000-0000-0000-0000" }, - ], - parentOrganisations: [], - childOrganisations: [], - countries: [{ id: 1, name: "France" }], - savedSearches: [], - }, - }), - })), + default: vi.fn(function () { + return { + executeQuery: vi.fn().mockResolvedValue({ + organisation: { + id: 1, + name: "Test Org", + homepage: "https://test.org", + rorLink: "https://ror.org/test", + urlForLogo: "/media/logo.png", + alternativeNames: ["Alt1", "Alt2"], + types: ["Institute"], + users: [ + { + id: 1, + username: "testuser", + orcid: "0000-0000-0000-0000", + }, + ], + parentOrganisations: [], + childOrganisations: [], + countries: [{ id: 1, name: "France" }], + savedSearches: [], + }, + }), + }; + }), }; }); vi.mock("@/lib/Client/RESTClient.js", () => { return { - default: vi.fn().mockImplementation(() => ({ - editOrganisation: mockEditOrganisation, - deleteOrganisation: mockDeleteOrganisation, - updateSaveSearch: mockUpdateSaveSearch, - })), + default: vi.fn(function () { + return { + editOrganisation: mockEditOrganisation, + deleteOrganisation: mockDeleteOrganisation, + updateSaveSearch: mockUpdateSaveSearch, + }; + }), }; }); @@ -113,6 +121,12 @@ describe("Organisation.vue", () => { getCountries: mockGetCountries, }, }, + saveSearch: { + namespaced: true, + mutations: { + setSaveSearchResult: vi.fn(), + }, + }, }, }); }; diff --git a/tests/unit/views/Users/EditPublicProfile.spec.js b/tests/unit/views/Users/EditPublicProfile.spec.js index 0d1e8c746e..fde1b87ed4 100644 --- a/tests/unit/views/Users/EditPublicProfile.spec.js +++ b/tests/unit/views/Users/EditPublicProfile.spec.js @@ -38,12 +38,19 @@ let $store = new Vuex.Store({ $router.go = vi.fn(); describe("EditPublicProfile.vue", function () { - let wrapper, restStubProfile, restStubRole, restStubUser; + let wrapper, + restStubProfile, + restStubRole, + restStubUser, + restStubUpdateUser, + restStubDeleteUser; beforeAll(() => { restStubProfile = sinon.stub(Client.prototype, "getProfileTypes"); restStubRole = sinon.stub(Client.prototype, "getUserRoles"); restStubUser = sinon.stub(Client.prototype, "getPublicUser"); + restStubUpdateUser = sinon.stub(Client.prototype, "editPublicUser"); + restStubDeleteUser = sinon.stub(Client.prototype, "deletePublicUser"); restStubProfile.returns(["profile 1", "profile 2"]); restStubRole.returns([ { @@ -62,11 +69,15 @@ describe("EditPublicProfile.vue", function () { role: "user", deactivated: false, }); + restStubUpdateUser.resolves({ error: false }); + restStubDeleteUser.resolves({ error: false }); }); afterAll(() => { restStubRole.restore(); restStubProfile.restore(); restStubUser.restore(); + restStubUpdateUser.restore(); + restStubDeleteUser.restore(); }); beforeEach(async () => { From 221b777250b4404992c6218f43927feaee0ea22b Mon Sep 17 00:00:00 2001 From: knirirr <3583375+knirirr@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:27:00 +0000 Subject: [PATCH 02/12] docs: autogenerated documentation files --- documentation/html/ExternalRESTClients.html | 2 +- documentation/html/GraphQLClient.html | 2 +- documentation/html/RESTClient.html | 2 +- documentation/html/Static.html | 2 +- documentation/html/classes.list.html | 2 +- .../components_Curators_CuratorRecordsAwaitingApproval.vue.html | 2 +- ..._DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html | 2 +- ...rators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html | 2 +- ...ors_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html | 2 +- ...tors_DownLoadRecordsComponents_RecordsNeedingReview.vue.html | 2 +- ...rators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html | 2 +- documentation/html/components_Curators_HiddenRecords.vue.html | 2 +- .../html/components_Curators_IncompleteRecords.vue.html | 2 +- .../html/components_Curators_MaintenanceRequests.vue.html | 2 +- .../html/components_Curators_RecentCuratorCreation.vue.html | 2 +- documentation/html/components_Curators_SystemMessages.vue.html | 2 +- .../components_Curators_UserRecordsAwaitingApproval.vue.html | 2 +- .../html/components_Records_Record_Collections.vue.html | 2 +- ...components_Records_Record_GeneralInfo_SavedSearches.vue.html | 2 +- .../html/components_Records_Record_RelatedContent.vue.html | 2 +- .../html/components_Records_Search_Header_FilterChips.vue.html | 2 +- .../html/components_Records_Search_Header_Pagination.vue.html | 2 +- .../html/components_Records_Search_Header_Sorting.vue.html | 2 +- ...Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html | 2 +- ..._QueryBuilderComponents_GeneralComponents_Countries.vue.html | 2 +- ...ch_QueryBuilderComponents_GeneralComponents_Domains.vue.html | 2 +- ...h_QueryBuilderComponents_GeneralComponents_Licences.vue.html | 2 +- ...ueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html | 2 +- ...ryBuilderComponents_GeneralComponents_Organisations.vue.html | 2 +- ...ch_QueryBuilderComponents_GeneralComponents_Subject.vue.html | 2 +- ...QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html | 2 +- ...yBuilderComponents_GeneralComponents_UserDefinedTag.vue.html | 2 +- ...h_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html | 2 +- ...QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html | 2 +- ...ch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html | 2 +- ..._QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html | 2 +- ...rch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html | 2 +- ...h_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html | 2 +- ...ecords_Search_Input_AdvancedSearch_QueryBuilderView.vue.html | 2 +- .../components_Records_Search_Input_FilterAutocomplete.vue.html | 2 +- .../html/components_Records_Search_Input_FilterButton.vue.html | 2 +- .../html/components_Records_Search_Input_SearchInput.vue.html | 2 +- ...mponents_Records_Search_SaveSearch_SaveSearchButton.vue.html | 2 +- ...ponents_Records_Search_SaveSearch_SaveSearchStepper.vue.html | 2 +- ...ch_SaveSearch_StepperComponents_OrganisationStepper.vue.html | 2 +- ...s_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html | 2 +- ...ords_Search_SaveSearch_StepperComponents_ResultCard.vue.html | 2 +- ...ch_SaveSearch_StepperComponents_StepperDialogHeader.vue.html | 2 +- ...rds_Search_SaveSearch_StepperComponents_UserStepper.vue.html | 2 +- ...nents_Users_Profiles_Private_ViewSavedSearchesTable.vue.html | 2 +- documentation/html/global.html | 2 +- documentation/html/index.html | 2 +- documentation/html/lib_Client_ExternalClients.js.html | 2 +- documentation/html/lib_Client_RESTClient.js.html | 2 +- documentation/html/lib_GraphClient_GraphClient.js.html | 2 +- documentation/html/lib_GraphClient_GraphClientSEO.js.html | 2 +- documentation/html/module-Home.html | 2 +- documentation/html/module-Login.html | 2 +- documentation/html/module-NewRecord.html | 2 +- documentation/html/module-Pagination.html | 2 +- documentation/html/module-Signup.html | 2 +- documentation/html/module-User.html | 2 +- documentation/html/modules.list.html | 2 +- documentation/html/namespaces.list.html | 2 +- documentation/html/router_hackSearch.js.html | 2 +- documentation/html/store_introspector.js.html | 2 +- documentation/html/store_recordData.js.html | 2 +- documentation/html/store_recordSearch.js.html | 2 +- documentation/html/store_searchFilters.js.html | 2 +- documentation/html/utils_advancedSearchUtils.js.html | 2 +- .../utils_query-builder-vue-3_dist_query-builder-vue-3.js.html | 2 +- documentation/html/utils_recordTabUtils.js.html | 2 +- documentation/html/utils_rules.js.html | 2 +- .../views_AdvancedSearch_AdvancedSearchResultTable.vue.html | 2 +- .../html/views_AdvancedSearch_AdvancedSearchSelection.vue.html | 2 +- documentation/html/views_Browsers_OntologyBrowser.vue.html | 2 +- documentation/html/views_CreateRecord_NewRecord.vue.html | 2 +- documentation/html/views_Home_Home.vue.html | 2 +- documentation/html/views_Organisations_Organisation.vue.html | 2 +- documentation/html/views_Records_NetworkGraph.vue.html | 2 +- documentation/html/views_Records_Record.vue.html | 2 +- documentation/html/views_Records_Records.vue.html | 2 +- documentation/html/views_Static_Community_Community.vue.html | 2 +- documentation/html/views_Static_Timeline_Timeline.vue.html | 2 +- documentation/html/views_Users_Login_Login.vue.html | 2 +- documentation/html/views_Users_Signup.vue.html | 2 +- 86 files changed, 86 insertions(+), 86 deletions(-) diff --git a/documentation/html/ExternalRESTClients.html b/documentation/html/ExternalRESTClients.html index 10fc104964..fdf376c6fc 100644 --- a/documentation/html/ExternalRESTClients.html +++ b/documentation/html/ExternalRESTClients.html @@ -414,7 +414,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/GraphQLClient.html b/documentation/html/GraphQLClient.html index e29141b167..8ae30aab17 100644 --- a/documentation/html/GraphQLClient.html +++ b/documentation/html/GraphQLClient.html @@ -912,7 +912,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/RESTClient.html b/documentation/html/RESTClient.html index 87d44c61ce..1009f2b236 100644 --- a/documentation/html/RESTClient.html +++ b/documentation/html/RESTClient.html @@ -10217,7 +10217,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/Static.html b/documentation/html/Static.html index ae4d56fcf6..d62db8129c 100644 --- a/documentation/html/Static.html +++ b/documentation/html/Static.html @@ -391,7 +391,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/classes.list.html b/documentation/html/classes.list.html index c803560872..5d78dc887e 100644 --- a/documentation/html/classes.list.html +++ b/documentation/html/classes.list.html @@ -2984,7 +2984,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_CuratorRecordsAwaitingApproval.vue.html b/documentation/html/components_Curators_CuratorRecordsAwaitingApproval.vue.html index cfdccb8660..43bd158a64 100644 --- a/documentation/html/components_Curators_CuratorRecordsAwaitingApproval.vue.html +++ b/documentation/html/components_Curators_CuratorRecordsAwaitingApproval.vue.html @@ -833,7 +833,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html index b96ea4f24a..3146c2d3e6 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html @@ -199,7 +199,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html index fbab801f3b..3ff7e08e58 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html @@ -202,7 +202,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html index b0d3006869..b033249d40 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html @@ -204,7 +204,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsNeedingReview.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsNeedingReview.vue.html index 47eb81cb89..b21a0490d2 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsNeedingReview.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsNeedingReview.vue.html @@ -199,7 +199,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html index d455277d69..a6f3262182 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html @@ -205,7 +205,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_HiddenRecords.vue.html b/documentation/html/components_Curators_HiddenRecords.vue.html index 043c22f32a..eec9713882 100644 --- a/documentation/html/components_Curators_HiddenRecords.vue.html +++ b/documentation/html/components_Curators_HiddenRecords.vue.html @@ -299,7 +299,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_IncompleteRecords.vue.html b/documentation/html/components_Curators_IncompleteRecords.vue.html index 56b951ebed..3d8590e8d8 100644 --- a/documentation/html/components_Curators_IncompleteRecords.vue.html +++ b/documentation/html/components_Curators_IncompleteRecords.vue.html @@ -385,7 +385,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_MaintenanceRequests.vue.html b/documentation/html/components_Curators_MaintenanceRequests.vue.html index b9205b32e6..9fab61a9dd 100644 --- a/documentation/html/components_Curators_MaintenanceRequests.vue.html +++ b/documentation/html/components_Curators_MaintenanceRequests.vue.html @@ -672,7 +672,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_RecentCuratorCreation.vue.html b/documentation/html/components_Curators_RecentCuratorCreation.vue.html index 57ae88787f..d35b0a48b5 100644 --- a/documentation/html/components_Curators_RecentCuratorCreation.vue.html +++ b/documentation/html/components_Curators_RecentCuratorCreation.vue.html @@ -294,7 +294,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_SystemMessages.vue.html b/documentation/html/components_Curators_SystemMessages.vue.html index 2d2d70c097..695e310394 100644 --- a/documentation/html/components_Curators_SystemMessages.vue.html +++ b/documentation/html/components_Curators_SystemMessages.vue.html @@ -474,7 +474,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_UserRecordsAwaitingApproval.vue.html b/documentation/html/components_Curators_UserRecordsAwaitingApproval.vue.html index bc03f58468..07c80509ae 100644 --- a/documentation/html/components_Curators_UserRecordsAwaitingApproval.vue.html +++ b/documentation/html/components_Curators_UserRecordsAwaitingApproval.vue.html @@ -839,7 +839,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Record_Collections.vue.html b/documentation/html/components_Records_Record_Collections.vue.html index 2f7262bd8d..01a4eee9f1 100644 --- a/documentation/html/components_Records_Record_Collections.vue.html +++ b/documentation/html/components_Records_Record_Collections.vue.html @@ -462,7 +462,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Record_GeneralInfo_SavedSearches.vue.html b/documentation/html/components_Records_Record_GeneralInfo_SavedSearches.vue.html index a7c154da7b..a778b13e7c 100644 --- a/documentation/html/components_Records_Record_GeneralInfo_SavedSearches.vue.html +++ b/documentation/html/components_Records_Record_GeneralInfo_SavedSearches.vue.html @@ -319,7 +319,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Record_RelatedContent.vue.html b/documentation/html/components_Records_Record_RelatedContent.vue.html index bfe443255c..627e756cf4 100644 --- a/documentation/html/components_Records_Record_RelatedContent.vue.html +++ b/documentation/html/components_Records_Record_RelatedContent.vue.html @@ -454,7 +454,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Header_FilterChips.vue.html b/documentation/html/components_Records_Search_Header_FilterChips.vue.html index 4eb5c670e2..ee93782613 100644 --- a/documentation/html/components_Records_Search_Header_FilterChips.vue.html +++ b/documentation/html/components_Records_Search_Header_FilterChips.vue.html @@ -251,7 +251,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Header_Pagination.vue.html b/documentation/html/components_Records_Search_Header_Pagination.vue.html index 2cbd765b3e..af4e07c606 100644 --- a/documentation/html/components_Records_Search_Header_Pagination.vue.html +++ b/documentation/html/components_Records_Search_Header_Pagination.vue.html @@ -262,7 +262,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Header_Sorting.vue.html b/documentation/html/components_Records_Search_Header_Sorting.vue.html index 7e7c9ddcba..0b66664a0a 100644 --- a/documentation/html/components_Records_Search_Header_Sorting.vue.html +++ b/documentation/html/components_Records_Search_Header_Sorting.vue.html @@ -219,7 +219,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html index c8e4973227..e40682b8e7 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html @@ -487,7 +487,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Countries.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Countries.vue.html index a203a04ed4..7a8972c25a 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Countries.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Countries.vue.html @@ -225,7 +225,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Domains.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Domains.vue.html index e759f31cb9..19cdbc4e0a 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Domains.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Domains.vue.html @@ -218,7 +218,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Licences.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Licences.vue.html index 3a3e5fe5a3..d5beb13aba 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Licences.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Licences.vue.html @@ -218,7 +218,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html index 020c3665ca..69ab096d0f 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Organisations.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Organisations.vue.html index f051ddfca1..3b21bceddc 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Organisations.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Organisations.vue.html @@ -229,7 +229,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Subject.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Subject.vue.html index 3010e0a0a0..32d3ac3d2f 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Subject.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Subject.vue.html @@ -218,7 +218,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html index 6b99f20938..75eb02f8b4 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html @@ -224,7 +224,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_UserDefinedTag.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_UserDefinedTag.vue.html index e26686168f..3bb0362108 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_UserDefinedTag.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_UserDefinedTag.vue.html @@ -224,7 +224,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html index 28edb01249..556a0464c8 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html @@ -315,7 +315,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html index f6a04f88f2..337c836824 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html @@ -252,7 +252,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html index 6092e2cbce..b2efdc4644 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html @@ -272,7 +272,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html index 44be1009b4..978993f25d 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html @@ -199,7 +199,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html index ac79a5c303..f158a9175a 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html @@ -328,7 +328,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html index 3f5979be98..289315d3bc 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html @@ -230,7 +230,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderView.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderView.vue.html index 7d1cdcdd38..16a2ae19db 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderView.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderView.vue.html @@ -676,7 +676,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_FilterAutocomplete.vue.html b/documentation/html/components_Records_Search_Input_FilterAutocomplete.vue.html index 950f4d0b2f..623a24ca10 100644 --- a/documentation/html/components_Records_Search_Input_FilterAutocomplete.vue.html +++ b/documentation/html/components_Records_Search_Input_FilterAutocomplete.vue.html @@ -376,7 +376,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_FilterButton.vue.html b/documentation/html/components_Records_Search_Input_FilterButton.vue.html index a448b2ac84..013a1de5f8 100644 --- a/documentation/html/components_Records_Search_Input_FilterButton.vue.html +++ b/documentation/html/components_Records_Search_Input_FilterButton.vue.html @@ -287,7 +287,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_SearchInput.vue.html b/documentation/html/components_Records_Search_Input_SearchInput.vue.html index 9d8a522d27..ab91e7bd65 100644 --- a/documentation/html/components_Records_Search_Input_SearchInput.vue.html +++ b/documentation/html/components_Records_Search_Input_SearchInput.vue.html @@ -284,7 +284,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_SaveSearchButton.vue.html b/documentation/html/components_Records_Search_SaveSearch_SaveSearchButton.vue.html index 8c222b410a..c4ca9f16cb 100644 --- a/documentation/html/components_Records_Search_SaveSearch_SaveSearchButton.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_SaveSearchButton.vue.html @@ -182,7 +182,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_SaveSearchStepper.vue.html b/documentation/html/components_Records_Search_SaveSearch_SaveSearchStepper.vue.html index 98d419e011..7635024cd5 100644 --- a/documentation/html/components_Records_Search_SaveSearch_SaveSearchStepper.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_SaveSearchStepper.vue.html @@ -464,7 +464,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_OrganisationStepper.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_OrganisationStepper.vue.html index f0c0237794..7dab894e63 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_OrganisationStepper.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_OrganisationStepper.vue.html @@ -259,7 +259,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html index 032b16b49b..cfdff6efa5 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html @@ -259,7 +259,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_ResultCard.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_ResultCard.vue.html index efdea90e51..c743ea3015 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_ResultCard.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_ResultCard.vue.html @@ -259,7 +259,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_StepperDialogHeader.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_StepperDialogHeader.vue.html index 510f82584d..957a666cc3 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_StepperDialogHeader.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_StepperDialogHeader.vue.html @@ -182,7 +182,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_UserStepper.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_UserStepper.vue.html index 29d7b64173..be144b027e 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_UserStepper.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_UserStepper.vue.html @@ -211,7 +211,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/components_Users_Profiles_Private_ViewSavedSearchesTable.vue.html b/documentation/html/components_Users_Profiles_Private_ViewSavedSearchesTable.vue.html index 9e3b9726e3..2f536157ac 100644 --- a/documentation/html/components_Users_Profiles_Private_ViewSavedSearchesTable.vue.html +++ b/documentation/html/components_Users_Profiles_Private_ViewSavedSearchesTable.vue.html @@ -509,7 +509,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/global.html b/documentation/html/global.html index 5d7c0f624f..35dade6394 100644 --- a/documentation/html/global.html +++ b/documentation/html/global.html @@ -2964,7 +2964,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/index.html b/documentation/html/index.html index 14c5709d59..7809317f36 100644 --- a/documentation/html/index.html +++ b/documentation/html/index.html @@ -216,7 +216,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/lib_Client_ExternalClients.js.html b/documentation/html/lib_Client_ExternalClients.js.html index ad87fa86ca..508971c625 100644 --- a/documentation/html/lib_Client_ExternalClients.js.html +++ b/documentation/html/lib_Client_ExternalClients.js.html @@ -256,7 +256,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/lib_Client_RESTClient.js.html b/documentation/html/lib_Client_RESTClient.js.html index ce0a02737b..a4357535c7 100644 --- a/documentation/html/lib_Client_RESTClient.js.html +++ b/documentation/html/lib_Client_RESTClient.js.html @@ -1284,7 +1284,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/lib_GraphClient_GraphClient.js.html b/documentation/html/lib_GraphClient_GraphClient.js.html index 51d6c37cb4..b6a77361d3 100644 --- a/documentation/html/lib_GraphClient_GraphClient.js.html +++ b/documentation/html/lib_GraphClient_GraphClient.js.html @@ -285,7 +285,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/lib_GraphClient_GraphClientSEO.js.html b/documentation/html/lib_GraphClient_GraphClientSEO.js.html index 207f0fbec1..763f893cd6 100644 --- a/documentation/html/lib_GraphClient_GraphClientSEO.js.html +++ b/documentation/html/lib_GraphClient_GraphClientSEO.js.html @@ -286,7 +286,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/module-Home.html b/documentation/html/module-Home.html index 5c22b1c6ff..14d56a0955 100644 --- a/documentation/html/module-Home.html +++ b/documentation/html/module-Home.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/module-Login.html b/documentation/html/module-Login.html index 262cb08329..cbaf4bc194 100644 --- a/documentation/html/module-Login.html +++ b/documentation/html/module-Login.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/module-NewRecord.html b/documentation/html/module-NewRecord.html index b59425fc4c..f0fa685d82 100644 --- a/documentation/html/module-NewRecord.html +++ b/documentation/html/module-NewRecord.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/module-Pagination.html b/documentation/html/module-Pagination.html index 9f2505ffd7..3260832d03 100644 --- a/documentation/html/module-Pagination.html +++ b/documentation/html/module-Pagination.html @@ -527,7 +527,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/module-Signup.html b/documentation/html/module-Signup.html index a720d14734..5adccec419 100644 --- a/documentation/html/module-Signup.html +++ b/documentation/html/module-Signup.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/module-User.html b/documentation/html/module-User.html index ba94522cc7..1399573480 100644 --- a/documentation/html/module-User.html +++ b/documentation/html/module-User.html @@ -228,7 +228,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/modules.list.html b/documentation/html/modules.list.html index 1089d26429..e00eae37d4 100644 --- a/documentation/html/modules.list.html +++ b/documentation/html/modules.list.html @@ -2984,7 +2984,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/namespaces.list.html b/documentation/html/namespaces.list.html index 07891c03fe..81e370440d 100644 --- a/documentation/html/namespaces.list.html +++ b/documentation/html/namespaces.list.html @@ -2984,7 +2984,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/router_hackSearch.js.html b/documentation/html/router_hackSearch.js.html index 6b100bb22b..7777193e8e 100644 --- a/documentation/html/router_hackSearch.js.html +++ b/documentation/html/router_hackSearch.js.html @@ -209,7 +209,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/store_introspector.js.html b/documentation/html/store_introspector.js.html index 318632760f..e998bdb525 100644 --- a/documentation/html/store_introspector.js.html +++ b/documentation/html/store_introspector.js.html @@ -325,7 +325,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/store_recordData.js.html b/documentation/html/store_recordData.js.html index 2d8ef51a77..55ec29e219 100644 --- a/documentation/html/store_recordData.js.html +++ b/documentation/html/store_recordData.js.html @@ -872,7 +872,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/store_recordSearch.js.html b/documentation/html/store_recordSearch.js.html index f7d452230a..2a3fa6ba0b 100644 --- a/documentation/html/store_recordSearch.js.html +++ b/documentation/html/store_recordSearch.js.html @@ -355,7 +355,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/store_searchFilters.js.html b/documentation/html/store_searchFilters.js.html index 4531819ad9..d6fb2e4dcd 100644 --- a/documentation/html/store_searchFilters.js.html +++ b/documentation/html/store_searchFilters.js.html @@ -301,7 +301,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/utils_advancedSearchUtils.js.html b/documentation/html/utils_advancedSearchUtils.js.html index 99a35cd13a..cc42a18feb 100644 --- a/documentation/html/utils_advancedSearchUtils.js.html +++ b/documentation/html/utils_advancedSearchUtils.js.html @@ -196,7 +196,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/utils_query-builder-vue-3_dist_query-builder-vue-3.js.html b/documentation/html/utils_query-builder-vue-3_dist_query-builder-vue-3.js.html index 3b2ec69e8f..9f854b888e 100644 --- a/documentation/html/utils_query-builder-vue-3_dist_query-builder-vue-3.js.html +++ b/documentation/html/utils_query-builder-vue-3_dist_query-builder-vue-3.js.html @@ -3653,7 +3653,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/utils_recordTabUtils.js.html b/documentation/html/utils_recordTabUtils.js.html index 0185ac53c2..e6ddf10d67 100644 --- a/documentation/html/utils_recordTabUtils.js.html +++ b/documentation/html/utils_recordTabUtils.js.html @@ -270,7 +270,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/utils_rules.js.html b/documentation/html/utils_rules.js.html index 6f19c73248..aa29604fa2 100644 --- a/documentation/html/utils_rules.js.html +++ b/documentation/html/utils_rules.js.html @@ -293,7 +293,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_AdvancedSearch_AdvancedSearchResultTable.vue.html b/documentation/html/views_AdvancedSearch_AdvancedSearchResultTable.vue.html index cffaa20c9c..4d4da809c3 100644 --- a/documentation/html/views_AdvancedSearch_AdvancedSearchResultTable.vue.html +++ b/documentation/html/views_AdvancedSearch_AdvancedSearchResultTable.vue.html @@ -451,7 +451,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_AdvancedSearch_AdvancedSearchSelection.vue.html b/documentation/html/views_AdvancedSearch_AdvancedSearchSelection.vue.html index f9656c3567..cebf1cb317 100644 --- a/documentation/html/views_AdvancedSearch_AdvancedSearchSelection.vue.html +++ b/documentation/html/views_AdvancedSearch_AdvancedSearchSelection.vue.html @@ -373,7 +373,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Browsers_OntologyBrowser.vue.html b/documentation/html/views_Browsers_OntologyBrowser.vue.html index dfe152c145..234319da1f 100644 --- a/documentation/html/views_Browsers_OntologyBrowser.vue.html +++ b/documentation/html/views_Browsers_OntologyBrowser.vue.html @@ -697,7 +697,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_CreateRecord_NewRecord.vue.html b/documentation/html/views_CreateRecord_NewRecord.vue.html index baa9016b6c..866bdc80e5 100644 --- a/documentation/html/views_CreateRecord_NewRecord.vue.html +++ b/documentation/html/views_CreateRecord_NewRecord.vue.html @@ -401,7 +401,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Home_Home.vue.html b/documentation/html/views_Home_Home.vue.html index b6f423cafa..266a6c5ea3 100644 --- a/documentation/html/views_Home_Home.vue.html +++ b/documentation/html/views_Home_Home.vue.html @@ -188,7 +188,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Organisations_Organisation.vue.html b/documentation/html/views_Organisations_Organisation.vue.html index 820d9c2242..53b705a15e 100644 --- a/documentation/html/views_Organisations_Organisation.vue.html +++ b/documentation/html/views_Organisations_Organisation.vue.html @@ -991,7 +991,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Records_NetworkGraph.vue.html b/documentation/html/views_Records_NetworkGraph.vue.html index 6c85a0c833..d34bf3cdea 100644 --- a/documentation/html/views_Records_NetworkGraph.vue.html +++ b/documentation/html/views_Records_NetworkGraph.vue.html @@ -734,7 +734,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Records_Record.vue.html b/documentation/html/views_Records_Record.vue.html index acfe2b9ccc..a9b26e0b38 100644 --- a/documentation/html/views_Records_Record.vue.html +++ b/documentation/html/views_Records_Record.vue.html @@ -1494,7 +1494,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Records_Records.vue.html b/documentation/html/views_Records_Records.vue.html index 752c5e8c49..2edd7e5a87 100644 --- a/documentation/html/views_Records_Records.vue.html +++ b/documentation/html/views_Records_Records.vue.html @@ -450,7 +450,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Static_Community_Community.vue.html b/documentation/html/views_Static_Community_Community.vue.html index e8592eb54c..b2d6c639ec 100644 --- a/documentation/html/views_Static_Community_Community.vue.html +++ b/documentation/html/views_Static_Community_Community.vue.html @@ -999,7 +999,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Static_Timeline_Timeline.vue.html b/documentation/html/views_Static_Timeline_Timeline.vue.html index 186c04f757..ecf5f73250 100644 --- a/documentation/html/views_Static_Timeline_Timeline.vue.html +++ b/documentation/html/views_Static_Timeline_Timeline.vue.html @@ -153,7 +153,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Users_Login_Login.vue.html b/documentation/html/views_Users_Login_Login.vue.html index 11b5aa542b..8041cf3252 100644 --- a/documentation/html/views_Users_Login_Login.vue.html +++ b/documentation/html/views_Users_Login_Login.vue.html @@ -462,7 +462,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. diff --git a/documentation/html/views_Users_Signup.vue.html b/documentation/html/views_Users_Signup.vue.html index bf9e9dfc1a..b065347c61 100644 --- a/documentation/html/views_Users_Signup.vue.html +++ b/documentation/html/views_Users_Signup.vue.html @@ -150,7 +150,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 16th 2026 + on Wed Jul 22nd 2026 using the DocStrap template. From 615949f0b5a4ee6103bc6335f188c1b35b54db3e Mon Sep 17 00:00:00 2001 From: Milo Thurston Date: Wed, 22 Jul 2026 16:53:20 +0100 Subject: [PATCH 03/12] Coverage increase. --- tests/setup.js | 28 +++++++++++++++------------- vite.config.mjs | 4 ++-- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/tests/setup.js b/tests/setup.js index 5c083714cb..92f5360909 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -190,19 +190,21 @@ global.IntersectionObserver = class IntersectionObserver { // --- 3. window.matchMedia Polyfill --- // CRITICAL for $vuetify.display (mdAndDown, lgAndUp, etc.) // We default 'matches' to false, meaning the test assumes "Desktop" view by default. -Object.defineProperty(window, "matchMedia", { - writable: true, - value: vi.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: vi.fn(), // deprecated - removeListener: vi.fn(), // deprecated - addEventListener: vi.fn(), - removeEventListener: vi.fn(), - dispatchEvent: vi.fn(), - })), -}); +if (typeof window !== "undefined") { + Object.defineProperty(window, "matchMedia", { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }); +} // --- 4. Mock global CSS support --- // Prevents errors in some Vuetify computed properties diff --git a/vite.config.mjs b/vite.config.mjs index 2555e91ae9..b820306d0f 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -24,7 +24,7 @@ export default defineConfig(({ isSsrBuild }) => { }); // Force it to ONLY run on the client build (The Vike-native way) - polyfills.apply = (config, env) => !env.isSsrBuild; + polyfills.apply = (config, env) => !env.isSsrBuild && env.mode !== "test"; return { base: "/", @@ -96,4 +96,4 @@ export default defineConfig(({ isSsrBuild }) => { modulePreload: false, } }; -}); \ No newline at end of file +}); From 9054d9cfad0b7344fc1cd2ba55f813ee23f7744f Mon Sep 17 00:00:00 2001 From: Milo Thurston Date: Wed, 22 Jul 2026 17:06:58 +0100 Subject: [PATCH 04/12] Exclude compiled files on Github. --- vitest.config.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vitest.config.mjs b/vitest.config.mjs index 21b37681f2..066dfbc677 100644 --- a/vitest.config.mjs +++ b/vitest.config.mjs @@ -51,6 +51,7 @@ export default defineConfig(async (env) => { include: ["tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], coverage: { provider: "v8", // or 'istanbul' + include: ["src/**/*.js"], // In v3, 'all' is true by default, which might "drop" your % // because it now counts untested files. all: false, // Set to false to match Vitest 2 behavior if preferred @@ -88,4 +89,4 @@ export default defineConfig(async (env) => { }, } ); -}); \ No newline at end of file +}); From b11d4c1f0a98ae6be62461d4902f1ed68ea202be Mon Sep 17 00:00:00 2001 From: Milo Thurston Date: Wed, 22 Jul 2026 17:19:48 +0100 Subject: [PATCH 05/12] Added missing files. --- public/assets/Home/BlockHero/pattern-blue.png | Bin 0 -> 101028 bytes .../lib/GraphClient/GraphClientSEO.spec.js | 91 ++++++++++ .../unit/lib/Prerender/prerenderUtils.spec.js | 74 ++++++++ tests/unit/pages/data.spec.js | 119 +++++++++++++ tests/unit/pages/indexData.spec.js | 47 +++++ tests/unit/pages/metadata.spec.js | 162 ++++++++++++++++++ tests/unit/pages/onCreateApp.spec.js | 106 ++++++++++++ tests/unit/pages/partialBuild.spec.js | 30 ++++ .../Documentation/Documentation.spec.js | 20 +++ 9 files changed, 649 insertions(+) create mode 100644 public/assets/Home/BlockHero/pattern-blue.png create mode 100644 tests/unit/lib/GraphClient/GraphClientSEO.spec.js create mode 100644 tests/unit/lib/Prerender/prerenderUtils.spec.js create mode 100644 tests/unit/pages/data.spec.js create mode 100644 tests/unit/pages/indexData.spec.js create mode 100644 tests/unit/pages/metadata.spec.js create mode 100644 tests/unit/pages/onCreateApp.spec.js create mode 100644 tests/unit/pages/partialBuild.spec.js create mode 100644 tests/unit/views/Static/Documentation/Documentation.spec.js diff --git a/public/assets/Home/BlockHero/pattern-blue.png b/public/assets/Home/BlockHero/pattern-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..c1052d8c11c67b89981116ed4be4748d622fa394 GIT binary patch literal 101028 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 VBeN^GN(B7T)ilzmy<;E!{{R}rs{#N3 literal 0 HcmV?d00001 diff --git a/tests/unit/lib/GraphClient/GraphClientSEO.spec.js b/tests/unit/lib/GraphClient/GraphClientSEO.spec.js new file mode 100644 index 0000000000..5dda924373 --- /dev/null +++ b/tests/unit/lib/GraphClient/GraphClientSEO.spec.js @@ -0,0 +1,91 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import axios from "axios"; +import GraphClientSEO from "@/lib/GraphClient/GraphClientSEO.js"; + +vi.mock("axios", () => ({ + default: vi.fn(), +})); + +describe("GraphClientSEO", () => { + let client; + + beforeEach(() => { + GraphClientSEO._instance = undefined; + process.env.VITE_API_ENDPOINT = "https://api.example.org/"; + process.env.VITE_CLIENT_ID = "client-id"; + axios.mockReset(); + client = new GraphClientSEO(); + }); + + it("initializes headers, normalizes the endpoint, and remains a singleton", () => { + expect(client.url).toBe("https://api.example.org/graphql"); + expect(client.headers["X-Client-Id"]).toBe("client-id"); + expect(new GraphClientSEO()).toBe(client); + + client.setHeader("token"); + expect(client.headers.Authorization).toBe("Bearer token"); + }); + + it("omits the optional client ID header", () => { + GraphClientSEO._instance = undefined; + delete process.env.VITE_CLIENT_ID; + + const clientWithoutId = new GraphClientSEO(); + + expect(clientWithoutId.headers).not.toHaveProperty("X-Client-Id"); + }); + + it("builds parameters, fragments, and nested fields", () => { + const query = { + queryName: "records", + queryParam: { + active: true, + page: 2, + name: "Example", + filter: '{status: "ready"}', + ids: [1, "two"], + }, + fields: [ + "id", + { $ref: "keywords" }, + { $ref: "objectTypes" }, + { + name: "owner", + fields: ["name", { queryName: "profile", fields: ["id"] }], + }, + ], + }; + + const output = client.buildQuery(query); + + expect(output).toContain("records("); + expect(output).toContain("active:true"); + expect(output).toContain("page:2"); + expect(output).toContain('name:"Example"'); + expect(output).toContain('filter:{status: "ready"}'); + expect(output).toContain('ids:[1,"two"]'); + expect(output).toContain("owner{name profile{ id}}"); + expect(output).toContain("objectTypes{"); + expect(client.buildQuery({ queryName: "ping" })).toBe("ping"); + }); + + it("posts queries and returns GraphQL data or errors", async () => { + axios.mockResolvedValueOnce({ data: { data: { records: [1] } } }); + + await expect( + client.executeQuery({ queryName: "records", fields: ["id"] }), + ).resolves.toEqual({ records: [1] }); + expect(axios).toHaveBeenCalledWith({ + method: "post", + url: "https://api.example.org/graphql", + data: { query: "{records{ id}}" }, + headers: client.headers, + }); + + axios.mockResolvedValueOnce({ data: { errors: [{ message: "bad query" }] } }); + await expect(client.executeQuery({ queryName: "broken" })).resolves.toEqual([ + { message: "bad query" }, + ]); + }); +}); diff --git a/tests/unit/lib/Prerender/prerenderUtils.spec.js b/tests/unit/lib/Prerender/prerenderUtils.spec.js new file mode 100644 index 0000000000..3c6f95a979 --- /dev/null +++ b/tests/unit/lib/Prerender/prerenderUtils.spec.js @@ -0,0 +1,74 @@ +// @vitest-environment node + +import fs from "node:fs"; +import path from "node:path"; +import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; + +const mockPaths = vi.hoisted(() => { + const root = "/tmp/fairsharing-prerender-utils-tests"; + return { + root, + records: `${root}/records.json`, + organisations: `${root}/organisations.json`, + jsonld: `${root}/jsonld`, + }; +}); + +vi.mock("@/lib/Prerender/build-context.json", () => ({ + default: { + recordsFile: mockPaths.records, + organisationsFile: mockPaths.organisations, + jsonldDir: mockPaths.jsonld, + }, +})); + +import { + readGeneratedOrganisations, + readGeneratedRecords, + readGeneratedSchemaOrg, +} from "@/lib/Prerender/prerenderUtils.server.js"; +import { normalizeDoi } from "@/lib/Prerender/prerenderUtils.shared.js"; + +describe("prerender utilities", () => { + beforeAll(() => { + fs.mkdirSync(mockPaths.jsonld, { recursive: true }); + fs.writeFileSync(mockPaths.records, JSON.stringify([{ id: 1 }])); + fs.writeFileSync( + mockPaths.organisations, + JSON.stringify([{ id: 2, name: "Example" }]), + ); + fs.writeFileSync( + path.join(mockPaths.jsonld, "1.jsonld"), + JSON.stringify({ "@type": "Dataset" }), + ); + }); + + afterAll(() => { + fs.rmSync(mockPaths.root, { recursive: true, force: true }); + }); + + it("reads generated records, organisations, and schema.org data", () => { + expect(readGeneratedRecords()).toEqual([{ id: 1 }]); + expect(readGeneratedOrganisations()).toEqual([{ id: 2, name: "Example" }]); + expect(readGeneratedSchemaOrg(1)).toEqual({ "@type": "Dataset" }); + }); + + it("returns the schema fallback when a generated file is absent", () => { + const warning = vi.spyOn(console, "warn").mockImplementation(() => {}); + + expect(readGeneratedSchemaOrg("missing")).toBeNull(); + expect(warning).toHaveBeenCalledWith( + expect.stringContaining("missing.jsonld"), + ); + + warning.mockRestore(); + }); + + it.each([ + [" https://doi.org/10.1234/example/ ", "10.1234/example"], + ["http://dx.doi.org/10.1234%2Fencoded", "10.1234/encoded"], + ["doi:/10.1234/example/", "10.1234/example"], + ])("normalizes DOI value %s", (input, expected) => { + expect(normalizeDoi(input)).toBe(expected); + }); +}); diff --git a/tests/unit/pages/data.spec.js b/tests/unit/pages/data.spec.js new file mode 100644 index 0000000000..f9115ec730 --- /dev/null +++ b/tests/unit/pages/data.spec.js @@ -0,0 +1,119 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const fixtures = vi.hoisted(() => ({ + records: [ + { + id: 1, + doi: "10.1234/example", + name: "Example record", + description: "Record description", + }, + { id: 2, doi: "", name: "Second record", description: "" }, + { id: "invalid", doi: "10.1234/other", name: "Other record" }, + ], + organisations: [ + { id: 1, name: "First organisation" }, + { id: 2, name: "Second organisation" }, + ], + schemaOrg: { "@type": "Dataset" }, +})); + +vi.mock("@/lib/Prerender/build-context.json", () => ({ + default: { skipFull: false, batch: 1, batchSize: 2 }, +})); +vi.mock("@/lib/Prerender/prerenderUtils.server.js", () => ({ + readGeneratedRecords: vi.fn(async () => fixtures.records), + readGeneratedOrganisations: vi.fn(async () => fixtures.organisations), + readGeneratedSchemaOrg: vi.fn(() => fixtures.schemaOrg), +})); + +import { data as recordData } from "@/pages/all/+data.js"; +import { onBeforePrerenderStart } from "@/pages/all/+onBeforePrerenderStart.js"; +import { data as organisationsData } from "@/pages/organisations/+data.js"; +import { data as organisationData } from "@/pages/organisations/@id/+data.js"; + +describe("prerender page data", () => { + beforeEach(() => { + vi.stubEnv("SSR", true); + }); + + it("returns empty metadata for empty and unknown record routes", async () => { + await expect( + recordData({ routeParams: { "*": "index" } }), + ).resolves.toMatchObject({ record: null, schemaOrg: null }); + await expect( + recordData({ routeParams: { "*": "not-found" } }), + ).resolves.toMatchObject({ record: null, canonicalUrl: null }); + }); + + it("finds numeric and DOI record routes and builds canonical metadata", async () => { + const numeric = await recordData({ routeParams: { "*": "1" } }); + const doiAlias = await recordData({ routeParams: { "*": "example" } }); + + expect(numeric).toMatchObject({ + record: fixtures.records[0], + schemaOrg: fixtures.schemaOrg, + canonicalUrl: "https://fairsharing.org/10.1234/example", + seoTitle: "Example record | FAIRsharing", + seoDescription: "Record description", + }); + expect(doiAlias.record).toEqual(fixtures.records[0]); + }); + + it("returns record-only data in the browser", async () => { + vi.stubEnv("SSR", false); + + await expect(recordData({ routeParams: { "*": "2" } })).resolves.toEqual({ + record: fixtures.records[1], + schemaOrg: null, + }); + }); + + it("builds unique static, record, DOI, and organisation prerender routes", async () => { + const log = vi.spyOn(console, "log").mockImplementation(() => {}); + const routes = await onBeforePrerenderStart(); + + expect(routes).toContain("/"); + expect(routes).toContain("/1"); + expect(routes).toContain("/10.1234/example"); + expect(routes).toContain("/example"); + expect(routes).toContain("/2"); + expect(routes).toContain("/organisations/2"); + expect(new Set(routes).size).toBe(routes.length); + expect(log).toHaveBeenCalledWith(expect.stringContaining("Building Batch #1")); + + log.mockRestore(); + }); + + it("logs when a batch contains no record routes", async () => { + const records = [...fixtures.records]; + const organisations = [...fixtures.organisations]; + fixtures.records.splice(0); + fixtures.organisations.splice(0); + const log = vi.spyOn(console, "log").mockImplementation(() => {}); + + const routes = await onBeforePrerenderStart(); + + expect(routes).toContain("/"); + expect(log).toHaveBeenCalledWith("No records found for batch #1."); + + fixtures.records.push(...records); + fixtures.organisations.push(...organisations); + log.mockRestore(); + }); + + it("returns organisation collections and selects an organisation by ID", async () => { + await expect(organisationsData()).resolves.toEqual({ + organisations: fixtures.organisations, + }); + await expect( + organisationData({ routeParams: { id: "2" } }), + ).resolves.toEqual({ organisation: fixtures.organisations[1] }); + await expect( + organisationData({ routeParams: {} }), + ).resolves.toEqual({ organisation: null }); + await expect( + organisationData({ routeParams: { id: "99" } }), + ).resolves.toEqual({ organisation: null }); + }); +}); diff --git a/tests/unit/pages/indexData.spec.js b/tests/unit/pages/indexData.spec.js new file mode 100644 index 0000000000..e0e0786cf8 --- /dev/null +++ b/tests/unit/pages/indexData.spec.js @@ -0,0 +1,47 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const mocks = vi.hoisted(() => ({ + getHomepageJsonld: vi.fn(), + setConfig: vi.fn(), +})); + +vi.mock("@/lib/Client/RESTClient.js", () => ({ + default: vi.fn(function () { + return { getHomepageJsonld: mocks.getHomepageJsonld }; + }), +})); +vi.mock("vike-vue/useConfig", () => ({ + useConfig: () => mocks.setConfig, +})); + +import { data } from "@/pages/index/+data.js"; + +describe("homepage data", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("adds non-empty schema.org data to the page head", async () => { + mocks.getHomepageJsonld.mockResolvedValue({ + "@type": "WebSite", + description: "", + }); + + const result = await data(); + const head = mocks.setConfig.mock.calls[0][0].Head; + + expect(result.JSONLD).toEqual({ + "@type": "WebSite", + description: "", + }); + expect(head.type).toBe("script"); + expect(head.props.innerHTML).toContain("\\u003cunsafe>"); + }); + + it("returns null and leaves the head unchanged without schema.org data", async () => { + mocks.getHomepageJsonld.mockResolvedValue(null); + + await expect(data()).resolves.toEqual({ JSONLD: null }); + expect(mocks.setConfig).not.toHaveBeenCalled(); + }); +}); diff --git a/tests/unit/pages/metadata.spec.js b/tests/unit/pages/metadata.spec.js new file mode 100644 index 0000000000..2396dbe63f --- /dev/null +++ b/tests/unit/pages/metadata.spec.js @@ -0,0 +1,162 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const pageData = vi.hoisted(() => ({ current: {} })); + +vi.mock("vike-vue/useData", () => ({ + useData: () => pageData.current, +})); +vi.mock("vike-vue/config", () => ({ default: { name: "vike-vue" } })); +vi.mock("@/pages/+Layout.vue", () => ({ default: { name: "Layout" } })); + +import config from "@/pages/+config.js"; +import Head from "@/pages/all/+Head.js"; +import description from "@/pages/all/+description.js"; +import route from "@/pages/all/+route.js"; +import title from "@/pages/all/+title.js"; +import organisationDescription from "@/pages/organisations/@id/+description.js"; +import organisationTitle from "@/pages/organisations/@id/+title.js"; + +describe("page metadata", () => { + beforeEach(() => { + pageData.current = {}; + }); + + it("exports the root Vike configuration and catch-all route", () => { + expect(config.extends).toEqual([{ name: "vike-vue" }]); + expect(config.Layout).toEqual({ name: "Layout" }); + expect(config.ssr).toBe(true); + expect(config.prerender).toMatchObject({ partial: true, parallel: false }); + expect(route).toBe("/*"); + }); + + it("does not create record head elements without a record", () => { + expect(Head()).toBeNull(); + }); + + it("creates canonical, Open Graph, and escaped schema.org head elements", () => { + pageData.current = { + record: { + doi: "10.1234/example", + name: "Example record", + description: "Description ", + }, + schemaOrg: { "@context": "https://schema.org", ignoredName: "old" }, + canonicalUrl: "https://fairsharing.org/10.1234/example", + seoTitle: "Example record | FAIRsharing", + seoDescription: "Example description", + }; + + const elements = Head(); + const script = elements.find((element) => element.type === "script"); + + expect(elements).toHaveLength(7); + expect(elements.find((element) => element.type === "title").children).toBe( + "Example record | FAIRsharing", + ); + expect(script.props.innerHTML).toContain("\\u003cunsafe>"); + expect(script.props.innerHTML).toContain( + '"url":"https://fairsharing.org/10.1234/example"', + ); + }); + + it("filters optional head elements and schema when values are absent", () => { + pageData.current = { record: { name: "Minimal" } }; + + expect(Head()).toEqual([]); + }); + + it("uses schema.org fallbacks when DOI and description are absent", () => { + pageData.current = { + record: { name: "Minimal" }, + schemaOrg: { "@context": "https://schema.org" }, + canonicalUrl: "https://fairsharing.org/1", + }; + + const script = Head().find((element) => element.type === "script"); + const schema = JSON.parse(script.props.innerHTML); + + expect(schema.identifier).toEqual([]); + expect(schema.description).toBe(""); + }); + + it("returns record, static, search, and fallback titles", () => { + expect( + title({ urlPathname: "/anything", data: { record: { name: "Record" } } }), + ).toBe("Record | FAIRsharing"); + expect(title({ urlPathname: "/privacy" })).toBe( + "Privacy Policy | FAIRsharing", + ); + expect( + title({ + urlPathname: "/search", + urlParsed: { search: "?fairsharingRegistry=DATABASE" }, + }), + ).toBe("Databases | FAIRsharing"); + expect( + title({ + urlPathname: "/search", + urlParsed: { search: "?fairsharingRegistry=unknown" }, + }), + ).toBe("Search | FAIRsharing"); + expect(title({ urlPathname: "/unknown" })).toBe("FAIRsharing"); + }); + + it("returns record, static, search, and fallback descriptions", () => { + expect( + description({ + urlPathname: "/anything", + data: { record: { name: "Record", description: "Record description" } }, + }), + ).toBe("Record description"); + expect( + description({ + urlPathname: "/anything", + data: { record: { name: "Record" } }, + }), + ).toContain("Record"); + expect(description({ urlPathname: "/organisations" })).toBe( + "List of Organisations", + ); + expect( + description({ + urlPathname: "/search", + urlParsed: { search: "?fairsharingRegistry=POLICY" }, + }), + ).toContain("data preservation"); + expect(description({ urlPathname: "/search" })).toContain( + "advanced filtering", + ); + expect( + description({ + urlPathname: "/search", + urlParsed: { search: "?fairsharingRegistry=unknown" }, + }), + ).toContain("advanced filtering"); + expect(description({ urlPathname: "/unknown" })).toContain( + "A curated, informative", + ); + }); + + it("creates organisation titles and descriptions with fallbacks", () => { + const context = { + data: { + organisation: { + name: "Example Organisation", + homepage: "https://example.org", + }, + }, + }; + + expect(organisationTitle(context)).toBe( + "Example Organisation | FAIRsharing", + ); + expect(organisationDescription(context)).toBe("https://example.org"); + expect( + organisationDescription({ + data: { organisation: { name: "No homepage", length: 1 } }, + }), + ).toContain("1 organisations available"); + expect(organisationTitle({})).toBe("Organisations | FAIRsharing"); + expect(organisationDescription({})).toContain("A curated, informative"); + }); +}); diff --git a/tests/unit/pages/onCreateApp.spec.js b/tests/unit/pages/onCreateApp.spec.js new file mode 100644 index 0000000000..bceb07e3f4 --- /dev/null +++ b/tests/unit/pages/onCreateApp.spec.js @@ -0,0 +1,106 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const mocks = vi.hoisted(() => ({ + store: { name: "store" }, + router: { + push: vi.fn(), + isReady: vi.fn().mockResolvedValue(undefined), + }, + bootstrapApp: vi.fn().mockResolvedValue(undefined), + vuetify: { name: "vuetify" }, + metaManager: { name: "meta" }, + sanitize: vi.fn((value) => `clean:${value}`), + accessibilityInit: vi.fn(), + loadFull: vi.fn().mockResolvedValue(undefined), +})); + +vi.mock("@/store", () => ({ createMyStore: () => mocks.store })); +vi.mock("@/router", () => ({ createMyRouter: () => mocks.router })); +vi.mock("@/plugins/vuetify", () => ({ default: () => mocks.vuetify })); +vi.mock("@/utils/setupUtils", () => ({ + bootstrapApp: mocks.bootstrapApp, + globalFilters: { capitalize: vi.fn() }, +})); +vi.mock("vue-meta", () => ({ createMetaManager: () => mocks.metaManager })); +vi.mock("vue-3-sanitize", () => ({ default: { name: "sanitize-plugin" } })); +vi.mock("vue-3-linkify", () => ({ default: { name: "linkify" } })); +vi.mock("dompurify", () => ({ default: { sanitize: mocks.sanitize } })); +vi.mock("@/components/Static/APIDoc/CodeBlock.vue", () => ({ + default: { name: "CodeBlock" }, +})); +vi.mock("highcharts-vue", () => ({ default: { name: "highcharts-vue" } })); +vi.mock("highcharts", () => ({ default: { name: "highcharts" } })); +vi.mock("highcharts/modules/accessibility", () => ({ + default: mocks.accessibilityInit, +})); +vi.mock("simple-analytics-vue", () => ({ default: { name: "analytics" } })); +vi.mock("vue-gtag", () => ({ default: { name: "gtag" } })); +vi.mock("vue-scrollto", () => ({ default: { name: "scroll-to" } })); +vi.mock("@tsparticles/vue3", () => ({ default: { name: "particles" } })); +vi.mock("tsparticles", () => ({ loadFull: mocks.loadFull })); + +import onCreateApp from "@/pages/+onCreateApp.js"; + +function createApp() { + const directives = {}; + const app = { + use: vi.fn(() => app), + component: vi.fn(), + directive: vi.fn((name, handler) => { + directives[name] = handler; + }), + config: { globalProperties: {} }, + }; + return { app, directives }; +} + +describe("onCreateApp", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("initializes the isolated store and router for server rendering", async () => { + vi.stubEnv("SSR", true); + const { app, directives } = createApp(); + + await onCreateApp({ app, urlPathname: "/privacy" }); + + expect(app.use).toHaveBeenCalledWith(mocks.store); + expect(app.use).toHaveBeenCalledWith(mocks.router); + expect(mocks.bootstrapApp).toHaveBeenCalledWith(mocks.store, mocks.router); + expect(mocks.router.push).toHaveBeenCalledWith("/privacy"); + expect(mocks.router.isReady).toHaveBeenCalled(); + expect(app.component).toHaveBeenCalledWith( + "CodeBlock", + expect.objectContaining({ name: "CodeBlock" }), + ); + + const element = { innerHTML: "" }; + directives["safe-html"](element, { value: " From 21c1dc84fcf9dfa7f0cca01fb5c7b267489d4604 Mon Sep 17 00:00:00 2001 From: Milo Thurston Date: Thu, 23 Jul 2026 16:38:03 +0100 Subject: [PATCH 11/12] Increase test coverage. --- tests/unit/store/editor.spec.js | 283 +++++++++++++++++ tests/unit/store/recordData.spec.js | 473 ++++++++++++++++++++++++++++ 2 files changed, 756 insertions(+) create mode 100644 tests/unit/store/editor.spec.js create mode 100644 tests/unit/store/recordData.spec.js diff --git a/tests/unit/store/editor.spec.js b/tests/unit/store/editor.spec.js new file mode 100644 index 0000000000..2c343e52ca --- /dev/null +++ b/tests/unit/store/editor.spec.js @@ -0,0 +1,283 @@ +import GraphClient from "@/lib/GraphClient/GraphClient.js"; +import RESTClient from "@/lib/Client/RESTClient.js"; +import editorStore from "@/store/editor.js"; + +describe("editor store", () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it("generates the most recent 100 years", () => { + const years = editorStore.state.years(); + + expect(years).toHaveLength(100); + expect(years[0]).toBe(new Date().getFullYear()); + expect(years[99]).toBe(new Date().getFullYear() - 99); + }); + + it("updates and cleans its state", () => { + const state = { + countries: ["old"], + recordTypes: ["old"], + allTags: false, + tags: [], + objectTypes: ["old"], + organisations: ["old"], + organisationsTypes: ["old"], + grants: ["old"], + availablePublications: ["old"], + availableLicences: [], + availableRecords: [], + relationsTypes: [], + allowedFields: {}, + possibleDuplicates: ["old"], + }; + const { mutations } = editorStore; + + mutations.setCountries(state, ["UK"]); + mutations.setRecordTypes(state, ["standard"]); + mutations.setObjectTypes(state, ["dataset"]); + mutations.setTags(state, { data: ["tag"], firstTime: true }); + mutations.setTags(state, { data: ["filtered"], firstTime: false }); + mutations.setOrganisations(state, ["org"]); + mutations.setOrganisationsTypes(state, ["type"]); + mutations.setGrants(state, ["grant"]); + mutations.setAvailablePublications(state, ["publication"]); + mutations.setAvailableLicences(state, ["licence"]); + mutations.setAvailableRecords(state, ["record"]); + mutations.setAvailableRelationsTypes(state, { standard: [] }); + mutations.setAllowedFields(state, { field: true }); + mutations.setPossibleDuplicates(state, ["duplicate"]); + + expect(state.allTags).toEqual(["tag"]); + expect(state.tags).toEqual(["filtered"]); + expect(state.availableLicences).toEqual(["licence"]); + expect(state.availableRecords).toEqual(["record"]); + expect(state.relationsTypes).toEqual({ standard: [] }); + expect(state.allowedFields).toEqual({ field: true }); + + mutations.clearPossibleDuplicates(state); + expect(state.possibleDuplicates).toEqual([]); + + mutations.cleanEditorStore(state); + expect(state).toMatchObject({ + countries: null, + recordTypes: null, + allTags: [], + tags: [], + objectTypes: [], + organisations: null, + organisationsTypes: null, + grants: null, + availablePublications: [], + possibleDuplicates: [], + }); + }); + + it("loads editor lookup data", async () => { + const executeQuery = vi + .spyOn(GraphClient.prototype, "executeQuery") + .mockResolvedValueOnce({ searchCountries: [{ id: 1 }] }) + .mockResolvedValueOnce({ + fairsharingRegistries: { + records: [ + null, + { name: "", recordTypes: [] }, + { + name: "Standard", + recordTypes: [{ id: 2, name: "Model", description: "A model" }], + }, + { name: "Database" }, + ], + }, + }) + .mockResolvedValueOnce({ + fairsharingRegistries: { + records: [ + { name: "Standard", recordTypes: [] }, + { + name: "FAIRassist", + recordTypes: [{ id: 3, name: "Assessment" }], + }, + ], + }, + }) + .mockResolvedValueOnce({ objectTypes: { records: [{ id: 4 }] } }) + .mockResolvedValueOnce({ searchTags: [{ id: 5 }] }) + .mockResolvedValueOnce({ searchOrganisations: [{ id: 6 }] }) + .mockResolvedValueOnce({ searchOrganisationTypes: [{ id: 7 }] }) + .mockResolvedValueOnce({ searchGrants: [{ id: 8 }] }) + .mockResolvedValueOnce({ + searchPublications: [{ id: 9 }, { id: 10 }], + }) + .mockResolvedValueOnce({ searchLicences: [{ id: 11 }] }) + .mockResolvedValueOnce({ + searchFairsharingRecords: { records: [{ id: 12 }] }, + }) + .mockResolvedValueOnce({ duplicateCheck: [{ id: 13 }] }); + const commit = vi.fn(); + const context = { commit, state: { allTags: false } }; + + await editorStore.actions.getCountries(context); + await editorStore.actions.getRecordTypes(context); + await editorStore.actions.getRecordTypes(context, true); + await editorStore.actions.getObjectTypes(context); + await editorStore.actions.getTags(context, "genomics"); + await editorStore.actions.getOrganisations(context); + await editorStore.actions.getOrganisationsTypes(context); + await editorStore.actions.getGrants(context); + + const publications = [{ id: 10 }]; + await editorStore.actions.getAvailablePublications(context, publications); + await editorStore.actions.getLicences(context); + await editorStore.actions.getAvailableRecords(context, { + q: "record", + fairsharingRegistry: "Standard", + recordType: "Model", + excludeId: 1, + }); + await editorStore.actions.getPossibleDuplicates(context, { + fields: ["name"], + }); + + expect(executeQuery).toHaveBeenCalledTimes(12); + expect(commit).toHaveBeenCalledWith("setCountries", [{ id: 1 }]); + expect(commit).toHaveBeenCalledWith("setRecordTypes", [ + { header: "Standard" }, + { name: "Model", group: "Standard", id: 2, description: "A model" }, + { divider: true }, + { header: "Database" }, + ]); + expect(commit).toHaveBeenCalledWith("setRecordTypes", [ + { header: "FAIRassist" }, + { + name: "Assessment", + group: "FAIRassist", + id: 3, + description: undefined, + }, + ]); + expect(commit).toHaveBeenCalledWith("setTags", { + data: [{ id: 5 }], + firstTime: true, + }); + expect(publications[0].tablePosition).toBe(1); + expect(commit).toHaveBeenCalledWith( + "setAvailablePublications", + expect.arrayContaining([ + expect.objectContaining({ id: 9, isCitation: false }), + expect.objectContaining({ + id: 10, + isCitation: false, + tablePosition: 1, + }), + ]), + ); + expect(commit).toHaveBeenCalledWith("setAvailableRecords", [{ id: 12 }]); + expect(commit).toHaveBeenCalledWith("setPossibleDuplicates", [{ id: 13 }]); + }); + + it("uses empty lookup values when GraphQL requests fail", async () => { + vi.spyOn(GraphClient.prototype, "executeQuery").mockRejectedValue( + new Error("network error"), + ); + const commit = vi.fn(); + const context = { commit, state: { allTags: false } }; + + await editorStore.actions.getCountries(context); + await editorStore.actions.getRecordTypes(context); + await editorStore.actions.getObjectTypes(context); + await editorStore.actions.getTags(context); + + expect(commit).toHaveBeenCalledWith("setCountries", []); + expect(commit).toHaveBeenCalledWith("setRecordTypes", []); + expect(commit).toHaveBeenCalledWith("setObjectTypes", []); + expect(commit).toHaveBeenCalledWith("setTags", { + data: [], + firstTime: true, + }); + }); + + it("builds relation rules and loads allowed metadata fields", async () => { + vi.spyOn(RESTClient.prototype, "getRelationsTypes").mockResolvedValue([ + { + id: 1, + name: "maintains", + allowed_associations: [ + { from: "standard", to: "database" }, + { from: "standard", to: "policy" }, + ], + }, + { id: 2, name: "related_to", allowed_associations: [] }, + ]); + vi.spyOn(RESTClient.prototype, "extraMetadataFields").mockResolvedValue({ + field: true, + }); + const commit = vi.fn(); + + await editorStore.actions.getAvailableRelationsTypes({ commit }); + await editorStore.actions.getAllowedFields( + { commit }, + { type: "standard", token: "token" }, + ); + + const relationCommit = commit.mock.calls.find( + ([name]) => name === "setAvailableRelationsTypes", + ); + expect(relationCommit[1].standard).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + relation: "maintains", + target: "database", + }), + expect.objectContaining({ + relation: "maintains", + target: "policy", + }), + expect.objectContaining({ + relation: "related_to", + target: "standard", + }), + ]), + ); + expect(commit).toHaveBeenCalledWith("setAllowedFields", { field: true }); + }); + + it("filters tags, relations, and relation targets", () => { + const relation = { relation: "maintains", target: "database" }; + const duplicate = { ...relation }; + const other = { relation: "funds", target: "policy" }; + const state = { + tags: [ + { id: 1, model: "subject" }, + { id: 2, model: "domain" }, + ], + relationsTypes: { + standard: [relation, other], + Standards: [relation], + database: [duplicate, { relation: "invalid", target: "not_a_type" }], + }, + }; + + expect(editorStore.getters.getPartialTags(state)(["subject"])).toEqual([ + { id: 1, model: "subject" }, + ]); + expect( + editorStore.getters.allowedRelations(state)({ + sourceType: "standard", + sourceRegistry: "Standards", + target: null, + }), + ).toEqual([relation, other]); + expect( + editorStore.getters.allowedRelations(state)({ + sourceType: "standard", + sourceRegistry: "Standards", + target: { registry: "Policies", type: "database" }, + }), + ).toEqual([relation]); + expect(editorStore.getters.allowedTargets(state)("DATABASE")).toEqual([ + "database", + ]); + }); +}); diff --git a/tests/unit/store/recordData.spec.js b/tests/unit/store/recordData.spec.js new file mode 100644 index 0000000000..af1d9e05ec --- /dev/null +++ b/tests/unit/store/recordData.spec.js @@ -0,0 +1,473 @@ +import GraphClient from "@/lib/GraphClient/GraphClient.js"; +import RESTClient from "@/lib/Client/RESTClient.js"; +import recordStore from "@/store/recordData.js"; + +const makeState = () => ({ + currentRecord: { fairsharingRecord: { id: 42 } }, + currentRecordHistory: { old: true }, + recordUpdate: {}, + editOrganisationLink: { data: {} }, + newRecord: false, + sections: { + generalInformation: { + data: { + type: { id: 1 }, + metadata: { contacts: [], support_links: [] }, + }, + initialData: { type: { name: "Standard" }, metadata: {} }, + changes: 1, + message: null, + error: false, + }, + publications: { data: [], changes: 2, message: null }, + organisations: { + data: [], + initialData: [], + changes: 3, + message: null, + }, + additionalInformation: { + data: {}, + initialData: {}, + changes: 4, + message: null, + }, + dataAccess: { + data: { exhaustiveLicences: false, licences: [], support_links: [] }, + initialData: { licences: [] }, + changes: 5, + message: null, + }, + relations: { + data: { recordAssociations: [] }, + initialData: { recordAssociations: [] }, + changes: 6, + message: null, + error: false, + }, + }, +}); + +describe("record data store", () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it("updates the simple record state", () => { + const state = makeState(); + const { mutations } = recordStore; + + mutations.setRecordHistory(state, { version: 1 }); + mutations.resetCurrentRecordHistory(state); + mutations.resetMessage(state, "publications"); + mutations.setSectionError(state, { + section: "publications", + value: "failed", + }); + mutations.setChanges(state, { section: "publications", value: 7 }); + mutations.setContacts(state, [{ name: "Contact" }]); + mutations.setTags(state, { target: "domains", value: [{ id: 1 }] }); + mutations.resetRegistry(state); + mutations.setPublications(state, [{ id: 2 }]); + mutations.setEditOrganisationLink(state, { data: {} }); + mutations.setEditOrganisationLinkOrganisation(state, { id: 3 }); + mutations.setEditOrganisationLinkGrant(state, { id: 4 }); + mutations.setCreatingNewRecord(state); + mutations.setEditingRecord(state); + mutations.setMessage(state, { target: "organisations", value: "saved" }); + mutations.setNewRecord(state, 5); + + expect(state.currentRecordHistory).toEqual({}); + expect(state.sections.publications).toMatchObject({ + data: [{ id: 2 }], + changes: 7, + message: "failed", + error: true, + }); + expect(state.sections.generalInformation.data).toMatchObject({ + type: "", + domains: [{ id: 1 }], + metadata: { contacts: [{ name: "Contact" }] }, + }); + expect(state.editOrganisationLink.data).toEqual({ + organisation: { id: 3 }, + grant: { id: 4 }, + }); + expect(state.newRecord).toBe(false); + expect(state.recordUpdate).toEqual({ + error: false, + message: "success", + id: 5, + }); + + mutations.setError(state, "nope"); + expect(state.recordUpdate).toEqual({ + error: true, + message: "nope", + id: null, + }); + }); + + it("sets tag types on the current record", () => { + const state = makeState(); + const fairsharingRecord = { + subjects: [{ id: 1 }], + domains: [], + taxonomies: [{ id: 2 }], + userDefinedTags: [{ id: 3 }], + }; + + recordStore.mutations.setCurrentRecord(state, { fairsharingRecord }); + + expect(fairsharingRecord.subjects[0].type).toBe("subjects"); + expect(fairsharingRecord.taxonomies[0].type).toBe("taxonomies"); + expect(fairsharingRecord.userDefinedTags[0].type).toBe("userDefinedTags"); + }); + + it("edits additional-information fields", () => { + const state = makeState(); + const { mutations } = recordStore; + + mutations.setAdditionalInformation(state, { + fieldName: "single", + fieldValue: "value", + }); + state.sections.additionalInformation.data.nested = {}; + mutations.setAdditionalInformation(state, { + fieldName: "nested", + subfieldName: "child", + fieldValue: "nested value", + }); + mutations.setAdditionalInformationSubField(state, { + fieldName: "items", + id: null, + fieldValue: "first", + }); + mutations.setAdditionalInformationSubField(state, { + fieldName: "items", + id: 0, + fieldValue: "updated", + }); + mutations.setAdditionalInformationSubField(state, { + fieldName: "items", + id: null, + fieldValue: "second", + }); + mutations.removeAdditionalInformationSubField(state, { + fieldName: "items", + id: 0, + }); + + expect(state.sections.additionalInformation.data).toMatchObject({ + single: "value", + nested: { child: "nested value" }, + items: ["second"], + }); + }); + + it("refreshes organisation, data-access, additional-info and relation sections", () => { + const state = makeState(); + const { mutations } = recordStore; + + mutations.updateOrganisationsLinks(state, [{ id: 1 }]); + mutations.setDataAccess(state, { + exhaustiveLicences: true, + licenceLinks: [{ id: 2 }], + metadata: { + support_links: [ + { name: "API", url: "https://example.com/api" }, + { url: "https://example.com/help" }, + ], + }, + }); + mutations.updateAdditionalInformation(state, { + record: { included: { value: true }, excluded: "no" }, + fields: ["included"], + }); + mutations.setRelations(state, [{ id: 3 }]); + + expect(state.sections.organisations).toMatchObject({ + data: [{ id: 1 }], + initialData: [{ id: 1 }], + changes: 0, + message: "Record successfully updated!", + }); + expect(state.sections.dataAccess.data).toMatchObject({ + exhaustiveLicences: true, + licences: [{ id: 2 }], + support_links: [ + { + name: "API", + url: { + title: "API", + url: "https://example.com/api", + }, + }, + { url: "https://example.com/help" }, + ], + }); + expect(state.sections.additionalInformation.data).toEqual({ + included: { value: true }, + }); + expect(state.sections.relations).toMatchObject({ + data: { recordAssociations: [{ id: 3 }] }, + initialData: { recordAssociations: [{ id: 3 }] }, + changes: 0, + message: "Record successfully updated!", + error: false, + }); + }); + + it("fetches records, previews, and history", async () => { + const fetchedRecord = { + id: 42, + metadata: {}, + subjects: [], + domains: [], + taxonomies: [], + userDefinedTags: [], + }; + vi.spyOn(GraphClient.prototype, "executeQuery") + .mockResolvedValueOnce({ fairsharingRecord: fetchedRecord }) + .mockResolvedValueOnce({ fairsharingRecord: { id: 43 } }) + .mockResolvedValueOnce({ fairsharingRecord: { versions: [] } }); + const setHeader = vi.spyOn(GraphClient.prototype, "setHeader"); + const initializeHeader = vi.spyOn(GraphClient.prototype, "initalizeHeader"); + const commit = vi.fn(); + + await recordStore.actions.fetchRecord( + { commit }, + { id: 42, token: "token" }, + ); + await recordStore.actions.fetchPreviewRecord({ commit }, 43); + await recordStore.actions.fetchRecordHistory( + { commit }, + { id: 42, token: "token" }, + ); + + expect(setHeader).toHaveBeenCalledWith("token"); + expect(initializeHeader).toHaveBeenCalled(); + expect(fetchedRecord.metadata).toEqual({ contacts: [], citations: [] }); + expect(commit).toHaveBeenCalledWith("setCurrentRecord", { + fairsharingRecord: expect.objectContaining({ + id: 42, + metadata: { contacts: [], citations: [] }, + }), + }); + expect(commit).toHaveBeenCalledWith("setRecordHistory", { versions: [] }); + }); + + it("updates publications and handles errors", async () => { + const state = makeState(); + state.sections.publications.data = [ + { id: 1, isCitation: true }, + { id: 2, isCitation: false }, + ]; + const updateRecord = vi + .spyOn(RESTClient.prototype, "updateRecord") + .mockResolvedValueOnce({}) + .mockResolvedValueOnce({ error: "failed" }); + const commit = vi.fn(); + + await recordStore.actions.updatePublications( + { state, commit }, + { id: 42, token: "token" }, + ); + const error = await recordStore.actions.updatePublications( + { state, commit }, + { id: 42, token: "token" }, + ); + + expect(updateRecord).toHaveBeenCalledWith({ + record: { publication_ids: [1, 2], citation_ids: [1] }, + id: 42, + token: "token", + }); + expect(commit).toHaveBeenCalledWith("setMessage", { + target: "publications", + value: "Record successfully updated!", + }); + expect(error).toBe("failed"); + }); + + it("creates, updates, and deletes organisation links", async () => { + const state = makeState(); + state.sections.organisations.initialData = [{ id: 1 }]; + state.sections.organisations.data = [ + { + organisation: { id: 2 }, + relation: "maintains", + grant: null, + isLead: true, + }, + { + id: 3, + organisation: { id: 4 }, + relation: "funds", + grant: { id: 5 }, + isLead: false, + }, + ]; + const deleteLink = vi + .spyOn(RESTClient.prototype, "deleteOrganisationLink") + .mockResolvedValue({}); + const createLink = vi + .spyOn(RESTClient.prototype, "createOrganisationLink") + .mockResolvedValue({}); + const updateLink = vi + .spyOn(RESTClient.prototype, "updateOrganisationLink") + .mockResolvedValue({ error: "link warning" }); + vi.spyOn(GraphClient.prototype, "setHeader"); + vi.spyOn(GraphClient.prototype, "executeQuery").mockResolvedValue({ + fairsharingRecord: { organisationLinks: [{ id: 6 }] }, + }); + const commit = vi.fn(); + + await recordStore.actions.updateOrganisations({ state, commit }, "token"); + + expect(deleteLink).toHaveBeenCalledWith(1, "token"); + expect(createLink).toHaveBeenCalledWith( + { + fairsharing_record_id: 42, + organisation_id: 2, + relation: "maintains", + grant_id: null, + is_lead: true, + }, + "token", + ); + expect(updateLink).toHaveBeenCalledWith( + { + fairsharing_record_id: 42, + organisation_id: 4, + relation: "funds", + grant_id: 5, + is_lead: false, + }, + 3, + "token", + ); + expect(commit).toHaveBeenCalledWith("setSectionError", { + section: "organisations", + value: "link warning", + }); + expect(commit).toHaveBeenCalledWith("updateOrganisationsLinks", [ + { id: 6 }, + ]); + }); + + it("saves new relations, removes stale relations, and refreshes the section", async () => { + const state = makeState(); + state.sections.relations.data.recordAssociations = [ + { + new: true, + linkedRecord: { id: 2 }, + recordAssocLabel: { id: 10 }, + }, + { + linkedRecord: { id: 3 }, + recordAssocLabelId: 11, + }, + ]; + state.sections.relations.initialData.recordAssociations = [ + { + id: 1, + linkedRecord: { id: 3 }, + recordAssocLabelId: 11, + }, + { + id: 2, + linkedRecord: { id: 4 }, + recordAssocLabelId: 12, + }, + ]; + const saveRelations = vi + .spyOn(RESTClient.prototype, "saveRelations") + .mockResolvedValue({}); + const deleteRelations = vi + .spyOn(RESTClient.prototype, "deleteRelations") + .mockResolvedValue({}); + vi.spyOn(GraphClient.prototype, "setHeader"); + vi.spyOn(GraphClient.prototype, "executeQuery").mockResolvedValue({ + fairsharingRecord: { recordAssociations: [{ id: 20 }] }, + }); + const commit = vi.fn(); + + await recordStore.actions.updateRelations( + { state, commit }, + { source: 42, token: "token" }, + ); + + expect(saveRelations).toHaveBeenCalledWith({ + token: "token", + relations: [ + { + fairsharing_record_id: 42, + linked_record_id: 2, + record_assoc_label_id: 10, + }, + ], + target: 42, + }); + expect(deleteRelations).toHaveBeenCalledWith({ + token: "token", + relations: [{ id: 2, _destroy: 1 }], + target: 42, + }); + expect(commit).toHaveBeenCalledWith("setRelations", [{ id: 20 }]); + }); + + it("does not refresh relations when saving fails", async () => { + const state = makeState(); + vi.spyOn(RESTClient.prototype, "saveRelations").mockResolvedValue({ + error: "save failed", + }); + vi.spyOn(RESTClient.prototype, "deleteRelations").mockResolvedValue({}); + const executeQuery = vi.spyOn(GraphClient.prototype, "executeQuery"); + const commit = vi.fn(); + + await recordStore.actions.updateRelations( + { state, commit }, + { source: 42, token: "token" }, + ); + + expect(commit).toHaveBeenCalledWith("setSectionError", { + section: "relations", + value: "save failed", + }); + expect(executeQuery).not.toHaveBeenCalled(); + }); + + it("updates a new record and exposes record getters", async () => { + const state = makeState(); + state.currentRecord.fairsharingRecord.name = "Example"; + const commit = vi.fn(); + vi.spyOn(RESTClient.prototype, "updateRecord") + .mockResolvedValueOnce(99) + .mockResolvedValueOnce({ error: { response: "bad record" } }); + + recordStore.actions.resetRecord({ commit }); + await recordStore.actions.updateRecord({ commit }, { record: {} }); + await recordStore.actions.updateRecord({ commit }, { record: {} }); + + expect(commit).toHaveBeenCalledWith("setGeneralInformation", { + fairsharingRecord: false, + }); + expect(commit).toHaveBeenCalledWith("setNewRecord", 99); + expect(commit).toHaveBeenCalledWith("setError", "bad record"); + expect(recordStore.getters.getField(state)("name")).toBe("Example"); + expect(recordStore.getters.getSection(state)("publications")).toBe( + state.sections.publications, + ); + expect(recordStore.getters.getChanges(state)).toMatchObject({ + generalInformation: 1, + publications: 2, + relations: 6, + }); + expect(recordStore.getters.getAllChanges(state)).toBe(21); + expect(recordStore.getters.getCreatingNewRecord(state)).toBe(false); + expect(recordStore.getters.getRecordType(state)).toEqual({ + name: "Standard", + }); + }); +}); From c1932f3bf865154541bf6cd835e03e1418cc8db1 Mon Sep 17 00:00:00 2001 From: Milo Thurston Date: Tue, 28 Jul 2026 11:28:38 +0100 Subject: [PATCH 12/12] Updated docs. --- documentation/html/ExternalRESTClients.html | 2 +- documentation/html/GraphQLClient.html | 2 +- documentation/html/RESTClient.html | 2 +- documentation/html/Static.html | 2 +- documentation/html/classes.list.html | 2 +- .../components_Curators_CuratorRecordsAwaitingApproval.vue.html | 2 +- ..._DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html | 2 +- ...rators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html | 2 +- ...ors_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html | 2 +- ...tors_DownLoadRecordsComponents_RecordsNeedingReview.vue.html | 2 +- ...rators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html | 2 +- documentation/html/components_Curators_HiddenRecords.vue.html | 2 +- .../html/components_Curators_IncompleteRecords.vue.html | 2 +- .../html/components_Curators_MaintenanceRequests.vue.html | 2 +- .../html/components_Curators_RecentCuratorCreation.vue.html | 2 +- documentation/html/components_Curators_SystemMessages.vue.html | 2 +- .../components_Curators_UserRecordsAwaitingApproval.vue.html | 2 +- .../html/components_Records_Record_Collections.vue.html | 2 +- ...components_Records_Record_GeneralInfo_SavedSearches.vue.html | 2 +- .../html/components_Records_Record_RelatedContent.vue.html | 2 +- .../html/components_Records_Search_Header_FilterChips.vue.html | 2 +- .../html/components_Records_Search_Header_Pagination.vue.html | 2 +- .../html/components_Records_Search_Header_Sorting.vue.html | 2 +- ...Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html | 2 +- ..._QueryBuilderComponents_GeneralComponents_Countries.vue.html | 2 +- ...ch_QueryBuilderComponents_GeneralComponents_Domains.vue.html | 2 +- ...h_QueryBuilderComponents_GeneralComponents_Licences.vue.html | 2 +- ...ueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html | 2 +- ...ryBuilderComponents_GeneralComponents_Organisations.vue.html | 2 +- ...ch_QueryBuilderComponents_GeneralComponents_Subject.vue.html | 2 +- ...QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html | 2 +- ...yBuilderComponents_GeneralComponents_UserDefinedTag.vue.html | 2 +- ...h_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html | 2 +- ...QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html | 2 +- ...ch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html | 2 +- ..._QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html | 2 +- ...rch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html | 2 +- ...h_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html | 2 +- ...ecords_Search_Input_AdvancedSearch_QueryBuilderView.vue.html | 2 +- .../components_Records_Search_Input_FilterAutocomplete.vue.html | 2 +- .../html/components_Records_Search_Input_FilterButton.vue.html | 2 +- .../html/components_Records_Search_Input_SearchInput.vue.html | 2 +- ...mponents_Records_Search_SaveSearch_SaveSearchButton.vue.html | 2 +- ...ponents_Records_Search_SaveSearch_SaveSearchStepper.vue.html | 2 +- ...ch_SaveSearch_StepperComponents_OrganisationStepper.vue.html | 2 +- ...s_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html | 2 +- ...ords_Search_SaveSearch_StepperComponents_ResultCard.vue.html | 2 +- ...ch_SaveSearch_StepperComponents_StepperDialogHeader.vue.html | 2 +- ...rds_Search_SaveSearch_StepperComponents_UserStepper.vue.html | 2 +- ...nents_Users_Profiles_Private_ViewSavedSearchesTable.vue.html | 2 +- documentation/html/global.html | 2 +- documentation/html/index.html | 2 +- documentation/html/lib_Client_ExternalClients.js.html | 2 +- documentation/html/lib_Client_RESTClient.js.html | 2 +- documentation/html/lib_GraphClient_GraphClient.js.html | 2 +- documentation/html/lib_GraphClient_GraphClientSEO.js.html | 2 +- documentation/html/module-Home.html | 2 +- documentation/html/module-Login.html | 2 +- documentation/html/module-NewRecord.html | 2 +- documentation/html/module-Pagination.html | 2 +- documentation/html/module-Signup.html | 2 +- documentation/html/module-User.html | 2 +- documentation/html/modules.list.html | 2 +- documentation/html/namespaces.list.html | 2 +- documentation/html/router_hackSearch.js.html | 2 +- documentation/html/store_introspector.js.html | 2 +- documentation/html/store_recordData.js.html | 2 +- documentation/html/store_recordSearch.js.html | 2 +- documentation/html/store_searchFilters.js.html | 2 +- documentation/html/utils_advancedSearchUtils.js.html | 2 +- .../utils_query-builder-vue-3_dist_query-builder-vue-3.js.html | 2 +- documentation/html/utils_recordTabUtils.js.html | 2 +- documentation/html/utils_rules.js.html | 2 +- .../views_AdvancedSearch_AdvancedSearchResultTable.vue.html | 2 +- .../html/views_AdvancedSearch_AdvancedSearchSelection.vue.html | 2 +- documentation/html/views_Browsers_OntologyBrowser.vue.html | 2 +- documentation/html/views_CreateRecord_NewRecord.vue.html | 2 +- documentation/html/views_Home_Home.vue.html | 2 +- documentation/html/views_Organisations_Organisation.vue.html | 2 +- documentation/html/views_Records_NetworkGraph.vue.html | 2 +- documentation/html/views_Records_Record.vue.html | 2 +- documentation/html/views_Records_Records.vue.html | 2 +- documentation/html/views_Static_Community_Community.vue.html | 2 +- documentation/html/views_Static_Timeline_Timeline.vue.html | 2 +- documentation/html/views_Users_Login_Login.vue.html | 2 +- documentation/html/views_Users_Signup.vue.html | 2 +- 86 files changed, 86 insertions(+), 86 deletions(-) diff --git a/documentation/html/ExternalRESTClients.html b/documentation/html/ExternalRESTClients.html index a15aca17e9..937351fefe 100644 --- a/documentation/html/ExternalRESTClients.html +++ b/documentation/html/ExternalRESTClients.html @@ -414,7 +414,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/GraphQLClient.html b/documentation/html/GraphQLClient.html index 878a9ac7e4..79ddd85de6 100644 --- a/documentation/html/GraphQLClient.html +++ b/documentation/html/GraphQLClient.html @@ -912,7 +912,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/RESTClient.html b/documentation/html/RESTClient.html index 3c5d1a2b9f..e24372e1d8 100644 --- a/documentation/html/RESTClient.html +++ b/documentation/html/RESTClient.html @@ -10217,7 +10217,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/Static.html b/documentation/html/Static.html index 605b000b4c..bbfe91e8fb 100644 --- a/documentation/html/Static.html +++ b/documentation/html/Static.html @@ -391,7 +391,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/classes.list.html b/documentation/html/classes.list.html index fbd998a404..04cfe29bae 100644 --- a/documentation/html/classes.list.html +++ b/documentation/html/classes.list.html @@ -2984,7 +2984,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_CuratorRecordsAwaitingApproval.vue.html b/documentation/html/components_Curators_CuratorRecordsAwaitingApproval.vue.html index e5fe1f4db5..2bebd1b06f 100644 --- a/documentation/html/components_Curators_CuratorRecordsAwaitingApproval.vue.html +++ b/documentation/html/components_Curators_CuratorRecordsAwaitingApproval.vue.html @@ -833,7 +833,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html index d71de0d599..6be409a62d 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_CuratorSummaryStatistics.vue.html @@ -199,7 +199,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html index 4719c2c9ba..935f0c3f20 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordEditsByMonth.vue.html @@ -202,7 +202,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html index d833eea598..15f3a147ce 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsCreatedByMonth.vue.html @@ -204,7 +204,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsNeedingReview.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsNeedingReview.vue.html index a4da197f95..03ced4b9c8 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsNeedingReview.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsNeedingReview.vue.html @@ -199,7 +199,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html index 58e63bcd86..be409a71ae 100644 --- a/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html +++ b/documentation/html/components_Curators_DownLoadRecordsComponents_RecordsWithoutDois.vue.html @@ -205,7 +205,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_HiddenRecords.vue.html b/documentation/html/components_Curators_HiddenRecords.vue.html index e54566d90f..825d42136d 100644 --- a/documentation/html/components_Curators_HiddenRecords.vue.html +++ b/documentation/html/components_Curators_HiddenRecords.vue.html @@ -299,7 +299,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_IncompleteRecords.vue.html b/documentation/html/components_Curators_IncompleteRecords.vue.html index 99e6f3d731..fbc9d8f8d9 100644 --- a/documentation/html/components_Curators_IncompleteRecords.vue.html +++ b/documentation/html/components_Curators_IncompleteRecords.vue.html @@ -385,7 +385,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_MaintenanceRequests.vue.html b/documentation/html/components_Curators_MaintenanceRequests.vue.html index b115ccd51b..cc802db9a7 100644 --- a/documentation/html/components_Curators_MaintenanceRequests.vue.html +++ b/documentation/html/components_Curators_MaintenanceRequests.vue.html @@ -672,7 +672,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_RecentCuratorCreation.vue.html b/documentation/html/components_Curators_RecentCuratorCreation.vue.html index c021c200de..7592d43952 100644 --- a/documentation/html/components_Curators_RecentCuratorCreation.vue.html +++ b/documentation/html/components_Curators_RecentCuratorCreation.vue.html @@ -294,7 +294,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_SystemMessages.vue.html b/documentation/html/components_Curators_SystemMessages.vue.html index 5323898f3c..87f30e59a2 100644 --- a/documentation/html/components_Curators_SystemMessages.vue.html +++ b/documentation/html/components_Curators_SystemMessages.vue.html @@ -474,7 +474,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Curators_UserRecordsAwaitingApproval.vue.html b/documentation/html/components_Curators_UserRecordsAwaitingApproval.vue.html index bcee68fb7a..e128d59c00 100644 --- a/documentation/html/components_Curators_UserRecordsAwaitingApproval.vue.html +++ b/documentation/html/components_Curators_UserRecordsAwaitingApproval.vue.html @@ -839,7 +839,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Record_Collections.vue.html b/documentation/html/components_Records_Record_Collections.vue.html index 70a096747a..355305c0a0 100644 --- a/documentation/html/components_Records_Record_Collections.vue.html +++ b/documentation/html/components_Records_Record_Collections.vue.html @@ -462,7 +462,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Record_GeneralInfo_SavedSearches.vue.html b/documentation/html/components_Records_Record_GeneralInfo_SavedSearches.vue.html index b7454c7a96..79c1a46ee6 100644 --- a/documentation/html/components_Records_Record_GeneralInfo_SavedSearches.vue.html +++ b/documentation/html/components_Records_Record_GeneralInfo_SavedSearches.vue.html @@ -319,7 +319,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Record_RelatedContent.vue.html b/documentation/html/components_Records_Record_RelatedContent.vue.html index bed4b7537e..60f228344b 100644 --- a/documentation/html/components_Records_Record_RelatedContent.vue.html +++ b/documentation/html/components_Records_Record_RelatedContent.vue.html @@ -454,7 +454,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Header_FilterChips.vue.html b/documentation/html/components_Records_Search_Header_FilterChips.vue.html index 0fcb29e290..76bed49902 100644 --- a/documentation/html/components_Records_Search_Header_FilterChips.vue.html +++ b/documentation/html/components_Records_Search_Header_FilterChips.vue.html @@ -251,7 +251,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Header_Pagination.vue.html b/documentation/html/components_Records_Search_Header_Pagination.vue.html index b7a028f0bb..66572d54c7 100644 --- a/documentation/html/components_Records_Search_Header_Pagination.vue.html +++ b/documentation/html/components_Records_Search_Header_Pagination.vue.html @@ -262,7 +262,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Header_Sorting.vue.html b/documentation/html/components_Records_Search_Header_Sorting.vue.html index 2870855c1a..76321fa7f6 100644 --- a/documentation/html/components_Records_Search_Header_Sorting.vue.html +++ b/documentation/html/components_Records_Search_Header_Sorting.vue.html @@ -219,7 +219,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html index 27041bc58e..034bd24ec2 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_AdvancedSearchDialogBox.vue.html @@ -487,7 +487,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Countries.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Countries.vue.html index b56512b901..5caad10fe2 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Countries.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Countries.vue.html @@ -225,7 +225,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Domains.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Domains.vue.html index 9d1b4236e9..57c9129579 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Domains.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Domains.vue.html @@ -218,7 +218,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Licences.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Licences.vue.html index 0e5c532e82..27f67ba891 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Licences.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Licences.vue.html @@ -218,7 +218,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html index 41d6a67af5..431b8ebd41 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_ObjectTypes.vue.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Organisations.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Organisations.vue.html index 6837f12d71..fe647c3c86 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Organisations.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Organisations.vue.html @@ -229,7 +229,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Subject.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Subject.vue.html index e5e03bc9f2..13494c9f07 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Subject.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Subject.vue.html @@ -218,7 +218,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html index da693e66b1..a04916de20 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_Taxonomies.vue.html @@ -224,7 +224,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_UserDefinedTag.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_UserDefinedTag.vue.html index c4877b0d6b..f7cf8af867 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_UserDefinedTag.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GeneralComponents_UserDefinedTag.vue.html @@ -224,7 +224,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html index a771eb7582..132627d34e 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_DatabaseRule.vue.html @@ -315,7 +315,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html index 7c760deeef..4e214dde44 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_FairassistRule.vue.html @@ -252,7 +252,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html index d9f72c3c26..8f71a07faf 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GeneralRule.vue.html @@ -272,7 +272,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html index c43ebe7f2a..155bbf9311 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_GroupCtrlSlot.vue.html @@ -199,7 +199,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html index 408b2e85ad..0bd0cac247 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_PolicyRule.vue.html @@ -328,7 +328,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html index 351b4ca17c..e6f0b286ff 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderComponents_GroupCtrlSlot_StandardRule.vue.html @@ -230,7 +230,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderView.vue.html b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderView.vue.html index a129121460..763461866b 100644 --- a/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderView.vue.html +++ b/documentation/html/components_Records_Search_Input_AdvancedSearch_QueryBuilderView.vue.html @@ -676,7 +676,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_FilterAutocomplete.vue.html b/documentation/html/components_Records_Search_Input_FilterAutocomplete.vue.html index c0bc7d216b..40ba5b84ab 100644 --- a/documentation/html/components_Records_Search_Input_FilterAutocomplete.vue.html +++ b/documentation/html/components_Records_Search_Input_FilterAutocomplete.vue.html @@ -376,7 +376,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_FilterButton.vue.html b/documentation/html/components_Records_Search_Input_FilterButton.vue.html index 126744efbb..26440398a5 100644 --- a/documentation/html/components_Records_Search_Input_FilterButton.vue.html +++ b/documentation/html/components_Records_Search_Input_FilterButton.vue.html @@ -287,7 +287,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_Input_SearchInput.vue.html b/documentation/html/components_Records_Search_Input_SearchInput.vue.html index 7597f6b6ac..a55bf493eb 100644 --- a/documentation/html/components_Records_Search_Input_SearchInput.vue.html +++ b/documentation/html/components_Records_Search_Input_SearchInput.vue.html @@ -284,7 +284,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_SaveSearchButton.vue.html b/documentation/html/components_Records_Search_SaveSearch_SaveSearchButton.vue.html index aa95e81058..01e9d276fc 100644 --- a/documentation/html/components_Records_Search_SaveSearch_SaveSearchButton.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_SaveSearchButton.vue.html @@ -182,7 +182,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_SaveSearchStepper.vue.html b/documentation/html/components_Records_Search_SaveSearch_SaveSearchStepper.vue.html index 3b4065096d..862352eb21 100644 --- a/documentation/html/components_Records_Search_SaveSearch_SaveSearchStepper.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_SaveSearchStepper.vue.html @@ -464,7 +464,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_OrganisationStepper.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_OrganisationStepper.vue.html index 9b1f5af07b..be81b14644 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_OrganisationStepper.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_OrganisationStepper.vue.html @@ -259,7 +259,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html index fba2287185..1624444bac 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_PolicyStepper.vue.html @@ -259,7 +259,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_ResultCard.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_ResultCard.vue.html index ede9f090c6..8b52dca4bc 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_ResultCard.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_ResultCard.vue.html @@ -259,7 +259,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_StepperDialogHeader.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_StepperDialogHeader.vue.html index 66d6e0cbdc..0589679282 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_StepperDialogHeader.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_StepperDialogHeader.vue.html @@ -182,7 +182,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_UserStepper.vue.html b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_UserStepper.vue.html index 374d33ef7a..8f8ef85f8f 100644 --- a/documentation/html/components_Records_Search_SaveSearch_StepperComponents_UserStepper.vue.html +++ b/documentation/html/components_Records_Search_SaveSearch_StepperComponents_UserStepper.vue.html @@ -211,7 +211,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/components_Users_Profiles_Private_ViewSavedSearchesTable.vue.html b/documentation/html/components_Users_Profiles_Private_ViewSavedSearchesTable.vue.html index 13bb3c11e0..44f80458e9 100644 --- a/documentation/html/components_Users_Profiles_Private_ViewSavedSearchesTable.vue.html +++ b/documentation/html/components_Users_Profiles_Private_ViewSavedSearchesTable.vue.html @@ -509,7 +509,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/global.html b/documentation/html/global.html index 671e0ff357..4f6c4faa00 100644 --- a/documentation/html/global.html +++ b/documentation/html/global.html @@ -2964,7 +2964,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/index.html b/documentation/html/index.html index 0d436b98e4..4252cde104 100644 --- a/documentation/html/index.html +++ b/documentation/html/index.html @@ -216,7 +216,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/lib_Client_ExternalClients.js.html b/documentation/html/lib_Client_ExternalClients.js.html index e6ef5b10e0..a8fd4a9792 100644 --- a/documentation/html/lib_Client_ExternalClients.js.html +++ b/documentation/html/lib_Client_ExternalClients.js.html @@ -256,7 +256,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/lib_Client_RESTClient.js.html b/documentation/html/lib_Client_RESTClient.js.html index 944a8175b0..d520e4818b 100644 --- a/documentation/html/lib_Client_RESTClient.js.html +++ b/documentation/html/lib_Client_RESTClient.js.html @@ -1284,7 +1284,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/lib_GraphClient_GraphClient.js.html b/documentation/html/lib_GraphClient_GraphClient.js.html index c58523cc02..203765670b 100644 --- a/documentation/html/lib_GraphClient_GraphClient.js.html +++ b/documentation/html/lib_GraphClient_GraphClient.js.html @@ -285,7 +285,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/lib_GraphClient_GraphClientSEO.js.html b/documentation/html/lib_GraphClient_GraphClientSEO.js.html index 48b18b1a09..138198ffb3 100644 --- a/documentation/html/lib_GraphClient_GraphClientSEO.js.html +++ b/documentation/html/lib_GraphClient_GraphClientSEO.js.html @@ -286,7 +286,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/module-Home.html b/documentation/html/module-Home.html index 07ca6f0184..a50b095197 100644 --- a/documentation/html/module-Home.html +++ b/documentation/html/module-Home.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/module-Login.html b/documentation/html/module-Login.html index 0972d83265..88c320c669 100644 --- a/documentation/html/module-Login.html +++ b/documentation/html/module-Login.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/module-NewRecord.html b/documentation/html/module-NewRecord.html index 85282d01a3..e7e3892713 100644 --- a/documentation/html/module-NewRecord.html +++ b/documentation/html/module-NewRecord.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/module-Pagination.html b/documentation/html/module-Pagination.html index c27244b736..ef08864178 100644 --- a/documentation/html/module-Pagination.html +++ b/documentation/html/module-Pagination.html @@ -527,7 +527,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/module-Signup.html b/documentation/html/module-Signup.html index 6e9b9aeaa6..faf41c1bfb 100644 --- a/documentation/html/module-Signup.html +++ b/documentation/html/module-Signup.html @@ -220,7 +220,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/module-User.html b/documentation/html/module-User.html index f28f497f09..a3df91ad22 100644 --- a/documentation/html/module-User.html +++ b/documentation/html/module-User.html @@ -228,7 +228,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/modules.list.html b/documentation/html/modules.list.html index 998608f9f9..a45d2d1e5f 100644 --- a/documentation/html/modules.list.html +++ b/documentation/html/modules.list.html @@ -2984,7 +2984,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/namespaces.list.html b/documentation/html/namespaces.list.html index 5db84f9b86..38922a7a27 100644 --- a/documentation/html/namespaces.list.html +++ b/documentation/html/namespaces.list.html @@ -2984,7 +2984,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/router_hackSearch.js.html b/documentation/html/router_hackSearch.js.html index 4139a0581e..6cc422e95b 100644 --- a/documentation/html/router_hackSearch.js.html +++ b/documentation/html/router_hackSearch.js.html @@ -209,7 +209,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/store_introspector.js.html b/documentation/html/store_introspector.js.html index 84499a67f3..80e05d05bf 100644 --- a/documentation/html/store_introspector.js.html +++ b/documentation/html/store_introspector.js.html @@ -325,7 +325,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/store_recordData.js.html b/documentation/html/store_recordData.js.html index e4131d8ef8..470eae8589 100644 --- a/documentation/html/store_recordData.js.html +++ b/documentation/html/store_recordData.js.html @@ -872,7 +872,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/store_recordSearch.js.html b/documentation/html/store_recordSearch.js.html index c2e3e1a460..c0fdd31eac 100644 --- a/documentation/html/store_recordSearch.js.html +++ b/documentation/html/store_recordSearch.js.html @@ -355,7 +355,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/store_searchFilters.js.html b/documentation/html/store_searchFilters.js.html index 20b67e3721..dcf776c884 100644 --- a/documentation/html/store_searchFilters.js.html +++ b/documentation/html/store_searchFilters.js.html @@ -301,7 +301,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/utils_advancedSearchUtils.js.html b/documentation/html/utils_advancedSearchUtils.js.html index f60aa0572c..e46d93e1a5 100644 --- a/documentation/html/utils_advancedSearchUtils.js.html +++ b/documentation/html/utils_advancedSearchUtils.js.html @@ -196,7 +196,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/utils_query-builder-vue-3_dist_query-builder-vue-3.js.html b/documentation/html/utils_query-builder-vue-3_dist_query-builder-vue-3.js.html index 8e02342baa..4031a3cbbe 100644 --- a/documentation/html/utils_query-builder-vue-3_dist_query-builder-vue-3.js.html +++ b/documentation/html/utils_query-builder-vue-3_dist_query-builder-vue-3.js.html @@ -3653,7 +3653,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/utils_recordTabUtils.js.html b/documentation/html/utils_recordTabUtils.js.html index 711aeefb38..03652e6a2d 100644 --- a/documentation/html/utils_recordTabUtils.js.html +++ b/documentation/html/utils_recordTabUtils.js.html @@ -270,7 +270,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/utils_rules.js.html b/documentation/html/utils_rules.js.html index ab88f86fd2..413be9760c 100644 --- a/documentation/html/utils_rules.js.html +++ b/documentation/html/utils_rules.js.html @@ -293,7 +293,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_AdvancedSearch_AdvancedSearchResultTable.vue.html b/documentation/html/views_AdvancedSearch_AdvancedSearchResultTable.vue.html index 8668af1070..5a41542d0e 100644 --- a/documentation/html/views_AdvancedSearch_AdvancedSearchResultTable.vue.html +++ b/documentation/html/views_AdvancedSearch_AdvancedSearchResultTable.vue.html @@ -451,7 +451,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_AdvancedSearch_AdvancedSearchSelection.vue.html b/documentation/html/views_AdvancedSearch_AdvancedSearchSelection.vue.html index 24f8989915..94816e2ca2 100644 --- a/documentation/html/views_AdvancedSearch_AdvancedSearchSelection.vue.html +++ b/documentation/html/views_AdvancedSearch_AdvancedSearchSelection.vue.html @@ -373,7 +373,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Browsers_OntologyBrowser.vue.html b/documentation/html/views_Browsers_OntologyBrowser.vue.html index ae2ed16fdf..bfe467aaa3 100644 --- a/documentation/html/views_Browsers_OntologyBrowser.vue.html +++ b/documentation/html/views_Browsers_OntologyBrowser.vue.html @@ -697,7 +697,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_CreateRecord_NewRecord.vue.html b/documentation/html/views_CreateRecord_NewRecord.vue.html index cdaa1aeca0..250da99ed4 100644 --- a/documentation/html/views_CreateRecord_NewRecord.vue.html +++ b/documentation/html/views_CreateRecord_NewRecord.vue.html @@ -401,7 +401,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Home_Home.vue.html b/documentation/html/views_Home_Home.vue.html index aaa22e0a0b..d9250c4c41 100644 --- a/documentation/html/views_Home_Home.vue.html +++ b/documentation/html/views_Home_Home.vue.html @@ -188,7 +188,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Organisations_Organisation.vue.html b/documentation/html/views_Organisations_Organisation.vue.html index 0a4e78e33e..896a7823ee 100644 --- a/documentation/html/views_Organisations_Organisation.vue.html +++ b/documentation/html/views_Organisations_Organisation.vue.html @@ -991,7 +991,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Records_NetworkGraph.vue.html b/documentation/html/views_Records_NetworkGraph.vue.html index 80b37ce02d..15e997f968 100644 --- a/documentation/html/views_Records_NetworkGraph.vue.html +++ b/documentation/html/views_Records_NetworkGraph.vue.html @@ -734,7 +734,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Records_Record.vue.html b/documentation/html/views_Records_Record.vue.html index 64f769f910..1f384cbe15 100644 --- a/documentation/html/views_Records_Record.vue.html +++ b/documentation/html/views_Records_Record.vue.html @@ -1494,7 +1494,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Records_Records.vue.html b/documentation/html/views_Records_Records.vue.html index 98f2c85820..319190aa29 100644 --- a/documentation/html/views_Records_Records.vue.html +++ b/documentation/html/views_Records_Records.vue.html @@ -450,7 +450,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Static_Community_Community.vue.html b/documentation/html/views_Static_Community_Community.vue.html index e0d0043e78..da492c27e2 100644 --- a/documentation/html/views_Static_Community_Community.vue.html +++ b/documentation/html/views_Static_Community_Community.vue.html @@ -999,7 +999,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Static_Timeline_Timeline.vue.html b/documentation/html/views_Static_Timeline_Timeline.vue.html index 2fc1accfb0..44595584db 100644 --- a/documentation/html/views_Static_Timeline_Timeline.vue.html +++ b/documentation/html/views_Static_Timeline_Timeline.vue.html @@ -153,7 +153,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Users_Login_Login.vue.html b/documentation/html/views_Users_Login_Login.vue.html index aa12fd8636..822faf9196 100644 --- a/documentation/html/views_Users_Login_Login.vue.html +++ b/documentation/html/views_Users_Login_Login.vue.html @@ -462,7 +462,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template. diff --git a/documentation/html/views_Users_Signup.vue.html b/documentation/html/views_Users_Signup.vue.html index 30f0dc70dc..5218f52afb 100644 --- a/documentation/html/views_Users_Signup.vue.html +++ b/documentation/html/views_Users_Signup.vue.html @@ -150,7 +150,7 @@ Documentation generated by JSDoc 4.0.5 - on Thu Jul 23rd 2026 + on Tue Jul 28th 2026 using the DocStrap template.