mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 11:04:25 +00:00
Merge remote-tracking branch 'origin/master' into new-eventstore
This commit is contained in:
commit
3bd4d3a8e3
@ -12,7 +12,7 @@
|
|||||||
},
|
},
|
||||||
"root": "",
|
"root": "",
|
||||||
"sourceRoot": "src",
|
"sourceRoot": "src",
|
||||||
"prefix": "app",
|
"prefix": "cnsl",
|
||||||
"architect": {
|
"architect": {
|
||||||
"build": {
|
"build": {
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
1775
console/package-lock.json
generated
1775
console/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -30,8 +30,8 @@
|
|||||||
"angular-oauth2-oidc": "^10.0.3",
|
"angular-oauth2-oidc": "^10.0.3",
|
||||||
"angularx-qrcode": "^10.0.11",
|
"angularx-qrcode": "^10.0.11",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.5",
|
||||||
"google-proto-files": "^2.2.0",
|
"google-proto-files": "^2.3.0",
|
||||||
"google-protobuf": "^3.13.0",
|
"google-protobuf": "^3.13.0",
|
||||||
"grpc": "^1.24.3",
|
"grpc": "^1.24.3",
|
||||||
"grpc-web": "^1.2.1",
|
"grpc-web": "^1.2.1",
|
||||||
@ -44,24 +44,24 @@
|
|||||||
"zone.js": "~0.11.3"
|
"zone.js": "~0.11.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "~0.1100.1",
|
"@angular-devkit/build-angular": "~0.1100.2",
|
||||||
"@angular/cli": "~11.0.1",
|
"@angular/cli": "~11.0.2",
|
||||||
"@angular/compiler-cli": "~11.0.0",
|
"@angular/compiler-cli": "~11.0.0",
|
||||||
"@angular/language-service": "~11.0.0",
|
"@types/jasmine": "~3.6.2",
|
||||||
"@types/jasmine": "~3.6.0",
|
"@angular/language-service": "~11.0.2",
|
||||||
"@types/jasminewd2": "~2.0.3",
|
"@types/jasminewd2": "~2.0.3",
|
||||||
"@types/node": "^14.14.6",
|
"@types/node": "^14.14.9",
|
||||||
"codelyzer": "^6.0.0",
|
"codelyzer": "^6.0.0",
|
||||||
"jasmine-core": "~3.6.0",
|
"jasmine-core": "~3.6.0",
|
||||||
"jasmine-spec-reporter": "~5.0.0",
|
"jasmine-spec-reporter": "~6.0.0",
|
||||||
"karma": "~5.2.3",
|
"karma": "~5.2.3",
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||||
"karma-jasmine": "~4.0.0",
|
"karma-jasmine": "~4.0.0",
|
||||||
"karma-jasmine-html-reporter": "^1.5.0",
|
"karma-jasmine-html-reporter": "^1.5.0",
|
||||||
"prettier": "^2.1.2",
|
"prettier": "^2.2.0",
|
||||||
"protractor": "~7.0.0",
|
"protractor": "~7.0.0",
|
||||||
"stylelint": "^13.7.2",
|
"stylelint": "^13.8.0",
|
||||||
"stylelint-config-standard": "^20.0.0",
|
"stylelint-config-standard": "^20.0.0",
|
||||||
"stylelint-scss": "^3.18.0",
|
"stylelint-scss": "^3.18.0",
|
||||||
"ts-node": "~9.0.0",
|
"ts-node": "~9.0.0",
|
||||||
|
@ -27,6 +27,23 @@ export const toolbarAnimation: AnimationTriggerMetadata =
|
|||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
export const adminLineAnimation: AnimationTriggerMetadata =
|
||||||
|
trigger('adminline', [
|
||||||
|
transition(':enter', [
|
||||||
|
style({
|
||||||
|
transform: 'translateY(100%)',
|
||||||
|
opacity: 0.5,
|
||||||
|
}),
|
||||||
|
animate(
|
||||||
|
'.2s ease-out',
|
||||||
|
style({
|
||||||
|
transform: 'translateY(0%)',
|
||||||
|
opacity: 1,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
export const accountCard: AnimationTriggerMetadata = trigger('accounts', [
|
export const accountCard: AnimationTriggerMetadata = trigger('accounts', [
|
||||||
transition(':enter', [
|
transition(':enter', [
|
||||||
style({
|
style({
|
||||||
|
@ -24,10 +24,11 @@
|
|||||||
</mat-spinner>
|
</mat-spinner>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-form-field class="filter-form" appearance="fill">
|
<div class="filter-wrapper">
|
||||||
<input matInput [formControl]="filterControl" autocomplete="off" (click)="$event.stopPropagation()"
|
<input cnslInput class="filter-input" [formControl]="filterControl" autocomplete="off"
|
||||||
placeholder="{{'ORG.PAGES.FILTERPLACEHOLDER' | translate}}" #input>
|
(click)="$event.stopPropagation()" placeholder="{{'ORG.PAGES.FILTERPLACEHOLDER' | translate}}"
|
||||||
</mat-form-field>
|
#input>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="org-wrapper">
|
<div class="org-wrapper">
|
||||||
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id"
|
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id"
|
||||||
@ -64,8 +65,9 @@
|
|||||||
<div class="side-column">
|
<div class="side-column">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<ng-container *ngIf="authenticationService.authenticationChanged | async">
|
<ng-container *ngIf="authenticationService.authenticationChanged | async">
|
||||||
<a @navitem class="nav-item" [routerLinkActive]="['active']"
|
<a @navitem matTooltip="{{'MENU.TOOLTIP.PERSONAL' | translate}}" class="nav-item"
|
||||||
[routerLinkActiveOptions]="{ exact: true }" [routerLink]="['/users/me']">
|
[routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
|
||||||
|
[routerLink]="['/users/me']">
|
||||||
<i class="icon las la-user-circle"></i>
|
<i class="icon las la-user-circle"></i>
|
||||||
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
||||||
</a>
|
</a>
|
||||||
@ -77,7 +79,8 @@
|
|||||||
<span>{{'MENU.ADMINSECTION' | translate}}</span>
|
<span>{{'MENU.ADMINSECTION' | translate}}</span>
|
||||||
<div class="hiddenline"></div>
|
<div class="hiddenline"></div>
|
||||||
</div>
|
</div>
|
||||||
<a @navitem class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/iam']">
|
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAM' | translate}}" class="nav-item"
|
||||||
|
[routerLinkActive]="['active']" [routerLink]="[ '/iam']">
|
||||||
<i class="icon las la-gem"></i>
|
<i class="icon las la-gem"></i>
|
||||||
<span class="label">{{'MENU.IAM' | translate}}</span>
|
<span class="label">{{'MENU.IAM' | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
@ -85,7 +88,14 @@
|
|||||||
|
|
||||||
<div *ngIf="org" [@navAnimation]="org">
|
<div *ngIf="org" [@navAnimation]="org">
|
||||||
<ng-template appHasRole [appHasRole]="['org.read']">
|
<ng-template appHasRole [appHasRole]="['org.read']">
|
||||||
<a @navitem class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
<div @navitem class="divider">
|
||||||
|
<div class="line"></div>
|
||||||
|
<span>{{'MENU.ORGSECTION' | translate}}</span>
|
||||||
|
<div class="hiddenline"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a @navitem matTooltip="{{'MENU.TOOLTIP.ORG' | translate}}" class="nav-item"
|
||||||
|
[routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
||||||
<i class="icon las la-archway"></i>
|
<i class="icon las la-archway"></i>
|
||||||
<span
|
<span
|
||||||
class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
|
class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
|
||||||
@ -93,13 +103,8 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['project.read(:[0-9]*)?']">
|
<ng-template appHasRole [appHasRole]="['project.read(:[0-9]*)?']">
|
||||||
<div @navitem class="divider">
|
<a @navitem matTooltip="{{'MENU.TOOLTIP.SELFPROJECTS' | translate}}"
|
||||||
<div class="line"></div>
|
class="nav-item indented" [routerLinkActive]="['active']"
|
||||||
<span>{{'MENU.PROJECTSSECTION' | translate}}</span>
|
|
||||||
<div class="hiddenline"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a @navitem class="nav-item" [routerLinkActive]="['active']"
|
|
||||||
[routerLink]="[ '/projects']">
|
[routerLink]="[ '/projects']">
|
||||||
<i class="icon las la-layer-group"></i>
|
<i class="icon las la-layer-group"></i>
|
||||||
|
|
||||||
@ -111,9 +116,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a @navitem
|
<a @navitem matTooltip="{{'MENU.TOOLTIP.GRANTEDPROJECTS' | translate}}"
|
||||||
*ngIf="mgmtService?.grantedProjectsCount && (mgmtService?.grantedProjectsCount | async)"
|
*ngIf="mgmtService?.grantedProjectsCount && (mgmtService?.grantedProjectsCount | async)"
|
||||||
class="nav-item" [routerLinkActive]="['active']"
|
class="nav-item indented" [routerLinkActive]="['active']"
|
||||||
[routerLink]="[ '/granted-projects']">
|
[routerLink]="[ '/granted-projects']">
|
||||||
<i class="icon las la-layer-group"></i>
|
<i class="icon las la-layer-group"></i>
|
||||||
<div class="c_label">
|
<div class="c_label">
|
||||||
@ -124,20 +129,15 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['user.read(:[0-9]*)?']">
|
<ng-template appHasRole [appHasRole]="['user.read(:[0-9]*)?']">
|
||||||
<div @navitem class="divider">
|
<a @navitem matTooltip="{{'MENU.TOOLTIP.HUMANUSERS' | translate}}"
|
||||||
<div class="line"></div>
|
class="nav-item indented" [routerLinkActive]="['active']"
|
||||||
<span class="label">
|
|
||||||
{{ 'MENU.USERSECTION' | translate }}</span>
|
|
||||||
<div class="hiddenline"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a @navitem class="nav-item" [routerLinkActive]="['active']"
|
|
||||||
[routerLink]="[ '/users/list/humans']" [routerLinkActiveOptions]="{ exact: true }">
|
[routerLink]="[ '/users/list/humans']" [routerLinkActiveOptions]="{ exact: true }">
|
||||||
<i class="icon las la-user-friends"></i>
|
<i class="icon las la-user-friends"></i>
|
||||||
<span class="label">{{ 'MENU.HUMANUSERS' | translate }}</span>
|
<span class="label">{{ 'MENU.HUMANUSERS' | translate }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a @navitem class="nav-item" [routerLinkActive]="['active']"
|
<a @navitem matTooltip="{{'MENU.TOOLTIP.MACHINEUSERS' | translate}}"
|
||||||
|
class="nav-item indented" [routerLinkActive]="['active']"
|
||||||
[routerLink]="[ '/users/list/machines']"
|
[routerLink]="[ '/users/list/machines']"
|
||||||
[routerLinkActiveOptions]="{ exact: true }">
|
[routerLinkActiveOptions]="{ exact: true }">
|
||||||
<i class="icon las la-users-cog"></i>
|
<i class="icon las la-users-cog"></i>
|
||||||
@ -146,15 +146,15 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['user.grant.read(:[0-9]*)?']">
|
<ng-template appHasRole [appHasRole]="['user.grant.read(:[0-9]*)?']">
|
||||||
<div @navitem class="divider">
|
<!-- <div @navitem class="divider">
|
||||||
<div class="line"></div>
|
<div class="line"></div>
|
||||||
<span class="label">
|
<span class="label">
|
||||||
{{ 'MENU.GRANTSECTION' | translate }}</span>
|
{{ 'MENU.GRANTSECTION' | translate }}</span>
|
||||||
<div class="hiddenline"></div>
|
<div class="hiddenline"></div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<a @navitem class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/grants']"
|
<a @navitem class="nav-item indented" [routerLinkActive]="['active']"
|
||||||
[routerLinkActiveOptions]="{ exact: true }">
|
[routerLink]="[ '/grants']" [routerLinkActiveOptions]="{ exact: true }">
|
||||||
<i class="icon las la-shield-alt"></i>
|
<i class="icon las la-shield-alt"></i>
|
||||||
<span class="label">{{ 'MENU.GRANTS' | translate }}</span>
|
<span class="label">{{ 'MENU.GRANTS' | translate }}</span>
|
||||||
</a>
|
</a>
|
||||||
@ -172,7 +172,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</mat-drawer-content>
|
</mat-drawer-content>
|
||||||
</mat-drawer-container>
|
</mat-drawer-container>
|
||||||
<div @toolbar *ngIf="iamuser$ | async" class="admin-line" [ngClass]="{'expanded': !hideAdminWarn}"
|
<div @adminline *ngIf="iamuser$ | async" class="admin-line" [ngClass]="{'expanded': !hideAdminWarn}"
|
||||||
matTooltip="IAM Administrator">
|
matTooltip="IAM Administrator">
|
||||||
<button [matTooltip]="!hideAdminWarn ? 'Unpin': 'Pin'" (click)="toggleAdminHide()" mat-icon-button>
|
<button [matTooltip]="!hideAdminWarn ? 'Unpin': 'Pin'" (click)="toggleAdminHide()" mat-icon-button>
|
||||||
<mat-icon *ngIf="!hideAdminWarn" svgIcon="mdi_pin"></mat-icon>
|
<mat-icon *ngIf="!hideAdminWarn" svgIcon="mdi_pin"></mat-icon>
|
||||||
|
@ -103,17 +103,21 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: .2rem 1rem;
|
padding: 0 1rem;
|
||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
|
|
||||||
|
&.indented {
|
||||||
|
padding-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin: .5rem 1rem;
|
margin: .5rem 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
font-weight: 500;
|
font-size: 14px;
|
||||||
font-size: .9rem;
|
letter-spacing: .05em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c_label {
|
.c_label {
|
||||||
@ -121,7 +125,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: .9rem;
|
font-size: 14px;
|
||||||
|
letter-spacing: .03em;
|
||||||
|
|
||||||
.count {
|
.count {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -198,7 +203,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: .5rem 0;
|
margin: 5px 0;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
border: 1px solid #81868a40;
|
border: 1px solid #81868a40;
|
||||||
@ -219,7 +224,6 @@
|
|||||||
.hiddenline {
|
.hiddenline {
|
||||||
display: block;
|
display: block;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
// flex: 1;
|
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +232,6 @@
|
|||||||
.filter-form {
|
.filter-form {
|
||||||
margin: 0 .5rem;
|
margin: 0 .5rem;
|
||||||
/* stylelint-disable */
|
/* stylelint-disable */
|
||||||
|
|
||||||
$foreground: map-get($theme, foreground);
|
$foreground: map-get($theme, foreground);
|
||||||
color: mat-color($foreground, text) !important;
|
color: mat-color($foreground, text) !important;
|
||||||
}
|
}
|
||||||
@ -245,6 +248,10 @@
|
|||||||
.menu {
|
.menu {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
.filter-wrapper {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.spinner-w {
|
.spinner-w {
|
||||||
top: 1rem;
|
top: 1rem;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -11,7 +11,7 @@ import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
|
|||||||
import { BehaviorSubject, from, Observable, of, Subscription } from 'rxjs';
|
import { BehaviorSubject, from, Observable, of, Subscription } from 'rxjs';
|
||||||
import { catchError, debounceTime, finalize, map, take } from 'rxjs/operators';
|
import { catchError, debounceTime, finalize, map, take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { accountCard, navAnimations, routeAnimations, toolbarAnimation } from './animations';
|
import { accountCard, adminLineAnimation, navAnimations, routeAnimations, toolbarAnimation } from './animations';
|
||||||
import {
|
import {
|
||||||
MyProjectOrgSearchKey,
|
MyProjectOrgSearchKey,
|
||||||
MyProjectOrgSearchQuery,
|
MyProjectOrgSearchQuery,
|
||||||
@ -34,6 +34,7 @@ import { UpdateService } from './services/update.service';
|
|||||||
...navAnimations,
|
...navAnimations,
|
||||||
accountCard,
|
accountCard,
|
||||||
routeAnimations,
|
routeAnimations,
|
||||||
|
adminLineAnimation,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnDestroy {
|
export class AppComponent implements OnDestroy {
|
||||||
|
@ -8,9 +8,7 @@ import { MatButtonModule } from '@angular/material/button';
|
|||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { MatNativeDateModule } from '@angular/material/core';
|
import { MatNativeDateModule } from '@angular/material/core';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
@ -34,6 +32,7 @@ import { HasRoleModule } from './directives/has-role/has-role.module';
|
|||||||
import { OutsideClickModule } from './directives/outside-click/outside-click.module';
|
import { OutsideClickModule } from './directives/outside-click/outside-click.module';
|
||||||
import { AccountsCardModule } from './modules/accounts-card/accounts-card.module';
|
import { AccountsCardModule } from './modules/accounts-card/accounts-card.module';
|
||||||
import { AvatarModule } from './modules/avatar/avatar.module';
|
import { AvatarModule } from './modules/avatar/avatar.module';
|
||||||
|
import { InputModule } from './modules/input/input.module';
|
||||||
import { WarnDialogModule } from './modules/warn-dialog/warn-dialog.module';
|
import { WarnDialogModule } from './modules/warn-dialog/warn-dialog.module';
|
||||||
import { SignedoutComponent } from './pages/signedout/signedout.component';
|
import { SignedoutComponent } from './pages/signedout/signedout.component';
|
||||||
import { HasRolePipeModule } from './pipes/has-role-pipe/has-role-pipe.module';
|
import { HasRolePipeModule } from './pipes/has-role-pipe/has-role-pipe.module';
|
||||||
@ -110,8 +109,7 @@ const authConfig: AuthConfig = {
|
|||||||
MatSidenavModule,
|
MatSidenavModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
OutsideClickModule,
|
OutsideClickModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatInputModule,
|
|
||||||
HasRolePipeModule,
|
HasRolePipeModule,
|
||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
|
@ -6,15 +6,15 @@
|
|||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<!-- if no context -->
|
<!-- if no context -->
|
||||||
<ng-container *ngIf="showCreationTypeSelector">
|
<ng-container *ngIf="showCreationTypeSelector">
|
||||||
<mat-form-field class="full-width" appearance="outline">
|
<cnsl-form-field class="full-width" appearance="outline">
|
||||||
<mat-label>{{ 'MEMBER.CREATIONTYPE' | translate }}</mat-label>
|
<cnsl-label>{{ 'MEMBER.CREATIONTYPE' | translate }}</cnsl-label>
|
||||||
<mat-select [(ngModel)]="creationType" (selectionChange)="loadRoles()">
|
<mat-select [(ngModel)]="creationType" (selectionChange)="loadRoles()">
|
||||||
<mat-option *ngFor="let type of creationTypes" [value]="type.type"
|
<mat-option *ngFor="let type of creationTypes" [value]="type.type"
|
||||||
[disabled]="(type.disabled$ | async) == false">
|
[disabled]="(type.disabled$ | async) == false">
|
||||||
{{ 'MEMBER.CREATIONTYPES.'+type.type | translate}}
|
{{ 'MEMBER.CREATIONTYPES.'+type.type | translate}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngIf="creationType === CreationType.PROJECT_OWNED || creationType === CreationType.PROJECT_GRANTED">
|
*ngIf="creationType === CreationType.PROJECT_OWNED || creationType === CreationType.PROJECT_GRANTED">
|
||||||
@ -30,15 +30,15 @@
|
|||||||
<app-search-user-autocomplete [users]="preselectedUsers" (selectionChanged)="users = $event">
|
<app-search-user-autocomplete [users]="preselectedUsers" (selectionChanged)="users = $event">
|
||||||
</app-search-user-autocomplete>
|
</app-search-user-autocomplete>
|
||||||
|
|
||||||
<mat-form-field class="full-width" appearance="outline"
|
<cnsl-form-field class="full-width" appearance="outline"
|
||||||
*ngIf="creationType === CreationType.PROJECT_OWNED || creationType === CreationType.PROJECT_GRANTED || creationType === CreationType.IAM">
|
*ngIf="creationType === CreationType.PROJECT_OWNED || creationType === CreationType.PROJECT_GRANTED || creationType === CreationType.IAM">
|
||||||
<mat-label>{{ 'ROLESLABEL' | translate }}</mat-label>
|
<cnsl-label>{{ 'ROLESLABEL' | translate }}</cnsl-label>
|
||||||
<mat-select [(ngModel)]="roles" multiple>
|
<mat-select [(ngModel)]="roles" multiple>
|
||||||
<mat-option *ngFor="let role of memberRoleOptions" [value]="role">
|
<mat-option *ngFor="let role of memberRoleOptions" [value]="role">
|
||||||
{{ role }}
|
{{ role }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<ng-container *ngIf="creationType === CreationType.ORG">
|
<ng-container *ngIf="creationType === CreationType.ORG">
|
||||||
<app-org-member-roles-autocomplete (selectionChanged)="setOrgMemberRoles($event)">
|
<app-org-member-roles-autocomplete (selectionChanged)="setOrgMemberRoles($event)">
|
||||||
|
@ -4,10 +4,9 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { SearchUserAutocompleteModule } from 'src/app/modules/search-user-autocomplete/search-user-autocomplete.module';
|
import { SearchUserAutocompleteModule } from 'src/app/modules/search-user-autocomplete/search-user-autocomplete.module';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -24,9 +23,8 @@ import { MemberCreateDialogComponent } from './member-create-dialog.component';
|
|||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
MatInputModule,
|
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div class="avatar-circle dontcloseonclick" matRipple [matRippleColor]="'#ffffff20'" matRippleUnbounded="true"
|
<div class="avatar-circle dontcloseonclick" matRipple [matRippleColor]="'#ffffff20'" matRippleUnbounded="true"
|
||||||
matRippleCentered="true"
|
matRippleCentered="true"
|
||||||
[ngStyle]="{'height': size+'px', 'width': size+'px', 'fontSize': (fontSize-1)+'px', 'background-color': color}"
|
[ngStyle]="{'height': size+'px', 'width': size+'px', 'fontSize': (fontSize-1)+'px', 'background': color}"
|
||||||
[ngClass]="{'active': active}">
|
[ngClass]="{'active': active}">
|
||||||
{{credentials}}
|
{{credentials}}
|
||||||
</div>
|
</div>
|
@ -13,7 +13,10 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
background-color: $primary-color;
|
background-color: $primary-color;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
letter-spacing: .05em;
|
||||||
|
font-size: 14px;
|
||||||
outline: none;
|
outline: none;
|
||||||
color: white;
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ export class AvatarComponent implements OnInit {
|
|||||||
@Input() name: string = '';
|
@Input() name: string = '';
|
||||||
@Input() credentials: string = '';
|
@Input() credentials: string = '';
|
||||||
@Input() size: number = 24;
|
@Input() size: number = 24;
|
||||||
@Input() fontSize: number = 16;
|
@Input() fontSize: number = 14;
|
||||||
@Input() active: boolean = false;
|
@Input() active: boolean = false;
|
||||||
@Input() color: string = '';
|
@Input() color: string = '';
|
||||||
constructor() { }
|
constructor() { }
|
||||||
@ -30,22 +30,22 @@ export class AvatarComponent implements OnInit {
|
|||||||
|
|
||||||
getColor(userName: string): string {
|
getColor(userName: string): string {
|
||||||
const colors = [
|
const colors = [
|
||||||
'#B44D51',
|
'linear-gradient(40deg, #B44D51 30%, rgb(241,138,138))',
|
||||||
'#B75073',
|
'linear-gradient(40deg, #B75073 30%, rgb(234,96,143))',
|
||||||
'#84498E',
|
'linear-gradient(40deg, #84498E 30%, rgb(214,116,230))',
|
||||||
'#705998',
|
'linear-gradient(40deg, #705998 30%, rgb(163,131,220))',
|
||||||
'#5C6598',
|
'linear-gradient(40deg, #5C6598 30%, rgb(135,148,222))',
|
||||||
'#7F90D3',
|
'linear-gradient(40deg, #7F90D3 30%, rgb(181,196,247))',
|
||||||
'#3E93B9',
|
'linear-gradient(40deg, #3E93B9 30%, rgb(150,215,245))',
|
||||||
'#3494A0',
|
'linear-gradient(40deg, #3494A0 30%, rgb(71,205,222))',
|
||||||
'#25716A',
|
'linear-gradient(40deg, #25716A 30%, rgb(58,185,173))',
|
||||||
'#427E41',
|
'linear-gradient(40deg, #427E41 30%, rgb(97,185,96))',
|
||||||
'#89A568',
|
'linear-gradient(40deg, #89A568 30%, rgb(176,212,133))',
|
||||||
'#90924D',
|
'linear-gradient(40deg, #90924D 30%, rgb(187,189,98))',
|
||||||
'#E2B032',
|
'linear-gradient(40deg, #E2B032 30%, rgb(245,203,99))',
|
||||||
'#C97358',
|
'linear-gradient(40deg, #C97358 30%, rgb(245,148,118))',
|
||||||
'#6D5B54',
|
'linear-gradient(40deg, #6D5B54 30%, rgb(152,121,108))',
|
||||||
'#6B7980',
|
'linear-gradient(40deg, #6B7980 30%, rgb(134,163,177))',
|
||||||
];
|
];
|
||||||
|
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
min-width: 350px;
|
min-width: 300px;
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@ -21,7 +21,9 @@
|
|||||||
.title {
|
.title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 18px;
|
font-size: 16px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .05em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fill-space {
|
.fill-space {
|
||||||
@ -45,4 +47,9 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 500px) {
|
||||||
|
margin: .5rem 0;
|
||||||
|
padding: .5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
<span class="header">{{ 'CHANGES.LISTTITLE' | translate }}</span>
|
<div class="change-header">
|
||||||
|
<span class="ch-header">{{ 'CHANGES.LISTTITLE' | translate }}</span>
|
||||||
|
<button matTooltip="{{'ACTIONS.REFRESH' | translate}}" (click)="init()" mat-icon-button>
|
||||||
|
<mat-icon class="icon">refresh</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="scroll-container" appScrollable (scrollPosition)="scrollHandler($event)">
|
<div class="scroll-container" appScrollable (scrollPosition)="scrollHandler($event)">
|
||||||
<li class="item change-item-back" *ngFor="let event of data | async">
|
<li class="item change-item-back" *ngFor="let event of data | async">
|
||||||
|
@ -1,11 +1,23 @@
|
|||||||
@import '~@angular/material/theming';
|
@import '~@angular/material/theming';
|
||||||
|
|
||||||
.header {
|
.change-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.ch-header {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
letter-spacing: .05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin changes-theme($theme) {
|
@mixin changes-theme($theme) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { BehaviorSubject, from, Observable, of } from 'rxjs';
|
import { BehaviorSubject, from, Observable, of, Subject } from 'rxjs';
|
||||||
import { catchError, scan, take, tap } from 'rxjs/operators';
|
import { catchError, debounceTime, scan, take, takeUntil, tap } from 'rxjs/operators';
|
||||||
import { Change, Changes } from 'src/app/proto/generated/management_pb';
|
import { Change, Changes } from 'src/app/proto/generated/management_pb';
|
||||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
@ -10,6 +10,7 @@ export enum ChangeType {
|
|||||||
USER = 'user',
|
USER = 'user',
|
||||||
ORG = 'org',
|
ORG = 'org',
|
||||||
PROJECT = 'project',
|
PROJECT = 'project',
|
||||||
|
APP = 'app',
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -17,10 +18,12 @@ export enum ChangeType {
|
|||||||
templateUrl: './changes.component.html',
|
templateUrl: './changes.component.html',
|
||||||
styleUrls: ['./changes.component.scss'],
|
styleUrls: ['./changes.component.scss'],
|
||||||
})
|
})
|
||||||
export class ChangesComponent implements OnInit {
|
export class ChangesComponent implements OnInit, OnDestroy {
|
||||||
@Input() public changeType: ChangeType = ChangeType.USER;
|
@Input() public changeType: ChangeType = ChangeType.USER;
|
||||||
@Input() public id: string = '';
|
@Input() public id: string = '';
|
||||||
|
@Input() public secId: string = '';
|
||||||
@Input() public sortDirectionAsc: boolean = true;
|
@Input() public sortDirectionAsc: boolean = true;
|
||||||
|
@Input() public refresh!: Observable<void>;
|
||||||
public bottom: boolean = false;
|
public bottom: boolean = false;
|
||||||
|
|
||||||
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
|
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||||
@ -30,10 +33,23 @@ export class ChangesComponent implements OnInit {
|
|||||||
loading: Observable<boolean> = this._loading.asObservable();
|
loading: Observable<boolean> = this._loading.asObservable();
|
||||||
public data!: Observable<Change.AsObject[]>;
|
public data!: Observable<Change.AsObject[]>;
|
||||||
public changes!: Changes.AsObject;
|
public changes!: Changes.AsObject;
|
||||||
constructor(private mgmtUserService: ManagementService, private authUserService: GrpcAuthService) { }
|
private destroyed$: Subject<void> = new Subject();
|
||||||
|
constructor(private mgmtUserService: ManagementService, private authUserService: GrpcAuthService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.init();
|
this.init();
|
||||||
|
if (this.refresh) {
|
||||||
|
this.refresh.pipe(takeUntil(this.destroyed$), debounceTime(2000)).subscribe(() => {
|
||||||
|
console.log('asdf');
|
||||||
|
this.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.destroyed$.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
public scrollHandler(e: any): void {
|
public scrollHandler(e: any): void {
|
||||||
@ -42,7 +58,7 @@ export class ChangesComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private init(): void {
|
public init(): void {
|
||||||
let first: Promise<Changes>;
|
let first: Promise<Changes>;
|
||||||
switch (this.changeType) {
|
switch (this.changeType) {
|
||||||
case ChangeType.MYUSER: first = this.authUserService.GetMyUserChanges(20, 0);
|
case ChangeType.MYUSER: first = this.authUserService.GetMyUserChanges(20, 0);
|
||||||
@ -53,6 +69,8 @@ export class ChangesComponent implements OnInit {
|
|||||||
break;
|
break;
|
||||||
case ChangeType.ORG: first = this.mgmtUserService.OrgChanges(this.id, 20, 0);
|
case ChangeType.ORG: first = this.mgmtUserService.OrgChanges(this.id, 20, 0);
|
||||||
break;
|
break;
|
||||||
|
case ChangeType.APP: first = this.mgmtUserService.ApplicationChanges(this.id, this.secId, 20, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mapAndUpdate(first);
|
this.mapAndUpdate(first);
|
||||||
@ -78,6 +96,8 @@ export class ChangesComponent implements OnInit {
|
|||||||
break;
|
break;
|
||||||
case ChangeType.ORG: more = this.mgmtUserService.OrgChanges(this.id, 20, cursor);
|
case ChangeType.ORG: more = this.mgmtUserService.OrgChanges(this.id, 20, cursor);
|
||||||
break;
|
break;
|
||||||
|
case ChangeType.APP: more = this.mgmtUserService.ApplicationChanges(this.id, this.secId, 20, cursor);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mapAndUpdate(more);
|
this.mapAndUpdate(more);
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { ScrollingModule } from '@angular/cdk/scrolling';
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { ScrollableModule } from 'src/app/directives/scrollable/scrollable.module';
|
import { ScrollableModule } from 'src/app/directives/scrollable/scrollable.module';
|
||||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||||
@ -20,10 +23,13 @@ import { ChangesComponent } from './changes.component';
|
|||||||
ScrollableModule,
|
ScrollableModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatButtonModule,
|
||||||
HasRolePipeModule,
|
HasRolePipeModule,
|
||||||
ScrollingModule,
|
ScrollingModule,
|
||||||
LocalizedDatePipeModule,
|
LocalizedDatePipeModule,
|
||||||
TimestampToDatePipeModule,
|
TimestampToDatePipeModule,
|
||||||
|
MatTooltipModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
ChangesComponent,
|
ChangesComponent,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="groups">
|
<div class="groups">
|
||||||
<span class="header">{{ title }}</span>
|
<span class="co-header">{{ title }}</span>
|
||||||
<span class="sub-header">{{ description }}</span>
|
<span class="sub-header">{{ description }}</span>
|
||||||
<div class="people">
|
<div class="people">
|
||||||
<div class="img-list" [@cardAnimation]="totalResult">
|
<div class="img-list" [@cardAnimation]="totalResult">
|
||||||
@ -34,9 +34,9 @@
|
|||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
<button class="refresh-img" (click)="emitRefresh()" [disabled]="disabled" mat-icon-button
|
<button matTooltip="{{'ACTIONS.REFRESH' | translate}}" class="refresh-img" (click)="emitRefresh()"
|
||||||
aria-label="refresh contributors">
|
[disabled]="disabled" mat-icon-button aria-label="refresh contributors">
|
||||||
<mat-icon>refresh</mat-icon>
|
<mat-icon class="icon">refresh</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
.groups {
|
.groups {
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
|
|
||||||
.header {
|
.co-header {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
letter-spacing: .05em;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sub-header {
|
.sub-header {
|
||||||
@ -45,7 +48,11 @@
|
|||||||
|
|
||||||
.refresh-img {
|
.refresh-img {
|
||||||
float: left;
|
float: left;
|
||||||
margin: 0 8px 0 -15px;
|
margin: 0 0 0 -15px;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-circle {
|
.avatar-circle {
|
||||||
|
@ -4,6 +4,7 @@ import { MatButtonModule } from '@angular/material/button';
|
|||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { AvatarModule } from '../avatar/avatar.module';
|
import { AvatarModule } from '../avatar/avatar.module';
|
||||||
import { ContributorsComponent } from './contributors.component';
|
import { ContributorsComponent } from './contributors.component';
|
||||||
@ -19,6 +20,7 @@ import { ContributorsComponent } from './contributors.component';
|
|||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
|
TranslateModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
ContributorsComponent,
|
ContributorsComponent,
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
padding-bottom: 3rem;
|
padding-bottom: 3rem;
|
||||||
|
|
||||||
.detail-left {
|
.detail-left {
|
||||||
|
align-self: flex-start;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
18
console/src/app/modules/form-field/animations.ts
Normal file
18
console/src/app/modules/form-field/animations.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { animate, AnimationTriggerMetadata, state, style, transition, trigger } from '@angular/animations';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animations used by the CnslFormFieldComponent.
|
||||||
|
*/
|
||||||
|
export const cnslFormFieldAnimations: {
|
||||||
|
readonly transitionMessages: AnimationTriggerMetadata;
|
||||||
|
} = {
|
||||||
|
/** Animation that transitions the form field's error and hint messages. */
|
||||||
|
transitionMessages: trigger('transitionMessages', [
|
||||||
|
// TODO(mmalerba): Use angular animations for label animation as well.
|
||||||
|
state('enter', style({ opacity: 1, transform: 'translateY(0%)' })),
|
||||||
|
transition('void => enter', [
|
||||||
|
style({ opacity: 0, transform: 'translateY(-100%)' }),
|
||||||
|
animate('3000ms cubic-bezier(0.55, 0, 0.55, 0.2)'),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
};
|
20
console/src/app/modules/form-field/error.directive.ts
Normal file
20
console/src/app/modules/form-field/error.directive.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Directive, InjectionToken, Input } from '@angular/core';
|
||||||
|
|
||||||
|
let nextUniqueId = 0;
|
||||||
|
|
||||||
|
export const CNSL_ERROR = new InjectionToken<CnslErrorDirective>('CnslError');
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[cnsl-error]',
|
||||||
|
host: {
|
||||||
|
'class': 'cnsl-error',
|
||||||
|
'role': 'alert',
|
||||||
|
'[attr.id]': 'id',
|
||||||
|
},
|
||||||
|
providers: [{ provide: CNSL_ERROR, useExisting: CnslErrorDirective }],
|
||||||
|
})
|
||||||
|
export class CnslErrorDirective {
|
||||||
|
@Input() id: string = `cnsl-error-${nextUniqueId++}`;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
}
|
17
console/src/app/modules/form-field/form-field.component.html
Normal file
17
console/src/app/modules/form-field/form-field.component.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<div class="cnsl-form-field-wrapper" (click)="_control.onContainerClick && _control.onContainerClick($event)">
|
||||||
|
<ng-content select="cnsl-label"></ng-content>
|
||||||
|
<div class="cnsl-rel" #inputContainer>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
<ng-content select="cnslSuffix"></ng-content>
|
||||||
|
</div>
|
||||||
|
<div class="cnsl-form-field-subscript-wrapper" [ngSwitch]="_getDisplayedMessages()">
|
||||||
|
<div *ngSwitchCase="'error'" class="cnsl-form-field-error-wrapper"
|
||||||
|
[@transitionMessages]="_subscriptAnimationState">
|
||||||
|
<ng-content select="cnsl-error"></ng-content>
|
||||||
|
</div>
|
||||||
|
<div *ngSwitchCase="'hint'" class="cnsl-form-field-hint-wrapper"
|
||||||
|
[@transitionMessages]="_subscriptAnimationState">
|
||||||
|
<ng-content select="cnsl-hint"></ng-content>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
45
console/src/app/modules/form-field/form-field.component.scss
Normal file
45
console/src/app/modules/form-field/form-field.component.scss
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
@import '~@angular/material/theming';
|
||||||
|
|
||||||
|
@mixin cnsl-form-field-theme($theme) {
|
||||||
|
$primary: map-get($theme, primary);
|
||||||
|
$primary-color: mat-color($primary, 500);
|
||||||
|
$is-dark-theme: map-get($theme, is-dark);
|
||||||
|
|
||||||
|
.ng-untouched {
|
||||||
|
.cnsl-error {
|
||||||
|
visibility: hidden;
|
||||||
|
transition: visibility .2 ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cnsl-form-field-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cnsl-rel {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
[cnslSuffix] {
|
||||||
|
position: absolute;
|
||||||
|
right: .5rem;
|
||||||
|
top: 9px;
|
||||||
|
height: inherit;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper for the hints and error messages.
|
||||||
|
.cnsl-form-field-subscript-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden; // prevents multi-line errors from overlapping the control
|
||||||
|
}
|
||||||
|
|
||||||
|
.cnsl-form-field-hint-wrapper,
|
||||||
|
.cnsl-form-field-error-wrapper {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CnslFormFieldComponent } from './form-field.component';
|
||||||
|
|
||||||
|
describe('CnslFormFieldComponent', () => {
|
||||||
|
let component: CnslFormFieldComponent;
|
||||||
|
let fixture: ComponentFixture<CnslFormFieldComponent>;
|
||||||
|
|
||||||
|
beforeEach(waitForAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [CnslFormFieldComponent],
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CnslFormFieldComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
164
console/src/app/modules/form-field/form-field.component.ts
Normal file
164
console/src/app/modules/form-field/form-field.component.ts
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
import {
|
||||||
|
AfterContentInit,
|
||||||
|
AfterViewInit,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Component,
|
||||||
|
ContentChild,
|
||||||
|
ContentChildren,
|
||||||
|
ElementRef,
|
||||||
|
HostListener,
|
||||||
|
Inject,
|
||||||
|
InjectionToken,
|
||||||
|
OnDestroy,
|
||||||
|
QueryList,
|
||||||
|
ViewChild,
|
||||||
|
ViewEncapsulation,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { NgControl } from '@angular/forms';
|
||||||
|
import { MatFormFieldControl } from '@angular/material/form-field';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import { startWith, takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { cnslFormFieldAnimations } from './animations';
|
||||||
|
import { CNSL_ERROR, CnslErrorDirective } from './error.directive';
|
||||||
|
import { _CNSL_HINT, CnslHintDirective } from './hint.directive';
|
||||||
|
|
||||||
|
export const CNSL_FORM_FIELD = new InjectionToken<CnslFormFieldComponent>('CnslFormFieldComponent');
|
||||||
|
|
||||||
|
class CnslFormFieldBase {
|
||||||
|
constructor(public _elementRef: ElementRef) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'cnsl-form-field',
|
||||||
|
templateUrl: './form-field.component.html',
|
||||||
|
styleUrls: ['./form-field.component.scss'],
|
||||||
|
providers: [
|
||||||
|
{ provide: CNSL_FORM_FIELD, useExisting: CnslFormFieldComponent },
|
||||||
|
],
|
||||||
|
host: {
|
||||||
|
'[class.ng-untouched]': '_shouldForward("untouched")',
|
||||||
|
'[class.ng-touched]': '_shouldForward("touched")',
|
||||||
|
'[class.ng-pristine]': '_shouldForward("pristine")',
|
||||||
|
'[class.ng-dirty]': '_shouldForward("dirty")',
|
||||||
|
'[class.ng-valid]': '_shouldForward("valid")',
|
||||||
|
'[class.ng-invalid]': '_shouldForward("invalid")',
|
||||||
|
'[class.ng-pending]': '_shouldForward("pending")',
|
||||||
|
// '[class.cnsl-form-field-invalid]': '_control.errorState',
|
||||||
|
},
|
||||||
|
encapsulation: ViewEncapsulation.None,
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
animations: [cnslFormFieldAnimations.transitionMessages],
|
||||||
|
})
|
||||||
|
export class CnslFormFieldComponent extends CnslFormFieldBase implements OnDestroy, AfterContentInit, AfterViewInit {
|
||||||
|
focused: boolean = false;
|
||||||
|
private _destroyed: Subject<void> = new Subject<void>();
|
||||||
|
|
||||||
|
@ViewChild('connectionContainer', { static: true }) _connectionContainerRef!: ElementRef;
|
||||||
|
@ViewChild('inputContainer') _inputContainerRef!: ElementRef;
|
||||||
|
@ContentChild(MatFormFieldControl) _controlNonStatic!: MatFormFieldControl<any>;
|
||||||
|
@ContentChild(MatFormFieldControl, { static: true }) _controlStatic!: MatFormFieldControl<any>;
|
||||||
|
get _control(): MatFormFieldControl<any> {
|
||||||
|
// TODO(crisbeto): we need this workaround in order to support both Ivy and ViewEngine.
|
||||||
|
// We should clean this up once Ivy is the default renderer.
|
||||||
|
return this._explicitFormFieldControl || this._controlNonStatic || this._controlStatic;
|
||||||
|
}
|
||||||
|
set _control(value: MatFormFieldControl<any>) {
|
||||||
|
this._explicitFormFieldControl = value;
|
||||||
|
}
|
||||||
|
private _explicitFormFieldControl!: MatFormFieldControl<any>;
|
||||||
|
readonly stateChanges: Subject<void> = new Subject<void>();
|
||||||
|
|
||||||
|
_subscriptAnimationState: string = '';
|
||||||
|
|
||||||
|
@ContentChildren(CNSL_ERROR as any, { descendants: true }) _errorChildren!: QueryList<CnslErrorDirective>;
|
||||||
|
@ContentChildren(_CNSL_HINT, { descendants: true }) _hintChildren!: QueryList<CnslHintDirective>;
|
||||||
|
|
||||||
|
@HostListener('blur', ['false'])
|
||||||
|
_focusChanged(isFocused: boolean): void {
|
||||||
|
console.log('blur1');
|
||||||
|
if (isFocused !== this.focused && (!isFocused)) {
|
||||||
|
this.focused = isFocused;
|
||||||
|
this.stateChanges.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(public _elementRef: ElementRef, private _changeDetectorRef: ChangeDetectorRef,
|
||||||
|
@Inject(ElementRef)
|
||||||
|
// Use `ElementRef` here so Angular has something to inject.
|
||||||
|
_labelOptions: any) {
|
||||||
|
super(_elementRef);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngAfterViewInit(): void {
|
||||||
|
// Avoid animations on load.
|
||||||
|
this._subscriptAnimationState = 'enter';
|
||||||
|
this._changeDetectorRef.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy(): void {
|
||||||
|
this._destroyed.next();
|
||||||
|
this._destroyed.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngAfterContentInit(): void {
|
||||||
|
this._validateControlChild();
|
||||||
|
|
||||||
|
const control = this._control;
|
||||||
|
control.stateChanges.pipe(startWith(null)).subscribe(() => {
|
||||||
|
this._syncDescribedByIds();
|
||||||
|
this._changeDetectorRef.markForCheck();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run change detection if the value changes.
|
||||||
|
if (control.ngControl && control.ngControl.valueChanges) {
|
||||||
|
control.ngControl.valueChanges
|
||||||
|
.pipe(takeUntil(this._destroyed))
|
||||||
|
.subscribe(() => this._changeDetectorRef.markForCheck());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the aria-described by when the number of errors changes.
|
||||||
|
this._errorChildren.changes.pipe(startWith(null)).subscribe(() => {
|
||||||
|
this._syncDescribedByIds();
|
||||||
|
this._changeDetectorRef.markForCheck();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Throws an error if the form field's control is missing. */
|
||||||
|
protected _validateControlChild(): void {
|
||||||
|
if (!this._control) {
|
||||||
|
throw Error('cnsl-form-field must contain a MatFormFieldControl.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _syncDescribedByIds(): void {
|
||||||
|
if (this._control) {
|
||||||
|
const ids: string[] = [];
|
||||||
|
|
||||||
|
// TODO(wagnermaciel): Remove the type check when we find the root cause of this bug.
|
||||||
|
if (this._control.userAriaDescribedBy &&
|
||||||
|
typeof this._control.userAriaDescribedBy === 'string') {
|
||||||
|
ids.push(...this._control.userAriaDescribedBy.split(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._errorChildren) {
|
||||||
|
ids.push(...this._errorChildren.map(error => error.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._control.setDescribedByIds(ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Determines whether a class from the NgControl should be forwarded to the host element. */
|
||||||
|
_shouldForward(prop: keyof NgControl): boolean {
|
||||||
|
const ngControl = this._control ? this._control.ngControl : null;
|
||||||
|
return ngControl && ngControl[prop];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Determines whether to display hints or errors. */
|
||||||
|
_getDisplayedMessages(): 'error' | 'hint' {
|
||||||
|
return (this._errorChildren && this._errorChildren.length > 0) ? 'error' : 'hint';
|
||||||
|
}
|
||||||
|
}
|
30
console/src/app/modules/form-field/form-field.module.ts
Normal file
30
console/src/app/modules/form-field/form-field.module.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { MatRippleModule } from '@angular/material/core';
|
||||||
|
import { LabelModule } from 'src/app/modules/label/label.module';
|
||||||
|
|
||||||
|
import { LabelComponent } from '../label/label.component';
|
||||||
|
import { CnslErrorDirective } from './error.directive';
|
||||||
|
import { CnslFormFieldComponent } from './form-field.component';
|
||||||
|
import { CnslHintDirective } from './hint.directive';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
CnslFormFieldComponent,
|
||||||
|
CnslErrorDirective,
|
||||||
|
CnslHintDirective,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
MatRippleModule,
|
||||||
|
LabelModule,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
CnslFormFieldComponent,
|
||||||
|
LabelComponent,
|
||||||
|
CnslErrorDirective,
|
||||||
|
CnslHintDirective,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class FormFieldModule { }
|
||||||
|
|
33
console/src/app/modules/form-field/hint.directive.ts
Normal file
33
console/src/app/modules/form-field/hint.directive.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { Directive, InjectionToken, Input } from '@angular/core';
|
||||||
|
|
||||||
|
let nextUniqueId = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection token that can be used to reference instances of `MatHint`. It serves as
|
||||||
|
* alternative token to the actual `MatHint` class which could cause unnecessary
|
||||||
|
* retention of the class and its directive metadata.
|
||||||
|
*
|
||||||
|
* *Note*: This is not part of the public API as the MDC-based form-field will not
|
||||||
|
* need a lightweight token for `MatHint` and we want to reduce breaking changes.
|
||||||
|
*/
|
||||||
|
export const _CNSL_HINT = new InjectionToken<CnslHintDirective>('CnslHintDirective');
|
||||||
|
|
||||||
|
/** Hint text to be shown underneath the form field control. */
|
||||||
|
@Directive({
|
||||||
|
selector: 'cnsl-hint',
|
||||||
|
host: {
|
||||||
|
'class': 'cnsl-hint',
|
||||||
|
'[class.cnsl-form-field-hint-end]': 'align === "end"',
|
||||||
|
'[attr.id]': 'id',
|
||||||
|
// Remove align attribute to prevent it from interfering with layout.
|
||||||
|
'[attr.align]': 'null',
|
||||||
|
},
|
||||||
|
providers: [{ provide: _CNSL_HINT, useExisting: CnslHintDirective }],
|
||||||
|
})
|
||||||
|
export class CnslHintDirective {
|
||||||
|
/** Whether to align the hint label at the start or end of the line. */
|
||||||
|
@Input() align: 'start' | 'end' = 'start';
|
||||||
|
|
||||||
|
/** Unique ID for the hint. Used for the aria-describedby on the form field control. */
|
||||||
|
@Input() id: string = `mat-hint-${nextUniqueId++}`;
|
||||||
|
}
|
@ -16,56 +16,57 @@
|
|||||||
<form (ngSubmit)="addIdp()">
|
<form (ngSubmit)="addIdp()">
|
||||||
<ng-container [formGroup]="formGroup">
|
<ng-container [formGroup]="formGroup">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.NAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.NAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="name" />
|
<input cnslInput formControlName="name" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.ISSUER' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.ISSUER' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="issuer" />
|
<input cnslInput formControlName="issuer" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p class="desc">Client Id / Client Secret</p>
|
<p class="desc">Client Id / Client Secret</p>
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.CLIENTID' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.CLIENTID' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="clientId" />
|
<input cnslInput formControlName="clientId" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.CLIENTSECRET' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.CLIENTSECRET' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="clientSecret" />
|
<input cnslInput formControlName="clientSecret" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.SCOPESLIST' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.SCOPESLIST' | translate }}</cnsl-label>
|
||||||
<mat-chip-list #chipScopesList aria-label="scope selection" *ngIf="scopesList">
|
<mat-chip-list #chipScopesList aria-label="scope selection" *ngIf="scopesList">
|
||||||
<mat-chip class="chip" *ngFor="let scope of scopesList.value" selectable="false" removable
|
<mat-chip class="chip" *ngFor="let scope of scopesList.value" selectable="false" removable
|
||||||
(removed)="removeScope(scope)">
|
(removed)="removeScope(scope)">
|
||||||
{{scope}} <mat-icon matChipRemove>cancel</mat-icon>
|
{{scope}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input [matChipInputFor]="chipScopesList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
<input cnslInput [matChipInputFor]="chipScopesList"
|
||||||
[matChipInputAddOnBlur]="true" (matChipInputTokenEnd)="addScope($event)">
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
||||||
|
(matChipInputTokenEnd)="addScope($event)">
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="idpDisplayNameMapping">
|
<mat-select formControlName="idpDisplayNameMapping">
|
||||||
<mat-option *ngFor="let field of mappingFields" [value]="field">
|
<mat-option *ngFor="let field of mappingFields" [value]="field">
|
||||||
{{ 'IDP.MAPPINTFIELD.'+field | translate }}
|
{{ 'IDP.MAPPINTFIELD.'+field | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'IDP.USERNAMEMAPPING' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.USERNAMEMAPPING' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="usernameMapping">
|
<mat-select formControlName="usernameMapping">
|
||||||
<mat-option *ngFor="let field of mappingFields" [value]="field">
|
<mat-option *ngFor="let field of mappingFields" [value]="field">
|
||||||
{{ 'IDP.MAPPINTFIELD.'+field | translate }}
|
{{ 'IDP.MAPPINTFIELD.'+field | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@ -3,13 +3,12 @@ import { NgModule } from '@angular/core';
|
|||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { IdpCreateRoutingModule } from './idp-create-routing.module';
|
import { IdpCreateRoutingModule } from './idp-create-routing.module';
|
||||||
import { IdpCreateComponent } from './idp-create.component';
|
import { IdpCreateComponent } from './idp-create.component';
|
||||||
@ -21,8 +20,7 @@ import { IdpCreateComponent } from './idp-create.component';
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -4,22 +4,22 @@
|
|||||||
<form (ngSubmit)="updateIdp()">
|
<form (ngSubmit)="updateIdp()">
|
||||||
<ng-container [formGroup]="idpForm">
|
<ng-container [formGroup]="idpForm">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.ID' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.ID' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="id" />
|
<input cnslInput formControlName="id" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.NAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.NAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="name" />
|
<input cnslInput formControlName="name" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'IDP.STYLE' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.STYLE' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="stylingType">
|
<mat-select formControlName="stylingType">
|
||||||
<mat-option *ngFor="let field of styleFields" [value]="field">
|
<mat-option *ngFor="let field of styleFields" [value]="field">
|
||||||
{{ 'IDP.STYLEFIELD.'+field | translate }}
|
{{ 'IDP.STYLEFIELD.'+field | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
@ -38,51 +38,51 @@
|
|||||||
<form (ngSubmit)="updateOidcConfig()">
|
<form (ngSubmit)="updateOidcConfig()">
|
||||||
<ng-container [formGroup]="oidcConfigForm">
|
<ng-container [formGroup]="oidcConfigForm">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.ISSUER' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.ISSUER' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="issuer" />
|
<input cnslInput formControlName="issuer" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'IDP.CLIENTID' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.CLIENTID' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="clientId" />
|
<input cnslInput formControlName="clientId" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-checkbox class="desc" [(ngModel)]="showIdSecretSection"
|
<mat-checkbox class="desc" [(ngModel)]="showIdSecretSection"
|
||||||
[ngModelOptions]="{standalone: true}">
|
[ngModelOptions]="{standalone: true}">
|
||||||
Update Client Secret
|
Update Client Secret
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
<mat-form-field appearance="outline" class="formfield" *ngIf="showIdSecretSection">
|
<cnsl-form-field appearance="outline" class="formfield" *ngIf="showIdSecretSection">
|
||||||
<mat-label>{{ 'IDP.CLIENTSECRET' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.CLIENTSECRET' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="clientSecret" />
|
<input cnslInput formControlName="clientSecret" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field appearance="outline" class="formfield fullwidth">
|
<cnsl-form-field appearance="outline" class="formfield fullwidth">
|
||||||
<mat-label>{{ 'IDP.SCOPESLIST' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.SCOPESLIST' | translate }}</cnsl-label>
|
||||||
<mat-chip-list #chipScopesList aria-label="scope selection">
|
<mat-chip-list #chipScopesList aria-label="scope selection">
|
||||||
<mat-chip class="chip" *ngFor="let scope of scopesList?.value" selectable="false"
|
<mat-chip class="chip" *ngFor="let scope of scopesList?.value" selectable="false"
|
||||||
removable (removed)="removeScope(scope)">
|
removable (removed)="removeScope(scope)">
|
||||||
{{scope}} <mat-icon matChipRemove>cancel</mat-icon>
|
{{scope}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input [matChipInputFor]="chipScopesList"
|
<input cnslInput [matChipInputFor]="chipScopesList"
|
||||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
||||||
(matChipInputTokenEnd)="addScope($event)">
|
(matChipInputTokenEnd)="addScope($event)">
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="idpDisplayNameMapping">
|
<mat-select formControlName="idpDisplayNameMapping">
|
||||||
<mat-option *ngFor="let field of mappingFields" [value]="field">
|
<mat-option *ngFor="let field of mappingFields" [value]="field">
|
||||||
{{ 'IDP.MAPPINGFIELD.'+field | translate }}
|
{{ 'IDP.MAPPINGFIELD.'+field | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'IDP.USERNAMEMAPPING' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.USERNAMEMAPPING' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="usernameMapping">
|
<mat-select formControlName="usernameMapping">
|
||||||
<mat-option *ngFor="let field of mappingFields" [value]="field">
|
<mat-option *ngFor="let field of mappingFields" [value]="field">
|
||||||
{{ 'IDP.MAPPINGFIELD.'+field | translate }}
|
{{ 'IDP.MAPPINGFIELD.'+field | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@ -4,16 +4,15 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { IdpRoutingModule } from './idp-routing.module';
|
import { IdpRoutingModule } from './idp-routing.module';
|
||||||
import { IdpComponent } from './idp.component';
|
import { IdpComponent } from './idp.component';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [IdpComponent],
|
declarations: [IdpComponent],
|
||||||
@ -22,8 +21,7 @@ import { MatSelectModule } from '@angular/material/select';
|
|||||||
IdpRoutingModule,
|
IdpRoutingModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
|
19
console/src/app/modules/input/error-options.ts
Normal file
19
console/src/app/modules/input/error-options.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { FormControl, FormGroupDirective, NgForm } from '@angular/forms';
|
||||||
|
|
||||||
|
|
||||||
|
/** Provider that defines how form controls behave with regards to displaying error messages. */
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class ErrorStateMatcher {
|
||||||
|
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
||||||
|
return !!(control && control.invalid && (control.touched || (form && form.submitted)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Error state matcher that matches when a control is invalid and dirty. */
|
||||||
|
@Injectable()
|
||||||
|
export class ShowOnDirtyErrorStateMatcher implements ErrorStateMatcher {
|
||||||
|
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
||||||
|
return !!(control && control.invalid && (control.dirty || (form && form.submitted)));
|
||||||
|
}
|
||||||
|
}
|
8
console/src/app/modules/input/input.directive.spec.ts
Normal file
8
console/src/app/modules/input/input.directive.spec.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { InputDirective } from './input.directive';
|
||||||
|
|
||||||
|
describe('InputDirective', () => {
|
||||||
|
it('should create an instance', () => {
|
||||||
|
const directive = new InputDirective();
|
||||||
|
expect(directive).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
459
console/src/app/modules/input/input.directive.ts
Normal file
459
console/src/app/modules/input/input.directive.ts
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||||
|
import { getSupportedInputTypes, Platform } from '@angular/cdk/platform';
|
||||||
|
import { AutofillMonitor } from '@angular/cdk/text-field';
|
||||||
|
import {
|
||||||
|
AfterViewInit,
|
||||||
|
Directive,
|
||||||
|
DoCheck,
|
||||||
|
ElementRef,
|
||||||
|
HostListener,
|
||||||
|
Inject,
|
||||||
|
Input,
|
||||||
|
NgZone,
|
||||||
|
OnChanges,
|
||||||
|
OnDestroy,
|
||||||
|
Optional,
|
||||||
|
Self,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { FormGroupDirective, NgControl, NgForm } from '@angular/forms';
|
||||||
|
import { CanUpdateErrorState, CanUpdateErrorStateCtor, ErrorStateMatcher, mixinErrorState } from '@angular/material/core';
|
||||||
|
import { MAT_FORM_FIELD, MatFormField, MatFormFieldControl } from '@angular/material/form-field';
|
||||||
|
import { getMatInputUnsupportedTypeError, MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
|
|
||||||
|
// Invalid input type. Using one of these will throw an MatInputUnsupportedTypeError.
|
||||||
|
const MAT_INPUT_INVALID_TYPES = [
|
||||||
|
'button',
|
||||||
|
'checkbox',
|
||||||
|
'file',
|
||||||
|
'hidden',
|
||||||
|
'image',
|
||||||
|
'radio',
|
||||||
|
'range',
|
||||||
|
'reset',
|
||||||
|
'submit',
|
||||||
|
];
|
||||||
|
|
||||||
|
let nextUniqueId = 0;
|
||||||
|
|
||||||
|
// Boilerplate for applying mixins to MatInput.
|
||||||
|
/** @docs-private */
|
||||||
|
class MatInputBase {
|
||||||
|
constructor(public _defaultErrorStateMatcher: ErrorStateMatcher,
|
||||||
|
public _parentForm: NgForm,
|
||||||
|
public _parentFormGroup: FormGroupDirective,
|
||||||
|
/** @docs-private */
|
||||||
|
public ngControl: NgControl) { }
|
||||||
|
}
|
||||||
|
const _MatInputMixinBase: CanUpdateErrorStateCtor & typeof MatInputBase =
|
||||||
|
mixinErrorState(MatInputBase);
|
||||||
|
|
||||||
|
/** Directive that allows a native input to work inside a `MatFormField`. */
|
||||||
|
@Directive({
|
||||||
|
selector: `input[cnslInput], textarea[cnslInput], select[cnslNativeControl]`,
|
||||||
|
exportAs: 'cnslInput',
|
||||||
|
host: {
|
||||||
|
/**
|
||||||
|
* @breaking-change 8.0.0 remove .mat-form-field-autofill-control in favor of AutofillMonitor.
|
||||||
|
*/
|
||||||
|
// 'class': 'cnsl-input-element cnsl-form-field-autofill-control',
|
||||||
|
// '[class.mat-input-server]': '_isServer',
|
||||||
|
// Native input properties that are overwritten by Angular inputs need to be synced with
|
||||||
|
// the native input element. Otherwise property bindings for those don't work.
|
||||||
|
'[attr.id]': 'id',
|
||||||
|
// At the time of writing, we have a lot of customer tests that look up the input based on its
|
||||||
|
// placeholder. Since we sometimes omit the placeholder attribute from the DOM to prevent screen
|
||||||
|
// readers from reading it twice, we have to keep it somewhere in the DOM for the lookup.
|
||||||
|
'[attr.data-placeholder]': 'placeholder',
|
||||||
|
'[disabled]': 'disabled',
|
||||||
|
'[required]': 'required',
|
||||||
|
'[attr.readonly]': 'readonly && !_isNativeSelect || null',
|
||||||
|
'[attr.aria-invalid]': 'errorState',
|
||||||
|
'[attr.aria-required]': 'required.toString()',
|
||||||
|
},
|
||||||
|
providers: [{ provide: MatFormFieldControl, useExisting: InputDirective }],
|
||||||
|
})
|
||||||
|
export class InputDirective extends _MatInputMixinBase implements MatFormFieldControl<any>, OnChanges,
|
||||||
|
OnDestroy, AfterViewInit, DoCheck, CanUpdateErrorState {
|
||||||
|
protected _uid: string = `cnsl-input-${nextUniqueId++}`;
|
||||||
|
protected _previousNativeValue: any;
|
||||||
|
private _inputValueAccessor: { value: any; };
|
||||||
|
private _previousPlaceholder!: string | null;
|
||||||
|
|
||||||
|
/** Whether the component is being rendered on the server. */
|
||||||
|
readonly _isServer: boolean;
|
||||||
|
|
||||||
|
/** Whether the component is a native html select. */
|
||||||
|
readonly _isNativeSelect: boolean;
|
||||||
|
|
||||||
|
/** Whether the component is a textarea. */
|
||||||
|
readonly _isTextarea: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
focused: boolean = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
readonly stateChanges: Subject<void> = new Subject<void>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
controlType: string = 'mat-input';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
autofilled: boolean = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
@Input()
|
||||||
|
get disabled(): boolean {
|
||||||
|
if (this.ngControl && this.ngControl.disabled !== null) {
|
||||||
|
return this.ngControl.disabled;
|
||||||
|
}
|
||||||
|
return this._disabled;
|
||||||
|
}
|
||||||
|
set disabled(value: boolean) {
|
||||||
|
this._disabled = coerceBooleanProperty(value);
|
||||||
|
|
||||||
|
// Browsers may not fire the blur event if the input is disabled too quickly.
|
||||||
|
// Reset from here to ensure that the element doesn't become stuck.
|
||||||
|
if (this.focused) {
|
||||||
|
this.focused = false;
|
||||||
|
this.stateChanges.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected _disabled: boolean = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
@Input()
|
||||||
|
get id(): string { return this._id; }
|
||||||
|
set id(value: string) { this._id = value || this._uid; }
|
||||||
|
protected _id!: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
@Input() placeholder!: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
@Input()
|
||||||
|
get required(): boolean { return this._required; }
|
||||||
|
set required(value: boolean) { this._required = coerceBooleanProperty(value); }
|
||||||
|
protected _required: boolean = false;
|
||||||
|
|
||||||
|
/** Input type of the element. */
|
||||||
|
@Input()
|
||||||
|
get type(): string { return this._type; }
|
||||||
|
set type(value: string) {
|
||||||
|
this._type = value || 'text';
|
||||||
|
this._validateType();
|
||||||
|
|
||||||
|
// When using Angular inputs, developers are no longer able to set the properties on the native
|
||||||
|
// input element. To ensure that bindings for `type` work, we need to sync the setter
|
||||||
|
// with the native property. Textarea elements don't support the type property or attribute.
|
||||||
|
if (!this._isTextarea && getSupportedInputTypes().has(this._type)) {
|
||||||
|
(this._elementRef.nativeElement as HTMLInputElement).type = this._type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected _type: string = 'text';
|
||||||
|
|
||||||
|
/** An object used to control when error messages are shown. */
|
||||||
|
@Input() errorStateMatcher!: ErrorStateMatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
// tslint:disable-next-line:no-input-rename
|
||||||
|
@Input('aria-describedby') userAriaDescribedBy!: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
@Input()
|
||||||
|
get value(): string { return this._inputValueAccessor.value; }
|
||||||
|
set value(value: string) {
|
||||||
|
if (value !== this.value) {
|
||||||
|
this._inputValueAccessor.value = value;
|
||||||
|
this.stateChanges.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Whether the element is readonly. */
|
||||||
|
@Input()
|
||||||
|
get readonly(): boolean { return this._readonly; }
|
||||||
|
set readonly(value: boolean) { this._readonly = coerceBooleanProperty(value); }
|
||||||
|
private _readonly: boolean = false;
|
||||||
|
|
||||||
|
protected _neverEmptyInputTypes: string[] = [
|
||||||
|
'date',
|
||||||
|
'datetime',
|
||||||
|
'datetime-local',
|
||||||
|
'month',
|
||||||
|
'time',
|
||||||
|
'week',
|
||||||
|
].filter(t => getSupportedInputTypes().has(t));
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected _elementRef: ElementRef<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
|
||||||
|
protected _platform: Platform,
|
||||||
|
/** @docs-private */
|
||||||
|
@Optional() @Self() public ngControl: NgControl,
|
||||||
|
@Optional() _parentForm: NgForm,
|
||||||
|
@Optional() _parentFormGroup: FormGroupDirective,
|
||||||
|
_defaultErrorStateMatcher: ErrorStateMatcher,
|
||||||
|
@Optional() @Self() @Inject(MAT_INPUT_VALUE_ACCESSOR) inputValueAccessor: any,
|
||||||
|
private _autofillMonitor: AutofillMonitor,
|
||||||
|
ngZone: NgZone,
|
||||||
|
// TODO: Remove this once the legacy appearance has been removed. We only need
|
||||||
|
// to inject the form-field for determining whether the placeholder has been promoted.
|
||||||
|
@Optional() @Inject(MAT_FORM_FIELD) private _formField?: MatFormField) {
|
||||||
|
|
||||||
|
super(_defaultErrorStateMatcher, _parentForm, _parentFormGroup, ngControl);
|
||||||
|
|
||||||
|
const element = this._elementRef.nativeElement;
|
||||||
|
const nodeName = element.nodeName.toLowerCase();
|
||||||
|
|
||||||
|
// If no input value accessor was explicitly specified, use the element as the input value
|
||||||
|
// accessor.
|
||||||
|
this._inputValueAccessor = inputValueAccessor || element;
|
||||||
|
|
||||||
|
this._previousNativeValue = this.value;
|
||||||
|
|
||||||
|
// Force setter to be called in case id was not specified.
|
||||||
|
this.id = this.id;
|
||||||
|
|
||||||
|
// On some versions of iOS the caret gets stuck in the wrong place when holding down the delete
|
||||||
|
// key. In order to get around this we need to "jiggle" the caret loose. Since this bug only
|
||||||
|
// exists on iOS, we only bother to install the listener on iOS.
|
||||||
|
if (_platform.IOS) {
|
||||||
|
ngZone.runOutsideAngular(() => {
|
||||||
|
_elementRef.nativeElement.addEventListener('keyup', (event: Event) => {
|
||||||
|
const el: HTMLInputElement = event.target as HTMLInputElement;
|
||||||
|
if (!el.value && !el.selectionStart && !el.selectionEnd) {
|
||||||
|
// Note: Just setting `0, 0` doesn't fix the issue. Setting
|
||||||
|
// `1, 1` fixes it for the first time that you type text and
|
||||||
|
// then hold delete. Toggling to `1, 1` and then back to
|
||||||
|
// `0, 0` seems to completely fix it.
|
||||||
|
el.setSelectionRange(1, 1);
|
||||||
|
el.setSelectionRange(0, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this._isServer = !this._platform.isBrowser;
|
||||||
|
this._isNativeSelect = nodeName === 'select';
|
||||||
|
this._isTextarea = nodeName === 'textarea';
|
||||||
|
|
||||||
|
if (this._isNativeSelect) {
|
||||||
|
this.controlType = (element as HTMLSelectElement).multiple ? 'mat-native-select-multiple' :
|
||||||
|
'mat-native-select';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
if (this._platform.isBrowser) {
|
||||||
|
this._autofillMonitor.monitor(this._elementRef.nativeElement).subscribe(event => {
|
||||||
|
this.autofilled = event.isAutofilled;
|
||||||
|
this.stateChanges.next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(): void {
|
||||||
|
this.stateChanges.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.stateChanges.complete();
|
||||||
|
|
||||||
|
if (this._platform.isBrowser) {
|
||||||
|
this._autofillMonitor.stopMonitoring(this._elementRef.nativeElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngDoCheck(): void {
|
||||||
|
if (this.ngControl) {
|
||||||
|
// We need to re-evaluate this on every change detection cycle, because there are some
|
||||||
|
// error triggers that we can't subscribe to (e.g. parent form submissions). This means
|
||||||
|
// that whatever logic is in here has to be super lean or we risk destroying the performance.
|
||||||
|
this.updateErrorState();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to dirty-check the native element's value, because there are some cases where
|
||||||
|
// we won't be notified when it changes (e.g. the consumer isn't using forms or they're
|
||||||
|
// updating the value using `emitEvent: false`).
|
||||||
|
this._dirtyCheckNativeValue();
|
||||||
|
|
||||||
|
// We need to dirty-check and set the placeholder attribute ourselves, because whether it's
|
||||||
|
// present or not depends on a query which is prone to "changed after checked" errors.
|
||||||
|
this._dirtyCheckPlaceholder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Focuses the input. */
|
||||||
|
focus(options?: FocusOptions): void {
|
||||||
|
this._elementRef.nativeElement.focus(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
|
||||||
|
// In Ivy the `host` bindings will be merged when this class is extended, whereas in
|
||||||
|
// ViewEngine they're overwritten.
|
||||||
|
// TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
|
||||||
|
/** Callback for the cases where the focused state of the input changes. */
|
||||||
|
// tslint:disable:no-host-decorator-in-concrete
|
||||||
|
@HostListener('focus', ['true'])
|
||||||
|
@HostListener('blur', ['false'])
|
||||||
|
// tslint:enable:no-host-decorator-in-concrete
|
||||||
|
_focusChanged(isFocused: boolean): void {
|
||||||
|
if (isFocused !== this.focused && (!this.readonly || !isFocused)) {
|
||||||
|
this.focused = isFocused;
|
||||||
|
this.stateChanges.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
|
||||||
|
// In Ivy the `host` bindings will be merged when this class is extended, whereas in
|
||||||
|
// ViewEngine they're overwritten.
|
||||||
|
// TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
|
||||||
|
// tslint:disable-next-line:no-host-decorator-in-concrete
|
||||||
|
@HostListener('input')
|
||||||
|
_onInput(): void {
|
||||||
|
// This is a noop function and is used to let Angular know whenever the value changes.
|
||||||
|
// Angular will run a new change detection each time the `input` event has been dispatched.
|
||||||
|
// It's necessary that Angular recognizes the value change, because when floatingLabel
|
||||||
|
// is set to false and Angular forms aren't used, the placeholder won't recognize the
|
||||||
|
// value changes and will not disappear.
|
||||||
|
// Listening to the input event wouldn't be necessary when the input is using the
|
||||||
|
// FormsModule or ReactiveFormsModule, because Angular forms also listens to input events.
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Does some manual dirty checking on the native input `placeholder` attribute. */
|
||||||
|
private _dirtyCheckPlaceholder(): void {
|
||||||
|
// If we're hiding the native placeholder, it should also be cleared from the DOM, otherwise
|
||||||
|
// screen readers will read it out twice: once from the label and once from the attribute.
|
||||||
|
// TODO: can be removed once we get rid of the `legacy` style for the form field, because it's
|
||||||
|
// the only one that supports promoting the placeholder to a label.
|
||||||
|
const placeholder = this._formField?._hideControlPlaceholder?.() ? null : this.placeholder;
|
||||||
|
if (placeholder !== this._previousPlaceholder) {
|
||||||
|
const element = this._elementRef.nativeElement;
|
||||||
|
this._previousPlaceholder = placeholder;
|
||||||
|
placeholder ?
|
||||||
|
element.setAttribute('placeholder', placeholder) : element.removeAttribute('placeholder');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Does some manual dirty checking on the native input `value` property. */
|
||||||
|
protected _dirtyCheckNativeValue(): void {
|
||||||
|
const newValue = this._elementRef.nativeElement.value;
|
||||||
|
|
||||||
|
if (this._previousNativeValue !== newValue) {
|
||||||
|
this._previousNativeValue = newValue;
|
||||||
|
this.stateChanges.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Make sure the input is a supported type. */
|
||||||
|
protected _validateType(): void {
|
||||||
|
if (MAT_INPUT_INVALID_TYPES.indexOf(this._type) > -1) {
|
||||||
|
throw getMatInputUnsupportedTypeError(this._type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks whether the input type is one of the types that are never empty. */
|
||||||
|
protected _isNeverEmpty(): boolean {
|
||||||
|
return this._neverEmptyInputTypes.indexOf(this._type) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks whether the input is invalid based on the native validation. */
|
||||||
|
protected _isBadInput(): boolean {
|
||||||
|
// The `validity` property won't be present on platform-server.
|
||||||
|
const validity = (this._elementRef.nativeElement as HTMLInputElement).validity;
|
||||||
|
return validity && validity.badInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
get empty(): boolean {
|
||||||
|
return !this._isNeverEmpty() && !this._elementRef.nativeElement.value && !this._isBadInput() &&
|
||||||
|
!this.autofilled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
get shouldLabelFloat(): boolean {
|
||||||
|
if (this._isNativeSelect) {
|
||||||
|
// For a single-selection `<select>`, the label should float when the selected option has
|
||||||
|
// a non-empty display value. For a `<select multiple>`, the label *always* floats to avoid
|
||||||
|
// overlapping the label with the options.
|
||||||
|
const selectElement = this._elementRef.nativeElement as HTMLSelectElement;
|
||||||
|
const firstOption: HTMLOptionElement | undefined = selectElement.options[0];
|
||||||
|
|
||||||
|
// On most browsers the `selectedIndex` will always be 0, however on IE and Edge it'll be
|
||||||
|
// -1 if the `value` is set to something, that isn't in the list of options, at a later point.
|
||||||
|
return this.focused || selectElement.multiple || !this.empty ||
|
||||||
|
!!(selectElement.selectedIndex > -1 && firstOption && firstOption.label);
|
||||||
|
} else {
|
||||||
|
return this.focused || !this.empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
setDescribedByIds(ids: string[]): void {
|
||||||
|
if (ids.length) {
|
||||||
|
this._elementRef.nativeElement.setAttribute('aria-describedby', ids.join(' '));
|
||||||
|
} else {
|
||||||
|
this._elementRef.nativeElement.removeAttribute('aria-describedby');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented as part of MatFormFieldControl.
|
||||||
|
* @docs-private
|
||||||
|
*/
|
||||||
|
onContainerClick(): void {
|
||||||
|
// Do not re-focus the input element if the element is already focused. Otherwise it can happen
|
||||||
|
// that someone clicks on a time input and the cursor resets to the "hours" field while the
|
||||||
|
// "minutes" field was actually clicked. See: https://github.com/angular/components/issues/12849
|
||||||
|
if (!this.focused) {
|
||||||
|
this.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// tslint:disable
|
||||||
|
static ngAcceptInputType_disabled: BooleanInput;
|
||||||
|
static ngAcceptInputType_readonly: BooleanInput;
|
||||||
|
static ngAcceptInputType_required: BooleanInput;
|
||||||
|
|
||||||
|
// Accept `any` to avoid conflicts with other directives on `<input>` that may
|
||||||
|
// accept different types.
|
||||||
|
static ngAcceptInputType_value: any;
|
||||||
|
// tslint:enable
|
||||||
|
}
|
22
console/src/app/modules/input/input.module.ts
Normal file
22
console/src/app/modules/input/input.module.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { MatRippleModule } from '@angular/material/core';
|
||||||
|
|
||||||
|
import { FormFieldModule } from '../form-field/form-field.module';
|
||||||
|
import { LabelModule } from '../label/label.module';
|
||||||
|
import { ErrorStateMatcher } from './error-options';
|
||||||
|
import { InputDirective } from './input.directive';
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [InputDirective],
|
||||||
|
imports: [
|
||||||
|
LabelModule,
|
||||||
|
CommonModule,
|
||||||
|
FormFieldModule,
|
||||||
|
MatRippleModule,
|
||||||
|
],
|
||||||
|
exports: [InputDirective, FormFieldModule],
|
||||||
|
providers: [ErrorStateMatcher],
|
||||||
|
})
|
||||||
|
export class InputModule { }
|
3
console/src/app/modules/label/label.component.html
Normal file
3
console/src/app/modules/label/label.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<span class="cnsl-label">
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</span>
|
16
console/src/app/modules/label/label.component.scss
Normal file
16
console/src/app/modules/label/label.component.scss
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
@import '~@angular/material/theming';
|
||||||
|
|
||||||
|
@mixin cnsl-label-theme($theme) {
|
||||||
|
$primary: map-get($theme, primary);
|
||||||
|
$primary-color: mat-color($primary, 500);
|
||||||
|
$is-dark-theme: map-get($theme, is-dark);
|
||||||
|
|
||||||
|
.cnsl-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 12px;
|
||||||
|
color: if($is-dark-theme, var(--grey), var(--grey));
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
25
console/src/app/modules/label/label.component.spec.ts
Normal file
25
console/src/app/modules/label/label.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AvatarComponent } from './avatar.component';
|
||||||
|
|
||||||
|
describe('AvatarComponent', () => {
|
||||||
|
let component: AvatarComponent;
|
||||||
|
let fixture: ComponentFixture<AvatarComponent>;
|
||||||
|
|
||||||
|
beforeEach(waitForAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [AvatarComponent],
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AvatarComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
10
console/src/app/modules/label/label.component.ts
Normal file
10
console/src/app/modules/label/label.component.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'cnsl-label',
|
||||||
|
templateUrl: './label.component.html',
|
||||||
|
styleUrls: ['./label.component.scss'],
|
||||||
|
})
|
||||||
|
export class LabelComponent {
|
||||||
|
constructor() { }
|
||||||
|
}
|
20
console/src/app/modules/label/label.module.ts
Normal file
20
console/src/app/modules/label/label.module.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { MatRippleModule } from '@angular/material/core';
|
||||||
|
|
||||||
|
import { LabelComponent } from './label.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [LabelComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
MatRippleModule,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
LabelComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class LabelModule { }
|
||||||
|
|
@ -73,17 +73,16 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="roles">
|
<ng-container matColumnDef="roles">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'ROLESLABEL' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef class="role-row"> {{ 'ROLESLABEL' | translate }} </th>
|
||||||
<td mat-cell *matCellDef="let member">
|
<td mat-cell *matCellDef="let member" class="role-row">
|
||||||
<mat-form-field class="form-field" appearance="outline">
|
<cnsl-form-field class="form-field" appearance="outline">
|
||||||
<mat-label>{{ 'ROLESLABEL' | translate }}</mat-label>
|
|
||||||
<mat-select [(ngModel)]="member.rolesList" multiple [disabled]="!canWrite"
|
<mat-select [(ngModel)]="member.rolesList" multiple [disabled]="!canWrite"
|
||||||
(selectionChange)="updateRoles.emit({member: member, change: $event})">
|
(selectionChange)="updateRoles.emit({member: member, change: $event})">
|
||||||
<mat-option *ngFor="let role of memberRoleOptions" [value]="role">
|
<mat-option *ngFor="let role of memberRoleOptions" [value]="role">
|
||||||
{{ role }}
|
{{ role }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@ -26,11 +26,6 @@
|
|||||||
.action {
|
.action {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.selection {
|
|
||||||
width: 50px;
|
|
||||||
max-width: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
@ -60,3 +55,7 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.role-row {
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
@ -3,7 +3,6 @@ import { NgModule } from '@angular/core';
|
|||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
@ -12,6 +11,7 @@ import { MatTableModule } from '@angular/material/table';
|
|||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { AvatarModule } from '../avatar/avatar.module';
|
import { AvatarModule } from '../avatar/avatar.module';
|
||||||
import { RefreshTableModule } from '../refresh-table/refresh-table.module';
|
import { RefreshTableModule } from '../refresh-table/refresh-table.module';
|
||||||
@ -23,7 +23,7 @@ import { MembersTableComponent } from './members-table.component';
|
|||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -15,7 +15,7 @@ export class MetaLayoutComponent {
|
|||||||
}
|
}
|
||||||
public hidden: boolean = false;
|
public hidden: boolean = false;
|
||||||
public isSmallScreen$: Observable<boolean> = this.breakpointObserver
|
public isSmallScreen$: Observable<boolean> = this.breakpointObserver
|
||||||
.observe('(max-width: 899px)')
|
.observe('(max-width: 1000px)')
|
||||||
.pipe(map(result => {
|
.pipe(map(result => {
|
||||||
return result.matches;
|
return result.matches;
|
||||||
}));
|
}));
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
@import '~@angular/material/theming';
|
|
||||||
|
|
||||||
@mixin meta-theme($theme) {
|
|
||||||
/* stylelint-disable */
|
|
||||||
$primary: map-get($theme, primary);
|
|
||||||
$primary-color: mat-color($primary, 500);
|
|
||||||
$primary-dark: mat-color($primary, A800);
|
|
||||||
/* stylelint-enable */
|
|
||||||
|
|
||||||
.meta-wrapper {
|
|
||||||
.meta {
|
|
||||||
position: relative;
|
|
||||||
flex: 1 0 300px;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
border-left: 2px solid $primary-color;
|
|
||||||
-webkit-border-image:
|
|
||||||
-webkit-gradient(
|
|
||||||
linear,
|
|
||||||
left top,
|
|
||||||
left bottom,
|
|
||||||
from($primary-color),
|
|
||||||
to(rgb(0, 0, 0, .5)),
|
|
||||||
color-stop(
|
|
||||||
01,
|
|
||||||
$primary-dark
|
|
||||||
)
|
|
||||||
) 50 21;
|
|
||||||
border-image:
|
|
||||||
-webkit-gradient(
|
|
||||||
linear,
|
|
||||||
left top,
|
|
||||||
left bottom,
|
|
||||||
from($primary-color),
|
|
||||||
to(rgb(0, 0, 0, .5)),
|
|
||||||
color-stop(
|
|
||||||
01,
|
|
||||||
$primary-dark
|
|
||||||
)
|
|
||||||
) 50 21;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,15 +2,15 @@
|
|||||||
[description]="'POLICY.LABEL.DESCRIPTION' | translate">
|
[description]="'POLICY.LABEL.DESCRIPTION' | translate">
|
||||||
|
|
||||||
<div class="content" *ngIf="labelData">
|
<div class="content" *ngIf="labelData">
|
||||||
<mat-form-field class="form-field" appearance="outline">
|
<cnsl-form-field class="form-field" appearance="outline">
|
||||||
<mat-label>{{'POLICY.LABEL.PRIMARYCOLOR' | translate}}</mat-label>
|
<cnsl-label>{{'POLICY.LABEL.PRIMARYCOLOR' | translate}}</cnsl-label>
|
||||||
<input [(ngModel)]="labelData.primaryColor" matInput />
|
<input cnslInput [(ngModel)]="labelData.primaryColor" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-form-field class="form-field" appearance="outline">
|
<cnsl-form-field class="form-field" appearance="outline">
|
||||||
<mat-label>{{'POLICY.LABEL.SECONDARYCOLOR' | translate}}</mat-label>
|
<cnsl-label>{{'POLICY.LABEL.SECONDARYCOLOR' | translate}}</cnsl-label>
|
||||||
<input [(ngModel)]="labelData.secondaryColor" matInput />
|
<input cnslInput [(ngModel)]="labelData.secondaryColor" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
|
@ -2,14 +2,13 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { LabelPolicyRoutingModule } from './label-policy-routing.module';
|
import { LabelPolicyRoutingModule } from './label-policy-routing.module';
|
||||||
import { LabelPolicyComponent } from './label-policy.component';
|
import { LabelPolicyComponent } from './label-policy.component';
|
||||||
@ -20,8 +19,7 @@ import { LabelPolicyComponent } from './label-policy.component';
|
|||||||
LabelPolicyRoutingModule,
|
LabelPolicyRoutingModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -4,25 +4,25 @@
|
|||||||
<p class="desc"> {{'LOGINPOLICY.ADDIDP.DESCRIPTION' | translate}}</p>
|
<p class="desc"> {{'LOGINPOLICY.ADDIDP.DESCRIPTION' | translate}}</p>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<mat-form-field *ngIf="serviceType == PolicyComponentServiceType.MGMT" class="full-width" appearance="outline">
|
<cnsl-form-field *ngIf="serviceType == PolicyComponentServiceType.MGMT" class="full-width" appearance="outline">
|
||||||
<mat-label>{{ 'IDP.TYPE' | translate }}</mat-label>
|
<cnsl-label>{{ 'IDP.TYPE' | translate }}</cnsl-label>
|
||||||
<mat-select [(ngModel)]="idpType" (selectionChange)="loadIdps()">
|
<mat-select [(ngModel)]="idpType" (selectionChange)="loadIdps()">
|
||||||
<mat-option *ngFor="let type of idpTypes" [value]="type">
|
<mat-option *ngFor="let type of idpTypes" [value]="type">
|
||||||
{{ 'IDP.TYPES.'+type | translate}}
|
{{ 'IDP.TYPES.'+type | translate}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<p>{{'LOGINPOLICY.ADDIDP.SELECTIDPS' | translate}}</p>
|
<p>{{'LOGINPOLICY.ADDIDP.SELECTIDPS' | translate}}</p>
|
||||||
|
|
||||||
<mat-form-field class="full-width" appearance="outline">
|
<cnsl-form-field class="full-width" appearance="outline">
|
||||||
<mat-label>{{ 'LOGINPOLICY.ADDIDP.SELECTIDPS' | translate }}</mat-label>
|
<cnsl-label>{{ 'LOGINPOLICY.ADDIDP.SELECTIDPS' | translate }}</cnsl-label>
|
||||||
<mat-select [(ngModel)]="idp">
|
<mat-select [(ngModel)]="idp">
|
||||||
<mat-option *ngFor="let idp of availableIdps" [value]="idp">
|
<mat-option *ngFor="let idp of availableIdps" [value]="idp">
|
||||||
{{ idp.name }}
|
{{ idp.name }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions class="action">
|
<div mat-dialog-actions class="action">
|
||||||
<button mat-button (click)="closeDialog()">
|
<button mat-button (click)="closeDialog()">
|
||||||
|
@ -61,8 +61,7 @@ export class AddIdpDialogComponent {
|
|||||||
query.setKey(IdpSearchKey.IDPSEARCHKEY_PROVIDER_TYPE);
|
query.setKey(IdpSearchKey.IDPSEARCHKEY_PROVIDER_TYPE);
|
||||||
query.setMethod(SearchMethod.SEARCHMETHOD_EQUALS);
|
query.setMethod(SearchMethod.SEARCHMETHOD_EQUALS);
|
||||||
query.setValue(this.idpType.toString());
|
query.setValue(this.idpType.toString());
|
||||||
console.log(this.idpType);
|
|
||||||
console.log(query.toObject());
|
|
||||||
this.mgmtService.SearchIdps(undefined, undefined, [query]).then(idps => {
|
this.mgmtService.SearchIdps(undefined, undefined, [query]).then(idps => {
|
||||||
this.availableIdps = idps.toObject().resultList;
|
this.availableIdps = idps.toObject().resultList;
|
||||||
});
|
});
|
||||||
|
@ -3,9 +3,9 @@ import { NgModule } from '@angular/core';
|
|||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { AddIdpDialogComponent } from './add-idp-dialog.component';
|
import { AddIdpDialogComponent } from './add-idp-dialog.component';
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ import { AddIdpDialogComponent } from './add-idp-dialog.component';
|
|||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
],
|
],
|
||||||
|
@ -2,9 +2,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
@ -13,6 +11,7 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
|||||||
import { CardModule } from 'src/app/modules/card/card.module';
|
import { CardModule } from 'src/app/modules/card/card.module';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
import { IdpTableModule } from 'src/app/modules/idp-table/idp-table.module';
|
import { IdpTableModule } from 'src/app/modules/idp-table/idp-table.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||||
|
|
||||||
import { AddIdpDialogModule } from './add-idp-dialog/add-idp-dialog.module';
|
import { AddIdpDialogModule } from './add-idp-dialog/add-idp-dialog.module';
|
||||||
@ -26,8 +25,7 @@ import { LoginPolicyComponent } from './login-policy.component';
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
CardModule,
|
CardModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -2,14 +2,13 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { OrgIamPolicyRoutingModule } from './org-iam-policy-routing.module';
|
import { OrgIamPolicyRoutingModule } from './org-iam-policy-routing.module';
|
||||||
import { OrgIamPolicyComponent } from './org-iam-policy.component';
|
import { OrgIamPolicyComponent } from './org-iam-policy.component';
|
||||||
@ -20,8 +19,7 @@ import { OrgIamPolicyComponent } from './org-iam-policy.component';
|
|||||||
OrgIamPolicyRoutingModule,
|
OrgIamPolicyRoutingModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -2,14 +2,13 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { PasswordAgePolicyRoutingModule } from './password-age-policy-routing.module';
|
import { PasswordAgePolicyRoutingModule } from './password-age-policy-routing.module';
|
||||||
import { PasswordAgePolicyComponent } from './password-age-policy.component';
|
import { PasswordAgePolicyComponent } from './password-age-policy.component';
|
||||||
@ -20,8 +19,7 @@ import { PasswordAgePolicyComponent } from './password-age-policy.component';
|
|||||||
PasswordAgePolicyRoutingModule,
|
PasswordAgePolicyRoutingModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -2,15 +2,14 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { PasswordComplexityPolicyRoutingModule } from './password-complexity-policy-routing.module';
|
import { PasswordComplexityPolicyRoutingModule } from './password-complexity-policy-routing.module';
|
||||||
import { PasswordComplexityPolicyComponent } from './password-complexity-policy.component';
|
import { PasswordComplexityPolicyComponent } from './password-complexity-policy.component';
|
||||||
@ -21,8 +20,7 @@ import { PasswordComplexityPolicyComponent } from './password-complexity-policy.
|
|||||||
PasswordComplexityPolicyRoutingModule,
|
PasswordComplexityPolicyRoutingModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -2,14 +2,13 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { PasswordLockoutPolicyRoutingModule } from './password-lockout-policy-routing.module';
|
import { PasswordLockoutPolicyRoutingModule } from './password-lockout-policy-routing.module';
|
||||||
import { PasswordLockoutPolicyComponent } from './password-lockout-policy.component';
|
import { PasswordLockoutPolicyComponent } from './password-lockout-policy.component';
|
||||||
@ -20,8 +19,7 @@ import { PasswordLockoutPolicyComponent } from './password-lockout-policy.compon
|
|||||||
PasswordLockoutPolicyRoutingModule,
|
PasswordLockoutPolicyRoutingModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<h1>{{'POLICY.TITLE' | translate}}</h1>
|
<h2>{{'POLICY.TITLE' | translate}}</h2>
|
||||||
|
|
||||||
<p class="top-desc">{{'POLICY.DESCRIPTION' | translate}}</p>
|
<p class="top-desc">{{'POLICY.DESCRIPTION' | translate}}</p>
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
h1 {
|
h2 {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
letter-spacing: .05em;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-desc {
|
.top-desc {
|
||||||
@ -28,7 +30,7 @@ h1 {
|
|||||||
height: 60px;
|
height: 60px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: linear-gradient(40deg, rgb(129, 85, 185) 30%, #8983f7);
|
background: linear-gradient(40deg, rgb(129, 85, 185) 30%, #5469d4);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -4,18 +4,18 @@
|
|||||||
<p class="desc"> {{'PROJECT.ROLE.EDITDESCRIPTION' | translate}}</p>
|
<p class="desc"> {{'PROJECT.ROLE.EDITDESCRIPTION' | translate}}</p>
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<form *ngIf="formGroup" class="full-width" [formGroup]="formGroup" (ngSubmit)="submitForm()">
|
<form *ngIf="formGroup" class="full-width" [formGroup]="formGroup" (ngSubmit)="submitForm()">
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'PROJECT.ROLE.KEY' | translate }}</mat-label>
|
<cnsl-label>{{ 'PROJECT.ROLE.KEY' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="key" />
|
<input cnslInput formControlName="key" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="displayName" />
|
<input cnslInput formControlName="displayName" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'PROJECT.ROLE.GROUP' | translate }}</mat-label>
|
<cnsl-label>{{ 'PROJECT.ROLE.GROUP' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="group" />
|
<input cnslInput formControlName="group" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -60,6 +60,11 @@
|
|||||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
<mat-paginator #paginator [length]="dataSource.totalResult" [pageSize]="50"
|
<mat-paginator #paginator [length]="dataSource.totalResult" [pageSize]="50"
|
||||||
[pageSizeOptions]="[25, 50, 100, 250]">
|
[pageSizeOptions]="[25, 50, 100, 250]">
|
||||||
</mat-paginator>
|
</mat-paginator>
|
||||||
|
@ -26,11 +26,6 @@
|
|||||||
width: 40px;
|
width: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.selection {
|
|
||||||
width: 50px;
|
|
||||||
max-width: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.margin-neg {
|
.margin-neg {
|
||||||
margin-left: -1rem;
|
margin-left: -1rem;
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
@ -15,6 +13,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
||||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
||||||
@ -33,10 +32,9 @@ import { ProjectRolesComponent } from './project-roles.component';
|
|||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
<div class="table-header-row">
|
<div class="table-header-row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<span class="desc"
|
<span *ngIf="!selection.hasValue()" class="count">{{dataSize}}</span>
|
||||||
*ngIf="timestamp">{{timestamp | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'}}</span>
|
<span *ngIf="selection.hasValue()" class="count">{{selection?.selected?.length}}</span>
|
||||||
<ng-container *ngIf="!selection.hasValue()">
|
<div class="desc">
|
||||||
<span class="desc">{{'ORG_DETAIL.TABLE.TOTAL' | translate}}</span>
|
<span *ngIf="!selection.hasValue()">{{'ORG_DETAIL.TABLE.TOTAL' | translate}}</span>
|
||||||
<span class="count">{{dataSize}}</span>
|
<span *ngIf="selection.hasValue()">{{'ORG_DETAIL.TABLE.SELECTION' | translate}}</span>
|
||||||
</ng-container>
|
<span *ngIf="timestamp">{{timestamp | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'}}</span>
|
||||||
<ng-container *ngIf="selection.hasValue()">
|
</div>
|
||||||
<span class="desc">{{'ORG_DETAIL.TABLE.SELECTION' | translate}}</span>
|
|
||||||
<span class="count">{{selection?.selected?.length}}</span>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
</div>
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
<mat-spinner class="spinner" *ngIf="loading" diameter="20"></mat-spinner>
|
<mat-spinner class="spinner" *ngIf="loading" diameter="20"></mat-spinner>
|
||||||
|
@ -6,10 +6,16 @@
|
|||||||
.col {
|
.col {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
.desc {
|
.desc {
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
color: var(--grey);
|
color: var(--grey);
|
||||||
|
margin-right: 1rem;
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.count {
|
.count {
|
||||||
@ -31,8 +37,3 @@
|
|||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// .table-wrapper {
|
|
||||||
// width: 100%;
|
|
||||||
// overflow-x: auto;
|
|
||||||
// }
|
|
||||||
|
@ -48,7 +48,6 @@ export class RefreshTableComponent implements OnInit {
|
|||||||
if (this.emitRefreshOnPreviousRoutes.length && this.refreshService.previousUrls
|
if (this.emitRefreshOnPreviousRoutes.length && this.refreshService.previousUrls
|
||||||
.some(url => this.emitRefreshOnPreviousRoutes.includes(url))) {
|
.some(url => this.emitRefreshOnPreviousRoutes.includes(url))) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('refresh now');
|
|
||||||
this.emitRefresh();
|
this.emitRefresh();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<form>
|
<form>
|
||||||
<mat-form-field appearance="outline" class="full-width">
|
<cnsl-form-field appearance="outline" class="full-width">
|
||||||
<mat-label>Project Name</mat-label>
|
<cnsl-label>Project Name</cnsl-label>
|
||||||
<input matInput *ngIf="singleOutput" type="text" placeholder="Search for the project name" #nameInput
|
<input cnslInput *ngIf="singleOutput" type="text" placeholder="Search for the project name" #nameInput
|
||||||
[formControl]="myControl" [matAutocomplete]="auto" />
|
[formControl]="myControl" [matAutocomplete]="auto" />
|
||||||
|
|
||||||
<mat-chip-list *ngIf="!singleOutput" #chipList aria-label="name selection">
|
<mat-chip-list *ngIf="!singleOutput" #chipList aria-label="name selection">
|
||||||
@ -10,7 +10,7 @@
|
|||||||
{{selectedProject?.name ? selectedProject.name + ' (owned)' : selectedProject?.projectName ? selectedProject.projectName + ' (granted)': ''}}
|
{{selectedProject?.name ? selectedProject.name + ' (owned)' : selectedProject?.projectName ? selectedProject.projectName + ' (granted)': ''}}
|
||||||
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
|
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input placeholder="{{'PROJECT.NAME' | translate}}" #nameInput [formControl]="myControl"
|
<input cnslInput placeholder="{{'PROJECT.NAME' | translate}}" #nameInput [formControl]="myControl"
|
||||||
[matAutocomplete]="auto" [matChipInputFor]="chipList"
|
[matAutocomplete]="auto" [matChipInputFor]="chipList"
|
||||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="addOnBlur"
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="addOnBlur"
|
||||||
(matChipInputTokenEnd)="add($event)" />
|
(matChipInputTokenEnd)="add($event)" />
|
||||||
@ -24,5 +24,5 @@
|
|||||||
{{project?.name ? project.name + ' (owned)' : project?.projectName ? project.projectName + ' (granted)': ''}}
|
{{project?.name ? project.name + ' (owned)' : project?.projectName ? project.projectName + ' (granted)': ''}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</form>
|
</form>
|
@ -4,12 +4,11 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { SearchProjectAutocompleteComponent } from './search-project-autocomplete.component';
|
import { SearchProjectAutocompleteComponent } from './search-project-autocomplete.component';
|
||||||
|
|
||||||
@ -22,9 +21,8 @@ import { SearchProjectAutocompleteComponent } from './search-project-autocomplet
|
|||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatInputModule,
|
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<form>
|
<form>
|
||||||
<mat-form-field appearance="outline" class="full-width">
|
<cnsl-form-field appearance="outline" class="full-width">
|
||||||
<mat-label>Role Name</mat-label>
|
<cnsl-label>Role Name</cnsl-label>
|
||||||
<input matInput *ngIf="singleOutput" type="text" placeholder="Search for the role name" #nameInput
|
<input cnslInput *ngIf="singleOutput" type="text" placeholder="Search for the role name" #nameInput
|
||||||
[formControl]="myControl" [matAutocomplete]="auto" />
|
[formControl]="myControl" [matAutocomplete]="auto" />
|
||||||
|
|
||||||
<mat-chip-list *ngIf="!singleOutput" #chipList aria-label="name selection">
|
<mat-chip-list *ngIf="!singleOutput" #chipList aria-label="name selection">
|
||||||
@ -10,7 +10,7 @@
|
|||||||
{{selectedRole.displayName}}
|
{{selectedRole.displayName}}
|
||||||
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
|
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input placeholder="Role Name" #nameInput [formControl]="myControl" [matAutocomplete]="auto"
|
<input cnslInput placeholder="Role Name" #nameInput [formControl]="myControl" [matAutocomplete]="auto"
|
||||||
[matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
[matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||||
[matChipInputAddOnBlur]="addOnBlur" (matChipInputTokenEnd)="add($event)" />
|
[matChipInputAddOnBlur]="addOnBlur" (matChipInputTokenEnd)="add($event)" />
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
@ -23,5 +23,5 @@
|
|||||||
{{role.displayName}}
|
{{role.displayName}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</form>
|
</form>
|
@ -4,11 +4,10 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { SearchRolesAutocompleteComponent } from './search-roles-autocomplete.component';
|
import { SearchRolesAutocompleteComponent } from './search-roles-autocomplete.component';
|
||||||
|
|
||||||
@ -20,9 +19,8 @@ import { SearchRolesAutocompleteComponent } from './search-roles-autocomplete.co
|
|||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatInputModule,
|
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<form>
|
<form>
|
||||||
<mat-form-field *ngIf="target && target == UserTarget.SELF" appearance="outline" class="full-width">
|
<cnsl-form-field *ngIf="target && target == UserTarget.SELF" appearance="outline" class="full-width more-space">
|
||||||
<mat-label>Organizations User Loginname</mat-label>
|
<cnsl-label>Organizations User Loginname</cnsl-label>
|
||||||
|
|
||||||
<input matInput *ngIf="singleOutput" type="text" placeholder="Search for the user loginname" #usernameInput
|
<input cnslInput *ngIf="singleOutput" type="text" placeholder="Search for the user loginname" #usernameInput
|
||||||
[formControl]="myControl" [matAutocomplete]="auto" />
|
[formControl]="myControl" [matAutocomplete]="auto" />
|
||||||
|
|
||||||
<mat-chip-list *ngIf="!singleOutput" #chipList aria-label="loginname selection">
|
<mat-chip-list *ngIf="!singleOutput" #chipList aria-label="loginname selection">
|
||||||
@ -13,8 +13,8 @@
|
|||||||
{{selecteduser.preferredLoginName}}</small>
|
{{selecteduser.preferredLoginName}}</small>
|
||||||
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
|
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input placeholder="{{'ORG_DETAIL.MEMBER.LOGINNAME' | translate}}" #usernameInput [formControl]="myControl"
|
<input cnslInput placeholder="{{'ORG_DETAIL.MEMBER.LOGINNAME' | translate}}" #usernameInput
|
||||||
[matAutocomplete]="auto" [matChipInputFor]="chipList"
|
[formControl]="myControl" [matAutocomplete]="auto" [matChipInputFor]="chipList"
|
||||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="addOnBlur"
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="addOnBlur"
|
||||||
(matChipInputTokenEnd)="add($event)" />
|
(matChipInputTokenEnd)="add($event)" />
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
@ -29,21 +29,21 @@
|
|||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-autocomplete>
|
</mat-autocomplete>
|
||||||
|
|
||||||
<mat-hint class="target-desc">
|
<span class="target-desc">
|
||||||
{{'USER.TARGET.SELF'| translate}}
|
{{'USER.TARGET.SELF'| translate}}
|
||||||
<a (click)="changeTarget()">{{'USER.TARGET.CLICKHERE' | translate}}</a>
|
<a (click)="changeTarget()">{{'USER.TARGET.CLICKHERE' | translate}}</a>
|
||||||
</mat-hint>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<div *ngIf="target && target == UserTarget.EXTERNAL" class="line">
|
<div *ngIf="target && target == UserTarget.EXTERNAL" class="line">
|
||||||
<mat-form-field class="form-field" appearance="outline">
|
<cnsl-form-field class="form-field" appearance="outline">
|
||||||
<mat-label>Global User Loginname</mat-label>
|
<cnsl-label>Global User Loginname</cnsl-label>
|
||||||
<input matInput type="text" [formControl]="globalLoginNameControl" />
|
<input cnslInput type="text" [formControl]="globalLoginNameControl" />
|
||||||
<mat-hint class="target-desc">
|
<span class="target-desc">
|
||||||
{{(target == UserTarget.SELF ? 'USER.TARGET.SELF' : 'USER.TARGET.EXTERNAL') | translate}}
|
{{(target == UserTarget.SELF ? 'USER.TARGET.SELF' : 'USER.TARGET.EXTERNAL') | translate}}
|
||||||
<a (click)="changeTarget()">{{'USER.TARGET.CLICKHERE' | translate}}</a>
|
<a (click)="changeTarget()">{{'USER.TARGET.CLICKHERE' | translate}}</a>
|
||||||
</mat-hint>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<button color="primary" mat-icon-button (click)="getGlobalUser()">
|
<button color="primary" mat-icon-button (click)="getGlobalUser()">
|
||||||
<i class="las la-search"></i>
|
<i class="las la-search"></i>
|
||||||
|
@ -2,7 +2,13 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.more-space {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.target-desc {
|
.target-desc {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #4072b4;
|
color: #4072b4;
|
||||||
|
|
||||||
@ -23,7 +29,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
margin-top: 1rem;
|
margin-top: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,14 +4,13 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { AvatarModule } from '../avatar/avatar.module';
|
import { AvatarModule } from '../avatar/avatar.module';
|
||||||
|
import { InputModule } from '../input/input.module';
|
||||||
import { SearchUserAutocompleteComponent } from './search-user-autocomplete.component';
|
import { SearchUserAutocompleteComponent } from './search-user-autocomplete.component';
|
||||||
|
|
||||||
|
|
||||||
@ -22,8 +21,7 @@ import { SearchUserAutocompleteComponent } from './search-user-autocomplete.comp
|
|||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatInputModule,
|
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
<app-refresh-table [loading]="dataSource?.loading$ | async" (refreshed)="changePage()"
|
<app-refresh-table [loading]="dataSource?.loading$ | async" (refreshed)="changePage()"
|
||||||
[emitRefreshOnPreviousRoutes]="refreshOnPreviousRoutes" [timestamp]="dataSource?.viewTimestamp"
|
[emitRefreshOnPreviousRoutes]="refreshOnPreviousRoutes" [timestamp]="dataSource?.viewTimestamp"
|
||||||
[dataSize]="dataSource?.totalResult" [selection]="selection">
|
[dataSize]="dataSource?.totalResult" [selection]="selection">
|
||||||
<mat-form-field @appearfade *ngIf="userGrantSearchKey != undefined" actions class="filtername">
|
<cnsl-form-field @appearfade *ngIf="userGrantSearchKey != undefined" actions class="filtername">
|
||||||
<mat-label>{{'USER.PAGES.FILTER' | translate}}</mat-label>
|
<input cnslInput (keyup)="applyFilter($event)"
|
||||||
<input matInput (keyup)="applyFilter($event)"
|
|
||||||
[placeholder]="('USER.TABLE.FILTER.' + userGrantSearchKey.toString()) | translate" #input>
|
[placeholder]="('USER.TABLE.FILTER.' + userGrantSearchKey.toString()) | translate" #input>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<button color="warn" matTooltip="{{'GRANTS.DELETE' | translate}}" class="icon-button" mat-icon-button actions
|
<button color="warn" matTooltip="{{'GRANTS.DELETE' | translate}}" class="icon-button" mat-icon-button actions
|
||||||
(click)="deleteGrantSelection()" *ngIf="selection.hasValue() && disableDelete == false">
|
(click)="deleteGrantSelection()" *ngIf="selection.hasValue() && disableDelete == false">
|
||||||
@ -65,25 +64,27 @@
|
|||||||
{{grant.projectName}} </td>
|
{{grant.projectName}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="creationDate">
|
<ng-container matColumnDef="dates">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.CREATIONDATE' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef> DATES </th>
|
||||||
<td mat-cell *matCellDef="let grant">
|
<td mat-cell *matCellDef="let grant">
|
||||||
{{grant.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} </td>
|
<div class="date-block">
|
||||||
</ng-container>
|
<span class="date-sub">{{ 'PROJECT.GRANT.CREATIONDATE' | translate }}:</span>
|
||||||
|
<span>{{grant.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span>
|
||||||
<ng-container matColumnDef="changeDate">
|
</div>
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.CHANGEDATE' | translate }} </th>
|
<div class="date-block">
|
||||||
<td mat-cell *matCellDef="let grant">
|
<span class="date-sub">{{ 'PROJECT.GRANT.CHANGEDATE' | translate }}</span>
|
||||||
{{grant.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} </td>
|
<span>{{grant.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="roleNamesList">
|
<ng-container matColumnDef="roleNamesList">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<th mat-header-cell *matHeaderCellDef class="role-data">
|
||||||
{{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }}
|
{{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }}
|
||||||
<template [ngTemplateOutlet]="templateRef"
|
<template [ngTemplateOutlet]="templateRef"
|
||||||
[ngTemplateOutletContext]="{key: UserGrantSearchKey.USERGRANTSEARCHKEY_ROLE_KEY}"></template>
|
[ngTemplateOutletContext]="{key: UserGrantSearchKey.USERGRANTSEARCHKEY_ROLE_KEY}"></template>
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let grant; let i = index">
|
<td mat-cell *matCellDef="let grant; let i = index" class="role-data">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngIf="(context === UserGrantContext.USER || context === UserGrantContext.NONE) && (grant.grantId && grantToEdit !== grant.id) || (grantToEdit !== grant.id)">
|
*ngIf="(context === UserGrantContext.USER || context === UserGrantContext.NONE) && (grant.grantId && grantToEdit !== grant.id) || (grantToEdit !== grant.id)">
|
||||||
<div class="flex-row">
|
<div class="flex-row">
|
||||||
@ -101,10 +102,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<div class="row-form">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngIf="(context === UserGrantContext.OWNED_PROJECT || context === UserGrantContext.USER || context === UserGrantContext.NONE) && grantToEdit == grant.id && loadedProjectId && loadedProjectId === grant.projectId">
|
*ngIf="(context === UserGrantContext.OWNED_PROJECT || context === UserGrantContext.USER || context === UserGrantContext.NONE) && grantToEdit == grant.id && loadedProjectId && loadedProjectId === grant.projectId">
|
||||||
<mat-form-field class="form-field" appearance="outline">
|
<cnsl-form-field class="form-field" appearance="outline">
|
||||||
<mat-label>{{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }}</mat-label>
|
<!-- <cnsl-label>{{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }}</cnsl-label> -->
|
||||||
<mat-select [(ngModel)]="grant.roleKeysList" multiple
|
<mat-select [(ngModel)]="grant.roleKeysList" multiple
|
||||||
[disabled]="disableWrite || !((['user.grant.write$'] | hasRole | async) || ((context === UserGrantContext.OWNED_PROJECT ? ['user.grant.write:' + grant?.projectId] : context === UserGrantContext.GRANTED_PROJECT ? ['user.grant.write:' + grant?.grantId] : []) | hasRole | async))"
|
[disabled]="disableWrite || !((['user.grant.write$'] | hasRole | async) || ((context === UserGrantContext.OWNED_PROJECT ? ['user.grant.write:' + grant?.projectId] : context === UserGrantContext.GRANTED_PROJECT ? ['user.grant.write:' + grant?.grantId] : []) | hasRole | async))"
|
||||||
(selectionChange)="updateRoles(grant, $event)">
|
(selectionChange)="updateRoles(grant, $event)">
|
||||||
@ -112,8 +114,9 @@
|
|||||||
{{role.key}}
|
{{role.key}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<button *ngIf="context === UserGrantContext.USER || context === UserGrantContext.NONE"
|
<button matTooltip="{{'ACTIONS.CLOSE' | translate}}"
|
||||||
|
*ngIf="context === UserGrantContext.USER || context === UserGrantContext.NONE"
|
||||||
mat-icon-button (click)="grantToEdit=''">
|
mat-icon-button (click)="grantToEdit=''">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
@ -121,8 +124,8 @@
|
|||||||
|
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngIf="(context === UserGrantContext.GRANTED_PROJECT || context === UserGrantContext.USER || context === UserGrantContext.NONE) && loadedGrantId && loadedGrantId === grant.grantId && grantToEdit == grant.id">
|
*ngIf="(context === UserGrantContext.GRANTED_PROJECT || context === UserGrantContext.USER || context === UserGrantContext.NONE) && loadedGrantId && loadedGrantId === grant.grantId && grantToEdit == grant.id">
|
||||||
<mat-form-field class="form-field" appearance="outline">
|
<cnsl-form-field class="form-field" appearance="outline">
|
||||||
<mat-label>{{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }}</mat-label>
|
<!-- <cnsl-label>{{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }}</cnsl-label> -->
|
||||||
<mat-select [(ngModel)]="grant.roleKeysList" multiple
|
<mat-select [(ngModel)]="grant.roleKeysList" multiple
|
||||||
[disabled]="disableWrite || !((['user.grant.write$'] | hasRole | async) || ((context === UserGrantContext.OWNED_PROJECT ? ['user.grant.write:' + grant?.projectId] : context === UserGrantContext.GRANTED_PROJECT ? ['user.grant.write:' + grant?.grantId] : []) | hasRole | async))"
|
[disabled]="disableWrite || !((['user.grant.write$'] | hasRole | async) || ((context === UserGrantContext.OWNED_PROJECT ? ['user.grant.write:' + grant?.projectId] : context === UserGrantContext.GRANTED_PROJECT ? ['user.grant.write:' + grant?.grantId] : []) | hasRole | async))"
|
||||||
(selectionChange)="updateRoles(grant, $event)">
|
(selectionChange)="updateRoles(grant, $event)">
|
||||||
@ -130,12 +133,14 @@
|
|||||||
{{role}}
|
{{role}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<button *ngIf="context === UserGrantContext.USER || context === UserGrantContext.NONE"
|
<button matTooltip="{{'ACTIONS.CLOSE' | translate}}"
|
||||||
|
*ngIf="context === UserGrantContext.USER || context === UserGrantContext.NONE"
|
||||||
mat-icon-button (click)="grantToEdit=''">
|
mat-icon-button (click)="grantToEdit=''">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
@ -144,6 +149,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div *ngIf="(dataSource.loading$ | async) == false && !dataSource?.totalResult" class="no-content-row">
|
||||||
|
<i class="las la-exclamation"></i>
|
||||||
|
<span>{{'GRANTS.EMPTY' | translate}}</span>
|
||||||
|
</div>
|
||||||
<mat-paginator class="paginator" #paginator [length]="dataSource.totalResult" [pageSize]="INITIAL_PAGE_SIZE"
|
<mat-paginator class="paginator" #paginator [length]="dataSource.totalResult" [pageSize]="INITIAL_PAGE_SIZE"
|
||||||
[length]="dataSource.totalResult" [pageSizeOptions]="[2, 3, 25, 50, 100, 250]" (page)="changePage($event)">
|
[length]="dataSource.totalResult" [pageSizeOptions]="[2, 3, 25, 50, 100, 250]" (page)="changePage($event)">
|
||||||
</mat-paginator>
|
</mat-paginator>
|
||||||
@ -152,7 +161,7 @@
|
|||||||
|
|
||||||
<ng-template #templateRef let-key="key">
|
<ng-template #templateRef let-key="key">
|
||||||
<button class="search-button" mat-icon-button (click)="setFilter(key)">
|
<button class="search-button" mat-icon-button (click)="setFilter(key)">
|
||||||
<mat-icon *ngIf="this.userGrantSearchKey != key">search</mat-icon>
|
<mat-icon class="icon" *ngIf="this.userGrantSearchKey != key">search</mat-icon>
|
||||||
<mat-icon *ngIf="this.userGrantSearchKey == key">search_off</mat-icon>
|
<mat-icon class="icon" *ngIf="this.userGrantSearchKey == key">search_off</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
@ -23,21 +23,21 @@
|
|||||||
|
|
||||||
th {
|
th {
|
||||||
.search-button {
|
.search-button {
|
||||||
display: none;
|
visibility: hidden;
|
||||||
|
width: 30px;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&.search-active {
|
&.search-active {
|
||||||
.search-button {
|
.search-button {
|
||||||
display: inline-block;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.selection {
|
|
||||||
width: 50px;
|
|
||||||
max-width: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,9 @@
|
|||||||
|
|
||||||
button {
|
button {
|
||||||
margin: .5rem 0;
|
margin: .5rem 0;
|
||||||
|
display: block;
|
||||||
max-width: 120px;
|
max-width: 120px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
i {
|
i {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
@ -77,10 +79,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.row-form {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.form-field {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.fill-space {
|
.fill-space {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.role-data {
|
||||||
|
min-width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-block {
|
||||||
|
margin: .5rem 0;
|
||||||
|
display: block;
|
||||||
|
min-width: 120px;
|
||||||
|
|
||||||
|
.date-sub {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--grey);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.filtername {
|
.filtername {
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
|||||||
@Input() public displayedColumns: string[] = ['select',
|
@Input() public displayedColumns: string[] = ['select',
|
||||||
'user',
|
'user',
|
||||||
'org',
|
'org',
|
||||||
'projectId', 'creationDate', 'changeDate', 'roleNamesList'];
|
'projectId', 'dates', 'roleNamesList'];
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.dataSource = new UserGrantsDataSource(this.userService);
|
this.dataSource = new UserGrantsDataSource(this.userService);
|
||||||
|
@ -3,9 +3,7 @@ import { NgModule } from '@angular/core';
|
|||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
@ -18,12 +16,12 @@ import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.mod
|
|||||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
||||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
||||||
|
|
||||||
|
import { InputModule } from '../../modules/input/input.module';
|
||||||
import { AvatarModule } from '../avatar/avatar.module';
|
import { AvatarModule } from '../avatar/avatar.module';
|
||||||
import { RefreshTableModule } from '../refresh-table/refresh-table.module';
|
import { RefreshTableModule } from '../refresh-table/refresh-table.module';
|
||||||
import { UserGrantsComponent } from './user-grants.component';
|
import { UserGrantsComponent } from './user-grants.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [UserGrantsComponent],
|
declarations: [UserGrantsComponent],
|
||||||
imports: [
|
imports: [
|
||||||
@ -40,13 +38,12 @@ import { UserGrantsComponent } from './user-grants.component';
|
|||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatInputModule,
|
|
||||||
MatFormFieldModule,
|
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
HasRolePipeModule,
|
HasRolePipeModule,
|
||||||
TimestampToDatePipeModule,
|
TimestampToDatePipeModule,
|
||||||
RefreshTableModule,
|
RefreshTableModule,
|
||||||
LocalizedDatePipeModule,
|
LocalizedDatePipeModule,
|
||||||
|
InputModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
UserGrantsComponent,
|
UserGrantsComponent,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<div class="max-width-container">
|
<div class="max-width-container">
|
||||||
<h2>{{ 'GRANTS.TITLE' | translate }}</h2>
|
<h1>{{ 'GRANTS.TITLE' | translate }}</h1>
|
||||||
<p class="desc">{{'GRANTS.DESC' | translate }}</p>
|
<p class="desc">{{'GRANTS.DESC' | translate }}</p>
|
||||||
<app-user-grants
|
<app-user-grants [displayedColumns]="['select', 'user', 'org', 'projectId', 'dates', 'roleNamesList']"
|
||||||
[displayedColumns]="['select', 'user', 'org', 'projectId', 'creationDate', 'changeDate', 'roleNamesList']"
|
|
||||||
[disableWrite]="((['user.grant.write$'] | hasRole) | async) == false"
|
[disableWrite]="((['user.grant.write$'] | hasRole) | async) == false"
|
||||||
[disableDelete]="((['user.grant.delete$'] | hasRole) | async) == false">
|
[disableDelete]="((['user.grant.delete$'] | hasRole) | async) == false"
|
||||||
|
[refreshOnPreviousRoutes]="['/grant-create']">
|
||||||
</app-user-grants>
|
</app-user-grants>
|
||||||
</div>
|
</div>
|
@ -1,3 +1,7 @@
|
|||||||
|
h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.desc {
|
.desc {
|
||||||
color: var(--grey);
|
color: var(--grey);
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
|
@ -19,11 +19,6 @@
|
|||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.selection {
|
|
||||||
width: 50px;
|
|
||||||
max-width: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,6 @@ export class IamMembersComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public removeMemberSelection(): void {
|
public removeMemberSelection(): void {
|
||||||
console.log(this.selection);
|
|
||||||
Promise.all(this.selection.map(member => {
|
Promise.all(this.selection.map(member => {
|
||||||
return this.adminService.RemoveIamMember(member.userId).then(() => {
|
return this.adminService.RemoveIamMember(member.userId).then(() => {
|
||||||
this.toast.showInfo('IAM.TOAST.MEMBERREMOVED', true);
|
this.toast.showInfo('IAM.TOAST.MEMBERREMOVED', true);
|
||||||
|
@ -19,11 +19,6 @@
|
|||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.selection {
|
|
||||||
width: 50px;
|
|
||||||
max-width: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,19 +6,18 @@ import { MatButtonModule } from '@angular/material/button';
|
|||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSortModule } from '@angular/material/sort';
|
import { MatSortModule } from '@angular/material/sort';
|
||||||
import { MatTableModule } from '@angular/material/table';
|
import { MatTableModule } from '@angular/material/table';
|
||||||
import { MatTabsModule } from '@angular/material/tabs';
|
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
import { CardModule } from 'src/app/modules/card/card.module';
|
import { CardModule } from 'src/app/modules/card/card.module';
|
||||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||||
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||||
import { PolicyGridModule } from 'src/app/modules/policy-grid/policy-grid.module';
|
import { PolicyGridModule } from 'src/app/modules/policy-grid/policy-grid.module';
|
||||||
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
||||||
@ -46,10 +45,9 @@ import { IamComponent } from './iam.component';
|
|||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MetaLayoutModule,
|
MetaLayoutModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatTabsModule,
|
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
@ -12,17 +12,18 @@
|
|||||||
|
|
||||||
<ng-container *ngIf="!forSelf">
|
<ng-container *ngIf="!forSelf">
|
||||||
<ng-container *ngIf="currentCreateStep == 1">
|
<ng-container *ngIf="currentCreateStep == 1">
|
||||||
<h1>{{'ORG.PAGES.ORGDETAIL_TITLE' | translate}}</h1>
|
<h1>{{'ORG.PAGES.ORGDETAIL_TITLE' | translate}} </h1>
|
||||||
|
|
||||||
<form [formGroup]="orgForm" (ngSubmit)="next()">
|
<form [formGroup]="orgForm" (ngSubmit)="next()">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="name" />
|
<input cnslInput formControlName="name" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'ORG_DETAIL.DETAIL.DOMAIN' | translate }}</mat-label>
|
<cnsl-label>{{ 'ORG_DETAIL.DETAIL.DOMAIN' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="domain" />
|
<input cnslInput formControlName="domain" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
@ -42,67 +43,67 @@
|
|||||||
<form [formGroup]="userForm" class="form">
|
<form [formGroup]="userForm" class="form">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p class="section">{{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}</p>
|
<p class="section">{{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}</p>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.USERNAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PROFILE.USERNAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="userName" required />
|
<input cnslInput formControlName="userName" required />
|
||||||
<mat-error *ngIf="userName?.invalid && userName?.errors?.required">
|
<span cnsl-error *ngIf="userName?.invalid && userName?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.EMAIL' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PROFILE.EMAIL' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="email" required />
|
<input cnslInput formControlName="email" required />
|
||||||
<mat-error *ngIf="email?.invalid && email?.errors?.required">
|
<span cnsl-error *ngIf="email?.invalid && email?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="firstName" required />
|
<input cnslInput formControlName="firstName" required />
|
||||||
<mat-error *ngIf="firstName?.invalid && firstName?.errors?.required">
|
<span cnsl-error *ngIf="firstName?.invalid && firstName?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.LASTNAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PROFILE.LASTNAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="lastName" required />
|
<input cnslInput formControlName="lastName" required />
|
||||||
<mat-error *ngIf="lastName?.invalid && lastName?.errors?.required">
|
<span cnsl-error *ngIf="lastName?.invalid && lastName?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="nickName" />
|
<input cnslInput formControlName="nickName" />
|
||||||
<mat-error *ngIf="nickName?.invalid && nickName?.errors?.required">
|
<span cnsl-error *ngIf="nickName?.invalid && nickName?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<p class="section">{{ 'USER.CREATE.GENDERLANGSECTION' | translate }}</p>
|
<p class="section">{{ 'USER.CREATE.GENDERLANGSECTION' | translate }}</p>
|
||||||
|
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.GENDER' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PROFILE.GENDER' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="gender">
|
<mat-select formControlName="gender">
|
||||||
<mat-option *ngFor="let gender of genders" [value]="gender">
|
<mat-option *ngFor="let gender of genders" [value]="gender">
|
||||||
{{ 'GENDERS.'+gender | translate }}
|
{{ 'GENDERS.'+gender | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
<mat-error *ngIf="gender?.invalid && gender?.errors?.required">
|
<span cnsl-error *ngIf="gender?.invalid && gender?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="preferredLanguage">
|
<mat-select formControlName="preferredLanguage">
|
||||||
<mat-option *ngFor="let language of languages" [value]="language">
|
<mat-option *ngFor="let language of languages" [value]="language">
|
||||||
{{ 'LANGUAGES.'+language | translate }}
|
{{ 'LANGUAGES.'+language | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
<mat-error
|
<span cnsl-error
|
||||||
*ngIf="preferredLanguage?.invalid && preferredLanguage?.errors?.required">
|
*ngIf="preferredLanguage?.invalid && preferredLanguage?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-checkbox class="checkbox" [(ngModel)]="usePassword"
|
<mat-checkbox class="checkbox" [(ngModel)]="usePassword"
|
||||||
[ngModelOptions]="{standalone: true}" (change)="initPwdValidators()">
|
[ngModelOptions]="{standalone: true}" (change)="initPwdValidators()">
|
||||||
@ -116,28 +117,28 @@
|
|||||||
</app-password-complexity-view>
|
</app-password-complexity-view>
|
||||||
|
|
||||||
<form [formGroup]="pwdForm" class="form">
|
<form [formGroup]="pwdForm" class="form">
|
||||||
<mat-form-field class="formfield" *ngIf="password" appearance="outline">
|
<cnsl-form-field class="formfield" *ngIf="password" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PASSWORD.NEW' | translate }}</cnsl-label>
|
||||||
<input autocomplete="off" name="firstpassword" matInput
|
<input cnslInput autocomplete="off" name="firstpassword"
|
||||||
formControlName="password" type="password" />
|
formControlName="password" type="password" />
|
||||||
|
|
||||||
<mat-error *ngIf="password?.errors?.required">
|
<span cnsl-error *ngIf="password?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
|
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
<mat-form-field class="formfield" *ngIf="confirmPassword" appearance="outline">
|
<cnsl-form-field class="formfield" *ngIf="confirmPassword" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</mat-label>
|
<cnsl-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</cnsl-label>
|
||||||
<input autocomplete="off" name="confirmPassword" matInput
|
<input cnslInput autocomplete="off" name="confirmPassword"
|
||||||
formControlName="confirmPassword" type="password" />
|
formControlName="confirmPassword" type="password" />
|
||||||
|
|
||||||
<mat-error *ngIf="confirmPassword?.errors?.required">
|
<span cnsl-error *ngIf="confirmPassword?.errors?.required">
|
||||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
<span cnsl-error *ngIf="confirmPassword?.errors?.notequal">
|
||||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||||
</mat-error>
|
</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</form>
|
</form>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
@ -157,13 +158,14 @@
|
|||||||
<ng-template appHasRole [appHasRole]="['org.create']">
|
<ng-template appHasRole [appHasRole]="['org.create']">
|
||||||
<div *ngIf="forSelf">
|
<div *ngIf="forSelf">
|
||||||
<ng-container *ngIf="currentCreateStep == 1">
|
<ng-container *ngIf="currentCreateStep == 1">
|
||||||
<h1>{{'ORG.PAGES.ORGDETAIL_TITLE' | translate}}</h1>
|
<h1>{{'ORG.PAGES.ORGDETAIL_TITLE_WITHOUT_DOMAIN' | translate}} </h1>
|
||||||
|
|
||||||
<form [formGroup]="orgForm" (ngSubmit)="createOrgForSelf()">
|
<form [formGroup]="orgForm" (ngSubmit)="createOrgForSelf()">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field class="formfield" appearance="outline">
|
<cnsl-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="name" />
|
<input cnslInput formControlName="name" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
|
@ -107,8 +107,15 @@ export class OrgCreateComponent {
|
|||||||
|
|
||||||
this.adminService
|
this.adminService
|
||||||
.SetUpOrg(createOrgRequest, humanRequest)
|
.SetUpOrg(createOrgRequest, humanRequest)
|
||||||
.then((data: OrgSetUpResponse) => {
|
.then((org: OrgSetUpResponse) => {
|
||||||
this.router.navigate(['orgs', data.toObject().org?.id]);
|
this.router.navigate(['/org/overview']);
|
||||||
|
// const orgResp = org.getOrg();
|
||||||
|
// if (orgResp) {
|
||||||
|
// this.authService.setActiveOrg(orgResp.toObject());
|
||||||
|
// this.router.navigate(['/org']);
|
||||||
|
// } else {
|
||||||
|
// this.router.navigate(['/org', 'overview']);
|
||||||
|
// }
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
@ -193,7 +200,12 @@ export class OrgCreateComponent {
|
|||||||
public createOrgForSelf(): void {
|
public createOrgForSelf(): void {
|
||||||
if (this.name && this.name.value) {
|
if (this.name && this.name.value) {
|
||||||
this.mgmtService.CreateOrg(this.name.value).then((org) => {
|
this.mgmtService.CreateOrg(this.name.value).then((org) => {
|
||||||
this.router.navigate(['orgs', org.toObject().id]);
|
this.router.navigate(['/org/overview']);
|
||||||
|
// const newOrg = org.toObject();
|
||||||
|
// setTimeout(() => {
|
||||||
|
// this.authService.setActiveOrg(newOrg);
|
||||||
|
// this.router.navigate(['/org']);
|
||||||
|
// }, 1000);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
|
@ -3,13 +3,12 @@ import { NgModule } from '@angular/core';
|
|||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { PasswordComplexityViewModule } from 'src/app/modules/password-complexity-view/password-complexity-view.module';
|
import { PasswordComplexityViewModule } from 'src/app/modules/password-complexity-view/password-complexity-view.module';
|
||||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||||
|
|
||||||
@ -23,8 +22,7 @@ import { OrgCreateComponent } from './org-create.component';
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
InputModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<p class="desc"> {{'ORG.DOMAINS.ADD.DESCRIPTION' | translate}}</p>
|
<p class="desc"> {{'ORG.DOMAINS.ADD.DESCRIPTION' | translate}}</p>
|
||||||
|
|
||||||
<mat-form-field label="Domain" required="true" class="form-field" appearance="outline">
|
<cnsl-form-field label="Domain" required="true" class="form-field" appearance="outline">
|
||||||
<mat-label>Domain</mat-label>
|
<cnsl-label>Domain</cnsl-label>
|
||||||
<input matInput [(ngModel)]="newdomain" />
|
<input cnslInput [(ngModel)]="newdomain" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions class="action">
|
<div mat-dialog-actions class="action">
|
||||||
<button mat-button (click)="closeDialog()">
|
<button mat-button (click)="closeDialog()">
|
||||||
|
@ -2,9 +2,8 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { AddDomainDialogComponent } from './add-domain-dialog.component';
|
import { AddDomainDialogComponent } from './add-domain-dialog.component';
|
||||||
|
|
||||||
@ -14,8 +13,7 @@ import { AddDomainDialogComponent } from './add-domain-dialog.component';
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatInputModule,
|
|
||||||
FormsModule,
|
FormsModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
color="primary">{{ 'ORG.PAGES.DOWNLOAD_FILE' | translate }}</button>
|
color="primary">{{ 'ORG.PAGES.DOWNLOAD_FILE' | translate }}</button>
|
||||||
<button color="primary" class="verify-button" type="submit" mat-raised-button (click)="validate()">
|
<button color="primary" class="verify-button" type="submit" mat-raised-button (click)="validate()">
|
||||||
<span>{{ 'ACTIONS.VERIFY' | translate }}</span>
|
<span>{{ 'ACTIONS.VERIFY' | translate }}</span>
|
||||||
<mat-spinner class="spinner" *ngIf="!validating" diameter="20" mode="indeterminate"></mat-spinner>
|
|
||||||
</button>
|
</button>
|
||||||
<mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner>
|
<mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
.domain {
|
.domain {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: .5rem 0;
|
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@ -55,6 +54,7 @@
|
|||||||
&:hover {
|
&:hover {
|
||||||
.rem-button {
|
.rem-button {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
|
transition: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<app-refresh-table *ngIf="dataSource" (refreshed)="refresh()" [dataSize]="dataSource.data.length"
|
<app-refresh-table *ngIf="dataSource" (refreshed)="refresh()" [dataSize]="dataSource.data.length"
|
||||||
[loading]="loading$ | async">
|
[loading]="loading$ | async">
|
||||||
|
|
||||||
<mat-form-field @appearfade *ngIf="orgSearchKey != undefined" actions class="filter">
|
<cnsl-form-field @appearfade *ngIf="orgSearchKey != undefined" actions class="filter">
|
||||||
<mat-label>{{'ORG.PAGES.FILTER' | translate}}</mat-label>
|
<cnsl-label>{{'ORG.PAGES.FILTER' | translate}}</cnsl-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="{{'ORG.PAGES.FILTERPLACEHOLDER' | translate}}"
|
<input cnslInput (keyup)="applyFilter($event)" placeholder="{{'ORG.PAGES.FILTERPLACEHOLDER' | translate}}"
|
||||||
#input>
|
#input>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<table [dataSource]="dataSource" mat-table class="table" matSort aria-label="Elements">
|
<table [dataSource]="dataSource" mat-table class="table" matSort aria-label="Elements">
|
||||||
|
|
||||||
|
@ -23,11 +23,6 @@ h1 {
|
|||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.selection {
|
|
||||||
width: 50px;
|
|
||||||
max-width: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pointer {
|
.pointer {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { AfterViewInit, Component, ViewChild } from '@angular/core';
|
import { AfterViewInit, Component, Input, ViewChild } from '@angular/core';
|
||||||
import { MatInput } from '@angular/material/input';
|
|
||||||
import { MatPaginator } from '@angular/material/paginator';
|
import { MatPaginator } from '@angular/material/paginator';
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatSort } from '@angular/material/sort';
|
||||||
import { MatTableDataSource } from '@angular/material/table';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
@ -23,7 +22,7 @@ export class OrgListComponent implements AfterViewInit {
|
|||||||
|
|
||||||
@ViewChild(MatPaginator) public paginator!: MatPaginator;
|
@ViewChild(MatPaginator) public paginator!: MatPaginator;
|
||||||
@ViewChild(MatSort) sort!: MatSort;
|
@ViewChild(MatSort) sort!: MatSort;
|
||||||
@ViewChild('input') public filter!: MatInput;
|
@ViewChild('input') public filter!: Input;
|
||||||
|
|
||||||
public dataSource!: MatTableDataSource<Org.AsObject>;
|
public dataSource!: MatTableDataSource<Org.AsObject>;
|
||||||
public displayedColumns: string[] = ['select', 'id', 'name'];
|
public displayedColumns: string[] = ['select', 'id', 'name'];
|
||||||
|
@ -2,15 +2,14 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatRadioModule } from '@angular/material/radio';
|
import { MatRadioModule } from '@angular/material/radio';
|
||||||
import { MatSortModule } from '@angular/material/sort';
|
import { MatSortModule } from '@angular/material/sort';
|
||||||
import { MatTableModule } from '@angular/material/table';
|
import { MatTableModule } from '@angular/material/table';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
||||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
||||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
||||||
@ -34,8 +33,7 @@ import { OrgListComponent } from './org-list.component';
|
|||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
MatRadioModule,
|
MatRadioModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatInputModule,
|
|
||||||
FormsModule,
|
FormsModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<form>
|
<form>
|
||||||
<mat-form-field appearance="outline" class="full-width">
|
<cnsl-form-field appearance="outline" class="full-width">
|
||||||
<mat-label>Role Name</mat-label>
|
<cnsl-label>Role Name</cnsl-label>
|
||||||
|
|
||||||
<mat-select [formControl]="myControl" multiple>
|
<mat-select [formControl]="myControl" multiple>
|
||||||
<mat-option *ngIf="isLoading" class="is-loading">
|
<mat-option *ngIf="isLoading" class="is-loading">
|
||||||
@ -10,5 +10,5 @@
|
|||||||
{{ role }}
|
{{ role }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
</form>
|
</form>
|
@ -2,12 +2,11 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
|
|
||||||
import { OrgMemberRolesAutocompleteComponent } from './org-member-roles-autocomplete.component';
|
import { OrgMemberRolesAutocompleteComponent } from './org-member-roles-autocomplete.component';
|
||||||
|
|
||||||
@ -17,9 +16,8 @@ import { OrgMemberRolesAutocompleteComponent } from './org-member-roles-autocomp
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatInputModule,
|
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
@ -4,9 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatTabsModule } from '@angular/material/tabs';
|
import { MatTabsModule } from '@angular/material/tabs';
|
||||||
@ -17,6 +15,7 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
|||||||
import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/member-create-dialog.module';
|
import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/member-create-dialog.module';
|
||||||
import { CardModule } from 'src/app/modules/card/card.module';
|
import { CardModule } from 'src/app/modules/card/card.module';
|
||||||
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
||||||
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||||
import { PolicyGridModule } from 'src/app/modules/policy-grid/policy-grid.module';
|
import { PolicyGridModule } from 'src/app/modules/policy-grid/policy-grid.module';
|
||||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||||
@ -37,8 +36,7 @@ import { OrgsRoutingModule } from './orgs-routing.module';
|
|||||||
OrgsRoutingModule,
|
OrgsRoutingModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HasRoleModule,
|
HasRoleModule,
|
||||||
MatFormFieldModule,
|
InputModule,
|
||||||
MatInputModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
CardModule,
|
CardModule,
|
||||||
|
@ -21,18 +21,18 @@
|
|||||||
<ng-template matStepLabel>{{'APP.OIDC.NAMEANDTYPESECTION' | translate}}</ng-template>
|
<ng-template matStepLabel>{{'APP.OIDC.NAMEANDTYPESECTION' | translate}}</ng-template>
|
||||||
|
|
||||||
<p class="step-title">{{'APP.OIDC.TITLEFIRST' | translate}}</p>
|
<p class="step-title">{{'APP.OIDC.TITLEFIRST' | translate}}</p>
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'APP.NAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="name" />
|
<input cnslInput formControlName="name" />
|
||||||
<mat-error *ngIf="name?.errors?.required">{{'PROJECT.APP.NAMEREQUIRED' | translate}}</mat-error>
|
<span cnsl-error *ngIf="name?.errors?.required">{{'PROJECT.APP.NAMEREQUIRED' | translate}}</span>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<p class="step-title">{{'APP.OIDC.TYPETITLE' | translate}}</p>
|
<p class="step-title">{{'APP.OIDC.TYPETITLE' | translate}}</p>
|
||||||
<mat-radio-group color="primary" aria-labelledby="radio-group-label" class="radio-group"
|
<mat-radio-group color="primary" aria-labelledby="radio-group-label" class="radio-group"
|
||||||
formControlName="applicationType">
|
formControlName="applicationType">
|
||||||
<mat-radio-button class="radio-button" *ngFor="let type of oidcAppTypes | keyvalue"
|
<mat-radio-button class="radio-button" *ngFor="let type of oidcAppTypes | keyvalue"
|
||||||
[value]="type.value">
|
[value]="type.value">
|
||||||
<div>{{'APP.OIDC.APPTYPE'+type.key | translate}}</div>
|
<div>{{('APP.OIDC.APPTYPE'+type.key.toString()) | translate}}</div>
|
||||||
</mat-radio-button>
|
</mat-radio-button>
|
||||||
</mat-radio-group>
|
</mat-radio-group>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
@ -89,19 +89,24 @@
|
|||||||
<p class="step-description" *ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB">
|
<p class="step-description" *ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB">
|
||||||
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}</p>
|
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}</p>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="full-width">
|
<form class="chip-form" (ngSubmit)="addUri(redInput, 'REDIRECT')">
|
||||||
<mat-label>{{ 'APP.OIDC.REDIRECT' | translate }}</mat-label>
|
<cnsl-form-field appearance="outline" class="full-width">
|
||||||
|
<cnsl-label>{{ 'APP.OIDC.REDIRECT' | translate }}</cnsl-label>
|
||||||
|
<input #redInput cnslInput placeholder="{{'APP.OIDC.COMMAORENTERSEPERATION' | translate}}"
|
||||||
|
[formControl]="redirectControl">
|
||||||
|
</cnsl-form-field>
|
||||||
|
<button matTooltip="{{'ACTIONS.ADD' | translate}}" type="submit" mat-icon-button>
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
<mat-chip-list #chipRedirectList aria-label="uri selection">
|
<mat-chip-list #chipRedirectList aria-label="uri selection">
|
||||||
<mat-chip class="chip" *ngFor="let uri of oidcApp.redirectUrisList" selected removable
|
<mat-chip #redInput class="chip" *ngFor="let uri of oidcApp.redirectUrisList" selected removable
|
||||||
[matTooltip]="!uri.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''"
|
[matTooltip]="!uri?.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''"
|
||||||
[color]="!uri.startsWith('https://') ? 'warn': 'white'" (removed)="removeUri(uri, 'REDIRECT')">
|
[color]="!uri?.startsWith('https://') ? 'warn': 'white'" (removed)="removeUri(uri, 'REDIRECT')">
|
||||||
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input [matChipInputFor]="chipRedirectList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
|
||||||
[matChipInputAddOnBlur]="true" [formControl]="redirectControl"
|
|
||||||
(matChipInputTokenEnd)="addUri($event, 'REDIRECT')">
|
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-form-field>
|
|
||||||
<p *ngIf="redirectControl.invalid" class="error">{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
<p *ngIf="redirectControl.invalid" class="error">{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
||||||
|
|
||||||
<p class="step-title">{{'APP.OIDC.POSTREDIRECTTITLE' | translate}}</p>
|
<p class="step-title">{{'APP.OIDC.POSTREDIRECTTITLE' | translate}}</p>
|
||||||
@ -112,20 +117,25 @@
|
|||||||
*ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB || oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT">
|
*ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB || oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT">
|
||||||
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}</p>
|
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}</p>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="full-width">
|
<form class="chip-form" (ngSubmit)="addUri(postInput, 'POSTREDIRECT')">
|
||||||
<mat-label>{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}</mat-label>
|
<cnsl-form-field appearance="outline" class="full-width">
|
||||||
|
<cnsl-label>{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}</cnsl-label>
|
||||||
|
<input #postInput cnslInput placeholder="{{'APP.OIDC.COMMAORENTERSEPERATION' | translate}}"
|
||||||
|
[formControl]="postRedirectControl">
|
||||||
|
</cnsl-form-field>
|
||||||
|
<button matTooltip="{{'ACTIONS.ADD' | translate}}" type="submit" mat-icon-button>
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
<mat-chip-list #chipPostRedirectList aria-label="uri selection">
|
<mat-chip-list #chipPostRedirectList aria-label="uri selection">
|
||||||
<mat-chip class="chip" *ngFor="let uri of oidcApp.postLogoutRedirectUrisList"
|
<mat-chip class="chip" *ngFor="let uri of oidcApp.postLogoutRedirectUrisList"
|
||||||
[matTooltip]="!uri.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''"
|
[matTooltip]="!uri?.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''"
|
||||||
removable (removed)="removeUri(uri, 'POSTREDIRECT')" selected
|
removable (removed)="removeUri(uri, 'POSTREDIRECT')" selected
|
||||||
[color]="!uri.startsWith('https://') ? 'warn': 'white'">
|
[color]="!uri?.startsWith('https://') ? 'warn': 'white'">
|
||||||
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input [matChipInputFor]="chipPostRedirectList" [formControl]="postRedirectControl"
|
|
||||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
|
||||||
(matChipInputTokenEnd)="addUri($event, 'POSTREDIRECT')">
|
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-form-field>
|
|
||||||
<p *ngIf="postRedirectControl.invalid" class="error">{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
<p *ngIf="postRedirectControl.invalid" class="error">{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
@ -223,71 +233,72 @@
|
|||||||
<div *ngIf="devmode" class="dev">
|
<div *ngIf="devmode" class="dev">
|
||||||
<form [formGroup]="form" (ngSubmit)="saveOIDCApp()">
|
<form [formGroup]="form" (ngSubmit)="saveOIDCApp()">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'APP.NAME' | translate }}</mat-label>
|
<cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label>
|
||||||
<input matInput formControlName="name" />
|
<input cnslInput formControlName="name" />
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'APP.OIDC.APPTYPE' | translate }}</mat-label>
|
<cnsl-label>{{ 'APP.OIDC.APPTYPE' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="applicationType">
|
<mat-select formControlName="applicationType">
|
||||||
<mat-option *ngFor="let type of oidcAppTypes" [value]="type">
|
<mat-option *ngFor="let type of oidcAppTypes" [value]="type">
|
||||||
{{ 'APP.OIDC.APPTYPE'+type | translate }}
|
{{ 'APP.OIDC.APPTYPE'+type | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'APP.OIDC.GRANT' | translate }}</mat-label>
|
<cnsl-label>{{ 'APP.OIDC.GRANT' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="grantTypesList" multiple>
|
<mat-select formControlName="grantTypesList" multiple>
|
||||||
<mat-option *ngFor="let grant of oidcGrantTypes" [value]="grant.type">
|
<mat-option *ngFor="let grant of oidcGrantTypes" [value]="grant.type">
|
||||||
{{ ('APP.OIDC.GRANT' + grant.type) | translate }}
|
{{ ('APP.OIDC.GRANT' + grant.type) | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'APP.OIDC.RESPONSE' | translate }}</mat-label>
|
<cnsl-label>{{ 'APP.OIDC.RESPONSE' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="responseTypesList" multiple>
|
<mat-select formControlName="responseTypesList" multiple>
|
||||||
<mat-option *ngFor="let type of oidcResponseTypes" [value]="type.type">
|
<mat-option *ngFor="let type of oidcResponseTypes" [value]="type.type">
|
||||||
{{ 'APP.OIDC.RESPONSE'+type.type | translate }}
|
{{ 'APP.OIDC.RESPONSE'+type.type | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="formfield">
|
<cnsl-form-field appearance="outline" class="formfield">
|
||||||
<mat-label>{{ 'APP.OIDC.AUTHMETHOD' | translate }}</mat-label>
|
<cnsl-label>{{ 'APP.OIDC.AUTHMETHOD' | translate }}</cnsl-label>
|
||||||
<mat-select formControlName="authMethodType">
|
<mat-select formControlName="authMethodType">
|
||||||
<mat-option *ngFor="let type of oidcAuthMethodType" [value]="type.type">
|
<mat-option *ngFor="let type of oidcAuthMethodType" [value]="type.type">
|
||||||
{{ 'APP.OIDC.AUTHMETHOD'+type.type | translate }}
|
{{ 'APP.OIDC.AUTHMETHOD'+type.type | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="formfield full-width">
|
<cnsl-form-field appearance="outline" class="formfield full-width">
|
||||||
<mat-label>{{ 'APP.OIDC.REDIRECT' | translate }}</mat-label>
|
<cnsl-label>{{ 'APP.OIDC.REDIRECT' | translate }}</cnsl-label>
|
||||||
<mat-chip-list #chipRedirectList aria-label="uri selection">
|
<mat-chip-list #chipRedirectList aria-label="uri selection">
|
||||||
<mat-chip class="chip" *ngFor="let uri of oidcApp.redirectUrisList" removable
|
<mat-chip class="chip" *ngFor="let uri of oidcApp.redirectUrisList" removable
|
||||||
(removed)="removeUri(uri, 'REDIRECT')">
|
(removed)="removeUri(uri, 'REDIRECT')">
|
||||||
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input [matChipInputFor]="chipRedirectList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
<input cnslInput [matChipInputFor]="chipRedirectList"
|
||||||
[matChipInputAddOnBlur]="true" (matChipInputTokenEnd)="addUri($event, 'REDIRECT')">
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
||||||
|
(matChipInputTokenEnd)="addUri($event, 'REDIRECT')">
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="formfield full-width">
|
<cnsl-form-field appearance="outline" class="formfield full-width">
|
||||||
<mat-label>{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}</mat-label>
|
<cnsl-label>{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}</cnsl-label>
|
||||||
<mat-chip-list #chipPostRedirectList aria-label="uri selection">
|
<mat-chip-list #chipPostRedirectList aria-label="uri selection">
|
||||||
<mat-chip class="chip" *ngFor="let uri of oidcApp.postLogoutRedirectUrisList" removable
|
<mat-chip class="chip" *ngFor="let uri of oidcApp.postLogoutRedirectUrisList" removable
|
||||||
(removed)="removeUri(uri, 'POSTREDIRECT')">
|
(removed)="removeUri(uri, 'POSTREDIRECT')">
|
||||||
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input [matChipInputFor]="chipPostRedirectList"
|
<input cnslInput [matChipInputFor]="chipPostRedirectList"
|
||||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
||||||
(matChipInputTokenEnd)="addUri($event, 'POSTREDIRECT')">
|
(matChipInputTokenEnd)="addUri($event, 'POSTREDIRECT')">
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</mat-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -56,8 +56,9 @@ p.desc {
|
|||||||
margin: 0 -1.5rem;
|
margin: 0 -1.5rem;
|
||||||
|
|
||||||
.step-title {
|
.step-title {
|
||||||
font-size: 1.2rem;
|
font-size: 1rem;
|
||||||
color: var(--grey);
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .05em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.step-description {
|
.step-description {
|
||||||
@ -65,12 +66,31 @@ p.desc {
|
|||||||
color: var(--grey);
|
color: var(--grey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chip-form {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.formfield {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #f44336;
|
color: #f44336;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chip {
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.chip[color='white'] {
|
.chip[color='white'] {
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user