mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 03:27:32 +00:00
feat: failed events (#582)
This commit is contained in:
@@ -4,15 +4,15 @@
|
|||||||
<p class="desc"> {{'PROJECT.ROLE.EDITDESCRIPTION' | translate}}</p>
|
<p class="desc"> {{'PROJECT.ROLE.EDITDESCRIPTION' | translate}}</p>
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<form *ngIf="formGroup" class="full-width" [formGroup]="formGroup" (ngSubmit)="submitForm()">
|
<form *ngIf="formGroup" class="full-width" [formGroup]="formGroup" (ngSubmit)="submitForm()">
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'PROJECT.ROLE.KEY' | translate }}</mat-label>
|
<mat-label>{{ 'PROJECT.ROLE.KEY' | translate }}</mat-label>
|
||||||
<input matInput formControlName="key" />
|
<input matInput formControlName="key" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</mat-label>
|
<mat-label>{{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }}</mat-label>
|
||||||
<input matInput formControlName="displayName" />
|
<input matInput formControlName="displayName" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'PROJECT.ROLE.GROUP' | translate }}</mat-label>
|
<mat-label>{{ 'PROJECT.ROLE.GROUP' | translate }}</mat-label>
|
||||||
<input matInput formControlName="group" />
|
<input matInput formControlName="group" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
@@ -0,0 +1,54 @@
|
|||||||
|
<div class="table-wrapper">
|
||||||
|
<app-refresh-table *ngIf="eventDataSource" (refreshed)="loadEvents()" [dataSize]="eventDataSource.data.length"
|
||||||
|
[loading]="loading$ | async">
|
||||||
|
|
||||||
|
<table [dataSource]="eventDataSource" mat-table class="table background-style" aria-label="Elements">
|
||||||
|
<ng-container matColumnDef="viewName">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.FAILEDEVENTS.VIEWNAME' | translate }} </th>
|
||||||
|
<td mat-cell *matCellDef="let event"> {{event.viewName}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="database">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.FAILEDEVENTS.DATABASE' | translate }} </th>
|
||||||
|
<td mat-cell *matCellDef="let event"> {{event.database}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="failedSequence">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.FAILEDEVENTS.FAILEDSEQUENCE' | translate }} </th>
|
||||||
|
<td mat-cell *matCellDef="let event">
|
||||||
|
<span class="role app-label">{{event?.failedSequence}}</span>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="failureCount">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.FAILEDEVENTS.FAILURECOUNT' | translate }} </th>
|
||||||
|
<td mat-cell *matCellDef="let event">
|
||||||
|
<span>{{event?.failureCount }}</span>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="errorMessage">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.FAILEDEVENTS.ERRORMESSAGE' | translate }} </th>
|
||||||
|
<td mat-cell *matCellDef="let event">
|
||||||
|
<span>{{event?.errorMessage }}</span>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="actions">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.FAILEDEVENTS.ACTIONS' | translate }} </th>
|
||||||
|
<td mat-cell *matCellDef="let event">
|
||||||
|
<button color="warn" mat-icon-button matTooltip="{{'IAM.FAILEDEVENTS.DELETE' | translate}}"
|
||||||
|
(click)="cancelEvent(event.viewName, event.database, event.failedSequence)">
|
||||||
|
<i class="las la-minus-circle"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="eventDisplayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: eventDisplayedColumns;"></tr>
|
||||||
|
</table>
|
||||||
|
<mat-paginator class="paginator background-style" [pageSize]="10" #paginator
|
||||||
|
[pageSizeOptions]="[10, 20, 100, 250]">
|
||||||
|
</mat-paginator>
|
||||||
|
</app-refresh-table>
|
||||||
|
</div>
|
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
.table-wrapper {
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.table,
|
||||||
|
.paginator {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
padding: 0 1rem;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection {
|
||||||
|
width: 50px;
|
||||||
|
max-width: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { FailedEventsComponent } from './failed-events.component';
|
||||||
|
|
||||||
|
describe('FailedEventsComponent', () => {
|
||||||
|
let component: FailedEventsComponent;
|
||||||
|
let fixture: ComponentFixture<FailedEventsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [FailedEventsComponent],
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(FailedEventsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,46 @@
|
|||||||
|
import { Component, ViewChild } from '@angular/core';
|
||||||
|
import { MatPaginator } from '@angular/material/paginator';
|
||||||
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
|
import { BehaviorSubject, from, Observable, of } from 'rxjs';
|
||||||
|
import { catchError, finalize, map } from 'rxjs/operators';
|
||||||
|
import { FailedEvent } from 'src/app/proto/generated/admin_pb';
|
||||||
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-iam-failed-events',
|
||||||
|
templateUrl: './failed-events.component.html',
|
||||||
|
styleUrls: ['./failed-events.component.scss'],
|
||||||
|
})
|
||||||
|
export class FailedEventsComponent {
|
||||||
|
@ViewChild(MatPaginator) public eventPaginator!: MatPaginator;
|
||||||
|
public eventDataSource!: MatTableDataSource<FailedEvent.AsObject>;
|
||||||
|
|
||||||
|
public eventDisplayedColumns: string[] = ['viewName', 'database', 'failedSequence', 'failureCount', 'errorMessage', 'actions'];
|
||||||
|
|
||||||
|
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
|
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||||
|
constructor(private adminService: AdminService, private toast: ToastService) {
|
||||||
|
this.loadEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
public loadEvents(): void {
|
||||||
|
this.loadingSubject.next(true);
|
||||||
|
from(this.adminService.GetFailedEvents()).pipe(
|
||||||
|
map(resp => {
|
||||||
|
return resp.toObject().failedEventsList;
|
||||||
|
}),
|
||||||
|
catchError(() => of([])),
|
||||||
|
finalize(() => this.loadingSubject.next(false)),
|
||||||
|
).subscribe(views => {
|
||||||
|
this.eventDataSource = new MatTableDataSource(views);
|
||||||
|
this.eventDataSource.paginator = this.eventPaginator;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public cancelEvent(viewname: string, db: string, seq: number): void {
|
||||||
|
this.adminService.RemoveFailedEvent(viewname, db, seq).then(() => {
|
||||||
|
this.toast.showInfo('IAM.FAILEDEVENTS.DELETESUCCESS', true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -1,55 +1,47 @@
|
|||||||
<div class="table-header-row">
|
|
||||||
<div class="col">
|
|
||||||
<span class="desc">{{'ORG_DETAIL.TABLE.TOTAL' | translate}}</span>
|
|
||||||
<span class="count">{{dataSource?.data?.length}}</span>
|
|
||||||
</div>
|
|
||||||
<span class="fill-space"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<div class="spinner-container" *ngIf="loading$ | async">
|
<app-refresh-table *ngIf="dataSource" (refreshed)="loadViews()" [dataSize]="dataSource.data.length"
|
||||||
<mat-spinner diameter="50"></mat-spinner>
|
[loading]="loading$ | async">
|
||||||
</div>
|
|
||||||
|
|
||||||
<table *ngIf="dataSource" [dataSource]="dataSource" mat-table class="table background-style" matSort
|
<table [dataSource]="dataSource" mat-table class="table background-style" aria-label="Elements">
|
||||||
aria-label="Elements">
|
<ng-container matColumnDef="viewName">
|
||||||
<ng-container matColumnDef="viewName">
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.VIEWS.VIEWNAME' | translate }} </th>
|
||||||
<th mat-header-cell mat-sort-header *matHeaderCellDef> {{ 'IAM.VIEWS.VIEWNAME' | translate }} </th>
|
<td mat-cell *matCellDef="let view"> {{view.viewName}} </td>
|
||||||
<td mat-cell *matCellDef="let role"> {{role.viewName}} </td>
|
</ng-container>
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="database">
|
<ng-container matColumnDef="database">
|
||||||
<th mat-header-cell mat-sort-header *matHeaderCellDef> {{ 'IAM.VIEWS.DATABASE' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.VIEWS.DATABASE' | translate }} </th>
|
||||||
<td mat-cell *matCellDef="let role"> {{role.database}} </td>
|
<td mat-cell *matCellDef="let view"> {{view.database}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="sequence">
|
<ng-container matColumnDef="sequence">
|
||||||
<th mat-header-cell mat-sort-header *matHeaderCellDef> {{ 'IAM.VIEWS.SEQUENCE' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.VIEWS.SEQUENCE' | translate }} </th>
|
||||||
<td mat-cell *matCellDef="let role">
|
<td mat-cell *matCellDef="let view">
|
||||||
<span class="role app-label">{{role?.processedSequence}}</span>
|
<span>{{view?.processedSequence}}</span>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="timestamp">
|
<ng-container matColumnDef="timestamp">
|
||||||
<th mat-header-cell mat-sort-header *matHeaderCellDef> {{ 'IAM.VIEWS.SEQUENCE' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.VIEWS.TIMESTAMP' | translate }} </th>
|
||||||
<td mat-cell *matCellDef="let role">
|
<td mat-cell *matCellDef="let view">
|
||||||
<span>{{role?.viewTimestamp | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}</span>
|
<span>{{view?.viewTimestamp | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}</span>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.VIEWS.ACTIONS' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef> {{ 'IAM.VIEWS.ACTIONS' | translate }} </th>
|
||||||
<td mat-cell *matCellDef="let role">
|
<td mat-cell *matCellDef="let view">
|
||||||
<button mat-icon-button matTooltip="{{'IAM.VIEWS.CLEAR' | translate}}"
|
<button mat-icon-button matTooltip="{{'IAM.VIEWS.CLEAR' | translate}}"
|
||||||
(click)="cancelView(role.viewName, role.database)">
|
(click)="cancelView(view.viewName, view.database)">
|
||||||
<mat-icon svgIcon="mdi_broom"></mat-icon>
|
<mat-icon svgIcon="mdi_broom"></mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
</table>
|
</table>
|
||||||
<mat-paginator class="paginator background-style" #paginator [pageSize]="10" [pageSizeOptions]="[10, 20, 100, 250]">
|
<mat-paginator class="paginator background-style" [pageSize]="10" #paginator
|
||||||
</mat-paginator>
|
[pageSizeOptions]="[10, 20, 100, 250]">
|
||||||
|
</mat-paginator>
|
||||||
|
</app-refresh-table>
|
||||||
</div>
|
</div>
|
@@ -1,40 +1,7 @@
|
|||||||
|
|
||||||
.table-header-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.col {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.desc {
|
|
||||||
font-size: .8rem;
|
|
||||||
color: #8795a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fill-space {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-button {
|
|
||||||
margin-right: .5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-wrapper {
|
.table-wrapper {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
.spinner-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table,
|
.table,
|
||||||
.paginator {
|
.paginator {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Component, ViewChild } from '@angular/core';
|
import { Component, ViewChild } from '@angular/core';
|
||||||
import { MatPaginator } from '@angular/material/paginator';
|
import { MatPaginator } from '@angular/material/paginator';
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { MatTable, MatTableDataSource } from '@angular/material/table';
|
|
||||||
import { BehaviorSubject, from, Observable, of } from 'rxjs';
|
import { BehaviorSubject, from, Observable, of } from 'rxjs';
|
||||||
import { catchError, finalize, map } from 'rxjs/operators';
|
import { catchError, finalize, map } from 'rxjs/operators';
|
||||||
import { View } from 'src/app/proto/generated/admin_pb';
|
import { View } from 'src/app/proto/generated/admin_pb';
|
||||||
@@ -13,15 +12,11 @@ import { AdminService } from 'src/app/services/admin.service';
|
|||||||
styleUrls: ['./iam-views.component.scss'],
|
styleUrls: ['./iam-views.component.scss'],
|
||||||
})
|
})
|
||||||
export class IamViewsComponent {
|
export class IamViewsComponent {
|
||||||
public views: View.AsObject[] = [];
|
|
||||||
|
|
||||||
|
|
||||||
@ViewChild(MatPaginator) public paginator!: MatPaginator;
|
@ViewChild(MatPaginator) public paginator!: MatPaginator;
|
||||||
@ViewChild(MatTable) public table!: MatTable<View.AsObject>;
|
|
||||||
@ViewChild(MatSort) public sort!: MatSort;
|
|
||||||
public dataSource!: MatTableDataSource<View.AsObject>;
|
public dataSource!: MatTableDataSource<View.AsObject>;
|
||||||
|
|
||||||
public displayedColumns: string[] = ['viewName', 'database', 'sequence', 'timestamp', 'actions'];
|
public displayedColumns: string[] = ['viewName', 'database', 'sequence', 'timestamp', 'actions'];
|
||||||
|
|
||||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||||
constructor(private adminService: AdminService) {
|
constructor(private adminService: AdminService) {
|
||||||
@@ -39,7 +34,6 @@ export class IamViewsComponent {
|
|||||||
).subscribe(views => {
|
).subscribe(views => {
|
||||||
this.dataSource = new MatTableDataSource(views);
|
this.dataSource = new MatTableDataSource(views);
|
||||||
this.dataSource.paginator = this.paginator;
|
this.dataSource.paginator = this.paginator;
|
||||||
this.dataSource.sort = this.sort;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,6 +6,11 @@
|
|||||||
<app-card title="{{ 'IAM.VIEWS.TITLE' | translate }}" description="{{ 'IAM.VIEWS.DESCRIPTION' | translate }}">
|
<app-card title="{{ 'IAM.VIEWS.TITLE' | translate }}" description="{{ 'IAM.VIEWS.DESCRIPTION' | translate }}">
|
||||||
<app-iam-views></app-iam-views>
|
<app-iam-views></app-iam-views>
|
||||||
</app-card>
|
</app-card>
|
||||||
|
|
||||||
|
<app-card title="{{ 'IAM.FAILEDEVENTS.TITLE' | translate }}"
|
||||||
|
description="{{ 'IAM.FAILEDEVENTS.DESCRIPTION' | translate }}">
|
||||||
|
<app-iam-failed-events></app-iam-failed-events>
|
||||||
|
</app-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="side" metainfo>
|
<div class="side" metainfo>
|
||||||
|
@@ -20,18 +20,19 @@ import { CardModule } from 'src/app/modules/card/card.module';
|
|||||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||||
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
||||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||||
|
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
||||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
|
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
|
||||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
|
||||||
|
|
||||||
|
import { FailedEventsComponent } from './failed-events/failed-events.component';
|
||||||
import { IamRoutingModule } from './iam-routing.module';
|
import { IamRoutingModule } from './iam-routing.module';
|
||||||
import { IamViewsComponent } from './iam-views/iam-views.component';
|
import { IamViewsComponent } from './iam-views/iam-views.component';
|
||||||
import { IamComponent } from './iam.component';
|
import { IamComponent } from './iam.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [IamComponent, IamViewsComponent],
|
declarations: [IamComponent, IamViewsComponent, FailedEventsComponent],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
IamRoutingModule,
|
IamRoutingModule,
|
||||||
@@ -59,6 +60,7 @@ import { IamComponent } from './iam.component';
|
|||||||
LocalizedDatePipeModule,
|
LocalizedDatePipeModule,
|
||||||
TimestampToDatePipeModule,
|
TimestampToDatePipeModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
|
RefreshTableModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class IamModule { }
|
export class IamModule { }
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<p class="desc"> {{'ORG.DOMAINS.ADD.DESCRIPTION' | translate}}</p>
|
<p class="desc"> {{'ORG.DOMAINS.ADD.DESCRIPTION' | translate}}</p>
|
||||||
|
|
||||||
<mat-form-field label="Domain" required="true" class="form-field">
|
<mat-form-field label="Domain" required="true" class="form-field" appearance="outline">
|
||||||
<mat-label>Domain</mat-label>
|
<mat-label>Domain</mat-label>
|
||||||
<input matInput [(ngModel)]="newdomain" />
|
<input matInput [(ngModel)]="newdomain" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@@ -12,7 +12,8 @@
|
|||||||
{{'ACTIONS.CANCEL' | translate}}
|
{{'ACTIONS.CANCEL' | translate}}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button color="warn" mat-raised-button class="ok-button" [disabled]="!newdomain" (click)="closeDialogWithSuccess()">
|
<button color="primary" mat-raised-button class="ok-button" [disabled]="!newdomain"
|
||||||
|
(click)="closeDialogWithSuccess()">
|
||||||
{{'ACTIONS.ADD' | translate}}
|
{{'ACTIONS.ADD' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
@@ -26,7 +26,7 @@
|
|||||||
<button [disabled]="complexityPolicy" [routerLink]="[ 'policy', PolicyComponentType.COMPLEXITY,'create' ]"
|
<button [disabled]="complexityPolicy" [routerLink]="[ 'policy', PolicyComponentType.COMPLEXITY,'create' ]"
|
||||||
color="primary" mat-raised-button>{{'ORG.POLICY.BTN_INSTALL' | translate}}</button>
|
color="primary" mat-raised-button>{{'ORG.POLICY.BTN_INSTALL' | translate}}</button>
|
||||||
<button [disabled]="!complexityPolicy" [routerLink]="[ 'policy', PolicyComponentType.COMPLEXITY ]"
|
<button [disabled]="!complexityPolicy" [routerLink]="[ 'policy', PolicyComponentType.COMPLEXITY ]"
|
||||||
mat-raised-button>{{'ORG.POLICY.BTN_EDIT' | translate}}</button>
|
mat-stroked-button>{{'ORG.POLICY.BTN_EDIT' | translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
<button [disabled]="iamPolicy" [routerLink]="[ 'policy', PolicyComponentType.IAM_POLICY,'create' ]"
|
<button [disabled]="iamPolicy" [routerLink]="[ 'policy', PolicyComponentType.IAM_POLICY,'create' ]"
|
||||||
color="primary" mat-raised-button>{{'ORG.POLICY.BTN_INSTALL' | translate}}</button>
|
color="primary" mat-raised-button>{{'ORG.POLICY.BTN_INSTALL' | translate}}</button>
|
||||||
<button [disabled]="!iamPolicy" [routerLink]="[ 'policy', PolicyComponentType.IAM_POLICY ]"
|
<button [disabled]="!iamPolicy" [routerLink]="[ 'policy', PolicyComponentType.IAM_POLICY ]"
|
||||||
mat-raised-button>{{'ORG.POLICY.BTN_EDIT' | translate}}</button>
|
mat-stroked-button>{{'ORG.POLICY.BTN_EDIT' | translate}}</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -34,7 +34,7 @@
|
|||||||
<mat-form-field *ngIf="editstate && project?.name" class="formfield"
|
<mat-form-field *ngIf="editstate && project?.name" class="formfield"
|
||||||
hintLabel="The name is required!">
|
hintLabel="The name is required!">
|
||||||
<mat-label>{{'PROJECT.NAME' | translate}}</mat-label>
|
<mat-label>{{'PROJECT.NAME' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="project.name" />
|
<input matInput [(ngModel)]="project.name" name="name" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<button class="icon-button" *ngIf="editstate" mat-icon-button (click)="updateName()">
|
<button class="icon-button" *ngIf="editstate" mat-icon-button (click)="updateName()">
|
||||||
<mat-icon>check</mat-icon>
|
<mat-icon>check</mat-icon>
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatRippleModule } from '@angular/material/core';
|
import { MatRippleModule } from '@angular/material/core';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
@@ -45,7 +46,9 @@ import { ProjectGrantsComponent } from './project-grants/project-grants.componen
|
|||||||
FormsModule,
|
FormsModule,
|
||||||
OwnedProjectDetailRoutingModule,
|
OwnedProjectDetailRoutingModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
HasRoleModule,
|
HasRoleModule,
|
||||||
|
MatInputModule,
|
||||||
MatTabsModule,
|
MatTabsModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
@@ -1,25 +1,25 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="abort-container">
|
<div class="abort-container">
|
||||||
<button (click)="close()" mat-icon-button>
|
<button (click)="close()" mat-icon-button>
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<span class="abort">{{ 'PROJECT.PAGES.CREATE' | translate }}</span><span class="abort-2">Step
|
<span class="abort">{{ 'PROJECT.PAGES.CREATE' | translate }}</span><span class="abort-2">Step
|
||||||
{{ currentCreateStep }} of
|
{{ currentCreateStep }} of
|
||||||
{{ createSteps }}</span>
|
{{ createSteps }}</span>
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1>{{'PROJECT.PAGES.CREATE_DESC' | translate}}</h1>
|
|
||||||
<form (ngSubmit)="saveProject()">
|
|
||||||
<div class="column">
|
|
||||||
<mat-form-field class="formfield" hintLabel="The name is required!">
|
|
||||||
<mat-label>{{'PROJECT.NAME' | translate}}</mat-label>
|
|
||||||
<input matInput autofocus [(ngModel)]="project.name" [ngModelOptions]="{ standalone: true }" />
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="!project.name" cdkFocusInitial
|
<h1>{{'PROJECT.PAGES.CREATE_DESC' | translate}}</h1>
|
||||||
type="submit">
|
<form (ngSubmit)="saveProject()">
|
||||||
{{'CONTINUE' | translate}}
|
<div class="column">
|
||||||
</button>
|
<mat-form-field class="formfield" hintLabel="The name is required!">
|
||||||
</form>
|
<mat-label>{{'PROJECT.NAME' | translate}}</mat-label>
|
||||||
|
<input matInput autofocus [(ngModel)]="project.name" [ngModelOptions]="{ standalone: true }" />
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button color="primary" mat-raised-button class="continue-button" [disabled]="!project.name" cdkFocusInitial
|
||||||
|
type="submit">
|
||||||
|
{{'CONTINUE' | translate}}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
@@ -1,22 +1,22 @@
|
|||||||
<form [formGroup]="profileForm" *ngIf="profileForm" (ngSubmit)="submitForm()">
|
<form [formGroup]="profileForm" *ngIf="profileForm" (ngSubmit)="submitForm()">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.USERNAME' | translate }}</mat-label>
|
<mat-label>{{ 'USER.PROFILE.USERNAME' | translate }}</mat-label>
|
||||||
<input matInput formControlName="userName" />
|
<input matInput formControlName="userName" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}</mat-label>
|
<mat-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}</mat-label>
|
||||||
<input matInput formControlName="firstName" />
|
<input matInput formControlName="firstName" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.LASTNAME' | translate }}</mat-label>
|
<mat-label>{{ 'USER.PROFILE.LASTNAME' | translate }}</mat-label>
|
||||||
<input matInput formControlName="lastName" />
|
<input matInput formControlName="lastName" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</mat-label>
|
<mat-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</mat-label>
|
||||||
<input matInput formControlName="nickName" />
|
<input matInput formControlName="nickName" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.GENDER' | translate }}</mat-label>
|
<mat-label>{{ 'USER.PROFILE.GENDER' | translate }}</mat-label>
|
||||||
<mat-select formControlName="gender">
|
<mat-select formControlName="gender">
|
||||||
<mat-option *ngFor="let gender of genders" [value]="gender">
|
<mat-option *ngFor="let gender of genders" [value]="gender">
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="formfield">
|
<mat-form-field class="formfield" appearance="outline">
|
||||||
<mat-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</mat-label>
|
<mat-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</mat-label>
|
||||||
<mat-select formControlName="preferredLanguage">
|
<mat-select formControlName="preferredLanguage">
|
||||||
<mat-option *ngFor="let language of languages" [value]="language">
|
<mat-option *ngFor="let language of languages" [value]="language">
|
||||||
|
@@ -8,6 +8,8 @@ import {
|
|||||||
ChangeIamMemberRequest,
|
ChangeIamMemberRequest,
|
||||||
CreateOrgRequest,
|
CreateOrgRequest,
|
||||||
CreateUserRequest,
|
CreateUserRequest,
|
||||||
|
FailedEventID,
|
||||||
|
FailedEvents,
|
||||||
IamMember,
|
IamMember,
|
||||||
IamMemberRoles,
|
IamMemberRoles,
|
||||||
IamMemberSearchQuery,
|
IamMemberSearchQuery,
|
||||||
@@ -78,6 +80,14 @@ export class AdminService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async GetFailedEvents(): Promise<FailedEvents> {
|
||||||
|
return await this.request(
|
||||||
|
c => c.getFailedEvents,
|
||||||
|
new Empty(),
|
||||||
|
f => f,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public async ClearView(viewname: string, db: string): Promise<Empty> {
|
public async ClearView(viewname: string, db: string): Promise<Empty> {
|
||||||
const req: ViewID = new ViewID();
|
const req: ViewID = new ViewID();
|
||||||
req.setDatabase(db);
|
req.setDatabase(db);
|
||||||
@@ -89,6 +99,18 @@ export class AdminService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async RemoveFailedEvent(viewname: string, db: string, sequence: number): Promise<Empty> {
|
||||||
|
const req: FailedEventID = new FailedEventID();
|
||||||
|
req.setDatabase(db);
|
||||||
|
req.setViewName(viewname);
|
||||||
|
req.setFailedSequence(sequence);
|
||||||
|
return await this.request(
|
||||||
|
c => c.removeFailedEvent,
|
||||||
|
req,
|
||||||
|
f => f,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public async SearchIamMembers(
|
public async SearchIamMembers(
|
||||||
limit: number,
|
limit: number,
|
||||||
offset: number,
|
offset: number,
|
||||||
|
@@ -239,14 +239,27 @@
|
|||||||
"DESCRIPTION": "Manger können die Organisation editieren und Projekte verwalten."
|
"DESCRIPTION": "Manger können die Organisation editieren und Projekte verwalten."
|
||||||
},
|
},
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"TITLE":"Views und Events",
|
"TITLE":"Views",
|
||||||
"DESCRIPTION":"Diese Ansicht zeigt die ZITADEL Views, du kannst diese zurücksetzen und fehlgeschlagene Events entfernen.",
|
"DESCRIPTION":"Diese Ansicht zeigt die ZITADEL Views. Diese können bei Bedarf zurückgesetzt werden.",
|
||||||
"VIEWNAME":"Name",
|
"VIEWNAME":"Name",
|
||||||
"DATABASE":"Datenbank",
|
"DATABASE":"Datenbank",
|
||||||
"SEQUENCE":"Sequenz",
|
"SEQUENCE":"Sequenz",
|
||||||
|
"TIMESTAMP":"Zeitstempel",
|
||||||
"ACTIONS":"Aktionen",
|
"ACTIONS":"Aktionen",
|
||||||
"CLEAR":"Aufräumen"
|
"CLEAR":"Aufräumen"
|
||||||
},
|
},
|
||||||
|
"FAILEDEVENTS": {
|
||||||
|
"TITLE":"Gescheiterte Events",
|
||||||
|
"DESCRIPTION":"Das sind die gescheiterten Events.",
|
||||||
|
"VIEWNAME":"Name",
|
||||||
|
"DATABASE":"Datenbank",
|
||||||
|
"FAILEDSEQUENCE":"betroffene Sequenz",
|
||||||
|
"FAILURECOUNT":"Fehleranzahl",
|
||||||
|
"ERRORMESSAGE":"Meldung",
|
||||||
|
"ACTIONS":"Aktionen",
|
||||||
|
"DELETE":"Entfernen",
|
||||||
|
"DELETESUCCESS":"Gescheiterte Events entfernt!"
|
||||||
|
},
|
||||||
"TOAST":{
|
"TOAST":{
|
||||||
"MEMBERREMOVED":"Manager entfernt!",
|
"MEMBERREMOVED":"Manager entfernt!",
|
||||||
"MEMBERSADDED": "Manager hinzugefügt!",
|
"MEMBERSADDED": "Manager hinzugefügt!",
|
||||||
|
@@ -239,14 +239,27 @@
|
|||||||
"DESCRIPTION":"Managers can add and edit organisations and make changes to their corresponding projects and apps"
|
"DESCRIPTION":"Managers can add and edit organisations and make changes to their corresponding projects and apps"
|
||||||
},
|
},
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"TITLE":"Views and Events",
|
"TITLE":"Views",
|
||||||
"DESCRIPTION":"This Card shows your Zitadel Views, you can clear them and remove failed events.",
|
"DESCRIPTION":"This Card shows your Zitadel Views.",
|
||||||
"VIEWNAME":"Name",
|
"VIEWNAME":"Name",
|
||||||
"DATABASE":"Database",
|
"DATABASE":"Database",
|
||||||
"SEQUENCE":"Sequence",
|
"SEQUENCE":"Sequence",
|
||||||
|
"TIMESTAMP":"Timestamp",
|
||||||
"ACTIONS":"Actions",
|
"ACTIONS":"Actions",
|
||||||
"CLEAR":"Clear"
|
"CLEAR":"Clear"
|
||||||
},
|
},
|
||||||
|
"FAILEDEVENTS": {
|
||||||
|
"TITLE":"Failed Events",
|
||||||
|
"DESCRIPTION":"This Card shows your failed Events.",
|
||||||
|
"VIEWNAME":"Name",
|
||||||
|
"DATABASE":"Database",
|
||||||
|
"FAILEDSEQUENCE":"Failed Sequence",
|
||||||
|
"FAILURECOUNT":"Failure Count",
|
||||||
|
"ERRORMESSAGE":"Error message",
|
||||||
|
"ACTIONS":"Actions",
|
||||||
|
"DELETE":"Remove",
|
||||||
|
"DELETESUCCESS":"Failed Events removed!"
|
||||||
|
},
|
||||||
"TOAST":{
|
"TOAST":{
|
||||||
"MEMBERREMOVED":"Manager removed!",
|
"MEMBERREMOVED":"Manager removed!",
|
||||||
"MEMBERSADDED": "Managers added!",
|
"MEMBERSADDED": "Managers added!",
|
||||||
|
Reference in New Issue
Block a user