mirror of
https://github.com/bitwarden/browser
synced 2026-02-07 04:03:29 +00:00
[PM-18721] handle cross-component async actions
This commit is contained in:
@@ -28,7 +28,13 @@
|
||||
</div>
|
||||
|
||||
<ng-container bitDialogFooter>
|
||||
<button type="button" bitButton buttonType="primary" (click)="handlePrimaryButtonClick()">
|
||||
<button
|
||||
type="button"
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
[disabled]="submitting$ | async"
|
||||
(click)="handlePrimaryButtonClick()"
|
||||
>
|
||||
{{ "save" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitButton buttonType="secondary" bitDialogClose>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, Inject, OnInit, ViewChild } from "@angular/core";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { AfterViewInit, Component, Inject, OnInit, ViewChild } from "@angular/core";
|
||||
import { BehaviorSubject, combineLatest, map } from "rxjs";
|
||||
|
||||
import {
|
||||
InputPasswordComponent,
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import {
|
||||
@@ -61,10 +60,13 @@ type EmergencyAccessTakeoverDialogResultType =
|
||||
InputPasswordComponent,
|
||||
],
|
||||
})
|
||||
export class EmergencyAccessTakeoverDialogComponent implements OnInit {
|
||||
export class EmergencyAccessTakeoverDialogComponent implements OnInit, AfterViewInit {
|
||||
@ViewChild(InputPasswordComponent)
|
||||
inputPasswordComponent!: InputPasswordComponent;
|
||||
|
||||
private submittingBehaviorSubject = new BehaviorSubject(false);
|
||||
submitting$ = this.submittingBehaviorSubject.asObservable();
|
||||
|
||||
initializing = true;
|
||||
inputPasswordFlow = InputPasswordFlow.ChangePasswordDelegation;
|
||||
masterPasswordPolicyOptions?: MasterPasswordPolicyOptions;
|
||||
@@ -93,11 +95,25 @@ export class EmergencyAccessTakeoverDialogComponent implements OnInit {
|
||||
this.initializing = false;
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.submitting$ = combineLatest([
|
||||
this.submittingBehaviorSubject.asObservable(),
|
||||
this.inputPasswordComponent.submitting$,
|
||||
]).pipe(
|
||||
map(
|
||||
([dialogCompIsSubmitting, inputPasswordCompIsSubmitting]) =>
|
||||
dialogCompIsSubmitting || inputPasswordCompIsSubmitting,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected handlePrimaryButtonClick = async () => {
|
||||
await this.inputPasswordComponent.submit();
|
||||
};
|
||||
|
||||
protected async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
|
||||
this.submittingBehaviorSubject.next(true);
|
||||
|
||||
try {
|
||||
await this.emergencyAccessService.takeover(
|
||||
this.dialogData.emergencyAccessId,
|
||||
@@ -112,6 +128,8 @@ export class EmergencyAccessTakeoverDialogComponent implements OnInit {
|
||||
title: this.i18nService.t("errorOccurred"),
|
||||
message: this.i18nService.t("unexpectedError"),
|
||||
});
|
||||
} finally {
|
||||
this.submittingBehaviorSubject.next(false);
|
||||
}
|
||||
|
||||
this.dialogRef.close(EmergencyAccessTakeoverDialogResultTypes.Done);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core";
|
||||
import { ReactiveFormsModule, FormBuilder, Validators, FormControl } from "@angular/forms";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { BehaviorSubject, firstValueFrom } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import {
|
||||
@@ -116,6 +116,9 @@ interface InputPasswordForm {
|
||||
],
|
||||
})
|
||||
export class InputPasswordComponent implements OnInit {
|
||||
private submittingBehaviorSubject = new BehaviorSubject(false);
|
||||
submitting$ = this.submittingBehaviorSubject.asObservable();
|
||||
|
||||
@ViewChild(PasswordStrengthV2Component) passwordStrengthComponent!: PasswordStrengthV2Component;
|
||||
|
||||
@Output() onPasswordFormSubmit = new EventEmitter<PasswordInputResult>();
|
||||
@@ -258,12 +261,15 @@ export class InputPasswordComponent implements OnInit {
|
||||
}
|
||||
|
||||
submit = async () => {
|
||||
this.submittingBehaviorSubject.next(true);
|
||||
|
||||
this.verifyFlow();
|
||||
|
||||
this.formGroup.markAllAsTouched();
|
||||
|
||||
if (this.formGroup.invalid) {
|
||||
this.showErrorSummary = true;
|
||||
this.submittingBehaviorSubject.next(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -274,6 +280,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
|
||||
if (this.flow === InputPasswordFlow.ChangePasswordDelegation) {
|
||||
await this.handleChangePasswordDelegationFlow(newPassword);
|
||||
this.submittingBehaviorSubject.next(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -305,6 +312,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
this.kdfConfig,
|
||||
);
|
||||
if (!currentPasswordVerified) {
|
||||
this.submittingBehaviorSubject.next(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -316,6 +324,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
checkForBreaches,
|
||||
);
|
||||
if (!newPasswordVerified) {
|
||||
this.submittingBehaviorSubject.next(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -381,6 +390,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
|
||||
// 5. Emit cryptographic keys and other password related properties
|
||||
this.onPasswordFormSubmit.emit(passwordInputResult);
|
||||
this.submittingBehaviorSubject.next(false);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -436,6 +446,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
false,
|
||||
);
|
||||
if (!newPasswordVerified) {
|
||||
this.submittingBehaviorSubject.next(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user