File

projects/congarevenuecloud/elements/src/lib/product-card/product-card.component.ts

Description

The Product Card component generates a card template which displays the product information. A product description is displayed if type input is set to 'media'.

Preview

1.) Card

2.) Media

Usage

Example :
import { ProductCardModule } from '@congarevenuecloud/elements';

@NgModule({
imports: [ProductCardModule, ...]
})
export class AppModule {}
Example :
// Basic Usage
```typescript
<apt-product-card [product]="product"></apt-product-card>
Example :
// All inputs and outputs
```typescript
<apt-product-card
             [product]="product"
             [thumbnail]="showThumbnail"
             [type]="card"
             [showCategory]="showingCategory"
             [showCode]="showingCode"
             [showPrice]="showingPrice"
             [canAddToCart]="canAddToCart"
></apt-product-card>

Implements

OnInit OnChanges OnDestroy

Metadata

Index

Properties
Inputs

Constructor

constructor(config: ConfigurationService, batchSelectionService: BatchSelectionService, productService: ProductService, activatedRoute: ActivatedRoute, router: Router, userService: UserService, storefrontService: StorefrontService, batchActionService: BatchActionService)
Parameters :
Name Type Optional
config ConfigurationService No
batchSelectionService BatchSelectionService No
productService ProductService No
activatedRoute ActivatedRoute No
router Router No
userService UserService No
storefrontService StorefrontService No
batchActionService BatchActionService No

Inputs

canAddToCart
Type : boolean
Default value : true

Flag to show the add to cart button on the card.

product
Type : Product | string

The product associated with this component.

quantity
Type : number

The product quantity associated with this component.

showCategory
Type : boolean
Default value : true

Flag to show the category of the product.

showCode
Type : boolean
Default value : true

Flag to show the code of the product.

showPrice
Type : boolean
Default value : true

Flag to show the price of the product.

showQty
Type : boolean
Default value : false

Show quantity.

skipRules
Type : boolean
Default value : false

Rules to be skipped or not.

thumbnail
Type : boolean
Default value : true

Flag to show the thumbnail image on the product card.

type
Type : "card" | "media" | "readonly"
Default value : 'card'

Display type of the product card.

Properties

