diff --git a/console/src/app/modules/project-roles/project-role-detail/project-role-detail.component.html b/console/src/app/modules/project-roles/project-role-detail/project-role-detail.component.html index 9336a1efa9..f2afe3c71c 100644 --- a/console/src/app/modules/project-roles/project-role-detail/project-role-detail.component.html +++ b/console/src/app/modules/project-roles/project-role-detail/project-role-detail.component.html @@ -4,15 +4,15 @@

{{'PROJECT.ROLE.EDITDESCRIPTION' | translate}}

- + {{ 'PROJECT.ROLE.KEY' | translate }} - + {{ 'PROJECT.ROLE.DISPLAY_NAME' | translate }} - + {{ 'PROJECT.ROLE.GROUP' | translate }} diff --git a/console/src/app/pages/iam/failed-events/failed-events.component.html b/console/src/app/pages/iam/failed-events/failed-events.component.html new file mode 100644 index 0000000000..1431264b2e --- /dev/null +++ b/console/src/app/pages/iam/failed-events/failed-events.component.html @@ -0,0 +1,54 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'IAM.FAILEDEVENTS.VIEWNAME' | translate }} {{event.viewName}} {{ 'IAM.FAILEDEVENTS.DATABASE' | translate }} {{event.database}} {{ 'IAM.FAILEDEVENTS.FAILEDSEQUENCE' | translate }} + {{event?.failedSequence}} + {{ 'IAM.FAILEDEVENTS.FAILURECOUNT' | translate }} + {{event?.failureCount }} + {{ 'IAM.FAILEDEVENTS.ERRORMESSAGE' | translate }} + {{event?.errorMessage }} + {{ 'IAM.FAILEDEVENTS.ACTIONS' | translate }} + +
+ + +
+
\ No newline at end of file diff --git a/console/src/app/pages/iam/failed-events/failed-events.component.scss b/console/src/app/pages/iam/failed-events/failed-events.component.scss new file mode 100644 index 0000000000..5a2bc04204 --- /dev/null +++ b/console/src/app/pages/iam/failed-events/failed-events.component.scss @@ -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; +} diff --git a/console/src/app/pages/iam/failed-events/failed-events.component.spec.ts b/console/src/app/pages/iam/failed-events/failed-events.component.spec.ts new file mode 100644 index 0000000000..2c2175580c --- /dev/null +++ b/console/src/app/pages/iam/failed-events/failed-events.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [FailedEventsComponent], + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FailedEventsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/pages/iam/failed-events/failed-events.component.ts b/console/src/app/pages/iam/failed-events/failed-events.component.ts new file mode 100644 index 0000000000..78ed665ab6 --- /dev/null +++ b/console/src/app/pages/iam/failed-events/failed-events.component.ts @@ -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; + + public eventDisplayedColumns: string[] = ['viewName', 'database', 'failedSequence', 'failureCount', 'errorMessage', 'actions']; + + private loadingSubject: BehaviorSubject = new BehaviorSubject(false); + public loading$: Observable = 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); + }); + } +} diff --git a/console/src/app/pages/iam/iam-views/iam-views.component.html b/console/src/app/pages/iam/iam-views/iam-views.component.html index d15a6ad1fc..b059adc676 100644 --- a/console/src/app/pages/iam/iam-views/iam-views.component.html +++ b/console/src/app/pages/iam/iam-views/iam-views.component.html @@ -1,55 +1,47 @@ -
-
- {{'ORG_DETAIL.TABLE.TOTAL' | translate}} - {{dataSource?.data?.length}} -
- -
-
-
- -
+ - - - - - +
{{ 'IAM.VIEWS.VIEWNAME' | translate }} {{role.viewName}}
+ + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - -
{{ 'IAM.VIEWS.VIEWNAME' | translate }} {{view.viewName}} {{ 'IAM.VIEWS.DATABASE' | translate }} {{role.database}} {{ 'IAM.VIEWS.DATABASE' | translate }} {{view.database}} {{ 'IAM.VIEWS.SEQUENCE' | translate }} - {{role?.processedSequence}} - {{ 'IAM.VIEWS.SEQUENCE' | translate }} + {{view?.processedSequence}} + {{ 'IAM.VIEWS.SEQUENCE' | translate }} - {{role?.viewTimestamp | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }} - {{ 'IAM.VIEWS.TIMESTAMP' | translate }} + {{view?.viewTimestamp | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }} + {{ 'IAM.VIEWS.ACTIONS' | translate }} - - {{ 'IAM.VIEWS.ACTIONS' | translate }} + +
- - + + + + + +
\ No newline at end of file diff --git a/console/src/app/pages/iam/iam-views/iam-views.component.scss b/console/src/app/pages/iam/iam-views/iam-views.component.scss index d14460e53f..5a2bc04204 100644 --- a/console/src/app/pages/iam/iam-views/iam-views.component.scss +++ b/console/src/app/pages/iam/iam-views/iam-views.component.scss @@ -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 { overflow: auto; - .spinner-container { - display: flex; - align-items: center; - justify-content: center; - } - .table, .paginator { width: 100%; diff --git a/console/src/app/pages/iam/iam-views/iam-views.component.ts b/console/src/app/pages/iam/iam-views/iam-views.component.ts index 55c6b7b792..0a4456bfc5 100644 --- a/console/src/app/pages/iam/iam-views/iam-views.component.ts +++ b/console/src/app/pages/iam/iam-views/iam-views.component.ts @@ -1,7 +1,6 @@ import { Component, ViewChild } from '@angular/core'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { MatTable, MatTableDataSource } from '@angular/material/table'; +import { MatTableDataSource } from '@angular/material/table'; import { BehaviorSubject, from, Observable, of } from 'rxjs'; import { catchError, finalize, map } from 'rxjs/operators'; 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'], }) export class IamViewsComponent { - public views: View.AsObject[] = []; - - @ViewChild(MatPaginator) public paginator!: MatPaginator; - @ViewChild(MatTable) public table!: MatTable; - @ViewChild(MatSort) public sort!: MatSort; public dataSource!: MatTableDataSource; public displayedColumns: string[] = ['viewName', 'database', 'sequence', 'timestamp', 'actions']; + private loadingSubject: BehaviorSubject = new BehaviorSubject(false); public loading$: Observable = this.loadingSubject.asObservable(); constructor(private adminService: AdminService) { @@ -39,7 +34,6 @@ export class IamViewsComponent { ).subscribe(views => { this.dataSource = new MatTableDataSource(views); this.dataSource.paginator = this.paginator; - this.dataSource.sort = this.sort; }); } diff --git a/console/src/app/pages/iam/iam.component.html b/console/src/app/pages/iam/iam.component.html index 05dd155abb..b493fde342 100644 --- a/console/src/app/pages/iam/iam.component.html +++ b/console/src/app/pages/iam/iam.component.html @@ -6,6 +6,11 @@ + + + +
diff --git a/console/src/app/pages/iam/iam.module.ts b/console/src/app/pages/iam/iam.module.ts index 95c74189fd..54e427e25c 100644 --- a/console/src/app/pages/iam/iam.module.ts +++ b/console/src/app/pages/iam/iam.module.ts @@ -20,18 +20,19 @@ import { CardModule } from 'src/app/modules/card/card.module'; import { ChangesModule } from 'src/app/modules/changes/changes.module'; import { ContributorsModule } from 'src/app/modules/contributors/contributors.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 { LocalizedDatePipeModule } from 'src/app/pipes/localized-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 { IamViewsComponent } from './iam-views/iam-views.component'; import { IamComponent } from './iam.component'; - @NgModule({ - declarations: [IamComponent, IamViewsComponent], + declarations: [IamComponent, IamViewsComponent, FailedEventsComponent], imports: [ CommonModule, IamRoutingModule, @@ -59,6 +60,7 @@ import { IamComponent } from './iam.component'; LocalizedDatePipeModule, TimestampToDatePipeModule, SharedModule, + RefreshTableModule, ], }) export class IamModule { } diff --git a/console/src/app/pages/orgs/org-detail/add-domain-dialog/add-domain-dialog.component.html b/console/src/app/pages/orgs/org-detail/add-domain-dialog/add-domain-dialog.component.html index 0b7c608724..7f00acc917 100644 --- a/console/src/app/pages/orgs/org-detail/add-domain-dialog/add-domain-dialog.component.html +++ b/console/src/app/pages/orgs/org-detail/add-domain-dialog/add-domain-dialog.component.html @@ -2,7 +2,7 @@

{{'ORG.DOMAINS.ADD.DESCRIPTION' | translate}}

- + Domain @@ -12,7 +12,8 @@ {{'ACTIONS.CANCEL' | translate}} -
\ No newline at end of file diff --git a/console/src/app/pages/orgs/policy-grid/policy-grid.component.html b/console/src/app/pages/orgs/policy-grid/policy-grid.component.html index 28e93ee69b..e3b8898434 100644 --- a/console/src/app/pages/orgs/policy-grid/policy-grid.component.html +++ b/console/src/app/pages/orgs/policy-grid/policy-grid.component.html @@ -26,7 +26,7 @@ + mat-stroked-button>{{'ORG.POLICY.BTN_EDIT' | translate}}
@@ -55,7 +55,7 @@ + mat-stroked-button>{{'ORG.POLICY.BTN_EDIT' | translate}} diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.html b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.html index 16944fb5f0..24d8d8d91a 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.html +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.html @@ -34,7 +34,7 @@ {{'PROJECT.NAME' | translate}} - + - {{ 'PROJECT.PAGES.CREATE' | translate }}Step - {{ currentCreateStep }} of - {{ createSteps }} - - -

{{'PROJECT.PAGES.CREATE_DESC' | translate}}

- -
- - {{'PROJECT.NAME' | translate}} - - +
+ + {{ 'PROJECT.PAGES.CREATE' | translate }}Step + {{ currentCreateStep }} of + {{ createSteps }}
- - +

{{'PROJECT.PAGES.CREATE_DESC' | translate}}

+
+
+ + {{'PROJECT.NAME' | translate}} + + +
+ + +
\ No newline at end of file diff --git a/console/src/app/pages/users/user-detail/detail-form/detail-form.component.html b/console/src/app/pages/users/user-detail/detail-form/detail-form.component.html index 36e01bab59..a3c3b4a285 100644 --- a/console/src/app/pages/users/user-detail/detail-form/detail-form.component.html +++ b/console/src/app/pages/users/user-detail/detail-form/detail-form.component.html @@ -1,22 +1,22 @@
- + {{ 'USER.PROFILE.USERNAME' | translate }} - + {{ 'USER.PROFILE.FIRSTNAME' | translate }} - + {{ 'USER.PROFILE.LASTNAME' | translate }} - + {{ 'USER.PROFILE.NICKNAME' | translate }} - + {{ 'USER.PROFILE.GENDER' | translate }} @@ -24,7 +24,7 @@ - + {{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }} diff --git a/console/src/app/services/admin.service.ts b/console/src/app/services/admin.service.ts index 09a32c04ed..238d7892c3 100644 --- a/console/src/app/services/admin.service.ts +++ b/console/src/app/services/admin.service.ts @@ -8,6 +8,8 @@ import { ChangeIamMemberRequest, CreateOrgRequest, CreateUserRequest, + FailedEventID, + FailedEvents, IamMember, IamMemberRoles, IamMemberSearchQuery, @@ -78,6 +80,14 @@ export class AdminService { ); } + public async GetFailedEvents(): Promise { + return await this.request( + c => c.getFailedEvents, + new Empty(), + f => f, + ); + } + public async ClearView(viewname: string, db: string): Promise { const req: ViewID = new ViewID(); req.setDatabase(db); @@ -89,6 +99,18 @@ export class AdminService { ); } + public async RemoveFailedEvent(viewname: string, db: string, sequence: number): Promise { + 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( limit: number, offset: number, diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index 65f30c0a52..2be8d32f38 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -239,14 +239,27 @@ "DESCRIPTION": "Manger können die Organisation editieren und Projekte verwalten." }, "VIEWS": { - "TITLE":"Views und Events", - "DESCRIPTION":"Diese Ansicht zeigt die ZITADEL Views, du kannst diese zurücksetzen und fehlgeschlagene Events entfernen.", + "TITLE":"Views", + "DESCRIPTION":"Diese Ansicht zeigt die ZITADEL Views. Diese können bei Bedarf zurückgesetzt werden.", "VIEWNAME":"Name", "DATABASE":"Datenbank", "SEQUENCE":"Sequenz", + "TIMESTAMP":"Zeitstempel", "ACTIONS":"Aktionen", "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":{ "MEMBERREMOVED":"Manager entfernt!", "MEMBERSADDED": "Manager hinzugefügt!", diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index e15acb6ccd..4b8e3f32cf 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -239,14 +239,27 @@ "DESCRIPTION":"Managers can add and edit organisations and make changes to their corresponding projects and apps" }, "VIEWS": { - "TITLE":"Views and Events", - "DESCRIPTION":"This Card shows your Zitadel Views, you can clear them and remove failed events.", + "TITLE":"Views", + "DESCRIPTION":"This Card shows your Zitadel Views.", "VIEWNAME":"Name", "DATABASE":"Database", "SEQUENCE":"Sequence", + "TIMESTAMP":"Timestamp", "ACTIONS":"Actions", "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":{ "MEMBERREMOVED":"Manager removed!", "MEMBERSADDED": "Managers added!",