diff --git a/client/package-lock.json b/client/package-lock.json index d050c22757..d48a498af1 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,38 +9,38 @@ "version": "4.1.x-dev", "license": "MIT", "dependencies": { - "@angular/animations": "^18.2.3", - "@angular/cdk": "^18.2.3", - "@angular/common": "^18.2.3", - "@angular/compiler": "^18.2.3", - "@angular/core": "^18.2.3", - "@angular/forms": "^18.2.3", - "@angular/material": "^18.2.3", - "@angular/material-date-fns-adapter": "^18.2.3", - "@angular/platform-browser": "^18.2.3", - "@angular/platform-browser-dynamic": "^18.2.3", - "@angular/router": "^18.2.3", - "@angular/service-worker": "^18.2.3", + "@angular/animations": "^18.2.5", + "@angular/cdk": "^18.2.5", + "@angular/common": "^18.2.5", + "@angular/compiler": "^18.2.5", + "@angular/core": "^18.2.5", + "@angular/forms": "^18.2.5", + "@angular/material": "^18.2.5", + "@angular/material-date-fns-adapter": "^18.2.5", + "@angular/platform-browser": "^18.2.5", + "@angular/platform-browser-dynamic": "^18.2.5", + "@angular/router": "^18.2.5", + "@angular/service-worker": "^18.2.5", "@material/typography": "^14.0.0", "@ngx-pwa/local-storage": "^18.0.0", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", - "@tiptap/core": "^2.6.6", - "@tiptap/extension-color": "^2.6.6", - "@tiptap/extension-highlight": "^2.6.6", - "@tiptap/extension-image": "^2.6.6", - "@tiptap/extension-link": "^2.6.6", - "@tiptap/extension-subscript": "^2.6.6", - "@tiptap/extension-superscript": "^2.6.6", - "@tiptap/extension-table": "^2.6.6", - "@tiptap/extension-table-cell": "^2.6.6", - "@tiptap/extension-table-header": "^2.6.6", - "@tiptap/extension-table-row": "^2.6.6", - "@tiptap/extension-text-align": "^2.6.6", + "@tiptap/core": "^2.7.2", + "@tiptap/extension-color": "^2.7.2", + "@tiptap/extension-highlight": "^2.7.2", + "@tiptap/extension-image": "^2.7.2", + "@tiptap/extension-link": "^2.7.2", + "@tiptap/extension-subscript": "^2.7.2", + "@tiptap/extension-superscript": "^2.7.2", + "@tiptap/extension-table": "^2.7.2", + "@tiptap/extension-table-cell": "^2.7.2", + "@tiptap/extension-table-header": "^2.7.2", + "@tiptap/extension-table-row": "^2.7.2", + "@tiptap/extension-text-align": "^2.7.2", "@tiptap/extension-text-style": "^2.5.4", - "@tiptap/extension-underline": "^2.6.6", + "@tiptap/extension-underline": "^2.7.2", "@tiptap/pm": "^2.5.4", - "@tiptap/starter-kit": "^2.6.6", + "@tiptap/starter-kit": "^2.7.2", "@tsparticles/angular": "^3.0.0", "@tsparticles/engine": "^3.5.0", "@tsparticles/plugin-emitters": "^3.5.0", @@ -56,7 +56,7 @@ "jszip": "^3.10.1", "material-design-icons-iconfont": "^6.7.0", "ng2-charts": "^6.0.1", - "ng2-pdf-viewer": "^10.3.0", + "ng2-pdf-viewer": "^10.3.1", "ngx-date-fns": "^11.0.0", "ngx-device-detector": "^8.0.0", "ngx-file-drop": "^16.0.0", @@ -68,18 +68,18 @@ "qrcode": "^1.5.4", "rxjs": "^7.8.1", "tinycolor2": "1.6.0", - "video.js": "^8.17.3", + "video.js": "^8.17.4", "zone.js": "^0.14.10" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.2.3", - "@angular-eslint/builder": "^18.3.0", - "@angular-eslint/eslint-plugin": "^18.3.0", - "@angular-eslint/eslint-plugin-template": "^18.3.0", - "@angular-eslint/schematics": "^18.3.0", - "@angular-eslint/template-parser": "^18.3.0", - "@angular/cli": "^18.2.3", - "@angular/compiler-cli": "^18.2.3", + "@angular-devkit/build-angular": "^18.2.5", + "@angular-eslint/builder": "^18.3.1", + "@angular-eslint/eslint-plugin": "^18.3.1", + "@angular-eslint/eslint-plugin-template": "^18.3.1", + "@angular-eslint/schematics": "^18.3.1", + "@angular-eslint/template-parser": "^18.3.1", + "@angular/cli": "^18.2.5", + "@angular/compiler-cli": "^18.2.5", "@colsen1991/ngx-translate-extract-marker": "^2.0.8", "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.4", @@ -92,12 +92,12 @@ "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "@vendure/ngx-translate-extract": "^9.2.1", - "eslint": "^8.57.0", + "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-simple-import-sort": "^12.1.1", - "eslint-plugin-unused-imports": "^4.1.3", - "fetch-mock": "^11.1.3", + "eslint-plugin-unused-imports": "^4.1.4", + "fetch-mock": "^11.1.4", "jasmine-core": "~5.3.0", "js-yaml": "^4.1.0", "karma": "~6.4.4", @@ -128,12 +128,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1802.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.3.tgz", - "integrity": "sha512-WQ2AmkUKy1bqrDlNfozW8+VT2Tv/Fdmu4GIXps3ytZANyAKiIvTzmmql2cRCXXraa9FNMjLWNvz+qolDxWVdYQ==", + "version": "0.1802.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.5.tgz", + "integrity": "sha512-c7sVoW85Yqj7IYvNKxtNSGS5I7gWpORorg/xxLZX3OkHWXDrwYbb5LN/2p5/Aytxyb0aXl4o5fFOu6CUwcaLUw==", "dev": true, "dependencies": { - "@angular-devkit/core": "18.2.3", + "@angular-devkit/core": "18.2.5", "rxjs": "7.8.1" }, "engines": { @@ -143,16 +143,16 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.3.tgz", - "integrity": "sha512-uUQba0SIskKORHcPayt7LpqPRKD//48EW92SgGHEArn2KklM+FSYBOA9OtrJeZ/UAcoJpdLDtvyY4+S7oFzomg==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.5.tgz", + "integrity": "sha512-dIvb0AHoRIMM6tLuG4t6lDDslSAYP77wqytodsN317UzFOuuCPernXbO8NJs+QHxj09nPsem1T5vnvpO2E/PVQ==", "dev": true, "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.3", - "@angular-devkit/build-webpack": "0.1802.3", - "@angular-devkit/core": "18.2.3", - "@angular/build": "18.2.3", + "@angular-devkit/architect": "0.1802.5", + "@angular-devkit/build-webpack": "0.1802.5", + "@angular-devkit/core": "18.2.5", + "@angular/build": "18.2.5", "@babel/core": "7.25.2", "@babel/generator": "7.25.0", "@babel/helper-annotate-as-pure": "7.24.7", @@ -163,7 +163,7 @@ "@babel/preset-env": "7.25.3", "@babel/runtime": "7.25.0", "@discoveryjs/json-ext": "0.6.1", - "@ngtools/webpack": "18.2.3", + "@ngtools/webpack": "18.2.5", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", "autoprefixer": "10.4.20", @@ -203,7 +203,7 @@ "terser": "5.31.6", "tree-kill": "1.2.2", "tslib": "2.6.3", - "vite": "5.4.0", + "vite": "5.4.6", "watchpack": "2.4.1", "webpack": "5.94.0", "webpack-dev-middleware": "7.4.2", @@ -316,12 +316,12 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1802.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.3.tgz", - "integrity": "sha512-/Nixv9uAg6v/OPoZa0PB0zi+iezzBkgLrnrJnestny5B536l9WRtsw97RjeQDu+x2BClQsxNe8NL2A7EvjVD6w==", + "version": "0.1802.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.5.tgz", + "integrity": "sha512-6qkcrWBdkxojCVHGWcdJaz4G+7QTjFvmc+3g8xvLc9sYvJq1I059gfXhDnC0FxiA0MT4cY/26ECYWUHTD5CJLQ==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1802.3", + "@angular-devkit/architect": "0.1802.5", "rxjs": "7.8.1" }, "engines": { @@ -335,9 +335,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.3.tgz", - "integrity": "sha512-vbFs+ofNK9OWeMIcFarFjegXVklhtSdLTEFKZ9trDVr8alTJdjI9AiYa6OOUTDAyq0hqYxV26xlCisWAPe7s5w==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.5.tgz", + "integrity": "sha512-r9TumPlJ8PvA2+yz4sp+bUHgtznaVKzhvXTN5qL1k4YP8LJ7iZWMR2FOP+HjukHZOTsenzmV9pszbogabqwoZQ==", "dev": true, "dependencies": { "ajv": "8.17.1", @@ -391,12 +391,12 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.3.tgz", - "integrity": "sha512-N3tRAzBW2yWQhebvc1Ha18XTMSXOQTfr8HNjx7Fasx0Fg1tNyGR612MJNZw6je/PqyItKeUHOhztvFMfCQjRyg==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.5.tgz", + "integrity": "sha512-NUmz2UQ1Xl4cf4j1AgkwIfsCjBzAPgfeC3IBrD29hSOBE1Y3j6auqjBkvw50v6mbSPxESND995Xy13HpK1Xflw==", "dev": true, "dependencies": { - "@angular-devkit/core": "18.2.3", + "@angular-devkit/core": "18.2.5", "jsonc-parser": "3.3.1", "magic-string": "0.30.11", "ora": "5.4.1", @@ -409,9 +409,9 @@ } }, "node_modules/@angular-eslint/builder": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-18.3.0.tgz", - "integrity": "sha512-httEQyqyBw3+0CRtAa7muFxHrauRfkEfk/jmrh5fn2Eiu+I53hAqFPgrwVi1V6AP/kj2zbAiWhd5xM3pMJdoRQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-18.3.1.tgz", + "integrity": "sha512-cPc7Ye9zDs5M4i+feL6vob+mh7yX5vxvOS5KQIhneUrp5e9D+IGuNFMmBLlOPpmklSc9XJBtuvI5Zjuh4z1ETw==", "dev": true, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", @@ -419,19 +419,19 @@ } }, "node_modules/@angular-eslint/bundled-angular-compiler": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-18.3.0.tgz", - "integrity": "sha512-v/59FxUKnMzymVce99gV43huxoqXWMb85aKvzlNvLN+ScDu6ZE4YMiTQNpfapVL2lkxhs0uwB3jH17EYd5TcsA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-18.3.1.tgz", + "integrity": "sha512-sikmkjfsXPpPTku1aQkQ1MNNEKGBgGGRvUN/WeNS9dhCJ4dxU3O7dZctt1aQWj+W3nbuUtDiimAWF5fZHGFE2Q==", "dev": true }, "node_modules/@angular-eslint/eslint-plugin": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-18.3.0.tgz", - "integrity": "sha512-Vl7gfPMXxvtHTjYdlzR161aj5xrqW6T57wd8ToQ7Gqzm0qHGfY6kE4SQobUa2LCYckTNSlv+zXe48C4ah/dSjw==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-18.3.1.tgz", + "integrity": "sha512-MP4Nm+SHboF8KdnN0KpPEGAaTTzDLPm3+S/4W3Mg8onqWCyadyd4mActh9mK/pvCj8TVlb/SW1zeTtdMYhwonw==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "18.3.0", - "@angular-eslint/utils": "18.3.0" + "@angular-eslint/bundled-angular-compiler": "18.3.1", + "@angular-eslint/utils": "18.3.1" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", @@ -440,13 +440,13 @@ } }, "node_modules/@angular-eslint/eslint-plugin-template": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-18.3.0.tgz", - "integrity": "sha512-ddR/qwYbUeq9IpyVKrPbfZyRBTy6V8uc5I0JcBKttQ4CZ4joXhqsVgWFsI+JAMi8E66uNj1VC7NuKCOjDINv2Q==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-18.3.1.tgz", + "integrity": "sha512-hBJ3+f7VSidvrtYaXH7Vp0sWvblA9jLK2c6uQzhYGWdEDUcTg7g7VI9ThW39WvMbHqkyzNE4PPOynK69cBEDGg==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "18.3.0", - "@angular-eslint/utils": "18.3.0", + "@angular-eslint/bundled-angular-compiler": "18.3.1", + "@angular-eslint/utils": "18.3.1", "aria-query": "5.3.0", "axobject-query": "4.1.0" }, @@ -456,42 +456,14 @@ "typescript": "*" } }, - "node_modules/@angular-eslint/eslint-plugin-template/node_modules/@angular-eslint/utils": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-18.3.0.tgz", - "integrity": "sha512-sCrkHkpxBJZLuCikdboZoawCfc2UgbJv+T14tu2uQCv+Vwzeadnu04vkeY2vTkA8GeBdBij/G9/N/nvwmwVw3g==", - "dev": true, - "dependencies": { - "@angular-eslint/bundled-angular-compiler": "18.3.0" - }, - "peerDependencies": { - "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": "*" - } - }, - "node_modules/@angular-eslint/eslint-plugin/node_modules/@angular-eslint/utils": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-18.3.0.tgz", - "integrity": "sha512-sCrkHkpxBJZLuCikdboZoawCfc2UgbJv+T14tu2uQCv+Vwzeadnu04vkeY2vTkA8GeBdBij/G9/N/nvwmwVw3g==", - "dev": true, - "dependencies": { - "@angular-eslint/bundled-angular-compiler": "18.3.0" - }, - "peerDependencies": { - "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": "*" - } - }, "node_modules/@angular-eslint/schematics": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-18.3.0.tgz", - "integrity": "sha512-rQ4DEWwf3f5n096GAK6JvXD0SRzRJ52WRaIyKg8MMkk6qvUDfZI8seOkcbjDtZoIe6Ds7DfqSfJgNVte75qvPQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-18.3.1.tgz", + "integrity": "sha512-BTsQHDu7LjvXannJTb5BqMPCFIHRNN94eRyb60VfjJxB/ZFtsbAQDFFOi5lEZsRsd4mBeUMuL9mW4IMcPtUQ9Q==", "dev": true, "dependencies": { - "@angular-eslint/eslint-plugin": "18.3.0", - "@angular-eslint/eslint-plugin-template": "18.3.0", + "@angular-eslint/eslint-plugin": "18.3.1", + "@angular-eslint/eslint-plugin-template": "18.3.1", "ignore": "5.3.2", "semver": "7.6.3", "strip-json-comments": "3.1.1" @@ -502,12 +474,12 @@ } }, "node_modules/@angular-eslint/template-parser": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-18.3.0.tgz", - "integrity": "sha512-1mUquqcnugI4qsoxcYZKZ6WMi6RPelDcJZg2YqGyuaIuhWmi3ZqJZLErSSpjP60+TbYZu7wM8Kchqa1bwJtEaQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-18.3.1.tgz", + "integrity": "sha512-JUUkfWH1G+u/Uk85ZYvJSt/qwN/Ko+jlXFtzBEcknJZsTWTwBcp36v77gPZe5FmKSziJZpyPUd+7Kiy6tuSCTw==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "18.3.0", + "@angular-eslint/bundled-angular-compiler": "18.3.1", "eslint-scope": "^8.0.2" }, "peerDependencies": { @@ -531,10 +503,24 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@angular-eslint/utils": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-18.3.1.tgz", + "integrity": "sha512-sd9niZI7h9H2FQ7OLiQsLFBhjhRQTASh+Q0+4+hyjv9idbSHBJli8Gsi2fqj9zhtMKpAZFTrWzuLUpubJ9UYbA==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "18.3.1" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, "node_modules/@angular/animations": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.3.tgz", - "integrity": "sha512-rIATopHr83lYR0X05buHeHssq9CGw0I0YPIQcpUTGnlqIpJcQVCf7jCFn4KGZrE9V55hFY3MD4S28njlwCToQQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.5.tgz", + "integrity": "sha512-IlXtW/Nj48ZzjHUzH1TykZcSR64ScJx39T3IHnjV2z/bVATzZ36JGoadQHdqpJNKBodYJNgtJCGLCbgAvGWY2g==", "dependencies": { "tslib": "^2.3.0" }, @@ -542,17 +528,17 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.3" + "@angular/core": "18.2.5" } }, "node_modules/@angular/build": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.3.tgz", - "integrity": "sha512-USrD2Zvcb1te2dnqhH7JZ5XeJDg/t7fjUHR4f93vvMrnrncwCjLoHbHpz01HCHfcIVRgsYUdAmAi1iG7vpak7w==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.5.tgz", + "integrity": "sha512-XWkmjzgeUga0SJ0lYSYcTuYOWTyqcln2mNfBp7Ae/GZ+/7+APbedsIZEiZGZwveOIyOpTM5wguNSoe9khDl5Ig==", "dev": true, "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.3", + "@angular-devkit/architect": "0.1802.5", "@babel/core": "7.25.2", "@babel/helper-annotate-as-pure": "7.24.7", "@babel/helper-split-export-declaration": "7.24.7", @@ -574,7 +560,7 @@ "rollup": "4.20.0", "sass": "1.77.6", "semver": "7.6.3", - "vite": "5.4.0", + "vite": "5.4.6", "watchpack": "2.4.1" }, "engines": { @@ -643,9 +629,9 @@ } }, "node_modules/@angular/cdk": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.3.tgz", - "integrity": "sha512-lUcpYTxPZuntJ1FK7V2ugapCGMIhT6TUDjIGgXfS9AxGSSKgwr8HNs6Ze9pcjYC44UhP40sYAZuiaFwmE60A2A==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.5.tgz", + "integrity": "sha512-HLg5cfrIrgNIJJ+0v3kLieHeLPJLFNOBO359holXOrKUPRG+XQ3CT8EzSvREFm1XkaSEsDC0+dnG0ouNhOPFpQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -659,17 +645,17 @@ } }, "node_modules/@angular/cli": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.3.tgz", - "integrity": "sha512-40258vuliH6+p8QSByZe5EcIXSj0iR3PNF6yuusClR/ByToHOnmuPw7WC+AYr0ooozmqlim/EjQe4/037OUB3w==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.5.tgz", + "integrity": "sha512-97uNs0HsOdnMaTlNJKFjIBUXw0wz43uYvSSKmIpBt7eq1LaPLju1G/qpDIHx2YwhMClPrXXrW2H/xdvqZiIw+w==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1802.3", - "@angular-devkit/core": "18.2.3", - "@angular-devkit/schematics": "18.2.3", + "@angular-devkit/architect": "0.1802.5", + "@angular-devkit/core": "18.2.5", + "@angular-devkit/schematics": "18.2.5", "@inquirer/prompts": "5.3.8", "@listr2/prompt-adapter-inquirer": "2.0.15", - "@schematics/angular": "18.2.3", + "@schematics/angular": "18.2.5", "@yarnpkg/lockfile": "1.1.0", "ini": "4.1.3", "jsonc-parser": "3.3.1", @@ -692,9 +678,9 @@ } }, "node_modules/@angular/common": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.3.tgz", - "integrity": "sha512-NFL4yXXImSCH7i1xnHykUjHa9vl9827fGiwSV2mnf7LjSUsyDzFD8/54dNuYN9OY8AUD+PnK0YdNro6cczVyIA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.5.tgz", + "integrity": "sha512-m+KJrtbFXTE36jP/po6UAMeUR/enQxRHpVGLCRcIcE7VWVH1ZcOvoW1yqh2A6k+KxWXeajlq/Z04nnMhcoxMRw==", "dependencies": { "tslib": "^2.3.0" }, @@ -702,14 +688,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.3", + "@angular/core": "18.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.3.tgz", - "integrity": "sha512-Il3ljs0j1GaYoqYFdShjUP1ryck5xTOaA8uQuRgqwU0FOwEDfugSAM3Qf7nJx/sgxTM0Lm/Nrdv2u6i1gZWeuQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.5.tgz", + "integrity": "sha512-vcqe9x4dGGAnMfPhEpcZyiSVgAiqJeK80LqP1vWoAmBR+HeOqAilSv6SflcLAtuTzwgzMMAvD2T+SMCgUvaqww==", "dependencies": { "tslib": "^2.3.0" }, @@ -717,7 +703,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.3" + "@angular/core": "18.2.5" }, "peerDependenciesMeta": { "@angular/core": { @@ -726,9 +712,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.3.tgz", - "integrity": "sha512-BcmqYKnkcJTkGjuPztClZNQve7tdI290J5F3iZBx6c7/vaw8EU8EGZtpWYZpgiVn5S6jhcKyc1dLF9ggO9vftg==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.5.tgz", + "integrity": "sha512-CCCtZobUTUfId/RTYtuDCw5R1oK0w65hdAUMRP1MdGmd8bb8DKJA86u1QCWwozL3rbXlIIX4ognQ6urQ43k/Gw==", "dev": true, "dependencies": { "@babel/core": "7.25.2", @@ -749,14 +735,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "18.2.3", + "@angular/compiler": "18.2.5", "typescript": ">=5.4 <5.6" } }, "node_modules/@angular/core": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.3.tgz", - "integrity": "sha512-VGhMJxj7d0rYpqVfQrcGRB7EE/BCziotft/I/YPl6bOMPSAvMukG7DXQuJdYpNrr62ks78mlzHlZX/cdmB9Prw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.5.tgz", + "integrity": "sha512-5BLVc5gXxzanQkADNS9WPsor3vNF5nQcyIHBi5VScErwM5vVZ7ATH1iZwaOg1ykDEVTFVhKDwD0X1aaqGDbhmQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -769,9 +755,9 @@ } }, "node_modules/@angular/forms": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.3.tgz", - "integrity": "sha512-+OBaAH0e8hue9eyLnbgpxg1/X9fps6bwXECfJ0nL5BDPU5itZ428YJbEnj5bTx0hEbqfTRiV4LgexdI+D9eOpw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.5.tgz", + "integrity": "sha512-ohKeH+EZCCIyGSiFYlraWLzssGAZc13P92cuYpXB62322PkcA5u0IT72mML9JWGKRqF2zteVsw4koWHVxXM5mA==", "dependencies": { "tslib": "^2.3.0" }, @@ -779,22 +765,22 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.3", - "@angular/core": "18.2.3", - "@angular/platform-browser": "18.2.3", + "@angular/common": "18.2.5", + "@angular/core": "18.2.5", + "@angular/platform-browser": "18.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/material": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.3.tgz", - "integrity": "sha512-JFfvXaMHMhskncaxxus4sDvie9VYdMkfYgfinkLXpZlPFyn1IzjDw0c1BcrcsuD7UxQVZ/v5tucCgq1FQfGRpA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.5.tgz", + "integrity": "sha512-+Yz8ayKz1ALz2UvPrM33FHSUmrE0GKHn+Gg79l6NdC4eSrzAAYBVdLfQvCBWCgtdvs7IiegbCnnAJiqXVC1DDg==", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/animations": "^18.0.0 || ^19.0.0", - "@angular/cdk": "18.2.3", + "@angular/cdk": "18.2.5", "@angular/common": "^18.0.0 || ^19.0.0", "@angular/core": "^18.0.0 || ^19.0.0", "@angular/forms": "^18.0.0 || ^19.0.0", @@ -803,22 +789,22 @@ } }, "node_modules/@angular/material-date-fns-adapter": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/material-date-fns-adapter/-/material-date-fns-adapter-18.2.3.tgz", - "integrity": "sha512-tIBorpTAUZ0wnjjdWt7YL2blLoClMVkyWfvIcve6Tgll0ddndhdMvrNms19+Z5YinrDVIgGdjIP4W0KscnNmtQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/material-date-fns-adapter/-/material-date-fns-adapter-18.2.5.tgz", + "integrity": "sha512-m4wsgPRbuyhN/fB+VtrvW4jFyH5TIUol0oj/ZT9dQP1+y7NLrYhbLg2LIxe+DMzsbVVMMEccRGnJYRftk5Nm3Q==", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/core": "^18.0.0 || ^19.0.0", - "@angular/material": "18.2.3", + "@angular/material": "18.2.5", "date-fns": ">2.20.0 <4.0" } }, "node_modules/@angular/platform-browser": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.3.tgz", - "integrity": "sha512-M2ob4zN7tAcL2mx7U6KnZNqNFPFl9MlPBE0FrjQjIzAjU0wSYPIJXmaPu9aMUp9niyo+He5iX98I+URi2Yc99g==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.5.tgz", + "integrity": "sha512-PoX9idwnOpTJBlujzZ2nFGOsmCnZzOH7uNSWIR7trdoq0b1AFXfrxlCQ36qWamk7bbhJI4H28L8YTmKew/nXDA==", "dependencies": { "tslib": "^2.3.0" }, @@ -826,9 +812,9 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "18.2.3", - "@angular/common": "18.2.3", - "@angular/core": "18.2.3" + "@angular/animations": "18.2.5", + "@angular/common": "18.2.5", + "@angular/core": "18.2.5" }, "peerDependenciesMeta": { "@angular/animations": { @@ -837,9 +823,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.3.tgz", - "integrity": "sha512-nWi9ZxN4KpbJkttIckFO1PCoW0+gb/18xFO+JWyLBAtcbsudj/Mv0P/fdOaSfQdLkPhZfORr3ZcfiTkhmuGyEg==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.5.tgz", + "integrity": "sha512-5u0IuAt1r5e2u2vSKhp3phnaf6hH89B/q7GErfPse1sdDfNI6wHVppxai28PAfAj9gwooJun6MjFWhJFLzS44A==", "dependencies": { "tslib": "^2.3.0" }, @@ -847,16 +833,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.3", - "@angular/compiler": "18.2.3", - "@angular/core": "18.2.3", - "@angular/platform-browser": "18.2.3" + "@angular/common": "18.2.5", + "@angular/compiler": "18.2.5", + "@angular/core": "18.2.5", + "@angular/platform-browser": "18.2.5" } }, "node_modules/@angular/router": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.3.tgz", - "integrity": "sha512-fvD9eSDIiIbeYoUokoWkXzu7/ZaxlzKPUHFqX1JuKuH5ciQDeT/d7lp4mj31Bxammhohzi3+z12THJYsCkj/iQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.5.tgz", + "integrity": "sha512-OjZV1PTiSwT0ytmR0ykveLYzs4uQWf0EuIclZmWqM/bb8Q4P+gJl7/sya05nGnZsj6nHGOL0e/LhSZ3N+5p6qg==", "dependencies": { "tslib": "^2.3.0" }, @@ -864,16 +850,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.3", - "@angular/core": "18.2.3", - "@angular/platform-browser": "18.2.3", + "@angular/common": "18.2.5", + "@angular/core": "18.2.5", + "@angular/platform-browser": "18.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-18.2.3.tgz", - "integrity": "sha512-KplaBYhhwsM3gPeOImfDGhAknN+BIcZJkHl8YRnhoUEFHsTZ8LTV02C4LWQL3YTu3pK+uj/lPMKi1CA37cXQ8g==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-18.2.5.tgz", + "integrity": "sha512-MoF2n7z/X+yqK89mIRHQutVHIBTyEUo/fDEL8LcuBP4KOZmX9cRoCEt+vqH49BkArsgOM0jNFMYCM8yt0jg7pw==", "dependencies": { "tslib": "^2.3.0" }, @@ -884,8 +870,8 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.3", - "@angular/core": "18.2.3" + "@angular/common": "18.2.5", + "@angular/core": "18.2.5" } }, "node_modules/@babel/code-frame": { @@ -3179,9 +3165,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3270,12 +3256,13 @@ "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -4058,9 +4045,9 @@ ] }, "node_modules/@ngtools/webpack": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.3.tgz", - "integrity": "sha512-DDuBHcu23qckt43SexBJaPEIeMc/HKaFOidILZM9D4gU4C9VroMActdR218dvQ802QfL0S46t5Ykz8ENprIfjA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.5.tgz", + "integrity": "sha512-L0n4eHObeqEOYRfSP+e4SeF/dmwxOIFy9xYvYCOUwOLrW4b3+a1+kkT30pqyfL72LFtpf0cmUwaWEFIcWl5PCg==", "dev": true, "engines": { "node": "^18.19.1 || ^20.11.1 || >=22.0.0", @@ -4454,9 +4441,9 @@ } }, "node_modules/@remirror/core-constants": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-2.0.2.tgz", - "integrity": "sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==" }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.20.0", @@ -4667,13 +4654,13 @@ ] }, "node_modules/@schematics/angular": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.3.tgz", - "integrity": "sha512-whSON70z9HYb4WboVXmPFE/RLKJJQLWNzNcUyi8OSDZkQbJnYgPp0///n738m26Y/XeJDv11q1gESy+Zl2AdUw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.5.tgz", + "integrity": "sha512-tBXhk9OGT4U6VsBNbuCNl2ITDOF3NYdGrEieIHU+lHSkpJNGZUIGxCgXCETXkmXDq1pe4wFZSKelWjeqYDfX0g==", "dev": true, "dependencies": { - "@angular-devkit/core": "18.2.3", - "@angular-devkit/schematics": "18.2.3", + "@angular-devkit/core": "18.2.5", + "@angular-devkit/schematics": "18.2.5", "jsonc-parser": "3.3.1" }, "engines": { @@ -4775,219 +4762,219 @@ "dev": true }, "node_modules/@tiptap/core": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.6.6.tgz", - "integrity": "sha512-VO5qTsjt6rwworkuo0s5AqYMfDA0ZwiTiH6FHKFSu2G/6sS7HKcc/LjPq+5Legzps4QYdBDl3W28wGsGuS1GdQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.7.2.tgz", + "integrity": "sha512-rGAH90LPMR5OIG7vuTDRw8WxDYxPXSxuGtu++mxPF+Bv7V2ijPOy3P1oyV1G3KGoS0pPiNugLh+tVLsElcx/9Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/pm": "^2.6.6" + "@tiptap/pm": "^2.7.0" } }, "node_modules/@tiptap/extension-blockquote": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.6.6.tgz", - "integrity": "sha512-hAdsNlMfzzxld154hJqPqtWqO5i4/7HoDfuxmyqBxdMJ+e2UMaIGBGwoLRXG0V9UoRwJusjqlpyD7pIorxNlgA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.7.2.tgz", + "integrity": "sha512-EUBYiEE9lL49YUZC9rv5UjiS04byB0HhsWoCerc1nBO6wjqv+TK/3rCFHzqRQ0LpVuLDwzBMaoD08+kHe43y+A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-bold": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.6.6.tgz", - "integrity": "sha512-CD6gBhdQtCoqYSmx8oAV8gvKtVOGZSyyvuNYo7by9eZ56DqLYnd7kbUj0RH7o9Ymf/iJTOUJ6XcvrsWwo4lubg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.7.2.tgz", + "integrity": "sha512-idRZz5/c5CJTDQ8xCU+45gyhbAM+9P8l9wpkeSAEGV4N1i8HBO7FXbWk+ZMQLhZhGJ0Ng36gzBVTsv5bNGpAAg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.6.6.tgz", - "integrity": "sha512-WEKxbVSYuvmX2wkHWP8HXk5nzA7stYwtdaubwWH/R17kGI3IGScJuMQ9sEN82uzJU8bfgL9yCbH2bY8Fj/Q4Ow==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.7.2.tgz", + "integrity": "sha512-/RBy/qZpJe4Il1LzI1unQAKWMDjLXQoAU9gNIu6eAlHunHzwRUQ9zvH+7PNF5JkFkEbMtJLoz7NTS5qdndHldw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-code": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.6.6.tgz", - "integrity": "sha512-JrEFKsZiLvfvOFhOnnrpA0TzCuJjDeysfbMeuKUZNV4+DhYOL28d39H1++rEtJAX0LcbBU60oC5/PrlU9SpvRQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.7.2.tgz", + "integrity": "sha512-C2umR5tNR0PJ7v+mvkm869nsjQm2rbM0ZgOQb/75htEScVAttNxMg2TYAEbIE8WM7mcIVUFhxPz8QuuUDMPCaA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-code-block": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.6.6.tgz", - "integrity": "sha512-1YLp/zHMHSkE2xzht8nPR6T4sQJJ3ket798czxWuQEbetFv/l0U/mpiPpYSLObj6oTAoqYZ0kWXZj5eQSpPB8Q==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.7.2.tgz", + "integrity": "sha512-ATvrH59IG/dsfpH6+Yb+RvRFbNx6BUVBZoIMbG/jA76vbXxIcT3UcGoDIorCUJqA2KwpniZOfQOmZ2o6eg9hZQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/pm": "^2.6.6" + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" } }, "node_modules/@tiptap/extension-color": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-color/-/extension-color-2.6.6.tgz", - "integrity": "sha512-aq2XnbWMak1yJxH2EoVKpCjFONRkZcX9D72LvvgOgtDQ62wG3/axZ75bT1B/NNfqlEp7U78Fpqib7jq/uCLYTg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-color/-/extension-color-2.7.2.tgz", + "integrity": "sha512-PFblz3384reTN0v4niNSkwIit06SQEgdwXQDBnuuyh4Stwb5sf+Pv2znvUR9O0g52RoI0qwbXG+QFiWYoo6Sww==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/extension-text-style": "^2.6.6" + "@tiptap/core": "^2.7.0", + "@tiptap/extension-text-style": "^2.7.0" } }, "node_modules/@tiptap/extension-document": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.6.6.tgz", - "integrity": "sha512-6qlH5VWzLHHRVeeciRC6C4ZHpMsAGPNG16EF53z0GeMSaaFD/zU3B239QlmqXmLsAl8bpf8Bn93N0t2ABUvScw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.7.2.tgz", + "integrity": "sha512-WyMGytHhb3MbNhJ8kUXTx/jHZ9XPaaPRJu1TYdVZNQ4pg7K47qLJ2KMOyLEFy7e5HcJUkYfhRHpyQGHkiu3brg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.6.6.tgz", - "integrity": "sha512-O6CeKriA9uyHsg7Ui4z5ZjEWXQxrIL+1zDekffW0wenGC3G4LUsCzAiFS4LSrR9a3u7tnwqGApW10rdkmCGF4w==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.7.2.tgz", + "integrity": "sha512-hZCIl5C/8m+4yIXa39+qFmUyH1/pPlnxu3OAgSxwxpA2NIM7DUMJnFZFt+4pEkmGD/5XEGKlLuBqvYzHC3OUBg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/pm": "^2.6.6" + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.6.6.tgz", - "integrity": "sha512-O2lQ2t0X0Vsbn3yLWxFFHrXY6C2N9Y6ZF/M7LWzpcDTUZeWuhoNkFE/1yOM0h6ZX1DO2A9hNIrKpi5Ny8yx+QA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.7.2.tgz", + "integrity": "sha512-4gFwVp9J+d1M/6OqqsJmtg3/SLgiRiTM+h40vlCveu/yqliON9qSOhpuFE1PJkH4OpCH2l7YtyZRGEjo3ffuJQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/pm": "^2.6.6" + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" } }, "node_modules/@tiptap/extension-hard-break": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.6.6.tgz", - "integrity": "sha512-bsUuyYBrMDEiudx1dOQSr9MzKv13m0xHWrOK+DYxuIDYJb5g+c9un5cK7Js+et/HEYYSPOoH/iTW6h+4I5YeUg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.7.2.tgz", + "integrity": "sha512-44dZMi0N1fNhQ8i7bFnj4JYfhn4B6+vHuEueJPZS1iOsJc715m3e8ZSfDBk7VXCGKrksCxPMJ7guO0Y1PVryow==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-heading": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.6.6.tgz", - "integrity": "sha512-bgx9vptVFi5yFkIw1OI53J7+xJ71Or3SOe/Q8eSpZv53DlaKpL/TzKw8Z54t1PrI2rJ6H9vrLtkvixJvBZH1Ug==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.7.2.tgz", + "integrity": "sha512-i26Skx/womkqkG3aQW9PPh8UUS5znAWxNb5SzxBowJoISq1thOUsdmb16PdL9tljsO8vKy4sAPOx3hT5oVN7uw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-highlight": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.6.6.tgz", - "integrity": "sha512-Z02AYWm1AJAfhmfT4fGCI3YitijF4uNu+eiuq7OxhCiVf9IYaq8xlH2YMxa09QvMUo70ovklxk97+vQUUHeqfQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.7.2.tgz", + "integrity": "sha512-mWlwvhv9kQ9JiGpTS29MXX9UQ90gZ3QgdcZlRANOjwTlh9GOcxCzJ7VW1fLfPgqNvswpbUTwJnlCAP2owKKMFA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-history": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.6.6.tgz", - "integrity": "sha512-tPTzAmPGqMX5Bd5H8lzRpmsaMvB9DvI5Dy2za/VQuFtxgXmDiFVgHRkRXIuluSkPTuANu84XBOQ0cBijqY8x4w==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.7.2.tgz", + "integrity": "sha512-l5jyPawcJ5qdZmSzryMLV+egEJeh2p9AmZRzv6QHug0PhhFNvujEHWEc1WXn+tY/OP2fAesfyed3bjdTVh2sFw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/pm": "^2.6.6" + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.6.6.tgz", - "integrity": "sha512-cFEfv7euDpuLSe8exY8buwxkreKBAZY9Hn3EetKhPcLQo+ut5Y24chZTxFyf9b+Y0wz3UhOhLTZSz7fTobLqBA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.7.2.tgz", + "integrity": "sha512-WneHFFgAqCwksb5bJ6dfK3mLwZVSJ51FtaooXp4d1C/KZjqNTWoQBTrXHsPTFqz6swcRSFLG9xQgsh48grcmZw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/pm": "^2.6.6" + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" } }, "node_modules/@tiptap/extension-image": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.6.6.tgz", - "integrity": "sha512-dwJKvoqsr72B4tcTH8hXhfBJzUMs/jXUEE9MnfzYnSXf+CYALLjF8r/IkGYbxce62GP/bMDoj8BgpF8saeHtqA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.7.2.tgz", + "integrity": "sha512-gGjUXhsoART3FZ/12+JdqAEdHGNi3chga6l6LKraXva2+S4JIcadODQP9oRSNineCSyISoxpZMZtWt5cdoG7vw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-italic": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.6.6.tgz", - "integrity": "sha512-t7ZPsXqa8nJZZ/6D0rQyZ/KsvzLaSihC6hBTjUQ77CeDGV9PhDWjIcBW4OrvwraJDBd12ETBeQ2CkULJOgH+lQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.7.2.tgz", + "integrity": "sha512-evrvsuMNhx9X4SG6iIcIRS0BdIwMlKTEKLc5jWWu5A3NnS9wOb8JT+wLTS1glwFAdrqKHUjUpWS6JMWF4O/mgQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-link": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.6.6.tgz", - "integrity": "sha512-NJSR5Yf/dI3do0+Mr6e6nkbxRQcqbL7NOPxo5Xw8VaKs2Oe8PX+c7hyqN3GZgn6uEbZdbVi1xjAniUokouwpFg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.7.2.tgz", + "integrity": "sha512-9RDhkp+naG53Ffmhqt6kRLkLT0Iun6WF++/If+os6w0w9t6BQUL4+A2ngZob65eu/xkN4NZXnjWcLg9gSrxGIQ==", "dependencies": { "linkifyjs": "^4.1.0" }, @@ -4996,187 +4983,187 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/pm": "^2.6.6" + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.6.6.tgz", - "integrity": "sha512-k+oEzZu2cgVKqPqOP1HzASOKLpTEV9m7mRVPAbuaaX8mSyvIgD6f+JUx9PvgYv//D918wk98LMoRBFX53tDJ4w==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.7.2.tgz", + "integrity": "sha512-aP9E9XcwUMnsAdL4QD5e0HLZeW1I6Br67SH/e2yN1ZaJjJeN3XMq8N11QbBfMtkequqNk9cGrEj52TPi22MqXg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.6.6.tgz", - "integrity": "sha512-AJwyfLXIi7iUGnK5twJbwdVVpQyh7fU6OK75h1AwDztzsOcoPcxtffDlZvUOd4ZtwuyhkzYqVkeI0f+abTWZTw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.7.2.tgz", + "integrity": "sha512-uanvByYOYdFRgn/71UmIc0B7pIt9srL0XG5d8k8SeQS3cbdGgOMy7CjzwY7n3MuW3KJx6AqIZPfOsA2dKhVSEQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-paragraph": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.6.6.tgz", - "integrity": "sha512-fD/onCr16UQWx+/xEmuFC2MccZZ7J5u4YaENh8LMnAnBXf78iwU7CAcmuc9rfAEO3qiLoYGXgLKiHlh2ZfD4wA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.7.2.tgz", + "integrity": "sha512-yMzUGNojNv0lLEE+38GOpgRI327EyEZK/uEHlyzbjAWRvqE6aZ+oEB4JUuoJXX2Ad9gwN16dGHnxL//ieTxrkQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-strike": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.6.6.tgz", - "integrity": "sha512-Ze8KhGk+wzSJSJRl5fbhTI6AvPu2LmcHYeO3pMEH8u4gV5WTXfmKJVStEIAzkoqvwEQVWzXvy8nDgsFQHiojPg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.7.2.tgz", + "integrity": "sha512-ryDAdG/yXVCSdoDnEHeLBYxnjFXbIVHX4MmiagGSQRlgznlgylXjf+gnO9mxW+ulLvH4Wfz8FzZl2ra7nqLLwQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-subscript": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.6.6.tgz", - "integrity": "sha512-EiVnVN89siMdYNNVcyPe5kuQhiSlDMKpnO3aRNYKf6EcHdUiRJH+Np8E8ojQc5M/gOq4qWqeUZXk/107AYayQA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.7.2.tgz", + "integrity": "sha512-goqv2TtpmbmL/7eLvhtIZvZ0Jq28pnLE/ni1kEoar01Jnt4vb63ZvGTkIPUPwP/7C8SsXB4KlVofa6rcpkjwhw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-superscript": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.6.6.tgz", - "integrity": "sha512-e8RqTRIUnXJNSVfKJV6C2nPGtVRPqYSa9k3m4TN6jsFrNJ+NvOjp8sMUcLM4UzwLloQaKn/UcDHidNQaRc7dTA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.7.2.tgz", + "integrity": "sha512-QLWiDaVGnXsNTFW6VTp3kMHb8iL1HcbHWZHVD44OvuK+qmjbdtJF7zFRTj8iTiL9LjbjujRfpRvtIt9r8J09CQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-table": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.6.6.tgz", - "integrity": "sha512-Ay/IClmB9R8MjnLobGnA9tI0+7ev4GUwvNf/JA2razI8CeaMCJ7CcAzG6pnIp4d7I6ELWYmAt3vwxoRlsAZcEw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.7.2.tgz", + "integrity": "sha512-FHNSh6k319p1OW+KZbn5yXp6YwlgfkpPz5eI4YbyXOKRYQw+mh/uDeBhlzaPUpoc0FRXdBGQWmGHj7KPpGJpAw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/pm": "^2.6.6" + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" } }, "node_modules/@tiptap/extension-table-cell": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.6.6.tgz", - "integrity": "sha512-XakU9qnlYAf/ux4q7zgiJs2pvkjOl9mVzQw5j55aQHYLiw0gXomEgUbrkn7jhA7N6WP9PlngS3quwIDfyoqLvw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.7.2.tgz", + "integrity": "sha512-I2H9FtqGxYvym6eUX+x94sDXpczDhhhjertdH64cf6HDbUGm0FQloE0XdA0f6VaL4I8qaSpnybd04R8nztTe5g==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-table-header": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.6.6.tgz", - "integrity": "sha512-BX2cVTrOZzIQAAWrNjD2Dzk/RpCJWUqgdW2bh27x0nJwKfMWfqLPoplTTuCZ+J9yK7rlNj3jEhKewe/yR1Tudw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.7.2.tgz", + "integrity": "sha512-e076DPR1mZelfkyl0bWrgHsOvA0QQ7VJpgVld7vVBN8KzK1NNCyg7gp+5uKh84UEfsCyQIZ6IM8X8RljbM1bCg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-table-row": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.6.6.tgz", - "integrity": "sha512-VN8MwrEbq2hs/BE3cizbasFMLfh0F9I9MF7cmU8V1j1Zju0ONUIEXOscO4TNFfCB8lf5tTwIp1sr+fxYUUprhg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.7.2.tgz", + "integrity": "sha512-O2RA0R8TA9ejoxCpOIWqIvklGzjv8f5VhBBbfYMgAM9tgD4jsNCHsKBwZuy0V5eEu3gnwyKXHEpWLyG08tJuFA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-text": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.6.6.tgz", - "integrity": "sha512-e84uILnRzNzcwK1DVQNpXVmBG1Cq3BJipTOIDl1LHifOok7MBjhI/X+/NR0bd3N2t6gmDTWi63+4GuJ5EeDmsg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.7.2.tgz", + "integrity": "sha512-VjzG7W53Lx2q8XV0rUHetVTQWDK28XTCTW3IzxYxHp2joB/k9q3xgE/5Vs+7DOLSHIKq2BmwQNyaE+XjUF5iYQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-text-align": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.6.6.tgz", - "integrity": "sha512-WdyxULEEHfI3hRDHAFOUoeP84h9myabadfjtZrub7/zO2PKKPAZLBN2vWat5PowH8E8GYX8vqKr9vaX+slfh5g==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.7.2.tgz", + "integrity": "sha512-sLQ7sl2fgkJD4MOP2t83kJccIJCnj19Bt5DRmlVb7pFDBaoDrQPH3Q9kw8GZznqr3PYCckRkPOyg0C3AdAVsnw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-text-style": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.6.6.tgz", - "integrity": "sha512-8fO8m0/QI+rFKgZLP28GG2Nz0zhYsYd76O2Y+HsDTmMypJl/cdiNcVOWWffAwXAfMN43BNX7b1VI1XwGAMgYlg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.7.2.tgz", + "integrity": "sha512-AvUHV6ULnB0AWpyzw895cUNwRCC5lu4+6Vdn5u81xqMC+J6+8WdYqAmfprqBlcMwpj40Q9K+OAYgXRyisu+zIA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-underline": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.6.6.tgz", - "integrity": "sha512-3A4HqsDM/AFb2VaeWACpGexjgI257kz0yU4jNV8uyydDR2KhqeinuEnoSoOmx9T3pL006TWfPg4vaQYPO3qvrQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.7.2.tgz", + "integrity": "sha512-c3tPjxOusNZAlF/LG2RcTOPQrpUEKSjB9xwpEIJa/pZ59zQdivOdZGdOoCe6zqkDOT+Sh7sBoQKKwzIPi1csTQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.6.6" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/pm": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.6.6.tgz", - "integrity": "sha512-56FGLPn3fwwUlIbLs+BO21bYfyqP9fKyZQbQyY0zWwA/AG2kOwoXaRn7FOVbjP6CylyWpFJnpRRmgn694QKHEg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.7.2.tgz", + "integrity": "sha512-RiRPlwpuE6IHDJytE0tglbFlWELOaqeyGRGv25wBTjzV1plnqC5B3U65XY/8kKuuLjdd3NpRfR68DXBafusSBg==", "dependencies": { "prosemirror-changeset": "^2.2.1", "prosemirror-collab": "^1.3.1", - "prosemirror-commands": "^1.5.2", + "prosemirror-commands": "^1.6.0", "prosemirror-dropcursor": "^1.8.1", "prosemirror-gapcursor": "^1.3.2", "prosemirror-history": "^1.4.1", @@ -5184,14 +5171,14 @@ "prosemirror-keymap": "^1.2.2", "prosemirror-markdown": "^1.13.0", "prosemirror-menu": "^1.2.4", - "prosemirror-model": "^1.22.2", + "prosemirror-model": "^1.22.3", "prosemirror-schema-basic": "^1.2.3", "prosemirror-schema-list": "^1.4.1", "prosemirror-state": "^1.4.3", "prosemirror-tables": "^1.4.0", - "prosemirror-trailing-node": "^2.0.9", - "prosemirror-transform": "^1.9.0", - "prosemirror-view": "^1.33.9" + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.0", + "prosemirror-view": "^1.33.10" }, "funding": { "type": "github", @@ -5199,30 +5186,30 @@ } }, "node_modules/@tiptap/starter-kit": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.6.6.tgz", - "integrity": "sha512-zb9xIg3WjG9AsJoyWrfqx5SL9WH7/HTdkB79jFpWtOF/Kaigo7fHFmhs2FsXtJMJlcdMTO2xeRuCYHt5ozXlhg==", - "dependencies": { - "@tiptap/core": "^2.6.6", - "@tiptap/extension-blockquote": "^2.6.6", - "@tiptap/extension-bold": "^2.6.6", - "@tiptap/extension-bullet-list": "^2.6.6", - "@tiptap/extension-code": "^2.6.6", - "@tiptap/extension-code-block": "^2.6.6", - "@tiptap/extension-document": "^2.6.6", - "@tiptap/extension-dropcursor": "^2.6.6", - "@tiptap/extension-gapcursor": "^2.6.6", - "@tiptap/extension-hard-break": "^2.6.6", - "@tiptap/extension-heading": "^2.6.6", - "@tiptap/extension-history": "^2.6.6", - "@tiptap/extension-horizontal-rule": "^2.6.6", - "@tiptap/extension-italic": "^2.6.6", - "@tiptap/extension-list-item": "^2.6.6", - "@tiptap/extension-ordered-list": "^2.6.6", - "@tiptap/extension-paragraph": "^2.6.6", - "@tiptap/extension-strike": "^2.6.6", - "@tiptap/extension-text": "^2.6.6", - "@tiptap/pm": "^2.6.6" + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.7.2.tgz", + "integrity": "sha512-cKbhGXsi3IFtQcEZ2jGiRhuDy3AmT7oajrCgQ6KI6yis40yilTsVafUcLhDRchBaOvNJeS6kPy8QVKS7cJKqFw==", + "dependencies": { + "@tiptap/core": "^2.7.2", + "@tiptap/extension-blockquote": "^2.7.2", + "@tiptap/extension-bold": "^2.7.2", + "@tiptap/extension-bullet-list": "^2.7.2", + "@tiptap/extension-code": "^2.7.2", + "@tiptap/extension-code-block": "^2.7.2", + "@tiptap/extension-document": "^2.7.2", + "@tiptap/extension-dropcursor": "^2.7.2", + "@tiptap/extension-gapcursor": "^2.7.2", + "@tiptap/extension-hard-break": "^2.7.2", + "@tiptap/extension-heading": "^2.7.2", + "@tiptap/extension-history": "^2.7.2", + "@tiptap/extension-horizontal-rule": "^2.7.2", + "@tiptap/extension-italic": "^2.7.2", + "@tiptap/extension-list-item": "^2.7.2", + "@tiptap/extension-ordered-list": "^2.7.2", + "@tiptap/extension-paragraph": "^2.7.2", + "@tiptap/extension-strike": "^2.7.2", + "@tiptap/extension-text": "^2.7.2", + "@tiptap/pm": "^2.7.2" }, "funding": { "type": "github", @@ -5960,9 +5947,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", "dev": true }, "node_modules/@types/range-parser": { @@ -6355,9 +6342,9 @@ } }, "node_modules/@videojs/http-streaming": { - "version": "3.13.2", - "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.13.2.tgz", - "integrity": "sha512-eCfQp61w00hg7Y9npmLnsJ6UvDF+SsFYzu7mQJgVXxWpVm9AthYWA3KQEKA7F7Sy6yzlm/Sps8BHs5ItelNZgQ==", + "version": "3.13.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.13.3.tgz", + "integrity": "sha512-L7H+iTeqHeZ5PylzOx+pT3CVyzn4TALWYTJKkIc1pDaV/cTVfNGtG+9/vXPAydD+wR/xH1M9/t2JH8tn/DCT4w==", "dependencies": { "@babel/runtime": "^7.12.5", "@videojs/vhs-utils": "4.0.0", @@ -6376,6 +6363,31 @@ "video.js": "^8.14.0" } }, + "node_modules/@videojs/http-streaming/node_modules/aes-decrypter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.1.tgz", + "integrity": "sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^3.0.5", + "global": "^4.4.0", + "pkcs7": "^1.0.4" + } + }, + "node_modules/@videojs/http-streaming/node_modules/aes-decrypter/node_modules/@videojs/vhs-utils": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", + "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "global": "^4.4.0", + "url-toolkit": "^2.2.1" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + } + }, "node_modules/@videojs/vhs-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.0.0.tgz", @@ -6661,24 +6673,23 @@ } }, "node_modules/aes-decrypter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.1.tgz", - "integrity": "sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.2.tgz", + "integrity": "sha512-lc+/9s6iJvuaRe5qDlMTpCFjnwpkeOXp8qP3oiZ5jsj1MRg+SBVUmmICrhxHvc8OELSmc+fEyyxAuppY6hrWzw==", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", + "@videojs/vhs-utils": "^4.1.1", "global": "^4.4.0", "pkcs7": "^1.0.4" } }, "node_modules/aes-decrypter/node_modules/@videojs/vhs-utils": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", - "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.1.1.tgz", + "integrity": "sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==", "dependencies": { "@babel/runtime": "^7.12.5", - "global": "^4.4.0", - "url-toolkit": "^2.2.1" + "global": "^4.4.0" }, "engines": { "node": ">=8", @@ -9124,16 +9135,16 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -9230,9 +9241,9 @@ } }, "node_modules/eslint-plugin-unused-imports": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.3.tgz", - "integrity": "sha512-lqrNZIZjFMUr7P06eoKtQLwyVRibvG7N+LtfKtObYGizAAGrcqLkc3tDx+iAik2z7q0j/XI3ihjupIqxhFabFA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz", + "integrity": "sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==", "dev": true, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", @@ -9833,9 +9844,9 @@ } }, "node_modules/fetch-mock": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-11.1.3.tgz", - "integrity": "sha512-ATh0dWgnVrUHiiXuvQm1Ry+ThWfSv1QQgqJTCtybrNxyUrFiSOaDKsNG29eyysp1SHeNP6Q+dH50+8VifN51Ig==", + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-11.1.4.tgz", + "integrity": "sha512-Enndh1ApARgYDPfWFgfzLeSgdQVasMj6qDWDArya6quj3Z83AVGsl1YrVe8OxWVWsN7a+56RQRoGNmo9HdldAg==", "dev": true, "dependencies": { "@types/glob-to-regexp": "^0.4.4", @@ -10845,11 +10856,6 @@ "node": ">=8" } }, - "node_modules/individual": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz", - "integrity": "sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g==" - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -12569,23 +12575,22 @@ } }, "node_modules/m3u8-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.1.0.tgz", - "integrity": "sha512-7N+pk79EH4oLKPEYdgRXgAsKDyA/VCo0qCHlUwacttQA0WqsjZQYmNfywMvjlY9MpEBVZEt0jKFd73Kv15EBYQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.2.0.tgz", + "integrity": "sha512-CRatFqpjVtMiMaKXxNvuI3I++vUumIXVVT/JpCpdU/FynV/ceVw1qpPyyBNindL+JlPMSesx+WX1QJaZEJSaMQ==", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", + "@videojs/vhs-utils": "^4.1.1", "global": "^4.4.0" } }, "node_modules/m3u8-parser/node_modules/@videojs/vhs-utils": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", - "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.1.1.tgz", + "integrity": "sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==", "dependencies": { "@babel/runtime": "^7.12.5", - "global": "^4.4.0", - "url-toolkit": "^2.2.1" + "global": "^4.4.0" }, "engines": { "node": ">=8", @@ -12681,9 +12686,9 @@ } }, "node_modules/memfs": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.11.1.tgz", - "integrity": "sha512-LZcMTBAgqUUKNXZagcZxvXXfgF1bHX7Y7nQ0QyEiNbRJgE29GhgPd8Yna1VQcLlPiHt/5RFJMWYN9Uv/VPNvjQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz", + "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==", "dev": true, "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", @@ -13220,9 +13225,9 @@ } }, "node_modules/ng2-pdf-viewer": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-10.3.0.tgz", - "integrity": "sha512-zU51lVcsmCy1Nytw94r2ABHfdBKlJWc+Zllk7Fct3pT3b7Q8UbMiZ8IbA4d5iXoe2/iznsS2YXGzMn0/vPHcXA==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-10.3.1.tgz", + "integrity": "sha512-Tdeu74Go1qzBMmpVbiKA96bgtHCeh+Qnq7ErVLHsV/9TPoCO6cRBsGW/7ojdH1S92MnnM6/iQGLY3EnMYh1wOg==", "dependencies": { "pdfjs-dist": "^4.5.136", "tslib": "^2.3.0" @@ -14279,9 +14284,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -14678,9 +14683,9 @@ } }, "node_modules/prosemirror-commands": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz", - "integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.0.tgz", + "integrity": "sha512-xn1U/g36OqXn2tn5nGmvnnimAj/g1pUx2ypJJIe8WkVX83WyJVC5LTARaxZa2AtQRwntu9Jc5zXs9gL9svp/mg==", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -14758,9 +14763,9 @@ } }, "node_modules/prosemirror-model": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.2.tgz", - "integrity": "sha512-I4lS7HHIW47D0Xv/gWmi4iUWcQIDYaJKd8Hk4+lcSps+553FlQrhmxtItpEvTr75iAruhzVShVp6WUwsT6Boww==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.3.tgz", + "integrity": "sha512-V4XCysitErI+i0rKFILGt/xClnFJaohe/wrrlT2NSZ+zk8ggQfDH4x2wNK7Gm0Hp4CIoWizvXFP7L9KMaCuI0Q==", "dependencies": { "orderedmap": "^2.0.0" } @@ -14806,11 +14811,11 @@ } }, "node_modules/prosemirror-trailing-node": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.9.tgz", - "integrity": "sha512-YvyIn3/UaLFlFKrlJB6cObvUhmwFNZVhy1Q8OpW/avoTbD/Y7H5EcjK4AZFKhmuS6/N6WkGgt7gWtBWDnmFvHg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", "dependencies": { - "@remirror/core-constants": "^2.0.2", + "@remirror/core-constants": "3.0.0", "escape-string-regexp": "^4.0.0" }, "peerDependencies": { @@ -14831,17 +14836,17 @@ } }, "node_modules/prosemirror-transform": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.9.0.tgz", - "integrity": "sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.0.tgz", + "integrity": "sha512-9UOgFSgN6Gj2ekQH5CTDJ8Rp/fnKR2IkYfGdzzp5zQMFsS4zDllLVx/+jGcX86YlACpG7UR5fwAXiWzxqWtBTg==", "dependencies": { "prosemirror-model": "^1.21.0" } }, "node_modules/prosemirror-view": { - "version": "1.33.9", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.9.tgz", - "integrity": "sha512-xV1A0Vz9cIcEnwmMhKKFAOkfIp8XmJRnaZoPqNXrPS7EK5n11Ov8V76KhR0RsfQd/SIzmWY+bg+M44A2Lx/Nnw==", + "version": "1.34.3", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.34.3.tgz", + "integrity": "sha512-mKZ54PrX19sSaQye+sef+YjBbNu2voNwLS1ivb6aD2IRmxRGW64HU9B644+7OfJStGLyxvOreKqEgfvXa91WIA==", "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -15580,14 +15585,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rust-result": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz", - "integrity": "sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==", - "dependencies": { - "individual": "^2.0.0" - } - }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -15615,14 +15612,6 @@ } ] }, - "node_modules/safe-json-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz", - "integrity": "sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==", - "dependencies": { - "rust-result": "^1.0.0" - } - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -16260,9 +16249,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -17405,12 +17394,12 @@ } }, "node_modules/video.js": { - "version": "8.17.3", - "resolved": "https://registry.npmjs.org/video.js/-/video.js-8.17.3.tgz", - "integrity": "sha512-zhhmE0LNxJRA603/48oYzF7GYdT+rQRscvcsouYxFE71aKhalHLBP6S9/XjixnyjcrYgwIx8OQo6eSjcbbAW0Q==", + "version": "8.17.4", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-8.17.4.tgz", + "integrity": "sha512-AECieAxKMKB/QgYK36ci50phfpWys6bFT6+pGMpSafeFYSoZaQ2Vpl83T9Qqcesv4TO7oNtiycnVeaBnrva2oA==", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/http-streaming": "3.13.2", + "@videojs/http-streaming": "3.13.3", "@videojs/vhs-utils": "^4.0.0", "@videojs/xhr": "2.7.0", "aes-decrypter": "^4.0.1", @@ -17418,7 +17407,6 @@ "m3u8-parser": "^7.1.0", "mpd-parser": "^1.2.2", "mux.js": "^7.0.1", - "safe-json-parse": "4.0.0", "videojs-contrib-quality-levels": "4.1.0", "videojs-font": "4.2.0", "videojs-vtt.js": "0.15.5" @@ -17453,14 +17441,14 @@ } }, "node_modules/vite": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", - "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", + "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", "dev": true, "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.40", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -17917,6 +17905,34 @@ "@esbuild/win32-x64": "0.21.5" } }, + "node_modules/vite/node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", diff --git a/client/package.json b/client/package.json index e547f833b8..c3efe4bfda 100644 --- a/client/package.json +++ b/client/package.json @@ -36,38 +36,38 @@ "get-available-languages": "npm run ts -- cli/get-available-languages.ts" }, "dependencies": { - "@angular/animations": "^18.2.3", - "@angular/cdk": "^18.2.3", - "@angular/common": "^18.2.3", - "@angular/compiler": "^18.2.3", - "@angular/core": "^18.2.3", - "@angular/forms": "^18.2.3", - "@angular/material": "^18.2.3", - "@angular/material-date-fns-adapter": "^18.2.3", - "@angular/platform-browser": "^18.2.3", - "@angular/platform-browser-dynamic": "^18.2.3", - "@angular/router": "^18.2.3", - "@angular/service-worker": "^18.2.3", + "@angular/animations": "^18.2.5", + "@angular/cdk": "^18.2.5", + "@angular/common": "^18.2.5", + "@angular/compiler": "^18.2.5", + "@angular/core": "^18.2.5", + "@angular/forms": "^18.2.5", + "@angular/material": "^18.2.5", + "@angular/material-date-fns-adapter": "^18.2.5", + "@angular/platform-browser": "^18.2.5", + "@angular/platform-browser-dynamic": "^18.2.5", + "@angular/router": "^18.2.5", + "@angular/service-worker": "^18.2.5", "@material/typography": "^14.0.0", "@ngx-pwa/local-storage": "^18.0.0", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", - "@tiptap/core": "^2.6.6", - "@tiptap/extension-color": "^2.6.6", - "@tiptap/extension-highlight": "^2.6.6", - "@tiptap/extension-image": "^2.6.6", - "@tiptap/extension-link": "^2.6.6", - "@tiptap/extension-subscript": "^2.6.6", - "@tiptap/extension-superscript": "^2.6.6", - "@tiptap/extension-table": "^2.6.6", - "@tiptap/extension-table-cell": "^2.6.6", - "@tiptap/extension-table-header": "^2.6.6", - "@tiptap/extension-table-row": "^2.6.6", - "@tiptap/extension-text-align": "^2.6.6", + "@tiptap/core": "^2.7.2", + "@tiptap/extension-color": "^2.7.2", + "@tiptap/extension-highlight": "^2.7.2", + "@tiptap/extension-image": "^2.7.2", + "@tiptap/extension-link": "^2.7.2", + "@tiptap/extension-subscript": "^2.7.2", + "@tiptap/extension-superscript": "^2.7.2", + "@tiptap/extension-table": "^2.7.2", + "@tiptap/extension-table-cell": "^2.7.2", + "@tiptap/extension-table-header": "^2.7.2", + "@tiptap/extension-table-row": "^2.7.2", + "@tiptap/extension-text-align": "^2.7.2", "@tiptap/extension-text-style": "^2.5.4", - "@tiptap/extension-underline": "^2.6.6", + "@tiptap/extension-underline": "^2.7.2", "@tiptap/pm": "^2.5.4", - "@tiptap/starter-kit": "^2.6.6", + "@tiptap/starter-kit": "^2.7.2", "@tsparticles/angular": "^3.0.0", "@tsparticles/engine": "^3.5.0", "@tsparticles/plugin-emitters": "^3.5.0", @@ -83,7 +83,7 @@ "jszip": "^3.10.1", "material-design-icons-iconfont": "^6.7.0", "ng2-charts": "^6.0.1", - "ng2-pdf-viewer": "^10.3.0", + "ng2-pdf-viewer": "^10.3.1", "ngx-date-fns": "^11.0.0", "ngx-device-detector": "^8.0.0", "ngx-file-drop": "^16.0.0", @@ -95,18 +95,18 @@ "qrcode": "^1.5.4", "rxjs": "^7.8.1", "tinycolor2": "1.6.0", - "video.js": "^8.17.3", + "video.js": "^8.17.4", "zone.js": "^0.14.10" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.2.3", - "@angular-eslint/builder": "^18.3.0", - "@angular-eslint/eslint-plugin": "^18.3.0", - "@angular-eslint/eslint-plugin-template": "^18.3.0", - "@angular-eslint/schematics": "^18.3.0", - "@angular-eslint/template-parser": "^18.3.0", - "@angular/cli": "^18.2.3", - "@angular/compiler-cli": "^18.2.3", + "@angular-devkit/build-angular": "^18.2.5", + "@angular-eslint/builder": "^18.3.1", + "@angular-eslint/eslint-plugin": "^18.3.1", + "@angular-eslint/eslint-plugin-template": "^18.3.1", + "@angular-eslint/schematics": "^18.3.1", + "@angular-eslint/template-parser": "^18.3.1", + "@angular/cli": "^18.2.5", + "@angular/compiler-cli": "^18.2.5", "@colsen1991/ngx-translate-extract-marker": "^2.0.8", "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.4", @@ -119,12 +119,12 @@ "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "@vendure/ngx-translate-extract": "^9.2.1", - "eslint": "^8.57.0", + "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-simple-import-sort": "^12.1.1", - "eslint-plugin-unused-imports": "^4.1.3", - "fetch-mock": "^11.1.3", + "eslint-plugin-unused-imports": "^4.1.4", + "fetch-mock": "^11.1.4", "jasmine-core": "~5.3.0", "js-yaml": "^4.1.0", "karma": "~6.4.4", diff --git a/client/src/app/domain/definitions/meeting-settings-defaults.ts b/client/src/app/domain/definitions/meeting-settings-defaults.ts index 6b79c5820c..77a5b1ca80 100644 --- a/client/src/app/domain/definitions/meeting-settings-defaults.ts +++ b/client/src/app/domain/definitions/meeting-settings-defaults.ts @@ -60,6 +60,7 @@ export const meetingSettingsDefaults: { [key: string]: any } = { motions_supporters_min_amount: 0, motions_block_slide_columns: 3, motion_poll_default_type: `pseudoanonymous`, + motion_poll_default_method: `YNA`, motion_poll_default_onehundred_percent_base: `YNA`, motion_poll_ballot_paper_selection: `CUSTOM_NUMBER`, motion_poll_ballot_paper_number: 8, diff --git a/client/src/app/domain/definitions/permission.config.ts b/client/src/app/domain/definitions/permission.config.ts index d4e77a95b0..e53f46d07d 100644 --- a/client/src/app/domain/definitions/permission.config.ts +++ b/client/src/app/domain/definitions/permission.config.ts @@ -217,7 +217,9 @@ Meeting specific information: Structure level, Group, Participant number, About }, { display_name: _(`Can see sensitive data`), - help_text: _(`Can see email, username and SSO identification of all participants.`), + help_text: _( + `Can see email, username, membership number, SSO identification and locked out state of all participants.` + ), value: Permission.userCanSeeSensitiveData }, { diff --git a/client/src/app/domain/fieldsets/user.ts b/client/src/app/domain/fieldsets/user.ts index 5c630d00b7..165b4c4c32 100644 --- a/client/src/app/domain/fieldsets/user.ts +++ b/client/src/app/domain/fieldsets/user.ts @@ -2,7 +2,7 @@ import { BaseSimplifiedModelRequest } from 'src/app/site/services/model-request- export class UserFieldsets { public static readonly FullNameSubscription: BaseSimplifiedModelRequest = { - fieldset: [`title`, `first_name`, `last_name`, `pronoun`, `username`, `gender`, `default_vote_weight`] + fieldset: [`title`, `first_name`, `last_name`, `pronoun`, `username`, `default_vote_weight`, `gender_id`] }; } diff --git a/client/src/app/domain/models/gender/gender.ts b/client/src/app/domain/models/gender/gender.ts new file mode 100644 index 0000000000..3046600b1f --- /dev/null +++ b/client/src/app/domain/models/gender/gender.ts @@ -0,0 +1,21 @@ +import { Id } from '../../definitions/key-types'; +import { BaseModel } from '../base/base-model'; +/** + * Representation of a gender. + * @ignore + */ + +export class Gender extends BaseModel { + public static COLLECTION = `gender`; + + public readonly name!: string; + public organization_id!: Id; // (organization/gender_ids)[] + public user_ids!: Id[]; // user/gender_id + + public constructor(input?: Partial) { + super(Gender.COLLECTION, input); + } + + public static readonly REQUESTABLE_FIELDS: (keyof Gender)[] = [`id`, `name`, `organization_id`, `user_ids`]; +} +export interface Gender {} diff --git a/client/src/app/domain/models/meeting-users/meeting-user.ts b/client/src/app/domain/models/meeting-users/meeting-user.ts index 7a90d7de09..da6b2bf257 100644 --- a/client/src/app/domain/models/meeting-users/meeting-user.ts +++ b/client/src/app/domain/models/meeting-users/meeting-user.ts @@ -11,6 +11,7 @@ export class MeetingUser extends BaseDecimalModel { public readonly number!: string; public readonly about_me!: string; public readonly vote_weight!: number; + public readonly locked_out!: boolean; public user_id!: Id; public meeting_id!: Id; @@ -42,6 +43,7 @@ export class MeetingUser extends BaseDecimalModel { `number`, `about_me`, `vote_weight`, + `locked_out`, `user_id`, `meeting_id`, `personal_note_ids`, diff --git a/client/src/app/domain/models/meetings/meeting.ts b/client/src/app/domain/models/meetings/meeting.ts index 3734056266..8eb731a4db 100644 --- a/client/src/app/domain/models/meetings/meeting.ts +++ b/client/src/app/domain/models/meetings/meeting.ts @@ -146,6 +146,7 @@ export class Settings { public motion_poll_default_onehundred_percent_base!: PollPercentBase; public motion_poll_default_group_ids!: Id[]; // (group/used_as_motion_poll_default_id)[]; public motion_poll_default_backend!: PollBackendDurationType; + public motion_poll_default_method!: PollMethod; // Users public users_enable_presence_view!: boolean; @@ -394,6 +395,7 @@ export class Meeting extends BaseModel { `motion_poll_ballot_paper_selection`, `motion_poll_ballot_paper_number`, `motion_poll_default_type`, + `motion_poll_default_method`, `motion_poll_default_onehundred_percent_base`, `motion_poll_default_group_ids`, `motion_poll_default_backend`, diff --git a/client/src/app/domain/models/organizations/organization.ts b/client/src/app/domain/models/organizations/organization.ts index cfb2d96df3..94ad79f30c 100644 --- a/client/src/app/domain/models/organizations/organization.ts +++ b/client/src/app/domain/models/organizations/organization.ts @@ -34,7 +34,6 @@ export class OrganizationSetting { public saml_metadata_idp!: string; public saml_metadata_sp!: string; public saml_private_key!: string; - public genders!: string[]; } export class Organization extends BaseModel { @@ -52,6 +51,7 @@ export class Organization extends BaseModel { public archived_meeting_ids!: Id[]; // (meeting/is_archived_in_organization_id)[]; public template_meeting_ids!: Id[]; // (meeting/template_for_organization_id)[]; public mediafile_ids!: Id[]; + public gender_ids!: Id[]; // (gender/organization_id); public published_mediafile_ids!: Id[]; public constructor(input?: any) { @@ -66,7 +66,7 @@ export class Organization extends BaseModel { `privacy_policy`, `login_text`, `reset_password_verbose_errors`, - `genders`, + `gender_ids`, `enable_electronic_voting`, `enable_chat`, `limit_of_meetings`, diff --git a/client/src/app/domain/models/users/user.constants.ts b/client/src/app/domain/models/users/user.constants.ts index bb3cdb7387..aac477bdea 100644 --- a/client/src/app/domain/models/users/user.constants.ts +++ b/client/src/app/domain/models/users/user.constants.ts @@ -2,7 +2,7 @@ import { marker as _ } from '@colsen1991/ngx-translate-extract-marker'; import { User } from './user'; -export const userHeadersAndVerboseNames: { [key in keyof User]?: any } = { +export const userHeadersAndVerboseNames: { [key in keyof User | 'gender']?: any } = { title: _(`Title`), first_name: _(`Given name`), last_name: _(`Surname`), diff --git a/client/src/app/domain/models/users/user.ts b/client/src/app/domain/models/users/user.ts index daa58839be..4389fdd324 100644 --- a/client/src/app/domain/models/users/user.ts +++ b/client/src/app/domain/models/users/user.ts @@ -29,7 +29,6 @@ export class User extends BaseDecimalModel { public readonly is_physical_person!: boolean; public readonly default_password!: string; public readonly can_change_own_password!: boolean; - public readonly gender!: string; public readonly email!: string; public readonly last_email_sent!: number; // comes in seconds public readonly last_login!: number; // comes in seconds @@ -52,6 +51,7 @@ export class User extends BaseDecimalModel { public organization_management_level!: keyof OMLMapping; public committee_management_ids!: Id[]; + public gender_id: Id; // (gender/user_ids)[] public constructor(input?: Partial) { super(User.COLLECTION, input); @@ -74,12 +74,12 @@ export class User extends BaseDecimalModel { `is_physical_person`, `default_password`, `can_change_own_password`, - `gender`, `email`, `default_vote_weight`, `last_email_sent`, `is_demo_user`, `last_login`, + `gender_id`, `organization_management_level`, `is_present_in_meeting_ids`, `committee_ids`, diff --git a/client/src/app/gateways/repositories/gender/gender-repository.service.spec.ts b/client/src/app/gateways/repositories/gender/gender-repository.service.spec.ts new file mode 100644 index 0000000000..14d24c0351 --- /dev/null +++ b/client/src/app/gateways/repositories/gender/gender-repository.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { GenderRepositoryService } from './gender-repository.service'; + +xdescribe(`GenderRepositoryService`, () => { + let service: GenderRepositoryService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(GenderRepositoryService); + }); + + it(`should be created`, () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/client/src/app/gateways/repositories/gender/gender-repository.service.ts b/client/src/app/gateways/repositories/gender/gender-repository.service.ts new file mode 100644 index 0000000000..f6c4619ea5 --- /dev/null +++ b/client/src/app/gateways/repositories/gender/gender-repository.service.ts @@ -0,0 +1,49 @@ +import { Injectable } from '@angular/core'; +import { Id } from 'src/app/domain/definitions/key-types'; +import { Identifiable } from 'src/app/domain/interfaces'; +import { Gender } from 'src/app/domain/models/gender/gender'; +import { BaseRepository } from 'src/app/gateways/repositories/base-repository'; +import { ViewGender } from 'src/app/site/pages/organization/pages/accounts/pages/gender/view-models/view-gender'; +import { Fieldsets } from 'src/app/site/services/model-request-builder'; + +import { Action } from '../../actions'; +import { RepositoryServiceCollectorService } from '../repository-service-collector.service'; +import { GenderAction } from './gender.action'; + +@Injectable({ + providedIn: `root` +}) +export class GenderRepositoryService extends BaseRepository { + public constructor(repositoryServiceCollector: RepositoryServiceCollectorService) { + super(repositoryServiceCollector, Gender); + } + + public getVerboseName = (plural?: boolean): string => (plural ? `Genders` : `Gender`); + public getTitle = (viewModel: ViewGender): string => viewModel.name; + public override getFieldsets(): Fieldsets { + const baseFields: (keyof Gender)[] = []; + const requiredFields: (keyof Gender)[] = baseFields.concat([`name`]); + return { + ...super.getFieldsets(), + required: requiredFields + }; + } + + public create(...genders: any[]): Action { + const payload = genders; + return this.createAction(GenderAction.CREATE, payload); + } + + public update(update: any, id: Id): Action { + const payload = { + id, + ...update + }; + return this.createAction(GenderAction.UPDATE, payload); + } + + public delete(...ids: Id[]): Action { + const payload = ids.map(id => ({ id })); + return this.createAction(GenderAction.DELETE, payload); + } +} diff --git a/client/src/app/gateways/repositories/gender/gender.action.ts b/client/src/app/gateways/repositories/gender/gender.action.ts new file mode 100644 index 0000000000..9707ea7e70 --- /dev/null +++ b/client/src/app/gateways/repositories/gender/gender.action.ts @@ -0,0 +1,5 @@ +export class GenderAction { + public static readonly CREATE = `gender.create`; + public static readonly UPDATE = `gender.update`; + public static readonly DELETE = `gender.delete`; +} diff --git a/client/src/app/gateways/repositories/meeting_user/meeting-user-repository.service.ts b/client/src/app/gateways/repositories/meeting_user/meeting-user-repository.service.ts index 1ff8b96974..0a9f7135e0 100644 --- a/client/src/app/gateways/repositories/meeting_user/meeting-user-repository.service.ts +++ b/client/src/app/gateways/repositories/meeting_user/meeting-user-repository.service.ts @@ -33,7 +33,8 @@ export class MeetingUserRepositoryService extends BaseMeetingRelatedRepository = [`about_me`, `user_id`, `meeting_id`]; @@ -57,7 +58,8 @@ export class MeetingUserRepositoryService extends BaseMeetingRelatedRepository val !== undefined).length > 1 && partialPayload.meeting_id) diff --git a/client/src/app/gateways/repositories/organization-repository.service.ts b/client/src/app/gateways/repositories/organization-repository.service.ts index 4ff8d2d92d..894cb0cece 100644 --- a/client/src/app/gateways/repositories/organization-repository.service.ts +++ b/client/src/app/gateways/repositories/organization-repository.service.ts @@ -44,8 +44,7 @@ export class OrganizationRepositoryService extends BaseRepository { `last_name`, `pronoun`, `username` /* Required! To getShortName */, - `gender`, + `gender_id`, `default_vote_weight`, `is_physical_person`, `is_active`, @@ -122,14 +123,15 @@ export class UserRepositoryService extends BaseRepository { const accountListFields: TypedFieldset = filterableListFields.concat([ `committee_ids`, - `committee_management_ids` + `committee_management_ids`, + `default_password` ]); const participantListFieldsMinimal: TypedFieldset = listFields.concat([`meeting_user_ids`]); const participantListFields: TypedFieldset = participantListFieldsMinimal .concat(filterableListFields) - .concat([`is_present_in_meeting_ids`, `default_password`]); + .concat([`is_present_in_meeting_ids`, `default_password`, `committee_ids`, `committee_management_ids`]); const detailFields: TypedFieldset = [`default_password`, `can_change_own_password`]; @@ -224,7 +226,7 @@ export class UserRepositoryService extends BaseRepository { email: update.email, username: update.username, pronoun: update.pronoun, - gender: update.gender + gender_id: update.gender_id }; return this.sendActionToBackend(UserAction.UPDATE_SELF, payload); } @@ -257,7 +259,7 @@ export class UserRepositoryService extends BaseRepository { is_active: partialUser.is_active, is_physical_person: partialUser.is_physical_person, default_password: partialUser.default_password, - gender: partialUser.gender, + gender_id: partialUser.gender_id, email: partialUser.email, default_vote_weight: toDecimal(partialUser.default_vote_weight, false) as any, organization_management_level: partialUser.organization_management_level, @@ -542,7 +544,8 @@ export class UserRepositoryService extends BaseRepository { `comment`, `about_me`, `number`, - `structure_level` + `structure_level`, + `locked_out` ]; if (!create) { fields.push(`member_number`); diff --git a/client/src/app/infrastructure/definitions/relations/relations.ts b/client/src/app/infrastructure/definitions/relations/relations.ts index 60e706a88e..8621a66717 100644 --- a/client/src/app/infrastructure/definitions/relations/relations.ts +++ b/client/src/app/infrastructure/definitions/relations/relations.ts @@ -21,6 +21,7 @@ import { import { ViewPollCandidate } from 'src/app/site/pages/meetings/pages/polls/view-models/view-poll-candidate'; import { ViewPollCandidateList } from 'src/app/site/pages/meetings/pages/polls/view-models/view-poll-candidate-list'; import { ViewMeetingUser } from 'src/app/site/pages/meetings/view-models/view-meeting-user'; +import { ViewGender } from 'src/app/site/pages/organization/pages/accounts/pages/gender/view-models/view-gender'; import { ViewResource } from 'src/app/site/pages/organization/pages/resources'; import { BaseViewModel, ViewModelConstructor } from '../../../site/base/base-view-model'; @@ -150,8 +151,7 @@ export const RELATIONS: Relation[] = [ OViewModel: ViewOrganization, MViewModel: ViewMeeting, OField: `template_meetings`, - MField: `template_for_organization`, - isExclusiveList: true + MField: `template_for_organization` }), ...makeM2O({ OViewModel: ViewOrganization, @@ -166,6 +166,13 @@ export const RELATIONS: Relation[] = [ AField: `theme`, BField: `theme_for_organization` }), + ...makeM2O({ + OViewModel: ViewOrganization, + MViewModel: ViewGender, + OField: `genders`, + MField: `organization`, + isFullList: true + }), // ########## Organization tags ...makeGenericM2M({ viewModel: ViewOrganizationTag, @@ -273,6 +280,12 @@ export const RELATIONS: Relation[] = [ AField: `meeting_users`, BField: `structure_levels` }), + ...makeM2O({ + MViewModel: ViewUser, + OViewModel: ViewGender, + MField: `gender`, + OField: `users` + }), // Vote delegations // vote_delegated_to_id -> vote_delegations_from_ids { diff --git a/client/src/app/openslides-main-module/services/app-load.service.ts b/client/src/app/openslides-main-module/services/app-load.service.ts index 36af52d6b5..a428945e78 100644 --- a/client/src/app/openslides-main-module/services/app-load.service.ts +++ b/client/src/app/openslides-main-module/services/app-load.service.ts @@ -17,6 +17,7 @@ import { MotionsAppConfig } from 'src/app/site/pages/meetings/pages/motions'; import { PollsAppConfig } from 'src/app/site/pages/meetings/pages/polls/polls.config'; import { ProjectorAppConfig } from 'src/app/site/pages/meetings/pages/projectors/projector.config'; import { MainMenuService } from 'src/app/site/pages/meetings/services/main-menu.service'; +import { GendersAppConfig } from 'src/app/site/pages/organization/pages/accounts/pages/gender/genders.config'; import { CollectionMapperService } from 'src/app/site/services/collection-mapper.service'; import { FallbackRoutesService } from 'src/app/site/services/fallback-routes.service'; import { ModelRequestBuilderService } from 'src/app/site/services/model-request-builder'; @@ -55,7 +56,8 @@ const appConfigs: AppConfig[] = [ MeetingSettingsAppConfig, ChatAppConfig, ActionWorkerAppConfig, - MeetingUserAppConfig + MeetingUserAppConfig, + GendersAppConfig ]; @Injectable({ diff --git a/client/src/app/site/modules/global-headbar/components/account-dialog/account-dialog.component.ts b/client/src/app/site/modules/global-headbar/components/account-dialog/account-dialog.component.ts index 8df09e61e3..ab16c596d5 100644 --- a/client/src/app/site/modules/global-headbar/components/account-dialog/account-dialog.component.ts +++ b/client/src/app/site/modules/global-headbar/components/account-dialog/account-dialog.component.ts @@ -193,10 +193,14 @@ export class AccountDialogComponent extends BaseUiComponent implements OnInit { public async saveUserChanges(): Promise { if (this.self) { + const payload = this.userPersonalForm; + if (payload.gender_id === 0) { + payload.gender_id = null; + } if (this.operator.hasPerms(Permission.userCanUpdate) && this._isUserInScope) { - await this.repo.update(this.userPersonalForm, this.self).resolve(); + await this.repo.update(payload, this.self).resolve(); } else { - await this.repo.updateSelf(this.userPersonalForm, this.self); + await this.repo.updateSelf(payload, this.self); } } this.isUserFormValid = false; diff --git a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.html b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.html index 424f6587cc..89bf0ecb00 100644 --- a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.html +++ b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.html @@ -82,14 +82,12 @@

{{ 'Personal information' | translate }}

{{ 'Gender' | translate }} - - - - @for (gender of genders; track gender) { - - {{ gender | translate }} - - } - + @@ -230,7 +228,7 @@

{{ 'Name' | translate }}

@if (user.gender) {

{{ 'Gender' | translate }}

- {{ user.gender | translate }} + {{ user.gender?.name | translate }}
} diff --git a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts index 5062731ff4..d91d12e30a 100644 --- a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts +++ b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts @@ -21,10 +21,11 @@ import { } from '@angular/forms'; import { Subscription } from 'rxjs'; import { createEmailValidator } from 'src/app/infrastructure/utils/validators/email'; +import { getGenderListSubscriptionConfig } from 'src/app/site/pages/organization/pages/accounts/pages/gender/gender.subscription'; +import { GenderControllerService } from 'src/app/site/pages/organization/pages/accounts/pages/gender/services/gender-controller.service'; import { OperatorService } from 'src/app/site/services/operator.service'; import { BaseUiComponent } from 'src/app/ui/base/base-ui-component'; -import { GENDERS } from '../../../../../domain/models/users/user'; import { ViewUser } from '../../../../../site/pages/meetings/view-models/view-user'; import { OneOfValidator } from '../../validators'; @@ -123,12 +124,12 @@ export class UserDetailViewComponent extends BaseUiComponent implements OnInit, public personalInfoForm!: UntypedFormGroup; - public genders = GENDERS; - public get isSelf(): boolean { return this.operator.operatorId === this._user?.id; } + public genderListSubscriptionConfig = getGenderListSubscriptionConfig(); + private set _initialState(state: any | null) { this._initialStateString = JSON.stringify(state); } @@ -153,6 +154,7 @@ export class UserDetailViewComponent extends BaseUiComponent implements OnInit, public constructor( private fb: UntypedFormBuilder, private operator: OperatorService, + public genderRepo: GenderControllerService, private cd: ChangeDetectorRef ) { super(); @@ -306,7 +308,7 @@ export class UserDetailViewComponent extends BaseUiComponent implements OnInit, title: [``], first_name: [``], last_name: [``], - gender: [``], + gender_id: [``], email: [``, [createEmailValidator()]], last_email_sent: [``], default_password: [``], diff --git a/client/src/app/site/modules/user-components/user-components.module.ts b/client/src/app/site/modules/user-components/user-components.module.ts index 446fb57b1f..9edd9460b6 100644 --- a/client/src/app/site/modules/user-components/user-components.module.ts +++ b/client/src/app/site/modules/user-components/user-components.module.ts @@ -14,6 +14,7 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatSelectModule } from '@angular/material/select'; import { MatTooltipModule } from '@angular/material/tooltip'; import { IconContainerModule } from 'src/app/ui/modules/icon-container'; +import { SearchSelectorModule } from 'src/app/ui/modules/search-selector'; import { OpenSlidesTranslationModule } from '../../../site/modules/translations/openslides-translation.module'; import { PasswordFormComponent } from './components/password-form/password-form.component'; @@ -51,6 +52,7 @@ const MODULES = [MatInputModule, MatMenuModule]; MatFormFieldModule, MatCardModule, MatSelectModule, + SearchSelectorModule, ...MODULES ] }) diff --git a/client/src/app/site/pages/login/pages/reset-password/components/reset-password/reset-password.component.html b/client/src/app/site/pages/login/pages/reset-password/components/reset-password/reset-password.component.html index ed268635fe..18883842af 100644 --- a/client/src/app/site/pages/login/pages/reset-password/components/reset-password/reset-password.component.html +++ b/client/src/app/site/pages/login/pages/reset-password/components/reset-password/reset-password.component.html @@ -21,7 +21,7 @@

