mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-13 17:35:12 +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:
@@ -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
-11
@@ -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>
|
||||
-1
@@ -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);
|
||||
});
|
||||
|
||||
+4
-4
@@ -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 { }
|
||||
|
||||
+5
-5
@@ -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();
|
||||
});
|
||||
+4
-4
@@ -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();
|
||||
-4
@@ -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>
|
||||
+34
@@ -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();
|
||||
});
|
||||
});
|
||||
+5
-5
@@ -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;
|
||||
+23
@@ -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 { }
|
||||
+10
-11
@@ -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>
|
||||
+4
-4
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+64
@@ -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 { }
|
||||
-1
@@ -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);
|
||||
});
|
||||
}
|
||||
+1
-2
@@ -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
-11
@@ -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 }}
|
||||
|
||||
+4
-4
@@ -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 { }
|
||||
|
||||
-34
@@ -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();
|
||||
});
|
||||
});
|
||||
+1
-1
@@ -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);
|
||||
});
|
||||
|
||||
-4
@@ -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,
|
||||
|
||||
+4
-5
@@ -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,
|
||||
|
||||
+4
-7
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user