fix(console): intercept navigator.language, set browser lang as default for user without explicit setting, user table outline, member create dialog import (#820)

* i18n interceptor, set language to browser lang

* nullcheck

* rm external idp log

* fix module imports, rm user displayname from i18n

* Update console/src/assets/i18n/de.json

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
This commit is contained in:
Max Peintner 2020-10-08 14:49:47 +02:00 committed by GitHub
parent 0bbc9c7c49
commit 286bba1c70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 54 additions and 13 deletions

View File

@ -220,7 +220,9 @@ export class AppComponent implements OnDestroy {
this.authService.user.subscribe(userprofile => {
this.profile = userprofile;
const lang = userprofile.preferredLanguage.match(/en|de/) ? userprofile.preferredLanguage : 'en';
const cropped = navigator.language.split('-')[0] ?? 'en';
const fallbackLang = cropped.match(/en|de/) ? cropped : 'en';
const lang = userprofile.preferredLanguage.match(/en|de/) ? userprofile.preferredLanguage : fallbackLang;
this.translate.use(lang);
this.document.documentElement.lang = lang;
});

View File

@ -40,6 +40,7 @@ import { GrpcAuthService } from './services/grpc-auth.service';
import { GrpcService } from './services/grpc.service';
import { AuthInterceptor } from './services/interceptors/auth.interceptor';
import { GRPC_INTERCEPTORS } from './services/interceptors/grpc-interceptor';
import { I18nInterceptor } from './services/interceptors/i18n.interceptor';
import { OrgInterceptor } from './services/interceptors/org.interceptor';
import { RefreshService } from './services/refresh.service';
import { StatehandlerProcessorService, StatehandlerProcessorServiceImpl } from './services/statehandler-processor.service';
@ -156,6 +157,11 @@ const authConfig: AuthConfig = {
multi: true,
useClass: AuthInterceptor,
},
{
provide: GRPC_INTERCEPTORS,
multi: true,
useClass: I18nInterceptor,
},
{
provide: GRPC_INTERCEPTORS,
multi: true,

View File

@ -2,8 +2,10 @@ import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatChipsModule } from '@angular/material/chips';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { TranslateModule } from '@ngx-translate/core';
import { SearchUserAutocompleteModule } from 'src/app/modules/search-user-autocomplete/search-user-autocomplete.module';
@ -21,6 +23,8 @@ import { MemberCreateDialogComponent } from './member-create-dialog.component';
CommonModule,
MatDialogModule,
MatButtonModule,
MatChipsModule,
MatInputModule,
TranslateModule,
MatFormFieldModule,
MatSelectModule,

View File

@ -4,12 +4,12 @@
<button (click)="deactivateSelectedIdps()" matTooltip="{{'IDP.DEACTIVATE' | translate}}" class="icon-button"
mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT"
[disabled]="disabled">
<mat-icon svgIcon="mdi_account_cancel"></mat-icon>
<mat-icon>block</mat-icon>
</button>
<button (click)="reactivateSelectedIdps()" matTooltip="{{'IDP.ACTIVATE' | translate}}" class="icon-button"
mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT"
[disabled]="disabled">
<mat-icon svgIcon="mdi_account_check_outline"></mat-icon>
<mat-icon>play_circle_outline</mat-icon>
</button>
<button color="warn" (click)="removeSelectedIdps()" matTooltip="{{'IDP.DELETE' | translate}}"
class="icon-button" mat-icon-button

View File

@ -10,6 +10,7 @@ import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.
import { MembersTableModule } from 'src/app/modules/members-table/members-table.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
import { MemberCreateDialogModule } from '../add-member-dialog/member-create-dialog.module';
import { ProjectMembersRoutingModule } from './project-members-routing.module';
import { ProjectMembersComponent } from './project-members.component';
@ -27,6 +28,7 @@ import { ProjectMembersComponent } from './project-members.component';
MatDialogModule,
MembersTableModule,
HasRolePipeModule,
MemberCreateDialogModule,
],
})
export class ProjectMembersModule { }

View File

@ -5,6 +5,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/member-create-dialog.module';
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
import { MembersTableModule } from 'src/app/modules/members-table/members-table.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
@ -26,6 +27,7 @@ import { IamMembersComponent } from './iam-members.component';
TranslateModule,
MembersTableModule,
HasRolePipeModule,
MemberCreateDialogModule,
],
})
export class IamMembersModule { }

View File

@ -6,6 +6,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/member-create-dialog.module';
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
import { MembersTableModule } from 'src/app/modules/members-table/members-table.module';
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
@ -30,6 +31,7 @@ import { OrgMembersComponent } from './org-members.component';
RefreshTableModule,
MembersTableModule,
HasRolePipeModule,
MemberCreateDialogModule,
],
})
export class OrgMembersModule { }

View File