{{ 'Enter your email to send the password reset link' | translate }}

{{ 'Reset password' | translate }}   - diff --git a/client/src/app/site/pages/login/pages/reset-password/components/reset-password/reset-password.component.scss b/client/src/app/site/pages/login/pages/reset-password/components/reset-password/reset-password.component.scss index de74b1cb92..9b71852cca 100644 --- a/client/src/app/site/pages/login/pages/reset-password/components/reset-password/reset-password.component.scss +++ b/client/src/app/site/pages/login/pages/reset-password/components/reset-password/reset-password.component.scss @@ -14,6 +14,10 @@ mat-form-field { margin-right: auto; } +.back-button { + margin-top: 30px; +} + .form-wrapper { padding-left: 30px; padding-right: 30px; diff --git a/client/src/app/site/pages/meetings/modules/meetings-component-collector/projectable-list/components/projectable-list/projectable-list.component.ts b/client/src/app/site/pages/meetings/modules/meetings-component-collector/projectable-list/components/projectable-list/projectable-list.component.ts index e667b1ba7f..c8b066bc76 100644 --- a/client/src/app/site/pages/meetings/modules/meetings-component-collector/projectable-list/components/projectable-list/projectable-list.component.ts +++ b/client/src/app/site/pages/meetings/modules/meetings-component-collector/projectable-list/components/projectable-list/projectable-list.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, ViewChild } from '@angular/core'; import { map, Observable } from 'rxjs'; import { Permission } from 'src/app/domain/definitions/permission'; import { BaseViewModel } from 'src/app/site/base/base-view-model'; @@ -8,6 +8,7 @@ import { BaseProjectableViewModel } from 'src/app/site/pages/meetings/view-model import { OperatorService } from 'src/app/site/services/operator.service'; import { ColumnRestriction, ListComponent } from 'src/app/ui/modules/list'; import { BaseListComponent } from 'src/app/ui/modules/list/base/base-list.component'; +import { ViewListComponent } from 'src/app/ui/modules/list/components/view-list/view-list.component'; import { END_POSITION, START_POSITION @@ -33,6 +34,9 @@ export class ProjectableListComponent | undefined; + /** * If a Projector column should be shown (at all) */ diff --git a/client/src/app/site/pages/meetings/modules/meetings-navigation/components/meetings-navigation-wrapper/meetings-navigation-wrapper.component.html b/client/src/app/site/pages/meetings/modules/meetings-navigation/components/meetings-navigation-wrapper/meetings-navigation-wrapper.component.html index 2f4a7f8fd3..cf8fdc79be 100644 --- a/client/src/app/site/pages/meetings/modules/meetings-navigation/components/meetings-navigation-wrapper/meetings-navigation-wrapper.component.html +++ b/client/src/app/site/pages/meetings/modules/meetings-navigation/components/meetings-navigation-wrapper/meetings-navigation-wrapper.component.html @@ -1,4 +1,4 @@ - + + @if (isLockedOutAndCanManage) { +

