Merge branch 'dev' into feature-global-search
This commit is contained in:
commit
4877a8e263
1016
src-ui/messages.xlf
1016
src-ui/messages.xlf
File diff suppressed because it is too large
Load Diff
258
src-ui/package-lock.json
generated
258
src-ui/package-lock.json
generated
@ -9,15 +9,15 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/cdk": "^17.3.2",
|
"@angular/cdk": "^17.3.6",
|
||||||
"@angular/common": "~17.3.2",
|
"@angular/common": "~17.3.7",
|
||||||
"@angular/compiler": "~17.3.2",
|
"@angular/compiler": "~17.3.7",
|
||||||
"@angular/core": "~17.3.2",
|
"@angular/core": "~17.3.7",
|
||||||
"@angular/forms": "~17.3.2",
|
"@angular/forms": "~17.3.7",
|
||||||
"@angular/localize": "~17.3.2",
|
"@angular/localize": "~17.3.7",
|
||||||
"@angular/platform-browser": "~17.3.2",
|
"@angular/platform-browser": "~17.3.7",
|
||||||
"@angular/platform-browser-dynamic": "~17.3.2",
|
"@angular/platform-browser-dynamic": "~17.3.7",
|
||||||
"@angular/router": "~17.3.2",
|
"@angular/router": "~17.3.7",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
|
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
|
||||||
"@ng-select/ng-select": "^12.0.7",
|
"@ng-select/ng-select": "^12.0.7",
|
||||||
"@ngneat/dirty-check-forms": "^3.0.3",
|
"@ngneat/dirty-check-forms": "^3.0.3",
|
||||||
@ -38,14 +38,14 @@
|
|||||||
"zone.js": "^0.14.4"
|
"zone.js": "^0.14.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-builders/jest": "17.0.2",
|
"@angular-builders/jest": "17.0.3",
|
||||||
"@angular-devkit/build-angular": "~17.3.2",
|
"@angular-devkit/build-angular": "~17.3.6",
|
||||||
"@angular-eslint/builder": "17.3.0",
|
"@angular-eslint/builder": "17.3.0",
|
||||||
"@angular-eslint/eslint-plugin": "17.3.0",
|
"@angular-eslint/eslint-plugin": "17.3.0",
|
||||||
"@angular-eslint/eslint-plugin-template": "17.3.0",
|
"@angular-eslint/eslint-plugin-template": "17.3.0",
|
||||||
"@angular-eslint/schematics": "17.3.0",
|
"@angular-eslint/schematics": "17.3.0",
|
||||||
"@angular-eslint/template-parser": "17.3.0",
|
"@angular-eslint/template-parser": "17.3.0",
|
||||||
"@angular/cli": "~17.3.2",
|
"@angular/cli": "~17.3.6",
|
||||||
"@angular/compiler-cli": "~17.3.2",
|
"@angular/compiler-cli": "~17.3.2",
|
||||||
"@playwright/test": "^1.42.1",
|
"@playwright/test": "^1.42.1",
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
@ -86,9 +86,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular-builders/common": {
|
"node_modules/@angular-builders/common": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-builders/common/-/common-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-builders/common/-/common-1.0.2.tgz",
|
||||||
"integrity": "sha512-qPgTjz3ISdGIY+vOIiUzpZRXwchdL/HEhCRzM2QKdqz/c5AB06X9wKhvXezabtzpYSq4lN9fliPYCntqimefFw==",
|
"integrity": "sha512-lUusRq6jN1It5LcUTLS6Q+AYAYGTo/EEN8hV0M6Ek9qXzweAouJaSEnwv7p04/pD7yJTl0YOCbN79u+wGm3x4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/core": "^17.1.0",
|
"@angular-devkit/core": "^17.1.0",
|
||||||
@ -100,12 +100,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular-builders/jest": {
|
"node_modules/@angular-builders/jest": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-builders/jest/-/jest-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-builders/jest/-/jest-17.0.3.tgz",
|
||||||
"integrity": "sha512-IoEDqudGTpPBhUv0R7TU0eewASVDMIj+pFZTyHCSb2Y17DkE98mo5wp/GXRBl09LO6VK63bHNBB56oXbKG93fA==",
|
"integrity": "sha512-LW4s8t+NLnWR7Aud+EZup8dOBfQF8rfOIncsarDtP/48rz/Ucnzvum7xEt/NYAlZ6y/Dpk7wO6SlqAsaOPf8mA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-builders/common": "1.0.1",
|
"@angular-builders/common": "1.0.2",
|
||||||
"@angular-devkit/architect": ">=0.1700.0 < 0.1800.0",
|
"@angular-devkit/architect": ">=0.1700.0 < 0.1800.0",
|
||||||
"@angular-devkit/core": "^17.0.0",
|
"@angular-devkit/core": "^17.0.0",
|
||||||
"jest-preset-angular": "14.0.3",
|
"jest-preset-angular": "14.0.3",
|
||||||
@ -123,12 +123,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular-devkit/architect": {
|
"node_modules/@angular-devkit/architect": {
|
||||||
"version": "0.1703.2",
|
"version": "0.1703.6",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.6.tgz",
|
||||||
"integrity": "sha512-fT5gSzwDHOyGv8zF97t8rjeoYSGSxXjWWstl3rN1nXdO0qgJ5m6Sv0fupON+HltdXDCBLRH+2khNpqx/Fh0Qww==",
|
"integrity": "sha512-Ck501FD/QuOjeKVFs7hU92w8+Ffetv0d5Sq09XY2/uygo5c/thMzp9nkevaIWBxUSeU5RqYZizDrhFVgYzbbOw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/core": "17.3.2",
|
"@angular-devkit/core": "17.3.6",
|
||||||
"rxjs": "7.8.1"
|
"rxjs": "7.8.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -138,15 +138,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular-devkit/build-angular": {
|
"node_modules/@angular-devkit/build-angular": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.3.6.tgz",
|
||||||
"integrity": "sha512-muPCUyL0uHvRkLH4NLWiccER6P2vCm/Q5DDvqyN4XOzzY3tAHHLrKrpvY87sgd2oNJ6Ci8x7GPNcfzR5KELCnw==",
|
"integrity": "sha512-K4CEZvhQZUUOpmXPVoI1YBM8BARbIlqE6FZRxakmnr+YOtVTYE5s+Dr1wgja8hZIohNz6L7j167G9Aut7oPU/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "2.3.0",
|
"@ampproject/remapping": "2.3.0",
|
||||||
"@angular-devkit/architect": "0.1703.2",
|
"@angular-devkit/architect": "0.1703.6",
|
||||||
"@angular-devkit/build-webpack": "0.1703.2",
|
"@angular-devkit/build-webpack": "0.1703.6",
|
||||||
"@angular-devkit/core": "17.3.2",
|
"@angular-devkit/core": "17.3.6",
|
||||||
"@babel/core": "7.24.0",
|
"@babel/core": "7.24.0",
|
||||||
"@babel/generator": "7.23.6",
|
"@babel/generator": "7.23.6",
|
||||||
"@babel/helper-annotate-as-pure": "7.22.5",
|
"@babel/helper-annotate-as-pure": "7.22.5",
|
||||||
@ -157,7 +157,7 @@
|
|||||||
"@babel/preset-env": "7.24.0",
|
"@babel/preset-env": "7.24.0",
|
||||||
"@babel/runtime": "7.24.0",
|
"@babel/runtime": "7.24.0",
|
||||||
"@discoveryjs/json-ext": "0.5.7",
|
"@discoveryjs/json-ext": "0.5.7",
|
||||||
"@ngtools/webpack": "17.3.2",
|
"@ngtools/webpack": "17.3.6",
|
||||||
"@vitejs/plugin-basic-ssl": "1.1.0",
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
||||||
"ansi-colors": "4.1.3",
|
"ansi-colors": "4.1.3",
|
||||||
"autoprefixer": "10.4.18",
|
"autoprefixer": "10.4.18",
|
||||||
@ -198,8 +198,8 @@
|
|||||||
"terser": "5.29.1",
|
"terser": "5.29.1",
|
||||||
"tree-kill": "1.2.2",
|
"tree-kill": "1.2.2",
|
||||||
"tslib": "2.6.2",
|
"tslib": "2.6.2",
|
||||||
"undici": "6.7.1",
|
"undici": "6.11.1",
|
||||||
"vite": "5.1.5",
|
"vite": "5.1.7",
|
||||||
"watchpack": "2.4.0",
|
"watchpack": "2.4.0",
|
||||||
"webpack": "5.90.3",
|
"webpack": "5.90.3",
|
||||||
"webpack-dev-middleware": "6.1.2",
|
"webpack-dev-middleware": "6.1.2",
|
||||||
@ -725,12 +725,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@angular-devkit/build-webpack": {
|
"node_modules/@angular-devkit/build-webpack": {
|
||||||
"version": "0.1703.2",
|
"version": "0.1703.6",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1703.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1703.6.tgz",
|
||||||
"integrity": "sha512-w7rVFQcZK4iTCd/MLfQWIkDkwBOfAs++txNQyS9qYID8KvLs1V+oWYd2qDBRelRv1u3YtaCIS1pQx3GFKBC3OA==",
|
"integrity": "sha512-pJu0et2SiF0kfXenHSTtAART0omzbWpLgBfeUo4hBh4uwX5IaT+mRpYpr8gCXMq+qsjoQp3HobSU3lPDeBn+bg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/architect": "0.1703.2",
|
"@angular-devkit/architect": "0.1703.6",
|
||||||
"rxjs": "7.8.1"
|
"rxjs": "7.8.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -744,9 +744,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular-devkit/core": {
|
"node_modules/@angular-devkit/core": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.6.tgz",
|
||||||
"integrity": "sha512-1vxKo9+pdSwTOwqPDSYQh84gZYmCJo6OgR5+AZoGLGMZSeqvi9RG5RiUcOMLQYOnuYv0arlhlWxz0ZjyR8ApKw==",
|
"integrity": "sha512-FVbkT9dEwHEvjnxr4mvMNSMg2bCFoGoP4X68xXU9dhLEUpC05opLvfbaR3Qh543eCJ5AstosBFVzB/krfIkOvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "8.12.0",
|
"ajv": "8.12.0",
|
||||||
@ -777,12 +777,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@angular-devkit/schematics": {
|
"node_modules/@angular-devkit/schematics": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.6.tgz",
|
||||||
"integrity": "sha512-AYO6oc6QpFGigc1KiDzEVT1CeLnwvnIedU5Q/U3JDZ/Yqmvgc09D64g9XXER2kg6tV7iEgLxiYnonIAQOHq7eA==",
|
"integrity": "sha512-2G1YuPInd8znG7uUgKOS7z72Aku50lTzB/2csWkWPJLAFkh7vKC8QZ40x8S1nC9npVYPhI5CRLX/HVpBh9CyxA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/core": "17.3.2",
|
"@angular-devkit/core": "17.3.6",
|
||||||
"jsonc-parser": "3.2.1",
|
"jsonc-parser": "3.2.1",
|
||||||
"magic-string": "0.30.8",
|
"magic-string": "0.30.8",
|
||||||
"ora": "5.4.1",
|
"ora": "5.4.1",
|
||||||
@ -1287,9 +1287,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/cdk": {
|
"node_modules/@angular/cdk": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.3.6.tgz",
|
||||||
"integrity": "sha512-mC2U7aoIf7RSpGgIwVyfQEbaPDDX59plQt88KeTz15wjF8vosLt2DG0rZEoV8Mq14YS47J+jI76q/LJfd6/GCw==",
|
"integrity": "sha512-7eKrC61/6pmMAxllU/vYKadZRF7x7GxUYpA5G70fNaQsIUUiZvxx/SJN9AuZEoPGAtF6atKlJD8QVmFoDzv/Lw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
@ -1303,15 +1303,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/cli": {
|
"node_modules/@angular/cli": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.3.6.tgz",
|
||||||
"integrity": "sha512-g6r4XZyGnh9P6GmWgaFh8RmR4L6UdQ408e3SpG3rjncuPRD57Ur8806GfCLPt6HIA9TARiKmaJ0EJ3RsIjag0g==",
|
"integrity": "sha512-poKaRPeI+hFqX+AxIaEriaIggFVcC3XqlT9E1/uBC2rfHirE1n5F9Z7xqEDtMHduKwLbNXhQIPoKIKya8+Hnew==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/architect": "0.1703.2",
|
"@angular-devkit/architect": "0.1703.6",
|
||||||
"@angular-devkit/core": "17.3.2",
|
"@angular-devkit/core": "17.3.6",
|
||||||
"@angular-devkit/schematics": "17.3.2",
|
"@angular-devkit/schematics": "17.3.6",
|
||||||
"@schematics/angular": "17.3.2",
|
"@schematics/angular": "17.3.6",
|
||||||
"@yarnpkg/lockfile": "1.1.0",
|
"@yarnpkg/lockfile": "1.1.0",
|
||||||
"ansi-colors": "4.1.3",
|
"ansi-colors": "4.1.3",
|
||||||
"ini": "4.1.2",
|
"ini": "4.1.2",
|
||||||
@ -1343,9 +1343,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@angular/common": {
|
"node_modules/@angular/common": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/common/-/common-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/common/-/common-17.3.7.tgz",
|
||||||
"integrity": "sha512-7fo+hrQEzo+VX0fJAKK+P4YNeiEnpdMOAkyIdwweyAeUZYeFIs6TKtax3CiJAubnkIkhQ/52uxiusDhK3Wg/WQ==",
|
"integrity": "sha512-A7LRJu1vVCGGgrfZXjU+njz50SiU4weheKCar5PIUprcdIofS1IrHAJDqYh+kwXxkjXbZMOr/ijQY0+AESLEsw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
@ -1353,14 +1353,14 @@
|
|||||||
"node": "^18.13.0 || >=20.9.0"
|
"node": "^18.13.0 || >=20.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/core": "17.3.2",
|
"@angular/core": "17.3.7",
|
||||||
"rxjs": "^6.5.3 || ^7.4.0"
|
"rxjs": "^6.5.3 || ^7.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/compiler": {
|
"node_modules/@angular/compiler": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.3.7.tgz",
|
||||||
"integrity": "sha512-+/l/FQpVsOPbxZzSKyqEra+yxoI/r8LlTRqshVACv10+DKMWJMHnDkVUrNxvWHutfn4RszpGMtbtHp3yM9rxcA==",
|
"integrity": "sha512-AlKiqPoxnrpQ0hn13fIaQPSVodaVAIjBW4vpFyuKFqs2LBKg6iolwZ21s8rEI0KR2gXl+8ugj0/UZ6YADiVM5w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
@ -1368,7 +1368,7 @@
|
|||||||
"node": "^18.13.0 || >=20.9.0"
|
"node": "^18.13.0 || >=20.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/core": "17.3.2"
|
"@angular/core": "17.3.7"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@angular/core": {
|
"@angular/core": {
|
||||||
@ -1377,9 +1377,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/compiler-cli": {
|
"node_modules/@angular/compiler-cli": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.3.7.tgz",
|
||||||
"integrity": "sha512-PG81BrJjeF679tkafjt+t9VEBE1rPq39cdLoBTnPY7Q+E/thVoem5JTRG6hmnLmwEc0xxY6sfYpvx2BB5ywUSA==",
|
"integrity": "sha512-vSg5IQZ9jGmvYjpbfH8KbH4Sl1IVeE+Mr1ogcxkGEsURSRvKo7EWc0K7LSEI9+gg0VLamMiP9EyCJdPxiJeLJQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "7.23.9",
|
"@babel/core": "7.23.9",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.14",
|
"@jridgewell/sourcemap-codec": "^1.4.14",
|
||||||
@ -1399,14 +1399,14 @@
|
|||||||
"node": "^18.13.0 || >=20.9.0"
|
"node": "^18.13.0 || >=20.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/compiler": "17.3.2",
|
"@angular/compiler": "17.3.7",
|
||||||
"typescript": ">=5.2 <5.5"
|
"typescript": ">=5.2 <5.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/core": {
|
"node_modules/@angular/core": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/core/-/core-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/core/-/core-17.3.7.tgz",
|
||||||
"integrity": "sha512-eylatBGaN8uihKomEcXkaSHmAea5bEqu1OXifEoVOJiJpJA9Dbt/VcLXkIRFnRGH2NWUT5W79vSoU9GRvPMk5w==",
|
"integrity": "sha512-HWcrbxqnvIMSxFuQdN0KPt08bc87hqr0LKm89yuRTUwx/2sNJlNQUobk6aJj4trswGBttcRDT+GOS4DQP2Nr4g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
@ -1419,9 +1419,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/forms": {
|
"node_modules/@angular/forms": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.3.7.tgz",
|
||||||
"integrity": "sha512-sbHYjAEeEWW+02YDEKuuuTEUukm6AayQuHiAu37vACj/2q/2RWQar49IoRcSJfAwP2ckqRSK4mmLoDX4IG/KSg==",
|
"integrity": "sha512-FEhXh/VmT++XCoO8i7bBtzxG7Am/cE1zrr9aF+fWW+4jpWvJvVN1IaSiJxgBB+iPsOJ9lTBRwfRW3onlcDkhrw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
@ -1429,16 +1429,16 @@
|
|||||||
"node": "^18.13.0 || >=20.9.0"
|
"node": "^18.13.0 || >=20.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/common": "17.3.2",
|
"@angular/common": "17.3.7",
|
||||||
"@angular/core": "17.3.2",
|
"@angular/core": "17.3.7",
|
||||||
"@angular/platform-browser": "17.3.2",
|
"@angular/platform-browser": "17.3.7",
|
||||||
"rxjs": "^6.5.3 || ^7.4.0"
|
"rxjs": "^6.5.3 || ^7.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/localize": {
|
"node_modules/@angular/localize": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/localize/-/localize-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/localize/-/localize-17.3.7.tgz",
|
||||||
"integrity": "sha512-8DMdpWqBZwj367jdT2fSnD406wyNP6WD9wmZr1gzDyViGsM6xUM4udbIJHQ+EABkriSKj3usHqZw6LAzO9kepw==",
|
"integrity": "sha512-GidwcxquawJBZXNQs6cJ3GvmyowupW9JFkG5sVsS6KG4yu9SIt4FZC+EbrVtYDhXI3U2wxGkm+9vDKvkSGzG0g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "7.23.9",
|
"@babel/core": "7.23.9",
|
||||||
"@types/babel__core": "7.20.5",
|
"@types/babel__core": "7.20.5",
|
||||||
@ -1454,14 +1454,14 @@
|
|||||||
"node": "^18.13.0 || >=20.9.0"
|
"node": "^18.13.0 || >=20.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/compiler": "17.3.2",
|
"@angular/compiler": "17.3.7",
|
||||||
"@angular/compiler-cli": "17.3.2"
|
"@angular/compiler-cli": "17.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/platform-browser": {
|
"node_modules/@angular/platform-browser": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.3.7.tgz",
|
||||||
"integrity": "sha512-rBVmpJ/uh+CTjYef3Nib1K+31GFbM4mZaw2R2PowKZLgWOT3MWXKy41i44NEyM8qY1dxESmzMzy4NuGfZol42Q==",
|
"integrity": "sha512-Nn8ZMaftAvO9dEwribWdNv+QBHhYIBrRkv85G6et80AXfXoYAr/xcfnQECRFtZgPmANqHC5auv/xrmExQG+Yeg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
@ -1469,9 +1469,9 @@
|
|||||||
"node": "^18.13.0 || >=20.9.0"
|
"node": "^18.13.0 || >=20.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/animations": "17.3.2",
|
"@angular/animations": "17.3.7",
|
||||||
"@angular/common": "17.3.2",
|
"@angular/common": "17.3.7",
|
||||||
"@angular/core": "17.3.2"
|
"@angular/core": "17.3.7"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@angular/animations": {
|
"@angular/animations": {
|
||||||
@ -1480,9 +1480,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/platform-browser-dynamic": {
|
"node_modules/@angular/platform-browser-dynamic": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.3.7.tgz",
|
||||||
"integrity": "sha512-fcGo9yQ+t9VaG9zPgjQW5HIizbYOKj+9kVk9FPru+uJbYyvJUwEDgpD3aI0DUrQy/OvSf4NMzY/Ucgw1AUknQw==",
|
"integrity": "sha512-9c2I4u0L1p2v1/lW8qy+WaNHisUWbyy6wqsv2v9FfCaSM49Lxymgo9LPFPC4qEG5ei5nE+eIQ2ocRiXXsf5QkQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
@ -1490,16 +1490,16 @@
|
|||||||
"node": "^18.13.0 || >=20.9.0"
|
"node": "^18.13.0 || >=20.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/common": "17.3.2",
|
"@angular/common": "17.3.7",
|
||||||
"@angular/compiler": "17.3.2",
|
"@angular/compiler": "17.3.7",
|
||||||
"@angular/core": "17.3.2",
|
"@angular/core": "17.3.7",
|
||||||
"@angular/platform-browser": "17.3.2"
|
"@angular/platform-browser": "17.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@angular/router": {
|
"node_modules/@angular/router": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/router/-/router-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/router/-/router-17.3.7.tgz",
|
||||||
"integrity": "sha512-BJiaG7zldhe8FPsg3Xv1o2xsmWNMIuntubRiSt2NlSceAr/NEgHoARpZfAGKTaFSngl6jc407wHOmBBPPALECw==",
|
"integrity": "sha512-lMkuRrc1ZjP5JPDxNHqoAhB0uAnfPQ/q6mJrw1s8IZoVV6VyM+FxR5r13ajNcXWC38xy/YhBjpXPF1vBdxuLXg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
@ -1507,9 +1507,9 @@
|
|||||||
"node": "^18.13.0 || >=20.9.0"
|
"node": "^18.13.0 || >=20.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/common": "17.3.2",
|
"@angular/common": "17.3.7",
|
||||||
"@angular/core": "17.3.2",
|
"@angular/core": "17.3.7",
|
||||||
"@angular/platform-browser": "17.3.2",
|
"@angular/platform-browser": "17.3.7",
|
||||||
"rxjs": "^6.5.3 || ^7.4.0"
|
"rxjs": "^6.5.3 || ^7.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -4844,9 +4844,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ngtools/webpack": {
|
"node_modules/@ngtools/webpack": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.6.tgz",
|
||||||
"integrity": "sha512-E8zejFF4aJ8l2XcF+GgnE/1IqsZepnPT1xzulLB4LXtjVuXLFLoF9xkHQwxs7cJWWZsxd/SlNsCIcn/ezrYBcQ==",
|
"integrity": "sha512-equxbgh2DKzZtiFMoVf1KD4yJcH1q8lpqQ/GSPPQUvONcmHrr+yqdRUdaJ7oZCyCYmXF/nByBxtMKtJr6nKZVg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.13.0 || >=20.9.0",
|
"node": "^18.13.0 || >=20.9.0",
|
||||||
@ -5604,13 +5604,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@schematics/angular": {
|
"node_modules/@schematics/angular": {
|
||||||
"version": "17.3.2",
|
"version": "17.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.3.6.tgz",
|
||||||
"integrity": "sha512-zPINvow0Qo6ionnDl25ZzSSLDyDxBjqRPEJWGHU70expbjXK4A2caQT9P/8ImhapbJAXJCfxg4GF9z1d/sWe4w==",
|
"integrity": "sha512-jCNZdjHSVrI8TrrCnCoXC8GYvQRj7zh+SDdmm91Ve8dbikYNmBOKYLuPaCTsmojWx7ytv962yLlgKzpaa2bbfw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/core": "17.3.2",
|
"@angular-devkit/core": "17.3.6",
|
||||||
"@angular-devkit/schematics": "17.3.2",
|
"@angular-devkit/schematics": "17.3.6",
|
||||||
"jsonc-parser": "3.2.1"
|
"jsonc-parser": "3.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -5935,9 +5935,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/express-serve-static-core": {
|
"node_modules/@types/express-serve-static-core": {
|
||||||
"version": "4.17.43",
|
"version": "4.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz",
|
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz",
|
||||||
"integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==",
|
"integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
@ -6046,9 +6046,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/qs": {
|
"node_modules/@types/qs": {
|
||||||
"version": "6.9.14",
|
"version": "6.9.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz",
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
|
||||||
"integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==",
|
"integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/range-parser": {
|
"node_modules/@types/range-parser": {
|
||||||
@ -6089,14 +6089,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/serve-static": {
|
"node_modules/@types/serve-static": {
|
||||||
"version": "1.15.5",
|
"version": "1.15.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
|
||||||
"integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
|
"integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/http-errors": "*",
|
"@types/http-errors": "*",
|
||||||
"@types/mime": "*",
|
"@types/node": "*",
|
||||||
"@types/node": "*"
|
"@types/send": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/sockjs": {
|
"node_modules/@types/sockjs": {
|
||||||
@ -9100,9 +9100,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/ejs": {
|
"node_modules/ejs": {
|
||||||
"version": "3.1.9",
|
"version": "3.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||||
"integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
|
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jake": "^10.8.5"
|
"jake": "^10.8.5"
|
||||||
@ -11056,9 +11056,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/ipaddr.js": {
|
"node_modules/ipaddr.js": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
|
||||||
"integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==",
|
"integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
@ -18066,9 +18066,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.7.1",
|
"version": "6.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.11.1.tgz",
|
||||||
"integrity": "sha512-+Wtb9bAQw6HYWzCnxrPTMVEV3Q1QjYanI0E4q02ehReMuquQdLTEFEYbfs7hcImVYKcQkWSwT6buEmSVIiDDtQ==",
|
"integrity": "sha512-KyhzaLJnV1qa3BSHdj4AZ2ndqI0QWPxYzaIOio0WzcEJB9gvuysprJSLtpvc2D9mhR9jPDUk7xlJlZbH2KR5iw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0"
|
"node": ">=18.0"
|
||||||
@ -18295,9 +18295,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "5.1.5",
|
"version": "5.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.7.tgz",
|
||||||
"integrity": "sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==",
|
"integrity": "sha512-sgnEEFTZYMui/sTlH1/XEnVNHMujOahPLGMxn1+5sIT45Xjng1Ec1K78jRP15dSmVgg5WBin9yO81j3o9OxofA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.19.3",
|
"esbuild": "^0.19.3",
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/cdk": "^17.3.2",
|
"@angular/cdk": "^17.3.6",
|
||||||
"@angular/common": "~17.3.2",
|
"@angular/common": "~17.3.7",
|
||||||
"@angular/compiler": "~17.3.2",
|
"@angular/compiler": "~17.3.7",
|
||||||
"@angular/core": "~17.3.2",
|
"@angular/core": "~17.3.7",
|
||||||
"@angular/forms": "~17.3.2",
|
"@angular/forms": "~17.3.7",
|
||||||
"@angular/localize": "~17.3.2",
|
"@angular/localize": "~17.3.7",
|
||||||
"@angular/platform-browser": "~17.3.2",
|
"@angular/platform-browser": "~17.3.7",
|
||||||
"@angular/platform-browser-dynamic": "~17.3.2",
|
"@angular/platform-browser-dynamic": "~17.3.7",
|
||||||
"@angular/router": "~17.3.2",
|
"@angular/router": "~17.3.7",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
|
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
|
||||||
"@ng-select/ng-select": "^12.0.7",
|
"@ng-select/ng-select": "^12.0.7",
|
||||||
"@ngneat/dirty-check-forms": "^3.0.3",
|
"@ngneat/dirty-check-forms": "^3.0.3",
|
||||||
@ -40,14 +40,14 @@
|
|||||||
"zone.js": "^0.14.4"
|
"zone.js": "^0.14.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-builders/jest": "17.0.2",
|
"@angular-builders/jest": "17.0.3",
|
||||||
"@angular-devkit/build-angular": "~17.3.2",
|
"@angular-devkit/build-angular": "~17.3.6",
|
||||||
"@angular-eslint/builder": "17.3.0",
|
"@angular-eslint/builder": "17.3.0",
|
||||||
"@angular-eslint/eslint-plugin": "17.3.0",
|
"@angular-eslint/eslint-plugin": "17.3.0",
|
||||||
"@angular-eslint/eslint-plugin-template": "17.3.0",
|
"@angular-eslint/eslint-plugin-template": "17.3.0",
|
||||||
"@angular-eslint/schematics": "17.3.0",
|
"@angular-eslint/schematics": "17.3.0",
|
||||||
"@angular-eslint/template-parser": "17.3.0",
|
"@angular-eslint/template-parser": "17.3.0",
|
||||||
"@angular/cli": "~17.3.2",
|
"@angular/cli": "~17.3.6",
|
||||||
"@angular/compiler-cli": "~17.3.2",
|
"@angular/compiler-cli": "~17.3.2",
|
||||||
"@playwright/test": "^1.42.1",
|
"@playwright/test": "^1.42.1",
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
|
@ -1,31 +1,27 @@
|
|||||||
<div ngbDropdown #fieldDropdown="ngbDropdown" (openChange)="onOpenClose()">
|
<div ngbDropdown #fieldDropdown="ngbDropdown" (openChange)="onOpenClose($event)">
|
||||||
<button class="btn btn-sm btn-outline-primary" id="customFieldsDropdown" [disabled]="disabled" ngbDropdownToggle>
|
<button class="btn btn-sm btn-outline-primary" id="customFieldsDropdown" [disabled]="disabled" ngbDropdownToggle>
|
||||||
<i-bs name="ui-radios"></i-bs>
|
<i-bs name="ui-radios"></i-bs>
|
||||||
<div class="d-none d-sm-inline"> <ng-container i18n>Custom Fields</ng-container></div>
|
<div class="d-none d-sm-inline"> <ng-container i18n>Custom Fields</ng-container></div>
|
||||||
</button>
|
</button>
|
||||||
<div ngbDropdownMenu aria-labelledby="customFieldsDropdown" class="shadow custom-fields-dropdown">
|
<div ngbDropdownMenu aria-labelledby="customFieldsDropdown" class="shadow custom-fields-dropdown">
|
||||||
<ul class="list-group list-group-flush">
|
<div class="list-group list-group-flush" (keydown)="listKeyDown($event)">
|
||||||
<li class="list-group-item">
|
<div class="list-group-item">
|
||||||
<pngx-input-select
|
<div class="input-group input-group-sm">
|
||||||
[items]="unusedFields"
|
<input class="form-control" type="text" [(ngModel)]="filterText" placeholder="Search fields" i18n-placeholder (keyup.enter)="listFilterEnter()" #listFilterTextInput>
|
||||||
bindLabel="name"
|
|
||||||
[(ngModel)]="field"
|
|
||||||
[placeholder]="placeholderText"
|
|
||||||
[notFoundText]="notFoundText"
|
|
||||||
[disableCreateNew]="!canCreateFields"
|
|
||||||
(createNew)="createField($event)"
|
|
||||||
[hideAddButton]="true"
|
|
||||||
bindValue="id">
|
|
||||||
</pngx-input-select>
|
|
||||||
<div class="btn-toolbar" role="toolbar">
|
|
||||||
<button class="btn btn-sm btn-outline-secondary me-auto" type="button" (click)="createField()" [disabled]="!canCreateFields">
|
|
||||||
<i-bs width="1em" height="1em" name="asterisk"></i-bs> <ng-container i18n>Create New Field</ng-container>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-sm btn-outline-primary" type="button" (click)="addField(); fieldDropdown.close()" [disabled]="field === undefined">
|
|
||||||
<i-bs width="1.2em" height="1.2em" name="plus-circle"></i-bs> <ng-container i18n>Add to document</ng-container>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
@for (field of filteredFields; track field.id) {
|
||||||
|
<button class="list-group-item list-group-item-action bg-light" (click)="addField(field)" #button>
|
||||||
|
<small class="d-flex">{{field.name}} <small class="ms-auto text-muted">{{getDataTypeLabel(field.data_type)}}</small></small>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
@if (!filterText?.length || filteredFields.length === 0) {
|
||||||
|
<button class="list-group-item list-group-item-action bg-light" (click)="createField(filterText)" [disabled]="!canCreateFields" #button>
|
||||||
|
<small>
|
||||||
|
<i-bs width=".9em" height=".9em" name="asterisk"></i-bs> <ng-container i18n>Create new field</ng-container>
|
||||||
|
</small>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.custom-fields-dropdown {
|
.custom-fields-dropdown {
|
||||||
min-width: 380px;
|
min-width: 300px;
|
||||||
|
|
||||||
// correct position on mobile
|
// correct position on mobile
|
||||||
@media (max-width: 575.98px) {
|
@media (max-width: 575.98px) {
|
||||||
@ -8,13 +8,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::ng-deep .custom-fields-dropdown .ng-select .ng-select-container .ng-value-container .ng-placeholder,
|
|
||||||
::ng-deep .custom-fields-dropdown .ng-select .ng-option,
|
|
||||||
::ng-deep .custom-fields-dropdown .ng-select .ng-select-container .ng-value-container .ng-value {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .custom-fields-dropdown .paperless-input-select .ng-select .ng-select-container .ng-value-container .ng-input {
|
|
||||||
top: 4px;
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
import {
|
||||||
|
ComponentFixture,
|
||||||
|
TestBed,
|
||||||
|
fakeAsync,
|
||||||
|
tick,
|
||||||
|
} from '@angular/core/testing'
|
||||||
import { CustomFieldsDropdownComponent } from './custom-fields-dropdown.component'
|
import { CustomFieldsDropdownComponent } from './custom-fields-dropdown.component'
|
||||||
import { HttpClientTestingModule } from '@angular/common/http/testing'
|
import { HttpClientTestingModule } from '@angular/common/http/testing'
|
||||||
import { ToastService } from 'src/app/services/toast.service'
|
import { ToastService } from 'src/app/services/toast.service'
|
||||||
@ -71,28 +75,33 @@ describe('CustomFieldsDropdownComponent', () => {
|
|||||||
let addedField
|
let addedField
|
||||||
component.added.subscribe((f) => (addedField = f))
|
component.added.subscribe((f) => (addedField = f))
|
||||||
component.documentId = 11
|
component.documentId = 11
|
||||||
component.field = fields[0].id
|
component.addField({ field: fields[0].id } as any)
|
||||||
component.addField()
|
|
||||||
expect(addedField).not.toBeUndefined()
|
expect(addedField).not.toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should clear field on open / close, updated unused fields', () => {
|
it('should support filtering fields', () => {
|
||||||
component.field = fields[1].id
|
const input = fixture.debugElement.query(By.css('input'))
|
||||||
component.onOpenClose()
|
input.nativeElement.value = 'Field 1'
|
||||||
expect(component.field).toBeUndefined()
|
input.triggerEventHandler('input', { target: input.nativeElement })
|
||||||
|
fixture.detectChanges()
|
||||||
expect(component.unusedFields).toEqual(fields)
|
expect(component.filteredFields.length).toEqual(1)
|
||||||
const updateSpy = jest.spyOn(
|
expect(component.filteredFields[0].name).toEqual('Field 1')
|
||||||
CustomFieldsDropdownComponent.prototype as any,
|
|
||||||
'updateUnusedFields'
|
|
||||||
)
|
|
||||||
component.existingFields = [{ field: fields[1].id } as any]
|
|
||||||
component.onOpenClose()
|
|
||||||
expect(updateSpy).toHaveBeenCalled()
|
|
||||||
expect(component.unusedFields).toEqual([fields[0]])
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support creating field, show error if necessary', () => {
|
it('should support update unused fields', () => {
|
||||||
|
component.existingFields = [{ field: fields[0].id } as any]
|
||||||
|
component['updateUnusedFields']()
|
||||||
|
expect(component['unusedFields'].length).toEqual(1)
|
||||||
|
expect(component['unusedFields'][0].name).toEqual('Field 2')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should support getting data type label', () => {
|
||||||
|
expect(component.getDataTypeLabel(CustomFieldDataType.Integer)).toEqual(
|
||||||
|
'Integer'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should support creating field, show error if necessary, then add', fakeAsync(() => {
|
||||||
let modal: NgbModalRef
|
let modal: NgbModalRef
|
||||||
modalService.activeInstances.subscribe((m) => (modal = m[m.length - 1]))
|
modalService.activeInstances.subscribe((m) => (modal = m[m.length - 1]))
|
||||||
const toastErrorSpy = jest.spyOn(toastService, 'showError')
|
const toastErrorSpy = jest.spyOn(toastService, 'showError')
|
||||||
@ -101,8 +110,9 @@ describe('CustomFieldsDropdownComponent', () => {
|
|||||||
CustomFieldsDropdownComponent.prototype as any,
|
CustomFieldsDropdownComponent.prototype as any,
|
||||||
'getFields'
|
'getFields'
|
||||||
)
|
)
|
||||||
|
const addFieldSpy = jest.spyOn(component, 'addField')
|
||||||
|
|
||||||
const createButton = fixture.debugElement.queryAll(By.css('button'))[1]
|
const createButton = fixture.debugElement.queryAll(By.css('button'))[3]
|
||||||
createButton.triggerEventHandler('click')
|
createButton.triggerEventHandler('click')
|
||||||
|
|
||||||
expect(modal).not.toBeUndefined()
|
expect(modal).not.toBeUndefined()
|
||||||
@ -115,9 +125,11 @@ describe('CustomFieldsDropdownComponent', () => {
|
|||||||
|
|
||||||
// succeed
|
// succeed
|
||||||
editDialog.succeeded.emit(fields[0])
|
editDialog.succeeded.emit(fields[0])
|
||||||
|
tick(100)
|
||||||
expect(toastInfoSpy).toHaveBeenCalled()
|
expect(toastInfoSpy).toHaveBeenCalled()
|
||||||
expect(getFieldsSpy).toHaveBeenCalled()
|
expect(getFieldsSpy).toHaveBeenCalled()
|
||||||
})
|
expect(addFieldSpy).toHaveBeenCalled()
|
||||||
|
}))
|
||||||
|
|
||||||
it('should support creating field with name', () => {
|
it('should support creating field with name', () => {
|
||||||
let modal: NgbModalRef
|
let modal: NgbModalRef
|
||||||
@ -128,4 +140,106 @@ describe('CustomFieldsDropdownComponent', () => {
|
|||||||
const editDialog = modal.componentInstance as CustomFieldEditDialogComponent
|
const editDialog = modal.componentInstance as CustomFieldEditDialogComponent
|
||||||
expect(editDialog.object.name).toEqual('Foo bar')
|
expect(editDialog.object.name).toEqual('Foo bar')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should support arrow keyboard navigation', fakeAsync(() => {
|
||||||
|
fixture.nativeElement
|
||||||
|
.querySelector('button')
|
||||||
|
.dispatchEvent(new MouseEvent('click')) // open
|
||||||
|
fixture.detectChanges()
|
||||||
|
tick(100)
|
||||||
|
const filterInputEl: HTMLInputElement =
|
||||||
|
component.listFilterTextInput.nativeElement
|
||||||
|
expect(document.activeElement).toEqual(filterInputEl)
|
||||||
|
const itemButtons = Array.from(
|
||||||
|
(fixture.nativeElement as HTMLDivElement).querySelectorAll(
|
||||||
|
'.custom-fields-dropdown button'
|
||||||
|
)
|
||||||
|
).filter((b) => b.textContent.includes('Field'))
|
||||||
|
filterInputEl.dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
|
||||||
|
)
|
||||||
|
expect(document.activeElement).toEqual(itemButtons[0])
|
||||||
|
itemButtons[0].dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
|
||||||
|
)
|
||||||
|
expect(document.activeElement).toEqual(itemButtons[1])
|
||||||
|
itemButtons[1].dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true })
|
||||||
|
)
|
||||||
|
expect(document.activeElement).toEqual(itemButtons[0])
|
||||||
|
itemButtons[0].dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true })
|
||||||
|
)
|
||||||
|
expect(document.activeElement).toEqual(filterInputEl)
|
||||||
|
filterInputEl.value = 'foo'
|
||||||
|
component.filterText = 'foo'
|
||||||
|
|
||||||
|
// dont move focus if we're traversing the field
|
||||||
|
filterInputEl.selectionStart = 1
|
||||||
|
expect(document.activeElement).toEqual(filterInputEl)
|
||||||
|
|
||||||
|
// now we're at end, so move focus
|
||||||
|
filterInputEl.selectionStart = 3
|
||||||
|
filterInputEl.dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
|
||||||
|
)
|
||||||
|
expect(document.activeElement).toEqual(itemButtons[0])
|
||||||
|
}))
|
||||||
|
|
||||||
|
it('should support arrow keyboard navigation after tab keyboard navigation', fakeAsync(() => {
|
||||||
|
fixture.nativeElement
|
||||||
|
.querySelector('button')
|
||||||
|
.dispatchEvent(new MouseEvent('click')) // open
|
||||||
|
fixture.detectChanges()
|
||||||
|
tick(100)
|
||||||
|
const filterInputEl: HTMLInputElement =
|
||||||
|
component.listFilterTextInput.nativeElement
|
||||||
|
expect(document.activeElement).toEqual(filterInputEl)
|
||||||
|
const itemButtons = Array.from(
|
||||||
|
(fixture.nativeElement as HTMLDivElement).querySelectorAll(
|
||||||
|
'.custom-fields-dropdown button'
|
||||||
|
)
|
||||||
|
).filter((b) => b.textContent.includes('Field'))
|
||||||
|
filterInputEl.dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'Tab', bubbles: true })
|
||||||
|
)
|
||||||
|
itemButtons[0]['focus']() // normally handled by browser
|
||||||
|
itemButtons[0].dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'Tab', bubbles: true })
|
||||||
|
)
|
||||||
|
itemButtons[1]['focus']() // normally handled by browser
|
||||||
|
itemButtons[1].dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', {
|
||||||
|
key: 'Tab',
|
||||||
|
shiftKey: true,
|
||||||
|
bubbles: true,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
itemButtons[0]['focus']() // normally handled by browser
|
||||||
|
itemButtons[0].dispatchEvent(
|
||||||
|
new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
|
||||||
|
)
|
||||||
|
expect(document.activeElement).toEqual(itemButtons[1])
|
||||||
|
}))
|
||||||
|
|
||||||
|
it('should support enter keyboard navigation', fakeAsync(() => {
|
||||||
|
jest.spyOn(component, 'canCreateFields', 'get').mockReturnValue(true)
|
||||||
|
const addFieldSpy = jest.spyOn(component, 'addField')
|
||||||
|
const createFieldSpy = jest.spyOn(component, 'createField')
|
||||||
|
component.filterText = 'Field 1'
|
||||||
|
component.listFilterEnter()
|
||||||
|
expect(addFieldSpy).toHaveBeenCalled()
|
||||||
|
|
||||||
|
component.filterText = 'Field 3'
|
||||||
|
component.listFilterEnter()
|
||||||
|
expect(createFieldSpy).toHaveBeenCalledWith('Field 3')
|
||||||
|
|
||||||
|
addFieldSpy.mockClear()
|
||||||
|
createFieldSpy.mockClear()
|
||||||
|
|
||||||
|
component.filterText = undefined
|
||||||
|
component.listFilterEnter()
|
||||||
|
expect(createFieldSpy).not.toHaveBeenCalled()
|
||||||
|
expect(addFieldSpy).not.toHaveBeenCalled()
|
||||||
|
}))
|
||||||
})
|
})
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
|
ElementRef,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
Input,
|
Input,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
Output,
|
Output,
|
||||||
|
QueryList,
|
||||||
|
ViewChild,
|
||||||
|
ViewChildren,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { Subject, first, takeUntil } from 'rxjs'
|
import { Subject, first, takeUntil } from 'rxjs'
|
||||||
import { CustomField } from 'src/app/data/custom-field'
|
import { CustomField, DATA_TYPE_LABELS } from 'src/app/data/custom-field'
|
||||||
import { CustomFieldInstance } from 'src/app/data/custom-field-instance'
|
import { CustomFieldInstance } from 'src/app/data/custom-field-instance'
|
||||||
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
|
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
|
||||||
import { ToastService } from 'src/app/services/toast.service'
|
import { ToastService } from 'src/app/services/toast.service'
|
||||||
@ -39,23 +43,25 @@ export class CustomFieldsDropdownComponent implements OnDestroy {
|
|||||||
@Output()
|
@Output()
|
||||||
created: EventEmitter<CustomField> = new EventEmitter()
|
created: EventEmitter<CustomField> = new EventEmitter()
|
||||||
|
|
||||||
|
@ViewChild('listFilterTextInput') listFilterTextInput: ElementRef
|
||||||
|
@ViewChildren('button') buttons: QueryList<ElementRef>
|
||||||
|
|
||||||
private customFields: CustomField[] = []
|
private customFields: CustomField[] = []
|
||||||
public unusedFields: CustomField[]
|
private unusedFields: CustomField[] = []
|
||||||
|
private keyboardIndex: number
|
||||||
|
|
||||||
public name: string
|
public get filteredFields(): CustomField[] {
|
||||||
|
return this.unusedFields.filter(
|
||||||
|
(f) =>
|
||||||
|
!this.filterText ||
|
||||||
|
f.name.toLowerCase().includes(this.filterText.toLowerCase())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
public field: number
|
public filterText: string
|
||||||
|
|
||||||
private unsubscribeNotifier: Subject<any> = new Subject()
|
private unsubscribeNotifier: Subject<any> = new Subject()
|
||||||
|
|
||||||
get placeholderText(): string {
|
|
||||||
return $localize`Choose field`
|
|
||||||
}
|
|
||||||
|
|
||||||
get notFoundText(): string {
|
|
||||||
return $localize`No unused fields found`
|
|
||||||
}
|
|
||||||
|
|
||||||
get canCreateFields(): boolean {
|
get canCreateFields(): boolean {
|
||||||
return this.permissionsService.currentUserCan(
|
return this.permissionsService.currentUserCan(
|
||||||
PermissionAction.Add,
|
PermissionAction.Add,
|
||||||
@ -87,28 +93,26 @@ export class CustomFieldsDropdownComponent implements OnDestroy {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCustomFieldFromInstance(
|
|
||||||
instance: CustomFieldInstance
|
|
||||||
): CustomField {
|
|
||||||
return this.customFields.find((f) => f.id === instance.field)
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateUnusedFields() {
|
private updateUnusedFields() {
|
||||||
this.unusedFields = this.customFields.filter(
|
this.unusedFields = this.customFields.filter(
|
||||||
(f) =>
|
(f) => !this.existingFields?.find((e) => e.field === f.id)
|
||||||
!this.existingFields?.find(
|
|
||||||
(e) => this.getCustomFieldFromInstance(e)?.id === f.id
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpenClose() {
|
onOpenClose(open: boolean) {
|
||||||
this.field = undefined
|
if (open) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.listFilterTextInput.nativeElement.focus()
|
||||||
|
}, 100)
|
||||||
|
} else {
|
||||||
|
this.filterText = undefined
|
||||||
|
}
|
||||||
this.updateUnusedFields()
|
this.updateUnusedFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
addField() {
|
addField(field: CustomField) {
|
||||||
this.added.emit(this.customFields.find((f) => f.id === this.field))
|
this.added.emit(field)
|
||||||
|
this.updateUnusedFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
createField(newName: string = null) {
|
createField(newName: string = null) {
|
||||||
@ -121,6 +125,7 @@ export class CustomFieldsDropdownComponent implements OnDestroy {
|
|||||||
this.customFieldsService.clearCache()
|
this.customFieldsService.clearCache()
|
||||||
this.getFields()
|
this.getFields()
|
||||||
this.created.emit(newField)
|
this.created.emit(newField)
|
||||||
|
setTimeout(() => this.addField(newField), 100)
|
||||||
})
|
})
|
||||||
modal.componentInstance.failed
|
modal.componentInstance.failed
|
||||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||||
@ -128,4 +133,82 @@ export class CustomFieldsDropdownComponent implements OnDestroy {
|
|||||||
this.toastService.showError($localize`Error saving field.`, e)
|
this.toastService.showError($localize`Error saving field.`, e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDataTypeLabel(dataType: string) {
|
||||||
|
return DATA_TYPE_LABELS.find((l) => l.id === dataType)?.name
|
||||||
|
}
|
||||||
|
|
||||||
|
public listFilterEnter() {
|
||||||
|
if (this.filteredFields.length === 1) {
|
||||||
|
this.addField(this.filteredFields[0])
|
||||||
|
} else if (
|
||||||
|
this.filterText &&
|
||||||
|
this.filteredFields.length === 0 &&
|
||||||
|
this.canCreateFields
|
||||||
|
) {
|
||||||
|
this.createField(this.filterText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private focusNextButtonItem(setFocus: boolean = true) {
|
||||||
|
this.keyboardIndex = Math.min(
|
||||||
|
this.buttons.length - 1,
|
||||||
|
this.keyboardIndex + 1
|
||||||
|
)
|
||||||
|
if (setFocus) this.setButtonItemFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
focusPreviousButtonItem(setFocus: boolean = true) {
|
||||||
|
this.keyboardIndex = Math.max(0, this.keyboardIndex - 1)
|
||||||
|
if (setFocus) this.setButtonItemFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
setButtonItemFocus() {
|
||||||
|
this.buttons.get(this.keyboardIndex)?.nativeElement.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
public listKeyDown(event: KeyboardEvent) {
|
||||||
|
switch (event.key) {
|
||||||
|
case 'ArrowDown':
|
||||||
|
if (event.target instanceof HTMLInputElement) {
|
||||||
|
if (
|
||||||
|
!this.filterText ||
|
||||||
|
event.target.selectionStart === this.filterText.length
|
||||||
|
) {
|
||||||
|
this.keyboardIndex = -1
|
||||||
|
this.focusNextButtonItem()
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
} else if (event.target instanceof HTMLButtonElement) {
|
||||||
|
this.focusNextButtonItem()
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'ArrowUp':
|
||||||
|
if (event.target instanceof HTMLButtonElement) {
|
||||||
|
if (this.keyboardIndex === 0) {
|
||||||
|
this.listFilterTextInput.nativeElement.focus()
|
||||||
|
} else {
|
||||||
|
this.focusPreviousButtonItem()
|
||||||
|
}
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'Tab':
|
||||||
|
// just track the index in case user uses arrows
|
||||||
|
if (event.target instanceof HTMLInputElement) {
|
||||||
|
this.keyboardIndex = 0
|
||||||
|
} else if (event.target instanceof HTMLButtonElement) {
|
||||||
|
if (event.shiftKey) {
|
||||||
|
if (this.keyboardIndex > 0) {
|
||||||
|
this.focusPreviousButtonItem(false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.focusNextButtonItem(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -949,9 +949,9 @@ describe('DocumentDetailComponent', () => {
|
|||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
expect(component.document.custom_fields).toHaveLength(initialLength - 1)
|
expect(component.document.custom_fields).toHaveLength(initialLength - 1)
|
||||||
expect(component.customFieldFormFields).toHaveLength(initialLength - 1)
|
expect(component.customFieldFormFields).toHaveLength(initialLength - 1)
|
||||||
expect(fixture.debugElement.nativeElement.textContent).not.toContain(
|
expect(
|
||||||
'Field 1'
|
fixture.debugElement.query(By.css('form')).nativeElement.textContent
|
||||||
)
|
).not.toContain('Field 1')
|
||||||
const updateSpy = jest.spyOn(documentService, 'update')
|
const updateSpy = jest.spyOn(documentService, 'update')
|
||||||
component.save(true)
|
component.save(true)
|
||||||
expect(updateSpy.mock.lastCall[0].custom_fields).toHaveLength(
|
expect(updateSpy.mock.lastCall[0].custom_fields).toHaveLength(
|
||||||
|
@ -674,13 +674,17 @@ export class DocumentDetailComponent
|
|||||||
this.documentForm.patchValue(docValues)
|
this.documentForm.patchValue(docValues)
|
||||||
this.store.next(this.documentForm.value)
|
this.store.next(this.documentForm.value)
|
||||||
this.openDocumentService.setDirty(this.document, false)
|
this.openDocumentService.setDirty(this.document, false)
|
||||||
|
this.openDocumentService.save()
|
||||||
this.toastService.showInfo($localize`Document saved successfully.`)
|
this.toastService.showInfo($localize`Document saved successfully.`)
|
||||||
this.networkActive = false
|
this.networkActive = false
|
||||||
this.error = null
|
this.error = null
|
||||||
close &&
|
if (close) {
|
||||||
this.close(() =>
|
this.close(() =>
|
||||||
this.openDocumentService.refreshDocument(this.documentId)
|
this.openDocumentService.refreshDocument(this.documentId)
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
this.openDocumentService.refreshDocument(this.documentId)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
this.networkActive = false
|
this.networkActive = false
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
[disabled]="disabled"
|
[disabled]="disabled"
|
||||||
shortcutKey="u"></pngx-filterable-dropdown>
|
shortcutKey="u"></pngx-filterable-dropdown>
|
||||||
}
|
}
|
||||||
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.StoragePath)) {
|
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.StoragePath) && storagePaths.length > 0) {
|
||||||
<pngx-filterable-dropdown class="flex-fill" title="Storage path" icon="folder-fill" i18n-title
|
<pngx-filterable-dropdown class="flex-fill" title="Storage path" icon="folder-fill" i18n-title
|
||||||
filterPlaceholder="Filter storage paths" i18n-filterPlaceholder
|
filterPlaceholder="Filter storage paths" i18n-filterPlaceholder
|
||||||
[items]="storagePaths"
|
[items]="storagePaths"
|
||||||
@ -85,7 +85,7 @@
|
|||||||
shortcutKey="i"></pngx-filterable-dropdown>
|
shortcutKey="i"></pngx-filterable-dropdown>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.CustomField)) {
|
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.CustomField) && customFields.length > 0) {
|
||||||
<pngx-filterable-dropdown class="flex-fill" title="Custom fields" icon="ui-radios" i18n-title
|
<pngx-filterable-dropdown class="flex-fill" title="Custom fields" icon="ui-radios" i18n-title
|
||||||
filterPlaceholder="Filter custom fields" i18n-filterPlaceholder
|
filterPlaceholder="Filter custom fields" i18n-filterPlaceholder
|
||||||
[items]="customFields"
|
[items]="customFields"
|
||||||
|
@ -33,8 +33,9 @@ describe('CustomDatePipe', () => {
|
|||||||
const notNow = new Date(now)
|
const notNow = new Date(now)
|
||||||
notNow.setDate(now.getDate() - 1)
|
notNow.setDate(now.getDate() - 1)
|
||||||
expect(datePipe.transform(notNow, 'relative')).toEqual('1 day ago')
|
expect(datePipe.transform(notNow, 'relative')).toEqual('1 day ago')
|
||||||
notNow.setDate(now.getDate() - 2)
|
notNow.setDate(now.getDate())
|
||||||
expect(datePipe.transform(notNow, 'relative')).toEqual('2 days ago')
|
notNow.setMonth(now.getMonth() - 1)
|
||||||
|
expect(datePipe.transform(notNow, 'relative')).toEqual('1 month ago')
|
||||||
expect(datePipe.transform(now, 'relative')).toEqual('Just now')
|
expect(datePipe.transform(now, 'relative')).toEqual('Just now')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user