[PM-10934] Remove last form-field bottom border (#10751)

* match API of new CL FormField component

* remove readonly border for additional options component

* remove readonly border for last autofill option

* remove readonly border for last custom-field form field

* remove readonly border for when collection,org or folder is available

* add `ReadOnlyCipherCardComponent` to handle readonly border

* remove readonly border for the last identity form field

* remove readonly border for the last card form field

* remove readonly border for the last login form field

* remove unneeded true value
This commit is contained in:
Nick Krantz 2024-09-04 10:50:34 -05:00 committed by GitHub
parent 192fd885d5
commit 3e9fb2009e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 67 additions and 15 deletions

View File

@ -1,6 +1,7 @@
import { coerceBooleanProperty } from "@angular/cdk/coercion";
import {
AfterContentChecked,
booleanAttribute,
Component,
ContentChild,
ContentChildren,
@ -38,6 +39,13 @@ export class BitFormFieldComponent implements AfterContentChecked {
return this._disableMargin;
}
/**
* NOTE: Placeholder to match the API of the form-field component in the `ps/extension` branch,
* no functionality is implemented as of now.
*/
@Input({ transform: booleanAttribute })
disableReadOnlyBorder = false;
@HostBinding("class")
get classList() {
return ["tw-block"].concat(this.disableMargin ? [] : ["tw-mb-6"]);

View File

@ -3,7 +3,7 @@
<h2 bitTypography="h6">{{ "additionalOptions" | i18n }}</h2>
</bit-section-header>
<bit-card class="[&_bit-form-field:last-of-type]:tw-mb-0">
<bit-form-field>
<bit-form-field disableReadOnlyBorder>
<bit-label>{{ "note" | i18n }}</bit-label>
<textarea readonly bitInput aria-readonly="true">{{ notes }}</textarea>
<button

View File

@ -4,7 +4,11 @@
</bit-section-header>
<bit-card>
<ng-container *ngFor="let login of loginUris; let last = last">
<bit-form-field [disableMargin]="last" data-testid="autofill-view-list">
<bit-form-field
[disableMargin]="last"
[disableReadOnlyBorder]="last"
data-testid="autofill-view-list"
>
<bit-label>
{{ "website" | i18n }}
</bit-label>

View File

@ -2,7 +2,7 @@
<bit-section-header>
<h2 bitTypography="h6">{{ setSectionTitle }}</h2>
</bit-section-header>
<bit-card class="[&_bit-form-field:last-of-type]:tw-mb-0">
<read-only-cipher-card>
<bit-form-field *ngIf="card.cardholderName">
<bit-label>{{ "cardholderName" | i18n }}</bit-label>
<input
@ -81,5 +81,5 @@
data-testid="copy-code"
></button>
</bit-form-field>
</bit-card>
</read-only-cipher-card>
</bit-section>

View File

@ -13,6 +13,8 @@ import {
IconButtonModule,
} from "@bitwarden/components";
import { ReadOnlyCipherCardComponent } from "../read-only-cipher-card/read-only-cipher-card.component";
@Component({
selector: "app-card-details-view",
templateUrl: "card-details-view.component.html",
@ -26,6 +28,7 @@ import {
TypographyModule,
FormFieldModule,
IconButtonModule,
ReadOnlyCipherCardComponent,
],
})
export class CardDetailsComponent {

View File

@ -8,7 +8,7 @@
*ngFor="let field of fields; let last = last"
[ngClass]="{ 'tw-mb-4': !last }"
>
<bit-form-field *ngIf="field.type === fieldType.Text">
<bit-form-field *ngIf="field.type === fieldType.Text" [disableReadOnlyBorder]="last">
<bit-label>{{ field.name }}</bit-label>
<input readonly bitInput type="text" [value]="field.value" aria-readonly="true" />
<button
@ -21,7 +21,7 @@
[appA11yTitle]="'copyValue' | i18n"
></button>
</bit-form-field>
<bit-form-field *ngIf="field.type === fieldType.Hidden">
<bit-form-field *ngIf="field.type === fieldType.Hidden" [disableReadOnlyBorder]="last">
<bit-label>{{ field.name }}</bit-label>
<input readonly bitInput type="password" [value]="field.value" aria-readonly="true" />
<button bitSuffix type="button" bitIconButton bitPasswordInputToggle></button>
@ -45,7 +45,7 @@
/>
<bit-label> {{ field.name }} </bit-label>
</bit-form-control>
<bit-form-field *ngIf="field.type === fieldType.Linked">
<bit-form-field *ngIf="field.type === fieldType.Linked" [disableReadOnlyBorder]="last">
<bit-label> {{ "linked" | i18n }}: {{ field.name }} </bit-label>
<input
readonly

View File

@ -5,6 +5,9 @@
<bit-card>
<bit-form-field
[disableMargin]="!cipher.collectionIds?.length && !cipher.organizationId && !cipher.folderId"
[disableReadOnlyBorder]="
!cipher.collectionIds?.length && !cipher.organizationId && !cipher.folderId
"
>
<bit-label>
{{ "itemName" | i18n }}

View File

@ -2,7 +2,7 @@
<bit-section-header>
<h2 bitTypography="h6">{{ "loginCredentials" | i18n }}</h2>
</bit-section-header>
<bit-card class="[&_bit-form-field:last-of-type]:tw-mb-0">
<read-only-cipher-card>
<bit-form-field *ngIf="cipher.login.username">
<bit-label>
{{ "username" | i18n }}
@ -132,5 +132,5 @@
class="disabled:tw-cursor-default"
></button>
</bit-form-field>
</bit-card>
</read-only-cipher-card>
</bit-section>

View File

@ -19,6 +19,7 @@ import {
} from "@bitwarden/components";
import { BitTotpCountdownComponent } from "../../components/totp-countdown/totp-countdown.component";
import { ReadOnlyCipherCardComponent } from "../read-only-cipher-card/read-only-cipher-card.component";
type TotpCodeValues = {
totpCode: string;
@ -41,6 +42,7 @@ type TotpCodeValues = {
BadgeModule,
ColorPasswordModule,
BitTotpCountdownComponent,
ReadOnlyCipherCardComponent,
],
})
export class LoginCredentialsViewComponent {

View File

@ -0,0 +1,3 @@
<bit-card class="[&_bit-form-field:last-of-type]:tw-mb-0">
<ng-content></ng-content>
</bit-card>

View File

@ -0,0 +1,26 @@
import { AfterViewInit, Component, ContentChildren, QueryList } from "@angular/core";
import { CardComponent, BitFormFieldComponent } from "@bitwarden/components";
@Component({
selector: "read-only-cipher-card",
templateUrl: "./read-only-cipher-card.component.html",
standalone: true,
imports: [CardComponent],
})
/**
* A thin wrapper around the `bit-card` component that disables the bottom border for the last form field.
*/
export class ReadOnlyCipherCardComponent implements AfterViewInit {
@ContentChildren(BitFormFieldComponent) formFields: QueryList<BitFormFieldComponent>;
ngAfterViewInit(): void {
// Disable the bottom border for the last form field
if (this.formFields.last) {
// Delay model update until next change detection cycle
setTimeout(() => {
this.formFields.last.disableReadOnlyBorder = true;
});
}
}
}

View File

@ -3,7 +3,7 @@
<h2 bitTypography="h6">{{ "personalDetails" | i18n }}</h2>
</bit-section-header>
<bit-card class="[&_bit-form-field:last-of-type]:tw-mb-0">
<read-only-cipher-card>
<bit-form-field *ngIf="cipher.identity.fullName">
<bit-label>{{ "name" | i18n }}</bit-label>
<input bitInput [value]="cipher.identity.fullName" readonly data-testid="name" />
@ -43,7 +43,7 @@
[valueLabel]="'company' | i18n"
></button>
</bit-form-field>
</bit-card>
</read-only-cipher-card>
</bit-section>
<bit-section *ngIf="showIdentificationDetails">
@ -51,7 +51,7 @@
<h2 bitTypography="h6">{{ "identification" | i18n }}</h2>
</bit-section-header>
<bit-card class="[&_bit-form-field:last-of-type]:tw-mb-0">
<read-only-cipher-card>
<bit-form-field *ngIf="cipher.identity.ssn">
<bit-label>{{ "ssn" | i18n }}</bit-label>
<input bitInput type="password" [value]="cipher.identity.ssn" readonly data-testid="ssn" />
@ -111,7 +111,7 @@
[valueLabel]="'licenseNumber' | i18n"
></button>
</bit-form-field>
</bit-card>
</read-only-cipher-card>
</bit-section>
<bit-section *ngIf="showContactDetails">
@ -119,7 +119,7 @@
<h2 bitTypography="h6">{{ "contactInfo" | i18n }}</h2>
</bit-section-header>
<bit-card class="[&_bit-form-field:last-of-type]:tw-mb-0">
<read-only-cipher-card>
<bit-form-field *ngIf="cipher.identity.email">
<bit-label>{{ "email" | i18n }}</bit-label>
<input bitInput [value]="cipher.identity.email" readonly data-testid="email" />
@ -166,5 +166,5 @@
[valueLabel]="'address' | i18n"
></button>
</bit-form-field>
</bit-card>
</read-only-cipher-card>
</bit-section>

View File

@ -12,6 +12,8 @@ import {
TypographyModule,
} from "@bitwarden/components";
import { ReadOnlyCipherCardComponent } from "../read-only-cipher-card/read-only-cipher-card.component";
@Component({
standalone: true,
selector: "app-view-identity-sections",
@ -25,6 +27,7 @@ import {
TypographyModule,
FormFieldModule,
IconButtonModule,
ReadOnlyCipherCardComponent,
],
})
export class ViewIdentitySectionsComponent implements OnInit {