diff --git a/build/console/generate-grpc.sh b/build/console/generate-grpc.sh index 677b922155..06e1fd18ba 100755 --- a/build/console/generate-grpc.sh +++ b/build/console/generate-grpc.sh @@ -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" diff --git a/console/src/app/app.module.ts b/console/src/app/app.module.ts index c27d11e188..1d49a5a55d 100644 --- a/console/src/app/app.module.ts +++ b/console/src/app/app.module.ts @@ -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, diff --git a/console/src/app/modules/accounts-card/accounts-card.component.html b/console/src/app/modules/accounts-card/accounts-card.component.html index 8ec771c0dd..c705f50765 100644 --- a/console/src/app/modules/accounts-card/accounts-card.component.html +++ b/console/src/app/modules/accounts-card/accounts-card.component.html @@ -10,7 +10,7 @@
- + @@ -22,7 +22,7 @@ keyboard_arrow_right - +
diff --git a/console/src/app/modules/accounts-card/accounts-card.component.ts b/console/src/app/modules/accounts-card/accounts-card.component.ts index b8a15ea6c5..7cdac48adb 100644 --- a/console/src/app/modules/accounts-card/accounts-card.component.ts +++ b/console/src/app/modules/accounts-card/accounts-card.component.ts @@ -45,21 +45,27 @@ export class AccountsCardComponent implements OnInit { } } - public selectAccount(loginHint?: string, idToken?: string): void { + public selectAccount(loginName?: string): void { const configWithPrompt: Partial = { customQueryParams: { - prompt: 'select_account', + // prompt: 'select_account', } as any, }; - if (loginHint) { - (configWithPrompt as any).customQueryParams['login_hint'] = loginHint; - } - if (idToken) { - (configWithPrompt as any).customQueryParams['id_token_hint'] = idToken; + if (loginName) { + (configWithPrompt as any).customQueryParams['login_hint'] = loginName; } this.authService.authenticate(configWithPrompt); } + public selectNewAccount(): void { + const configWithPrompt: Partial = { + customQueryParams: { + prompt: 'login', + } as any, + }; + this.authService.authenticate(configWithPrompt); + } + public logout(): void { this.authService.signout(); this.close.emit(); diff --git a/console/src/app/modules/user-grants/user-grants-datasource.ts b/console/src/app/modules/user-grants/user-grants-datasource.ts index 9a88fe96a1..818c630d46 100644 --- a/console/src/app/modules/user-grants/user-grants-datasource.ts +++ b/console/src/app/modules/user-grants/user-grants-datasource.ts @@ -39,11 +39,10 @@ export class UserGrantsDataSource extends DataSource { ): 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 { 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); } diff --git a/console/src/app/modules/user-grants/user-grants.component.ts b/console/src/app/modules/user-grants/user-grants.component.ts index d620009d04..0ea371e759 100644 --- a/console/src/app/modules/user-grants/user-grants.component.ts +++ b/console/src/app/modules/user-grants/user-grants.component.ts @@ -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); }); diff --git a/console/src/app/modules/warn-dialog/warn-dialog.component.html b/console/src/app/modules/warn-dialog/warn-dialog.component.html new file mode 100644 index 0000000000..a37542480b --- /dev/null +++ b/console/src/app/modules/warn-dialog/warn-dialog.component.html @@ -0,0 +1,13 @@ +{{data.titleKey | translate}} +
+

{{data.descriptionKey | translate}}

+
+
+ + + +
\ No newline at end of file diff --git a/console/src/app/modules/warn-dialog/warn-dialog.component.scss b/console/src/app/modules/warn-dialog/warn-dialog.component.scss new file mode 100644 index 0000000000..1fdc5bd3c7 --- /dev/null +++ b/console/src/app/modules/warn-dialog/warn-dialog.component.scss @@ -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; + } +} \ No newline at end of file diff --git a/console/src/app/modules/warn-dialog/warn-dialog.component.spec.ts b/console/src/app/modules/warn-dialog/warn-dialog.component.spec.ts new file mode 100644 index 0000000000..7d7c703976 --- /dev/null +++ b/console/src/app/modules/warn-dialog/warn-dialog.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [WarnDialogComponent], + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(WarnDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/warn-dialog/warn-dialog.component.ts b/console/src/app/modules/warn-dialog/warn-dialog.component.ts new file mode 100644 index 0000000000..8012e29a61 --- /dev/null +++ b/console/src/app/modules/warn-dialog/warn-dialog.component.ts @@ -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, + @Inject(MAT_DIALOG_DATA) public data: any, + ) { } + + ngOnInit(): void { + } + + public closeDialog(): void { + this.dialogRef.close(false); + } + + public closeDialogWithSuccess(): void { + this.dialogRef.close(true); + } +} diff --git a/console/src/app/modules/warn-dialog/warn-dialog.module.ts b/console/src/app/modules/warn-dialog/warn-dialog.module.ts new file mode 100644 index 0000000000..bbe5428a5c --- /dev/null +++ b/console/src/app/modules/warn-dialog/warn-dialog.module.ts @@ -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 { } diff --git a/console/src/app/pages/orgs/org-detail/org-detail.component.ts b/console/src/app/pages/orgs/org-detail/org-detail.component.ts index 4e7edaaa2a..55f35d0e05 100644 --- a/console/src/app/pages/orgs/org-detail/org-detail.component.ts +++ b/console/src/app/pages/orgs/org-detail/org-detail.component.ts @@ -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,14 +85,28 @@ export class OrgDetailComponent implements OnInit, OnDestroy { } public removeDomain(domain: string): void { - this.orgService.RemoveMyOrgDomain(domain).then(() => { - this.toast.showInfo('Removed'); - const index = this.domains.findIndex(d => d.domain === domain); - if (index > -1) { - this.domains.splice(index, 1); + 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); + if (index > -1) { + this.domains.splice(index, 1); + } + }).catch(error => { + this.toast.showError(error.message); + }); } - }).catch(error => { - this.toast.showError(error.message); }); } } diff --git a/console/src/app/pages/orgs/orgs.module.ts b/console/src/app/pages/orgs/orgs.module.ts index 01e629540c..6a411d630b 100644 --- a/console/src/app/pages/orgs/orgs.module.ts +++ b/console/src/app/pages/orgs/orgs.module.ts @@ -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({ diff --git a/console/src/assets/environment.json b/console/src/assets/environment.json index 45569b0b8f..6c6684a289 100644 --- a/console/src/assets/environment.json +++ b/console/src/assets/environment.json @@ -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" } diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index 076c63a469..677c720c29 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -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", diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index 71fa521a6d..cc4c0b4abf 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -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", @@ -626,4 +630,4 @@ "user.selfregistered":"self registered" } } -} \ No newline at end of file +}