parent
cbac5fde11
commit
80af356fd1
|
@ -3,10 +3,8 @@
|
||||||
<h2 bitTypography="h6">{{ "additionalOptions" | i18n }}</h2>
|
<h2 bitTypography="h6">{{ "additionalOptions" | i18n }}</h2>
|
||||||
</bit-section-header>
|
</bit-section-header>
|
||||||
<bit-card>
|
<bit-card>
|
||||||
<label class="tw-text-xs tw-text-muted tw-select-none">
|
|
||||||
{{ "note" | i18n }}
|
|
||||||
</label>
|
|
||||||
<bit-form-field>
|
<bit-form-field>
|
||||||
|
<bit-label>{{ "note" | i18n }}</bit-label>
|
||||||
<textarea readonly bitInput aria-readonly="true">{{ notes }}</textarea>
|
<textarea readonly bitInput aria-readonly="true">{{ notes }}</textarea>
|
||||||
<button
|
<button
|
||||||
bitSuffix
|
bitSuffix
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<bit-section>
|
||||||
|
<bit-section-header>
|
||||||
|
<h2 bitTypography="h6">{{ setSectionTitle }}</h2>
|
||||||
|
</bit-section-header>
|
||||||
|
<bit-card>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>{{ "cardholderName" | i18n }}</bit-label>
|
||||||
|
<input
|
||||||
|
readonly
|
||||||
|
bitInput
|
||||||
|
type="text"
|
||||||
|
[value]="card.cardholderName"
|
||||||
|
aria-readonly="true"
|
||||||
|
data-testid="cardholder-name"
|
||||||
|
/>
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field *ngIf="card.number" [disableMargin]="!card.expiration && !card.code">
|
||||||
|
<bit-label>{{ "number" | i18n }}</bit-label>
|
||||||
|
<input
|
||||||
|
readonly
|
||||||
|
bitInput
|
||||||
|
type="password"
|
||||||
|
[value]="card.number"
|
||||||
|
aria-readonly="true"
|
||||||
|
data-testid="cardholder-number"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
bitSuffix
|
||||||
|
type="button"
|
||||||
|
bitIconButton
|
||||||
|
bitPasswordInputToggle
|
||||||
|
data-testid="toggle-number"
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
bitIconButton="bwi-clone"
|
||||||
|
bitSuffix
|
||||||
|
type="button"
|
||||||
|
[appCopyClick]="card.number"
|
||||||
|
showToast
|
||||||
|
[appA11yTitle]="'copyValue' | i18n"
|
||||||
|
data-testid="copy-number"
|
||||||
|
></button>
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field *ngIf="card.expiration" [disableMargin]="!card.code">
|
||||||
|
<bit-label>{{ "expiration" | i18n }}</bit-label>
|
||||||
|
<input
|
||||||
|
readonly
|
||||||
|
bitInput
|
||||||
|
type="text"
|
||||||
|
[value]="card.expiration"
|
||||||
|
aria-readonly="true"
|
||||||
|
data-testid="cardholder-expiration"
|
||||||
|
/>
|
||||||
|
</bit-form-field>
|
||||||
|
<bit-form-field *ngIf="card.code" disableMargin>
|
||||||
|
<bit-label>{{ "securityCode" | i18n }}</bit-label>
|
||||||
|
<input
|
||||||
|
readonly
|
||||||
|
bitInput
|
||||||
|
type="password"
|
||||||
|
[value]="card.code"
|
||||||
|
aria-readonly="true"
|
||||||
|
data-testid="cardholder-code"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
bitSuffix
|
||||||
|
type="button"
|
||||||
|
bitIconButton
|
||||||
|
bitPasswordInputToggle
|
||||||
|
data-testid="toggle-code"
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
bitIconButton="bwi-clone"
|
||||||
|
bitSuffix
|
||||||
|
type="button"
|
||||||
|
[appCopyClick]="card.code"
|
||||||
|
showToast
|
||||||
|
[appA11yTitle]="'copyValue' | i18n"
|
||||||
|
data-testid="copy-code"
|
||||||
|
></button>
|
||||||
|
</bit-form-field>
|
||||||
|
</bit-card>
|
||||||
|
</bit-section>
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { Component, Input } from "@angular/core";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
import { CardView } from "@bitwarden/common/vault/models/view/card.view";
|
||||||
|
import {
|
||||||
|
CardComponent,
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
TypographyModule,
|
||||||
|
FormFieldModule,
|
||||||
|
IconButtonModule,
|
||||||
|
} from "@bitwarden/components";
|
||||||
|
|
||||||
|
import { OrgIconDirective } from "../../components/org-icon.directive";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-card-details-view",
|
||||||
|
templateUrl: "card-details-view.component.html",
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
JslibModule,
|
||||||
|
CardComponent,
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
TypographyModule,
|
||||||
|
OrgIconDirective,
|
||||||
|
FormFieldModule,
|
||||||
|
IconButtonModule,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class CardDetailsComponent {
|
||||||
|
@Input() card: CardView;
|
||||||
|
|
||||||
|
constructor(private i18nService: I18nService) {}
|
||||||
|
|
||||||
|
get setSectionTitle() {
|
||||||
|
if (this.card.brand && this.card.brand !== "Other") {
|
||||||
|
return this.i18nService.t("cardBrandDetails", this.card.brand);
|
||||||
|
}
|
||||||
|
return this.i18nService.t("cardDetails");
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,11 @@
|
||||||
>
|
>
|
||||||
</app-item-details-v2>
|
</app-item-details-v2>
|
||||||
|
|
||||||
|
<!-- CARD DETAILS -->
|
||||||
|
<ng-container *ngIf="hasCard">
|
||||||
|
<app-card-details-view [card]="cipher.card"></app-card-details-view>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<!-- IDENTITY SECTIONS -->
|
<!-- IDENTITY SECTIONS -->
|
||||||
<app-view-identity-sections *ngIf="cipher.identity" [cipher]="cipher">
|
<app-view-identity-sections *ngIf="cipher.identity" [cipher]="cipher">
|
||||||
</app-view-identity-sections>
|
</app-view-identity-sections>
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { PopupPageComponent } from "../../../../apps/browser/src/platform/popup/
|
||||||
|
|
||||||
import { AdditionalOptionsComponent } from "./additional-options/additional-options.component";
|
import { AdditionalOptionsComponent } from "./additional-options/additional-options.component";
|
||||||
import { AttachmentsV2ViewComponent } from "./attachments/attachments-v2-view.component";
|
import { AttachmentsV2ViewComponent } from "./attachments/attachments-v2-view.component";
|
||||||
|
import { CardDetailsComponent } from "./card-details/card-details-view.component";
|
||||||
import { CustomFieldV2Component } from "./custom-fields/custom-fields-v2.component";
|
import { CustomFieldV2Component } from "./custom-fields/custom-fields-v2.component";
|
||||||
import { ItemDetailsV2Component } from "./item-details/item-details-v2.component";
|
import { ItemDetailsV2Component } from "./item-details/item-details-v2.component";
|
||||||
import { ItemHistoryV2Component } from "./item-history/item-history-v2.component";
|
import { ItemHistoryV2Component } from "./item-history/item-history-v2.component";
|
||||||
|
@ -40,6 +41,7 @@ import { ViewIdentitySectionsComponent } from "./view-identity-sections/view-ide
|
||||||
AttachmentsV2ViewComponent,
|
AttachmentsV2ViewComponent,
|
||||||
ItemHistoryV2Component,
|
ItemHistoryV2Component,
|
||||||
CustomFieldV2Component,
|
CustomFieldV2Component,
|
||||||
|
CardDetailsComponent,
|
||||||
ViewIdentitySectionsComponent,
|
ViewIdentitySectionsComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
@ -64,6 +66,11 @@ export class CipherViewComponent implements OnInit {
|
||||||
this.destroyed$.complete();
|
this.destroyed$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get hasCard() {
|
||||||
|
const { cardholderName, code, expMonth, expYear, brand, number } = this.cipher.card;
|
||||||
|
return cardholderName || code || expMonth || expYear || brand || number;
|
||||||
|
}
|
||||||
|
|
||||||
async loadCipherData() {
|
async loadCipherData() {
|
||||||
if (this.cipher.collectionIds.length > 0) {
|
if (this.cipher.collectionIds.length > 0) {
|
||||||
this.collections$ = this.collectionService
|
this.collections$ = this.collectionService
|
||||||
|
|
|
@ -8,65 +8,51 @@
|
||||||
*ngFor="let field of fields; let last = last"
|
*ngFor="let field of fields; let last = last"
|
||||||
[ngClass]="{ 'tw-mb-4': !last }"
|
[ngClass]="{ 'tw-mb-4': !last }"
|
||||||
>
|
>
|
||||||
<ng-container *ngIf="field.type === fieldType.Text">
|
<bit-form-field *ngIf="field.type === fieldType.Text">
|
||||||
<label class="tw-text-xs tw-text-muted tw-select-none">
|
<bit-label>{{ field.name }}</bit-label>
|
||||||
{{ field.name }}
|
<input readonly bitInput type="text" [value]="field.value" aria-readonly="true" />
|
||||||
</label>
|
<button
|
||||||
<bit-form-field>
|
bitIconButton="bwi-clone"
|
||||||
<input readonly bitInput type="text" [value]="field.value" aria-readonly="true" />
|
bitSuffix
|
||||||
<button
|
type="button"
|
||||||
bitIconButton="bwi-clone"
|
[appCopyClick]="field.value"
|
||||||
bitSuffix
|
showToast
|
||||||
type="button"
|
[appA11yTitle]="'copyValue' | i18n"
|
||||||
[appCopyClick]="field.value"
|
></button>
|
||||||
showToast
|
</bit-form-field>
|
||||||
[appA11yTitle]="'copyValue' | i18n"
|
<bit-form-field *ngIf="field.type === fieldType.Hidden">
|
||||||
></button>
|
<bit-label>{{ field.name }}</bit-label>
|
||||||
</bit-form-field>
|
<input readonly bitInput type="password" [value]="field.value" aria-readonly="true" />
|
||||||
</ng-container>
|
<button bitSuffix type="button" bitIconButton bitPasswordInputToggle></button>
|
||||||
<ng-container *ngIf="field.type === fieldType.Hidden">
|
<button
|
||||||
<label class="tw-text-xs tw-text-muted tw-select-none">
|
bitIconButton="bwi-clone"
|
||||||
{{ field.name }}
|
bitSuffix
|
||||||
</label>
|
type="button"
|
||||||
<bit-form-field>
|
[appCopyClick]="field.value"
|
||||||
<input readonly bitInput type="password" [value]="field.value" aria-readonly="true" />
|
showToast
|
||||||
<button bitSuffix type="button" bitIconButton bitPasswordInputToggle></button>
|
[appA11yTitle]="'copyValue' | i18n"
|
||||||
<button
|
></button>
|
||||||
bitIconButton="bwi-clone"
|
</bit-form-field>
|
||||||
bitSuffix
|
<bit-form-control *ngIf="field.type === fieldType.Boolean">
|
||||||
type="button"
|
<input
|
||||||
[appCopyClick]="field.value"
|
bitCheckbox
|
||||||
showToast
|
type="checkbox"
|
||||||
[appA11yTitle]="'copyValue' | i18n"
|
[checked]="field.value === 'true'"
|
||||||
></button>
|
aria-readonly="true"
|
||||||
</bit-form-field>
|
disabled
|
||||||
</ng-container>
|
/>
|
||||||
<ng-container *ngIf="field.type === fieldType.Boolean">
|
<bit-label> {{ field.name }} </bit-label>
|
||||||
<bit-form-control>
|
</bit-form-control>
|
||||||
<input
|
<bit-form-field *ngIf="field.type === fieldType.Linked">
|
||||||
bitCheckbox
|
<bit-label> {{ "linked" | i18n }}: {{ field.name }} </bit-label>
|
||||||
type="checkbox"
|
<input
|
||||||
[checked]="field.value === 'true'"
|
readonly
|
||||||
aria-readonly="true"
|
bitInput
|
||||||
disabled
|
type="text"
|
||||||
/>
|
[value]="getLinkedType(field.linkedId)"
|
||||||
<bit-label> {{ field.name }} </bit-label>
|
aria-readonly="true"
|
||||||
</bit-form-control>
|
/>
|
||||||
</ng-container>
|
</bit-form-field>
|
||||||
<ng-container *ngIf="field.type === fieldType.Linked">
|
|
||||||
<label class="tw-text-xs tw-text-muted tw-select-none">
|
|
||||||
{{ "linked" | i18n }}: {{ field.name }}
|
|
||||||
</label>
|
|
||||||
<bit-form-field>
|
|
||||||
<input
|
|
||||||
readonly
|
|
||||||
bitInput
|
|
||||||
type="text"
|
|
||||||
[value]="getLinkedType(field.linkedId)"
|
|
||||||
aria-readonly="true"
|
|
||||||
/>
|
|
||||||
</bit-form-field>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
</div>
|
||||||
</bit-card>
|
</bit-card>
|
||||||
</bit-section>
|
</bit-section>
|
||||||
|
|
Loading…
Reference in New Issue