projects/congarevenuecloud/elements/src/lib/product-configuration/product-configuration.component.ts
Product configuration component is used to show the hierarchical view of the configurations for a given product or cart line item.
This component is responsible for loading configuration of product
import { ProductConfigurationModule } from '@congarevenuecloud/elements';
@NgModule({
imports: [ProductConfigurationModule, ...]
})
export class AppModule {}
```typescript
<apt-product-configuration
[product]="product.Id"
[relatedTo]="parent"
[accordion]="true"
></apt-product-configuration>
OnChanges
OnDestroy
selector | apt-product-configuration |
styleUrls | ./product-configuration.component.scss |
templateUrl | ./product-configuration.component.html |
Properties |
Methods |
Inputs |
constructor(cdr: ChangeDetectorRef, productOptionService: ProductOptionService, cartItemService: CartItemService, secondaryCartService: SecondaryCartService, primaryCartService: CartService, productConfigurationService: ProductConfigurationService, araiService: AppliedRuleActionInfoService, productService: ProductService)
|
|||||||||||||||||||||||||||
Parameters :
|
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. |
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 :
Returns :
void
|
getAllComponents | ||||||
getAllComponents(view: ConfigurationView)
|
||||||
This method will return list of option product
Parameters :
Returns :
Array<ProductOptionComponent>
|
getComponentArray | ||||||||
getComponentArray(component: ProductOptionComponent)
|
||||||||
Method returns a flat array of components and their children of the product option
Parameters :
Returns :
Array<ProductOptionComponent>
|
getProductOptionComponent | ||||||||||||
getProductOptionComponent(productId: string, view: ConfigurationView)
|
||||||||||||
Method returns an instance of product option component for the product Id passed.
Parameters :
Returns :
ProductOptionComponent
|
isTriggeringProduct | ||||||||||||||||
isTriggeringProduct(rules: Array<AppliedRuleActionInfo>, componentId: string, bundleProduct: CartItem)
|
||||||||||||||||
This function checks if a given component ID triggers any of the given rules.
Parameters :
Returns :
boolean
|
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 :
Returns :
void
|
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"> </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;
}
}