+ It is not allowed to set the permisson UserCanManage to a locked out user. + Please unset the lockout before adding a group with UserCanManage. +

+ }
diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/pages/participant-detail-manage/components/participant-create-wizard/participant-create-wizard.component.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/pages/participant-detail-manage/components/participant-create-wizard/participant-create-wizard.component.ts index af42444849..6b363534c2 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/pages/participant-detail-manage/components/participant-create-wizard/participant-create-wizard.component.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/pages/participant-detail-manage/components/participant-create-wizard/participant-create-wizard.component.ts @@ -5,6 +5,7 @@ import { MatStepper } from '@angular/material/stepper'; import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, distinctUntilChanged, Observable } from 'rxjs'; import { Id } from 'src/app/domain/definitions/key-types'; +import { Permission } from 'src/app/domain/definitions/permission'; import { User } from 'src/app/domain/models/users/user'; import { SearchUsersPresenterService } from 'src/app/gateways/presenter/search-users-presenter.service'; import { createEmailValidator } from 'src/app/infrastructure/utils/validators/email'; @@ -51,7 +52,8 @@ export class ParticipantCreateWizardComponent extends BaseMeetingComponent imple group_ids: [``], vote_delegations_from_ids: [``], vote_delegated_to_id: [``], - is_present: [``] + is_present: [``], + locked_out: [``] }; public get randomPasswordFn(): (() => string) | null { @@ -274,6 +276,9 @@ export class ParticipantCreateWizardComponent extends BaseMeetingComponent imple .filter((id: Id | undefined) => !!id) : [] }; + if (payload.gender_id === 0) { + payload.gender_id = null; + } if (this._accountId) { this.repo .update(payload, { @@ -319,4 +324,32 @@ export class ParticipantCreateWizardComponent extends BaseMeetingComponent imple } } } + + public get isLockedOutAndCanManage(): boolean { + const lockedOutHelper = this.personalInfoFormValue?.locked_out ?? this.user?.is_locked_out; + return lockedOutHelper && this.checkSelectedGroupsCanManage(); + } + + public get lockoutCheckboxDisabled(): boolean { + const notChanged = (this.personalInfoFormValue?.locked_out ?? null) === null; + const isLockedOut = this.user?.is_locked_out; + return notChanged && !isLockedOut && this.checkSelectedGroupsCanManage(); + } + + public updateByValueChange(event: any): void { + this.personalInfoFormValue = event; + if (this.detailView.personalInfoForm.get(`locked_out`).disabled !== this.lockoutCheckboxDisabled) { + if (this.lockoutCheckboxDisabled) { + this.detailView.personalInfoForm.get(`locked_out`).disable(); + } else { + this.detailView.personalInfoForm.get(`locked_out`).enable(); + } + } + } + + private checkSelectedGroupsCanManage(): boolean { + return (this.detailView.personalInfoForm.get(`group_ids`).value ?? []) + .map((id: Id): ViewGroup => this.groupRepo.getViewModel(id)) + .some(group => group.hasPermission(Permission.userCanManage)); + } } diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-import/definitions/index.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-import/definitions/index.ts index 663ee73b74..5959a0f947 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-import/definitions/index.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-import/definitions/index.ts @@ -8,6 +8,7 @@ export const participantHeadersAndVerboseNames: { [key in keyof GeneralUser]?: a number: `Participant number`, vote_weight: `Vote weight`, is_present: `Is present`, + locked_out: `Locked out`, comment: `Comment` }; @@ -28,6 +29,7 @@ export const participantColumns: (keyof GeneralUser)[] = [ `is_active`, `is_physical_person`, `is_present`, + `locked_out`, `saml_id`, `comment` ]; diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.html b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.html index 502a32db89..fc4fe590ce 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.html +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.html @@ -89,9 +89,6 @@

