File

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

Description

Product configuration component is used to show the hierarchical view of the configurations for a given product or cart line item.

Preview

This component is responsible for loading configuration of product

Usage

Example :
import { ProductConfigurationModule } from '@congarevenuecloud/elements';
@NgModule({
imports: [ProductConfigurationModule, ...]
})
export class AppModule {}
Example :
```typescript
<apt-product-configuration
              [product]="product.Id"
              [relatedTo]="parent"
[accordion]="true"
></apt-product-configuration>
Example :

Implements

OnChanges OnDestroy

Metadata

Index

Properties
Methods
Inputs

Constructor

constructor(cdr: ChangeDetectorRef, productOptionService: ProductOptionService, cartItemService: CartItemService, secondaryCartService: SecondaryCartService, primaryCartService: CartService, productConfigurationService: ProductConfigurationService, araiService: AppliedRuleActionInfoService, productService: ProductService)
Parameters :
Name Type Optional
cdr ChangeDetectorRef No
productOptionService ProductOptionService No
cartItemService CartItemService No
secondaryCartService SecondaryCartService No
primaryCartService CartService No
productConfigurationService ProductConfigurationService No
araiService AppliedRuleActionInfoService No
productService ProductService No

Inputs

accordion
Type : boolean
Default value : true

Flag to determine the accordion expand/collapse.

discovery
Type : string
Default value : null

The flag is of type string . It has productDetailsPage & cartItemDetailsPage as its string value. EX: discovery = 'productDetailsPage;cartItemDetailsPage' If string 'productDetailsPage' is set , allows to configure product before add to cart. If value not set as 'productDetailsPage', then only shows READ-ONLY version of config component with default configuration and this is the default behaviour. Similarly, 'cartItemDetailsPage' value is set, allows configure before update the bundle. If 'cartItemDetailsPage' value is not set, do not allow configure before update the bundle. 'CartItemDetailsPage' It's a work in progress. Therefore, configure before update the bundle is not supported.

product
Type : string | Product

The primitive id of the product to render the configuration or the product record.

relatedTo
Type : CartItem

The primitive id of the parent product line item that should be used to render the configuration.

Methods

assignCartItems
assignCartItems(component: ProductOptionComponent, parentBundleNumber: number, cartItems: Array)

Method traverses the component and its children and assigns the cart items to their corresponding component

Parameters :
Name Type Optional Description
component ProductOptionComponent No

The input component

parentBundleNumber number No

The starting components parent bundle number

cartItems Array<CartItem> No

Array of cart items to assign

Returns : void
getAllComponents
getAllComponents(view: ConfigurationView)

This method will return list of option product

Parameters :
Name Type Optional
view ConfigurationView No
Returns : Array<ProductOptionComponent>
getComponentArray
getComponentArray(component: ProductOptionComponent)

Method returns a flat array of components and their children of the product option

Parameters :
Name Type Optional Description
component ProductOptionComponent No

it is an object type of ProductOptionComponent

Returns : Array<ProductOptionComponent>
getProductOptionComponent
getProductOptionComponent(productId: string, view: ConfigurationView)

Method returns an instance of product option component for the product Id passed.

Parameters :
Name Type Optional Description
productId string No

String value representing the product Id.

view ConfigurationView No
isTriggeringProduct
isTriggeringProduct(rules: Array<AppliedRuleActionInfo>, componentId: string, bundleProduct: CartItem)

This function checks if a given component ID triggers any of the given rules.

Parameters :
Name Type Optional Description
rules Array<AppliedRuleActionInfo> No
  • An array of constraint rules.
componentId string No
  • The ID of the component being checked.
bundleProduct CartItem No
Returns : boolean
  • Boolean Whether the component ID triggers any of the given rules.
toggleOption
toggleOption(component: ProductOptionComponent, group: ProductOptionGroup, reference: string, view: ConfigurationView, evt?: any, showLoader: boolean)

This function allows you to add or remove options for a product.

Parameters :
Name Type Optional Default value Description
component ProductOptionComponent No

object of type ProductOptionComponent required for add /remove on toggling.

group ProductOptionGroup No

Product option group of type ProductOptionGroup of the option toggled.

reference string No
view ConfigurationView No

An interface Object of type ConfigurationView which consist product, cart, rule list.

evt any Yes

Optional Parameters for events of type any.

showLoader boolean No false

Optional Parameters to show loader on button.

Returns : void

Properties

attributeChanged
Type : boolean
Default value : false

Flag determines changes in attribute.

cart$
Type : Observable<Cart>

Cart$ holds Observable of cart

collapseAll
Type : boolean
Default value : true

Used for all configuration accordian collapse.

onConfigChange
Type : boolean
Default value : false

Flag determines config change.

productQuantity
Type : number
Default value : 1

Used to hold quantity of product.

readOnly
Type : boolean
Default value : false
searchText
Type : string
Default value : null

Search query to filter configuration.

view$
Type : BehaviorSubject<ConfigurationView>
Default value : new BehaviorSubject<ConfigurationView>(null)

The view object used to hold information for rendering the view, of type ConfigurationView.

<div class="card">
    <div class="card-body">
        <ng-container *ngIf="(view$ | async) as view; else loading">
            <ng-container *ngIf="view?.product?.OptionGroups?.length > 0 || view?.product?.HasAttributes && view?.product?.AttributeGroups?.length > 0
                            ; else empty">
                <div>
                    <div class="d-flex justify-content-between mb-2">

                        <form class="input-group input-group-sm col-lg-4 col-md-4 col-sm-9 col-9 d-flex align-items-center pl-0">
                            <div class="input-group-append">
                                <button class="btn btn-link">
                                    <i class="fas fa-search"></i>
                                </button>
                            </div>
                            <input type="search" class="form-control"
                                placeholder="{{'COMMON.SEARCH_CONFIGURATION' | translate}}" [(ngModel)]="searchText"
                                name="searchText" (ngModelChange)="searchChange()">
                        </form>
                        <div>
                            <button class="btn btn-link px-2" [disabled]="accordion"
                                (click)="accordion = true; collapseAll = false;">
                                <i class="fa fa-angle-double-up fa-lg" title="Collapse All"></i>
                            </button>
                            <button class="btn btn-link px-2" [disabled]="!accordion"
                                (click)="accordion = false; collapseAll = true;">
                                <i class="fa fa-angle-double-down fa-lg" title="Expand All"></i>
                            </button>
                        </div>
                    </div>

                    <div class="accordion" id="optionAccordion">
                        <ng-container *ngIf="view?.product?.AttributeGroups?.length > 0">
                            <apt-product-attribute [product]="view.product" [relatedTo]="relatedTo"
                                [(productAttributeValue)]="view.product._metadata.item.AttributeValue"
                                (productAttributeValueChange)="onAttributeChange($event, view)" [readOnly]="readOnly"
                                container="optionAccordion" (attributeValueChange)="handleAttributeValueChange($event)"
                                [accordion]="accordion" [collapseAll]="collapseAll">
                            </apt-product-attribute>
                        </ng-container>

                        <ng-container *ngIf="view?.product?.HasOptions && view?.product?.OptionGroups?.length > 0">
                            <div class="card border"
                                *ngFor="let productOptionGroup of view?.product?.OptionGroups; let optionIndex = index; trackBy: trackById"
                                [hidden]="productOptionGroup.get('hide')">
                                <ng-container *ngIf="!productOptionGroup?.IsHidden">
                                    <div [id]="'ac' + productOptionGroup.Id" class="accordion">
                                        <div class="card-header px-2 py-1">
                                            <h2 class="mb-0 d-flex justify-content-between align-items-center">
                                                <button class="btn btn-link chevron" type="button"
                                                    data-toggle="collapse"
                                                    [attr.data-target]="'#a' + productOptionGroup.Id"
                                                    [attr.aria-expanded]="((optionIndex + view?.product?.AttributeGroups?.length === 0 || productOptionGroup._metadata.expand) && collapseAll) || !accordion ? 'true' : 'false'">
                                                    {{productOptionGroup?.OptionGroup?.Label}}
                                                </button>
                                                <apt-alert [record]="productOptionGroup"
                                                    message="ERROR.OPTION_GROUP.ERROR" layout="inline"  [hideAlert]="true"
                                                    *ngIf="!readOnly && productOptionGroup?.ModifiableType !== 'Fixed'">
                                                </apt-alert>
                                            </h2>
                                        </div>

                                        <div [id]="'a' + productOptionGroup.Id" class="collapse"
                                            [class.show]="((optionIndex + view?.product?.AttributeGroups?.length === 0 || productOptionGroup._metadata.expand) && collapseAll) || !accordion"
                                            [attr.data-parent]="'#ac' + productOptionGroup.Id">
                                            <div class="card-body">
                                                <div
                                                    *ngIf="productOptionGroup?.IsPicklist &&  productOptionGroup.MaxOptions === 1 && productOptionGroup.MinOptions === 1">
                                                    <ng-template [ngTemplateOutlet]="picklistTemplate"
                                                        [ngTemplateOutletContext]="{componentList: productOptionGroup?.Options, parent: productOptionGroup.Id, group: productOptionGroup}">
                                                    </ng-template>
                                                </div>
                                                <div *ngIf="!productOptionGroup?.IsPicklist">
                                                    <ng-template [ngTemplateOutlet]="productOptionGroupTemplate"
                                                        [ngTemplateOutletContext]="{optionGroupList: productOptionGroup?.ChildOptionGroups, parent: productOptionGroup.Id}">
                                                    </ng-template>
                                                    <div class="pl-4">
                                                        <ng-template [ngTemplateOutlet]="componentListTemplate"
                                                            [ngTemplateOutletContext]="{componentList: productOptionGroup?.Options, parent: productOptionGroup.Id, group: productOptionGroup}">
                                                        </ng-template>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </ng-container>
                            </div>
                        </ng-container>
                    </div>

                    <ng-template #productOptionGroupTemplate let-optionGroupList="optionGroupList" let-parent="parent"
                        let-parentProduct="parentProduct">
                        <div class="accordion" [id]="parent">
                            <div *ngFor="let subProductOptionGroup of optionGroupList; let categoryIndex = index; let l = last; let f = first; trackBy: trackById"
                                class="mb-3">
                                <ng-container *ngIf="!subProductOptionGroup?.IsHidden">
                                    <h5 class="d-flex justify-content-between align-items-center border-bottom">
                                        <button class="btn btn-link chevron" type="button" data-toggle="collapse"
                                            [attr.data-target]="'#' + parent + '-' + subProductOptionGroup.Id"
                                            [attr.aria-expanded]="((subProductOptionGroup._metadata.expand) && collapseAll) || !accordion ? 'true' : 'false'">
                                            {{subProductOptionGroup?.OptionGroup?.Label}}
                                        </button>
                                        <apt-alert message="ERROR.OPTION_GROUP.ERROR" layout="inline"
                                            [record]="subProductOptionGroup" [hideAlert]="true"
                                            *ngIf="!readOnly && subProductOptionGroup?.ModifiableType !== 'Fixed'"></apt-alert>
                                    </h5>

                                    <div [id]="parent + '-' + subProductOptionGroup.Id" class="collapse pl-lg-4 pl-md-4 pl-sm-2 pl-2"
                                        [attr.data-parent]="'#' + parent"
                                        [class.show]="((subProductOptionGroup._metadata.expand) && collapseAll) || !accordion">
                                        <div class="mt-4"
                                            *ngIf="subProductOptionGroup?.IsPicklist &&  subProductOptionGroup.MaxOptions === 1 && subProductOptionGroup.MinOptions === 1">
                                            <ng-template [ngTemplateOutlet]="picklistTemplate"
                                                [ngTemplateOutletContext]="{componentList: subProductOptionGroup?.Options, parent: subProductOptionGroup.Id, group: subProductOptionGroup}">
                                            </ng-template>
                                        </div>
                                        <div *ngIf="!subProductOptionGroup?.IsPicklist">
                                            <ng-template [ngTemplateOutlet]="componentListTemplate"
                                                [ngTemplateOutletContext]="{componentList: subProductOptionGroup?.Options, parent: parent + '-' + subProductOptionGroup.Id, group: subProductOptionGroup}">
                                            </ng-template>
                                        </div>
                                    </div>
                                </ng-container>
                            </div>
                        </div>
                    </ng-template>

                    <ng-template #componentListTemplate let-componentList="componentList" let-parent="parent"
                        let-group="group">
                        <ng-container
                            *ngIf="componentList?.length > 0 || group?.ChildOptionGroups?.length > 0; else cLoading">
                            <ng-container class="custom-border-bottom"
                                *ngFor="let component of componentList; let f = first; let l = last; trackBy: trackById">
                                <div class="option" *ngIf="!component.get('hidden')" [class.border-bottom]="!l"
                                    [hidden]="component.get('hide')">

                                    <ng-template
                                        *ngIf="component?.ComponentProduct?._metadata?.item?.AssetLineItem?.PriceType === 'One Time'"
                                        [ngTemplateOutlet]="readOnlyComponent" [ngTemplateOutletContext]="{
                                                                component: component,
                                                                parent: parent,
                                                                selected: isOptionSelected(component),
                                                                cartItem: component?.ComponentProduct?._metadata?.item,
                                                                group: group
                                                            }"></ng-template>

                                    <ng-template
                                        *ngIf="component?.ComponentProduct?._metadata?.item?.AssetLineItem?.PriceType !== 'One Time'"
                                        [ngTemplateOutlet]="componentTemplate" [ngTemplateOutletContext]="{
                                                            component: component, 
                                                            parent: parent, 
                                                            selected: isOptionSelected(component), 
                                                            cartItem: component?.ComponentProduct?._metadata?.item,
                                                            group: group}">
                                    </ng-template>
                                </div>
                            </ng-container>
                        </ng-container>
                        <ng-template #cLoading>
                            <div class="d-flex justify-content-center pt-5">
                                <apt-dots></apt-dots>
                            </div>
                        </ng-template>
                    </ng-template>

                    <ng-template #picklistTemplate let-componentList="componentList" let-parent="parent"
                        let-group="group">
                        <ng-container
                            *ngIf="componentList?.length > 0 || group?.ChildOptionGroups?.length > 0; else cLoading">
                            <ng-select [items]="componentList" class="optionPicklist"
                                placeholder="{{'PRODUCT_DETAILS.SELECT_ONE_OPTION' | translate}}"
                                labelForId="group.Id+'-'+ parent.Id" [(ngModel)]="group._metadata.componentName"
                                (ngModelChange)="isPicklistChangeValue($event, group, view)" [disabled]="readOnly"
                                bindLabel="ComponentProduct.Name" [virtualScroll]="true">
                                <ng-template ng-option-tmp let-item="item" let-index="index">
                                    <div class="d-flex py-2"
                                        [ngClass]="{'border-bottom': index !== componentList?.length-1}">
                                        <div class="d-flex flex-grow-1">
                                            <div class="d-flex cr-popover-container">
                                                <div class="image-container d-flex justify-content-center">
                                                    <img [src]="item?.ComponentProduct?.IconId | image" height="50">
                                                </div>
                                            </div>
                                            <div class="mx-3">
                                                <p class="m-0 font-weight-bold d-flex">{{item?.ComponentProduct?.Name}}
                                                </p>
                                                <small
                                                    class="d-block desc">{{item?.ComponentProduct?.Description}}</small>
                                            </div>
                                        </div>
                                        <div class="width-picklist-fixed border-left d-flex">
                                            <div class="form-group col">
                                                <label>{{'COMMON.PRICE' | translate}}</label>
                                                <h5 class="pt-1">
                                                    <apt-price [record]="item?.ComponentProduct"
                                                        [type]="'list'"></apt-price>
                                                </h5>
                                            </div>
                                        </div>
                                    </div>
                                </ng-template>
                            </ng-select>
                            <ng-template *ngIf="group._metadata.componentName" [ngTemplateOutlet]="componentTemplate"
                                [ngTemplateOutletContext]="{
                                                component: group._metadata?.optionSelected, 
                                                parent: group.Id, 
                                                selected: !!group._metadata.componentName, 
                                                cartItem: group._metadata?.optionSelected?.ComponentProduct?._metadata?.item,
                                                group: group,
                                                isPicklist: true}"></ng-template>
                        </ng-container>
                        <ng-template #cLoading>
                            <div class="d-flex justify-content-center pt-5">
                                <apt-dots></apt-dots>
                            </div>
                        </ng-template>
                    </ng-template>

                    <ng-template #readOnlyComponent let-component="component" let-parent="parent"
                        let-cartItem="cartItem" let-group="group" let-selected="selected">
                        <div class="d-flex py-2">
                            <div class="d-flex flex-grow-1">
                                <div class="d-flex">
                                    <div class="mr-2">
                                        <i class="fa fa-check-square-o fa-lg"></i>
                                    </div>
                                    <div class="image-container d-flex justify-content-center">
                                        <img [src]="component?.ComponentProduct?.IconId | image" height="50">
                                    </div>
                                </div>
                                <div class="mx-3">
                                    <p class="m-0 font-weight-bold">{{component?.ComponentProduct?.Name}}</p>
                                    <small class="d-block desc">{{component?.ComponentProduct?.Description}}</small>
                                </div>
                            </div>
                            <div class="width-fixed border-left d-flex">
                                <div class="form-group col">
                                    <label>{{'COMMON.PRICE' | translate}}</label>
                                    <h5 class="pt-1">
                                        <apt-price [record]="component?.ComponentProduct" [quantity]="1"
                                            [type]="'list'"></apt-price>
                                    </h5>
                                </div>

                                <div class="form-group col">
                                    <label for="qty">{{'COMMON.QTY' | translate}}</label>
                                    <input type="number" min="0" class="form-control form-control-sm text-center"
                                        [disabled]="true" id="qty" [value]="cartItem?.Quantity" name="quantity">
                                </div>
                            </div>
                        </div>

                        <div class="pl-lg-3" [hidden]="!selected">
                            <ng-container
                                *ngIf="component?.ComponentProduct?._metadata?.item && component?.ComponentProduct?.HasAttributes">
                                <apt-product-attribute [product]="component.ComponentProduct"
                                    [relatedTo]="component.ComponentProduct._metadata.item"
                                    [container]="parent + '-' + component.Id" lineType="Option"
                                    [(productAttributeValue)]="component.ComponentProduct._metadata.item.AttributeValue"
                                    (productAttributeValueChange)="onAttributeChange($event, view)"
                                    [readOnly]="readOnly" (attributeValueChange)="handleAttributeValueChange($event)"
                                    [accordion]="accordion" [collapseAll]="collapseAll"></apt-product-attribute>
                            </ng-container>


                            <ng-template *ngIf="component?.ComponentProduct?._metadata?.item?.Id"
                                [ngTemplateOutlet]="productOptionGroupTemplate"
                                [ngTemplateOutletContext]="{optionGroupList: component?.ComponentProduct?.OptionGroups, parent: parent + '-' + component.Id, parentProduct: component?.ComponentProduct}">
                            </ng-template>
                        </div>
                    </ng-template>

                    <ng-template #componentTemplate let-component="component" let-parent="parent"
                        let-selected="selected" let-cartItem="cartItem" let-group="group" let-isPicklist="isPicklist">
                        <div class="d-lg-flex d-md-flex py-lg-2 py-md-2 py-sm-3 py-3">
                            <div class="d-flex flex-grow-1">
                                <div class="d-flex cr-popover-container">
                                    <div class="custom-control custom-checkbox"
                                        *ngIf="!component?._metadata?.processing; else spinner">
                                        <input type="checkbox" class="custom-control-input"
                                            [(ngModel)]="component._metadata.isDirty" [id]="parent + '-' + component.Id"
                                            [checked]="selected"
                                            (ngModelChange)="toggleOption(component, group, parent, view, component?._metadata?.disabled)"
                                            [disabled]="group?._metadata?.summary?.disabled || component?._metadata?.disabled || group.ModifiableType === 'Fixed' || readOnly">
                                        <label class="custom-control-label"
                                            [for]="parent + '-' + component.Id">&nbsp;</label>
                                    </div>
                                    <ng-template #spinner><apt-spinner class="pr-1 mr-2"
                                            [large]="false"></apt-spinner></ng-template>

                                    <div class="image-container col-auto row-auto p-0 justify-content-center d-lg-block d-md-block d-sm-none d-none">
                                        <img [src]="component?.ComponentProduct?.IconId | image" height="50">
                                    </div>
                                </div>
                                <div class="mx-lg-3 mx-md-3 mx-sm-0 mx-0">
                                    <p class="m-0 font-weight-bold d-flex">{{component?.ComponentProduct?.Name}}
                                        <i *ngIf='!readOnly && component?.IsRequired'
                                            class="fa fa-asterisk text-danger fa-xs" aria-hidden="true"></i>
                                        <apt-popover *ngIf="!readOnly" [placement]="'right'" [constraintRules]="isTriggeringProduct(component?.ComponentProduct?._metadata?.rules, component?.ComponentProduct?.Id, view?.product?._metadata?.item)
                                            ? component?.ComponentProduct?._metadata?.rules : null"
                                            [outsideClick]="false"
                                            [isClose]="component?.ComponentProduct?._metadata?.hidePopover">
                                            <i role="button" class="fas fa-info-circle ml-2 text-primary"
                                                *ngIf="isTriggeringProduct(component?.ComponentProduct?._metadata?.rules, component?.ComponentProduct?.Id, view?.product?._metadata?.item)"></i>
                                        </apt-popover>
                                    </p>
                                    <small class="d-block desc">{{component?.ComponentProduct?.Description}}</small>
                                    <apt-alert [record]="component" message="ERROR.OPTION_GROUP.ERROR" layout="inline" [hideAlert]="true"
                                        *ngIf="!readOnly && productOptionGroup?.ModifiableType !== 'Fixed'">
                                    </apt-alert>
                                </div>
                            </div>
                            <div class="border-left d-lg-flex d-md-flex d-sm-none d-none px-3 py-4" *ngIf="selected && cartItem">
                                <div class="custom-control custom-checkbox">
                                    <input type="checkbox" class="custom-control-input"
                                        [(ngModel)]="cartItem.IsOptional" [id]="cartItem.Id"
                                        [checked]="cartItem.IsOptional"
                                        (ngModelChange)="changeItemToOptional($event, cartItem, component)">
                                    <label class="custom-control-label pl-1 pt-1"
                                        [for]="cartItem.Id">{{'PRODUCT_DETAILS.IS_OPTIONAL' | translate}}</label>
                                </div>
                            </div>
                            <div class="d-lg-none d-md-none d-sm-flex d-flex pl-4 ml-1 py-2" *ngIf="selected && cartItem">
                                <div class="custom-control custom-checkbox">
                                    <input type="checkbox" class="custom-control-input"
                                        [(ngModel)]="cartItem.IsOptional" [id]="cartItem.Id"
                                        [checked]="cartItem.IsOptional"
                                        (ngModelChange)="changeItemToOptional($event, cartItem, component)">
                                    <label class="custom-control-label pl-1 pt-1"
                                        [for]="cartItem.Id">{{'PRODUCT_DETAILS.IS_OPTIONAL' | translate}}</label>
                                </div>
                            </div>
                            <div class="width-fixed border-left d-lg-flex d-md-flex d-sm-none d-none">
                                <div class="form-group col">
                                    <label>{{'COMMON.PRICE' | translate}}</label>
                                    <h5 class="pt-1">
                                        <ng-container
                                            *ngIf="!component?.ComponentProduct?._metadata?.item; else itemPrice">
                                            <apt-price [record]="component?.ComponentProduct"
                                                [type]="'list'"></apt-price>
                                        </ng-container>
                                        <ng-template #itemPrice>
                                            <span>{{component?.ComponentProduct?._metadata?.item?.NetPrice |
                                                localCurrency | async}}</span>
                                        </ng-template>
                                    </h5>
                                </div>

                                <div class="form-group col">
                                    <label for="qty">{{'COMMON.QTY' | translate}}</label>
                                    <i role="button" class="fas fa-info-circle ml-2 text-primary"
                                        [tooltip]="'COMMON.QUANTITY_NOT_MODIFIABLE' | translate"
                                        *ngIf="!readOnly && ((selected && !component?.IsModifiable) || group?.ModifiableType === 'Fixed')"></i>
                                    <input type="number" [min]="component?.IsRequired ? 1 : 0"
                                        class="form-control form-control-sm text-center"
                                        *ngIf="cartItem; else disabledInput"
                                        [disabled]="!selected || group?.ModifiableType === 'Fixed' || !component?.IsModifiable"
                                        id="qty" placeholder="1" name="quantity"
                                        (change)="emitChange(view); changeItemQuantity(cartItem, component)"
                                        [(ngModel)]="!selected ? 0 : cartItem.Quantity">
                                    <ng-template #disabledInput>
                                        <input type="number" min="0" class="form-control form-control-sm text-center"
                                            [disabled]="true" id="qty" placeholder="1" name="quantity">
                                    </ng-template>
                                </div>
                            </div>
                            <div class="width-fixed d-lg-none d-md-none d-sm-block d-block pl-3">
                                <div class="form-group col">
                                    <label>{{'COMMON.PRICE' | translate}}</label>
                                    <h5 class="pt-1">
                                        <ng-container
                                            *ngIf="!component?.ComponentProduct?._metadata?.item; else itemPrice">
                                            <apt-price [record]="component?.ComponentProduct"
                                                [type]="'list'"></apt-price>
                                        </ng-container>
                                        <ng-template #itemPrice>
                                            <span>{{component?.ComponentProduct?._metadata?.item?.NetPrice |
                                                localCurrency | async}}</span>
                                        </ng-template>
                                    </h5>
                                </div>

                                <div class="form-group col">
                                    <label for="qty">{{'COMMON.QTY' | translate}}</label>
                                    <i role="button" class="fas fa-info-circle ml-2 text-primary"
                                        [tooltip]="'COMMON.QUANTITY_NOT_MODIFIABLE' | translate"
                                        *ngIf="!readOnly && ((selected && !component?.IsModifiable) || group?.ModifiableType === 'Fixed')"></i>
                                    <input type="number" [min]="component?.IsRequired ? 1 : 0"
                                        class="form-control form-control-sm text-center"
                                        *ngIf="cartItem; else disabledInput"
                                        [disabled]="!selected || group?.ModifiableType === 'Fixed' || !component?.IsModifiable"
                                        id="qty" placeholder="1" name="quantity"
                                        (change)="emitChange(view); changeItemQuantity(cartItem, component)"
                                        [(ngModel)]="!selected ? 0 : cartItem.Quantity">
                                    <ng-template #disabledInput>
                                        <input type="number" min="0" class="form-control form-control-sm text-center"
                                            [disabled]="true" id="qty" placeholder="1" name="quantity">
                                    </ng-template>
                                </div>
                            </div>
                        </div>

                        <div class="pl-lg-3 pl-md-0 pl-sm-0 pl-0" [hidden]="!selected">
                            <ng-container
                                *ngIf="component?.ComponentProduct?._metadata?.item && component?.ComponentProduct?.HasAttributes">
                                <apt-product-attribute [product]="component.ComponentProduct"
                                    [relatedTo]="component.ComponentProduct._metadata.item"
                                    [container]="parent + '-' + component.Id" lineType="Option"
                                    [(productAttributeValue)]="component.ComponentProduct._metadata.item.AttributeValue"
                                    (productAttributeValueChange)="onAttributeChange($event, view)"
                                    [readOnly]="readOnly" (attributeValueChange)="handleAttributeValueChange($event)"
                                    [accordion]="accordion" [collapseAll]="collapseAll"></apt-product-attribute>
                            </ng-container>


                            <ng-template *ngIf="component?.ComponentProduct?._metadata?.item?.Id"
                                [ngTemplateOutlet]="productOptionGroupTemplate"
                                [ngTemplateOutletContext]="{optionGroupList: component?.ComponentProduct?.OptionGroups, parent: 'ad' + parent + '-' + component.Id, parentProduct: component?.ComponentProduct}">
                            </ng-template>
                        </div>
                    </ng-template>
                </div>
            </ng-container>
            <ng-template #empty>
                <div class="d-flex justify-content-center flex-column align-items-center py-5 my-5">
                    <i class="fa fa-cog fa-5x text-primary xl text-faded"></i>
                    <div class="mt-4">{{'CONFIGURATION.NO_CONFIGURATION' | translate}}</div>
                </div>
            </ng-template>
        </ng-container>
        <ng-template #loading>
            <div class="d-flex justify-content-center py-5">
                <apt-dots></apt-dots>
            </div>
        </ng-template>
    </div>
</div>

./product-configuration.component.scss

.accordion {
  .cr-popover-container {
    min-width: 10%;
  }

  .image-container {
    width: 64px;

    img {
      max-height: 50px;
      max-width: 64px;
    }
  }

  .form-group {
    margin-bottom: 0;
  }

  input {
    max-width: 70px;
  }

  .custom-control {
    margin-top: -3px;
  }

  .width-fixed {
    min-width: 14rem;
  }

  .desc {
    max-height: 40px;
    overflow-y: hidden;
  }

  .card {
    overflow: visible;
  }
}

.search {
  min-width: 300px;
}

apt-cr-popover {
  .custom-checkbox {
    input[type="checkbox"][disabled] {
      + label {
        pointer-events: none;
      }
    }
  }
}

@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
  /* IE10+ CSS styles go here */
  apt-product-configuration
    div.accordion
    div.card
    div.option
    div.py-2
    div.mx-3 {
    margin-left: 3rem;
  }
}

.input-group-append {
  position: absolute;
  z-index: 1;
}

.input-group {
  input {
    border-radius: 0.3rem;
    padding-left: 2rem !important;
    z-index: 0;
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""