From e4b9ea51a92ce69b1535721bbc38abe53f105247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henry=20T=C3=A4schner?= <129834483+HenryT-CG@users.noreply.github.com> Date: Tue, 10 Dec 2024 13:30:02 +0100 Subject: [PATCH] feat: add message if iam user not exists (#299) --- package-lock.json | 172 ++++--- package.json | 28 +- src/app/_apm-mixins.scss | 2 +- src/app/permission/permission.module.ts | 2 +- .../user-roles-permissions.component.html | 448 +++++++++--------- .../user-roles-permissions.component.scss | 9 +- .../user-roles-permissions.component.spec.ts | 29 +- .../user-roles-permissions.component.ts | 99 ++-- .../model/assignmentUserSearchCriteria.ts | 2 +- src/assets/api/openapi-bff.yaml | 2 + src/assets/i18n/de.json | 1 + src/assets/i18n/en.json | 1 + src/bootstrap.ts | 3 +- tsconfig.spec.json | 2 +- 14 files changed, 439 insertions(+), 361 deletions(-) diff --git a/package-lock.json b/package-lock.json index d29c27f..ad520f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,20 +26,21 @@ "@ngrx/router-store": "^18.0.1", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", - "@onecx/accelerator": "^5.26.0", - "@onecx/angular-accelerator": "^5.26.0", - "@onecx/angular-auth": "^5.26.0", - "@onecx/angular-integration-interface": "^5.26.0", - "@onecx/angular-remote-components": "^5.26.0", - "@onecx/angular-testing": "^5.26.0", - "@onecx/angular-webcomponents": "^5.26.0", - "@onecx/integration-interface": "^5.26.0", - "@onecx/keycloak-auth": "^5.26.0", - "@onecx/portal-integration-angular": "^5.26.0", - "@onecx/portal-layout-styles": "^5.26.0", + "@onecx/accelerator": "^5.28.0", + "@onecx/angular-accelerator": "^5.28.0", + "@onecx/angular-auth": "^5.28.0", + "@onecx/angular-integration-interface": "^5.28.0", + "@onecx/angular-remote-components": "^5.28.0", + "@onecx/angular-testing": "^5.28.0", + "@onecx/angular-webcomponents": "^5.28.0", + "@onecx/integration-interface": "^5.28.0", + "@onecx/keycloak-auth": "^5.28.0", + "@onecx/portal-integration-angular": "^5.28.0", + "@onecx/portal-layout-styles": "^5.28.0", "@webcomponents/webcomponentsjs": "^2.8.0", "file-saver": "^2.0.5", "keycloak-angular": "^16.0.1", + "ngx-filesaver": "^19.0.0", "primeflex": "^3.3.1", "primeicons": "^7.0.0", "primeng": "^17.18.11", @@ -62,6 +63,7 @@ "@commitlint/config-conventional": "^19.5.0", "@openapitools/openapi-generator-cli": "^2.15.3", "@schematics/angular": "^18.2.10", + "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.4", "@types/node": "~22.9.0", "@typescript-eslint/eslint-plugin": "^7.18.0", @@ -94,7 +96,7 @@ "ts-node": "10.9.2", "typescript": "5.5.4", "url-loader": "^4.1.1", - "webpack": "^5.95.0", + "webpack": "5.95.0", "webpack-merge": "^6.0.1" } }, @@ -5392,9 +5394,9 @@ ] }, "node_modules/@mswjs/interceptors": { - "version": "0.37.1", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.1.tgz", - "integrity": "sha512-SvE+tSpcX884RJrPCskXxoS965Ky/pYABDEhWW6oeSRhpUDLrS5nTvT5n1LLSDVDYvty4imVmXsy+3/ROVuknA==", + "version": "0.37.3", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.3.tgz", + "integrity": "sha512-USvgCL/uOGFtVa6SVyRrC8kIAedzRohxIXN5LISlg5C5vLZCn7dgMFVSNhSF9cuBEFrm/O2spDWEZeMnw4ZXYg==", "license": "MIT", "peer": true, "dependencies": { @@ -5992,9 +5994,9 @@ } }, "node_modules/@onecx/accelerator": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/accelerator/-/accelerator-5.26.0.tgz", - "integrity": "sha512-X8FTBaq0op7wo8oeMA28fmRi/dJicYw9f3wa0Y8ml3609D6KcMooH3Brd91MN3ntsJXPJ2ZpAnSz/0lzdafWiA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/accelerator/-/accelerator-5.29.0.tgz", + "integrity": "sha512-d07Pl0ItQ0n2iOxaoTxIxIp+nLc/QzMdjAyrQH5we3tJIA211AGrDJC1W+tp5VS7j3pTwDjYWtkPxBmRfW0miA==", "license": "Apache-2.0", "peerDependencies": { "rxjs": "^7.8.1", @@ -6002,9 +6004,9 @@ } }, "node_modules/@onecx/angular-accelerator": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/angular-accelerator/-/angular-accelerator-5.26.0.tgz", - "integrity": "sha512-Gq5hhFMsqozpN49KJ4Wtep+VlpUTuyL5sAuESewJAC+2vgCiu9PojhEaPyc8P26wCinFbUSBjdj/D6oyqaxGpw==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/angular-accelerator/-/angular-accelerator-5.29.0.tgz", + "integrity": "sha512-qJvzOnSHsbvjub6najhJ7crcwiKN3YINz1rx3rn66EN+XtQjLFOyrJe2NdlEl+0bplpM8MQsVoOUtQkjZoL+xA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6018,10 +6020,10 @@ "@angular/router": "^18.0.5", "@ngneat/until-destroy": "^10.0.0", "@ngx-translate/core": "^15.0.0", - "@onecx/angular-integration-interface": "^5.26.0", - "@onecx/angular-remote-components": "^5.26.0", - "@onecx/angular-testing": "^5.26.0", - "@onecx/integration-interface": "^5.26.0", + "@onecx/angular-integration-interface": "^5.29.0", + "@onecx/angular-remote-components": "^5.29.0", + "@onecx/angular-testing": "^5.29.0", + "@onecx/integration-interface": "^5.29.0", "chart.js": "^4.4.3", "d3-scale-chromatic": "^3.1.0", "primeng": "^17.18.6", @@ -6029,9 +6031,9 @@ } }, "node_modules/@onecx/angular-auth": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/angular-auth/-/angular-auth-5.26.0.tgz", - "integrity": "sha512-Bkg9SzZFIsYVq61vCc3CDVotQA6wcwvkzfMRWIFMRtl2hK0tZRoeUQMji1hkv0sCtMNMz5YfZ1sATB3oKMfnfA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/angular-auth/-/angular-auth-5.29.0.tgz", + "integrity": "sha512-6PWBkl5vObErDUBZwYl03T8FUknIF8hXI9XN3TXnf0t8+VMG/8SjcVWLWBuaziPVBQA0bzikSYW6czBSUBzBgg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6040,31 +6042,31 @@ "@angular-architects/module-federation": "^18.0.4", "@angular/common": "^18.0.5", "@angular/core": "^18.0.5", - "@onecx/angular-integration-interface": "^5.26.0", - "@onecx/integration-interface": "^5.26.0", + "@onecx/angular-integration-interface": "^5.29.0", + "@onecx/integration-interface": "^5.29.0", "keycloak-angular": "^16.0.1", "keycloak-js": "^25.0.1", "rxjs": "~7.8.0" } }, "node_modules/@onecx/angular-integration-interface": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/angular-integration-interface/-/angular-integration-interface-5.26.0.tgz", - "integrity": "sha512-qpkxAvOhB3M/YY+hmSPn4/6lHNUl1+GYrlgIEdWa0neZdXv/Hkf1CfKRZDnC2lSoVIGTb57TV9UCs2h8WRzctQ==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/angular-integration-interface/-/angular-integration-interface-5.29.0.tgz", + "integrity": "sha512-MsX/9EwdPDYeG868k5NpBaDKD3sRzwEM1erxnK2a5Tt6X2xm3pV0Sz8F0LsF0zXzWw7DW0/RXuHnMCR2fgkGBg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/core": "^18.0.5", - "@onecx/integration-interface": "^5.26.0", + "@onecx/integration-interface": "^5.29.0", "rxjs": "~7.8.1" } }, "node_modules/@onecx/angular-remote-components": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/angular-remote-components/-/angular-remote-components-5.26.0.tgz", - "integrity": "sha512-PFdUOL6NuD6J+LC10ADlZxUclUf5o1IJSxQVjBe10RZbyQXbgYqzNP5BJEzCHtVKM5ArcBIAnOlWajXw2+MnxQ==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/angular-remote-components/-/angular-remote-components-5.29.0.tgz", + "integrity": "sha512-H1jvHKxmLN5d4t1Wl33gSujx5I/c5pGgokEoWz0ZRzJNwkK0rMtSJ69EZRnc3c3KTodFtSZz7F8cjz7InKeE3Q==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6074,14 +6076,14 @@ "@angular/common": "^18.0.5", "@angular/core": "^18.0.5", "@ngx-translate/core": "^15.0.0", - "@onecx/integration-interface": "^5.26.0", + "@onecx/integration-interface": "^5.29.0", "rxjs": "^7.8.1" } }, "node_modules/@onecx/angular-testing": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/angular-testing/-/angular-testing-5.26.0.tgz", - "integrity": "sha512-iLMLKUG2ZowtOokNuaXA02BvXl/1VTJkgudoH6HB1VevFj7sP02CwRlXnTNby3s2KV6eDjaprnk5uvCCYxo1Eg==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/angular-testing/-/angular-testing-5.29.0.tgz", + "integrity": "sha512-AFiBAd3Xq/YBx2+jfDuVz2yu5SnvvdIbbFNWPbEuXQYzaq3Y1e0TVGVbJ3r3Fvmg56xYqp3Dbrxh+TtGHnl2AQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6092,9 +6094,9 @@ } }, "node_modules/@onecx/angular-webcomponents": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/angular-webcomponents/-/angular-webcomponents-5.26.0.tgz", - "integrity": "sha512-e/jkSqDJw7Tq4CfMuA6C+Yaw/U79S1roavJpXhFd9siBcregaRco1s47On4dY1/buX23WapulOYnZyakY/GoZw==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/angular-webcomponents/-/angular-webcomponents-5.29.0.tgz", + "integrity": "sha512-QKng9HwJ8Sy08gxcefZTPwhKHDeDCWvzzCFhY3noFXdifED7uVadprQvtJO1nnSswmjJsB3bED1YBMhpZHrHiw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6104,26 +6106,26 @@ "@angular/elements": "^18.0.5", "@angular/platform-browser": "^18.0.5", "@angular/router": "^18.0.5", - "@onecx/accelerator": "^5.26.0", - "@onecx/portal-integration-angular": "^5.26.0", + "@onecx/accelerator": "^5.29.0", + "@onecx/portal-integration-angular": "^5.29.0", "rxjs": "~7.8.1" } }, "node_modules/@onecx/integration-interface": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/integration-interface/-/integration-interface-5.26.0.tgz", - "integrity": "sha512-9SV/QJbBAB4YmRV/eqd/DAXms7IHNuwUUfbLfELrHlPeYJ9n4KhExIKSlMwE2gJQ4TBp74ljEh9698tPSoUtsw==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/integration-interface/-/integration-interface-5.29.0.tgz", + "integrity": "sha512-JBIu2V9Fve5ReOUEloxFlfRnpvRGQcvpE0m3jlcYZtwbxLTllCX1vTQehqlzB8IwPWi21XSFFYHPtU+umRjoZQ==", "license": "Apache-2.0", "peerDependencies": { - "@onecx/accelerator": "^5.26.0", + "@onecx/accelerator": "^5.29.0", "rxjs": "^7.8.1", "tslib": "^2.6.3" } }, "node_modules/@onecx/keycloak-auth": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/keycloak-auth/-/keycloak-auth-5.26.0.tgz", - "integrity": "sha512-Qq2IQNgENp7wUgnJlJTwjVv7taK1VxV8L6HqG0NsiguZQ9UBrL5179qrGMxsvURgm23RmbpMhq8b+32lF0Br2w==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/keycloak-auth/-/keycloak-auth-5.29.0.tgz", + "integrity": "sha512-ieL4xyVuqJPHDygiUDH8e/8pAoYuQFlu8iqTIWqfxscXeJqGY6ek1VhM7tfzXuf1EhbFMmW3JW8rSWab77wn8Q==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6131,17 +6133,17 @@ "peerDependencies": { "@angular/common": "^18.0.5", "@angular/core": "^18.0.5", - "@onecx/angular-integration-interface": "^5.26.0", - "@onecx/integration-interface": "^5.26.0", + "@onecx/angular-integration-interface": "^5.29.0", + "@onecx/integration-interface": "^5.29.0", "keycloak-angular": "^16.0.1", "keycloak-js": "^25.0.1", "rxjs": "^7.8.1" } }, "node_modules/@onecx/portal-integration-angular": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/portal-integration-angular/-/portal-integration-angular-5.26.0.tgz", - "integrity": "sha512-1mUMPcTQmocKeN7dxrlD/91vl/KPFriP7KTqGIwHCuBzCVHgHZ2br9YOKRyMov0S39xaSeOVEtokrKb4lH2AKQ==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/portal-integration-angular/-/portal-integration-angular-5.29.0.tgz", + "integrity": "sha512-G8z14oTD/JTgQ/uNsDeSc2BhZlbxDewOS4Z7ahtBV1fzqHm0GSWdCzCHX5AetHlFxAICVYnKb1+V/ohFPyEWoQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6162,10 +6164,10 @@ "@ngrx/store": "^18.0.1", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", - "@onecx/angular-accelerator": "^5.26.0", - "@onecx/angular-integration-interface": "^5.26.0", - "@onecx/angular-testing": "^5.26.0", - "@onecx/integration-interface": "^5.26.0", + "@onecx/angular-accelerator": "^5.29.0", + "@onecx/angular-integration-interface": "^5.29.0", + "@onecx/angular-testing": "^5.29.0", + "@onecx/integration-interface": "^5.29.0", "fast-deep-equal": "^3.1.3", "msw": "^2.3.1", "primeng": "^17.18.6", @@ -6174,9 +6176,9 @@ } }, "node_modules/@onecx/portal-layout-styles": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@onecx/portal-layout-styles/-/portal-layout-styles-5.26.0.tgz", - "integrity": "sha512-queHqt4TvdqE4nIAIanUOt22/h9pOVBU1MJXHcZGr3JqAn7i780w3brgNBVuHPta3LpFi4LkIe+apwJFfv9JRA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@onecx/portal-layout-styles/-/portal-layout-styles-5.29.0.tgz", + "integrity": "sha512-kRedTv3No7sLDHkroeThOZmOnY66fejGhHUoTXj96peuoMtzy5oVhZ0HqionLpLxqfnGxLiX0vkmdHTdFwI5kA==", "license": "Apache-2.0", "peerDependencies": { "tslib": "^2.6.3" @@ -7257,6 +7259,12 @@ "@types/send": "*" } }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", + "license": "MIT" + }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -15413,9 +15421,9 @@ } }, "node_modules/msw": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.6.5.tgz", - "integrity": "sha512-PnlnTpUlOrj441kYQzzFhzMzMCGFT6a2jKUBG7zSpLkYS5oh8Arrbc0dL8/rNAtxaoBy0EVs2mFqj2qdmWK7lQ==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.6.6.tgz", + "integrity": "sha512-npfIIVRHKQX3Lw4aLWX4wBh+lQwpqdZNyJYB5K/+ktK8NhtkdsTxGK7WDrgknozcVyRI7TOqY6yBS9j2FTR+YQ==", "hasInstallScript": true, "license": "MIT", "peer": true, @@ -15891,6 +15899,19 @@ "node": ">=10.0.0" } }, + "node_modules/ngx-filesaver": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/ngx-filesaver/-/ngx-filesaver-19.0.0.tgz", + "integrity": "sha512-YGI9yXwLYGyxE9a493HOEx68ttnVrBzHLGEuEQISlNTDUMt6dho70ukT8MYdpxG8tu7nuAfhgWd54y+xl3tnJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@types/file-saver": "^2.0.0", + "file-saver": "^2.0.0" + } + }, "node_modules/ngx-translate-testing": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/ngx-translate-testing/-/ngx-translate-testing-7.0.0.tgz", @@ -18163,13 +18184,16 @@ "optional": true }, "node_modules/psl": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.10.0.tgz", - "integrity": "sha512-KSKHEbjAnpUuAUserOq0FxGXCUrzC3WniuSJhvdbs102rL55266ZcHBqLWOsG30spQMlPdpy7icATiAQehg/iA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", "license": "MIT", "peer": true, "dependencies": { "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" } }, "node_modules/psl/node_modules/punycode": { @@ -20293,9 +20317,9 @@ } }, "node_modules/type-fest": { - "version": "4.27.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.27.0.tgz", - "integrity": "sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==", + "version": "4.30.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.30.0.tgz", + "integrity": "sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==", "license": "(MIT OR CC0-1.0)", "peer": true, "engines": { diff --git a/package.json b/package.json index 9b7cf80..4da2d04 100644 --- a/package.json +++ b/package.json @@ -52,20 +52,21 @@ "@ngrx/router-store": "^18.0.1", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", - "@onecx/accelerator": "^5.26.0", - "@onecx/angular-accelerator": "^5.26.0", - "@onecx/angular-auth": "^5.26.0", - "@onecx/angular-integration-interface": "^5.26.0", - "@onecx/angular-remote-components": "^5.26.0", - "@onecx/angular-testing": "^5.26.0", - "@onecx/angular-webcomponents": "^5.26.0", - "@onecx/integration-interface": "^5.26.0", - "@onecx/keycloak-auth": "^5.26.0", - "@onecx/portal-integration-angular": "^5.26.0", - "@onecx/portal-layout-styles": "^5.26.0", + "@onecx/accelerator": "^5.28.0", + "@onecx/angular-accelerator": "^5.28.0", + "@onecx/angular-auth": "^5.28.0", + "@onecx/angular-integration-interface": "^5.28.0", + "@onecx/angular-remote-components": "^5.28.0", + "@onecx/angular-testing": "^5.28.0", + "@onecx/angular-webcomponents": "^5.28.0", + "@onecx/integration-interface": "^5.28.0", + "@onecx/keycloak-auth": "^5.28.0", + "@onecx/portal-integration-angular": "^5.28.0", + "@onecx/portal-layout-styles": "^5.28.0", "@webcomponents/webcomponentsjs": "^2.8.0", "file-saver": "^2.0.5", "keycloak-angular": "^16.0.1", + "ngx-filesaver": "^19.0.0", "primeflex": "^3.3.1", "primeicons": "^7.0.0", "primeng": "^17.18.11", @@ -88,6 +89,7 @@ "@commitlint/config-conventional": "^19.5.0", "@openapitools/openapi-generator-cli": "^2.15.3", "@schematics/angular": "^18.2.10", + "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.4", "@types/node": "~22.9.0", "@typescript-eslint/eslint-plugin": "^7.18.0", @@ -95,9 +97,9 @@ "css-loader": "^7.1.2", "eslint": "^8.57.1", "eslint-config-prettier": "9.1.0", + "eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-import": "2.31.0", "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-deprecation": "^3.0.0", "husky": "^9.1.6", "jasmine-core": "~5.4.0", "jasmine-spec-reporter": "^7.0.0", @@ -120,7 +122,7 @@ "ts-node": "10.9.2", "typescript": "5.5.4", "url-loader": "^4.1.1", - "webpack": "^5.95.0", + "webpack": "5.95.0", "webpack-merge": "^6.0.1" } } diff --git a/src/app/_apm-mixins.scss b/src/app/_apm-mixins.scss index 4b655e1..5982efc 100644 --- a/src/app/_apm-mixins.scss +++ b/src/app/_apm-mixins.scss @@ -180,7 +180,7 @@ .p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item { padding-top: 0.4rem; padding-bottom: 0.4rem; - &:nth-child(odd) { + &:nth-child(even) { background-color: #f8f9fa; } } diff --git a/src/app/permission/permission.module.ts b/src/app/permission/permission.module.ts index 41dc127..86f72ea 100644 --- a/src/app/permission/permission.module.ts +++ b/src/app/permission/permission.module.ts @@ -13,7 +13,7 @@ import { AppDetailComponent } from './app-detail/app-detail.component' import { RoleDetailComponent } from './role-detail/role-detail.component' import { PermissionDetailComponent } from './permission-detail/permission-detail.component' import { PermissionExportComponent } from './permission-export/permission-export.component' -import { OneCXUserRolesPermissionsComponent } from '../remotes/user-roles-permissions/user-roles-permissions.component' +import { OneCXUserRolesPermissionsComponent } from 'src/app/remotes/user-roles-permissions/user-roles-permissions.component' const routes: Routes = [ { diff --git a/src/app/remotes/user-roles-permissions/user-roles-permissions.component.html b/src/app/remotes/user-roles-permissions/user-roles-permissions.component.html index dfe9cc1..c31b9fc 100644 --- a/src/app/remotes/user-roles-permissions/user-roles-permissions.component.html +++ b/src/app/remotes/user-roles-permissions/user-roles-permissions.component.html @@ -1,240 +1,240 @@ -
- {{ displayName }} -
+
+
+ {{ displayName }} +
+ + + - - - - + + + + {{ 'USER_ROLE_PERMISSIONS.TABS.PERMISSIONS' | translate }} + + + - {{ 'USER_ROLE_PERMISSIONS.TABS.PERMISSIONS' | translate }} - - - - - - -
-
- {{ 'USER_ROLE_PERMISSIONS.TABS.PERMISSIONS.TITLE' | translate }} {{ items.length }} -
-
- - - - - +
+
+ {{ 'USER_ROLE_PERMISSIONS.TABS.PERMISSIONS.TITLE' | translate }} {{ items.length }} +
+
+ + + + + + + + - - - + +
+ - +
- - -
- + - - - - {{ 'USER_ROLE_PERMISSIONS.PERMISSION' | translate }} - - - - - -
- {{ col.header | translate }} - - - - - - -
- - -
+ + + + {{ 'USER_ROLE_PERMISSIONS.PERMISSION' | translate }} + + + + + +
+ {{ col.header | translate }} + + + + + + +
+ + +
- - - - {{ item[col.field] }} - - - - - - - {{ 'USER_ROLE_PERMISSIONS.NO_RESULTS' | translate }} - - - - - + + + + {{ item[col.field] }} + + + + + + + {{ 'USER_ROLE_PERMISSIONS.NO_RESULTS' | translate }} + + + + + - - - - - {{ 'USER_ROLE_PERMISSIONS.TABS.ROLES_N_MORE' | translate }} - - + + + + + {{ 'USER_ROLE_PERMISSIONS.TABS.ROLES_N_MORE' | translate }} + + -
- - -
-
- {{ 'USER_ROLE_PERMISSIONS.TABS.ROLES.TITLE' | translate }} {{ roles.length }} +
+ + +
+
+ {{ 'USER_ROLE_PERMISSIONS.TABS.ROLES.TITLE' | translate }} {{ roles.length }} +
+
- -
- + - - -
-
- {{ 'USER_ROLE_PERMISSIONS.TABS.PRODUCTS.TITLE' | translate }} {{ products[0] }} + + +
+
+ {{ 'USER_ROLE_PERMISSIONS.TABS.PRODUCTS.TITLE' | translate }} {{ products[0] }} +
-
-
-
- {{ 'USER_ROLE_PERMISSIONS.TABS.PRODUCTS.TITLE' | translate }} {{ products.length }} +
+
+ {{ 'USER_ROLE_PERMISSIONS.TABS.PRODUCTS.TITLE' | translate }} {{ products.length }} +
+
- -
- -
- - + +
+ + +
diff --git a/src/app/remotes/user-roles-permissions/user-roles-permissions.component.scss b/src/app/remotes/user-roles-permissions/user-roles-permissions.component.scss index 33e75cb..5f029a6 100644 --- a/src/app/remotes/user-roles-permissions/user-roles-permissions.component.scss +++ b/src/app/remotes/user-roles-permissions/user-roles-permissions.component.scss @@ -10,7 +10,6 @@ background-color: rgba(var(--primary-color-rgb), 0.12); } } - :host ::ng-deep { .p-dialog .p-dialog-content { border-bottom-left-radius: var(--border-radius) !important; @@ -24,12 +23,16 @@ font-size: var(--dialog-header-font-size); } - // reduce on all panels + // reduce on all panels (tab content) .p-tabview .p-tabview-panels { padding: 0; } - .p-datatable .p-datatable-thead > tr > th { + .p-datatable .p-datatable-thead > tr:nth-child(2) > th { border-bottom-width: 2px; } + + .p-datatable .p-datatable-tbody > tr > td { + padding: 0.5rem; + } } diff --git a/src/app/remotes/user-roles-permissions/user-roles-permissions.component.spec.ts b/src/app/remotes/user-roles-permissions/user-roles-permissions.component.spec.ts index 22c7744..819966e 100644 --- a/src/app/remotes/user-roles-permissions/user-roles-permissions.component.spec.ts +++ b/src/app/remotes/user-roles-permissions/user-roles-permissions.component.spec.ts @@ -93,6 +93,7 @@ describe('OneCXUserRolesPermissionsComponent', () => { function initializeComponent() { fixture = TestBed.createComponent(OneCXUserRolesPermissionsComponent) component = fixture.componentInstance + component.active = true fixture.detectChanges() } @@ -135,7 +136,7 @@ describe('OneCXUserRolesPermissionsComponent', () => { initializeComponent() }) - it('should search user assignments', () => { + it('should search user assignments on reload', () => { spyOn(component, 'searchUserAssignments') component.onReload() @@ -171,16 +172,34 @@ describe('OneCXUserRolesPermissionsComponent', () => { }) it('should handle error when trying to get another users assignments', () => { - const err = { error: 'error', status: 403 } - assgnmtApiSpy.searchUserAssignments.and.returnValue(throwError(() => err)) + const errorResponse = { error: 'error', status: 403, statusText: 'No permissions' } + assgnmtApiSpy.searchUserAssignments.and.returnValue(throwError(() => errorResponse)) spyOn(console, 'error') component.userId = 'id' component.ngOnChanges() component.userAssignments$.subscribe(() => { - expect(console.error).toHaveBeenCalledWith('searchUserAssignments():', err) - expect(component.exceptionKey).toEqual('EXCEPTIONS.HTTP_STATUS_' + err.status + '.PERMISSIONS') + expect(console.error).toHaveBeenCalledWith('searchUserAssignments', errorResponse) + expect(component.exceptionKey).toEqual('EXCEPTIONS.HTTP_STATUS_' + errorResponse.status + '.PERMISSIONS') + }) + }) + + it('should handle error when user not longer exist in IAM', () => { + const errorResponse = { + error: { errorCode: '400', detail: 'USER_NOT_FOUND' }, + status: 400, + statusText: 'User does not exist' + } + assgnmtApiSpy.searchUserAssignments.and.returnValue(throwError(() => errorResponse)) + spyOn(console, 'error') + component.userId = 'id' + + component.ngOnChanges() + + component.userAssignments$.subscribe(() => { + expect(console.error).toHaveBeenCalledWith('searchUserAssignments', errorResponse) + expect(component.exceptionKey).toEqual('EXCEPTIONS.NOT_FOUND.USER') }) }) diff --git a/src/app/remotes/user-roles-permissions/user-roles-permissions.component.ts b/src/app/remotes/user-roles-permissions/user-roles-permissions.component.ts index 6e53143..29ace58 100644 --- a/src/app/remotes/user-roles-permissions/user-roles-permissions.component.ts +++ b/src/app/remotes/user-roles-permissions/user-roles-permissions.component.ts @@ -6,6 +6,8 @@ import { Inject, Input, ViewChild, + Renderer2, + AfterViewInit, OnChanges } from '@angular/core' import { CommonModule, Location } from '@angular/common' @@ -61,9 +63,12 @@ type PROPERTY_NAME = 'productName' | 'roleName' | 'resource' | 'action' ], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA] }) -export class OneCXUserRolesPermissionsComponent implements ocxRemoteComponent, ocxRemoteWebcomponent, OnChanges { +export class OneCXUserRolesPermissionsComponent + implements ocxRemoteComponent, ocxRemoteWebcomponent, OnChanges, AfterViewInit +{ @Input() userId: string | undefined = undefined @Input() displayName: string | undefined = undefined + @Input() active: boolean | undefined = undefined // this is set actively on call the component @Input() set ocxRemoteComponentConfig(config: RemoteComponentConfig) { this.ocxInitRemoteComponent(config) } @@ -73,7 +78,7 @@ export class OneCXUserRolesPermissionsComponent implements ocxRemoteComponent, o public userAssignments$: Observable = of([]) public columns public environment = environment - public exceptionKey = '' + public exceptionKey: string | undefined = undefined public loading = false constructor( @@ -81,41 +86,13 @@ export class OneCXUserRolesPermissionsComponent implements ocxRemoteComponent, o private readonly userService: UserService, private readonly userApi: UserAPIService, private readonly assgnmtApi: AssignmentAPIService, - private readonly translate: TranslateService + private readonly translate: TranslateService, + private readonly renderer: Renderer2, + private readonly elem: ElementRef ) { this.userService.lang$.subscribe((lang) => this.translate.use(lang)) - this.columns = [ - { - field: 'resource', - header: 'USER_ROLE_PERMISSIONS.RESOURCE', - tooltip: 'USER_ROLE_PERMISSIONS.TOOLTIPS.RESOURCE', - filter: true, - value: null - }, - { - field: 'action', - header: 'USER_ROLE_PERMISSIONS.ACTION', - tooltip: 'USER_ROLE_PERMISSIONS.TOOLTIPS.ACTION', - filter: true, - value: null - }, - { - field: 'productName', - header: 'USER_ROLE_PERMISSIONS.PRODUCT', - tooltip: 'USER_ROLE_PERMISSIONS.TOOLTIPS.PRODUCT', - filter: true, - value: null - }, - { - field: 'roleName', - header: 'USER_ROLE_PERMISSIONS.ROLE', - tooltip: 'USER_ROLE_PERMISSIONS.TOOLTIPS.ROLE', - filter: true, - value: null - } - ] + this.columns = this.prepareColumn() } - public ocxInitRemoteComponent(remoteComponentConfig: RemoteComponentConfig) { this.loading = true this.baseUrl.next(remoteComponentConfig.baseUrl) @@ -127,8 +104,20 @@ export class OneCXUserRolesPermissionsComponent implements ocxRemoteComponent, o }) } + // remove styles set by lib (why ever) + public ngAfterViewInit() { + try { + const el = this.renderer.selectRootElement('.buttonDialogScrollableContent', true) + if (el) { + this.renderer.setStyle(el, 'overflow', 'unset') + this.renderer.setStyle(el, 'max-height', 'unset') + this.renderer.setStyle(el, 'margin-bottom', '10px') + } + } catch (err) {} // ignore runtime error if component not used within dialog + } + public ngOnChanges(): void { - this.onReload() + if (this.active !== undefined) this.onReload() } public onReload() { @@ -137,6 +126,7 @@ export class OneCXUserRolesPermissionsComponent implements ocxRemoteComponent, o public searchUserAssignments(): Observable { this.loading = true + this.exceptionKey = undefined // on admin view the userId is set, otherwise the me services are used if (this.userId) { return this.assgnmtApi @@ -146,8 +136,10 @@ export class OneCXUserRolesPermissionsComponent implements ocxRemoteComponent, o return pageResult.stream ?? [] }), catchError((err) => { - this.exceptionKey = 'EXCEPTIONS.HTTP_STATUS_' + err.status + '.PERMISSIONS' - console.error('searchUserAssignments():', err) + if (err.error?.errorCode === '400' && err.error?.detail === 'USER_NOT_FOUND') + this.exceptionKey = 'EXCEPTIONS.NOT_FOUND.USER' + else this.exceptionKey = 'EXCEPTIONS.HTTP_STATUS_' + err.status + '.PERMISSIONS' + console.error('searchUserAssignments', err) return of([]) }), finalize(() => (this.loading = false)) @@ -200,4 +192,37 @@ export class OneCXUserRolesPermissionsComponent implements ocxRemoteComponent, o this.permissionTableFilter.nativeElement.value = '' } } + + private prepareColumn() { + return [ + { + field: 'resource', + header: 'USER_ROLE_PERMISSIONS.RESOURCE', + tooltip: 'USER_ROLE_PERMISSIONS.TOOLTIPS.RESOURCE', + filter: true, + value: null + }, + { + field: 'action', + header: 'USER_ROLE_PERMISSIONS.ACTION', + tooltip: 'USER_ROLE_PERMISSIONS.TOOLTIPS.ACTION', + filter: true, + value: null + }, + { + field: 'productName', + header: 'USER_ROLE_PERMISSIONS.PRODUCT', + tooltip: 'USER_ROLE_PERMISSIONS.TOOLTIPS.PRODUCT', + filter: true, + value: null + }, + { + field: 'roleName', + header: 'USER_ROLE_PERMISSIONS.ROLE', + tooltip: 'USER_ROLE_PERMISSIONS.TOOLTIPS.ROLE', + filter: true, + value: null + } + ] + } } diff --git a/src/app/shared/generated/model/assignmentUserSearchCriteria.ts b/src/app/shared/generated/model/assignmentUserSearchCriteria.ts index 896895f..c8d0e02 100644 --- a/src/app/shared/generated/model/assignmentUserSearchCriteria.ts +++ b/src/app/shared/generated/model/assignmentUserSearchCriteria.ts @@ -12,7 +12,7 @@ export interface AssignmentUserSearchCriteria { - userId?: string; + userId: string; /** * The number of page. */ diff --git a/src/assets/api/openapi-bff.yaml b/src/assets/api/openapi-bff.yaml index bc8eb69..3d5164a 100644 --- a/src/assets/api/openapi-bff.yaml +++ b/src/assets/api/openapi-bff.yaml @@ -1158,6 +1158,8 @@ components: type: integer AssignmentUserSearchCriteria: type: object + required: + - userId properties: userId: type: string diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 3e27940..1cc0039 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -331,6 +331,7 @@ "EXCEPTIONS": { "NOT_FOUND": { "PRODUCT": "Es konnten keine Daten zu dieser Applikation gefunden werden.", + "USER": "Der Benutzer existiert nicht mehr im IAM (Identity Access Management).", "WORKSPACE": "Es konnten keine Daten zu diesem Workspace gefunden werden." }, "HTTP_MISSING_PARAMETER": "Parameter aus der URL konnten nicht ermittelt werden", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 0fbea19..b9eb23e 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -331,6 +331,7 @@ "EXCEPTIONS": { "NOT_FOUND": { "PRODUCT": "No data could be found for this Application.", + "USER": "The user no longer exist in IAM (Identity Access Management).", "WORKSPACE": "No data could be found for this Workspace." }, "HTTP_MISSING_PARAMETER": "Parameters from the URL could not be determined", diff --git a/src/bootstrap.ts b/src/bootstrap.ts index 075c949..84b5b44 100644 --- a/src/bootstrap.ts +++ b/src/bootstrap.ts @@ -1,5 +1,6 @@ +import { bootstrapModule } from '@onecx/angular-webcomponents' + import { environment } from 'src/environments/environment' import { OneCXPermissionModule } from './app/onecx-permission-remote.module' -import { bootstrapModule } from '@onecx/angular-webcomponents' bootstrapModule(OneCXPermissionModule, 'microfrontend', environment.production) diff --git a/tsconfig.spec.json b/tsconfig.spec.json index a366065..0907110 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -11,5 +11,5 @@ }, "files": ["src/test.ts", "src/polyfills.ts"], "exclude": ["src/app/shared/generated/**/*", "node_modules"], - "include": ["**/*.spec.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts"] }