1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-22 11:45:59 +01:00

[PM-7901] added new card view (#10321)

* added new card view
This commit is contained in:
Jason Ng 2024-07-30 15:54:45 -04:00 committed by GitHub
parent cbac5fde11
commit 80af356fd1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 186 additions and 62 deletions

View File

@ -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

View File

@ -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>

View File

@ -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");
}
}

View File

@ -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>

View File

@ -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

View File

@ -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>