@veloceapps/sdk 3.1.17-1 → 3.1.18

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.
Files changed (34) hide show
  1. package/README.md +2 -6
  2. package/bundles/veloce-sdk-core.umd.js +68 -212
  3. package/bundles/veloce-sdk-core.umd.js.map +1 -1
  4. package/bundles/veloce-sdk-runtime.umd.js +6 -5
  5. package/bundles/veloce-sdk-runtime.umd.js.map +1 -1
  6. package/bundles/veloce-sdk.umd.js +35 -42
  7. package/bundles/veloce-sdk.umd.js.map +1 -1
  8. package/core/modules/flow-configuration/services/flow-configuration.service.d.ts +17 -11
  9. package/core/services/quote-draft.service.d.ts +7 -41
  10. package/esm2015/core/modules/configuration/services/configuration.service.js +3 -3
  11. package/esm2015/core/modules/flow-configuration/services/flow-configuration.service.js +49 -43
  12. package/esm2015/core/services/quote-draft.service.js +22 -138
  13. package/esm2015/runtime/components/ui-runtime/runtime.component.js +2 -2
  14. package/esm2015/runtime/execution/directives/section-script.directive.js +2 -2
  15. package/esm2015/runtime/services/cart.service.js +3 -2
  16. package/esm2015/runtime/services/section.service.js +1 -1
  17. package/esm2015/src/components/header/header.component.js +19 -23
  18. package/esm2015/src/components/header/header.types.js +1 -1
  19. package/esm2015/src/pages/legacy-product/legacy-product.component.js +4 -4
  20. package/esm2015/src/pages/product/product.component.js +5 -8
  21. package/esm2015/src/resolvers/quote.resolver.js +11 -4
  22. package/esm2015/src/services/flow.service.js +5 -6
  23. package/fesm2015/veloce-sdk-core.js +66 -177
  24. package/fesm2015/veloce-sdk-core.js.map +1 -1
  25. package/fesm2015/veloce-sdk-runtime.js +4 -3
  26. package/fesm2015/veloce-sdk-runtime.js.map +1 -1
  27. package/fesm2015/veloce-sdk.js +36 -38
  28. package/fesm2015/veloce-sdk.js.map +1 -1
  29. package/package.json +1 -1
  30. package/runtime/services/cart.service.d.ts +1 -1
  31. package/src/components/header/header.component.d.ts +2 -5
  32. package/src/components/header/header.types.d.ts +1 -0
  33. package/src/pages/product/product.component.d.ts +0 -1
  34. package/src/resolvers/quote.resolver.d.ts +1 -0