enableOneTime$
Type : Observable<boolean>
<ng-container *ngIf="_product && _product[identifier]">
  <div class="card" *ngIf="type == 'card'">
    <div class="card-body">
      <div class="custom-control custom-checkbox custom-checkbox-lg card-title">
        <input [id]="_product.Id" type="checkbox" class="custom-control-input" (change)="handleCheckbox($event)"
          [checked]="selected$ | async" />
        <label class="custom-control-label d-flex justify-content-between d-block d-sm-none text-size-lg" [for]="_product.Id"></label>
        <label class="custom-control-label d-flex justify-content-between d-none d-sm-block text-size-xl" [for]="_product.Id"></label>
        <div class="d-flex justify-content-between">
          <p class="m-0 font-weight-bold d-flex text-break" tooltip="{{_product?.Name}}" container="body"
            placement="top">{{ _product?.Name | truncate:30 }}</p>
          <span class="pt-1 text-muted icons d-flex">
            <i class="fa fa-shopping-bag" tooltip="{{'PRODUCT_CARD.INSTALLED_PRODUCT' | translate}}" container="body"
              [adaptivePosition]="false"
              *ngIf="aboEnabled && _product?.AssetLineItems?.length > 0 && isLoggedIn$ | async">
            </i>
            <i class="fa fa-wrench wrench-icon" tooltip="{{'PRODUCT_CARD.COMPLEX_PRODUCT' | translate}}" container="body"
              [adaptivePosition]="false" *ngIf="_product.HasAttributes || _product.HasOptions"></i>
          </span>
        </div>
      </div>
      <a href="javascript:void(0)" [routerLink]="['/products', _product[identifier]]" [state]="_product">
        <div class="img-container">
          <img class="card-img-top w-100 h-100 m-auto d-flex align-self-center" [src]="_product.IconId | image"
            [alt]="_product.Name" *ngIf="thumbnail">
        </div>

        <div class="d-flex my-1 align-items-center split-items">
          <span class="text-muted product-code pr-1 text-truncate" *ngIf="showCode">{{_product.ProductCode}}</span>
          <span class="text-muted product-category pl-1 pr-1 border-left text-truncate"
            *ngIf="showCategory && _product.Categories?.length > 0">{{_product.Categories[0]?.Classification?.Name}}</span>
        </div>
      </a>
      <div class="d-flex flex-row">
        <apt-popover [placement]="'right'" [popoverContent]="popoverTemplate">
          <span class="card-text font-weight-bold d-flex flex-column justify-content-between" *ngIf="showPrice">
            <label>{{'PRODUCT_CARD.STANDARD_PRICE' | translate}}
              <!-- TODO: Add info icon when DC-8455 implementation is taken up.
              <i class="fas fa-info-circle"></i> -->
            </label>
            <apt-price [record]="_product" [type]="'list'"></apt-price>
          </span>
        </apt-popover>
      </div>

    </div>
    <div class="card-footer px-2 pb-3 border-top" *ngIf="canAddToCart">
      <apt-add-to-cart size="sm" [product]="_product" [label]="label" [assetRoute]="'/assets'"
        (updateProductQuantity)="fetchQuantity($event)" [enableOneTime]="enableOneTime$ | async"></apt-add-to-cart>
    </div>
  </div>

  <div *ngIf="type == 'media'" class="media">
    <div class="custom-control custom-checkbox custom-checkbox-lg">
      <input [id]="_product.Id" type="checkbox" class="custom-control-input" (change)="handleCheckbox($event)"
        [checked]="selected$ | async" />
      <label class="custom-control-label mt-2 ml-2" [for]="_product.Id">&nbsp;</label>
    </div>

    <a href="javascript:void(0)" [routerLink]="['/products', _product[identifier]]"
      class="d-flex justify-content-center w-25" [state]="_product">
      <img class="mr-3" [src]="_product.IconId | image" [alt]="_product.Name">
    </a>
    <div class="media-body px-3">
      <h5 class="m-0">
        <a href="javascript:void(0)" [routerLink]="['/products', _product[identifier]]" [state]="_product">
          {{_product.Name}}
        </a>
        <span class="ml-auto mr-3 purchased list-purchasedbucket">
          <i *ngIf="aboEnabled && _product?.AssetLineItems?.length>0 && isLoggedIn$ | async" class="fa fa-shopping-bag"
            tooltip="{{'PRODUCT_CARD.INSTALLED_PRODUCT' | translate}}" container="body" [adaptivePosition]="false"
            aria-hidden="true"></i>
            <i class="fa fa-wrench" tooltip="{{'PRODUCT_CARD.COMPLEX_PRODUCT' | translate}}" container="body"
            [adaptivePosition]="false" *ngIf="_product.HasAttributes || _product.HasOptions"></i>
        </span>
      </h5>
      <div class="d-flex mb-3 align-items-center split-items">
        <div class="text-muted" *ngIf="showCode">{{_product.ProductCode}}</div>
        <div class="text-muted" *ngIf="showCategory && _product.Categories?.length > 0">
          {{_product.Categories[0]?.Classification?.Name}}</div>
      </div>
      <div class="productDescription">
        {{_product.Description}}
      </div>
    </div>
    <div class="pl-4 align-self-stretch d-flex align-items-start flex-column">
      <strong class="mb-auto align-self-end" *ngIf="showPrice">
        <apt-price [record]="_product" [type]="'list'"></apt-price>
      </strong>
      <div *ngIf="canAddToCart">
        <apt-add-to-cart size="sm" [product]="_product" [label]="label" [assetRoute]="'/assets'"
          (updateProductQuantity)="fetchQuantity($event)" [enableOneTime]="enableOneTime$ | async">
        </apt-add-to-cart>
      </div>
    </div>
  </div>

  <div class="card" *ngIf="type === 'readonly'">
    <div class="card-body readonly p-2">
      <div class="card-title d-flex justify-content-between align-items-start m-0">
        <p class="m-0 card-title font-weight-bold text-break" tooltip="{{_product?.Name}}" container="body"
          placement="top">{{_product?.Name | truncate:30}}</p>
        <button type="button" class="btn btn-link p-0 close" aria-label="Close" (click)="removeProduct()"
          *ngIf="selected$ | async">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <a href="javascript:void(0)" [routerLink]="['/products', _product[identifier]]" [state]="_product">
        <div class="img-container">
          <img class="card-img-top w-100 h-100 m-auto d-flex align-self-center" [src]="_product.IconId | image"
            [alt]="_product.Name" *ngIf="thumbnail">
        </div>
      </a>

      <div class="d-flex mt-3 align-items-center split-items" *ngIf="showCategory || showCode">
        <span class="text-muted product-code" *ngIf="showCode">{{_product.ProductCode}}</span>
        <span class="text-muted product-category"
          *ngIf="showCategory && _product.Categories?.length > 0">{{_product.Categories[0].Classification.Name}}</span>&nbsp;
      </div>

      <div class="d-flex mt-2 justify-content-center" *ngIf="showQty">
        <input type="number" [Id]="_product.Id" min="1" class="form-control form-control-sm mb-2 w-50"
          (change)="changeQty(_product.Id, _quantity)" [(ngModel)]="_quantity" />
      </div>

      <span class="card-text font-weight-bold d-flex flex-column justify-content-between" *ngIf="showPrice">
        <label>{{'PRODUCT_CARD.STANDARD_PRICE' | translate}}</label>
        <apt-price [record]="_product" [type]="'list'"></apt-price>
      </span>
    </div>
  </div>
