1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-22 07:50:04 +02:00

fix username options and service box display crosstalk

This commit is contained in:
✨ Audrey ✨ 2024-10-17 16:13:55 -04:00
parent 0cb3e809dd
commit e496798867
No known key found for this signature in database
GPG Key ID: 0CF8B4C0D9088B97
3 changed files with 31 additions and 18 deletions

View File

@ -32,13 +32,13 @@
</bit-card> </bit-card>
<tools-password-settings <tools-password-settings
class="tw-mt-6" class="tw-mt-6"
*ngIf="(algorithm$ | async)?.id === 'password'" *ngIf="(showAlgorithm$ | async)?.id === 'password'"
[userId]="userId$ | async" [userId]="userId$ | async"
(onUpdated)="generate$.next()" (onUpdated)="generate$.next()"
/> />
<tools-passphrase-settings <tools-passphrase-settings
class="tw-mt-6" class="tw-mt-6"
*ngIf="(algorithm$ | async)?.id === 'passphrase'" *ngIf="(showAlgorithm$ | async)?.id === 'passphrase'"
[userId]="userId$ | async" [userId]="userId$ | async"
(onUpdated)="generate$.next()" (onUpdated)="generate$.next()"
/> />
@ -57,29 +57,29 @@
}}</bit-hint> }}</bit-hint>
</bit-form-field> </bit-form-field>
</form> </form>
<form *ngIf="!!(showForwarder$ | async)" [formGroup]="forwarder" class="box tw-container"> <form *ngIf="showForwarder$ | async" [formGroup]="forwarder" class="box tw-container">
<bit-form-field> <bit-form-field>
<bit-label>{{ "service" | i18n }}</bit-label> <bit-label>{{ "service" | i18n }}</bit-label>
<bit-select [items]="forwarderOptions$ | async" formControlName="nav"> </bit-select> <bit-select [items]="forwarderOptions$ | async" formControlName="nav"> </bit-select>
</bit-form-field> </bit-form-field>
</form> </form>
<tools-catchall-settings <tools-catchall-settings
*ngIf="(algorithm$ | async)?.id === 'catchall'" *ngIf="(showAlgorithm$ | async)?.id === 'catchall'"
[userId]="userId$ | async" [userId]="userId$ | async"
(onUpdated)="generate$.next()" (onUpdated)="generate$.next()"
/> />
<tools-forwarder-settings <tools-forwarder-settings
*ngIf="!!(showForwarder$ | async)" *ngIf="!!(forwarderId$ | async)"
[forwarder]="forwarderId$ | async" [forwarder]="forwarderId$ | async"
[userId]="this.userId$ | async" [userId]="this.userId$ | async"
/> />
<tools-subaddress-settings <tools-subaddress-settings
*ngIf="(algorithm$ | async)?.id === 'subaddress'" *ngIf="(showAlgorithm$ | async)?.id === 'subaddress'"
[userId]="userId$ | async" [userId]="userId$ | async"
(onUpdated)="generate$.next()" (onUpdated)="generate$.next()"
/> />
<tools-username-settings <tools-username-settings
*ngIf="(algorithm$ | async)?.id === 'username'" *ngIf="(showAlgorithm$ | async)?.id === 'username'"
[userId]="userId$ | async" [userId]="userId$ | async"
(onUpdated)="generate$.next()" (onUpdated)="generate$.next()"
/> />

View File