@@ -406,8 +406,6 @@ class FlowHeaderComponent {
406
406
  this.mode = ctx.mode;
407
407
  this.objectName = ctx.mode.toLowerCase();
408
408
  this.contextProperties = ctx.properties;
409
- this.assetPriceLists = this.quoteDraftService.assetPriceLists;
410
- this.activePriceList$ = this.quoteDraftService.activePriceList$;
411
409
  this.status$ = this.contextService.resolve$().pipe(map(context => { var _a; return (_a = context.properties.Status) !== null && _a !== void 0 ? _a : ''; }));
412
410
  this.isEditMode$ = this.quoteDraftService.isEditMode$();
413
411
  this.products$ = this.flowConfiguration.get().pipe(map(lineItems => this.generateProducts(lineItems)));
@@ -428,10 +426,10 @@ class FlowHeaderComponent {
428
426
  get isQuoteMode() {
429
427
  return this.mode === ConfigurationContextMode.QUOTE;
430
428
  }
431
- back(objectId) {
432
- const targetId = objectId !== null && objectId !== void 0 ? objectId : this.contextService.resolve().headerId;
433
- if (targetId) {
434
- window.VELO_BACK_FN.apply(null, [targetId]);
429
+ back() {
430
+ const objectId = this.contextService.resolve().headerId;
431
+ if (objectId) {
432
+ window.VELO_BACK_FN.apply(null, [objectId]);
435
433
  }
436
434
  }
437
435
  getSalesforceObjectLink(objectId) {
@@ -465,16 +463,18 @@ class FlowHeaderComponent {
465
463
  this.dialogService.showEmptyCartDialog().subscribe();
466
464
  return;
467
465
  }
468
- const quoteDraft = this.quoteDraftService.quoteDraft;
466
+ const quoteDraft = this.quoteDraftService.quoteSnapshot;
469
467
  if (!quoteDraft) {
470
468
  return;
471
469
  }
472
470
  this.isSaveInProgress$.next(true);
473
471
  this.quoteApiService
474
472
  .upsertQuote(quoteDraft)
475
- .pipe(tap(({ quoteId }) => {
476
- this.quoteDraftService.hasUnsavedChanges = false;
477
- this.back(quoteId);
473
+ .pipe(tap(() => {
474
+ // navigate back to quote on successful save
475
+ if (this.mode === ConfigurationContextMode.QUOTE) {
476
+ this.back();
477
+ }
478
478
  }), finalize(() => this.isSaveInProgress$.next(false)))
479
479
  .subscribe();
480
480
  }
@@ -487,22 +487,16 @@ class FlowHeaderComponent {
487
487
  this.dialogService.showAccountSubmitFailureDialog();
488
488
  return;
489
489
  }
490
- const quoteDraft = this.quoteDraftService.quoteDraft;
490
+ const quoteDraft = this.quoteDraftService.quoteSnapshot;
491
491
  if (!quoteDraft) {
492
492
  return;
493
493
  }
494
494
  this.isSubmitInProgress$.next(true);
495
495
  this.quoteApiService
496
496
  .submitQuote(quoteDraft)
497
- .pipe(switchMap(() => this.quoteApiService.getQuoteDraft(quoteDraft.quoteId)), tap(updatedQuoteDraft => {
498
- this.contextService.update({ properties: updatedQuoteDraft.context.properties });
499
- this.quoteDraftService.hasUnsavedChanges = false;
500
- }), finalize(() => this.isSubmitInProgress$.next(false)), takeUntil(this.destroyed$))
497
+ .pipe(switchMap(() => this.quoteApiService.getQuoteDraft(quoteDraft.quoteId)), tap(updatedQuoteDraft => this.contextService.update({ properties: updatedQuoteDraft.context.properties })), finalize(() => this.isSubmitInProgress$.next(false)), takeUntil(this.destroyed$))
501
498
  .subscribe();
502
499
  }
503
- selectPriceList(priceListId) {
504
- this.quoteDraftService.updateActivePriceList(priceListId);
505
- }
506
500
  queryName$(objectName, id) {
507
501
  if (!id) {
508
502
  return of('');
@@ -515,17 +509,19 @@ class FlowHeaderComponent {
515
509
  return this.sfApiService.query(searchRequest, objectName).pipe(map(result => { var _a, _b; return (_b = (_a = result[0]) === null || _a === void 0 ? void 0 : _a.Name) !== null && _b !== void 0 ? _b : ''; }), takeUntil(this.destroyed$));
516
510
  }
517
511
  populateObjectDetails() {
518
- var _a;
512
+ var _a, _b;
519
513
  const accountId = this.isAccountMode ? this.contextProperties.Id : this.contextProperties.AccountId;
520
514
  const opportunityId = this.contextProperties.OpportunityId;
521
515
  const quoteId = this.isQuoteMode ? this.contextProperties.Id : undefined;
522
516
  const quoteName = this.isQuoteMode ? this.contextProperties.Name : undefined;
523
517
  const quoteNumber = this.isQuoteMode ? (_a = this.contextProperties.QuoteNumber) === null || _a === void 0 ? void 0 : _a.replace(/^0+/, '') : undefined;
518
+ const priceListName = (_b = this.quoteDraftService.quotePriceList) === null || _b === void 0 ? void 0 : _b.name;
524
519
  this.objectDetails$.next(Object.assign(Object.assign({}, this.objectDetails$.value), { accountId,
525
520
  opportunityId,
526
521
  quoteId,
527
522
  quoteName,
528
- quoteNumber }));
523
+ quoteNumber,
524
+ priceListName }));
529
525
  this.queryName$('Account', accountId).subscribe(accountName => this.objectDetails$.next(Object.assign(Object.assign({}, this.objectDetails$.value), { accountName })));
530
526
  this.queryName$('Opportunity', opportunityId).subscribe(opportunityName => this.objectDetails$.next(Object.assign(Object.assign({}, this.objectDetails$.value), { opportunityName })));
531
527
  }
@@ -562,7 +558,7 @@ class FlowHeaderComponent {
562
558
  }
563
559
  }
564
560
  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: i1$2.QuoteApiService }, { token: i1$2.SalesforceApiService }, { token: i2$1.FlowConfigurationService }, { token: FlowRouterService }, { token: FlowDialogService }], target: i0.ɵɵFactoryTarget.Component });
