add boundary help text to credential settings (#11757)

This commit is contained in:
✨ Audrey ✨ 2024-10-28 15:55:16 -04:00 committed by GitHub
parent b5e509409b
commit 9a83509183
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 76 additions and 2 deletions

View File

@ -2877,6 +2877,20 @@
"generateEmail": { "generateEmail": {
"message": "Generate email" "message": "Generate email"
}, },
"generatorBoundariesHint": {
"message": "Value must be between $MIN$ and $MAX$",
"description": "Explains spin box minimum and maximum values to the user",
"placeholders": {
"min": {
"content": "$1",
"example": "8"
},
"max": {
"content": "$2",
"example": "128"
}
}
},
"usernameType": { "usernameType": {
"message": "Username type" "message": "Username type"
}, },

View File

@ -2393,6 +2393,20 @@
"generateEmail": { "generateEmail": {
"message": "Generate email" "message": "Generate email"
}, },
"generatorBoundariesHint": {
"message": "Value must be between $MIN$ and $MAX$",
"description": "Explains spin box minimum and maximum values to the user",
"placeholders": {
"min": {
"content": "$1",
"example": "8"
},
"max": {
"content": "$2",
"example": "128"
}
}
},
"usernameType": { "usernameType": {
"message": "Username type" "message": "Username type"
}, },

View File

@ -6412,6 +6412,20 @@
"generateEmail": { "generateEmail": {
"message": "Generate email" "message": "Generate email"
}, },
"generatorBoundariesHint": {
"message": "Value must be between $MIN$ and $MAX$",
"description": "Explains spin box minimum and maximum values to the user",
"placeholders": {
"min": {
"content": "$1",
"example": "8"
},
"max": {
"content": "$2",
"example": "128"
}
}
},
"usernameType": { "usernameType": {
"message": "Username type" "message": "Username type"
}, },

View File

@ -8,6 +8,7 @@
<bit-form-field disableMargin> <bit-form-field disableMargin>
<bit-label>{{ "numWords" | i18n }}</bit-label> <bit-label>{{ "numWords" | i18n }}</bit-label>
<input bitInput formControlName="numWords" id="num-words" type="number" /> <input bitInput formControlName="numWords" id="num-words" type="number" />
<bit-hint>{{ numWordsBoundariesHint$ | async }}</bit-hint>
</bit-form-field> </bit-form-field>
</bit-card> </bit-card>
</div> </div>

View File

@ -1,9 +1,10 @@
import { coerceBooleanProperty } from "@angular/cdk/coercion"; import { coerceBooleanProperty } from "@angular/cdk/coercion";
import { OnInit, Input, Output, EventEmitter, Component, OnDestroy } from "@angular/core"; import { OnInit, Input, Output, EventEmitter, Component, OnDestroy } from "@angular/core";
import { FormBuilder } from "@angular/forms"; import { FormBuilder } from "@angular/forms";
import { BehaviorSubject, skip, takeUntil, Subject } from "rxjs"; import { BehaviorSubject, skip, takeUntil, Subject, ReplaySubject } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { UserId } from "@bitwarden/common/types/guid"; import { UserId } from "@bitwarden/common/types/guid";
import { import {
Generators, Generators,
@ -29,11 +30,13 @@ export class PassphraseSettingsComponent implements OnInit, OnDestroy {
/** Instantiates the component /** Instantiates the component
* @param accountService queries user availability * @param accountService queries user availability
* @param generatorService settings and policy logic * @param generatorService settings and policy logic
* @param i18nService localize hints
* @param formBuilder reactive form controls * @param formBuilder reactive form controls
*/ */
constructor( constructor(
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private generatorService: CredentialGeneratorService, private generatorService: CredentialGeneratorService,
private i18nService: I18nService,
private accountService: AccountService, private accountService: AccountService,
) {} ) {}
@ -97,6 +100,13 @@ export class PassphraseSettingsComponent implements OnInit, OnDestroy {
this.toggleEnabled(Controls.capitalize, !constraints.capitalize?.readonly); this.toggleEnabled(Controls.capitalize, !constraints.capitalize?.readonly);
this.toggleEnabled(Controls.includeNumber, !constraints.includeNumber?.readonly); this.toggleEnabled(Controls.includeNumber, !constraints.includeNumber?.readonly);
const boundariesHint = this.i18nService.t(
"generatorBoundariesHint",
constraints.numWords.min,
constraints.numWords.max,
);
this.numWordsBoundariesHint.next(boundariesHint);
}); });
// now that outputs are set up, connect inputs // now that outputs are set up, connect inputs
@ -106,6 +116,11 @@ export class PassphraseSettingsComponent implements OnInit, OnDestroy {
/** display binding for enterprise policy notice */ /** display binding for enterprise policy notice */
protected policyInEffect: boolean; protected policyInEffect: boolean;
private numWordsBoundariesHint = new ReplaySubject<string>(1);
/** display binding for min/max constraints of `numWords` */
protected numWordsBoundariesHint$ = this.numWordsBoundariesHint.asObservable();
private toggleEnabled(setting: keyof typeof Controls, enabled: boolean) { private toggleEnabled(setting: keyof typeof Controls, enabled: boolean) {
if (enabled) { if (enabled) {
this.settings.get(setting).enable({ emitEvent: false }); this.settings.get(setting).enable({ emitEvent: false });

View File

@ -8,6 +8,7 @@
<bit-form-field disableMargin> <bit-form-field disableMargin>
<bit-label>{{ "length" | i18n }}</bit-label> <bit-label>{{ "length" | i18n }}</bit-label>
<input bitInput formControlName="length" type="number" /> <input bitInput formControlName="length" type="number" />
<bit-hint>{{ lengthBoundariesHint$ | async }}</bit-hint>
</bit-form-field> </bit-form-field>
</bit-card> </bit-card>
</div> </div>

View File

@ -1,9 +1,10 @@
import { coerceBooleanProperty } from "@angular/cdk/coercion"; import { coerceBooleanProperty } from "@angular/cdk/coercion";
import { OnInit, Input, Output, EventEmitter, Component, OnDestroy } from "@angular/core"; import { OnInit, Input, Output, EventEmitter, Component, OnDestroy } from "@angular/core";
import { FormBuilder } from "@angular/forms"; import { FormBuilder } from "@angular/forms";
import { BehaviorSubject, takeUntil, Subject, map, filter, tap, skip } from "rxjs"; import { BehaviorSubject, takeUntil, Subject, map, filter, tap, skip, ReplaySubject } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { UserId } from "@bitwarden/common/types/guid"; import { UserId } from "@bitwarden/common/types/guid";
import { import {
Generators, Generators,
@ -33,11 +34,13 @@ export class PasswordSettingsComponent implements OnInit, OnDestroy {
/** Instantiates the component /** Instantiates the component
* @param accountService queries user availability * @param accountService queries user availability
* @param generatorService settings and policy logic * @param generatorService settings and policy logic
* @param i18nService localize hints
* @param formBuilder reactive form controls * @param formBuilder reactive form controls
*/ */
constructor( constructor(
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private generatorService: CredentialGeneratorService, private generatorService: CredentialGeneratorService,
private i18nService: I18nService,
private accountService: AccountService, private accountService: AccountService,
) {} ) {}
@ -147,6 +150,13 @@ export class PasswordSettingsComponent implements OnInit, OnDestroy {
for (const [control, enabled] of toggles) { for (const [control, enabled] of toggles) {
this.toggleEnabled(control, enabled); this.toggleEnabled(control, enabled);
} }
const boundariesHint = this.i18nService.t(
"generatorBoundariesHint",
constraints.length.min,
constraints.length.max,
);
this.lengthBoundariesHint.next(boundariesHint);
}); });
// cascade selections between checkboxes and spinboxes // cascade selections between checkboxes and spinboxes
@ -208,6 +218,11 @@ export class PasswordSettingsComponent implements OnInit, OnDestroy {
/** display binding for enterprise policy notice */ /** display binding for enterprise policy notice */
protected policyInEffect: boolean; protected policyInEffect: boolean;
private lengthBoundariesHint = new ReplaySubject<string>(1);
/** display binding for min/max constraints of `length` */
protected lengthBoundariesHint$ = this.lengthBoundariesHint.asObservable();
private toggleEnabled(setting: keyof typeof Controls, enabled: boolean) { private toggleEnabled(setting: keyof typeof Controls, enabled: boolean) {
if (enabled) { if (enabled) {
this.settings.get(setting).enable({ emitEvent: false }); this.settings.get(setting).enable({ emitEvent: false });