mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 23:03:32 +00:00
[PM-8527] Identity Add Edit Browser V2 (#10016)
* Add Identity Edit Section for Browser V2 Edit Work
This commit is contained in:
@@ -3607,6 +3607,15 @@
|
|||||||
"filters": {
|
"filters": {
|
||||||
"message": "Filters"
|
"message": "Filters"
|
||||||
},
|
},
|
||||||
|
"personalDetails": {
|
||||||
|
"message": "Personal details"
|
||||||
|
},
|
||||||
|
"identification": {
|
||||||
|
"message": "Identification"
|
||||||
|
},
|
||||||
|
"contactInfo": {
|
||||||
|
"message": "Contact info"
|
||||||
|
},
|
||||||
"downloadAttachment": {
|
"downloadAttachment": {
|
||||||
"message": "Download - $ITEMNAME$",
|
"message": "Download - $ITEMNAME$",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ export class OpenAttachmentsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
|
if (!this.cipherId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const cipherDomain = await this.cipherService.get(this.cipherId);
|
const cipherDomain = await this.cipherService.get(this.cipherId);
|
||||||
const cipher = await cipherDomain.decrypt(
|
const cipher = await cipherDomain.decrypt(
|
||||||
await this.cipherService.getKeyForCipherKeyDecryption(cipherDomain),
|
await this.cipherService.getKeyForCipherKeyDecryption(cipherDomain),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
|
||||||
import { CardDetailsSectionComponent } from "./components/card-details-section/card-details-section.component";
|
import { CardDetailsSectionComponent } from "./components/card-details-section/card-details-section.component";
|
||||||
|
import { IdentitySectionComponent } from "./components/identity/identity.component";
|
||||||
import { ItemDetailsSectionComponent } from "./components/item-details/item-details-section.component";
|
import { ItemDetailsSectionComponent } from "./components/item-details/item-details-section.component";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -10,6 +11,7 @@ import { ItemDetailsSectionComponent } from "./components/item-details/item-deta
|
|||||||
export type CipherForm = {
|
export type CipherForm = {
|
||||||
itemDetails?: ItemDetailsSectionComponent["itemDetailsForm"];
|
itemDetails?: ItemDetailsSectionComponent["itemDetailsForm"];
|
||||||
cardDetails?: CardDetailsSectionComponent["cardDetailsForm"];
|
cardDetails?: CardDetailsSectionComponent["cardDetailsForm"];
|
||||||
|
identityDetails?: IdentitySectionComponent["identityForm"];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
[originalCipherView]="originalCipherView"
|
[originalCipherView]="originalCipherView"
|
||||||
></vault-item-details-section>
|
></vault-item-details-section>
|
||||||
|
|
||||||
|
<vault-identity-section
|
||||||
|
*ngIf="config.cipherType === CipherType.Identity"
|
||||||
|
[disabled]="config.mode === 'partial-edit'"
|
||||||
|
[originalCipherView]="originalCipherView"
|
||||||
|
></vault-identity-section>
|
||||||
|
|
||||||
<vault-card-details-section
|
<vault-card-details-section
|
||||||
*ngIf="config.cipherType === CipherType.Card"
|
*ngIf="config.cipherType === CipherType.Card"
|
||||||
[originalCipherView]="originalCipherView"
|
[originalCipherView]="originalCipherView"
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import { CipherFormService } from "../abstractions/cipher-form.service";
|
|||||||
import { CipherForm, CipherFormContainer } from "../cipher-form-container";
|
import { CipherForm, CipherFormContainer } from "../cipher-form-container";
|
||||||
|
|
||||||
import { CardDetailsSectionComponent } from "./card-details-section/card-details-section.component";
|
import { CardDetailsSectionComponent } from "./card-details-section/card-details-section.component";
|
||||||
|
import { IdentitySectionComponent } from "./identity/identity.component";
|
||||||
import { ItemDetailsSectionComponent } from "./item-details/item-details-section.component";
|
import { ItemDetailsSectionComponent } from "./item-details/item-details-section.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -59,6 +60,7 @@ import { ItemDetailsSectionComponent } from "./item-details/item-details-section
|
|||||||
SelectModule,
|
SelectModule,
|
||||||
ItemDetailsSectionComponent,
|
ItemDetailsSectionComponent,
|
||||||
CardDetailsSectionComponent,
|
CardDetailsSectionComponent,
|
||||||
|
IdentitySectionComponent,
|
||||||
NgIf,
|
NgIf,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
<form [formGroup]="identityForm">
|
||||||
|
<bit-section>
|
||||||
|
<bit-section-header>
|
||||||
|
<h2 bitTypography="h5">{{ "personalDetails" | i18n }}</h2>
|
||||||
|
</bit-section-header>
|
||||||
|
<bit-card>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "title" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<bit-select formControlName="title">
|
||||||
|
<bit-option
|
||||||
|
*ngFor="let title of identityTitleOptions"
|
||||||
|
[value]="title.value"
|
||||||
|
[label]="title.name"
|
||||||
|
>
|
||||||
|
</bit-option>
|
||||||
|
</bit-select>
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "firstName" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="firstName" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "lastName" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="lastName" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "username" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="username" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "company" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="company" />
|
||||||
|
</bit-form-field>
|
||||||
|
</bit-card>
|
||||||
|
</bit-section>
|
||||||
|
<bit-section>
|
||||||
|
<bit-section-header>
|
||||||
|
<h2 bitTypography="h5">{{ "identification" | i18n }}</h2>
|
||||||
|
</bit-section-header>
|
||||||
|
<bit-card>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "ssn" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input formControlName="ssn" bitInput type="password" />
|
||||||
|
<button type="button" bitIconButton bitPasswordInputToggle></button>
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "passportNumber" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input formControlName="passportNumber" bitInput type="password" />
|
||||||
|
<button type="button" bitIconButton bitPasswordInputToggle></button>
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "licenseNumber" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="licenseNumber" />
|
||||||
|
</bit-form-field>
|
||||||
|
</bit-card>
|
||||||
|
</bit-section>
|
||||||
|
<bit-section>
|
||||||
|
<bit-section-header>
|
||||||
|
<h2 bitTypography="h5">{{ "contactInfo" | i18n }}</h2>
|
||||||
|
</bit-section-header>
|
||||||
|
<bit-card>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "email" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="email" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "phone" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="phone" />
|
||||||
|
</bit-form-field>
|
||||||
|
</bit-card>
|
||||||
|
</bit-section>
|
||||||
|
<bit-section>
|
||||||
|
<bit-section-header>
|
||||||
|
<h2 bitTypography="h5">{{ "address" | i18n }}</h2>
|
||||||
|
</bit-section-header>
|
||||||
|
<bit-card>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "address1" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="address1" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "address2" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="address2" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "address3" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="address3" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "cityTown" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="city" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "stateProvince" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="state" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "zipPostalCode" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="postalCode" />
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>
|
||||||
|
{{ "country" | i18n }}
|
||||||
|
</bit-label>
|
||||||
|
<input bitInput formControlName="country" />
|
||||||
|
</bit-form-field>
|
||||||
|
</bit-card>
|
||||||
|
</bit-section>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { Component, Input, OnInit } from "@angular/core";
|
||||||
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view";
|
||||||
|
import {
|
||||||
|
ButtonModule,
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
CardComponent,
|
||||||
|
FormFieldModule,
|
||||||
|
IconButtonModule,
|
||||||
|
SelectModule,
|
||||||
|
} from "@bitwarden/components";
|
||||||
|
|
||||||
|
import { CipherFormContainer } from "../../cipher-form-container";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
standalone: true,
|
||||||
|
selector: "vault-identity-section",
|
||||||
|
templateUrl: "./identity.component.html",
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
ButtonModule,
|
||||||
|
JslibModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
CardComponent,
|
||||||
|
FormFieldModule,
|
||||||
|
IconButtonModule,
|
||||||
|
SelectModule,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class IdentitySectionComponent implements OnInit {
|
||||||
|
@Input() originalCipherView: CipherView;
|
||||||
|
@Input() disabled: boolean;
|
||||||
|
identityTitleOptions = [
|
||||||
|
{ name: "-- " + this.i18nService.t("select") + " --", value: null },
|
||||||
|
{ name: this.i18nService.t("mr"), value: this.i18nService.t("mr") },
|
||||||
|
{ name: this.i18nService.t("mrs"), value: this.i18nService.t("mrs") },
|
||||||
|
{ name: this.i18nService.t("ms"), value: this.i18nService.t("ms") },
|
||||||
|
{ name: this.i18nService.t("mx"), value: this.i18nService.t("mx") },
|
||||||
|
{ name: this.i18nService.t("dr"), value: this.i18nService.t("dr") },
|
||||||
|
];
|
||||||
|
|
||||||
|
protected identityForm = this.formBuilder.group({
|
||||||
|
title: [null],
|
||||||
|
firstName: [""],
|
||||||
|
lastName: [""],
|
||||||
|
username: [""],
|
||||||
|
company: [""],
|
||||||
|
ssn: [""],
|
||||||
|
passportNumber: [""],
|
||||||
|
licenseNumber: [""],
|
||||||
|
email: [""],
|
||||||
|
phone: [""],
|
||||||
|
address1: [""],
|
||||||
|
address2: [""],
|
||||||
|
address3: [""],
|
||||||
|
city: [""],
|
||||||
|
state: [""],
|
||||||
|
postalCode: [""],
|
||||||
|
country: [""],
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private cipherFormContainer: CipherFormContainer,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private i18nService: I18nService,
|
||||||
|
) {
|
||||||
|
this.cipherFormContainer.registerChildForm("identityDetails", this.identityForm);
|
||||||
|
this.identityForm.valueChanges.pipe(takeUntilDestroyed()).subscribe((value) => {
|
||||||
|
const data = new IdentityView();
|
||||||
|
data.title = value.title;
|
||||||
|
data.firstName = value.firstName;
|
||||||
|
data.lastName = value.lastName;
|
||||||
|
data.username = value.username;
|
||||||
|
data.company = value.company;
|
||||||
|
data.ssn = value.ssn;
|
||||||
|
data.passportNumber = value.passportNumber;
|
||||||
|
data.licenseNumber = value.licenseNumber;
|
||||||
|
data.email = value.email;
|
||||||
|
data.phone = value.phone;
|
||||||
|
data.address1 = value.address1;
|
||||||
|
data.address2 = value.address2;
|
||||||
|
data.address3 = value.address3;
|
||||||
|
data.city = value.city;
|
||||||
|
data.state = value.state;
|
||||||
|
data.postalCode = value.postalCode;
|
||||||
|
data.country = value.country;
|
||||||
|
|
||||||
|
this.cipherFormContainer.patchCipher({
|
||||||
|
identity: data,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
// If true will disable all inputs
|
||||||
|
if (this.disabled) {
|
||||||
|
this.identityForm.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.originalCipherView && this.originalCipherView.id) {
|
||||||
|
this.populateFormData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
populateFormData() {
|
||||||
|
const { identity } = this.originalCipherView;
|
||||||
|
this.identityForm.setValue({
|
||||||
|
title: identity.title,
|
||||||
|
firstName: identity.firstName,
|
||||||
|
lastName: identity.lastName,
|
||||||
|
username: identity.username,
|
||||||
|
company: identity.company,
|
||||||
|
ssn: identity.ssn,
|
||||||
|
passportNumber: identity.passportNumber,
|
||||||
|
licenseNumber: identity.licenseNumber,
|
||||||
|
email: identity.email,
|
||||||
|
phone: identity.phone,
|
||||||
|
address1: identity.address1,
|
||||||
|
address2: identity.address2,
|
||||||
|
address3: identity.address3,
|
||||||
|
city: identity.city,
|
||||||
|
state: identity.state,
|
||||||
|
postalCode: identity.postalCode,
|
||||||
|
country: identity.country,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user