parent
cbac5fde11
commit
80af356fd1
|
@ -3,10 +3,8 @@
|
|||
<h2 bitTypography="h6">{{ "additionalOptions" | i18n }}</h2>
|
||||
</bit-section-header>
|
||||
<bit-card>
|
||||
<label class="tw-text-xs tw-text-muted tw-select-none">
|
||||
{{ "note" | i18n }}
|
||||
</label>
|
||||
<bit-form-field>
|
||||
<bit-label>{{ "note" | i18n }}</bit-label>
|
||||
<textarea readonly bitInput aria-readonly="true">{{ notes }}</textarea>
|
||||
<button
|
||||
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>
|
||||
|
||||
<!-- CARD DETAILS -->
|
||||
<ng-container *ngIf="hasCard">
|
||||
<app-card-details-view [card]="cipher.card"></app-card-details-view>
|
||||
</ng-container>
|
||||
|
||||
<!-- IDENTITY SECTIONS -->
|
||||
<app-view-identity-sections *ngIf="cipher.identity" [cipher]="cipher">
|
||||
</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 { 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 { ItemDetailsV2Component } from "./item-details/item-details-v2.component";
|
||||
import { ItemHistoryV2Component } from "./item-history/item-history-v2.component";
|
||||
|
@ -40,6 +41,7 @@ import { ViewIdentitySectionsComponent } from "./view-identity-sections/view-ide
|
|||
AttachmentsV2ViewComponent,
|
||||
ItemHistoryV2Component,
|
||||
CustomFieldV2Component,
|
||||
CardDetailsComponent,
|
||||
ViewIdentitySectionsComponent,
|
||||
],
|
||||
})
|
||||
|
@ -64,6 +66,11 @@ export class CipherViewComponent implements OnInit {
|
|||
this.destroyed$.complete();
|
||||
}
|
||||
|
||||
get hasCard() {
|
||||
const { cardholderName, code, expMonth, expYear, brand, number } = this.cipher.card;
|
||||
return cardholderName || code || expMonth || expYear || brand || number;
|
||||
}
|
||||
|
||||
async loadCipherData() {
|
||||
if (this.cipher.collectionIds.length > 0) {
|
||||
this.collections$ = this.collectionService
|
||||
|
|
|
@ -8,65 +8,51 @@
|
|||
*ngFor="let field of fields; let last = last"
|
||||
[ngClass]="{ 'tw-mb-4': !last }"
|
||||
>
|
||||
<ng-container *ngIf="field.type === fieldType.Text">
|
||||
<label class="tw-text-xs tw-text-muted tw-select-none">
|
||||
{{ field.name }}
|
||||
</label>
|
||||
<bit-form-field>
|
||||
<input readonly bitInput type="text" [value]="field.value" aria-readonly="true" />
|
||||
<button
|
||||
bitIconButton="bwi-clone"
|
||||
bitSuffix
|
||||
type="button"
|
||||
[appCopyClick]="field.value"
|
||||
showToast
|
||||
[appA11yTitle]="'copyValue' | i18n"
|
||||
></button>
|
||||
</bit-form-field>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="field.type === fieldType.Hidden">
|
||||
<label class="tw-text-xs tw-text-muted tw-select-none">
|
||||
{{ field.name }}
|
||||
</label>
|
||||
<bit-form-field>
|
||||
<input readonly bitInput type="password" [value]="field.value" aria-readonly="true" />
|
||||
<button bitSuffix type="button" bitIconButton bitPasswordInputToggle></button>
|
||||
<button
|
||||
bitIconButton="bwi-clone"
|
||||
bitSuffix
|
||||
type="button"
|
||||
[appCopyClick]="field.value"
|
||||
showToast
|
||||
[appA11yTitle]="'copyValue' | i18n"
|
||||
></button>
|
||||
</bit-form-field>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="field.type === fieldType.Boolean">
|
||||
<bit-form-control>
|
||||
<input
|
||||
bitCheckbox
|
||||
type="checkbox"
|
||||
[checked]="field.value === 'true'"
|
||||
aria-readonly="true"
|
||||
disabled
|
||||
/>
|
||||
<bit-label> {{ field.name }} </bit-label>
|
||||
</bit-form-control>
|
||||
</ng-container>
|
||||
<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>
|
||||
<bit-form-field *ngIf="field.type === fieldType.Text">
|
||||
<bit-label>{{ field.name }}</bit-label>
|
||||
<input readonly bitInput type="text" [value]="field.value" aria-readonly="true" />
|
||||
<button
|
||||
bitIconButton="bwi-clone"
|
||||
bitSuffix
|
||||
type="button"
|
||||
[appCopyClick]="field.value"
|
||||
showToast
|
||||
[appA11yTitle]="'copyValue' | i18n"
|
||||
></button>
|
||||
</bit-form-field>
|
||||
<bit-form-field *ngIf="field.type === fieldType.Hidden">
|
||||
<bit-label>{{ field.name }}</bit-label>
|
||||
<input readonly bitInput type="password" [value]="field.value" aria-readonly="true" />
|
||||
<button bitSuffix type="button" bitIconButton bitPasswordInputToggle></button>
|
||||
<button
|
||||
bitIconButton="bwi-clone"
|
||||
bitSuffix
|
||||
type="button"
|
||||
[appCopyClick]="field.value"
|
||||
showToast
|
||||
[appA11yTitle]="'copyValue' | i18n"
|
||||
></button>
|
||||
</bit-form-field>
|
||||
<bit-form-control *ngIf="field.type === fieldType.Boolean">
|
||||
<input
|
||||
bitCheckbox
|
||||
type="checkbox"
|
||||
[checked]="field.value === 'true'"
|
||||
aria-readonly="true"
|
||||
disabled
|
||||
/>
|
||||
<bit-label> {{ field.name }} </bit-label>
|
||||
</bit-form-control>
|
||||
<bit-form-field *ngIf="field.type === fieldType.Linked">
|
||||
<bit-label> {{ "linked" | i18n }}: {{ field.name }} </bit-label>
|
||||
<input
|
||||
readonly
|
||||
bitInput
|
||||
type="text"
|
||||
[value]="getLinkedType(field.linkedId)"
|
||||
aria-readonly="true"
|
||||
/>
|
||||
</bit-form-field>
|
||||
</div>
|
||||
</bit-card>
|
||||
</bit-section>
|
||||
|
|
Loading…
Reference in New Issue