diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 8cbbf48e27..5ce5831e2e 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2949,6 +2949,18 @@ } } }, + "singleFieldNeedsAttention": { + "message": "1 field needs your attention." + }, + "multipleFieldsNeedAttention": { + "message": "$COUNT$ fields need your attention.", + "placeholders": { + "count": { + "content": "$1", + "example": "2" + } + } + }, "selectPlaceholder": { "message": "-- Select --" }, diff --git a/libs/vault/src/cipher-form/components/cipher-form.component.ts b/libs/vault/src/cipher-form/components/cipher-form.component.ts index d7f96d19c5..534b08ad43 100644 --- a/libs/vault/src/cipher-form/components/cipher-form.component.ts +++ b/libs/vault/src/cipher-form/components/cipher-form.component.ts @@ -13,7 +13,7 @@ import { ViewChild, } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { FormBuilder, ReactiveFormsModule } from "@angular/forms"; +import { FormBuilder, FormGroup, ReactiveFormsModule } from "@angular/forms"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { CipherType, SecureNoteType } from "@bitwarden/common/vault/enums"; @@ -213,9 +213,35 @@ export class CipherFormComponent implements AfterViewInit, OnInit, OnChanges, Ci private i18nService: I18nService, ) {} + /** + * Counts the number of invalid fields in a form group. + * @param formGroup - The form group to count the invalid fields in. + * @returns The number of invalid fields in the form group. + */ + private countInvalidFields(formGroup: FormGroup): number { + return Object.values(formGroup.controls).reduce((count, control) => { + if (control instanceof FormGroup) { + return count + this.countInvalidFields(control); + } + return count + (control.invalid ? 1 : 0); + }, 0); + } + submit = async () => { if (this.cipherForm.invalid) { this.cipherForm.markAllAsTouched(); + + const invalidFieldsCount = this.countInvalidFields(this.cipherForm); + if (invalidFieldsCount > 0) { + this.toastService.showToast({ + variant: "error", + title: null, + message: + invalidFieldsCount === 1 + ? this.i18nService.t("singleFieldNeedsAttention") + : this.i18nService.t("multipleFieldsNeedAttention", invalidFieldsCount), + }); + } return; }