mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 02:54:20 +00:00
feat(console): replace wget with curl, user login prompt, warn dialog (#387)
* remove evil wget, add warn-dialog, login hint * i18n * reference ngsw.js * update clientid * fix warn dialog * lint * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster <florian@caos.ch> * Update console/src/assets/i18n/en.json Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Florian Forster <florian@caos.ch>
This commit is contained in:
parent
a5bfd085a1
commit
c621fdee41
@ -10,10 +10,14 @@ rm -rf $GEN_PATH
|
||||
echo "Create folders"
|
||||
mkdir -p $GEN_PATH
|
||||
|
||||
targetcurl () {
|
||||
mkdir -p $1 && cd $1 && { curl -O $2; cd -; }
|
||||
}
|
||||
|
||||
echo "Download additional protofiles"
|
||||
wget -P tmp/validate https://raw.githubusercontent.com/envoyproxy/protoc-gen-validate/v0.4.0/validate/validate.proto
|
||||
wget -P tmp/protoc-gen-swagger/options https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/v1.14.6/protoc-gen-swagger/options/annotations.proto
|
||||
wget -P tmp/protoc-gen-swagger/options https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/v1.14.6/protoc-gen-swagger/options/openapiv2.proto
|
||||
targetcurl tmp/validate https://raw.githubusercontent.com/envoyproxy/protoc-gen-validate/v0.4.0/validate/validate.proto
|
||||
targetcurl tmp/protoc-gen-swagger/options https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/v1.14.6/protoc-gen-swagger/options/annotations.proto
|
||||
targetcurl tmp/protoc-gen-swagger/options https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/v1.14.6/protoc-gen-swagger/options/openapiv2.proto
|
||||
|
||||
echo "Generate grpc"
|
||||
|
||||
|
@ -103,7 +103,7 @@ export let authConfig = {
|
||||
MatMenuModule,
|
||||
MatSnackBarModule,
|
||||
AvatarModule,
|
||||
ServiceWorkerModule.register('ngsw-config.json', { enabled: environment.production }),
|
||||
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
|
||||
],
|
||||
providers: [
|
||||
ThemeService,
|
||||
|
@ -10,7 +10,7 @@
|
||||
<button (click)="editUserProfile()" mat-stroked-button>{{'USER.EDITACCOUNT' | translate}}</button>
|
||||
<div class="l-accounts">
|
||||
<mat-progress-bar *ngIf="loadingUsers" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
<a class="row" *ngFor="let user of users" (click)="selectAccount(user.userName)">
|
||||
<a class="row" *ngFor="let user of users" (click)="selectAccount(user.loginName)">
|
||||
<app-avatar *ngIf="user && user.displayName" class="small-avatar"
|
||||
[name]="user.displayName ? user.displayName : ''" [size]="32">
|
||||
</app-avatar>
|
||||
@ -22,7 +22,7 @@
|
||||
<span class="fill-space"></span>
|
||||
<mat-icon>keyboard_arrow_right</mat-icon>
|
||||
</a>
|
||||
<a class="row" (click)="selectAccount()">
|
||||
<a class="row" (click)="selectNewAccount()">
|
||||
<div class="icon-wrapper">
|
||||
<i class="las la-user-plus"></i>
|
||||
</div>
|
||||
|
@ -45,18 +45,24 @@ export class AccountsCardComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
public selectAccount(loginHint?: string, idToken?: string): void {
|
||||
public selectAccount(loginName?: string): void {
|
||||
const configWithPrompt: Partial<AuthConfig> = {
|
||||
customQueryParams: {
|
||||
prompt: 'select_account',
|
||||
// prompt: 'select_account',
|
||||
} as any,
|
||||
};
|
||||
if (loginHint) {
|
||||
(configWithPrompt as any).customQueryParams['login_hint'] = loginHint;
|
||||
if (loginName) {
|
||||
(configWithPrompt as any).customQueryParams['login_hint'] = loginName;
|
||||
}
|
||||
if (idToken) {
|
||||
(configWithPrompt as any).customQueryParams['id_token_hint'] = idToken;
|
||||
this.authService.authenticate(configWithPrompt);
|
||||
}
|
||||
|
||||
public selectNewAccount(): void {
|
||||
const configWithPrompt: Partial<AuthConfig> = {
|
||||
customQueryParams: {
|
||||
prompt: 'login',
|
||||
} as any,
|
||||
};
|
||||
this.authService.authenticate(configWithPrompt);
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,10 @@ export class UserGrantsDataSource extends DataSource<UserGrant.AsObject> {
|
||||
): void {
|
||||
const offset = pageIndex * pageSize;
|
||||
|
||||
this.loadingSubject.next(true);
|
||||
|
||||
switch (context) {
|
||||
case UserGrantContext.USER:
|
||||
if (data && data.userId) {
|
||||
this.loadingSubject.next(true);
|
||||
const userfilter = new UserGrantSearchQuery();
|
||||
userfilter.setKey(UserGrantSearchKey.USERGRANTSEARCHKEY_USER_ID);
|
||||
userfilter.setValue(data.userId);
|
||||
@ -59,12 +58,14 @@ export class UserGrantsDataSource extends DataSource<UserGrant.AsObject> {
|
||||
break;
|
||||
case UserGrantContext.OWNED_PROJECT:
|
||||
if (data && data.projectId) {
|
||||
this.loadingSubject.next(true);
|
||||
const promise1 = this.userService.SearchProjectUserGrants(data.projectId, 10, 0, queries);
|
||||
this.loadResponse(promise1);
|
||||
}
|
||||
break;
|
||||
case UserGrantContext.GRANTED_PROJECT:
|
||||
if (data && data.grantId) {
|
||||
this.loadingSubject.next(true);
|
||||
const promise2 = this.userService.SearchProjectGrantUserGrants(data.grantId, 10, 0, queries);
|
||||
this.loadResponse(promise2);
|
||||
}
|
||||
|
@ -139,7 +139,17 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
||||
deleteGrantSelection(): void {
|
||||
this.userService.BulkRemoveUserGrant(this.selection.selected.map(grant => grant.id)).then(() => {
|
||||
this.toast.showInfo('Grants deleted');
|
||||
this.loadGrantsPage();
|
||||
const data = this.dataSource.grantsSubject.getValue();
|
||||
console.log(data);
|
||||
this.selection.selected.forEach((item) => {
|
||||
console.log(item);
|
||||
const index = data.findIndex(i => i.id === item.id);
|
||||
if (index > -1) {
|
||||
data.splice(index, 1);
|
||||
this.dataSource.grantsSubject.next(data);
|
||||
}
|
||||
});
|
||||
this.selection.clear();
|
||||
}).catch(error => {
|
||||
this.toast.showError(error.message);
|
||||
});
|
||||
|
@ -0,0 +1,13 @@
|
||||
<span class="title" mat-dialog-title>{{data.titleKey | translate}}</span>
|
||||
<div mat-dialog-content>
|
||||
<p class="desc"> {{data.descriptionKey | translate}}</p>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
<button mat-button (click)="closeDialog()">
|
||||
{{data.cancelKey | translate}}
|
||||
</button>
|
||||
|
||||
<button color="warn" mat-raised-button class="ok-button" (click)="closeDialogWithSuccess()">
|
||||
{{data.confirmKey | translate}}
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,22 @@
|
||||
.title {
|
||||
font-size: 1.2rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #8795a1;
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.ok-button {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { WarnDialogComponent } from './warn-dialog.component';
|
||||
|
||||
describe('WarnDialogComponent', () => {
|
||||
let component: WarnDialogComponent;
|
||||
let fixture: ComponentFixture<WarnDialogComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [WarnDialogComponent],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(WarnDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
26
console/src/app/modules/warn-dialog/warn-dialog.component.ts
Normal file
26
console/src/app/modules/warn-dialog/warn-dialog.component.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'app-warn-dialog',
|
||||
templateUrl: './warn-dialog.component.html',
|
||||
styleUrls: ['./warn-dialog.component.scss'],
|
||||
})
|
||||
export class WarnDialogComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<WarnDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
public closeDialogWithSuccess(): void {
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
}
|
21
console/src/app/modules/warn-dialog/warn-dialog.module.ts
Normal file
21
console/src/app/modules/warn-dialog/warn-dialog.module.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { WarnDialogComponent } from './warn-dialog.component';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [WarnDialogComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
TranslateModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
entryComponents: [
|
||||
WarnDialogComponent,
|
||||
],
|
||||
})
|
||||
export class WarnDialogModule { }
|
@ -1,10 +1,12 @@
|
||||
import { SelectionModel } from '@angular/cdk/collections';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { MatButtonToggleChange } from '@angular/material/button-toggle';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { ChangeType } from 'src/app/modules/changes/changes.component';
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
import { Org, OrgDomainView, OrgMember, OrgMemberSearchResponse, OrgState } from 'src/app/proto/generated/management_pb';
|
||||
import { OrgService } from 'src/app/services/org.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
@ -32,6 +34,7 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
|
||||
public newDomain: string = '';
|
||||
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
public translate: TranslateService,
|
||||
private orgService: OrgService,
|
||||
private toast: ToastService,
|
||||
@ -82,6 +85,18 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public removeDomain(domain: string): void {
|
||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||
data: {
|
||||
confirmKey: 'ACTIONS.DELETE',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
titleKey: 'ORG.DOMAINS.DELETE.TITLE',
|
||||
descriptionKey: 'ORG.DOMAINS.DELETE.DESCRIPTION',
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
if (resp) {
|
||||
this.orgService.RemoveMyOrgDomain(domain).then(() => {
|
||||
this.toast.showInfo('Removed');
|
||||
const index = this.domains.findIndex(d => d.domain === domain);
|
||||
@ -92,4 +107,6 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
|
||||
this.toast.showError(error.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import { HttpLoaderFactory } from 'src/app/app.module';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||
import { WarnDialogModule } from 'src/app/modules/warn-dialog/warn-dialog.module';
|
||||
|
||||
import { ChangesModule } from '../../modules/changes/changes.module';
|
||||
import { OrgContributorsModule } from './org-contributors/org-contributors.module';
|
||||
@ -43,6 +44,8 @@ import { PolicyGridComponent } from './policy-grid/policy-grid.component';
|
||||
MetaLayoutModule,
|
||||
MatTabsModule,
|
||||
MatTooltipModule,
|
||||
MatDialogModule,
|
||||
WarnDialogModule,
|
||||
MatMenuModule,
|
||||
ChangesModule,
|
||||
TranslateModule.forChild({
|
||||
|
@ -3,5 +3,5 @@
|
||||
"mgmtServiceUrl": "https://api.zitadel.dev",
|
||||
"adminServiceUrl":"https://api.zitadel.dev",
|
||||
"issuer": "https://issuer.zitadel.dev",
|
||||
"clientid": "61542534056307917@zitadel"
|
||||
"clientid": "63146698922323188@zitadel"
|
||||
}
|
||||
|
@ -22,10 +22,10 @@
|
||||
"PERSONAL_INFO": "Persönliche Informationen",
|
||||
"IAM":"Administration",
|
||||
"ORGANIZATION": "Organisation",
|
||||
"PROJECTSSECTION":"Projekte",
|
||||
"PROJECTSSECTION":"Projektsektion",
|
||||
"PROJECT": "Projekte",
|
||||
"GRANTEDPROJECT":"Berechtigte Projekte",
|
||||
"USERSECTION":"Benutzer",
|
||||
"USERSECTION":"Benutzersektion",
|
||||
"USER": "Benutzer",
|
||||
"LOGOUT": "alle Benutzer abmelden",
|
||||
"NEWORG":"Neue Organisation",
|
||||
@ -230,7 +230,11 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"TITLE":"Domains",
|
||||
"DESCRIPTION":"Konfigurieren Sie Ihre Domains mit denen sich Ihre Nutzer einloggen können."
|
||||
"DESCRIPTION":"Konfigurieren Sie die Domains mit denen sich Ihre Nutzer einloggen können.",
|
||||
"DELETE": {
|
||||
"TITLE":"Domain löschen?",
|
||||
"DESCRIPTION":"Sie sind im Begriff eine Domain aus Ihrer Organisation zu löschen. Ihre Benutzer können diese nach dem Löschen nicht mehr für den Login nutzen."
|
||||
}
|
||||
},
|
||||
"STATE": {
|
||||
"0": "nicht definiert",
|
||||
|
@ -22,10 +22,10 @@
|
||||
"PERSONAL_INFO": "Personal Information",
|
||||
"IAM":"Administration",
|
||||
"ORGANIZATION": "Organization",
|
||||
"PROJECTSSECTION":"Projects",
|
||||
"PROJECTSSECTION":"projects section",
|
||||
"PROJECT": "Projects",
|
||||
"GRANTEDPROJECT":"Granted Projects",
|
||||
"USERSECTION":"Benutzer",
|
||||
"USERSECTION":"user section",
|
||||
"USER": "Users",
|
||||
"LOGOUT": "Logout all users",
|
||||
"NEWORG":"New Organization",
|
||||
@ -231,7 +231,11 @@
|
||||
},
|
||||
"DOMAINS": {
|
||||
"TITLE":"Domains",
|
||||
"DESCRIPTION":"Configure your domains on which your users will be registered."
|
||||
"DESCRIPTION":"Configure your domains on which your users will be registered.",
|
||||
"DELETE": {
|
||||
"TITLE":"Delete domain?",
|
||||
"DESCRIPTION":"You are about to delete one of your domains. Note that your users can no longer use this domain for their logins."
|
||||
}
|
||||
},
|
||||
"STATE": {
|
||||
"0": "not defined",
|
||||
|
Loading…
Reference in New Issue
Block a user