@ -47,7 +47,6 @@ import { PolicyGridComponent } from './policy-grid/policy-grid.component';
MetaLayoutModule,
MatTabsModule,
MatTooltipModule,
MatDialogModule,
WarnDialogModule,
MemberCreateDialogModule,
MatMenuModule,

View File

@ -67,7 +67,6 @@ export class ExternalIdpsComponent implements OnInit {
promise.then(resp => {
this.externalIdpResult = resp.toObject();
this.dataSource.data = this.externalIdpResult.resultList;
console.log(this.externalIdpResult.resultList);
this.loadingSubject.next(false);
}).catch((error: any) => {
this.toast.showError(error);

View File

@ -199,8 +199,6 @@ export class UserDetailComponent implements OnInit, OnDestroy {
confirmKey: 'ACTIONS.DELETE',
cancelKey: 'ACTIONS.CANCEL',
titleKey: 'USER.DIALOG.DELETE_TITLE',
descriptionParam: this.user.human ??
this.user.machine ? { displayName: this.user.machine?.name } : { displayName: '' },
descriptionKey: 'USER.DIALOG.DELETE_DESCRIPTION',
},
width: '400px',

View File

@ -126,7 +126,7 @@
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let user">
<button [disabled]="(['user.delete$', 'user.delete:'+user.id] | hasRole | async) == false"
color="warn" mat-icon-button matTooltip="{{'IAM.VIEWS.DELETE' | translate}}"
color="warn" mat-icon-button matTooltip="{{'USER.PAGES.DELETE' | translate}}"
(click)="deleteUser(user)">
<i class="las la-trash"></i>
</button>

View File

@ -8,6 +8,7 @@
td,
th {
padding: .5rem;
outline: none;
&:first-child {
padding-left: 0;
@ -27,8 +28,6 @@
}
tr {
outline: none;
button {
visibility: hidden;
}

View File

@ -152,7 +152,6 @@ export class UserTableComponent implements OnInit {
confirmKey: 'ACTIONS.DELETE',
cancelKey: 'ACTIONS.CANCEL',
titleKey: 'USER.DIALOG.DELETE_TITLE',
descriptionParam: user.human ?? user.machine ? { displayName: user.machine?.name } : { displayName: '' },
descriptionKey: 'USER.DIALOG.DELETE_DESCRIPTION',
},
width: '400px',

View File

@ -9,6 +9,7 @@ import { AuthServicePromiseClient } from '../proto/generated/auth_grpc_web_pb';
import { ManagementServicePromiseClient } from '../proto/generated/management_grpc_web_pb';
import { AuthenticationService } from './authentication.service';
import { AuthInterceptor } from './interceptors/auth.interceptor';
import { I18nInterceptor } from './interceptors/i18n.interceptor';
import { OrgInterceptor } from './interceptors/org.interceptor';
import { StorageService } from './storage.service';
@ -37,6 +38,7 @@ export class GrpcService {
unaryInterceptors: [
new OrgInterceptor(this.storageService),
new AuthInterceptor(this.authenticationService, this.storageService, this.dialog),
new I18nInterceptor(),
],
};

View File

@ -0,0 +1,27 @@
import { Injectable } from '@angular/core';
import { Request, UnaryInterceptor, UnaryResponse } from 'grpc-web';
const i18nHeader = 'Accept-Language';
@Injectable({ providedIn: 'root' })
/**
* Set the navigator language as header to all grpc requests
*/
export class I18nInterceptor<TReq = unknown, TResp = unknown> implements UnaryInterceptor<TReq, TResp> {
constructor() { }
public async intercept(request: Request<TReq, TResp>, invoker: any): Promise<UnaryResponse<TReq, TResp>> {
const metadata = request.getMetadata();
const navLang = navigator.language;
if (navLang) {
metadata[i18nHeader] = navLang;
}
return invoker(request).then((response: any) => {
return response;
}).catch((error: any) => {
return Promise.reject(error);
});
}
}

View File

@ -94,7 +94,7 @@
},
"DIALOG": {
"DELETE_TITLE":"User löschen",
"DELETE_DESCRIPTION":"Sie sind im Begriff den Benutzer {{displayName}} entgültig zu löschen. Wollen Sie dies wirklich tun?"
"DELETE_DESCRIPTION":"Sie sind im Begriff einen Benutzer endgültig zu löschen. Wollen Sie dies wirklich tun?"
},
"TABLE":{
"DEACTIVATE":"Deaktivieren",

View File

@ -94,7 +94,7 @@
},
"DIALOG": {
"DELETE_TITLE":"Delete User",
"DELETE_DESCRIPTION":"You are about to permanently delete the user {{displayName}}. Are you sure?"
"DELETE_DESCRIPTION":"You are about to permanently delete a user. Are you sure?"
},
"TABLE":{
"DEACTIVATE":"Deactivate",