fix(console): datepicker, formfield cleanup, member role help, domain layout (#3765)

* key datepicker, formfield cleanup, member role help, domain layout

* accounts card template overlay

* fix account card trigger

* chore(deps-dev): bump @typescript-eslint/parser from 5.26.0 to 5.27.0 in /console (#3752)

chore(deps-dev): bump @typescript-eslint/parser in /console

Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.26.0 to 5.27.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.27.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* deps, i18n, feature info section

* lint

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
Max Peintner 2022-06-07 11:08:05 +02:00 committed by GitHub
parent 5e4b38d69b
commit c1f59c7950
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 648 additions and 456 deletions

View File

@ -62,10 +62,10 @@
"@types/jsonwebtoken": "^8.5.5", "@types/jsonwebtoken": "^8.5.5",
"@types/node": "^17.0.35", "@types/node": "^17.0.35",
"@typescript-eslint/eslint-plugin": "5.25.0", "@typescript-eslint/eslint-plugin": "5.25.0",
"@typescript-eslint/parser": "5.26.0", "@typescript-eslint/parser": "5.27.0",
"codelyzer": "^6.0.0", "codelyzer": "^6.0.0",
"cypress": "^9.5.1", "cypress": "^9.5.1",
"cypress-terminal-report": "^3.4.1", "cypress-terminal-report": "^4.0.1",
"eslint": "^8.16.0", "eslint": "^8.16.0",
"jasmine-core": "~4.1.1", "jasmine-core": "~4.1.1",
"jasmine-spec-reporter": "~7.0.0", "jasmine-spec-reporter": "~7.0.0",
@ -4415,14 +4415,14 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz",
"integrity": "sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==", "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.26.0", "@typescript-eslint/scope-manager": "5.27.0",
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"@typescript-eslint/typescript-estree": "5.26.0", "@typescript-eslint/typescript-estree": "5.27.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -4442,13 +4442,13 @@
} }
}, },
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz",
"integrity": "sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==", "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"@typescript-eslint/visitor-keys": "5.26.0" "@typescript-eslint/visitor-keys": "5.27.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -4459,12 +4459,12 @@
} }
}, },
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz",
"integrity": "sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==", "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@ -4566,9 +4566,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz",
"integrity": "sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==", "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -4579,13 +4579,13 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz",
"integrity": "sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==", "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"@typescript-eslint/visitor-keys": "5.26.0", "@typescript-eslint/visitor-keys": "5.27.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -4606,12 +4606,12 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz",
"integrity": "sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==", "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@ -7169,9 +7169,9 @@
} }
}, },
"node_modules/cypress-terminal-report": { "node_modules/cypress-terminal-report": {
"version": "3.5.2", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/cypress-terminal-report/-/cypress-terminal-report-3.5.2.tgz", "resolved": "https://registry.npmjs.org/cypress-terminal-report/-/cypress-terminal-report-4.0.1.tgz",
"integrity": "sha512-06y4xTOnztyUOIwk3B+YoAYrK5DSwgCMZhUieUdU3EDXjIb4BgRs/wqPYbfCrH/N5/Yb9aV2hjO95pjzEClwqQ==", "integrity": "sha512-d74XcGKIeKUzFBccmWCiXmDXkI8KkxYAXZGOaLpejT1cAtJYDRmy7tbbbroO5r6JBXU0tNCabgZbccsReEWDag==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"chalk": "^3.0.0", "chalk": "^3.0.0",
@ -22588,34 +22588,34 @@
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz",
"integrity": "sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==", "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.26.0", "@typescript-eslint/scope-manager": "5.27.0",
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"@typescript-eslint/typescript-estree": "5.26.0", "@typescript-eslint/typescript-estree": "5.27.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": { "@typescript-eslint/scope-manager": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz",
"integrity": "sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==", "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"@typescript-eslint/visitor-keys": "5.26.0" "@typescript-eslint/visitor-keys": "5.27.0"
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz",
"integrity": "sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==", "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
} }
}, },
@ -22671,19 +22671,19 @@
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz",
"integrity": "sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==", "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz",
"integrity": "sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==", "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"@typescript-eslint/visitor-keys": "5.26.0", "@typescript-eslint/visitor-keys": "5.27.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -22692,12 +22692,12 @@
}, },
"dependencies": { "dependencies": {
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "5.26.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz",
"integrity": "sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==", "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.26.0", "@typescript-eslint/types": "5.27.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
} }
}, },
@ -24692,9 +24692,9 @@
} }
}, },
"cypress-terminal-report": { "cypress-terminal-report": {
"version": "3.5.2", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/cypress-terminal-report/-/cypress-terminal-report-3.5.2.tgz", "resolved": "https://registry.npmjs.org/cypress-terminal-report/-/cypress-terminal-report-4.0.1.tgz",
"integrity": "sha512-06y4xTOnztyUOIwk3B+YoAYrK5DSwgCMZhUieUdU3EDXjIb4BgRs/wqPYbfCrH/N5/Yb9aV2hjO95pjzEClwqQ==", "integrity": "sha512-d74XcGKIeKUzFBccmWCiXmDXkI8KkxYAXZGOaLpejT1cAtJYDRmy7tbbbroO5r6JBXU0tNCabgZbccsReEWDag==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^3.0.0", "chalk": "^3.0.0",

View File

@ -65,10 +65,10 @@
"@types/jasminewd2": "~2.0.10", "@types/jasminewd2": "~2.0.10",
"@types/jsonwebtoken": "^8.5.5", "@types/jsonwebtoken": "^8.5.5",
"@types/node": "^17.0.35", "@types/node": "^17.0.35",
"@typescript-eslint/parser": "5.26.0", "@typescript-eslint/parser": "5.27.0",
"codelyzer": "^6.0.0", "codelyzer": "^6.0.0",
"cypress": "^9.5.1", "cypress": "^9.5.1",
"cypress-terminal-report": "^3.4.1", "cypress-terminal-report": "^4.0.1",
"eslint": "^8.16.0", "eslint": "^8.16.0",
"@typescript-eslint/eslint-plugin": "5.25.0", "@typescript-eslint/eslint-plugin": "5.25.0",
"jasmine-core": "~4.1.1", "jasmine-core": "~4.1.1",

View File

@ -1,17 +0,0 @@
import { Directive, ElementRef, EventEmitter, HostListener, Output } from '@angular/core';
@Directive({
selector: '[cnslOutsideClick]',
})
export class OutsideClickDirective {
constructor(private elementRef: ElementRef) { }
@Output() public clickOutside: EventEmitter<HTMLElement> = new EventEmitter();
@HostListener('document:click', ['$event.target']) onMouseEnter(targetElement: HTMLElement): void {
const clickedInside = this.elementRef.nativeElement.contains(targetElement);
if (!clickedInside) {
this.clickOutside.emit(targetElement);
}
}
}

View File

@ -1,20 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { OutsideClickDirective } from './outside-click.directive';
@NgModule({
declarations: [
OutsideClickDirective,
],
imports: [
CommonModule,
],
exports: [
OutsideClickDirective,
],
})
export class OutsideClickModule { }

View File

@ -1,4 +1,4 @@
<div class="accounts-card" cnslOutsideClick (clickOutside)="closeCard($event)"> <div class="accounts-card">
<cnsl-avatar <cnsl-avatar
(click)="editUserProfile()" (click)="editUserProfile()"
*ngIf="user.human?.profile && user.human?.profile?.displayName" *ngIf="user.human?.profile && user.human?.profile?.displayName"
@ -35,7 +35,14 @@
<div class="col"> <div class="col">
<span class="user-title">{{ session.displayName ? session.displayName : session.userName }} </span> <span class="user-title">{{ session.displayName ? session.displayName : session.userName }} </span>
<span class="loginname">{{ session.loginName }}</span> <span class="loginname">{{ session.loginName }}</span>
<span class="email">{{ 'USER.STATE.' + session.authState | translate }}</span> <span
class="state"
[ngClass]="{
active: session.authState === UserState.USER_STATE_ACTIVE,
inactive: session.authState === UserState.USER_STATE_INACTIVE
}"
>{{ 'USER.STATE.' + session.authState | translate }}</span
>
</div> </div>
<span class="fill-space"></span> <span class="fill-space"></span>
<mat-icon>keyboard_arrow_right</mat-icon> <mat-icon>keyboard_arrow_right</mat-icon>

View File

@ -28,6 +28,7 @@
align-items: center; align-items: center;
padding: 1rem 0; padding: 1rem 0;
position: relative; position: relative;
color: map-get($foreground, text);
.avatar { .avatar {
font-size: 80px; font-size: 80px;
@ -47,7 +48,7 @@
.u-email { .u-email {
font-size: 0.8rem; font-size: 0.8rem;
margin-top: 0; margin: 0.5rem 0;
} }
button { button {
@ -96,6 +97,7 @@
border-radius: 50%; border-radius: 50%;
margin: 0 1rem; margin: 0 1rem;
text-align: center; text-align: center;
display: flex;
i { i {
margin: auto; margin: auto;
@ -112,13 +114,26 @@
font-weight: 500; font-weight: 500;
font-size: 0.9rem; font-size: 0.9rem;
line-height: 1rem; line-height: 1rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
} }
.email, .state,
.loginname { .loginname {
color: $secondary-text;
font-size: 0.8rem; font-size: 0.8rem;
line-height: 1rem; line-height: 1rem;
width: fit-content;
}
.loginname {
color: $secondary-text;
}
.state {
margin-top: 3px;
font-size: 11px;
padding: 1px 0.5rem;
} }
} }

View File

@ -1,7 +1,7 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AuthConfig } from 'angular-oauth2-oidc'; import { AuthConfig } from 'angular-oauth2-oidc';
import { Session, User } from 'src/app/proto/generated/zitadel/user_pb'; import { Session, User, UserState } from 'src/app/proto/generated/zitadel/user_pb';
import { AuthenticationService } from 'src/app/services/authentication.service'; import { AuthenticationService } from 'src/app/services/authentication.service';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
@ -17,6 +17,7 @@ export class AccountsCardComponent implements OnInit {
@Output() public closedCard: EventEmitter<void> = new EventEmitter(); @Output() public closedCard: EventEmitter<void> = new EventEmitter();
public sessions: Session.AsObject[] = []; public sessions: Session.AsObject[] = [];
public loadingUsers: boolean = false; public loadingUsers: boolean = false;
public UserState: any = UserState;
constructor(public authService: AuthenticationService, private router: Router, private userService: GrpcAuthService) { constructor(public authService: AuthenticationService, private router: Router, private userService: GrpcAuthService) {
this.userService this.userService
.listMyUserSessions() .listMyUserSessions()
@ -34,7 +35,7 @@ export class AccountsCardComponent implements OnInit {
}); });
} }
public ngOnInit(): void { ngOnInit(): void {
this.loadingUsers = true; this.loadingUsers = true;
} }
@ -49,10 +50,6 @@ export class AccountsCardComponent implements OnInit {
} }
} }
public close(): void {
this.closedCard.emit();
}
public selectAccount(loginHint?: string): void { public selectAccount(loginHint?: string): void {
const configWithPrompt: Partial<AuthConfig> = { const configWithPrompt: Partial<AuthConfig> = {
customQueryParams: { customQueryParams: {

View File

@ -5,23 +5,13 @@ import { MatIconModule } from '@angular/material/icon';
import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressBarModule } from '@angular/material/progress-bar';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { OutsideClickModule } from 'src/app/directives/outside-click/outside-click.module';
import { AvatarModule } from '../avatar/avatar.module'; import { AvatarModule } from '../avatar/avatar.module';
import { AccountsCardComponent } from './accounts-card.component'; import { AccountsCardComponent } from './accounts-card.component';
@NgModule({ @NgModule({
declarations: [AccountsCardComponent], declarations: [AccountsCardComponent],
imports: [ imports: [CommonModule, MatIconModule, MatButtonModule, MatProgressBarModule, RouterModule, AvatarModule, TranslateModule],
CommonModule,
MatIconModule,
MatButtonModule,
MatProgressBarModule,
OutsideClickModule,
RouterModule,
AvatarModule,
TranslateModule,
],
exports: [AccountsCardComponent], exports: [AccountsCardComponent],
}) })
export class AccountsCardModule {} export class AccountsCardModule {}

View File

@ -1,34 +1,39 @@
<span class="title" mat-dialog-title>{{'USER.MACHINE.ADD.TITLE' | translate}}</span> <span class="title" mat-dialog-title>{{ 'USER.MACHINE.ADD.TITLE' | translate }}</span>
<div mat-dialog-content> <div mat-dialog-content>
<p class="desc cnsl-secondary-text"> {{'USER.MACHINE.ADD.DESCRIPTION' | translate}}</p> <p class="desc cnsl-secondary-text">{{ 'USER.MACHINE.ADD.DESCRIPTION' | translate }}</p>
<cnsl-form-field class="form-field" appearance="outline"> <cnsl-form-field class="form-field">
<cnsl-label>{{'USER.MACHINE.TYPE' | translate}}</cnsl-label> <cnsl-label>{{ 'USER.MACHINE.TYPE' | translate }}</cnsl-label>
<mat-select [(ngModel)]="type"> <mat-select [(ngModel)]="type">
<mat-option *ngFor="let t of types" [value]="t"> <mat-option *ngFor="let t of types" [value]="t">
{{'USER.MACHINE.KEYTYPES.'+t | translate}} {{ 'USER.MACHINE.KEYTYPES.' + t | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="add-key-form-field" appearance="outline"> <cnsl-form-field class="add-key-form-field">
<cnsl-label>{{'USER.MACHINE.CHOOSEEXPIRY' | translate}} (optional)</cnsl-label> <cnsl-label>{{ 'USER.MACHINE.CHOOSEEXPIRY' | translate }} (optional)</cnsl-label>
<input cnslInput [matDatepicker]="picker" [min]="startDate" [formControl]="dateControl"> <input cnslInput [matDatepicker]="picker" [min]="startDate" [formControl]="dateControl" />
<mat-datepicker-toggle style="top: 0;" cnslSuffix [for]="picker"></mat-datepicker-toggle> <mat-datepicker-toggle style="top: 0" cnslSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker> <mat-datepicker #picker [startAt]="startDate"></mat-datepicker>
<span cnslError *ngIf="dateControl?.errors?.matDatepickerMin?.min"> <span cnslError *ngIf="dateControl?.errors?.matDatepickerMin?.min">
{{'USER.MACHINE.CHOOSEDATEAFTER' | translate}}: {{ 'USER.MACHINE.CHOOSEDATEAFTER' | translate }}:
{{dateControl?.errors?.matDatepickerMin.min.toDate() | localizedDate: 'EEE dd. MMM'}} {{ dateControl?.errors?.matDatepickerMin.min.toDate() | localizedDate: 'EEE dd. MMM' }}
</span> </span>
</cnsl-form-field> </cnsl-form-field>
</div> </div>
<div mat-dialog-actions class=" action"> <div mat-dialog-actions class="action">
<button mat-stroked-button (click)="closeDialog()"> <button mat-stroked-button (click)="closeDialog()">
{{'ACTIONS.CANCEL' | translate}} {{ 'ACTIONS.CANCEL' | translate }}
</button> </button>
<button color="primary" mat-raised-button class="ok-button" [disabled]="type === undefined || dateControl.invalid" <button
(click)="closeDialogWithSuccess()"> color="primary"
{{'ACTIONS.ADD' | translate}} mat-raised-button
class="ok-button"
[disabled]="type === undefined || dateControl.invalid"
(click)="closeDialogWithSuccess()"
>
{{ 'ACTIONS.ADD' | translate }}
</button> </button>
</div> </div>

View File

@ -1,24 +1,32 @@
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span class="title">{{'MEMBER.ADD' | translate}}</span> <span class="title">{{ 'MEMBER.ADD' | translate }}</span>
</h1> </h1>
<p class="desc cnsl-secondary-text"> {{'ORG_DETAIL.MEMBER.ADDDESCRIPTION' | translate}}</p> <p class="desc cnsl-secondary-text">{{ 'ORG_DETAIL.MEMBER.ADDDESCRIPTION' | translate }}</p>
<div mat-dialog-content> <div mat-dialog-content>
<ng-container *ngIf="showCreationTypeSelector"> <ng-container *ngIf="showCreationTypeSelector">
<cnsl-form-field class="full-width" appearance="outline"> <cnsl-form-field class="full-width">
<cnsl-label>{{ 'MEMBER.CREATIONTYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'MEMBER.CREATIONTYPE' | translate }}</cnsl-label>
<mat-select [(ngModel)]="creationType" (selectionChange)="loadRoles()"> <mat-select [(ngModel)]="creationType" (selectionChange)="loadRoles()">
<mat-option *ngFor="let type of creationTypes" [value]="type.type" <mat-option *ngFor="let type of creationTypes" [value]="type.type" [disabled]="(type.disabled$ | async) === false">
[disabled]="(type.disabled$ | async) === false"> {{ 'MEMBER.CREATIONTYPES.' + type.type | translate }}
{{ 'MEMBER.CREATIONTYPES.'+type.type | translate}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<ng-container *ngIf="creationType === CreationType.PROJECT_OWNED || creationType === CreationType.PROJECT_GRANTED"> <ng-container *ngIf="creationType === CreationType.PROJECT_OWNED || creationType === CreationType.PROJECT_GRANTED">
<p>{{'PROJECT.GRANT.CREATE.SEL_PROJECT' | translate}}</p> <p>{{ 'PROJECT.GRANT.CREATE.SEL_PROJECT' | translate }}</p>
<cnsl-search-project-autocomplete class="block" (selectionChanged)="selectProject($event)" <cnsl-search-project-autocomplete
[autocompleteType]="creationType === CreationType.PROJECT_OWNED ? ProjectAutocompleteType.PROJECT_OWNED : creationType === CreationType.PROJECT_GRANTED ? ProjectAutocompleteType.PROJECT_GRANTED : undefined"> class="block"
(selectionChanged)="selectProject($event)"
[autocompleteType]="
creationType === CreationType.PROJECT_OWNED
? ProjectAutocompleteType.PROJECT_OWNED
: creationType === CreationType.PROJECT_GRANTED
? ProjectAutocompleteType.PROJECT_GRANTED
: undefined
"
>
</cnsl-search-project-autocomplete> </cnsl-search-project-autocomplete>
</ng-container> </ng-container>
</ng-container> </ng-container>
@ -27,23 +35,33 @@
</cnsl-search-user-autocomplete> </cnsl-search-user-autocomplete>
<div class="roles-selection"> <div class="roles-selection">
<mat-checkbox class="role-cb" *ngFor="let role of memberRoleOptions" color="primary" (change)="toggleRole(role)" <mat-checkbox
[checked]="roles.includes(role)"> class="role-cb"
*ngFor="let role of memberRoleOptions"
color="primary"
(change)="toggleRole(role)"
[checked]="roles.includes(role)"
>
<div class="role-cb-content"> <div class="role-cb-content">
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div> <div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
<span>{{role | roletransform}}</span> <span>{{ role | roletransform }}</span>
<i class="info-hover las la-question-circle" matTooltip="{{ 'MEMBERROLES.' + role | translate }}"></i>
</div> </div>
</mat-checkbox> </mat-checkbox>
</div> </div>
</div> </div>
<div mat-dialog-actions class="action"> <div mat-dialog-actions class="action">
<button mat-stroked-button (click)="closeDialog()"> <button mat-stroked-button (click)="closeDialog()">
{{'ACTIONS.CANCEL' | translate}} {{ 'ACTIONS.CANCEL' | translate }}
</button> </button>
<button [disabled]="users.length === 0 || roles.length === 0" color="primary" mat-raised-button class="ok-button" <button
(click)="closeDialogWithSuccess()"> [disabled]="users.length === 0 || roles.length === 0"
{{'ACTIONS.ADD' | translate}} color="primary"
mat-raised-button
class="ok-button"
(click)="closeDialogWithSuccess()"
>
{{ 'ACTIONS.ADD' | translate }}
</button> </button>
</div> </div>

View File

@ -22,6 +22,11 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
.info-hover {
font-size: 1.2rem;
margin-left: 0.5rem;
}
} }
} }
} }

View File

@ -6,6 +6,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips'; import { MatChipsModule } from '@angular/material/chips';
import { MatDialogModule } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog';
import { MatSelectModule } from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { InputModule } from 'src/app/modules/input/input.module'; import { InputModule } from 'src/app/modules/input/input.module';
import { SearchUserAutocompleteModule } from 'src/app/modules/search-user-autocomplete/search-user-autocomplete.module'; import { SearchUserAutocompleteModule } from 'src/app/modules/search-user-autocomplete/search-user-autocomplete.module';
@ -24,6 +25,7 @@ import { MemberCreateDialogComponent } from './member-create-dialog.component';
MatChipsModule, MatChipsModule,
TranslateModule, TranslateModule,
InputModule, InputModule,
MatTooltipModule,
MatSelectModule, MatSelectModule,
RoleTransformPipeModule, RoleTransformPipeModule,
FormsModule, FormsModule,

View File

@ -12,6 +12,7 @@
<div class="role-cb-content"> <div class="role-cb-content">
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div> <div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
<span>{{ role | roletransform }}</span> <span>{{ role | roletransform }}</span>
<i class="info-hover las la-question-circle" matTooltip="{{ 'MEMBERROLES.' + role | translate }}"></i>
</div> </div>
</mat-checkbox> </mat-checkbox>
</div> </div>

View File

@ -19,6 +19,11 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
.info-hover {
font-size: 1.2rem;
margin-left: 0.5rem;
}
} }
} }
} }

