mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 23:27:23 +00:00
fix(console): cleanup structure, role guard, paginated requests, cleanup policies, toast i18n, view timestamp, preloading strategy, maennchenfindings, fix passwordchange (#483)
* routes, move grid to list comopnent * rename app list component, move to project sub * add owned-project-detail child module * seperate pipes * set password validators only if needed * create org initialize without pwd * no caps * self xss message * fix user table * fix project member paginator * fix project members pagination, user grant pag * move project grants, fix imports * fix owned project detail imports * use pipe and directives * ng content bindings, rem custom schemas * i18n, fix error toast parameter * toast i18n * side background * fix: sequence, add timestamp * audit * fix metanav background * org domain label * cleanup policy component * shorten user grant roles, mk cols visible as bind * move user components, show otp only if available * preload modules * fix password change * fix org create buttons * class css
This commit is contained in:
parent
2a3ecc0c6a
commit
4f3ccbfad0
21
console/package-lock.json
generated
21
console/package-lock.json
generated
@ -9381,9 +9381,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
"version": "4.17.19",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
|
||||
},
|
||||
"lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
@ -10167,6 +10167,21 @@
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"ngx-quicklink": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.2.3.tgz",
|
||||
"integrity": "sha512-a7yxNKNdkuL87GWuPAknxYyo+jRm7KTjHN7Ni8ohNQrVfPzV3c6UV4QWg88Hxi0gJC4wF3vEG3uviDnj5wJRaw==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
|
||||
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
|
@ -35,6 +35,7 @@
|
||||
"grpc-web": "^1.2.0",
|
||||
"moment": "^2.27.0",
|
||||
"ngx-moment": "^5.0.0",
|
||||
"ngx-quicklink": "^0.2.3",
|
||||
"prettier-stylelint": "^0.4.2",
|
||||
"rxjs": "~6.6.0",
|
||||
"ts-protoc-gen": "^0.12.0",
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { QuicklinkStrategy } from 'ngx-quicklink';
|
||||
|
||||
import { AuthGuard } from './guards/auth.guard';
|
||||
import { RoleGuard } from './guards/role.guard';
|
||||
@ -30,15 +31,30 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'users',
|
||||
loadChildren: () => import('./pages/users/users.module').then(m => m.UsersModule),
|
||||
canActivate: [AuthGuard],
|
||||
children: [
|
||||
{
|
||||
path: 'all',
|
||||
loadChildren: () => import('src/app/pages/users/user-list/user-list.module')
|
||||
.then(m => m.UserListModule),
|
||||
canActivate: [RoleGuard],
|
||||
data: {
|
||||
roles: ['user.read'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
loadChildren: () => import('src/app/pages/users/user-detail/user-detail.module')
|
||||
.then(m => m.UserDetailModule),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'iam',
|
||||
loadChildren: () => import('./pages/iam/iam.module').then(m => m.IamModule),
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
data: {
|
||||
roles: ['iam.read'],
|
||||
roles: ['iam.read', 'iam.write'],
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -49,27 +65,30 @@ const routes: Routes = [
|
||||
roles: ['org.read'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'grant-create/project/:projectid/grant/:grantid',
|
||||
loadChildren: () => import('src/app/pages/user-grant-create/user-grant-create.module')
|
||||
.then(m => m.UserGrantCreateModule),
|
||||
},
|
||||
{
|
||||
path: 'grant-create/project/:projectid',
|
||||
loadChildren: () => import('src/app/pages/user-grant-create/user-grant-create.module')
|
||||
.then(m => m.UserGrantCreateModule),
|
||||
},
|
||||
{
|
||||
path: 'grant-create/user/:userid',
|
||||
loadChildren: () => import('src/app/pages/user-grant-create/user-grant-create.module')
|
||||
.then(m => m.UserGrantCreateModule),
|
||||
},
|
||||
{
|
||||
path: 'grant-create',
|
||||
loadChildren: () => import('src/app/pages/user-grant-create/user-grant-create.module')
|
||||
.then(m => m.UserGrantCreateModule),
|
||||
canActivate: [AuthGuard],
|
||||
children: [
|
||||
{
|
||||
path: 'project/:projectid/grant/:grantid',
|
||||
loadChildren: () => import('src/app/pages/user-grant-create/user-grant-create.module')
|
||||
.then(m => m.UserGrantCreateModule),
|
||||
canActivate: [RoleGuard],
|
||||
data: {
|
||||
roles: ['project.grant.user.grant.write'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'project/:projectid',
|
||||
loadChildren: () => import('src/app/pages/user-grant-create/user-grant-create.module')
|
||||
.then(m => m.UserGrantCreateModule),
|
||||
canActivate: [RoleGuard],
|
||||
data: {
|
||||
roles: ['project.user.grant.write'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: 'signedout',
|
||||
loadChildren: () => import('./pages/signedout/signedout.module').then(m => m.SignedoutModule),
|
||||
@ -81,7 +100,14 @@ const routes: Routes = [
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
imports: [
|
||||
RouterModule.forRoot(
|
||||
routes,
|
||||
{
|
||||
preloadingStrategy: QuicklinkStrategy,
|
||||
},
|
||||
),
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
|
@ -1,130 +1,130 @@
|
||||
<ng-container *ngIf="(authService.user | async) || {} as user">
|
||||
<mat-toolbar class="root-header">
|
||||
<button aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
||||
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||
</button>
|
||||
<a *ngIf="(isHandset$ | async) == false" class="title" [routerLink]="['/']">
|
||||
<img class="logo" alt="zitadel logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
||||
src="../assets/images/zitadel-logo-oneline-darkdesign.svg" />
|
||||
<ng-template #lighttheme>
|
||||
<img alt="zitadel logo" class="logo" src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
||||
</ng-template>
|
||||
</a>
|
||||
<ng-container *ngIf="((['iam.read','iam.write'] | hasRole)) as iamuser$">
|
||||
<mat-toolbar class="root-header">
|
||||
<button aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
||||
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||
</button>
|
||||
<a *ngIf="(isHandset$ | async) == false" class="title" [routerLink]="['/']">
|
||||
<img class="logo" alt="zitadel logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
||||
src="../assets/images/zitadel-logo-oneline-darkdesign.svg" />
|
||||
<ng-template #lighttheme>
|
||||
<img alt="zitadel logo" class="logo" src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
||||
</ng-template>
|
||||
</a>
|
||||
|
||||
<button (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button
|
||||
[matMenuTriggerFor]="menu">{{org?.name ? org.name : 'NO NAME'}}
|
||||
<mat-icon>
|
||||
arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #menu="matMenu">
|
||||
<mat-progress-bar *ngIf="orgLoading" color="accent" mode="indeterminate"></mat-progress-bar>
|
||||
<button class="show-all" mat-menu-item
|
||||
[routerLink]="[ '/org/overview' ]">{{'MENU.SHOWORGS' | translate}}</button>
|
||||
|
||||
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id" *ngFor="let temporg of orgs"
|
||||
mat-menu-item (click)="setActiveOrg(temporg)">
|
||||
{{temporg?.name ? temporg.name : 'NO NAME'}}
|
||||
<button (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button
|
||||
[matMenuTriggerFor]="menu">{{org?.name ? org.name : 'NO NAME'}}
|
||||
<mat-icon>
|
||||
arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
||||
<mat-icon class="avatar">add</mat-icon>
|
||||
{{'MENU.NEWORG' | translate}}
|
||||
<mat-menu #menu="matMenu">
|
||||
<mat-progress-bar *ngIf="orgLoading" color="accent" mode="indeterminate"></mat-progress-bar>
|
||||
<button class="show-all" mat-menu-item
|
||||
[routerLink]="[ '/org/overview' ]">{{'MENU.SHOWORGS' | translate}}</button>
|
||||
|
||||
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id"
|
||||
*ngFor="let temporg of orgs" mat-menu-item (click)="setActiveOrg(temporg)">
|
||||
{{temporg?.name ? temporg.name : 'NO NAME'}}
|
||||
</button>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<div (clickOutside)="closeAccountCard()" class="icon-container">
|
||||
<app-avatar *ngIf="user && (user.displayName || (user.firstName && user.lastName))"
|
||||
class="avatar dontcloseonclick" (click)="showAccount = !showAccount" [active]="showAccount"
|
||||
[name]="user.displayName ? user.displayName : (user.firstName + ' '+ user.lastName)" [size]="38">
|
||||
</app-avatar>
|
||||
<app-accounts-card @accounts class="a_card mat-elevation-z5" *ngIf="showAccount"
|
||||
(close)="showAccount = false" [profile]="profile" [iamuser]="iamreadwrite">
|
||||
</app-accounts-card>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
||||
<mat-icon class="avatar">add</mat-icon>
|
||||
{{'MENU.NEWORG' | translate}}
|
||||
</button>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<mat-drawer-container class="main-container">
|
||||
<mat-drawer #drawer class="side" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||
[opened]="!(isHandset$ | async)">
|
||||
<div class="side-column">
|
||||
<div class="list">
|
||||
<ng-container *ngIf="authService.authenticationChanged | async">
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
|
||||
[routerLink]="['/users/me']">
|
||||
<i class="icon las la-user-circle"></i>
|
||||
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
<div (clickOutside)="closeAccountCard()" class="icon-container">
|
||||
<app-avatar *ngIf="user && (user.displayName || (user.firstName && user.lastName))"
|
||||
class="avatar dontcloseonclick" (click)="showAccount = !showAccount" [active]="showAccount"
|
||||
[name]="user.displayName ? user.displayName : (user.firstName + ' '+ user.lastName)" [size]="38">
|
||||
</app-avatar>
|
||||
<app-accounts-card @accounts class="a_card mat-elevation-z5" *ngIf="showAccount"
|
||||
(close)="showAccount = false" [profile]="profile" [iamuser]="iamuser$ | async">
|
||||
</app-accounts-card>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
|
||||
<ng-container *ngIf="iamreadwrite">
|
||||
<div class="divider">
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/iam']">
|
||||
<i class="icon las la-gem"></i>
|
||||
<span class="label">{{'MENU.IAM' | translate}}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
<mat-drawer-container class="main-container">
|
||||
<mat-drawer #drawer class="sidenav" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||
[opened]="!(isHandset$ | async)">
|
||||
<div class="side-column">
|
||||
<div class="list">
|
||||
<ng-container *ngIf="authService.authenticationChanged | async">
|
||||
<a class="nav-item" [routerLinkActive]="['active']"
|
||||
[routerLinkActiveOptions]="{ exact: true }" [routerLink]="['/users/me']">
|
||||
<i class="icon las la-user-circle"></i>
|
||||
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="showOrgSection">
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
||||
<i class="icon las la-archway"></i>
|
||||
<span class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="iamuser$ | async">
|
||||
<div class="divider">
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/iam']">
|
||||
<i class="icon las la-gem"></i>
|
||||
<span class="label">{{'MENU.IAM' | translate}}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="showProjectSection">
|
||||
<div class="divider">
|
||||
<div class="line"></div>
|
||||
<span>{{'MENU.PROJECTSSECTION' | translate}}</span>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<ng-template appHasRole [appHasRole]="['org.read']">
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
||||
<i class="icon las la-archway"></i>
|
||||
<span class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/projects']">
|
||||
<i class="icon las la-layer-group"></i>
|
||||
<span class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}
|
||||
{{ 'MENU.PROJECT' | translate }}</span>
|
||||
</a>
|
||||
<ng-template appHasRole [appHasRole]="['project.read']">
|
||||
<div class="divider">
|
||||
<div class="line"></div>
|
||||
<span>{{'MENU.PROJECTSSECTION' | translate}}</span>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/granted-projects']">
|
||||
<i class="icon las la-layer-group"></i>
|
||||
<span class="label">{{ 'MENU.GRANTEDPROJECT' | translate }}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/projects']">
|
||||
<i class="icon las la-layer-group"></i>
|
||||
<span class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}
|
||||
{{ 'MENU.PROJECT' | translate }}</span>
|
||||
</a>
|
||||
|
||||
<ng-container *ngIf="showUserSection">
|
||||
<div class="divider">
|
||||
<div class="line"></div>
|
||||
<span class="label">
|
||||
{{ 'MENU.USERSECTION' | translate }}</span>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/granted-projects']">
|
||||
<i class="icon las la-layer-group"></i>
|
||||
<span class="label">{{ 'MENU.GRANTEDPROJECT' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/users/all']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-users"></i>
|
||||
<span class="label">{{ 'MENU.USER' | translate }}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
<ng-template appHasRole [appHasRole]="['user.read']">
|
||||
<div class="divider">
|
||||
<div class="line"></div>
|
||||
<span class="label">
|
||||
{{ 'MENU.USERSECTION' | translate }}</span>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
|
||||
<a class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/users/all']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-users"></i>
|
||||
<span class="label">{{ 'MENU.USER' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
</mat-drawer>
|
||||
<mat-drawer-content class="content">
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<div class="admin-line" matTooltip="IAM Administrator">
|
||||
</mat-drawer>
|
||||
<mat-drawer-content class="content">
|
||||
<div *ngIf="iamuser$ | async" class="admin-line" matTooltip="IAM Administrator">
|
||||
<span>{{'MENU.IAMADMIN' | translate}}</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
<div class="router" [@routeAnimations]="prepareRoute(outlet)">
|
||||
<router-outlet #outlet="outlet"></router-outlet>
|
||||
</div>
|
||||
</mat-drawer-content>
|
||||
</mat-drawer-container>
|
||||
<div class="router" [@routeAnimations]="prepareRoute(outlet)">
|
||||
<router-outlet #outlet="outlet"></router-outlet>
|
||||
</div>
|
||||
</mat-drawer-content>
|
||||
</mat-drawer-container>
|
||||
</ng-container>
|
||||
</ng-container>
|
@ -76,7 +76,7 @@
|
||||
height: calc(100vh - 60px);
|
||||
width: 100%;
|
||||
|
||||
.side {
|
||||
.sidenav {
|
||||
width: 300px;
|
||||
border-right: none;
|
||||
|
||||
|
@ -134,10 +134,6 @@ export class AppComponent implements OnDestroy {
|
||||
public orgLoading: boolean = false;
|
||||
|
||||
public showProjectSection: boolean = false;
|
||||
public showOrgSection: boolean = false;
|
||||
public showUserSection: boolean = false;
|
||||
public iamreadwrite: boolean = false;
|
||||
|
||||
private authSub: Subscription = new Subscription();
|
||||
private orgSub: Subscription = new Subscription();
|
||||
|
||||
@ -207,13 +203,10 @@ export class AppComponent implements OnDestroy {
|
||||
|
||||
this.orgSub = this.authService.activeOrgChanged.subscribe(org => {
|
||||
this.org = org;
|
||||
this.loadPermissions();
|
||||
});
|
||||
|
||||
this.authSub = this.authService.authenticationChanged.subscribe((authenticated) => {
|
||||
if (authenticated) {
|
||||
// this.userService.GetMyzitadelPermissions().pipe(take(1)).subscribe(perm => console.log(perm.toObject()));
|
||||
this.loadPermissions();
|
||||
this.authService.GetActiveOrg().then(org => {
|
||||
this.org = org;
|
||||
});
|
||||
@ -235,13 +228,6 @@ export class AppComponent implements OnDestroy {
|
||||
this.orgSub.unsubscribe();
|
||||
}
|
||||
|
||||
public loadPermissions(): void {
|
||||
this.userService.isAllowed(['iam.read', 'iam.write'], true).subscribe(allowed => this.iamreadwrite = allowed);
|
||||
this.userService.isAllowed(['org.read']).subscribe(allowed => this.showOrgSection = allowed);
|
||||
this.userService.isAllowed(['project.read']).subscribe(allowed => this.showProjectSection = allowed);
|
||||
this.userService.isAllowed(['user.read']).subscribe(allowed => this.showUserSection = allowed);
|
||||
}
|
||||
|
||||
public loadOrgs(): void {
|
||||
this.orgLoading = true;
|
||||
this.userService.SearchMyProjectOrgs(10, 0).then(res => {
|
||||
|
@ -18,6 +18,7 @@ import { ServiceWorkerModule } from '@angular/service-worker';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||
import { AuthConfig, OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
|
||||
import { QuicklinkModule } from 'ngx-quicklink';
|
||||
|
||||
import { environment } from '../environments/environment';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
@ -27,6 +28,7 @@ import { OutsideClickModule } from './directives/outside-click/outside-click.mod
|
||||
import { AccountsCardModule } from './modules/accounts-card/accounts-card.module';
|
||||
import { AvatarModule } from './modules/avatar/avatar.module';
|
||||
import { SignedoutComponent } from './pages/signedout/signedout.component';
|
||||
import { HasRolePipeModule } from './pipes/has-role-pipe.module';
|
||||
import { AuthUserService } from './services/auth-user.service';
|
||||
import { AuthService } from './services/auth.service';
|
||||
import { GrpcService } from './services/grpc.service';
|
||||
@ -86,6 +88,7 @@ const authConfig: AuthConfig = {
|
||||
deps: [HttpClient],
|
||||
},
|
||||
}),
|
||||
QuicklinkModule,
|
||||
AccountsCardModule,
|
||||
HasRoleModule,
|
||||
BrowserAnimationsModule,
|
||||
@ -96,6 +99,7 @@ const authConfig: AuthConfig = {
|
||||
MatSidenavModule,
|
||||
MatCardModule,
|
||||
OutsideClickModule,
|
||||
HasRolePipeModule,
|
||||
MatProgressBarModule,
|
||||
MatToolbarModule,
|
||||
MatMenuModule,
|
||||
|
@ -15,6 +15,6 @@ export class RoleGuard implements CanActivate {
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
): Observable<boolean> {
|
||||
return this.userService.isAllowed(route.data['roles']);
|
||||
return this.userService.isAllowed(route.data['roles'], true);
|
||||
}
|
||||
}
|
||||
|
@ -33,8 +33,6 @@ export class MemberCreateDialogComponent {
|
||||
this.creationType = data.creationType;
|
||||
this.projectId = data.projectId;
|
||||
|
||||
console.log(this.creationType);
|
||||
|
||||
if (this.creationType === CreationType.PROJECT_GRANTED) {
|
||||
this.projectService.GetProjectGrantMemberRoles().then(resp => {
|
||||
this.memberRoleOptions = resp.toObject().rolesList;
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div *ngIf="title" class="row">
|
||||
<h2 class="title">{{title}}</h2>
|
||||
<span class="fill-space"></span>
|
||||
<ng-content select="card-actions"></ng-content>
|
||||
<ng-content select="[card-actions]"></ng-content>
|
||||
<button class="button" matTooltip="Expand or collapse" mat-icon-button (click)="expanded = !expanded">
|
||||
<mat-icon *ngIf="!expanded">keyboard_arrow_down</mat-icon>
|
||||
<mat-icon *ngIf="expanded">keyboard_arrow_up</mat-icon>
|
||||
|
@ -119,7 +119,6 @@ export class ChangesComponent implements OnInit {
|
||||
}
|
||||
}),
|
||||
catchError(err => {
|
||||
console.error(err);
|
||||
this._loading.next(false);
|
||||
this.bottom = true;
|
||||
return of([]);
|
||||
|
@ -4,12 +4,13 @@ import { NgModule } from '@angular/core';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ScrollableModule } from 'src/app/directives/scrollable/scrollable.module';
|
||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
||||
|
||||
import { ChangesComponent } from './changes.component';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ChangesComponent,
|
||||
@ -19,8 +20,10 @@ import { ChangesComponent } from './changes.component';
|
||||
ScrollableModule,
|
||||
MatProgressSpinnerModule,
|
||||
TranslateModule,
|
||||
PipesModule,
|
||||
HasRolePipeModule,
|
||||
ScrollingModule,
|
||||
LocalizedDatePipeModule,
|
||||
TimestampToDatePipeModule,
|
||||
],
|
||||
exports: [
|
||||
ChangesComponent,
|
||||
|
@ -5,6 +5,6 @@
|
||||
<div class="meta" [ngClass]="{'hidden': hidden}">
|
||||
<button (click)="hidden = !hidden" color="primary" class="hide" mat-icon-button><i
|
||||
class="las la-arrow-right"></i></button>
|
||||
<ng-content class="meta-content" select="metainfo"></ng-content>
|
||||
<ng-content class="meta-content" select="[metainfo]"></ng-content>
|
||||
</div>
|
||||
</div>
|
@ -85,7 +85,7 @@ export class ProjectContributorsComponent implements OnInit {
|
||||
case ProjectType.PROJECTTYPE_OWNED:
|
||||
return this.projectService.AddProjectMember(this.project.projectId, user.id, roles)
|
||||
.then(() => {
|
||||
this.toast.showInfo('members added');
|
||||
this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -96,7 +96,7 @@ export class ProjectContributorsComponent implements OnInit {
|
||||
user.id,
|
||||
roles,
|
||||
).then(() => {
|
||||
this.toast.showInfo('members added');
|
||||
this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
|
@ -25,8 +25,7 @@ export class ProjectMembersDataSource extends DataSource<ProjectMember.AsObject>
|
||||
const offset = pageIndex * pageSize;
|
||||
|
||||
this.loadingSubject.next(true);
|
||||
console.log(grantId);
|
||||
// TODO
|
||||
|
||||
const promise: Promise<ProjectMemberSearchResponse> | undefined =
|
||||
projectType === ProjectType.PROJECTTYPE_OWNED ?
|
||||
this.projectService.SearchProjectMembers(projectId, pageSize, offset) :
|
||||
|
@ -98,7 +98,7 @@
|
||||
<mat-form-field class="form-field" appearance="outline" *ngIf="project">
|
||||
<mat-label>{{ 'PROJECT.GRANT.TITLE' | translate }}</mat-label>
|
||||
<mat-select [(ngModel)]="member.rolesList" multiple
|
||||
[disabled]="(['project.member.write:'+project.projectId] | hasRole) == false"
|
||||
[disabled]="([('project.member.write:' + project.projectId)] | hasRole | async) == false"
|
||||
(selectionChange)="updateRoles(member, $event)">
|
||||
<mat-option *ngFor="let role of memberRoleOptions" [value]="role">
|
||||
{{ 'ROLES.'+role | translate }}
|
||||
@ -113,8 +113,9 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator class="background-style" #paginator [pageSize]="50"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]">
|
||||
<mat-paginator *ngIf="dataSource" class="background-style" #paginator [pageSize]="INITIALPAGESIZE"
|
||||
[length]="dataSource.totalResult" [pageSizeOptions]="[25, 50, 100, 250]"
|
||||
(page)="changePage($event)">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { SelectionModel } from '@angular/cdk/collections';
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatPaginator, PageEvent } from '@angular/material/paginator';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import { MatTable } from '@angular/material/table';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
@ -13,12 +13,14 @@ import { ToastService } from 'src/app/services/toast.service';
|
||||
import { CreationType, MemberCreateDialogComponent } from '../add-member-dialog/member-create-dialog.component';
|
||||
import { ProjectMembersDataSource } from './project-members-datasource';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-members',
|
||||
templateUrl: './project-members.component.html',
|
||||
styleUrls: ['./project-members.component.scss'],
|
||||
})
|
||||
export class ProjectMembersComponent {
|
||||
public INITIALPAGESIZE: number = 25;
|
||||
public project!: ProjectView.AsObject | ProjectGrantView.AsObject;
|
||||
public projectType: ProjectType = ProjectType.PROJECTTYPE_OWNED;
|
||||
public disabled: boolean = false;
|
||||
@ -50,15 +52,19 @@ export class ProjectMembersComponent {
|
||||
this.project = project.toObject();
|
||||
this.projectName = this.project.name;
|
||||
this.dataSource = new ProjectMembersDataSource(this.projectService);
|
||||
this.dataSource.loadMembers(this.project.projectId, this.projectType, 0, 25);
|
||||
this.dataSource.loadMembers(this.project.projectId, this.projectType, 0, this.INITIALPAGESIZE);
|
||||
});
|
||||
} else if (this.projectType === ProjectType.PROJECTTYPE_GRANTED) {
|
||||
console.log(params.projectid, params.grantid);
|
||||
this.projectService.GetGrantedProjectByID(params.projectid, params.grantid).then(project => {
|
||||
this.project = project.toObject();
|
||||
this.projectName = this.project.projectName;
|
||||
this.dataSource = new ProjectMembersDataSource(this.projectService);
|
||||
this.dataSource.loadMembers(this.project.projectId, this.projectType, 0, 25, this.grantId);
|
||||
this.dataSource.loadMembers(this.project.projectId,
|
||||
this.projectType,
|
||||
0,
|
||||
this.INITIALPAGESIZE,
|
||||
this.grantId,
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -149,7 +155,7 @@ export class ProjectMembersComponent {
|
||||
if (this.projectType === ProjectType.PROJECTTYPE_OWNED) {
|
||||
this.projectService.ChangeProjectMember(this.project.projectId, member.userId, selectionChange.value)
|
||||
.then((newmember: ProjectMember) => {
|
||||
this.toast.showInfo('Member changed');
|
||||
this.toast.showInfo('PROJECT.TOAST.MEMBERCHANGED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -157,10 +163,14 @@ export class ProjectMembersComponent {
|
||||
this.projectService.ChangeProjectGrantMember(this.project.projectId,
|
||||
this.grantId, member.userId, selectionChange.value)
|
||||
.then((newmember: ProjectMember) => {
|
||||
this.toast.showInfo('Member changed');
|
||||
this.toast.showInfo('PROJECT.TOAST.MEMBERCHANGED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public changePage(event: PageEvent): void {
|
||||
this.dataSource.loadMembers(this.project.projectId, this.projectType, event.pageIndex, event.pageSize, this.grantId);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
|
||||
import { ProjectMembersRoutingModule } from './project-members-routing.module';
|
||||
import { ProjectMembersComponent } from './project-members.component';
|
||||
@ -42,7 +42,7 @@ import { ProjectMembersComponent } from './project-members.component';
|
||||
MatProgressSpinnerModule,
|
||||
FormsModule,
|
||||
TranslateModule,
|
||||
PipesModule,
|
||||
HasRolePipeModule,
|
||||
],
|
||||
})
|
||||
export class ProjectMembersModule { }
|
||||
|
@ -93,7 +93,7 @@ export class ProjectRolesComponent implements AfterViewInit, OnInit {
|
||||
});
|
||||
this.selection.clear();
|
||||
}).catch(error => {
|
||||
this.toast.showError(error?.message || 'Error');
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
@ -105,8 +105,8 @@ export class ProjectRolesComponent implements AfterViewInit, OnInit {
|
||||
this.dataSource.rolesSubject.value.splice(index, 1);
|
||||
this.dataSource.rolesSubject.next(this.dataSource.rolesSubject.value);
|
||||
})
|
||||
.catch(data => {
|
||||
this.toast.showError(data.message);
|
||||
.catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,8 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
||||
|
||||
import { ProjectRoleDetailComponent } from './project-role-detail/project-role-detail.component';
|
||||
import { ProjectRolesComponent } from './project-roles.component';
|
||||
@ -39,9 +40,10 @@ import { ProjectRolesComponent } from './project-roles.component';
|
||||
MatCheckboxModule,
|
||||
RouterModule,
|
||||
MatTooltipModule,
|
||||
PipesModule,
|
||||
HasRolePipeModule,
|
||||
TranslateModule,
|
||||
MatMenuModule,
|
||||
TimestampToDatePipeModule,
|
||||
],
|
||||
exports: [
|
||||
ProjectRolesComponent,
|
||||
|
@ -1,13 +1,15 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { UsersRoutingModule } from './users-routing.module';
|
||||
import { QuicklinkModule } from 'ngx-quicklink';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
CommonModule,
|
||||
UsersRoutingModule,
|
||||
QuicklinkModule,
|
||||
],
|
||||
exports: [
|
||||
QuicklinkModule,
|
||||
],
|
||||
})
|
||||
export class UsersModule { }
|
||||
export class SharedModule { }
|
@ -6,6 +6,7 @@ import {
|
||||
UserGrantSearchKey,
|
||||
UserGrantSearchQuery,
|
||||
UserGrantSearchResponse,
|
||||
UserGrantView,
|
||||
} from 'src/app/proto/generated/management_pb';
|
||||
import { MgmtUserService } from 'src/app/services/mgmt-user.service';
|
||||
|
||||
@ -18,7 +19,7 @@ export enum UserGrantContext {
|
||||
|
||||
export class UserGrantsDataSource extends DataSource<UserGrant.AsObject> {
|
||||
public totalResult: number = 0;
|
||||
public grantsSubject: BehaviorSubject<UserGrant.AsObject[]> = new BehaviorSubject<UserGrant.AsObject[]>([]);
|
||||
public grantsSubject: BehaviorSubject<UserGrantView.AsObject[]> = new BehaviorSubject<UserGrantView.AsObject[]>([]);
|
||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||
|
||||
@ -82,7 +83,6 @@ export class UserGrantsDataSource extends DataSource<UserGrant.AsObject> {
|
||||
catchError(() => of([])),
|
||||
finalize(() => this.loadingSubject.next(false)),
|
||||
).subscribe(grants => {
|
||||
console.log(grants);
|
||||
this.grantsSubject.next(grants);
|
||||
});
|
||||
}
|
||||
@ -93,7 +93,7 @@ export class UserGrantsDataSource extends DataSource<UserGrant.AsObject> {
|
||||
* the returned stream emits new items.
|
||||
* @returns A stream of the items to be rendered.
|
||||
*/
|
||||
public connect(): Observable<UserGrant.AsObject[]> {
|
||||
public connect(): Observable<UserGrantView.AsObject[]> {
|
||||
return this.grantsSubject.asObservable();
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
<mat-spinner diameter="50"></mat-spinner>
|
||||
</div>
|
||||
<table mat-table multiTemplateDataRows class="full-width-table" aria-label="Elements" [dataSource]="dataSource">
|
||||
|
||||
<ng-container matColumnDef="select">
|
||||
<th class="selection" mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox color="primary" (change)="$event ? masterToggle() : null"
|
||||
@ -53,7 +52,7 @@
|
||||
<ng-container matColumnDef="org">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.GRANTEDORGDOMAIN' | translate }} </th>
|
||||
<td class="pointer" mat-cell *matCellDef="let grant">
|
||||
{{grant.orgDomain}} {{grant.orgName}} </td>
|
||||
{{grant.orgName}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="projectId">
|
||||
@ -81,7 +80,8 @@
|
||||
<ng-container *ngIf="context === UserGrantContext.USER">
|
||||
<span class="no-roles"
|
||||
*ngIf="grant.roleKeysList?.length === 0">{{'PROJECT.GRANT.NOROLES' | translate}}</span>
|
||||
<span *ngFor="let role of grant.roleKeysList">{{role}}</span>
|
||||
<span
|
||||
*ngFor="let role of grant.roleKeysList">{{ (role.length>8)? (role | slice:0:8)+'..':(role) }}</span>
|
||||
</ng-container>
|
||||
|
||||
<!-- <ng-container *ngIf="context === UserGrantContext.USER">
|
||||
@ -105,7 +105,8 @@
|
||||
|
||||
<ng-container *ngIf="context === UserGrantContext.OWNED_PROJECT">
|
||||
<ng-container *ngIf="loadedProjectId !== grant.projectId">
|
||||
<span class="role app-label" *ngFor="let role of grant.roleKeysList">{{role}}</span>
|
||||
<span class="role app-label"
|
||||
*ngFor="let role of grant.roleKeysList">{{ (role.length>6)? (role | slice:0:6)+'..':(role) }}</span>
|
||||
<button mat-icon-button (click)="getProjectRoleOptions(grant.projectId)"
|
||||
matTooltip="{{'ACTIONS.CHANGE' | translate}}">
|
||||
<i class="las la-edit"></i>
|
||||
@ -141,6 +142,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator #paginator [length]="dataSource.totalResult" [pageSize]="50" [pageSizeOptions]="[25, 50, 100, 250]">
|
||||
<mat-paginator #paginator [length]="dataSource.totalResult" [pageSize]="50" [length]="dataSource.totalResult"
|
||||
[pageSizeOptions]="[2, 3, 25, 50, 100, 250]" (page)="changePage($event)">
|
||||
</mat-paginator>
|
||||
</div>
|
@ -1,10 +1,10 @@
|
||||
import { SelectionModel } from '@angular/cdk/collections';
|
||||
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatPaginator, PageEvent } from '@angular/material/paginator';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import { MatTable } from '@angular/material/table';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { ProjectGrant, ProjectRoleView, UserGrant } from 'src/app/proto/generated/management_pb';
|
||||
import { ProjectRoleView, UserGrant, UserGrantView } from 'src/app/proto/generated/management_pb';
|
||||
import { MgmtUserService } from 'src/app/services/mgmt-user.service';
|
||||
import { ProjectService } from 'src/app/services/project.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
@ -17,15 +17,13 @@ import { UserGrantContext, UserGrantsDataSource } from './user-grants-datasource
|
||||
styleUrls: ['./user-grants.component.scss'],
|
||||
})
|
||||
export class UserGrantsComponent implements OnInit, AfterViewInit {
|
||||
// @Input() filterValue: string = '';
|
||||
// @Input() filter: UserGrantSearchKey = UserGrantSearchKey.USERGRANTSEARCHKEY_USER_ID;
|
||||
@Input() context: UserGrantContext = UserGrantContext.USER;
|
||||
public grants: UserGrant.AsObject[] = [];
|
||||
public grants: UserGrantView.AsObject[] = [];
|
||||
|
||||
public dataSource!: UserGrantsDataSource;
|
||||
public selection: SelectionModel<UserGrant.AsObject> = new SelectionModel<UserGrant.AsObject>(true, []);
|
||||
public selection: SelectionModel<UserGrantView.AsObject> = new SelectionModel<UserGrantView.AsObject>(true, []);
|
||||
@ViewChild(MatPaginator) public paginator!: MatPaginator;
|
||||
@ViewChild(MatTable) public table!: MatTable<ProjectGrant.AsObject>;
|
||||
@ViewChild(MatTable) public table!: MatTable<UserGrantView.AsObject>;
|
||||
|
||||
@Input() allowCreate: boolean = false;
|
||||
@Input() allowDelete: boolean = false;
|
||||
@ -51,19 +49,13 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
||||
private toast: ToastService,
|
||||
) { }
|
||||
|
||||
public displayedColumns: string[] = ['select',
|
||||
@Input() public displayedColumns: string[] = ['select',
|
||||
'user',
|
||||
'org',
|
||||
'projectId', 'creationDate', 'changeDate', 'roleNamesList'];
|
||||
|
||||
public ngOnInit(): void {
|
||||
console.log(this.context);
|
||||
this.dataSource = new UserGrantsDataSource(this.userService);
|
||||
const data = {
|
||||
projectId: this.projectId,
|
||||
grantId: this.grantId,
|
||||
userId: this.userId,
|
||||
};
|
||||
|
||||
switch (this.context) {
|
||||
case UserGrantContext.OWNED_PROJECT:
|
||||
@ -73,7 +65,7 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
break;
|
||||
case UserGrantContext.GRANTED_PROJECT:
|
||||
if (data && data.grantId) {
|
||||
if (this.grantId) {
|
||||
this.routerLink = ['/grant-create', 'project', this.projectId, 'grant', this.grantId];
|
||||
this.getGrantRoleOptions(this.grantId, this.projectId);
|
||||
}
|
||||
@ -86,7 +78,11 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
||||
default:
|
||||
this.routerLink = ['/grant-create'];
|
||||
}
|
||||
this.dataSource.loadGrants(this.context, 0, 25, data);
|
||||
this.dataSource.loadGrants(this.context, 0, 25, {
|
||||
projectId: this.projectId,
|
||||
grantId: this.grantId,
|
||||
userId: this.userId,
|
||||
});
|
||||
}
|
||||
|
||||
public ngAfterViewInit(): void {
|
||||
@ -122,8 +118,6 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
|
||||
public getGrantRoleOptions(grantId: string, projectId: string): void {
|
||||
console.log(grantId, projectId);
|
||||
|
||||
this.projectService.GetGrantedProjectByID(projectId, grantId).then(resp => {
|
||||
this.loadedGrantId = projectId;
|
||||
this.grantRoleOptions = resp.toObject().roleKeysList;
|
||||
@ -133,7 +127,6 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
|
||||
public getProjectRoleOptions(projectId: string): void {
|
||||
console.log(projectId);
|
||||
this.projectService.SearchProjectRoles(projectId, 100, 0).then(resp => {
|
||||
this.loadedProjectId = projectId;
|
||||
this.projectRoleOptions = resp.toObject().resultList;
|
||||
@ -182,4 +175,12 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
public changePage(event: PageEvent): void {
|
||||
this.dataSource.loadGrants(this.context, event.pageIndex, event.pageSize, {
|
||||
projectId: this.projectId,
|
||||
grantId: this.grantId,
|
||||
userId: this.userId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
||||
|
||||
import { AvatarModule } from '../avatar/avatar.module';
|
||||
import { UserGrantsComponent } from './user-grants.component';
|
||||
@ -38,7 +39,8 @@ import { UserGrantsComponent } from './user-grants.component';
|
||||
MatSelectModule,
|
||||
MatFormFieldModule,
|
||||
TranslateModule,
|
||||
PipesModule,
|
||||
HasRolePipeModule,
|
||||
TimestampToDatePipeModule,
|
||||
],
|
||||
exports: [
|
||||
UserGrantsComponent,
|
||||
|
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="accent" mat-button [routerLink]="['/iam']">{{'HOME.IAM_BUTTON' | translate}}</a>
|
||||
<a color="primary" mat-button [routerLink]="['/iam']">{{'HOME.IAM_BUTTON' | translate}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
@ -31,7 +31,7 @@
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="accent" mat-button
|
||||
<a color="primary" mat-button
|
||||
[routerLink]="['/users/me']">{{'HOME.SECURITYANDPRIVACY_BUTTON' | translate}}</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -46,7 +46,8 @@
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="accent" mat-button [routerLink]="['/projects']">{{'HOME.PROJECTS_BUTTON' | translate}}</a>
|
||||
<a color="primary" mat-button
|
||||
[routerLink]="['/projects']">{{'HOME.PROJECTS_BUTTON' | translate}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
@ -60,7 +61,7 @@
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="accent" mat-button [routerLink]="['/org']">{{'HOME.PROTECTION_BUTTON' | translate}}</a>
|
||||
<a color="primary" mat-button [routerLink]="['/org']">{{'HOME.PROTECTION_BUTTON' | translate}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
@ -75,7 +76,7 @@
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="accent" mat-button [routerLink]="['/users/me']">{{'HOME.USERS_BUTTON' | translate}}</a>
|
||||
<a color="primary" mat-button [routerLink]="['/users/me']">{{'HOME.USERS_BUTTON' | translate}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -4,6 +4,7 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
|
||||
import { HomeRoutingModule } from './home-routing.module';
|
||||
import { HomeComponent } from './home.component';
|
||||
@ -19,6 +20,7 @@ import { HomeComponent } from './home.component';
|
||||
HomeRoutingModule,
|
||||
MatButtonModule,
|
||||
TranslateModule,
|
||||
SharedModule,
|
||||
],
|
||||
})
|
||||
export class HomeModule { }
|
||||
|
@ -74,7 +74,7 @@ export class IamContributorsComponent implements OnInit {
|
||||
Promise.all(users.map(user => {
|
||||
return this.adminService.AddIamMember(user.id, roles);
|
||||
})).then(() => {
|
||||
this.toast.showError('members added');
|
||||
this.toast.showInfo('IAM.TOAST.MEMBERADDED');
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
|
@ -53,7 +53,7 @@ export class IamMembersComponent implements AfterViewInit {
|
||||
public removeProjectMemberSelection(): void {
|
||||
Promise.all(this.selection.selected.map(member => {
|
||||
return this.adminService.RemoveIamMember(member.userId).then(() => {
|
||||
this.toast.showInfo('Removed successfully');
|
||||
this.toast.showInfo('IAM.TOAST.MEMBERREMOVED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -62,7 +62,7 @@ export class IamMembersComponent implements AfterViewInit {
|
||||
|
||||
public removeMember(member: ProjectMember.AsObject): void {
|
||||
this.adminService.RemoveIamMember(member.userId).then(() => {
|
||||
this.toast.showInfo('Member removed successfully');
|
||||
this.toast.showInfo('IAM.TOAST.MEMBERREMOVED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -97,7 +97,7 @@ export class IamMembersComponent implements AfterViewInit {
|
||||
Promise.all(users.map(user => {
|
||||
return this.adminService.AddIamMember(user.id, roles);
|
||||
})).then(() => {
|
||||
this.toast.showError('members added');
|
||||
this.toast.showInfo('IAM.TOAST.MEMBERADDED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { AuthGuard } from 'src/app/guards/auth.guard';
|
||||
import { RoleGuard } from 'src/app/guards/role.guard';
|
||||
|
||||
import { IamComponent } from './iam.component';
|
||||
|
||||
@ -7,10 +9,18 @@ const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: IamComponent,
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
data: {
|
||||
roles: ['iam.read'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'members',
|
||||
loadChildren: () => import('./iam-members/iam-members.module').then(m => m.IamMembersModule),
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
data: {
|
||||
roles: ['iam.member.read'],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -26,7 +26,14 @@
|
||||
<ng-container matColumnDef="sequence">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef> {{ 'IAM.VIEWS.SEQUENCE' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let role">
|
||||
<span class="role app-label">{{role.sequence}}</span>
|
||||
<span class="role app-label">{{role?.processedSequence}}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="timestamp">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef> {{ 'IAM.VIEWS.SEQUENCE' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let role">
|
||||
<span>{{role?.viewTimestamp | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
@ -37,6 +37,8 @@
|
||||
width: 100%;
|
||||
|
||||
td, th {
|
||||
padding: 0 1rem;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
padding-right: 1rem;
|
||||
|
@ -21,7 +21,7 @@ export class IamViewsComponent {
|
||||
@ViewChild(MatSort) public sort!: MatSort;
|
||||
public dataSource!: MatTableDataSource<View.AsObject>;
|
||||
|
||||
public displayedColumns: string[] = ['viewName', 'database', 'sequence', 'actions'];
|
||||
public displayedColumns: string[] = ['viewName', 'database', 'sequence', 'timestamp', 'actions'];
|
||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||
constructor(private adminService: AdminService) {
|
||||
|
@ -8,8 +8,8 @@
|
||||
</app-card>
|
||||
</div>
|
||||
|
||||
<metainfo class="side">
|
||||
<div class="side" metainfo>
|
||||
<app-iam-contributors>
|
||||
</app-iam-contributors>
|
||||
</metainfo>
|
||||
</div>
|
||||
</app-meta-layout>
|
@ -1,5 +1,5 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
@ -16,13 +16,17 @@ import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
||||
|
||||
import { IamContributorsModule } from './iam-contributors/iam-contributors.module';
|
||||
import { IamRoutingModule } from './iam-routing.module';
|
||||
import { IamComponent } from './iam.component';
|
||||
import { IamViewsComponent } from './iam-views/iam-views.component';
|
||||
import { IamComponent } from './iam.component';
|
||||
|
||||
|
||||
|
||||
@ -32,6 +36,7 @@ import { IamViewsComponent } from './iam-views/iam-views.component';
|
||||
CommonModule,
|
||||
IamRoutingModule,
|
||||
ChangesModule,
|
||||
CardModule,
|
||||
MatAutocompleteModule,
|
||||
MatChipsModule,
|
||||
MatButtonModule,
|
||||
@ -51,7 +56,9 @@ import { IamViewsComponent } from './iam-views/iam-views.component';
|
||||
TranslateModule,
|
||||
MatDialogModule,
|
||||
IamContributorsModule,
|
||||
LocalizedDatePipeModule,
|
||||
TimestampToDatePipeModule,
|
||||
SharedModule,
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
})
|
||||
export class IamModule { }
|
||||
|
@ -75,7 +75,7 @@ export class OrgContributorsComponent implements OnInit {
|
||||
Promise.all(users.map(user => {
|
||||
return this.orgService.AddMyOrgMember(user.id, roles);
|
||||
})).then(() => {
|
||||
this.toast.showError('members added');
|
||||
this.toast.showInfo('ORG.TOAST.MEMBERADDED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
|
@ -22,10 +22,13 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<button [disabled]="orgForm.invalid" color="primary" mat-raised-button class="continue-button"
|
||||
cdkFocusInitial type="submit">
|
||||
{{'CONTINUE' | translate}}
|
||||
</button>
|
||||
<div class="btn-container">
|
||||
<span class="fill-space"></span>
|
||||
<button [disabled]="orgForm.invalid" color="primary" mat-raised-button class="big-button"
|
||||
cdkFocusInitial type="submit">
|
||||
{{'CONTINUE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- <div *ngIf="name?.touched" @openClose>
|
||||
@ -174,7 +177,10 @@
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button color="primary" class="continue-button" [disabled]="orgForm.invalid || userForm.invalid"
|
||||
<button color="primary" class="small-button" type="button" (click)="previous()"
|
||||
mat-stroked-button>{{ 'ACTIONS.BACK' | translate }}</button>
|
||||
<span class="fill-space"></span>
|
||||
<button color="primary" class="big-button" [disabled]="orgForm.invalid || userForm.invalid"
|
||||
type="submit" mat-raised-button>{{ 'ACTIONS.FINISH' | translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -74,7 +74,7 @@ h1 {
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
button {
|
||||
.continue-button {
|
||||
margin-top: 3rem;
|
||||
display: block;
|
||||
padding: 0.5rem 4rem;
|
||||
@ -125,19 +125,23 @@ h1 {
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.continue-button {
|
||||
align-items: center;
|
||||
margin-top: 3rem;
|
||||
display: block;
|
||||
padding: 0.5rem 4rem;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
.small-button {
|
||||
display: block;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.big-button {
|
||||
display: block;
|
||||
padding: 0.5rem 4rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
mat-checkbox {
|
||||
|
@ -96,8 +96,8 @@ export class OrgCreateComponent {
|
||||
.then((data: OrgSetUpResponse) => {
|
||||
this.router.navigate(['orgs', data.toObject().org?.id]);
|
||||
})
|
||||
.catch(data => {
|
||||
this.toast.showError(data.message);
|
||||
.catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
|
||||
import { OrgCreateRoutingModule } from './org-create-routing.module';
|
||||
import { OrgCreateComponent } from './org-create.component';
|
||||
@ -25,7 +25,7 @@ import { OrgCreateComponent } from './org-create.component';
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatSelectModule,
|
||||
PipesModule,
|
||||
HasRolePipeModule,
|
||||
TranslateModule,
|
||||
MatCheckboxModule,
|
||||
],
|
||||
|
@ -2,8 +2,8 @@
|
||||
<div mat-dialog-content>
|
||||
<p class="desc"> {{'ORG.DOMAINS.ADD.DESCRIPTION' | translate}}</p>
|
||||
|
||||
<mat-form-field label="Access Code" required="true">
|
||||
<mat-label>Code</mat-label>
|
||||
<mat-form-field label="Domain" required="true">
|
||||
<mat-label>Domain</mat-label>
|
||||
<input matInput [(ngModel)]="newdomain" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
@ -24,7 +24,7 @@
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<metainfo class="side">
|
||||
<div class="side" metainfo>
|
||||
<div class="details">
|
||||
<div class="row">
|
||||
<span class="first">{{'ORG.PAGES.PRIMARYDOMAIN' | translate}}</span>
|
||||
@ -46,5 +46,5 @@
|
||||
<app-changes *ngIf="org" [changeType]="ChangeType.ORG" [id]="org.id"></app-changes>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</metainfo>
|
||||
</div>
|
||||
</app-meta-layout>
|
@ -91,13 +91,11 @@ export class OrgGridComponent {
|
||||
private getData(limit: number, offset: number): void {
|
||||
this.userService.SearchMyProjectOrgs(limit, offset).then(res => {
|
||||
this.orgList = res.toObject().resultList;
|
||||
console.log(this.orgList);
|
||||
|
||||
this.notPinned = Object.assign([], this.orgList);
|
||||
this.reorganizeItems();
|
||||
this.loading = false;
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
this.toast.showError(error);
|
||||
this.loading = false;
|
||||
});
|
||||
|
@ -57,7 +57,7 @@ export class OrgMembersComponent implements AfterViewInit {
|
||||
public removeProjectMemberSelection(): void {
|
||||
Promise.all(this.selection.selected.map(member => {
|
||||
return this.orgService.RemoveMyOrgMember(member.userId).then(() => {
|
||||
this.toast.showInfo('Removed successfully');
|
||||
this.toast.showInfo('ORG.TOAST.MEMBERREMOVED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -66,7 +66,7 @@ export class OrgMembersComponent implements AfterViewInit {
|
||||
|
||||
public removeMember(member: ProjectMember.AsObject): void {
|
||||
this.orgService.RemoveMyOrgMember(member.userId).then(() => {
|
||||
this.toast.showInfo('Member removed successfully');
|
||||
this.toast.showInfo('ORG.TOAST.MEMBERREMOVED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -101,7 +101,7 @@ export class OrgMembersComponent implements AfterViewInit {
|
||||
Promise.all(users.map(user => {
|
||||
return this.orgService.AddMyOrgMember(user.id, roles);
|
||||
})).then(() => {
|
||||
this.toast.showError('members added');
|
||||
this.toast.showInfo('ORG.TOAST.MEMBERADDED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||
@ -14,6 +14,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { WarnDialogModule } from 'src/app/modules/warn-dialog/warn-dialog.module';
|
||||
|
||||
import { ChangesModule } from '../../modules/changes/changes.module';
|
||||
@ -49,8 +50,7 @@ import { PolicyGridComponent } from './policy-grid/policy-grid.component';
|
||||
ChangesModule,
|
||||
AddDomainDialogModule,
|
||||
TranslateModule,
|
||||
SharedModule,
|
||||
],
|
||||
exports: [],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
})
|
||||
export class OrgsModule { }
|
||||
|
@ -21,7 +21,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="content" *ngIf="policyType === PolicyComponentType?.LOCKOUT">
|
||||
<div class="content" *ngIf="policyType === PolicyComponentType?.LOCKOUT && lockoutData">
|
||||
<mat-form-field class="description-formfield" appearance="outline">
|
||||
<mat-label>{{ 'ORG.POLICY.DATA.DESCRIPTION' | translate }}</mat-label>
|
||||
<input matInput name="description" ngDefaultControl [(ngModel)]="lockoutData.description"
|
||||
@ -44,12 +44,12 @@
|
||||
<span class="left-desc">{{'ORG.POLICY.DATA.SHOWLOCKOUTFAILURES' | translate}}</span>
|
||||
<span class="fill-space"></span>
|
||||
<mat-slide-toggle color="primary" name="showLockOutFailures" ngDefaultControl
|
||||
[(ngModel)]="complexityData.showLockOutFailures">
|
||||
[(ngModel)]="lockoutData.showLockOutFailures">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="policyType === PolicyComponentType?.COMPLEXITY" class="content">
|
||||
<div *ngIf="policyType === PolicyComponentType?.COMPLEXITY && complexityData" class="content">
|
||||
<mat-form-field class="description-formfield" appearance="outline">
|
||||
<mat-label>{{ 'ORG.POLICY.DATA.DESCRIPTION' | translate }}</mat-label>
|
||||
<input matInput name="description" ngDefaultControl [(ngModel)]="complexityData.description"
|
||||
@ -98,7 +98,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content" *ngIf="policyType === PolicyComponentType?.AGE">
|
||||
<div class="content" *ngIf="policyType === PolicyComponentType?.AGE && ageData">
|
||||
<mat-form-field class="description-formfield" appearance="outline">
|
||||
<mat-label>{{ 'ORG.POLICY.DATA.DESCRIPTION' | translate }}</mat-label>
|
||||
<input matInput name="description" ngDefaultControl [(ngModel)]="ageData.description"
|
||||
@ -133,7 +133,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content" *ngIf="policyType === PolicyComponentType?.IAM_POLICY">
|
||||
<div class="content" *ngIf="policyType === PolicyComponentType?.IAM_POLICY && iamData">
|
||||
<mat-form-field class="description-formfield" appearance="outline">
|
||||
<mat-label>{{ 'ORG.POLICY.DATA.DESCRIPTION' | translate }}</mat-label>
|
||||
<input matInput name="description" ngDefaultControl [(ngModel)]="iamData.description"
|
||||
|
@ -3,6 +3,12 @@ import { FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BehaviorSubject, Subscription } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import {
|
||||
OrgIamPolicy,
|
||||
PasswordAgePolicy,
|
||||
PasswordComplexityPolicy,
|
||||
PasswordLockoutPolicy,
|
||||
} from 'src/app/proto/generated/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { OrgService } from 'src/app/services/org.service';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
@ -39,31 +45,10 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
public lockoutForm!: FormGroup;
|
||||
public ageForm!: FormGroup;
|
||||
|
||||
public complexityData: any = {
|
||||
minLength: 8,
|
||||
description: '',
|
||||
hasNumber: true,
|
||||
hasSymbol: true,
|
||||
hasLowercase: true,
|
||||
hasUppercase: true,
|
||||
};
|
||||
|
||||
public lockoutData: any = {
|
||||
description: '',
|
||||
maxAttempts: 5,
|
||||
showLockOutFailures: true,
|
||||
};
|
||||
|
||||
public ageData: any = {
|
||||
description: '',
|
||||
expireWarnDays: 80,
|
||||
maxAgeDays: 90,
|
||||
};
|
||||
|
||||
public iamData: any = {
|
||||
description: '',
|
||||
userLoginMustBeDomain: false,
|
||||
};
|
||||
public complexityData!: PasswordComplexityPolicy.AsObject;
|
||||
public lockoutData!: PasswordLockoutPolicy.AsObject;
|
||||
public ageData!: PasswordAgePolicy.AsObject;
|
||||
public iamData!: OrgIamPolicy.AsObject;
|
||||
|
||||
private sub: Subscription = new Subscription();
|
||||
|
||||
@ -102,19 +87,21 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
|
||||
if (this.componentAction === PolicyComponentAction.MODIFY) {
|
||||
this.getData(params).then(data => {
|
||||
switch (this.policyType) {
|
||||
case PolicyComponentType.LOCKOUT:
|
||||
this.lockoutData = data.toObject();
|
||||
break;
|
||||
case PolicyComponentType.AGE:
|
||||
this.ageData = data.toObject();
|
||||
break;
|
||||
case PolicyComponentType.COMPLEXITY:
|
||||
this.complexityData = data.toObject();
|
||||
break;
|
||||
case PolicyComponentType.IAM_POLICY:
|
||||
this.iamData = data.toObject();
|
||||
break;
|
||||
if (data) {
|
||||
switch (this.policyType) {
|
||||
case PolicyComponentType.LOCKOUT:
|
||||
this.lockoutData = data.toObject() as PasswordLockoutPolicy.AsObject;
|
||||
break;
|
||||
case PolicyComponentType.AGE:
|
||||
this.ageData = data.toObject() as PasswordAgePolicy.AsObject;
|
||||
break;
|
||||
case PolicyComponentType.COMPLEXITY:
|
||||
this.complexityData = data.toObject() as PasswordComplexityPolicy.AsObject;
|
||||
break;
|
||||
case PolicyComponentType.IAM_POLICY:
|
||||
this.iamData = data.toObject() as OrgIamPolicy.AsObject;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -128,7 +115,8 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
this.sub.unsubscribe();
|
||||
}
|
||||
|
||||
private async getData(params: any): Promise<any> {
|
||||
private async getData(params: any):
|
||||
Promise<PasswordLockoutPolicy | PasswordAgePolicy | PasswordComplexityPolicy | OrgIamPolicy | undefined> {
|
||||
switch (params.policytype) {
|
||||
case PolicyComponentType.LOCKOUT:
|
||||
this.titleSub.next('ORG.POLICY.PWD_LOCKOUT.TITLE');
|
||||
@ -270,8 +258,8 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
if (orgId) {
|
||||
this.adminService.CreateOrgIamPolicy(
|
||||
orgId,
|
||||
this.complexityData.description,
|
||||
this.complexityData.userLoginMustBeDomain,
|
||||
this.iamData.description,
|
||||
this.iamData.userLoginMustBeDomain,
|
||||
).then(() => {
|
||||
this.router.navigate(['org']);
|
||||
}).catch(error => {
|
||||
@ -326,8 +314,8 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
if (orgId) {
|
||||
this.adminService.UpdateOrgIamPolicy(
|
||||
orgId,
|
||||
this.complexityData.description,
|
||||
this.complexityData.userLoginMustBeDomain,
|
||||
this.iamData.description,
|
||||
this.iamData.userLoginMustBeDomain,
|
||||
).then(() => {
|
||||
this.router.navigate(['org']);
|
||||
}).catch(error => {
|
||||
|
@ -104,9 +104,8 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
.then((data: Application) => {
|
||||
this.showSavedDialog(data.toObject());
|
||||
})
|
||||
.catch(data => {
|
||||
console.error(data);
|
||||
this.toast.showError(data.message);
|
||||
.catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,10 @@
|
||||
</app-card>
|
||||
|
||||
<app-card title="{{ 'APP.OIDC.TITLE' | translate }}" *ngIf="app && app.oidcConfig">
|
||||
<card-actions class="card-actions">
|
||||
<div class="card-actions" card-actions>
|
||||
<button mat-stroked-button
|
||||
(click)="regenerateOIDCClientSecret()">{{'APP.OIDC.REGENERATESECRET' | translate}}</button>
|
||||
</card-actions>
|
||||
</div>
|
||||
<form *ngIf="appForm" [formGroup]="appForm" (ngSubmit)="saveOIDCApp()">
|
||||
<div class="content">
|
||||
<mat-form-field appearance="outline">
|
||||
|
@ -17,7 +17,6 @@ import {
|
||||
OIDCGrantType,
|
||||
OIDCResponseType,
|
||||
} from 'src/app/proto/generated/management_pb';
|
||||
import { GrpcService } from 'src/app/services/grpc.service';
|
||||
import { OrgService } from 'src/app/services/org.service';
|
||||
import { ProjectService } from 'src/app/services/project.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
@ -84,7 +83,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
private fb: FormBuilder,
|
||||
private _location: Location,
|
||||
private dialog: MatDialog,
|
||||
private grpcService: GrpcService,
|
||||
private orgService: OrgService,
|
||||
) {
|
||||
this.appNameForm = this.fb.group({
|
||||
@ -224,8 +222,8 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
.then((data: OIDCConfig) => {
|
||||
this.toast.showInfo('APP.TOAST.OIDCUPDATED', true);
|
||||
})
|
||||
.catch(data => {
|
||||
this.toast.showError(data.message);
|
||||
.catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||
@ -53,6 +53,5 @@ import { AppsRoutingModule } from './apps-routing.module';
|
||||
TranslateModule,
|
||||
],
|
||||
exports: [TranslateModule],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
|
||||
})
|
||||
export class AppsModule { }
|
||||
|
@ -12,17 +12,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <ng-template appHasRole [appHasRole]="['project.grant.user.grant.read']"> -->
|
||||
<app-card *ngIf="project?.projectId" title="{{ 'GRANTS.PROJECT.TITLE' | translate }}"
|
||||
description="{{'GRANTS.PROJECT.DESCRIPTION' | translate }}">
|
||||
<app-user-grants [context]="userGrantContext" [projectId]="projectId" [grantId]="grantId"
|
||||
[allowCreate]="['project.grant.user.grant.write'] | hasRole"
|
||||
[allowDelete]="['project.grant.user.grant.delete'] | hasRole">
|
||||
</app-user-grants>
|
||||
</app-card>
|
||||
<!-- </ng-template> -->
|
||||
<ng-template appHasRole [appHasRole]="['project.grant.user.grant.read']">
|
||||
<app-card *ngIf="project?.projectId" title="{{ 'GRANTS.PROJECT.TITLE' | translate }}"
|
||||
description="{{'GRANTS.PROJECT.DESCRIPTION' | translate }}">
|
||||
<app-user-grants [context]="userGrantContext" [projectId]="projectId" [grantId]="grantId"
|
||||
[displayedColumns]="['select', 'projectId', 'creationDate', 'changeDate', 'roleNamesList']"
|
||||
[allowCreate]="['project.grant.user.grant.write'] | hasRole | async"
|
||||
[allowDelete]="['project.grant.user.grant.delete'] | hasRole | async">
|
||||
</app-user-grants>
|
||||
</app-card>
|
||||
</ng-template>
|
||||
</div>
|
||||
<metainfo class="side">
|
||||
<div class="side" metainfo>
|
||||
<div class="details">
|
||||
<div class="row">
|
||||
<span class="first">{{'PROJECT.STATE.TITLE' | translate}}:</span>
|
||||
@ -42,5 +43,5 @@
|
||||
<app-changes *ngIf="project" [changeType]="ChangeType.PROJECT" [id]="project.id"></app-changes>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</metainfo>
|
||||
</div>
|
||||
</app-meta-layout>
|
@ -91,7 +91,6 @@ export class GrantedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
if (this.projectId && this.grantId) {
|
||||
this.projectService.GetGrantedProjectByID(this.projectId, this.grantId).then(proj => {
|
||||
this.project = proj.toObject();
|
||||
console.log('granted-project', this.project);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
|
@ -106,9 +106,9 @@ export class GrantedProjectListComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
this.toast.showInfo('Reactivated selected projects successfully');
|
||||
this.toast.showInfo('PROJECT.TOAST.REACTIVATED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showInfo(error.message);
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
@ -119,9 +119,9 @@ export class GrantedProjectListComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
this.toast.showInfo('Deactivated selected projects Successfully');
|
||||
this.toast.showInfo('PROJECT.TOAST.DEACTIVATED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showInfo(error.message);
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ const routes: Routes = [
|
||||
path: ':projectid/grant/:grantid/members',
|
||||
data: {
|
||||
type: ProjectType.PROJECTTYPE_GRANTED,
|
||||
roles: ['project.grant.member.read'],
|
||||
},
|
||||
loadChildren: () => import('src/app/modules/project-members/project-members.module')
|
||||
.then(m => m.ProjectMembersModule),
|
||||
@ -37,7 +38,10 @@ const routes: Routes = [
|
||||
{
|
||||
path: ':projectid/roles/create',
|
||||
loadChildren: () => import('../project-role-create/project-role-create.module').then(m => m.ProjectRoleCreateModule),
|
||||
|
||||
canActivate: [RoleGuard],
|
||||
data: {
|
||||
roles: ['project.write'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: ':projectid/grants/create',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
@ -21,11 +21,13 @@ import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||
import { ProjectContributorsModule } from 'src/app/modules/project-contributors/project-contributors.module';
|
||||
import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.module';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
|
||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
||||
|
||||
import { GrantedProjectDetailComponent } from './granted-project-detail/granted-project-detail.component';
|
||||
import { GrantedProjectGridComponent } from './granted-project-grid/granted-project-grid.component';
|
||||
import { GrantedProjectGridComponent } from './granted-project-list/granted-project-grid/granted-project-grid.component';
|
||||
import { GrantedProjectListComponent } from './granted-project-list/granted-project-list.component';
|
||||
import { GrantedProjectsRoutingModule } from './granted-projects-routing.module';
|
||||
import { GrantedProjectsComponent } from './granted-projects.component';
|
||||
@ -63,9 +65,10 @@ import { GrantedProjectsComponent } from './granted-projects.component';
|
||||
CardModule,
|
||||
MatTooltipModule,
|
||||
MatSortModule,
|
||||
PipesModule,
|
||||
HasRolePipeModule,
|
||||
TranslateModule,
|
||||
TimestampToDatePipeModule,
|
||||
SharedModule,
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
})
|
||||
export class GrantedProjectsModule { }
|
||||
|
@ -1,20 +1,20 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ProjectApplicationGridComponent } from './project-application-grid.component';
|
||||
import { ApplicationGridComponent } from './application-grid.component';
|
||||
|
||||
describe('AppGridComponent', () => {
|
||||
let component: ProjectApplicationGridComponent;
|
||||
let fixture: ComponentFixture<ProjectApplicationGridComponent>;
|
||||
let component: ApplicationGridComponent;
|
||||
let fixture: ComponentFixture<ApplicationGridComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ProjectApplicationGridComponent],
|
||||
declarations: [ApplicationGridComponent],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProjectApplicationGridComponent);
|
||||
fixture = TestBed.createComponent(ApplicationGridComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
@ -5,11 +5,11 @@ import { Application } from 'src/app/proto/generated/management_pb';
|
||||
import { ProjectService } from 'src/app/services/project.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-application-grid',
|
||||
templateUrl: './project-application-grid.component.html',
|
||||
styleUrls: ['./project-application-grid.component.scss'],
|
||||
selector: 'app-application-grid',
|
||||
templateUrl: './application-grid.component.html',
|
||||
styleUrls: ['./application-grid.component.scss'],
|
||||
})
|
||||
export class ProjectApplicationGridComponent implements OnInit {
|
||||
export class ApplicationGridComponent implements OnInit {
|
||||
@Input() public projectId: string = '';
|
||||
@Input() public disabled: boolean = false;
|
||||
@Output() public changeView: EventEmitter<void> = new EventEmitter();
|
@ -10,10 +10,6 @@
|
||||
</ng-container>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<!-- <button [disabled]="disabled" matTooltip="{{'ORG_DETAIL.TABLE.DELETE' | translate}}" class="icon-button"
|
||||
mat-icon-button *ngIf="selection.hasValue()">
|
||||
<i class="las la-trash"></i>
|
||||
</button> -->
|
||||
<ng-template appHasRole [appHasRole]="['project.app.write']">
|
||||
<a [disabled]="disabled" class="add-button" [routerLink]="[ '/projects', projectId, 'apps', 'create']"
|
||||
color="primary" mat-raised-button>
|
@ -0,0 +1,34 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
import { ApplicationsComponent } from './applications.component';
|
||||
|
||||
describe('ProjectApplicationsComponent', () => {
|
||||
let component: ApplicationsComponent;
|
||||
let fixture: ComponentFixture<ApplicationsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ApplicationsComponent],
|
||||
imports: [
|
||||
NoopAnimationsModule,
|
||||
MatPaginatorModule,
|
||||
MatSortModule,
|
||||
MatTableModule,
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ApplicationsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should compile', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -9,15 +9,15 @@ import { Application } from 'src/app/proto/generated/management_pb';
|
||||
import { ProjectService } from 'src/app/services/project.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
import { ProjectApplicationsDataSource } from './project-applications-datasource';
|
||||
import { ProjectApplicationsDataSource } from './applications-datasource';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-applications',
|
||||
templateUrl: './project-applications.component.html',
|
||||
styleUrls: ['./project-applications.component.scss'],
|
||||
selector: 'app-applications',
|
||||
templateUrl: './applications.component.html',
|
||||
styleUrls: ['./applications.component.scss'],
|
||||
})
|
||||
export class ProjectApplicationsComponent implements AfterViewInit, OnInit {
|
||||
export class ApplicationsComponent implements AfterViewInit, OnInit {
|
||||
@Input() public projectId: string = '';
|
||||
@Input() public disabled: boolean = false;
|
||||
@ViewChild(MatPaginator) public paginator!: MatPaginator;
|
@ -0,0 +1,23 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { RoleGuard } from 'src/app/guards/role.guard';
|
||||
|
||||
import { OwnedProjectDetailComponent } from './owned-project-detail.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: OwnedProjectDetailComponent,
|
||||
data: {
|
||||
animation: 'HomePage',
|
||||
roles: ['project.read'],
|
||||
},
|
||||
canActivate: [RoleGuard],
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class OwnedProjectDetailRoutingModule { }
|
@ -43,18 +43,17 @@
|
||||
|
||||
<ng-container *ngIf="project">
|
||||
<ng-template appHasRole [appHasRole]="['project.app.read:' + project.projectId, 'project.app.read']">
|
||||
<app-project-application-grid *ngIf="grid"
|
||||
<app-application-grid *ngIf="grid"
|
||||
[disabled]="project?.state !== ProjectState.PROJECTSTATE_ACTIVE || isZitadel"
|
||||
(changeView)="grid = false" [projectId]="projectId"></app-project-application-grid>
|
||||
(changeView)="grid = false" [projectId]="projectId"></app-application-grid>
|
||||
<app-card *ngIf="!grid" title="{{ 'PROJECT.APP.TITLE' | translate }}">
|
||||
<card-actions class="card-actions">
|
||||
<div class="card-actions" card-actions>
|
||||
<button mat-icon-button (click)="grid = true">
|
||||
<i matTooltip="show grid view" class="las la-th-large"></i>
|
||||
</button>
|
||||
</card-actions>
|
||||
<app-project-applications
|
||||
[disabled]="project?.state !== ProjectState.PROJECTSTATE_ACTIVE || isZitadel"
|
||||
[projectId]="projectId"></app-project-applications>
|
||||
</div>
|
||||
<app-applications [disabled]="project?.state !== ProjectState.PROJECTSTATE_ACTIVE || isZitadel"
|
||||
[projectId]="projectId"></app-applications>
|
||||
</app-card>
|
||||
</ng-template>
|
||||
|
||||
@ -83,15 +82,15 @@
|
||||
description="{{'GRANTS.PROJECT.DESCRIPTION' | translate }}">
|
||||
<app-user-grants [context]="userGrantContext" [projectId]="projectId"
|
||||
[disabled]="project?.state !== ProjectState.PROJECTSTATE_ACTIVE"
|
||||
[allowCreate]="project?.state == ProjectState.PROJECTSTATE_ACTIVE && (['user.grant.write'] | hasRole)"
|
||||
[allowDelete]="project?.state == ProjectState.PROJECTSTATE_ACTIVE && (['user.grant.delete'] | hasRole)">
|
||||
[allowCreate]="project?.state == ProjectState.PROJECTSTATE_ACTIVE && (['user.grant.write'] | hasRole | async)"
|
||||
[allowDelete]="project?.state == ProjectState.PROJECTSTATE_ACTIVE && (['user.grant.delete'] | hasRole | async)">
|
||||
</app-user-grants>
|
||||
</app-card>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
<metainfo class="side">
|
||||
<div class="side" metainfo>
|
||||
<div class="details">
|
||||
<div class="row">
|
||||
<span class="first">{{'PROJECT.STATE.TITLE' | translate}}:</span>
|
||||
@ -111,5 +110,5 @@
|
||||
<app-changes *ngIf="project" [changeType]="ChangeType.PROJECT" [id]="project.projectId"></app-changes>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</metainfo>
|
||||
</div>
|
||||
</app-meta-layout>
|
@ -114,7 +114,7 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
if (resp) {
|
||||
this.projectService.ReactivateProject(this.projectId).then(() => {
|
||||
this.toast.showInfo('Reactivated Project');
|
||||
this.toast.showInfo('PROJECT.TOAST.REACTIVATED', true);
|
||||
this.project.state = ProjectState.PROJECTSTATE_ACTIVE;
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
@ -135,7 +135,7 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
if (resp) {
|
||||
this.projectService.DeactivateProject(this.projectId).then(() => {
|
||||
this.toast.showInfo('Deactivated Project');
|
||||
this.toast.showInfo('PROJECT.TOAST.DEACTIVATED', true);
|
||||
this.project.state = ProjectState.PROJECTSTATE_INACTIVE;
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
@ -147,9 +147,9 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
|
||||
public saveProject(): void {
|
||||
this.projectService.UpdateProject(this.project.projectId, this.project.name).then(() => {
|
||||
this.toast.showInfo('Project updated');
|
||||
this.toast.showInfo('PROJECT.TOAST.UPDATED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showInfo(error.message);
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,64 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||
import { ProjectContributorsModule } from 'src/app/modules/project-contributors/project-contributors.module';
|
||||
import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.module';
|
||||
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
|
||||
import { WarnDialogModule } from 'src/app/modules/warn-dialog/warn-dialog.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
||||
|
||||
import { ApplicationGridComponent } from './application-grid/application-grid.component';
|
||||
import { ApplicationsComponent } from './applications/applications.component';
|
||||
import { OwnedProjectDetailRoutingModule } from './owned-project-detail-routing.module';
|
||||
import { OwnedProjectDetailComponent } from './owned-project-detail.component';
|
||||
import { ProjectGrantsComponent } from './project-grants/project-grants.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
OwnedProjectDetailComponent,
|
||||
ApplicationGridComponent,
|
||||
ApplicationsComponent,
|
||||
ProjectGrantsComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
OwnedProjectDetailRoutingModule,
|
||||
TranslateModule,
|
||||
HasRoleModule,
|
||||
MatTabsModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
ProjectContributorsModule,
|
||||
WarnDialogModule,
|
||||
ProjectRolesModule,
|
||||
HasRolePipeModule,
|
||||
UserGrantsModule,
|
||||
TimestampToDatePipeModule,
|
||||
MatTableModule,
|
||||
MatFormFieldModule,
|
||||
CardModule,
|
||||
MatPaginatorModule,
|
||||
MatCheckboxModule,
|
||||
MatSelectModule,
|
||||
MatProgressSpinnerModule,
|
||||
ChangesModule,
|
||||
MetaLayoutModule,
|
||||
],
|
||||
})
|
||||
export class OwnedProjectDetailModule { }
|
@ -29,7 +29,6 @@ export class ProjectGrantsDataSource extends DataSource<ProjectGrant.AsObject> {
|
||||
catchError(() => of([])),
|
||||
finalize(() => this.loadingSubject.next(false)),
|
||||
).subscribe(grants => {
|
||||
console.log(grants);
|
||||
this.grantsSubject.next(grants);
|
||||
});
|
||||
}
|
@ -75,14 +75,13 @@ export class ProjectGrantsComponent implements OnInit, AfterViewInit {
|
||||
public getRoleOptions(projectId: string): void {
|
||||
this.projectService.SearchProjectRoles(projectId, 100, 0).then(resp => {
|
||||
this.memberRoleOptions = resp.toObject().resultList;
|
||||
console.log(resp.toObject());
|
||||
});
|
||||
}
|
||||
|
||||
updateRoles(grant: ProjectGrant.AsObject, selectionChange: MatSelectChange): void {
|
||||
this.projectService.UpdateProjectGrant(grant.id, grant.projectId, selectionChange.value)
|
||||
.then((newgrant: ProjectGrant) => {
|
||||
this.toast.showInfo('Grant updated!');
|
||||
this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTCHANGED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
<app-owned-project-grid *ngIf="grid" [loading]="loading$ | async" (changedView)="grid = false"
|
||||
[items]="ownedProjectList" (newClicked)="addProject()">
|
||||
[items]="ownedProjectList || []" (newClicked)="addProject()">
|
||||
</app-owned-project-grid>
|
||||
|
||||
<div *ngIf="!grid" class="view-toggle">
|
||||
@ -20,16 +20,6 @@
|
||||
</ng-container>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div @list class="action-btns" *ngIf="selection.hasValue()">
|
||||
<button @animate (click)="deactivateSelectedProjects()"
|
||||
matTooltip="{{'PROJECT.TABLE.DEACTIVATE' | translate}}" class="icon-button" mat-icon-button>
|
||||
<mat-icon svgIcon="mdi_light_off"></mat-icon>
|
||||
</button>
|
||||
<button @animate (click)="reactivateSelectedProjects()"
|
||||
matTooltip="{{'PROJECT.TABLE.ACTIVATE' | translate}}" class="icon-button" mat-icon-button>
|
||||
<mat-icon svgIcon="mdi_light_on"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<ng-template appHasRole [appHasRole]="['project.write']">
|
||||
<a class="add-button" [routerLink]="[ '/projects', 'create']" color="primary" mat-raised-button>
|
||||
<mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }}
|
||||
|
@ -108,9 +108,9 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
this.toast.showInfo('Reactivated selected projects successfully');
|
||||
this.toast.showInfo('PROJECT.TOAST.REACTIVATED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showInfo(error.message);
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
@ -121,9 +121,9 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
this.toast.showInfo('Deactivated selected projects Successfully');
|
||||
this.toast.showInfo('PROJECT.TOAST.DEACTIVATED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showInfo(error.message);
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { AuthGuard } from 'src/app/guards/auth.guard';
|
||||
import { RoleGuard } from 'src/app/guards/role.guard';
|
||||
import { ProjectType } from 'src/app/proto/generated/management_pb';
|
||||
|
||||
import { OwnedProjectDetailComponent } from './owned-project-detail/owned-project-detail.component';
|
||||
import { OwnedProjectsComponent } from './owned-projects.component';
|
||||
|
||||
const routes: Routes = [
|
||||
@ -16,42 +14,60 @@ const routes: Routes = [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('../project-create/project-create.module').then(m => m.ProjectCreateModule),
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
canActivate: [RoleGuard],
|
||||
data: {
|
||||
roles: ['project.write'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
component: OwnedProjectDetailComponent,
|
||||
data: { animation: 'HomePage' },
|
||||
},
|
||||
{
|
||||
path: ':projectid/members',
|
||||
data: {
|
||||
type: ProjectType.PROJECTTYPE_OWNED,
|
||||
animation: 'HomePage',
|
||||
roles: ['project.read'],
|
||||
},
|
||||
loadChildren: () => import('src/app/modules/project-members/project-members.module')
|
||||
.then(m => m.ProjectMembersModule),
|
||||
canActivate: [RoleGuard],
|
||||
loadChildren: () => import('./owned-project-detail/owned-project-detail.module')
|
||||
.then(m => m.OwnedProjectDetailModule),
|
||||
},
|
||||
{
|
||||
path: ':projectid/apps',
|
||||
data: { animation: 'AddPage' },
|
||||
loadChildren: () => import('src/app/pages/projects/apps/apps.module').then(m => m.AppsModule),
|
||||
},
|
||||
{
|
||||
path: ':projectid/roles/create',
|
||||
loadChildren: () => import('../project-role-create/project-role-create.module').then(m => m.ProjectRoleCreateModule),
|
||||
},
|
||||
{
|
||||
path: ':projectid/grants/create',
|
||||
loadChildren: () => import('../project-grant-create/project-grant-create.module')
|
||||
.then(m => m.ProjectGrantCreateModule),
|
||||
},
|
||||
{
|
||||
path: ':projectid/grant/:grantid',
|
||||
loadChildren: () => import('./project-grant-detail/project-grant-detail.module')
|
||||
.then(m => m.ProjectGrantDetailModule),
|
||||
path: ':projectid',
|
||||
children: [
|
||||
{
|
||||
path: 'members',
|
||||
data: {
|
||||
type: ProjectType.PROJECTTYPE_OWNED,
|
||||
roles: ['project.member.read'],
|
||||
},
|
||||
canActivate: [RoleGuard],
|
||||
loadChildren: () => import('src/app/modules/project-members/project-members.module')
|
||||
.then(m => m.ProjectMembersModule),
|
||||
},
|
||||
{
|
||||
path: 'apps',
|
||||
data: {
|
||||
animation: 'AddPage',
|
||||
roles: ['project.app.read'],
|
||||
},
|
||||
canActivate: [RoleGuard],
|
||||
loadChildren: () => import('src/app/pages/projects/apps/apps.module')
|
||||
.then(m => m.AppsModule),
|
||||
},
|
||||
{
|
||||
path: 'roles/create',
|
||||
loadChildren: () => import('../project-role-create/project-role-create.module')
|
||||
.then(m => m.ProjectRoleCreateModule),
|
||||
},
|
||||
{
|
||||
path: 'grants/create',
|
||||
loadChildren: () => import('../project-grant-create/project-grant-create.module')
|
||||
.then(m => m.ProjectGrantCreateModule),
|
||||
},
|
||||
{
|
||||
path: 'grant/:grantid',
|
||||
loadChildren: () => import('./project-grant-detail/project-grant-detail.module')
|
||||
.then(m => m.ProjectGrantDetailModule),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
@ -10,47 +10,33 @@ import { MatInputModule } from '@angular/material/input';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { AvatarModule } from 'src/app/modules/avatar/avatar.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||
import { ProjectContributorsModule } from 'src/app/modules/project-contributors/project-contributors.module';
|
||||
import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.module';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
|
||||
import { WarnDialogModule } from 'src/app/modules/warn-dialog/warn-dialog.module';
|
||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
||||
|
||||
import { OwnedProjectDetailComponent } from './owned-project-detail/owned-project-detail.component';
|
||||
import { OwnedProjectGridComponent } from './owned-project-grid/owned-project-grid.component';
|
||||
import { OwnedProjectGridComponent } from './owned-project-list/owned-project-grid/owned-project-grid.component';
|
||||
import { OwnedProjectListComponent } from './owned-project-list/owned-project-list.component';
|
||||
import { OwnedProjectsRoutingModule } from './owned-projects-routing.module';
|
||||
import { OwnedProjectsComponent } from './owned-projects.component';
|
||||
import { ProjectApplicationGridComponent } from './project-application-grid/project-application-grid.component';
|
||||
import { ProjectApplicationsComponent } from './project-applications/project-applications.component';
|
||||
import { ProjectGrantsComponent } from './project-grants/project-grants.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
OwnedProjectsComponent,
|
||||
OwnedProjectListComponent,
|
||||
OwnedProjectGridComponent,
|
||||
OwnedProjectDetailComponent,
|
||||
ProjectApplicationGridComponent,
|
||||
ProjectApplicationsComponent,
|
||||
ProjectGrantsComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
OwnedProjectsRoutingModule,
|
||||
UserGrantsModule,
|
||||
ProjectContributorsModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
TranslateModule,
|
||||
@ -61,24 +47,18 @@ import { ProjectGrantsComponent } from './project-grants/project-grants.componen
|
||||
MatPaginatorModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
ChangesModule,
|
||||
MatChipsModule,
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
WarnDialogModule,
|
||||
MatProgressSpinnerModule,
|
||||
MetaLayoutModule,
|
||||
MatProgressBarModule,
|
||||
ProjectRolesModule,
|
||||
MatTabsModule,
|
||||
MatCheckboxModule,
|
||||
CardModule,
|
||||
MatSelectModule,
|
||||
MatTooltipModule,
|
||||
MatSortModule,
|
||||
PipesModule,
|
||||
TranslateModule,
|
||||
HasRolePipeModule,
|
||||
TimestampToDatePipeModule,
|
||||
SharedModule,
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
})
|
||||
export class OwnedProjectsModule { }
|
||||
|
@ -1,34 +0,0 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
import { ProjectApplicationsComponent } from './project-applications.component';
|
||||
|
||||
describe('ProjectApplicationsComponent', () => {
|
||||
let component: ProjectApplicationsComponent;
|
||||
let fixture: ComponentFixture<ProjectApplicationsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ProjectApplicationsComponent],
|
||||
imports: [
|
||||
NoopAnimationsModule,
|
||||
MatPaginatorModule,
|
||||
MatSortModule,
|
||||
MatTableModule,
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProjectApplicationsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should compile', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -80,7 +80,7 @@ export class ProjectGrantDetailComponent {
|
||||
updateRoles(selectionChange: MatSelectChange): void {
|
||||
this.projectService.UpdateProjectGrant(this.grant.id, this.grant.projectId, selectionChange.value)
|
||||
.then((newgrant: ProjectGrant) => {
|
||||
this.toast.showInfo('Grant updated!');
|
||||
this.toast.showInfo('PROJECT.TOAST.GRANTUPDATED');
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
|
@ -9,8 +9,6 @@ import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@ -36,8 +34,6 @@ import { ProjectGrantMembersModule } from './project-grant-members/project-grant
|
||||
MatTableModule,
|
||||
MatPaginatorModule,
|
||||
MatFormFieldModule,
|
||||
MatSelectModule,
|
||||
MatSortModule,
|
||||
MatTooltipModule,
|
||||
ReactiveFormsModule,
|
||||
MatProgressSpinnerModule,
|
||||
|
@ -87,7 +87,7 @@ export class ProjectGrantMembersComponent implements AfterViewInit, OnInit {
|
||||
public removeProjectMemberSelection(): void {
|
||||
Promise.all(this.selection.selected.map(member => {
|
||||
return this.projectService.RemoveProjectGrantMember(this.projectId, this.grantId, member.userId).then(() => {
|
||||
this.toast.showInfo('Removed successfully');
|
||||
this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTMEMBERREMOVED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -96,7 +96,7 @@ export class ProjectGrantMembersComponent implements AfterViewInit, OnInit {
|
||||
|
||||
public removeMember(member: ProjectMember.AsObject): void {
|
||||
this.projectService.RemoveProjectGrantMember(this.projectId, this.grantId, member.userId).then(() => {
|
||||
this.toast.showInfo('Member removed successfully');
|
||||
this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTMEMBERREMOVED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -134,8 +134,7 @@ export class ProjectGrantMembersComponent implements AfterViewInit, OnInit {
|
||||
dataToAdd.rolesKeyList,
|
||||
);
|
||||
})).then(() => {
|
||||
console.log('this');
|
||||
this.toast.showInfo('Project Grant Member successfully added!');
|
||||
this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTMEMBERADDED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -146,7 +145,7 @@ export class ProjectGrantMembersComponent implements AfterViewInit, OnInit {
|
||||
updateRoles(member: ProjectMember.AsObject, selectionChange: MatSelectChange): void {
|
||||
this.projectService.ChangeProjectGrantMember(this.projectId, this.grantId, member.userId, selectionChange.value)
|
||||
.then((newmember: ProjectMember) => {
|
||||
this.toast.showInfo('Member updated!');
|
||||
this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTMEMBERCHANGED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
|
@ -30,8 +30,8 @@ export class ProjectCreateComponent implements OnInit {
|
||||
.then((data: Project) => {
|
||||
this.router.navigate(['projects', data.getId()]);
|
||||
})
|
||||
.catch(data => {
|
||||
this.toast.showError(data.message);
|
||||
.catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { ProjectRolesModule } from 'src/app/modules/project-roles/project-roles.module';
|
||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
|
||||
|
||||
import { ProjectGrantCreateRoutingModule } from './project-grant-create-routing.module';
|
||||
import { ProjectGrantCreateComponent } from './project-grant-create.component';
|
||||
@ -33,7 +33,7 @@ import { ProjectGrantCreateComponent } from './project-grant-create.component';
|
||||
ProjectRolesModule,
|
||||
MatIconModule,
|
||||
MatTooltipModule,
|
||||
PipesModule,
|
||||
HasRolePipeModule,
|
||||
ReactiveFormsModule,
|
||||
MatProgressSpinnerModule,
|
||||
FormsModule,
|
||||
|
@ -9,8 +9,8 @@
|
||||
</div>
|
||||
|
||||
<h1>{{'PROJECT.ROLE.ADDDESCRIPTION' | translate}}</h1>
|
||||
<button class="add-line-btn" color="primary" mat-stroked-button (click)="addEntry()">
|
||||
Add another role
|
||||
<button class="add-line-btn" color="primary" type="button" mat-stroked-button (click)="addEntry()">
|
||||
{{'PROJECT.ROLE.ADDNEWLINE' | translate}}
|
||||
</button>
|
||||
<form @list (ngSubmit)="addRole()">
|
||||
<div @animate *ngFor="let formGroup of formArray.controls; index as i" class="content">
|
||||
@ -18,8 +18,6 @@
|
||||
<mat-form-field appearance="outline" class="formfield">
|
||||
<mat-label>{{ 'PROJECT.ROLE.KEY' | translate }}</mat-label>
|
||||
<input matInput formControlName="key" />
|
||||
<!-- <mat-error *ngIf="formGroup.get('key')?.errors?.required">{{'ERRORS.REQUIRED' | translate}}
|
||||
</mat-error> -->
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline" class="formfield">
|
||||
<mat-label>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</mat-label>
|
||||
@ -29,15 +27,14 @@
|
||||
<mat-label>{{ 'PROJECT.ROLE.GROUP' | translate }}</mat-label>
|
||||
<input matInput formControlName="group" />
|
||||
</mat-form-field>
|
||||
<button mat-icon-button (click)="removeEntry(i)" color="warn"
|
||||
<button mat-icon-button (click)="removeEntry(i)" type="button" color="warn"
|
||||
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}">
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="formArray.invalid" cdkFocusInitial
|
||||
type="submit">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="formArray.invalid" type="submit">
|
||||
{{ 'ACTIONS.SAVE' | translate }}
|
||||
</button>
|
||||
</form>
|
||||
|
@ -84,6 +84,7 @@ export class ProjectRoleCreateComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public addRole(): void {
|
||||
console.log(this.formArray.value);
|
||||
const rolesToAdd: ProjectRoleAdd[] = this.formArray.value.map((element: any) => {
|
||||
const role = new ProjectRoleAdd();
|
||||
role.setKey(element.key);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
|
||||
import { SignedoutRoutingModule } from './signedout-routing.module';
|
||||
|
||||
@ -8,6 +9,7 @@ import { SignedoutRoutingModule } from './signedout-routing.module';
|
||||
imports: [
|
||||
CommonModule,
|
||||
SignedoutRoutingModule,
|
||||
SharedModule,
|
||||
],
|
||||
})
|
||||
export class SignedoutModule { }
|
||||
|
@ -50,19 +50,11 @@ export class UserGrantCreateComponent implements OnDestroy {
|
||||
this.grantId = grantid;
|
||||
this.userId = userid;
|
||||
|
||||
console.log('usergrantcreate');
|
||||
|
||||
// if (this.userId) {
|
||||
// this.context = UserGrantContext.USER;
|
||||
// } else
|
||||
|
||||
if (this.projectId && !this.grantId) {
|
||||
this.context = UserGrantContext.OWNED_PROJECT;
|
||||
} else if (this.projectId && this.grantId) {
|
||||
this.context = UserGrantContext.GRANTED_PROJECT;
|
||||
console.log(this.grantId, this.projectId);
|
||||
this.projectService.GetGrantedProjectByID(this.projectId, this.grantId).then(resp => {
|
||||
console.log(resp.toObject());
|
||||
this.grantRolesKeyList = resp.toObject().roleKeysList;
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
@ -81,25 +73,13 @@ export class UserGrantCreateComponent implements OnDestroy {
|
||||
|
||||
public addGrant(): void {
|
||||
switch (this.context) {
|
||||
// case UserGrantContext.USER:
|
||||
// this.userService.CreateUserGrant(
|
||||
// this.projectId,
|
||||
// this.userId,
|
||||
// this.rolesList,
|
||||
// ).then((data: UserGrant) => {
|
||||
// this.toast.showInfo('User Grant added');
|
||||
// this.close();
|
||||
// }).catch(error => {
|
||||
// this.toast.showError(error);
|
||||
// });
|
||||
// break;
|
||||
case UserGrantContext.OWNED_PROJECT:
|
||||
this.userService.CreateProjectUserGrant(
|
||||
this.projectId,
|
||||
this.userId,
|
||||
this.rolesList,
|
||||
).then((data: UserGrant) => {
|
||||
this.toast.showInfo('Project User Grant added');
|
||||
this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTADDED', true);
|
||||
this.close();
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
@ -113,13 +93,12 @@ export class UserGrantCreateComponent implements OnDestroy {
|
||||
this.userId,
|
||||
this.rolesList,
|
||||
).then((data: UserGrant) => {
|
||||
this.toast.showInfo('Project Grant User Grant added');
|
||||
this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTUSERGRANTADDED', true);
|
||||
this.close();
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
@ -10,6 +10,7 @@ import {
|
||||
SearchProjectAutocompleteModule,
|
||||
} from 'src/app/modules/search-project-autocomplete/search-project-autocomplete.module';
|
||||
import { SearchUserAutocompleteModule } from 'src/app/modules/search-user-autocomplete/search-user-autocomplete.module';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
|
||||
import { ProjectRolesModule } from '../../modules/project-roles/project-roles.module';
|
||||
import { UserGrantCreateRoutingModule } from './user-grant-create-routing.module';
|
||||
@ -31,9 +32,7 @@ import { UserGrantCreateComponent } from './user-grant-create.component';
|
||||
SearchProjectAutocompleteModule,
|
||||
SearchUserAutocompleteModule,
|
||||
ProjectRolesModule,
|
||||
],
|
||||
schemas: [
|
||||
CUSTOM_ELEMENTS_SCHEMA,
|
||||
SharedModule,
|
||||
],
|
||||
})
|
||||
export class UserGrantCreateModule { }
|
||||
|
@ -89,8 +89,8 @@ export class UserCreateComponent implements OnDestroy {
|
||||
this.toast.showInfo('USER.TOAST.CREATED', true);
|
||||
this.router.navigate(['users', data.getId()]);
|
||||
})
|
||||
.catch(data => {
|
||||
this.toast.showError(data.message);
|
||||
.catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@
|
||||
<app-auth-user-mfa *ngIf="user"></app-auth-user-mfa>
|
||||
</div>
|
||||
|
||||
<metainfo *ngIf="user" class="side">
|
||||
<div *ngIf="user" class="side" metainfo>
|
||||
<div class="details">
|
||||
<div class="row" *ngIf="user?.preferredLoginName">
|
||||
<span class="first">Preferred Loginname:</span>
|
||||
@ -138,5 +138,5 @@
|
||||
</div>
|
||||
|
||||
<app-changes [changeType]="ChangeType.MYUSER" [id]="user.id"></app-changes>
|
||||
</metainfo>
|
||||
</div>
|
||||
</app-meta-layout>
|
@ -69,8 +69,8 @@ export class AuthUserDetailComponent implements OnDestroy {
|
||||
this.toast.showInfo('USER.TOAST.SAVED', true);
|
||||
this.user = Object.assign(this.user, data.toObject());
|
||||
})
|
||||
.catch(data => {
|
||||
this.toast.showError(data.message);
|
||||
.catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
@ -144,8 +144,8 @@ export class AuthUserDetailComponent implements OnDestroy {
|
||||
this.toast.showInfo('USER.TOAST.PHONESAVED', true);
|
||||
this.user.phone = data.toObject().phone;
|
||||
this.phoneEditState = false;
|
||||
}).catch(data => {
|
||||
this.toast.showError(data);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
this.phoneEditState = false;
|
||||
});
|
||||
}
|
||||
@ -153,8 +153,8 @@ export class AuthUserDetailComponent implements OnDestroy {
|
||||
private async getData(): Promise<void> {
|
||||
this.userService.GetMyUser().then(user => {
|
||||
this.user = user.toObject();
|
||||
}).catch(err => {
|
||||
this.toast.showError(err);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user