feat(console): refresh roles, user-grants and project-members based on previous navigation (#728)

* feat: refresh roles, user-grants, project-members

* refresh keys

* user grants on granted projects

* refresh on member changes

* membership refresh

* lint
This commit is contained in:
Max Peintner 2020-09-11 14:24:41 +02:00 committed by GitHub
parent 15c977dab4
commit 4926509de0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 134 additions and 13 deletions

View File

@ -38,6 +38,7 @@ import { GrpcService } from './services/grpc.service';
import { AuthInterceptor } from './services/interceptors/auth.interceptor'; import { AuthInterceptor } from './services/interceptors/auth.interceptor';
import { GRPC_INTERCEPTORS } from './services/interceptors/grpc-interceptor'; import { GRPC_INTERCEPTORS } from './services/interceptors/grpc-interceptor';
import { OrgInterceptor } from './services/interceptors/org.interceptor'; import { OrgInterceptor } from './services/interceptors/org.interceptor';
import { RefreshService } from './services/refresh.service';
import { StatehandlerProcessorService, StatehandlerProcessorServiceImpl } from './services/statehandler-processor.service'; import { StatehandlerProcessorService, StatehandlerProcessorServiceImpl } from './services/statehandler-processor.service';
import { StatehandlerService, StatehandlerServiceImpl } from './services/statehandler.service'; import { StatehandlerService, StatehandlerServiceImpl } from './services/statehandler.service';
import { StorageService } from './services/storage.service'; import { StorageService } from './services/storage.service';
@ -154,6 +155,7 @@ const authConfig: AuthConfig = {
multi: true, multi: true,
useClass: OrgInterceptor, useClass: OrgInterceptor,
}, },
RefreshService,
GrpcService, GrpcService,
GrpcAuthService, GrpcAuthService,
{ provide: 'windowObject', useValue: window }, { provide: 'windowObject', useValue: window },

View File