View File

@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module'; import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { RoleTransformPipeModule } from 'src/app/pipes/role-transform/role-transform.module'; import { RoleTransformPipeModule } from 'src/app/pipes/role-transform/role-transform.module';
@ -17,6 +18,7 @@ import { AddMemberRolesDialogComponent } from './add-member-roles-dialog.compone
MatCheckboxModule, MatCheckboxModule,
MatButtonModule, MatButtonModule,
LocalizedDatePipeModule, LocalizedDatePipeModule,
MatTooltipModule,
RoleTransformPipeModule, RoleTransformPipeModule,
TimestampToDatePipeModule, TimestampToDatePipeModule,
], ],

View File

@ -1,25 +1,30 @@
<span class="title" mat-dialog-title>{{'USER.PERSONALACCESSTOKEN.ADD.TITLE' | translate}}</span> <span class="title" mat-dialog-title>{{ 'USER.PERSONALACCESSTOKEN.ADD.TITLE' | translate }}</span>
<div mat-dialog-content> <div mat-dialog-content>
<cnsl-info-section class="desc"> {{'USER.PERSONALACCESSTOKEN.ADD.DESCRIPTION' | translate}}</cnsl-info-section> <cnsl-info-section class="desc"> {{ 'USER.PERSONALACCESSTOKEN.ADD.DESCRIPTION' | translate }}</cnsl-info-section>
<cnsl-form-field class="form-field" appearance="outline"> <cnsl-form-field>
<cnsl-label>{{'USER.PERSONALACCESSTOKEN.ADD.CHOOSEEXPIRY' | translate}} (optional)</cnsl-label> <cnsl-label>{{ 'USER.PERSONALACCESSTOKEN.ADD.CHOOSEEXPIRY' | translate }} (optional)</cnsl-label>
<input cnslInput [matDatepicker]="picker" [min]="startDate" [formControl]="dateControl"> <input cnslInput [matDatepicker]="picker" [min]="startDate" [formControl]="dateControl" />
<mat-datepicker-toggle style="top: 0;" cnslSuffix [for]="picker"></mat-datepicker-toggle> <mat-datepicker-toggle style="top: 0" cnslSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker> <mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker>
<span cnslError *ngIf="dateControl?.errors?.matDatepickerMin?.min"> <span cnslError *ngIf="dateControl?.errors?.matDatepickerMin?.min">
{{'USER.PERSONALACCESSTOKEN.ADD.CHOOSEDATEAFTER' | translate}}: {{ 'USER.PERSONALACCESSTOKEN.ADD.CHOOSEDATEAFTER' | translate }}:
{{dateControl?.errors?.matDatepickerMin.min.toDate() | localizedDate: 'EEE dd. MMM'}} {{ dateControl?.errors?.matDatepickerMin.min.toDate() | localizedDate: 'EEE dd. MMM' }}
</span> </span>
</cnsl-form-field> </cnsl-form-field>
</div> </div>
<div mat-dialog-actions class=" action"> <div mat-dialog-actions class="action">
<button mat-button (click)="closeDialog()"> <button mat-button (click)="closeDialog()">
{{'ACTIONS.CANCEL' | translate}} {{ 'ACTIONS.CANCEL' | translate }}
</button> </button>
<button color="primary" mat-raised-button class="ok-button" [disabled]="dateControl.invalid" <button
(click)="closeDialogWithSuccess()"> color="primary"
{{'ACTIONS.ADD' | translate}} mat-raised-button
class="ok-button"
[disabled]="dateControl.invalid"
(click)="closeDialogWithSuccess()"
>
{{ 'ACTIONS.ADD' | translate }}
</button> </button>
</div> </div>

