@veloceapps/sdk 3.1.31 → 3.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,9 @@ import { UITemplateComponentType, UITemplateType, ConfigurationContextMode, Enti
17
17
  import { Subject, BehaviorSubject, tap, takeUntil, first, catchError, of, map, switchMap, filter, shareReplay, startWith, distinctUntilChanged, combineLatest, finalize, noop, from, throwError } from 'rxjs';
18
18
  import * as i3$1 from 'primeng/overlaypanel';
19
19
  import { OverlayPanel, OverlayPanelModule } from 'primeng/overlaypanel';
20
- import * as i11 from 'primeng/tooltip';
20
+ import * as i9 from 'primeng/splitbutton';
21
+ import { SplitButtonModule } from 'primeng/splitbutton';
22
+ import * as i12 from 'primeng/tooltip';
21
23
  import { TooltipModule } from 'primeng/tooltip';
22
24
  import * as i7 from '@angular/forms';
23
25
  import { FormGroup, FormControl, ReactiveFormsModule, FormsModule } from '@angular/forms';
@@ -493,6 +495,13 @@ class FlowDialogService {
493
495
  primaryButton: 'OK',
494
496
  });
495
497
  }
498
+ showQuoteOutsideShoppingCartDialog() {
499
+ return this.show({
500
+ title: 'Quote Cannot be Saved',
501
+ description: 'It is only possible to save quotes from the Shopping Cart. To proceed, go to the Shopping Cart.',
502
+ primaryButton: 'OK',
503
+ });
504
+ }
496
505
  showAccountNoChangesDialog() {
497
506
  return this.show({
498
507
  title: 'No Changes to Save',
@@ -515,6 +524,13 @@ class FlowDialogService {
515
524
  primaryButton: 'OK',
516
525
  });
517
526
  }
527
+ showOutsideShoppingCartQuoteSubmitFailureDialog() {
528
+ return this.show({
529
+ title: 'Cannot Submit for Approval',
530
+ description: 'It is only possible to submit quotes for approval from the Shopping Cart. To proceed, go to the Shopping Cart.',
531
+ primaryButton: 'OK',
532
+ });
533
+ }
518
534
  showAccountSubmitFailureDialog() {
519
535
  return this.show({
520
536
  title: 'Save Changes',
@@ -536,6 +552,13 @@ class FlowDialogService {
536
552
  primaryButton: 'OK',
537
553
  });
538
554
  }
555
+ showDocgenOutsideShoppingCartDialog() {
556
+ return this.show({
557
+ title: 'Document Generation is not Available',
558
+ description: 'It is only possible to generate documents for quotes from the Shopping Cart. To proceed, go to the Shopping Cart.',
559
+ primaryButton: 'OK',
560
+ });
561
+ }
539
562
  showDocgenUnsavedChangesDialog() {
540
563
  return this.show({
541
564
  title: 'Unsaved Changes',
@@ -561,7 +584,6 @@ class FlowHeaderComponent {
561
584
  this.routerService = routerService;
562
585
  this.dialogService = dialogService;
563
586
  this.integrationState = integrationState;
564
- this.disabledActionButtonTooltip = 'Available from the Shopping Cart';
565
587
  this.objectDetails$ = new BehaviorSubject({});
566
588
  this.isSaveInProgress$ = new BehaviorSubject(false);
567
589
  this.isSubmitInProgress$ = new BehaviorSubject(false);
@@ -594,6 +616,22 @@ class FlowHeaderComponent {
594
616
  get isQuoteMode() {
595
617
  return this.mode === ConfigurationContextMode.QUOTE;
596
618
  }
619
+ getSplitButtonActions(isCartRoute) {
620
+ return [
621
+ {
622
+ label: 'Save to Quote',
623
+ command: () => {
624
+ this.saveButtonClickHandler(isCartRoute);
625
+ },
626
+ },
627
+ {
628
+ label: 'Submit For Approval',
629
+ command: () => {
630
+ this.submitButtonClickHandler(isCartRoute);
631
+ },
632
+ },
633
+ ];
634
+ }
597
635
  back(objectId) {
598
636
  const targetId = objectId !== null && objectId !== void 0 ? objectId : this.contextService.resolve().headerId;
599
637
  if (targetId) {
@@ -612,7 +650,7 @@ class FlowHeaderComponent {
612
650
  navigateToCatalog() {
613
651
  this.routerService.navigateToCatalog();
614
652
  }
615
- docGenButtonClickHandler() {
653
+ docGenButtonClickHandler(isCartRoute) {
616
654
  if (this.mode === ConfigurationContextMode.ACCOUNT) {
617
655
  if (!this.quoteDraftService.hasUnsavedChanges) {
618
656
  this.dialogService.showAccountNoChangesDialog().subscribe();
@@ -626,6 +664,10 @@ class FlowHeaderComponent {
626
664
  this.dialogService.showDocgenReadonlyDialog().subscribe();
627
665
  return;
628
666
  }
667
+ if (!isCartRoute) {
668
+ this.dialogService.showDocgenOutsideShoppingCartDialog().subscribe();
669
+ return;
670
+ }
629
671
  let observable = of(true);
630
672
  if (this.quoteDraftService.hasUnsavedChanges) {
631
673
  observable = this.dialogService.showDocgenUnsavedChangesDialog().pipe(switchMap(confirmed => (confirmed ? this.saveQuote$(true) : of(true))), map(() => true));
@@ -634,7 +676,7 @@ class FlowHeaderComponent {
634
676
  .pipe(first(), tap(() => this.integrationState.dispatch(OpenDocGenAction())))
635
677
  .subscribe();
636
678
  }
637
- saveButtonClickHandler() {
679
+ saveButtonClickHandler(isCartRoute) {
638
680
  if (!this.quoteDraftService.isEditMode()) {
639
681
  if (this.mode === ConfigurationContextMode.QUOTE) {
640
682
  this.dialogService.showQuoteReadonlyModeDialog().subscribe();
@@ -648,6 +690,10 @@ class FlowHeaderComponent {
648
690
  this.dialogService.showAccountNoChangesDialog().subscribe();
649
691
  return;
650
692
  }
693
+ if (!isCartRoute) {
694
+ this.dialogService.showQuoteOutsideShoppingCartDialog().subscribe();
695
+ return;
696
+ }
651
697
  const lineItems = this.flowConfiguration.getSnapshot();
652
698
  if (!lineItems.length) {
653
699
  this.dialogService.showEmptyCartDialog().subscribe();
@@ -655,7 +701,7 @@ class FlowHeaderComponent {
655
701
  }
656
702
  this.saveQuote$().subscribe();
657
703
  }
658
- submitButtonClickHandler() {
704
+ submitButtonClickHandler(isCartRoute) {
659
705
  if (this.mode === ConfigurationContextMode.QUOTE && !this.quoteDraftService.isEditMode()) {
660
706
  this.dialogService.showReadonlyQuoteSubmitFailureDialog();
661
707
  return;
@@ -664,6 +710,10 @@ class FlowHeaderComponent {
664
710
  this.dialogService.showAccountSubmitFailureDialog();
665
711
  return;
666
712
  }
713
+ if (!isCartRoute) {
714
+ this.dialogService.showOutsideShoppingCartQuoteSubmitFailureDialog().subscribe();
715
+ return;
716
+ }
667
717
  const quoteDraft = this.quoteDraftService.quoteDraft;
668
718
  if (!quoteDraft) {
669
719
  return;
@@ -681,7 +731,7 @@ class FlowHeaderComponent {
681
731
  this.quoteDraftService.updateActivePriceList(priceListId);
682
732
  }
683
733
  saveQuote$(stayOnPage = false) {
684
- const quoteDraft = this.quoteDraftService.quoteDraft;
734
+ const quoteDraft = this.quoteDraftService.quoteDraftForActivePriceList;
685
735
  if (!quoteDraft) {
686
736
  return of(undefined);
687
737
  }
@@ -755,7 +805,7 @@ class FlowHeaderComponent {
755
805
  }
756
806
  }
757
807
  FlowHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderComponent, deps: [{ token: i2$1.ContextService }, { token: i2$1.QuoteDraftService }, { token: i2$2.QuoteApiService }, { token: i2$2.SalesforceApiService }, { token: i2$1.FlowConfigurationService }, { token: FlowRouterService }, { token: FlowDialogService }, { token: i1$1.IntegrationState }], target: i0.ɵɵFactoryTarget.Component });
758
- FlowHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: FlowHeaderComponent, selector: "vl-flow-header", ngImport: i0, template: "<div class=\"flow-info\" *vlLet=\"objectDetails$ | async as details\">\n <nav class=\"nav-item nav-back\" (click)=\"back()\">\n <i class=\"nav-icon vl-icon vl-icon-arrow-left\"></i>\n\n <span> Back </span>\n <span *ngIf=\"objectName\" class=\"object-name\">&nbsp;To {{ objectName }}</span>\n </nav>\n\n <ng-container *ngIf=\"isAccountMode\">\n <span class=\"dot-separator\"></span>\n\n <span>Account name</span>\n\n <nav class=\"account-name\" [pTooltip]=\"contextProperties.Name ?? ''\" tooltipPosition=\"bottom\" [showDelay]=\"1000\">\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(contextProperties.Id)\">{{ contextProperties.Name }}</a>\n </nav>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span class=\"dot-separator\"></span>\n\n <span>Quote #{{ details.quoteNumber }}</span>\n\n <span class=\"dot-separator\"></span>\n\n <nav class=\"nav-item\" (click)=\"quoteDetails.toggle($event)\">\n <span>{{ status$ | async }}</span>\n\n <i *ngIf=\"!quoteDetails.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"quoteDetails.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <p-overlayPanel styleClass=\"navigation-settings-overlay flow-header-overlay center\" #quoteDetails>\n <ng-template pTemplate>\n <div class=\"flow-header-overlay__wrapper\">\n <h2 class=\"flow-header-overlay__title\">\n <span>Quote Information</span>\n <i class=\"vl-icon vl-icon-close close-icon\" (click)=\"quoteDetails.hide()\"></i>\n </h2>\n\n <ul class=\"info-list\">\n <li class=\"info-list__row\">\n <span>Account Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.accountId)\">\n <span>{{ details.accountName }}</span>\n </a>\n </li>\n <li class=\"info-list__row\">\n <span>Opportunity Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.opportunityId)\">\n <span>{{ details.opportunityName }}</span>\n </a>\n </li>\n <li class=\"info-list__row\">\n <span>Quote Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.quoteId)\">\n <span>{{ details.quoteName }}</span>\n </a>\n </li>\n </ul>\n </div>\n </ng-template>\n </p-overlayPanel>\n </ng-container>\n</div>\n\n<div class=\"flow-navigation\">\n <nav class=\"nav-item\" [ngClass]=\"{ active: isCatalogRoute$ | async }\" (click)=\"navigateToCatalog()\">Catalog</nav>\n <nav class=\"nav-item disabled\" [ngClass]=\"{ active: isConfigurationRoute$ | async }\">Configurator</nav>\n <ng-container *vlLet=\"products$ | async as products\">\n <nav class=\"nav-item\" [ngClass]=\"{ active: isCartRoute$ | async }\" (click)=\"navigateToShoppingCart()\">\n Shopping Cart ({{ products.length }})\n </nav>\n\n <nav class=\"nav-popover-toggle active\" (click)=\"cart?.overlayPanel?.toggle($event)\">\n <i *ngIf=\"!cart?.overlayPanel?.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"cart?.overlayPanel?.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <vl-cart-preview #cart [products]=\"products\"></vl-cart-preview>\n </ng-container>\n</div>\n\n<div class=\"flow-controls\" *vlLet=\"objectDetails$ | async as details\">\n <ng-container *vlLet=\"activePriceList$ | async as priceList\">\n <ng-container *ngIf=\"isAccountMode && assetPriceLists.length > 1\">\n <nav class=\"nav-item\" (click)=\"priceListsOverlay?.toggle($event)\">\n <span>{{ priceList?.name }}</span>\n <i *ngIf=\"!priceListsOverlay?.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"priceListsOverlay?.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <p-overlayPanel styleClass=\"price-list-overlay\" #priceListsOverlay>\n <ng-template pTemplate>\n <span\n *ngFor=\"let option of assetPriceLists\"\n class=\"price-list-option\"\n [class.active]=\"priceList?.id === option.id\"\n (click)=\"selectPriceList(option.id); priceListsOverlay.hide()\"\n >{{ option.name }}</span\n >\n </ng-template>\n </p-overlayPanel>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span>{{ priceList?.name }}</span>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span *ngIf=\"contextProperties.StartDate\">{{ contextProperties.StartDate | date: 'MM.dd.yyyy' }}</span>\n\n <span class=\"slash-separator\"></span>\n\n <span class=\"metrics\">\n <div class=\"metrics__row\">\n MRR: <span class=\"font-semibold\">${{ totalMRR$ | async }}</span>\n </div>\n <div class=\"metrics__row\">\n NRR: <span class=\"font-semibold\">${{ totalNRR$ | async }}</span>\n </div>\n </span>\n </ng-container>\n\n <ng-container *vlLet=\"isCartRoute$ | async as isCartRoute\">\n <p-button\n styleClass=\"p-button-outlined\"\n label=\"Generate Doc\"\n [disabled]=\"!isCartRoute\"\n tooltipPosition=\"bottom\"\n [showDelay]=\"300\"\n [pTooltip]=\"isCartRoute ? '' : disabledActionButtonTooltip\"\n (onClick)=\"docGenButtonClickHandler()\"\n ></p-button>\n\n <p-button\n *vlLet=\"isSaveInProgress$ | async as isSaveInProgress\"\n class=\"save-button\"\n styleClass=\"p-button-outlined\"\n [label]=\"isSaveInProgress ? 'Saving' : 'Save to Quote'\"\n (onClick)=\"saveButtonClickHandler()\"\n [loading]=\"isSaveInProgress\"\n ></p-button>\n\n <p-button\n *vlLet=\"isSubmitInProgress$ | async as isSubmitInProgress\"\n class=\"submit-button\"\n styleClass=\"p-button\"\n [label]=\"isSubmitInProgress ? 'Submitting' : 'Submit For Approval'\"\n [disabled]=\"!isCartRoute\"\n tooltipPosition=\"bottom\"\n [showDelay]=\"300\"\n [pTooltip]=\"isCartRoute ? '' : disabledActionButtonTooltip\"\n (onClick)=\"submitButtonClickHandler()\"\n [loading]=\"isSubmitInProgress\"\n ></p-button>\n </ng-container>\n</div>\n", styles: [":host{display:flex;align-items:center;height:48px;width:100%;background-color:var(--vl-primary-color);color:#fff;padding:0 32px;flex-shrink:0}::ng-deep .p-overlaypanel.flow-header-overlay .p-overlaypanel-content{background-color:#fff;padding:16px}::ng-deep .p-overlaypanel.flow-header-overlay.left:before{left:6px!important}::ng-deep .p-overlaypanel.flow-header-overlay.right:before{right:6px!important}::ng-deep .p-overlaypanel.flow-header-overlay.left .p-overlaypanel-content{margin-left:-16px}::ng-deep .p-overlaypanel.flow-header-overlay.right .p-overlaypanel-content{margin-right:-16px}::ng-deep .p-overlaypanel.flow-header-overlay:before{background-color:#fff}::ng-deep .p-overlaypanel.price-list-overlay .p-overlaypanel-content{border-radius:5px;border-color:var(--vl-border-color);padding:0;display:flex;flex-direction:column;max-height:140px;overflow:auto}:host ::ng-deep .p-button{padding:5px 15px;font-size:12px}:host ::ng-deep .p-button{color:var(--vl-primary-color);background-color:#fff;border-color:#fff}:host ::ng-deep .p-button:enabled:hover{background-color:var(--vl-primary-color);color:#fff;border-color:#fff}:host ::ng-deep .p-button.p-button-outlined{background-color:var(--vl-primary-color);color:#fff;border-color:#fff}:host ::ng-deep .p-button.p-button-outlined:enabled:hover{color:var(--vl-primary-color);background-color:#fff;border-color:#fff}:host ::ng-deep .p-button .p-button-label{white-space:nowrap}:host ::ng-deep .save-button .p-button{width:120px}:host ::ng-deep .submit-button .p-button{width:160px}.vl-icon{display:inline-block}.flow-info{flex-shrink:0;display:flex;grid-gap:8px;gap:8px;align-items:center}.flow-info .nav-popover-toggle{margin-left:-8px}.flow-info .object-name{text-transform:capitalize}.flow-info .nav-back{font-weight:bold}.flow-info .nav-item:not(.disabled):hover,.flow-info .nav-popover-toggle:not(.disabled):hover{opacity:.6}nav{display:flex;align-items:center;cursor:pointer;padding:4px 0}nav.disabled{opacity:.6;cursor:default}nav .nav-icon{margin-right:10px}nav .icon-with-margin{margin:0 4px}nav a{color:#fff}nav.account-name{margin-left:4px;display:block;max-width:200px;overflow:hidden;text-overflow:ellipsis}nav.nav-popover-toggle{width:24px;display:flex;justify-content:center}nav.nav-popover-toggle i{pointer-events:none;margin:0}nav i{pointer-events:none}.dot-separator:after{content:\"\";display:block;width:4px;height:4px;border-radius:50%;background:#fff}.slash-separator:after{content:\"\";display:block;background:#fff;width:1px;height:16px}.flow-header-overlay__wrapper{width:360px}.flow-header-overlay__wrapper .close-icon{cursor:pointer}.flow-header-overlay__wrapper .info-list{list-style:none;padding:0;font-size:12px}.flow-header-overlay__wrapper .info-list__row{padding:8px 0;display:flex;justify-content:space-between}.flow-header-overlay__wrapper .info-list__row a{text-align:right}.flow-header-overlay__title{display:flex;justify-content:space-between;align-items:center;margin:0 0 24px}.flow-navigation{flex-grow:1;display:flex;grid-gap:16px;gap:16px;justify-content:center;font-weight:600}.flow-navigation .cart-nav-container{display:flex}.flow-navigation .nav-popover-toggle{margin-left:-14px}.flow-navigation .nav-item,.flow-navigation .nav-popover-toggle{opacity:.6}.flow-navigation .nav-item.active,.flow-navigation .nav-item:not(.disabled):hover,.flow-navigation .nav-popover-toggle.active,.flow-navigation .nav-popover-toggle:not(.disabled):hover{opacity:1}.price-list-option{padding:8px;color:var(--vl-primary-color);cursor:pointer}.price-list-option.active,.price-list-option:hover{background:var(--vl-secondary-nav-bg)}.flow-controls{flex-shrink:0;display:flex;align-items:center;grid-gap:8px;gap:8px}\n"], components: [{ type: i3$1.OverlayPanel, selector: "p-overlayPanel", inputs: ["dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { type: CartPreviewComponent, selector: "vl-cart-preview", inputs: ["products"] }, { type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }], directives: [{ type: i3.LetDirective, selector: "[vlLet]", inputs: ["vlLet"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i11.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i2$3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i8.AsyncPipe, "date": i8.DatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
808
+ FlowHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: FlowHeaderComponent, selector: "vl-flow-header", ngImport: i0, template: "<div class=\"flow-info\" *vlLet=\"objectDetails$ | async as details\">\n <nav class=\"nav-item nav-back\" (click)=\"back()\">\n <i class=\"nav-icon vl-icon vl-icon-arrow-left\"></i>\n\n <span> Back </span>\n <span *ngIf=\"objectName\" class=\"object-name\">&nbsp;To {{ objectName }}</span>\n </nav>\n\n <ng-container *ngIf=\"isAccountMode\">\n <span class=\"dot-separator\"></span>\n\n <span>Account name</span>\n\n <nav class=\"account-name\" [pTooltip]=\"contextProperties.Name ?? ''\" tooltipPosition=\"bottom\" [showDelay]=\"1000\">\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(contextProperties.Id)\">{{ contextProperties.Name }}</a>\n </nav>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span class=\"dot-separator\"></span>\n\n <span>Quote #{{ details.quoteNumber }}</span>\n\n <span class=\"dot-separator\"></span>\n\n <nav class=\"nav-item\" (click)=\"quoteDetails.toggle($event)\">\n <span>{{ status$ | async }}</span>\n\n <i *ngIf=\"!quoteDetails.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"quoteDetails.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <p-overlayPanel styleClass=\"navigation-settings-overlay flow-header-overlay center\" #quoteDetails>\n <ng-template pTemplate>\n <div class=\"flow-header-overlay__wrapper\">\n <h2 class=\"flow-header-overlay__title\">\n <span>Quote Information</span>\n <i class=\"vl-icon vl-icon-close close-icon\" (click)=\"quoteDetails.hide()\"></i>\n </h2>\n\n <ul class=\"info-list\">\n <li class=\"info-list__row\">\n <span>Account Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.accountId)\">\n <span>{{ details.accountName }}</span>\n </a>\n </li>\n <li class=\"info-list__row\">\n <span>Opportunity Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.opportunityId)\">\n <span>{{ details.opportunityName }}</span>\n </a>\n </li>\n <li class=\"info-list__row\">\n <span>Quote Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.quoteId)\">\n <span>{{ details.quoteName }}</span>\n </a>\n </li>\n </ul>\n </div>\n </ng-template>\n </p-overlayPanel>\n </ng-container>\n</div>\n\n<div class=\"flow-navigation\">\n <nav class=\"nav-item\" [ngClass]=\"{ active: isCatalogRoute$ | async }\" (click)=\"navigateToCatalog()\">Catalog</nav>\n <nav class=\"nav-item disabled\" [ngClass]=\"{ active: isConfigurationRoute$ | async }\">Configurator</nav>\n <ng-container *vlLet=\"products$ | async as products\">\n <nav class=\"nav-item\" [ngClass]=\"{ active: isCartRoute$ | async }\" (click)=\"navigateToShoppingCart()\">\n Shopping Cart ({{ products.length }})\n </nav>\n\n <nav class=\"nav-popover-toggle active\" (click)=\"cart?.overlayPanel?.toggle($event)\">\n <i *ngIf=\"!cart?.overlayPanel?.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"cart?.overlayPanel?.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <vl-cart-preview #cart [products]=\"products\"></vl-cart-preview>\n </ng-container>\n</div>\n\n<div class=\"flow-controls\" *vlLet=\"objectDetails$ | async as details\">\n <ng-container *vlLet=\"activePriceList$ | async as priceList\">\n <ng-container *ngIf=\"isAccountMode && assetPriceLists.length > 1\">\n <nav class=\"nav-item\" (click)=\"priceListsOverlay?.toggle($event)\">\n <span>{{ priceList?.name }}</span>\n <i *ngIf=\"!priceListsOverlay?.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"priceListsOverlay?.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <p-overlayPanel styleClass=\"price-list-overlay\" #priceListsOverlay>\n <ng-template pTemplate>\n <span\n *ngFor=\"let option of assetPriceLists\"\n class=\"price-list-option\"\n [class.active]=\"priceList?.id === option.id\"\n (click)=\"selectPriceList(option.id); priceListsOverlay.hide()\"\n >{{ option.name }}</span\n >\n </ng-template>\n </p-overlayPanel>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span>{{ priceList?.name }}</span>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span *ngIf=\"contextProperties.StartDate\">{{ contextProperties.StartDate | date: 'MM.dd.yyyy' }}</span>\n\n <span class=\"slash-separator\"></span>\n\n <span class=\"metrics\">\n <div class=\"metrics__row\">\n MRR: <span class=\"font-semibold\">${{ totalMRR$ | async }}</span>\n </div>\n <div class=\"metrics__row\">\n NRR: <span class=\"font-semibold\">${{ totalNRR$ | async }}</span>\n </div>\n </span>\n </ng-container>\n\n <ng-container *vlLet=\"isCartRoute$ | async as isCartRoute\">\n <p-button\n class=\"doc-gen-button\"\n icon=\"vl-icon vl-icon-doc-gen\"\n (onClick)=\"docGenButtonClickHandler(isCartRoute)\"\n ></p-button>\n\n <ng-container *vlLet=\"isSaveInProgress$ | async as isSaveInProgress\">\n <ng-container *vlLet=\"isSubmitInProgress$ | async as isSubmitInProgress\">\n <p-splitButton\n *ngIf=\"!isSaveInProgress && !isSubmitInProgress\"\n label=\"Save to Quote\"\n (onClick)=\"saveButtonClickHandler(isCartRoute)\"\n [model]=\"getSplitButtonActions(isCartRoute)\"\n styleClass=\"p-button-outlined\"\n >\n </p-splitButton>\n\n <p-button\n *ngIf=\"isSaveInProgress\"\n class=\"save-button\"\n styleClass=\"p-button\"\n label=\"Saving\"\n [loading]=\"true\"\n ></p-button>\n\n <p-button\n *ngIf=\"isSubmitInProgress\"\n class=\"submit-button\"\n styleClass=\"p-button\"\n label=\"Submitting\"\n [loading]=\"true\"\n ></p-button>\n </ng-container>\n </ng-container>\n </ng-container>\n</div>\n", styles: [":host{display:flex;align-items:center;height:48px;width:100%;background-color:var(--vl-primary-color);color:#fff;padding:0 32px;flex-shrink:0}::ng-deep .p-overlaypanel.flow-header-overlay .p-overlaypanel-content{background-color:#fff;padding:16px}::ng-deep .p-overlaypanel.flow-header-overlay.left:before{left:6px!important}::ng-deep .p-overlaypanel.flow-header-overlay.right:before{right:6px!important}::ng-deep .p-overlaypanel.flow-header-overlay.left .p-overlaypanel-content{margin-left:-16px}::ng-deep .p-overlaypanel.flow-header-overlay.right .p-overlaypanel-content{margin-right:-16px}::ng-deep .p-overlaypanel.flow-header-overlay:before{background-color:#fff}::ng-deep .p-overlaypanel.price-list-overlay .p-overlaypanel-content{border-radius:5px;border-color:var(--vl-border-color);padding:0;display:flex;flex-direction:column;max-height:140px;overflow:auto}:host ::ng-deep p-splitButton{height:32px;width:146px;display:flex}:host ::ng-deep p-splitButton .p-splitbutton{display:flex;font-size:12px;border-radius:2px;height:100%;width:100%}:host ::ng-deep p-splitButton .p-splitbutton.p-button-outlined .p-button{background-color:#fff;color:var(--vl-primary-color);border:none}:host ::ng-deep p-splitButton .p-splitbutton.p-button-outlined .p-button:enabled:hover{background-color:var(--vl-secondary-nav-bg);color:var(--vl-primary-color);border:none}:host ::ng-deep p-splitButton .p-splitbutton.p-button-outlined .p-button.p-splitbutton-menubutton{background-color:var(--vl-secondary-nav-bg);border-radius:0 2px 2px 0;border-left:none}:host ::ng-deep p-splitButton .p-splitbutton.p-button-outlined .p-button.p-splitbutton-menubutton:hover{background-color:var(--vl-secondary-nav-bg);border-left:none}:host ::ng-deep p-splitButton .p-splitbutton.p-button-outlined .p-button.p-splitbutton-defaultbutton{border-radius:2px 0 0 2px}:host ::ng-deep p-splitButton .p-splitbutton.p-button-outlined .p-button.p-splitbutton-defaultbutton .p-button-label{font-size:12px;line-height:16px;letter-spacing:.3px;white-space:nowrap}:host ::ng-deep p-splitButton .p-splitbutton .p-menu{display:flex;width:auto;margin-top:2px;border-radius:4px;border:1px solid var(--vl-border-color);box-shadow:0 4px 20px #2767c11a}:host ::ng-deep p-splitButton .p-splitbutton .p-menu .p-menu-list{display:flex;flex-direction:column}:host ::ng-deep p-splitButton .p-splitbutton .p-menu .p-menu-list .p-menuitem{display:flex;width:100%;height:32px}:host ::ng-deep p-splitButton .p-splitbutton .p-menu .p-menu-list .p-menuitem .p-menuitem-link{padding:8px;width:100%;height:100%}:host ::ng-deep p-splitButton .p-splitbutton .p-menu .p-menu-list .p-menuitem .p-menuitem-link:not(.p-disabled):hover{background-color:var(--vl-secondary-nav-bg)}:host ::ng-deep p-splitButton .p-splitbutton .p-menu .p-menu-list .p-menuitem .p-menuitem-link:not(.p-disabled):hover .p-menuitem-text{color:var(--vl-primary-color)}:host ::ng-deep p-splitButton .p-splitbutton .p-menu .p-menu-list .p-menuitem .p-menuitem-link .p-menuitem-text{line-height:16px;font-size:12px;letter-spacing:.3px;white-space:nowrap}:host ::ng-deep .doc-gen-button{height:32px;width:32px;display:inline-flex}:host ::ng-deep .doc-gen-button .p-button{border:1px solid #fff;border-radius:2px;width:100%;height:100%}:host ::ng-deep .save-button,:host ::ng-deep .submit-button{height:32px;width:146px;display:flex}:host ::ng-deep .save-button .p-button,:host ::ng-deep .submit-button .p-button{border-radius:3px;width:100%;height:100%;background:rgba(255,255,255,.3);opacity:1;border:none}:host ::ng-deep .save-button .p-button .p-button-label,:host ::ng-deep .submit-button .p-button .p-button-label{font-size:12px;line-height:16px;letter-spacing:.3px;white-space:nowrap}.vl-icon{display:inline-block}.flow-info{flex-shrink:0;display:flex;grid-gap:8px;gap:8px;align-items:center}.flow-info .nav-popover-toggle{margin-left:-8px}.flow-info .object-name{text-transform:capitalize}.flow-info .nav-back{font-weight:bold}.flow-info .nav-item:not(.disabled):hover,.flow-info .nav-popover-toggle:not(.disabled):hover{opacity:.6}nav{display:flex;align-items:center;cursor:pointer;padding:4px 0}nav.disabled{opacity:.6;cursor:default}nav .nav-icon{margin-right:10px}nav .icon-with-margin{margin:0 4px}nav a{color:#fff}nav.account-name{margin-left:4px;display:block;max-width:200px;overflow:hidden;text-overflow:ellipsis}nav.nav-popover-toggle{width:24px;display:flex;justify-content:center}nav.nav-popover-toggle i{pointer-events:none;margin:0}nav i{pointer-events:none}.dot-separator:after{content:\"\";display:block;width:4px;height:4px;border-radius:50%;background:#fff}.slash-separator:after{content:\"\";display:block;background:#fff;width:1px;height:16px}.flow-header-overlay__wrapper{width:360px}.flow-header-overlay__wrapper .close-icon{cursor:pointer}.flow-header-overlay__wrapper .info-list{list-style:none;padding:0;font-size:12px}.flow-header-overlay__wrapper .info-list__row{padding:8px 0;display:flex;justify-content:space-between}.flow-header-overlay__wrapper .info-list__row a{text-align:right}.flow-header-overlay__title{display:flex;justify-content:space-between;align-items:center;margin:0 0 24px}.flow-navigation{flex-grow:1;display:flex;grid-gap:16px;gap:16px;justify-content:center;font-weight:600}.flow-navigation .cart-nav-container{display:flex}.flow-navigation .nav-popover-toggle{margin-left:-14px}.flow-navigation .nav-item,.flow-navigation .nav-popover-toggle{opacity:.6}.flow-navigation .nav-item.active,.flow-navigation .nav-item:not(.disabled):hover,.flow-navigation .nav-popover-toggle.active,.flow-navigation .nav-popover-toggle:not(.disabled):hover{opacity:1}.price-list-option{padding:8px;color:var(--vl-primary-color);cursor:pointer}.price-list-option.active,.price-list-option:hover{background:var(--vl-secondary-nav-bg)}.flow-controls{flex-shrink:0;display:flex;align-items:center;grid-gap:8px;gap:8px}\n"], components: [{ type: i3$1.OverlayPanel, selector: "p-overlayPanel", inputs: ["dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { type: CartPreviewComponent, selector: "vl-cart-preview", inputs: ["products"] }, { type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }, { type: i9.SplitButton, selector: "p-splitButton", inputs: ["model", "icon", "iconPos", "label", "style", "styleClass", "menuStyle", "menuStyleClass", "disabled", "tabindex", "appendTo", "dir", "expandAriaLabel", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onClick", "onDropdownClick"] }], directives: [{ type: i3.LetDirective, selector: "[vlLet]", inputs: ["vlLet"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i2$3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i8.AsyncPipe, "date": i8.DatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
759
809
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderComponent, decorators: [{
760
810
  type: Component,
761
811
  args: [{
@@ -769,13 +819,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
769
819
  class FlowHeaderModule {
770
820
  }
771
821
  FlowHeaderModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
772
- FlowHeaderModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, declarations: [FlowHeaderComponent], imports: [CommonModule, OverlayPanelModule, LetDirectiveModule, TooltipModule, ButtonModule, CartPreviewModule], exports: [FlowHeaderComponent] });
773
- FlowHeaderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, imports: [[CommonModule, OverlayPanelModule, LetDirectiveModule, TooltipModule, ButtonModule, CartPreviewModule]] });
822
+ FlowHeaderModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, declarations: [FlowHeaderComponent], imports: [CommonModule,
823
+ OverlayPanelModule,
824
+ LetDirectiveModule,
825
+ TooltipModule,
826
+ ButtonModule,
827
+ CartPreviewModule,
828
+ SplitButtonModule], exports: [FlowHeaderComponent] });
829
+ FlowHeaderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, imports: [[
830
+ CommonModule,
831
+ OverlayPanelModule,
832
+ LetDirectiveModule,
833
+ TooltipModule,
834
+ ButtonModule,
835
+ CartPreviewModule,
836
+ SplitButtonModule,
837
+ ]] });
774
838
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, decorators: [{
775
839
  type: NgModule,
776
840
  args: [{
777
841
  declarations: [FlowHeaderComponent],
778
- imports: [CommonModule, OverlayPanelModule, LetDirectiveModule, TooltipModule, ButtonModule, CartPreviewModule],
842
+ imports: [
843
+ CommonModule,
844
+ OverlayPanelModule,
845
+ LetDirectiveModule,
846
+ TooltipModule,
847
+ ButtonModule,
848
+ CartPreviewModule,
849
+ SplitButtonModule,
850
+ ],
779
851
  exports: [FlowHeaderComponent],
780
852
  }]
781
853
  }] });
@@ -1408,7 +1480,7 @@ class ProductComponent {
1408
1480
  if (!productId) {
1409
1481
  return;
1410
1482
  }
1411
- const lineItemId = this.getLineItemId(quote, contextProperties.lineItemId);
1483
+ const lineItemId = this.getLineItemId(quote, productId, contextProperties.lineItemId);
1412
1484
  const currentStateItem = quote.currentState.find(({ id }) => id === lineItemId);
1413
1485
  if (currentStateItem) {
1414
1486
  this.configurationService.updateCurrentStates({
@@ -1440,9 +1512,14 @@ class ProductComponent {
1440
1512
  }));
1441
1513
  };
1442
1514
  }
1443
- getLineItemId(quote, lineItemId) {
1444
- var _a;
1445
- return (_a = quote.currentState.find(li => li.id === lineItemId)) === null || _a === void 0 ? void 0 : _a.id;
1515
+ getLineItemId(quote, productId, lineItemId) {
1516
+ var _a, _b;
1517
+ // search by lineItemId first
1518
+ let id = (_a = quote.currentState.find(li => li.id === lineItemId)) === null || _a === void 0 ? void 0 : _a.id;
1519
+ if (!id && this.quoteDraftService.isStandalone) {
1520
+ id = (_b = quote.currentState.find(li => li.productId === productId)) === null || _b === void 0 ? void 0 : _b.id;
1521
+ }
1522
+ return id;
1446
1523
  }
1447
1524
  getAsset(quote, lineItem) {
1448
1525
  return quote.initialState.find(a => a.id === lineItem.openOrderLineItemId || a.id === lineItem.assetId);