@ -103,7 +103,11 @@ export class ProjectMembersComponent {
this.toast.showError(error); this.toast.showError(error);
}); });
} }
})); })).then(() => {
setTimeout(() => {
this.changePage();
}, 1000);
});
} }
public isAllSelected(): boolean { public isAllSelected(): boolean {
@ -141,6 +145,9 @@ export class ProjectMembersComponent {
user.id, roles); user.id, roles);
} }
})).then(() => { })).then(() => {
setTimeout(() => {
this.changePage();
}, 1000);
this.toast.showInfo('PROJECT.TOAST.MEMBERSADDED', true); this.toast.showInfo('PROJECT.TOAST.MEMBERSADDED', true);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);

View File

@ -1,5 +1,6 @@
<app-refresh-table *ngIf="projectId" (refreshed)="refreshPage()" [dataSize]="dataSource?.totalResult" <app-refresh-table *ngIf="projectId" (refreshed)="refreshPage()" [dataSize]="dataSource?.totalResult"
[selection]="selection" [loading]="dataSource?.loading$ | async" [timestamp]="dataSource?.viewTimestamp"> emitRefreshOnPreviousRoute="/projects/{{projectId}}/roles/create" [selection]="selection"
[loading]="dataSource?.loading$ | async" [timestamp]="dataSource?.viewTimestamp">
<ng-template appHasRole [appHasRole]="['project.role.delete', 'project.role.delete:' + projectId]" actions> <ng-template appHasRole [appHasRole]="['project.role.delete', 'project.role.delete:' + projectId]" actions>
<button color="warn" class="icon-button" [disabled]="disabled" <button color="warn" class="icon-button" [disabled]="disabled"
matTooltip="{{'PROJECT.ROLE.DELETE' | translate}}" (click)="deleteSelectedRoles()" mat-icon-button matTooltip="{{'PROJECT.ROLE.DELETE' | translate}}" (click)="deleteSelectedRoles()" mat-icon-button

View File

@ -2,6 +2,7 @@ import { animate, animation, keyframes, style, transition, trigger, useAnimation
import { SelectionModel } from '@angular/cdk/collections'; import { SelectionModel } from '@angular/cdk/collections';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb'; import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';
import { RefreshService } from 'src/app/services/refresh.service';
const rotate = animation([ const rotate = animation([
animate( animate(
@ -32,14 +33,24 @@ export class RefreshTableComponent implements OnInit {
@Input() public dataSize: number = 0; @Input() public dataSize: number = 0;
@Input() public emitRefreshAfterTimeoutInMs: number = 0; @Input() public emitRefreshAfterTimeoutInMs: number = 0;
@Input() public loading: boolean = false; @Input() public loading: boolean = false;
@Input() public emitRefreshOnPreviousRoute: string = '';
@Output() public refreshed: EventEmitter<void> = new EventEmitter(); @Output() public refreshed: EventEmitter<void> = new EventEmitter();
constructor(private refreshService: RefreshService) { }
ngOnInit(): void { ngOnInit(): void {
if (this.emitRefreshAfterTimeoutInMs) { if (this.emitRefreshAfterTimeoutInMs) {
setTimeout(() => { setTimeout(() => {
this.emitRefresh(); this.emitRefresh();
}, this.emitRefreshAfterTimeoutInMs); }, this.emitRefreshAfterTimeoutInMs);
} }
if (this.emitRefreshOnPreviousRoute && this.refreshService.previousUrls.includes(this.emitRefreshOnPreviousRoute)) {
setTimeout(() => {
console.log('refresh now');
this.emitRefresh();
}, 1000);
}
} }
emitRefresh(): void { emitRefresh(): void {

View File

@ -1,5 +1,6 @@
<app-refresh-table [loading]="dataSource?.loading$ | async" (refreshed)="changePage()" <app-refresh-table [loading]="dataSource?.loading$ | async" (refreshed)="changePage()"
[timestamp]="dataSource?.viewTimestamp" [dataSize]="dataSource?.totalResult" [selection]="selection"> [emitRefreshOnPreviousRoute]="refreshOnPreviousRoute" [timestamp]="dataSource?.viewTimestamp"
[dataSize]="dataSource?.totalResult" [selection]="selection">
<button color="warn" matTooltip="{{'GRANTS.DELETE' | translate}}" class="icon-button" mat-icon-button actions <button color="warn" matTooltip="{{'GRANTS.DELETE' | translate}}" class="icon-button" mat-icon-button actions
(click)="deleteGrantSelection()" *ngIf="selection.hasValue() && allowDelete"> (click)="deleteGrantSelection()" *ngIf="selection.hasValue() && allowDelete">
<i class="las la-trash"></i> <i class="las la-trash"></i>
@ -21,9 +22,8 @@
<td class="selection" mat-cell *matCellDef="let row"> <td class="selection" mat-cell *matCellDef="let row">
<mat-checkbox color="primary" (click)="$event.stopPropagation()" <mat-checkbox color="primary" (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null" [checked]="selection.isSelected(row)"> (change)="$event ? selection.toggle(row) : null" [checked]="selection.isSelected(row)">
<app-avatar *ngIf="row && (row?.displayName || (row.firstName && row.lastName))" class="avatar" <app-avatar *ngIf="row && row?.displayName && row.firstName && row.lastName" class="avatar"
[name]="row.displayName ? row.displayName : (row.firstName + ' '+ row.lastName)" [name]="row.displayName" [size]="32">
[size]="32">
</app-avatar> </app-avatar>
</mat-checkbox> </mat-checkbox>
</td> </td>
@ -33,7 +33,7 @@
<ng-container matColumnDef="user"> <ng-container matColumnDef="user">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.USER' | translate }} </th> <th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.USER' | translate }} </th>
<td class="pointer" mat-cell *matCellDef="let grant"> <td class="pointer" mat-cell *matCellDef="let grant">
{{grant?.firstName}} {{grant?.lastName}}</td> {{grant?.displayName}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="org"> <ng-container matColumnDef="org">

View File

@ -24,6 +24,7 @@ import { UserGrantContext, UserGrantsDataSource } from './user-grants-datasource
}) })
export class UserGrantsComponent implements OnInit, AfterViewInit { export class UserGrantsComponent implements OnInit, AfterViewInit {
@Input() context: UserGrantContext = UserGrantContext.USER; @Input() context: UserGrantContext = UserGrantContext.USER;
@Input() refreshOnPreviousRoute: string = '';
public grants: UserGrantView.AsObject[] = []; public grants: UserGrantView.AsObject[] = [];
public dataSource!: UserGrantsDataSource; public dataSource!: UserGrantsDataSource;

View File

@ -85,6 +85,9 @@ export class IamMembersComponent implements AfterViewInit {
public removeMember(member: ProjectMember.AsObject): void { public removeMember(member: ProjectMember.AsObject): void {
this.adminService.RemoveIamMember(member.userId).then(() => { this.adminService.RemoveIamMember(member.userId).then(() => {
this.toast.showInfo('IAM.TOAST.MEMBERREMOVED', true); this.toast.showInfo('IAM.TOAST.MEMBERREMOVED', true);
setTimeout(() => {
this.refreshPage();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });
@ -120,6 +123,9 @@ export class IamMembersComponent implements AfterViewInit {
return this.adminService.AddIamMember(user.id, roles); return this.adminService.AddIamMember(user.id, roles);
})).then(() => { })).then(() => {
this.toast.showInfo('IAM.TOAST.MEMBERADDED', true); this.toast.showInfo('IAM.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.refreshPage();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -57,6 +57,9 @@ export class IamComponent {
return this.adminService.AddIamMember(user.id, roles); return this.adminService.AddIamMember(user.id, roles);
})).then(() => { })).then(() => {
this.toast.showInfo('IAM.TOAST.MEMBERADDED'); this.toast.showInfo('IAM.TOAST.MEMBERADDED');
setTimeout(() => {
this.loadMembers();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -180,6 +180,9 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
return this.mgmtService.AddMyOrgMember(user.id, roles); return this.mgmtService.AddMyOrgMember(user.id, roles);
})).then(() => { })).then(() => {
this.toast.showInfo('ORG.TOAST.MEMBERADDED', true); this.toast.showInfo('ORG.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.loadMembers();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -82,7 +82,11 @@ export class OrgMembersComponent implements AfterViewInit {
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });
})); })).then(() => {
setTimeout(() => {
this.refreshPage();
}, 1000);
});
} }
public isAllSelected(): boolean { public isAllSelected(): boolean {
@ -115,6 +119,9 @@ export class OrgMembersComponent implements AfterViewInit {
return this.mgmtService.AddMyOrgMember(user.id, roles); return this.mgmtService.AddMyOrgMember(user.id, roles);
})).then(() => { })).then(() => {
this.toast.showInfo('ORG.TOAST.MEMBERADDED', true); this.toast.showInfo('ORG.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.refreshPage();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -19,7 +19,8 @@
[projectId]="projectId" [grantId]="grantId" [projectId]="projectId" [grantId]="grantId"
[displayedColumns]="['select','user', 'projectId', 'creationDate', 'changeDate', 'roleNamesList']" [displayedColumns]="['select','user', 'projectId', 'creationDate', 'changeDate', 'roleNamesList']"
[allowCreate]="['user.grant.write','user.grant.write:'+grantId] | hasRole | async" [allowCreate]="['user.grant.write','user.grant.write:'+grantId] | hasRole | async"
[allowDelete]="['user.grant.delete','user.grant.delete:'+grantId] | hasRole | async"> [allowDelete]="['user.grant.delete','user.grant.delete:'+grantId] | hasRole | async"
refreshOnPreviousRoute="/grant-create/project/{{projectId}}/grant/{{grantId}}">
</app-user-grants> </app-user-grants>
</app-card> </app-card>
</ng-template> </ng-template>

View File

@ -152,6 +152,9 @@ export class GrantedProjectDetailComponent implements OnInit, OnDestroy {
roles, roles,
).then(() => { ).then(() => {
this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true); this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.loadMembers();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -68,7 +68,7 @@
[appHasRole]="['project.grant.read:' + project.projectId, 'project.grant.read']"> [appHasRole]="['project.grant.read:' + project.projectId, 'project.grant.read']">
<app-card title="{{ 'PROJECT.GRANT.TITLE' | translate }}" <app-card title="{{ 'PROJECT.GRANT.TITLE' | translate }}"
description="{{ 'PROJECT.GRANT.DESCRIPTION' | translate }}"> description="{{ 'PROJECT.GRANT.DESCRIPTION' | translate }}">
<app-project-grants <app-project-grants refreshOnPreviousRoute="/projects/{{projectId}}/grants/create"
[disabled]="((['project.grant.write', 'project.grant.write:'+ project.projectId]| hasRole | async) && (['org.global.read']| hasRole | async))== false" [disabled]="((['project.grant.write', 'project.grant.write:'+ project.projectId]| hasRole | async) && (['org.global.read']| hasRole | async))== false"
[projectId]="projectId"> [projectId]="projectId">
</app-project-grants> </app-project-grants>
@ -89,6 +89,7 @@
<app-card *ngIf="project?.projectId" title="{{ 'GRANTS.PROJECT.TITLE' | translate }}" <app-card *ngIf="project?.projectId" title="{{ 'GRANTS.PROJECT.TITLE' | translate }}"
description="{{'GRANTS.PROJECT.DESCRIPTION' | translate }}"> description="{{'GRANTS.PROJECT.DESCRIPTION' | translate }}">
<app-user-grants [context]="UserGrantContext.OWNED_PROJECT" [projectId]="projectId" <app-user-grants [context]="UserGrantContext.OWNED_PROJECT" [projectId]="projectId"
refreshOnPreviousRoute="/grant-create/project/{{projectId}}"
[allowCreate]="(['user.grant.write', 'user.grant.write:'+projectId] | hasRole) | async" [allowCreate]="(['user.grant.write', 'user.grant.write:'+projectId] | hasRole) | async"
[allowDelete]="(['user.grant.delete','user.grant.delete:'+projectId] | hasRole) | async"> [allowDelete]="(['user.grant.delete','user.grant.delete:'+projectId] | hasRole) | async">
</app-user-grants> </app-user-grants>

View File

@ -226,6 +226,9 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
return this.mgmtService.AddProjectMember(this.projectId, user.id, roles) return this.mgmtService.AddProjectMember(this.projectId, user.id, roles)
.then(() => { .then(() => {
this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true); this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.loadMembers();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -1,5 +1,6 @@
<app-refresh-table [loading]="dataSource?.loading$ | async" *ngIf="projectId" (refreshed)="loadGrantsPage()" <app-refresh-table [loading]="dataSource?.loading$ | async" *ngIf="projectId" (refreshed)="loadGrantsPage()"
[dataSize]="dataSource.totalResult" [selection]="selection" [timestamp]="dataSource?.viewTimestamp"> [dataSize]="dataSource.totalResult" [selection]="selection" [timestamp]="dataSource?.viewTimestamp"
[emitRefreshOnPreviousRoute]="refreshOnPreviousRoute">
<ng-template appHasRole [appHasRole]="['project.grant.member.delete:'+projectId, 'project.grant.member.delete']" <ng-template appHasRole [appHasRole]="['project.grant.member.delete:'+projectId, 'project.grant.member.delete']"
actions> actions>
<button (click)="deleteSelectedGrants()" [disabled]="disabled" mat-icon-button *ngIf="selection.hasValue()" <button (click)="deleteSelectedGrants()" [disabled]="disabled" mat-icon-button *ngIf="selection.hasValue()"

View File

@ -24,6 +24,7 @@ import { ProjectGrantsDataSource } from './project-grants-datasource';
], ],
}) })
export class ProjectGrantsComponent implements OnInit, AfterViewInit { export class ProjectGrantsComponent implements OnInit, AfterViewInit {
@Input() refreshOnPreviousRoute: string = '';
@Input() public projectId: string = ''; @Input() public projectId: string = '';
@Input() public disabled: boolean = false; @Input() public disabled: boolean = false;
@ViewChild(MatPaginator) public paginator!: MatPaginator; @ViewChild(MatPaginator) public paginator!: MatPaginator;

View File

@ -100,7 +100,10 @@ export class MachineKeysComponent implements OnInit {
console.log(this.userId, type, date); console.log(this.userId, type, date);
return this.userService.AddMachineKey(this.userId, type, date).then((response) => { return this.userService.AddMachineKey(this.userId, type, date).then((response) => {
if (response) { if (response) {
console.log(response.toObject()); setTimeout(() => {
this.refreshPage();
}, 1000);
this.dialog.open(ShowKeyDialogComponent, { this.dialog.open(ShowKeyDialogComponent, {
data: { data: {
key: response.toObject(), key: response.toObject(),

View File

@ -132,6 +132,9 @@ export class MembershipDetailComponent implements AfterViewInit {
return this.adminService.AddIamMember(user.id, roles); return this.adminService.AddIamMember(user.id, roles);
})).then(() => { })).then(() => {
this.toast.showInfo('IAM.TOAST.MEMBERADDED', true); this.toast.showInfo('IAM.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.refreshPage();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });
@ -147,6 +150,9 @@ export class MembershipDetailComponent implements AfterViewInit {
return this.mgmtService.AddMyOrgMember(user.id, roles); return this.mgmtService.AddMyOrgMember(user.id, roles);
})).then(() => { })).then(() => {
this.toast.showInfo('ORG.TOAST.MEMBERADDED', true); this.toast.showInfo('ORG.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.refreshPage();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });
@ -166,6 +172,9 @@ export class MembershipDetailComponent implements AfterViewInit {
roles, roles,
).then(() => { ).then(() => {
this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true); this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.refreshPage();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });
@ -182,6 +191,9 @@ export class MembershipDetailComponent implements AfterViewInit {
return this.mgmtService.AddProjectMember(response.projectId, user.id, roles) return this.mgmtService.AddProjectMember(response.projectId, user.id, roles)
.then(() => { .then(() => {
this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true); this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.refreshPage();
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -32,6 +32,11 @@
aria-label="add membership"> aria-label="add membership">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
</button> </button>
<span class="fill-space"></span>
<button class="refresh-img" (click)="loadManager(user.id)" [disabled]="disabled" mat-icon-button
aria-label="refresh contributors">
<mat-icon>refresh</mat-icon>
</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -48,6 +48,15 @@
margin: 0 8px 0 -15px; margin: 0 8px 0 -15px;
} }
.fill-space {
flex: 1;
}
.refresh-img {
float: left;
margin: 0 8px 0 -15px;
}
.avatar-circle { .avatar-circle {
float: left; float: left;
margin: 0 8px 0 -12px; margin: 0 8px 0 -12px;

View File

@ -100,6 +100,9 @@ export class MembershipsComponent implements OnInit {
return this.adminService.AddIamMember(user.id, roles); return this.adminService.AddIamMember(user.id, roles);
})).then(() => { })).then(() => {
this.toast.showInfo('IAM.TOAST.MEMBERADDED', true); this.toast.showInfo('IAM.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.loadManager(this.user.id);
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });
@ -115,6 +118,9 @@ export class MembershipsComponent implements OnInit {
return this.mgmtService.AddMyOrgMember(user.id, roles); return this.mgmtService.AddMyOrgMember(user.id, roles);
})).then(() => { })).then(() => {
this.toast.showInfo('ORG.TOAST.MEMBERADDED', true); this.toast.showInfo('ORG.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.loadManager(this.user.id);
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });
@ -134,6 +140,9 @@ export class MembershipsComponent implements OnInit {
roles, roles,
).then(() => { ).then(() => {
this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true); this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.loadManager(this.user.id);
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });
@ -150,6 +159,9 @@ export class MembershipsComponent implements OnInit {
return this.mgmtService.AddProjectMember(response.projectId, user.id, roles) return this.mgmtService.AddProjectMember(response.projectId, user.id, roles)
.then(() => { .then(() => {
this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true); this.toast.showInfo('PROJECT.TOAST.MEMBERADDED', true);
setTimeout(() => {
this.loadManager(this.user.id);
}, 1000);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -1,5 +1,6 @@
<app-refresh-table [loading]="loading$ | async" (refreshed)="refreshPage()" [dataSize]="dataSource.data.length" <app-refresh-table [loading]="loading$ | async" (refreshed)="refreshPage()" [dataSize]="dataSource.data.length"
[timestamp]="userResult?.viewTimestamp" [selection]="selection"> [timestamp]="userResult?.viewTimestamp" [selection]="selection"
[emitRefreshOnPreviousRoute]="refreshOnPreviousRoute">
<ng-template appHasRole [appHasRole]="['user.write']" actions> <ng-template appHasRole [appHasRole]="['user.write']" actions>
<button (click)="deactivateSelectedUsers()" matTooltip="{{'ORG_DETAIL.TABLE.DEACTIVATE' | translate}}" <button (click)="deactivateSelectedUsers()" matTooltip="{{'ORG_DETAIL.TABLE.DEACTIVATE' | translate}}"
class="icon-button" mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled"> class="icon-button" mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled">

View File

@ -19,6 +19,7 @@ import { UserType } from '../user-list.component';
export class UserTableComponent implements OnInit { export class UserTableComponent implements OnInit {
public UserType: any = UserType; public UserType: any = UserType;
@Input() userType: UserType = UserType.HUMAN; @Input() userType: UserType = UserType.HUMAN;
@Input() refreshOnPreviousRoute: string = '';
@Input() disabled: boolean = false; @Input() disabled: boolean = false;
@ViewChild(MatPaginator) public paginator!: MatPaginator; @ViewChild(MatPaginator) public paginator!: MatPaginator;
public dataSource: MatTableDataSource<UserView.AsObject> = new MatTableDataSource<UserView.AsObject>(); public dataSource: MatTableDataSource<UserView.AsObject> = new MatTableDataSource<UserView.AsObject>();

View File

@ -0,0 +1,27 @@
import { Injectable } from '@angular/core';
import { Event, NavigationEnd, Router } from '@angular/router';
import { filter } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class RefreshService {
private fifo: Array<string> = ['', ''];
constructor(router: Router) {
router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe((event: Event | any) => {
console.log('prev:', event.url);
this.moveInto(event.url);
});
}
public get previousUrls(): Array<string> {
return this.fifo;
}
private moveInto(value: string): void {
this.fifo[1] = this.fifo[0];
this.fifo[0] = value;
}
}