File

projects/congarevenuecloud/elements/src/lib/constraint-rule/constraint-rule-sidebar/constraint-rule-sidebar.component.ts

Description

This component is a work in progress.

Constraint rule sidebar is used to show a list of all the constraint rule messages that have been applied to the current cart.

Preview

Constraint rule validation panel with error and warning message

Usage

Example :
import { ConstraintRuleModule } from '@congarevenuecloud/elements';
import { ModalModule } from 'ngx-bootstrap/modal';

@NgModule({
imports: [ConstraintRuleModule, ModalModule, ...]
})
export class AppModule {}
Example :
```typescript
import { ConstraintRuleSidebarComponent } from '@congarevenuecloud/elements';
import { BsModalService } from 'ngx-bootstrap/modal';

constructor(private bsModalService: BsModalService) {}

showSidebar() { this.bsModalService.show(ConstraintRuleSidebarComponent, { backdrop: false, class: 'constraintRuleSidebar' }); }

Example :

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods

Constructor

constructor(bsModalRef: BsModalRef, constraintRuleMessageService: ConstraintRuleMessageService, productConfigurationService: ProductConfigurationService)
Parameters :
Name Type Optional
bsModalRef BsModalRef No
constraintRuleMessageService ConstraintRuleMessageService No
productConfigurationService ProductConfigurationService No

Methods

isItemSelected
isItemSelected(product: Product)

The method is work in progress. Method responsible to disable/enable the products in the sidebar to add/remove based on the rule configured and product selection.

Parameters :
Name Type Optional Description
product Product No

instance of Product object.

Returns : boolean

boolean value is returned.

Properties

Public bsModalRef
Type : BsModalRef
showProductConfig
Type : boolean
Default value : false

Flag used to specify if this component is showing product level constraint rules. If false this component will show cart level configuration rules.

<ng-container *ngIf="showRules$ | async">
  <ng-container *ngIf="ruleDetailGroups$ | async as ruleDetailGroups">
    <div class="modal-header bg-white py-2 border-0">
      <h5 class="modal-title pull-left font-weight-bold">{{ "CONSTRAINT_SIDE_MENU.VALIDATION_MESSAGES" | translate }}</h5>
      <button type="button" class="close pull-left" aria-label="Close">
        <span aria-hidden="true" (click)="bsModalRef.hide()">&times;</span>
      </button>
    </div>
    <div class="modal-body bg-white p-0">
      <!-- Errors -->
      <div *ngIf="ruleDetailGroups.errors.length > 0" class="card border-0">
        <div class="card-header border-bottom-0 border-top">
          <i class="fas fa-minus-circle text-danger mr-2"></i> <span>
            {{ (ruleDetailGroups.errors.length > 1 ? "CONSTRAINT_SIDE_MENU.NUM_OF_ERRORS.PLURAL" : "CONSTRAINT_SIDE_MENU.NUM_OF_ERRORS.ONE") | translate: {amount: ruleDetailGroups.errors.length} }}
          </span>
        </div>
        <ng-container *ngFor="let error of ruleDetailGroups.errors; let i = index">
          <ng-container [ngSwitch]="error.actionType">
            <!-- Inclusions -->
            <ng-container *ngSwitchCase="'Inclusion'">
              <div class="card-body bg-white py-2 flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="error.messageHtml !== null;">
                  <div [innerHtml]="error.messageHtml"></div>
                </ng-container>
                <ng-container *ngFor="let item of error.actionItems">
                  <div class="py-3">
                    <a class="pt-2" href="javascript:void(0)"
                      [routerLink]="['/products/', item.product.Id]">{{item.product.Name}}</a>
                    <div class="d-flex py-2 align-items-center justify-content-between">
                      <small class="font-weight-bold">{{item.chargeType}}</small>
                      <small class="font-weight-bold">
                        <apt-price [record]="item.product" [type]="'list'"></apt-price>
                      </small>
                    </div>
                    <div class="d-flex align-items-center justify-content-end">
                      <label [for]="item.product.Name + i" class="mr-2 mb-0">{{ "COMMON.QTY" | translate }}</label>
                      <input class="form-control mr-2 w-25" [id]="item.product.Name + i" type="number" min="1"
                        [(ngModel)]="quantityControlValues[item.product.Name + i]" placeholder="1">
                      <div class="input-group-append">
                        <button *ngIf="!showProductConfig" class="btn btn-outline-primary"
                          (click)="handleAddToCart(error, item.product, quantityControlValues[item.product.Name + i], item.product.Name + i)"
                          [ladda]="loading[item.product.Name + i]"
                          data-style="zoom-in">{{ "COMMON.ADD_TO_CART" | translate }}</button>
                        <button *ngIf="showProductConfig" class="btn btn-outline-primary"
                          [disabled]="isItemSelected(item.product)"
                          (click)="handleAddToConfiguration(item.product, quantityControlValues[item.product.Name + i], item.product.Name + i, error.targetBundleNumber)"
                          [ladda]="loading[item.product.Name + i]"
                          data-style="zoom-in">{{ "COMMON.ADD" | translate }}</button>
                      </div>
                    </div>
                  </div>
                </ng-container>
              </div>
              <div class="card-footer bg-white border-0 py-2">
              </div>
            </ng-container>
            <!-- Exclusions -->
            <ng-container *ngSwitchCase="'Exclusion'">
              <div class="card-body bg-white py-2 flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="error.messageHtml !== null;">
                  <span [innerHtml]="error.messageHtml"></span>
                </ng-container>
                <ng-container *ngFor="let item of error.actionItems">
                  <div class="py-3">
                    <a class="pt-2" href="javascript:void(0)"
                      [routerLink]="['/products/', item.product.Id]">{{item.product.Name}}</a>
                    <div class="d-flex py-2 align-items-center justify-content-between">
                      <small class="font-weight-bold">{{item.chargeType}}</small>
                      <small class="font-weight-bold">
                        <apt-price [record]="item.product" [type]="'list'"></apt-price>
                      </small>
                    </div>
                    <div class="d-flex align-items-center justify-content-end">
                      <label [for]="item.product.Name + i" class="mr-2 mb-0">{{ "COMMON.QTY" | translate }}</label>
                      <input class="form-control mr-2 w-25" [id]="item.product.Name + i" type="number" min="1"
                        [(ngModel)]="quantityControlValues[item.product.Name + i]" placeholder="1">
                      <div class="input-group-append">
                        <button *ngIf="!showProductConfig" class="btn btn-outline-danger"
                          (click)="handleDeleteFromCart(error, item.product, item.product?.Name + i)"
                          [ladda]="loading[item.product?.Name + i]"
                          data-style="zoom-in">{{ "CONSTRAINT_SIDE_MENU.REMOVE_FROM_CART" | translate }}</button>
                        <button *ngIf="showProductConfig" class="btn btn-outline-danger"
                          [disabled]="!isItemSelected(item.product, 'remove')"
                          (click)="handleRemoveFromBundle(item.product, error.triggeringProducts[0], item.product?.Name + i)"
                          [ladda]="loading[item.product?.Name + i]"
                          data-style="zoom-in">{{ "COMMON.REMOVE" | translate }}</button>
                      </div>
                    </div>
                  </div>
                </ng-container>
              </div>
              <div class="card-footer bg-white border-0 py-2">
              </div>
            </ng-container>
            <!-- Validation -->
            <ng-container *ngSwitchCase="'Validation'">
              <div class="card-body bg-white py-2 d-flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="error.messageHtml !== null;">
                  <div [innerHtml]="error.messageHtml"></div>
                </ng-container>
              </div>
            </ng-container>
            <!-- Recommendation -->
            <ng-container *ngSwitchCase="'Recommendation'">
              <div class="card-body bg-white py-2 d-flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="error.messageHtml !== null;">
                  <div [innerHtml]="error.messageHtml"></div>
                </ng-container>
              </div>
            </ng-container>
            <!-- Replacement -->
            <ng-container *ngSwitchCase="'Replacement'">
              <div class="card-body bg-white py-2 d-flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="error.messageHtml !== null;">
                  <div [innerHtml]="error.messageHtml"></div>
                </ng-container>
              </div>
            </ng-container>
          </ng-container>
        </ng-container>
      </div>
      <!-- Warnings -->
      <div *ngIf="ruleDetailGroups.warnings.length > 0" class="card border-0">
        <div class="card-header border-bottom-0 border-top">
          <i class="fas fa-exclamation-triangle text-warning mr-2"></i> <span>
            {{ (ruleDetailGroups.warnings.length > 1 ? "CONSTRAINT_SIDE_MENU.NUM_OF_WARNINGS.PLURAL" : "CONSTRAINT_SIDE_MENU.NUM_OF_WARNINGS.ONE") | translate: {amount: ruleDetailGroups.warnings.length} }}</span>
        </div>
        <ng-container *ngFor="let warning of ruleDetailGroups.warnings; let i = index">
          <ng-container [ngSwitch]="warning.actionType">
            <!-- Inclusion -->
            <ng-container *ngSwitchCase="'Inclusion'">
              <div class="card-body bg-white py-2 flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="warning.messageHtml !== null;">
                  <div [innerHtml]="warning.messageHtml"></div>
                </ng-container>
                <ng-container *ngFor="let item of warning.actionItems">
                  <div class="py-3">
                    <a class="pt-2" href="javascript:void(0)"
                      [routerLink]="['/products/', item.product.Id]">{{item.product.Name}}</a>
                    <div class="d-flex py-2 align-items-center justify-content-between">
                      <small class="font-weight-bold">{{item.chargeType}}</small>
                      <small class="font-weight-bold">
                        <apt-price [record]="item.product" [type]="'list'"></apt-price>
                      </small>
                    </div>
                    <div class="d-flex align-items-center justify-content-end">
                      <label [for]="item.product.Name + i" class="mr-2 mb-0">{{ "COMMON.QTY" | translate }}</label>
                      <input class="form-control mr-2 w-25" [id]="item.product.Name + i" type="number" min="1"
                        [(ngModel)]="quantityControlValues[item.product.Name + i]" placeholder="1">
                      <div class="input-group-append">
                        <button *ngIf="!showProductConfig" class="btn btn-outline-primary"
                          (click)="handleAddToCart(warning, item.product, quantityControlValues[item.product.Name + i], item.product.Name + i)"
                          [ladda]="loading[item.product.Name + i]"
                          data-style="zoom-in">{{ "COMMON.ADD_TO_CART" | translate }}</button>
                        <button *ngIf="showProductConfig" class="btn btn-outline-primary"
                          [disabled]="isItemSelected(item.product)"
                          (click)="handleAddToConfiguration(item.product, quantityControlValues[item.product.Name + i], item.product.Name + i, warning.targetBundleNumber)"
                          [ladda]="loading[item.product.Name + i]"
                          data-style="zoom-in">{{ "COMMON.ADD" | translate }}</button>
                      </div>
                    </div>
                  </div>
                </ng-container>
              </div>
              <div class="card-footer bg-white border-0 py-2">
              </div>
            </ng-container>
            <!-- Exclusion -->
            <ng-container *ngSwitchCase="'Exclusion'">
              <div class="card-body bg-white py-2 flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="warning.messageHtml !== null;">
                  <span [innerHtml]="warning.messageHtml"></span>
                </ng-container>
                <ng-container *ngFor="let item of warning.actionItems">
                  <div class="py-3">
                    <a class="pt-2" href="javascript:void(0)"
                      [routerLink]="['/products/', item.product.Id]">{{item.product.Name}}</a>
                    <div class="d-flex py-2 align-items-center justify-content-between">
                      <small class="font-weight-bold">{{item.chargeType}}</small>
                      <small class="font-weight-bold">
                        <apt-price [record]="item.product" [type]="'list'"></apt-price>
                      </small>
                    </div>
                    <div class="d-flex align-items-center justify-content-end">
                      <label [for]="item.product.Name + i" class="mr-2 mb-0">{{ "COMMON.QTY" | translate }}</label>
                      <input class="form-control mr-2 w-25" [id]="item.product.Name + i" type="number" min="1"
                        [(ngModel)]="quantityControlValues[item.product.Name + i]" placeholder="1">
                      <div class="input-group-append">
                        <button *ngIf="!showProductConfig" class="btn btn-outline-danger"
                          (click)="handleDeleteFromCart(warning, item.product, item.product?.Name + i)"
                          [ladda]="loading[item.product?.Name + i]"
                          data-style="zoom-in">{{ "CONSTRAINT_SIDE_MENU.REMOVE_FROM_CART" | translate }}</button>
                        <button *ngIf="showProductConfig" class="btn btn-outline-danger"
                          [disabled]="!isItemSelected(item.product, 'remove')"
                          (click)="handleRemoveFromBundle(item.product, warning.triggeringProducts[0], item.product?.Name + i)"
                          [ladda]="loading[item.product?.Name + i]"
                          data-style="zoom-in">{{ "COMMON.REMOVE" | translate }}</button>
                      </div>
                    </div>
                  </div>
                </ng-container>
              </div>
              <div class="card-footer bg-white border-0 py-2">
              </div>
            </ng-container>
            <!-- Validation -->
            <ng-container *ngSwitchCase="'Validation'">
              <div class="card-body bg-white py-2 d-flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="warning.messageHtml !== null;">
                  <div [innerHtml]="warning.messageHtml"></div>
                </ng-container>
              </div>
            </ng-container>
            <!-- Recommendation -->
            <ng-container *ngSwitchCase="'Recommendation'">
              <div class="card-body bg-white py-2 d-flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="warning.messageHtml !== null;">
                  <div [innerHtml]="warning.messageHtml"></div>
                </ng-container>
              </div>
            </ng-container>
            <!-- Replacement -->
            <ng-container *ngSwitchCase="'Replacement'">
              <div class="card-body bg-white py-2 d-flex-column" [class.border-top]="i > 0">
                <ng-container *ngIf="warning.messageHtml !== null;">
                  <div [innerHtml]="warning.messageHtml"></div>
                </ng-container>
              </div>
            </ng-container>
          </ng-container>
        </ng-container>
      </div>
      <!-- Info Messages -->
      <!-- <div *ngIf="ruleDetailGroups.info.length > 0" class="card border-0">
        <div class="card-header border-bottom-0 border-top">
          <i class="fas fa-info-circle"></i> <span> {{ruleDetailGroups.info.length}}</span> {{ruleDetailGroups.info.length > 1 ? 'Information Messages' : 'Information Message'}}
        </div>
        <ng-container *ngFor="let info of data.infoMessages; let i = index">
          <div class="card-body bg-white py-2" [class.border-top]="i > 0">
            <strong>{{info.includedProduct.name}}</strong> is included with product <a href="javascript:void(0)">{{info.product.name}}</a>.
          </div>
          <div class="card-footer bg-white border-0 py-2">
            <div class="d-flex justify-content-end">
              <button class="btn btn-outline-danger">Delete All</button>
            </div>
          </div>
        </ng-container>
      </div> -->
      <!-- Success Messages -->
      <div *ngIf="ruleDetailGroups.success.length > 0" class="card border-0">
        <div class="card-header border-bottom-0 border-top">
          <i class="fas fa-info-circle"></i> <span>
            {{ (ruleDetailGroups.success.length > 1 ? "CONSTRAINT_SIDE_MENU.NUM_OF_INFO_MESSAGES.PLURAL" : "CONSTRAINT_SIDE_MENU.NUM_OF_INFO_MESSAGES.ONE") | translate: {amount: ruleDetailGroups.success.length} }}</span>
        </div>
        <ng-container *ngFor="let success of ruleDetailGroups.success; let i = index">
          <div class="card-body bg-white py-2" [class.border-top]="i > 0">
            <ng-container *ngIf="success.message !== null;">
              <span [innerHtml]="success.message"></span>
            </ng-container>
          </div>
        </ng-container>
      </div>
    </div>
  </ng-container>
</ng-container>

./constraint-rule-sidebar.component.scss

.modal.show {
  div.constraintRuleSidebar.modal-dialog {
    background-color: white;
    right: -1px;
    top: 0px;
  }
}

.modal {
  div.constraintRuleSidebar.modal-dialog {
    position: absolute;
    transition: right 300ms;
    margin: -1px 0px 0px 0px;
    right: -20rem;
    width: 20rem;
    .modal-content{
        height: 100vh;
        overflow-y: auto;
    }
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""