fix(console): add missing login interface texts, update dependencies, cleanup storage (#2430)

* name

* core cli

* material cdk

* chore(deps): bump libphonenumber-js from 1.9.23 to 1.9.34 in /console (#2386)

Bumps [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) from 1.9.23 to 1.9.34.
- [Release notes](https://gitlab.com/catamphetamine/libphonenumber-js/tags)
- [Changelog](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/catamphetamine/libphonenumber-js/compare/v1.9.23...v1.9.34)

---
updated-dependencies:
- dependency-name: libphonenumber-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump jasmine-core from 3.7.1 to 3.9.0 in /console (#2373)

Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 3.7.1 to 3.9.0.
- [Release notes](https://github.com/jasmine/jasmine/releases)
- [Changelog](https://github.com/jasmine/jasmine/blob/main/RELEASE.md)
- [Commits](https://github.com/jasmine/jasmine/compare/v3.7.1...v3.9.0)

---
updated-dependencies:
- dependency-name: jasmine-core
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump rxjs from 6.6.7 to 7.3.0 in /console (#2366)

Bumps [rxjs](https://github.com/reactivex/rxjs) from 6.6.7 to 7.3.0.
- [Release notes](https://github.com/reactivex/rxjs/releases)
- [Changelog](https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactivex/rxjs/compare/6.6.7...7.3.0)

---
updated-dependencies:
- dependency-name: rxjs
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* add missing login texts, fix application table

* storage cleanup

* storage location local

* org session storage, remember in local

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
Max Peintner
2021-09-30 08:33:58 +02:00
committed by GitHub
parent 440030b20b
commit 7579bf56f6
19 changed files with 762 additions and 547 deletions

View File

@@ -4,7 +4,7 @@ import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from
import { Router } from '@angular/router';
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
import { GrantedProject, ProjectGrantState } from 'src/app/proto/generated/zitadel/project_pb';
import { StorageKey, StorageService } from 'src/app/services/storage.service';
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
@Component({
selector: 'app-granted-project-grid',
@@ -81,12 +81,12 @@ export class GrantedProjectGridComponent implements OnChanges {
}
private async getPrefixedItem(key: string): Promise<string | null> {
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization) as Org.AsObject;
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session) as Org.AsObject;
return localStorage.getItem(`${org.id}:${key}`);
}
private async setPrefixedItem(key: string, value: any): Promise<void> {
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization) as Org.AsObject;
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session) as Org.AsObject;
return localStorage.setItem(`${org.id}:${key}`, value);
}

View File

@@ -8,7 +8,7 @@
</ng-template>
<div class="table-wrapper">
<table [dataSource]="dataSource" mat-table class="table" matSort aria-label="Elements">
<table [dataSource]="dataSource" mat-table class="table" aria-label="Elements">
<ng-container matColumnDef="select">
<th class="selection" mat-header-cell *matHeaderCellDef>
<mat-checkbox color="primary" (change)="$event ? masterToggle() : null"

View File

@@ -1,8 +1,7 @@
import { SelectionModel } from '@angular/cdk/collections';
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
import { MatSort } from '@angular/material/sort';
import { MatTable } from '@angular/material/table';
import { merge, of } from 'rxjs';
import { merge } from 'rxjs';
import { tap } from 'rxjs/operators';
import { PaginatorComponent } from 'src/app/modules/paginator/paginator.component';
import { App } from 'src/app/proto/generated/zitadel/app_pb';
@@ -11,57 +10,56 @@ import { ManagementService } from 'src/app/services/mgmt.service';
import { ProjectApplicationsDataSource } from './applications-datasource';
@Component({
selector: 'app-applications',
templateUrl: './applications.component.html',
styleUrls: ['./applications.component.scss'],
selector: 'app-applications',
templateUrl: './applications.component.html',
styleUrls: ['./applications.component.scss'],
})
export class ApplicationsComponent implements AfterViewInit, OnInit {
@Input() public projectId: string = '';
@Input() public disabled: boolean = false;
@ViewChild(PaginatorComponent) public paginator!: PaginatorComponent;
@ViewChild(MatSort) public sort!: MatSort;
@ViewChild(MatTable) public table!: MatTable<App.AsObject>;
public dataSource!: ProjectApplicationsDataSource;
public selection: SelectionModel<App.AsObject> = new SelectionModel<App.AsObject>(true, []);
@Input() public projectId: string = '';
@Input() public disabled: boolean = false;
@ViewChild(PaginatorComponent) public paginator!: PaginatorComponent;
@ViewChild(MatTable) public table!: MatTable<App.AsObject>;
public dataSource!: ProjectApplicationsDataSource;
public selection: SelectionModel<App.AsObject> = new SelectionModel<App.AsObject>(true, []);
public displayedColumns: string[] = ['select', 'name', 'type'];
public displayedColumns: string[] = ['select', 'name', 'type'];
constructor(private mgmtService: ManagementService) { }
constructor(private mgmtService: ManagementService) { }
public ngOnInit(): void {
this.dataSource = new ProjectApplicationsDataSource(this.mgmtService);
this.dataSource.loadApps(this.projectId, 0, 25);
}
public ngOnInit(): void {
this.dataSource = new ProjectApplicationsDataSource(this.mgmtService);
this.dataSource.loadApps(this.projectId, 0, 25);
}
public ngAfterViewInit(): void {
merge(this.sort ? this.sort?.sortChange : of(null), this.paginator.page)
.pipe(
tap(() => this.loadRolesPage()),
)
.subscribe();
}
public ngAfterViewInit(): void {
merge(this.paginator.page)
.pipe(
tap(() => this.loadRolesPage()),
)
.subscribe();
}
private loadRolesPage(): void {
this.dataSource.loadApps(
this.projectId,
this.paginator.pageIndex,
this.paginator.pageSize,
);
}
private loadRolesPage(): void {
this.dataSource.loadApps(
this.projectId,
this.paginator.pageIndex,
this.paginator.pageSize,
);
}
public isAllSelected(): boolean {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.appsSubject.value.length;
return numSelected === numRows;
}
public isAllSelected(): boolean {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.appsSubject.value.length;
return numSelected === numRows;
}
public masterToggle(): void {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.appsSubject.value.forEach((row: App.AsObject) => this.selection.select(row));
}
public masterToggle(): void {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.appsSubject.value.forEach((row: App.AsObject) => this.selection.select(row));
}
public refreshPage(): void {
this.dataSource.loadApps(this.projectId, this.paginator.pageIndex, this.paginator.pageSize);
}
public refreshPage(): void {
this.dataSource.loadApps(this.projectId, this.paginator.pageIndex, this.paginator.pageSize);
}
}

View File

@@ -7,162 +7,162 @@ import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.com
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
import { Project, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
import { ManagementService } from 'src/app/services/mgmt.service';
import { StorageKey, StorageService } from 'src/app/services/storage.service';
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
import { ToastService } from 'src/app/services/toast.service';
@Component({
selector: 'app-owned-project-grid',
templateUrl: './owned-project-grid.component.html',
styleUrls: ['./owned-project-grid.component.scss'],
animations: [
trigger('cardAnimation', [
transition('* => *', [
query('@animate', stagger('100ms', animateChild()), { optional: true }),
]),
]),
trigger('animate', [
transition(':enter', [
animate('.2s ease-in', keyframes([
style({ opacity: 0, transform: 'translateY(-50%)', offset: 0 }),
style({ opacity: .5, transform: 'translateY(-10px) scale(1.1)', offset: 0.3 }),
style({ opacity: 1, transform: 'translateY(0)', offset: 1 }),
])),
]),
transition(':leave', [
animate('.2s ease-out', keyframes([
style({ opacity: 1, transform: 'scale(1.1)', offset: 0 }),
style({ opacity: .5, transform: 'scale(.5)', offset: 0.3 }),
style({ opacity: 0, transform: 'scale(0)', offset: 1 }),
])),
]),
]),
],
selector: 'app-owned-project-grid',
templateUrl: './owned-project-grid.component.html',
styleUrls: ['./owned-project-grid.component.scss'],
animations: [
trigger('cardAnimation', [
transition('* => *', [
query('@animate', stagger('100ms', animateChild()), { optional: true }),
]),
]),
trigger('animate', [
transition(':enter', [
animate('.2s ease-in', keyframes([
style({ opacity: 0, transform: 'translateY(-50%)', offset: 0 }),
style({ opacity: .5, transform: 'translateY(-10px) scale(1.1)', offset: 0.3 }),
style({ opacity: 1, transform: 'translateY(0)', offset: 1 }),
])),
]),
transition(':leave', [
animate('.2s ease-out', keyframes([
style({ opacity: 1, transform: 'scale(1.1)', offset: 0 }),
style({ opacity: .5, transform: 'scale(.5)', offset: 0.3 }),
style({ opacity: 0, transform: 'scale(0)', offset: 1 }),
])),
]),
]),
],
})
export class OwnedProjectGridComponent implements OnChanges {
@Input() items: Array<Project.AsObject> = [];
public notPinned: Array<Project.AsObject> = [];
@Input() items: Array<Project.AsObject> = [];
public notPinned: Array<Project.AsObject> = [];
@Output() newClicked: EventEmitter<boolean> = new EventEmitter();
@Output() changedView: EventEmitter<boolean> = new EventEmitter();
@Input() loading: boolean = false;
@Output() newClicked: EventEmitter<boolean> = new EventEmitter();
@Output() changedView: EventEmitter<boolean> = new EventEmitter();
@Input() loading: boolean = false;
public selection: SelectionModel<Project.AsObject> = new SelectionModel<Project.AsObject>(true, []);
public selection: SelectionModel<Project.AsObject> = new SelectionModel<Project.AsObject>(true, []);
public showNewProject: boolean = false;
public ProjectState: any = ProjectState;
@Input() public zitadelProjectId: string = '';
constructor(
private router: Router,
private dialog: MatDialog,
private storage: StorageService,
private mgmtService: ManagementService,
private toast: ToastService,
) {
this.selection.changed.subscribe(selection => {
this.setPrefixedItem('pinned-projects', JSON.stringify(
this.selection.selected.map(item => item.id),
)).then(() => {
selection.added.forEach(item => {
const index = this.notPinned.findIndex(i => i.id === item.id);
this.notPinned.splice(index, 1);
});
this.notPinned.push(...selection.removed);
});
public showNewProject: boolean = false;
public ProjectState: any = ProjectState;
@Input() public zitadelProjectId: string = '';
constructor(
private router: Router,
private dialog: MatDialog,
private storage: StorageService,
private mgmtService: ManagementService,
private toast: ToastService,
) {
this.selection.changed.subscribe(selection => {
this.setPrefixedItem('pinned-projects', JSON.stringify(
this.selection.selected.map(item => item.id),
)).then(() => {
selection.added.forEach(item => {
const index = this.notPinned.findIndex(i => i.id === item.id);
this.notPinned.splice(index, 1);
});
}
this.notPinned.push(...selection.removed);
});
});
}
public selectItem(item: Project.AsObject, event?: any): void {
if (event && !event.target.classList.contains('mat-icon')) {
this.router.navigate(['/projects', item.id]);
} else if (!event) {
this.router.navigate(['/projects', item.id]);
}
public selectItem(item: Project.AsObject, event?: any): void {
if (event && !event.target.classList.contains('mat-icon')) {
this.router.navigate(['/projects', item.id]);
} else if (!event) {
this.router.navigate(['/projects', item.id]);
}
}
public addItem(): void {
this.newClicked.emit(true);
public addItem(): void {
this.newClicked.emit(true);
}
public ngOnChanges(changes: SimpleChanges): void {
if (changes.items.currentValue && changes.items.currentValue.length > 0) {
this.notPinned = Object.assign([], this.items);
this.reorganizeItems();
}
}
public ngOnChanges(changes: SimpleChanges): void {
if (changes.items.currentValue && changes.items.currentValue.length > 0) {
this.notPinned = Object.assign([], this.items);
this.reorganizeItems();
}
}
public reorganizeItems(): void {
this.getPrefixedItem('pinned-projects').then(storageEntry => {
if (storageEntry) {
const array: string[] = JSON.parse(storageEntry);
const toSelect: Project.AsObject[] = this.items.filter((item, index) => {
if (array.includes(item.id)) {
return true;
}
});
this.selection.select(...toSelect);
}
public reorganizeItems(): void {
this.getPrefixedItem('pinned-projects').then(storageEntry => {
if (storageEntry) {
const array: string[] = JSON.parse(storageEntry);
const toSelect: Project.AsObject[] = this.items.filter((item, index) => {
if (array.includes(item.id)) {
return true;
}
});
}
this.selection.select(...toSelect);
}
});
}
private async getPrefixedItem(key: string): Promise<string | null> {
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization) as Org.AsObject;
return localStorage.getItem(`${org.id}:${key}`);
}
private async getPrefixedItem(key: string): Promise<string | null> {
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session) as Org.AsObject;
return localStorage.getItem(`${org.id}:${key}`);
}
private async setPrefixedItem(key: string, value: any): Promise<void> {
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization) as Org.AsObject;
return localStorage.setItem(`${org.id}:${key}`, value);
}
private async setPrefixedItem(key: string, value: any): Promise<void> {
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session) as Org.AsObject;
return localStorage.setItem(`${org.id}:${key}`, value);
}
public navigateToProject(id: string, event: any): void {
if (event && event.srcElement && event.srcElement.localName !== 'button') {
this.router.navigate(['/projects', id]);
}
public navigateToProject(id: string, event: any): void {
if (event && event.srcElement && event.srcElement.localName !== 'button') {
this.router.navigate(['/projects', id]);
}
}
public closeGridView(): void {
this.changedView.emit(true);
}
public closeGridView(): void {
this.changedView.emit(true);
}
public toggle(item: Project.AsObject, event: any): void {
event.stopPropagation();
this.selection.toggle(item);
}
public toggle(item: Project.AsObject, event: any): void {
event.stopPropagation();
this.selection.toggle(item);
}
public deleteProject(event: any, item: Project.AsObject): void {
event.stopPropagation();
const dialogRef = this.dialog.open(WarnDialogComponent, {
data: {
confirmKey: 'ACTIONS.DELETE',
cancelKey: 'ACTIONS.CANCEL',
titleKey: 'PROJECT.PAGES.DIALOG.DELETE.TITLE',
descriptionKey: 'PROJECT.PAGES.DIALOG.DELETE.DESCRIPTION',
},
width: '400px',
public deleteProject(event: any, item: Project.AsObject): void {
event.stopPropagation();
const dialogRef = this.dialog.open(WarnDialogComponent, {
data: {
confirmKey: 'ACTIONS.DELETE',
cancelKey: 'ACTIONS.CANCEL',
titleKey: 'PROJECT.PAGES.DIALOG.DELETE.TITLE',
descriptionKey: 'PROJECT.PAGES.DIALOG.DELETE.DESCRIPTION',
},
width: '400px',
});
dialogRef.afterClosed().subscribe(resp => {
if (resp && item.id !== this.zitadelProjectId) {
this.mgmtService.removeProject(item.id).then(() => {
this.toast.showInfo('PROJECT.TOAST.DELETED', true);
const index = this.items.findIndex(iter => iter.id === item.id);
if (index > -1) {
this.items.splice(index, 1);
}
const indexSelection = this.selection.selected.findIndex(iter => iter.id === item.id);
if (indexSelection > -1) {
this.selection.selected.splice(indexSelection, 1);
}
const indexPinned = this.notPinned.findIndex(iter => iter.id === item.id);
if (indexPinned > -1) {
this.notPinned.splice(indexPinned, 1);
}
}).catch(error => {
this.toast.showError(error);
});
dialogRef.afterClosed().subscribe(resp => {
if (resp && item.id !== this.zitadelProjectId) {
this.mgmtService.removeProject(item.id).then(() => {
this.toast.showInfo('PROJECT.TOAST.DELETED', true);
const index = this.items.findIndex(iter => iter.id === item.id);
if (index > -1) {
this.items.splice(index, 1);
}
const indexSelection = this.selection.selected.findIndex(iter => iter.id === item.id);
if (indexSelection > -1) {
this.selection.selected.splice(indexSelection, 1);
}
const indexPinned = this.notPinned.findIndex(iter => iter.id === item.id);
if (indexPinned > -1) {
this.notPinned.splice(indexPinned, 1);
}
}).catch(error => {
this.toast.showError(error);
});
}
});
}
}
});
}
}

View File

@@ -121,7 +121,6 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy {
if (resp.details?.viewTimestamp) {
this.viewTimestamp = resp.details?.viewTimestamp;
}
console.log(resp.resultList);
this.dataSource.data = this.ownedProjectList;
this.loadingSubject.next(false);
}).catch(error => {

View File

@@ -9,7 +9,7 @@ import { GrantedProject, Project, Role } from 'src/app/proto/generated/zitadel/p
import { User } from 'src/app/proto/generated/zitadel/user_pb';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ManagementService } from 'src/app/services/mgmt.service';
import { StorageKey, StorageService } from 'src/app/services/storage.service';
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
import { ToastService } from 'src/app/services/toast.service';
@Component({
@@ -94,7 +94,7 @@ export class UserGrantCreateComponent implements OnDestroy {
}
});
const temporg = this.storage.getItem<Org.AsObject>(StorageKey.organization);
const temporg = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.session);
if (temporg) {
this.org = temporg;
}