View File

@ -3,10 +3,6 @@
margin-top: 0; margin-top: 0;
} }
.form-field {
width: 100%;
}
.action { .action {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;

View File

@ -13,7 +13,7 @@
{{ 'FILTER.METHODS.1' | translate }} {{ 'FILTER.METHODS.1' | translate }}
</span> </span>
<cnsl-form-field class="filter-select-value" appearance="outline"> <cnsl-form-field class="filter-select-value">
<mat-select [value]="sq.getState()" (selectionChange)="setValue(SubQuery.STATE, sq, $event)"> <mat-select [value]="sq.getState()" (selectionChange)="setValue(SubQuery.STATE, sq, $event)">
<mat-option *ngFor="let state of states" [value]="state"> <mat-option *ngFor="let state of states" [value]="state">
{{ 'USER.STATE.' + state | translate }} {{ 'USER.STATE.' + state | translate }}
@ -32,7 +32,7 @@
>{{ 'FILTER.DISPLAYNAME' | translate }} >{{ 'FILTER.DISPLAYNAME' | translate }}
</mat-checkbox> </mat-checkbox>
<div class="subquery" *ngIf="getSubFilter(SubQuery.DISPLAYNAME) as dnq"> <div class="subquery" *ngIf="getSubFilter(SubQuery.DISPLAYNAME) as dnq">
<cnsl-form-field class="filter-select-method" appearance="outline"> <cnsl-form-field class="filter-select-method">
<mat-select [value]="dnq.getMethod()" (selectionChange)="setMethod(dnq, $event)"> <mat-select [value]="dnq.getMethod()" (selectionChange)="setMethod(dnq, $event)">
<mat-option *ngFor="let method of methods" [value]="method"> <mat-option *ngFor="let method of methods" [value]="method">
{{ 'FILTER.METHODS.' + method | translate }} {{ 'FILTER.METHODS.' + method | translate }}
@ -40,7 +40,7 @@
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="filter-input-value" appearance="outline"> <cnsl-form-field class="filter-input-value">
<input <input
cnslInput cnslInput
name="value" name="value"
@ -60,7 +60,7 @@
>{{ 'FILTER.EMAIL' | translate }} >{{ 'FILTER.EMAIL' | translate }}
</mat-checkbox> </mat-checkbox>
<div class="subquery" *ngIf="getSubFilter(SubQuery.EMAIL) as eq"> <div class="subquery" *ngIf="getSubFilter(SubQuery.EMAIL) as eq">
<cnsl-form-field class="filter-select-method" appearance="outline"> <cnsl-form-field class="filter-select-method">
<mat-select [value]="eq.getMethod()" (selectionChange)="setMethod(eq, $event)"> <mat-select [value]="eq.getMethod()" (selectionChange)="setMethod(eq, $event)">
<mat-option *ngFor="let method of methods" [value]="method"> <mat-option *ngFor="let method of methods" [value]="method">
{{ 'FILTER.METHODS.' + method | translate }} {{ 'FILTER.METHODS.' + method | translate }}
@ -68,7 +68,7 @@
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="filter-input-value" appearance="outline"> <cnsl-form-field class="filter-input-value">
<input cnslInput name="value" [value]="eq.getEmailAddress()" (change)="setValue(SubQuery.EMAIL, eq, $event)" /> <input cnslInput name="value" [value]="eq.getEmailAddress()" (change)="setValue(SubQuery.EMAIL, eq, $event)" />
</cnsl-form-field> </cnsl-form-field>
</div> </div>
@ -83,7 +83,7 @@
>{{ 'FILTER.USERNAME' | translate }} >{{ 'FILTER.USERNAME' | translate }}
</mat-checkbox> </mat-checkbox>
<div class="subquery" *ngIf="getSubFilter(SubQuery.USERNAME) as unq"> <div class="subquery" *ngIf="getSubFilter(SubQuery.USERNAME) as unq">
<cnsl-form-field class="filter-select-method" appearance="outline"> <cnsl-form-field class="filter-select-method">
<mat-select [value]="unq.getMethod()" (selectionChange)="setMethod(unq, $event)"> <mat-select [value]="unq.getMethod()" (selectionChange)="setMethod(unq, $event)">
<mat-option *ngFor="let method of methods" [value]="method"> <mat-option *ngFor="let method of methods" [value]="method">
{{ 'FILTER.METHODS.' + method | translate }} {{ 'FILTER.METHODS.' + method | translate }}
@ -91,7 +91,7 @@
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="filter-input-value" appearance="outline"> <cnsl-form-field class="filter-input-value">
<input cnslInput name="value" [value]="unq.getUserName()" (change)="setValue(SubQuery.USERNAME, unq, $event)" /> <input cnslInput name="value" [value]="unq.getUserName()" (change)="setValue(SubQuery.USERNAME, unq, $event)" />
</cnsl-form-field> </cnsl-form-field>
</div> </div>

View File

@ -7,7 +7,6 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatSelectModule } from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { OutsideClickModule } from 'src/app/directives/outside-click/outside-click.module';
import { ActionKeysModule } from '../action-keys/action-keys.module'; import { ActionKeysModule } from '../action-keys/action-keys.module';
import { InputModule } from '../input/input.module'; import { InputModule } from '../input/input.module';
@ -26,7 +25,6 @@ import { FilterComponent } from './filter.component';
MatCheckboxModule, MatCheckboxModule,
InputModule, InputModule,
MatSelectModule, MatSelectModule,
OutsideClickModule,
], ],
exports: [FilterComponent], exports: [FilterComponent],
}) })

View File

@ -196,30 +196,46 @@
</a> </a>
</div> </div>
<div <div class="account-card-wrapper">
cnslOutsideClick <button
(clickOutside)="closeAccountCard()" cdkOverlayOrigin
class="icon-container" #accounttrigger="cdkOverlayOrigin"
[ngClass]="{ 'iam-user': (['iam.write$'] | hasRole | async) }" class="icon-container"
>
<cnsl-avatar
id="avatartoggle"
*ngIf="
user && (user.human?.profile?.displayName || (user.human?.profile?.firstName && user.human?.profile?.lastName))
"
class="avatar-toggle dontcloseonclick"
(click)="showAccount = !showAccount" (click)="showAccount = !showAccount"
[active]="showAccount" [ngClass]="{ 'iam-user': (['iam.write$'] | hasRole | async) }"
[avatarUrl]="user.human?.profile?.avatarUrl || ''"
[forColor]="user?.preferredLoginName || ''"
[name]="
user.human?.profile?.displayName
? user.human?.profile?.displayName ?? ''
: user.human?.profile?.firstName + ' ' + user.human?.profile?.lastName
"
[size]="38"
> >
</cnsl-avatar> <cnsl-avatar
id="avatartoggle"
*ngIf="
user && (user.human?.profile?.displayName || (user.human?.profile?.firstName && user.human?.profile?.lastName))
"
class="avatar-toggle dontcloseonclick"
[active]="showAccount"
[avatarUrl]="user.human?.profile?.avatarUrl || ''"
[forColor]="user?.preferredLoginName || ''"
[name]="
user.human?.profile?.displayName
? user.human?.profile?.displayName ?? ''
: user.human?.profile?.firstName + ' ' + user.human?.profile?.lastName
"
[size]="38"
>
</cnsl-avatar>
</button>
</div>
<ng-template
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="accounttrigger"
[flexibleDimensions]="true"
[lockPosition]="true"
[cdkConnectedOverlayOffsetY]="10"
[cdkConnectedOverlayHasBackdrop]="true"
[cdkConnectedOverlayPositions]="accountCardPositions"
cdkConnectedOverlayBackdropClass="transparent-backdrop"
[cdkConnectedOverlayOpen]="showAccount"
(backdropClick)="showAccount = false"
(detach)="showAccount = false"
>
<cnsl-accounts-card <cnsl-accounts-card
@accounts @accounts
class="a_card" class="a_card"
@ -229,6 +245,6 @@
[iamuser]="['iam.write$'] | hasRole | async" [iamuser]="['iam.write$'] | hasRole | async"
> >
</cnsl-accounts-card> </cnsl-accounts-card>
</div> </ng-template>
</div> </div>
</mat-toolbar> </mat-toolbar>

View File

