diff --git a/package-lock.json b/package-lock.json index df1766219a1737e149cfe4d45658530ef415faf1..b3ce605a7ff4fc0bcb2e0f50a0287e59244129ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,28 +8,28 @@ "name": "nacsos-web", "version": "0.2.0", "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.2.0", - "@fortawesome/free-brands-svg-icons": "^6.2.0", - "@fortawesome/free-regular-svg-icons": "^6.2.0", - "@fortawesome/free-solid-svg-icons": "^6.2.0", - "@fortawesome/vue-fontawesome": "^3.0.1", + "@fortawesome/fontawesome-svg-core": "^6.2.1", + "@fortawesome/free-brands-svg-icons": "^6.2.1", + "@fortawesome/free-regular-svg-icons": "^6.2.1", + "@fortawesome/free-solid-svg-icons": "^6.2.1", + "@fortawesome/vue-fontawesome": "^3.0.2", "@vuelidate/core": "^2.0.0", "@vuelidate/validators": "^2.0.0", - "@vueuse/core": "^9.3.1", - "axios": "^1.1.3", - "bootstrap": "^5.2.2", - "core-js": "^3.26.0", + "@vueuse/core": "^9.6.0", + "axios": "^1.2.0", + "bootstrap": "^5.2.3", + "core-js": "^3.26.1", "form-data": "^4.0.0", - "marked": "^4.1.1", - "pinia": "^2.0.23", - "vue": "^3.2.41", + "marked": "^4.2.3", + "pinia": "^2.0.27", + "vue": "^3.2.45", "vue-router": "^4.1.6" }, "devDependencies": { "@rushstack/eslint-patch": "^1.2.0", "@types/marked": "^4.0.7", - "@typescript-eslint/eslint-plugin": "^5.40.1", - "@typescript-eslint/parser": "^5.40.1", + "@typescript-eslint/eslint-plugin": "^5.45.0", + "@typescript-eslint/parser": "^5.45.0", "@vue/cli-plugin-babel": "^5.0.8", "@vue/cli-plugin-eslint": "^5.0.8", "@vue/cli-plugin-router": "^5.0.8", @@ -39,16 +39,16 @@ "@vue/eslint-config-airbnb-with-typescript": "^7.0.0", "camelcase": "^6.3.0", "commander": "^9.4.1", - "eslint": "^8.26.0", + "eslint": "^8.28.0", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-vue": "^9.6.0", - "eslint-plugin-vuejs-accessibility": "^1.2.0", - "fs-extra": "^10.1.0", + "eslint-plugin-vue": "^9.8.0", + "eslint-plugin-vuejs-accessibility": "^2.0.0", + "fs-extra": "^11.0.0", "handlebars": "^4.7.7", "json-schema-ref-parser": "^9.0.9", - "sass": "^1.55.0", - "sass-loader": "^13.1.0", - "typescript": "^4.8.4" + "sass": "^1.56.1", + "sass-loader": "^13.2.0", + "typescript": "^4.9.3" } }, "node_modules/@achrinza/node-ipc": { @@ -1780,66 +1780,66 @@ } }, "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.0.tgz", - "integrity": "sha512-rBevIsj2nclStJ7AxTdfsa3ovHb1H+qApwrxcTVo+NNdeJiB9V75hsKfrkG5AwNcRUNxrPPiScGYCNmLMoh8pg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", + "integrity": "sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==", "hasInstallScript": true, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.0.tgz", - "integrity": "sha512-Cf2mAAeMWFMzpLC7Y9H1I4o3wEU+XovVJhTiNG8ZNgSQj53yl7OCJaS80K4YjrABWZzbAHVaoHE1dVJ27AAYXw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz", + "integrity": "sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.0" + "@fortawesome/fontawesome-common-types": "6.2.1" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-brands-svg-icons": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.0.tgz", - "integrity": "sha512-fm1y4NyZ2qKYNmYhdMz9VAWRw1Et7PMHNunSw3W0SVAwKwv6o0qiJworLH3Y9SnmhHzAymXJwCX1op22FFvGiA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.1.tgz", + "integrity": "sha512-L8l4MfdHPmZlJ72PvzdfwOwbwcCAL0vx48tJRnI6u1PJXh+j2f3yDoKyQgO3qjEsgD5Fr2tQV/cPP8F/k6aUig==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.0" + "@fortawesome/fontawesome-common-types": "6.2.1" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.0.tgz", - "integrity": "sha512-M1dG+PAmkYMTL9BSUHFXY5oaHwBYfHCPhbJ8qj8JELsc9XCrUJ6eEHWip4q0tE+h9C0DVyFkwIM9t7QYyCpprQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.1.tgz", + "integrity": "sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.0" + "@fortawesome/fontawesome-common-types": "6.2.1" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.0.tgz", - "integrity": "sha512-UjCILHIQ4I8cN46EiQn0CZL/h8AwCGgR//1c4R96Q5viSRwuKVo0NdQEc4bm+69ZwC0dUvjbDqAHF1RR5FA3XA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.1.tgz", + "integrity": "sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.0" + "@fortawesome/fontawesome-common-types": "6.2.1" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/vue-fontawesome": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.1.tgz", - "integrity": "sha512-CdXZJoCS+aEPec26ZP7hWWU3SaJlQPZSCGdgpQ2qGl2HUmtUUNrI3zC4XWdn1JUmh3t5OuDeRG1qB4eGRNSD4A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.2.tgz", + "integrity": "sha512-xHVtVY8ASUeEvgcA/7vULUesENhD+pi/EirRHdMBqooHlXBqK+yrV6d8tUye1m5UKQKVgYAHMhUBfOnoiwvc8Q==", "peerDependencies": { "@fortawesome/fontawesome-svg-core": "~1 || ~6", "vue": ">= 3.0.0 < 4" @@ -2398,9 +2398,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.3.12", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", - "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, "node_modules/@types/serve-index": { @@ -2452,16 +2452,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.1.tgz", - "integrity": "sha512-FsWboKkWdytGiXT5O1/R9j37YgcjO8MKHSUmWnIEjVaz0krHkplPnYi7mwdb+5+cs0toFNQb0HIrN7zONdIEWg==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz", + "integrity": "sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/type-utils": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/type-utils": "5.45.0", + "@typescript-eslint/utils": "5.45.0", "debug": "^4.3.4", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" @@ -2499,14 +2500,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.1.tgz", - "integrity": "sha512-IK6x55va5w4YvXd4b3VrXQPldV9vQTxi5ov+g4pMANsXPTXOcfjx08CRR1Dfrcc51syPtXHF5bgLlMHYFrvQtg==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz", + "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/typescript-estree": "5.45.0", "debug": "^4.3.4" }, "engines": { @@ -2526,13 +2527,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz", - "integrity": "sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz", + "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1" + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/visitor-keys": "5.45.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2543,13 +2544,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.1.tgz", - "integrity": "sha512-DLAs+AHQOe6n5LRraXiv27IYPhleF0ldEmx6yBqBgBLaNRKTkffhV1RPsjoJBhVup2zHxfaRtan8/YRBgYhU9Q==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz", + "integrity": "sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "@typescript-eslint/typescript-estree": "5.45.0", + "@typescript-eslint/utils": "5.45.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2570,9 +2571,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.1.tgz", - "integrity": "sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz", + "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2583,13 +2584,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz", - "integrity": "sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz", + "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1", + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/visitor-keys": "5.45.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2625,16 +2626,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.1.tgz", - "integrity": "sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.45.0.tgz", + "integrity": "sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/typescript-estree": "5.45.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -2666,12 +2667,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz", - "integrity": "sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz", + "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.40.1", + "@typescript-eslint/types": "5.45.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -3228,36 +3229,36 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz", - "integrity": "sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz", + "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.41", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz", - "integrity": "sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", + "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", "dependencies": { - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz", - "integrity": "sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", + "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-ssr": "3.2.41", - "@vue/reactivity-transform": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-ssr": "3.2.45", + "@vue/reactivity-transform": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -3265,12 +3266,12 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz", - "integrity": "sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", + "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", "dependencies": { - "@vue/compiler-dom": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/component-compiler-utils": { @@ -3380,61 +3381,81 @@ "typescript": "*" } }, + "node_modules/@vue/eslint-config-airbnb/node_modules/emoji-regex": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.2.1.tgz", + "integrity": "sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==", + "dev": true + }, + "node_modules/@vue/eslint-config-airbnb/node_modules/eslint-plugin-vuejs-accessibility": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vuejs-accessibility/-/eslint-plugin-vuejs-accessibility-1.2.0.tgz", + "integrity": "sha512-wF7kT22lS2VOmIpDeI65bnFFKFgESEEpI+CWKr43mdfDRywA4sCk7cKhtZsvfbPOtKO0GDlnpFxZbOIGsFn7IQ==", + "dev": true, + "dependencies": { + "aria-query": "^5.0.0", + "emoji-regex": "^10.0.0", + "vue-eslint-parser": "^9.0.1" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/@vue/reactivity": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.41.tgz", - "integrity": "sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz", + "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==", "dependencies": { - "@vue/shared": "3.2.41" + "@vue/shared": "3.2.45" } }, "node_modules/@vue/reactivity-transform": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz", - "integrity": "sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", + "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "node_modules/@vue/runtime-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.41.tgz", - "integrity": "sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz", + "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==", "dependencies": { - "@vue/reactivity": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/reactivity": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/runtime-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.41.tgz", - "integrity": "sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz", + "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==", "dependencies": { - "@vue/runtime-core": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/runtime-core": "3.2.45", + "@vue/shared": "3.2.45", "csstype": "^2.6.8" } }, "node_modules/@vue/server-renderer": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.41.tgz", - "integrity": "sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz", + "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==", "dependencies": { - "@vue/compiler-ssr": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-ssr": "3.2.45", + "@vue/shared": "3.2.45" }, "peerDependencies": { - "vue": "3.2.41" + "vue": "3.2.45" } }, "node_modules/@vue/shared": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz", - "integrity": "sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==" + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz", + "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" }, "node_modules/@vue/vue-loader-v15": { "name": "vue-loader", @@ -3559,13 +3580,13 @@ } }, "node_modules/@vueuse/core": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.3.1.tgz", - "integrity": "sha512-xriyD+v3D2ObH/UtnkEl+1sbcLBVHNaZaLi/rqoNEe/B92hggDEFQIGXoQUjdRzYOjASHSezf9uCDtmd7LeWyA==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz", + "integrity": "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==", "dependencies": { "@types/web-bluetooth": "^0.0.16", - "@vueuse/metadata": "9.3.1", - "@vueuse/shared": "9.3.1", + "@vueuse/metadata": "9.6.0", + "@vueuse/shared": "9.6.0", "vue-demi": "*" }, "funding": { @@ -3598,17 +3619,17 @@ } }, "node_modules/@vueuse/metadata": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.3.1.tgz", - "integrity": "sha512-G1BPhtx3OHaL/y4OZBofh6Xt02G1VA9PuOO8nac9sTKMkMqfyez5VfkF3D9GUjSRNO7cVWyH4rceeGXfr2wdMg==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz", + "integrity": "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.3.1.tgz", - "integrity": "sha512-YFu3qcnVeu0S2L4XdQJtBpDcjz6xwqHZtTv/XRhu66/yge1XVhxskUcc7VZbX52xF9A34V6KCfwncP9YDqYFiw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz", + "integrity": "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==", "dependencies": { "vue-demi": "*" }, @@ -4127,9 +4148,9 @@ } }, "node_modules/axios": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", - "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.0.tgz", + "integrity": "sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -4340,9 +4361,9 @@ "dev": true }, "node_modules/bootstrap": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.2.tgz", - "integrity": "sha512-dEtzMTV71n6Fhmbg4fYJzQsw1N29hJKO1js5ackCgIpDcGid2ETMGC6zwSYw09v05Y+oRdQ9loC54zB1La3hHQ==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz", + "integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==", "funding": [ { "type": "github", @@ -4961,9 +4982,9 @@ } }, "node_modules/core-js": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", - "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", + "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5844,9 +5865,9 @@ } }, "node_modules/eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", + "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", "dev": true, "dependencies": { "@eslint/eslintrc": "^1.3.3", @@ -6310,9 +6331,9 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.6.0.tgz", - "integrity": "sha512-zzySkJgVbFCylnG2+9MDF7N+2Rjze2y0bF8GyUNpFOnT8mCMfqqtLDJkHBuYu9N/psW1A6DVbQhPkP92E+qakA==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.8.0.tgz", + "integrity": "sha512-E/AXwcTzunyzM83C2QqDHxepMzvI2y6x+mmeYHbVDQlKFqmKYvRrhaVixEeeG27uI44p9oKDFiyCRw4XxgtfHA==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -6346,12 +6367,12 @@ } }, "node_modules/eslint-plugin-vuejs-accessibility": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vuejs-accessibility/-/eslint-plugin-vuejs-accessibility-1.2.0.tgz", - "integrity": "sha512-wF7kT22lS2VOmIpDeI65bnFFKFgESEEpI+CWKr43mdfDRywA4sCk7cKhtZsvfbPOtKO0GDlnpFxZbOIGsFn7IQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vuejs-accessibility/-/eslint-plugin-vuejs-accessibility-2.0.0.tgz", + "integrity": "sha512-mjbXnncDT9+5K+/QXXhOVWhEU6OOJck/JNlC6tewo3R+Kzsbaecyq3ylN1NqmyKo78vsgun34JLd+vGdxSPFWQ==", "dev": true, "dependencies": { - "aria-query": "^5.0.0", + "aria-query": ">=5.0.0", "emoji-regex": "^10.0.0", "vue-eslint-parser": "^9.0.1" }, @@ -7277,9 +7298,9 @@ } }, "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.0.0.tgz", + "integrity": "sha512-4YxRvMi4P5C3WQTvdRfrv5UVqbISpqjORFQAW5QPiKAauaxNCwrEdIi6pG3tDFhKKpMen+enEhHIzB/tvIO+/w==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -7287,7 +7308,7 @@ "universalify": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.14" } }, "node_modules/fs-monkey": { @@ -8817,9 +8838,9 @@ } }, "node_modules/marked": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", - "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz", + "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==", "bin": { "marked": "bin/marked.js" }, @@ -9116,6 +9137,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz", @@ -9718,11 +9745,11 @@ } }, "node_modules/pinia": { - "version": "2.0.23", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.23.tgz", - "integrity": "sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.27.tgz", + "integrity": "sha512-nOnXP0OFeL8R4WjAHsterU+11vptda643gH02xKNtSCDPiRzVfRYodOLihLDoa0gL1KKuQKV+KOzEgdt3YvqEw==", "dependencies": { - "@vue/devtools-api": "^6.4.4", + "@vue/devtools-api": "^6.4.5", "vue-demi": "*" }, "funding": { @@ -10829,9 +10856,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.55.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", - "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.1.tgz", + "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -10846,9 +10873,9 @@ } }, "node_modules/sass-loader": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.1.0.tgz", - "integrity": "sha512-tZS1RJQ2n2+QNyf3CCAo1H562WjL/5AM6Gi8YcPVVoNxQX8d19mx8E+8fRrMWsyc93ZL6Q8vZDSM0FHVTJaVnQ==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz", + "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==", "dev": true, "dependencies": { "klona": "^2.0.4", @@ -10863,7 +10890,7 @@ }, "peerDependencies": { "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", "sass": "^1.3.0", "sass-embedded": "*", "webpack": "^5.0.0" @@ -11888,9 +11915,9 @@ } }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", "devOptional": true, "bin": { "tsc": "bin/tsc", @@ -12068,15 +12095,15 @@ } }, "node_modules/vue": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.41.tgz", - "integrity": "sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz", + "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==", "dependencies": { - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-sfc": "3.2.41", - "@vue/runtime-dom": "3.2.41", - "@vue/server-renderer": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/runtime-dom": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/vue-eslint-parser": { @@ -14215,46 +14242,46 @@ } }, "@fortawesome/fontawesome-common-types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.0.tgz", - "integrity": "sha512-rBevIsj2nclStJ7AxTdfsa3ovHb1H+qApwrxcTVo+NNdeJiB9V75hsKfrkG5AwNcRUNxrPPiScGYCNmLMoh8pg==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", + "integrity": "sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==" }, "@fortawesome/fontawesome-svg-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.0.tgz", - "integrity": "sha512-Cf2mAAeMWFMzpLC7Y9H1I4o3wEU+XovVJhTiNG8ZNgSQj53yl7OCJaS80K4YjrABWZzbAHVaoHE1dVJ27AAYXw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz", + "integrity": "sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.0" + "@fortawesome/fontawesome-common-types": "6.2.1" } }, "@fortawesome/free-brands-svg-icons": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.0.tgz", - "integrity": "sha512-fm1y4NyZ2qKYNmYhdMz9VAWRw1Et7PMHNunSw3W0SVAwKwv6o0qiJworLH3Y9SnmhHzAymXJwCX1op22FFvGiA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.1.tgz", + "integrity": "sha512-L8l4MfdHPmZlJ72PvzdfwOwbwcCAL0vx48tJRnI6u1PJXh+j2f3yDoKyQgO3qjEsgD5Fr2tQV/cPP8F/k6aUig==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.0" + "@fortawesome/fontawesome-common-types": "6.2.1" } }, "@fortawesome/free-regular-svg-icons": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.0.tgz", - "integrity": "sha512-M1dG+PAmkYMTL9BSUHFXY5oaHwBYfHCPhbJ8qj8JELsc9XCrUJ6eEHWip4q0tE+h9C0DVyFkwIM9t7QYyCpprQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.1.tgz", + "integrity": "sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.0" + "@fortawesome/fontawesome-common-types": "6.2.1" } }, "@fortawesome/free-solid-svg-icons": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.0.tgz", - "integrity": "sha512-UjCILHIQ4I8cN46EiQn0CZL/h8AwCGgR//1c4R96Q5viSRwuKVo0NdQEc4bm+69ZwC0dUvjbDqAHF1RR5FA3XA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.1.tgz", + "integrity": "sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.0" + "@fortawesome/fontawesome-common-types": "6.2.1" } }, "@fortawesome/vue-fontawesome": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.1.tgz", - "integrity": "sha512-CdXZJoCS+aEPec26ZP7hWWU3SaJlQPZSCGdgpQ2qGl2HUmtUUNrI3zC4XWdn1JUmh3t5OuDeRG1qB4eGRNSD4A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.2.tgz", + "integrity": "sha512-xHVtVY8ASUeEvgcA/7vULUesENhD+pi/EirRHdMBqooHlXBqK+yrV6d8tUye1m5UKQKVgYAHMhUBfOnoiwvc8Q==", "requires": {} }, "@hapi/hoek": { @@ -14731,9 +14758,9 @@ "dev": true }, "@types/semver": { - "version": "7.3.12", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", - "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, "@types/serve-index": { @@ -14785,16 +14812,17 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.1.tgz", - "integrity": "sha512-FsWboKkWdytGiXT5O1/R9j37YgcjO8MKHSUmWnIEjVaz0krHkplPnYi7mwdb+5+cs0toFNQb0HIrN7zONdIEWg==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz", + "integrity": "sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/type-utils": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/type-utils": "5.45.0", + "@typescript-eslint/utils": "5.45.0", "debug": "^4.3.4", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" @@ -14812,53 +14840,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.1.tgz", - "integrity": "sha512-IK6x55va5w4YvXd4b3VrXQPldV9vQTxi5ov+g4pMANsXPTXOcfjx08CRR1Dfrcc51syPtXHF5bgLlMHYFrvQtg==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz", + "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/typescript-estree": "5.45.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz", - "integrity": "sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz", + "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1" + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/visitor-keys": "5.45.0" } }, "@typescript-eslint/type-utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.1.tgz", - "integrity": "sha512-DLAs+AHQOe6n5LRraXiv27IYPhleF0ldEmx6yBqBgBLaNRKTkffhV1RPsjoJBhVup2zHxfaRtan8/YRBgYhU9Q==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz", + "integrity": "sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "@typescript-eslint/typescript-estree": "5.45.0", + "@typescript-eslint/utils": "5.45.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.1.tgz", - "integrity": "sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz", + "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz", - "integrity": "sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz", + "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1", + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/visitor-keys": "5.45.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -14878,16 +14906,16 @@ } }, "@typescript-eslint/utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.1.tgz", - "integrity": "sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.45.0.tgz", + "integrity": "sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/typescript-estree": "5.45.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -14905,12 +14933,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz", - "integrity": "sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==", + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz", + "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.40.1", + "@typescript-eslint/types": "5.45.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -15324,36 +15352,36 @@ } }, "@vue/compiler-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz", - "integrity": "sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz", + "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", "requires": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.41", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "@vue/compiler-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz", - "integrity": "sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", + "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", "requires": { - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" } }, "@vue/compiler-sfc": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz", - "integrity": "sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", + "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-ssr": "3.2.41", - "@vue/reactivity-transform": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-ssr": "3.2.45", + "@vue/reactivity-transform": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -15361,12 +15389,12 @@ } }, "@vue/compiler-ssr": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz", - "integrity": "sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", + "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", "requires": { - "@vue/compiler-dom": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45" } }, "@vue/component-compiler-utils": { @@ -15445,6 +15473,25 @@ "eslint-plugin-react": "^7.30.1", "eslint-plugin-vuejs-accessibility": "^1.2.0", "vue-eslint-parser": "^9.0.3" + }, + "dependencies": { + "emoji-regex": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.2.1.tgz", + "integrity": "sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==", + "dev": true + }, + "eslint-plugin-vuejs-accessibility": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vuejs-accessibility/-/eslint-plugin-vuejs-accessibility-1.2.0.tgz", + "integrity": "sha512-wF7kT22lS2VOmIpDeI65bnFFKFgESEEpI+CWKr43mdfDRywA4sCk7cKhtZsvfbPOtKO0GDlnpFxZbOIGsFn7IQ==", + "dev": true, + "requires": { + "aria-query": "^5.0.0", + "emoji-regex": "^10.0.0", + "vue-eslint-parser": "^9.0.1" + } + } } }, "@vue/eslint-config-airbnb-with-typescript": { @@ -15465,57 +15512,57 @@ } }, "@vue/reactivity": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.41.tgz", - "integrity": "sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz", + "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==", "requires": { - "@vue/shared": "3.2.41" + "@vue/shared": "3.2.45" } }, "@vue/reactivity-transform": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz", - "integrity": "sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", + "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "@vue/runtime-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.41.tgz", - "integrity": "sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz", + "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==", "requires": { - "@vue/reactivity": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/reactivity": "3.2.45", + "@vue/shared": "3.2.45" } }, "@vue/runtime-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.41.tgz", - "integrity": "sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz", + "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==", "requires": { - "@vue/runtime-core": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/runtime-core": "3.2.45", + "@vue/shared": "3.2.45", "csstype": "^2.6.8" } }, "@vue/server-renderer": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.41.tgz", - "integrity": "sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz", + "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==", "requires": { - "@vue/compiler-ssr": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-ssr": "3.2.45", + "@vue/shared": "3.2.45" } }, "@vue/shared": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz", - "integrity": "sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==" + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz", + "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" }, "@vue/vue-loader-v15": { "version": "npm:vue-loader@15.9.8", @@ -15577,13 +15624,13 @@ } }, "@vueuse/core": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.3.1.tgz", - "integrity": "sha512-xriyD+v3D2ObH/UtnkEl+1sbcLBVHNaZaLi/rqoNEe/B92hggDEFQIGXoQUjdRzYOjASHSezf9uCDtmd7LeWyA==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz", + "integrity": "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==", "requires": { "@types/web-bluetooth": "^0.0.16", - "@vueuse/metadata": "9.3.1", - "@vueuse/shared": "9.3.1", + "@vueuse/metadata": "9.6.0", + "@vueuse/shared": "9.6.0", "vue-demi": "*" }, "dependencies": { @@ -15596,14 +15643,14 @@ } }, "@vueuse/metadata": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.3.1.tgz", - "integrity": "sha512-G1BPhtx3OHaL/y4OZBofh6Xt02G1VA9PuOO8nac9sTKMkMqfyez5VfkF3D9GUjSRNO7cVWyH4rceeGXfr2wdMg==" + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz", + "integrity": "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==" }, "@vueuse/shared": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.3.1.tgz", - "integrity": "sha512-YFu3qcnVeu0S2L4XdQJtBpDcjz6xwqHZtTv/XRhu66/yge1XVhxskUcc7VZbX52xF9A34V6KCfwncP9YDqYFiw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz", + "integrity": "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==", "requires": { "vue-demi": "*" }, @@ -16021,9 +16068,9 @@ "dev": true }, "axios": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", - "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.0.tgz", + "integrity": "sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -16207,9 +16254,9 @@ "dev": true }, "bootstrap": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.2.tgz", - "integrity": "sha512-dEtzMTV71n6Fhmbg4fYJzQsw1N29hJKO1js5ackCgIpDcGid2ETMGC6zwSYw09v05Y+oRdQ9loC54zB1La3hHQ==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz", + "integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==", "requires": {} }, "brace-expansion": { @@ -16692,9 +16739,9 @@ } }, "core-js": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", - "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==" + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", + "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==" }, "core-js-compat": { "version": "3.23.4", @@ -17385,9 +17432,9 @@ "dev": true }, "eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", + "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", "dev": true, "requires": { "@eslint/eslintrc": "^1.3.3", @@ -17909,9 +17956,9 @@ } }, "eslint-plugin-vue": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.6.0.tgz", - "integrity": "sha512-zzySkJgVbFCylnG2+9MDF7N+2Rjze2y0bF8GyUNpFOnT8mCMfqqtLDJkHBuYu9N/psW1A6DVbQhPkP92E+qakA==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.8.0.tgz", + "integrity": "sha512-E/AXwcTzunyzM83C2QqDHxepMzvI2y6x+mmeYHbVDQlKFqmKYvRrhaVixEeeG27uI44p9oKDFiyCRw4XxgtfHA==", "dev": true, "requires": { "eslint-utils": "^3.0.0", @@ -17935,12 +17982,12 @@ } }, "eslint-plugin-vuejs-accessibility": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vuejs-accessibility/-/eslint-plugin-vuejs-accessibility-1.2.0.tgz", - "integrity": "sha512-wF7kT22lS2VOmIpDeI65bnFFKFgESEEpI+CWKr43mdfDRywA4sCk7cKhtZsvfbPOtKO0GDlnpFxZbOIGsFn7IQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vuejs-accessibility/-/eslint-plugin-vuejs-accessibility-2.0.0.tgz", + "integrity": "sha512-mjbXnncDT9+5K+/QXXhOVWhEU6OOJck/JNlC6tewo3R+Kzsbaecyq3ylN1NqmyKo78vsgun34JLd+vGdxSPFWQ==", "dev": true, "requires": { - "aria-query": "^5.0.0", + "aria-query": ">=5.0.0", "emoji-regex": "^10.0.0", "vue-eslint-parser": "^9.0.1" }, @@ -18474,9 +18521,9 @@ "dev": true }, "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.0.0.tgz", + "integrity": "sha512-4YxRvMi4P5C3WQTvdRfrv5UVqbISpqjORFQAW5QPiKAauaxNCwrEdIi6pG3tDFhKKpMen+enEhHIzB/tvIO+/w==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -19699,9 +19746,9 @@ } }, "marked": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", - "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==" + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz", + "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==" }, "mdn-data": { "version": "2.0.14", @@ -19931,6 +19978,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz", @@ -20405,11 +20458,11 @@ "dev": true }, "pinia": { - "version": "2.0.23", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.23.tgz", - "integrity": "sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.27.tgz", + "integrity": "sha512-nOnXP0OFeL8R4WjAHsterU+11vptda643gH02xKNtSCDPiRzVfRYodOLihLDoa0gL1KKuQKV+KOzEgdt3YvqEw==", "requires": { - "@vue/devtools-api": "^6.4.4", + "@vue/devtools-api": "^6.4.5", "vue-demi": "*" }, "dependencies": { @@ -21190,9 +21243,9 @@ "dev": true }, "sass": { - "version": "1.55.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", - "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.1.tgz", + "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", @@ -21201,9 +21254,9 @@ } }, "sass-loader": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.1.0.tgz", - "integrity": "sha512-tZS1RJQ2n2+QNyf3CCAo1H562WjL/5AM6Gi8YcPVVoNxQX8d19mx8E+8fRrMWsyc93ZL6Q8vZDSM0FHVTJaVnQ==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz", + "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==", "dev": true, "requires": { "klona": "^2.0.4", @@ -22030,9 +22083,9 @@ } }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", "devOptional": true }, "uglify-js": { @@ -22154,15 +22207,15 @@ "dev": true }, "vue": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.41.tgz", - "integrity": "sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==", - "requires": { - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-sfc": "3.2.41", - "@vue/runtime-dom": "3.2.41", - "@vue/server-renderer": "3.2.41", - "@vue/shared": "3.2.41" + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz", + "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==", + "requires": { + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/runtime-dom": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45" } }, "vue-eslint-parser": { diff --git a/package.json b/package.json index 626e4811ce0e0f2ae16765821d095f45e89f7edf..0c1cce6bc86559c4b58a07fbd63e5b6d2b499638 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "nacsos_pipe": "http://127.0.0.1:8000" }, "scripts": { - "serve": "vue-cli-service serve", + "serve": "vue-cli-service serve --host localhost --mode development", "build": "vue-cli-service build", "lint": "vue-cli-service lint", "api-core": "node ./tools/openapi-gen/bin/index.js --input $npm_package_config_nacsos_core/openapi.json --output src/plugins/api/api-core --name CoreClient --client axios --indent 2 --useOptions --exportModels true --exportServices true --exportSchemas true --exportCore false --corePathTop @/plugins/api/core --corePathDeep @/plugins/api/core", @@ -15,28 +15,28 @@ "build-dev": "vue-cli-service build --mode=development" }, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.2.0", - "@fortawesome/free-brands-svg-icons": "^6.2.0", - "@fortawesome/free-regular-svg-icons": "^6.2.0", - "@fortawesome/free-solid-svg-icons": "^6.2.0", - "@fortawesome/vue-fontawesome": "^3.0.1", + "@fortawesome/fontawesome-svg-core": "^6.2.1", + "@fortawesome/free-brands-svg-icons": "^6.2.1", + "@fortawesome/free-regular-svg-icons": "^6.2.1", + "@fortawesome/free-solid-svg-icons": "^6.2.1", + "@fortawesome/vue-fontawesome": "^3.0.2", "@vuelidate/core": "^2.0.0", "@vuelidate/validators": "^2.0.0", - "@vueuse/core": "^9.3.1", - "axios": "^1.1.3", - "bootstrap": "^5.2.2", - "core-js": "^3.26.0", + "@vueuse/core": "^9.6.0", + "axios": "^1.2.0", + "bootstrap": "^5.2.3", + "core-js": "^3.26.1", "form-data": "^4.0.0", - "marked": "^4.1.1", - "pinia": "^2.0.23", - "vue": "^3.2.41", + "marked": "^4.2.3", + "pinia": "^2.0.27", + "vue": "^3.2.45", "vue-router": "^4.1.6" }, "devDependencies": { "@rushstack/eslint-patch": "^1.2.0", "@types/marked": "^4.0.7", - "@typescript-eslint/eslint-plugin": "^5.40.1", - "@typescript-eslint/parser": "^5.40.1", + "@typescript-eslint/eslint-plugin": "^5.45.0", + "@typescript-eslint/parser": "^5.45.0", "@vue/cli-plugin-babel": "^5.0.8", "@vue/cli-plugin-eslint": "^5.0.8", "@vue/cli-plugin-router": "^5.0.8", @@ -44,16 +44,16 @@ "@vue/cli-plugin-vuex": "^5.0.8", "@vue/cli-service": "^5.0.8", "@vue/eslint-config-airbnb-with-typescript": "^7.0.0", - "eslint": "^8.26.0", + "eslint": "^8.28.0", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-vue": "^9.6.0", - "eslint-plugin-vuejs-accessibility": "^1.2.0", - "sass": "^1.55.0", - "sass-loader": "^13.1.0", - "typescript": "^4.8.4", + "eslint-plugin-vue": "^9.8.0", + "eslint-plugin-vuejs-accessibility": "^2.0.0", + "sass": "^1.56.1", + "sass-loader": "^13.2.0", + "typescript": "^4.9.3", "camelcase": "^6.3.0", "commander": "^9.4.1", - "fs-extra": "^10.1.0", + "fs-extra": "^11.0.0", "handlebars": "^4.7.7", "json-schema-ref-parser": "^9.0.9" } diff --git a/src/assets/style.css b/src/assets/style.css index 42e37e1eef1e286954d5e82e5040bcfd2bb2efbb..3c79ec9d6b890c113ad58622f0de358d18986e54 100644 --- a/src/assets/style.css +++ b/src/assets/style.css @@ -19,6 +19,11 @@ .nacsos-tooltip { position: relative; display: inline-block; + + --tooltip-margin-x: 1rem; + --tooltip-margin-y: -1rem; + --tooltip-padding-x: 1rem; + --tooltip-padding-y: 0.5rem; } /* Tooltip text */ @@ -27,29 +32,45 @@ visibility: hidden; background-color: rgba(0, 0, 0, 0.9); color: #fff; - padding: 0.5rem 1rem; - margin: -1rem 1rem; + padding: var(--tooltip-padding-y) var(--tooltip-padding-x); + margin: var(--tooltip-margin-y) var(--tooltip-margin-x); border-radius: 6px; /* Position the tooltip text - see examples below! */ position: absolute; z-index: 1; + inline-size: max-content; +} + +.nacsos-tooltip > .right { + transform: translate(0%, 0%); + --tooltip-margin-x: 0.2rem; +} + +.nacsos-tooltip > .top { + transform: translate(-50%, -100%); +} + +.nacsos-tooltip > .bottom { + transform: translate(-50%, 33%); +} + +.nacsos-tooltip > .left { + transform: translate(calc(-100% - 2 * var(--tooltip-padding-x)), -33%); } .nacsos-tooltip > .small { margin: 0; - transform: translate(-50%,-100%); max-width: 10rem; text-align: center; - inline-size: max-content; } .nacsos-tooltip > .medium { - width: 25rem; + max-width: 25rem; } .nacsos-tooltip > .wide { - width: 50rem; + max-width: 50rem; } /* Show the tooltip text when you mouse over the tooltip container */ @@ -96,3 +117,29 @@ .collapsible > .toggle:checked + .lbl-toggle + .collapsible-content { max-height: 350px; } + +/* +Analogous to LaTeX +\tiny .fs-tiny (0.5rem) +\scriptsize .fs-script (0.6125rem) +\footnotesize .fs-fn (0.75rem) +\small .small (0.875rem) # already in bootstrap +\normalsize .fs-6 (1.00rem) +\large .fs-5 (1.25rem) +\Large .fs-4 (1.50rem) +\LARGE .fs-3 (1.75rem) +\huge .fs-2 (2.00rem) +\Huge .fs-1 (2.50rem) +*/ + +.fs-tiny { + font-size: 0.5rem !important; +} + +.fs-script { + font-size: 0.6125rem !important; +} + +.fs-fn { + font-size: 0.75rem !important; +} \ No newline at end of file diff --git a/src/components/InlineToolTip.vue b/src/components/InlineToolTip.vue index 83319403f866c35dbdc11ed61ba2c2aefa6d579a..36ea948cf3ad2d3dc01693f9e453210c305cdedd 100644 --- a/src/components/InlineToolTip.vue +++ b/src/components/InlineToolTip.vue @@ -5,7 +5,7 @@ <template v-else> <span class="nacsos-tooltip"> <slot /> - <span class="nacsos-tooltiptext small"> + <span class="nacsos-tooltiptext" :class="[size, placement]"> {{ info }} </span> </span> @@ -14,8 +14,25 @@ <script lang="ts"> +// type Placement = 'top' | 'left' | 'bottom' | 'right'; +// type Size = 'small' | 'medium' | 'wide'; export default { name: 'InlineToolTip', - props: ['info'], + props: { + info: { + type: String, + required: true, + }, + placement: { + type: String, + required: false, + default: 'top', + }, + size: { + type: String, + required: false, + default: 'small', + }, + }, }; </script> diff --git a/src/components/SideBar.vue b/src/components/SideBar.vue index 729b9e339f2cecb14631a99e48f08a51336e2c32..2de2e0d66c6cac104025d69aeab9d7379858c0ee 100644 --- a/src/components/SideBar.vue +++ b/src/components/SideBar.vue @@ -49,13 +49,13 @@ v-if="projectPermissions.annotations_read && isActive('project-pipelines')" to="/project/pipelines/setup" class="list-group-item list-group-item-action list-group-item-info border-end-0 sub-link" - active-class="active"> Task Configuration + exact-active-class="active"> Task Configuration </router-link> <router-link v-if="projectPermissions.annotations_read && isActive('project-pipelines')" to="/project/pipelines/presets" class="list-group-item list-group-item-action list-group-item-info border-end-0 sub-link" - active-class="active"> Presets + exact-active-class="active"> Presets </router-link> <router-link v-if="projectPermissions.annotations_edit" @@ -65,9 +65,26 @@ <font-awesome-icon icon="gear" /> Annotations </router-link> + <router-link + v-if="projectPermissions.annotations_edit && isActive('config-annotation-schemes')" + to="/project/config/annotations/list" + class="list-group-item list-group-item-action list-group-item-info border-end-0 sub-link" + :class="{ + active: anyOf(['config-annotation-scheme-edit', + 'config-annotation-scheme-scope', + 'config-annotation-scheme-list']), + }"> Schemes & Scopes + </router-link> + <router-link + v-if="projectPermissions.annotations_edit && isActive('config-annotation-schemes')" + to="/project/config/annotations/resolved" + class="list-group-item list-group-item-action list-group-item-info border-end-0 sub-link" + :class="{ active: anyOf(['config-annotation-resolve', 'config-resolved-annotations-list']) }"> + Label Centre + </router-link> <router-link v-if="projectPermissions.owner" - to="/project/config/project" + to="/project/settings" class="list-group-item list-group-item-action border-end-0" active-class="active"> <font-awesome-icon icon="gear" /> @@ -120,12 +137,15 @@ export default { isActive(parentName: string): boolean { return this.$router.currentRoute.value.matched.some((route: RouteLocationMatched) => route.name === parentName); }, + anyOf(routeNames: string[]): boolean { + return routeNames.indexOf(this.$router.currentRoute.value.name) >= 0; + }, toggleVisibility(): void { this.visible = (this.visible === undefined) ? false : !this.visible; }, - setVisibility(newState: boolean): void { - this.visible = newState; - }, + // setVisibility(newState: boolean): void { + // this.visible = newState; + // }, }, mounted() { window.onresize = () => { diff --git a/src/components/annotations/resolve/BoolLabel.vue b/src/components/annotations/resolve/BoolLabel.vue new file mode 100644 index 0000000000000000000000000000000000000000..732b164c4fcf8272d6b668c15198ae8a1c36daac --- /dev/null +++ b/src/components/annotations/resolve/BoolLabel.vue @@ -0,0 +1,106 @@ +<template> + <div> + <span v-for="annotation in userAnnotations" :key="annotation.annotation_id"> + <InlineToolTip :info="getPrettyUsername(annotation.user_id)"> + <font-awesome-icon + :icon="['fas', annotation2icon(annotation.value_bool)]" + :class="[annotation2classes(annotation.value_bool)]" + class="border text-light p-1" + style="height: 1rem; width: 1rem;" /> + </InlineToolTip> + </span> + + <div class="dropdown ps-2 d-inline-block"> + <font-awesome-icon + :icon="['fas', annotation2icon(botAnnotation.value_bool)]" + :class="annotation2classes(botAnnotation.value_bool)" + class="border border-dark border-2 rounded-3 text-light p-1 dropdown-toggle" + role="button" + style="height: 1rem; width: 1rem;" + @click="editMode = !editMode" /> + <ul class="dropdown-menu end-0" :class="{ show: editMode }"> + <li><span class="dropdown-item" role="button" tabindex="-1" @click="setBotAnnotation(true)">True</span></li> + <li><span class="dropdown-item" role="button" tabindex="-1" @click="setBotAnnotation(false)">False</span></li> + <li><span + class="dropdown-item" + role="button" + tabindex="-1" + @click="setBotAnnotation(undefined)">[NONE]</span></li> + </ul> + </div> + </div> +</template> + +<script lang="ts"> +import { AnnotationModel, BotAnnotationModel, FlattenedAnnotationSchemeLabel, UserModel } from '@/plugins/api/api-core'; +import InlineToolTip from '@/components/InlineToolTip.vue'; +import { PropType } from 'vue'; +import { EventBus } from '@/plugins/events'; +import { ToastEvent } from '@/plugins/events/events/toast'; + +interface BoolLabelData { + changed: boolean, + editMode: boolean, +} + +export default { + name: 'BoolLabel', + components: { InlineToolTip }, + data(): BoolLabelData { + return { + // set to true when bot annotation was manipulated + changed: false, + editMode: false, + }; + }, + emits: ['botAnnotationChanged'], + props: { + info: { + type: Object as PropType<FlattenedAnnotationSchemeLabel>, + required: true, + }, + users: { + type: Object as PropType<Record<string, UserModel>>, + required: true, + }, + userAnnotations: { + type: Array as PropType<AnnotationModel[]>, + required: true, + }, + botAnnotation: { + type: Object as PropType<BotAnnotationModel>, + required: true, + }, + }, + methods: { + annotation2icon(val: boolean | undefined): string { + if (val === undefined) return 'question'; + return (val) ? 'check' : 'xmark'; + }, + annotation2classes(val: boolean | undefined): string[] { + if (val === undefined) return ['bg-light', 'text-dark']; + return (val) ? ['bg-success', 'text-light'] : ['bg-danger', 'text-light']; + }, + setBotAnnotation(value: boolean | undefined) { + if (this.botAnnotation !== undefined) { + const anno = this.botAnnotation; + anno.value_bool = value; + this.$emit('botAnnotationChanged', anno); + this.editMode = false; + } else { + // FIXME: not implemented (handle adding new BotAnnotation, i.e. handle the case where item has no annotation here) + // const anno: BotAnnotationModel = {}; + EventBus.emit(new ToastEvent('WARN', 'Not implemented yet.')); + } + }, + getPrettyUsername(userId: string): string { + const user: UserModel | undefined = this.users[userId]; + if (!user) return '??'; + return `${user.username} (${user.full_name})`; + }, + }, + computed: { + // pass + }, +}; +</script> diff --git a/src/components/annotations/resolve/ChoiceLabel.vue b/src/components/annotations/resolve/ChoiceLabel.vue new file mode 100644 index 0000000000000000000000000000000000000000..d3c2b445c3c152878694d44f5d14ff13bf47df62 --- /dev/null +++ b/src/components/annotations/resolve/ChoiceLabel.vue @@ -0,0 +1,150 @@ +<template> + <div v-if="userAnnotations !== undefined"> + + <!-- User Annotations --> + <span v-for="annotation in userAnnotations" :key="annotation.annotation_id"> + <InlineToolTip :info="getPrettyUsername(annotation.user_id)"> + <span + class="border text-light p-1 ps-2 pe-2" + :style="{ backgroundColor: annotation2bgColor(annotation) }"> + <template v-if="annotation.value_int === undefined"> + <font-awesome-icon :icon="['fas', 'question']" class="text-dark" /> + </template> + <template v-else> + {{ annotation.value_int }} + </template> + </span> + </InlineToolTip> + </span> + <!-- / User Annotations --> + + <!-- BotAnnotation --> + <div class="dropdown ps-2 d-inline-block"> + <span + class="border text-light p-1 border-dark border-2 rounded-3 dropdown-toggle" + :style="{ backgroundColor: annotation2bgColor(botAnnotation) }" + role="button" + tabindex="-1" + @click="editMode = !editMode"> + <template v-if="!hasValue(botAnnotation)"> + <font-awesome-icon :icon="['fas', 'question']" class="text-dark" /> + </template> + <template v-else> + {{ botAnnotation.value_int }} + </template> + </span> + <ul class="dropdown-menu end-0" :class="{ show: editMode }"> + <li v-for="choice in info.choices" :key="choice.value"> + <span class="dropdown-item" role="button" tabindex="-1" @click="setBotAnnotation(choice.value)"> + {{ choice.name }} ({{ choice.value }}) + </span> + </li> + <li><span + class="dropdown-item" + role="button" + tabindex="-1" + @click="setBotAnnotation(undefined)">[NONE]</span></li> + </ul> + </div> + <!-- / BotAnnotation --> + + </div> +</template> + +<script lang="ts"> + +import { + AnnotationModel, + AnnotationSchemeLabelChoiceFlat, + BotAnnotationModel, + FlattenedAnnotationSchemeLabel, UserModel, +} from '@/plugins/api/api-core'; +import InlineToolTip from '@/components/InlineToolTip.vue'; +import { PropType } from 'vue'; +import { cmap10, cmap20 } from '@/types/colours'; +import { EventBus } from '@/plugins/events'; +import { ToastEvent } from '@/plugins/events/events/toast'; + +function hasValue(model: AnnotationModel | BotAnnotationModel | undefined | null): + model is (AnnotationModel | BotAnnotationModel) & { value_int: number } { + if (model === null || model === undefined) return false; + return (model.value_int !== undefined && model.value_int !== null); +} + +interface ChoiceLabelData { + changed: boolean, + editMode: boolean, +} + +export default { + name: 'ChoiceLabel', + components: { InlineToolTip }, + data(): ChoiceLabelData { + return { + changed: false, + editMode: false, + }; + }, + emits: ['botAnnotationChanged', 'botAnnotationConfirmed'], + props: { + info: { + type: Object as PropType<FlattenedAnnotationSchemeLabel>, + required: true, + }, + users: { + type: Object as PropType<Record<string, UserModel>>, + required: true, + }, + userAnnotations: { + type: Array as PropType<AnnotationModel[]>, + required: false, + default: () => undefined, + }, + botAnnotation: { + type: Object as PropType<BotAnnotationModel>, + required: false, + default: () => undefined, + }, + }, + methods: { + hasValue(model: AnnotationModel | BotAnnotationModel | undefined | null): + model is (AnnotationModel | BotAnnotationModel) & { value_int: number } { + return hasValue(model); + }, + annotation2bgColor(val: AnnotationModel | BotAnnotationModel | undefined) { + if (hasValue(val)) { + return this.cmap[val.value_int % this.cmap.length]; + } + return 'transparent'; + }, + setBotAnnotation(value: number | undefined) { + if (this.botAnnotation !== undefined) { + if (this.botAnnotation.value_int !== value) { + this.changed = true; + const anno = this.botAnnotation; + anno.value_int = value; + this.$emit('botAnnotationChanged', anno); + this.editMode = false; + } + } else { + // FIXME: not implemented (handle adding new BotAnnotation, i.e. handle the case where item has no annotation here) + // const anno: BotAnnotationModel = {}; + EventBus.emit(new ToastEvent('WARN', 'Not implemented yet.')); + } + }, + getPrettyUsername(userId: string): string { + const user: UserModel | undefined = this.users[userId]; + if (!user) return '??'; + return `${user.username} (${user.full_name})`; + }, + }, + computed: { + cmap(): string[] { + return (this.info.choices.length > 10) ? cmap20 : cmap10; + }, + choiceLookup(): Record<number, AnnotationSchemeLabelChoiceFlat> { + return Object.fromEntries(this.info.choices.map((choice: AnnotationSchemeLabelChoiceFlat) => [choice.value, choice])); + }, + }, +}; +</script> diff --git a/src/components/imports/ConfigJSONL.vue b/src/components/imports/ConfigJSONL.vue index 633b0f729f98d255505a0c267e2411be2d086864..90af2dfedc889e8e494f37db043111afe7f4b86d 100644 --- a/src/components/imports/ConfigJSONL.vue +++ b/src/components/imports/ConfigJSONL.vue @@ -50,15 +50,15 @@ <script lang="ts"> import FilesUploader, { UploadFile } from '@/components/FilesUploader.vue'; import { PropType } from 'vue'; -import { ImportConfigJSONL, ProjectType } from '@/plugins/api/api-core'; +import { ImportConfigJSONL, ItemType } from '@/plugins/api/api-core'; import { currentProjectStore } from '@/stores'; import useVuelidate, { BaseValidation, ValidationRule } from '@vuelidate/core'; import { required } from '@vuelidate/validators'; import types = ImportConfigJSONL.line_type; -type CompatibilityMapping = { [key in ProjectType]: types[] }; +type CompatibilityMapping = { [key in ItemType]: types[] }; const jsonlTypeCompatibility: CompatibilityMapping = { - basic: [types.DB_BASIC_ITEM], + generic: [types.DB_GENERIC_ITEM], academic: [types.DB_ACADEMIC_ITEM], patents: [types.DB_PATENT_ITEM], twitter: [types.DB_TWITTER_ITEM, types.TWITTER_API_PAGE], diff --git a/src/components/items/AnyItem.vue b/src/components/items/AnyItem.vue new file mode 100644 index 0000000000000000000000000000000000000000..d203800709e46700ecfe66817e524aed5b6caf04 --- /dev/null +++ b/src/components/items/AnyItem.vue @@ -0,0 +1,42 @@ +<template> + <component :is="component" :item="item" /> +</template> + +<script lang="ts"> +import { AnyItem } from '@/types/items.d'; +import { PropType, Component } from 'vue'; +import TwitterItemComponent from '@/components/items/TwitterItem.vue'; +import GenericItemComponent from '@/components/items/GenericItem.vue'; +import { useCurrentProjectStore } from '@/stores/CurrentProjectStore'; +import { ItemType } from '@/plugins/api/api-core'; + +type TypeMapType = { [key in ItemType]: Component }; + +export default { + name: 'GenericItem', + props: { + item: { + type: Object as PropType<AnyItem>, + required: true, + default: null, + }, + }, + data() { + const typeMap: TypeMapType = { + generic: GenericItemComponent, + twitter: TwitterItemComponent, + academic: GenericItemComponent, // FIXME: replace with correct component + patents: GenericItemComponent, // FIXME: replace with correct component + }; + const store = useCurrentProjectStore(); + const { type } = store.project; + return { + component: typeMap[type], + }; + }, +}; +</script> + +<style scoped> + +</style> diff --git a/src/components/items/BaseItem.vue b/src/components/items/BaseItem.vue deleted file mode 100644 index 0fa323e41927f930cb5925ca08e0265caf2b253e..0000000000000000000000000000000000000000 --- a/src/components/items/BaseItem.vue +++ /dev/null @@ -1,42 +0,0 @@ -<template> - <div class="card m-2 p-0 text-start"> - <div class="card-body"> - <p class="card-text" v-html="htmlText" /> - </div> - <div class="card-footer d-flex justify-content-between small text-muted" v-if="item.meta"> - <ul class="list-unstyled"> - <template v-for="(value, key) in item.meta" :key="key"> - <li v-if="!key.startsWith('_')"> - <strong>{{ key }}:</strong> {{ value }} - </li> - </template> - </ul> - </div> - </div> -</template> - -<script lang="ts"> -import { PropType } from 'vue'; -import { marked } from 'marked'; -import { BaseItem as BaseItemModel } from '@/types/items.d'; - -export default { - name: 'BaseItem', - props: { - item: { - type: Object as PropType<BaseItemModel>, - required: true, - default: null, - }, - }, - computed: { - htmlText() { - return marked(this.item.text); - }, - }, -}; -</script> - -<style scoped> - -</style> diff --git a/src/components/items/GenericItem.vue b/src/components/items/GenericItem.vue index 267c298271b869d61988739b3f6465c5ab572e05..aee42f84e57cc5d93beef1cb4dcb1e91765c137b 100644 --- a/src/components/items/GenericItem.vue +++ b/src/components/items/GenericItem.vue @@ -1,38 +1,38 @@ <template> - <component :is="component" :item="item" /> + <div class="card m-2 p-0 text-start"> + <div class="card-body"> + <p class="card-text" v-html="htmlText" /> + </div> + <div class="card-footer d-flex justify-content-between small text-muted" v-if="item.meta"> + <ul class="list-unstyled"> + <template v-for="(value, key) in item.meta" :key="key"> + <li v-if="!key.startsWith('_')"> + <strong>{{ key }}:</strong> {{ value }} + </li> + </template> + </ul> + </div> + </div> </template> <script lang="ts"> -import { AnyItem } from '@/types/items.d'; -import { PropType, Component } from 'vue'; -import TwitterItemComponent from '@/components/items/TwitterItem.vue'; -import BaseItemComponent from '@/components/items/BaseItem.vue'; -import { useCurrentProjectStore } from '@/stores/CurrentProjectStore'; -import { ProjectType } from '@/plugins/api/api-core'; - -type TypeMapType = { [key in ProjectType]: Component }; +import { PropType } from 'vue'; +import { marked } from 'marked'; +import { BaseItem as BaseItemModel } from '@/types/items.d'; export default { name: 'GenericItem', props: { item: { - type: Object as PropType<AnyItem>, + type: Object as PropType<BaseItemModel>, required: true, default: null, }, }, - data() { - const typeMap: TypeMapType = { - basic: BaseItemComponent, - twitter: TwitterItemComponent, - academic: BaseItemComponent, // FIXME: replace with correct component - patents: BaseItemComponent, // FIXME: replace with correct component - }; - const store = useCurrentProjectStore(); - const { type } = store.project; - return { - component: typeMap[type], - }; + computed: { + htmlText() { + return marked(this.item.text); + }, }, }; </script> diff --git a/src/components/items/ItemModal.vue b/src/components/items/ItemModal.vue new file mode 100644 index 0000000000000000000000000000000000000000..8cb5f048cbbe2676839d5a750d8cbc0a291c64c4 --- /dev/null +++ b/src/components/items/ItemModal.vue @@ -0,0 +1,110 @@ +<template> + <div v-if="showItemModal"> + <div + class="modal fade show" + data-bs-backdrop="static" + data-bs-keyboard="false" + tabindex="-1" + style="display: block" + @click="dismissModal" + aria-hidden="true"> + <div class="modal-dialog modal-xl modal-dialog-scrollable" @click.stop="stop"> + <div class="modal-content"> + <div class="modal-header"> + <h1 class="modal-title fs-5" id="staticBackdropLabel">Details for item {{ itemId }}</h1> + <button type="button" class="btn-close" aria-label="Close" @click="dismissModal" /> + </div> + <div class="modal-body"> + <template v-if="isLoading"> + <p class="card-text placeholder-glow"> + <span class="placeholder col-7" /> + <span class="placeholder col-4" /> + <span class="placeholder col-4" /> + <span class="placeholder col-6" /> + <span class="placeholder col-8" /> + </p> + </template> + <template v-else> + <AnyItemComponent :item="itemInfo" /> + </template> + </div> + <!-- <div class="modal-footer">--> + <!-- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>--> + <!-- <button type="button" class="btn btn-primary">Understood</button>--> + <!-- </div>--> + </div> + </div> + </div> + <div class="modal-backdrop fade show" /> + </div> +</template> + +<script lang="ts"> + +import { AnyItem } from '@/types/items'; +import { API } from '@/plugins/api'; +import { currentProjectStore } from '@/stores'; +import { CancelablePromise } from '@/plugins/api/core/CancelablePromise'; +import AnyItemComponent from '@/components/items/AnyItem.vue'; + +type ItemModalData = { + itemInfo: AnyItem | undefined, + requestPromise: CancelablePromise<AnyItem> | undefined, +}; + +export default { + components: { AnyItemComponent }, + props: ['itemId'], + emits: ['dismissed'], + data(): ItemModalData { + return { + itemInfo: undefined, + requestPromise: undefined, + }; + }, + computed: { + showItemModal() { + // show modal if data is present or request is running + return this.itemInfo !== undefined || this.requestPromise !== undefined; + }, + isLoading() { + return this.requestPromise !== undefined; + }, + }, + methods: { + getItemInfo(itemId: string) { + this.itemInfo = null; + this.requestPromise = API.core.project.getDetailForItemApiProjectItemsDetailItemIdGet({ + itemId, + xProjectId: currentProjectStore.projectId, + }).then((result) => { + this.itemInfo = result.data; + this.requestPromise = undefined; + }).catch(() => { + this.dismissModal(); + }); + }, + dismissModal() { + this.resetRequest(); + this.itemInfo = undefined; + this.$emit('dismissed'); + }, + resetRequest() { + if (this.requestPromise !== undefined) { + this.requestPromise.cancel(); + this.requestPromise = undefined; + } + }, + }, + watch: { + itemId(newId: string | null | undefined) { + // reset any prior request (if present) + this.resetRequest(); + // fetch the data + if (newId !== null && newId !== undefined) { + this.getItemInfo(newId); + } + }, + }, +}; +</script> diff --git a/src/components/items/TwitterItem.vue b/src/components/items/TwitterItem.vue index 77afd5d453a0eeac0ca51ce31efbc8dbc02b66d8..fc74d3012286f0662c6659fd73e74c8b51adb9eb 100644 --- a/src/components/items/TwitterItem.vue +++ b/src/components/items/TwitterItem.vue @@ -90,11 +90,11 @@ export default { .sort((a, b) => a.start - b.start) .forEach((replacement) => { // FIXME: something has to be done with the slicing offsets... sometimes they are off - ret += this.item.status.slice(prevEnd, replacement.start); + ret += this.item.text.slice(prevEnd, replacement.start); ret += replacement.html; prevEnd = replacement.end; }); - ret += this.item.status.slice(prevEnd, this.item.status.length); + ret += this.item.text.slice(prevEnd, this.item.text.length); return ret; }, }, diff --git a/src/plugins/api/api-core/index.ts b/src/plugins/api/api-core/index.ts index 7e005efbb4e144df85fbd8d735274c12f6f9e5b7..d380149dcfba79cc65370cb426bf94e437a84a4b 100644 --- a/src/plugins/api/api-core/index.ts +++ b/src/plugins/api/api-core/index.ts @@ -4,21 +4,35 @@ export { CoreClient } from './CoreClient'; +export type { AcademicItemModel } from './models/AcademicItemModel'; export type { AnnotatedItem } from './models/AnnotatedItem'; +export type { AnnotationCollection } from './models/AnnotationCollection'; +export type { AnnotationCollectionDB } from './models/AnnotationCollectionDB'; +export type { AnnotationFilters } from './models/AnnotationFilters'; export type { AnnotationItem } from './models/AnnotationItem'; export type { AnnotationModel } from './models/AnnotationModel'; export { AnnotationSchemeLabel } from './models/AnnotationSchemeLabel'; export type { AnnotationSchemeLabelChoice } from './models/AnnotationSchemeLabelChoice'; +export type { AnnotationSchemeLabelChoiceFlat } from './models/AnnotationSchemeLabelChoiceFlat'; export type { AnnotationSchemeModel } from './models/AnnotationSchemeModel'; +export type { AnnotationSchemeModelFlat } from './models/AnnotationSchemeModelFlat'; export type { AssignmentCounts } from './models/AssignmentCounts'; export type { AssignmentModel } from './models/AssignmentModel'; export type { AssignmentScopeModel } from './models/AssignmentScopeModel'; export { AssignmentScopeRandomConfig } from './models/AssignmentScopeRandomConfig'; export { AssignmentStatus } from './models/AssignmentStatus'; export type { Body_login_for_access_token_api_login_token_post } from './models/Body_login_for_access_token_api_login_token_post'; +export type { BotAnnotationMetaDataBaseModel } from './models/BotAnnotationMetaDataBaseModel'; +export type { BotAnnotationModel } from './models/BotAnnotationModel'; +export { BotKind } from './models/BotKind'; +export { BotMetaResolve } from './models/BotMetaResolve'; export type { Cashtag } from './models/Cashtag'; export type { ContextAnnotation } from './models/ContextAnnotation'; export { Event } from './models/Event'; +export { FlattenedAnnotationSchemeLabel } from './models/FlattenedAnnotationSchemeLabel'; +export type { GenericItemModel } from './models/GenericItemModel'; +export type { GroupedAnnotations } from './models/GroupedAnnotations'; +export type { GroupedBotAnnotation } from './models/GroupedBotAnnotation'; export type { Hashtag } from './models/Hashtag'; export type { HTTPValidationError } from './models/HTTPValidationError'; export { ImportConfigJSONL } from './models/ImportConfigJSONL'; @@ -26,8 +40,9 @@ export type { ImportConfigRIS } from './models/ImportConfigRIS'; export { ImportConfigTwitter } from './models/ImportConfigTwitter'; export type { ImportModel } from './models/ImportModel'; export { ImportType } from './models/ImportType'; -export type { ItemModel } from './models/ItemModel'; +export { ItemType } from './models/ItemType'; export type { ItemWithCount } from './models/ItemWithCount'; +export type { Label } from './models/Label'; export type { MakeAssignmentsRequestModel } from './models/MakeAssignmentsRequestModel'; export type { Mention } from './models/Mention'; export { PipelineTaskStatusChangedEvent } from './models/PipelineTaskStatusChangedEvent'; @@ -36,8 +51,10 @@ export { PipelineTaskStatusFailedEvent } from './models/PipelineTaskStatusFailed export { PipelineTaskStatusStartedEvent } from './models/PipelineTaskStatusStartedEvent'; export type { ProjectModel } from './models/ProjectModel'; export type { ProjectPermissionsModel } from './models/ProjectPermissionsModel'; -export { ProjectType } from './models/ProjectType'; export { ReferencedTweet } from './models/ReferencedTweet'; +export { ResolutionPayload } from './models/ResolutionPayload'; +export type { ResolutionProposalResponse } from './models/ResolutionProposalResponse'; +export type { SavedResolutionResponse } from './models/SavedResolutionResponse'; export type { Token } from './models/Token'; export type { TwitterItemModel } from './models/TwitterItemModel'; export type { TwitterUserModel } from './models/TwitterUserModel'; @@ -46,21 +63,35 @@ export type { UserModel } from './models/UserModel'; export type { UserProjectAssignmentScope } from './models/UserProjectAssignmentScope'; export type { ValidationError } from './models/ValidationError'; +export { $AcademicItemModel } from './schemas/$AcademicItemModel'; export { $AnnotatedItem } from './schemas/$AnnotatedItem'; +export { $AnnotationCollection } from './schemas/$AnnotationCollection'; +export { $AnnotationCollectionDB } from './schemas/$AnnotationCollectionDB'; +export { $AnnotationFilters } from './schemas/$AnnotationFilters'; export { $AnnotationItem } from './schemas/$AnnotationItem'; export { $AnnotationModel } from './schemas/$AnnotationModel'; export { $AnnotationSchemeLabel } from './schemas/$AnnotationSchemeLabel'; export { $AnnotationSchemeLabelChoice } from './schemas/$AnnotationSchemeLabelChoice'; +export { $AnnotationSchemeLabelChoiceFlat } from './schemas/$AnnotationSchemeLabelChoiceFlat'; export { $AnnotationSchemeModel } from './schemas/$AnnotationSchemeModel'; +export { $AnnotationSchemeModelFlat } from './schemas/$AnnotationSchemeModelFlat'; export { $AssignmentCounts } from './schemas/$AssignmentCounts'; export { $AssignmentModel } from './schemas/$AssignmentModel'; export { $AssignmentScopeModel } from './schemas/$AssignmentScopeModel'; export { $AssignmentScopeRandomConfig } from './schemas/$AssignmentScopeRandomConfig'; export { $AssignmentStatus } from './schemas/$AssignmentStatus'; export { $Body_login_for_access_token_api_login_token_post } from './schemas/$Body_login_for_access_token_api_login_token_post'; +export { $BotAnnotationMetaDataBaseModel } from './schemas/$BotAnnotationMetaDataBaseModel'; +export { $BotAnnotationModel } from './schemas/$BotAnnotationModel'; +export { $BotKind } from './schemas/$BotKind'; +export { $BotMetaResolve } from './schemas/$BotMetaResolve'; export { $Cashtag } from './schemas/$Cashtag'; export { $ContextAnnotation } from './schemas/$ContextAnnotation'; export { $Event } from './schemas/$Event'; +export { $FlattenedAnnotationSchemeLabel } from './schemas/$FlattenedAnnotationSchemeLabel'; +export { $GenericItemModel } from './schemas/$GenericItemModel'; +export { $GroupedAnnotations } from './schemas/$GroupedAnnotations'; +export { $GroupedBotAnnotation } from './schemas/$GroupedBotAnnotation'; export { $Hashtag } from './schemas/$Hashtag'; export { $HTTPValidationError } from './schemas/$HTTPValidationError'; export { $ImportConfigJSONL } from './schemas/$ImportConfigJSONL'; @@ -68,8 +99,9 @@ export { $ImportConfigRIS } from './schemas/$ImportConfigRIS'; export { $ImportConfigTwitter } from './schemas/$ImportConfigTwitter'; export { $ImportModel } from './schemas/$ImportModel'; export { $ImportType } from './schemas/$ImportType'; -export { $ItemModel } from './schemas/$ItemModel'; +export { $ItemType } from './schemas/$ItemType'; export { $ItemWithCount } from './schemas/$ItemWithCount'; +export { $Label } from './schemas/$Label'; export { $MakeAssignmentsRequestModel } from './schemas/$MakeAssignmentsRequestModel'; export { $Mention } from './schemas/$Mention'; export { $PipelineTaskStatusChangedEvent } from './schemas/$PipelineTaskStatusChangedEvent'; @@ -78,8 +110,10 @@ export { $PipelineTaskStatusFailedEvent } from './schemas/$PipelineTaskStatusFai export { $PipelineTaskStatusStartedEvent } from './schemas/$PipelineTaskStatusStartedEvent'; export { $ProjectModel } from './schemas/$ProjectModel'; export { $ProjectPermissionsModel } from './schemas/$ProjectPermissionsModel'; -export { $ProjectType } from './schemas/$ProjectType'; export { $ReferencedTweet } from './schemas/$ReferencedTweet'; +export { $ResolutionPayload } from './schemas/$ResolutionPayload'; +export { $ResolutionProposalResponse } from './schemas/$ResolutionProposalResponse'; +export { $SavedResolutionResponse } from './schemas/$SavedResolutionResponse'; export { $Token } from './schemas/$Token'; export { $TwitterItemModel } from './schemas/$TwitterItemModel'; export { $TwitterUserModel } from './schemas/$TwitterUserModel'; diff --git a/src/plugins/api/api-core/models/AcademicItemModel.ts b/src/plugins/api/api-core/models/AcademicItemModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..b72aecbea54301d6ccd74d45ac0840c0b2cdfef3 --- /dev/null +++ b/src/plugins/api/api-core/models/AcademicItemModel.ts @@ -0,0 +1,16 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemType } from './ItemType'; + +/** + * Corresponds to db.schema.items.academic.AcademicItem + */ +export type AcademicItemModel = { + item_id?: string; + project_id?: string; + type?: ItemType; + text: string; +}; + diff --git a/src/plugins/api/api-core/models/AnnotationCollection.ts b/src/plugins/api/api-core/models/AnnotationCollection.ts new file mode 100644 index 0000000000000000000000000000000000000000..7552a3451a843e77a6af7752f0a345abed0c59af --- /dev/null +++ b/src/plugins/api/api-core/models/AnnotationCollection.ts @@ -0,0 +1,14 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { Label } from './Label'; +import type { UserModel } from './UserModel'; + +export type AnnotationCollection = { + scheme_id: string; + labels: Array<Array<Label>>; + annotations: Record<string, Array<Array<any>>>; + annotators: Array<UserModel>; +}; + diff --git a/src/plugins/api/api-core/models/AnnotationCollectionDB.ts b/src/plugins/api/api-core/models/AnnotationCollectionDB.ts new file mode 100644 index 0000000000000000000000000000000000000000..92bc5bf354841084967296f5f0057997c431033b --- /dev/null +++ b/src/plugins/api/api-core/models/AnnotationCollectionDB.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { Label } from './Label'; + +export type AnnotationCollectionDB = { + scheme_id: string; + labels: Array<Array<Label>>; + annotations: Record<string, Array<Array<any>>>; + annotators: Array<string>; +}; + diff --git a/src/plugins/api/api-core/models/AnnotationFilters.ts b/src/plugins/api/api-core/models/AnnotationFilters.ts new file mode 100644 index 0000000000000000000000000000000000000000..70a3600ae3e1b73c1eb5abb1a1263d28a9e38f48 --- /dev/null +++ b/src/plugins/api/api-core/models/AnnotationFilters.ts @@ -0,0 +1,25 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * Filter rules for fetching all annotations that match these conditions + * It is up to the user of this function to make sure to provide sensible filters! + * All filters are conjunctive (connected with "AND"); if None, they are not included + * + * There are no "exclude" filters by design. If needed, they should be simulated in the interface. + * + * :param scheme_id: if not None: annotation has to be part of this annotation scheme + * :param scope_id: if not None: annotation has to be part of this assignment scope + * :param user_id: if not None: annotation has to be by this user + * :param key: if not None: annotation has to be for this AnnotationSchemeLabel.key (or list/tuple of keys) + * :param repeat: if not None: annotation has to be primary/secondary/... + */ +export type AnnotationFilters = { + scheme_id: string; + scope_id?: (string | Array<string>); + user_id?: (string | Array<string>); + key?: (string | Array<string>); + repeat?: (number | Array<number>); +}; + diff --git a/src/plugins/api/api-core/models/AnnotationItem.ts b/src/plugins/api/api-core/models/AnnotationItem.ts index 9c1d2d4174e7ad6b5871a08babf8b7fbdc98fd55..4724781c704a42a28149afda9131364552a1c4b6 100644 --- a/src/plugins/api/api-core/models/AnnotationItem.ts +++ b/src/plugins/api/api-core/models/AnnotationItem.ts @@ -2,16 +2,17 @@ /* tslint:disable */ /* eslint-disable */ +import type { AcademicItemModel } from './AcademicItemModel'; import type { AnnotationSchemeModel } from './AnnotationSchemeModel'; import type { AssignmentModel } from './AssignmentModel'; import type { AssignmentScopeModel } from './AssignmentScopeModel'; -import type { ItemModel } from './ItemModel'; +import type { GenericItemModel } from './GenericItemModel'; import type { TwitterItemModel } from './TwitterItemModel'; export type AnnotationItem = { scheme: AnnotationSchemeModel; assignment: AssignmentModel; scope: AssignmentScopeModel; - item: (ItemModel | TwitterItemModel); + item: (GenericItemModel | TwitterItemModel | AcademicItemModel); }; diff --git a/src/plugins/api/api-core/models/AnnotationModel.ts b/src/plugins/api/api-core/models/AnnotationModel.ts index 8fe69e1f9c0963ef3117c83daa993960df574e7e..fee4145e49ae4b0248819ba4107c0352aa8ba128 100644 --- a/src/plugins/api/api-core/models/AnnotationModel.ts +++ b/src/plugins/api/api-core/models/AnnotationModel.ts @@ -38,6 +38,7 @@ export type AnnotationModel = { value_int?: number; value_float?: number; value_str?: string; + multi_int?: Array<number>; text_offset_start?: number; text_offset_stop?: number; }; diff --git a/src/plugins/api/api-core/models/AnnotationSchemeLabel.ts b/src/plugins/api/api-core/models/AnnotationSchemeLabel.ts index 1d4fa3c142fb67fb98f3e57696ce91ed7a472156..ee89fd172d20cf27f68204bd99a0cedd98a91e18 100644 --- a/src/plugins/api/api-core/models/AnnotationSchemeLabel.ts +++ b/src/plugins/api/api-core/models/AnnotationSchemeLabel.ts @@ -21,8 +21,8 @@ export namespace AnnotationSchemeLabel { export enum kind { BOOL = 'bool', STR = 'str', - INT = 'int', FLOAT = 'float', + INT = 'int', SINGLE = 'single', MULTI = 'multi', INTEXT = 'intext', diff --git a/src/plugins/api/api-core/models/AnnotationSchemeLabelChoiceFlat.ts b/src/plugins/api/api-core/models/AnnotationSchemeLabelChoiceFlat.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb7611f6adeab50054771c7710921e88566bdd3f --- /dev/null +++ b/src/plugins/api/api-core/models/AnnotationSchemeLabelChoiceFlat.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type AnnotationSchemeLabelChoiceFlat = { + name: string; + hint?: string; + value: number; +}; + diff --git a/src/plugins/api/api-core/models/AnnotationSchemeModelFlat.ts b/src/plugins/api/api-core/models/AnnotationSchemeModelFlat.ts new file mode 100644 index 0000000000000000000000000000000000000000..6815b3d2e843f4cac4535c64ebc487939ac2d660 --- /dev/null +++ b/src/plugins/api/api-core/models/AnnotationSchemeModelFlat.ts @@ -0,0 +1,17 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { FlattenedAnnotationSchemeLabel } from './FlattenedAnnotationSchemeLabel'; + +/** + * Same as AnnotationSchemeModel but with flattened structure. + */ +export type AnnotationSchemeModelFlat = { + annotation_scheme_id?: string; + project_id?: string; + name: string; + description?: string; + labels: Array<FlattenedAnnotationSchemeLabel>; +}; + diff --git a/src/plugins/api/api-core/models/BotAnnotationMetaDataBaseModel.ts b/src/plugins/api/api-core/models/BotAnnotationMetaDataBaseModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb812e88962251ce17b608f857270ee129b83745 --- /dev/null +++ b/src/plugins/api/api-core/models/BotAnnotationMetaDataBaseModel.ts @@ -0,0 +1,17 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { BotKind } from './BotKind'; + +export type BotAnnotationMetaDataBaseModel = { + bot_annotation_metadata_id?: string; + name: string; + kind: BotKind; + project_id: string; + time_created?: string; + time_updated?: string; + annotation_scope_id?: string; + annotation_scheme_id?: string; +}; + diff --git a/src/plugins/api/api-core/models/BotAnnotationModel.ts b/src/plugins/api/api-core/models/BotAnnotationModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..43358aa32303c6f62a084a79cf5308009fc00489 --- /dev/null +++ b/src/plugins/api/api-core/models/BotAnnotationModel.ts @@ -0,0 +1,21 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type BotAnnotationModel = { + bot_annotation_id?: string; + bot_annotation_metadata_id?: string; + time_created?: string; + time_updated?: string; + item_id: string; + parent?: string; + key?: string; + repeat?: number; + value_bool?: boolean; + value_int?: number; + value_float?: number; + value_str?: string; + multi_int?: Array<number>; + confidence?: number; +}; + diff --git a/src/plugins/api/api-core/models/BotKind.ts b/src/plugins/api/api-core/models/BotKind.ts new file mode 100644 index 0000000000000000000000000000000000000000..3f8e7d365d754de1adda440259cc67811e4b8a70 --- /dev/null +++ b/src/plugins/api/api-core/models/BotKind.ts @@ -0,0 +1,14 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * An enumeration. + */ +export enum BotKind { + CLASSIFICATION = 'CLASSIFICATION', + RULES = 'RULES', + TOPICS = 'TOPICS', + RESOLVE = 'RESOLVE', + SCRIPT = 'SCRIPT', +} diff --git a/src/plugins/api/api-core/models/BotMetaResolve.ts b/src/plugins/api/api-core/models/BotMetaResolve.ts new file mode 100644 index 0000000000000000000000000000000000000000..3adf0910df331d0b1dd8c14372fb89a3626e2c80 --- /dev/null +++ b/src/plugins/api/api-core/models/BotMetaResolve.ts @@ -0,0 +1,28 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { AnnotationCollectionDB } from './AnnotationCollectionDB'; +import type { AnnotationFilters } from './AnnotationFilters'; + +export type BotMetaResolve = { + algorithm: BotMetaResolve.algorithm; + filters: AnnotationFilters; + ignore_hierarchy: boolean; + ignore_repeat: boolean; + trust?: Record<string, number>; + collection: AnnotationCollectionDB; +}; + +export namespace BotMetaResolve { + + export enum algorithm { + MAJORITY = 'majority', + FIRST = 'first', + LAST = 'last', + TRUST = 'trust', + } + + +} + diff --git a/src/plugins/api/api-core/models/Event.ts b/src/plugins/api/api-core/models/Event.ts index 8f736e2d681a9f41a4414a4ae9c640f88a9d211c..7174362dd785f7b53f0bd6784d85f22dcd6ab2c7 100644 --- a/src/plugins/api/api-core/models/Event.ts +++ b/src/plugins/api/api-core/models/Event.ts @@ -9,16 +9,16 @@ import type { PipelineTaskStatusStartedEvent } from './PipelineTaskStatusStarted export type Event = { event: Event.event; - payload: (PipelineTaskStatusChangedEvent | PipelineTaskStatusCompletedEvent | PipelineTaskStatusStartedEvent | PipelineTaskStatusFailedEvent); + payload: (PipelineTaskStatusFailedEvent | PipelineTaskStatusChangedEvent | PipelineTaskStatusCompletedEvent | PipelineTaskStatusStartedEvent); }; export namespace Event { export enum event { + PIPELINE_TASK_STATUS_FAILED_EVENT = 'PipelineTaskStatusFailedEvent', PIPELINE_TASK_STATUS_CHANGED_EVENT = 'PipelineTaskStatusChangedEvent', PIPELINE_TASK_STATUS_COMPLETED_EVENT = 'PipelineTaskStatusCompletedEvent', PIPELINE_TASK_STATUS_STARTED_EVENT = 'PipelineTaskStatusStartedEvent', - PIPELINE_TASK_STATUS_FAILED_EVENT = 'PipelineTaskStatusFailedEvent', } diff --git a/src/plugins/api/api-core/models/FlattenedAnnotationSchemeLabel.ts b/src/plugins/api/api-core/models/FlattenedAnnotationSchemeLabel.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b976993fe895c4ec80cc158ee304def0904a3fe --- /dev/null +++ b/src/plugins/api/api-core/models/FlattenedAnnotationSchemeLabel.ts @@ -0,0 +1,34 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { AnnotationSchemeLabelChoiceFlat } from './AnnotationSchemeLabelChoiceFlat'; + +export type FlattenedAnnotationSchemeLabel = { + name: string; + hint?: string; + key: string; + required: boolean; + max_repeat: number; + implicit_max_repeat: number; + kind: FlattenedAnnotationSchemeLabel.kind; + choices?: Array<AnnotationSchemeLabelChoiceFlat>; + parent_label?: string; + parent_choice?: number; +}; + +export namespace FlattenedAnnotationSchemeLabel { + + export enum kind { + BOOL = 'bool', + STR = 'str', + FLOAT = 'float', + INT = 'int', + SINGLE = 'single', + MULTI = 'multi', + INTEXT = 'intext', + } + + +} + diff --git a/src/plugins/api/api-core/models/GenericItemModel.ts b/src/plugins/api/api-core/models/GenericItemModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..9067d07807d2e73229c5ce12def4e8a252ba112f --- /dev/null +++ b/src/plugins/api/api-core/models/GenericItemModel.ts @@ -0,0 +1,17 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemType } from './ItemType'; + +/** + * Corresponds to db.models.items.generic.GenericItem + */ +export type GenericItemModel = { + item_id?: string; + project_id?: string; + type?: ItemType; + text: string; + meta: any; +}; + diff --git a/src/plugins/api/api-core/models/GroupedAnnotations.ts b/src/plugins/api/api-core/models/GroupedAnnotations.ts new file mode 100644 index 0000000000000000000000000000000000000000..3dbc746758ffdbbdbb5fdb6f777cd87b1d9ae7a8 --- /dev/null +++ b/src/plugins/api/api-core/models/GroupedAnnotations.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { AnnotationModel } from './AnnotationModel'; +import type { Label } from './Label'; + +export type GroupedAnnotations = { + path: Array<Label>; + annotations: Array<AnnotationModel>; +}; + diff --git a/src/plugins/api/api-core/models/GroupedBotAnnotation.ts b/src/plugins/api/api-core/models/GroupedBotAnnotation.ts new file mode 100644 index 0000000000000000000000000000000000000000..c0f06651a6c31cbdfc60792e0cf26381aa92920c --- /dev/null +++ b/src/plugins/api/api-core/models/GroupedBotAnnotation.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { BotAnnotationModel } from './BotAnnotationModel'; +import type { Label } from './Label'; + +export type GroupedBotAnnotation = { + path: Array<Label>; + annotation: BotAnnotationModel; +}; + diff --git a/src/plugins/api/api-core/models/ImportConfigJSONL.ts b/src/plugins/api/api-core/models/ImportConfigJSONL.ts index f8edfbad3b5abc59e17915e047fabd00254f9a50..045cfb0684b82956e091790963980d3fd5985e7b 100644 --- a/src/plugins/api/api-core/models/ImportConfigJSONL.ts +++ b/src/plugins/api/api-core/models/ImportConfigJSONL.ts @@ -12,7 +12,7 @@ export namespace ImportConfigJSONL { export enum line_type { DB_TWITTER_ITEM = 'db-twitter-item', TWITTER_API_PAGE = 'twitter-api-page', - DB_BASIC_ITEM = 'db-basic-item', + DB_GENERIC_ITEM = 'db-generic-item', DB_ACADEMIC_ITEM = 'db-academic-item', DB_PATENT_ITEM = 'db-patent-item', } diff --git a/src/plugins/api/api-core/models/ItemModel.ts b/src/plugins/api/api-core/models/ItemModel.ts deleted file mode 100644 index 1ec6cdcec8a75bcce6675692dc03abab90bf4251..0000000000000000000000000000000000000000 --- a/src/plugins/api/api-core/models/ItemModel.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Corresponds to db.models.items.Item - */ -export type ItemModel = { - item_id?: string; - text: string; - meta: any; -}; - diff --git a/src/plugins/api/api-core/models/ProjectType.ts b/src/plugins/api/api-core/models/ItemType.ts similarity index 78% rename from src/plugins/api/api-core/models/ProjectType.ts rename to src/plugins/api/api-core/models/ItemType.ts index db3a98bb29a37224f2ae4d517a38f84316a0a790..0679ef80fe6e1503e6cc38fef9a711fed3d77d3f 100644 --- a/src/plugins/api/api-core/models/ProjectType.ts +++ b/src/plugins/api/api-core/models/ItemType.ts @@ -5,8 +5,8 @@ /** * An enumeration. */ -export enum ProjectType { - BASIC = 'basic', +export enum ItemType { + GENERIC = 'generic', TWITTER = 'twitter', ACADEMIC = 'academic', PATENTS = 'patents', diff --git a/src/plugins/api/api-core/models/Label.ts b/src/plugins/api/api-core/models/Label.ts new file mode 100644 index 0000000000000000000000000000000000000000..080b681183fc855adbe37e54504d7c5501ba0895 --- /dev/null +++ b/src/plugins/api/api-core/models/Label.ts @@ -0,0 +1,15 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * Convenience type (corresponding to internal type in db annotation_label). + * For Annotation or BotAnnotation, this is the combination of their respective key, repeat value. + * + * Mainly used during resolving annotations. + */ +export type Label = { + key: string; + repeat: number; +}; + diff --git a/src/plugins/api/api-core/models/ProjectModel.ts b/src/plugins/api/api-core/models/ProjectModel.ts index aa5d6f358fdad95c982e656cd3fe08dbc6f8a00f..8adc98fe4d10ce53ff1933c366e9302384dae3f4 100644 --- a/src/plugins/api/api-core/models/ProjectModel.ts +++ b/src/plugins/api/api-core/models/ProjectModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -import type { ProjectType } from './ProjectType'; +import type { ItemType } from './ItemType'; /** * Project is the basic structural and conceptual place around which all functionality evolves. @@ -16,6 +16,6 @@ export type ProjectModel = { project_id?: string; name: string; description?: string; - type: ('basic' | 'twitter' | 'academic' | 'patents' | ProjectType); + type: ('generic' | 'twitter' | 'academic' | 'patents' | ItemType); }; diff --git a/src/plugins/api/api-core/models/ResolutionPayload.ts b/src/plugins/api/api-core/models/ResolutionPayload.ts new file mode 100644 index 0000000000000000000000000000000000000000..e4b06642a9a0f4e8516448b04a07d4cba25710dc --- /dev/null +++ b/src/plugins/api/api-core/models/ResolutionPayload.ts @@ -0,0 +1,30 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { AnnotationCollectionDB } from './AnnotationCollectionDB'; +import type { AnnotationFilters } from './AnnotationFilters'; +import type { BotAnnotationModel } from './BotAnnotationModel'; + +export type ResolutionPayload = { + name: string; + strategy: ResolutionPayload.strategy; + filters: AnnotationFilters; + ignore_order: boolean; + ignore_hierarchy: boolean; + collection: AnnotationCollectionDB; + bot_annotations: Array<BotAnnotationModel>; +}; + +export namespace ResolutionPayload { + + export enum strategy { + MAJORITY = 'majority', + FIRST = 'first', + LAST = 'last', + TRUST = 'trust', + } + + +} + diff --git a/src/plugins/api/api-core/models/ResolutionProposalResponse.ts b/src/plugins/api/api-core/models/ResolutionProposalResponse.ts new file mode 100644 index 0000000000000000000000000000000000000000..2ffc415eac297e3ae8fc9e2f4870dd817e3d594b --- /dev/null +++ b/src/plugins/api/api-core/models/ResolutionProposalResponse.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { AnnotationCollection } from './AnnotationCollection'; +import type { FlattenedAnnotationSchemeLabel } from './FlattenedAnnotationSchemeLabel'; + +export type ResolutionProposalResponse = { + collection: AnnotationCollection; + proposal: Record<string, Array<Array<any>>>; + scheme_flat: Array<FlattenedAnnotationSchemeLabel>; +}; + diff --git a/src/plugins/api/api-core/models/SavedResolutionResponse.ts b/src/plugins/api/api-core/models/SavedResolutionResponse.ts new file mode 100644 index 0000000000000000000000000000000000000000..3c68457e2dfe973a01b98f927ecfdb74f12c222d --- /dev/null +++ b/src/plugins/api/api-core/models/SavedResolutionResponse.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { BotMetaResolve } from './BotMetaResolve'; + +export type SavedResolutionResponse = { + name: string; + meta: BotMetaResolve; + saved: Record<string, Array<Array<any>>>; +}; + diff --git a/src/plugins/api/api-core/models/TwitterItemModel.ts b/src/plugins/api/api-core/models/TwitterItemModel.ts index 80fa24ea8883927488200c73845f349d4a7ff939..17e1f8f3cfede8bfd8aadfe118613ed6ea195766 100644 --- a/src/plugins/api/api-core/models/TwitterItemModel.ts +++ b/src/plugins/api/api-core/models/TwitterItemModel.ts @@ -5,6 +5,7 @@ import type { Cashtag } from './Cashtag'; import type { ContextAnnotation } from './ContextAnnotation'; import type { Hashtag } from './Hashtag'; +import type { ItemType } from './ItemType'; import type { Mention } from './Mention'; import type { ReferencedTweet } from './ReferencedTweet'; import type { TwitterUserModel } from './TwitterUserModel'; @@ -18,9 +19,11 @@ import type { URL } from './URL'; */ export type TwitterItemModel = { item_id?: string; + project_id?: string; + type?: ItemType; + text: string; twitter_id?: string; twitter_author_id?: string; - status: string; created_at: string; language?: string; conversation_id?: string; diff --git a/src/plugins/api/api-core/schemas/$AcademicItemModel.ts b/src/plugins/api/api-core/schemas/$AcademicItemModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..fa4102b7feee744e1fd47da250b77d3ac79e6584 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$AcademicItemModel.ts @@ -0,0 +1,33 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $AcademicItemModel = { + description: `Corresponds to db.schema.items.academic.AcademicItem`, + properties: { + item_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + project_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + type: { + type: 'ItemType', + }, + text: { + type: 'string', + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$AnnotationCollection.ts b/src/plugins/api/api-core/schemas/$AnnotationCollection.ts new file mode 100644 index 0000000000000000000000000000000000000000..a155b92731cc669e7aa629ede1fd7f9bc08ae04f --- /dev/null +++ b/src/plugins/api/api-core/schemas/$AnnotationCollection.ts @@ -0,0 +1,42 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $AnnotationCollection = { + properties: { + scheme_id: { + type: 'string', + isRequired: true, + }, + labels: { + type: 'array', + contains: { + type: 'array', + contains: { + type: 'Label', + }, + }, + isRequired: true, + }, + annotations: { + type: 'dictionary', + contains: { + type: 'array', + contains: { + type: 'array', + contains: { + properties: { + }, + }, + }, + }, + isRequired: true, + }, + annotators: { + type: 'array', + contains: { + type: 'UserModel', + }, + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$AnnotationCollectionDB.ts b/src/plugins/api/api-core/schemas/$AnnotationCollectionDB.ts new file mode 100644 index 0000000000000000000000000000000000000000..973be1853db0587874672b5ca05b3800ff62f72a --- /dev/null +++ b/src/plugins/api/api-core/schemas/$AnnotationCollectionDB.ts @@ -0,0 +1,42 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $AnnotationCollectionDB = { + properties: { + scheme_id: { + type: 'string', + isRequired: true, + }, + labels: { + type: 'array', + contains: { + type: 'array', + contains: { + type: 'Label', + }, + }, + isRequired: true, + }, + annotations: { + type: 'dictionary', + contains: { + type: 'array', + contains: { + type: 'array', + contains: { + properties: { + }, + }, + }, + }, + isRequired: true, + }, + annotators: { + type: 'array', + contains: { + type: 'string', + }, + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$AnnotationFilters.ts b/src/plugins/api/api-core/schemas/$AnnotationFilters.ts new file mode 100644 index 0000000000000000000000000000000000000000..35ac5cf06d12f77814678736f586731a6fdd2550 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$AnnotationFilters.ts @@ -0,0 +1,66 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $AnnotationFilters = { + description: `Filter rules for fetching all annotations that match these conditions + It is up to the user of this function to make sure to provide sensible filters! + All filters are conjunctive (connected with "AND"); if None, they are not included + + There are no "exclude" filters by design. If needed, they should be simulated in the interface. + + :param scheme_id: if not None: annotation has to be part of this annotation scheme + :param scope_id: if not None: annotation has to be part of this assignment scope + :param user_id: if not None: annotation has to be by this user + :param key: if not None: annotation has to be for this AnnotationSchemeLabel.key (or list/tuple of keys) + :param repeat: if not None: annotation has to be primary/secondary/...`, + properties: { + scheme_id: { + type: 'string', + isRequired: true, + }, + scope_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'array', + contains: { + type: 'string', + }, + }], + }, + user_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'array', + contains: { + type: 'string', + }, + }], + }, + key: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'array', + contains: { + type: 'string', + }, + }], + }, + repeat: { + type: 'any-of', + contains: [{ + type: 'number', + }, { + type: 'array', + contains: { + type: 'number', + }, + }], + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$AnnotationItem.ts b/src/plugins/api/api-core/schemas/$AnnotationItem.ts index 8171ae732c98f3c79e6095b07472c3c5d39d06d5..952e886f50fe7cf637f7f313b82a24213cf072d8 100644 --- a/src/plugins/api/api-core/schemas/$AnnotationItem.ts +++ b/src/plugins/api/api-core/schemas/$AnnotationItem.ts @@ -18,9 +18,11 @@ export const $AnnotationItem = { item: { type: 'any-of', contains: [{ - type: 'ItemModel', + type: 'GenericItemModel', }, { type: 'TwitterItemModel', + }, { + type: 'AcademicItemModel', }], isRequired: true, }, diff --git a/src/plugins/api/api-core/schemas/$AnnotationModel.ts b/src/plugins/api/api-core/schemas/$AnnotationModel.ts index 8a5cc3992337fcc9ca8ab951498ceaf235f280a6..97e55a3242a1a3b3cc2e0b3b0ad893fa5acd9842 100644 --- a/src/plugins/api/api-core/schemas/$AnnotationModel.ts +++ b/src/plugins/api/api-core/schemas/$AnnotationModel.ts @@ -107,6 +107,12 @@ export const $AnnotationModel = { value_str: { type: 'string', }, + multi_int: { + type: 'array', + contains: { + type: 'number', + }, + }, text_offset_start: { type: 'number', }, diff --git a/src/plugins/api/api-core/schemas/$AnnotationSchemeLabelChoiceFlat.ts b/src/plugins/api/api-core/schemas/$AnnotationSchemeLabelChoiceFlat.ts new file mode 100644 index 0000000000000000000000000000000000000000..ee50861b66c8fbcff0f40063e0266c959ca29181 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$AnnotationSchemeLabelChoiceFlat.ts @@ -0,0 +1,18 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $AnnotationSchemeLabelChoiceFlat = { + properties: { + name: { + type: 'string', + isRequired: true, + }, + hint: { + type: 'string', + }, + value: { + type: 'number', + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$AnnotationSchemeModelFlat.ts b/src/plugins/api/api-core/schemas/$AnnotationSchemeModelFlat.ts new file mode 100644 index 0000000000000000000000000000000000000000..4a98b0961bdbb9803a568bb1bbd9fabca966ed4b --- /dev/null +++ b/src/plugins/api/api-core/schemas/$AnnotationSchemeModelFlat.ts @@ -0,0 +1,40 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $AnnotationSchemeModelFlat = { + description: `Same as AnnotationSchemeModel but with flattened structure.`, + properties: { + annotation_scheme_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + project_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + name: { + type: 'string', + isRequired: true, + }, + description: { + type: 'string', + }, + labels: { + type: 'array', + contains: { + type: 'FlattenedAnnotationSchemeLabel', + }, + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$BotAnnotationMetaDataBaseModel.ts b/src/plugins/api/api-core/schemas/$BotAnnotationMetaDataBaseModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..f1aab60ea639e321162970d232d4c417a1cd0779 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$BotAnnotationMetaDataBaseModel.ts @@ -0,0 +1,60 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $BotAnnotationMetaDataBaseModel = { + properties: { + bot_annotation_metadata_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + name: { + type: 'string', + isRequired: true, + }, + kind: { + type: 'BotKind', + isRequired: true, + }, + project_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + isRequired: true, + }, + time_created: { + type: 'string', + format: 'date-time', + }, + time_updated: { + type: 'string', + format: 'date-time', + }, + annotation_scope_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + annotation_scheme_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$BotAnnotationModel.ts b/src/plugins/api/api-core/schemas/$BotAnnotationModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..b727ba86922be6afe98582c62837cc90a87c69a1 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$BotAnnotationModel.ts @@ -0,0 +1,79 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $BotAnnotationModel = { + properties: { + bot_annotation_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + bot_annotation_metadata_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + time_created: { + type: 'string', + format: 'date-time', + }, + time_updated: { + type: 'string', + format: 'date-time', + }, + item_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + isRequired: true, + }, + parent: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + key: { + type: 'string', + }, + repeat: { + type: 'number', + }, + value_bool: { + type: 'boolean', + }, + value_int: { + type: 'number', + }, + value_float: { + type: 'number', + }, + value_str: { + type: 'string', + }, + multi_int: { + type: 'array', + contains: { + type: 'number', + }, + }, + confidence: { + type: 'number', + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$ProjectType.ts b/src/plugins/api/api-core/schemas/$BotKind.ts similarity index 76% rename from src/plugins/api/api-core/schemas/$ProjectType.ts rename to src/plugins/api/api-core/schemas/$BotKind.ts index 361b06372a54b214f97c4373847d43e75f37d3df..7fa62d4baf51a5418198da907550bc2bf3661970 100644 --- a/src/plugins/api/api-core/schemas/$ProjectType.ts +++ b/src/plugins/api/api-core/schemas/$BotKind.ts @@ -1,6 +1,6 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export const $ProjectType = { +export const $BotKind = { type: 'Enum', } as const; diff --git a/src/plugins/api/api-core/schemas/$BotMetaResolve.ts b/src/plugins/api/api-core/schemas/$BotMetaResolve.ts new file mode 100644 index 0000000000000000000000000000000000000000..445f5d68bfe598cd17ac813062fd13d2474920f4 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$BotMetaResolve.ts @@ -0,0 +1,33 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $BotMetaResolve = { + properties: { + algorithm: { + type: 'Enum', + isRequired: true, + }, + filters: { + type: 'AnnotationFilters', + isRequired: true, + }, + ignore_hierarchy: { + type: 'boolean', + isRequired: true, + }, + ignore_repeat: { + type: 'boolean', + isRequired: true, + }, + trust: { + type: 'dictionary', + contains: { + type: 'number', + }, + }, + collection: { + type: 'AnnotationCollectionDB', + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$Event.ts b/src/plugins/api/api-core/schemas/$Event.ts index 511707a71cd12ad8231882ec382796b1ad46cfbf..66494354076daef1a12887b0e212f530670bf429 100644 --- a/src/plugins/api/api-core/schemas/$Event.ts +++ b/src/plugins/api/api-core/schemas/$Event.ts @@ -10,13 +10,13 @@ export const $Event = { payload: { type: 'any-of', contains: [{ + type: 'PipelineTaskStatusFailedEvent', + }, { type: 'PipelineTaskStatusChangedEvent', }, { type: 'PipelineTaskStatusCompletedEvent', }, { type: 'PipelineTaskStatusStartedEvent', - }, { - type: 'PipelineTaskStatusFailedEvent', }], isRequired: true, }, diff --git a/src/plugins/api/api-core/schemas/$FlattenedAnnotationSchemeLabel.ts b/src/plugins/api/api-core/schemas/$FlattenedAnnotationSchemeLabel.ts new file mode 100644 index 0000000000000000000000000000000000000000..a4a3b33a78c73867f0c6752c9093f457ba6ecd81 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$FlattenedAnnotationSchemeLabel.ts @@ -0,0 +1,46 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $FlattenedAnnotationSchemeLabel = { + properties: { + name: { + type: 'string', + isRequired: true, + }, + hint: { + type: 'string', + }, + key: { + type: 'string', + isRequired: true, + }, + required: { + type: 'boolean', + isRequired: true, + }, + max_repeat: { + type: 'number', + isRequired: true, + }, + implicit_max_repeat: { + type: 'number', + isRequired: true, + }, + kind: { + type: 'Enum', + isRequired: true, + }, + choices: { + type: 'array', + contains: { + type: 'AnnotationSchemeLabelChoiceFlat', + }, + }, + parent_label: { + type: 'string', + }, + parent_choice: { + type: 'number', + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$ItemModel.ts b/src/plugins/api/api-core/schemas/$GenericItemModel.ts similarity index 56% rename from src/plugins/api/api-core/schemas/$ItemModel.ts rename to src/plugins/api/api-core/schemas/$GenericItemModel.ts index d4dc26d3608da77ab1dd955e27eb0a5474679a42..ed5549973d21b34ee8e21efd44dd7dd878896a37 100644 --- a/src/plugins/api/api-core/schemas/$ItemModel.ts +++ b/src/plugins/api/api-core/schemas/$GenericItemModel.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export const $ItemModel = { - description: `Corresponds to db.models.items.Item`, +export const $GenericItemModel = { + description: `Corresponds to db.models.items.generic.GenericItem`, properties: { item_id: { type: 'any-of', @@ -13,6 +13,18 @@ export const $ItemModel = { format: 'uuid', }], }, + project_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + type: { + type: 'ItemType', + }, text: { type: 'string', isRequired: true, diff --git a/src/plugins/api/api-core/schemas/$GroupedAnnotations.ts b/src/plugins/api/api-core/schemas/$GroupedAnnotations.ts new file mode 100644 index 0000000000000000000000000000000000000000..6ac88a3c25edc26f9303333f6d137d970811942c --- /dev/null +++ b/src/plugins/api/api-core/schemas/$GroupedAnnotations.ts @@ -0,0 +1,21 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $GroupedAnnotations = { + properties: { + path: { + type: 'array', + contains: { + type: 'Label', + }, + isRequired: true, + }, + annotations: { + type: 'array', + contains: { + type: 'AnnotationModel', + }, + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$GroupedBotAnnotation.ts b/src/plugins/api/api-core/schemas/$GroupedBotAnnotation.ts new file mode 100644 index 0000000000000000000000000000000000000000..baab78eb68e5c2ac0bc1a8bdc10a8329ea131088 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$GroupedBotAnnotation.ts @@ -0,0 +1,18 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $GroupedBotAnnotation = { + properties: { + path: { + type: 'array', + contains: { + type: 'Label', + }, + isRequired: true, + }, + annotation: { + type: 'BotAnnotationModel', + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$ItemType.ts b/src/plugins/api/api-core/schemas/$ItemType.ts new file mode 100644 index 0000000000000000000000000000000000000000..91b58a8378b7aed40561ee68473cc6c679028ebc --- /dev/null +++ b/src/plugins/api/api-core/schemas/$ItemType.ts @@ -0,0 +1,6 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $ItemType = { + type: 'Enum', +} as const; diff --git a/src/plugins/api/api-core/schemas/$Label.ts b/src/plugins/api/api-core/schemas/$Label.ts new file mode 100644 index 0000000000000000000000000000000000000000..a57be1f3601afecc5ad2522cc3e2d36176c795a7 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$Label.ts @@ -0,0 +1,19 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $Label = { + description: `Convenience type (corresponding to internal type in db annotation_label). + For Annotation or BotAnnotation, this is the combination of their respective key, repeat value. + + Mainly used during resolving annotations.`, + properties: { + key: { + type: 'string', + isRequired: true, + }, + repeat: { + type: 'number', + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$ProjectModel.ts b/src/plugins/api/api-core/schemas/$ProjectModel.ts index cb1d201d4159fca498b3f2e486aea5ca91589b45..ac92efa150a78f1a14e0c934a8755740a4c454fb 100644 --- a/src/plugins/api/api-core/schemas/$ProjectModel.ts +++ b/src/plugins/api/api-core/schemas/$ProjectModel.ts @@ -30,7 +30,7 @@ export const $ProjectModel = { contains: [{ type: 'Enum', }, { - type: 'ProjectType', + type: 'ItemType', }], isRequired: true, }, diff --git a/src/plugins/api/api-core/schemas/$ResolutionPayload.ts b/src/plugins/api/api-core/schemas/$ResolutionPayload.ts new file mode 100644 index 0000000000000000000000000000000000000000..164a5a52f8c56441c8f4eec7db879564bf439eae --- /dev/null +++ b/src/plugins/api/api-core/schemas/$ResolutionPayload.ts @@ -0,0 +1,38 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $ResolutionPayload = { + properties: { + name: { + type: 'string', + isRequired: true, + }, + strategy: { + type: 'Enum', + isRequired: true, + }, + filters: { + type: 'AnnotationFilters', + isRequired: true, + }, + ignore_order: { + type: 'boolean', + isRequired: true, + }, + ignore_hierarchy: { + type: 'boolean', + isRequired: true, + }, + collection: { + type: 'AnnotationCollectionDB', + isRequired: true, + }, + bot_annotations: { + type: 'array', + contains: { + type: 'BotAnnotationModel', + }, + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$ResolutionProposalResponse.ts b/src/plugins/api/api-core/schemas/$ResolutionProposalResponse.ts new file mode 100644 index 0000000000000000000000000000000000000000..98cb12ed663ef504576dc506435c4adcd87365a4 --- /dev/null +++ b/src/plugins/api/api-core/schemas/$ResolutionProposalResponse.ts @@ -0,0 +1,32 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $ResolutionProposalResponse = { + properties: { + collection: { + type: 'AnnotationCollection', + isRequired: true, + }, + proposal: { + type: 'dictionary', + contains: { + type: 'array', + contains: { + type: 'array', + contains: { + properties: { + }, + }, + }, + }, + isRequired: true, + }, + scheme_flat: { + type: 'array', + contains: { + type: 'FlattenedAnnotationSchemeLabel', + }, + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$SavedResolutionResponse.ts b/src/plugins/api/api-core/schemas/$SavedResolutionResponse.ts new file mode 100644 index 0000000000000000000000000000000000000000..8ad91ad4399edad611a773b8d2c438de21bc5c5c --- /dev/null +++ b/src/plugins/api/api-core/schemas/$SavedResolutionResponse.ts @@ -0,0 +1,29 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $SavedResolutionResponse = { + properties: { + name: { + type: 'string', + isRequired: true, + }, + meta: { + type: 'BotMetaResolve', + isRequired: true, + }, + saved: { + type: 'dictionary', + contains: { + type: 'array', + contains: { + type: 'array', + contains: { + properties: { + }, + }, + }, + }, + isRequired: true, + }, + }, +} as const; diff --git a/src/plugins/api/api-core/schemas/$TwitterItemModel.ts b/src/plugins/api/api-core/schemas/$TwitterItemModel.ts index 8170ad18220421ca3dd515027330873af6551a03..b3aa32329ab843d5ff0e856ee324c3e4a73ca964 100644 --- a/src/plugins/api/api-core/schemas/$TwitterItemModel.ts +++ b/src/plugins/api/api-core/schemas/$TwitterItemModel.ts @@ -16,15 +16,27 @@ export const $TwitterItemModel = { format: 'uuid', }], }, - twitter_id: { + project_id: { + type: 'any-of', + contains: [{ + type: 'string', + }, { + type: 'string', + format: 'uuid', + }], + }, + type: { + type: 'ItemType', + }, + text: { type: 'string', + isRequired: true, }, - twitter_author_id: { + twitter_id: { type: 'string', }, - status: { + twitter_author_id: { type: 'string', - isRequired: true, }, created_at: { type: 'string', diff --git a/src/plugins/api/api-core/services/AnnotationsService.ts b/src/plugins/api/api-core/services/AnnotationsService.ts index 0842e5d26e4ff751d4870e6406c59550027f0765..b4a9b6a50714813b7da11870ef933c3f6fbdf4e3 100644 --- a/src/plugins/api/api-core/services/AnnotationsService.ts +++ b/src/plugins/api/api-core/services/AnnotationsService.ts @@ -4,12 +4,19 @@ import type { AnnotatedItem } from '../models/AnnotatedItem'; import type { AnnotationItem } from '../models/AnnotationItem'; import type { AnnotationSchemeModel } from '../models/AnnotationSchemeModel'; +import type { AnnotationSchemeModelFlat } from '../models/AnnotationSchemeModelFlat'; import type { AssignmentCounts } from '../models/AssignmentCounts'; import type { AssignmentModel } from '../models/AssignmentModel'; import type { AssignmentScopeModel } from '../models/AssignmentScopeModel'; import type { AssignmentStatus } from '../models/AssignmentStatus'; +import type { BotAnnotationMetaDataBaseModel } from '../models/BotAnnotationMetaDataBaseModel'; +import type { BotAnnotationModel } from '../models/BotAnnotationModel'; import type { ItemWithCount } from '../models/ItemWithCount'; import type { MakeAssignmentsRequestModel } from '../models/MakeAssignmentsRequestModel'; +import type { ResolutionPayload } from '../models/ResolutionPayload'; +import type { ResolutionProposalResponse } from '../models/ResolutionProposalResponse'; +import type { SavedResolutionResponse } from '../models/SavedResolutionResponse'; +import type { UserModel } from '../models/UserModel'; import type { UserProjectAssignmentScope } from '../models/UserProjectAssignmentScope'; import type { CancelablePromise } from '@/plugins/api/core/CancelablePromise'; @@ -26,21 +33,33 @@ export class AnnotationsService { * This endpoint returns the detailed definition of an annotation scheme. * * :param annotation_scheme_id: database id of the annotation scheme. + * :param flat: True to get the flattened scheme + * :param permissions: * :return: a single annotation scheme - * @returns AnnotationSchemeModel Successful Response + * @returns any Successful Response * @throws ApiError */ public getSchemeDefinitionApiAnnotationsSchemesDefinitionAnnotationSchemeIdGet({ annotationSchemeId, + xProjectId, + flat = false, }: { annotationSchemeId: string, - }, options?: Partial<ApiRequestOptions>): CancelablePromise<AnnotationSchemeModel> { + xProjectId: string, + flat?: boolean, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<(AnnotationSchemeModelFlat | AnnotationSchemeModel)> { return this.httpRequest.request({ method: 'GET', url: '/api/annotations/schemes/definition/{annotation_scheme_id}', path: { 'annotation_scheme_id': annotationSchemeId, }, + headers: { + 'x-project-id': xProjectId, + }, + query: { + 'flat': flat, + }, errors: { 422: `Validation Error`, }, @@ -108,14 +127,17 @@ export class AnnotationsService { * This endpoint returns the detailed definitions of all annotation schemes associated with a project. * * :param project_id: database id of the project + * :param permissions: * :return: list of annotation schemes * @returns AnnotationSchemeModel Successful Response * @throws ApiError */ public getSchemeDefinitionsForProjectApiAnnotationsSchemesListProjectIdGet({ projectId, + xProjectId, }: { projectId: string, + xProjectId: string, }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<AnnotationSchemeModel>> { return this.httpRequest.request({ method: 'GET', @@ -123,6 +145,9 @@ export class AnnotationsService { path: { 'project_id': projectId, }, + headers: { + 'x-project-id': xProjectId, + }, errors: { 422: `Validation Error`, }, @@ -540,4 +565,266 @@ export class AnnotationsService { }); } + /** + * Get Assignment Scopes For Scheme + * @returns AssignmentScopeModel Successful Response + * @throws ApiError + */ + public getAssignmentScopesForSchemeApiAnnotationsConfigScopesSchemeIdGet({ + schemeId, + xProjectId, + }: { + schemeId: string, + xProjectId: string, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<AssignmentScopeModel>> { + return this.httpRequest.request({ + method: 'GET', + url: '/api/annotations/config/scopes/{scheme_id}', + path: { + 'scheme_id': schemeId, + }, + headers: { + 'x-project-id': xProjectId, + }, + errors: { + 422: `Validation Error`, + }, + ...options, + }); + } + + /** + * Get Annotators For Scheme + * @returns UserModel Successful Response + * @throws ApiError + */ + public getAnnotatorsForSchemeApiAnnotationsConfigAnnotatorsSchemeIdGet({ + schemeId, + xProjectId, + }: { + schemeId: string, + xProjectId: string, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<UserModel>> { + return this.httpRequest.request({ + method: 'GET', + url: '/api/annotations/config/annotators/{scheme_id}', + path: { + 'scheme_id': schemeId, + }, + headers: { + 'x-project-id': xProjectId, + }, + errors: { + 422: `Validation Error`, + }, + ...options, + }); + } + + /** + * Get Resolved Annotations + * Get all annotations that match the filters (e.g. all annotations made by users in scope with :scope_id). + * Annotations are returned in a 3D matrix: + * rows (dict entries): items (key: item_id) + * columns (list index of dict entry): Label (key in scheme + repeat); index map in matrix.keys + * cells: list of annotations by each user for item/Label combination + * + * :param strategy + * :param scheme_id: + * :param scope_id: + * :param user_id: + * :param key: + * :param repeat: + * :param permissions: + * :param ignore_order: + * :param ignore_hierarchy: + * :return: + * @returns ResolutionProposalResponse Successful Response + * @throws ApiError + */ + public getResolvedAnnotationsApiAnnotationsConfigResolveGet({ + strategy, + schemeId, + xProjectId, + scopeId, + userId, + key, + repeat, + ignoreOrder = false, + ignoreHierarchy = false, + }: { + strategy: 'majority' | 'first' | 'last' | 'trust', + schemeId: string, + xProjectId: string, + scopeId?: Array<string>, + userId?: Array<string>, + key?: Array<string>, + repeat?: Array<number>, + ignoreOrder?: boolean, + ignoreHierarchy?: boolean, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<ResolutionProposalResponse> { + return this.httpRequest.request({ + method: 'GET', + url: '/api/annotations/config/resolve/', + headers: { + 'x-project-id': xProjectId, + }, + query: { + 'strategy': strategy, + 'scheme_id': schemeId, + 'scope_id': scopeId, + 'user_id': userId, + 'key': key, + 'repeat': repeat, + 'ignore_order': ignoreOrder, + 'ignore_hierarchy': ignoreHierarchy, + }, + errors: { + 422: `Validation Error`, + }, + ...options, + }); + } + + /** + * Save Resolved Annotations + * @returns string Successful Response + * @throws ApiError + */ + public saveResolvedAnnotationsApiAnnotationsConfigResolvePut({ + xProjectId, + requestBody, + }: { + xProjectId: string, + requestBody: ResolutionPayload, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<string> { + return this.httpRequest.request({ + method: 'PUT', + url: '/api/annotations/config/resolve/', + headers: { + 'x-project-id': xProjectId, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + ...options, + }); + } + + /** + * Update Resolved Annotations + * @returns any Successful Response + * @throws ApiError + */ + public updateResolvedAnnotationsApiAnnotationsConfigResolveUpdatePut({ + botAnnotationMetadataId, + name, + xProjectId, + requestBody, + }: { + botAnnotationMetadataId: string, + name: string, + xProjectId: string, + requestBody: Array<BotAnnotationModel>, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<any> { + return this.httpRequest.request({ + method: 'PUT', + url: '/api/annotations/config/resolve/update', + headers: { + 'x-project-id': xProjectId, + }, + query: { + 'bot_annotation_metadata_id': botAnnotationMetadataId, + 'name': name, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + ...options, + }); + } + + /** + * List Saved Resolved Annotations + * @returns BotAnnotationMetaDataBaseModel Successful Response + * @throws ApiError + */ + public listSavedResolvedAnnotationsApiAnnotationsConfigResolvedListGet({ + xProjectId, + }: { + xProjectId: string, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<BotAnnotationMetaDataBaseModel>> { + return this.httpRequest.request({ + method: 'GET', + url: '/api/annotations/config/resolved-list/', + headers: { + 'x-project-id': xProjectId, + }, + errors: { + 422: `Validation Error`, + }, + ...options, + }); + } + + /** + * Get Saved Resolved Annotations + * @returns SavedResolutionResponse Successful Response + * @throws ApiError + */ + public getSavedResolvedAnnotationsApiAnnotationsConfigResolvedBotAnnotationMetaIdGet({ + botAnnotationMetadataId, + xProjectId, + }: { + botAnnotationMetadataId: string, + xProjectId: string, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<SavedResolutionResponse> { + return this.httpRequest.request({ + method: 'GET', + url: '/api/annotations/config/resolved/:bot_annotation_meta_id', + headers: { + 'x-project-id': xProjectId, + }, + query: { + 'bot_annotation_metadata_id': botAnnotationMetadataId, + }, + errors: { + 422: `Validation Error`, + }, + ...options, + }); + } + + /** + * Delete Saved Resolved Annotations + * @returns any Successful Response + * @throws ApiError + */ + public deleteSavedResolvedAnnotationsApiAnnotationsConfigResolvedBotAnnotationMetaIdDelete({ + botAnnotationMetadataId, + xProjectId, + }: { + botAnnotationMetadataId: string, + xProjectId: string, + }, options?: Partial<ApiRequestOptions>): CancelablePromise<any> { + return this.httpRequest.request({ + method: 'DELETE', + url: '/api/annotations/config/resolved/:bot_annotation_meta_id', + headers: { + 'x-project-id': xProjectId, + }, + query: { + 'bot_annotation_metadata_id': botAnnotationMetadataId, + }, + errors: { + 422: `Validation Error`, + }, + ...options, + }); + } + } diff --git a/src/plugins/api/api-core/services/DefaultService.ts b/src/plugins/api/api-core/services/DefaultService.ts index 4f40ff749a087588478d82a6f6e672f665baaa64..95e441b1c4b8573bd7c525fbcc231807eb7d202c 100644 --- a/src/plugins/api/api-core/services/DefaultService.ts +++ b/src/plugins/api/api-core/services/DefaultService.ts @@ -85,17 +85,4 @@ export class DefaultService { }); } - /** - * Test - * @returns any Successful Response - * @throws ApiError - */ - public testApiPingTestGet(options?: Partial<ApiRequestOptions>): CancelablePromise<any> { - return this.httpRequest.request({ - method: 'GET', - url: '/api/ping/test', - ...options, - }); - } - } diff --git a/src/plugins/api/api-core/services/ProjectService.ts b/src/plugins/api/api-core/services/ProjectService.ts index 042d9185bef1983d86fa075eac35ae6cad09ee06..054cd0d2b44ba0365ff1b8e32619803bca08f3e4 100644 --- a/src/plugins/api/api-core/services/ProjectService.ts +++ b/src/plugins/api/api-core/services/ProjectService.ts @@ -1,7 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ItemModel } from '../models/ItemModel'; +import type { AcademicItemModel } from '../models/AcademicItemModel'; +import type { GenericItemModel } from '../models/GenericItemModel'; import type { ProjectModel } from '../models/ProjectModel'; import type { ProjectPermissionsModel } from '../models/ProjectPermissionsModel'; import type { TwitterItemModel } from '../models/TwitterItemModel'; @@ -20,19 +21,14 @@ export class ProjectService { * @returns ProjectModel Successful Response * @throws ApiError */ - public getProjectApiProjectProjectIdInfoGet({ - projectId, + public getProjectApiProjectInfoGet({ xProjectId, }: { - projectId: string, xProjectId: string, }, options?: Partial<ApiRequestOptions>): CancelablePromise<ProjectModel> { return this.httpRequest.request({ method: 'GET', - url: '/api/project/{project_id}/info/', - path: { - 'project_id': projectId, - }, + url: '/api/project/info', headers: { 'x-project-id': xProjectId, }, @@ -48,14 +44,14 @@ export class ProjectService { * @returns ProjectPermissionsModel Successful Response * @throws ApiError */ - public getProjectPermissionsCurrentUserApiProjectProjectIdPermissionsMeGet({ + public getProjectPermissionsCurrentUserApiProjectPermissionsMeGet({ xProjectId, }: { xProjectId: string, }, options?: Partial<ApiRequestOptions>): CancelablePromise<ProjectPermissionsModel> { return this.httpRequest.request({ method: 'GET', - url: '/api/project/{project_id}/permissions/me', + url: '/api/project/permissions/me', headers: { 'x-project-id': xProjectId, }, @@ -71,7 +67,7 @@ export class ProjectService { * @returns ProjectPermissionsModel Successful Response * @throws ApiError */ - public getAllProjectPermissionsApiProjectProjectIdPermissionsListGet({ + public getAllProjectPermissionsApiProjectPermissionsListProjectIdGet({ projectId, xProjectId, }: { @@ -80,7 +76,7 @@ export class ProjectService { }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<ProjectPermissionsModel>> { return this.httpRequest.request({ method: 'GET', - url: '/api/project/{project_id}/permissions/list', + url: '/api/project/permissions/list/{project_id}', path: { 'project_id': projectId, }, @@ -99,7 +95,7 @@ export class ProjectService { * @returns ProjectPermissionsModel Successful Response * @throws ApiError */ - public getProjectPermissionsByIdApiProjectProjectIdPermissionsProjectPermissionIdGet({ + public getProjectPermissionsByIdApiProjectPermissionsProjectPermissionIdGet({ projectPermissionId, xProjectId, }: { @@ -108,7 +104,7 @@ export class ProjectService { }, options?: Partial<ApiRequestOptions>): CancelablePromise<ProjectPermissionsModel> { return this.httpRequest.request({ method: 'GET', - url: '/api/project/{project_id}/permissions/{project_permission_id}', + url: '/api/project/permissions/{project_permission_id}', path: { 'project_permission_id': projectPermissionId, }, @@ -127,20 +123,17 @@ export class ProjectService { * @returns any Successful Response * @throws ApiError */ - public listProjectDataApiProjectProjectIdItemsItemTypeListGet({ - projectId, + public listProjectDataApiProjectItemsItemTypeListGet({ itemType, xProjectId, }: { - projectId: string, - itemType: 'basic' | 'twitter' | 'academic' | 'patents', + itemType: 'generic' | 'twitter' | 'academic' | 'patents', xProjectId: string, - }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<(ItemModel | TwitterItemModel)>> { + }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<(GenericItemModel | TwitterItemModel | AcademicItemModel)>> { return this.httpRequest.request({ method: 'GET', - url: '/api/project/{project_id}/items/{item_type}/list', + url: '/api/project/items/{item_type}/list', path: { - 'project_id': projectId, 'item_type': itemType, }, headers: { @@ -158,24 +151,21 @@ export class ProjectService { * @returns any Successful Response * @throws ApiError */ - public listProjectDataPagedApiProjectProjectIdItemsItemTypeListPagePageSizeGet({ - projectId, + public listProjectDataPagedApiProjectItemsItemTypeListPagePageSizeGet({ itemType, page, pageSize, xProjectId, }: { - projectId: string, - itemType: 'basic' | 'twitter' | 'academic' | 'patents', + itemType: 'generic' | 'twitter' | 'academic' | 'patents', page: number, pageSize: number, xProjectId: string, - }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<(ItemModel | TwitterItemModel)>> { + }, options?: Partial<ApiRequestOptions>): CancelablePromise<Array<(GenericItemModel | TwitterItemModel | AcademicItemModel)>> { return this.httpRequest.request({ method: 'GET', - url: '/api/project/{project_id}/items/{item_type}/list/{page}/{page_size}', + url: '/api/project/items/{item_type}/list/{page}/{page_size}', path: { - 'project_id': projectId, 'item_type': itemType, 'page': page, 'page_size': pageSize, @@ -195,25 +185,27 @@ export class ProjectService { * @returns any Successful Response * @throws ApiError */ - public getDetailForItemApiProjectProjectIdItemsItemTypeDetailItemIdGet({ + public getDetailForItemApiProjectItemsDetailItemIdGet({ itemId, - itemType, xProjectId, + itemType, }: { itemId: string, - itemType: 'basic' | 'twitter' | 'academic' | 'patents', xProjectId: string, - }, options?: Partial<ApiRequestOptions>): CancelablePromise<(ItemModel | TwitterItemModel)> { + itemType?: 'generic' | 'twitter' | 'academic' | 'patents', + }, options?: Partial<ApiRequestOptions>): CancelablePromise<(GenericItemModel | TwitterItemModel | AcademicItemModel)> { return this.httpRequest.request({ method: 'GET', - url: '/api/project/{project_id}/items/{item_type}/detail/{item_id}', + url: '/api/project/items/detail/{item_id}', path: { 'item_id': itemId, - 'item_type': itemType, }, headers: { 'x-project-id': xProjectId, }, + query: { + 'item_type': itemType, + }, errors: { 422: `Validation Error`, }, @@ -226,19 +218,14 @@ export class ProjectService { * @returns number Successful Response * @throws ApiError */ - public countProjectItemsApiProjectProjectIdItemsCountGet({ - projectId, + public countProjectItemsApiProjectItemsCountGet({ xProjectId, }: { - projectId: string, xProjectId: string, }, options?: Partial<ApiRequestOptions>): CancelablePromise<number> { return this.httpRequest.request({ method: 'GET', - url: '/api/project/{project_id}/items/count', - path: { - 'project_id': projectId, - }, + url: '/api/project/items/count', headers: { 'x-project-id': xProjectId, }, @@ -254,24 +241,24 @@ export class ProjectService { * @returns any Successful Response * @throws ApiError */ - public addTweetApiProjectProjectIdItemsTwitterAddPost({ - projectId, + public addTweetApiProjectItemsTwitterAddPost({ xProjectId, requestBody, + importId, }: { - projectId: string, xProjectId: string, requestBody: TwitterItemModel, + importId?: string, }, options?: Partial<ApiRequestOptions>): CancelablePromise<any> { return this.httpRequest.request({ method: 'POST', - url: '/api/project/{project_id}/items/twitter/add', - path: { - 'project_id': projectId, - }, + url: '/api/project/items/twitter/add', headers: { 'x-project-id': xProjectId, }, + query: { + 'import_id': importId, + }, body: requestBody, mediaType: 'application/json', errors: { diff --git a/src/plugins/events/EventHandlers/project.ts b/src/plugins/events/EventHandlers/project.ts index b3993efe67afab1778092a8172a4f5ffc2021992..ff5f59ce99783d3b776d615192bb23102fcb4b27 100644 --- a/src/plugins/events/EventHandlers/project.ts +++ b/src/plugins/events/EventHandlers/project.ts @@ -14,8 +14,8 @@ export default () => { currentProjectStore.projectId = projectId; Promise .allSettled([ - API.core.project.getProjectApiProjectProjectIdInfoGet({ xProjectId: projectId, projectId }), - API.core.project.getProjectPermissionsCurrentUserApiProjectProjectIdPermissionsMeGet({ xProjectId: projectId }), + API.core.project.getProjectApiProjectInfoGet({ xProjectId: projectId }), + API.core.project.getProjectPermissionsCurrentUserApiProjectPermissionsMeGet({ xProjectId: projectId }), ]) .then((values) => { const [projectInfo, projectPermissions] = values; diff --git a/src/router/index.ts b/src/router/index.ts index 9529c099cfca9bb2bec482e189d7a2b75d847b0d..cb15a955b6782e6991e88a87c71773fbc14886e0 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -137,6 +137,29 @@ const routes: Array<RouteRecordRaw> = [ name: 'config-annotation-scheme-edit', component: () => import(/* webpackChunkName: "AnnotationConfigEditView" */ '../views/Annotations/AnnotationConfigs/AnnotationConfigEditView.vue'), }, + { + path: 'resolved/', + name: 'config-resolved-annotations-list', + component: () => import(/* webpackChunkName: "AnnotationConfigResolveView" */ '../views/Annotations/AnnotationConfigs/AnnotationConfigResolvedListView.vue'), + }, + { + path: 'resolve/:bot_annotation_metadata_id?', + name: 'config-annotation-resolve', + component: () => import(/* webpackChunkName: "AnnotationConfigResolveView" */ '../views/Annotations/AnnotationConfigs/AnnotationConfigResolveView.vue'), + }, + ], + }, + { + path: '/project/settings', + name: 'project-settings', + component: () => import(/* webpackChunkName: "ProjectSettingsContainer" */ '../views/Projects/ProjectSettingsContainer.vue'), + children: [ + { + path: '', + alias: ['', 'settings'], + name: 'project-settings-settings', + component: () => import(/* webpackChunkName: "ProjectSettingsView" */ '../views/Projects/ProjectSettingsView.vue'), + }, ], }, ]; @@ -147,7 +170,7 @@ const router = createRouter({ }); // eslint-disable-next-line @typescript-eslint/no-unused-vars -router.beforeEach(async (to, from) => { +router.beforeEach(async (to) => { // if user is not authenticated -> redirect to login page // prevent infinite redirects if user isn't logged in if (!currentUserStore.isLoggedIn && to.name !== 'login') { diff --git a/src/types/annotations.ts b/src/types/annotations.ts new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/types/colours.ts b/src/types/colours.ts new file mode 100644 index 0000000000000000000000000000000000000000..5f8d0585a0fe8e57be1c921ecc10f5e2f8106833 --- /dev/null +++ b/src/types/colours.ts @@ -0,0 +1,37 @@ +export const cmap20 = [ + '#e6194B', // # 0 + '#3cb44b', // # 1 + '#ffe119', // # 2 + '#4363d8', // # 3 + '#f58231', // # 4 + '#911eb4', // # 5 + '#42d4f4', // # 6 + '#f032e6', // # 7 + '#bfef45', // # 8 + '#fabed4', // # 9 + '#469990', // # 10 + '#dcbeff', // # 11 + '#9A6324', // # 12 + '#fffac8', // # 13 + '#800000', // # 14 + '#aaffc3', // # 15 + '#808000', // # 16 + '#ffd8b1', // # 17 + '#000075', // # 18 + '#a9a9a9', // # 19 + '#ffffff', // # 20 + '#000000', // # 21 +]; + +export const cmap10 = [ + '#4e79a7', // # 0 + '#f28e2c', // # 1 + '#e15759', // # 2 + '#76b7b2', // # 3 + '#59a14f', // # 4 + '#edc949', // # 5 + '#af7aa1', // # 6 + '#ff9da7', // # 7 + '#9c755f', // # 8 + '#bab0ab', // # 9 +]; diff --git a/src/views/Annotations/AnnotationConfigs/AnnotationConfigEditView.vue b/src/views/Annotations/AnnotationConfigs/AnnotationConfigEditView.vue index 57ae7f13a81ae716c2d663be6b0374837166217b..27565ec7cdc1a1a260ffd75e3a2a5d0243ecd48a 100644 --- a/src/views/Annotations/AnnotationConfigs/AnnotationConfigEditView.vue +++ b/src/views/Annotations/AnnotationConfigs/AnnotationConfigEditView.vue @@ -97,6 +97,8 @@ export default { if (!this.isNewScheme) { API.core.annotations.getSchemeDefinitionApiAnnotationsSchemesDefinitionAnnotationSchemeIdGet({ annotationSchemeId: this.annotationSchemeId, + xProjectId: currentProjectStore.projectId, + flat: false, }) .then((response) => { this.scheme = ref(response.data); diff --git a/src/views/Annotations/AnnotationConfigs/AnnotationConfigListView.vue b/src/views/Annotations/AnnotationConfigs/AnnotationConfigListView.vue index a11652a580bc330e4333ce4ce77671f824046302..4ee57d4cbc1c463001bd061909dc2209b7d5a2ff 100644 --- a/src/views/Annotations/AnnotationConfigs/AnnotationConfigListView.vue +++ b/src/views/Annotations/AnnotationConfigs/AnnotationConfigListView.vue @@ -103,6 +103,7 @@ export default { try { this.projectSchemes = (await API.core.annotations.getSchemeDefinitionsForProjectApiAnnotationsSchemesListProjectIdGet({ projectId: currentProjectStore.projectId, + xProjectId: currentProjectStore.projectId, })).data; this.projectScopes = (await API.core.annotations.getAssignmentScopesForProjectApiAnnotationsAnnotateScopesGet({ xProjectId: currentProjectStore.projectId, @@ -128,6 +129,7 @@ export default { const schemes = await API.core.annotations.getSchemeDefinitionsForProjectApiAnnotationsSchemesListProjectIdGet({ projectId: currentProjectStore.projectId, + xProjectId: currentProjectStore.projectId, }); this.projectSchemes = schemes.data; } catch (e) { diff --git a/src/views/Annotations/AnnotationConfigs/AnnotationConfigResolveView.vue b/src/views/Annotations/AnnotationConfigs/AnnotationConfigResolveView.vue new file mode 100644 index 0000000000000000000000000000000000000000..cd0a80f67f7f9300e9fbc6f23d5a436bb7be2b3c --- /dev/null +++ b/src/views/Annotations/AnnotationConfigs/AnnotationConfigResolveView.vue @@ -0,0 +1,668 @@ +<template> + <div class="text-start"> + <div class="row"> + <h1>Resolve Annotations</h1> + </div> + <div class="row mx-auto"> + <div class="accordion"> + <div class="accordion-item"> + <h2 class="accordion-header"> + <button + class="accordion-button" + type="button" + data-bs-toggle="collapse" + data-bs-target="#resolve-config" + aria-expanded="true" + aria-controls="resolve-config"> + Annotation Export Configuration + </button> + </h2> + <div + id="resolve-config" + class="accordion-collapse collapse show"> + <div class="accordion-body"> + <div class="row"> + <div class="col"> + <div class="mb-3"> + <div class="form-floating mb-3"> + <input type="text" class="form-control" id="resolve-name" v-model="name" placeholder="Name" /> + <label for="resolve-name">Descriptive name for this annotation export</label> + </div> + </div> + </div> + </div> + <div class="row gy-5"> + <div class="col border-end"> + <div class="mb-3"> + <label for="schema-selector" class="form-label">Annotation Scheme</label> + <select + :disabled="!isNew" + id="schema-selector" + class="form-select" + aria-label="Schema selector" + v-model="filters.scheme_id"> + <option :value="undefined" disabled>Please choose...</option> + <option + v-for="scheme in projectAnnotationSchemes" + :key="scheme.annotation_scheme_id" + :value="scheme.annotation_scheme_id"> + {{ scheme.name }} + </option> + </select> + </div> + <div v-if="schemeFlat.length > 0" class="mb-3 border-bottom"> + <div class="form-label">Scheme labels to resolve</div> + <ul class="list-unstyled ms-lg-2"> + <li v-for="label in schemeFlat" :key="label.key"> + <input + class="form-check-input me-1" + type="checkbox" + :id="`schema-label-selector-${label.key}`" + :value="label.key" + v-model="filters.key" + :disabled="!isNew" /> + <label + class="form-check-label" + :for="`schema-label-selector-${label.key}`"><strong>{{ label.key }}</strong> – {{ + label.name + }}</label> + </li> + </ul> + </div> + <div class="mb-3 border-bottom" v-if="filters.key.length > 0"> + <div class="form-label"> + Repeats to resolve + <ToolTip> + Allows you to select which annotations to resolve if annotations can have an order. + For example, whether to only resolve primary annotation of a kind (and ignore secondary,...) + annotations. + </ToolTip> + </div> + <div class="form-check form-check-inline" v-if="filters.key.length > 0"> + <input + class="form-check-input" + type="checkbox" + id="repeat-selector-1" + :value="1" + v-model="filters.repeat" + :disabled="!isNew"> + <label class="form-check-label" for="repeat-selector-1">1</label> + </div> + <div class="form-check form-check-inline"> + <input + class="form-check-input" + type="checkbox" + id="repeat-selector-2" + :value="2" + v-model="filters.repeat" + :disabled="!isNew"> + <label class="form-check-label" for="repeat-selector-2">2</label> + </div> + <div class="form-check form-check-inline"> + <input + class="form-check-input" + type="checkbox" + id="repeat-selector-3" + :value="3" + v-model="filters.repeat" + :disabled="!isNew"> + <label class="form-check-label" for="repeat-selector-3">3</label> + </div> + <div class="form-check form-check-inline"> + <input + class="form-check-input" + type="checkbox" + id="repeat-selector-4" + :value="4" + v-model="filters.repeat" + :disabled="!isNew"> + <label class="form-check-label" for="repeat-selector-4">4</label> + </div> + </div> + <div class="mb-3 border-bottom" v-if="filters.key.length > 0"> + <div class="form-check"> + <input + class="form-check-input" + type="checkbox" + v-model="ignoreHierarchy" + id="check-ignore-hierarchy" + :disabled="!isNew"> + <label class="form-check-label" for="check-ignore-hierarchy"> + Ignore scheme hierarchy + </label> + </div> + <div class="form-check"> + <input + class="form-check-input" + type="checkbox" + v-model="ignoreOrder" + id="check-ignore-order" + :disabled="!isNew"> + <label class="form-check-label" for="check-ignore-order"> + Ignore annotation order (<code>repeat</code>s) + </label> + </div> + </div> + </div> + <div class="col"> + <div v-if="(assignmentScopes || []).length > 0" class="mb-3 border-bottom"> + <div class="form-label">Source assignment scopes</div> + <ul class="list-unstyled ms-lg-2"> + <li v-for="scope in assignmentScopes" :key="scope.assignment_scope_id"> + <input + class="form-check-input me-1" + type="checkbox" + :id="`scope-selector-${scope.assignment_scope_id}`" + :value="scope.assignment_scope_id" + v-model="filters.scope_id" + :disabled="!isNew" /> + <label + class="form-check-label" + :for="`scope-selector-${scope.assignment_scope_id}`">{{ scope.name }}</label> + </li> + </ul> + </div> + <div v-if="(annotators || []).length > 0" class="mb-3 border-bottom"> + <div class="form-label">Annotator selector</div> + <ul class="list-unstyled ms-lg-2"> + <li v-for="user in annotators" :key="user.user_id"> + <input + class="form-check-input me-1" + type="checkbox" + :id="`annotator-selector-${user.user_id}`" + :value="user.user_id" + v-model="filters.user_id" + :disabled="!isNew" /> + <label + class="form-check-label" + :for="`annotator-selector-${user.user_id}`"> + <strong>{{ user.username }}</strong> – {{ user.full_name }} + </label> + </li> + </ul> + </div> + <div class="mb-3"> + <label for="algorithm-selector" class="form-label">Resolution algorithm</label> + <select + id="algorithm-selector" + class="form-select" + aria-label="Resolution algorithm" + v-model="algorithm" + :disabled="!isNew"> + <option value="majority">majority vote</option> + <option value="trust" disabled>weighted majority</option> + <option value="first" disabled>first annotation</option> + <option value="last" disabled>last annotation</option> + <option value="??" disabled>sorcery</option> + </select> + </div> + </div> + </div> + <div class="row"> + <div class="col text-end"> + <button class="btn btn-primary" type="button" disabled v-if="loadingProposals"> + <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" /> + Loading... + </button> + <button + class="btn btn-primary" + type="button" + v-else + @click="fetchProposal" + :disabled="!isConfigValid || !isNew"> + Load + </button> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <div class="row text-end" v-if="isTableReady"> + <div class="col"> + <button + @click="save" + type="button" + class="btn btn-success m-2">Save + </button> + </div> + </div> + <div class="row" v-if="isTableReady"> + <div class="table-responsive-sm position-relative"> + <table class="table" style="width: calc(100% - 1rem)"> + <thead class="sticky-top bg-light"> + <tr> + <th> + Item + <label for="item-id-search" class="d-none">Search</label> + <input + id="item-id-search" + class="form-control form-control-sm" + type="text" + placeholder="Filter item_id" + v-model="itemIdSearch" /> + </th> + <th v-for="label in collection.labels" :key="label" class="text-end"> + <div v-for="skey in label.slice().reverse()" :key="skey.key" class="nacsos-tooltip label-pill m-1"> + <span>{{ skey.key }}</span> + <span>{{ skey.repeat }}</span> + <div + class="nacsos-tooltiptext popover bs-popover-auto show bg-light p-0" + style="position: absolute; right: 0; margin: 0.5rem 0 0 0;" + role="tooltip" + data-popper-placement="bottom"> + <div + class="popover-arrow" + style="position: absolute; right: 0; transform: translateX(-30px);" /> + <h3 class="popover-header text-dark">{{ schemeLookup[skey.key].name }}</h3> + <div class="popover-body"> + <template v-if="schemeLookup[skey.key].choices"> + <ul class="list-unstyled"> + <li v-for="choice in schemeLookup[skey.key].choices" :key="choice.value"> + <strong>{{ choice.value }}:</strong> {{ choice.name }} + </li> + </ul> + </template> + <template v-else> + {{ schemeLookup[skey.key].kind }} + </template> + </div> + </div> + </div> + </th> + </tr> + </thead> + <tbody> + <tr + v-for="itemId in Object.keys(collection.annotations)" + :key="itemId" + v-show="itemIdSearch === '' || itemId.indexOf(itemIdSearch) >= 0"> + <td> + <span + class="text-muted font-monospace fs-fn text-break me-2 d-inline-block" + style="width: 20ch;" + role="button" + tabindex="-1" + @click="this.focusItem = itemId"> + {{ itemId }} + </span> + </td> + <td + v-for="(labelInfo, strLabel) in labels" + :key="strLabel" + class="text-end" + :class="{ 'bg-warning': !isValid(labelInfo, itemId, strLabel) }"> + <template v-if="schemeLookup[labelInfo.path[0].key]?.kind === 'bool'"> + <BoolLabel + :user-annotations="matrix[itemId][strLabel].users" + :bot-annotation="matrix[itemId][strLabel].bot" + :info="schemeLookup[labelInfo.path[0].key]" + :users="userLookup" + @bot-annotation-changed="handleChangedBotAnnotation" /> + </template> + <template v-else-if="schemeLookup[labelInfo.path[0].key]?.kind === 'single'"> + <ChoiceLabel + :user-annotations="matrix[itemId][strLabel].users" + :bot-annotation="matrix[itemId][strLabel].bot" + :info="schemeLookup[labelInfo.path[0].key]" + :users="userLookup" + @bot-annotation-changed="handleChangedBotAnnotation" /> + </template> + <template v-else> + Unhandled "{{ schemeLookup[labelInfo.path[0].key]?.kind }}" + </template> + </td> + </tr> + </tbody> + </table> + </div> + </div> + <ItemModal :item-id="focusItem" @dismissed="focusItem = undefined" /> + </div> +</template> + +<script lang="ts"> +import { currentProjectStore } from '@/stores'; +import { + AnnotationSchemeModel, + AnnotationModel, + FlattenedAnnotationSchemeLabel, + AssignmentScopeModel, + BotMetaResolve, + BotAnnotationModel, + AnnotationFilters, + AnnotationCollection, + Label, + UserModel, + AnnotationCollectionDB, +} from '@/plugins/api/api-core'; +import { API } from '@/plugins/api'; +import BoolLabel from '@/components/annotations/resolve/BoolLabel.vue'; +import ItemModal from '@/components/items/ItemModal.vue'; +import ChoiceLabel from '@/components/annotations/resolve/ChoiceLabel.vue'; +import ToolTip from '@/components/ToolTip.vue'; +import { EventBus } from '@/plugins/events'; +import { ToastEvent } from '@/plugins/events/events/toast'; + +type LookupMatrix = Record<string, Record<string, { users: AnnotationModel[], bot: BotAnnotationModel | undefined }>>; +type LabelLookupValue = { + parentChoice?: number, + parentKey?: string, + path: Label[], + strParent?: string, +}; +type LabelLookup = Record<string, LabelLookupValue>; + +type ResolveData = { + botAnnotationMetaDataId: string | undefined, + isNew: boolean, // set to true if this is not saved yet + name: string, + algorithm: BotMetaResolve.algorithm, + ignoreHierarchy: boolean, + ignoreOrder: boolean, + filters: Partial<AnnotationFilters>, + schemeFlat: FlattenedAnnotationSchemeLabel[], + collection: AnnotationCollection | undefined, + botAnnotations: Record<string, Array<[Label[], BotAnnotationModel]>>, + // id of item in focus (to be opened in modal) + focusItem: string | undefined, + // only used for setup (empty when botAnnotationMetaDataId not None) + projectAnnotationSchemes: AnnotationSchemeModel[], + // assignment scopes linking to filters.scheme_id + assignmentScopes: AssignmentScopeModel[], + annotators: UserModel[], + loadingProposals: boolean, + itemIdSearch: string, +}; + +export default { + name: 'AnnotationConfigResolveView', + components: { ToolTip, ItemModal, BoolLabel, ChoiceLabel }, + data(): ResolveData { + const botAnnotationMetaDataId: string | undefined = this.$route.params.bot_annotation_metadata_id; + + return { + botAnnotationMetaDataId, + isNew: !botAnnotationMetaDataId, + name: '', + filters: { + scheme_id: undefined, + scope_id: [] as string[], + key: [] as string[], + user_id: [] as string[], + repeat: [1, 2, 3, 4], + } as Partial<AnnotationFilters>, + algorithm: BotMetaResolve.algorithm.MAJORITY, + ignoreHierarchy: false, + ignoreOrder: false, + schemeFlat: [] as FlattenedAnnotationSchemeLabel[], + collection: undefined as AnnotationCollection | undefined, + botAnnotations: {} as Record<string, Array<[Label[], BotAnnotationModel]>>, + focusItem: undefined as string | undefined, + projectAnnotationSchemes: [] as AnnotationSchemeModel[], + assignmentScopes: [] as AssignmentScopeModel[], + annotators: [] as UserModel[], + loadingProposals: false, + itemIdSearch: '', + }; + }, + + mounted() { + this.fetchProjectSchemas(); + + if (!this.isNew && this.botAnnotationMetaDataId !== undefined) { + API.core.annotations.getSavedResolvedAnnotationsApiAnnotationsConfigResolvedBotAnnotationMetaIdGet({ + botAnnotationMetadataId: this.botAnnotationMetaDataId, + xProjectId: currentProjectStore.projectId, + }).then((response) => { + const { data } = response; + + this.name = data.name; + this.algorithm = data.meta.algorithm; + this.filters = data.meta.filters; + this.ignoreOrder = data.meta.ignore_repeat; + this.ignoreHierarchy = data.meta.ignore_hierarchy; + this.collection = data.meta.collection; + this.botAnnotations = data.saved; + }); + } + }, + + watch: { + 'filters.scheme_id': { + handler(schemeId: string) { + if (schemeId) { + // fetch `AssignmentScope`s for the current `AnnotationScheme` + API.core.annotations.getAssignmentScopesForSchemeApiAnnotationsConfigScopesSchemeIdGet({ + schemeId, + xProjectId: currentProjectStore.projectId, + }).then((response) => { + const { data } = response; + this.assignmentScopes = data; + }); + + // fetch `Users`s that created annotations linked to the current `AnnotationScheme` + API.core.annotations.getAnnotatorsForSchemeApiAnnotationsConfigAnnotatorsSchemeIdGet({ + schemeId, + xProjectId: currentProjectStore.projectId, + }).then((response) => { + const { data } = response; + this.annotators = data; + }); + + // fetch flattened annotation scheme + API.core.annotations.getSchemeDefinitionApiAnnotationsSchemesDefinitionAnnotationSchemeIdGet({ + annotationSchemeId: schemeId, + xProjectId: currentProjectStore.projectId, + flat: true, + }).then((response) => { + const { data } = response; + this.schemeFlat = data.labels; + }); + } + }, + immediate: true, + }, + }, + + methods: { + isValid(labelInfo: LabelLookupValue, itemId: string, strPath: string): boolean { + /** + * This function checks the validity of the resolved label for an item. + * A label is invalid, if the parent label does not have this one as a child. + */ + + // entries w/o parents are always valid + if (labelInfo.strParent === undefined) return true; + // empty bot annotations are always valid (independent of parent label) + if (this.matrix[itemId][strPath] === undefined + || this.matrix[itemId][strPath].bot === undefined + || (this.matrix[itemId][strPath].bot?.value_int === undefined + && this.matrix[itemId][strPath].bot?.value_bool === undefined + && this.matrix[itemId][strPath].bot?.value_str === undefined + && this.matrix[itemId][strPath].bot?.value_float === undefined + && this.matrix[itemId][strPath].bot?.multi_int === undefined)) return true; + // ignore if parent label not in this view + // FIXME: verify that this is safe to assume (e.g. what if parent choice was never assigned rather + // than explicitly not selected in this configuration) + if (!(labelInfo.strParent in this.labels)) return true; + // check if parent choice has this label as child + return this.matrix[itemId][labelInfo.strParent].bot?.value_int === this.schemeLookup[labelInfo.path[0].key].parent_choice; + }, + fetchProposal() { + this.loadingProposals = true; + API.core.annotations.getResolvedAnnotationsApiAnnotationsConfigResolveGet({ + strategy: this.algorithm, + xProjectId: currentProjectStore.projectId, + schemeId: this.filters.scheme_id, + scopeId: (!this.filters.scope_id) ? undefined : [this.filters.scope_id], + userId: (!this.filters.user_id) ? undefined : [this.filters.user_id], + key: (!this.filters.key) ? undefined : [this.filters.key], + repeat: (!this.filters.repeat) ? undefined : [this.filters.repeat], + ignoreHierarchy: this.ignoreHierarchy, + ignoreOrder: this.ignoreOrder, + }).then((response) => { + const { data } = response; + this.collection = data.collection; + this.botAnnotations = data.proposal; + this.loadingProposals = false; + }); + }, + fetchProjectSchemas() { + API.core.annotations.getSchemeDefinitionsForProjectApiAnnotationsSchemesListProjectIdGet({ + projectId: currentProjectStore.projectId, + xProjectId: currentProjectStore.projectId, + }).then((response) => { + const { data } = response; + this.projectAnnotationSchemes = data; + }); + }, + handleChangedBotAnnotation(updatedBotAnnotation: BotAnnotationModel) { + console.log(updatedBotAnnotation); + console.log('asd'); + }, + save() { + if (!this.isNew) { + this.update(); + } else { + this.saveNew(); + } + }, + update() { + API.core.annotations.updateResolvedAnnotationsApiAnnotationsConfigResolveUpdatePut({ + botAnnotationMetadataId: this.botAnnotationMetaDataId, + name: this.name, + xProjectId: currentProjectStore.projectId, + requestBody: this.flattenBotAnnotations(), + }); + }, + flattenBotAnnotations(): BotAnnotationModel[] { + return (Object.values(this.botAnnotations) as [Label[], BotAnnotationModel][][]) + .map((itemAnnotations) => (itemAnnotations as [Label[], BotAnnotationModel][]) + .map(([, annotation]) => annotation)).flat(); + }, + saveNew() { + const collection: AnnotationCollectionDB = JSON.parse(JSON.stringify(this.collection)); + collection.annotators = this.collection.annotators.map((user: UserModel) => user.user_id); + API.core.annotations.saveResolvedAnnotationsApiAnnotationsConfigResolvePut({ + xProjectId: currentProjectStore.projectId, + requestBody: { + name: this.name, + strategy: this.algorithm, + filters: this.filters, + ignore_order: this.ignoreOrder, + ignore_hierarchy: this.ignoreHierarchy, + collection, + bot_annotations: this.flattenBotAnnotations(), + }, + }).then((response) => { + const { data } = response; + EventBus.emit(new ToastEvent('SUCCESS', `Saved new annotation resolution as ${data}`)); + this.isNew = false; + this.botAnnotationMetaDataId = data; + this.$router.replace({ name: 'config-annotation-resolve', params: { bot_annotation_metadata_id: data } }); + }).catch((reason) => { + console.error(reason); + EventBus.emit(new ToastEvent('ERROR', 'Failed to save new annotation resolution!')); + }); + }, + label2string(label: Label[]) { + return label.map((label_: Label) => `${label_.key}:${label_.repeat}`).join('-'); + }, + }, + computed: { + userLookup(): Record<string, UserModel> { + if (!this.annotators) { + return {}; + } + return Object.fromEntries(this.annotators.map((user: UserModel) => [user.user_id, user])); + }, + labels(): LabelLookup { + if (!this.collection || !this.collection.labels || Object.keys(this.schemeLookup).length === 0) { + return {}; + } + return Object.fromEntries(this.collection.labels.map((label: Label[]) => [this.label2string(label), + { + path: label, + strParent: (label.length > 1) ? this.label2string(label.slice(1)) : undefined, + parentChoice: this.schemeLookup[label[0].key]?.parent_choice, + parentKey: this.schemeLookup[label[0].key]?.parent_label, + }])); + }, + schemeLookup(): Record<string, FlattenedAnnotationSchemeLabel> { + if (!this.schemeFlat) return {}; + return Object.fromEntries(this.schemeFlat.map((label: FlattenedAnnotationSchemeLabel) => [label.key, label])); + }, + isTableReady(): boolean { + return this.collection && this.collection.annotations && Object.keys(this.labels).length > 0; + }, + isConfigValid(): boolean { + // returns true if all necessary data is available to request a resolution proposal + return this.filters.scheme_id && this.filters.key.length > 0 && this.filters.user_id.length > 0; + }, + matrix(): LookupMatrix { + if (!this.collection || !this.collection.annotations) { + return {}; + } + const itemIds = Object.keys(this.collection.annotations); + const strPaths = Object.keys(this.labels); + + const matrix = Object.fromEntries(itemIds.map((itemId) => [ + itemId, + Object.fromEntries(strPaths.map((strPath) => [ + strPath, + { + users: [] as AnnotationModel[], + bot: undefined as BotAnnotationModel | undefined, + }]))])); + + Object.entries(this.collection.annotations).forEach((entry) => { + const [itemId, groupedAnnotations] = entry as [string, Array<[Label[], AnnotationModel[]]>]; + groupedAnnotations.forEach(([path, annotations]) => { + matrix[itemId][this.label2string(path)].users = annotations; + }); + }); + if (this.botAnnotations) { + Object.entries(this.botAnnotations).forEach((entry) => { + const [itemId, botAnnotationEntry] = entry as [string, Array<[Label[], BotAnnotationModel]>]; + botAnnotationEntry.forEach(([path, botAnnotation]) => { + const strPath = this.label2string(path); + matrix[itemId][strPath].bot = botAnnotation; + }); + }); + } + return matrix; + }, + }, +}; +</script> + +<style scoped> +.label-pill { + display: block !important; +} + +.label-pill span { + border-radius: var(--bs-border-radius-pill); + border: 1px solid var(--bs-gray-500); + font-weight: normal; + /*font-size: var(--bs-badge-font-size);*/ + font-size: 0.75em; + /*padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x);*/ + padding: .35em .65em; +} + +.label-pill span:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.label-pill span:last-of-type { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-left: 0; + background-color: var(--bs-gray-300); +} + +</style> diff --git a/src/views/Annotations/AnnotationConfigs/AnnotationConfigResolvedListView.vue b/src/views/Annotations/AnnotationConfigs/AnnotationConfigResolvedListView.vue new file mode 100644 index 0000000000000000000000000000000000000000..32a8ea67bc9fed620f41b34d089eca6065ba9347 --- /dev/null +++ b/src/views/Annotations/AnnotationConfigs/AnnotationConfigResolvedListView.vue @@ -0,0 +1,137 @@ +<template> + <div class="text-start"> + <h1>Resolve and Export Annotations</h1> + <ul> + <li v-for="meta in exports" :key="meta.b"> + {{ meta.name }} + <router-link + :to="{ name: 'config-annotation-resolve', params: { bot_annotation_metadata_id: meta.bot_annotation_metadata_id } }" + class="link-secondary me-1"> + <InlineToolTip info="View & Resolve Annotations"> + <font-awesome-icon :icon="['fas', 'pen']" /> + </InlineToolTip> + </router-link> + <a + @click="clone(meta.bot_annotation_metadata_id)" + tabindex="0" + aria-label="Copy scheme" + class="link-secondary me-1" + role="button"> + <InlineToolTip info="Copy"> + <font-awesome-icon :icon="['far', 'clone']" /> + </InlineToolTip> + </a> + <a + role="button" + class="link-secondary me-1" + tabindex="0" + aria-label="Delete resolved annotations" + @click="remove(meta)"> + <InlineToolTip info="Delete"> + <font-awesome-icon :icon="['fas', 'trash-can']" /> + </InlineToolTip> + </a> + <a + role="button" + class="link-secondary me-1" + tabindex="0" + aria-label="Download annotations" + @click="download(meta.bot_annotation_metadata_id)"> + <InlineToolTip info="Export data"> + <font-awesome-icon :icon="['fas', 'file-export']" /> + </InlineToolTip> + </a> + </li> + </ul> + <router-link + role="button" + class="btn btn-outline-primary m-2 btn-sm" + :to="{ name: 'config-annotation-resolve' }"> + <font-awesome-icon :icon="['far', 'square-plus']" /> + Create new export + </router-link> + </div> +</template> + +<script lang="ts"> +import { currentProjectStore } from '@/stores'; +import { EventBus } from '@/plugins/events'; +import InlineToolTip from '@/components/InlineToolTip.vue'; +import { ToastEvent } from '@/plugins/events/events/toast'; +import { API, ApiResponseReject } from '@/plugins/api'; +import { BotAnnotationMetaDataBaseModel } from '@/plugins/api/api-core'; +import { ConfirmationRequestEvent } from '@/plugins/events/events/confirmation'; + +type DataModel = { + exports: BotAnnotationMetaDataBaseModel[], +}; + +export default { + name: 'AnnotationConfigResolvedListView', + components: { InlineToolTip }, + data(): DataModel { + return { + exports: [] as BotAnnotationMetaDataBaseModel[], + } as DataModel; + }, + mounted() { + this.refreshData(); + }, + methods: { + refreshData() { + API.core.annotations.listSavedResolvedAnnotationsApiAnnotationsConfigResolvedListGet({ + xProjectId: currentProjectStore.projectId, + }).then((response) => { + const { data } = response; + this.exports = data; + }).catch((reason) => { + console.error(reason); + const err = reason as ApiResponseReject; + EventBus.emit(new ToastEvent('ERROR', `Failed to load data (${err.error.type}: ${err.error.message})`)); + }); + }, + clone(bot_annotation_metadata_id: string) { + // TODO + EventBus.emit(new ToastEvent( + 'INFO', + `Not implemented yet, can't clone ${bot_annotation_metadata_id}.`, + )); + }, + download(bot_annotation_metadata_id: string) { + // TODO + EventBus.emit(new ToastEvent( + 'INFO', + `Not implemented yet, can't export ${bot_annotation_metadata_id}.`, + )); + }, + remove(meta: BotAnnotationMetaDataBaseModel) { + EventBus.emit(new ConfirmationRequestEvent( + 'Do you really want to **permanently delete** all resolved annotations associated to the scope shown below?\n' + + `- "${meta.name}"\n` + + `- ID: ${meta.bot_annotation_metadata_id}`, + (confirmationResponse) => { + if (confirmationResponse === 'ACCEPT') { + API.core.annotations.deleteSavedResolvedAnnotationsApiAnnotationsConfigResolvedBotAnnotationMetaIdDelete({ + botAnnotationMetadataId: meta.bot_annotation_metadata_id!, + xProjectId: currentProjectStore.projectId, + }).then(() => { + EventBus.emit(new ToastEvent('SUCCESS', `Deleted ${meta.bot_annotation_metadata_id}`)); + this.refreshData(); + }).catch(() => { + EventBus.emit(new ToastEvent( + 'ERROR', + `Failed to delete ${meta.bot_annotation_metadata_id}.`, + )); + }); + } + }, + 'Delete resolved annotations', + )); + }, + }, +}; +</script> + +<style scoped> + +</style> diff --git a/src/views/Annotations/Annotations/AnnotationsView.vue b/src/views/Annotations/Annotations/AnnotationsView.vue index ddb1f4daf25810549ea33d0bb3ac2c7449b400fe..275d19d4e4f3b71e5e6cebaf1dd1ab3cc495088d 100644 --- a/src/views/Annotations/Annotations/AnnotationsView.vue +++ b/src/views/Annotations/Annotations/AnnotationsView.vue @@ -17,7 +17,7 @@ </ul> </div> <div class="row g-0"> - <GenericItemComponent :item="item" /> + <AnyItemComponent :item="item" /> </div> </div> <div class="col border-start p-2 overflow-auto h-md-100 position-relative" :class="sidebarWidthClass"> @@ -69,7 +69,7 @@ <script lang="ts"> import { marked } from 'marked'; -import GenericItemComponent from '@/components/items/GenericItem.vue'; +import AnyItemComponent from '@/components/items/AnyItem.vue'; import AnnotationLabels from '@/components/annotations/AnnotationLabels.vue'; import { EventBus } from '@/plugins/events'; import { ToastEvent } from '@/plugins/events/events/toast'; @@ -124,7 +124,7 @@ type AnnotationsViewData = { export default { name: 'AnnotationsView', - components: { AnnotationLabels, GenericItemComponent }, + components: { AnnotationLabels, AnyItemComponent }, data(): AnnotationsViewData { return { item: undefined, diff --git a/src/views/Dataset/DatasetListView.vue b/src/views/Dataset/DatasetListView.vue index 8715799dfd62137dac842cbb0b3bfa5a38dcd4a2..a1ff13de04539336adf735f1edc8a28ebdc7965a 100644 --- a/src/views/Dataset/DatasetListView.vue +++ b/src/views/Dataset/DatasetListView.vue @@ -61,7 +61,7 @@ <div class="d-flex flex-row flex-wrap p-2 overflow-auto"> <template v-if="this.itemList && this.itemList.length > 0"> <template v-if="projectType === 'twitter'"> - <GenericItemComponent + <AnyItemComponent v-for="(item) in itemList" :key="item.item_id" :item="item" /> @@ -150,7 +150,7 @@ <script lang="ts"> import { currentProjectStore } from '@/stores'; -import GenericItemComponent from '@/components/items/GenericItem.vue'; +import AnyItemComponent from '@/components/items/AnyItem.vue'; import { useOffsetPagination, UseOffsetPaginationReturn } from '@vueuse/core'; import ClosablePill from '@/components/ClosablePill.vue'; import { reactive } from 'vue'; @@ -159,7 +159,7 @@ import { API, toastReject } from '@/plugins/api'; export default { name: 'ProjectDataView', - components: { ClosablePill, GenericItemComponent }, + components: { ClosablePill, AnyItemComponent }, data() { return { projectType: currentProjectStore.project.type, @@ -171,8 +171,7 @@ export default { }; }, async mounted() { - API.core.project.countProjectItemsApiProjectProjectIdItemsCountGet({ - projectId: currentProjectStore.projectId, + API.core.project.countProjectItemsApiProjectItemsCountGet({ xProjectId: currentProjectStore.projectId, }) .then((response) => { @@ -190,9 +189,8 @@ export default { }, methods: { fetchData({ currentPage, currentPageSize }: UseOffsetPaginationReturn): void { - API.core.project.listProjectDataPagedApiProjectProjectIdItemsItemTypeListPagePageSizeGet({ + API.core.project.listProjectDataPagedApiProjectItemsItemTypeListPagePageSizeGet({ xProjectId: currentProjectStore.projectId, - projectId: currentProjectStore.projectId, page: this.pagination.currentPage, pageSize: this.pagination.currentPageSize, itemType: currentProjectStore.project.type, diff --git a/src/views/Imports/ImportDetailsView.vue b/src/views/Imports/ImportDetailsView.vue index 86e0b65ee8e66f757358b620930f2d596503b32d..ca845d5e3b66145a1fc852b384aa780093907181 100644 --- a/src/views/Imports/ImportDetailsView.vue +++ b/src/views/Imports/ImportDetailsView.vue @@ -94,7 +94,7 @@ import { Component } from 'vue'; import { ToastEvent } from '@/plugins/events/events/toast'; import { EventBus } from '@/plugins/events'; import { CompatibilityMapping, ComponentMapping } from '@/types/imports.d'; -import { ImportModel, ImportType, ProjectModel, ProjectPermissionsModel, ProjectType } from '@/plugins/api/api-core'; +import { ImportModel, ImportType, ItemType, ProjectModel, ProjectPermissionsModel } from '@/plugins/api/api-core'; import ConfigTwitter from '@/components/imports/ConfigTwitter.vue'; import ConfigJSONL from '@/components/imports/ConfigJSONL.vue'; import ConfigRIS from '@/components/imports/ConfigRIS.vue'; @@ -248,7 +248,7 @@ export default { return undefined; }, compatibleImportTypes() { - const projectType: ProjectType = this.currentProject.type; + const projectType: ItemType = this.currentProject.type; const compatibleTypes = projectTypeImportTypeCompatibility[projectType]; return Object.fromEntries( diff --git a/src/views/Projects/ProjectSettingsContainer.vue b/src/views/Projects/ProjectSettingsContainer.vue new file mode 100644 index 0000000000000000000000000000000000000000..0f07ccd71fba5572a63a4e6804372453b2d32dd4 --- /dev/null +++ b/src/views/Projects/ProjectSettingsContainer.vue @@ -0,0 +1,28 @@ +<template> + <div> + <div v-if="projectPermissions.owner"> + <router-view /> + </div> + <div v-else> + Unfortunately, you don't have permission to access this page. + </div> + </div> +</template> + +<script lang="ts"> +import { currentProjectStore } from '@/stores'; +import { ProjectPermissionsModel } from '@/plugins/api/api-core'; + +export default { + name: 'ProjectSettingsContainer', + data() { + return { + projectPermissions: currentProjectStore.projectPermissions as ProjectPermissionsModel, + }; + }, +}; +</script> + +<style scoped> + +</style> diff --git a/src/views/Projects/ProjectSettingsView.vue b/src/views/Projects/ProjectSettingsView.vue new file mode 100644 index 0000000000000000000000000000000000000000..2f579f2835701e761dd2a9650b1de403f09806cc --- /dev/null +++ b/src/views/Projects/ProjectSettingsView.vue @@ -0,0 +1,14 @@ +<template> + settings +</template> +<script lang="ts"> + +export default { + name: 'ProjectSettingsView', + data() { + return { + // pass + }; + }, +}; +</script>