projects/congarevenuecloud/elements/src/lib/line-item-table-row/line-item-table-row.component.ts
Line item table row component is used to display line items on cart, quote, and order detail pages.
import { LineItemTableRowModule } from '@congarevenuecloud/elements';
@NgModule({
imports: [LineItemTableRowModule, ...]
})
export class AppModule {}
```typescript
<apt-line-item-table-row
[cart]="cart"
[parent]="parentItem"
[children]="childItems"
[index]="index"
></apt-line-item-table-row>
OnInit
OnChanges
changeDetection | ChangeDetectionStrategy.OnPush |
encapsulation | ViewEncapsulation.None |
selector | apt-line-item-table-row |
styleUrls | ./line-item-table-row.component.scss |
templateUrl | ./line-item-table-row.component.html |
Properties |
Methods |
Inputs |
constructor(cartService: CartService, userViewMappingService: UserViewMappingService, storefrontService: StorefrontService, configurationService: ConfigurationService, batchSelectionService: BatchSelectionService, exceptionService: ExceptionService, cdr: ChangeDetectorRef, cartItemService: CartItemService)
|
|||||||||||||||||||||||||||
Parameters :
|
cart |
Type : Cart
|
Reference to the current cart. |
children |
Type : any
|
Non primary child line items associated with this row. |
disabled |
Type : boolean
|
Default value : false
|
Flag defines whether line item actions should be disabled or not. |
editableFields |
Type : boolean
|
Default value : true
|
Flag defines whether line item fields should be editable. |
index |
Type : number
|
The index of the row in the parent table |
options |
Type : Array<CartItem | AssetLineItem | QuoteLineItem | OrderLineItem>
|
Taking product options for tax breakup items. |
parent |
Type : CartItem | QuoteLineItem | OrderLineItem
|
Primary line item to show in table. |
readOnly |
Type : boolean
|
Default value : false
|
Flag to check if this component should be read only. |
showCheckbox |
Type : boolean
|
Flag to show checkbox. |
changeItemQuantity | ||||||||
changeItemQuantity(cartItem: CartItem)
|
||||||||
Changes the quantity of the cart item passed to this method.
Parameters :
Returns :
void
|
removeCartItem | ||||||||||||
removeCartItem(item: CartItem, evt)
|
||||||||||||
Removes the provided CartItem from the user's current active cart.
Parameters :
Returns :
void
|
updateAdjustments | ||||||||
updateAdjustments(cartItem: CartItem)
|
||||||||
Changes the adjustment amount and type.
Parameters :
Returns :
void
|
enableAction |
Type : boolean
|
<ng-container *ngIf="parent?.LineType === 'Product/Service' && userView$ | async as userView">
<!-- Changes for mobile view support -->
<tr [attr.data-index]="index" class="d-lg-block d-md-block d-sm-block d-none">
<td width="2%" class="pt-4 pr-0 pl-3" *ngIf="isCartLineItem(parent) && !isCancelledLine(parent)">
<div class="custom-control custom-checkbox custom-checkbox-lg card-title" *ngIf="showCheckbox">
<input [id]="parent.Id" type="checkbox" class="custom-control-input" (change)="handleCheckbox($event)"
[checked]="selected$ | async" />
<label class="custom-control-label d-flex justify-content-between" [for]="parent.Id"></label>
</div>
</td>
<td width="15%" class="pt-4">
<img [src]="parent?.Product?.IconId | image" class="w-100" />
</td>
<td class="col-md-6 pt-4 pr-0">
<div class="h-100 d-flex flex-column border-right pr-3">
<div class="d-flex align-items-center mb-2">
<h5 class="mr-2 mb-0">
<!-- For Orders and Proposal details page dont show line items as link. -->
<ng-container *ngIf="isOrderOrProposal(parent) || readOnly ||enableAction; else showLink">
<span class="productName" id="productName" *ngIf="parent?.Product && parent?.Product[identifier]">
{{parent?.Product?.Name}}
</span>
</ng-container>
<!-- For other pages show line items as link. -->
<ng-template #showLink>
<a class="productName" id="productNameLink" href="javascript:void(0)"
*ngIf="parent?.Product && parent?.Product[identifier]"
[routerLink]="isFavoriteConfigurationItem? ['/products', parent.Product[identifier]] : ['/products', parent.Product[identifier], parent.Id]">
{{parent?.Product?.Name}}
</a>
</ng-template>
<span *ngIf="parent?.HasAttributes || parent?.HasOptions">
<button class="text-muted btn btn-link btn-sm p-0" (click)="showSummary()">
<i class="fas fa-wrench"></i>
</button>
</span>
</h5>
<h6>
<span *ngIf="parent?.AddedBy==='Constraint Rule'" class="badge badge-pill badge-primary">{{
'COMMON.INCLUDED' | translate}}
</span>
</h6>
<ng-template [ngTemplateOutlet]="statusBadge" [ngTemplateOutletContext]="{cartItem: parent}"></ng-template>
</div>
<p class="subtitle" id="subtitle">
<span *ngIf="parent?.Product?.ProductCode" [innerHTML]="parent.Product?.ProductCode"></span>
<span *ngIf="parent?.Product?.Family" [innerHTML]="parent.Product?.Family"></span>
<span *ngIf="parent?.ChargeType" [innerHTML]="parent.ChargeType"></span>
</p>
<small class="description" id="description">
{{parent?.Description}}
</small>
<div *ngIf="!isCartLineItem(parent)">
<!-- Frequency -->
<div class="d-flex flex-flow flex-wrap">
<div class="flex-shrink-1 col-md-4 mb-2 pl-0" *ngIf="parent?.PriceType !== 'One Time'">
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" layout="stacked" label="Frequency"
field="Frequency" [editable]="editableFields"></apt-output-field>
</div>
<!-- Price Type -->
<div class="flex-shrink-1 col-md-4 mb-2 pl-0">
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" layout="stacked" label="Price Type"
field="PriceType" [editable]="editableFields"></apt-output-field>
</div>
<!-- Selling Term -->
<div class="flex-shrink-1 col-md-4 mb-2 pl-0">
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" layout="stacked"
label="SellingTerm" field="SellingTerm" [editable]="editableFields">
</apt-output-field>
</div>
</div>
</div>
<!-- Start Date / End Date -->
<div class="row" *ngIf="!isCartLineItem(parent); else displayFields">
<apt-date-range-input class="flex-shrink-1 col-md-8 pl-0 mb-2"
*ngIf="parent?.PriceType === 'Recurring' || parent?.PriceType === 'Usage'"
[disableStartDate]="parent?.LineStatus?.toLowerCase() ==='cancelled' || parent?.LineStatus?.toLowerCase() ==='renewed'"
(onStartDateChange)="changeItemQuantity(parent)" (onEndDateChange)="changeItemQuantity(parent)"
[cartItem]="parent" [readonly]="readOnly || !(checkModifiableField('StartDate'))" small="true">
</apt-date-range-input>
<div class="flex-shrink-1 col-md-4 mb-2"
[class.pl-0]="parent?.PriceType === 'Recurring' || parent?.PriceType === 'Usage'">
<apt-input-field [(ngModel)]="parent.Quantity" field="Quantity" (change)="changeItemQuantity(parent)"
[entity]="parent" [readonly]="parent?.LineStatus?.toLowerCase() ==='cancelled'"
[labelClass]="'font-weight-light'" label="Quantity" [errorMsg]="'ERROR.INVALID_QUANTITY'"
[asterisk]="false" [required]="true" class="w-75" *ngIf="!readOnly && !(checkModifiableField('Quantity'))" [inputSize]="'small'">
</apt-input-field>
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" field="Quantity" label="Quantity"
class="w-75" *ngIf="readOnly || (checkModifiableField('Quantity'))" [editable]="editableFields">
</apt-output-field>
</div>
</div>
<!-- Adjustment Type / Adjustment Amount -->
<div class="row" *ngIf="!isCartLineItem(parent)">
<div class="flex-shrink-1 col-md-4"> <!--col-4"> -->
<apt-input-field [(ngModel)]="parent.AdjustmentType" [entity]="parent" field="AdjustmentType"
*ngIf="!readOnly && !(checkModifiableField('AdjustmentType'))" [label]="'COMMON.ADJUSTMENT_TYPE' | translate" [labelClass]="'font-weight-light'"
[readonly]="parent?.LineStatus?.toLowerCase() ==='cancelled'" [inputSize]="'small'"></apt-input-field>
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" field="AdjustmentType"
[label]="'COMMON.ADJUSTMENT_TYPE' | translate" *ngIf="readOnly" [editable]="editableFields">
</apt-output-field>
</div>
<div class="flex-shrink-1 col-md-4"> <!--col-4"> -->
<apt-input-field [(ngModel)]="parent.AdjustmentAmount" [entity]="parent" field="AdjustmentAmount"
[labelClass]="'font-weight-light'" *ngIf="!readOnly && !((checkModifiableField('AdjustmentAmount')))" [label]="'COMMON.ADJUSTMENT_AMOUNT' | translate"
(change)="updateAdjustments(parent)" [ellipsis]="true"
[readonly]="parent?.LineStatus?.toLowerCase() ==='cancelled'" minVal="0"
[inputSize]="'small'"></apt-input-field>
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" field="AdjustmentAmount"
[label]="'COMMON.ADJUSTMENT_AMOUNT' | translate" *ngIf="readOnly || ((checkModifiableField('AdjustmentAmount')))" [editable]="editableFields">
</apt-output-field>
</div>
</div>
<ng-template #displayFields>
<div class="row">
<div class="col-lg-4 col-md-12 col-12" *ngFor="let view of userView.slice(0,3); let i=index">
<div *ngIf="i < 3">
<!-- Render input field -->
<ng-container *ngIf="view?.fieldName !== 'StartDate' && view?.fieldName !== 'EndDate'; else date">
<apt-input-field *ngIf="view.isEditable && !isCancelledLine(parent) && !(checkModifiableField(view.fieldName)); else outputField"
[entity]="parent" [(ngModel)]="parent[view.fieldName]" [class]="view.fieldName"
[field]="view.fieldName" [textareaRows]="1" (change)="updateValues(parent)"
[displayFieldType]="'radio'">
</apt-input-field>
</ng-container>
<!-- Render output field -->
<ng-template #outputField>
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" [class]="view.fieldName"
layout="stacked" [label]="view.label" [editable]="editableFields" [field]="view.fieldName">
</apt-output-field>
</ng-template>
<!-- Render Start/End date -->
<ng-template #date>
<apt-date-range-input
[disableStartDate]="parent?.LineStatus?.toLowerCase() ==='cancelled' || parent?.LineStatus?.toLowerCase() ==='renewed'"
(onStartDateChange)="changeItemQuantity(parent)" (onEndDateChange)="changeItemQuantity(parent)"
[cartItem]="parent"
[readonly]="!view?.isEditable || (parent?.PriceType !== 'Recurring' && parent?.PriceType !== 'Usage')|| (checkModifiableField(view.fieldName))"
[displayDate]="view.fieldName">
</apt-date-range-input>
</ng-template>
</div>
</div>
</div>
</ng-template>
</div>
</td>
<td class="pt-4 col-md-3">
<div class="d-flex flex-column h-100 justify-content-between">
<div>
<div class="d-flex justify-content-between align-items-center mt-1" id="unitPrice">
<label class="mr-2 mr-sm-2"> {{'MANAGE_CART.CART_TABLE.UNIT_PRICE' | translate }} </label>
<span>
<span>{{parent?.ListPrice | localCurrency | async}}</span>
</span>
</div>
<div class="d-flex justify-content-between align-items-center mt-1" id="extended">
<label class="mr-2 mr-sm-2"> {{'MANAGE_CART.CART_TABLE.EXTENDED_PRICE' | translate }} </label>
<span> {{parent?.ExtendedPrice | localCurrency | async}} </span>
</div>
<div class="d-flex justify-content-between align-items-center mt-1" id="difference">
<label class="mr-2 mr-sm-2"> {{'MANAGE_CART.CART_TABLE.ADJUSTMENTS' | translate }} </label>
<span> {{(parent?.NetPrice - parent?.ExtendedPrice) | localCurrency | async}} </span>
</div>
<div class="d-flex justify-content-between align-items-center mt-1"
*ngIf="parent?.IncentiveAdjustmentAmount && (enablePromotions$ | async); else applyPromotion">
<button class="btn btn-link text-primary btn-sm text-capitalize p-0"
(click)="promotionModal.openLineItemModal(parent)">{{'PROMOTION.PROMOTION_APPLIED_TO' |
translate}}</button>
<span>{{parent?._metadata?.totalIncentiveAmount | localCurrency | async}}</span>
</div>
<ng-template #applyPromotion>
<div class="d-flex justify-content-between align-items-center mt-1"
*ngIf="(enablePromotions$ | async) && !readOnly">
<button class="btn btn-link text-primary btn-sm text-capitalize p-0 w-100"
(click)="promotionModal.openLineItemModal(parent)">{{'PROMOTION.APPLY_PROMOTION' |
translate}}</button>
</div>
</ng-template>
<div class="d-flex justify-content-between small mt-1"
*ngIf="storefront?.EnableTaxCalculations && showTaxPopupLink();">
<span>
<button placement="auto" [popover]="popTemplate" [outsideClick]="true"
class="btn btn-link text-primary btn-sm text-capitalize p-0" data-toggle="popover"
data-placement="bottom" (click)="openEstimateTaxPopup()">
{{'MANAGE_CART.CART_SUMMARY.TAX' | translate }} </button>
</span>
<span>{{totalEstimatedTax | localCurrency | async}}</span>
</div>
<div class="d-flex justify-content-between align-items-center mt-1" id="netPrice">
<label class="mr-2 mr-sm-2"> {{'MANAGE_CART.CART_TABLE.NET_PRICE' | translate }} </label>
<span> {{parent?.NetPrice | localCurrency | async}} </span>
</div>
<ng-template #popTemplate>
<apt-tax-pophover *ngIf="showTaxPopUp" [taxItems]="taxItems" [totalEstimatedTax]="totalEstimatedTax"
[showTaxPopUp]="true"></apt-tax-pophover>
</ng-template>
</div>
<div class="d-flex justify-content-end my-3">
<button *ngIf="parent?.IsPrimaryLine && !readOnly || (isCartLineItem(parent) && isCancelledLine(parent))"
class="btn btn-outline-danger btn-sm" id="removeButton" (click)="removeCartItem(parent, $event)"
[ladda]="parent?._metadata?._loading" data-style="zoom-in" data-spinner-color="black">
{{'MANAGE_CART.CART_TABLE.REMOVE' | translate }}
</button>
</div>
</div>
</td>
</tr>
<!-- Mobile view support -->
<tr [attr.data-index]="index" class="d-lg-none d-md-none d-sm-none d-block px-3">
<td width="2%" class="pt-2 pr-0 pl-2 pb-0" *ngIf="isCartLineItem(parent) && !isCancelledLine(parent)">
<div class="custom-control custom-checkbox custom-checkbox-lg card-title m-0" *ngIf="!showCheckbox">
<input [id]="parent.Id" type="checkbox" class="custom-control-input" (change)="handleCheckbox($event)"
[checked]="selected$ | async" />
<label class="custom-control-label d-flex justify-content-between" [for]="parent.Id"></label>
</div>
</td>
<td width="100%" class="pt-2 pb-0">
<div class="d-flex align-items-center mb-2">
<h5 class="mr-2 mb-0">
<!-- For Orders and Proposal details page dont show line items as link. -->
<ng-container *ngIf="isOrderOrProposal(parent) || readOnly ||enableAction; else showLink">
<span class="productName" id="productName" *ngIf="parent?.Product && parent?.Product[identifier]">
{{parent?.Product?.Name}}
</span>
</ng-container>
<!-- For other pages show line items as link. -->
<ng-template #showLink>
<a class="productName" id="productNameLink" href="javascript:void(0)"
*ngIf="parent?.Product && parent?.Product[identifier]"
[routerLink]="isFavoriteConfigurationItem? ['/products', parent.Product[identifier]] : ['/products', parent.Product[identifier], parent.Id]">
{{parent?.Product?.Name}}
</a>
</ng-template>
<span *ngIf="parent?.HasAttributes || parent?.HasOptions">
<button class="text-muted btn btn-link btn-sm p-0 pl-3" (click)="showSummary()">
<i class="fas fa-wrench"></i>
</button>
</span>
</h5>
<h6>
<span *ngIf="parent?.AddedBy==='Constraint Rule'" class="badge badge-pill badge-primary">{{
'COMMON.INCLUDED' | translate}}
</span>
</h6>
<ng-template [ngTemplateOutlet]="statusBadge" [ngTemplateOutletContext]="{cartItem: parent}"></ng-template>
</div>
</td>
</tr>
<!-- Mobile view support -->
<tr [attr.data-index]="index" class="d-lg-none d-md-none d-sm-none d-block px-3">
<td width="50%" class="pt-2">
<img [src]="parent?.Product?.IconId | image" class="w-100" />
</td>
</tr>
<!-- Mobile view support -->
<tr [attr.data-index]="index" class="d-lg-none d-md-none d-sm-none d-block px-4">
<td class="pt-2 px-0 col-12">
<div class="h-100 d-flex flex-column">
<p class="subtitle m-0" id="subtitle">
<span *ngIf="parent?.Product?.ProductCode" [innerHTML]="parent.Product?.ProductCode"></span>
<span *ngIf="parent?.Product?.Family" [innerHTML]="parent.Product?.Family"></span>
<span *ngIf="parent?.ChargeType" [innerHTML]="parent.ChargeType"></span>
</p>
<small class="description pb-2" id="description">
{{parent?.Description}}
</small>
<div class="row" *ngIf="!isCartLineItem(parent)">
<!-- Frequency -->
<div class="d-flex flex-flow flex-wrap">
<div class="flex-shrink-1 col-md-4 mb-2" *ngIf="parent?.PriceType !== 'One Time'">
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" layout="stacked" label="Frequency"
field="Frequency" [editable]="editableFields"></apt-output-field>
</div>
<!-- Price Type -->
<div class="flex-shrink-1 col-md-4 mb-2">
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" layout="stacked" label="Price Type"
field="PriceType" [editable]="editableFields"></apt-output-field>
</div>
<!-- Selling Term -->
<div class="flex-shrink-1 col-md-4 mb-2">
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" layout="stacked"
label="SellingTerm" field="SellingTerm" [editable]="editableFields">
</apt-output-field>
</div>
</div>
</div>
<!-- Start Date / End Date -->
<div class="row" *ngIf="!isCartLineItem(parent); else displayFields">
<apt-date-range-input class="flex-shrink-1 col-md-8 pl-0 mb-2"
*ngIf="parent?.PriceType === 'Recurring' || parent?.PriceType === 'Usage'"
[disableStartDate]="parent?.LineStatus?.toLowerCase() ==='cancelled' || parent?.LineStatus?.toLowerCase() ==='renewed'"
(onStartDateChange)="changeItemQuantity(parent)" (onEndDateChange)="changeItemQuantity(parent)"
[cartItem]="parent" [readonly]="readOnly|| (checkModifiableField('Link'))" small="true">
</apt-date-range-input>
<div class="flex-shrink-1 col-md-4 mb-2">
<apt-input-field [(ngModel)]="parent.Quantity" field="Quantity" (change)="changeItemQuantity(parent)"
[entity]="parent" [readonly]="parent?.LineStatus?.toLowerCase() ==='cancelled'"
[labelClass]="'font-weight-light'" label="Quantity" [errorMsg]="'ERROR.INVALID_QUANTITY'"
[asterisk]="false" [required]="true" class="w-75" *ngIf="!readOnly && !(checkModifiableField('Quantity'))" [inputSize]="'small'">
</apt-input-field>
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" field="Quantity" label="Quantity"
class="w-75" *ngIf="readOnly && checkModifiableField('Quantity')" [editable]="editableFields">
</apt-output-field>
</div>
</div>
<!-- Adjustment Type / Adjustment Amount -->
<div class="row" *ngIf="!isCartLineItem(parent)">
<div class="flex-shrink-1 col-md-4"> <!--col-4"> -->
<apt-input-field [(ngModel)]="parent.AdjustmentType" [entity]="parent" field="AdjustmentType"
*ngIf="!readOnly && !(checkModifiableField('AdjustmentType'))" [label]="'COMMON.ADJUSTMENT_TYPE' | translate" [labelClass]="'font-weight-light'"
[readonly]="parent?.LineStatus?.toLowerCase() ==='cancelled'" [inputSize]="'small'"></apt-input-field>
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" field="AdjustmentType"
[label]="'COMMON.ADJUSTMENT_TYPE' | translate" *ngIf="readOnly" [editable]="editableFields">
</apt-output-field>
</div>
<div class="flex-shrink-1 col-md-4"> <!--col-4"> -->
<apt-input-field [(ngModel)]="parent.AdjustmentAmount" [entity]="parent" field="AdjustmentAmount"
[labelClass]="'font-weight-light'" *ngIf="!readOnly && !(checkModifiableField('AdjustmentAmount'))" [label]="'COMMON.ADJUSTMENT_AMOUNT' | translate"
(change)="updateAdjustments(parent)" [ellipsis]="true"
[readonly]="parent?.LineStatus?.toLowerCase() ==='cancelled'" minVal="0"
[inputSize]="'small'"></apt-input-field>
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" field="AdjustmentAmount"
[label]="'COMMON.ADJUSTMENT_AMOUNT' | translate" *ngIf="readOnly || (checkModifiableField('AdjustmentAmount'))" [editable]="editableFields">
</apt-output-field>
</div>
</div>
<ng-template #displayFields>
<div class="row">
<div class="col-lg-4 col-md-12 col-12" *ngFor="let view of userView.slice(0,3); let i=index">
<div *ngIf="i < 3">
<!-- Render input field -->
<ng-container *ngIf="view?.fieldName !== 'StartDate' && view?.fieldName !== 'EndDate'; else date">
<apt-input-field *ngIf="view.isEditable(checkModifiableField(view.fieldName)); else outputField" [entity]="parent"
[(ngModel)]="parent[view.fieldName]" [class]="view.fieldName" [field]="view.fieldName"
[textareaRows]="1" (change)="updateValues(parent)" [displayFieldType]="'radio'">
</apt-input-field>
</ng-container>
<!-- Render output field -->
<ng-template #outputField>
<apt-output-field [record]="parent" [labelClass]="'font-weight-light'" [class]="view.fieldName"
layout="stacked" [label]="view.label" [editable]="editableFields" [field]="view.fieldName">
</apt-output-field>
</ng-template>
<!-- Render Start/End date -->
<ng-template #date>
<apt-date-range-input
[disableStartDate]="parent?.LineStatus?.toLowerCase() ==='cancelled' || parent?.LineStatus?.toLowerCase() ==='renewed'"
(onStartDateChange)="changeItemQuantity(parent)" (onEndDateChange)="changeItemQuantity(parent)"
[cartItem]="parent"
[readonly]="!view?.isEditable || (parent?.PriceType !== 'Recurring' && parent?.PriceType !== 'Usage')|| (checkModifiableField(view.fieldName))"
[displayDate]="view.fieldName">
</apt-date-range-input>
</ng-template>
</div>
</div>
</div>
</ng-template>
</div>
</td>
</tr>
<!-- Mobile view support -->
<tr [attr.data-index]="index" class="d-lg-none d-md-none d-sm-none d-block px-4">
<td class="col-4 p-0 border-top">
<div class="d-flex flex-column h-100 justify-content-between">
<div>
<div class="d-flex justify-content-between align-items-center mt-1" id="unitPrice">
<label class="mr-2 mr-sm-2"> {{'MANAGE_CART.CART_TABLE.UNIT_PRICE' | translate }} </label>
<span>
<span>{{parent?.ListPrice | localCurrency | async}}</span>
</span>
</div>
<div class="d-flex justify-content-between align-items-center mt-1" id="extended">
<label class="mr-2 mr-sm-2"> {{'MANAGE_CART.CART_TABLE.EXTENDED_PRICE' | translate }} </label>
<span> {{parent?.ExtendedPrice | localCurrency | async}} </span>
</div>
<div class="d-flex justify-content-between align-items-center mt-1" id="difference">
<label class="mr-2 mr-sm-2"> {{'MANAGE_CART.CART_TABLE.ADJUSTMENTS' | translate }} </label>
<span> {{(parent?.NetPrice - parent?.ExtendedPrice) | localCurrency | async}} </span>
</div>
<div class="d-flex justify-content-between align-items-center mt-1"
*ngIf="parent?.IncentiveAdjustmentAmount && (enablePromotions$ | async); else applyPromotion">
<button class="btn btn-link text-primary btn-sm text-capitalize p-0"
(click)="promotionModal.openLineItemModal(parent)">{{'PROMOTION.PROMOTION_APPLIED_TO' |
translate}}</button>
<span>{{parent?._metadata?.totalIncentiveAmount | localCurrency | async}}</span>
</div>
<ng-template #applyPromotion>
<div class="d-flex justify-content-between align-items-center mt-1"
*ngIf="(enablePromotions$ | async) && !readOnly">
<button class="btn btn-link text-primary btn-sm text-capitalize p-0 w-100"
(click)="promotionModal.openLineItemModal(parent)">{{'PROMOTION.APPLY_PROMOTION' |
translate}}</button>
</div>
</ng-template>
<div class="d-flex justify-content-between small mt-1"
*ngIf="storefront?.EnableTaxCalculations && showTaxPopupLink();">
<span>
<button placement="auto" [popover]="popTemplate" [outsideClick]="true"
class="btn btn-link text-primary btn-sm text-capitalize p-0" data-toggle="popover"
data-placement="bottom" (click)="openEstimateTaxPopup()">
{{'MANAGE_CART.CART_SUMMARY.TAX' | translate }} </button>
</span>
<span>{{totalEstimatedTax | localCurrency | async}}</span>
</div>
<div class="d-flex justify-content-between align-items-center mt-1" id="netPrice">
<label class="mr-2 mr-sm-2"> {{'MANAGE_CART.CART_TABLE.NET_PRICE' | translate }} </label>
<span> {{parent?.NetPrice | localCurrency | async}} </span>
</div>
<ng-template #popTemplate>
<apt-tax-pophover *ngIf="showTaxPopUp" [taxItems]="taxItems" [totalEstimatedTax]="totalEstimatedTax"
[showTaxPopUp]="true"></apt-tax-pophover>
</ng-template>
</div>
<div class="d-flex justify-content-end my-2">
<button
*ngIf="(parent?.IsPrimaryLine && !readOnly) || (isCartLineItem(parent) && isCancelledLine(parent))"
class="btn btn-outline-danger btn-sm" id="removeButton" (click)="removeCartItem(parent, $event)"
[ladda]="parent?._metadata?._loading" data-style="zoom-in" data-spinner-color="black">
{{'MANAGE_CART.CART_TABLE.REMOVE' | translate }}
</button>
</div>
</div>
</td>
</tr>
<tr *ngIf="children">
<td class="border-0 p-0 w-25" colspan="4">
<div class="accordion">
<!-- Additional info section: show additional info section when there are more than three cart item fields to be shown -->
<div *ngIf="isCartLineItem(parent) && userView.length > 3">
<apt-additional-information [parent]="parent" [cart]="cart" [editableFields]="editableFields"
[userView]="userView" [quantity]="quantity" [enableOneTime]="enableOneTime" >
</apt-additional-information>
</div>
<div>
<apt-table-row-sub-item *ngFor="let subItem of children; trackBy: trackByFn" [subItem]="subItem"
[readOnly]="readOnly" [userView]="userView" [editableFields]="editableFields" [cart]="parent.Configuration"
[showCustomFields]=true [isFavoriteConfigurationItem]="isFavoriteConfigurationItem">
</apt-table-row-sub-item>
</div>
</div>
</td>
</tr>
</ng-container>
<ng-template #statusBadge let-cartItem="cartItem">
<ng-container [ngSwitch]="cartItem?.LineStatus">
<span class="badge ml-2 badge-danger" *ngSwitchCase="'Cancelled'">
{{cartItem?.LineStatus}}
</span>
<span class="badge ml-2 badge-warning" *ngSwitchCase="'Renewed'">
{{cartItem?.LineStatus}}
</span>
<span class="badge ml-2 badge-info" *ngSwitchCase="'Upgraded'">
{{cartItem?.LineStatus}}
</span>
<span class="badge ml-2 badge-warning" *ngSwitchCase="'Amended'">
{{cartItem?.LineStatus}}
</span>
<span class="badge ml-2 badge-warning" *ngSwitchCase="'Incremented'">
{{cartItem?.LineStatus}}
</span>
<span class="badge ml-2 badge-light" *ngSwitchCase="'Existing'">
{{cartItem?.LineStatus}}
</span>
</ng-container>
</ng-template>
<apt-pr-modal [cart]="cart" #promotionModal></apt-pr-modal>
<apt-product-configuration-summary *ngIf="renderSummary" [product]="parent?.Product.Id" [relatedTo]="parent"
[changes]="changes" [showActionButtons]="!isFavoriteConfigurationItem" [cart]="cart" #productConfiguration>
</apt-product-configuration-summary>
./line-item-table-row.component.scss
apt-line-item-table-row {
:host {
display: contents;
font-size: smaller;
}
.productName {
font-size: 1rem;
}
.description {
max-height: 50px;
overflow-y: hidden;
}
.quantity {
width: 4rem;
}
u {
text-decoration: underline;
cursor: pointer;
}
.subtitle>span:not(:last-child) {
&:after {
margin: 0 0.3rem;
content: "|";
}
}
@media all and (-ms-high-contrast: none),
(-ms-high-contrast: active) {
/* IE10+ CSS styles go here */
p.description {
max-width: 400px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
tr[data-index="0"] {
td {
border-top: none;
}
}
.adjustment-type-dropdown {
width: 50%;
padding-right: 1.875rem;
>apt-input-field {
>.form-group {
>div {
ng-select {
border: none;
background: none;
}
}
}
}
}
.adjustment-type-dropdown {
>apt-input-field {
>.form-group {
>div {
.ng-select.picklist .ng-select-container {
min-height: 2.1rem;
max-width: 12em;
>.ng-value-container {
padding-left: 0;
}
}
}
}
}
}
.adjustment-type-dropdown {
>apt-input-field {
>.form-group {
>div {
.ng-select.picklist .ng-dropdown-panel {
width: auto;
}
}
}
}
}
.badge-pill.badge-primary{
font-size: 0.5rem;
}
}