565
- 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)\">{{ details.accountName }}</a>\n </li>\n <li class=\"info-list__row\">\n <span>Opportunity Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.opportunityId)\">{{\n details.opportunityName\n }}</a>\n </li>\n <li class=\"info-list__row\">\n <span>Quote Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.quoteId)\">{{ details.quoteName }}</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>MRR: <span class=\"font-semibold\">$0.00</span></span>\n <span>NRR: <span class=\"font-semibold\">$0.00</span></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 ></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__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.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$1.LetDirective, selector: "[vlLet]", inputs: ["vlLet"] }, { type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i9.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i9.AsyncPipe, "date": i9.DatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
561
+ 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)\">{{ details.accountName }}</a>\n </li>\n <li class=\"info-list__row\">\n <span>Opportunity Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.opportunityId)\">{{\n details.opportunityName\n }}</a>\n </li>\n <li class=\"info-list__row\">\n <span>Quote Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.quoteId)\">{{ details.quoteName }}</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 *ngIf=\"isQuoteMode\">\n <span *ngIf=\"details.priceListName\">{{ details.priceListName }}</span>\n <span *ngIf=\"contextProperties.StartDate\">{{ contextProperties.StartDate | date: 'MM.dd.yyyy' }}</span>\n\n <span class=\"slash-separator\"></span>\n\n <span>MRR: <span class=\"font-semibold\">$0.00</span></span>\n <span>NRR: <span class=\"font-semibold\">$0.00</span></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 ></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}: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__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}.flow-controls{flex-shrink:0;display:flex;align-items:center;grid-gap:8px;gap:8px}\n"], components: [{ type: i3.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$1.LetDirective, selector: "[vlLet]", inputs: ["vlLet"] }, { type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i9.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], pipes: { "async": i9.AsyncPipe, "date": i9.DatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
566
562
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderComponent, decorators: [{
567
563
  type: Component,
568
564
  args: [{
@@ -600,8 +596,8 @@ class FlowService {
600
596
  this.integrationState
601
597
  .listen$(FlowAction.FLOW_CONFIGURE_PRODUCT)
602
598
  .pipe(takeUntil(this.cleanup$), tap(payload => {
603
- var _a, _b;
604
- const productId = (_a = payload.productId) !== null && _a !== void 0 ? _a : (_b = this.quoteDraftService.currentState.find(li => li.id === payload.lineItemId)) === null || _b === void 0 ? void 0 : _b.productId;
599
+ var _a, _b, _c;
600
+ const productId = (_a = payload.productId) !== null && _a !== void 0 ? _a : (_c = (_b = this.quoteDraftService.quoteSnapshot) === null || _b === void 0 ? void 0 : _b.currentState.find(li => li.id === payload.lineItemId)) === null || _c === void 0 ? void 0 : _c.productId;
605
601
  if (productId) {
606
602
  this.flowRouterService.navigateToProductConfiguration(productId, payload.lineItemId);
607
603
  }
@@ -621,7 +617,7 @@ class FlowService {
621
617
  if (!lineItem) {
622
618
  return of(undefined);
623
619
  }
624
- const currentState = this.quoteDraftService.currentState;
620
+ const currentState = this.flowConfigurationService.getSnapshot();
625
621
  const isNewLineItem = currentState.every(li => li.id !== lineItem.id);
626
622
  let updatedState;
627
623
  if (isNewLineItem) {
@@ -630,8 +626,7 @@ class FlowService {
630
626
  else {
631
627
  updatedState = currentState.map(li => (li.id === lineItem.id ? lineItem : li));
632
628
  }
633
- this.quoteDraftService.setCurrentLineItemState(updatedState);
634
- return this.flowConfigurationService.calculate$();
629
+ return this.flowConfigurationService.calculate$(updatedState);
635
630
  }), tap(() => {
636
631
  this.configurationService.hasUnsavedChanges = false;
637
632
  this.flowRouterService.navigateToShoppingCart();
@@ -1049,7 +1044,7 @@ class LegacyProductComponent {
1049
1044
  this.destroyed$ = new Subject();
1050
1045
  }
1051
1046
  ngOnInit() {
1052
- this.quoteDraftService.quoteDraft$
1047
+ this.quoteDraftService.quote$
1053
1048
  .pipe(first(), takeUntil$1(this.destroyed$))
1054
1049
  .subscribe(quote => this.init(quote, this.route.snapshot.queryParams));
1055
1050
  this.runtimeService.onSolutionStopEvent.pipe(take(1)).subscribe(lineItem => this.onSolutionStop(lineItem));
@@ -1065,7 +1060,7 @@ class LegacyProductComponent {
1065
1060
  lineItem.actionCode = (_a = lineItem.actionCode) !== null && _a !== void 0 ? _a : 'ADD';
1066
1061
  }
1067
1062
  onSolutionCancel() {
1068
- this.quoteDraftService.quoteDraft$.pipe(first(), takeUntil$1(this.destroyed$)).subscribe(quote => {
1063
+ this.quoteDraftService.quote$.pipe(first(), takeUntil$1(this.destroyed$)).subscribe(quote => {
1069
1064
  window['VELO_BACK_FN'].apply(null, [quote.quoteId]);
1070
1065
  });
1071
1066
  }
@@ -1078,7 +1073,7 @@ class LegacyProductComponent {
1078
1073
  this.runtimeService.updateRuntime(states);
1079
1074
  }
1080
1075
  onSolutionStop(lineItem) {
1081
- this.quoteDraftService.quoteDraft$.pipe(first(), takeUntil$1(this.destroyed$)).subscribe(quote => {
1076
+ this.quoteDraftService.quote$.pipe(first(), takeUntil$1(this.destroyed$)).subscribe(quote => {
1082
1077
  const quoteToUpsert = Object.assign(Object.assign({}, quote), { context: this.contextService.resolve(), currentState: [...(this.currentStateService.currentState || []).filter(li => li.id !== lineItem.id), lineItem] });
1083
1078
  this.quoteApiService
1084
1079
  .upsertQuote(quoteToUpsert)
@@ -1183,7 +1178,7 @@ class ProductComponent {
1183
1178
  this.state$ = new BehaviorSubject({ loading: true, failure: false });
1184
1179
  }
1185
1180
  ngOnInit() {
1186
- this.quoteDraftService.quoteDraft$.pipe(first$1(), takeUntil(this.destroy$)).subscribe(quote => this.init(quote));
1181
+ this.quoteDraftService.quote$.pipe(first$1(), takeUntil(this.destroy$)).subscribe(quote => this.init(quote));
1187
1182
  }
1188
1183
  ngOnDestroy() {
1189
1184
  this.destroy$.next();
@@ -1209,15 +1204,14 @@ class ProductComponent {
1209
1204
  return;
1210
1205
  }
1211
1206
  const lineItemId = this.getLineItemId(quote, productId, contextProperties.lineItemId);
1212
- const currentStateItem = quote.currentState.find(({ id }) => id === lineItemId);
1207
+ const currentStateItem = EntityUtil.findById(lineItemId, quote.currentState);
1208
+ const { offeringId } = currentStateItem !== null && currentStateItem !== void 0 ? currentStateItem : {};
1213
1209
  if (currentStateItem) {
1214
1210
  this.configurationService.updateCurrentStates({
1215
1211
  configurableRamp: currentStateItem,
1216
1212
  currentState: quote.currentState,
1217
- asset: this.getAsset(quote, currentStateItem),
1218
1213
  });
1219
1214
  }
1220
- const { offeringId } = currentStateItem !== null && currentStateItem !== void 0 ? currentStateItem : {};
1221
1215
  this.runtimeService
1222
1216
  .init({ productId, offeringId })
1223
1217
  .pipe(tap(context => (this.uiDefinition = context === null || context === void 0 ? void 0 : context.uiDefinition)), switchMap(() => this.customize(productId)), switchMap(() => this.configurationService.configure()), tap(() => this.state$.next({ loading: false, failure: false })), catchError(error => {
@@ -1239,9 +1233,6 @@ class ProductComponent {
1239
1233
  }
1240
1234
  return id;
1241
1235
  }
1242
- getAsset(quote, lineItem) {
1243
- return quote.initialState.find(a => a.id === lineItem.openOrderLineItemId || a.id === lineItem.assetId);
1244
- }
1245
1236
  }
1246
1237
  ProductComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ProductComponent, deps: [{ token: i2$1.ContextService }, { token: i2$1.ConfigurationRuntimeService }, { token: i2$1.ConfigurationService }, { token: i2$1.QuoteDraftService }, { token: i2$2.MessageService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1247
1238
  ProductComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: ProductComponent, selector: "vl-flow-product", ngImport: i0, template: "<ng-container *ngIf=\"state$ | async as state\">\n <vl-loader *ngIf=\"state.loading; else content\" [label]=\"'Loading UI'\"></vl-loader>\n\n <ng-template #content>\n <ng-container *ngIf=\"!state.failure\">\n <vl-cms-preview [uiDefinition]=\"uiDefinition\"></vl-cms-preview>\n </ng-container>\n </ng-template>\n</ng-container>\n", styles: [""], components: [{ type: i3$1.LoaderComponent, selector: "vl-loader", inputs: ["label", "overlayVisible"] }, { type: i4.PreviewComponent, selector: "vl-cms-preview", inputs: ["modelId", "uiDefinition", "clearState"] }], directives: [{ type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i9.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
@@ -1496,14 +1487,21 @@ class QuoteResolver {
1496
1487
  const parentUrl = this.routerService.getFlowRootPath(route);
1497
1488
  return from(this.router.navigate([parentUrl, '404'], { state: { message } }));
1498
1489
  }
1490
+ initFlow$() {
1491
+ if (this.quoteDraftService.isStandalone) {
1492
+ return of(undefined);
1493
+ }
1494
+ return this.flowConfiguration.initialize$();
1495
+ }
1499
1496
  resolve(route) {
1500
1497
  const { headerId } = this.contextService.resolve();
1501
- const quote = this.quoteDraftService.quoteDraft;
1498
+ const quote = this.quoteDraftService.quoteSnapshot;
1502
1499
  if (quote && quote.quoteId === headerId) {
1503
1500
  return of(true);
1504
1501
  }
1505
1502
  const { queryParams } = route;
1506
- return this.quoteDraftService.init(headerId, queryParams).pipe(catchError(e => {
1503
+ this.contextService.update({ properties: queryParams });
1504
+ return this.quoteDraftService.init(headerId, queryParams).pipe(switchMap(() => this.initFlow$()), catchError(e => {
1507
1505
  const message = e instanceof HttpErrorResponse ? e.error.message : e;
1508
1506
  return this.handleError(route, message);
1509
1507
  }));