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:
Max Peintner
2020-07-16 15:13:36 +02:00
committed by GitHub
parent 2a3ecc0c6a
commit 4f3ccbfad0
125 changed files with 807 additions and 614 deletions
@@ -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);