{{ 'Participants' | translate }}

@if (!user.is_physical_person) { account_balance } - @if (!user.is_active && canSeeSensitiveData) { - block - } @if (user.hasSamlId && canSeeSensitiveData) { fingerprint } @@ -179,17 +176,34 @@

{{ 'Participants' | translate }}

-
- - {{ 'Present' | translate }} - +
+
+ + {{ 'Present' | translate }} + + @if (user.is_locked_out) { +
+
+ visibility_off + {{ 'Locked out' | translate }} +
+
+ } + @if (!user.is_active && canSeeSensitiveData) { +
+
+ block + {{ 'Inactive' | translate }} +
+
+ } +
-
+ visibility_off + {{ 'Locked out' | translate }} + + +
diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.scss b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.scss index c0a2b7acaf..8045d3b939 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.scss +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.scss @@ -32,3 +32,12 @@ margin-left: 1em; z-index: 3; } + +.icon-part { + display: flex; + + span { + margin-top: 1px; + margin-left: 12px; + } +} diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.ts index 1ce9a0679e..4a5cd48a3c 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.ts @@ -210,6 +210,10 @@ export class ParticipantListComponent extends BaseMeetingListViewComponent group.hasPermission(Permission.userCanManage)) + ); + } + /** * This function opens the dialog, * where the user can quick change the groups, @@ -440,6 +463,10 @@ export class ParticipantListComponent extends BaseMeetingListViewComponent { + await this.setStateSelected(`locked_out`); + } + /** * Sets the user present * @@ -454,6 +481,22 @@ export class ParticipantListComponent extends BaseMeetingListViewComponent { + const isAllowed = this.canUpdate; + if (isAllowed) { + const title = this.isUserLockedOut(viewUser) + ? this.translate.instant(`Do you really want to include the participant back into the meeting?`) + : this.translate.instant(`Do you really want to lock this participant out of the meeting?`); + const content = viewUser.full_name; + if (await this.prompt.open(title, content)) { + this.repo.setState(`locked_out`, !this.isUserLockedOut(viewUser), viewUser); + } + } + } + public async sendInvitationEmail(viewUser: ViewUser): Promise { const title = this.translate.instant(`Are you sure you want to send an invitation email?`); const content = viewUser.full_name; @@ -498,6 +541,9 @@ export class ParticipantListComponent extends BaseMeetingListViewComponent this.filterForLockedOut(user)); + if (filteredRows.length > 0) { + await this.repo.setState(field, value, ...filteredRows); + } + const missing = this.selectedRows.length - filteredRows.length; + if (missing > 0) { + this.matSnackBar.open( + this.translate + .instant(`%num% participants could not be locked out, because of missing permissions.`) + .replace(`%num%`, missing), + this.translate.instant(`Ok`), + { duration: 3000 } + ); + } } else { await this.repo.setState(field, value, ...this.selectedRows); } diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/services/participant-list-filter/participant-list-filter.service.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/services/participant-list-filter/participant-list-filter.service.ts index 350616c014..898bfe0b16 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/services/participant-list-filter/participant-list-filter.service.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/services/participant-list-filter/participant-list-filter.service.ts @@ -1,13 +1,13 @@ import { Injectable } from '@angular/core'; import { marker as _ } from '@colsen1991/ngx-translate-extract-marker'; import { Permission } from 'src/app/domain/definitions/permission'; -import { GENDER_FITLERABLE, GENDERS } from 'src/app/domain/models/users/user'; import { OsFilter, OsHideFilterSetting } from 'src/app/site/base/base-filter.service'; import { BaseMeetingFilterListService } from 'src/app/site/pages/meetings/base/base-meeting-filter-list.service'; import { MeetingActiveFiltersService } from 'src/app/site/pages/meetings/services/meeting-active-filters.service'; import { MeetingSettingsService } from 'src/app/site/pages/meetings/services/meeting-settings.service'; import { DelegationType } from 'src/app/site/pages/meetings/view-models/delegation-type'; import { ViewUser } from 'src/app/site/pages/meetings/view-models/view-user'; +import { GenderControllerService } from 'src/app/site/pages/organization/pages/accounts/pages/gender/services/gender-controller.service'; import { OperatorService } from 'src/app/site/services/operator.service'; import { GroupControllerService } from '../../../../modules/groups/services/group-controller.service'; @@ -35,6 +35,12 @@ export class ParticipantListFilterService extends BaseMeetingFilterListService = { + property: `gender_id`, + label: _(`Gender`), + options: [] + }; + private _voteWeightEnabled: boolean; private _voteDelegationEnabled: boolean; @@ -42,6 +48,7 @@ export class ParticipantListFilterService extends BaseMeetingFilterListService (this._voteWeightEnabled = value)); this.meetingSettings .get(`users_enable_vote_delegations`) @@ -73,6 +85,14 @@ export class ParticipantListFilterService extends BaseMeetingFilterListService { { property: [`first_name`, `last_name`], label: _(`Given name`) }, { property: [`last_name`, `first_name`], label: _(`Surname`) }, { property: `is_present_in_meeting_ids`, label: _(`Presence`) }, + { property: `is_locked_out`, label: _(`Locked Out`) }, { property: `member_number`, label: _(`Membership number`) }, + { property: `gender_name`, label: _(`Gender`) }, { property: `is_active`, label: _(`Is active`) }, { property: `is_physical_person`, label: _(`Is a natural person`) }, { property: `number`, label: _(`Participant number`), foreignBaseKeys: { meeting_user: [`number`] } }, @@ -83,6 +85,10 @@ export class ParticipantListSortService extends BaseSortListService { { property: `last_login`, shouldHideFn: () => !this.operator.hasPerms(Permission.userCanUpdate) + }, + { + property: `is_locked_out`, + shouldHideFn: () => !this.operator.hasPerms(Permission.userCanSeeSensitiveData) } ]; } diff --git a/client/src/app/site/pages/meetings/pages/participants/participants.subscription.ts b/client/src/app/site/pages/meetings/pages/participants/participants.subscription.ts index 5187a92018..66709e2d1d 100644 --- a/client/src/app/site/pages/meetings/pages/participants/participants.subscription.ts +++ b/client/src/app/site/pages/meetings/pages/participants/participants.subscription.ts @@ -62,20 +62,28 @@ export const getParticipantIsPresentSubscriptionConfig: SubscriptionConfigGenera subscriptionName: PARTICIPANT_IS_PRESENT_LIST_SUBSCRIPTION }); -export const getParticipantListSubscriptionConfig: SubscriptionConfigGenerator = (id: Id) => ({ - modelRequest: { - viewModelCtor: ViewMeeting, - ids: [id], - follow: [ - { - idField: `meeting_user_ids`, - fieldset: `participantListMinimal`, - follow: [{ idField: `user_id`, fieldset: `participantList` }] - } - ] - }, - subscriptionName: PARTICIPANT_LIST_SUBSCRIPTION -}); +export const getParticipantListSubscriptionConfig: SubscriptionConfigGenerator = (id: Id) => { + return { + modelRequest: { + viewModelCtor: ViewMeeting, + ids: [id], + follow: [ + { + idField: `meeting_user_ids`, + fieldset: `participantListMinimal`, + follow: [ + { + idField: `user_id`, + fieldset: `participantList`, + follow: [{ idField: `gender_id`, fieldset: [`name`] }] + } + ] + } + ] + }, + subscriptionName: PARTICIPANT_LIST_SUBSCRIPTION + }; +}; export const getParticipantMinimalSubscriptionConfig: SubscriptionConfigGenerator = (id: Id) => ({ modelRequest: { @@ -89,7 +97,13 @@ export const getParticipantMinimalSubscriptionConfig: SubscriptionConfigGenerato { idField: `user_id`, fieldset: `participantListMinimal`, - additionalFields: [`is_present_in_meeting_ids`] + additionalFields: [`is_present_in_meeting_ids`], + follow: [ + { + idField: `gender_id`, + fieldset: [`name`] + } + ] }, { idField: `structure_level_ids`, fieldset: [`name`] } ] @@ -108,6 +122,10 @@ export const getParticipantDetailSubscription: SubscriptionConfigGenerator = (id { idField: `meeting_user_ids`, fieldset: DEFAULT_FIELDSET + }, + { + idField: `gender_id`, + fieldset: [`name`] } ] }, diff --git a/client/src/app/site/pages/meetings/pages/participants/services/common/participant-controller.service/participant-controller.service.ts b/client/src/app/site/pages/meetings/pages/participants/services/common/participant-controller.service/participant-controller.service.ts index 25040c381c..8ef5d05c3c 100644 --- a/client/src/app/site/pages/meetings/pages/participants/services/common/participant-controller.service/participant-controller.service.ts +++ b/client/src/app/site/pages/meetings/pages/participants/services/common/participant-controller.service/participant-controller.service.ts @@ -50,7 +50,8 @@ export const MEETING_RELATED_FORM_CONTROLS = [ `group_ids`, `vote_delegations_from_ids`, `vote_delegated_to_id`, - `is_present` + `is_present`, + `locked_out` ]; @Injectable({ @@ -244,6 +245,16 @@ export class ParticipantControllerService extends BaseMeetingControllerService { + this.repo.preventAlterationOnDemoUsers(users); + const payload: any[] = users.map(user => ({ + id: user.id, + meeting_id: this.activeMeetingId, + locked_out: locked_out + })); + return this.actions.create({ action: UserAction.UPDATE, data: payload }); + } + public async removeUsersFromMeeting( users: ViewUser[], meeting: ViewMeeting = this.activeMeeting @@ -347,7 +358,8 @@ export class ParticipantControllerService extends BaseMeetingControllerService /* implements Searchable */ { return this.isPresentInMeeting(); } + public get is_locked_out(): boolean { + return this.isLockedOutOfMeeting(); + } + public get hasMemberNumber(): boolean { return !!this.member_number; } + public get gender_name(): string { + return this.gender?.name ?? ``; + } + // Will be set by the repository public getName!: () => string; public getShortName!: () => string; @@ -134,14 +143,32 @@ export class ViewUser extends BaseViewModel /* implements Searchable */ { return this.is_present_in_meeting_ids?.includes(meetingId) || false; } + /** + * @param meetingId The meeting id. If not provided, tha active meeting id is used. + * If there is no active meeting, an error will be thrown. + * @returns if the user is locked out of the given meeting + */ + public isLockedOutOfMeeting(meetingId?: Id): boolean { + return this.getMeetingUser(meetingId || this.getEnsuredActiveMeetingId())?.locked_out || false; + } + public get hasMultipleMeetings(): boolean { + if (this.meeting_users?.length) { + return this.meeting_users.filter(mu => !mu.locked_out).length !== 1; + } + return this.meeting_ids?.length !== 1; // In case of `0` it should not return `true` } public get onlyMeeting(): Id { - const meetingAmount = this.meeting_ids?.length || 0; + let meetingIds = this.meeting_ids || []; + if (this.meeting_users?.length) { + meetingIds = this.ensuredMeetingIds; + } + + const meetingAmount = meetingIds.length; if (meetingAmount === 1) { - return this.meeting_ids[0]; + return meetingIds[0]; } else if (meetingAmount > 1) { throw new Error(`User has multiple meetings`); } else if (meetingAmount === 0) { @@ -155,7 +182,11 @@ export class ViewUser extends BaseViewModel /* implements Searchable */ { * Returns all meetings that the user actually has group memberships for. */ public get ensuredMeetingIds(): number[] { - return this.meeting_users.filter(mUser => mUser.group_ids?.length).map(mUser => mUser.meeting_id) || []; + return ( + this.meeting_users + .filter(mUser => mUser.group_ids?.length && !mUser.locked_out) + .map(mUser => mUser.meeting_id) || [] + ); } public hasVoteRightFromOthers(meetingId?: Id): boolean { @@ -338,6 +369,7 @@ interface IUserRelations { options: ViewOption[]; votes: ViewVote[]; poll_candidates: ViewPollCandidate[]; + gender?: ViewGender; } export interface ViewUser extends User, ViewModelRelations {} diff --git a/client/src/app/site/pages/organization/pages/accounts/accounts-routing.module.ts b/client/src/app/site/pages/organization/pages/accounts/accounts-routing.module.ts index 461452d1c9..a6d96dcc3a 100644 --- a/client/src/app/site/pages/organization/pages/accounts/accounts-routing.module.ts +++ b/client/src/app/site/pages/organization/pages/accounts/accounts-routing.module.ts @@ -39,6 +39,11 @@ const routes: Routes = [ loadChildren: () => import(`./pages/account-import/account-import.module`).then(m => m.AccountImportModule) }, + { + path: `genders`, + loadChildren: () => + import(`./pages/gender/pages/gender-list/gender-list.module`).then(m => m.GenderListModule) + }, { path: `:id`, loadChildren: () => diff --git a/client/src/app/site/pages/organization/pages/accounts/accounts.subscription.ts b/client/src/app/site/pages/organization/pages/accounts/accounts.subscription.ts index 6f4a0ae2ee..05a6e96736 100644 --- a/client/src/app/site/pages/organization/pages/accounts/accounts.subscription.ts +++ b/client/src/app/site/pages/organization/pages/accounts/accounts.subscription.ts @@ -18,7 +18,8 @@ export const getAccountDetailSubscriptionConfig: SubscriptionConfigGenerator = ( idField: `meeting_ids`, follow: [{ idField: `group_ids`, fieldset: [`name`], isFullList: false }], fieldset: [`name`, `committee_id`] - } + }, + { idField: `gender_id`, fieldset: [`name`] } ] }, subscriptionName: ACCOUNT_DETAIL_SUBSCRIPTION_NAME diff --git a/client/src/app/site/pages/organization/pages/accounts/components/account-main/account-main.component.ts b/client/src/app/site/pages/organization/pages/accounts/components/account-main/account-main.component.ts index b173d852e4..b228ec9c4a 100644 --- a/client/src/app/site/pages/organization/pages/accounts/components/account-main/account-main.component.ts +++ b/client/src/app/site/pages/organization/pages/accounts/components/account-main/account-main.component.ts @@ -25,6 +25,10 @@ const accountListSubsciptionContent = { follow: [{ idField: `committee_id`, fieldset: [`manager_ids`] }] } ] + }, + { + idField: `gender_id`, + fieldset: [`name`] } ] }; @@ -80,6 +84,10 @@ export class AccountMainComponent extends BaseModelRequestHandlerComponent { fieldset: [`name`] } ] + }, + { + idField: `gender_ids`, + fieldset: [`name`] } ] }, diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts index e1d9456dee..dc6c9b7df6 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts @@ -333,6 +333,13 @@ export class AccountDetailComponent extends BaseComponent implements OnInit { payload.member_number = null; } } + if (payload.gender_id === 0) { + if (isCreate) { + delete payload.gender_id; + } else { + payload.gender_id = null; + } + } return payload; } diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-import/components/account-import-list/account-import-list.component.ts b/client/src/app/site/pages/organization/pages/accounts/pages/account-import/components/account-import-list/account-import-list.component.ts index 6246b34338..5e90daee76 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-import/components/account-import-list/account-import-list.component.ts +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-import/components/account-import-list/account-import-list.component.ts @@ -1,6 +1,5 @@ import { Component } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { map, Observable } from 'rxjs'; import { BaseViaBackendImportListComponent } from 'src/app/site/base/base-via-backend-import-list.component'; import { OrganizationSettingsService } from 'src/app/site/pages/organization/services/organization-settings.service'; import { ImportListHeaderDefinition } from 'src/app/ui/modules/import-list'; @@ -19,8 +18,7 @@ export class AccountImportListComponent extends BaseViaBackendImportListComponen public columns: ImportListHeaderDefinition[] = this.possibleFields.map(header => ({ property: header, label: (accountHeadersAndVerboseNames)[header], - isTableColumn: true, - customInfo: header === `gender` ? this.getTranslatedGenderInfoObservable() : undefined + isTableColumn: true })); public constructor( @@ -30,10 +28,4 @@ export class AccountImportListComponent extends BaseViaBackendImportListComponen ) { super(importer); } - - private getTranslatedGenderInfoObservable(): Observable { - return this.translate - .get(`Possible options`) - .pipe(map(framework => framework + `: ` + this.orgaSettings.instant(`genders`).join(`, `))); - } } diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-import/definitions/index.ts b/client/src/app/site/pages/organization/pages/accounts/pages/account-import/definitions/index.ts index 5a12b341ce..a4b9dae215 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-import/definitions/index.ts +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-import/definitions/index.ts @@ -2,12 +2,12 @@ import { marker as _ } from '@colsen1991/ngx-translate-extract-marker'; import { User } from 'src/app/domain/models/users/user'; import { userHeadersAndVerboseNames } from 'src/app/domain/models/users/user.constants'; -export const accountHeadersAndVerboseNames: { [key in keyof User]?: any } = { +export const accountHeadersAndVerboseNames: { [key in keyof User | 'gender']?: any } = { ...userHeadersAndVerboseNames, default_vote_weight: _(`Vote weight`) }; -export const accountColumns: (keyof User)[] = [ +export const accountColumns: (keyof User | 'gender')[] = [ `title`, `first_name`, `last_name`, diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html index 5d4cda3ea6..5c16228953 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html @@ -175,6 +175,10 @@

