1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 06:13:38 +00:00
Files
browser/libs/vault/src/cipher-view/custom-fields/custom-fields-v2.component.ts
Daniel James Smith 574891d617 [PM-16132][16249] Custom hidden field missing color and character count toggle (#13402)
* Add colored characters to custom hidden field

* Add character count toggle to hidden field

* Check correct variable for revealed hidden field

* Merge branch 'main' into vault/pm-16132/custom-hidden-field-missing-color-and-character-count-toggle

* Toggle character count on per field basis

---------

Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
Co-authored-by: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com>
Co-authored-by: Leslie Tilton <23057410+Banrion@users.noreply.github.com>
2025-05-07 09:53:57 -05:00

127 lines
3.7 KiB
TypeScript

// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { CommonModule } from "@angular/common";
import { Component, Input, OnInit } from "@angular/core";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
import { EventType } from "@bitwarden/common/enums";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { CipherType, FieldType, LinkedIdType } from "@bitwarden/common/vault/enums";
import { CardView } from "@bitwarden/common/vault/models/view/card.view";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view";
import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
import {
CardComponent,
IconButtonModule,
FormFieldModule,
InputModule,
SectionComponent,
SectionHeaderComponent,
TypographyModule,
CheckboxModule,
ColorPasswordModule,
} from "@bitwarden/components";
import { VaultAutosizeReadOnlyTextArea } from "../../directives/readonly-textarea.directive";
@Component({
selector: "app-custom-fields-v2",
templateUrl: "custom-fields-v2.component.html",
standalone: true,
imports: [
CommonModule,
JslibModule,
CardComponent,
IconButtonModule,
FormFieldModule,
InputModule,
SectionComponent,
SectionHeaderComponent,
TypographyModule,
CheckboxModule,
ColorPasswordModule,
VaultAutosizeReadOnlyTextArea,
],
})
export class CustomFieldV2Component implements OnInit {
@Input() cipher: CipherView;
fieldType = FieldType;
fieldOptions: any;
/** Indexes of hidden fields that are revealed */
revealedHiddenFields: number[] = [];
/**
* Indicates whether the hidden field's character count should be shown
*/
showHiddenValueCountFields: number[] = [];
constructor(
private i18nService: I18nService,
private eventCollectionService: EventCollectionService,
) {}
ngOnInit(): void {
this.fieldOptions = this.getLinkedFieldsOptionsForCipher();
}
getLinkedType(linkedId: LinkedIdType) {
const linkedType = this.fieldOptions.get(linkedId);
return this.i18nService.t(linkedType.i18nKey);
}
get canViewPassword() {
return this.cipher.viewPassword;
}
toggleCharacterCount(index: number) {
const fieldIndex = this.showHiddenValueCountFields.indexOf(index);
if (fieldIndex > -1) {
this.showHiddenValueCountFields.splice(fieldIndex, 1);
} else {
this.showHiddenValueCountFields.push(index);
}
}
async toggleHiddenField(hiddenFieldVisible: boolean, index: number) {
if (hiddenFieldVisible) {
this.revealedHiddenFields.push(index);
} else {
this.revealedHiddenFields = this.revealedHiddenFields.filter((i) => i !== index);
}
if (hiddenFieldVisible) {
await this.eventCollectionService.collect(
EventType.Cipher_ClientToggledHiddenFieldVisible,
this.cipher.id,
false,
this.cipher.organizationId,
);
}
}
async logCopyEvent() {
await this.eventCollectionService.collect(
EventType.Cipher_ClientCopiedHiddenField,
this.cipher.id,
false,
this.cipher.organizationId,
);
}
private getLinkedFieldsOptionsForCipher() {
switch (this.cipher.type) {
case CipherType.Login:
return LoginView.prototype.linkedFieldOptions;
case CipherType.Card:
return CardView.prototype.linkedFieldOptions;
case CipherType.Identity:
return IdentityView.prototype.linkedFieldOptions;
default:
return null;
}
}
}