Skip to content

Commit e8cbcb0

Browse files
committed
[PM-18721] handle cross-component submit states
1 parent a425fb5 commit e8cbcb0

File tree

3 files changed

+21
-13
lines changed

3 files changed

+21
-13
lines changed

apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover-dialog.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
[flow]="inputPasswordFlow"
2424
[masterPasswordPolicyOptions]="masterPasswordPolicyOptions"
2525
(onPasswordFormSubmit)="handlePasswordFormSubmit($event)"
26+
(isSubmitting)="handleIsSubmittingChange($event)"
2627
></auth-input-password>
2728
}
2829
</div>

apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover-dialog.component.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { CommonModule } from "@angular/common";
22
import { Component, Inject, OnInit, ViewChild } from "@angular/core";
3-
import { BehaviorSubject, firstValueFrom } from "rxjs";
3+
import { BehaviorSubject, combineLatest, firstValueFrom, map } from "rxjs";
44

55
import {
66
InputPasswordComponent,
@@ -65,8 +65,15 @@ export class EmergencyAccessTakeoverDialogComponent implements OnInit {
6565
@ViewChild(InputPasswordComponent)
6666
inputPasswordComponent: InputPasswordComponent | undefined = undefined;
6767

68-
private submittingBehaviorSubject = new BehaviorSubject(false);
69-
submitting$ = this.submittingBehaviorSubject.asObservable();
68+
private parentSubmittingBehaviorSubject = new BehaviorSubject(false);
69+
parentSubmitting$ = this.parentSubmittingBehaviorSubject.asObservable();
70+
71+
private childSubmittingBehaviorSubject = new BehaviorSubject(false);
72+
childSubmitting$ = this.childSubmittingBehaviorSubject.asObservable();
73+
74+
submitting$ = combineLatest([this.parentSubmitting$, this.childSubmitting$]).pipe(
75+
map(([parentIsSubmitting, childIsSubmitting]) => parentIsSubmitting || childIsSubmitting),
76+
);
7077

7178
initializing = true;
7279
inputPasswordFlow = InputPasswordFlow.ChangePasswordDelegation;
@@ -105,7 +112,7 @@ export class EmergencyAccessTakeoverDialogComponent implements OnInit {
105112
};
106113

107114
protected async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
108-
this.submittingBehaviorSubject.next(true);
115+
this.parentSubmittingBehaviorSubject.next(true);
109116

110117
try {
111118
await this.emergencyAccessService.takeover(
@@ -122,12 +129,16 @@ export class EmergencyAccessTakeoverDialogComponent implements OnInit {
122129
message: this.i18nService.t("unexpectedError"),
123130
});
124131
} finally {
125-
this.submittingBehaviorSubject.next(false);
132+
this.parentSubmittingBehaviorSubject.next(false);
126133
}
127134

128135
this.dialogRef.close(EmergencyAccessTakeoverDialogResultTypes.Done);
129136
}
130137

138+
protected handleIsSubmittingChange(isSubmitting: boolean) {
139+
this.childSubmittingBehaviorSubject.next(isSubmitting);
140+
}
141+
131142
/**
132143
* Strongly typed helper to open an EmergencyAccessTakeoverDialogComponent
133144
* @param dialogService Instance of the dialog service that will be used to open the dialog

libs/auth/src/angular/input-password/input-password.component.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core";
22
import { ReactiveFormsModule, FormBuilder, Validators, FormControl } from "@angular/forms";
3-
import { BehaviorSubject, firstValueFrom } from "rxjs";
3+
import { firstValueFrom } from "rxjs";
44

55
import { JslibModule } from "@bitwarden/angular/jslib.module";
66
import {
@@ -117,15 +117,13 @@ interface InputPasswordForm {
117117
],
118118
})
119119
export class InputPasswordComponent implements OnInit {
120-
private submittingBehaviorSubject = new BehaviorSubject(false);
121-
submitting$ = this.submittingBehaviorSubject.asObservable();
122-
123120
@ViewChild(PasswordStrengthV2Component) passwordStrengthComponent:
124121
| PasswordStrengthV2Component
125122
| undefined = undefined;
126123

127124
@Output() onPasswordFormSubmit = new EventEmitter<PasswordInputResult>();
128125
@Output() onSecondaryButtonClick = new EventEmitter<void>();
126+
@Output() isSubmitting = new EventEmitter<boolean>();
129127

130128
@Input({ required: true }) flow!: InputPasswordFlow;
131129

@@ -267,15 +265,14 @@ export class InputPasswordComponent implements OnInit {
267265

268266
submit = async () => {
269267
try {
270-
this.submittingBehaviorSubject.next(true);
268+
this.isSubmitting.emit(true);
271269

272270
this.verifyFlow();
273271

274272
this.formGroup.markAllAsTouched();
275273

276274
if (this.formGroup.invalid) {
277275
this.showErrorSummary = true;
278-
this.submittingBehaviorSubject.next(false);
279276
return;
280277
}
281278

@@ -396,7 +393,7 @@ export class InputPasswordComponent implements OnInit {
396393
} catch (e) {
397394
this.validationService.showError(e);
398395
} finally {
399-
this.submittingBehaviorSubject.next(false);
396+
this.isSubmitting.emit(false);
400397
}
401398
};
402399

@@ -453,7 +450,6 @@ export class InputPasswordComponent implements OnInit {
453450
false,
454451
);
455452
if (!newPasswordVerified) {
456-
this.submittingBehaviorSubject.next(false);
457453
return;
458454
}
459455

0 commit comments

Comments
 (0)