mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
chore: deps update (#11968)
# Which Problems Are Solved This pr updates major and minor dependencies and is the first step on getting our dependabot alerts cut down. # How the Problems Are Solved Depedency updates across the board eg: - Upgrade Angular to v21 - Upgrade next.js to v16.2 - Upgrade tailwind to v4 in the login - Upgrade vitest to v4 in the login This is an uncompleted list refer to the changed files for a full overview of all the updates. # Additional Changes Migrated all control flow in the console to the modern control flow syntax. Fixed the dependsOn setting for the @zitadel/login:test-unit nx target. # Additional Context - Closes https://github.com/zitadel/zitadel/issues/11274 --------- Co-authored-by: Max Peintner <[email protected]>
This commit is contained in:
+43
-44
@@ -13,78 +13,77 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^20.3.16",
|
||||
"@angular/cdk": "^20.2.14",
|
||||
"@angular/common": "^20.3.16",
|
||||
"@angular/compiler": "^20.3.16",
|
||||
"@angular/core": "^20.3.16",
|
||||
"@angular/forms": "^20.3.16",
|
||||
"@angular/material": "^20.2.14",
|
||||
"@angular/material-moment-adapter": "^20.2.14",
|
||||
"@angular/platform-browser": "^20.3.16",
|
||||
"@angular/platform-browser-dynamic": "^20.3.16",
|
||||
"@angular/router": "^20.3.16",
|
||||
"@angular/service-worker": "^20.3.16",
|
||||
"@angular/animations": "^21.2.6",
|
||||
"@angular/cdk": "^21.2.4",
|
||||
"@angular/common": "^21.2.6",
|
||||
"@angular/compiler": "^21.2.6",
|
||||
"@angular/core": "^21.2.6",
|
||||
"@angular/forms": "^21.2.6",
|
||||
"@angular/material": "^21.2.4",
|
||||
"@angular/material-moment-adapter": "^21.2.4",
|
||||
"@angular/platform-browser": "^21.2.6",
|
||||
"@angular/platform-browser-dynamic": "^21.2.6",
|
||||
"@angular/router": "^21.2.6",
|
||||
"@angular/service-worker": "^21.2.6",
|
||||
"@bufbuild/protobuf": "^2.11.0",
|
||||
"@connectrpc/connect": "~2.0.4",
|
||||
"@connectrpc/connect-web": "~2.0.4",
|
||||
"@ctrl/ngx-codemirror": "^6.1.0",
|
||||
"@fortawesome/angular-fontawesome": "^3.0.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.7.2",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.7.2",
|
||||
"@netlify/build-info": "^10.3.0",
|
||||
"@ng-icons/core": "^32.5.0",
|
||||
"@ng-icons/heroicons": "^32.5.0",
|
||||
"@connectrpc/connect": "^2.1.1",
|
||||
"@connectrpc/connect-web": "^2.1.1",
|
||||
"@ctrl/ngx-codemirror": "^7.0.0",
|
||||
"@fortawesome/angular-fontawesome": "^4.0.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^7.2.0",
|
||||
"@netlify/build-info": "^10.4.0",
|
||||
"@ng-icons/core": "^33.2.0",
|
||||
"@ng-icons/heroicons": "^33.2.0",
|
||||
"@ngx-translate/core": "^17.0.0",
|
||||
"@tanstack/angular-query-experimental": "^5.90.24",
|
||||
"@tanstack/angular-query-experimental": "^5.96.1",
|
||||
"angular-oauth2-oidc": "^20.0.2",
|
||||
"angularx-qrcode": "^20.0.0",
|
||||
"angularx-qrcode": "^21.0.5",
|
||||
"buffer": "^6.0.3",
|
||||
"codemirror": "^5.65.20",
|
||||
"codemirror": "^5.65.21",
|
||||
"file-saver": "^2.0.5",
|
||||
"flag-icons": "^7.5.0",
|
||||
"google-protobuf": "~3.21.4",
|
||||
"grpc-web": "~1.5.0",
|
||||
"google-protobuf": "^4.0.2",
|
||||
"grpc-web": "^2.0.2",
|
||||
"i18n-iso-countries": "^7.14.0",
|
||||
"libphonenumber-js": "^1.12.35",
|
||||
"libphonenumber-js": "^1.12.41",
|
||||
"material-design-icons-iconfont": "^6.7.0",
|
||||
"moment": "^2.30.1",
|
||||
"ngx-color": "^9.0.0",
|
||||
"ngx-color": "^10.1.0",
|
||||
"opentype.js": "^1.3.4",
|
||||
"posthog-js": "^1.335.3",
|
||||
"posthog-js": "^1.364.5",
|
||||
"rxjs": "^7.8.2",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"tslib": "^2.8.1",
|
||||
"uuid": "^10.0.0",
|
||||
"uuid": "^13.0.0",
|
||||
"zone.js": "~0.15.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-eslint/eslint-plugin": "21.3.0",
|
||||
"@angular-eslint/eslint-plugin-template": "21.3.0",
|
||||
"@angular-eslint/template-parser": "21.3.0",
|
||||
"@angular/build": "^20.3.15",
|
||||
"@angular/cli": "^20.3.15",
|
||||
"@angular/compiler-cli": "^20.3.16",
|
||||
"@angular/language-service": "^20.3.16",
|
||||
"@eslint/js": "^10.0.0",
|
||||
"@angular/build": "^21.2.6",
|
||||
"@angular/cli": "^21.2.6",
|
||||
"@angular/compiler-cli": "^21.2.6",
|
||||
"@angular/language-service": "^21.2.6",
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/google-protobuf": "~3.15.12",
|
||||
"@types/google-protobuf": "^3.15.12",
|
||||
"@types/jasmine": "~5.1.15",
|
||||
"@types/jasminewd2": "~2.0.13",
|
||||
"@types/jsonwebtoken": "^9.0.10",
|
||||
"@types/node": "^22.19.7",
|
||||
"@types/node": "^25.5.0",
|
||||
"@types/opentype.js": "^1.3.9",
|
||||
"@types/qrcode": "^1.5.6",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.57.0",
|
||||
"@typescript-eslint/parser": "^8.57.0",
|
||||
"@types/uuid": "^11.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
||||
"@typescript-eslint/parser": "^8.58.0",
|
||||
"@zitadel/client": "workspace:*",
|
||||
"@zitadel/proto": "workspace:*",
|
||||
"eslint": "^10.0.0",
|
||||
"eslint": "^10.1.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-import-resolver-typescript": "^4.4.4",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"globals": "^17.0.0",
|
||||
"globals": "^17.4.0",
|
||||
"jasmine-core": "~5.12.1",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "^6.4.4",
|
||||
@@ -92,7 +91,7 @@
|
||||
"karma-coverage": "^2.2.1",
|
||||
"karma-coverage-istanbul-reporter": "^3.0.3",
|
||||
"karma-jasmine": "^5.1.0",
|
||||
"karma-jasmine-html-reporter": "^2.1.0",
|
||||
"karma-jasmine-html-reporter": "^2.2.0",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-organize-imports": "^4.3.0",
|
||||
"typescript": "5.9.2"
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<div class="main-container">
|
||||
<ng-container *ngIf="authService.user | async as user">
|
||||
@if (authService.user | async; as user) {
|
||||
<cnsl-header
|
||||
[org]="activeOrganizationQuery.data()"
|
||||
[user]="user"
|
||||
[isDarkTheme]="componentCssClass === 'dark-theme'"
|
||||
(changedActiveOrg)="changedOrg()"
|
||||
/>
|
||||
|
||||
<cnsl-nav
|
||||
id="mainnav"
|
||||
class="nav"
|
||||
@@ -15,7 +14,7 @@
|
||||
[user]="user"
|
||||
[isDarkTheme]="componentCssClass === 'dark-theme'"
|
||||
></cnsl-nav>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<div class="router-container" [@routeAnimations]="prepareRoute(outlet)">
|
||||
<div class="outlet">
|
||||
|
||||
@@ -1,40 +1,41 @@
|
||||
<div class="feature-row" *ngIf="toggleState$ | async as toggleState">
|
||||
<span>{{ 'SETTING.FEATURES.' + (toggleStateKey | uppercase) | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleState.enabled"
|
||||
(change)="toggleChange.emit(toggleState)"
|
||||
name="displayview"
|
||||
>
|
||||
<mat-button-toggle [value]="false">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
|
||||
<div
|
||||
*ngIf="!toggleState.enabled && (isInherited$ | async)"
|
||||
class="current-dot"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="true">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
<div
|
||||
*ngIf="toggleState.enabled && (isInherited$ | async)"
|
||||
class="current-dot"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
@if (toggleState$ | async; as toggleState) {
|
||||
<div class="feature-row">
|
||||
<span>{{ 'SETTING.FEATURES.' + (toggleStateKey | uppercase) | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleState.enabled"
|
||||
(change)="toggleChange.emit(toggleState)"
|
||||
name="displayview"
|
||||
>
|
||||
<mat-button-toggle [value]="false">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
@if (!toggleState.enabled && (isInherited$ | async)) {
|
||||
<div
|
||||
class="current-dot"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
}
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="true">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
@if (toggleState.enabled && (isInherited$ | async)) {
|
||||
<div
|
||||
class="current-dot"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
}
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<ng-content></ng-content>
|
||||
@if ('SETTING.FEATURES.' + (toggleStateKey | uppercase) + '_DESCRIPTION' | translate; as i18nDescription) {
|
||||
<cnsl-info-section class="feature-info">{{ i18nDescription }}</cnsl-info-section>
|
||||
}
|
||||
</div>
|
||||
<ng-content></ng-content>
|
||||
<cnsl-info-section
|
||||
class="feature-info"
|
||||
*ngIf="'SETTING.FEATURES.' + (toggleStateKey | uppercase) + '_DESCRIPTION' | translate as i18nDescription"
|
||||
>{{ i18nDescription }}</cnsl-info-section
|
||||
>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AsyncPipe, NgIf, UpperCasePipe } from '@angular/common';
|
||||
import { AsyncPipe, UpperCasePipe } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
@@ -23,7 +23,6 @@ import { map } from 'rxjs/operators';
|
||||
MatTooltipModule,
|
||||
InfoSectionModule,
|
||||
AsyncPipe,
|
||||
NgIf,
|
||||
],
|
||||
})
|
||||
export class FeatureToggleComponent<TKey extends ToggleStateKeys, TValue extends ToggleStates[TKey]> {
|
||||
|
||||
@@ -18,15 +18,21 @@
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<cnsl-card *ngIf="toggleStates$ | async as toggleStates">
|
||||
<div class="features">
|
||||
<cnsl-feature-toggle
|
||||
*ngFor="let key of FEATURE_KEYS"
|
||||
[toggleStateKey]="key"
|
||||
[toggleState]="toggleStates[key]"
|
||||
(toggleChange)="saveFeature(key, $event)"
|
||||
></cnsl-feature-toggle>
|
||||
<cnsl-login-v2-feature-toggle [toggleState]="toggleStates.loginV2" (toggleChanged)="saveFeature('loginV2', $event)" />
|
||||
</div>
|
||||
</cnsl-card>
|
||||
@if (toggleStates$ | async; as toggleStates) {
|
||||
<cnsl-card>
|
||||
<div class="features">
|
||||
@for (key of FEATURE_KEYS; track key) {
|
||||
<cnsl-feature-toggle
|
||||
[toggleStateKey]="key"
|
||||
[toggleState]="toggleStates[key]"
|
||||
(toggleChange)="saveFeature(key, $event)"
|
||||
></cnsl-feature-toggle>
|
||||
}
|
||||
<cnsl-login-v2-feature-toggle
|
||||
[toggleState]="toggleStates.loginV2"
|
||||
(toggleChanged)="saveFeature('loginV2', $event)"
|
||||
/>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
}
|
||||
</div>
|
||||
|
||||
+31
-23
@@ -4,32 +4,40 @@
|
||||
<input cnslInput type="text" placeholder="" #nameInput [formControl]="myControl" [matAutocomplete]="auto" />
|
||||
|
||||
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
|
||||
<mat-option *ngIf="isLoading()" class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let framework of filteredOptions | async" [value]="framework.id">
|
||||
<div class="framework-option">
|
||||
<div class="framework-option-column">
|
||||
<div class="img-wrapper">
|
||||
<img class="dark-only" *ngIf="framework.imgSrcDark" [src]="framework.imgSrcDark" />
|
||||
<img class="light-only" *ngIf="framework.imgSrcLight" [src]="framework.imgSrcLight" />
|
||||
@if (isLoading()) {
|
||||
<mat-option class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
}
|
||||
@for (framework of filteredOptions | async; track framework) {
|
||||
<mat-option [value]="framework.id">
|
||||
<div class="framework-option">
|
||||
<div class="framework-option-column">
|
||||
<div class="img-wrapper">
|
||||
@if (framework.imgSrcDark) {
|
||||
<img class="dark-only" [src]="framework.imgSrcDark" />
|
||||
}
|
||||
@if (framework.imgSrcLight) {
|
||||
<img class="light-only" [src]="framework.imgSrcLight" />
|
||||
}
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<span>{{ framework.title }}</span>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<span>{{ framework.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</mat-option>
|
||||
<mat-option *ngIf="withCustom" [value]="'other'">
|
||||
<div class="framework-option">
|
||||
<div class="framework-option-column">
|
||||
<div class="img-wrapper"></div>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<span>{{ 'QUICKSTART.FRAMEWORK_OTHER' | translate }}</span>
|
||||
</mat-option>
|
||||
}
|
||||
@if (withCustom) {
|
||||
<mat-option [value]="'other'">
|
||||
<div class="framework-option">
|
||||
<div class="framework-option-column">
|
||||
<div class="img-wrapper"></div>
|
||||
<span class="fill-space"></span>
|
||||
<span>{{ 'QUICKSTART.FRAMEWORK_OTHER' | translate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-option>
|
||||
</mat-option>
|
||||
}
|
||||
</mat-autocomplete>
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
<div class="framework-change-wrapper">
|
||||
<div class="framework-card-wrapper">
|
||||
<div class="framework-card card" *ngIf="framework | async as framework; else frameworkFallback">
|
||||
<div>
|
||||
<img class="dark-only" *ngIf="framework.imgSrcDark" [src]="framework.imgSrcDark" />
|
||||
<img class="light-only" *ngIf="framework.imgSrcLight" [src]="framework.imgSrcLight" />
|
||||
@if (framework | async; as framework) {
|
||||
<div class="framework-card card">
|
||||
<div>
|
||||
@if (framework.imgSrcDark) {
|
||||
<img class="dark-only" [src]="framework.imgSrcDark" />
|
||||
}
|
||||
@if (framework.imgSrcLight) {
|
||||
<img class="light-only" [src]="framework.imgSrcLight" />
|
||||
}
|
||||
</div>
|
||||
<span>{{ framework.title }}</span>
|
||||
</div>
|
||||
<span>{{ framework.title }}</span>
|
||||
</div>
|
||||
|
||||
<ng-template #frameworkFallback>
|
||||
} @else {
|
||||
<div class="framework-card card">
|
||||
<span>{{ 'QUICKSTART.SELECT_FRAMEWORK' | translate }}</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
}
|
||||
|
||||
<button (click)="openDialog()" mat-stroked-button>
|
||||
{{ 'ACTIONS.CHANGE' | translate }}
|
||||
|
||||
@@ -21,23 +21,35 @@
|
||||
<span class="left cnsl-secondary-text">
|
||||
{{ 'APP.GRANT' | translate }}
|
||||
</span>
|
||||
<span class="right" *ngIf="configuration.grantTypesList && configuration.grantTypesList.length > 0">
|
||||
[<span *ngFor="let element of configuration.grantTypesList ?? []; index as i">
|
||||
{{ 'APP.OIDC.GRANT.' + element | translate }}
|
||||
{{ i < configuration.grantTypesList.length - 1 ? ', ' : '' }} </span
|
||||
>]
|
||||
</span>
|
||||
@if (configuration.grantTypesList && configuration.grantTypesList.length > 0) {
|
||||
<span class="right">
|
||||
[
|
||||
@for (element of configuration.grantTypesList ?? []; track element; let i = $index) {
|
||||
<span>
|
||||
{{ 'APP.OIDC.GRANT.' + element | translate }}
|
||||
{{ i < configuration.grantTypesList.length - 1 ? ', ' : '' }}
|
||||
</span>
|
||||
}
|
||||
]
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="left cnsl-secondary-text">
|
||||
{{ 'APP.OIDC.RESPONSETYPE' | translate }}
|
||||
</span>
|
||||
<span class="right" *ngIf="configuration.responseTypesList && configuration.responseTypesList.length > 0">
|
||||
[<span *ngFor="let element of configuration.responseTypesList ?? []; index as i">
|
||||
{{ 'APP.OIDC.RESPONSE.' + element | translate }}
|
||||
{{ i < configuration.responseTypesList.length - 1 ? ', ' : '' }} </span
|
||||
>]
|
||||
</span>
|
||||
@if (configuration.responseTypesList && configuration.responseTypesList.length > 0) {
|
||||
<span class="right">
|
||||
[
|
||||
@for (element of configuration.responseTypesList ?? []; track element; let i = $index) {
|
||||
<span>
|
||||
{{ 'APP.OIDC.RESPONSE.' + element | translate }}
|
||||
{{ i < configuration.responseTypesList.length - 1 ? ', ' : '' }}
|
||||
</span>
|
||||
}
|
||||
]
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@@ -25,7 +24,7 @@ export type Framework = FrameworkDefinition & {
|
||||
selector: 'cnsl-oidc-app-configuration',
|
||||
templateUrl: './oidc-configuration.component.html',
|
||||
styleUrls: ['./oidc-configuration.component.scss'],
|
||||
imports: [TranslateModule, RouterModule, CommonModule, MatButtonModule],
|
||||
imports: [TranslateModule, RouterModule, MatButtonModule],
|
||||
})
|
||||
export class OIDCConfigurationComponent {
|
||||
@Input() public name?: string;
|
||||
|
||||
@@ -13,11 +13,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="quickstart-card-wrapper">
|
||||
<ng-container *ngFor="let framework of frameworks.slice(0, 18)">
|
||||
@for (framework of frameworks.slice(0, 18); track framework) {
|
||||
<a [routerLink]="['/projects', 'app-create']" [queryParams]="{ framework: framework.id }" class="quickstart-card card">
|
||||
<img class="dark-only" *ngIf="framework.imgSrcDark" [src]="framework.imgSrcDark" alt="{{ framework.title }}" />
|
||||
<img class="light-only" *ngIf="framework.imgSrcLight" [src]="framework.imgSrcLight" alt="{{ framework.title }}" />
|
||||
@if (framework.imgSrcDark) {
|
||||
<img class="dark-only" [src]="framework.imgSrcDark" alt="{{ framework.title }}" />
|
||||
}
|
||||
@if (framework.imgSrcLight) {
|
||||
<img class="light-only" [src]="framework.imgSrcLight" alt="{{ framework.title }}" />
|
||||
}
|
||||
</a>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@@ -27,7 +26,7 @@ export type Framework = FrameworkDefinition & {
|
||||
selector: 'cnsl-quickstart',
|
||||
templateUrl: './quickstart.component.html',
|
||||
styleUrls: ['./quickstart.component.scss'],
|
||||
imports: [TranslateModule, RouterModule, CommonModule, MatButtonModule],
|
||||
imports: [TranslateModule, RouterModule, MatButtonModule],
|
||||
})
|
||||
export class QuickstartComponent {
|
||||
public frameworks: FrameworkDefinition[] = frameworkDefinition
|
||||
|
||||
@@ -1,51 +1,56 @@
|
||||
<div class="accounts-card" *ngIf="user$ | async as user">
|
||||
<cnsl-avatar
|
||||
(click)="editUserProfile()"
|
||||
class="avatar"
|
||||
[ngClass]="{ 'iam-user': iamuser }"
|
||||
[forColor]="user.preferredLoginName"
|
||||
[avatarUrl]="user.human?.profile?.avatarUrl || ''"
|
||||
[name]="user.human?.profile?.displayName ?? ''"
|
||||
[size]="80"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
|
||||
<span class="u-name">{{ user?.human?.profile?.displayName ? user?.human?.profile?.displayName : 'A' }}</span>
|
||||
<span class="u-email" *ngIf="user?.preferredLoginName">{{ user?.preferredLoginName }}</span>
|
||||
|
||||
<button (click)="editUserProfile()" mat-stroked-button>{{ 'USER.EDITACCOUNT' | translate }}</button>
|
||||
<div class="l-accounts">
|
||||
<mat-progress-bar *ngIf="(sessions$ | async) === null" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
<a class="row" *ngFor="let session of sessions$ | async" (click)="selectAccount(session.loginName)">
|
||||
<cnsl-avatar
|
||||
*ngIf="session && session.displayName"
|
||||
class="small-avatar"
|
||||
[avatarUrl]="session.avatarUrl || ''"
|
||||
[name]="session.displayName"
|
||||
[forColor]="session.loginName"
|
||||
[size]="32"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
|
||||
<div class="col">
|
||||
<span class="user-title">{{ session.displayName ? session.displayName : session.userName }} </span>
|
||||
<span class="loginname">{{ session.loginName }}</span>
|
||||
<span class="state inactive" *ngIf="$any(session.authState) === UserState.USER_STATE_INACTIVE">{{
|
||||
'USER.STATE.' + session.authState | translate
|
||||
}}</span>
|
||||
</div>
|
||||
<mat-icon>keyboard_arrow_right</mat-icon>
|
||||
</a>
|
||||
<a class="row" (click)="selectNewAccount()">
|
||||
<div class="icon-wrapper">
|
||||
<i class="las la-user-plus"></i>
|
||||
</div>
|
||||
<span class="col">
|
||||
<span class="user-title">{{ 'USER.ADDACCOUNT' | translate }}</span>
|
||||
</span>
|
||||
<mat-icon>keyboard_arrow_right</mat-icon>
|
||||
</a>
|
||||
@if (user$ | async; as user) {
|
||||
<div class="accounts-card">
|
||||
<cnsl-avatar
|
||||
(click)="editUserProfile()"
|
||||
class="avatar"
|
||||
[ngClass]="{ 'iam-user': iamuser }"
|
||||
[forColor]="user.preferredLoginName"
|
||||
[avatarUrl]="user.human?.profile?.avatarUrl || ''"
|
||||
[name]="user.human?.profile?.displayName ?? ''"
|
||||
[size]="80"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
<span class="u-name">{{ user?.human?.profile?.displayName ? user?.human?.profile?.displayName : 'A' }}</span>
|
||||
@if (user?.preferredLoginName) {
|
||||
<span class="u-email">{{ user?.preferredLoginName }}</span>
|
||||
}
|
||||
<button (click)="editUserProfile()" mat-stroked-button>{{ 'USER.EDITACCOUNT' | translate }}</button>
|
||||
<div class="l-accounts">
|
||||
@if ((sessions$ | async) === null) {
|
||||
<mat-progress-bar color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
}
|
||||
@for (session of sessions$ | async; track session) {
|
||||
<a class="row" (click)="selectAccount(session.loginName)">
|
||||
@if (session && session.displayName) {
|
||||
<cnsl-avatar
|
||||
class="small-avatar"
|
||||
[avatarUrl]="session.avatarUrl || ''"
|
||||
[name]="session.displayName"
|
||||
[forColor]="session.loginName"
|
||||
[size]="32"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
}
|
||||
<div class="col">
|
||||
<span class="user-title">{{ session.displayName ? session.displayName : session.userName }} </span>
|
||||
<span class="loginname">{{ session.loginName }}</span>
|
||||
@if ($any(session.authState) === UserState.USER_STATE_INACTIVE) {
|
||||
<span class="state inactive">{{ 'USER.STATE.' + session.authState | translate }}</span>
|
||||
}
|
||||
</div>
|
||||
<mat-icon>keyboard_arrow_right</mat-icon>
|
||||
</a>
|
||||
}
|
||||
<a class="row" (click)="selectNewAccount()">
|
||||
<div class="icon-wrapper">
|
||||
<i class="las la-user-plus"></i>
|
||||
</div>
|
||||
<span class="col">
|
||||
<span class="user-title">{{ 'USER.ADDACCOUNT' | translate }}</span>
|
||||
</span>
|
||||
<mat-icon>keyboard_arrow_right</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
<button (click)="logout()" color="warn" mat-stroked-button>{{ 'MENU.LOGOUT' | translate }}</button>
|
||||
</div>
|
||||
|
||||
<button (click)="logout()" color="warn" mat-stroked-button>{{ 'MENU.LOGOUT' | translate }}</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,62 +1,81 @@
|
||||
<div
|
||||
*ngIf="type !== ActionKeysType.ORGSWITCHER && (isHandset$ | async) === false"
|
||||
class="action-keys-wrapper"
|
||||
[ngSwitch]="type"
|
||||
[ngClass]="{ 'without-margin': withoutMargin, 'no-contrast-mode': doNotUseContrast }"
|
||||
>
|
||||
<div *ngSwitchCase="ActionKeysType.CLEAR" class="action-keys-row">
|
||||
<div class="action-key esc">
|
||||
<div class="key-overlay"></div>
|
||||
<span>ESC</span>
|
||||
</div>
|
||||
@if (type !== ActionKeysType.ORGSWITCHER && (isHandset$ | async) === false) {
|
||||
<div class="action-keys-wrapper" [ngClass]="{ 'without-margin': withoutMargin, 'no-contrast-mode': doNotUseContrast }">
|
||||
@switch (type) {
|
||||
@case (ActionKeysType.CLEAR) {
|
||||
<div class="action-keys-row">
|
||||
<div class="action-key esc">
|
||||
<div class="key-overlay"></div>
|
||||
<span>ESC</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@case (ActionKeysType.ADD) {
|
||||
<div class="action-keys-row" data-e2e="action-key-add">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>N</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@case (ActionKeysType.DELETE) {
|
||||
<div class="action-keys-row">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
@if (isMacLike || isIOS) {
|
||||
<span>⌘</span>
|
||||
} @else {
|
||||
<span>crtl</span>
|
||||
}
|
||||
</div>
|
||||
+
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>BS</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@case (ActionKeysType.DEACTIVATE) {
|
||||
<div class="action-keys-row">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
@if (isMacLike || isIOS) {
|
||||
<span>⌘</span>
|
||||
} @else {
|
||||
<span>crtl</span>
|
||||
}
|
||||
</div>
|
||||
+
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>↓</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@case (ActionKeysType.REACTIVATE) {
|
||||
<div class="action-keys-row">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
@if (isMacLike || isIOS) {
|
||||
<span>⌘</span>
|
||||
} @else {
|
||||
<span>crtl</span>
|
||||
}
|
||||
</div>
|
||||
+
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>↑</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@case (ActionKeysType.FILTER) {
|
||||
<div class="action-keys-row">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>F</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div *ngSwitchCase="ActionKeysType.ADD" class="action-keys-row" data-e2e="action-key-add">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>N</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngSwitchCase="ActionKeysType.DELETE" class="action-keys-row">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span *ngIf="isMacLike || isIOS; else otherOS">⌘</span>
|
||||
</div>
|
||||
+
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>BS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngSwitchCase="ActionKeysType.DEACTIVATE" class="action-keys-row">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span *ngIf="isMacLike || isIOS; else otherOS">⌘</span>
|
||||
</div>
|
||||
+
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>↓</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngSwitchCase="ActionKeysType.REACTIVATE" class="action-keys-row">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span *ngIf="isMacLike || isIOS; else otherOS">⌘</span>
|
||||
</div>
|
||||
+
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>↑</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngSwitchCase="ActionKeysType.FILTER" class="action-keys-row">
|
||||
<div class="action-key">
|
||||
<div class="key-overlay"></div>
|
||||
<span>F</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #otherOS>
|
||||
<span>crtl</span>
|
||||
</ng-template>
|
||||
}
|
||||
|
||||
+5
-3
@@ -24,9 +24,11 @@
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'ACTIONSTWO.EXECUTION.TABLE.TARGET' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
<div class="target-key">
|
||||
<cnsl-project-role-chip *ngFor="let target of row.mappedTargets; trackBy: trackTarget" [roleName]="target.name">
|
||||
{{ target.name }}
|
||||
</cnsl-project-role-chip>
|
||||
@for (target of row.mappedTargets; track trackTarget($index, target)) {
|
||||
<cnsl-project-role-chip [roleName]="target.name">
|
||||
{{ target.name }}
|
||||
</cnsl-project-role-chip>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
+10
-6
@@ -3,12 +3,16 @@
|
||||
<input #input cnslInput type="text" placeholder="" [formControl]="control" [matAutocomplete]="autocomplete" />
|
||||
|
||||
<mat-autocomplete requireSelection #autocomplete="matAutocomplete">
|
||||
<mat-option *ngIf="items === undefined" class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let item of items | filter: input | async" [value]="item">
|
||||
<span>{{ item }}</span>
|
||||
</mat-option>
|
||||
@if (items === undefined) {
|
||||
<mat-option class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
}
|
||||
@for (item of items | filter: input | async; track item) {
|
||||
<mat-option [value]="item">
|
||||
<span>{{ item }}</span>
|
||||
</mat-option>
|
||||
}
|
||||
</mat-autocomplete>
|
||||
|
||||
<ng-content></ng-content>
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, Pipe, PipeTransform } from '@angular/core';
|
||||
import { AsyncPipe, NgForOf, NgIf } from '@angular/common';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { FormFieldModule } from 'src/app/modules/form-field/form-field.module';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
import { LabelModule } from 'src/app/modules/label/label.module';
|
||||
@@ -39,8 +39,6 @@ class Filter implements PipeTransform {
|
||||
MatOptionModule,
|
||||
MatProgressSpinnerModule,
|
||||
TranslateModule,
|
||||
NgIf,
|
||||
NgForOf,
|
||||
ReactiveFormsModule,
|
||||
],
|
||||
})
|
||||
|
||||
+69
-78
@@ -1,79 +1,70 @@
|
||||
<form *ngIf="form$ | async as form" [formGroup]="form.form" class="form-grid" (ngSubmit)="submit(form)">
|
||||
<ng-container *ngIf="form.case === 'request' || form.case === 'response'">
|
||||
<p class="cnsl-secondary-text">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.REQ_RESP_DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div class="emailVerified">
|
||||
<mat-checkbox [formControl]="form.form.controls.all">
|
||||
<div class="execution-condition-text">
|
||||
<span>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.ALL.TITLE' | translate }}</span>
|
||||
<span class="description cnsl-secondary-text">{{
|
||||
'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.ALL.DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
@if (form$ | async; as form) {
|
||||
<form [formGroup]="form.form" class="form-grid" (ngSubmit)="submit(form)">
|
||||
@if (form.case === 'request' || form.case === 'response') {
|
||||
<p class="cnsl-secondary-text">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.REQ_RESP_DESCRIPTION' | translate }}</p>
|
||||
<div class="emailVerified">
|
||||
<mat-checkbox [formControl]="form.form.controls.all">
|
||||
<div class="execution-condition-text">
|
||||
<span>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.ALL.TITLE' | translate }}</span>
|
||||
<span class="description cnsl-secondary-text">{{
|
||||
'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.ALL.DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_SERVICE.TITLE' | translate }}</p>
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_SERVICE.DESCRIPTION"
|
||||
[items]="listExecutionServicesQuery.data()"
|
||||
[control]="form.form.controls.service"
|
||||
></cnsl-actions-two-add-action-autocomplete-input>
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_METHOD.TITLE' | translate }}</p>
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_METHOD.DESCRIPTION"
|
||||
[items]="filteredExecutionMethods()"
|
||||
[control]="form.form.controls.method"
|
||||
></cnsl-actions-two-add-action-autocomplete-input>
|
||||
}
|
||||
@if (form.case === 'function') {
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.FUNCTIONNAME.TITLE"
|
||||
[items]="listExecutionFunctionsQuery.data()"
|
||||
[control]="form.form.controls.name"
|
||||
>
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.FUNCTIONNAME.DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</cnsl-actions-two-add-action-autocomplete-input>
|
||||
}
|
||||
@if (form.case === 'event') {
|
||||
<div class="emailVerified">
|
||||
<mat-checkbox [formControl]="form.form.controls.all">
|
||||
<div class="execution-condition-text">
|
||||
<span>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.ALL.TITLE' | translate }}</span>
|
||||
<span class="description cnsl-secondary-text">{{
|
||||
'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.ALL_EVENTS' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_GROUP.TITLE' | translate }}</p>
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_GROUP.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" [formControl]="form.form.controls.group" />
|
||||
</cnsl-form-field>
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_EVENT.TITLE' | translate }}</p>
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_EVENT.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" [formControl]="form.form.controls.event" />
|
||||
</cnsl-form-field>
|
||||
}
|
||||
<div class="actions">
|
||||
<button mat-stroked-button (click)="back.emit()">
|
||||
{{ 'ACTIONS.BACK' | translate }}
|
||||
</button>
|
||||
<button [disabled]="form.form.invalid" color="primary" mat-raised-button type="submit">
|
||||
{{ 'ACTIONS.CONTINUE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_SERVICE.TITLE' | translate }}</p>
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_SERVICE.DESCRIPTION"
|
||||
[items]="listExecutionServicesQuery.data()"
|
||||
[control]="form.form.controls.service"
|
||||
></cnsl-actions-two-add-action-autocomplete-input>
|
||||
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_METHOD.TITLE' | translate }}</p>
|
||||
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_METHOD.DESCRIPTION"
|
||||
[items]="filteredExecutionMethods()"
|
||||
[control]="form.form.controls.method"
|
||||
></cnsl-actions-two-add-action-autocomplete-input>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="form.case === 'function'">
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.FUNCTIONNAME.TITLE"
|
||||
[items]="listExecutionFunctionsQuery.data()"
|
||||
[control]="form.form.controls.name"
|
||||
>
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.FUNCTIONNAME.DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</cnsl-actions-two-add-action-autocomplete-input>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="form.case === 'event'">
|
||||
<div class="emailVerified">
|
||||
<mat-checkbox [formControl]="form.form.controls.all">
|
||||
<div class="execution-condition-text">
|
||||
<span>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.ALL.TITLE' | translate }}</span>
|
||||
<span class="description cnsl-secondary-text">{{
|
||||
'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.ALL_EVENTS' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_GROUP.TITLE' | translate }}</p>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_GROUP.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" [formControl]="form.form.controls.group" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_EVENT.TITLE' | translate }}</p>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_EVENT.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" [formControl]="form.form.controls.event" />
|
||||
</cnsl-form-field>
|
||||
</ng-container>
|
||||
|
||||
<div class="actions">
|
||||
<button mat-stroked-button (click)="back.emit()">
|
||||
{{ 'ACTIONS.BACK' | translate }}
|
||||
</button>
|
||||
<button [disabled]="form.form.invalid" color="primary" mat-raised-button type="submit">
|
||||
{{ 'ACTIONS.CONTINUE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
}
|
||||
|
||||
+31
-24
@@ -1,28 +1,35 @@
|
||||
<h2 *ngIf="!data.execution" mat-dialog-title>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CREATE_TITLE' | translate }}</h2>
|
||||
<h2 *ngIf="data.execution" mat-dialog-title>{{ 'ACTIONSTWO.EXECUTION.DIALOG.UPDATE_TITLE' | translate }}</h2>
|
||||
@if (!data.execution) {
|
||||
<h2 mat-dialog-title>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CREATE_TITLE' | translate }}</h2>
|
||||
}
|
||||
@if (data.execution) {
|
||||
<h2 mat-dialog-title>{{ 'ACTIONSTWO.EXECUTION.DIALOG.UPDATE_TITLE' | translate }}</h2>
|
||||
}
|
||||
|
||||
<mat-dialog-content>
|
||||
<div class="framework-change-block" [ngSwitch]="page()">
|
||||
<cnsl-actions-two-add-action-type
|
||||
*ngSwitchCase="Page.Type"
|
||||
[initialValue]="typeSignal()"
|
||||
(back)="back()"
|
||||
(continue)="typeSignal.set($event); continue()"
|
||||
></cnsl-actions-two-add-action-type>
|
||||
|
||||
<cnsl-actions-two-add-action-condition
|
||||
*ngSwitchCase="Page.Condition"
|
||||
[conditionType]="typeSignal()"
|
||||
(back)="back()"
|
||||
(continue)="conditionSignal.set({ conditionType: { case: typeSignal(), value: $event } }); continue()"
|
||||
></cnsl-actions-two-add-action-condition>
|
||||
|
||||
<cnsl-actions-two-add-action-target
|
||||
*ngSwitchCase="Page.Target"
|
||||
(back)="back()"
|
||||
[hideBackButton]="!!data.execution"
|
||||
(continue)="targetsSignal.set($event); continue()"
|
||||
[preselectedTargetIds]="preselectedTargetIds"
|
||||
></cnsl-actions-two-add-action-target>
|
||||
<div class="framework-change-block">
|
||||
@switch (page()) {
|
||||
@case (Page.Type) {
|
||||
<cnsl-actions-two-add-action-type
|
||||
[initialValue]="typeSignal()"
|
||||
(back)="back()"
|
||||
(continue)="typeSignal.set($event); continue()"
|
||||
></cnsl-actions-two-add-action-type>
|
||||
}
|
||||
@case (Page.Condition) {
|
||||
<cnsl-actions-two-add-action-condition
|
||||
[conditionType]="typeSignal()"
|
||||
(back)="back()"
|
||||
(continue)="conditionSignal.set({ conditionType: { case: typeSignal(), value: $event } }); continue()"
|
||||
></cnsl-actions-two-add-action-condition>
|
||||
}
|
||||
@case (Page.Target) {
|
||||
<cnsl-actions-two-add-action-target
|
||||
(back)="back()"
|
||||
[hideBackButton]="!!data.execution"
|
||||
(continue)="targetsSignal.set($event); continue()"
|
||||
[preselectedTargetIds]="preselectedTargetIds"
|
||||
></cnsl-actions-two-add-action-target>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
|
||||
+1
-2
@@ -9,7 +9,7 @@ import {
|
||||
ConditionType,
|
||||
} from './actions-two-add-action-condition/actions-two-add-action-condition.component';
|
||||
import { ActionsTwoAddActionTargetComponent } from './actions-two-add-action-target/actions-two-add-action-target.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { Condition, Execution } from '@zitadel/proto/zitadel/action/v2/execution_pb';
|
||||
import { Subject } from 'rxjs';
|
||||
import { SetExecutionRequestSchema } from '@zitadel/proto/zitadel/action/v2/action_service_pb';
|
||||
@@ -54,7 +54,6 @@ export type ActionTwoAddActionDialogResult = MessageInitShape<typeof SetExecutio
|
||||
templateUrl: './actions-two-add-action-dialog.component.html',
|
||||
styleUrls: ['./actions-two-add-action-dialog.component.scss'],
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
TranslateModule,
|
||||
|
||||
+72
-72
@@ -1,72 +1,72 @@
|
||||
<form *ngIf="form$ | async as form" class="form-grid" [formGroup]="form" (ngSubmit)="submit()">
|
||||
<p class="target-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.TARGET.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.TARGET.TARGET.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
#trigger="matAutocompleteTrigger"
|
||||
#input
|
||||
type="text"
|
||||
[formControl]="form.controls.autocomplete"
|
||||
[matAutocomplete]="autoservice"
|
||||
(keydown.enter)="handleEnter($event, form); input.blur(); trigger.closePanel()"
|
||||
/>
|
||||
<mat-autocomplete #autoservice="matAutocomplete">
|
||||
<mat-option *ngIf="targets().state === 'loading'" class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
<mat-option
|
||||
*ngFor="let target of selectableTargets(); trackBy: trackTarget"
|
||||
#option
|
||||
(click)="addTarget(target, form); option.deselect()"
|
||||
[value]="target.name"
|
||||
>
|
||||
{{ target.name }}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</cnsl-form-field>
|
||||
|
||||
<table mat-table cdkDropList (cdkDropListDropped)="drop($event, form)" [dataSource]="dataSource" [trackBy]="trackTarget">
|
||||
<ng-container matColumnDef="order">
|
||||
<th mat-header-cell *matHeaderCellDef>Reorder</th>
|
||||
<td mat-cell *cnslCellDef="let row; let i = index; dataSource: dataSource">
|
||||
<i class="las la-bars"></i>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Name</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
<cnsl-project-role-chip [roleName]="row.name">{{ row.name }}</cnsl-project-role-chip>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="deleteAction" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *cnslCellDef="let i = index; dataSource: dataSource">
|
||||
<cnsl-table-actions>
|
||||
<button
|
||||
actions
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
color="warn"
|
||||
(click)="removeTarget(i, form)"
|
||||
mat-icon-button
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</cnsl-table-actions>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="['order', 'name', 'deleteAction']"></tr>
|
||||
<tr class="drag-row" cdkDrag mat-row *matRowDef="let row; columns: ['order', 'name', 'deleteAction']"></tr>
|
||||
</table>
|
||||
|
||||
<div class="actions">
|
||||
<button *ngIf="!hideBackButton" mat-stroked-button (click)="back.emit()">
|
||||
{{ 'ACTIONS.BACK' | translate }}
|
||||
</button>
|
||||
<span class="fill-space"></span>
|
||||
<button color="primary" [disabled]="form.invalid" mat-raised-button type="submit">
|
||||
{{ 'ACTIONS.CONTINUE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@if (form$ | async; as form) {
|
||||
<form class="form-grid" [formGroup]="form" (ngSubmit)="submit()">
|
||||
<p class="target-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.TARGET.DESCRIPTION' | translate }}</p>
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.TARGET.TARGET.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
#trigger="matAutocompleteTrigger"
|
||||
#input
|
||||
type="text"
|
||||
[formControl]="form.controls.autocomplete"
|
||||
[matAutocomplete]="autoservice"
|
||||
(keydown.enter)="handleEnter($event, form); input.blur(); trigger.closePanel()"
|
||||
/>
|
||||
<mat-autocomplete #autoservice="matAutocomplete">
|
||||
@if (targets().state === 'loading') {
|
||||
<mat-option class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
}
|
||||
@for (target of selectableTargets(); track trackTarget($index, target)) {
|
||||
<mat-option #option (click)="addTarget(target, form); option.deselect()" [value]="target.name">
|
||||
{{ target.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-autocomplete>
|
||||
</cnsl-form-field>
|
||||
<table mat-table cdkDropList (cdkDropListDropped)="drop($event, form)" [dataSource]="dataSource" [trackBy]="trackTarget">
|
||||
<ng-container matColumnDef="order">
|
||||
<th mat-header-cell *matHeaderCellDef>Reorder</th>
|
||||
<td mat-cell *cnslCellDef="let row; let i = index; dataSource: dataSource">
|
||||
<i class="las la-bars"></i>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Name</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
<cnsl-project-role-chip [roleName]="row.name">{{ row.name }}</cnsl-project-role-chip>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="deleteAction" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *cnslCellDef="let i = index; dataSource: dataSource">
|
||||
<cnsl-table-actions>
|
||||
<button
|
||||
actions
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
color="warn"
|
||||
(click)="removeTarget(i, form)"
|
||||
mat-icon-button
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</cnsl-table-actions>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="['order', 'name', 'deleteAction']"></tr>
|
||||
<tr class="drag-row" cdkDrag mat-row *matRowDef="let row; columns: ['order', 'name', 'deleteAction']"></tr>
|
||||
</table>
|
||||
<div class="actions">
|
||||
@if (!hideBackButton) {
|
||||
<button mat-stroked-button (click)="back.emit()">
|
||||
{{ 'ACTIONS.BACK' | translate }}
|
||||
</button>
|
||||
}
|
||||
<span class="fill-space"></span>
|
||||
<button color="primary" [disabled]="form.invalid" mat-raised-button type="submit">
|
||||
{{ 'ACTIONS.CONTINUE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output, signal } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@@ -20,7 +19,7 @@ import { ConditionType } from '../actions-two-add-action-condition/actions-two-a
|
||||
selector: 'cnsl-actions-two-add-action-type',
|
||||
templateUrl: './actions-two-add-action-type.component.html',
|
||||
styleUrls: ['./actions-two-add-action-type.component.scss'],
|
||||
imports: [TranslateModule, MatRadioModule, RouterModule, ReactiveFormsModule, FormsModule, CommonModule, MatButtonModule],
|
||||
imports: [TranslateModule, MatRadioModule, RouterModule, ReactiveFormsModule, FormsModule, MatButtonModule],
|
||||
})
|
||||
export class ActionsTwoAddActionTypeComponent {
|
||||
protected readonly typeForm: ReturnType<typeof this.buildActionTypeForm> = this.buildActionTypeForm();
|
||||
|
||||
+62
-63
@@ -2,71 +2,70 @@
|
||||
<mat-dialog-content>
|
||||
<p class="target-description">{{ 'ACTIONSTWO.TARGET.CREATE.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<form *ngIf="targetForm" class="form-grid" [formGroup]="targetForm" (ngSubmit)="closeWithResult()">
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" formControlName="name" />
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.TARGET.CREATE.NAME_DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.ENDPOINT' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" formControlName="endpoint" />
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.TARGET.CREATE.ENDPOINT_DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.TYPE' | translate }}</cnsl-label>
|
||||
<mat-select [formControl]="targetForm.controls.type" name="type">
|
||||
<mat-option *ngFor="let type of targetTypes" [value]="type">
|
||||
{{ 'ACTIONSTWO.TARGET.CREATE.TYPES.' + type | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<span class="name-hint cnsl-secondary-text types-description">
|
||||
{{ 'ACTIONSTWO.TARGET.CREATE.TYPES_DESCRIPTION' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.PAYLOAD_TYPE' | translate }}</cnsl-label>
|
||||
<mat-select [formControl]="targetForm.controls.payloadType" name="payloadType">
|
||||
<mat-option *ngFor="let type of payloadTypes" [value]="type">
|
||||
{{ 'ACTIONSTWO.TARGET.CREATE.PAYLOAD_TYPES.' + type | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<span class="name-hint cnsl-secondary-text types-description">
|
||||
{{ 'ACTIONSTWO.TARGET.CREATE.PAYLOAD_TYPE_DESCRIPTION' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.TIMEOUT' | translate }}</cnsl-label>
|
||||
<input cnslInput type="number" placeholder="10" [formControl]="targetForm.controls.timeout" />
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.TARGET.CREATE.TIMEOUT_DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</cnsl-form-field>
|
||||
|
||||
<mat-checkbox
|
||||
*ngIf="targetForm.controls.type.value === 'restWebhook' || targetForm.controls.type.value === 'restCall'"
|
||||
class="target-checkbox"
|
||||
[formControl]="targetForm.controls.interruptOnError"
|
||||
>
|
||||
<div class="target-condition-text">
|
||||
<span>{{ 'ACTIONSTWO.TARGET.CREATE.INTERRUPT_ON_ERROR' | translate }}</span>
|
||||
<span class="description cnsl-secondary-text">{{
|
||||
'ACTIONSTWO.TARGET.CREATE.INTERRUPT_ON_ERROR_DESCRIPTION' | translate
|
||||
@if (targetForm) {
|
||||
<form class="form-grid" [formGroup]="targetForm" (ngSubmit)="closeWithResult()">
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" formControlName="name" />
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.TARGET.CREATE.NAME_DESCRIPTION' | translate
|
||||
}}</span>
|
||||
<span [style.color]="'var(--warn)'" class="description cnsl-secondary-text"
|
||||
>{{ 'ACTIONSTWO.TARGET.CREATE.INTERRUPT_ON_ERROR_WARNING' | translate }}
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.ENDPOINT' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" formControlName="endpoint" />
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.TARGET.CREATE.ENDPOINT_DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.TYPE' | translate }}</cnsl-label>
|
||||
<mat-select [formControl]="targetForm.controls.type" name="type">
|
||||
@for (type of targetTypes; track type) {
|
||||
<mat-option [value]="type">
|
||||
{{ 'ACTIONSTWO.TARGET.CREATE.TYPES.' + type | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<span class="name-hint cnsl-secondary-text types-description">
|
||||
{{ 'ACTIONSTWO.TARGET.CREATE.TYPES_DESCRIPTION' | translate }}
|
||||
</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</form>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.PAYLOAD_TYPE' | translate }}</cnsl-label>
|
||||
<mat-select [formControl]="targetForm.controls.payloadType" name="payloadType">
|
||||
@for (type of payloadTypes; track type) {
|
||||
<mat-option [value]="type">
|
||||
{{ 'ACTIONSTWO.TARGET.CREATE.PAYLOAD_TYPES.' + type | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<span class="name-hint cnsl-secondary-text types-description">
|
||||
{{ 'ACTIONSTWO.TARGET.CREATE.PAYLOAD_TYPE_DESCRIPTION' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.TARGET.CREATE.TIMEOUT' | translate }}</cnsl-label>
|
||||
<input cnslInput type="number" placeholder="10" [formControl]="targetForm.controls.timeout" />
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.TARGET.CREATE.TIMEOUT_DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</cnsl-form-field>
|
||||
@if (targetForm.controls.type.value === 'restWebhook' || targetForm.controls.type.value === 'restCall') {
|
||||
<mat-checkbox class="target-checkbox" [formControl]="targetForm.controls.interruptOnError">
|
||||
<div class="target-condition-text">
|
||||
<span>{{ 'ACTIONSTWO.TARGET.CREATE.INTERRUPT_ON_ERROR' | translate }}</span>
|
||||
<span class="description cnsl-secondary-text">{{
|
||||
'ACTIONSTWO.TARGET.CREATE.INTERRUPT_ON_ERROR_DESCRIPTION' | translate
|
||||
}}</span>
|
||||
<span [style.color]="'var(--warn)'" class="description cnsl-secondary-text"
|
||||
>{{ 'ACTIONSTWO.TARGET.CREATE.INTERRUPT_ON_ERROR_WARNING' | translate }}
|
||||
</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
}
|
||||
</form>
|
||||
}
|
||||
</mat-dialog-content>
|
||||
<div>
|
||||
<mat-dialog-actions class="actions">
|
||||
|
||||
+1
-2
@@ -2,7 +2,7 @@ import { Component, Inject } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { FormBuilder, FormControl, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { InputModule } from '../../input/input.module';
|
||||
@@ -21,7 +21,6 @@ type TargetTypes = ActionTwoAddTargetDialogComponent['targetTypes'][number];
|
||||
templateUrl: './actions-two-add-target-dialog.component.html',
|
||||
styleUrls: ['./actions-two-add-target-dialog.component.scss'],
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
ReactiveFormsModule,
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
<cnsl-form-field class="form-field">
|
||||
<cnsl-label>{{ 'USER.MACHINE.TYPE' | translate }}</cnsl-label>
|
||||
<mat-select [(ngModel)]="type">
|
||||
<mat-option *ngFor="let t of types" [value]="t">
|
||||
{{ 'USER.MACHINE.KEYTYPES.' + t | translate }}
|
||||
</mat-option>
|
||||
@for (t of types; track t) {
|
||||
<mat-option [value]="t">
|
||||
{{ 'USER.MACHINE.KEYTYPES.' + t | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
@@ -16,10 +18,12 @@
|
||||
<input cnslInput [matDatepicker]="picker" [min]="startDate" [formControl]="dateControl" />
|
||||
<mat-datepicker-toggle style="top: 0" cnslSuffix [for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker [startAt]="startDate"></mat-datepicker>
|
||||
<span cnslError *ngIf="dateControl && dateControl.errors && dateControl.errors['matDatepickerMin']?.min">
|
||||
{{ 'USER.MACHINE.CHOOSEDATEAFTER' | translate }}:
|
||||
{{ dateControl.errors['matDatepickerMin'].min.toDate() | localizedDate: 'EEE dd. MMM' }}
|
||||
</span>
|
||||
@if (dateControl && dateControl.errors && dateControl.errors['matDatepickerMin']?.min) {
|
||||
<span cnslError>
|
||||
{{ 'USER.MACHINE.CHOOSEDATEAFTER' | translate }}:
|
||||
{{ dateControl.errors['matDatepickerMin'].min.toDate() | localizedDate: 'EEE dd. MMM' }}
|
||||
</span>
|
||||
}
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
<div mat-dialog-content>
|
||||
<p class="desc cnsl-secondary-text">{{ 'ORG_DETAIL.MEMBER.ADDDESCRIPTION' | translate }}</p>
|
||||
|
||||
<ng-container *ngIf="showCreationTypeSelector">
|
||||
@if (showCreationTypeSelector) {
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'MEMBER.CREATIONTYPE' | translate }}</cnsl-label>
|
||||
<mat-select [(ngModel)]="creationType" (selectionChange)="loadRoles()">
|
||||
<mat-option *ngFor="let type of creationTypes" [value]="type.type" [disabled]="(type.disabled$ | async) === false">
|
||||
{{ 'MEMBER.CREATIONTYPES.' + type.type | translate }}
|
||||
</mat-option>
|
||||
@for (type of creationTypes; track type) {
|
||||
<mat-option [value]="type.type" [disabled]="(type.disabled$ | async) === false">
|
||||
{{ 'MEMBER.CREATIONTYPES.' + type.type | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<ng-container *ngIf="creationType === CreationType.PROJECT_OWNED || creationType === CreationType.PROJECT_GRANTED">
|
||||
@if (creationType === CreationType.PROJECT_OWNED || creationType === CreationType.PROJECT_GRANTED) {
|
||||
<p>{{ 'PROJECT.GRANT.CREATE.SEL_PROJECT' | translate }}</p>
|
||||
<cnsl-search-project-autocomplete
|
||||
class="block"
|
||||
@@ -29,26 +30,22 @@
|
||||
"
|
||||
>
|
||||
</cnsl-search-project-autocomplete>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
}
|
||||
}
|
||||
|
||||
<cnsl-search-user-autocomplete [users]="preselectedUsers" (selectionChanged)="users = $any($event)">
|
||||
</cnsl-search-user-autocomplete>
|
||||
|
||||
<div class="roles-selection">
|
||||
<mat-checkbox
|
||||
class="role-cb"
|
||||
*ngFor="let role of memberRoleOptions"
|
||||
color="primary"
|
||||
(change)="toggleRole(role)"
|
||||
[checked]="roles.includes(role)"
|
||||
>
|
||||
<div class="role-cb-content">
|
||||
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
|
||||
<span data-e2e="role-checkbox">{{ role | roletransform }}</span>
|
||||
<i class="info-hover las la-question-circle" matTooltip="{{ 'MEMBERROLES.' + role | translate }}"></i>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
@for (role of memberRoleOptions; track role) {
|
||||
<mat-checkbox class="role-cb" color="primary" (change)="toggleRole(role)" [checked]="roles.includes(role)">
|
||||
<div class="role-cb-content">
|
||||
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
|
||||
<span data-e2e="role-checkbox">{{ role | roletransform }}</span>
|
||||
<i class="info-hover las la-question-circle" matTooltip="{{ 'MEMBERROLES.' + role | translate }}"></i>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
|
||||
+9
-13
@@ -2,19 +2,15 @@
|
||||
<div mat-dialog-content>
|
||||
<p class="desc">{{ 'MEMBER.EDITFOR' | translate: { value: data.user } }}</p>
|
||||
<div class="roles-selection">
|
||||
<mat-checkbox
|
||||
class="role-cb"
|
||||
*ngFor="let role of allRoles"
|
||||
color="primary"
|
||||
(change)="toggleRole(role)"
|
||||
[checked]="selectedRoles.includes(role)"
|
||||
>
|
||||
<div class="role-cb-content">
|
||||
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
|
||||
<span>{{ role | roletransform }}</span>
|
||||
<i class="info-hover las la-question-circle" matTooltip="{{ 'MEMBERROLES.' + role | translate }}"></i>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
@for (role of allRoles; track role) {
|
||||
<mat-checkbox class="role-cb" color="primary" (change)="toggleRole(role)" [checked]="selectedRoles.includes(role)">
|
||||
<div class="role-cb-content">
|
||||
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
|
||||
<span>{{ role | roletransform }}</span>
|
||||
<i class="info-hover las la-question-circle" matTooltip="{{ 'MEMBERROLES.' + role | translate }}"></i>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
<input cnslInput [matDatepicker]="picker" [min]="startDate" [formControl]="dateControl" />
|
||||
<mat-datepicker-toggle style="top: 0" cnslSuffix [for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker>
|
||||
<span cnslError *ngIf="dateControl && dateControl.errors && dateControl.errors['matDatepickerMin']?.min">
|
||||
{{ 'USER.PERSONALACCESSTOKEN.ADD.CHOOSEDATEAFTER' | translate }}:
|
||||
{{ dateControl.errors['matDatepickerMin'].min.toDate() | localizedDate: 'EEE dd. MMM' }}
|
||||
</span>
|
||||
@if (dateControl && dateControl.errors && dateControl.errors['matDatepickerMin']?.min) {
|
||||
<span cnslError>
|
||||
{{ 'USER.PERSONALACCESSTOKEN.ADD.CHOOSEDATEAFTER' | translate }}:
|
||||
{{ dateControl.errors['matDatepickerMin'].min.toDate() | localizedDate: 'EEE dd. MMM' }}
|
||||
</span>
|
||||
}
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
|
||||
+38
-31
@@ -1,5 +1,5 @@
|
||||
<div class="auth-method-radio-button-wrapper" [ngClass]="{ compact: compact }">
|
||||
<ng-container *ngFor="let method of authMethods; index as i">
|
||||
@for (method of authMethods; track method; let i = $index) {
|
||||
<input
|
||||
type="radio"
|
||||
[disabled]="method.disabled"
|
||||
@@ -13,43 +13,50 @@
|
||||
[ngClass]="{ compact: compact, first: i === 0, last: i === authMethods.length - 1 }"
|
||||
[for]="method.key"
|
||||
>
|
||||
<div
|
||||
class="recommended"
|
||||
[ngClass]="{ not: method.notRecommended }"
|
||||
*ngIf="method.recommended || method.notRecommended"
|
||||
>
|
||||
{{ (method.recommended ? 'APP.OIDC.RECOMMENDED' : 'APP.OIDC.NOTRECOMMENDED') | translate }}
|
||||
</div>
|
||||
|
||||
@if (method.recommended || method.notRecommended) {
|
||||
<div class="recommended" [ngClass]="{ not: method.notRecommended }">
|
||||
{{ (method.recommended ? 'APP.OIDC.RECOMMENDED' : 'APP.OIDC.NOTRECOMMENDED') | translate }}
|
||||
</div>
|
||||
}
|
||||
<div class="cnsl-radio-header" [ngStyle]="{ background: method.background }">
|
||||
<span>{{ method.prefix }}</span>
|
||||
<div class="current" *ngIf="current === method.key">{{ 'APP.OIDC.CURRENT' | translate }}</div>
|
||||
@if (current === method.key) {
|
||||
<div class="current">{{ 'APP.OIDC.CURRENT' | translate }}</div>
|
||||
}
|
||||
</div>
|
||||
<p>{{ method.titleI18nKey | translate }}</p>
|
||||
<p class="type-desc cnsl-secondary-text">{{ method.descI18nKey | translate }}</p>
|
||||
<span class="fill-space"></span>
|
||||
<div class="app-specs cnsl-secondary-text">
|
||||
<div class="row" *ngIf="isOIDC && method && method.responseType !== undefined">
|
||||
<span class="row-entry">{{ 'APP.OIDC.RESPONSETYPE' | translate }}</span>
|
||||
<span>{{ 'APP.OIDC.RESPONSE.' + method.responseType.toString() | translate }}</span>
|
||||
</div>
|
||||
<div class="row" *ngIf="isOIDC && method.grantType !== undefined">
|
||||
<span class="row-entry">{{ 'APP.GRANT' | translate }}</span>
|
||||
<span
|
||||
><span class="space" *ngFor="let grant of method.grantType">{{
|
||||
'APP.OIDC.GRANT.' + grant.toString() | translate
|
||||
}}</span></span
|
||||
>
|
||||
</div>
|
||||
<div class="row" *ngIf="isOIDC && method.authMethod !== undefined">
|
||||
<span class="row-entry">{{ 'APP.AUTHMETHOD' | translate }}</span>
|
||||
<span>{{ 'APP.OIDC.AUTHMETHOD.' + method.authMethod.toString() | translate }}</span>
|
||||
</div>
|
||||
<div class="row" *ngIf="!isOIDC && method.apiAuthMethod !== undefined">
|
||||
<span class="row-entry">{{ 'APP.AUTHMETHOD' | translate }}</span>
|
||||
<span>{{ 'APP.API.AUTHMETHOD.' + method.apiAuthMethod.toString() | translate }}</span>
|
||||
</div>
|
||||
@if (isOIDC && method && method.responseType !== undefined) {
|
||||
<div class="row">
|
||||
<span class="row-entry">{{ 'APP.OIDC.RESPONSETYPE' | translate }}</span>
|
||||
<span>{{ 'APP.OIDC.RESPONSE.' + method.responseType.toString() | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (isOIDC && method.grantType !== undefined) {
|
||||
<div class="row">
|
||||
<span class="row-entry">{{ 'APP.GRANT' | translate }}</span>
|
||||
<span>
|
||||
@for (grant of method.grantType; track grant) {
|
||||
<span class="space">{{ 'APP.OIDC.GRANT.' + grant.toString() | translate }}</span>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
@if (isOIDC && method.authMethod !== undefined) {
|
||||
<div class="row">
|
||||
<span class="row-entry">{{ 'APP.AUTHMETHOD' | translate }}</span>
|
||||
<span>{{ 'APP.OIDC.AUTHMETHOD.' + method.authMethod.toString() | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (!isOIDC && method.apiAuthMethod !== undefined) {
|
||||
<div class="row">
|
||||
<span class="row-entry">{{ 'APP.AUTHMETHOD' | translate }}</span>
|
||||
<span>{{ 'APP.API.AUTHMETHOD.' + method.apiAuthMethod.toString() | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</label>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="app-type-radio-button-wrapper">
|
||||
<ng-container *ngFor="let type of types">
|
||||
@for (type of types; track type) {
|
||||
<input class="app" type="radio" (change)="emitChange()" [value]="type" [(ngModel)]="selected" [id]="type.prefix" />
|
||||
<label class="cnsl-type-radio-button" [for]="type.prefix">
|
||||
<div class="cnsl-type-radio-header" [ngStyle]="{ background: type.background }">
|
||||
@@ -8,7 +8,9 @@
|
||||
<p>{{ type.titleI18nKey | translate }}</p>
|
||||
<p class="type-desc cnsl-secondary-text">{{ type.descI18nKey | translate }}</p>
|
||||
<span class="fill-space"></span>
|
||||
<span class="cnsl-type-protocol state" *ngIf="type.protocol">{{ type.protocol }}</span>
|
||||
@if (type.protocol) {
|
||||
<span class="cnsl-type-protocol state">{{ type.protocol }}</span>
|
||||
}
|
||||
</label>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
}"
|
||||
[ngClass]="{ active: active }"
|
||||
>
|
||||
<ng-container *ngIf="isMachine; else human">
|
||||
@if (isMachine) {
|
||||
<i class="machine-icon las la-robot"></i>
|
||||
</ng-container>
|
||||
<ng-template #human>
|
||||
} @else {
|
||||
<span class="dontcloseonclick">{{ credentials }}</span>
|
||||
<img class="dontcloseonclick" *ngIf="avatarUrl" [src]="avatarUrl" (error)="errorHandler($event)" />
|
||||
</ng-template>
|
||||
@if (avatarUrl) {
|
||||
<img class="dontcloseonclick" [src]="avatarUrl" (error)="errorHandler($event)" />
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,37 @@
|
||||
<div class="card" [ngClass]="{ nomargin: nomargin, warn: warn }" data-e2e="app-card">
|
||||
<div *ngIf="title || description" class="header" [ngClass]="{ 'bottom-margin': expanded }">
|
||||
<div *ngIf="title" class="row">
|
||||
<h2 class="title" data-e2e="app-card-title">{{ title }}</h2>
|
||||
<span class="fill-space"></span>
|
||||
<ng-content select="[card-actions]"></ng-content>
|
||||
<button class="button" type="button" matTooltip="Expand or collapse" mat-icon-button (click)="expanded = !expanded">
|
||||
<mat-icon *ngIf="!expanded">keyboard_arrow_down</mat-icon>
|
||||
<mat-icon *ngIf="expanded">keyboard_arrow_up</mat-icon>
|
||||
</button>
|
||||
@if (title || description) {
|
||||
<div class="header" [ngClass]="{ 'bottom-margin': expanded }">
|
||||
@if (title) {
|
||||
<div class="row">
|
||||
<h2 class="title" data-e2e="app-card-title">{{ title }}</h2>
|
||||
<span class="fill-space"></span>
|
||||
<ng-content select="[card-actions]"></ng-content>
|
||||
<button
|
||||
class="button"
|
||||
type="button"
|
||||
matTooltip="Expand or collapse"
|
||||
mat-icon-button
|
||||
(click)="expanded = !expanded"
|
||||
>
|
||||
@if (!expanded) {
|
||||
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||
}
|
||||
@if (expanded) {
|
||||
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
@if (description) {
|
||||
<p class="desc cnsl-secondary-text">
|
||||
{{ description }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<p *ngIf="description" class="desc cnsl-secondary-text">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-content" *ngIf="expanded">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
}
|
||||
@if (expanded) {
|
||||
<div class="card-content">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -3,49 +3,63 @@
|
||||
</div>
|
||||
|
||||
<div class="scroll-container">
|
||||
<li class="item" *ngFor="let hist of data | async; index as histindex">
|
||||
<span *ngIf="hist.values[0].dates[0]" class="date">
|
||||
{{ hist.values[0].dates[0] | timestampToDate | localizedDate: 'dd. MMM yyyy' }}
|
||||
</span>
|
||||
<div class="item" *ngFor="let dayelement of hist.values; index as i">
|
||||
<div class="row">
|
||||
<cnsl-avatar
|
||||
matTooltip="{{ dayelement.editorDisplayName }}"
|
||||
*ngIf="dayelement.editorDisplayName; else spacer"
|
||||
class="avatar"
|
||||
[name]="dayelement.editorDisplayName"
|
||||
[size]="32"
|
||||
[forColor]="dayelement?.editorPreferredLoginName ?? 'A'"
|
||||
[avatarUrl]="dayelement.editorAvatarUrl || ''"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
<ng-template #spacer>
|
||||
<div class="spacer"></div>
|
||||
</ng-template>
|
||||
<div class="change-actions">
|
||||
<div class="change-action" *ngFor="let action of dayelement.eventTypes; index as j">
|
||||
<div>
|
||||
<span class="msg">{{ action.localizedMessage }}</span>
|
||||
<span
|
||||
class="block"
|
||||
matTooltip="{{ dayelement.dates[j] | timestampToDate | localizedDate: 'dd. MM yyyy, HH:mm:ss.SSS' }}"
|
||||
>{{ dayelement.dates[j] | timestampToDate | localizedDate: 'HH:mm' }}</span
|
||||
@for (hist of data | async; track hist; let histindex = $index) {
|
||||
<li class="item">
|
||||
@if (hist.values[0].dates[0]) {
|
||||
<span class="date">
|
||||
{{ hist.values[0].dates[0] | timestampToDate | localizedDate: 'dd. MMM yyyy' }}
|
||||
</span>
|
||||
}
|
||||
@for (dayelement of hist.values; track dayelement; let i = $index) {
|
||||
<div class="item">
|
||||
<div class="row">
|
||||
@if (dayelement.editorDisplayName) {
|
||||
<cnsl-avatar
|
||||
matTooltip="{{ dayelement.editorDisplayName }}"
|
||||
class="avatar"
|
||||
[name]="dayelement.editorDisplayName"
|
||||
[size]="32"
|
||||
[forColor]="dayelement?.editorPreferredLoginName ?? 'A'"
|
||||
[avatarUrl]="dayelement.editorAvatarUrl || ''"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
} @else {
|
||||
<div class="spacer"></div>
|
||||
}
|
||||
<div class="change-actions">
|
||||
@for (action of dayelement.eventTypes; track action; let j = $index) {
|
||||
<div class="change-action">
|
||||
<div>
|
||||
<span class="msg">{{ action.localizedMessage }}</span>
|
||||
<span
|
||||
class="block"
|
||||
matTooltip="{{ dayelement.dates[j] | timestampToDate | localizedDate: 'dd. MM yyyy, HH:mm:ss.SSS' }}"
|
||||
>{{ dayelement.dates[j] | timestampToDate | localizedDate: 'HH:mm' }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</li>
|
||||
}
|
||||
<div class="ch-sp-wrapper">
|
||||
<mat-spinner *ngIf="loading | async" diameter="25"></mat-spinner>
|
||||
@if (loading | async) {
|
||||
<mat-spinner diameter="25"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<button (click)="more()" class="load-more-button" *ngIf="!bottom" mat-stroked-button>
|
||||
{{ 'CHANGES.LOADMORE' | translate }}
|
||||
</button>
|
||||
@if (!bottom) {
|
||||
<button (click)="more()" class="load-more-button" mat-stroked-button>
|
||||
{{ 'CHANGES.LOADMORE' | translate }}
|
||||
</button>
|
||||
}
|
||||
|
||||
<div *ngIf="bottom" class="end-container">
|
||||
<span class="cnsl-secondary-text">{{ 'CHANGES.BOTTOM' | translate }}</span>
|
||||
</div>
|
||||
@if (bottom) {
|
||||
<div class="end-container">
|
||||
<span class="cnsl-secondary-text">{{ 'CHANGES.BOTTOM' | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<div class="contributor-groups">
|
||||
<div class="contributor-people">
|
||||
<div class="contributor-img-list" [ngClass]="{ 'padd-left': totalResult > 0 }" [@cardAnimation]="totalResult">
|
||||
<mat-spinner class="spinner" diameter="20" *ngIf="loading"></mat-spinner>
|
||||
<ng-container *ngIf="totalResult < 10; else compact">
|
||||
<ng-container *ngFor="let member of membersSubject | async; index as i">
|
||||
@if (loading) {
|
||||
<mat-spinner class="spinner" diameter="20"></mat-spinner>
|
||||
}
|
||||
@if (totalResult < 10) {
|
||||
@for (member of membersSubject | async; track member; let i = $index) {
|
||||
<div
|
||||
@animate
|
||||
(click)="emitShowDetail()"
|
||||
@@ -12,24 +14,23 @@
|
||||
[ngStyle]="{ 'z-index': 20 - i }"
|
||||
data-e2e="member-avatar"
|
||||
>
|
||||
<cnsl-avatar
|
||||
*ngIf="member && member.userType === UserType.TYPE_HUMAN; else cog"
|
||||
class="contributor-avatar dontcloseonclick"
|
||||
[avatarUrl]="member.avatarUrl || ''"
|
||||
[name]="member.displayName"
|
||||
[forColor]="member.preferredLoginName"
|
||||
[size]="32"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
<ng-template #cog>
|
||||
@if (member && member.userType === UserType.TYPE_HUMAN) {
|
||||
<cnsl-avatar
|
||||
class="contributor-avatar dontcloseonclick"
|
||||
[avatarUrl]="member.avatarUrl || ''"
|
||||
[name]="member.displayName"
|
||||
[forColor]="member.preferredLoginName"
|
||||
[size]="32"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
} @else {
|
||||
<cnsl-avatar [forColor]="member.preferredLoginName" [isMachine]="true">
|
||||
<i class="las la-robot"></i>
|
||||
</cnsl-avatar>
|
||||
</ng-template>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-template #compact>
|
||||
}
|
||||
} @else {
|
||||
<div
|
||||
(click)="emitShowDetail()"
|
||||
class="contributor-avatar-circle"
|
||||
@@ -37,7 +38,7 @@
|
||||
>
|
||||
<span>{{ totalResult }}</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
}
|
||||
<button
|
||||
class="add-img"
|
||||
[ngClass]="{ 'no-margin': totalResult === 0 }"
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
<button (click)="close()" mat-icon-button matTooltip="{{ 'ACTIONS.CLOSE' | translate }}">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
<span class="abort">{{ title }}</span
|
||||
><span class="abort-2" *ngIf="createSteps > 1"
|
||||
>{{ 'ACTIONS.STEP' | translate }} {{ currentCreateStep }} {{ 'ACTIONS.OF' | translate }} {{ createSteps }}</span
|
||||
>
|
||||
<span class="abort">{{ title }}</span>
|
||||
@if (createSteps > 1) {
|
||||
<span class="abort-2"
|
||||
>{{ 'ACTIONS.STEP' | translate }} {{ currentCreateStep }} {{ 'ACTIONS.OF' | translate }} {{ createSteps }}</span
|
||||
>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="create-layout-content">
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
<div class="detail-layout-top-view">
|
||||
<div>
|
||||
<div class="back-row">
|
||||
<a *ngIf="hasBackButton" cnslBack mat-icon-button>
|
||||
<mat-icon class="icon">arrow_back</mat-icon>
|
||||
</a>
|
||||
@if (hasBackButton) {
|
||||
<a cnslBack mat-icon-button>
|
||||
<mat-icon class="icon">arrow_back</mat-icon>
|
||||
</a>
|
||||
}
|
||||
<div>
|
||||
<h1>{{ title }}</h1>
|
||||
<ng-content select="[sub]"></ng-content>
|
||||
|
||||
@@ -1,76 +1,87 @@
|
||||
<h2 class="title" mat-dialog-title>{{ 'IAM.EVENTS.DIALOG.TITLE' | translate }}</h2>
|
||||
<div mat-dialog-content>
|
||||
<div class="event-data-column" *ngIf="event && (event | toobject) as event">
|
||||
<div class="data-row" *ngIf="event && event.type && event.type.localized && event.type.localized.localizedMessage">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.TYPE' | translate }}</span>
|
||||
<span>{{ event.type.localized.localizedMessage }}</span>
|
||||
</div>
|
||||
|
||||
<div class="data-row" *ngIf="event && event.creationDate">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.CREATIONDATE' | translate }}</span>
|
||||
<span>{{ event.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="data-row" *ngIf="event && event.aggregate && event.aggregate.id">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.AGGREGATEID' | translate }}</span>
|
||||
<span>{{ event.aggregate.id }}</span>
|
||||
</div>
|
||||
|
||||
<div class="data-row" *ngIf="event && event.aggregate && event.aggregate.resourceOwner">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.RESOURCEOWNER' | translate }}</span>
|
||||
<span>{{ event.aggregate.resourceOwner }}</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="data-row"
|
||||
*ngIf="
|
||||
@if (event && (event | toobject); as event) {
|
||||
<div class="event-data-column">
|
||||
@if (event && event.type && event.type.localized && event.type.localized.localizedMessage) {
|
||||
<div class="data-row">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.TYPE' | translate }}</span>
|
||||
<span>{{ event.type.localized.localizedMessage }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (event && event.creationDate) {
|
||||
<div class="data-row">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.CREATIONDATE' | translate }}</span>
|
||||
<span>{{ event.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (event && event.aggregate && event.aggregate.id) {
|
||||
<div class="data-row">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.AGGREGATEID' | translate }}</span>
|
||||
<span>{{ event.aggregate.id }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (event && event.aggregate && event.aggregate.resourceOwner) {
|
||||
<div class="data-row">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.RESOURCEOWNER' | translate }}</span>
|
||||
<span>{{ event.aggregate.resourceOwner }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (
|
||||
event &&
|
||||
event.aggregate &&
|
||||
event.aggregate.type &&
|
||||
event.aggregate.type.localized &&
|
||||
event.aggregate.type.localized.localizedMessage
|
||||
"
|
||||
>
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.AGGREGATETYPE' | translate }}</span>
|
||||
<span class="state aggregate-type">{{ event.aggregate.type.localized.localizedMessage }}</span>
|
||||
) {
|
||||
<div class="data-row">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.AGGREGATETYPE' | translate }}</span>
|
||||
<span class="state aggregate-type">{{ event.aggregate.type.localized.localizedMessage }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (event && event.editor?.userId) {
|
||||
<div class="data-row">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.EDITORID' | translate }}</span>
|
||||
<span>{{ event.editor?.userId }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (event && event.editor?.displayName) {
|
||||
<div class="data-row">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.EDITOR' | translate }}</span>
|
||||
<span>{{ event.editor?.displayName }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (event && event.sequence) {
|
||||
<div class="data-row">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.SEQUENCE' | translate }}</span>
|
||||
<span>{{ event.sequence }}</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="data-row" *ngIf="event && event.editor?.userId">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.EDITORID' | translate }}</span>
|
||||
<span>{{ event.editor?.userId }}</span>
|
||||
@if (opened$ | async) {
|
||||
<div class="code">
|
||||
@if (event) {
|
||||
<ngx-codemirror
|
||||
[ngModel]="event | topayload | json"
|
||||
[options]="{
|
||||
height: 'auto',
|
||||
readOnly: true,
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
indentWithTabs: false,
|
||||
tabSize: 2,
|
||||
theme: 'material',
|
||||
mode: {
|
||||
name: 'javascript',
|
||||
json: true,
|
||||
statementIndent: 2,
|
||||
},
|
||||
}"
|
||||
></ngx-codemirror>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="data-row" *ngIf="event && event.editor?.displayName">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.EDITOR' | translate }}</span>
|
||||
<span>{{ event.editor?.displayName }}</span>
|
||||
</div>
|
||||
|
||||
<div class="data-row" *ngIf="event && event.sequence">
|
||||
<span class="label cnsl-secondary-text">{{ 'IAM.EVENTS.SEQUENCE' | translate }}</span>
|
||||
<span>{{ event.sequence }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="code" *ngIf="opened$ | async">
|
||||
<ngx-codemirror
|
||||
*ngIf="event"
|
||||
[ngModel]="event | topayload | json"
|
||||
[options]="{
|
||||
height: 'auto',
|
||||
readOnly: true,
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
indentWithTabs: false,
|
||||
tabSize: 2,
|
||||
theme: 'material',
|
||||
mode: {
|
||||
name: 'javascript',
|
||||
json: true,
|
||||
statementIndent: 2,
|
||||
},
|
||||
}"
|
||||
></ngx-codemirror>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
<button mat-stroked-button (click)="closeDialog()">
|
||||
|
||||
+123
-94
@@ -14,110 +14,139 @@
|
||||
</div>
|
||||
|
||||
<div mat-dialog-content cdkFocusInitial autofocus>
|
||||
<div *ngIf="showNew && !(dns || http)">
|
||||
<p class="domain-desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION' | translate }}</p>
|
||||
<p class="domain-desc">
|
||||
{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_HTML' | translate }}
|
||||
@if (showNew && !(dns || http)) {
|
||||
<div>
|
||||
<p class="domain-desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION' | translate }}</p>
|
||||
<p class="domain-desc">
|
||||
{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_HTML' | translate }}
|
||||
</p>
|
||||
<p class="domain-desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_DNS' | translate }}</p>
|
||||
<p class="domain-desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_SKIP' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (showNew && !(dns || http)) {
|
||||
<cnsl-info-section [type]="InfoSectionType.WARN" class="desc">{{
|
||||
'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_DESC' | translate
|
||||
}}</cnsl-info-section>
|
||||
}
|
||||
|
||||
@if (!showNew && !(dns || http)) {
|
||||
<p class="desc">
|
||||
{{
|
||||
'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_ONGOING'
|
||||
| translate: { value: domain?.validationType == 1 ? 'HTTP' : 'DNS' }
|
||||
}}
|
||||
</p>
|
||||
<p class="domain-desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_DNS' | translate }}</p>
|
||||
<p class="domain-desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_SKIP' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
<cnsl-info-section [type]="InfoSectionType.WARN" *ngIf="showNew && !(dns || http)" class="desc">{{
|
||||
'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_DESC' | translate
|
||||
}}</cnsl-info-section>
|
||||
|
||||
<p *ngIf="!showNew && !(dns || http)" class="desc">
|
||||
{{
|
||||
'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_ONGOING'
|
||||
| translate: { value: domain?.validationType == 1 ? 'HTTP' : 'DNS' }
|
||||
}}
|
||||
</p>
|
||||
|
||||
<ng-container *ngIf="showNew">
|
||||
<div *ngIf="http">
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_HTTP_DESC' | translate: { value: domain?.domainName } }}</p>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_HTTP_URL_LABEL' | translate }}</p>
|
||||
<div class="domain-entry" *ngIf="http.url">
|
||||
<p>{{ http.url }}</p>
|
||||
<button
|
||||
color="primary"
|
||||
[disabled]="copied === data.clientSecret"
|
||||
matTooltip="copy to clipboard"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="http.url"
|
||||
(copiedValue)="copied = $event"
|
||||
mat-icon-button
|
||||
>
|
||||
<i *ngIf="copied !== http.url" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === http.url" class="las la-clipboard-check"></i>
|
||||
</button>
|
||||
@if (showNew) {
|
||||
@if (http) {
|
||||
<div>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_HTTP_DESC' | translate: { value: domain?.domainName } }}</p>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_HTTP_URL_LABEL' | translate }}</p>
|
||||
@if (http.url) {
|
||||
<div class="domain-entry">
|
||||
<p>{{ http.url }}</p>
|
||||
<button
|
||||
color="primary"
|
||||
[disabled]="copied === data.clientSecret"
|
||||
matTooltip="copy to clipboard"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="http.url"
|
||||
(copiedValue)="copied = $event"
|
||||
mat-icon-button
|
||||
>
|
||||
@if (copied !== http.url) {
|
||||
<i class="las la-clipboard"></i>
|
||||
}
|
||||
@if (copied === http.url) {
|
||||
<i class="las la-clipboard-check"></i>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_HTTP_FILE_LABEL' | translate }}</p>
|
||||
<button mat-stroked-button (click)="saveFile()" color="primary">{{ 'ORG.PAGES.DOWNLOAD_FILE' | translate }}</button>
|
||||
</div>
|
||||
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_HTTP_FILE_LABEL' | translate }}</p>
|
||||
<button mat-stroked-button (click)="saveFile()" color="primary">{{ 'ORG.PAGES.DOWNLOAD_FILE' | translate }}</button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="dns">
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_DNS_DESC' | translate: { value: domain?.domainName } }}</p>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_DNS_HOST_LABEL' | translate }}</p>
|
||||
<div class="domain-line">
|
||||
<div class="domain-entry" *ngIf="dns.token">
|
||||
<p>{{ dnsChallenge }}</p>
|
||||
<button
|
||||
color="primary"
|
||||
[disabled]="copied === data.clientSecret"
|
||||
matTooltip="copy to clipboard"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="dnsChallenge"
|
||||
(copiedValue)="copied = $event"
|
||||
mat-icon-button
|
||||
>
|
||||
<i *ngIf="copied !== dnsChallenge" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === dnsChallenge" class="las la-clipboard-check"></i>
|
||||
</button>
|
||||
}
|
||||
@if (dns) {
|
||||
<div>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_DNS_DESC' | translate: { value: domain?.domainName } }}</p>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_DNS_HOST_LABEL' | translate }}</p>
|
||||
<div class="domain-line">
|
||||
@if (dns.token) {
|
||||
<div class="domain-entry">
|
||||
<p>{{ dnsChallenge }}</p>
|
||||
<button
|
||||
color="primary"
|
||||
[disabled]="copied === data.clientSecret"
|
||||
matTooltip="copy to clipboard"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="dnsChallenge"
|
||||
(copiedValue)="copied = $event"
|
||||
mat-icon-button
|
||||
>
|
||||
@if (copied !== dnsChallenge) {
|
||||
<i class="las la-clipboard"></i>
|
||||
}
|
||||
@if (copied === dnsChallenge) {
|
||||
<i class="las la-clipboard-check"></i>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
<span>.{{ domain?.domainName }}</span>
|
||||
</div>
|
||||
<span>.{{ domain?.domainName }}</span>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_DNS_CHALLENGE_LABEL' | translate }}</p>
|
||||
@if (dns.token) {
|
||||
<div class="domain-entry">
|
||||
<p>{{ dns.token }}</p>
|
||||
<button
|
||||
color="primary"
|
||||
[disabled]="copied === data.clientSecret"
|
||||
matTooltip="copy to clipboard"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="dns.token"
|
||||
(copiedValue)="copied = $event"
|
||||
mat-icon-button
|
||||
>
|
||||
@if (copied !== dns.token) {
|
||||
<i class="las la-clipboard"></i>
|
||||
}
|
||||
@if (copied === dns.token) {
|
||||
<i class="las la-clipboard-check"></i>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_DNS_CHALLENGE_LABEL' | translate }}</p>
|
||||
<div class="domain-entry" *ngIf="dns.token">
|
||||
<p>{{ dns.token }}</p>
|
||||
<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-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
<button
|
||||
*ngIf="!showNew || dns || http"
|
||||
color="primary"
|
||||
type="submit"
|
||||
mat-raised-button
|
||||
class="verify-button"
|
||||
(click)="validate()"
|
||||
>
|
||||
{{ 'ACTIONS.VERIFY' | translate }}
|
||||
</button>
|
||||
<mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner>
|
||||
@if (!showNew || dns || http) {
|
||||
<button color="primary" type="submit" mat-raised-button class="verify-button" (click)="validate()">
|
||||
{{ 'ACTIONS.VERIFY' | translate }}
|
||||
</button>
|
||||
}
|
||||
@if (validating) {
|
||||
<mat-spinner class="spinner" diameter="20" mode="indeterminate"></mat-spinner>
|
||||
}
|
||||
|
||||
<button *ngIf="!showNew" mat-stroked-button color="primary" (click)="showNew = true">
|
||||
{{ 'ORG.PAGES.ORGDOMAIN.RESETMETHOD' | translate }}
|
||||
</button>
|
||||
@if (!showNew) {
|
||||
<button mat-stroked-button color="primary" (click)="showNew = true">
|
||||
{{ 'ORG.PAGES.ORGDOMAIN.RESETMETHOD' | translate }}
|
||||
</button>
|
||||
}
|
||||
|
||||
<div>
|
||||
<button color="primary" *ngIf="showNew && !(dns || http)" mat-raised-button (click)="loadHttpToken()">HTTP</button>
|
||||
<button color="primary" *ngIf="showNew && !(dns || http)" mat-raised-button (click)="loadDnsToken()">DNS</button>
|
||||
@if (showNew && !(dns || http)) {
|
||||
<button color="primary" mat-raised-button (click)="loadHttpToken()">HTTP</button>
|
||||
}
|
||||
@if (showNew && !(dns || http)) {
|
||||
<button color="primary" mat-raised-button (click)="loadDnsToken()">DNS</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
<button mat-stroked-button (click)="closeDialog()">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<ng-container *ngIf="['org.write$'] | hasRole as canwrite$">
|
||||
@if (['org.write$'] | hasRole; as canwrite$) {
|
||||
<div class="domain-top-view">
|
||||
<div>
|
||||
<div class="domain-title-row">
|
||||
@@ -15,7 +15,6 @@
|
||||
<p class="domain-desc cnsl-secondary-text">{{ 'ORG.DOMAINS.DESCRIPTION' | translate }}</p>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<button
|
||||
[disabled]="(canwrite$ | async) === false"
|
||||
matTooltip="Add domain"
|
||||
@@ -31,39 +30,40 @@
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<cnsl-card *ngFor="let domain of domains" class="domain-card">
|
||||
<div class="domain">
|
||||
<span class="title">{{ domain.domainName }}</span>
|
||||
|
||||
<i matTooltip="verified" *ngIf="domain.isVerified" class="verified las la-check-circle"></i>
|
||||
<i matTooltip="primary" *ngIf="domain.isPrimary" class="primary las la-star"></i>
|
||||
<a
|
||||
*ngIf="domain.isVerified && !domain.isPrimary && (canwrite$ | async)"
|
||||
class="primaryset"
|
||||
(click)="setPrimary(domain)"
|
||||
>{{ 'ORG.DOMAINS.SETPRIMARY' | translate }}</a
|
||||
>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="(canwrite$ | async) === false || domain.isVerified"
|
||||
*ngIf="verifyOrgDomains"
|
||||
(click)="verifyDomain(domain)"
|
||||
>
|
||||
<i class="las la-pen"></i>
|
||||
</button>
|
||||
<button
|
||||
class="domain-rem-button"
|
||||
[disabled]="(canwrite$ | async) === false || domain.isPrimary"
|
||||
matTooltip="Remove domain"
|
||||
color="warn"
|
||||
mat-icon-button
|
||||
(click)="removeDomain(domain.domainName)"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</ng-container>
|
||||
@for (domain of domains; track domain) {
|
||||
<cnsl-card class="domain-card">
|
||||
<div class="domain">
|
||||
<span class="title">{{ domain.domainName }}</span>
|
||||
@if (domain.isVerified) {
|
||||
<i matTooltip="verified" class="verified las la-check-circle"></i>
|
||||
}
|
||||
@if (domain.isPrimary) {
|
||||
<i matTooltip="primary" class="primary las la-star"></i>
|
||||
}
|
||||
@if (domain.isVerified && !domain.isPrimary && (canwrite$ | async)) {
|
||||
<a class="primaryset" (click)="setPrimary(domain)">{{ 'ORG.DOMAINS.SETPRIMARY' | translate }}</a>
|
||||
}
|
||||
<span class="fill-space"></span>
|
||||
@if (verifyOrgDomains) {
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="(canwrite$ | async) === false || domain.isVerified"
|
||||
(click)="verifyDomain(domain)"
|
||||
>
|
||||
<i class="las la-pen"></i>
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
class="domain-rem-button"
|
||||
[disabled]="(canwrite$ | async) === false || domain.isPrimary"
|
||||
matTooltip="Remove domain"
|
||||
color="warn"
|
||||
mat-icon-button
|
||||
(click)="removeDomain(domain.domainName)"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,80 @@
|
||||
<div *ngIf="currentMap">
|
||||
<form [formGroup]="form">
|
||||
<ng-container *ngFor="let key of current$ | async | keyvalue">
|
||||
<div *ngIf="key.key !== 'isDefault'" class="edit-text-block">
|
||||
<div class="edit-text-flex" *ngIf="default$ | async as defaultmap">
|
||||
<cnsl-form-field class="edit-text-formfield">
|
||||
<cnsl-label>{{ key.key }}</cnsl-label>
|
||||
<textarea
|
||||
class="edit-text-area"
|
||||
cnslInput
|
||||
[formControlName]="key.key"
|
||||
[placeholder]="$any(defaultmap[key.key])"
|
||||
[name]="key.key"
|
||||
[ngClass]="{ defaulttext: form.get(key.key)?.value === '' }"
|
||||
></textarea>
|
||||
<div class="edit-text-chips" *ngIf="warnText[key.key] === undefined">
|
||||
<ng-container *ngFor="let chip of chips">
|
||||
<div
|
||||
class="chip"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="chip.value"
|
||||
(copiedValue)="copied = $event"
|
||||
(click)="addChip(key.key, chip.value)"
|
||||
>
|
||||
<span class="key">{{ chip.key | translate }}</span>
|
||||
<span class="value">{{ chip.value }}</span>
|
||||
<i *ngIf="copied !== chip.value" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === chip.value" class="las la-clipboard-check"></i>
|
||||
@if (currentMap) {
|
||||
<div>
|
||||
<form [formGroup]="form">
|
||||
@for (key of current$ | async | keyvalue; track key) {
|
||||
@if (key.key !== 'isDefault') {
|
||||
<div class="edit-text-block">
|
||||
@if (default$ | async; as defaultmap) {
|
||||
<div class="edit-text-flex">
|
||||
<cnsl-form-field class="edit-text-formfield">
|
||||
<cnsl-label>{{ key.key }}</cnsl-label>
|
||||
<textarea
|
||||
class="edit-text-area"
|
||||
cnslInput
|
||||
[formControlName]="key.key"
|
||||
[placeholder]="$any(defaultmap[key.key])"
|
||||
[name]="key.key"
|
||||
[ngClass]="{ defaulttext: form.get(key.key)?.value === '' }"
|
||||
></textarea>
|
||||
@if (warnText[key.key] === undefined) {
|
||||
<div class="edit-text-chips">
|
||||
@for (chip of chips; track chip) {
|
||||
<div
|
||||
class="chip"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="chip.value"
|
||||
(copiedValue)="copied = $event"
|
||||
(click)="addChip(key.key, chip.value)"
|
||||
>
|
||||
<span class="key">{{ chip.key | translate }}</span>
|
||||
<span class="value">{{ chip.value }}</span>
|
||||
@if (copied !== chip.value) {
|
||||
<i class="las la-clipboard"></i>
|
||||
}
|
||||
@if (copied === chip.value) {
|
||||
<i class="las la-clipboard-check"></i>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</cnsl-form-field>
|
||||
<div class="edit-text-actions">
|
||||
<button
|
||||
matTooltip="{{ 'ACTIONS.RESETDEFAULT' | translate }}"
|
||||
mat-icon-button
|
||||
[disabled]="form.get(key.key)?.value === defaultmap[key.key] || disabled"
|
||||
(click)="form.get(key.key)?.setValue(defaultmap[key.key])"
|
||||
(mouseenter)="
|
||||
form.get(key.key)?.value !== defaultmap[key.key] && setWarnText(key.key, $any(defaultmap[key.key]))
|
||||
"
|
||||
(mouseleave)="setWarnText(key.key, undefined)"
|
||||
>
|
||||
<i class="las la-history"></i>
|
||||
</button>
|
||||
<button
|
||||
matTooltip="{{ 'ACTIONS.RESETCURRENT' | translate }}"
|
||||
mat-icon-button
|
||||
[disabled]="form.get(key.key)?.value === currentMap[key.key] || disabled"
|
||||
(click)="form.get(key.key)?.setValue(currentMap[key.key])"
|
||||
(mouseenter)="
|
||||
form.get(key.key)?.value !== currentMap[key.key] && setWarnText(key.key, $any(currentMap[key.key]))
|
||||
"
|
||||
(mouseleave)="setWarnText(key.key, undefined)"
|
||||
>
|
||||
<i class="las la-undo"></i>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</cnsl-form-field>
|
||||
<div class="edit-text-actions">
|
||||
<button
|
||||
matTooltip="{{ 'ACTIONS.RESETDEFAULT' | translate }}"
|
||||
mat-icon-button
|
||||
[disabled]="form.get(key.key)?.value === defaultmap[key.key] || disabled"
|
||||
(click)="form.get(key.key)?.setValue(defaultmap[key.key])"
|
||||
(mouseenter)="
|
||||
form.get(key.key)?.value !== defaultmap[key.key] && setWarnText(key.key, $any(defaultmap[key.key]))
|
||||
"
|
||||
(mouseleave)="setWarnText(key.key, undefined)"
|
||||
>
|
||||
<i class="las la-history"></i>
|
||||
</button>
|
||||
<button
|
||||
matTooltip="{{ 'ACTIONS.RESETCURRENT' | translate }}"
|
||||
mat-icon-button
|
||||
[disabled]="form.get(key.key)?.value === currentMap[key.key] || disabled"
|
||||
(click)="form.get(key.key)?.setValue(currentMap[key.key])"
|
||||
(mouseenter)="
|
||||
form.get(key.key)?.value !== currentMap[key.key] && setWarnText(key.key, $any(currentMap[key.key]))
|
||||
"
|
||||
(mouseleave)="setWarnText(key.key, undefined)"
|
||||
>
|
||||
<i class="las la-undo"></i>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<cnsl-info-section *ngIf="warnText[key.key] !== undefined" class="edit-text-info" [type]="InfoSectionType.WARN">
|
||||
{{ 'ACTIONS.RESETTO' | translate }} <cite>'{{ warnText[key.key] }}'</cite></cnsl-info-section
|
||||
>
|
||||
</ng-container>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
@if (warnText[key.key] !== undefined) {
|
||||
<cnsl-info-section class="edit-text-info" [type]="InfoSectionType.WARN">
|
||||
{{ 'ACTIONS.RESETTO' | translate }} <cite>'{{ warnText[key.key] }}'</cite></cnsl-info-section
|
||||
>
|
||||
}
|
||||
}
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -22,49 +22,57 @@
|
||||
<ng-container matColumnDef="editor">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'IAM.EVENTS.EDITOR' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let event">
|
||||
<ng-container *ngIf="event | toobject as event">
|
||||
<div class="editor-row" *ngIf="event.editor as editor">
|
||||
<!-- <cnsl-avatar
|
||||
@if (event | toobject; as event) {
|
||||
@if (event.editor; as editor) {
|
||||
<div class="editor-row">
|
||||
<!-- <cnsl-avatar
|
||||
*ngIf="editor && editor.displayName; else cog"
|
||||
class="avatar"
|
||||
[name]="editor.displayName"
|
||||
[avatarUrl]="editor.avatarUrl || ''"
|
||||
[forColor]="editor.preferredLoginName ?? editor.displayName"
|
||||
[size]="32"
|
||||
>
|
||||
>
|
||||
</cnsl-avatar>
|
||||
<ng-template #cog>
|
||||
<cnsl-avatar [forColor]="editor?.preferredLoginName ?? 'franz'" [isMachine]="true">
|
||||
<i class="las la-robot"></i>
|
||||
</cnsl-avatar> </ng-template
|
||||
> -->
|
||||
<span class="name" *ngIf="editor.displayName">{{ editor.displayName }}</span>
|
||||
<span class="state" *ngIf="editor.service">{{ editor.service }}</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
> -->
|
||||
@if (editor.displayName) {
|
||||
<span class="name">{{ editor.displayName }}</span>
|
||||
}
|
||||
@if (editor.service) {
|
||||
<span class="state">{{ editor.service }}</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="aggregate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'IAM.EVENTS.AGGREGATE' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let event">
|
||||
<ng-container *ngIf="event | toobject as event">
|
||||
@if (event | toobject; as event) {
|
||||
<div class="aggregate-row">
|
||||
<span class="id">{{ event.aggregate.id }}</span
|
||||
><span class="state" *ngIf="event.aggregate?.type?.localized?.localizedMessage">{{
|
||||
event.aggregate.type.localized.localizedMessage
|
||||
}}</span>
|
||||
<span class="id">{{ event.aggregate.id }}</span>
|
||||
@if (event.aggregate?.type?.localized?.localizedMessage) {
|
||||
<span class="state">{{ event.aggregate.type.localized.localizedMessage }}</span>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="resourceOwner">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'IAM.EVENTS.RESOURCEOWNER' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let event">
|
||||
<ng-container *ngIf="event | toobject as event">
|
||||
<span *ngIf="event.aggregate.resourceOwner">{{ event.aggregate.resourceOwner }}</span>
|
||||
</ng-container>
|
||||
@if (event | toobject; as event) {
|
||||
@if (event.aggregate.resourceOwner) {
|
||||
<span>{{ event.aggregate.resourceOwner }}</span>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
@@ -73,9 +81,9 @@
|
||||
{{ 'IAM.EVENTS.SEQUENCE' | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let event">
|
||||
<ng-container *ngIf="event | toobject as event">
|
||||
@if (event | toobject; as event) {
|
||||
{{ event.sequence }}
|
||||
</ng-container>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
@@ -84,32 +92,34 @@
|
||||
{{ 'IAM.EVENTS.CREATIONDATE' | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let event">
|
||||
<ng-container *ngIf="event | toobject as event">
|
||||
@if (event | toobject; as event) {
|
||||
<span>{{ event?.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm:ss' }}</span>
|
||||
</ng-container>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'IAM.EVENTS.TYPE' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let event" data-e2e="event-type-cell">
|
||||
<ng-container *ngIf="event | toobject as event">
|
||||
<span *ngIf="event.type?.localized?.localizedMessage">{{ event.type.localized.localizedMessage }}</span>
|
||||
</ng-container>
|
||||
@if (event | toobject; as event) {
|
||||
@if (event.type?.localized?.localizedMessage) {
|
||||
<span>{{ event.type.localized.localizedMessage }}</span>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="payload">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'IAM.EVENTS.PAYLOAD' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let event">
|
||||
<ng-container *ngIf="event | topayload as payload">
|
||||
@if (event | topayload; as payload) {
|
||||
<span>{{ payload | json }}</span>
|
||||
<div class="btn-wrapper">
|
||||
<button class="open-in-dialog-btn" mat-icon-button (click)="openDialog(event)">
|
||||
<mat-icon svgIcon="mdi_arrow_expand"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
<div class="cnsl-action-button">
|
||||
<i class="las la-filter no-margin"></i>
|
||||
<span>{{ 'ACTIONS.FILTER' | translate }}</span>
|
||||
<span *ngIf="queryCount" class="filter-count">{{ queryCount }}</span>
|
||||
@if (queryCount) {
|
||||
<span class="filter-count">{{ queryCount }}</span>
|
||||
}
|
||||
<cnsl-action-keys
|
||||
[doNotUseContrast]="true"
|
||||
[type]="ActionKeysType.FILTER"
|
||||
@@ -37,190 +39,211 @@
|
||||
{{ 'ACTIONS.APPLY' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<form *ngIf="form" [formGroup]="form" (ngSubmit)="emitChange()">
|
||||
<div *ngIf="isLoading" class="sp_wrapper"><mat-spinner diameter="20"></mat-spinner></div>
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox id="userFilterSet" name="userFilterSet" class="cb" formControlName="userFilterSet"
|
||||
>{{ 'IAM.EVENTS.FILTERS.USER.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="filter-events-sub" *ngIf="userFilterSet?.value">
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.USER.IDLABEL' | translate }}</cnsl-label>
|
||||
<input cnslInput id="editorUserId" name="editorUserId" formControlName="editorUserId" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox id="aggregateFilterSet" name="aggregateFilterSet" class="cb" formControlName="aggregateFilterSet"
|
||||
>{{ 'IAM.EVENTS.FILTERS.AGGREGATE.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="filter-events-sub" *ngIf="aggregateFilterSet?.value">
|
||||
<cnsl-form-field class="aggregate-type-select">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.AGGREGATE.TYPELABEL' | translate }}</cnsl-label>
|
||||
|
||||
<mat-select
|
||||
id="aggregateTypesList"
|
||||
name="aggregateTypesList"
|
||||
formControlName="aggregateTypesList"
|
||||
[multiple]="true"
|
||||
>
|
||||
<mat-select-trigger>
|
||||
<span *ngIf="aggregateTypesList?.value && aggregateTypesList?.value.length">{{
|
||||
aggregateTypesList?.value[0]?.localized?.localizedMessage || ''
|
||||
}}</span>
|
||||
<small *ngIf="(aggregateTypesList?.value?.length || 0) > 1" class="cnsl-secondary-text">
|
||||
(+{{ (aggregateTypesList?.value?.length || 0) - 1 }}
|
||||
{{ aggregateTypesList?.value?.length === 2 ? 'other' : 'others' }})
|
||||
</small>
|
||||
</mat-select-trigger>
|
||||
<mat-option *ngFor="let aggregate of aggregateTypes" [value]="aggregate">
|
||||
<span *ngIf="aggregate.localized && aggregate.localized.localizedMessage">
|
||||
{{ aggregate.localized.localizedMessage }}
|
||||
</span>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.AGGREGATE.IDLABEL' | translate }}</cnsl-label>
|
||||
<input id="aggregateId" formControlName="aggregateId" cnslInput name="aggregateId" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox
|
||||
id="eventTypesFilterSet"
|
||||
name="eventTypesFilterSet"
|
||||
class="cb"
|
||||
formControlName="eventTypesFilterSet"
|
||||
data-e2e="event-type-filter-checkbox"
|
||||
>{{ 'IAM.EVENTS.FILTERS.TYPE.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="filter-events-sub" *ngIf="eventTypesFilterSet?.value">
|
||||
<cnsl-form-field class="event-types-select">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.TYPE.TYPELABEL' | translate }}</cnsl-label>
|
||||
|
||||
<mat-select id="eventTypesList" formControlName="eventTypesList" [multiple]="true">
|
||||
<mat-select-trigger>
|
||||
<span *ngIf="eventTypesList?.value && eventTypesList?.value.length">{{
|
||||
eventTypesList?.value[0]?.localized?.localizedMessage || ''
|
||||
}}</span>
|
||||
<small *ngIf="(eventTypesList?.value?.length || 0) > 1" class="cnsl-secondary-text">
|
||||
(+{{ (eventTypesList?.value?.length || 0) - 1 }}
|
||||
{{ eventTypesList?.value?.length === 2 ? 'other' : 'others' }})
|
||||
</small>
|
||||
</mat-select-trigger>
|
||||
<mat-option *ngFor="let eventType of eventTypes" [value]="eventType">
|
||||
<ng-container *ngIf="eventType.localized && eventType.localized.localizedMessage">
|
||||
{{ eventType.localized.localizedMessage }}
|
||||
</ng-container>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox
|
||||
id="resourceOwnerFilterSet"
|
||||
name="resourceOwnerFilterSet"
|
||||
class="cb"
|
||||
formControlName="resourceOwnerFilterSet"
|
||||
>{{ 'IAM.EVENTS.FILTERS.RESOURCEOWNER.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="filter-events-sub" *ngIf="resourceOwnerFilterSet?.value">
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.RESOURCEOWNER.LABEL' | translate }}</cnsl-label>
|
||||
<input cnslInput id="resourceOwner" name="resourceOwner" formControlName="resourceOwner" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox id="sequenceFilterSet" name="sequenceFilterSet" class="cb" formControlName="sequenceFilterSet"
|
||||
>{{ 'IAM.EVENTS.FILTERS.SEQUENCE.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="filter-events-sub" *ngIf="sequenceFilterSet?.value">
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.SEQUENCE.LABEL' | translate }}</cnsl-label>
|
||||
<input cnslInput id="sequence" name="sequence" formControlName="sequence" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-events-section">
|
||||
<mat-radio-group aria-label="Select an option" class="filter-events-sub" formControlName="creationDateFilterType">
|
||||
<mat-radio-button [value]="CreationDateFilterType.FROM">
|
||||
{{ 'IAM.EVENTS.FILTERS.CREATIONDATE.RADIO_FROM' | translate }}
|
||||
</mat-radio-button>
|
||||
<mat-radio-button [value]="CreationDateFilterType.RANGE">
|
||||
{{ 'IAM.EVENTS.FILTERS.CREATIONDATE.RADIO_RANGE' | translate }}
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<div class="filter-events-sub">
|
||||
<ng-container *ngIf="creationDateFilterType!.value === CreationDateFilterType.FROM">
|
||||
<mat-form-field class="datetime-input">
|
||||
<input
|
||||
class="datetime"
|
||||
matInput
|
||||
type="datetime-local"
|
||||
name="creationDateFrom"
|
||||
[value]="creationDateFrom!.value | date: 'yyyy-MM-dd HH:mm:ss'"
|
||||
(change)="creationDateFrom = $event.target"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="creationDateFilterType!.value === CreationDateFilterType.RANGE">
|
||||
<div class="datetime-range">
|
||||
<mat-form-field class="datetime-input">
|
||||
<cnsl-label
|
||||
>{{ 'IAM.EVENTS.FILTERS.CREATIONDATE.LABEL_SINCE' | translate }}
|
||||
<input
|
||||
matInput
|
||||
type="datetime-local"
|
||||
name="creationDateSince"
|
||||
[value]="creationDateSince!.value | date: 'yyyy-MM-dd HH:mm:ss'"
|
||||
(change)="creationDateSince = $event.target"
|
||||
/>
|
||||
</cnsl-label>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="datetime-input">
|
||||
<cnsl-label
|
||||
>{{ 'IAM.EVENTS.FILTERS.CREATIONDATE.LABEL_UNTIL' | translate }}
|
||||
<input
|
||||
matInput
|
||||
type="datetime-local"
|
||||
name="creationDateUntil"
|
||||
[value]="creationDateUntil!.value | date: 'yyyy-MM-dd HH:mm:ss'"
|
||||
(change)="creationDateUntil = $event.target"
|
||||
/>
|
||||
</cnsl-label>
|
||||
</mat-form-field>
|
||||
@if (form) {
|
||||
<form [formGroup]="form" (ngSubmit)="emitChange()">
|
||||
@if (isLoading) {
|
||||
<div class="sp_wrapper"><mat-spinner diameter="20"></mat-spinner></div>
|
||||
}
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox id="userFilterSet" name="userFilterSet" class="cb" formControlName="userFilterSet"
|
||||
>{{ 'IAM.EVENTS.FILTERS.USER.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@if (userFilterSet?.value) {
|
||||
<div class="filter-events-sub">
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.USER.IDLABEL' | translate }}</cnsl-label>
|
||||
<input cnslInput id="editorUserId" name="editorUserId" formControlName="editorUserId" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-events-section">
|
||||
<cnsl-form-field class="aggregate-type-select">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.SORT' | translate }}</cnsl-label>
|
||||
|
||||
<mat-select id="isAsc" formControlName="isAsc">
|
||||
<mat-option [value]="false"> {{ 'IAM.EVENTS.FILTERS.DESC' | translate }} </mat-option>
|
||||
<mat-option [value]="true">{{ 'IAM.EVENTS.FILTERS.ASC' | translate }} </mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</form>
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox id="aggregateFilterSet" name="aggregateFilterSet" class="cb" formControlName="aggregateFilterSet"
|
||||
>{{ 'IAM.EVENTS.FILTERS.AGGREGATE.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@if (aggregateFilterSet?.value) {
|
||||
<div class="filter-events-sub">
|
||||
<cnsl-form-field class="aggregate-type-select">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.AGGREGATE.TYPELABEL' | translate }}</cnsl-label>
|
||||
<mat-select
|
||||
id="aggregateTypesList"
|
||||
name="aggregateTypesList"
|
||||
formControlName="aggregateTypesList"
|
||||
[multiple]="true"
|
||||
>
|
||||
<mat-select-trigger>
|
||||
@if (aggregateTypesList?.value && aggregateTypesList?.value.length) {
|
||||
<span>{{ aggregateTypesList?.value[0]?.localized?.localizedMessage || '' }}</span>
|
||||
}
|
||||
@if ((aggregateTypesList?.value?.length || 0) > 1) {
|
||||
<small class="cnsl-secondary-text">
|
||||
(+{{ (aggregateTypesList?.value?.length || 0) - 1 }}
|
||||
{{ aggregateTypesList?.value?.length === 2 ? 'other' : 'others' }})
|
||||
</small>
|
||||
}
|
||||
</mat-select-trigger>
|
||||
@for (aggregate of aggregateTypes; track aggregate) {
|
||||
<mat-option [value]="aggregate">
|
||||
@if (aggregate.localized && aggregate.localized.localizedMessage) {
|
||||
<span>
|
||||
{{ aggregate.localized.localizedMessage }}
|
||||
</span>
|
||||
}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.AGGREGATE.IDLABEL' | translate }}</cnsl-label>
|
||||
<input id="aggregateId" formControlName="aggregateId" cnslInput name="aggregateId" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox
|
||||
id="eventTypesFilterSet"
|
||||
name="eventTypesFilterSet"
|
||||
class="cb"
|
||||
formControlName="eventTypesFilterSet"
|
||||
data-e2e="event-type-filter-checkbox"
|
||||
>{{ 'IAM.EVENTS.FILTERS.TYPE.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@if (eventTypesFilterSet?.value) {
|
||||
<div class="filter-events-sub">
|
||||
<cnsl-form-field class="event-types-select">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.TYPE.TYPELABEL' | translate }}</cnsl-label>
|
||||
<mat-select id="eventTypesList" formControlName="eventTypesList" [multiple]="true">
|
||||
<mat-select-trigger>
|
||||
@if (eventTypesList?.value && eventTypesList?.value.length) {
|
||||
<span>{{ eventTypesList?.value[0]?.localized?.localizedMessage || '' }}</span>
|
||||
}
|
||||
@if ((eventTypesList?.value?.length || 0) > 1) {
|
||||
<small class="cnsl-secondary-text">
|
||||
(+{{ (eventTypesList?.value?.length || 0) - 1 }}
|
||||
{{ eventTypesList?.value?.length === 2 ? 'other' : 'others' }})
|
||||
</small>
|
||||
}
|
||||
</mat-select-trigger>
|
||||
@for (eventType of eventTypes; track eventType) {
|
||||
<mat-option [value]="eventType">
|
||||
@if (eventType.localized && eventType.localized.localizedMessage) {
|
||||
{{ eventType.localized.localizedMessage }}
|
||||
}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox
|
||||
id="resourceOwnerFilterSet"
|
||||
name="resourceOwnerFilterSet"
|
||||
class="cb"
|
||||
formControlName="resourceOwnerFilterSet"
|
||||
>{{ 'IAM.EVENTS.FILTERS.RESOURCEOWNER.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@if (resourceOwnerFilterSet?.value) {
|
||||
<div class="filter-events-sub">
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.RESOURCEOWNER.LABEL' | translate }}</cnsl-label>
|
||||
<input cnslInput id="resourceOwner" name="resourceOwner" formControlName="resourceOwner" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="filter-events-section">
|
||||
<div class="checkbox-wrapper">
|
||||
<mat-checkbox id="sequenceFilterSet" name="sequenceFilterSet" class="cb" formControlName="sequenceFilterSet"
|
||||
>{{ 'IAM.EVENTS.FILTERS.SEQUENCE.CHECKBOX' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@if (sequenceFilterSet?.value) {
|
||||
<div class="filter-events-sub">
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.SEQUENCE.LABEL' | translate }}</cnsl-label>
|
||||
<input cnslInput id="sequence" name="sequence" formControlName="sequence" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="filter-events-section">
|
||||
<mat-radio-group
|
||||
aria-label="Select an option"
|
||||
class="filter-events-sub"
|
||||
formControlName="creationDateFilterType"
|
||||
>
|
||||
<mat-radio-button [value]="CreationDateFilterType.FROM">
|
||||
{{ 'IAM.EVENTS.FILTERS.CREATIONDATE.RADIO_FROM' | translate }}
|
||||
</mat-radio-button>
|
||||
<mat-radio-button [value]="CreationDateFilterType.RANGE">
|
||||
{{ 'IAM.EVENTS.FILTERS.CREATIONDATE.RADIO_RANGE' | translate }}
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<div class="filter-events-sub">
|
||||
@if (creationDateFilterType!.value === CreationDateFilterType.FROM) {
|
||||
<mat-form-field class="datetime-input">
|
||||
<input
|
||||
class="datetime"
|
||||
matInput
|
||||
type="datetime-local"
|
||||
name="creationDateFrom"
|
||||
[value]="creationDateFrom!.value | date: 'yyyy-MM-dd HH:mm:ss'"
|
||||
(change)="creationDateFrom = $event.target"
|
||||
/>
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (creationDateFilterType!.value === CreationDateFilterType.RANGE) {
|
||||
<div class="datetime-range">
|
||||
<mat-form-field class="datetime-input">
|
||||
<cnsl-label
|
||||
>{{ 'IAM.EVENTS.FILTERS.CREATIONDATE.LABEL_SINCE' | translate }}
|
||||
<input
|
||||
matInput
|
||||
type="datetime-local"
|
||||
name="creationDateSince"
|
||||
[value]="creationDateSince!.value | date: 'yyyy-MM-dd HH:mm:ss'"
|
||||
(change)="creationDateSince = $event.target"
|
||||
/>
|
||||
</cnsl-label>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="datetime-input">
|
||||
<cnsl-label
|
||||
>{{ 'IAM.EVENTS.FILTERS.CREATIONDATE.LABEL_UNTIL' | translate }}
|
||||
<input
|
||||
matInput
|
||||
type="datetime-local"
|
||||
name="creationDateUntil"
|
||||
[value]="creationDateUntil!.value | date: 'yyyy-MM-dd HH:mm:ss'"
|
||||
(change)="creationDateUntil = $event.target"
|
||||
/>
|
||||
</cnsl-label>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-events-section">
|
||||
<cnsl-form-field class="aggregate-type-select">
|
||||
<cnsl-label>{{ 'IAM.EVENTS.FILTERS.SORT' | translate }}</cnsl-label>
|
||||
<mat-select id="isAsc" formControlName="isAsc">
|
||||
<mat-option [value]="false"> {{ 'IAM.EVENTS.FILTERS.DESC' | translate }} </mat-option>
|
||||
<mat-option [value]="true">{{ 'IAM.EVENTS.FILTERS.ASC' | translate }} </mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
@@ -8,19 +8,22 @@
|
||||
(change)="changeCheckbox(SubQuery.NAME, $event)"
|
||||
>{{ 'FILTER.ORGNAME' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.NAME) as eq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="eq.getMethod()" (selectionChange)="setMethod(eq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="eq.getName()" (change)="setValue(SubQuery.NAME, eq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.NAME); as eq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="eq.getMethod()" (selectionChange)="setMethod(eq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="eq.getName()" (change)="setValue(SubQuery.NAME, eq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="name-query">
|
||||
@@ -31,19 +34,22 @@
|
||||
(change)="changeCheckbox(SubQuery.STATE, $event)"
|
||||
>{{ 'FILTER.STATE' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.STATE) as sq">
|
||||
<span class="nomethod cnsl-secondary-text">
|
||||
{{ 'FILTER.METHODS.1' | translate }}
|
||||
</span>
|
||||
|
||||
<cnsl-form-field class="filter-select-value">
|
||||
<mat-select [value]="sq.getState()" (selectionChange)="setValue(SubQuery.STATE, sq, $event)">
|
||||
<mat-option *ngFor="let state of states" [value]="state">
|
||||
{{ 'USER.STATE.' + state | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.STATE); as sq) {
|
||||
<div class="subquery">
|
||||
<span class="nomethod cnsl-secondary-text">
|
||||
{{ 'FILTER.METHODS.1' | translate }}
|
||||
</span>
|
||||
<cnsl-form-field class="filter-select-value">
|
||||
<mat-select [value]="sq.getState()" (selectionChange)="setValue(SubQuery.STATE, sq, $event)">
|
||||
@for (state of states; track state) {
|
||||
<mat-option [value]="state">
|
||||
{{ 'USER.STATE.' + state | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -55,33 +61,37 @@
|
||||
(change)="changeCheckbox(SubQuery.DOMAIN, $event)"
|
||||
>{{ 'FILTER.PRIMARYDOMAIN' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.DOMAIN) as dq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="dq.getMethod()" (selectionChange)="setMethod(dq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="dq.getDomain()" (change)="setValue(SubQuery.DOMAIN, dq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.DOMAIN); as dq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="dq.getMethod()" (selectionChange)="setMethod(dq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="dq.getDomain()" (change)="setValue(SubQuery.DOMAIN, dq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="id-query">
|
||||
<mat-checkbox id="id" class="cb" [checked]="getSubFilter(SubQuery.ID)" (change)="changeCheckbox(SubQuery.ID, $event)"
|
||||
>{{ 'FILTER.ORGID' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.ID) as idq">
|
||||
<span class="nomethod cnsl-secondary-text">
|
||||
{{ 'FILTER.METHODS.1' | translate }}
|
||||
</span>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="idq.getId()" (change)="setValue(SubQuery.ID, idq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.ID); as idq) {
|
||||
<div class="subquery">
|
||||
<span class="nomethod cnsl-secondary-text">
|
||||
{{ 'FILTER.METHODS.1' | translate }}
|
||||
</span>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="idq.getId()" (change)="setValue(SubQuery.ID, idq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</cnsl-filter>
|
||||
|
||||
@@ -8,19 +8,22 @@
|
||||
(change)="changeCheckbox(SubQuery.NAME, $event)"
|
||||
>{{ 'FILTER.PROJECTNAME' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.NAME) as eq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="eq.getMethod()" (selectionChange)="setMethod(eq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="eq.getName()" (change)="setValue(SubQuery.NAME, eq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.NAME); as eq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="eq.getMethod()" (selectionChange)="setMethod(eq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="eq.getName()" (change)="setValue(SubQuery.NAME, eq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-filter>
|
||||
|
||||
@@ -8,24 +8,27 @@
|
||||
(change)="changeCheckbox(SubQuery.DISPLAYNAME, $event)"
|
||||
>{{ 'FILTER.DISPLAYNAME' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.DISPLAYNAME) as dnq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="dnq.getMethod()" (selectionChange)="setMethod(dnq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input
|
||||
cnslInput
|
||||
name="value"
|
||||
[value]="dnq.getDisplayName()"
|
||||
(change)="setValue(SubQuery.DISPLAYNAME, dnq, $event)"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.DISPLAYNAME); as dnq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="dnq.getMethod()" (selectionChange)="setMethod(dnq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input
|
||||
cnslInput
|
||||
name="value"
|
||||
[value]="dnq.getDisplayName()"
|
||||
(change)="setValue(SubQuery.DISPLAYNAME, dnq, $event)"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="usernane-query">
|
||||
@@ -36,19 +39,22 @@
|
||||
(change)="changeCheckbox(SubQuery.USERNAME, $event)"
|
||||
>{{ 'FILTER.USERNAME' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.USERNAME) as unq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="unq.getMethod()" (selectionChange)="setMethod(unq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="unq.getUserName()" (change)="setValue(SubQuery.USERNAME, unq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.USERNAME); as unq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="unq.getMethod()" (selectionChange)="setMethod(unq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="unq.getUserName()" (change)="setValue(SubQuery.USERNAME, unq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="email-query">
|
||||
@@ -59,19 +65,22 @@
|
||||
(change)="changeCheckbox(SubQuery.ORGNAME, $event)"
|
||||
>{{ 'FILTER.ORGNAME' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.ORGNAME) as onq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="onq.getMethod()" (selectionChange)="setMethod(onq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="onq.getOrgName()" (change)="setValue(SubQuery.ORGNAME, onq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.ORGNAME); as onq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="onq.getMethod()" (selectionChange)="setMethod(onq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="onq.getOrgName()" (change)="setValue(SubQuery.ORGNAME, onq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="email-query">
|
||||
@@ -82,24 +91,27 @@
|
||||
(change)="changeCheckbox(SubQuery.PROJECTNAME, $event)"
|
||||
>{{ 'FILTER.PROJECTNAME' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.PROJECTNAME) as pnq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="pnq.getMethod()" (selectionChange)="setMethod(pnq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input
|
||||
cnslInput
|
||||
name="value"
|
||||
[value]="pnq.getProjectName()"
|
||||
(change)="setValue(SubQuery.PROJECTNAME, pnq, $event)"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.PROJECTNAME); as pnq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="pnq.getMethod()" (selectionChange)="setMethod(pnq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input
|
||||
cnslInput
|
||||
name="value"
|
||||
[value]="pnq.getProjectName()"
|
||||
(change)="setValue(SubQuery.PROJECTNAME, pnq, $event)"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-filter>
|
||||
|
||||
@@ -8,19 +8,22 @@
|
||||
(change)="changeCheckbox(SubQuery.STATE, $event)"
|
||||
>{{ 'FILTER.STATE' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.STATE) as sq">
|
||||
<span class="nomethod cnsl-secondary-text">
|
||||
{{ 'FILTER.METHODS.1' | translate }}
|
||||
</span>
|
||||
|
||||
<cnsl-form-field class="filter-select-value">
|
||||
<mat-select [value]="sq.getState()" (selectionChange)="setValue(SubQuery.STATE, sq, $event)">
|
||||
<mat-option *ngFor="let state of states" [value]="state">
|
||||
{{ 'USER.STATE.' + state | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.STATE); as sq) {
|
||||
<div class="subquery">
|
||||
<span class="nomethod cnsl-secondary-text">
|
||||
{{ 'FILTER.METHODS.1' | translate }}
|
||||
</span>
|
||||
<cnsl-form-field class="filter-select-value">
|
||||
<mat-select [value]="sq.getState()" (selectionChange)="setValue(SubQuery.STATE, sq, $event)">
|
||||
@for (state of states; track state) {
|
||||
<mat-option [value]="state">
|
||||
{{ 'USER.STATE.' + state | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="name-query">
|
||||
@@ -31,24 +34,27 @@
|
||||
(change)="changeCheckbox(SubQuery.DISPLAYNAME, $event)"
|
||||
>{{ 'FILTER.DISPLAYNAME' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.DISPLAYNAME) as dnq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="dnq.getMethod()" (selectionChange)="setMethod(dnq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input
|
||||
cnslInput
|
||||
name="value"
|
||||
[value]="dnq.getDisplayName()"
|
||||
(change)="setValue(SubQuery.DISPLAYNAME, dnq, $event)"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.DISPLAYNAME); as dnq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="dnq.getMethod()" (selectionChange)="setMethod(dnq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input
|
||||
cnslInput
|
||||
name="value"
|
||||
[value]="dnq.getDisplayName()"
|
||||
(change)="setValue(SubQuery.DISPLAYNAME, dnq, $event)"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="email-query">
|
||||
@@ -59,19 +65,22 @@
|
||||
(change)="changeCheckbox(SubQuery.EMAIL, $event)"
|
||||
>{{ 'FILTER.EMAIL' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.EMAIL) as eq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="eq.getMethod()" (selectionChange)="setMethod(eq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="eq.getEmailAddress()" (change)="setValue(SubQuery.EMAIL, eq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.EMAIL); as eq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="eq.getMethod()" (selectionChange)="setMethod(eq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="eq.getEmailAddress()" (change)="setValue(SubQuery.EMAIL, eq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="usernane-query">
|
||||
@@ -82,19 +91,22 @@
|
||||
(change)="changeCheckbox(SubQuery.USERNAME, $event)"
|
||||
>{{ 'FILTER.USERNAME' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="subquery" *ngIf="getSubFilter(SubQuery.USERNAME) as unq">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="unq.getMethod()" (selectionChange)="setMethod(unq, $event)">
|
||||
<mat-option *ngFor="let method of methods" [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="unq.getUserName()" (change)="setValue(SubQuery.USERNAME, unq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
@if (getSubFilter(SubQuery.USERNAME); as unq) {
|
||||
<div class="subquery">
|
||||
<cnsl-form-field class="filter-select-method">
|
||||
<mat-select [value]="unq.getMethod()" (selectionChange)="setMethod(unq, $event)">
|
||||
@for (method of methods; track method) {
|
||||
<mat-option [value]="method">
|
||||
{{ 'FILTER.METHODS.' + method | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="filter-input-value">
|
||||
<input cnslInput name="value" [value]="unq.getUserName()" (change)="setValue(SubQuery.USERNAME, unq, $event)" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-filter>
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
<div class="cnsl-action-button">
|
||||
<i class="las la-filter no-margin"></i>
|
||||
<span>{{ 'ACTIONS.FILTER' | translate }}</span>
|
||||
<span *ngIf="queryCount" class="filter-count">{{ queryCount }}</span>
|
||||
@if (queryCount) {
|
||||
<span class="filter-count">{{ queryCount }}</span>
|
||||
}
|
||||
<cnsl-action-keys [doNotUseContrast]="true" [type]="ActionKeysType.FILTER" (actionTriggered)="toggleFilter()">
|
||||
</cnsl-action-keys>
|
||||
</div>
|
||||
|
||||
@@ -1,35 +1,43 @@
|
||||
<div class="footer-wrapper">
|
||||
<div class="footer-row">
|
||||
<div class="footer-links" *ngIf="authService.privacypolicy$ | async as pP">
|
||||
<a target="_blank" *ngIf="pP?.tosLink" rel="noreferrer" [href]="pP?.tosLink" external>
|
||||
<span>{{ 'FOOTER.LINKS.TOS' | translate }}</span>
|
||||
<i class="las la-external-link-alt"></i>
|
||||
</a>
|
||||
<a target="_blank" *ngIf="pP?.privacyLink" rel="noreferrer" [href]="pP?.privacyLink" external>
|
||||
<span>{{ 'FOOTER.LINKS.PP' | translate }}</span>
|
||||
<i class="las la-external-link-alt"></i>
|
||||
</a>
|
||||
</div>
|
||||
@if (authService.privacypolicy$ | async; as pP) {
|
||||
<div class="footer-links">
|
||||
@if (pP?.tosLink) {
|
||||
<a target="_blank" rel="noreferrer" [href]="pP?.tosLink" external>
|
||||
<span>{{ 'FOOTER.LINKS.TOS' | translate }}</span>
|
||||
<i class="las la-external-link-alt"></i>
|
||||
</a>
|
||||
}
|
||||
@if (pP?.privacyLink) {
|
||||
<a target="_blank" rel="noreferrer" [href]="pP?.privacyLink" external>
|
||||
<span>{{ 'FOOTER.LINKS.PP' | translate }}</span>
|
||||
<i class="las la-external-link-alt"></i>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="footer-socials" *ngIf="authService.labelpolicy$ | async as lP">
|
||||
<ng-container *ngIf="lP?.disableWatermark === false">
|
||||
<a target="_blank" rel="noreferrer" href="https://github.com/zitadel">
|
||||
<i class="text-3xl lab la-github"></i>
|
||||
</a>
|
||||
<a target="_blank" rel="noreferrer" href="https://twitter.com/zitadel">
|
||||
<fa-icon [icon]="faXTwitter" size="xl"></fa-icon>
|
||||
</a>
|
||||
<a target="_blank" rel="noreferrer" href="https://www.linkedin.com/company/zitadel/">
|
||||
<i class="text-3xl lab la-linkedin"></i>
|
||||
</a>
|
||||
<a target="_blank" rel="noreferrer" href="https://zitadel.com/chat">
|
||||
<i class="text-3xl lab la-discord"></i>
|
||||
</a>
|
||||
<a target="_blank" rel="noreferrer" href="https://www.youtube.com/channel/UCUAWJUNYaRn1yIVrZxEfsuA">
|
||||
<i class="text-3xl lab la-youtube"></i>
|
||||
</a>
|
||||
</ng-container>
|
||||
</div>
|
||||
@if (authService.labelpolicy$ | async; as lP) {
|
||||
<div class="footer-socials">
|
||||
@if (lP?.disableWatermark === false) {
|
||||
<a target="_blank" rel="noreferrer" href="https://github.com/zitadel">
|
||||
<i class="text-3xl lab la-github"></i>
|
||||
</a>
|
||||
<a target="_blank" rel="noreferrer" href="https://twitter.com/zitadel">
|
||||
<fa-icon [icon]="faXTwitter" size="xl"></fa-icon>
|
||||
</a>
|
||||
<a target="_blank" rel="noreferrer" href="https://www.linkedin.com/company/zitadel/">
|
||||
<i class="text-3xl lab la-linkedin"></i>
|
||||
</a>
|
||||
<a target="_blank" rel="noreferrer" href="https://zitadel.com/chat">
|
||||
<i class="text-3xl lab la-discord"></i>
|
||||
</a>
|
||||
<a target="_blank" rel="noreferrer" href="https://www.youtube.com/channel/UCUAWJUNYaRn1yIVrZxEfsuA">
|
||||
<i class="text-3xl lab la-youtube"></i>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="theme">
|
||||
<cnsl-theme-setting></cnsl-theme-setting>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<ng-template #labelTemplate>
|
||||
<label class="cnsl-label-wrapper" [attr.for]="_control.id" [attr.aria-owns]="_control.id">
|
||||
<ng-content select="cnsl-label"></ng-content>
|
||||
<span *ngIf="_control.required && !hideRequiredMarker" aria-hidden="true" class="cnsl-form-field-required-marker"
|
||||
>*</span
|
||||
>
|
||||
@if (_control.required && !hideRequiredMarker) {
|
||||
<span aria-hidden="true" class="cnsl-form-field-required-marker">*</span>
|
||||
}
|
||||
</label>
|
||||
</ng-template>
|
||||
|
||||
@@ -13,17 +13,25 @@
|
||||
<ng-content></ng-content>
|
||||
<ng-content select="cnslSuffix"></ng-content>
|
||||
</div>
|
||||
<ng-container *ngIf="help$ && help$ | async as help">
|
||||
<div [ngSwitch]="help.type" class="cnsl-form-field-subscript-wrapper">
|
||||
<div *ngSwitchCase="'hints'" class="cnsl-form-field-hint-wrapper" [@transitionMessages]="_subscriptAnimationState">
|
||||
<ng-content select="cnsl-hint"></ng-content>
|
||||
</div>
|
||||
<div *ngSwitchCase="'errors'" class="cnsl-form-field-error-wrapper" [@transitionMessages]="_subscriptAnimationState">
|
||||
<span cnslError *ngFor="let err of help.validationErrors">
|
||||
{{ err.i18nKey | translate: err.params }}
|
||||
</span>
|
||||
<ng-content select="cnsl-error"></ng-content>
|
||||
</div>
|
||||
@if (help$ && help$ | async; as help) {
|
||||
<div class="cnsl-form-field-subscript-wrapper">
|
||||
@switch (help.type) {
|
||||
@case ('hints') {
|
||||
<div class="cnsl-form-field-hint-wrapper" [@transitionMessages]="_subscriptAnimationState">
|
||||
<ng-content select="cnsl-hint"></ng-content>
|
||||
</div>
|
||||
}
|
||||
@case ('errors') {
|
||||
<div class="cnsl-form-field-error-wrapper" [@transitionMessages]="_subscriptAnimationState">
|
||||
@for (err of help.validationErrors; track err) {
|
||||
<span cnslError>
|
||||
{{ err.i18nKey | translate: err.params }}
|
||||
</span>
|
||||
}
|
||||
<ng-content select="cnsl-error"></ng-content>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,44 +1,41 @@
|
||||
<mat-toolbar class="header-wrapper">
|
||||
<div class="header-content">
|
||||
<div *ngIf="authService.labelPolicyLoading$ | async; else logo" class="logo-placeholder">
|
||||
<mat-spinner [diameter]="20"></mat-spinner>
|
||||
</div>
|
||||
<ng-template #logo>
|
||||
<a class="title custom" [routerLink]="['/']" *ngIf="authService.labelpolicy$ | async as lP; else defaultHome">
|
||||
<img
|
||||
class="logo"
|
||||
alt="home logo"
|
||||
*ngIf="isDarkTheme; else customlighttheme"
|
||||
[src]="lP.iconUrlDark ? lP.iconUrlDark : './assets/images/zitadel-logo-solo-light.svg'"
|
||||
(error)="errorHandler($event, './assets/images/zitadel-logo-solo-light.svg')"
|
||||
/>
|
||||
<ng-template #customlighttheme>
|
||||
<img
|
||||
alt="home logo"
|
||||
class="logo"
|
||||
[src]="lP.iconUrl ? lP.iconUrl : './assets/images/zitadel-logo-solo-dark.svg'"
|
||||
(error)="errorHandler($event, './assets/images/zitadel-logo-solo-dark.svg')"
|
||||
/>
|
||||
</ng-template>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #defaultHome>
|
||||
<a class="title" [routerLink]="(authService.zitadelPermissions | async)?.length ? ['/'] : ['/users', 'me']">
|
||||
<img
|
||||
class="logo"
|
||||
alt="zitadel logo"
|
||||
*ngIf="isDarkTheme; else lighttheme"
|
||||
src="./assets/images/zitadel-logo-solo-light.svg"
|
||||
/>
|
||||
<ng-template #lighttheme>
|
||||
<img alt="zitadel logo" class="logo" src="./assets/images/zitadel-logo-solo-dark.svg" />
|
||||
</ng-template>
|
||||
</a>
|
||||
</ng-template>
|
||||
@if (authService.labelPolicyLoading$ | async) {
|
||||
<div class="logo-placeholder">
|
||||
<mat-spinner [diameter]="20"></mat-spinner>
|
||||
</div>
|
||||
} @else {
|
||||
@if (authService.labelpolicy$ | async; as lP) {
|
||||
<a class="title custom" [routerLink]="['/']">
|
||||
@if (isDarkTheme) {
|
||||
<img
|
||||
class="logo"
|
||||
alt="home logo"
|
||||
[src]="lP.iconUrlDark ? lP.iconUrlDark : './assets/images/zitadel-logo-solo-light.svg'"
|
||||
(error)="errorHandler($event, './assets/images/zitadel-logo-solo-light.svg')"
|
||||
/>
|
||||
} @else {
|
||||
<img
|
||||
alt="home logo"
|
||||
class="logo"
|
||||
[src]="lP.iconUrl ? lP.iconUrl : './assets/images/zitadel-logo-solo-dark.svg'"
|
||||
(error)="errorHandler($event, './assets/images/zitadel-logo-solo-dark.svg')"
|
||||
/>
|
||||
}
|
||||
</a>
|
||||
} @else {
|
||||
<a class="title" [routerLink]="(authService.zitadelPermissions | async)?.length ? ['/'] : ['/users', 'me']">
|
||||
@if (isDarkTheme) {
|
||||
<img class="logo" alt="zitadel logo" src="./assets/images/zitadel-logo-solo-light.svg" />
|
||||
} @else {
|
||||
<img alt="zitadel logo" class="logo" src="./assets/images/zitadel-logo-solo-dark.svg" />
|
||||
}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
|
||||
<ng-container *ngFor="let bread of breadcrumbService.breadcrumbs$ | async as bc; index as i">
|
||||
<ng-container *ngIf="bread.type === BreadcrumbType.INSTANCE">
|
||||
@if (bread.type === BreadcrumbType.INSTANCE) {
|
||||
<ng-template cnslHasRole [hasRole]="['iam.read']">
|
||||
<svg
|
||||
class="slash hide-on-small"
|
||||
@@ -53,16 +50,15 @@
|
||||
>
|
||||
<path d="M16.88 3.549L7.12 20.451"></path>
|
||||
</svg>
|
||||
|
||||
<div class="breadcrumb-context hide-on-small">
|
||||
<a matRipple [matRippleUnbounded]="false" class="breadcrumb-link" [routerLink]="bread.routerLink">
|
||||
{{ 'MENU.INSTANCE' | translate }}
|
||||
</a>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="bread.type === BreadcrumbType.ORG">
|
||||
@if (bread.type === BreadcrumbType.ORG) {
|
||||
<svg
|
||||
class="slash"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -76,20 +72,13 @@
|
||||
>
|
||||
<path d="M16.88 3.549L7.12 20.451"></path>
|
||||
</svg>
|
||||
|
||||
<div class="org-context">
|
||||
<a
|
||||
*ngIf="org() as org"
|
||||
matRipple
|
||||
[matRippleUnbounded]="false"
|
||||
class="org-link"
|
||||
id="orglink"
|
||||
[routerLink]="['/org']"
|
||||
>
|
||||
{{ org.name ? org.name : 'NO NAME' }}</a
|
||||
>
|
||||
|
||||
<div class="org-context-wrapper" *ngIf="org">
|
||||
@if (org(); as org) {
|
||||
<a matRipple [matRippleUnbounded]="false" class="org-link" id="orglink" [routerLink]="['/org']">
|
||||
{{ org.name ? org.name : 'NO NAME' }}</a
|
||||
>
|
||||
}
|
||||
<div class="org-context-wrapper">
|
||||
<button
|
||||
cdkOverlayOrigin
|
||||
#trigger="cdkOverlayOrigin"
|
||||
@@ -113,7 +102,6 @@
|
||||
[type]="ActionKeysType.ORGSWITCHER"
|
||||
></cnsl-action-keys>
|
||||
</button>
|
||||
|
||||
<ng-template
|
||||
cdkConnectedOverlay
|
||||
[cdkConnectedOverlayOrigin]="trigger"
|
||||
@@ -125,20 +113,21 @@
|
||||
(backdropClick)="showOrgContext = false"
|
||||
(detach)="showOrgContext = false"
|
||||
>
|
||||
<cnsl-org-context
|
||||
class="context_card"
|
||||
*ngIf="showOrgContext && org() as org"
|
||||
(closedCard)="showOrgContext = false"
|
||||
[org]="org"
|
||||
(setOrg)="setActiveOrg($event)"
|
||||
>
|
||||
</cnsl-org-context>
|
||||
@if (showOrgContext && org(); as org) {
|
||||
<cnsl-org-context
|
||||
class="context_card"
|
||||
(closedCard)="showOrgContext = false"
|
||||
[org]="org"
|
||||
(setOrg)="setActiveOrg($event)"
|
||||
>
|
||||
</cnsl-org-context>
|
||||
}
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="bread.type !== BreadcrumbType.INSTANCE && bread.type !== BreadcrumbType.ORG">
|
||||
@if (bread.type !== BreadcrumbType.INSTANCE && bread.type !== BreadcrumbType.ORG) {
|
||||
<svg
|
||||
class="slash"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -152,7 +141,6 @@
|
||||
>
|
||||
<path d="M16.88 3.549L7.12 20.451"></path>
|
||||
</svg>
|
||||
|
||||
<div class="breadcrumb-context">
|
||||
<a
|
||||
matRipple
|
||||
@@ -161,58 +149,54 @@
|
||||
[ngClass]="{ maxwidth: bc.length > 1 }"
|
||||
[routerLink]="bread.routerLink"
|
||||
>
|
||||
<ng-container *ngIf="i !== bc.length - 1; else defLabel">
|
||||
@if (i !== bc.length - 1) {
|
||||
<span class="desk">{{ bread.name }}</span>
|
||||
<span class="mob">...</span>
|
||||
</ng-container>
|
||||
<ng-template #defLabel>
|
||||
} @else {
|
||||
<span>{{ bread.name }}</span>
|
||||
</ng-template>
|
||||
}
|
||||
</a>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
</ng-container>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<ng-container *ngIf="authService.privacypolicy$ | async as pP">
|
||||
<a class="custom-link" *ngIf="pP.customLink" href="{{ pP.customLink }}" mat-stroked-button target="_blank">
|
||||
{{ pP.customLinkText }}
|
||||
</a>
|
||||
@if (authService.privacypolicy$ | async; as pP) {
|
||||
@if (pP.customLink) {
|
||||
<a class="custom-link" href="{{ pP.customLink }}" mat-stroked-button target="_blank">
|
||||
{{ pP.customLinkText }}
|
||||
</a>
|
||||
}
|
||||
@if (pP.docsLink) {
|
||||
<a class="doc-link" href="{{ pP.docsLink }}" mat-stroked-button target="_blank">
|
||||
{{ 'MENU.DOCUMENTATION' | translate }}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
|
||||
<a class="doc-link" *ngIf="pP.docsLink" href="{{ pP.docsLink }}" mat-stroked-button target="_blank">
|
||||
{{ 'MENU.DOCUMENTATION' | translate }}
|
||||
</a>
|
||||
</ng-container>
|
||||
@if (!isOnMe) {
|
||||
<div class="system-rel">
|
||||
@if (!isOnInstance && (['iam.read$', 'iam.write$'] | hasRole | async)) {
|
||||
<a id="systembutton" [routerLink]="['/instance']" class="iam-settings" mat-stroked-button>
|
||||
<div class="cnsl-action-button">
|
||||
<span class="iam-label">{{ 'MENU.INSTANCE' | translate }}</span>
|
||||
<i class="las la-cog"></i>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
@if (isOnInstance && (['org.read'] | hasRole | async)) {
|
||||
<a id="orgbutton" [routerLink]="['/org']" class="org-settings" mat-stroked-button>
|
||||
<div class="cnsl-action-button">
|
||||
<span class="iam-label">{{ 'MENU.ORGANIZATION' | translate }}</span>
|
||||
<i class="las la-cog"></i>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="system-rel" *ngIf="!isOnMe">
|
||||
<a
|
||||
id="systembutton"
|
||||
*ngIf="!isOnInstance && (['iam.read$', 'iam.write$'] | hasRole | async)"
|
||||
[routerLink]="['/instance']"
|
||||
class="iam-settings"
|
||||
mat-stroked-button
|
||||
>
|
||||
<div class="cnsl-action-button">
|
||||
<span class="iam-label">{{ 'MENU.INSTANCE' | translate }}</span>
|
||||
<i class="las la-cog"></i>
|
||||
</div>
|
||||
</a>
|
||||
<a
|
||||
id="orgbutton"
|
||||
*ngIf="isOnInstance && (['org.read'] | hasRole | async)"
|
||||
[routerLink]="['/org']"
|
||||
class="org-settings"
|
||||
mat-stroked-button
|
||||
>
|
||||
<div class="cnsl-action-button">
|
||||
<span class="iam-label">{{ 'MENU.ORGANIZATION' | translate }}</span>
|
||||
<i class="las la-cog"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="user && user.id">
|
||||
@if (user && user.id) {
|
||||
<div class="account-card-wrapper">
|
||||
<button
|
||||
cdkOverlayOrigin
|
||||
@@ -244,15 +228,16 @@
|
||||
(backdropClick)="showAccount = false"
|
||||
(detach)="showAccount = false"
|
||||
>
|
||||
<cnsl-accounts-card
|
||||
class="a_card"
|
||||
*ngIf="showAccount"
|
||||
(closedCard)="showAccount = false"
|
||||
[user]="user"
|
||||
[iamuser]="['iam.write$'] | hasRole | async"
|
||||
>
|
||||
</cnsl-accounts-card>
|
||||
@if (showAccount) {
|
||||
<cnsl-accounts-card
|
||||
class="a_card"
|
||||
(closedCard)="showAccount = false"
|
||||
[user]="user"
|
||||
[iamuser]="['iam.write$'] | hasRole | async"
|
||||
>
|
||||
</cnsl-accounts-card>
|
||||
}
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
|
||||
@@ -13,16 +13,12 @@
|
||||
<span>{{ 'IDP.AVAILABILITY' | translate }}</span>
|
||||
</th>
|
||||
<td class="pointer availability" mat-cell *matCellDef="let idp">
|
||||
<i
|
||||
matTooltip="{{ 'IDP.AVAILABLE' | translate }}"
|
||||
*ngIf="isEnabled(idp) && idp.state === IDPState.IDP_STATE_ACTIVE"
|
||||
class="idp-available las la-check-circle"
|
||||
></i>
|
||||
<i
|
||||
matTooltip="{{ 'IDP.AVAILABLEBUTINACTIVE' | translate }}"
|
||||
*ngIf="isEnabled(idp) && idp.state === IDPState.IDP_STATE_INACTIVE"
|
||||
class="idp-not-available las la-check-circle"
|
||||
></i>
|
||||
@if (isEnabled(idp) && idp.state === IDPState.IDP_STATE_ACTIVE) {
|
||||
<i matTooltip="{{ 'IDP.AVAILABLE' | translate }}" class="idp-available las la-check-circle"></i>
|
||||
}
|
||||
@if (isEnabled(idp) && idp.state === IDPState.IDP_STATE_INACTIVE) {
|
||||
<i matTooltip="{{ 'IDP.AVAILABLEBUTINACTIVE' | translate }}" class="idp-not-available las la-check-circle"></i>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
@@ -36,59 +32,87 @@
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'IDP.TYPE' | translate }}</th>
|
||||
<td class="pointer" mat-cell *matCellDef="let idp">
|
||||
<div [ngSwitch]="idp.type">
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_AZURE_AD">
|
||||
<img class="idp-logo" src="./assets/images/idp/ms.svg" alt="azure ad" />
|
||||
Microsoft
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_GOOGLE">
|
||||
<img class="idp-logo" src="./assets/images/idp/google.png" alt="google" />
|
||||
Google
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_GITHUB">
|
||||
<img class="idp-logo dark" src="./assets/images/idp/github-dark.svg" alt="github" />
|
||||
<img class="idp-logo light" src="./assets/images/idp/github.svg" alt="github" />
|
||||
GitHub
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_OIDC">
|
||||
<mat-icon class="idp-icon" svgIcon="mdi_openid" alt="oidc" />
|
||||
Generic OIDC
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_OAUTH">
|
||||
<img class="idp-logo" src="./assets/images/idp/oauth.svg" alt="oauth" />
|
||||
Generic OAuth
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_JWT">
|
||||
<mat-icon class="idp-icon" svgIcon="mdi_jwt" alt="jwt" />
|
||||
Generic JWT
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_GITLAB">
|
||||
<img class="idp-logo" src="./assets/images/idp/gitlab.svg" alt="gitlab" />
|
||||
Gitlab
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_GITLAB_SELF_HOSTED">
|
||||
<img class="idp-logo" src="./assets/images/idp/gitlab.svg" alt="gitlab self hosted" />
|
||||
Gitlab Self Hosted
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_GITHUB_ES">
|
||||
<img class="idp-logo dark" src="./assets/images/idp/github-dark.svg" alt="github" />
|
||||
<img class="idp-logo light" src="./assets/images/idp/github.svg" alt="github" />
|
||||
GitHub Enterprise Server
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_LDAP">
|
||||
<i class="idp-icon las la-building"></i>
|
||||
Active Directory / LDAP
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_APPLE">
|
||||
<img class="idp-logo apple dark" src="./assets/images/idp/apple-dark.svg" alt="apple" />
|
||||
<img class="idp-logo apple light" src="./assets/images/idp/apple.svg" alt="apple" />
|
||||
Apple
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_SAML">
|
||||
<img class="idp-logo" src="./assets/images/idp/saml-icon.svg" alt="saml" />
|
||||
SAML
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchDefault>coming soon</div>
|
||||
<div>
|
||||
@switch (idp.type) {
|
||||
@case (ProviderType.PROVIDER_TYPE_AZURE_AD) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo" src="./assets/images/idp/ms.svg" alt="azure ad" />
|
||||
Microsoft
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_GOOGLE) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo" src="./assets/images/idp/google.png" alt="google" />
|
||||
Google
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_GITHUB) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo dark" src="./assets/images/idp/github-dark.svg" alt="github" />
|
||||
<img class="idp-logo light" src="./assets/images/idp/github.svg" alt="github" />
|
||||
GitHub
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_OIDC) {
|
||||
<div class="idp-table-provider-type">
|
||||
<mat-icon class="idp-icon" svgIcon="mdi_openid" alt="oidc" />
|
||||
Generic OIDC
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_OAUTH) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo" src="./assets/images/idp/oauth.svg" alt="oauth" />
|
||||
Generic OAuth
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_JWT) {
|
||||
<div class="idp-table-provider-type">
|
||||
<mat-icon class="idp-icon" svgIcon="mdi_jwt" alt="jwt" />
|
||||
Generic JWT
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_GITLAB) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo" src="./assets/images/idp/gitlab.svg" alt="gitlab" />
|
||||
Gitlab
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_GITLAB_SELF_HOSTED) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo" src="./assets/images/idp/gitlab.svg" alt="gitlab self hosted" />
|
||||
Gitlab Self Hosted
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_GITHUB_ES) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo dark" src="./assets/images/idp/github-dark.svg" alt="github" />
|
||||
<img class="idp-logo light" src="./assets/images/idp/github.svg" alt="github" />
|
||||
GitHub Enterprise Server
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_LDAP) {
|
||||
<div class="idp-table-provider-type">
|
||||
<i class="idp-icon las la-building"></i>
|
||||
Active Directory / LDAP
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_APPLE) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo apple dark" src="./assets/images/idp/apple-dark.svg" alt="apple" />
|
||||
<img class="idp-logo apple light" src="./assets/images/idp/apple.svg" alt="apple" />
|
||||
Apple
|
||||
</div>
|
||||
}
|
||||
@case (ProviderType.PROVIDER_TYPE_SAML) {
|
||||
<div class="idp-table-provider-type">
|
||||
<img class="idp-logo" src="./assets/images/idp/saml-icon.svg" alt="saml" />
|
||||
SAML
|
||||
</div>
|
||||
}
|
||||
@default {
|
||||
<div class="idp-table-provider-type">coming soon</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
@@ -132,71 +156,75 @@
|
||||
<th class="idp-table-actions" mat-header-cell *matHeaderCellDef></th>
|
||||
<td class="idp-table-actions" mat-cell *matCellDef="let idp">
|
||||
<cnsl-table-actions>
|
||||
<button
|
||||
actions
|
||||
*ngIf="!isEnabled(idp)"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.idp.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'org.idp.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
mat-icon-button
|
||||
matTooltip="{{ 'IDP.SETAVAILABLE' | translate }}"
|
||||
(click)="addIdp(idp); $event.stopPropagation()"
|
||||
>
|
||||
<i class="las la-check-circle"></i>
|
||||
</button>
|
||||
<button
|
||||
actions
|
||||
*ngIf="isEnabled(idp)"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.idp.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'org.idp.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
mat-icon-button
|
||||
matTooltip="{{ 'IDP.SETUNAVAILABLE' | translate }}"
|
||||
(click)="removeIdp(idp); $event.stopPropagation()"
|
||||
>
|
||||
<i class="las la-times-circle"></i>
|
||||
</button>
|
||||
<button
|
||||
actions
|
||||
*ngIf="
|
||||
(serviceType === PolicyComponentServiceType.MGMT && idp.owner === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
|
||||
(serviceType === PolicyComponentServiceType.ADMIN && idp.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM)
|
||||
"
|
||||
[disabled]="
|
||||
(serviceType === PolicyComponentServiceType.MGMT && idp?.providerType === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.idp.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'org.idp.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
(click)="deleteIdp(idp); $event.stopPropagation()"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
@if (!isEnabled(idp)) {
|
||||
<button
|
||||
actions
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.idp.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'org.idp.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
mat-icon-button
|
||||
matTooltip="{{ 'IDP.SETAVAILABLE' | translate }}"
|
||||
(click)="addIdp(idp); $event.stopPropagation()"
|
||||
>
|
||||
<i class="las la-check-circle"></i>
|
||||
</button>
|
||||
}
|
||||
@if (isEnabled(idp)) {
|
||||
<button
|
||||
actions
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.idp.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'org.idp.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
mat-icon-button
|
||||
matTooltip="{{ 'IDP.SETUNAVAILABLE' | translate }}"
|
||||
(click)="removeIdp(idp); $event.stopPropagation()"
|
||||
>
|
||||
<i class="las la-times-circle"></i>
|
||||
</button>
|
||||
}
|
||||
@if (
|
||||
(serviceType === PolicyComponentServiceType.MGMT && idp.owner === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
|
||||
(serviceType === PolicyComponentServiceType.ADMIN && idp.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM)
|
||||
) {
|
||||
<button
|
||||
actions
|
||||
[disabled]="
|
||||
(serviceType === PolicyComponentServiceType.MGMT &&
|
||||
idp?.providerType === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.idp.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'org.idp.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
(click)="deleteIdp(idp); $event.stopPropagation()"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
}
|
||||
</cnsl-table-actions>
|
||||
</td>
|
||||
</ng-container>
|
||||
@@ -206,10 +234,12 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div *ngIf="(loading$ | async) === false && !dataSource?.data?.length" class="no-content-row">
|
||||
<i class="las la-exclamation"></i>
|
||||
<span>{{ 'IDP.EMPTY' | translate }}</span>
|
||||
</div>
|
||||
@if ((loading$ | async) === false && !dataSource?.data?.length) {
|
||||
<div class="no-content-row">
|
||||
<i class="las la-exclamation"></i>
|
||||
<span>{{ 'IDP.EMPTY' | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<cnsl-paginator
|
||||
#paginator
|
||||
|
||||
@@ -1,32 +1,19 @@
|
||||
<span class="title" mat-dialog-title>{{ data.titleKey | translate: data.titleParam }}</span>
|
||||
<span class="title" mat-dialog-title>{{ data.titleKey | translate }}</span>
|
||||
|
||||
<div mat-dialog-content>
|
||||
<div class="icon-wrapper" *ngIf="data.icon">
|
||||
<i class="icon {{ data.icon }}"></i>
|
||||
</div>
|
||||
<p class="desc cnsl-secondary-text">{{ data.descriptionKey | translate: data.descriptionParam }}</p>
|
||||
|
||||
<cnsl-info-section *ngIf="data.infoSectionKey" [type]="InfoSectionType.INFO">{{
|
||||
data.warnSectionKey | translate
|
||||
}}</cnsl-info-section>
|
||||
|
||||
<p *ngIf="data.hintKey" class="desc cnsl-secondary-text">{{ data.hintKey | translate: { value: data.confirmation } }}</p>
|
||||
|
||||
<cnsl-form-field *ngIf="data.confirmation && data.confirmationKey" class="formfield">
|
||||
<cnsl-label>{{ data.confirmationKey | translate: { value: data.confirmation } }}</cnsl-label>
|
||||
<input cnslInput [(ngModel)]="confirm" data-e2e="confirm-dialog-input" />
|
||||
</cnsl-form-field>
|
||||
<p class="desc cnsl-secondary-text">{{ data.descriptionKey | translate }}</p>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions class="action">
|
||||
<button *ngIf="data.cancelKey" mat-stroked-button (click)="closeDialog()">
|
||||
<button mat-stroked-button (click)="dialogRef.close(false)">
|
||||
{{ data.cancelKey | translate }}
|
||||
</button>
|
||||
<span class="fill-space"></span>
|
||||
<button
|
||||
color="primary"
|
||||
[disabled]="data.confirmation && confirm !== data.confirmation"
|
||||
mat-raised-button
|
||||
class="ok-button"
|
||||
(click)="closeDialogWithSuccess()"
|
||||
(click)="dialogRef.close(true)"
|
||||
data-e2e="confirm-dialog-button"
|
||||
>
|
||||
{{ data.confirmKey | translate }}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { InfoDialogComponent } from './info-dialog.component';
|
||||
|
||||
describe('InfoDialogComponent', () => {
|
||||
let component: InfoDialogComponent;
|
||||
let fixture: ComponentFixture<InfoDialogComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [InfoDialogComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(InfoDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,27 +1,28 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||
|
||||
import { InfoSectionType } from '../info-section/info-section.component';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
|
||||
export type InfoDialogData = {
|
||||
confirmKey: string;
|
||||
cancelKey: string;
|
||||
titleKey: string;
|
||||
descriptionKey: string;
|
||||
};
|
||||
|
||||
export type InfoDialogResult = boolean;
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-info-dialog',
|
||||
templateUrl: './info-dialog.component.html',
|
||||
styleUrls: ['./info-dialog.component.scss'],
|
||||
standalone: false,
|
||||
imports: [TranslateModule, MatDialogModule, MatButtonModule],
|
||||
})
|
||||
export class InfoDialogComponent {
|
||||
public confirm: string = '';
|
||||
InfoSectionType: any = InfoSectionType;
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<InfoDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
) {}
|
||||
protected readonly InfoSectionType = InfoSectionType;
|
||||
|
||||
public closeDialog(): void {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
public closeDialogWithSuccess(): void {
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
protected readonly dialogRef = inject<MatDialogRef<InfoDialogComponent>>(MatDialogRef);
|
||||
protected readonly data = inject<InfoDialogData>(MAT_DIALOG_DATA);
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { InfoSectionModule } from '../info-section/info-section.module';
|
||||
import { InputModule } from '../input/input.module';
|
||||
import { InfoDialogComponent } from './info-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [InfoDialogComponent],
|
||||
imports: [CommonModule, FormsModule, MatDialogModule, TranslateModule, InfoSectionModule, MatButtonModule, InputModule],
|
||||
})
|
||||
export class InfoDialogModule {}
|
||||
@@ -1,24 +1,27 @@
|
||||
<div class="context_intro_overlay">
|
||||
<div class="overlay-info-row">
|
||||
<span class="info"
|
||||
>INFO <span *ngIf="data.number && data.count">{{ data.number }}/{{ data.count }}</span></span
|
||||
>
|
||||
>INFO
|
||||
@if (data.number && data.count) {
|
||||
<span>{{ data.number }}/{{ data.count }}</span>
|
||||
}
|
||||
</span>
|
||||
<button mat-icon-button (click)="workflowService.reset()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<p>{{ data.i18nText | translate }}</p>
|
||||
<div class="overlay-actions">
|
||||
<button
|
||||
(click)="workflowService.nextStep()"
|
||||
*ngIf="workflowService.nextPossible && !workflowService.isLast"
|
||||
mat-stroked-button
|
||||
>
|
||||
{{ 'ACTIONS.NEXT' | translate }}
|
||||
</button>
|
||||
@if (workflowService.nextPossible && !workflowService.isLast) {
|
||||
<button (click)="workflowService.nextStep()" mat-stroked-button>
|
||||
{{ 'ACTIONS.NEXT' | translate }}
|
||||
</button>
|
||||
}
|
||||
|
||||
<button *ngIf="workflowService.isLast" (click)="workflowService.nextStep()" color="primary" mat-raised-button>
|
||||
{{ 'ACTIONS.FINISHED' | translate }}
|
||||
</button>
|
||||
@if (workflowService.isLast) {
|
||||
<button (click)="workflowService.nextStep()" color="primary" mat-raised-button>
|
||||
{{ 'ACTIONS.FINISHED' | translate }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,308 +1,363 @@
|
||||
<div class="info-row" *ngIf="user">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'USER.PAGES.STATE' | translate }}</p>
|
||||
<p
|
||||
*ngIf="user?.state"
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: user.state === UserState.USER_STATE_ACTIVE,
|
||||
inactive: user.state === UserState.USER_STATE_INACTIVE,
|
||||
}"
|
||||
>
|
||||
{{ (isV2(user) ? 'USER.STATEV2.' : 'USER.STATE.') + user.state | translate }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'USER.ID' | translate }}</p>
|
||||
<p *ngIf="userId" class="info-row-desc">{{ userId }}</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'USER.DETAILS.DATECREATED' | translate }}</p>
|
||||
<p *ngIf="creationDate" class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'USER.DETAILS.DATECHANGED' | translate }}</p>
|
||||
<p *ngIf="changeDate" class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper width">
|
||||
<p class="info-row-title">{{ 'USER.PAGES.LOGINMETHODS' | translate }}</p>
|
||||
<div class="copy-row" *ngFor="let login of loginMethods">
|
||||
<button
|
||||
[disabled]="copied === login"
|
||||
[matTooltip]="(copied !== login ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="login"
|
||||
(copiedValue)="copied = $event"
|
||||
data-e2e="copy-loginname"
|
||||
>
|
||||
{{ login }}
|
||||
</button>
|
||||
@if (user) {
|
||||
<div class="info-row">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'USER.PAGES.STATE' | translate }}</p>
|
||||
@if (user?.state) {
|
||||
<p
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: user.state === UserState.USER_STATE_ACTIVE,
|
||||
inactive: user.state === UserState.USER_STATE_INACTIVE,
|
||||
}"
|
||||
>
|
||||
{{ (isV2(user) ? 'USER.STATEV2.' : 'USER.STATE.') + user.state | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'USER.ID' | translate }}</p>
|
||||
@if (userId) {
|
||||
<p class="info-row-desc">{{ userId }}</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'USER.DETAILS.DATECREATED' | translate }}</p>
|
||||
@if (creationDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'USER.DETAILS.DATECHANGED' | translate }}</p>
|
||||
@if (changeDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper width">
|
||||
<p class="info-row-title">{{ 'USER.PAGES.LOGINMETHODS' | translate }}</p>
|
||||
@for (login of loginMethods; track login) {
|
||||
<div class="copy-row">
|
||||
<button
|
||||
[disabled]="copied === login"
|
||||
[matTooltip]="(copied !== login ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="login"
|
||||
(copiedValue)="copied = $event"
|
||||
data-e2e="copy-loginname"
|
||||
>
|
||||
{{ login }}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="info-row" *ngIf="instance">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'IAM.PAGES.STATE' | translate }}</p>
|
||||
<p
|
||||
*ngIf="instance?.state"
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: instance.state === State.STATE_RUNNING,
|
||||
inactive: instance.state === State.STATE_STOPPED || instance.state === State.STATE_STOPPING,
|
||||
}"
|
||||
>
|
||||
{{ 'IAM.STATE.' + instance.state | translate }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'INSTANCEID' | translate }}</p>
|
||||
<p *ngIf="instance?.id" class="info-row-desc">{{ instance.id }}</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'NAME' | translate }}</p>
|
||||
<p *ngIf="instance?.name" class="info-row-desc">{{ instance.name }}</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'VERSION' | translate }}</p>
|
||||
<p *ngIf="instance?.version" class="info-row-desc">{{ instance.version }}</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper width">
|
||||
<p class="info-row-title">{{ 'IAM.PAGES.DOMAINLIST' | translate }}</p>
|
||||
<div class="copy-row" *ngFor="let domain of instance?.domainsList">
|
||||
<button
|
||||
[disabled]="copied === domain.domain"
|
||||
[matTooltip]="(copied !== domain.domain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="domain.domain"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
{{ domain.domain }}
|
||||
</button>
|
||||
@if (instance) {
|
||||
<div class="info-row">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'IAM.PAGES.STATE' | translate }}</p>
|
||||
@if (instance?.state) {
|
||||
<p
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: instance.state === State.STATE_RUNNING,
|
||||
inactive: instance.state === State.STATE_STOPPED || instance.state === State.STATE_STOPPING,
|
||||
}"
|
||||
>
|
||||
{{ 'IAM.STATE.' + instance.state | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'INSTANCEID' | translate }}</p>
|
||||
@if (instance?.id) {
|
||||
<p class="info-row-desc">{{ instance.id }}</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'NAME' | translate }}</p>
|
||||
@if (instance?.name) {
|
||||
<p class="info-row-desc">{{ instance.name }}</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'VERSION' | translate }}</p>
|
||||
@if (instance?.version) {
|
||||
<p class="info-row-desc">{{ instance.version }}</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper width">
|
||||
<p class="info-row-title">{{ 'IAM.PAGES.DOMAINLIST' | translate }}</p>
|
||||
@for (domain of instance?.domainsList; track domain) {
|
||||
<div class="copy-row">
|
||||
<button
|
||||
[disabled]="copied === domain.domain"
|
||||
[matTooltip]="(copied !== domain.domain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="domain.domain"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
{{ domain.domain }}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p>
|
||||
@if (instance?.details?.creationDate; as creationDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p>
|
||||
@if (instance?.details?.changeDate; as changeDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p>
|
||||
<p *ngIf="instance?.details?.creationDate as creationDate" class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p>
|
||||
<p *ngIf="instance?.details?.changeDate as changeDate" class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-row" *ngIf="org">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.STATE' | translate }}</p>
|
||||
<p
|
||||
*ngIf="org?.state"
|
||||
class="state"
|
||||
[ngClass]="{ active: org.state === OrgState.ORG_STATE_ACTIVE, inactive: org.state === OrgState.ORG_STATE_INACTIVE }"
|
||||
>
|
||||
{{ 'ORG.STATE.' + org.state | translate }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.ID' | translate }}</p>
|
||||
<p *ngIf="org?.id" class="info-row-desc">{{ org.id }}</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper width">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.PRIMARYDOMAIN' | translate }}</p>
|
||||
<div class="copy-row" *ngIf="org.primaryDomain">
|
||||
<button
|
||||
[disabled]="copied === org.primaryDomain"
|
||||
[matTooltip]="(copied !== org.primaryDomain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="org.primaryDomain"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
{{ org.primaryDomain }}
|
||||
</button>
|
||||
@if (org) {
|
||||
<div class="info-row">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.STATE' | translate }}</p>
|
||||
@if (org?.state) {
|
||||
<p
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: org.state === OrgState.ORG_STATE_ACTIVE,
|
||||
inactive: org.state === OrgState.ORG_STATE_INACTIVE,
|
||||
}"
|
||||
>
|
||||
{{ 'ORG.STATE.' + org.state | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.ID' | translate }}</p>
|
||||
@if (org?.id) {
|
||||
<p class="info-row-desc">{{ org.id }}</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper width">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.PRIMARYDOMAIN' | translate }}</p>
|
||||
@if (org.primaryDomain) {
|
||||
<div class="copy-row">
|
||||
<button
|
||||
[disabled]="copied === org.primaryDomain"
|
||||
[matTooltip]="(copied !== org.primaryDomain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="org.primaryDomain"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
{{ org.primaryDomain }}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p>
|
||||
@if (org?.details?.creationDate; as creationDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p>
|
||||
@if (org?.details?.changeDate; as changeDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p>
|
||||
<p *ngIf="org?.details?.creationDate as creationDate" class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
@if (project) {
|
||||
<div class="info-row">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p>
|
||||
@if (project?.state) {
|
||||
<p
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: project.state === ProjectState.PROJECT_STATE_ACTIVE,
|
||||
inactive: project.state === ProjectState.PROJECT_STATE_INACTIVE,
|
||||
}"
|
||||
>
|
||||
{{ 'PROJECT.STATE.' + project.state | translate }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.ID' | translate }}</p>
|
||||
@if (project?.id) {
|
||||
<p class="info-row-desc">{{ project.id }}</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p>
|
||||
@if (project?.details?.creationDate; as creationDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p>
|
||||
@if (project?.details?.changeDate; as changeDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p>
|
||||
<p *ngIf="org?.details?.changeDate as changeDate" class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
@if (grantedProject) {
|
||||
<div class="info-row">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p>
|
||||
@if (grantedProject?.state) {
|
||||
<p
|
||||
class="state"
|
||||
[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 class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.ID' | translate }}</p>
|
||||
@if (grantedProject?.projectId) {
|
||||
<p class="info-row-desc">{{ grantedProject.projectId }}</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.GRANT.GRANTID' | translate }}</p>
|
||||
@if (grantedProject?.grantId) {
|
||||
<p class="info-row-desc">{{ grantedProject.grantId }}</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p>
|
||||
@if (grantedProject?.details?.creationDate; as creationDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p>
|
||||
@if (grantedProject?.details?.changeDate; as changeDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="info-row" *ngIf="project">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p>
|
||||
<p
|
||||
*ngIf="project?.state"
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: project.state === ProjectState.PROJECT_STATE_ACTIVE,
|
||||
inactive: project.state === ProjectState.PROJECT_STATE_INACTIVE,
|
||||
}"
|
||||
>
|
||||
{{ 'PROJECT.STATE.' + project.state | translate }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.ID' | translate }}</p>
|
||||
<p *ngIf="project?.id" class="info-row-desc">{{ project.id }}</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p>
|
||||
<p *ngIf="project?.details?.creationDate as creationDate" class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p>
|
||||
<p *ngIf="project?.details?.changeDate as changeDate" class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-row" *ngIf="grantedProject">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p>
|
||||
<p
|
||||
*ngIf="grantedProject?.state"
|
||||
class="state"
|
||||
[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 class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.ID' | translate }}</p>
|
||||
<p *ngIf="grantedProject?.projectId" class="info-row-desc">{{ grantedProject.projectId }}</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.GRANT.GRANTID' | translate }}</p>
|
||||
<p *ngIf="grantedProject?.grantId" class="info-row-desc">{{ grantedProject.grantId }}</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p>
|
||||
<p *ngIf="grantedProject?.details?.creationDate as creationDate" class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p>
|
||||
<p *ngIf="grantedProject?.details?.changeDate as changeDate" class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="app">
|
||||
@if (app) {
|
||||
<div class="info-row">
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'APP.PAGES.STATE' | translate }}</p>
|
||||
<p
|
||||
*ngIf="app?.state"
|
||||
class="state"
|
||||
[ngClass]="{ active: app.state === AppState.APP_STATE_ACTIVE, inactive: app.state === AppState.APP_STATE_INACTIVE }"
|
||||
>
|
||||
{{ 'APP.PAGES.DETAIL.STATE.' + app.state | translate }}
|
||||
</p>
|
||||
@if (app?.state) {
|
||||
<p
|
||||
class="state"
|
||||
[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 class="info-wrapper" *ngIf="app?.apiConfig?.authMethodType as authMethodType">
|
||||
<p class="info-row-title">{{ 'APP.AUTHMETHOD' | translate }}</p>
|
||||
<p class="info-row-desc">
|
||||
{{ 'APP.API.AUTHMETHOD.' + authMethodType | translate }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper" *ngIf="app?.oidcConfig?.authMethodType as authMethodType">
|
||||
<p class="info-row-title">{{ 'APP.AUTHMETHOD' | translate }}</p>
|
||||
<p class="info-row-desc">
|
||||
{{ 'APP.OIDC.AUTHMETHOD.' + authMethodType | translate }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@if (app?.apiConfig?.authMethodType; as authMethodType) {
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'APP.AUTHMETHOD' | translate }}</p>
|
||||
<p class="info-row-desc">
|
||||
{{ 'APP.API.AUTHMETHOD.' + authMethodType | translate }}
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
@if (app?.oidcConfig?.authMethodType; as authMethodType) {
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'APP.AUTHMETHOD' | translate }}</p>
|
||||
<p class="info-row-desc">
|
||||
{{ 'APP.OIDC.AUTHMETHOD.' + authMethodType | translate }}
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'APP.PAGES.ID' | translate }}</p>
|
||||
<p *ngIf="app?.id" class="info-row-desc">{{ app.id }}</p>
|
||||
@if (app?.id) {
|
||||
<p class="info-row-desc">{{ app.id }}</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'APP.PAGES.DATECREATED' | translate }}</p>
|
||||
<p *ngIf="app?.details?.creationDate as creationDate" class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
@if (app?.details?.creationDate; as creationDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'APP.PAGES.DATECHANGED' | translate }}</p>
|
||||
<p *ngIf="app?.details?.changeDate as changeDate" class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
@if (app?.details?.changeDate; as changeDate) {
|
||||
<p class="info-row-desc">
|
||||
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="info-wrapper" *ngIf="app">
|
||||
<p class="info-row-title">{{ 'APP.OIDC.INFO.CLIENTID' | translate }}</p>
|
||||
<div class="copy-row" *ngIf="app.oidcConfig?.clientId">
|
||||
<button
|
||||
*ngIf="app.oidcConfig?.clientId as clientId"
|
||||
[disabled]="copied === clientId"
|
||||
[matTooltip]="(copied !== clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="clientId"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
{{ clientId }}
|
||||
</button>
|
||||
@if (app) {
|
||||
<div class="info-wrapper">
|
||||
<p class="info-row-title">{{ 'APP.OIDC.INFO.CLIENTID' | translate }}</p>
|
||||
@if (app.oidcConfig?.clientId) {
|
||||
<div class="copy-row">
|
||||
@if (app.oidcConfig?.clientId; as clientId) {
|
||||
<button
|
||||
[disabled]="copied === clientId"
|
||||
[matTooltip]="(copied !== clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="clientId"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
{{ clientId }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if (app.apiConfig?.clientId) {
|
||||
<div class="copy-row">
|
||||
@if (app.apiConfig?.clientId; as clientId) {
|
||||
<button
|
||||
[disabled]="copied === clientId"
|
||||
[matTooltip]="(copied !== clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="clientId"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
{{ clientId }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="copy-row" *ngIf="app.apiConfig?.clientId">
|
||||
<button
|
||||
*ngIf="app.apiConfig?.clientId as clientId"
|
||||
[disabled]="copied === clientId"
|
||||
[matTooltip]="(copied !== clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="clientId"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
{{ clientId }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
@@ -7,9 +7,15 @@
|
||||
fit: fitWidth,
|
||||
}"
|
||||
>
|
||||
<i *ngIf="type === infoSectionType.INFO" class="icon las la-info"></i>
|
||||
<i *ngIf="type === infoSectionType.WARN" class="icon las la-exclamation"></i>
|
||||
<i *ngIf="type === infoSectionType.ALERT" class="icon las la-exclamation"></i>
|
||||
@if (type === infoSectionType.INFO) {
|
||||
<i class="icon las la-info"></i>
|
||||
}
|
||||
@if (type === infoSectionType.WARN) {
|
||||
<i class="icon las la-exclamation"></i>
|
||||
}
|
||||
@if (type === infoSectionType.ALERT) {
|
||||
<i class="icon las la-exclamation"></i>
|
||||
}
|
||||
|
||||
<div class="info-section-content">
|
||||
<ng-content></ng-content>
|
||||
|
||||
@@ -1,36 +1,42 @@
|
||||
<div class="keyboard-shortcuts">
|
||||
<h1 class="title" mat-dialog-title>{{ 'KEYBOARDSHORTCUTS.TITLE' | translate }}</h1>
|
||||
<div mat-dialog-content>
|
||||
<div *ngIf="isNotOnSystem" class="keyboard-shortcuts-group">
|
||||
<h2>{{ 'KEYBOARDSHORTCUTS.UNDERORGCONTEXT' | translate }}</h2>
|
||||
<div class="keyboard-shortcuts-wrapper">
|
||||
<div class="keyboard-shortcut" *ngFor="let shortcut of orgShortcuts">
|
||||
<span class="keyboard-shortcut-name cnsl-secondary-text" [innerHTML]="shortcut.i18nKey | translate"></span>
|
||||
<span class="fill-space"></span>
|
||||
<template
|
||||
*ngFor="let key of shortcut.keyboardKeys; index as i"
|
||||
[ngTemplateOutlet]="actionkey"
|
||||
[ngTemplateOutletContext]="{ key: key, last: i === shortcut.keyboardKeys.length - 1 }"
|
||||
></template>
|
||||
@if (isNotOnSystem) {
|
||||
<div class="keyboard-shortcuts-group">
|
||||
<h2>{{ 'KEYBOARDSHORTCUTS.UNDERORGCONTEXT' | translate }}</h2>
|
||||
<div class="keyboard-shortcuts-wrapper">
|
||||
@for (shortcut of orgShortcuts; track shortcut) {
|
||||
<div class="keyboard-shortcut">
|
||||
<span class="keyboard-shortcut-name cnsl-secondary-text" [innerHTML]="shortcut.i18nKey | translate"></span>
|
||||
<span class="fill-space"></span>
|
||||
@for (key of shortcut.keyboardKeys; track key; let i = $index) {
|
||||
<template
|
||||
[ngTemplateOutlet]="actionkey"
|
||||
[ngTemplateOutletContext]="{ key: key, last: i === shortcut.keyboardKeys.length - 1 }"
|
||||
></template>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="keyboard-shortcuts-group">
|
||||
<h2>{{ 'KEYBOARDSHORTCUTS.SIDEWIDE' | translate }}</h2>
|
||||
<div class="keyboard-shortcuts-wrapper">
|
||||
<ng-container *ngFor="let shortcut of shortcuts">
|
||||
@for (shortcut of shortcuts; track shortcut) {
|
||||
<ng-template cnslHasRole [hasRole]="shortcut.permissions">
|
||||
<div class="keyboard-shortcut">
|
||||
<span class="keyboard-shortcut-name cnsl-secondary-text" [innerHTML]="shortcut.i18nKey | translate"></span>
|
||||
<span class="fill-space"></span>
|
||||
<template
|
||||
*ngFor="let key of shortcut.keyboardKeys; index as i"
|
||||
[ngTemplateOutlet]="actionkey"
|
||||
[ngTemplateOutletContext]="{ key: key, last: i === shortcut.keyboardKeys.length - 1 }"
|
||||
></template>
|
||||
@for (key of shortcut.keyboardKeys; track key; let i = $index) {
|
||||
<template
|
||||
[ngTemplateOutlet]="actionkey"
|
||||
[ngTemplateOutletContext]="{ key: key, last: i === shortcut.keyboardKeys.length - 1 }"
|
||||
></template>
|
||||
}
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,162 +1,157 @@
|
||||
<cnsl-refresh-table
|
||||
*ngIf="dataSource"
|
||||
(refreshed)="changePage()"
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
[selection]="selection"
|
||||
[loading]="dataSource.loading$ | async"
|
||||
>
|
||||
<ng-container actions *ngIf="selection.hasValue()">
|
||||
<ng-content select="[selectactions]"></ng-content>
|
||||
</ng-container>
|
||||
|
||||
<div actions *ngIf="!selection.hasValue()">
|
||||
<ng-content select="[writeactions]"></ng-content>
|
||||
</div>
|
||||
|
||||
<div class="table-wrapper">
|
||||
<table
|
||||
*ngIf="displayedColumns$ | async as displayedColumns"
|
||||
mat-table
|
||||
class="table"
|
||||
aria-label="Elements"
|
||||
[dataSource]="dataSource"
|
||||
>
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
color="primary"
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
color="primary"
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
>
|
||||
<cnsl-avatar
|
||||
*ngIf="row?.userType === UserType.TYPE_HUMAN; else cog"
|
||||
class="avatar"
|
||||
[name]="row.displayName"
|
||||
[avatarUrl]="row.avatarUrl || ''"
|
||||
[avatarUrl]="row.avatarUrl || ''"
|
||||
[forColor]="row?.preferredLoginName"
|
||||
[size]="32"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
<ng-template #cog>
|
||||
<cnsl-avatar [forColor]="row.preferredLoginName" [isMachine]="true">
|
||||
<i class="las la-robot"></i>
|
||||
</cnsl-avatar>
|
||||
</ng-template>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="userId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.MEMBER.USERID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
{{ member.userId }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="displayName">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.MEMBER.DISPLAYNAME' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
{{ member.displayName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="loginname">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.MEMBER.LOGINNAME' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
{{ member.preferredLoginName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="email">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.MEMBER.EMAIL' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
{{ member.email }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let member" class="member-action-tr">
|
||||
<cnsl-table-actions [hasActions]="true">
|
||||
<button
|
||||
actions
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
color="warn"
|
||||
(click)="$event.stopPropagation(); triggerDeleteMember(member)"
|
||||
mat-icon-button
|
||||
[disabled]="(canDelete$ | async) === false"
|
||||
data-e2e="remove-member-button"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
|
||||
<button menuActions mat-menu-item [routerLink]="['/users', member.userId]">
|
||||
{{ 'ACTIONS.TABLE.SHOWUSER' | translate: { value: member.displayName } }}
|
||||
</button>
|
||||
</cnsl-table-actions>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="roles">
|
||||
<th mat-header-cell *matHeaderCellDef class="role-row">{{ 'ROLESLABEL' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member" class="role-row">
|
||||
<mat-chip-listbox class="cnsl-chip-list" aria-label="role selection">
|
||||
<mat-chip-option
|
||||
[selectable]="false"
|
||||
class="cnsl-chip"
|
||||
*ngFor="let role of member.rolesList"
|
||||
[removable]="canWrite$ | async"
|
||||
(removed)="removeRole(member, role)"
|
||||
data-e2e="role"
|
||||
>
|
||||
<div class="cnsl-chip-content">
|
||||
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
|
||||
<span>{{ role | roletransform }}</span>
|
||||
<button *ngIf="canWrite$ | async" matChipRemove data-e2e="remove-role-button">
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</mat-chip-option>
|
||||
</mat-chip-listbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr
|
||||
class="highlight"
|
||||
[ngClass]="{ pointer: canWrite$ | async }"
|
||||
(click)="addRole(member)"
|
||||
mat-row
|
||||
*matRowDef="let member; columns: displayedColumns"
|
||||
></tr>
|
||||
</table>
|
||||
</div>
|
||||
<cnsl-paginator
|
||||
*ngIf="dataSource"
|
||||
class="paginator"
|
||||
#paginator
|
||||
@if (dataSource) {
|
||||
<cnsl-refresh-table
|
||||
(refreshed)="changePage()"
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
[pageSize]="INITIALPAGESIZE"
|
||||
[length]="dataSource.totalResult"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]"
|
||||
(page)="changePage($event)"
|
||||
[selection]="selection"
|
||||
[loading]="dataSource.loading$ | async"
|
||||
>
|
||||
</cnsl-paginator>
|
||||
</cnsl-refresh-table>
|
||||
@if (selection.hasValue()) {
|
||||
<ng-container actions>
|
||||
<ng-content select="[selectactions]"></ng-content>
|
||||
</ng-container>
|
||||
}
|
||||
@if (!selection.hasValue()) {
|
||||
<div actions>
|
||||
<ng-content select="[writeactions]"></ng-content>
|
||||
</div>
|
||||
}
|
||||
<div class="table-wrapper">
|
||||
@if (displayedColumns$ | async; as displayedColumns) {
|
||||
<table mat-table class="table" aria-label="Elements" [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
color="primary"
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
color="primary"
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
>
|
||||
@if (row?.userType === UserType.TYPE_HUMAN) {
|
||||
<cnsl-avatar
|
||||
class="avatar"
|
||||
[name]="row.displayName"
|
||||
[avatarUrl]="row.avatarUrl || ''"
|
||||
[avatarUrl]="row.avatarUrl || ''"
|
||||
[forColor]="row?.preferredLoginName"
|
||||
[size]="32"
|
||||
>
|
||||
</cnsl-avatar>
|
||||
} @else {
|
||||
<cnsl-avatar [forColor]="row.preferredLoginName" [isMachine]="true">
|
||||
<i class="las la-robot"></i>
|
||||
</cnsl-avatar>
|
||||
}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="userId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.MEMBER.USERID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
{{ member.userId }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="displayName">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.MEMBER.DISPLAYNAME' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
{{ member.displayName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="loginname">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.MEMBER.LOGINNAME' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
{{ member.preferredLoginName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="email">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.MEMBER.EMAIL' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
{{ member.email }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let member" class="member-action-tr">
|
||||
<cnsl-table-actions [hasActions]="true">
|
||||
<button
|
||||
actions
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
color="warn"
|
||||
(click)="$event.stopPropagation(); triggerDeleteMember(member)"
|
||||
mat-icon-button
|
||||
[disabled]="(canDelete$ | async) === false"
|
||||
data-e2e="remove-member-button"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
<button menuActions mat-menu-item [routerLink]="['/users', member.userId]">
|
||||
{{ 'ACTIONS.TABLE.SHOWUSER' | translate: { value: member.displayName } }}
|
||||
</button>
|
||||
</cnsl-table-actions>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="roles">
|
||||
<th mat-header-cell *matHeaderCellDef class="role-row">{{ 'ROLESLABEL' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let member" class="role-row">
|
||||
<mat-chip-listbox class="cnsl-chip-list" aria-label="role selection">
|
||||
@for (role of member.rolesList; track role) {
|
||||
<mat-chip-option
|
||||
[selectable]="false"
|
||||
class="cnsl-chip"
|
||||
[removable]="canWrite$ | async"
|
||||
(removed)="removeRole(member, role)"
|
||||
data-e2e="role"
|
||||
>
|
||||
<div class="cnsl-chip-content">
|
||||
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
|
||||
<span>{{ role | roletransform }}</span>
|
||||
@if (canWrite$ | async) {
|
||||
<button matChipRemove data-e2e="remove-role-button">
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</mat-chip-option>
|
||||
}
|
||||
</mat-chip-listbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr
|
||||
class="highlight"
|
||||
[ngClass]="{ pointer: canWrite$ | async }"
|
||||
(click)="addRole(member)"
|
||||
mat-row
|
||||
*matRowDef="let member; columns: displayedColumns"
|
||||
></tr>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
@if (dataSource) {
|
||||
<cnsl-paginator
|
||||
class="paginator"
|
||||
#paginator
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
[pageSize]="INITIALPAGESIZE"
|
||||
[length]="dataSource.totalResult"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]"
|
||||
(page)="changePage($event)"
|
||||
>
|
||||
</cnsl-paginator>
|
||||
}
|
||||
</cnsl-refresh-table>
|
||||
}
|
||||
|
||||
@@ -1,115 +1,115 @@
|
||||
<cnsl-refresh-table
|
||||
*ngIf="dataSource"
|
||||
(refreshed)="changePage()"
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
[hideRefresh]="true"
|
||||
[selection]="selection"
|
||||
[loading]="dataSource.loading$ | async"
|
||||
>
|
||||
<ng-container actions *ngIf="selection.hasValue()">
|
||||
<ng-content select="[selectactions]"></ng-content>
|
||||
</ng-container>
|
||||
|
||||
<div actions>
|
||||
<ng-content select="[writeactions]"></ng-content>
|
||||
</div>
|
||||
|
||||
<div class="table-wrapper">
|
||||
<table mat-table class="table" aria-label="Elements" [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="false"
|
||||
color="primary"
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="false"
|
||||
color="primary"
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="displayName">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'USER.MEMBERSHIPS.DISPLAYNAME' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let membership">
|
||||
{{ membership.displayName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'USER.MEMBERSHIPS.TYPE' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let membership">
|
||||
<span class="state">{{ getType(membership) }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="orgId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'USER.MEMBERSHIPS.ORGID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let membership">
|
||||
{{ membership.orgId }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="rolesList">
|
||||
<th mat-header-cell *matHeaderCellDef class="role-row">{{ 'ROLESLABEL' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let membership">
|
||||
<div class="membership-line">
|
||||
<mat-chip-listbox class="cnsl-chip-list" aria-label="role selection">
|
||||
<mat-chip-option
|
||||
[selectable]="false"
|
||||
class="cnsl-chip"
|
||||
*ngFor="let role of membership.rolesList"
|
||||
[removable]="!!userId"
|
||||
(removed)="removeRole(membership, role)"
|
||||
>
|
||||
<div class="cnsl-chip-content">
|
||||
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
|
||||
<span>{{ role | roletransform }}</span>
|
||||
<button *ngIf="!!userId" matChipRemove>
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</mat-chip-option>
|
||||
</mat-chip-listbox>
|
||||
<button
|
||||
matTooltip="{{ 'ACTIONS.EDIT' | translate }}"
|
||||
(click)="goto(membership)"
|
||||
mat-icon-button
|
||||
class="goto-btn"
|
||||
>
|
||||
<mat-icon>navigate_next</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
<cnsl-paginator
|
||||
*ngIf="dataSource"
|
||||
class="paginator"
|
||||
#paginator
|
||||
@if (dataSource) {
|
||||
<cnsl-refresh-table
|
||||
(refreshed)="changePage()"
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
[pageSize]="INITIALPAGESIZE"
|
||||
[length]="dataSource.totalResult"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]"
|
||||
(page)="changePage($event)"
|
||||
[hideRefresh]="true"
|
||||
[selection]="selection"
|
||||
[loading]="dataSource.loading$ | async"
|
||||
>
|
||||
</cnsl-paginator>
|
||||
</cnsl-refresh-table>
|
||||
@if (selection.hasValue()) {
|
||||
<ng-container actions>
|
||||
<ng-content select="[selectactions]"></ng-content>
|
||||
</ng-container>
|
||||
}
|
||||
<div actions>
|
||||
<ng-content select="[writeactions]"></ng-content>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<table mat-table class="table" aria-label="Elements" [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="false"
|
||||
color="primary"
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="false"
|
||||
color="primary"
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="displayName">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'USER.MEMBERSHIPS.DISPLAYNAME' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let membership">
|
||||
{{ membership.displayName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'USER.MEMBERSHIPS.TYPE' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let membership">
|
||||
<span class="state">{{ getType(membership) }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="orgId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'USER.MEMBERSHIPS.ORGID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let membership">
|
||||
{{ membership.orgId }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="rolesList">
|
||||
<th mat-header-cell *matHeaderCellDef class="role-row">{{ 'ROLESLABEL' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let membership">
|
||||
<div class="membership-line">
|
||||
<mat-chip-listbox class="cnsl-chip-list" aria-label="role selection">
|
||||
@for (role of membership.rolesList; track role) {
|
||||
<mat-chip-option
|
||||
[selectable]="false"
|
||||
class="cnsl-chip"
|
||||
[removable]="!!userId"
|
||||
(removed)="removeRole(membership, role)"
|
||||
>
|
||||
<div class="cnsl-chip-content">
|
||||
<div class="cnsl-chip-dot" [style.background]="getColor(role)"></div>
|
||||
<span>{{ role | roletransform }}</span>
|
||||
@if (!!userId) {
|
||||
<button matChipRemove>
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</mat-chip-option>
|
||||
}
|
||||
</mat-chip-listbox>
|
||||
<button
|
||||
matTooltip="{{ 'ACTIONS.EDIT' | translate }}"
|
||||
(click)="goto(membership)"
|
||||
mat-icon-button
|
||||
class="goto-btn"
|
||||
>
|
||||
<mat-icon>navigate_next</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
@if (dataSource) {
|
||||
<cnsl-paginator
|
||||
class="paginator"
|
||||
#paginator
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
[pageSize]="INITIALPAGESIZE"
|
||||
[length]="dataSource.totalResult"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]"
|
||||
(page)="changePage($event)"
|
||||
>
|
||||
</cnsl-paginator>
|
||||
}
|
||||
</cnsl-refresh-table>
|
||||
}
|
||||
|
||||
@@ -1,43 +1,46 @@
|
||||
<div class="title-row">
|
||||
<h1 class="metadata-title" mat-dialog-title>{{ 'METADATA.TITLE' | translate }}</h1>
|
||||
<span class="fill-space"></span>
|
||||
<p *ngIf="ts" class="ts cnsl-secondary-text">{{ ts | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</p>
|
||||
@if (ts) {
|
||||
<p class="ts cnsl-secondary-text">{{ ts | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</p>
|
||||
}
|
||||
</div>
|
||||
<div mat-dialog-content class="metadata-dialog-content">
|
||||
<form *ngFor="let md of metadata; index as i" (ngSubmit)="saveElement(i)">
|
||||
<div class="content">
|
||||
<cnsl-form-field #key id="key{{ i }}" class="formfield">
|
||||
<cnsl-label>{{ 'METADATA.KEY' | translate }}</cnsl-label>
|
||||
<input cnslInput [(ngModel)]="md.key" [ngModelOptions]="{ standalone: true }" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field #value id="value{{ i }}" class="formfield">
|
||||
<cnsl-label>{{ 'METADATA.VALUE' | translate }}</cnsl-label>
|
||||
<input cnslInput [(ngModel)]="md.value" [ngModelOptions]="{ standalone: true }" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="!(md.key && md.value)"
|
||||
class="set-button"
|
||||
type="submit"
|
||||
color="primary"
|
||||
matTooltip="{{ 'ACTIONS.SAVE' | translate }}"
|
||||
>
|
||||
<i class="las la-save"></i>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="removeEntry(i)"
|
||||
[disabled]="metadata.length < 2 && i === 0 && !md.key"
|
||||
class="rm-button"
|
||||
type="button"
|
||||
color="warn"
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@for (md of metadata; track md; let i = $index) {
|
||||
<form (ngSubmit)="saveElement(i)">
|
||||
<div class="content">
|
||||
<cnsl-form-field #key id="key{{ i }}" class="formfield">
|
||||
<cnsl-label>{{ 'METADATA.KEY' | translate }}</cnsl-label>
|
||||
<input cnslInput [(ngModel)]="md.key" [ngModelOptions]="{ standalone: true }" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field #value id="value{{ i }}" class="formfield">
|
||||
<cnsl-label>{{ 'METADATA.VALUE' | translate }}</cnsl-label>
|
||||
<input cnslInput [(ngModel)]="md.value" [ngModelOptions]="{ standalone: true }" />
|
||||
</cnsl-form-field>
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="!(md.key && md.value)"
|
||||
class="set-button"
|
||||
type="submit"
|
||||
color="primary"
|
||||
matTooltip="{{ 'ACTIONS.SAVE' | translate }}"
|
||||
>
|
||||
<i class="las la-save"></i>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="removeEntry(i)"
|
||||
[disabled]="metadata.length < 2 && i === 0 && !md.key"
|
||||
class="rm-button"
|
||||
type="button"
|
||||
color="warn"
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
<button (click)="addEntry()" mat-stroked-button type="button">
|
||||
<div class="cnsl-action-button">
|
||||
<mat-icon>add</mat-icon>
|
||||
|
||||
@@ -1,36 +1,43 @@
|
||||
<cnsl-card class="metadata-details" [title]="'DESCRIPTIONS.METADATA_TITLE' | translate" [description]="description">
|
||||
<mat-spinner card-actions class="spinner" diameter="20" *ngIf="loading"></mat-spinner>
|
||||
@if (loading) {
|
||||
<mat-spinner card-actions class="spinner" diameter="20"></mat-spinner>
|
||||
}
|
||||
|
||||
<cnsl-refresh-table *ngIf="dataSource$ | async as dataSource" [loading]="loading" (refreshed)="refresh.emit()">
|
||||
<button actions [disabled]="disabled" mat-raised-button color="primary" class="edit" (click)="editClicked.emit()">
|
||||
{{ 'ACTIONS.EDIT' | translate }}
|
||||
</button>
|
||||
|
||||
<table class="table" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="key">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'METADATA.KEY' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let metadata">
|
||||
<span *ngIf="metadata?.key" class="centered">
|
||||
{{ metadata.key }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="value">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'METADATA.VALUE' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let metadata">
|
||||
<span *ngIf="metadata?.value" class="centered">
|
||||
{{ metadata.value }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
<div *ngIf="!loading && !dataSource?.data?.length" class="no-content-row">
|
||||
<i class="las la-exclamation"></i>
|
||||
<span>{{ 'USER.MFA.EMPTY' | translate }}</span>
|
||||
</div>
|
||||
</cnsl-refresh-table>
|
||||
@if (dataSource$ | async; as dataSource) {
|
||||
<cnsl-refresh-table [loading]="loading" (refreshed)="refresh.emit()">
|
||||
<button actions [disabled]="disabled" mat-raised-button color="primary" class="edit" (click)="editClicked.emit()">
|
||||
{{ 'ACTIONS.EDIT' | translate }}
|
||||
</button>
|
||||
<table class="table" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="key">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'METADATA.KEY' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let metadata">
|
||||
@if (metadata?.key) {
|
||||
<span class="centered">
|
||||
{{ metadata.key }}
|
||||
</span>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="value">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'METADATA.VALUE' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let metadata">
|
||||
@if (metadata?.value) {
|
||||
<span class="centered">
|
||||
{{ metadata.value }}
|
||||
</span>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
@if (!loading && !dataSource?.data?.length) {
|
||||
<div class="no-content-row">
|
||||
<i class="las la-exclamation"></i>
|
||||
<span>{{ 'USER.MFA.EMPTY' | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
</cnsl-refresh-table>
|
||||
}
|
||||
</cnsl-card>
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
<button class="nav-toggle" [ngClass]="{ active }" (click)="clicked.emit()">
|
||||
<div class="c_label">
|
||||
<span> {{ label }} </span>
|
||||
<div *ngIf="count && count < 100" class="count">
|
||||
<span>{{ count }}</span>
|
||||
</div>
|
||||
<div *ngIf="count && count >= 100" class="count">
|
||||
<span>99+</span>
|
||||
</div>
|
||||
@if (count && count < 100) {
|
||||
<div class="count">
|
||||
<span>{{ count }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (count && count >= 100) {
|
||||
<div class="count">
|
||||
<span>99+</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<div class="onboarding-card" cdkTrapFocus>
|
||||
<div class="spinner-w">
|
||||
<mat-spinner diameter="20" *ngIf="loading$ | async" color="accent"> </mat-spinner>
|
||||
@if (loading$ | async) {
|
||||
<mat-spinner diameter="20" color="accent"> </mat-spinner>
|
||||
}
|
||||
</div>
|
||||
<div class="progress-header">
|
||||
<h2>{{ 'ONBOARDING.CARD.TITLE' | translate }}</h2>
|
||||
@@ -15,7 +17,7 @@
|
||||
</div>
|
||||
|
||||
<div class="actions-list">
|
||||
<ng-container *ngFor="let action of actions | async">
|
||||
@for (action of actions | async; track action) {
|
||||
<a
|
||||
[routerLink]="action[1].link"
|
||||
[queryParams]="{ id: action[1].fragment }"
|
||||
@@ -23,18 +25,14 @@
|
||||
[ngClass]="{ done: action[1].reached !== undefined }"
|
||||
>
|
||||
<div class="state-circle">
|
||||
<mat-icon
|
||||
*ngIf="action[1]?.reached !== undefined"
|
||||
class="success-icon"
|
||||
matTooltip="{{ action[1].reached | milestone }}"
|
||||
>check_circle</mat-icon
|
||||
>
|
||||
@if (action[1]?.reached !== undefined) {
|
||||
<mat-icon class="success-icon" matTooltip="{{ action[1].reached | milestone }}">check_circle</mat-icon>
|
||||
}
|
||||
</div>
|
||||
|
||||
<span class="name">{{ 'ONBOARDING.MILESTONES.' + action[0] + '.title' | translate }}</span>
|
||||
<mat-icon class="arrow-right">keyboard_arrow_right</mat-icon>
|
||||
</a>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
<div class="no-thanks-wrapper">
|
||||
<a class="no-thanks-btn" (click)="dismiss()">{{ 'ONBOARDING.DISMISS' | translate }}</a>
|
||||
|
||||
@@ -1,62 +1,60 @@
|
||||
<div class="onboarding-header">
|
||||
<h2 class="desc">{{ 'ONBOARDING.DESCRIPTION' | translate }}</h2>
|
||||
|
||||
<ng-container *ngIf="!adminService.hideOnboarding && (adminService.progressAllDone | async) === false">
|
||||
@if (!adminService.hideOnboarding && (adminService.progressAllDone | async) === false) {
|
||||
<div class="onboarding-progress-bar-wrapper">
|
||||
<mat-progress-bar
|
||||
class="progress"
|
||||
mode="determinate"
|
||||
[value]="adminService.progressPercentage | async"
|
||||
></mat-progress-bar>
|
||||
|
||||
<div class="prog-desc cnsl-secondary-text">
|
||||
{{ adminService.progressDone | async }} / {{ adminService.progressTotal | async }}
|
||||
{{ 'ONBOARDING.COMPLETED' | translate }}
|
||||
</div>
|
||||
|
||||
<mat-spinner diameter="20" *ngIf="adminService.onboardingLoading | async"></mat-spinner>
|
||||
@if (adminService.onboardingLoading | async) {
|
||||
<mat-spinner diameter="20"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<div
|
||||
class="action-card-wrapper"
|
||||
[ngClass]="{ alldone: adminService.hideOnboarding || (adminService.progressAllDone | async) }"
|
||||
>
|
||||
<ng-container *ngFor="let action of actions | async">
|
||||
<a
|
||||
*ngIf="!action[1].externalLink"
|
||||
[routerLink]="action[1].link"
|
||||
[queryParams]="{ id: action[1].fragment }"
|
||||
class="action-card card"
|
||||
[ngClass]="{ done: action[1].reached !== undefined }"
|
||||
>
|
||||
<ng-template
|
||||
[ngTemplateOutlet]="onboardingContent"
|
||||
[ngTemplateOutletContext]="{ title: action[0], action: action[1] }"
|
||||
@for (action of actions | async; track action) {
|
||||
@if (!action[1].externalLink) {
|
||||
<a
|
||||
[routerLink]="action[1].link"
|
||||
[queryParams]="{ id: action[1].fragment }"
|
||||
class="action-card card"
|
||||
[ngClass]="{ done: action[1].reached !== undefined }"
|
||||
>
|
||||
</ng-template>
|
||||
</a>
|
||||
<a
|
||||
*ngIf="action[1].externalLink"
|
||||
[href]="action[1].link"
|
||||
class="action-card card"
|
||||
[ngClass]="{ done: action[1].reached !== undefined }"
|
||||
>
|
||||
<ng-template
|
||||
[ngTemplateOutlet]="onboardingContent"
|
||||
[ngTemplateOutletContext]="{ title: action[0], action: action[1] }"
|
||||
>
|
||||
</ng-template>
|
||||
</a>
|
||||
</ng-container>
|
||||
<ng-template
|
||||
[ngTemplateOutlet]="onboardingContent"
|
||||
[ngTemplateOutletContext]="{ title: action[0], action: action[1] }"
|
||||
>
|
||||
</ng-template>
|
||||
</a>
|
||||
}
|
||||
@if (action[1].externalLink) {
|
||||
<a [href]="action[1].link" class="action-card card" [ngClass]="{ done: action[1].reached !== undefined }">
|
||||
<ng-template
|
||||
[ngTemplateOutlet]="onboardingContent"
|
||||
[ngTemplateOutletContext]="{ title: action[0], action: action[1] }"
|
||||
>
|
||||
</ng-template>
|
||||
</a>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #onboardingContent let-action="action" let-title="title">
|
||||
<div class="state-circle">
|
||||
<mat-icon *ngIf="action?.reached !== undefined" matTooltip="{{ action.reached | milestone }}" class="success-icon"
|
||||
>check_circle</mat-icon
|
||||
>
|
||||
@if (action?.reached !== undefined) {
|
||||
<mat-icon matTooltip="{{ action.reached | milestone }}" class="success-icon">check_circle</mat-icon>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="action-content">
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<div class="org-context-card" cdkTrapFocus>
|
||||
<div class="spinner-w">
|
||||
<mat-spinner diameter="20" *ngIf="orgLoading$ | async" color="accent"> </mat-spinner>
|
||||
@if (orgLoading$ | async) {
|
||||
<mat-spinner diameter="20" color="accent"> </mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="filter-wrapper">
|
||||
@@ -16,37 +18,39 @@
|
||||
</div>
|
||||
|
||||
<div class="org-wrapper" cnslScrollable (scrollPosition)="onNearEndScroll($event)">
|
||||
<button
|
||||
class="org-button-with-pin"
|
||||
mat-button
|
||||
[ngClass]="{
|
||||
active: pinnedorg.id === org.id,
|
||||
'border-bottom': pinned.selected.length && i === pinned.selected.length - 1,
|
||||
}"
|
||||
[disabled]="!pinnedorg.id"
|
||||
*ngFor="let pinnedorg of pinned.selected; index as i"
|
||||
(click)="setActiveOrg(pinnedorg)"
|
||||
>
|
||||
<div class="org-flex-row">
|
||||
<span class="org-span">{{ pinnedorg?.name ? pinnedorg.name : 'NO NAME' }}</span>
|
||||
<template [ngTemplateOutlet]="toggleButton" [ngTemplateOutletContext]="{ key: pinnedorg }"></template>
|
||||
</div>
|
||||
</button>
|
||||
<ng-container *ngFor="let temporg of orgs$ | async">
|
||||
@for (pinnedorg of pinned.selected; track pinnedorg; let i = $index) {
|
||||
<button
|
||||
*ngIf="!pinned.isSelected(temporg)"
|
||||
class="org-button-with-pin"
|
||||
mat-button
|
||||
[ngClass]="{ active: temporg.id === org.id }"
|
||||
[disabled]="!temporg.id"
|
||||
(click)="setActiveOrg(temporg)"
|
||||
[ngClass]="{
|
||||
active: pinnedorg.id === org.id,
|
||||
'border-bottom': pinned.selected.length && i === pinned.selected.length - 1,
|
||||
}"
|
||||
[disabled]="!pinnedorg.id"
|
||||
(click)="setActiveOrg(pinnedorg)"
|
||||
>
|
||||
<div class="org-flex-row">
|
||||
<span class="org-span">{{ temporg?.name ? temporg.name : 'NO NAME' }}</span>
|
||||
<template [ngTemplateOutlet]="toggleButton" [ngTemplateOutletContext]="{ key: temporg }"></template>
|
||||
<span class="org-span">{{ pinnedorg?.name ? pinnedorg.name : 'NO NAME' }}</span>
|
||||
<template [ngTemplateOutlet]="toggleButton" [ngTemplateOutletContext]="{ key: pinnedorg }"></template>
|
||||
</div>
|
||||
</button>
|
||||
</ng-container>
|
||||
}
|
||||
@for (temporg of orgs$ | async; track temporg) {
|
||||
@if (!pinned.isSelected(temporg)) {
|
||||
<button
|
||||
class="org-button-with-pin"
|
||||
mat-button
|
||||
[ngClass]="{ active: temporg.id === org.id }"
|
||||
[disabled]="!temporg.id"
|
||||
(click)="setActiveOrg(temporg)"
|
||||
>
|
||||
<div class="org-flex-row">
|
||||
<span class="org-span">{{ temporg?.name ? temporg.name : 'NO NAME' }}</span>
|
||||
<template [ngTemplateOutlet]="toggleButton" [ngTemplateOutletContext]="{ key: temporg }"></template>
|
||||
</div>
|
||||
</button>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['iam.read']">
|
||||
@@ -73,7 +77,11 @@
|
||||
class="edit-button"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon *ngIf="pinned.isSelected(key)" svgIcon="mdi_pin"></mat-icon>
|
||||
<mat-icon svgIcon="mdi_pin_outline" *ngIf="!pinned.isSelected(key)"></mat-icon>
|
||||
@if (pinned.isSelected(key)) {
|
||||
<mat-icon svgIcon="mdi_pin"></mat-icon>
|
||||
}
|
||||
@if (!pinned.isSelected(key)) {
|
||||
<mat-icon svgIcon="mdi_pin_outline"></mat-icon>
|
||||
}
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
@@ -38,8 +38,12 @@
|
||||
[valueToCopy]="org.primaryDomain"
|
||||
(copiedValue)="copied = $event"
|
||||
>
|
||||
<i *ngIf="copied !== org.primaryDomain" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === org.primaryDomain" class="las la-clipboard-check"></i>
|
||||
@if (copied !== org.primaryDomain) {
|
||||
<i class="las la-clipboard"></i>
|
||||
}
|
||||
@if (copied === org.primaryDomain) {
|
||||
<i class="las la-clipboard-check"></i>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
@@ -50,25 +54,26 @@
|
||||
{{ 'ORG.PAGES.NAME' | translate }}
|
||||
</th>
|
||||
<td mat-cell *cnslCellDef="let org; dataSource: dataSource" (click)="setAndNavigateToOrg(org)">
|
||||
<span>{{ org.name }}</span
|
||||
><span *ngIf="defaultOrgId === org.id" class="state orgdefaultlabel">{{
|
||||
'ORG.PAGES.DEFAULTLABEL' | translate
|
||||
}}</span>
|
||||
<span>{{ org.name }}</span>
|
||||
@if (defaultOrgId === org.id) {
|
||||
<span class="state orgdefaultlabel">{{ 'ORG.PAGES.DEFAULTLABEL' | translate }}</span>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="state">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'ORG.PAGES.STATE' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let org; dataSource: dataSource" (click)="setAndNavigateToOrg(org)">
|
||||
<span
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: org.state === OrganizationState.ACTIVE,
|
||||
inactive: org.state === OrganizationState.INACTIVE,
|
||||
}"
|
||||
*ngIf="org.state"
|
||||
>{{ 'ORG.STATE.' + org.state | translate }}</span
|
||||
>
|
||||
@if (org.state) {
|
||||
<span
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: org.state === OrganizationState.ACTIVE,
|
||||
inactive: org.state === OrganizationState.INACTIVE,
|
||||
}"
|
||||
>{{ 'ORG.STATE.' + org.state | translate }}</span
|
||||
>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -3,31 +3,45 @@
|
||||
<p class="length">
|
||||
<span>{{ length }} </span>{{ 'PAGINATOR.COUNT' | translate }}
|
||||
</p>
|
||||
<p class="ts cnsl-secondary-text" *ngIf="timestamp" data-e2e="timestamp">
|
||||
{{ timestamp | timestampToDate | localizedDate: 'EEEE dd. MMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
@if (timestamp) {
|
||||
<p class="ts cnsl-secondary-text" data-e2e="timestamp">
|
||||
{{ timestamp | timestampToDate | localizedDate: 'EEEE dd. MMM yyyy, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<span class="pos cnsl-secondary-text" *ngIf="!hidePagination">{{ startIndex }} - {{ endIndex }} </span>
|
||||
<div class="row" *ngIf="!hidePagination">
|
||||
<cnsl-form-field class="size">
|
||||
<mat-select class="paginator-select" [value]="pageSize" (selectionChange)="updatePageSize($event.value)">
|
||||
<mat-option *ngFor="let sizeOption of pageSizeOptions" [value]="sizeOption">
|
||||
{{ sizeOption }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<button *ngIf="previousPossible" (click)="previous()" [disabled]="!previousPossible" mat-stroked-button>
|
||||
{{ 'PAGINATOR.PREVIOUS' | translate }}
|
||||
</button>
|
||||
<button *ngIf="nextPossible" (click)="next()" [disabled]="!nextPossible" mat-stroked-button>
|
||||
{{ 'PAGINATOR.NEXT' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
@if (!hidePagination) {
|
||||
<span class="pos cnsl-secondary-text">{{ startIndex }} - {{ endIndex }} </span>
|
||||
}
|
||||
@if (!hidePagination) {
|
||||
<div class="row">
|
||||
<cnsl-form-field class="size">
|
||||
<mat-select class="paginator-select" [value]="pageSize" (selectionChange)="updatePageSize($event.value)">
|
||||
@for (sizeOption of pageSizeOptions; track sizeOption) {
|
||||
<mat-option [value]="sizeOption">
|
||||
{{ sizeOption }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
@if (previousPossible) {
|
||||
<button (click)="previous()" [disabled]="!previousPossible" mat-stroked-button>
|
||||
{{ 'PAGINATOR.PREVIOUS' | translate }}
|
||||
</button>
|
||||
}
|
||||
@if (nextPossible) {
|
||||
<button (click)="next()" [disabled]="!nextPossible" mat-stroked-button>
|
||||
{{ 'PAGINATOR.NEXT' | translate }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="row" *ngIf="showMoreButton">
|
||||
<button (click)="moreRequested.emit()" mat-stroked-button [disabled]="disableShowMore">
|
||||
{{ 'PAGINATOR.MORE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
@if (showMoreButton) {
|
||||
<div class="row">
|
||||
<button (click)="moreRequested.emit()" mat-stroked-button [disabled]="disableShowMore">
|
||||
{{ 'PAGINATOR.MORE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
+80
-53
@@ -1,58 +1,85 @@
|
||||
<div class="validation-col">
|
||||
<div class="val" *ngIf="policy.minLength">
|
||||
<i *ngIf="password?.value?.length === 0; else showSpinner" class="las la-times red"></i>
|
||||
|
||||
<ng-template #showSpinner>
|
||||
<div
|
||||
*ngIf="
|
||||
(password && password.errors && password.errors['minlength']) || password?.value?.length === 0 as currentError;
|
||||
else trueminlength
|
||||
"
|
||||
class="complexity-sp-wrapper"
|
||||
>
|
||||
<mat-progress-spinner
|
||||
class="complexity-spinner"
|
||||
diameter="20"
|
||||
[color]="currentError ? 'warn' : 'valid'"
|
||||
mode="determinate"
|
||||
[value]="(password?.value?.length / minLength) * 100"
|
||||
>
|
||||
</mat-progress-spinner>
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #trueminlength>
|
||||
<i class="las la-check green"></i>
|
||||
</ng-template>
|
||||
|
||||
<span class="cnsl-secondary-text"
|
||||
>{{ 'USER.PASSWORD.MINLENGTHERROR' | translate: { value: policy.minLength } }} ({{ password?.value?.length }}/{{
|
||||
policy.minLength
|
||||
}})
|
||||
</span>
|
||||
</div>
|
||||
<div class="val" *ngIf="policy.hasSymbol">
|
||||
<i *ngIf="password?.pristine || password?.errors?.['errorssymbolerror']" class="las la-times red"></i>
|
||||
<i *ngIf="password?.dirty && !password?.errors?.['errorssymbolerror']" class="las la-check green"></i>
|
||||
<span class="cnsl-secondary-text"> {{ 'ERRORS.SYMBOLERROR' | translate }}</span>
|
||||
</div>
|
||||
<div class="val" *ngIf="policy.hasNumber">
|
||||
<i *ngIf="password?.pristine || password?.errors?.['errorsnumbererror']" class="las la-times red"></i>
|
||||
<i *ngIf="password?.dirty && !password?.errors?.['errorsnumbererror']" class="las la-check green"></i>
|
||||
<span class="cnsl-secondary-text"> {{ 'ERRORS.NUMBERERROR' | translate }}</span>
|
||||
</div>
|
||||
<div class="val" *ngIf="policy.hasUppercase">
|
||||
<i *ngIf="password?.pristine || password?.errors?.['errorsuppercasemissing']" class="las la-times red"></i>
|
||||
<i *ngIf="password?.dirty && !password?.errors?.['errorsuppercasemissing']" class="las la-check green"></i>
|
||||
<span class="cnsl-secondary-text"> {{ 'ERRORS.UPPERCASEMISSING' | translate }}</span>
|
||||
</div>
|
||||
<div class="val" *ngIf="policy.hasLowercase">
|
||||
<i *ngIf="password?.pristine || password?.errors?.['errorslowercasemissing']" class="las la-times red"></i>
|
||||
<i *ngIf="password?.dirty && !password?.errors?.['errorslowercasemissing']" class="las la-check green"></i>
|
||||
<span class="cnsl-secondary-text">{{ 'ERRORS.LOWERCASEMISSING' | translate }}</span>
|
||||
</div>
|
||||
@if (policy.minLength) {
|
||||
<div class="val">
|
||||
@if (password?.value?.length === 0) {
|
||||
<i class="las la-times red"></i>
|
||||
} @else {
|
||||
@if (
|
||||
(password && password.errors && password.errors['minlength']) || password?.value?.length === 0;
|
||||
as currentError
|
||||
) {
|
||||
<div class="complexity-sp-wrapper">
|
||||
<mat-progress-spinner
|
||||
class="complexity-spinner"
|
||||
diameter="20"
|
||||
[color]="currentError ? 'warn' : 'valid'"
|
||||
mode="determinate"
|
||||
[value]="(password?.value?.length / minLength) * 100"
|
||||
>
|
||||
</mat-progress-spinner>
|
||||
</div>
|
||||
} @else {
|
||||
<i class="las la-check green"></i>
|
||||
}
|
||||
}
|
||||
<span class="cnsl-secondary-text"
|
||||
>{{ 'USER.PASSWORD.MINLENGTHERROR' | translate: { value: policy.minLength } }} ({{ password?.value?.length }}/{{
|
||||
policy.minLength
|
||||
}})
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
@if (policy.hasSymbol) {
|
||||
<div class="val">
|
||||
@if (password?.pristine || password?.errors?.['errorssymbolerror']) {
|
||||
<i class="las la-times red"></i>
|
||||
}
|
||||
@if (password?.dirty && !password?.errors?.['errorssymbolerror']) {
|
||||
<i class="las la-check green"></i>
|
||||
}
|
||||
<span class="cnsl-secondary-text"> {{ 'ERRORS.SYMBOLERROR' | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (policy.hasNumber) {
|
||||
<div class="val">
|
||||
@if (password?.pristine || password?.errors?.['errorsnumbererror']) {
|
||||
<i class="las la-times red"></i>
|
||||
}
|
||||
@if (password?.dirty && !password?.errors?.['errorsnumbererror']) {
|
||||
<i class="las la-check green"></i>
|
||||
}
|
||||
<span class="cnsl-secondary-text"> {{ 'ERRORS.NUMBERERROR' | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (policy.hasUppercase) {
|
||||
<div class="val">
|
||||
@if (password?.pristine || password?.errors?.['errorsuppercasemissing']) {
|
||||
<i class="las la-times red"></i>
|
||||
}
|
||||
@if (password?.dirty && !password?.errors?.['errorsuppercasemissing']) {
|
||||
<i class="las la-check green"></i>
|
||||
}
|
||||
<span class="cnsl-secondary-text"> {{ 'ERRORS.UPPERCASEMISSING' | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (policy.hasLowercase) {
|
||||
<div class="val">
|
||||
@if (password?.pristine || password?.errors?.['errorslowercasemissing']) {
|
||||
<i class="las la-times red"></i>
|
||||
}
|
||||
@if (password?.dirty && !password?.errors?.['errorslowercasemissing']) {
|
||||
<i class="las la-check green"></i>
|
||||
}
|
||||
<span class="cnsl-secondary-text">{{ 'ERRORS.LOWERCASEMISSING' | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
<div class="val">
|
||||
<i *ngIf="password?.value?.length === 0 || password?.value?.length <= 70" class="las la-check green"></i>
|
||||
<i *ngIf="password?.value?.length > 70" class="las la-times red"></i>
|
||||
@if (password?.value?.length === 0 || password?.value?.length <= 70) {
|
||||
<i class="las la-check green"></i>
|
||||
}
|
||||
@if (password?.value?.length > 70) {
|
||||
<i class="las la-times red"></i>
|
||||
}
|
||||
|
||||
<span class="cnsl-secondary-text"
|
||||
>{{ 'USER.PASSWORD.MAXLENGTHERROR' | translate: { value: 70 } }} ({{ password?.value?.length }}/{{ 70 }})
|
||||
|
||||
@@ -1,140 +1,167 @@
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" *ngIf="loading" color="primary"></mat-spinner>
|
||||
@if (loading) {
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<h2>{{ 'DESCRIPTIONS.SETTINGS.DOMAINS.TITLE' | translate }}</h2>
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.DOMAINS.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<cnsl-info-section *ngIf="isDefault"> {{ 'POLICY.DEFAULTLABEL' | translate }}</cnsl-info-section>
|
||||
<button
|
||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||
color="warn"
|
||||
(click)="removePolicy()"
|
||||
mat-stroked-button
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
|
||||
<div class="domain-policy-content" *ngIf="domainData">
|
||||
<cnsl-card
|
||||
[title]="'DESCRIPTIONS.SETTINGS.DOMAINS.LOGIN_NAME_PATTERN.TITLE' | translate"
|
||||
[description]="'DESCRIPTIONS.SETTINGS.DOMAINS.LOGIN_NAME_PATTERN.DESCRIPTION' | translate"
|
||||
@if (isDefault) {
|
||||
<cnsl-info-section> {{ 'POLICY.DEFAULTLABEL' | translate }}</cnsl-info-section>
|
||||
}
|
||||
@if (serviceType === PolicyComponentServiceType.MGMT && !isDefault) {
|
||||
<button
|
||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||
color="warn"
|
||||
(click)="removePolicy()"
|
||||
mat-stroked-button
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
name="hasNumber"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="domainData.userLoginMustBeDomain"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.USERLOGINMUSTBEDOMAIN' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
}
|
||||
|
||||
<cnsl-info-section>
|
||||
<div>
|
||||
<span>{{ 'POLICY.DATA.USERLOGINMUSTBEDOMAIN_DESCRIPTION' | translate }}</span>
|
||||
|
||||
<div class="loginname-preview">
|
||||
<div class="left-right">
|
||||
<div *ngIf="domainData.userLoginMustBeDomain"><small>domain</small><span>acme.com</span></div>
|
||||
<div *ngIf="domainData.userLoginMustBeDomain"><small>username</small><span>john</span></div>
|
||||
<div *ngIf="domainData.userLoginMustBeDomain"><small>loginname</small><span>john@acme.com</span></div>
|
||||
|
||||
<div *ngIf="!domainData.userLoginMustBeDomain"><small>domain</small><span>acme.com</span></div>
|
||||
<div *ngIf="!domainData.userLoginMustBeDomain"><small>username</small><span>john@acme.com</span></div>
|
||||
<div *ngIf="!domainData.userLoginMustBeDomain"><small>loginname</small><span>john@acme.com</span></div>
|
||||
</div>
|
||||
<i class="las la-arrow-right"></i>
|
||||
<div class="left-right">
|
||||
<div *ngIf="domainData.userLoginMustBeDomain"><small>domain</small><span>acme.com</span></div>
|
||||
<div *ngIf="domainData.userLoginMustBeDomain"><small>username</small><span>john@acme.com</span></div>
|
||||
<div *ngIf="domainData.userLoginMustBeDomain"><small>loginname</small><span>john@acme.com</span></div>
|
||||
|
||||
<div *ngIf="!domainData.userLoginMustBeDomain"><small>domain</small><span>acme.com</span></div>
|
||||
<div *ngIf="!domainData.userLoginMustBeDomain"><small>username</small><span>john</span></div>
|
||||
<div *ngIf="!domainData.userLoginMustBeDomain"><small>loginname</small><span>john@acme.com</span></div>
|
||||
@if (domainData) {
|
||||
<div class="domain-policy-content">
|
||||
<cnsl-card
|
||||
[title]="'DESCRIPTIONS.SETTINGS.DOMAINS.LOGIN_NAME_PATTERN.TITLE' | translate"
|
||||
[description]="'DESCRIPTIONS.SETTINGS.DOMAINS.LOGIN_NAME_PATTERN.DESCRIPTION' | translate"
|
||||
>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
name="hasNumber"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="domainData.userLoginMustBeDomain"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.USERLOGINMUSTBEDOMAIN' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<cnsl-info-section>
|
||||
<div>
|
||||
<span>{{ 'POLICY.DATA.USERLOGINMUSTBEDOMAIN_DESCRIPTION' | translate }}</span>
|
||||
<div class="loginname-preview">
|
||||
<div class="left-right">
|
||||
@if (domainData.userLoginMustBeDomain) {
|
||||
<div><small>domain</small><span>acme.com</span></div>
|
||||
}
|
||||
@if (domainData.userLoginMustBeDomain) {
|
||||
<div><small>username</small><span>john</span></div>
|
||||
}
|
||||
@if (domainData.userLoginMustBeDomain) {
|
||||
<div><small>loginname</small><span>john@acme.com</span></div>
|
||||
}
|
||||
@if (!domainData.userLoginMustBeDomain) {
|
||||
<div><small>domain</small><span>acme.com</span></div>
|
||||
}
|
||||
@if (!domainData.userLoginMustBeDomain) {
|
||||
<div><small>username</small><span>john@acme.com</span></div>
|
||||
}
|
||||
@if (!domainData.userLoginMustBeDomain) {
|
||||
<div><small>loginname</small><span>john@acme.com</span></div>
|
||||
}
|
||||
</div>
|
||||
<i class="las la-arrow-right"></i>
|
||||
<div class="left-right">
|
||||
@if (domainData.userLoginMustBeDomain) {
|
||||
<div><small>domain</small><span>acme.com</span></div>
|
||||
}
|
||||
@if (domainData.userLoginMustBeDomain) {
|
||||
<div><small>username</small><span>john@acme.com</span></div>
|
||||
}
|
||||
@if (domainData.userLoginMustBeDomain) {
|
||||
<div><small>loginname</small><span>john@acme.com</span></div>
|
||||
}
|
||||
@if (!domainData.userLoginMustBeDomain) {
|
||||
<div><small>domain</small><span>acme.com</span></div>
|
||||
}
|
||||
@if (!domainData.userLoginMustBeDomain) {
|
||||
<div><small>username</small><span>john</span></div>
|
||||
}
|
||||
@if (!domainData.userLoginMustBeDomain) {
|
||||
<div><small>loginname</small><span>john@acme.com</span></div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-info-section>
|
||||
</cnsl-card>
|
||||
<cnsl-card
|
||||
[title]="'DESCRIPTIONS.SETTINGS.DOMAINS.DOMAIN_VERIFICATION.TITLE' | translate"
|
||||
[description]="'DESCRIPTIONS.SETTINGS.DOMAINS.DOMAIN_VERIFICATION.DESCRIPTION' | translate"
|
||||
>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
name="hasNumber"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="domainData.validateOrgDomains"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.VALIDATEORGDOMAINS' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</cnsl-info-section>
|
||||
</cnsl-card>
|
||||
<cnsl-card
|
||||
[title]="'DESCRIPTIONS.SETTINGS.DOMAINS.DOMAIN_VERIFICATION.TITLE' | translate"
|
||||
[description]="'DESCRIPTIONS.SETTINGS.DOMAINS.DOMAIN_VERIFICATION.DESCRIPTION' | translate"
|
||||
>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
name="hasNumber"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="domainData.validateOrgDomains"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.VALIDATEORGDOMAINS' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
<cnsl-card
|
||||
[title]="'DESCRIPTIONS.SETTINGS.DOMAINS.SMTP_SENDER_ADDRESS.TITLE' | translate"
|
||||
[description]="'DESCRIPTIONS.SETTINGS.DOMAINS.SMTP_SENDER_ADDRESS.DESCRIPTION' | translate"
|
||||
>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
name="hasNumber"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="domainData.smtpSenderAddressMatchesInstanceDomain"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.SMTPSENDERADDRESSMATCHESINSTANCEDOMAIN' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
<cnsl-card
|
||||
[title]="'DESCRIPTIONS.SETTINGS.DOMAINS.SMTP_SENDER_ADDRESS.TITLE' | translate"
|
||||
[description]="'DESCRIPTIONS.SETTINGS.DOMAINS.SMTP_SENDER_ADDRESS.DESCRIPTION' | translate"
|
||||
>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
name="hasNumber"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="domainData.smtpSenderAddressMatchesInstanceDomain"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.SMTPSENDERADDRESSMATCHESINSTANCEDOMAIN' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</div>
|
||||
}
|
||||
<div class="btn-container">
|
||||
<button
|
||||
(click)="savePolicy()"
|
||||
|
||||
+51
-48
@@ -2,7 +2,9 @@
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.LANGUAGES.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" *ngIf="loading" color="primary"></mat-spinner>
|
||||
@if (loading) {
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -30,43 +32,43 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="languages-drop-target">
|
||||
<div
|
||||
class="card languages-box"
|
||||
*ngFor="let lang of (localState$ | async)!.allowed; index as i"
|
||||
[cdkDragData]="lang"
|
||||
cdkDrag
|
||||
[cdkDragDisabled]="(canWriteRestrictions$ | async) === false"
|
||||
mat-list-item
|
||||
>
|
||||
<span class="index">{{ i + 1 }}</span>
|
||||
<span class="locale">{{ lang }}</span>
|
||||
<span class="lang">{{ 'SETTING.LANGUAGES.OPTIONS.' + lang | translate }} </span>
|
||||
<span *ngIf="lang === (defaultLang$ | async)" class="state orgdefaultlabel">{{
|
||||
'SETTING.LANGUAGES.DEFAULT' | translate
|
||||
}}</span>
|
||||
|
||||
<button
|
||||
(click)="$event.stopPropagation()"
|
||||
*ngIf="lang !== (defaultLang$ | async) && (isRemotelyAllowed$(lang) | async) === true"
|
||||
mat-icon-button
|
||||
class="more-button"
|
||||
[matMenuTriggerFor]="actions"
|
||||
data-e2e="table-actions-button"
|
||||
@for (lang of (localState$ | async)!.allowed; track lang; let i = $index) {
|
||||
<div
|
||||
class="card languages-box"
|
||||
[cdkDragData]="lang"
|
||||
cdkDrag
|
||||
[cdkDragDisabled]="(canWriteRestrictions$ | async) === false"
|
||||
mat-list-item
|
||||
>
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #actions="matMenu" xPosition="before" class="language-actions-menu">
|
||||
<button
|
||||
menuActions
|
||||
mat-menu-item
|
||||
(click)="setDefaultLang(lang)"
|
||||
[disabled]="(canWriteDefaultLanguage$ | async) === false"
|
||||
>
|
||||
{{ 'SETTING.LANGUAGES.SETASDEFAULT' | translate }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<span class="index">{{ i + 1 }}</span>
|
||||
<span class="locale">{{ lang }}</span>
|
||||
<span class="lang">{{ 'SETTING.LANGUAGES.OPTIONS.' + lang | translate }} </span>
|
||||
@if (lang === (defaultLang$ | async)) {
|
||||
<span class="state orgdefaultlabel">{{ 'SETTING.LANGUAGES.DEFAULT' | translate }}</span>
|
||||
}
|
||||
@if (lang !== (defaultLang$ | async) && (isRemotelyAllowed$(lang) | async) === true) {
|
||||
<button
|
||||
(click)="$event.stopPropagation()"
|
||||
mat-icon-button
|
||||
class="more-button"
|
||||
[matMenuTriggerFor]="actions"
|
||||
data-e2e="table-actions-button"
|
||||
>
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
}
|
||||
<mat-menu #actions="matMenu" xPosition="before" class="language-actions-menu">
|
||||
<button
|
||||
menuActions
|
||||
mat-menu-item
|
||||
(click)="setDefaultLang(lang)"
|
||||
[disabled]="(canWriteDefaultLanguage$ | async) === false"
|
||||
>
|
||||
{{ 'SETTING.LANGUAGES.SETASDEFAULT' | translate }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -95,17 +97,18 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="languages-drop-target">
|
||||
<div
|
||||
class="card languages-box"
|
||||
*ngFor="let lang of (localState$ | async)!.notAllowed"
|
||||
[cdkDragData]="lang"
|
||||
cdkDrag
|
||||
[cdkDragDisabled]="(canWriteRestrictions$ | async) === false"
|
||||
mat-list-item
|
||||
>
|
||||
<span class="locale">{{ lang }}</span>
|
||||
<span class="lang">{{ 'SETTING.LANGUAGES.OPTIONS.' + lang | translate }} </span>
|
||||
</div>
|
||||
@for (lang of (localState$ | async)!.notAllowed; track lang) {
|
||||
<div
|
||||
class="card languages-box"
|
||||
[cdkDragData]="lang"
|
||||
cdkDrag
|
||||
[cdkDragDisabled]="(canWriteRestrictions$ | async) === false"
|
||||
mat-list-item
|
||||
>
|
||||
<span class="locale">{{ lang }}</span>
|
||||
<span class="lang">{{ 'SETTING.LANGUAGES.OPTIONS.' + lang | translate }} </span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+11
-9
@@ -7,15 +7,17 @@
|
||||
<cnsl-form-field class="form-field" label="Access Code" required="true">
|
||||
<cnsl-label>{{ 'MFA.TYPE' | translate }}</cnsl-label>
|
||||
<mat-select [(ngModel)]="newMfaType">
|
||||
<mat-option *ngFor="let mfa of availableMfaTypes" [value]="mfa">
|
||||
{{
|
||||
(data.componentType === LoginMethodComponentType.SecondFactor
|
||||
? 'MFA.SECONDFACTORTYPES.'
|
||||
: LoginMethodComponentType.MultiFactor
|
||||
? 'MFA.MULTIFACTORTYPES.'
|
||||
: '') + mfa | translate
|
||||
}}
|
||||
</mat-option>
|
||||
@for (mfa of availableMfaTypes; track mfa) {
|
||||
<mat-option [value]="mfa">
|
||||
{{
|
||||
(data.componentType === LoginMethodComponentType.SecondFactor
|
||||
? 'MFA.SECONDFACTORTYPES.'
|
||||
: LoginMethodComponentType.MultiFactor
|
||||
? 'MFA.MULTIFACTORTYPES.'
|
||||
: '') + mfa | translate
|
||||
}}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
|
||||
+21
-16
@@ -1,23 +1,28 @@
|
||||
<div class="sp_wrapper">
|
||||
<mat-spinner diameter="30" *ngIf="loading$ | async"></mat-spinner>
|
||||
@if (loading$ | async) {
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="login-policy-mfa-list">
|
||||
<div class="mfa" *ngFor="let mfa of list">
|
||||
<span>
|
||||
{{
|
||||
(componentType === LoginMethodComponentType.SecondFactor
|
||||
? 'MFA.SECONDFACTORTYPES.'
|
||||
: LoginMethodComponentType.MultiFactor
|
||||
? 'MFA.MULTIFACTORTYPES.'
|
||||
: '') + mfa | translate
|
||||
}}
|
||||
</span>
|
||||
|
||||
<button color="warn" *ngIf="!disabled" mat-icon-button (click)="removeMfa(mfa)" class="rm">
|
||||
<i matTooltip="{{ 'ACTIONS.REMOVE' | translate }}" class="las la-times-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
@for (mfa of list; track mfa) {
|
||||
<div class="mfa">
|
||||
<span>
|
||||
{{
|
||||
(componentType === LoginMethodComponentType.SecondFactor
|
||||
? 'MFA.SECONDFACTORTYPES.'
|
||||
: LoginMethodComponentType.MultiFactor
|
||||
? 'MFA.MULTIFACTORTYPES.'
|
||||
: '') + mfa | translate
|
||||
}}
|
||||
</span>
|
||||
@if (!disabled) {
|
||||
<button color="warn" mat-icon-button (click)="removeMfa(mfa)" class="rm">
|
||||
<i matTooltip="{{ 'ACTIONS.REMOVE' | translate }}" class="las la-times-circle"></i>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="mfa-list-btns">
|
||||
<button
|
||||
mat-stroked-button
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" *ngIf="loading" color="primary"></mat-spinner>
|
||||
@if (loading) {
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<h2>{{ 'SETTINGS.LIST.LOGIN' | translate }}</h2>
|
||||
|
||||
<ng-container *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault">
|
||||
@if (serviceType === PolicyComponentServiceType.MGMT && !isDefault) {
|
||||
<ng-template cnslHasRole [hasRole]="['policy.delete']">
|
||||
<button
|
||||
color="primary"
|
||||
@@ -17,18 +19,81 @@
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<br />
|
||||
|
||||
<h3>{{ 'MFA.LIST.MULTIFACTORTITLE' | translate }}</h3>
|
||||
<p class="cnsl-secondary-text">{{ 'MFA.LIST.MULTIFACTORDESCRIPTION' | translate }}</p>
|
||||
|
||||
<div class="login-policy-row" *ngIf="loginData">
|
||||
<cnsl-form-field class="passwordless-allowed" label="Access Code" required="true">
|
||||
<cnsl-label>{{ 'LOGINPOLICY.PASSWORDLESS' | translate }}</cnsl-label>
|
||||
<mat-select
|
||||
[(ngModel)]="loginData.passwordlessType"
|
||||
@if (loginData) {
|
||||
<div class="login-policy-row">
|
||||
<cnsl-form-field class="passwordless-allowed" label="Access Code" required="true">
|
||||
<cnsl-label>{{ 'LOGINPOLICY.PASSWORDLESS' | translate }}</cnsl-label>
|
||||
<mat-select
|
||||
[(ngModel)]="loginData.passwordlessType"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
@for (pt of passwordlessTypes; track pt) {
|
||||
<mat-option [value]="pt">
|
||||
{{ 'LOGINPOLICY.PASSWORDLESSTYPE.' + pt | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (loginData) {
|
||||
<cnsl-card class="max-card-width">
|
||||
<cnsl-factor-table
|
||||
[service]="service"
|
||||
[serviceType]="serviceType"
|
||||
[componentType]="LoginMethodComponentType.MultiFactor"
|
||||
[list]="loginData.multiFactorsList"
|
||||
(typeRemoved)="removeFactor($event)"
|
||||
(beforeTypeAdd)="beforeAddFactor($event)"
|
||||
(typeAdded)="addFactor($event)"
|
||||
[disabled]="
|
||||
loginData.passwordlessType === PasswordlessType.PASSWORDLESS_TYPE_NOT_ALLOWED ||
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
</cnsl-factor-table>
|
||||
</cnsl-card>
|
||||
}
|
||||
|
||||
<br />
|
||||
|
||||
<h3>{{ 'MFA.LIST.SECONDFACTORTITLE' | translate }}</h3>
|
||||
<p class="cnsl-secondary-text">{{ 'MFA.LIST.SECONDFACTORDESCRIPTION' | translate }}</p>
|
||||
|
||||
@if (loginData) {
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
card-actions
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="loginData.forceMfa"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
@@ -41,110 +106,59 @@
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
<mat-option *ngFor="let pt of passwordlessTypes" [value]="pt">
|
||||
{{ 'LOGINPOLICY.PASSWORDLESSTYPE.' + pt | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
|
||||
<cnsl-card class="max-card-width" *ngIf="loginData">
|
||||
<cnsl-factor-table
|
||||
[service]="service"
|
||||
[serviceType]="serviceType"
|
||||
[componentType]="LoginMethodComponentType.MultiFactor"
|
||||
[list]="loginData.multiFactorsList"
|
||||
(typeRemoved)="removeFactor($event)"
|
||||
(beforeTypeAdd)="beforeAddFactor($event)"
|
||||
(typeAdded)="addFactor($event)"
|
||||
[disabled]="
|
||||
loginData.passwordlessType === PasswordlessType.PASSWORDLESS_TYPE_NOT_ALLOWED ||
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
</cnsl-factor-table>
|
||||
</cnsl-card>
|
||||
|
||||
<br />
|
||||
|
||||
<h3>{{ 'MFA.LIST.SECONDFACTORTITLE' | translate }}</h3>
|
||||
<p class="cnsl-secondary-text">{{ 'MFA.LIST.SECONDFACTORDESCRIPTION' | translate }}</p>
|
||||
|
||||
<div *ngIf="loginData" class="login-policy-row">
|
||||
<mat-checkbox
|
||||
card-actions
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="loginData.forceMfa"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.FORCEMFA' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div *ngIf="loginData" class="login-policy-row">
|
||||
<mat-checkbox
|
||||
card-actions
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="loginData.forceMfaLocalOnly"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.FORCEMFALOCALONLY' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<cnsl-card class="max-card-width" *ngIf="loginData">
|
||||
<cnsl-factor-table
|
||||
[service]="service"
|
||||
[serviceType]="serviceType"
|
||||
[componentType]="LoginMethodComponentType.SecondFactor"
|
||||
[list]="loginData.secondFactorsList"
|
||||
(typeRemoved)="removeFactor($event)"
|
||||
(beforeTypeAdd)="beforeAddFactor($event)"
|
||||
(typeAdded)="addFactor($event)"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
</cnsl-factor-table>
|
||||
</cnsl-card>
|
||||
{{ 'POLICY.DATA.FORCEMFA' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
}
|
||||
@if (loginData) {
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
card-actions
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="loginData.forceMfaLocalOnly"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'POLICY.DATA.FORCEMFALOCALONLY' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
}
|
||||
@if (loginData) {
|
||||
<cnsl-card class="max-card-width">
|
||||
<cnsl-factor-table
|
||||
[service]="service"
|
||||
[serviceType]="serviceType"
|
||||
[componentType]="LoginMethodComponentType.SecondFactor"
|
||||
[list]="loginData.secondFactorsList"
|
||||
(typeRemoved)="removeFactor($event)"
|
||||
(beforeTypeAdd)="beforeAddFactor($event)"
|
||||
(typeAdded)="addFactor($event)"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
</cnsl-factor-table>
|
||||
</cnsl-card>
|
||||
}
|
||||
|
||||
<br />
|
||||
|
||||
@@ -224,225 +238,15 @@
|
||||
<h3>{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.TITLE' | translate }}</h3>
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div class="max-card-width login-policy-content" *ngIf="loginData">
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.LOCAL_AUTHENTICATION_ALLOWED.DESCRIPTION' | translate }}"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="loginData.allowUsernamePassword"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.LOCAL_AUTHENTICATION_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<!-- <cnsl-info-section class="info">
|
||||
{{ 'POLICY.DATA.ALLOWUSERNAMEPASSWORD_DESC' | translate }}
|
||||
</cnsl-info-section> -->
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.USER_REGISTRATION_ALLOWED.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.allowRegister"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.USER_REGISTRATION_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.ORG_REGISTRATION_ALLOWED.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="allowOrgRegistration"
|
||||
*ngIf="serviceType === PolicyComponentServiceType.ADMIN"
|
||||
[disabled]="(['iam.restrictions.write'] | hasRole | async) === false"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.ORG_REGISTRATION_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.EXTERNAL_LOGIN_ALLOWED.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.allowExternalIdp"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.EXTERNAL_LOGIN_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<!-- <ng-template #idpInfo>
|
||||
<cnsl-info-section class="info">
|
||||
{{ 'POLICY.DATA.ALLOWEXTERNALIDP_DESC' | translate }}
|
||||
</cnsl-info-section>
|
||||
</ng-template> -->
|
||||
</div>
|
||||
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.HIDE_PASSWORD_RESET.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.hidePasswordReset"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.HIDE_PASSWORD_RESET.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<!-- <ng-template #passwordResetInfo>
|
||||
<cnsl-info-section class="info">
|
||||
{{ 'POLICY.DATA.HIDEPASSWORDRESET_DESC' | translate }}
|
||||
</cnsl-info-section>
|
||||
</ng-template> -->
|
||||
</div>
|
||||
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DOMAIN_DISCOVERY_ALLOWED.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.allowDomainDiscovery"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DOMAIN_DISCOVERY_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.IGNORE_UNKNOWN_USERNAMES.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.ignoreUnknownUsernames"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.IGNORE_UNKNOWN_USERNAMES.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DISABLE_EMAIL_LOGIN.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.disableLoginWithEmail"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DISABLE_EMAIL_LOGIN.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DISABLE_PHONE_LOGIN.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.disableLoginWithPhone"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DISABLE_PHONE_LOGIN.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="login-policy-row">
|
||||
<cnsl-form-field class="form-field" label="Access Code" required="true">
|
||||
<cnsl-label>{{ 'POLICY.DATA.DEFAULTREDIRECTURI' | translate }}</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
placeholder="https://"
|
||||
[(ngModel)]="loginData.defaultRedirectUri"
|
||||
@if (loginData) {
|
||||
<div class="max-card-width login-policy-content">
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.LOCAL_AUTHENTICATION_ALLOWED.DESCRIPTION' | translate }}"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="loginData.allowUsernamePassword"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
@@ -454,10 +258,214 @@
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.LOCAL_AUTHENTICATION_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
<!-- <cnsl-info-section class="info">
|
||||
{{ 'POLICY.DATA.ALLOWUSERNAMEPASSWORD_DESC' | translate }}
|
||||
</cnsl-info-section> -->
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.USER_REGISTRATION_ALLOWED.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.allowRegister"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.USER_REGISTRATION_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
@if (serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.ORG_REGISTRATION_ALLOWED.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="allowOrgRegistration"
|
||||
[disabled]="(['iam.restrictions.write'] | hasRole | async) === false"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.ORG_REGISTRATION_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
}
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.EXTERNAL_LOGIN_ALLOWED.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.allowExternalIdp"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.EXTERNAL_LOGIN_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
<!-- <ng-template #idpInfo>
|
||||
<cnsl-info-section class="info">
|
||||
{{ 'POLICY.DATA.ALLOWEXTERNALIDP_DESC' | translate }}
|
||||
</cnsl-info-section>
|
||||
</ng-template> -->
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.HIDE_PASSWORD_RESET.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.hidePasswordReset"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.HIDE_PASSWORD_RESET.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
<!-- <ng-template #passwordResetInfo>
|
||||
<cnsl-info-section class="info">
|
||||
{{ 'POLICY.DATA.HIDEPASSWORDRESET_DESC' | translate }}
|
||||
</cnsl-info-section>
|
||||
</ng-template> -->
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DOMAIN_DISCOVERY_ALLOWED.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.allowDomainDiscovery"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DOMAIN_DISCOVERY_ALLOWED.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.IGNORE_UNKNOWN_USERNAMES.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.ignoreUnknownUsernames"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.IGNORE_UNKNOWN_USERNAMES.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DISABLE_EMAIL_LOGIN.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.disableLoginWithEmail"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DISABLE_EMAIL_LOGIN.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<mat-checkbox
|
||||
class="login-policy-toggle"
|
||||
color="primary"
|
||||
ngDefaultControl
|
||||
matTooltip="{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DISABLE_PHONE_LOGIN.DESCRIPTION' | translate }}"
|
||||
[(ngModel)]="loginData.disableLoginWithPhone"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.LOGIN.FORM.DISABLE_PHONE_LOGIN.TITLE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="login-policy-row">
|
||||
<cnsl-form-field class="form-field" label="Access Code" required="true">
|
||||
<cnsl-label>{{ 'POLICY.DATA.DEFAULTREDIRECTURI' | translate }}</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
placeholder="https://"
|
||||
[(ngModel)]="loginData.defaultRedirectUri"
|
||||
[disabled]="
|
||||
([
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? 'iam.policy.write'
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? 'policy.write'
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async) === false
|
||||
"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
@@ -1,24 +1,34 @@
|
||||
<h2>{{ 'POLICY.LOGIN_TEXTS.TITLE' | translate }}</h2>
|
||||
<p class="cnsl-secondary-text">{{ 'POLICY.LOGIN_TEXTS.DESCRIPTION' | translate }}</p>
|
||||
<cnsl-info-section class="locked" *ngIf="langSvc.isNotAllowed(language) | async" [type]="InfoSectionType.WARN">
|
||||
{{ 'POLICY.LOGIN_TEXTS.ACTIVE_LANGUAGE_NOT_ALLOWED' | translate }}</cnsl-info-section
|
||||
>
|
||||
@if (langSvc.isNotAllowed(language) | async) {
|
||||
<cnsl-info-section class="locked" [type]="InfoSectionType.WARN">
|
||||
{{ 'POLICY.LOGIN_TEXTS.ACTIVE_LANGUAGE_NOT_ALLOWED' | translate }}</cnsl-info-section
|
||||
>
|
||||
}
|
||||
|
||||
<div *ngIf="loading" class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
@if (loading) {
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="date">
|
||||
<div>
|
||||
<p class="newer-title" *ngIf="newerVersionExists">{{ 'POLICY.LOGIN_TEXTS.NEWERVERSIONEXISTS' | translate }}</p>
|
||||
<p *ngIf="newerPolicyChangeDate && newerVersionExists">
|
||||
{{ 'POLICY.LOGIN_TEXTS.CHANGEDATE' | translate }}:
|
||||
{{ newerPolicyChangeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm:ss' }}
|
||||
</p>
|
||||
<p class="cnsl-secondary-text" *ngIf="currentPolicyChangeDate">
|
||||
{{ 'POLICY.LOGIN_TEXTS.CURRENTDATE' | translate }}:
|
||||
{{ currentPolicyChangeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm:ss' }}
|
||||
</p>
|
||||
@if (newerVersionExists) {
|
||||
<p class="newer-title">{{ 'POLICY.LOGIN_TEXTS.NEWERVERSIONEXISTS' | translate }}</p>
|
||||
}
|
||||
@if (newerPolicyChangeDate && newerVersionExists) {
|
||||
<p>
|
||||
{{ 'POLICY.LOGIN_TEXTS.CHANGEDATE' | translate }}:
|
||||
{{ newerPolicyChangeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm:ss' }}
|
||||
</p>
|
||||
}
|
||||
@if (currentPolicyChangeDate) {
|
||||
<p class="cnsl-secondary-text">
|
||||
{{ 'POLICY.LOGIN_TEXTS.CURRENTDATE' | translate }}:
|
||||
{{ currentPolicyChangeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm:ss' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<button [disabled]="!newerVersionExists" color="primary" mat-raised-button (click)="loadData()">
|
||||
<div class="cnsl-action-button">
|
||||
@@ -27,44 +37,53 @@
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<form *ngIf="allowed$ | async" class="top-actions" [formGroup]="form">
|
||||
<cnsl-form-field class="keys">
|
||||
<cnsl-label>{{ 'POLICY.LOGIN_TEXTS.KEYNAME' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="currentSubMap" name="currentSubMap">
|
||||
<mat-option *ngFor="let key of KeyNamesArray" [value]="key">
|
||||
{{ 'POLICY.LOGIN_TEXTS.KEYS.' + key | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="language">
|
||||
<cnsl-label>{{ 'POLICY.LOGIN_TEXTS.LANGUAGE' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="language" name="language">
|
||||
<mat-option *ngFor="let lang of allowed$ | async" [value]="lang">
|
||||
<div class="centerline">
|
||||
<span
|
||||
>{{ lang }}
|
||||
<span class="lighter cnsl-secondary-text"
|
||||
>| {{ 'POLICY.LOGIN_TEXTS.LANGUAGES.' + lang | translate }}</span
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</mat-option>
|
||||
<mat-optgroup [label]="'POLICY.LOGIN_TEXTS.LANGUAGES_NOT_ALLOWED' | translate" *ngIf="langSvc.restricted$ | async">
|
||||
<mat-option *ngFor="let lang of langSvc.notAllowed$ | async" [value]="lang">
|
||||
<div class="centerline">
|
||||
<span
|
||||
>{{ lang }}
|
||||
<span class="lighter cnsl-secondary-text"
|
||||
>| {{ 'POLICY.LOGIN_TEXTS.LANGUAGES.' + lang | translate }}</span
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</mat-option>
|
||||
</mat-optgroup>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
@if (allowed$ | async) {
|
||||
<form class="top-actions" [formGroup]="form">
|
||||
<cnsl-form-field class="keys">
|
||||
<cnsl-label>{{ 'POLICY.LOGIN_TEXTS.KEYNAME' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="currentSubMap" name="currentSubMap">
|
||||
@for (key of KeyNamesArray; track key) {
|
||||
<mat-option [value]="key">
|
||||
{{ 'POLICY.LOGIN_TEXTS.KEYS.' + key | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="language">
|
||||
<cnsl-label>{{ 'POLICY.LOGIN_TEXTS.LANGUAGE' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="language" name="language">
|
||||
@for (lang of allowed$ | async; track lang) {
|
||||
<mat-option [value]="lang">
|
||||
<div class="centerline">
|
||||
<span
|
||||
>{{ lang }}
|
||||
<span class="lighter cnsl-secondary-text"
|
||||
>| {{ 'POLICY.LOGIN_TEXTS.LANGUAGES.' + lang | translate }}</span
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</mat-option>
|
||||
}
|
||||
@if (langSvc.restricted$ | async) {
|
||||
<mat-optgroup [label]="'POLICY.LOGIN_TEXTS.LANGUAGES_NOT_ALLOWED' | translate">
|
||||
@for (lang of langSvc.notAllowed$ | async; track lang) {
|
||||
<mat-option [value]="lang">
|
||||
<div class="centerline">
|
||||
<span
|
||||
>{{ lang }}
|
||||
<span class="lighter cnsl-secondary-text"
|
||||
>| {{ 'POLICY.LOGIN_TEXTS.LANGUAGES.' + lang | translate }}</span
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</mat-option>
|
||||
}
|
||||
</mat-optgroup>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
}
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
|
||||
@@ -1,88 +1,102 @@
|
||||
<h2>{{ 'DESCRIPTIONS.SETTINGS.MESSAGE_TEXTS.TITLE' | translate }}</h2>
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.MESSAGE_TEXTS.DESCRIPTION' | translate }}</p>
|
||||
<cnsl-info-section class="locked" *ngIf="langSvc.isNotAllowed(language) | async" [type]="InfoSectionType.WARN">
|
||||
{{ 'POLICY.LOGIN_TEXTS.ACTIVE_LANGUAGE_NOT_ALLOWED' | translate }}</cnsl-info-section
|
||||
>
|
||||
@if (langSvc.isNotAllowed(language) | async) {
|
||||
<cnsl-info-section class="locked" [type]="InfoSectionType.WARN">
|
||||
{{ 'POLICY.LOGIN_TEXTS.ACTIVE_LANGUAGE_NOT_ALLOWED' | translate }}</cnsl-info-section
|
||||
>
|
||||
}
|
||||
|
||||
<div *ngIf="loading" class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
@if (loading) {
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div *ngIf="allowed$ | async">
|
||||
<div class="message-texts-top-actions">
|
||||
<cnsl-form-field class="type">
|
||||
<cnsl-label>{{ 'POLICY.MESSAGE_TEXTS.TYPE' | translate }}</cnsl-label>
|
||||
<mat-select [(ngModel)]="currentType" name="currentSubMap" (selectionChange)="changedCurrentType()">
|
||||
<mat-option *ngFor="let type of MESSAGETYPES | keyvalue" [value]="type.value">
|
||||
{{ 'POLICY.MESSAGE_TEXTS.TYPES.' + type.value | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="language">
|
||||
<cnsl-label>{{ 'POLICY.LOGIN_TEXTS.LANGUAGE' | translate }}</cnsl-label>
|
||||
<mat-select [(ngModel)]="language" (selectionChange)="changeLocale($event)" name="language">
|
||||
<mat-option *ngFor="let lang of langSvc.allowed$ | async" [value]="lang">
|
||||
<div class="centerline">
|
||||
<span
|
||||
>{{ lang }}
|
||||
<span class="lighter cnsl-secondary-text"
|
||||
>| {{ 'POLICY.LOGIN_TEXTS.LANGUAGES.' + lang | translate }}</span
|
||||
></span
|
||||
>
|
||||
@if (allowed$ | async) {
|
||||
<div>
|
||||
<div class="message-texts-top-actions">
|
||||
<cnsl-form-field class="type">
|
||||
<cnsl-label>{{ 'POLICY.MESSAGE_TEXTS.TYPE' | translate }}</cnsl-label>
|
||||
<mat-select [(ngModel)]="currentType" name="currentSubMap" (selectionChange)="changedCurrentType()">
|
||||
@for (type of MESSAGETYPES | keyvalue; track type) {
|
||||
<mat-option [value]="type.value">
|
||||
{{ 'POLICY.MESSAGE_TEXTS.TYPES.' + type.value | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="language">
|
||||
<cnsl-label>{{ 'POLICY.LOGIN_TEXTS.LANGUAGE' | translate }}</cnsl-label>
|
||||
<mat-select [(ngModel)]="language" (selectionChange)="changeLocale($event)" name="language">
|
||||
@for (lang of langSvc.allowed$ | async; track lang) {
|
||||
<mat-option [value]="lang">
|
||||
<div class="centerline">
|
||||
<span
|
||||
>{{ lang }}
|
||||
<span class="lighter cnsl-secondary-text"
|
||||
>| {{ 'POLICY.LOGIN_TEXTS.LANGUAGES.' + lang | translate }}</span
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</mat-option>
|
||||
}
|
||||
@if (langSvc.restricted$ | async) {
|
||||
<mat-optgroup [label]="'POLICY.LOGIN_TEXTS.LANGUAGES_NOT_ALLOWED' | translate">
|
||||
@for (lang of langSvc.notAllowed$ | async; track lang) {
|
||||
<mat-option [value]="lang">
|
||||
<div class="centerline">
|
||||
<span
|
||||
>{{ lang }}
|
||||
<span class="lighter cnsl-secondary-text"
|
||||
>| {{ 'POLICY.LOGIN_TEXTS.LANGUAGES.' + lang | translate }}</span
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</mat-option>
|
||||
}
|
||||
</mat-optgroup>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<p class="cnsl-secondary-text">
|
||||
{{ 'DESCRIPTIONS.SETTINGS.MESSAGE_TEXTS.TYPE_DESCRIPTIONS.' + currentType | translate }}
|
||||
</p>
|
||||
<div class="message-text-content">
|
||||
<cnsl-edit-text
|
||||
[chips]="chips[currentType]"
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
label="one"
|
||||
[default$]="getDefaultMessageTextMap$"
|
||||
[current$]="getCustomMessageTextMap$"
|
||||
(changedValues)="updateCurrentValues($event)"
|
||||
></cnsl-edit-text>
|
||||
</div>
|
||||
<div class="message-text-actions">
|
||||
@if ((getCustomMessageTextMap$ | async) && (getCustomMessageTextMap$ | async)?.['isDefault'] === false) {
|
||||
<button
|
||||
class="reset-button"
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
(click)="resetDefault()"
|
||||
color="message-text-warn"
|
||||
type="submit"
|
||||
mat-stroked-button
|
||||
>
|
||||
<div class="cnsl-action-button">
|
||||
<i class="las la-history"></i><span>{{ 'ACTIONS.RESETDEFAULT' | translate }}</span>
|
||||
</div>
|
||||
</mat-option>
|
||||
<mat-optgroup [label]="'POLICY.LOGIN_TEXTS.LANGUAGES_NOT_ALLOWED' | translate" *ngIf="langSvc.restricted$ | async">
|
||||
<mat-option *ngFor="let lang of langSvc.notAllowed$ | async" [value]="lang">
|
||||
<div class="centerline">
|
||||
<span
|
||||
>{{ lang }}
|
||||
<span class="lighter cnsl-secondary-text"
|
||||
>| {{ 'POLICY.LOGIN_TEXTS.LANGUAGES.' + lang | translate }}</span
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</mat-option>
|
||||
</mat-optgroup>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
class="save-button"
|
||||
[disabled]="!updateRequest || (canWrite$ | async) === false"
|
||||
(click)="saveCurrentMessage()"
|
||||
color="primary"
|
||||
type="submit"
|
||||
mat-raised-button
|
||||
>
|
||||
{{ 'ACTIONS.SAVE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.MESSAGE_TEXTS.TYPE_DESCRIPTIONS.' + currentType | translate }}</p>
|
||||
|
||||
<div class="message-text-content">
|
||||
<cnsl-edit-text
|
||||
[chips]="chips[currentType]"
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
label="one"
|
||||
[default$]="getDefaultMessageTextMap$"
|
||||
[current$]="getCustomMessageTextMap$"
|
||||
(changedValues)="updateCurrentValues($event)"
|
||||
></cnsl-edit-text>
|
||||
</div>
|
||||
|
||||
<div class="message-text-actions">
|
||||
<button
|
||||
class="reset-button"
|
||||
*ngIf="(getCustomMessageTextMap$ | async) && (getCustomMessageTextMap$ | async)?.['isDefault'] === false"
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
(click)="resetDefault()"
|
||||
color="message-text-warn"
|
||||
type="submit"
|
||||
mat-stroked-button
|
||||
>
|
||||
<div class="cnsl-action-button">
|
||||
<i class="las la-history"></i><span>{{ 'ACTIONS.RESETDEFAULT' | translate }}</span>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="save-button"
|
||||
[disabled]="!updateRequest || (canWrite$ | async) === false"
|
||||
(click)="saveCurrentMessage()"
|
||||
color="primary"
|
||||
type="submit"
|
||||
mat-raised-button
|
||||
>
|
||||
{{ 'ACTIONS.SAVE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
+28
-28
@@ -1,40 +1,40 @@
|
||||
<h2>{{ 'POLICY.NOTIFICATION.TITLE' | translate }}</h2>
|
||||
<p class="cnsl-secondary-text">{{ 'POLICY.NOTIFICATION.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div *ngIf="loading" class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
@if (loading) {
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['policy.delete']">
|
||||
<button
|
||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||
color="warn"
|
||||
(click)="removePolicy()"
|
||||
mat-stroked-button
|
||||
>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
@if (serviceType === PolicyComponentServiceType.MGMT && !isDefault) {
|
||||
<button matTooltip="{{ 'POLICY.RESET' | translate }}" color="warn" (click)="removePolicy()" mat-stroked-button>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<div class="notification-policy-card">
|
||||
<cnsl-card *ngIf="notificationData">
|
||||
<div class="notification-policy-content">
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasUppercase"
|
||||
ngDefaultControl
|
||||
data-e2e="notification-policy-checkbox"
|
||||
[(ngModel)]="notificationData.passwordChange"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
{{ 'POLICY.NOTIFICATION.PASSWORDCHANGE' | translate }}
|
||||
</mat-checkbox>
|
||||
@if (notificationData) {
|
||||
<cnsl-card>
|
||||
<div class="notification-policy-content">
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasUppercase"
|
||||
ngDefaultControl
|
||||
data-e2e="notification-policy-checkbox"
|
||||
[(ngModel)]="notificationData.passwordChange"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
{{ 'POLICY.NOTIFICATION.PASSWORDCHANGE' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</cnsl-card>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="btn-container">
|
||||
|
||||
+30
-28
@@ -2,34 +2,36 @@
|
||||
<span>{{ provider === SMSProviderType.Twilio ? 'Twilio' : ('SETTING.SMS.ADDPROVIDER' | translate) }}</span>
|
||||
</h1>
|
||||
<div mat-dialog-content>
|
||||
<form *ngIf="provider === SMSProviderType.Twilio" (ngSubmit)="closeDialogWithRequest()" [formGroup]="twilioForm">
|
||||
<cnsl-form-field class="sms-form-field" label="sid">
|
||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.SID' | translate }}</cnsl-label>
|
||||
<input cnslInput name="sid" formControlName="sid" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field *ngIf="token" class="sms-form-field" label="Token">
|
||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.TOKEN' | translate }}</cnsl-label>
|
||||
<input cnslInput name="token" formControlName="token" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="sms-form-field" label="Sender Number">
|
||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.SENDERNUMBER' | translate }}</cnsl-label>
|
||||
<input cnslInput name="senderNumber" formControlName="senderNumber" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="sms-form-field" label="Verification Service Sid">
|
||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.VERIFYSERVICESID' | translate }}</cnsl-label>
|
||||
<input cnslInput name="verifyServiceSid" formControlName="verifyServiceSid" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.SMS.TWILIO.VERIFYSERVICESID_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
|
||||
<button *ngIf="twilio" type="button" mat-stroked-button (click)="changeToken()" data-e2e="edit-sms-token-button">
|
||||
{{ 'SETTING.SMS.TWILIO.CHANGETOKEN' | translate }}
|
||||
</button>
|
||||
</form>
|
||||
@if (provider === SMSProviderType.Twilio) {
|
||||
<form (ngSubmit)="closeDialogWithRequest()" [formGroup]="twilioForm">
|
||||
<cnsl-form-field class="sms-form-field" label="sid">
|
||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.SID' | translate }}</cnsl-label>
|
||||
<input cnslInput name="sid" formControlName="sid" />
|
||||
</cnsl-form-field>
|
||||
@if (token) {
|
||||
<cnsl-form-field class="sms-form-field" label="Token">
|
||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.TOKEN' | translate }}</cnsl-label>
|
||||
<input cnslInput name="token" formControlName="token" />
|
||||
</cnsl-form-field>
|
||||
}
|
||||
<cnsl-form-field class="sms-form-field" label="Sender Number">
|
||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.SENDERNUMBER' | translate }}</cnsl-label>
|
||||
<input cnslInput name="senderNumber" formControlName="senderNumber" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="sms-form-field" label="Verification Service Sid">
|
||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.VERIFYSERVICESID' | translate }}</cnsl-label>
|
||||
<input cnslInput name="verifyServiceSid" formControlName="verifyServiceSid" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.SMS.TWILIO.VERIFYSERVICESID_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
@if (twilio) {
|
||||
<button type="button" mat-stroked-button (click)="changeToken()" data-e2e="edit-sms-token-button">
|
||||
{{ 'SETTING.SMS.TWILIO.CHANGETOKEN' | translate }}
|
||||
</button>
|
||||
}
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
<button mat-stroked-button (click)="closeDialog()">
|
||||
|
||||
+57
-52
@@ -2,57 +2,62 @@
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.SMS_PROVIDER.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" *ngIf="smsProvidersLoading" color="primary"></mat-spinner>
|
||||
@if (smsProvidersLoading) {
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="sms-providers" *ngIf="!smsProvidersLoading">
|
||||
<cnsl-card class="sms-card" [nomargin]="true">
|
||||
<div class="sms-provider">
|
||||
<h4 class="title">Twilio</h4>
|
||||
|
||||
<span
|
||||
*ngIf="twilio"
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE,
|
||||
inactive: twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE,
|
||||
}"
|
||||
>{{ 'SETTING.SMS.SMSPROVIDERSTATE.' + twilio.state | translate }}</span
|
||||
>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
<button
|
||||
*ngIf="twilio && twilio.id"
|
||||
[disabled]="(['iam.write'] | hasRole | async) === false"
|
||||
mat-stroked-button
|
||||
data-e2e="activate-sms-provider-button"
|
||||
(click)="toggleSMSProviderState(twilio.id)"
|
||||
>
|
||||
<span *ngIf="twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE">{{
|
||||
'ACTIONS.DEACTIVATE' | translate
|
||||
}}</span>
|
||||
<span *ngIf="twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE">{{
|
||||
'ACTIONS.ACTIVATE' | translate
|
||||
}}</span>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="twilio && twilio.id"
|
||||
color="warn"
|
||||
[disabled]="(['iam.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="removeSMSProvider(twilio.id)"
|
||||
data-e2e="remove-sms-provider-button"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
<button
|
||||
[disabled]="(['iam.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="editSMSProvider()"
|
||||
data-e2e="new-twilio-button"
|
||||
>
|
||||
<i class="las la-pen"></i>
|
||||
</button>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</div>
|
||||
@if (!smsProvidersLoading) {
|
||||
<div class="sms-providers">
|
||||
<cnsl-card class="sms-card" [nomargin]="true">
|
||||
<div class="sms-provider">
|
||||
<h4 class="title">Twilio</h4>
|
||||
@if (twilio) {
|
||||
<span
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE,
|
||||
inactive: twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE,
|
||||
}"
|
||||
>{{ 'SETTING.SMS.SMSPROVIDERSTATE.' + twilio.state | translate }}</span
|
||||
>
|
||||
}
|
||||
<span class="fill-space"></span>
|
||||
@if (twilio && twilio.id) {
|
||||
<button
|
||||
[disabled]="(['iam.write'] | hasRole | async) === false"
|
||||
mat-stroked-button
|
||||
data-e2e="activate-sms-provider-button"
|
||||
(click)="toggleSMSProviderState(twilio.id)"
|
||||
>
|
||||
@if (twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE) {
|
||||
<span>{{ 'ACTIONS.DEACTIVATE' | translate }}</span>
|
||||
}
|
||||
@if (twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE) {
|
||||
<span>{{ 'ACTIONS.ACTIVATE' | translate }}</span>
|
||||
}
|
||||
</button>
|
||||
}
|
||||
@if (twilio && twilio.id) {
|
||||
<button
|
||||
color="warn"
|
||||
[disabled]="(['iam.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="removeSMSProvider(twilio.id)"
|
||||
data-e2e="remove-sms-provider-button"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
[disabled]="(['iam.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="editSMSProvider()"
|
||||
data-e2e="new-twilio-button"
|
||||
>
|
||||
<i class="las la-pen"></i>
|
||||
</button>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</div>
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" *ngIf="loading" color="primary"></mat-spinner>
|
||||
@if (loading) {
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
<h2>{{ 'DESCRIPTIONS.SETTINGS.OIDC.TITLE' | translate }}</h2>
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.OIDC.DESCRIPTION' | translate }}</p>
|
||||
|
||||
+26
-31
@@ -4,37 +4,32 @@
|
||||
>
|
||||
<cnsl-refresh-table [hideRefresh]="true" [loading]="(dataSource$ | async) === null">
|
||||
<div class="table-wrapper">
|
||||
<table
|
||||
*ngIf="dataSource$ | async as dataSource"
|
||||
mat-table
|
||||
class="table"
|
||||
aria-label="Elements"
|
||||
[dataSource]="dataSource"
|
||||
>
|
||||
<ng-container matColumnDef="timestamp">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.PREVIOUS_TABLE.DEACTIVATED_ON' | translate }}
|
||||
</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.changeDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'APP.PAGES.ID' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.id }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.TYPE.TITLE' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.key.case | uppercase }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="['timestamp', 'id', 'type']"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['timestamp', 'id', 'type']"></tr>
|
||||
</table>
|
||||
@if (dataSource$ | async; as dataSource) {
|
||||
<table mat-table class="table" aria-label="Elements" [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="timestamp">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.PREVIOUS_TABLE.DEACTIVATED_ON' | translate }}
|
||||
</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.changeDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'APP.PAGES.ID' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.id }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.TYPE.TITLE' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.key.case | uppercase }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="['timestamp', 'id', 'type']"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['timestamp', 'id', 'type']"></tr>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
</cnsl-refresh-table>
|
||||
</cnsl-card>
|
||||
|
||||
+59
-49
@@ -3,55 +3,65 @@
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<table *ngIf="dataSource$ | async as dataSource" mat-table class="table" aria-label="Elements" [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="state">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'APP.PAGES.STATE' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; let i = index; dataSource: dataSource">
|
||||
<span
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: i === 0,
|
||||
neutral: i === 1,
|
||||
}"
|
||||
[ngSwitch]="i"
|
||||
>
|
||||
<ng-container *ngSwitchCase="0">{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.ACTIVE' | translate }}</ng-container>
|
||||
<ng-container *ngSwitchCase="1">{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.NEXT' | translate }}</ng-container>
|
||||
<ng-container *ngSwitchDefault>{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.FUTURE' | translate }}</ng-container>
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'APP.PAGES.ID' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.id }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.TYPE.TITLE' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.key.case | uppercase }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
<cnsl-table-actions *ngIf="row.state === State.INITIAL">
|
||||
<button
|
||||
actions
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
color="warn"
|
||||
(click)="delete.emit(row)"
|
||||
mat-icon-button
|
||||
@if (dataSource$ | async; as dataSource) {
|
||||
<table mat-table class="table" aria-label="Elements" [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="state">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'APP.PAGES.STATE' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; let i = index; dataSource: dataSource">
|
||||
<span
|
||||
class="state"
|
||||
[ngClass]="{
|
||||
active: i === 0,
|
||||
neutral: i === 1,
|
||||
}"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</cnsl-table-actions>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="['state', 'id', 'type', 'actions']"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['state', 'id', 'type', 'actions']"></tr>
|
||||
</table>
|
||||
@switch (i) {
|
||||
@case (0) {
|
||||
{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.ACTIVE' | translate }}
|
||||
}
|
||||
@case (1) {
|
||||
{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.NEXT' | translate }}
|
||||
}
|
||||
@default {
|
||||
{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.FUTURE' | translate }}
|
||||
}
|
||||
}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'APP.PAGES.ID' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.id }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.TYPE.TITLE' | translate }}</th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
{{ row.key.case | uppercase }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *cnslCellDef="let row; dataSource: dataSource">
|
||||
@if (row.state === State.INITIAL) {
|
||||
<cnsl-table-actions>
|
||||
<button
|
||||
actions
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||
color="warn"
|
||||
(click)="delete.emit(row)"
|
||||
mat-icon-button
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</cnsl-table-actions>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="['state', 'id', 'type', 'actions']"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['state', 'id', 'type', 'actions']"></tr>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
</cnsl-refresh-table>
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
<p>{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.DESCRIPTION' | translate }}</p>
|
||||
<p>{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.NOTE' | translate }}</p>
|
||||
<cnsl-oidc-webkeys-table (refresh)="refresh.next(true)" (delete)="deleteWebKey($event)" [webKeys]="webKeys$ | async">
|
||||
<button
|
||||
*ngIf="nextWebKeyCandidate$ | async as nextWebKeyCandidate"
|
||||
[disabled]="activateLoading()"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
(click)="activateWebKey(nextWebKeyCandidate)"
|
||||
>
|
||||
<mat-spinner diameter="20" *ngIf="activateLoading()"></mat-spinner>
|
||||
<span *ngIf="!activateLoading()">{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.ACTIVATE' | translate }}</span>
|
||||
</button>
|
||||
@if (nextWebKeyCandidate$ | async; as nextWebKeyCandidate) {
|
||||
<button [disabled]="activateLoading()" mat-raised-button color="primary" (click)="activateWebKey(nextWebKeyCandidate)">
|
||||
@if (activateLoading()) {
|
||||
<mat-spinner diameter="20"></mat-spinner>
|
||||
}
|
||||
@if (!activateLoading()) {
|
||||
<span>{{ 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.ACTIVATE' | translate }}</span>
|
||||
}
|
||||
</button>
|
||||
}
|
||||
</cnsl-oidc-webkeys-table>
|
||||
<cnsl-oidc-webkeys-create [loading]="createLoading()" (ngSubmit)="createWebKey($event)" />
|
||||
<cnsl-oidc-webkeys-inactive-table [inactiveWebKeys]="inactiveWebKeys$ | async" />
|
||||
|
||||
+27
-28
@@ -1,40 +1,39 @@
|
||||
<h2>{{ 'POLICY.PWD_AGE.TITLE' | translate }}</h2>
|
||||
<p class="cnsl-secondary-text">{{ 'POLICY.PWD_AGE.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div *ngIf="loading" class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
@if (loading) {
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['policy.delete']">
|
||||
<button
|
||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||
color="warn"
|
||||
(click)="resetPolicy()"
|
||||
mat-stroked-button
|
||||
>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
@if (serviceType === PolicyComponentServiceType.MGMT && !isDefault) {
|
||||
<button matTooltip="{{ 'POLICY.RESET' | translate }}" color="warn" (click)="resetPolicy()" mat-stroked-button>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<form class="lifetime-form" (ngSubmit)="savePolicy()" [formGroup]="passwordAgeForm" autocomplete="off">
|
||||
<cnsl-card *ngIf="passwordAgeData">
|
||||
<div class="age-content">
|
||||
<div class="row">
|
||||
<cnsl-form-field class="pwd-age-form-field" required="true">
|
||||
<cnsl-label>{{ 'POLICY.DATA.MAXAGEDAYS' | translate }}</cnsl-label>
|
||||
<input cnslInput type="number" name="maxAgeDays" formControlName="maxAgeDays" />
|
||||
</cnsl-form-field>
|
||||
@if (passwordAgeData) {
|
||||
<cnsl-card>
|
||||
<div class="age-content">
|
||||
<div class="row">
|
||||
<cnsl-form-field class="pwd-age-form-field" required="true">
|
||||
<cnsl-label>{{ 'POLICY.DATA.MAXAGEDAYS' | translate }}</cnsl-label>
|
||||
<input cnslInput type="number" name="maxAgeDays" formControlName="maxAgeDays" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div class="row">
|
||||
<cnsl-form-field class="pwd-age-form-field" required="true">
|
||||
<cnsl-label>{{ 'POLICY.DATA.EXPIREWARNDAYS' | translate }}</cnsl-label>
|
||||
<input cnslInput type="number" name="expireWarnDays" formControlName="expireWarnDays" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<cnsl-form-field class="pwd-age-form-field" required="true">
|
||||
<cnsl-label>{{ 'POLICY.DATA.EXPIREWARNDAYS' | translate }}</cnsl-label>
|
||||
<input cnslInput type="number" name="expireWarnDays" formControlName="expireWarnDays" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</cnsl-card>
|
||||
}
|
||||
</form>
|
||||
|
||||
<div class="btn-container">
|
||||
|
||||
+90
-91
@@ -1,106 +1,105 @@
|
||||
<!-- <cnsl-card
|
||||
title="{{ 'POLICY.PWD_COMPLEXITY.TITLE' | translate }}"
|
||||
description="{{ 'POLICY.PWD_COMPLEXITY.DESCRIPTION' | translate }}"
|
||||
title="{{ 'POLICY.PWD_COMPLEXITY.TITLE' | translate }}"
|
||||
description="{{ 'POLICY.PWD_COMPLEXITY.DESCRIPTION' | translate }}"
|
||||
> -->
|
||||
<h2>{{ 'DESCRIPTIONS.SETTINGS.PW_COMPLEXITY.TITLE' | translate }}</h2>
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.PW_COMPLEXITY.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div *ngIf="loading" class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
@if (loading) {
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['policy.delete']">
|
||||
<button
|
||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||
color="warn"
|
||||
(click)="removePolicy()"
|
||||
mat-stroked-button
|
||||
>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
@if (serviceType === PolicyComponentServiceType.MGMT && !isDefault) {
|
||||
<button matTooltip="{{ 'POLICY.RESET' | translate }}" color="warn" (click)="removePolicy()" mat-stroked-button>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<cnsl-card *ngIf="complexityData">
|
||||
<div class="complexity-content">
|
||||
<div class="row">
|
||||
<div class="length-wrapper">
|
||||
<button mat-icon-button (click)="decrementLength()" [disabled]="(['policy.write'] | hasRole | async) === false">
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
<span>{{ complexityData.minLength }}</span>
|
||||
<button mat-icon-button (click)="incrementLength()" [disabled]="(['policy.write'] | hasRole | async) === false">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
@if (complexityData) {
|
||||
<cnsl-card>
|
||||
<div class="complexity-content">
|
||||
<div class="row">
|
||||
<div class="length-wrapper">
|
||||
<button mat-icon-button (click)="decrementLength()" [disabled]="(['policy.write'] | hasRole | async) === false">
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
<span>{{ complexityData.minLength }}</span>
|
||||
<button mat-icon-button (click)="incrementLength()" [disabled]="(['policy.write'] | hasRole | async) === false">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="number-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_counter"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.MINLENGTH' | translate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="number-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_counter"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.MINLENGTH' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasNumber"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="complexityData.hasNumber"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_numeric"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.HASNUMBER' | translate }}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasSymbol"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="complexityData.hasSymbol"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_symbol"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.HASSYMBOL' | translate }}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasLowercase"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="complexityData.hasLowercase"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_format-letter-case-lower"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.HASLOWERCASE' | translate }}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasUppercase"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="complexityData.hasUppercase"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_format-letter-case-upper"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.HASUPPERCASE' | translate }}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasNumber"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="complexityData.hasNumber"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_numeric"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.HASNUMBER' | translate }}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasSymbol"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="complexityData.hasSymbol"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_symbol"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.HASSYMBOL' | translate }}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasLowercase"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="complexityData.hasLowercase"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_format-letter-case-lower"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.HASLOWERCASE' | translate }}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-checkbox
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="hasUppercase"
|
||||
ngDefaultControl
|
||||
[(ngModel)]="complexityData.hasUppercase"
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_format-letter-case-upper"></mat-icon>
|
||||
<span class="left-desc">{{ 'POLICY.DATA.HASUPPERCASE' | translate }}</span>
|
||||
</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</cnsl-card>
|
||||
}
|
||||
|
||||
<div class="btn-container">
|
||||
<button
|
||||
|
||||
+54
-58
@@ -2,69 +2,65 @@
|
||||
<p class="cnsl-secondary-text">{{ 'POLICY.PWD_LOCKOUT.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['policy.delete']">
|
||||
<button
|
||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||
color="warn"
|
||||
(click)="resetPolicy()"
|
||||
mat-stroked-button
|
||||
>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
@if (serviceType === PolicyComponentServiceType.MGMT && !isDefault) {
|
||||
<button matTooltip="{{ 'POLICY.RESET' | translate }}" color="warn" (click)="resetPolicy()" mat-stroked-button>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<cnsl-card *ngIf="lockoutData">
|
||||
<div class="lockout-content">
|
||||
<div class="row">
|
||||
<div class="length-wrapper">
|
||||
<button
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="decrementPasswordMaxAttempts()"
|
||||
>
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
<span>{{ lockoutData.maxPasswordAttempts }}</span>
|
||||
<button
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="incrementPasswordMaxAttempts()"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
@if (lockoutData) {
|
||||
<cnsl-card>
|
||||
<div class="lockout-content">
|
||||
<div class="row">
|
||||
<div class="length-wrapper">
|
||||
<button
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="decrementPasswordMaxAttempts()"
|
||||
>
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
<span>{{ lockoutData.maxPasswordAttempts }}</span>
|
||||
<button
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="incrementPasswordMaxAttempts()"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="number-toggle-row">
|
||||
<span class="left-desc">{{ 'POLICY.DATA.MAXPASSWORDATTEMPTS' | translate }}</span>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="number-toggle-row">
|
||||
<span class="left-desc">{{ 'POLICY.DATA.MAXPASSWORDATTEMPTS' | translate }}</span>
|
||||
<span class="fill-space"></span>
|
||||
<div class="row">
|
||||
<div class="length-wrapper">
|
||||
<button
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="decrementOTPMaxAttempts()"
|
||||
>
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
<span>{{ lockoutData.maxOtpAttempts }}</span>
|
||||
<button
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="incrementOTPMaxAttempts()"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="number-toggle-row">
|
||||
<span class="left-desc">{{ 'POLICY.DATA.MAXOTPATTEMPTS' | translate }}</span>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="length-wrapper">
|
||||
<button
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="decrementOTPMaxAttempts()"
|
||||
>
|
||||
<mat-icon>remove</mat-icon>
|
||||
</button>
|
||||
<span>{{ lockoutData.maxOtpAttempts }}</span>
|
||||
<button
|
||||
[disabled]="(['policy.write'] | hasRole | async) === false"
|
||||
mat-icon-button
|
||||
(click)="incrementOTPMaxAttempts()"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="number-toggle-row">
|
||||
<span class="left-desc">{{ 'POLICY.DATA.MAXOTPATTEMPTS' | translate }}</span>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</cnsl-card>
|
||||
}
|
||||
|
||||
<div class="btn-container">
|
||||
<button
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<h2>{{ 'DESCRIPTIONS.SETTINGS.PRIVACY_POLICY.TITLE' | translate }}</h2>
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.PRIVACY_POLICY.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<ng-container *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault">
|
||||
@if (serviceType === PolicyComponentServiceType.MGMT && !isDefault) {
|
||||
<ng-template cnslHasRole [hasRole]="['policy.delete']">
|
||||
<button
|
||||
color="primary"
|
||||
@@ -14,52 +14,48 @@
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<!-- <cnsl-info-section *ngIf="isDefault"> {{ 'POLICY.DEFAULTLABEL' | translate }}</cnsl-info-section> -->
|
||||
|
||||
<div>
|
||||
<form *ngIf="form" [formGroup]="form" class="policy-content">
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.TOSLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="tosLink" formControlName="tosLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'tosLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.POLICYLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="privacyLink" formControlName="privacyLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'privacyLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.HELPLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="helpLink" formControlName="helpLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'helpLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.SUPPORTEMAIL' | translate }}</cnsl-label>
|
||||
<input cnslInput name="supportEmail" formControlName="supportEmail" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.CUSTOMLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="customLink" formControlName="customLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'customLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.CUSTOMLINKTEXT' | translate }}</cnsl-label>
|
||||
<input cnslInput name="customLinkText" formControlName="customLinkText" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.DOCSLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="docsLink" formControlName="docsLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'docsLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
@if (form) {
|
||||
<form [formGroup]="form" class="policy-content">
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.TOSLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="tosLink" formControlName="tosLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'tosLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.POLICYLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="privacyLink" formControlName="privacyLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'privacyLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.HELPLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="helpLink" formControlName="helpLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'helpLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.SUPPORTEMAIL' | translate }}</cnsl-label>
|
||||
<input cnslInput name="supportEmail" formControlName="supportEmail" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.CUSTOMLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="customLink" formControlName="customLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'customLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.CUSTOMLINKTEXT' | translate }}</cnsl-label>
|
||||
<input cnslInput name="customLinkText" formControlName="customLinkText" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.DOCSLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="docsLink" formControlName="docsLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'docsLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="policy-actions">
|
||||
@@ -86,8 +82,12 @@
|
||||
(click)="addChip(key, LANGPLACEHOLDER)"
|
||||
>
|
||||
<span class="key">{{ LANGPLACEHOLDER }}</span>
|
||||
<i *ngIf="copied !== LANGPLACEHOLDER" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === LANGPLACEHOLDER" class="las la-clipboard-check"></i>
|
||||
@if (copied !== LANGPLACEHOLDER) {
|
||||
<i class="las la-clipboard"></i>
|
||||
}
|
||||
@if (copied === LANGPLACEHOLDER) {
|
||||
<i class="las la-clipboard-check"></i>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
+57
-60
@@ -1,63 +1,60 @@
|
||||
<div class="preview" *ngIf="policy">
|
||||
<div
|
||||
class="dashed"
|
||||
[ngClass]="{ dark: theme === Theme.DARK, light: theme === Theme.LIGHT }"
|
||||
[style.background]="theme === Theme.DARK ? policy.backgroundColorDark : policy.backgroundColor"
|
||||
>
|
||||
<div class="login-wrapper" [style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor">
|
||||
<img *ngIf="policy.logoUrl && theme === Theme.LIGHT" [src]="policy.logoUrl" alt="logo-mock" />
|
||||
<img *ngIf="policy.logoUrlDark && theme === Theme.DARK" [src]="policy.logoUrlDark" alt="logo-mock" />
|
||||
|
||||
<h1 [style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor">
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.TITLE' | translate }}
|
||||
</h1>
|
||||
<p [style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor" class="desc-text">
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.SECOND' | translate }}
|
||||
</p>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>Loginname</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
[style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor"
|
||||
value="road.runner"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
|
||||
<div class="error-msg" [style.color]="theme === Theme.DARK ? policy.warnColorDark : policy.warnColor">
|
||||
<i
|
||||
class="las la-exclamation-circle"
|
||||
[style.color]="theme === Theme.DARK ? policy.warnColorDark : policy.warnColor"
|
||||
></i>
|
||||
<span [style.color]="theme === Theme.DARK ? policy.warnColorDark : policy.warnColor">{{
|
||||
'POLICY.PRIVATELABELING.PREVIEW.ERROR' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<div class="btn-wrapper">
|
||||
<button
|
||||
mat-stroked-button
|
||||
[style.borderColor]="theme === Theme.DARK ? '#ffffff1f' : '#0000001f'"
|
||||
[style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor"
|
||||
>
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.SECONDARYBUTTON' | translate }}
|
||||
</button>
|
||||
<button
|
||||
*ngIf="theme === Theme.DARK"
|
||||
mat-raised-button
|
||||
[style.background]="policy.primaryColorDark"
|
||||
[style.color]="contrastTextColor"
|
||||
>
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.PRIMARYBUTTON' | translate }}
|
||||
</button>
|
||||
<button
|
||||
*ngIf="theme === Theme.LIGHT"
|
||||
mat-raised-button
|
||||
[style.background]="policy.primaryColor"
|
||||
[style.color]="contrastTextColor"
|
||||
>
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.PRIMARYBUTTON' | translate }}
|
||||
</button>
|
||||
@if (policy) {
|
||||
<div class="preview">
|
||||
<div
|
||||
class="dashed"
|
||||
[ngClass]="{ dark: theme === Theme.DARK, light: theme === Theme.LIGHT }"
|
||||
[style.background]="theme === Theme.DARK ? policy.backgroundColorDark : policy.backgroundColor"
|
||||
>
|
||||
<div class="login-wrapper" [style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor">
|
||||
@if (policy.logoUrl && theme === Theme.LIGHT) {
|
||||
<img [src]="policy.logoUrl" alt="logo-mock" />
|
||||
}
|
||||
@if (policy.logoUrlDark && theme === Theme.DARK) {
|
||||
<img [src]="policy.logoUrlDark" alt="logo-mock" />
|
||||
}
|
||||
<h1 [style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor">
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.TITLE' | translate }}
|
||||
</h1>
|
||||
<p [style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor" class="desc-text">
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.SECOND' | translate }}
|
||||
</p>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>Loginname</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
[style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor"
|
||||
value="road.runner"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
<div class="error-msg" [style.color]="theme === Theme.DARK ? policy.warnColorDark : policy.warnColor">
|
||||
<i
|
||||
class="las la-exclamation-circle"
|
||||
[style.color]="theme === Theme.DARK ? policy.warnColorDark : policy.warnColor"
|
||||
></i>
|
||||
<span [style.color]="theme === Theme.DARK ? policy.warnColorDark : policy.warnColor">{{
|
||||
'POLICY.PRIVATELABELING.PREVIEW.ERROR' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="btn-wrapper">
|
||||
<button
|
||||
mat-stroked-button
|
||||
[style.borderColor]="theme === Theme.DARK ? '#ffffff1f' : '#0000001f'"
|
||||
[style.color]="theme === Theme.DARK ? policy.fontColorDark : policy.fontColor"
|
||||
>
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.SECONDARYBUTTON' | translate }}
|
||||
</button>
|
||||
@if (theme === Theme.DARK) {
|
||||
<button mat-raised-button [style.background]="policy.primaryColorDark" [style.color]="contrastTextColor">
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.PRIMARYBUTTON' | translate }}
|
||||
</button>
|
||||
}
|
||||
@if (theme === Theme.LIGHT) {
|
||||
<button mat-raised-button [style.background]="policy.primaryColor" [style.color]="contrastTextColor">
|
||||
{{ 'POLICY.PRIVATELABELING.PREVIEW.PRIMARYBUTTON' | translate }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
+633
-635
File diff suppressed because it is too large
Load Diff
+68
-67
@@ -1,69 +1,66 @@
|
||||
<cnsl-card title="{{ 'SETTING.SECRETS.TYPE.' + generatorType | translate }}">
|
||||
<form *ngIf="specsForm" [formGroup]="specsForm" (ngSubmit)="saveSecretGenerator()">
|
||||
<cnsl-form-field class="generator-form-field" label="Expiration">
|
||||
<cnsl-label>{{ 'SETTING.SECRETS.EXPIRY' | translate }}</cnsl-label>
|
||||
<input cnslInput name="expiry" type="number" formControlName="expiry" id="{{ 'expiry' + generatorType }}" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="generator-form-field" label="Length">
|
||||
<cnsl-label>{{ 'SETTING.SECRETS.LENGTH' | translate }}</cnsl-label>
|
||||
<input cnslInput name="length" type="number" formControlName="length" id="{{ 'length' + generatorType }}" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<div class="slide-toggle-wrapper">
|
||||
<mat-slide-toggle
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="includeDigits"
|
||||
formControlName="includeDigits"
|
||||
id="{{ 'includeDigits' + generatorType }}"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_numeric"></mat-icon>
|
||||
<span class="left-desc">{{ 'SETTING.SECRETS.INCLUDEDIGITS' | translate }}</span>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-slide-toggle
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="includeSymbols"
|
||||
formControlName="includeSymbols"
|
||||
id="{{ 'includeSymbols' + generatorType }}"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_symbol"></mat-icon>
|
||||
<span class="left-desc">{{ 'SETTING.SECRETS.INCLUDESYMBOLS' | translate }}</span>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-slide-toggle
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="includeLowerLetters"
|
||||
formControlName="includeLowerLetters"
|
||||
id="{{ 'includeLowerLetters' + generatorType }}"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_format-letter-case-lower"></mat-icon>
|
||||
<span class="left-desc">{{ 'SETTING.SECRETS.INCLUDELOWERLETTERS' | translate }}</span>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-slide-toggle
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="includeUpperLetters"
|
||||
formControlName="includeUpperLetters"
|
||||
id="{{ 'includeUpperLetters' + generatorType }}"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_format-letter-case-upper"></mat-icon>
|
||||
<span class="left-desc">{{ 'SETTING.SECRETS.INCLUDEUPPERLETTERS' | translate }}</span>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
</form>
|
||||
@if (specsForm) {
|
||||
<form [formGroup]="specsForm" (ngSubmit)="saveSecretGenerator()">
|
||||
<cnsl-form-field class="generator-form-field" label="Expiration">
|
||||
<cnsl-label>{{ 'SETTING.SECRETS.EXPIRY' | translate }}</cnsl-label>
|
||||
<input cnslInput name="expiry" type="number" formControlName="expiry" id="{{ 'expiry' + generatorType }}" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="generator-form-field" label="Length">
|
||||
<cnsl-label>{{ 'SETTING.SECRETS.LENGTH' | translate }}</cnsl-label>
|
||||
<input cnslInput name="length" type="number" formControlName="length" id="{{ 'length' + generatorType }}" />
|
||||
</cnsl-form-field>
|
||||
<div class="slide-toggle-wrapper">
|
||||
<mat-slide-toggle
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="includeDigits"
|
||||
formControlName="includeDigits"
|
||||
id="{{ 'includeDigits' + generatorType }}"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_numeric"></mat-icon>
|
||||
<span class="left-desc">{{ 'SETTING.SECRETS.INCLUDEDIGITS' | translate }}</span>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
<mat-slide-toggle
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="includeSymbols"
|
||||
formControlName="includeSymbols"
|
||||
id="{{ 'includeSymbols' + generatorType }}"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_symbol"></mat-icon>
|
||||
<span class="left-desc">{{ 'SETTING.SECRETS.INCLUDESYMBOLS' | translate }}</span>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
<mat-slide-toggle
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="includeLowerLetters"
|
||||
formControlName="includeLowerLetters"
|
||||
id="{{ 'includeLowerLetters' + generatorType }}"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_format-letter-case-lower"></mat-icon>
|
||||
<span class="left-desc">{{ 'SETTING.SECRETS.INCLUDELOWERLETTERS' | translate }}</span>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
<mat-slide-toggle
|
||||
class="slide-toggle"
|
||||
color="primary"
|
||||
name="includeUpperLetters"
|
||||
formControlName="includeUpperLetters"
|
||||
id="{{ 'includeUpperLetters' + generatorType }}"
|
||||
>
|
||||
<div class="slide-toggle-row">
|
||||
<mat-icon class="icon" svgIcon="mdi_format-letter-case-upper"></mat-icon>
|
||||
<span class="left-desc">{{ 'SETTING.SECRETS.INCLUDEUPPERLETTERS' | translate }}</span>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
<div class="action">
|
||||
<button
|
||||
(click)="saveSecretGenerator()"
|
||||
@@ -73,8 +70,12 @@
|
||||
type="submit"
|
||||
id="{{ 'saveSecretGenerator' + generatorType }}"
|
||||
>
|
||||
<mat-spinner diameter="20" *ngIf="loading"></mat-spinner>
|
||||
<span *ngIf="!loading">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
@if (loading) {
|
||||
<mat-spinner diameter="20"></mat-spinner>
|
||||
}
|
||||
@if (!loading) {
|
||||
<span>{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
|
||||
@@ -2,5 +2,7 @@
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.SECRET_GENERATORS.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div class="generators">
|
||||
<cnsl-secret-generator-card *ngFor="let type of AVAILABLEGENERATORS" [generatorType]="type" />
|
||||
@for (type of AVAILABLEGENERATORS; track type) {
|
||||
<cnsl-secret-generator-card [generatorType]="type" />
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<p class="cnsl-secondary-text">{{ 'DESCRIPTIONS.SETTINGS.SECURITY.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<div class="spinner-wr">
|
||||
<mat-spinner diameter="30" *ngIf="loading" color="primary"></mat-spinner>
|
||||
@if (loading) {
|
||||
<mat-spinner diameter="30" color="primary"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="security-wrapper">
|
||||
@@ -40,14 +42,15 @@
|
||||
</form>
|
||||
|
||||
<div class="security-allowed-uris-list">
|
||||
<div *ngFor="let uri of originsList" class="uri-line" [ngClass]="{ disabled: !iframeEnabled }">
|
||||
<span class="uri">{{ uri }}</span>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<button matTooltip="{{ 'ACTIONS.DELETE' | translate }}" mat-icon-button (click)="remove(uri)" class="icon-button">
|
||||
<mat-icon class="icon">cancel</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
@for (uri of originsList; track uri) {
|
||||
<div class="uri-line" [ngClass]="{ disabled: !iframeEnabled }">
|
||||
<span class="uri">{{ uri }}</span>
|
||||
<span class="fill-space"></span>
|
||||
<button matTooltip="{{ 'ACTIONS.DELETE' | translate }}" mat-icon-button (click)="remove(uri)" class="icon-button">
|
||||
<mat-icon class="icon">cancel</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<h3>{{ 'SETTING.SECURITY.IMPERSONATIONTITLE' | translate }}</h3>
|
||||
|
||||
@@ -1,89 +1,88 @@
|
||||
<cnsl-detail-layout
|
||||
*ngIf="project"
|
||||
[hasBackButton]="true"
|
||||
title="{{ projectName }} {{ 'PROJECT.MEMBER.TITLE' | translate }}"
|
||||
>
|
||||
<p class="subinfo" sub>
|
||||
<span class="cnsl-secondary-text">{{ 'PROJECT.MEMBER.DESCRIPTION' | translate }}</span>
|
||||
<a mat-icon-button href="https://zitadel.com/docs/concepts/structure/administrators" target="_blank">
|
||||
<mat-icon class="icon">info_outline</mat-icon>
|
||||
</a>
|
||||
</p>
|
||||
<cnsl-members-table
|
||||
*ngIf="project"
|
||||
[dataSource]="dataSource"
|
||||
[memberRoleOptions]="memberRoleOptions"
|
||||
(updateRoles)="updateRoles($event.member, $event.change)"
|
||||
[factoryLoadFunc]="changePageFactory"
|
||||
(changedSelection)="selection = $event"
|
||||
[refreshTrigger]="changePage"
|
||||
[canWrite]="
|
||||
[
|
||||
'project.member.write$',
|
||||
'project.member.write:' + (projectType === ProjectType.PROJECTTYPE_OWNED)
|
||||
? $any(project)?.id
|
||||
: projectType === ProjectType.PROJECTTYPE_GRANTED
|
||||
? $any(project)?.projectId
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async
|
||||
"
|
||||
[canDelete]="
|
||||
[
|
||||
'project.member.delete$',
|
||||
'project.member.delete:' + (projectType === ProjectType.PROJECTTYPE_OWNED)
|
||||
? $any(project)?.id
|
||||
: projectType === ProjectType.PROJECTTYPE_GRANTED
|
||||
? $any(project)?.projectId
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async
|
||||
"
|
||||
(deleteMember)="removeProjectMember($event)"
|
||||
>
|
||||
<ng-template
|
||||
cnslHasRole
|
||||
selectactions
|
||||
[hasRole]="[
|
||||
'project.member.delete:' + (projectType === ProjectType.PROJECTTYPE_OWNED)
|
||||
? $any(project)?.id
|
||||
: projectType === ProjectType.PROJECTTYPE_GRANTED
|
||||
? $any(project)?.projectId
|
||||
: '',
|
||||
'project.member.delete',
|
||||
]"
|
||||
>
|
||||
<button
|
||||
(click)="removeProjectMemberSelection()"
|
||||
color="warn"
|
||||
matTooltip="{{ 'ORG_DETAIL.TABLE.DELETE' | translate }}"
|
||||
mat-raised-button
|
||||
@if (project) {
|
||||
<cnsl-detail-layout [hasBackButton]="true" title="{{ projectName }} {{ 'PROJECT.MEMBER.TITLE' | translate }}">
|
||||
<p class="subinfo" sub>
|
||||
<span class="cnsl-secondary-text">{{ 'PROJECT.MEMBER.DESCRIPTION' | translate }}</span>
|
||||
<a mat-icon-button href="https://zitadel.com/docs/concepts/structure/administrators" target="_blank">
|
||||
<mat-icon class="icon">info_outline</mat-icon>
|
||||
</a>
|
||||
</p>
|
||||
@if (project) {
|
||||
<cnsl-members-table
|
||||
[dataSource]="dataSource"
|
||||
[memberRoleOptions]="memberRoleOptions"
|
||||
(updateRoles)="updateRoles($event.member, $event.change)"
|
||||
[factoryLoadFunc]="changePageFactory"
|
||||
(changedSelection)="selection = $event"
|
||||
[refreshTrigger]="changePage"
|
||||
[canWrite]="
|
||||
[
|
||||
'project.member.write$',
|
||||
'project.member.write:' + (projectType === ProjectType.PROJECTTYPE_OWNED)
|
||||
? $any(project)?.id
|
||||
: projectType === ProjectType.PROJECTTYPE_GRANTED
|
||||
? $any(project)?.projectId
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async
|
||||
"
|
||||
[canDelete]="
|
||||
[
|
||||
'project.member.delete$',
|
||||
'project.member.delete:' + (projectType === ProjectType.PROJECTTYPE_OWNED)
|
||||
? $any(project)?.id
|
||||
: projectType === ProjectType.PROJECTTYPE_GRANTED
|
||||
? $any(project)?.projectId
|
||||
: '',
|
||||
]
|
||||
| hasRole
|
||||
| async
|
||||
"
|
||||
(deleteMember)="removeProjectMember($event)"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
<span>{{ 'ACTIONS.SELECTIONDELETE' | translate }}</span>
|
||||
<cnsl-action-keys [type]="ActionKeysType.DELETE" (actionTriggered)="removeProjectMemberSelection()">
|
||||
</cnsl-action-keys>
|
||||
</button>
|
||||
</ng-template>
|
||||
<ng-template
|
||||
cnslHasRole
|
||||
writeactions
|
||||
[hasRole]="[
|
||||
'project.member.write:' + (projectType === ProjectType.PROJECTTYPE_OWNED)
|
||||
? $any(project)?.id
|
||||
: projectType === ProjectType.PROJECTTYPE_GRANTED
|
||||
? $any(project)?.projectId
|
||||
: '',
|
||||
'project.member.write',
|
||||
]"
|
||||
>
|
||||
<button color="primary" (click)="openAddMember()" class="cnsl-action-button" mat-raised-button>
|
||||
<mat-icon class="icon">add</mat-icon>
|
||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||
<cnsl-action-keys (actionTriggered)="openAddMember()"> </cnsl-action-keys>
|
||||
</button>
|
||||
</ng-template>
|
||||
</cnsl-members-table>
|
||||
</cnsl-detail-layout>
|
||||
<ng-template
|
||||
cnslHasRole
|
||||
selectactions
|
||||
[hasRole]="[
|
||||
'project.member.delete:' + (projectType === ProjectType.PROJECTTYPE_OWNED)
|
||||
? $any(project)?.id
|
||||
: projectType === ProjectType.PROJECTTYPE_GRANTED
|
||||
? $any(project)?.projectId
|
||||
: '',
|
||||
'project.member.delete',
|
||||
]"
|
||||
>
|
||||
<button
|
||||
(click)="removeProjectMemberSelection()"
|
||||
color="warn"
|
||||
matTooltip="{{ 'ORG_DETAIL.TABLE.DELETE' | translate }}"
|
||||
mat-raised-button
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
<span>{{ 'ACTIONS.SELECTIONDELETE' | translate }}</span>
|
||||
<cnsl-action-keys [type]="ActionKeysType.DELETE" (actionTriggered)="removeProjectMemberSelection()">
|
||||
</cnsl-action-keys>
|
||||
</button>
|
||||
</ng-template>
|
||||
<ng-template
|
||||
cnslHasRole
|
||||
writeactions
|
||||
[hasRole]="[
|
||||
'project.member.write:' + (projectType === ProjectType.PROJECTTYPE_OWNED)
|
||||
? $any(project)?.id
|
||||
: projectType === ProjectType.PROJECTTYPE_GRANTED
|
||||
? $any(project)?.projectId
|
||||
: '',
|
||||
'project.member.write',
|
||||
]"
|
||||
>
|
||||
<button color="primary" (click)="openAddMember()" class="cnsl-action-button" mat-raised-button>
|
||||
<mat-icon class="icon">add</mat-icon>
|
||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||
<cnsl-action-keys (actionTriggered)="openAddMember()"> </cnsl-action-keys>
|
||||
</button>
|
||||
</ng-template>
|
||||
</cnsl-members-table>
|
||||
}
|
||||
</cnsl-detail-layout>
|
||||
}
|
||||
|
||||
+5
-3
@@ -4,9 +4,11 @@
|
||||
<p class="desc cnsl-secondary-text">{{ 'PROJECT.PAGES.PRIVATELABEL.DIALOG.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<mat-radio-group class="project-radio-group" [(ngModel)]="setting">
|
||||
<mat-radio-button class="radio-button" *ngFor="let selection of settings" [value]="selection">
|
||||
<span class="label">{{ 'PROJECT.PAGES.PRIVATELABEL.' + selection + '.TITLE' | translate }}</span>
|
||||
</mat-radio-button>
|
||||
@for (selection of settings; track selection) {
|
||||
<mat-radio-button class="radio-button" [value]="selection">
|
||||
<span class="label">{{ 'PROJECT.PAGES.PRIVATELABEL.' + selection + '.TITLE' | translate }}</span>
|
||||
</mat-radio-button>
|
||||
}
|
||||
</mat-radio-group>
|
||||
<cnsl-info-section class="info">{{ 'PROJECT.PAGES.PRIVATELABEL.' + setting + '.DESC' | translate }}</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
[style.borderColor]="role.color.hex + '30'"
|
||||
>
|
||||
<ng-content></ng-content>
|
||||
<button class="role-rm" mat-icon-button *ngIf="showRemove" (click)="emitRemove()">
|
||||
<mat-icon class="role-rm-icon">clear</mat-icon>
|
||||
</button>
|
||||
@if (showRemove) {
|
||||
<button class="role-rm" mat-icon-button (click)="emitRemove()">
|
||||
<mat-icon class="role-rm-icon">clear</mat-icon>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
+16
-14
@@ -3,20 +3,22 @@
|
||||
</h1>
|
||||
<p class="desc cnsl-secondary-text">{{ 'PROJECT.ROLE.EDITDESCRIPTION' | translate }}</p>
|
||||
<div mat-dialog-content>
|
||||
<form *ngIf="formGroup" class="role-detail-full-width" [formGroup]="formGroup" (ngSubmit)="submitForm()">
|
||||
<cnsl-form-field>
|
||||
<cnsl-label>{{ 'PROJECT.ROLE.KEY' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="key" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field>
|
||||
<cnsl-label>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="displayName" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field>
|
||||
<cnsl-label>{{ 'PROJECT.ROLE.GROUP' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="group" />
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
@if (formGroup) {
|
||||
<form class="role-detail-full-width" [formGroup]="formGroup" (ngSubmit)="submitForm()">
|
||||
<cnsl-form-field>
|
||||
<cnsl-label>{{ 'PROJECT.ROLE.KEY' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="key" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field>
|
||||
<cnsl-label>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="displayName" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field>
|
||||
<cnsl-label>{{ 'PROJECT.ROLE.GROUP' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="group" />
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions class="action">
|
||||
|
||||
@@ -1,142 +1,137 @@
|
||||
<cnsl-refresh-table
|
||||
[showSelectionActionButton]="showSelectionActionButton"
|
||||
*ngIf="projectId"
|
||||
(refreshed)="refreshPage()"
|
||||
[emitRefreshOnPreviousRoutes]="['/projects/' + projectId + '/roles/create']"
|
||||
[selection]="selection"
|
||||
[loading]="dataSource.loading$ | async"
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
>
|
||||
<ng-template cnslHasRole [hasRole]="['project.role.write:' + projectId, 'project.role.write']" actions>
|
||||
<a
|
||||
*ngIf="actionsVisible"
|
||||
[disabled]="disabled"
|
||||
[routerLink]="['/projects', projectId, 'roles', 'create']"
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
data-e2e="create-project-role-button"
|
||||
>
|
||||
<div class="cnsl-action-button">
|
||||
<mat-icon data-e2e="add-new-role" class="icon">add</mat-icon>
|
||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||
<cnsl-action-keys (actionTriggered)="gotoRouterLink(['/projects', projectId, 'roles', 'create'])">
|
||||
</cnsl-action-keys>
|
||||
</div>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<div class="table-wrapper">
|
||||
<table [dataSource]="dataSource" mat-table class="table" matSort aria-label="Elements">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="disabled"
|
||||
color="primary"
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="isAnySelected() && isAllSelected()"
|
||||
[indeterminate]="isAnySelected() && !isAllSelected()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
[disabled]="disabled"
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row.key) : null"
|
||||
[checked]="selection.isSelected(row.key)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="key">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.KEY' | translate }}</th>
|
||||
<td class="pointer" (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">
|
||||
<div class="role-key">
|
||||
<cnsl-project-role-chip [roleName]="role.key">{{ role.key }}</cnsl-project-role-chip>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="displayname">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</th>
|
||||
<td class="pointer" (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">{{ role.displayName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="group">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.GROUP' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let role" class="pointer">
|
||||
<span
|
||||
class="role state"
|
||||
[ngClass]="{ 'no-selection': !selectionAllowed }"
|
||||
*ngIf="role.group"
|
||||
(click)="selectionAllowed ? groupMasterToggle(role.group) : openDetailDialog(role)"
|
||||
[matTooltip]="selectionAllowed ? ('PROJECT.ROLE.SELECTGROUPTOOLTIP' | translate: role) : null"
|
||||
>{{ role.group }}</span
|
||||
>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="creationDate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.CREATIONDATE' | translate }}</th>
|
||||
<td class="pointer" (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">
|
||||
<span *ngIf="role?.details?.creationDate">{{
|
||||
role.details.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm'
|
||||
}}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="changeDate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.CHANGEDATE' | translate }}</th>
|
||||
<td class="pointer" (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">
|
||||
<span *ngIf="role?.details?.changeDate">{{
|
||||
role.details.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm'
|
||||
}}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef class="role-table-actions"></th>
|
||||
<td mat-cell *matCellDef="let role" class="role-table-actions">
|
||||
<cnsl-table-actions>
|
||||
<button
|
||||
actions
|
||||
[disabled]="
|
||||
disabled || (['project.role.delete', 'project.role.delete:' + projectId] | hasRole | async) === false
|
||||
"
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
matTooltip="{{ 'ACTIONS.DELETE' | translate }}"
|
||||
(click)="deleteRole(role)"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</cnsl-table-actions>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let role; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div *ngIf="(dataSource.loading$ | async) === false && !dataSource?.totalResult" class="no-content-row">
|
||||
<i class="las la-exclamation"></i>
|
||||
<span>{{ 'PROJECT.ROLE.EMPTY' | translate }}</span>
|
||||
</div>
|
||||
|
||||
<cnsl-paginator
|
||||
#paginator
|
||||
@if (projectId) {
|
||||
<cnsl-refresh-table
|
||||
[showSelectionActionButton]="showSelectionActionButton"
|
||||
(refreshed)="refreshPage()"
|
||||
[emitRefreshOnPreviousRoutes]="['/projects/' + projectId + '/roles/create']"
|
||||
[selection]="selection"
|
||||
[loading]="dataSource.loading$ | async"
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
[length]="dataSource.totalResult"
|
||||
[pageSize]="INITIAL_PAGE_SIZE"
|
||||
(page)="changePage()"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]"
|
||||
>
|
||||
</cnsl-paginator>
|
||||
</cnsl-refresh-table>
|
||||
<ng-template cnslHasRole [hasRole]="['project.role.write:' + projectId, 'project.role.write']" actions>
|
||||
@if (actionsVisible) {
|
||||
<a
|
||||
[disabled]="disabled"
|
||||
[routerLink]="['/projects', projectId, 'roles', 'create']"
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
data-e2e="create-project-role-button"
|
||||
>
|
||||
<div class="cnsl-action-button">
|
||||
<mat-icon data-e2e="add-new-role" class="icon">add</mat-icon>
|
||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||
<cnsl-action-keys (actionTriggered)="gotoRouterLink(['/projects', projectId, 'roles', 'create'])">
|
||||
</cnsl-action-keys>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
</ng-template>
|
||||
<div class="table-wrapper">
|
||||
<table [dataSource]="dataSource" mat-table class="table" matSort aria-label="Elements">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
[disabled]="disabled"
|
||||
color="primary"
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="isAnySelected() && isAllSelected()"
|
||||
[indeterminate]="isAnySelected() && !isAllSelected()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
[disabled]="disabled"
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row.key) : null"
|
||||
[checked]="selection.isSelected(row.key)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="key">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.KEY' | translate }}</th>
|
||||
<td class="pointer" (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">
|
||||
<div class="role-key">
|
||||
<cnsl-project-role-chip [roleName]="role.key">{{ role.key }}</cnsl-project-role-chip>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="displayname">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</th>
|
||||
<td class="pointer" (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">{{ role.displayName }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="group">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.GROUP' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let role" class="pointer">
|
||||
@if (role.group) {
|
||||
<span
|
||||
class="role state"
|
||||
[ngClass]="{ 'no-selection': !selectionAllowed }"
|
||||
(click)="selectionAllowed ? groupMasterToggle(role.group) : openDetailDialog(role)"
|
||||
[matTooltip]="selectionAllowed ? ('PROJECT.ROLE.SELECTGROUPTOOLTIP' | translate: role) : null"
|
||||
>{{ role.group }}</span
|
||||
>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="creationDate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.CREATIONDATE' | translate }}</th>
|
||||
<td class="pointer" (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">
|
||||
@if (role?.details?.creationDate) {
|
||||
<span>{{ role.details.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="changeDate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'PROJECT.ROLE.CHANGEDATE' | translate }}</th>
|
||||
<td class="pointer" (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">
|
||||
@if (role?.details?.changeDate) {
|
||||
<span>{{ role.details.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef class="role-table-actions"></th>
|
||||
<td mat-cell *matCellDef="let role" class="role-table-actions">
|
||||
<cnsl-table-actions>
|
||||
<button
|
||||
actions
|
||||
[disabled]="
|
||||
disabled || (['project.role.delete', 'project.role.delete:' + projectId] | hasRole | async) === false
|
||||
"
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
matTooltip="{{ 'ACTIONS.DELETE' | translate }}"
|
||||
(click)="deleteRole(role)"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</cnsl-table-actions>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let role; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
@if ((dataSource.loading$ | async) === false && !dataSource?.totalResult) {
|
||||
<div class="no-content-row">
|
||||
<i class="las la-exclamation"></i>
|
||||
<span>{{ 'PROJECT.ROLE.EMPTY' | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
<cnsl-paginator
|
||||
#paginator
|
||||
[timestamp]="dataSource.viewTimestamp"
|
||||
[length]="dataSource.totalResult"
|
||||
[pageSize]="INITIAL_PAGE_SIZE"
|
||||
(page)="changePage()"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]"
|
||||
>
|
||||
</cnsl-paginator>
|
||||
</cnsl-refresh-table>
|
||||
}
|
||||
|
||||
@@ -26,9 +26,11 @@
|
||||
<cnsl-info-section class="auto-reg-info">
|
||||
<p class="checkbox-desc">{{ 'IDP.OPTIONS.AUTOLINKING_DESC' | translate }}</p>
|
||||
<mat-select formControlName="autoLinking">
|
||||
<mat-option *ngFor="let linkingType of linkingTypes" [value]="linkingType">
|
||||
{{ 'IDP.OPTIONS.AUTOLINKINGTYPE.' + linkingType | translate }}
|
||||
</mat-option>
|
||||
@for (linkingType of linkingTypes; track linkingType) {
|
||||
<mat-option [value]="linkingType">
|
||||
{{ 'IDP.OPTIONS.AUTOLINKINGTYPE.' + linkingType | translate }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</cnsl-info-section>
|
||||
</form>
|
||||
|
||||
@@ -7,12 +7,16 @@
|
||||
<div class="attribute-more-row">
|
||||
<span>{{ 'ACTIONS.MORE' | translate }}</span>
|
||||
<button (click)="showMore = !showMore" type="button" mat-icon-button>
|
||||
<mat-icon *ngIf="showMore">keyboard_arrow_up</mat-icon>
|
||||
<mat-icon *ngIf="!showMore">keyboard_arrow_down</mat-icon>
|
||||
@if (showMore) {
|
||||
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||
}
|
||||
@if (!showMore) {
|
||||
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="showMore">
|
||||
@if (showMore) {
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.AVATARURLATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="avatarUrlAttribute" />
|
||||
@@ -61,5 +65,5 @@
|
||||
<cnsl-label>{{ 'IDP.PROFILEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="profileAttribute" />
|
||||
</cnsl-form-field>
|
||||
</ng-container>
|
||||
}
|
||||
</form>
|
||||
|
||||
@@ -7,15 +7,18 @@
|
||||
<img class="idp-logo apple dark" src="./assets/images/idp/apple-dark.svg" alt="apple" />
|
||||
<img class="idp-logo apple light" src="./assets/images/idp/apple.svg" alt="apple" />
|
||||
<h1>{{ 'IDP.CREATE.APPLE.TITLE' | translate }}</h1>
|
||||
<ng-container *ngIf="exists$ | async">
|
||||
<div
|
||||
*ngIf="{ isNotActive: (activateLink$ | async) } as idp"
|
||||
class="cnsl-state-dot"
|
||||
[matTooltip]="(idp.isNotActive ? 'IDP.STATES.2' : 'IDP.STATES.1') | translate"
|
||||
[ngClass]="{ active: !idp.isNotActive, inactive: !!idp.isNotActive }"
|
||||
></div>
|
||||
</ng-container>
|
||||
<mat-spinner diameter="25" *ngIf="loading" color="primary"></mat-spinner>
|
||||
@if (exists$ | async) {
|
||||
@if ({ isNotActive: (activateLink$ | async) }; as idp) {
|
||||
<div
|
||||
class="cnsl-state-dot"
|
||||
[matTooltip]="(idp.isNotActive ? 'IDP.STATES.2' : 'IDP.STATES.1') | translate"
|
||||
[ngClass]="{ active: !idp.isNotActive, inactive: !!idp.isNotActive }"
|
||||
></div>
|
||||
}
|
||||
}
|
||||
@if (loading) {
|
||||
<mat-spinner diameter="25" color="primary"></mat-spinner>
|
||||
}
|
||||
</div>
|
||||
|
||||
<cnsl-provider-next
|
||||
@@ -51,18 +54,19 @@
|
||||
<input cnslInput formControlName="keyId" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<mat-checkbox
|
||||
class="update-secret-checkbox"
|
||||
*ngIf="provider"
|
||||
[(ngModel)]="updatePrivateKey"
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
>{{ 'IDP.APPLE.UPDATEPRIVATEKEY' | translate }}</mat-checkbox
|
||||
>
|
||||
@if (provider) {
|
||||
<mat-checkbox
|
||||
class="update-secret-checkbox"
|
||||
[(ngModel)]="updatePrivateKey"
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
>{{ 'IDP.APPLE.UPDATEPRIVATEKEY' | translate }}</mat-checkbox
|
||||
>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="!provider || (provider && updatePrivateKey)">
|
||||
@if (!provider || (provider && updatePrivateKey)) {
|
||||
<span class="pk-label cnsl-secondary-text">{{ 'IDP.APPLE.PRIVATEKEY' | translate }}</span>
|
||||
<div class="private-key-wrapper">
|
||||
<ng-container *ngIf="privateKey?.value; else addLogoButton">
|
||||
@if (privateKey?.value) {
|
||||
<i class="las la-file"></i>
|
||||
<button
|
||||
class="dl-btn"
|
||||
@@ -73,8 +77,7 @@
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-template #addLogoButton>
|
||||
} @else {
|
||||
<input
|
||||
#keyFileInput
|
||||
style="display: none"
|
||||
@@ -91,56 +94,60 @@
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</ng-template>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<div class="identity-provider-optional-h-wrapper">
|
||||
<h2>{{ 'IDP.OPTIONAL' | translate }}</h2>
|
||||
<button (click)="showOptional = !showOptional" type="button" mat-icon-button>
|
||||
<mat-icon *ngIf="showOptional">keyboard_arrow_up</mat-icon
|
||||
><mat-icon *ngIf="!showOptional">keyboard_arrow_down</mat-icon>
|
||||
@if (showOptional) {
|
||||
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||
}
|
||||
@if (!showOptional) {
|
||||
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="showOptional">
|
||||
<div class="idp-scopes">
|
||||
<div class="flex-line">
|
||||
@if (showOptional) {
|
||||
<div>
|
||||
<div class="idp-scopes">
|
||||
<div class="flex-line">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.SCOPESLIST' | translate }}</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
[matChipInputFor]="chipScopesList"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addScope($event)"
|
||||
/>
|
||||
</cnsl-form-field>
|
||||
<button class="scope-add-button" (click)="addScope($any($event))" mat-icon-button>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.SCOPESLIST' | translate }}</cnsl-label>
|
||||
|
||||
<input
|
||||
cnslInput
|
||||
[matChipInputFor]="chipScopesList"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addScope($event)"
|
||||
/>
|
||||
<mat-chip-grid #chipScopesList aria-label="scope selection">
|
||||
@for (scope of scopesList?.value; track scope) {
|
||||
<mat-chip-row class="chip" removable (removed)="removeScope(scope)">
|
||||
{{ scope }} <mat-icon matChipRemove>cancel</mat-icon>
|
||||
</mat-chip-row>
|
||||
}
|
||||
</mat-chip-grid>
|
||||
</cnsl-form-field>
|
||||
<button class="scope-add-button" (click)="addScope($any($event))" mat-icon-button>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<mat-chip-grid #chipScopesList aria-label="scope selection">
|
||||
<mat-chip-row class="chip" *ngFor="let scope of scopesList?.value" removable (removed)="removeScope(scope)">
|
||||
{{ scope }} <mat-icon matChipRemove>cancel</mat-icon>
|
||||
</mat-chip-row>
|
||||
</mat-chip-grid>
|
||||
<cnsl-label>{{ 'IDP.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="name" />
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{ 'IDP.NAMEHINT' | translate }}</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-provider-options
|
||||
[initialOptions]="provider?.config?.options"
|
||||
(optionsChanged)="options = $event"
|
||||
></cnsl-provider-options>
|
||||
</div>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="name" />
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{ 'IDP.NAMEHINT' | translate }}</span>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-provider-options
|
||||
[initialOptions]="provider?.config?.options"
|
||||
(optionsChanged)="options = $event"
|
||||
></cnsl-provider-options>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
@@ -151,9 +158,9 @@
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="{ exists: (exists$ | async) } as idp">{{
|
||||
(!!idp.exists ? 'ACTIONS.SAVE' : 'ACTIONS.CREATE') | translate
|
||||
}}</span>
|
||||
@if ({ exists: (exists$ | async) }; as idp) {
|
||||
<span>{{ (!!idp.exists ? 'ACTIONS.SAVE' : 'ACTIONS.CREATE') | translate }}</span>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user