@ -2,13 +2,13 @@ import { Component, EventEmitter, Input, NgZone, OnDestroy, OnInit, Output } fro
import { FormBuilder } from "@angular/forms"; import { FormBuilder } from "@angular/forms";
import { import {
BehaviorSubject, BehaviorSubject,
combineLatestWith,
concat, concat,
distinctUntilChanged, distinctUntilChanged,
filter, filter,
map, map,
of, of,
ReplaySubject, ReplaySubject,
startWith,
Subject, Subject,
switchMap, switchMap,
takeUntil, takeUntil,
@ -50,8 +50,6 @@ type UsernameNavValue = UsernameAlgorithm | EmailAlgorithm | typeof FORWARDER;
const NONE_SELECTED = "none"; const NONE_SELECTED = "none";
type ForwarderNavValue = ForwarderIntegration | typeof NONE_SELECTED; type ForwarderNavValue = ForwarderIntegration | typeof NONE_SELECTED;
const FORWARDER_INITIALIZED = new GeneratedCredential("-", null, Date.now());
@Component({ @Component({
selector: "tools-credential-generator", selector: "tools-credential-generator",
templateUrl: "credential-generator.component.html", templateUrl: "credential-generator.component.html",
@ -184,8 +182,7 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
}); });
}); });
// assume the last-visible generator algorithm is the user's preferred one const username$ = new Subject<{ nav: UsernameNavValue }>();
const preferences = await this.generatorService.preferences({ singleUserId$: this.userId$ });
this.root$ this.root$
.pipe( .pipe(
filter(({ nav }) => !!nav), filter(({ nav }) => !!nav),
@ -196,6 +193,14 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
return of(maybeAlgorithm as { nav: CredentialAlgorithm }); return of(maybeAlgorithm as { nav: CredentialAlgorithm });
} }
}), }),
takeUntil(this.destroyed),
)
.subscribe(username$);
// assume the last-visible generator algorithm is the user's preferred one
const preferences = await this.generatorService.preferences({ singleUserId$: this.userId$ });
username$
.pipe(
switchMap((maybeAlgorithm) => { switchMap((maybeAlgorithm) => {
if (maybeAlgorithm.nav === FORWARDER) { if (maybeAlgorithm.nav === FORWARDER) {
return concat(of(this.forwarder.value), this.forwarder.valueChanges); return concat(of(this.forwarder.value), this.forwarder.valueChanges);
@ -229,19 +234,23 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
} else if (isPasswordAlgorithm(algorithm)) { } else if (isPasswordAlgorithm(algorithm)) {
setPreference("password"); setPreference("password");
} else { } else {
this.showForwarder$.next(false);
return; return;
} }
preferences.next(preference); preferences.next(preference);
}); });
this.username.valueChanges username$
.pipe( .pipe(
map(({ nav }) => nav === FORWARDER), map(({ nav }) => nav === FORWARDER),
takeUntil(this.destroyed), takeUntil(this.destroyed),
) )
.subscribe(this.showForwarder$); .subscribe((showForwarder) => {
if (showForwarder) {
this.value$.next("-");
}
this.showForwarder$.next(showForwarder);
});
// populate the form with the user's preferences to kick off interactivity // populate the form with the user's preferences to kick off interactivity
preferences.pipe(takeUntil(this.destroyed)).subscribe(({ email, username, password }) => { preferences.pipe(takeUntil(this.destroyed)).subscribe(({ email, username, password }) => {
@ -317,8 +326,7 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
const forwarder = getForwarderConfiguration(type.forwarder); const forwarder = getForwarderConfiguration(type.forwarder);
const configuration = toCredentialGeneratorConfiguration(forwarder); const configuration = toCredentialGeneratorConfiguration(forwarder);
const generator = this.generatorService.generate$(configuration, dependencies); const generator = this.generatorService.generate$(configuration, dependencies);
return generator;
return generator.pipe(startWith(FORWARDER_INITIALIZED));
} }
throw new Error(`Invalid generator type: "${type}"`); throw new Error(`Invalid generator type: "${type}"`);
@ -342,6 +350,11 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
/** tracks the currently selected credential type */ /** tracks the currently selected credential type */
protected algorithm$ = new ReplaySubject<AlgorithmInfo>(1); protected algorithm$ = new ReplaySubject<AlgorithmInfo>(1);
protected showAlgorithm$ = this.algorithm$.pipe(
combineLatestWith(this.showForwarder$),
map(([algorithm, showForwarder]) => (showForwarder ? null : algorithm)),
);
/** Emits hint key for the currently selected credential type */ /** Emits hint key for the currently selected credential type */
protected credentialTypeHint$ = new ReplaySubject<string>(1); protected credentialTypeHint$ = new ReplaySubject<string>(1);

View File

@ -30,7 +30,7 @@ const integrations = new Map(Object.values(Integrations).map((i) => [i.id, i]));
export function getForwarderConfiguration(id: IntegrationId): ForwarderConfiguration<ApiSettings> { export function getForwarderConfiguration(id: IntegrationId): ForwarderConfiguration<ApiSettings> {
const maybeForwarder = integrations.get(id); const maybeForwarder = integrations.get(id);
if ("forwarder" in maybeForwarder) { if (maybeForwarder && "forwarder" in maybeForwarder) {
return maybeForwarder as ForwarderConfiguration<ApiSettings>; return maybeForwarder as ForwarderConfiguration<ApiSettings>;
} else { } else {
return null; return null;