diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index ce73bd99d36..0c25288fb9a 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1397,14 +1397,14 @@ }, "useAnotherTwoStepMethod": { "message": "Use another two-step login method" - }, + }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" }, "useYourRecoveryCode": { "message": "Use your recovery code" - }, + }, "insertYubiKey": { "message": "Insert your YubiKey into your computer's USB port, then touch its button." }, @@ -2446,8 +2446,17 @@ "atRiskPasswords": { "message": "At-risk passwords" }, - "atRiskPasswordsDescSingleOrg": { - "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at risk.", + "atRiskPasswordDescSingleOrg": { + "message": "$ORGANIZATION$ is requesting you change one password because it is at-risk.", + "placeholders": { + "organization": { + "content": "$1", + "example": "Acme Corp" + } + } + }, + "atRiskPasswordsDescSingleOrgPlural": { + "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at-risk.", "placeholders": { "organization": { "content": "$1", @@ -2459,8 +2468,8 @@ } } }, - "atRiskPasswordsDescMultiOrg": { - "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at risk.", + "atRiskPasswordsDescMultiOrgPlural": { + "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at-risk.", "placeholders": { "count": { "content": "$1", diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html index 044848eec8c..cd93401c861 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html @@ -6,7 +6,7 @@ {{ "turnOnAutofill" | i18n }} diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts index c719618b33a..3bf786ad5b7 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts @@ -198,8 +198,27 @@ describe("AtRiskPasswordsComponent", () => { describe("pageDescription$", () => { it("should use single org description when tasks belong to one org", async () => { - const description = await firstValueFrom(component["pageDescription$"]); - expect(description).toBe("atRiskPasswordsDescSingleOrg"); + // Single task + let description = await firstValueFrom(component["pageDescription$"]); + expect(description).toBe("atRiskPasswordDescSingleOrg"); + + // Multiple tasks + mockTasks$.next([ + { + id: "task", + organizationId: "org", + cipherId: "cipher", + type: SecurityTaskType.UpdateAtRiskCredential, + } as SecurityTask, + { + id: "task2", + organizationId: "org", + cipherId: "cipher2", + type: SecurityTaskType.UpdateAtRiskCredential, + } as SecurityTask, + ]); + description = await firstValueFrom(component["pageDescription$"]); + expect(description).toBe("atRiskPasswordsDescSingleOrgPlural"); }); it("should use multiple org description when tasks belong to multiple orgs", async () => { @@ -218,7 +237,7 @@ describe("AtRiskPasswordsComponent", () => { } as SecurityTask, ]); const description = await firstValueFrom(component["pageDescription$"]); - expect(description).toBe("atRiskPasswordsDescMultiOrg"); + expect(description).toBe("atRiskPasswordsDescMultiOrgPlural"); }); }); diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts index 471bdfeed19..dd3d53fed7d 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts @@ -115,14 +115,23 @@ export class AtRiskPasswordsComponent implements OnInit { startWith(true), ); - protected calloutDismissed$ = this.activeUserData$.pipe( + private calloutDismissed$ = this.activeUserData$.pipe( switchMap(({ userId }) => this.atRiskPasswordPageService.isCalloutDismissed(userId)), ); - - protected inlineAutofillSettingEnabled$ = this.autofillSettingsService.inlineMenuVisibility$.pipe( + private inlineAutofillSettingEnabled$ = this.autofillSettingsService.inlineMenuVisibility$.pipe( map((setting) => setting !== AutofillOverlayVisibility.Off), ); + protected showAutofillCallout$ = combineLatest([ + this.calloutDismissed$, + this.inlineAutofillSettingEnabled$, + ]).pipe( + map(([calloutDismissed, inlineAutofillSettingEnabled]) => { + return !calloutDismissed && !inlineAutofillSettingEnabled; + }), + startWith(false), + ); + protected atRiskItems$ = this.activeUserData$.pipe( map(({ tasks, ciphers }) => tasks @@ -143,11 +152,19 @@ export class AtRiskPasswordsComponent implements OnInit { const [orgId] = orgIds; return this.organizationService.organizations$(userId).pipe( getOrganizationById(orgId), - map((org) => this.i18nService.t("atRiskPasswordsDescSingleOrg", org?.name, tasks.length)), + map((org) => + this.i18nService.t( + tasks.length === 1 + ? "atRiskPasswordDescSingleOrg" + : "atRiskPasswordsDescSingleOrgPlural", + org?.name, + tasks.length, + ), + ), ); } - return of(this.i18nService.t("atRiskPasswordsDescMultiOrg", tasks.length)); + return of(this.i18nService.t("atRiskPasswordsDescMultiOrgPlural", tasks.length)); }), );