</ng-container>

<!-- TODO: Add template when DC-8455 implementation is taken up
<ng-template #popoverTemplate>
</ng-template> -->

./product-card.component.scss

apt-product-card {
    :host{
        display: block;
        width: 100% // Added to fix IE 11 issue
    }
    
    .card .card-body{
        .card-title {
            p {
                height: 3rem;
            }
        }
        .img-container{
            height: 8rem;
        }
        .card-text{
            > span{
                font-size: x-small;
            }
            apt-price {
                font-size: large;
            }
        } 
        &.readonly{
            img{
                max-height: 6rem;
                max-width: 75%;
            }
            .img-container{
                height: 6rem;
            }  
        }
    }
    
    
    .split-items {
        height: 2rem;
        >* {
            border-radius: 0;
            line-height: 15px;
        }
    }
    .product-code{
        max-width: 50%;
    }
    .product-category{
        max-width: 50%;
    }
    .purchased {
       float: right;
       padding-top: 6px;
    }
    button.btn.close{
        margin-top: -5px;
        line-height: 0.9;
    }
    .btn.btn-primary.dropdown-toggle.dropdown-toggle-split{
        height: 31px;
        padding-top: 3px;
      }
    .icons{
        white-space: nowrap;
        i{
            margin-left: 5px;
        }
    }
     .list-purchasedbucket{  
        font-size: 1rem;
        font-weight: 400;
        position: absolute;
        padding-top: 3px;
        
        .fa{
           padding-left: 5px;
          }
       }
    
    label{
        &::before, &::after{
            top: 0.15rem;
        }
    }
    
    .media {
        img {
            max-height: 8rem;
            max-width: 100%;
        }
    
        apt-add-to-cart {
            form.d-flex {
                div:first-child {
                    justify-content: flex-end !important;
                }
            }
        }
    }
    
    .productDescription {
        max-height: 100px;
        overflow: auto;
    }

    
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""