mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-04 21:32:15 +00:00
* feat: return 404 or 409 if org reg disallowed * fix: system limit permissions * feat: add iam limits api * feat: disallow public org registrations on default instance * add integration test * test: integration * fix test * docs: describe public org registrations * avoid updating docs deps * fix system limits integration test * silence integration tests * fix linting * ignore strange linter complaints * review * improve reset properties naming * redefine the api * use restrictions aggregate * test query * simplify and test projection * test commands * fix unit tests * move integration test * support restrictions on default instance * also test GetRestrictions * self review * lint * abstract away resource owner * fix tests * configure supported languages * fix allowed languages * fix tests * default lang must not be restricted * preferred language must be allowed * change preferred languages * check languages everywhere * lint * test command side * lint * add integration test * add integration test * restrict supported ui locales * lint * lint * cleanup * lint * allow undefined preferred language * fix integration tests * update main * fix env var * ignore linter * ignore linter * improve integration test config * reduce cognitive complexity * compile * fix(console): switch back to saved language * feat(API): get allowed languages * fix(console): only make allowed languages selectable * warn when editing not allowed languages * feat: manage restrictions in console * check for duplicates * remove useless restriction checks * review * revert restriction renaming * manage languages * fix language restrictions * lint * generate * allow custom texts for supported langs for now * fix tests * cleanup * cleanup * cleanup * lint * unsupported preferred lang is allowed * fix integration test * allow unsupported preferred languages * lint * fix languages lists * simplify default language selection * translate * discard * lint * load languages for tests * load languages * lint * cleanup * lint * cleanup * get allowed only on admin * cleanup * reduce flakiness on very limited postgres * simplify langSvc * refactor according to suggestions in pr * lint * improve ux * update central allowed languages * set first allowed language as default * readd lost translations * disable sorting disallowed languages * fix permissions * lint * selectionchange for language in msg texts * initialize login texts * init message texts * lint * fix drag and drop list styles * start from 1 * cleanup * prettier * correct orgdefaultlabel * unsubscribe * lint * docs: describe language settings --------- Co-authored-by: peintnermax <[email protected]>
117 lines
4.1 KiB
TypeScript
117 lines
4.1 KiB
TypeScript
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
|
import { AdminService } from 'src/app/services/admin.service';
|
|
import { ToastService } from 'src/app/services/toast.service';
|
|
import { UntypedFormBuilder } from '@angular/forms';
|
|
import { LanguagesService } from '../../../services/languages.service';
|
|
import { BehaviorSubject, concat, forkJoin, from, Observable, of, Subject, switchMap, take, takeUntil } from 'rxjs';
|
|
import { GrpcAuthService } from '../../../services/grpc-auth.service';
|
|
import { CdkDrag, CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
|
|
import { catchError, map } from 'rxjs/operators';
|
|
|
|
interface State {
|
|
allowed: string[];
|
|
notAllowed: string[];
|
|
}
|
|
|
|
@Component({
|
|
selector: 'cnsl-language-settings',
|
|
templateUrl: './language-settings.component.html',
|
|
styleUrls: ['./language-settings.component.scss'],
|
|
})
|
|
export class LanguageSettingsComponent {
|
|
public canWriteRestrictions$: Observable<boolean> = this.authService.isAllowed(['iam.restrictions.write']);
|
|
public canWriteDefaultLanguage$: Observable<boolean> = this.authService.isAllowed(['iam.write']);
|
|
|
|
public localState$ = new BehaviorSubject<State>({ allowed: [], notAllowed: [] });
|
|
public remoteState$ = new BehaviorSubject<State>({ allowed: [], notAllowed: [] });
|
|
public defaultLang$ = new BehaviorSubject<string>('');
|
|
|
|
public loading: boolean = false;
|
|
constructor(
|
|
private service: AdminService,
|
|
private toast: ToastService,
|
|
private langSvc: LanguagesService,
|
|
private authService: GrpcAuthService,
|
|
) {
|
|
const sub = forkJoin([
|
|
langSvc.allowed$.pipe(take(1)),
|
|
langSvc.notAllowed$.pipe(take(1)),
|
|
from(this.service.getDefaultLanguage()).pipe(take(1)),
|
|
]).subscribe({
|
|
next: ([allowed, notAllowed, { language: defaultLang }]) => {
|
|
this.defaultLang$.next(defaultLang);
|
|
this.remoteState$.next({ notAllowed: [...notAllowed], ...{ allowed: [...allowed] } });
|
|
this.localState$.next({ notAllowed: [...notAllowed], ...{ allowed: [...allowed] } });
|
|
},
|
|
error: this.toast.showError,
|
|
complete: () => {
|
|
sub.unsubscribe();
|
|
},
|
|
});
|
|
}
|
|
|
|
drop(event: CdkDragDrop<string[]>) {
|
|
if (event.previousContainer === event.container) {
|
|
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
|
|
} else {
|
|
transferArrayItem(event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex);
|
|
}
|
|
}
|
|
|
|
public defaultLangPredicate = (lang: CdkDrag<string>) => {
|
|
return !!lang?.data && lang.data !== this.defaultLang$.value;
|
|
};
|
|
|
|
public isRemotelyAllowed$(lang: string): Observable<boolean> {
|
|
return this.remoteState$.pipe(map(({ allowed }) => allowed.includes(lang)));
|
|
}
|
|
|
|
public allowAll(): void {
|
|
this.localState$.next({ allowed: [...this.allLocalLangs()], notAllowed: [] });
|
|
}
|
|
|
|
public disallowAll(): void {
|
|
const disallowed = this.allLocalLangs().filter((lang) => lang !== this.defaultLang$.value);
|
|
this.localState$.next({ allowed: [this.defaultLang$.value], notAllowed: disallowed });
|
|
}
|
|
|
|
public submit(): void {
|
|
const { allowed, notAllowed } = this.localState$.value;
|
|
const sub = from(this.service.setRestrictions(undefined, allowed)).subscribe({
|
|
next: () => {
|
|
this.remoteState$.next({
|
|
allowed: [...allowed],
|
|
notAllowed: [...notAllowed],
|
|
});
|
|
this.langSvc.newAllowed(allowed);
|
|
this.toast.showInfo('SETTING.LANGUAGES.ALLOWED_SAVED', true);
|
|
},
|
|
error: this.toast.showError,
|
|
complete: () => {
|
|
sub.unsubscribe();
|
|
},
|
|
});
|
|
}
|
|
|
|
public discard(): void {
|
|
this.localState$.next(this.remoteState$.value);
|
|
}
|
|
|
|
public setDefaultLang(lang: string): void {
|
|
const sub = from(this.service.setDefaultLanguage(lang)).subscribe({
|
|
next: () => {
|
|
this.defaultLang$.next(lang);
|
|
this.toast.showInfo('SETTING.LANGUAGES.DEFAULT_SAVED', true);
|
|
},
|
|
error: this.toast.showError,
|
|
complete: () => {
|
|
sub.unsubscribe();
|
|
},
|
|
});
|
|
}
|
|
|
|
private allLocalLangs(): string[] {
|
|
return [...this.localState$.value.allowed, ...this.localState$.value.notAllowed];
|
|
}
|
|
}
|