1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-18463] [PM-18465] At-risk Password Page Fixes (#13573)

* [PM-18463] Add hyphen and fix description pluralization

* [PM-18463] Add spacing between buttons

* [PM-18463] Ensure callout does not flash
This commit is contained in:
Shane Melton
2025-02-26 13:45:57 -08:00
committed by GitHub
parent b9ebf0704a
commit 16ffedc06b
4 changed files with 61 additions and 15 deletions

View File

@@ -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",

View File

@@ -6,7 +6,7 @@
</popup-header>
<bit-callout
*ngIf="!(inlineAutofillSettingEnabled$ | async) && !(calloutDismissed$ | async)"
*ngIf="showAutofillCallout$ | async"
type="info"
[title]="'changeAtRiskPasswordsFaster' | i18n"
data-testid="autofill-callout"
@@ -18,6 +18,7 @@
buttonType="primary"
(click)="activateInlineAutofillMenuVisibility()"
data-testid="turn-on-autofill-button"
class="tw-mr-2"
>
{{ "turnOnAutofill" | i18n }}
</button>

View File

@@ -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");
});
});

View File

@@ -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));
}),
);