cloud_upload {{ 'Import' | translate }} +

} @if (isMultiSelect) { diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/services/account-list-sort.service/account-sort.service.ts b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/services/account-list-sort.service/account-sort.service.ts index 18cd39a820..a4351d3e94 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/services/account-list-sort.service/account-sort.service.ts +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/services/account-list-sort.service/account-sort.service.ts @@ -21,7 +21,7 @@ export class AccountSortService extends BaseSortListService { { property: `member_number`, label: _(`Membership number`) }, { property: `is_active`, label: _(`Is active`) }, { property: `default_vote_weight`, label: _(`Vote weight`) }, - { property: `gender`, label: _(`Gender`) }, + { property: `gender_name`, label: _(`Gender`) }, { property: `id`, label: _(`Sequential number`) }, { property: `numberOfMeetings`, label: _(`Amount of meetings`), baseKeys: [`meeting_ids`] }, { property: `last_email_sent`, label: _(`Last email sent`) }, diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/gender.subscription.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/gender.subscription.ts new file mode 100644 index 0000000000..46095f87e9 --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/gender.subscription.ts @@ -0,0 +1,20 @@ +import { SubscriptionConfigGenerator } from 'src/app/domain/interfaces/subscription-config'; + +import { ORGANIZATION_ID } from '../../../../services/organization.service'; +import { ViewOrganization } from '../../../../view-models/view-organization'; + +export const GENDER_LIST_SUBSCRIPTION = `gender_list`; + +export const getGenderListSubscriptionConfig: SubscriptionConfigGenerator = () => ({ + modelRequest: { + viewModelCtor: ViewOrganization, + ids: [ORGANIZATION_ID], + follow: [ + { + idField: `gender_ids`, + fieldset: [`name`] + } + ] + }, + subscriptionName: GENDER_LIST_SUBSCRIPTION +}); diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/genders.config.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/genders.config.ts new file mode 100644 index 0000000000..d6e066b207 --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/genders.config.ts @@ -0,0 +1,16 @@ +import { Gender } from 'src/app/domain/models/gender/gender'; +import { GenderRepositoryService } from 'src/app/gateways/repositories/gender/gender-repository.service'; +import { AppConfig } from 'src/app/infrastructure/definitions/app-config'; + +import { ViewGender } from './view-models/view-gender'; + +export const GendersAppConfig: AppConfig = { + name: `gender`, + models: [ + { + model: Gender, + viewModel: ViewGender, + repository: GenderRepositoryService + } + ] +}; diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.html new file mode 100644 index 0000000000..1ac27a692a --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.html @@ -0,0 +1,113 @@ + + +
+

{{ 'Genders' | translate }}

+
+ + + + + + + + + + {{ selectedRows.length }} {{ 'selected' | translate }} + +
+ + +
+
+ {{ gender.name }} +
+
+
+ @if (gender.id > 4 && !isMultiSelect) { + + } +
+
+ @if (gender.id > 4 && !isMultiSelect) { + + } +
+
+ + + @if (!isMultiSelect) { +
+ +
+ } @else { +
+ + + + +
+ } +
+ + + +

+ {{ 'Gender' | translate }} +

+ +
+ + + {{ 'Name' | translate }} + + + {{ 'A name is required' | translate }} + + +
+
+ + + + + +
diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.scss b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.spec.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.spec.ts new file mode 100644 index 0000000000..9466069a2a --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GenderListComponent } from './gender-list.component'; + +xdescribe(`GenderListComponent`, () => { + let component: GenderListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GenderListComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(GenderListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it(`should create`, () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.ts new file mode 100644 index 0000000000..f9eacb4b43 --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/components/gender-list/gender-list.component.ts @@ -0,0 +1,122 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, TemplateRef, ViewChild } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { TranslateService } from '@ngx-translate/core'; +import { infoDialogSettings } from 'src/app/infrastructure/utils/dialog-settings'; +import { BaseListViewComponent } from 'src/app/site/base/base-list-view.component'; +import { PromptService } from 'src/app/ui/modules/prompt-dialog'; + +import { GenderControllerService } from '../../../../services/gender-controller.service'; +import { ViewGender } from '../../../../view-models/view-gender'; + +@Component({ + selector: `os-gender-list`, + templateUrl: `./gender-list.component.html`, + styleUrl: `./gender-list.component.scss`, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class GenderListComponent extends BaseListViewComponent { + @ViewChild(`genderDialog`, { static: true }) + private genderDialog: TemplateRef | null = null; + + private dialogRef: MatDialogRef | null = null; + + /** + * Holds the create form + */ + public genderForm: UntypedFormGroup; + + /** + * Check in multiselect if a default gender is selected + */ + public get hasDefaultGenderSelected(): boolean { + return this.selectedRows.filter(view => view.id <= 4).length > 0; + } + + private currentGender: ViewGender; + + public constructor( + protected override translate: TranslateService, + public repo: GenderControllerService, + private dialog: MatDialog, + private formBuilder: UntypedFormBuilder, + private cd: ChangeDetectorRef, + private promptService: PromptService + ) { + super(); + this.setTitle(`Genders`); + this.canMultiSelect = true; + this.genderForm = this.formBuilder.group({ + name: [``, Validators.required] + }); + } + + public openGenderDialog(gender?: ViewGender): void { + this.currentGender = gender; + this.genderForm.reset(); + this.genderForm.get(`name`)!.setValue(gender ? gender.name : ``); + this.dialogRef = this.dialog.open(this.genderDialog!, infoDialogSettings); + this.dialogRef.afterClosed().subscribe(res => { + if (res) { + this.save(); + } + }); + } + + public async deleteGenders(...genders: ViewGender[]): Promise { + const title = + genders.length === 1 + ? this.translate.instant(`Are you sure you want to delete this gender?`) + : this.translate.instant(`Are you sure you want to delete all selected genders?`); + const content = genders.length === 1 ? genders[0].name : ``; + if (await this.promptService.open(title, content)) { + const deleteGenderIds = genders.map(g => g.id).filter(id => id > 4); + if (deleteGenderIds) { + return this.repo.delete(...deleteGenderIds).then(() => this.cd.detectChanges()); + } + } + } + + public deleteSelectedGenders(): void { + this.deleteGenders(...this.selectedRows); + } + + /** + * clicking Enter will save automatically + * clicking Escape will cancel the process + * + * @param event has the code + */ + public onKeyDown(event: KeyboardEvent): void { + if (event.key === `Enter`) { + this.save(); + this.dialogRef!.close(); + } + if (event.key === `Escape`) { + this.dialogRef!.close(); + } + } + + private updateGenderHelper(): void { + if (this.currentGender) { + const data = this.genderForm.value; + this.repo.update(data, this.currentGender.id); + } + } + + private createGenderHelper(): void { + this.repo.create(this.genderForm.value); + } + + private save(): void { + if (!this.genderForm.value || !this.genderForm.valid) { + return; + } + if (this.currentGender) { + this.updateGenderHelper(); + } else { + this.createGenderHelper(); + } + this.genderForm.reset(); + } +} diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/gender-list-routing.module.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/gender-list-routing.module.ts new file mode 100644 index 0000000000..213ae3f90d --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/gender-list-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { GenderListComponent } from './components/gender-list/gender-list.component'; + +const routes: Routes = [ + { + path: ``, + component: GenderListComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class GenderListRoutingModule {} diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/gender-list.module.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/gender-list.module.ts new file mode 100644 index 0000000000..e2497b8d1f --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/pages/gender-list/gender-list.module.ts @@ -0,0 +1,43 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { OpenSlidesTranslationModule } from 'src/app/site/modules/translations'; +import { ChipModule } from 'src/app/ui/modules/chip'; +import { HeadBarModule } from 'src/app/ui/modules/head-bar/head-bar.module'; +import { ListModule } from 'src/app/ui/modules/list'; +import { PromptDialogModule } from 'src/app/ui/modules/prompt-dialog'; + +import { GenderListComponent } from './components/gender-list/gender-list.component'; +import { GenderListRoutingModule } from './gender-list-routing.module'; + +@NgModule({ + declarations: [GenderListComponent], + imports: [ + CommonModule, + GenderListRoutingModule, + PromptDialogModule, + HeadBarModule, + ListModule, + ChipModule, + OpenSlidesTranslationModule.forChild(), + MatIconModule, + MatMenuModule, + MatButtonModule, + MatDividerModule, + MatDialogModule, + MatInputModule, + FormsModule, + ReactiveFormsModule, + MatFormFieldModule, + MatTooltipModule + ] +}) +export class GenderListModule {} diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/services/gender-controller.service.spec.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/services/gender-controller.service.spec.ts new file mode 100644 index 0000000000..96f3ff757b --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/services/gender-controller.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { GenderControllerService } from './gender-controller.service'; + +xdescribe(`GenderControllerService`, () => { + let service: GenderControllerService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(GenderControllerService); + }); + + it(`should be created`, () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/services/gender-controller.service.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/services/gender-controller.service.ts new file mode 100644 index 0000000000..9e3e895f97 --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/services/gender-controller.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; +import { Id } from 'src/app/domain/definitions/key-types'; +import { Gender } from 'src/app/domain/models/gender/gender'; +import { GenderRepositoryService } from 'src/app/gateways/repositories/gender/gender-repository.service'; +import { BaseController } from 'src/app/site/base/base-controller'; +import { ControllerServiceCollectorService } from 'src/app/site/services/controller-service-collector.service'; + +import { ViewGender } from '../view-models/view-gender'; + +@Injectable({ + providedIn: `root` +}) +export class GenderControllerService extends BaseController { + public constructor( + controllerServiceCollector: ControllerServiceCollectorService, + protected override repo: GenderRepositoryService + ) { + super(controllerServiceCollector, Gender, repo); + } + + public create(...models: Partial[]): void { + this.repo.create(...models).resolve(); + } + + public update(update: Partial, viewGenderId: Id): void { + this.repo.update(update, viewGenderId).resolve(); + } + + public delete(...ids: Id[]): Promise { + return this.repo.delete(...ids).resolve(); + } +} diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/gender/view-models/view-gender.ts b/client/src/app/site/pages/organization/pages/accounts/pages/gender/view-models/view-gender.ts new file mode 100644 index 0000000000..620aa52b40 --- /dev/null +++ b/client/src/app/site/pages/organization/pages/accounts/pages/gender/view-models/view-gender.ts @@ -0,0 +1,19 @@ +import { Gender } from 'src/app/domain/models/gender/gender'; +import { BaseViewModel } from 'src/app/site/base/base-view-model'; +import { ViewUser } from 'src/app/site/pages/meetings/view-models/view-user'; +import { ViewOrganization } from 'src/app/site/pages/organization/view-models/view-organization'; + +export class ViewGender extends BaseViewModel { + public static readonly COLLECTION = Gender.COLLECTION; + protected _collection = Gender.COLLECTION; + + public get gender(): Gender { + return this._model; + } +} + +interface IGenderRelations { + organization: ViewOrganization; + users: ViewUser[]; +} +export interface ViewGender extends Gender, IGenderRelations {} diff --git a/client/src/app/site/pages/organization/pages/accounts/services/common/account-filter.service.ts b/client/src/app/site/pages/organization/pages/accounts/services/common/account-filter.service.ts index 70d6692fc3..4ee1462367 100644 --- a/client/src/app/site/pages/organization/pages/accounts/services/common/account-filter.service.ts +++ b/client/src/app/site/pages/organization/pages/accounts/services/common/account-filter.service.ts @@ -10,6 +10,8 @@ import { ActiveFiltersService } from 'src/app/site/services/active-filters.servi import { OperatorService } from 'src/app/site/services/operator.service'; import { UserControllerService } from 'src/app/site/services/user-controller.service'; +import { GenderControllerService } from '../../pages/gender/services/gender-controller.service'; + type Email = string; type Name = string; @@ -24,6 +26,12 @@ export class AccountFilterService extends BaseFilterListService { private userNameMap = new Map(); private userInMeetingMap = new Map(); + private genderFilterOption: OsFilter = { + property: `gender_id`, + label: _(`Gender`), + options: [] + }; + /** * @return Observable data for the filtered output subject */ @@ -55,13 +63,19 @@ export class AccountFilterService extends BaseFilterListService { store: ActiveFiltersService, private operator: OperatorService, private controller: UserControllerService, - private meetingRepo: MeetingControllerService + private meetingRepo: MeetingControllerService, + private genderRepo: GenderControllerService ) { super(store); this.controller.getViewModelListObservable().subscribe(users => { this.updateUserMaps(users); }); + this.updateFilterForRepo({ + repo: genderRepo, + filter: this.genderFilterOption, + noneOptionLabel: _(`not specified`) + }); } public filterMeeting(id: Id): void { @@ -131,17 +145,7 @@ export class AccountFilterService extends BaseFilterListService { { condition: [false, null], label: _(`Is no natural person`) } ] }, - { - property: `gender`, - label: _(`Gender`), - options: [ - { condition: `female`, label: _(`female`) }, - { condition: `male`, label: _(`male`) }, - { condition: `diverse`, label: _(`diverse`) }, - { condition: `non-binary`, label: _(`non-binary`) }, - { condition: null, label: _(`not specified`) } - ] - }, + this.genderFilterOption, { property: `hasEmail`, label: _(`Email address`), diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html index 96afe96fc2..f9d9f1df05 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html @@ -158,12 +158,19 @@

{{ 'Calendar' | translate }}

[ngClass]="context?.cssClass" [routerLink]="meeting.id" > - @if (meeting.locked_from_inside) { - lock - }
-
{{ meeting.name }}
-
+
+ +
{{ meeting.name }}
+
+
+
@if (meeting.location) { {{ meeting.location }} } @@ -183,12 +190,11 @@

{{ 'Calendar' | translate }}

} @else {
- @if (meeting.locked_from_inside) { - lock - }
- {{ meeting.name }} + +
{{ meeting.name }}
+
@if (meeting.location) { diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.scss b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.scss index 95313c9d24..865250a2b5 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.scss +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.scss @@ -134,6 +134,12 @@ os-dashboard { } } + .show-lock-icon { + mat-icon { + display: inline-block !important; + } + } + .orga-information { width: calc(100% - 128px); @@ -298,4 +304,12 @@ os-dashboard { } } } + + .align-w-title-if-locked { + padding-left: 25px; + } + + .align-w-title-if-not-locked { + padding-left: 6px; + } } diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/dashboard-detail.module.ts b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/dashboard-detail.module.ts index 102aefca06..595dc76d92 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/dashboard-detail.module.ts +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/dashboard-detail.module.ts @@ -11,6 +11,7 @@ import { OpenSlidesTranslationModule } from 'src/app/site/modules/translations'; import { HeadBarModule } from 'src/app/ui/modules/head-bar'; import { MeetingTimeModule } from 'src/app/ui/modules/meeting-time/meeting-time.module'; +import { IconContainerModule } from '../../../../../../../ui/modules/icon-container/icon-container.module'; import { DashboardComponent } from './components/dashboard/dashboard.component'; import { DashboardDetailRoutingModule } from './dashboard-detail-routing.module'; @@ -28,7 +29,8 @@ import { DashboardDetailRoutingModule } from './dashboard-detail-routing.module' ScrollingModule, HeadBarModule, MeetingTimeModule, - OpenSlidesTranslationModule.forChild() + OpenSlidesTranslationModule.forChild(), + IconContainerModule ] }) export class DashboardDetailModule {} diff --git a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.html b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.html index 6d3f7cc03c..36e2f5a324 100644 --- a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.html +++ b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.html @@ -78,7 +78,14 @@

{{ 'Meetings' | translate }}

@if (meeting.location || meeting.start_time || meeting.end_time) { -
+ @let numIcons = meeting.isArchived + meeting.isTemplate + !!meeting.locked_from_inside; +
@if (meeting.location) { {{ meeting.location }} } diff --git a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.scss b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.scss index 26570fcc42..b402899f9b 100644 --- a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.scss +++ b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.scss @@ -18,3 +18,11 @@ .no-access { cursor: auto; } + +.align-w-title-w-one-icon { + padding-left: 17px; +} + +.align-w-title-w-two-icon { + padding-left: 33px; +} diff --git a/client/src/app/site/pages/organization/view-models/view-organization.ts b/client/src/app/site/pages/organization/view-models/view-organization.ts index b8e782af08..227d7f941b 100644 --- a/client/src/app/site/pages/organization/view-models/view-organization.ts +++ b/client/src/app/site/pages/organization/view-models/view-organization.ts @@ -4,6 +4,7 @@ import { BaseViewModel, ViewModelRelations } from '../../../base/base-view-model import { ViewMediafile } from '../../meetings/pages/mediafiles'; import { ViewMeeting } from '../../meetings/view-models/view-meeting'; import { ViewUser } from '../../meetings/view-models/view-user'; +import { ViewGender } from '../pages/accounts/pages/gender/view-models/view-gender'; import { ViewCommittee } from '../pages/committees'; import { ViewTheme } from '../pages/designs'; import { ViewOrganizationTag } from '../pages/organization-tags'; @@ -27,6 +28,7 @@ interface IOrganizationRelations { theme: ViewTheme; themes: ViewTheme[]; users: ViewUser[]; + genders: ViewGender[]; published_mediafiles: ViewMediafile[]; } export interface ViewOrganization extends Organization, ViewModelRelations {} diff --git a/client/src/app/site/services/autoupdate/autoupdate.service.ts b/client/src/app/site/services/autoupdate/autoupdate.service.ts index 039170da04..d8644f9c7f 100644 --- a/client/src/app/site/services/autoupdate/autoupdate.service.ts +++ b/client/src/app/site/services/autoupdate/autoupdate.service.ts @@ -269,7 +269,7 @@ export class AutoupdateService { } = {}; for (const id of requestIds) { - const { modelRequest } = this._activeRequestObjects[id]; + const modelRequest = this._activeRequestObjects[id]?.modelRequest; if (modelRequest) { for (const key of Object.keys(autoupdateData)) { const data = key.split(`/`); diff --git a/client/src/app/site/services/model-request-builder/model-request-builder.service.ts b/client/src/app/site/services/model-request-builder/model-request-builder.service.ts index 13cbfc6083..e216ffaa22 100644 --- a/client/src/app/site/services/model-request-builder/model-request-builder.service.ts +++ b/client/src/app/site/services/model-request-builder/model-request-builder.service.ts @@ -168,7 +168,7 @@ export class ModelRequestBuilderService { } } - private addFollowedRelations(modelRequestObject: ModelRequestObject): void { + private addFollowedRelations(modelRequestObject: ModelRequestObject, skipUnknownRelations = false): void { for (const entry of modelRequestObject.simplifiedRequest.follow || []) { let follow: Follow; if (typeof entry === `string`) { @@ -178,7 +178,13 @@ export class ModelRequestBuilderService { } else { follow = entry; } - this.getFollowedRelation(modelRequestObject, follow); + try { + this.getFollowedRelation(modelRequestObject, follow); + } catch (e) { + if (!skipUnknownRelations || !(e instanceof UnknownRelationError)) { + throw e; + } + } } } @@ -288,19 +294,9 @@ export class ModelRequestBuilderService { // Add relations if (request.follow) { for (const viewModel of possibleViewModels) { - try { - // The last to write to fields will win... - const modelRequestObject = new ModelRequestObject(viewModel.COLLECTION, request, fields); - this.addFollowedRelations(modelRequestObject); - } catch (e) { - if (e instanceof UnknownRelationError) { - // Explicitly allow following relations for only a subset of foreign models - // of this relation. If a specific relation cannot be found, just do not request it. - // This will succeed for the subset of models, that do have the requested relation. - continue; - } - throw e; - } + // The last to write to fields will win... + const modelRequestObject = new ModelRequestObject(viewModel.COLLECTION, request, fields); + this.addFollowedRelations(modelRequestObject, true); } } } diff --git a/client/src/app/site/services/openslides-router.service.ts b/client/src/app/site/services/openslides-router.service.ts index 0edb80c623..d862ef8490 100644 --- a/client/src/app/site/services/openslides-router.service.ts +++ b/client/src/app/site/services/openslides-router.service.ts @@ -76,6 +76,11 @@ export class OpenSlidesRouterService { .subscribe(event => this._currentParamMap.next(event)); activeMeetingIdService.meetingIdChanged.subscribe(event => console.log(`has meeting changed?`, event)); + this.operator.operatorUpdated.subscribe(() => { + if (!this.operator.knowsMultipleMeetings && !this.activeMeetingIdService.meetingId) { + this.checkCurrentRouteGuards(); + } + }); this.operator.permissionsObservable .pipe( filter(v => !!v), diff --git a/client/src/app/site/services/operator.service.ts b/client/src/app/site/services/operator.service.ts index c08370be67..86e50c095d 100644 --- a/client/src/app/site/services/operator.service.ts +++ b/client/src/app/site/services/operator.service.ts @@ -364,7 +364,7 @@ export class OperatorService { } public isInMeeting(meetingId: Id): boolean { - return this.user.meeting_ids?.includes(meetingId) || false; + return this.user.ensuredMeetingIds?.includes(meetingId) || false; } private updateUser(user: ViewUser): void { diff --git a/client/src/app/site/services/reroute.service.ts b/client/src/app/site/services/reroute.service.ts index 4808f9a2c4..3dc274c9f7 100644 --- a/client/src/app/site/services/reroute.service.ts +++ b/client/src/app/site/services/reroute.service.ts @@ -38,7 +38,7 @@ export class RerouteService { const fallbackRoute = this.fallbackRoutesService.getFallbackRoute(); if (fallbackRoute && (this.operator.user || fallbackMeetingId)) { return this.router.createUrlTree([ - fallbackMeetingId ?? this.operator.user.meeting_ids[0], + fallbackMeetingId ?? this.operator.user.ensuredMeetingIds[0], fallbackRoute ]); } diff --git a/client/src/app/ui/modules/editor/components/editor/editor.component.scss b/client/src/app/ui/modules/editor/components/editor/editor.component.scss index 7b30fbdc98..78a8012902 100644 --- a/client/src/app/ui/modules/editor/components/editor/editor.component.scss +++ b/client/src/app/ui/modules/editor/components/editor/editor.component.scss @@ -1,3 +1,5 @@ +@import 'src/assets/styles/mixins/detail-view-appearance.scss'; + .editor { .editor-menu { display: flex; @@ -84,6 +86,8 @@ border: 1px dashed #bbb; } } + + @include detail-view-appearance; } &:focus-within { border-bottom-color: var(--mdc-filled-text-field-focus-active-indicator-color); diff --git a/client/src/app/ui/modules/file-list/components/file-list/file-list.component.html b/client/src/app/ui/modules/file-list/components/file-list/file-list.component.html index a017cfbb0e..dc0d296039 100644 --- a/client/src/app/ui/modules/file-list/components/file-list/file-list.component.html +++ b/client/src/app/ui/modules/file-list/components/file-list/file-list.component.html @@ -118,7 +118,7 @@