@ -250,47 +250,56 @@
} }
} }
.icon-container { .account-card-wrapper {
display: flex;
justify-content: space-between;
position: relative; position: relative;
user-select: none;
border: 2px solid #ffffff80;
border-radius: 50%;
transition: border ease 0.15s;
&.iam-user { .icon-container {
border: 2px solid $primary-color; display: flex;
} justify-content: space-between;
position: relative;
user-select: none;
border-radius: 50%;
transition: border ease 0.15s;
padding: 0;
border: 2px solid if($is-dark-theme, #ffffff80, #00000010);
outline: none;
background: none;
&:hover { &.iam-user {
border-color: if($is-dark-theme, #fff, #00000050); border: 2px solid $primary-color;
} }
.docs { &:hover,
text-decoration: none; &:focus {
font-size: 1.4rem; border: 2px solid if($is-dark-theme, #fff, map-get($primary, 200));
} }
.avatar-toggle { .docs {
display: block; text-decoration: none;
margin: auto; font-size: 1.4rem;
cursor: pointer; }
}
.name { .avatar-toggle {
font-size: 1rem; display: block;
font-weight: 400; margin: auto;
} cursor: pointer;
border: none;
}
.a_card { .name {
position: absolute; font-size: 1rem;
z-index: 300; font-weight: 400;
top: 55px; }
right: 0;
overflow: hidden; .a_card {
box-shadow: 0 0 15px 0 rgb(0 0 0 / 10%); position: absolute;
border-radius: 0.5rem; z-index: 300;
top: 55px;
right: 0;
overflow: hidden;
box-shadow: 0 0 15px 0 rgb(0 0 0 / 10%);
border-radius: 0.5rem;
}
} }
} }
} }

View File

@ -38,6 +38,11 @@ export class HeaderComponent implements OnDestroy {
new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }, 0, 10), new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }, 0, 10),
new ConnectionPositionPair({ originX: 'end', originY: 'bottom' }, { overlayX: 'end', overlayY: 'top' }, 0, 10), new ConnectionPositionPair({ originX: 'end', originY: 'bottom' }, { overlayX: 'end', overlayY: 'top' }, 0, 10),
]; ];
public accountCardPositions: ConnectedPosition[] = [
new ConnectionPositionPair({ originX: 'end', originY: 'bottom' }, { overlayX: 'end', overlayY: 'top' }, 0, 10),
new ConnectionPositionPair({ originX: 'end', originY: 'bottom' }, { overlayX: 'end', overlayY: 'top' }, 0, 10),
];
constructor( constructor(
public authenticationService: AuthenticationService, public authenticationService: AuthenticationService,
private authService: GrpcAuthService, private authService: GrpcAuthService,

View File

@ -1,37 +1,48 @@
<div class="info-row" *ngIf="user"> <div class="info-row" *ngIf="user">
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'USER.PAGES.STATE' | translate }}</p> <p class="info-row-title">{{ 'USER.PAGES.STATE' | translate }}</p>
<p *ngIf="user && user.state !== undefined" class="state" <p
[ngClass]="{'active': user.state === UserState.USER_STATE_ACTIVE, 'inactive': user.state === UserState.USER_STATE_INACTIVE}"> *ngIf="user && user.state !== undefined"
{{'USER.DATA.STATE'+user.state class="state"
| translate}}</p> [ngClass]="{
active: user.state === UserState.USER_STATE_ACTIVE,
inactive: user.state === UserState.USER_STATE_INACTIVE
}"
>
{{ 'USER.DATA.STATE' + user.state | translate }}
</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'USER.ID' | translate }}</p> <p class="info-row-title">{{ 'USER.ID' | translate }}</p>
<p *ngIf="user && user.id" class="info-row-desc">{{user.id }}</p> <p *ngIf="user && user.id" class="info-row-desc">{{ user.id }}</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'USER.DETAILS.DATECREATED' | translate }}</p> <p class="info-row-title">{{ 'USER.DETAILS.DATECREATED' | translate }}</p>
<p *ngIf="user && user.details && user.details.creationDate" class="info-row-desc">{{user.details.creationDate | <p *ngIf="user && user.details && user.details.creationDate" class="info-row-desc">
timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> {{ user.details.creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'USER.DETAILS.DATECHANGED' | translate }}</p> <p class="info-row-title">{{ 'USER.DETAILS.DATECHANGED' | translate }}</p>
<p *ngIf="user && user.details && user.details.changeDate" class="info-row-desc">{{user.details.changeDate | <p *ngIf="user && user.details && user.details.changeDate" class="info-row-desc">
timestampToDate {{ user.details.changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
| localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> </p>
</div> </div>
<div class="info-wrapper width"> <div class="info-wrapper width">
<p class="info-row-title">{{ 'USER.PAGES.LOGINNAMES' | translate }}</p> <p class="info-row-title">{{ 'USER.PAGES.LOGINNAMES' | translate }}</p>
<div class="copy-row" *ngFor="let login of user?.loginNamesList"> <div class="copy-row" *ngFor="let login of user?.loginNamesList">
<button [disabled]="copied === login" <button
[matTooltip]="(copied !== login ? 'ACTIONS.COPY' : 'ACTIONS.COPIED' ) | translate" cnslCopyToClipboard [disabled]="copied === login"
[valueToCopy]="login" (copiedValue)="copied = $event"> [matTooltip]="(copied !== login ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
{{login}} cnslCopyToClipboard
[valueToCopy]="login"
(copiedValue)="copied = $event"
>
{{ login }}
</button> </button>
</div> </div>
</div> </div>
@ -40,99 +51,117 @@
<div class="info-row" *ngIf="org"> <div class="info-row" *ngIf="org">
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'ORG.PAGES.STATE' | translate }}</p> <p class="info-row-title">{{ 'ORG.PAGES.STATE' | translate }}</p>
<p *ngIf="org && org.state !== undefined" class="state" <p
[ngClass]="{'active': org.state === OrgState.ORG_STATE_ACTIVE, 'inactive': org.state === OrgState.ORG_STATE_INACTIVE}"> *ngIf="org && org.state !== undefined"
{{'ORG.STATE.'+org.state class="state"
| translate}}</p> [ngClass]="{ active: org.state === OrgState.ORG_STATE_ACTIVE, inactive: org.state === OrgState.ORG_STATE_INACTIVE }"
>
{{ 'ORG.STATE.' + org.state | translate }}
</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'RESOURCEID' | translate }}</p> <p class="info-row-title">{{ 'RESOURCEID' | translate }}</p>
<p *ngIf="org && org.id" class="info-row-desc">{{org.id }}</p> <p *ngIf="org && org.id" class="info-row-desc">{{ org.id }}</p>
</div> </div>
<div class="info-wrapper width"> <div class="info-wrapper width">
<p class="info-row-title">{{ 'ORG.PAGES.PRIMARYDOMAIN' | translate }}</p> <p class="info-row-title">{{ 'ORG.PAGES.PRIMARYDOMAIN' | translate }}</p>
<div class="copy-row" *ngIf="org.primaryDomain"> <div class="copy-row" *ngIf="org.primaryDomain">
<button [disabled]="copied === org.primaryDomain" <button
[matTooltip]="(copied !== org.primaryDomain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED' ) | translate" [disabled]="copied === org.primaryDomain"
cnslCopyToClipboard [valueToCopy]="org.primaryDomain" (copiedValue)="copied = $event"> [matTooltip]="(copied !== org.primaryDomain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
{{org.primaryDomain}} cnslCopyToClipboard
[valueToCopy]="org.primaryDomain"
(copiedValue)="copied = $event"
>
{{ org.primaryDomain }}
</button> </button>
</div> </div>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p> <p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p>
<p *ngIf="org && org.details && org.details.creationDate" class="info-row-desc">{{org.details.creationDate | <p *ngIf="org && org.details && org.details.creationDate" class="info-row-desc">
timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> {{ org.details.creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p> <p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p>
<p *ngIf="org && org.details && org.details.changeDate" class="info-row-desc">{{org.details.changeDate | <p *ngIf="org && org.details && org.details.changeDate" class="info-row-desc">
timestampToDate {{ org.details.changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
| localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> </p>
</div> </div>
</div> </div>
<div class="info-row" *ngIf="project"> <div class="info-row" *ngIf="project">
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p> <p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p>
<p *ngIf="project && project.state !== undefined" class="state" <p
[ngClass]="{'active': project.state === ProjectState.PROJECT_STATE_ACTIVE, 'inactive': project.state === ProjectState.PROJECT_STATE_INACTIVE}"> *ngIf="project && project.state !== undefined"
{{'PROJECT.STATE.'+project.state class="state"
| translate}}</p> [ngClass]="{
active: project.state === ProjectState.PROJECT_STATE_ACTIVE,
inactive: project.state === ProjectState.PROJECT_STATE_INACTIVE
}"
>
{{ 'PROJECT.STATE.' + project.state | translate }}
</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'RESOURCEID' | translate }}</p> <p class="info-row-title">{{ 'RESOURCEID' | translate }}</p>
<p *ngIf="project && project.id" class="info-row-desc">{{project.id }}</p> <p *ngIf="project && project.id" class="info-row-desc">{{ project.id }}</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p> <p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p>
<p *ngIf="project && project.details && project.details.creationDate" class="info-row-desc"> <p *ngIf="project && project.details && project.details.creationDate" class="info-row-desc">
{{project.details.creationDate | {{ project.details.creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> </p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p> <p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p>
<p *ngIf="project && project.details && project.details.changeDate" class="info-row-desc"> <p *ngIf="project && project.details && project.details.changeDate" class="info-row-desc">
{{project.details.changeDate | {{ project.details.changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
timestampToDate </p>
| localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p>
</div> </div>
</div> </div>
<div class="info-row" *ngIf="grantedProject"> <div class="info-row" *ngIf="grantedProject">
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p> <p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p>
<p *ngIf="grantedProject && grantedProject.state !== undefined" class="state" <p
[ngClass]="{'active': grantedProject.state === ProjectGrantState.PROJECT_GRANT_STATE_ACTIVE, 'inactive': grantedProject.state === ProjectGrantState.PROJECT_GRANT_STATE_INACTIVE}"> *ngIf="grantedProject && grantedProject.state !== undefined"
{{'PROJECT.STATE.'+grantedProject.state class="state"
| translate}}</p> [ngClass]="{
active: grantedProject.state === ProjectGrantState.PROJECT_GRANT_STATE_ACTIVE,
inactive: grantedProject.state === ProjectGrantState.PROJECT_GRANT_STATE_INACTIVE
}"
>
{{ 'PROJECT.STATE.' + grantedProject.state | translate }}
</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'RESOURCEID' | translate }}</p> <p class="info-row-title">{{ 'RESOURCEID' | translate }}</p>
<p *ngIf="grantedProject && grantedProject.projectId" class="info-row-desc">{{grantedProject.projectId }}</p> <p *ngIf="grantedProject && grantedProject.projectId" class="info-row-desc">{{ grantedProject.projectId }}</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p> <p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p>
<p *ngIf="grantedProject && grantedProject.details && grantedProject.details.creationDate" class="info-row-desc"> <p *ngIf="grantedProject && grantedProject.details && grantedProject.details.creationDate" class="info-row-desc">
{{grantedProject.details.creationDate | {{ grantedProject.details.creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> </p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p> <p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p>
<p *ngIf="grantedProject && grantedProject.details && grantedProject.details.changeDate" class="info-row-desc"> <p *ngIf="grantedProject && grantedProject.details && grantedProject.details.changeDate" class="info-row-desc">
{{grantedProject.details.changeDate | {{ grantedProject.details.changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
timestampToDate </p>
| localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p>
</div> </div>
</div> </div>
@ -140,84 +169,95 @@
<div class="info-row"> <div class="info-row">
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'APP.PAGES.STATE' | translate }}</p> <p class="info-row-title">{{ 'APP.PAGES.STATE' | translate }}</p>
<p *ngIf="app && app.state !== undefined" class="state" <p
[ngClass]="{'active': app.state === AppState.APP_STATE_ACTIVE, 'inactive': app.state === AppState.APP_STATE_INACTIVE}"> *ngIf="app && app.state !== undefined"
{{'APP.PAGES.DETAIL.STATE.'+app.state class="state"
| translate}}</p> [ngClass]="{ active: app.state === AppState.APP_STATE_ACTIVE, inactive: app.state === AppState.APP_STATE_INACTIVE }"
>
{{ 'APP.PAGES.DETAIL.STATE.' + app.state | translate }}
</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'APP.PAGES.ID' | translate }}</p> <p class="info-row-title">{{ 'APP.PAGES.ID' | translate }}</p>
<p *ngIf="app && app.id" class="info-row-desc">{{app.id }}</p> <p *ngIf="app && app.id" class="info-row-desc">{{ app.id }}</p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'APP.PAGES.DATECREATED' | translate }}</p> <p class="info-row-title">{{ 'APP.PAGES.DATECREATED' | translate }}</p>
<p *ngIf="app && app.details && app.details.creationDate" class="info-row-desc">{{app.details.creationDate | <p *ngIf="app && app.details && app.details.creationDate" class="info-row-desc">
timestampToDate {{ app.details.creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
| localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> </p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'APP.PAGES.DATECHANGED' | translate }}</p> <p class="info-row-title">{{ 'APP.PAGES.DATECHANGED' | translate }}</p>
<p *ngIf="app && app.details && app.details.changeDate" class="info-row-desc">{{app.details.changeDate | <p *ngIf="app && app.details && app.details.changeDate" class="info-row-desc">
timestampToDate | {{ app.details.changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> </p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'APP.OIDC.INFO.CLIENTID' | translate }}</p> <p class="info-row-title">{{ 'APP.OIDC.INFO.CLIENTID' | translate }}</p>
<div class="copy-row" *ngIf="app?.oidcConfig?.clientId"> <div class="copy-row" *ngIf="app?.oidcConfig?.clientId">
<button *ngIf="app.oidcConfig && app.oidcConfig?.clientId" [disabled]="copied === app.oidcConfig?.clientId" <button
[matTooltip]="(copied !== app.oidcConfig?.clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED' ) | translate" *ngIf="app.oidcConfig && app.oidcConfig?.clientId"
cnslCopyToClipboard [valueToCopy]="app.oidcConfig.clientId" (copiedValue)="copied = $event"> [disabled]="copied === app.oidcConfig?.clientId"
{{app.oidcConfig?.clientId}} [matTooltip]="(copied !== app.oidcConfig?.clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
cnslCopyToClipboard
[valueToCopy]="app.oidcConfig.clientId"
(copiedValue)="copied = $event"
>
{{ app.oidcConfig?.clientId }}
</button> </button>
</div> </div>
<div class="copy-row" *ngIf="app?.apiConfig?.clientId"> <div class="copy-row" *ngIf="app?.apiConfig?.clientId">
<button *ngIf="app && app.apiConfig && app.apiConfig.clientId" [disabled]="copied === app.apiConfig?.clientId" <button
[matTooltip]="(copied !== app.apiConfig?.clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED' ) | translate" *ngIf="app && app.apiConfig && app.apiConfig.clientId"
cnslCopyToClipboard [valueToCopy]="app.apiConfig.clientId" (copiedValue)="copied = $event"> [disabled]="copied === app.apiConfig?.clientId"
{{app.apiConfig?.clientId}} [matTooltip]="(copied !== app.apiConfig?.clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
cnslCopyToClipboard
[valueToCopy]="app.apiConfig.clientId"
(copiedValue)="copied = $event"
>
{{ app.apiConfig?.clientId }}
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</ng-container> </ng-container>
<div class="info-row" *ngIf="idp"> <div class="info-row" *ngIf="idp">
<div class="info-wrapper width"> <div class="info-wrapper width">
<p class="info-row-title">{{ 'IDP.ID' | translate }}</p> <p class="info-row-title">{{ 'IDP.ID' | translate }}</p>
<div class="copy-row"> <p class="info-row-desc">
<button [disabled]="copied === idp.id" {{ idp.id }}
[matTooltip]="(copied !== idp.id ? 'ACTIONS.COPY' : 'ACTIONS.COPIED' ) | translate" cnslCopyToClipboard </p>
[valueToCopy]="idp.id" (copiedValue)="copied = $event">
{{idp.id}}
</button>
</div>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'IDP.DETAIL.DATECREATED' | translate }}</p> <p class="info-row-title">{{ 'IDP.DETAIL.DATECREATED' | translate }}</p>
<p class="info-row-desc" *ngIf="idp && idp.details && idp.details.creationDate">{{idp.details.creationDate | <p class="info-row-desc" *ngIf="idp && idp.details && idp.details.creationDate">
timestampToDate {{ idp.details.creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
| localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> </p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'IDP.DETAIL.DATECHANGED' | translate }}</p> <p class="info-row-title">{{ 'IDP.DETAIL.DATECHANGED' | translate }}</p>
<p class="info-row-desc" *ngIf="idp && idp.details && idp.details.changeDate">{{idp.details.changeDate | <p class="info-row-desc" *ngIf="idp && idp.details && idp.details.changeDate">
timestampToDate | {{ idp.details.changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
localizedDate: 'dd. MMMM YYYY, HH:mm' }}</p> </p>
</div> </div>
<div class="info-wrapper"> <div class="info-wrapper">
<p class="info-row-title">{{ 'IDP.STATE' | translate }}</p> <p class="info-row-title">{{ 'IDP.STATE' | translate }}</p>
<p *ngIf="idp && idp.state !== undefined" class="state" <p
[ngClass]="{'active': idp.state === IDPState.IDP_STATE_ACTIVE, 'inactive': idp.state === IDPState.IDP_STATE_INACTIVE}"> *ngIf="idp && idp.state !== undefined"
{{'IDP.STATES.'+idp.state class="state"
| translate}}</p> [ngClass]="{ active: idp.state === IDPState.IDP_STATE_ACTIVE, inactive: idp.state === IDPState.IDP_STATE_INACTIVE }"
>
{{ 'IDP.STATES.' + idp.state | translate }}
</p>
</div> </div>
</div> </div>

View File

@ -12,7 +12,7 @@
>{{ pageIndex * pageSize }} - {{ pageIndex * pageSize + pageSize }} >{{ pageIndex * pageSize }} - {{ pageIndex * pageSize + pageSize }}
</span> </span>
<div class="row" *ngIf="!hidePagination"> <div class="row" *ngIf="!hidePagination">
<cnsl-form-field class="size" appearance="outline"> <cnsl-form-field class="size">
<mat-select class="paginator-select" [(ngModel)]="pageSize" (selectionChange)="emitChange()"> <mat-select class="paginator-select" [(ngModel)]="pageSize" (selectionChange)="emitChange()">
<mat-option *ngFor="let sizeOption of pageSizeOptions" [value]="sizeOption"> <mat-option *ngFor="let sizeOption of pageSizeOptions" [value]="sizeOption">
{{ sizeOption }} {{ sizeOption }}

View File

@ -1,5 +1,3 @@
<!-- <cnsl-info-section *ngIf="isDefault"> {{ 'POLICY.DEFAULTLABEL' | translate }}</cnsl-info-section> -->
<div class="spinner-wr"> <div class="spinner-wr">
<mat-spinner diameter="30" *ngIf="loading" color="primary"></mat-spinner> <mat-spinner diameter="30" *ngIf="loading" color="primary"></mat-spinner>
</div> </div>

View File

@ -23,7 +23,7 @@
</button> </button>
</div> </div>
<form *ngIf="form" class="top-actions" [formGroup]="form"> <form *ngIf="form" class="top-actions" [formGroup]="form">
<cnsl-form-field class="keys" appearance="outline"> <cnsl-form-field class="keys">
<cnsl-label>{{ 'POLICY.LOGIN_TEXTS.KEYNAME' | translate }}</cnsl-label> <cnsl-label>{{ 'POLICY.LOGIN_TEXTS.KEYNAME' | translate }}</cnsl-label>
<mat-select formControlName="currentSubMap" name="currentSubMap"> <mat-select formControlName="currentSubMap" name="currentSubMap">
<mat-option *ngFor="let key of KeyNamesArray" [value]="key"> <mat-option *ngFor="let key of KeyNamesArray" [value]="key">

View File

@ -24,7 +24,6 @@
(detach)="submitColor()" (detach)="submitColor()"
[cdkConnectedOverlayOrigin]="trigger" [cdkConnectedOverlayOrigin]="trigger"
[cdkConnectedOverlayOpen]="isOpen" [cdkConnectedOverlayOpen]="isOpen"
(overlayOutsideClick)="isOpen = false"
> >
<color-chrome class="picker" [color]="previewColor" (onChangeComplete)="changeComplete($event)"> </color-chrome> <color-chrome class="picker" [color]="previewColor" (onChangeComplete)="changeComplete($event)"> </color-chrome>
<button class="close-icon" mat-mini-fab color="primary" (click)="submitColor()"><mat-icon>check</mat-icon></button> <button class="close-icon" mat-mini-fab color="primary" (click)="submitColor()"><mat-icon>check</mat-icon></button>

View File

@ -1,8 +1,7 @@
<form> <form>
<cnsl-form-field appearance="outline" class="full-width"> <cnsl-form-field class="full-width">
<cnsl-label>{{'USER.GRANTS.PROJECTNAME' | translate}}</cnsl-label> <cnsl-label>{{ 'USER.GRANTS.PROJECTNAME' | translate }}</cnsl-label>
<input cnslInput type="text" placeholder="Project XY" #nameInput [formControl]="myControl" <input cnslInput type="text" placeholder="Project XY" #nameInput [formControl]="myControl" [matAutocomplete]="auto" />
[matAutocomplete]="auto" />
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)" [displayWith]="displayFn"> <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)" [displayWith]="displayFn">
<mat-option *ngIf="isLoading" class="is-loading"> <mat-option *ngIf="isLoading" class="is-loading">
@ -11,14 +10,15 @@
<mat-option *ngFor="let project of filteredProjects" [value]="project"> <mat-option *ngFor="let project of filteredProjects" [value]="project">
<div class="project-option"> <div class="project-option">
<div class="project-option-column"> <div class="project-option-column">
<span>{{project?.name ? project?.name : project?.projectName ? project?.projectName : ''}}</span> <span>{{ project?.name ? project?.name : project?.projectName ? project?.projectName : '' }}</span>
<span class="fill-space"></span> <span class="fill-space"></span>
<span class="smaller cnsl-secondary-text">{{(project.name ? 'USER.GRANTS.PROJECT-OWNED' : <span class="smaller cnsl-secondary-text">{{
project?.projectName ? 'USER.GRANTS.PROJECT-GRANTED' : '') | (project.name ? 'USER.GRANTS.PROJECT-OWNED' : project?.projectName ? 'USER.GRANTS.PROJECT-GRANTED' : '')
translate}}</span> | translate
}}</span>
</div> </div>
</div> </div>
</mat-option> </mat-option>
</mat-autocomplete> </mat-autocomplete>
</cnsl-form-field> </cnsl-form-field>
</form> </form>

View File

@ -1,27 +1,47 @@
<form> <form>
<cnsl-form-field appearance="outline" class="full-width"> <cnsl-form-field class="full-width">
<cnsl-label>Role Name</cnsl-label> <cnsl-label>Role Name</cnsl-label>
<input cnslInput *ngIf="singleOutput" type="text" placeholder="Search for the role name" #nameInput <input
[formControl]="myControl" [matAutocomplete]="auto" /> cnslInput
*ngIf="singleOutput"
type="text"
placeholder="Search for the role name"
#nameInput
[formControl]="myControl"
[matAutocomplete]="auto"
/>
<mat-chip-list *ngIf="!singleOutput" #chipList aria-label="name selection"> <mat-chip-list *ngIf="!singleOutput" #chipList aria-label="name selection">
<mat-chip class="chip" *ngFor="let selectedRole of roles" [selectable]="selectable" [removable]="removable" <mat-chip
(removed)="remove(selectedRole)"> class="chip"
{{selectedRole.displayName}} *ngFor="let selectedRole of roles"
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon> [selectable]="selectable"
</mat-chip> [removable]="removable"
<input cnslInput placeholder="Role Name" #nameInput [formControl]="myControl" [matAutocomplete]="auto" (removed)="remove(selectedRole)"
[matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" >
[matChipInputAddOnBlur]="addOnBlur" (matChipInputTokenEnd)="add($event)" /> {{ selectedRole.displayName }}
</mat-chip-list> <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<input
cnslInput
placeholder="Role Name"
#nameInput
[formControl]="myControl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)"
/>
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)" [displayWith]="displayFn"> <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)" [displayWith]="displayFn">
<mat-option *ngIf="isLoading" class="is-loading"> <mat-option *ngIf="isLoading" class="is-loading">
<mat-spinner diameter="30"></mat-spinner> <mat-spinner diameter="30"></mat-spinner>
</mat-option> </mat-option>
<mat-option *ngFor="let role of filteredRoles" [value]="role.key"> <mat-option *ngFor="let role of filteredRoles" [value]="role.key">
{{role.displayName}} {{ role.displayName }}
</mat-option> </mat-option>
</mat-autocomplete> </mat-autocomplete>
</cnsl-form-field> </cnsl-form-field>
</form> </form>

View File

@ -22,7 +22,7 @@
<ng-template cnslHasRole [hasRole]="['org.flow.read']"> <ng-template cnslHasRole [hasRole]="['org.flow.read']">
<div *ngIf="flow" class="flow"> <div *ngIf="flow" class="flow">
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'FLOWS.FLOWTYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'FLOWS.FLOWTYPE' | translate }}</cnsl-label>
<mat-select [formControl]="typeControl"> <mat-select [formControl]="typeControl">
<mat-option *ngFor="let type of typesForSelection" [value]="type"> <mat-option *ngFor="let type of typesForSelection" [value]="type">

View File

@ -1,38 +1,42 @@
<span *ngIf="!id" class="action-dialog-title" mat-dialog-title>{{'FLOWS.DIALOG.ADD.TITLE' | translate}}</span> <span *ngIf="!id" class="action-dialog-title" mat-dialog-title>{{ 'FLOWS.DIALOG.ADD.TITLE' | translate }}</span>
<span *ngIf="id" class="action-dialog-title" mat-dialog-title>{{'FLOWS.DIALOG.UPDATE.TITLE' | translate}}</span> <span *ngIf="id" class="action-dialog-title" mat-dialog-title>{{ 'FLOWS.DIALOG.UPDATE.TITLE' | translate }}</span>
<div mat-dialog-content> <div mat-dialog-content>
<cnsl-form-field class="form-field" appearance="outline"> <cnsl-form-field class="form-field">
<cnsl-label>{{'FLOWS.NAME' | translate}}</cnsl-label> <cnsl-label>{{ 'FLOWS.NAME' | translate }}</cnsl-label>
<input cnslInput [(ngModel)]="name"> <input cnslInput [(ngModel)]="name" />
</cnsl-form-field> </cnsl-form-field>
<ngx-codemirror *ngIf="opened$ | async" [(ngModel)]="script" [options]="{ <ngx-codemirror
lineNumbers: true, *ngIf="opened$ | async"
theme: 'material', [(ngModel)]="script"
mode: 'javascript' [options]="{
}"></ngx-codemirror> lineNumbers: true,
theme: 'material',
mode: 'javascript'
}"
></ngx-codemirror>
<cnsl-form-field class="form-field" appearance="outline"> <cnsl-form-field class="form-field">
<cnsl-label>{{'FLOWS.TIMEOUTINSEC' | translate}}</cnsl-label> <cnsl-label>{{ 'FLOWS.TIMEOUTINSEC' | translate }}</cnsl-label>
<input type="number" cnslInput [(ngModel)]="durationInSec"> <input type="number" cnslInput [(ngModel)]="durationInSec" />
</cnsl-form-field> </cnsl-form-field>
<mat-checkbox [(ngModel)]="allowedToFail">{{'FLOWS.ALLOWEDTOFAIL' | translate}}</mat-checkbox> <mat-checkbox [(ngModel)]="allowedToFail">{{ 'FLOWS.ALLOWEDTOFAIL' | translate }}</mat-checkbox>
</div> </div>
<div mat-dialog-actions class="action"> <div mat-dialog-actions class="action">
<button *ngIf="id" mat-stroked-button color="warn" (click)="deleteAndCloseDialog()"> <button *ngIf="id" mat-stroked-button color="warn" (click)="deleteAndCloseDialog()">
{{'ACTIONS.DELETE' | translate}} {{ 'ACTIONS.DELETE' | translate }}
</button> </button>
<span class="fill-space"></span> <span class="fill-space"></span>
<button mat-stroked-button (click)="closeDialog()"> <button mat-stroked-button (click)="closeDialog()">
{{'ACTIONS.CANCEL' | translate}} {{ 'ACTIONS.CANCEL' | translate }}
</button> </button>
<button color="primary" mat-raised-button class="ok-button" [disabled]="false" (click)="closeDialogWithSuccess()"> <button color="primary" mat-raised-button class="ok-button" [disabled]="false" (click)="closeDialogWithSuccess()">
<span *ngIf="!id">{{'ACTIONS.ADD' | translate}}</span> <span *ngIf="!id">{{ 'ACTIONS.ADD' | translate }}</span>
<span *ngIf="id">{{'ACTIONS.SAVE' | translate}}</span> <span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
</button> </button>
</div> </div>

View File

@ -1,27 +1,27 @@
<span class="title" mat-dialog-title>{{'FLOWS.DIALOG.ADD.TITLE' | translate}}</span> <span class="title" mat-dialog-title>{{ 'FLOWS.DIALOG.ADD.TITLE' | translate }}</span>
<div mat-dialog-content> <div mat-dialog-content>
<form *ngIf="form" [formGroup]="form"> <form *ngIf="form" [formGroup]="form">
<cnsl-form-field class="form-field" appearance="outline"> <cnsl-form-field class="form-field">
<cnsl-label>{{'FLOWS.FLOWTYPE' | translate}}</cnsl-label> <cnsl-label>{{ 'FLOWS.FLOWTYPE' | translate }}</cnsl-label>
<mat-select formControlName="flowType"> <mat-select formControlName="flowType">
<mat-option *ngFor="let type of typesForSelection" [value]="type"> <mat-option *ngFor="let type of typesForSelection" [value]="type">
{{ 'FLOWS.TYPES.'+type | translate }} {{ 'FLOWS.TYPES.' + type | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="form-field" appearance="outline"> <cnsl-form-field class="form-field">
<cnsl-label>{{'FLOWS.TRIGGERTYPE' | translate}}</cnsl-label> <cnsl-label>{{ 'FLOWS.TRIGGERTYPE' | translate }}</cnsl-label>
<mat-select formControlName="triggerType" name="triggerType"> <mat-select formControlName="triggerType" name="triggerType">
<mat-option *ngFor="let type of triggerTypesForSelection" [value]="type"> <mat-option *ngFor="let type of triggerTypesForSelection" [value]="type">
{{ 'FLOWS.TRIGGERTYPES.'+type | translate }} {{ 'FLOWS.TRIGGERTYPES.' + type | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="form-field" appearance="outline"> <cnsl-form-field class="form-field">
<cnsl-label>{{'FLOWS.ACTIONS' | translate}}</cnsl-label> <cnsl-label>{{ 'FLOWS.ACTIONS' | translate }}</cnsl-label>
<mat-select formControlName="actionIdsList" name="actionIdsList" multiple> <mat-select formControlName="actionIdsList" name="actionIdsList" multiple>
<mat-option *ngFor="let action of actions" [value]="action.id"> <mat-option *ngFor="let action of actions" [value]="action.id">
{{ action.name }} {{ action.name }}
@ -30,12 +30,12 @@
</cnsl-form-field> </cnsl-form-field>
</form> </form>
</div> </div>
<div mat-dialog-actions class=" action"> <div mat-dialog-actions class="action">
<button mat-stroked-button (click)="closeDialog()"> <button mat-stroked-button (click)="closeDialog()">
{{'ACTIONS.CANCEL' | translate}} {{ 'ACTIONS.CANCEL' | translate }}
</button> </button>
<button color="primary" mat-raised-button class="ok-button" [disabled]="false" (click)="closeDialogWithSuccess()"> <button color="primary" mat-raised-button class="ok-button" [disabled]="false" (click)="closeDialogWithSuccess()">
<span>{{'ACTIONS.SAVE' | translate}}</span> <span>{{ 'ACTIONS.SAVE' | translate }}</span>
</button> </button>
</div> </div>

View File

@ -2,7 +2,7 @@
<div mat-dialog-content> <div mat-dialog-content>
<p class="desc cnsl-secondary-text">{{ 'ORG.DOMAINS.ADD.DESCRIPTION' | translate }}</p> <p class="desc cnsl-secondary-text">{{ 'ORG.DOMAINS.ADD.DESCRIPTION' | translate }}</p>
<cnsl-form-field label="Domain" required="true" class="form-field" appearance="outline"> <cnsl-form-field label="Domain" required="true" class="form-field">
<cnsl-label>Domain</cnsl-label> <cnsl-label>Domain</cnsl-label>
<input cnslInput [(ngModel)]="newdomain" /> <input cnslInput [(ngModel)]="newdomain" />
</cnsl-form-field> </cnsl-form-field>

View File

@ -1,25 +1,36 @@
<span class="title" mat-dialog-title>{{'ORG.PAGES.ORGDOMAIN.TITLE' | translate}} {{domain.domainName}}</span> <span class="title" mat-dialog-title>{{ 'ORG.PAGES.ORGDOMAIN.TITLE' | translate }} {{ domain.domainName }}</span>
<div mat-dialog-content> <div mat-dialog-content>
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION' | translate }}</p> <p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION' | translate }}</p>
<cnsl-info-section [type]="InfoSectionType.WARN" class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_DESC' | <cnsl-info-section [type]="InfoSectionType.WARN" class="desc">{{
translate }}</cnsl-info-section> 'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_DESC' | translate
}}</cnsl-info-section>
<p *ngIf="domain.validationType !== DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED && !(dns || http)" <p
class="desc"> *ngIf="domain.validationType !== DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED && !(dns || http)"
{{'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_ONGOING' | translate: domain }} class="desc"
{{'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_ONGOING_TYPE' | translate}} >
{{'ORG.PAGES.ORGDOMAIN.TYPES.'+ domain.validationType | translate}}</p> {{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_ONGOING' | translate: domain }}
{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_ONGOING_TYPE' | translate }}
{{ 'ORG.PAGES.ORGDOMAIN.TYPES.' + domain.validationType | translate }}
</p>
<div class="btn-container"> <div class="btn-container">
<button [disabled]="domain.validationType === DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED" <button
color="primary" type="submit" mat-raised-button *ngIf="!(dns || http)" (click)="validate()"> [disabled]="domain.validationType === DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED"
color="primary"
type="submit"
mat-raised-button
*ngIf="!(dns || http)"
(click)="validate()"
>
{{ 'ACTIONS.VERIFY' | translate }} {{ 'ACTIONS.VERIFY' | translate }}
</button> </button>
<mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner> <mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner>
<button *ngIf="!showNew" mat-stroked-button color="primary" <button *ngIf="!showNew" mat-stroked-button color="primary" (click)="showNew = true">
(click)="showNew = true">{{'ORG.PAGES.ORGDOMAIN.REQUESTNEWTOKEN' | translate}}</button> {{ 'ORG.PAGES.ORGDOMAIN.REQUESTNEWTOKEN' | translate }}
</button>
</div> </div>
<ng-container *ngIf="showNew"> <ng-container *ngIf="showNew">
@ -33,11 +44,10 @@
<div *ngIf="http"> <div *ngIf="http">
<p>HTTP TOKEN</p> <p>HTTP TOKEN</p>
<p class="entry">{{http?.url}}.txt</p> <p class="entry">{{ http?.url }}.txt</p>
<div class="btn-container"> <div class="btn-container">
<button mat-stroked-button (click)="saveFile()" color="primary">{{ 'ORG.PAGES.DOWNLOAD_FILE' | translate <button mat-stroked-button (click)="saveFile()" color="primary">{{ 'ORG.PAGES.DOWNLOAD_FILE' | translate }}</button>
}}</button>
<button color="primary" class="verify-button" type="submit" mat-raised-button (click)="validate()"> <button color="primary" class="verify-button" type="submit" mat-raised-button (click)="validate()">
<span>{{ 'ACTIONS.VERIFY' | translate }}</span> <span>{{ 'ACTIONS.VERIFY' | translate }}</span>
</button> </button>
@ -47,10 +57,17 @@
<div *ngIf="dns"> <div *ngIf="dns">
<p>DNS TOKEN</p> <p>DNS TOKEN</p>
<div class="line" *ngIf="dns?.token"> <div class="domain-line" *ngIf="dns?.token">
<p class="entry">{{dns?.token}}</p> <p class="entry">{{ dns?.token }}</p>
<button color="primary" [disabled]="copied === data.clientSecret" matTooltip="copy to clipboard" <button
cnslCopyToClipboard [valueToCopy]="dns.token" (copiedValue)="copied = $event" mat-icon-button> color="primary"
[disabled]="copied === data.clientSecret"
matTooltip="copy to clipboard"
cnslCopyToClipboard
[valueToCopy]="dns.token"
(copiedValue)="copied = $event"
mat-icon-button
>
<i *ngIf="copied !== dns.token" class="las la-clipboard"></i> <i *ngIf="copied !== dns.token" class="las la-clipboard"></i>
<i *ngIf="copied === dns.token" class="las la-clipboard-check"></i> <i *ngIf="copied === dns.token" class="las la-clipboard-check"></i>
</button> </button>
@ -59,12 +76,12 @@
</button> </button>
<mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner> <mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner>
</div> </div>
<p class="entry">{{dns?.url}}</p> <p class="entry">{{ dns?.url }}</p>
</div> </div>
</ng-container> </ng-container>
</div> </div>
<div mat-dialog-actions class="action"> <div mat-dialog-actions class="action">
<button mat-stroked-button class="ok-button" (click)="closeDialog()"> <button mat-stroked-button (click)="closeDialog()">
{{'ACTIONS.CLOSE' | translate}} {{ 'ACTIONS.CLOSE' | translate }}
</button> </button>
</div> </div>

View File

@ -14,9 +14,10 @@
.entry { .entry {
margin: 0.5rem 0; margin: 0.5rem 0;
display: inline-block;
} }
.line { .domain-line {
display: flex; display: flex;
align-items: center; align-items: center;
} }
@ -24,8 +25,4 @@
.action { .action {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
.ok-button {
margin-left: 0.5rem;
}
} }

View File

@ -22,11 +22,11 @@
<form [formGroup]="orgForm" (ngSubmit)="next()"> <form [formGroup]="orgForm" (ngSubmit)="next()">
<div class="content"> <div class="content">
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</cnsl-label> <cnsl-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</cnsl-label>
<input cnslInput formControlName="name" /> <input cnslInput formControlName="name" />
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'ORG_DETAIL.DETAIL.DOMAIN' | translate }}</cnsl-label> <cnsl-label>{{ 'ORG_DETAIL.DETAIL.DOMAIN' | translate }}</cnsl-label>
<input cnslInput formControlName="domain" /> <input cnslInput formControlName="domain" />
</cnsl-form-field> </cnsl-form-field>
@ -54,35 +54,35 @@
<form [formGroup]="userForm" class="form"> <form [formGroup]="userForm" class="form">
<div class="content"> <div class="content">
<p class="section cnsl-secondary-text">{{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}</p> <p class="section cnsl-secondary-text">{{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}</p>
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PROFILE.USERNAME' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PROFILE.USERNAME' | translate }}</cnsl-label>
<input cnslInput formControlName="userName" required /> <input cnslInput formControlName="userName" required />
<span cnslError *ngIf="userName?.invalid && userName?.errors?.required"> <span cnslError *ngIf="userName?.invalid && userName?.errors?.required">
{{ 'USER.VALIDATION.REQUIRED' | translate }} {{ 'USER.VALIDATION.REQUIRED' | translate }}
</span> </span>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PROFILE.EMAIL' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PROFILE.EMAIL' | translate }}</cnsl-label>
<input cnslInput formControlName="email" required /> <input cnslInput formControlName="email" required />
<span cnslError *ngIf="email?.invalid && email?.errors?.required"> <span cnslError *ngIf="email?.invalid && email?.errors?.required">
{{ 'USER.VALIDATION.REQUIRED' | translate }} {{ 'USER.VALIDATION.REQUIRED' | translate }}
</span> </span>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}</cnsl-label>
<input cnslInput formControlName="firstName" required /> <input cnslInput formControlName="firstName" required />
<span cnslError *ngIf="firstName?.invalid && firstName?.errors?.required"> <span cnslError *ngIf="firstName?.invalid && firstName?.errors?.required">
{{ 'USER.VALIDATION.REQUIRED' | translate }} {{ 'USER.VALIDATION.REQUIRED' | translate }}
</span> </span>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PROFILE.LASTNAME' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PROFILE.LASTNAME' | translate }}</cnsl-label>
<input cnslInput formControlName="lastName" required /> <input cnslInput formControlName="lastName" required />
<span cnslError *ngIf="lastName?.invalid && lastName?.errors?.required"> <span cnslError *ngIf="lastName?.invalid && lastName?.errors?.required">
{{ 'USER.VALIDATION.REQUIRED' | translate }} {{ 'USER.VALIDATION.REQUIRED' | translate }}
</span> </span>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</cnsl-label>
<input cnslInput formControlName="nickName" /> <input cnslInput formControlName="nickName" />
<span cnslError *ngIf="nickName?.invalid && nickName?.errors?.required"> <span cnslError *ngIf="nickName?.invalid && nickName?.errors?.required">
@ -92,7 +92,7 @@
<p class="section cnsl-secondary-text">{{ 'USER.CREATE.GENDERLANGSECTION' | translate }}</p> <p class="section cnsl-secondary-text">{{ 'USER.CREATE.GENDERLANGSECTION' | translate }}</p>
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PROFILE.GENDER' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PROFILE.GENDER' | translate }}</cnsl-label>
<mat-select formControlName="gender"> <mat-select formControlName="gender">
<mat-option *ngFor="let gender of genders" [value]="gender"> <mat-option *ngFor="let gender of genders" [value]="gender">
@ -103,7 +103,7 @@
{{ 'USER.VALIDATION.REQUIRED' | translate }} {{ 'USER.VALIDATION.REQUIRED' | translate }}
</span> </span>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</cnsl-label>
<mat-select formControlName="preferredLanguage"> <mat-select formControlName="preferredLanguage">
<mat-option *ngFor="let language of languages" [value]="language"> <mat-option *ngFor="let language of languages" [value]="language">
@ -131,7 +131,7 @@
</cnsl-password-complexity-view> </cnsl-password-complexity-view>
<form [formGroup]="pwdForm" class="pwd-form"> <form [formGroup]="pwdForm" class="pwd-form">
<cnsl-form-field class="pwd" *ngIf="password" appearance="outline"> <cnsl-form-field class="pwd" *ngIf="password">
<cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label>
<input cnslInput autocomplete="off" name="firstpassword" formControlName="password" type="password" /> <input cnslInput autocomplete="off" name="firstpassword" formControlName="password" type="password" />
@ -139,7 +139,7 @@
{{ 'USER.VALIDATION.REQUIRED' | translate }} {{ 'USER.VALIDATION.REQUIRED' | translate }}
</span> </span>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="pwd" *ngIf="confirmPassword" appearance="outline"> <cnsl-form-field class="pwd" *ngIf="confirmPassword">
<cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label> <cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label>
<input <input
cnslInput cnslInput
@ -186,7 +186,7 @@
<form [formGroup]="orgForm" (ngSubmit)="createOrgForSelf()"> <form [formGroup]="orgForm" (ngSubmit)="createOrgForSelf()">
<div class="content"> <div class="content">
<cnsl-form-field class="formfield" appearance="outline"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</cnsl-label> <cnsl-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</cnsl-label>
<input cnslInput formControlName="name" /> <input cnslInput formControlName="name" />
</cnsl-form-field> </cnsl-form-field>

View File

@ -24,8 +24,16 @@
</cnsl-top-view> </cnsl-top-view>
<div class="max-width-container"> <div class="max-width-container">
<cnsl-meta-layout> <cnsl-meta-layout>
<ng-template cnslHasRole [hasRole]="['policy.read']"> <ng-container *ngIf="['policy.read'] | hasRole | async; else nopolicyreadpermission">
<cnsl-settings-grid [type]="PolicyComponentServiceType.MGMT"></cnsl-settings-grid> <cnsl-settings-grid [type]="PolicyComponentServiceType.MGMT"></cnsl-settings-grid>
</ng-container>
<ng-template #nopolicyreadpermission>
<div class="no-permission-warn-wrapper">
<cnsl-info-section class="info-section-warn" [fitWidth]="true" [type]="InfoSectionType.ALERT">{{
'ORG.PAGES.NOPERMISSION' | translate
}}</cnsl-info-section>
</div>
</ng-template> </ng-template>
<div metainfo> <div metainfo>

View File

@ -8,3 +8,7 @@
text-transform: uppercase; text-transform: uppercase;
margin-top: 2rem; margin-top: 2rem;
} }
.no-permission-warn-wrapper {
padding-top: 1.5rem;
}

View File

@ -5,6 +5,7 @@ import { BehaviorSubject, from, Observable, of, Subject, takeUntil } from 'rxjs'
import { catchError, finalize, map } from 'rxjs/operators'; import { catchError, finalize, map } from 'rxjs/operators';
import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-member-dialog/member-create-dialog.component'; import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-member-dialog/member-create-dialog.component';
import { ChangeType } from 'src/app/modules/changes/changes.component'; import { ChangeType } from 'src/app/modules/changes/changes.component';
import { InfoSectionType } from 'src/app/modules/info-section/info-section.component';
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum'; import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
import { Member } from 'src/app/proto/generated/zitadel/member_pb'; import { Member } from 'src/app/proto/generated/zitadel/member_pb';
import { Org, OrgState } from 'src/app/proto/generated/zitadel/org_pb'; import { Org, OrgState } from 'src/app/proto/generated/zitadel/org_pb';
@ -31,6 +32,8 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
public totalMemberResult: number = 0; public totalMemberResult: number = 0;
public membersSubject: BehaviorSubject<Member.AsObject[]> = new BehaviorSubject<Member.AsObject[]>([]); public membersSubject: BehaviorSubject<Member.AsObject[]> = new BehaviorSubject<Member.AsObject[]>([]);
private destroy$: Subject<void> = new Subject(); private destroy$: Subject<void> = new Subject();
public InfoSectionType: any = InfoSectionType;
constructor( constructor(
private dialog: MatDialog, private dialog: MatDialog,
public mgmtService: ManagementService, public mgmtService: ManagementService,

View File

@ -24,7 +24,7 @@
<ng-template matStepLabel>{{ 'APP.OIDC.NAMEANDTYPESECTION' | translate }}</ng-template> <ng-template matStepLabel>{{ 'APP.OIDC.NAMEANDTYPESECTION' | translate }}</ng-template>
<p class="step-title">{{ 'APP.OIDC.TITLEFIRST' | translate }}</p> <p class="step-title">{{ 'APP.OIDC.TITLEFIRST' | translate }}</p>
<cnsl-form-field appearance="outline" class="name-formfield"> <cnsl-form-field class="name-formfield">
<cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label>
<input cnslInput cdkFocusInitial formControlName="name" /> <input cnslInput cdkFocusInitial formControlName="name" />
<span cnslError *ngIf="name?.errors?.required">{{ 'PROJECT.APP.NAMEREQUIRED' | translate }}</span> <span cnslError *ngIf="name?.errors?.required">{{ 'PROJECT.APP.NAMEREQUIRED' | translate }}</span>
@ -250,12 +250,12 @@
<div *ngIf="devmode" class="dev"> <div *ngIf="devmode" class="dev">
<form [formGroup]="form" (ngSubmit)="createApp()" [attr.data-e2e]="'create-app-wizzard-3'"> <form [formGroup]="form" (ngSubmit)="createApp()" [attr.data-e2e]="'create-app-wizzard-3'">
<div class="content"> <div class="content">
<cnsl-form-field appearance="outline" class="formfield"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label>
<input cnslInput formControlName="name" /> <input cnslInput formControlName="name" />
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field appearance="outline" class="formfield"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'APP.TYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.TYPE' | translate }}</cnsl-label>
<mat-select formControlName="appType"> <mat-select formControlName="appType">
<mat-option *ngFor="let appType of appTypes" [value]="appType"> <mat-option *ngFor="let appType of appTypes" [value]="appType">
@ -265,7 +265,7 @@
</cnsl-form-field> </cnsl-form-field>
<ng-container *ngIf="formappType?.value?.createType === AppCreateType.OIDC"> <ng-container *ngIf="formappType?.value?.createType === AppCreateType.OIDC">
<cnsl-form-field appearance="outline" class="formfield"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'APP.OIDC.GRANTTYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.OIDC.GRANTTYPE' | translate }}</cnsl-label>
<mat-select formControlName="grantTypesList" multiple> <mat-select formControlName="grantTypesList" multiple>
<mat-option *ngFor="let grant of oidcGrantTypes" [value]="grant.type"> <mat-option *ngFor="let grant of oidcGrantTypes" [value]="grant.type">
@ -274,7 +274,7 @@
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field appearance="outline" class="formfield"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'APP.OIDC.RESPONSETYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.OIDC.RESPONSETYPE' | translate }}</cnsl-label>
<mat-select formControlName="responseTypesList" multiple> <mat-select formControlName="responseTypesList" multiple>
<mat-option *ngFor="let type of oidcResponseTypes" [value]="type.type"> <mat-option *ngFor="let type of oidcResponseTypes" [value]="type.type">
@ -284,7 +284,7 @@
</cnsl-form-field> </cnsl-form-field>
</ng-container> </ng-container>
<cnsl-form-field appearance="outline" class="formfield"> <cnsl-form-field class="formfield">
<cnsl-label>{{ 'APP.AUTHMETHOD' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.AUTHMETHOD' | translate }}</cnsl-label>
<mat-select formControlName="authMethodType"> <mat-select formControlName="authMethodType">
<mat-option *ngFor="let type of authMethodTypes" [value]="type.type"> <mat-option *ngFor="let type of authMethodTypes" [value]="type.type">

View File

@ -87,12 +87,12 @@
<form [formGroup]="oidcForm" (ngSubmit)="saveOIDCApp()"> <form [formGroup]="oidcForm" (ngSubmit)="saveOIDCApp()">
<div class="app-oidc-content"> <div class="app-oidc-content">
<div class="app-oidc-grid"> <div class="app-oidc-grid">
<cnsl-form-field class="app-formfield" appearance="outline"> <cnsl-form-field class="app-formfield">
<cnsl-label>{{ 'APP.OIDC.CLIENTID' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.OIDC.CLIENTID' | translate }}</cnsl-label>
<input cnslInput formControlName="clientId" /> <input cnslInput formControlName="clientId" />
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field appearance="outline" class="app-formfield"> <cnsl-form-field class="app-formfield">
<cnsl-label>{{ 'APP.TYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.TYPE' | translate }}</cnsl-label>
<mat-select formControlName="appType"> <mat-select formControlName="appType">
<mat-option *ngFor="let type of oidcAppTypes" [value]="type"> <mat-option *ngFor="let type of oidcAppTypes" [value]="type">
@ -101,7 +101,7 @@
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="app-formfield" appearance="outline"> <cnsl-form-field class="app-formfield">
<cnsl-label>{{ 'APP.OIDC.RESPONSETYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.OIDC.RESPONSETYPE' | translate }}</cnsl-label>
<mat-select formControlName="responseTypesList" multiple> <mat-select formControlName="responseTypesList" multiple>
<mat-option *ngFor="let type of oidcResponseTypes" [value]="type"> <mat-option *ngFor="let type of oidcResponseTypes" [value]="type">
@ -110,7 +110,7 @@
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field appearance="outline" class="app-formfield"> <cnsl-form-field class="app-formfield">
<cnsl-label>{{ 'APP.AUTHMETHOD' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.AUTHMETHOD' | translate }}</cnsl-label>
<mat-select formControlName="authMethodType"> <mat-select formControlName="authMethodType">
<mat-option *ngFor="let type of oidcAuthMethodType" [value]="type"> <mat-option *ngFor="let type of oidcAuthMethodType" [value]="type">
@ -119,7 +119,7 @@
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<cnsl-form-field class="app-formfield" appearance="outline"> <cnsl-form-field class="app-formfield">
<cnsl-label>{{ 'APP.OIDC.GRANTTYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.OIDC.GRANTTYPE' | translate }}</cnsl-label>
<mat-select formControlName="grantTypesList" multiple> <mat-select formControlName="grantTypesList" multiple>
<mat-option *ngFor="let grant of oidcGrantTypes" [value]="grant"> <mat-option *ngFor="let grant of oidcGrantTypes" [value]="grant">
@ -158,7 +158,7 @@
<ng-container *ngIf="currentSetting === 'token'"> <ng-container *ngIf="currentSetting === 'token'">
<cnsl-card *ngIf="oidcTokenForm && app?.oidcConfig" title=" {{ 'APP.OIDC.TOKENSECTIONTITLE' | translate }}"> <cnsl-card *ngIf="oidcTokenForm && app?.oidcConfig" title=" {{ 'APP.OIDC.TOKENSECTIONTITLE' | translate }}">
<form [formGroup]="oidcTokenForm" (ngSubmit)="saveOIDCApp()"> <form [formGroup]="oidcTokenForm" (ngSubmit)="saveOIDCApp()">
<cnsl-form-field appearance="outline" class="app-formfield"> <cnsl-form-field class="app-formfield">
<cnsl-label>{{ 'APP.OIDC.TOKENTYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'APP.OIDC.TOKENTYPE' | translate }}</cnsl-label>
<mat-select formControlName="accessTokenType"> <mat-select formControlName="accessTokenType">
<mat-option *ngFor="let type of oidcTokenTypes" [value]="type"> <mat-option *ngFor="let type of oidcTokenTypes" [value]="type">

View File

@ -124,6 +124,24 @@
"SHOWUSER": "Zeige Benutzer {{value}}" "SHOWUSER": "Zeige Benutzer {{value}}"
} }
}, },
"MEMBERROLES": {
"IAM_OWNER": "Hat die Kontrolle über die gesamte Instanz, einschließlich aller Organisationen",
"IAM_OWNER_VIEWER": "Hat die Leseberechtigung, die gesamte Instanz einschließlich aller Organisationen zu überprüfen",
"IAM_ORG_MANAGER": "Hat die Berechtigung zum Erstellen und Verwalten von Organisationen",
"IAM_USER_MANAGER": "Hat die Berechtigung zum Erstellen und Verwalten von Benutzern",
"ORG_OWNER": "Hat die Berechtigung für die gesamte Organisation",
"ORG_USER_MANAGER": "Hat die Berechtigung, Benutzer der Organisation zu erstellen und zu verwalten",
"ORG_OWNER_VIEWER": "Hat die Leseberechtigung, die gesamte Organisation zu überprüfen",
"ORG_USER_PERMISSION_EDITOR": "Verfügt über die Berechtigung zum Verwalten von User grants",
"ORG_PROJECT_PERMISSION_EDITOR": "Hat die Berechtigung, Projektberechtigungen für externe Organisationen zu verwalten",
"ORG_PROJECT_CREATOR": "Hat die Berechtigung, seine eigenen Projekte und zugrunde liegenden Einstellungen zu erstellen",
"PROJECT_OWNER": "Hat die Berechtigung für das gesamte Projekt",
"PROJECT_OWNER_VIEWER": "Hat die Leseberechtigung, das gesamte Projekt zu überprüfen",
"PROJECT_OWNER_GLOBAL": "Hat die Berechtigung für das gesamte Projekt",
"PROJECT_OWNER_VIEWER_GLOBAL": "Hat die Leseberechtigung, das gesamte Projekt zu überprüfen",
"PROJECT_GRANT_OWNER": "Hat die Berechtigung, die Projektberechtigungen für externe Organisationen zu verwalten",
"PROJECT_GRANT_OWNER_VIEWER": "Hat die Leseberechtigung, die Projektberechtigungen für externe Organisationen zu überprüfen"
},
"OVERLAYS": { "OVERLAYS": {
"ORGSWITCHER": { "ORGSWITCHER": {
"TEXT": "Alle Organisationseinstellungen und Tabellen basieren auf dieser ausgewählten Organisation. Klicken Sie auf diese Schaltfläche, um die Organisation zu wechseln oder eine neue zu erstellen." "TEXT": "Alle Organisationseinstellungen und Tabellen basieren auf dieser ausgewählten Organisation. Klicken Sie auf diese Schaltfläche, um die Organisation zu wechseln oder eine neue zu erstellen."
@ -738,6 +756,7 @@
"LISTDESCRIPTION": "Wähle eine Organisation aus.", "LISTDESCRIPTION": "Wähle eine Organisation aus.",
"ACTIVE": "Aktiv", "ACTIVE": "Aktiv",
"CREATE": "Organisation erstellen", "CREATE": "Organisation erstellen",
"NOPERMISSION": "Sie haben keine Berechtigung, auf Einstellungen der Organisation zuzugreifen.",
"USERSELFACCOUNT": "Verwenden Sie Ihr persönliches Konto als Organisationsinhaber", "USERSELFACCOUNT": "Verwenden Sie Ihr persönliches Konto als Organisationsinhaber",
"ORGDETAIL_TITLE": "Gebe den Namen und die Domain für die neue Organisation ein.", "ORGDETAIL_TITLE": "Gebe den Namen und die Domain für die neue Organisation ein.",
"ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Geben Sie den Namen der neuen Organisation ein.", "ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Geben Sie den Namen der neuen Organisation ein.",

View File

@ -124,6 +124,24 @@
"SHOWUSER": "Show user {{value}}" "SHOWUSER": "Show user {{value}}"
} }
}, },
"MEMBERROLES": {
"IAM_OWNER": "Has control over the whole instance, including all organizations",
"IAM_OWNER_VIEWER": "Has permission to review the whole instance, including all organizations",
"IAM_ORG_MANAGER": "Has permission to create and manage organizations",
"IAM_USER_MANAGER": "Has permission to create and manage users",
"ORG_OWNER": "Has permission over the whole organization",
"ORG_USER_MANAGER": "Has permission to create and manage users of the organization",
"ORG_OWNER_VIEWER": "Has permission to review the whole organization",
"ORG_USER_PERMISSION_EDITOR": "Has permission to manage user grants",
"ORG_PROJECT_PERMISSION_EDITOR": "Has permission to manage project grants",
"ORG_PROJECT_CREATOR": "Has permission to create his own projects and underlying settings",
"PROJECT_OWNER": "Has permission over the whole project",
"PROJECT_OWNER_VIEWER": "Has permission to review the whole project",
"PROJECT_OWNER_GLOBAL": "Has permission over the whole project",
"PROJECT_OWNER_VIEWER_GLOBAL": "Has permission to review the whole project",
"PROJECT_GRANT_OWNER": "Has permission to manage the project grant",
"PROJECT_GRANT_OWNER_VIEWER": "Has permission to review the project grant"
},
"OVERLAYS": { "OVERLAYS": {
"ORGSWITCHER": { "ORGSWITCHER": {
"TEXT": "All organization settings and tables in console are based on a selected organization. Click this button to switch organization or create a new one." "TEXT": "All organization settings and tables in console are based on a selected organization. Click this button to switch organization or create a new one."
@ -738,6 +756,7 @@
"LISTDESCRIPTION": "Choose an organization.", "LISTDESCRIPTION": "Choose an organization.",
"ACTIVE": "Active", "ACTIVE": "Active",
"CREATE": "Create Organization", "CREATE": "Create Organization",
"NOPERMISSION": "You don't have the permission to access organization settings.",
"USERSELFACCOUNT": "Use your personal account as organization owner", "USERSELFACCOUNT": "Use your personal account as organization owner",
"ORGDETAIL_TITLE": "Enter the name and domain of your new organization.", "ORGDETAIL_TITLE": "Enter the name and domain of your new organization.",
"ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Enter the name of your new organization.", "ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Enter the name of your new organization.",

View File

@ -124,6 +124,24 @@
"SHOWUSER": "Mostra utente {{value}}" "SHOWUSER": "Mostra utente {{value}}"
} }
}, },
"MEMBERROLES": {
"IAM_OWNER": "Ha il controllo sull'intera istanza, comprese tutte le organizzazioni",
"IAM_OWNER_VIEWER": "Ha l'autorizzazione per esaminare l'intera istanza, comprese tutte le organizzazioni",
"IAM_ORG_MANAGER": "Ha il permesso di creare e gestire organizzazioni",
"IAM_USER_MANAGER": "Ha l'autorizzazione per creare e gestire utenti",
"ORG_OWNER": "Ha il permesso su tutta l'organizzazione",
"ORG_USER_MANAGER": "Ha l'autorizzazione per creare e gestire gli utenti dell'organizzazione",
"ORG_OWNER_VIEWER": "Ha il permesso di esaminare l'intera organizzazione",
"ORG_USER_PERMISSION_EDITOR": "Ha l'autorizzazione per gestire le autorizzazioni degli utenti",
"ORG_PROJECT_PERMISSION_EDITOR": "Ha il permesso di gestire le sovvenzioni di progetto (Project Grant)",
"ORG_PROJECT_CREATOR": "Ha il permesso di creare propri progetti e le impostazioni sottostanti",
"PROJECT_OWNER": "Ha il permesso per l'intero progetto",
"PROJECT_OWNER_VIEWER": "Ha il permesso di esaminare l'intero progetto",
"PROJECT_OWNER_GLOBAL": "Ha il permesso per l'intero progetto",
"PROJECT_OWNER_VIEWER_GLOBAL": "Ha il permesso di esaminare l'intero progetto",
"PROJECT_GRANT_OWNER": "Ha l'autorizzazione per gestire le sovvenzioni di progetto (Project Grant)",
"PROJECT_GRANT_OWNER_VIEWER": "Ha il permesso di esaminare le sovvenzioni di progetto (Project Grant)"
},
"OVERLAYS": { "OVERLAYS": {
"ORGSWITCHER": { "ORGSWITCHER": {
"TEXT": "Tutte le impostazioni e le tabelle dell'organizzazione si basano su un'organizzazione selezionata. Fai clic sul pulsante per cambiare organizzazione o crearne una nuova." "TEXT": "Tutte le impostazioni e le tabelle dell'organizzazione si basano su un'organizzazione selezionata. Fai clic sul pulsante per cambiare organizzazione o crearne una nuova."
@ -738,6 +756,7 @@
"LISTDESCRIPTION": "Scegli un'organizzazione.", "LISTDESCRIPTION": "Scegli un'organizzazione.",
"ACTIVE": "Attivo", "ACTIVE": "Attivo",
"CREATE": "Creare un'organizzazione", "CREATE": "Creare un'organizzazione",
"NOPERMISSION": "Non hai l'autorizzazione per accedere alle impostazioni dell'organizzazione.",
"USERSELFACCOUNT": "Usa il tuo account personale come proprietario dell'organizzazione", "USERSELFACCOUNT": "Usa il tuo account personale come proprietario dell'organizzazione",
"ORGDETAIL_TITLE": "Inserisci il nome e il dominio della tua nuova organizzazione.", "ORGDETAIL_TITLE": "Inserisci il nome e il dominio della tua nuova organizzazione.",
"ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Inserisci il nome della tua nuova organizzazione.", "ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Inserisci il nome della tua nuova organizzazione.",

View File

@ -413,6 +413,10 @@ $custom-typography: mat.define-typography-config(
} }
} }
.mat-calendar-table {
height: 280px;
}
@include component-themes($caos-dark-app-theme); @include component-themes($caos-dark-app-theme);
@include mat.all-component-themes($caos-dark-app-theme); @include mat.all-component-themes($caos-dark-app-theme);
@ -448,7 +452,8 @@ $custom-typography: mat.define-typography-config(
} }
.main-container, .main-container,
.mat-dialog-container { .mat-dialog-container,
.mat-calendar {
background-color: map-get($background, background); background-color: map-get($background, background);
transition: background-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); transition: background-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
} }
@ -510,7 +515,8 @@ $custom-typography: mat.define-typography-config(
} }
.main-container, .main-container,
.mat-dialog-container { .mat-dialog-container,
.mat-calendar {
background-color: map-get($background, background); background-color: map-get($background, background);
transition: background-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); transition: background-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
} }