@veloceapps/sdk 3.1.8 → 3.1.10

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 (38) hide show
  1. package/bundles/veloce-sdk-cms.umd.js +1 -1
  2. package/bundles/veloce-sdk-cms.umd.js.map +1 -1
  3. package/bundles/veloce-sdk-core.umd.js +35 -2
  4. package/bundles/veloce-sdk-core.umd.js.map +1 -1
  5. package/bundles/veloce-sdk.umd.js +208 -262
  6. package/bundles/veloce-sdk.umd.js.map +1 -1
  7. package/cms/vendor-map.d.ts +2 -1
  8. package/core/services/index.d.ts +1 -0
  9. package/core/services/product-images.service.d.ts +12 -0
  10. package/esm2015/cms/vendor-map.js +4 -3
  11. package/esm2015/core/core.module.js +4 -4
  12. package/esm2015/core/services/index.js +2 -1
  13. package/esm2015/core/services/product-images.service.js +30 -0
  14. package/esm2015/src/components/header/cart-overlay/cart-preview.component.js +116 -0
  15. package/esm2015/src/components/header/cart-overlay/cart-preview.module.js +23 -0
  16. package/esm2015/src/components/header/header.component.js +3 -3
  17. package/esm2015/src/components/header/header.module.js +5 -5
  18. package/esm2015/src/flow-routing.module.js +7 -24
  19. package/esm2015/src/guards/context.guard.js +45 -33
  20. package/esm2015/src/guards/product-unload.guard.js +22 -10
  21. package/esm2015/src/resolvers/quote.resolver.js +3 -2
  22. package/fesm2015/veloce-sdk-cms.js +3 -2
  23. package/fesm2015/veloce-sdk-cms.js.map +1 -1
  24. package/fesm2015/veloce-sdk-core.js +34 -8
  25. package/fesm2015/veloce-sdk-core.js.map +1 -1
  26. package/fesm2015/veloce-sdk.js +136 -184
  27. package/fesm2015/veloce-sdk.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/components/header/cart-overlay/{cart-overlay.component.d.ts → cart-preview.component.d.ts} +7 -10
  30. package/src/components/header/cart-overlay/cart-preview.module.d.ts +13 -0
  31. package/src/components/header/header.module.d.ts +2 -2
  32. package/src/guards/context.guard.d.ts +6 -4
  33. package/src/guards/product-unload.guard.d.ts +5 -3
  34. package/esm2015/src/components/header/cart-overlay/cart-overlay.component.js +0 -133
  35. package/esm2015/src/components/header/cart-overlay/cart-overlay.module.js +0 -23
  36. package/esm2015/src/resolvers/context.resolver.js +0 -44
  37. package/src/components/header/cart-overlay/cart-overlay.module.d.ts +0 -13
  38. package/src/resolvers/context.resolver.d.ts +0 -16
@@ -2,43 +2,42 @@ import * as i9 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Component, ChangeDetectionStrategy, NgModule, Injectable, ViewChild, Input, InjectionToken, Optional, Inject } from '@angular/core';
5
- import * as i1$4 from '@veloce/api';
5
+ import * as i1$2 from '@veloce/api';
6
6
  import { ApiModule } from '@veloce/api';
7
- import * as i3 from '@veloce/components';
7
+ import * as i3$1 from '@veloce/components';
8
8
  import { LetDirectiveModule, ToastType, LoaderModule } from '@veloce/components';
9
- import * as i4$1 from '@veloce/sdk/cms';
9
+ import * as i4 from '@veloce/sdk/cms';
10
10
  import { FlowAction, PreviewModule, LauncherModule } from '@veloce/sdk/cms';
11
- import * as i1$2 from '@veloce/sdk/core';
11
+ import * as i2$1 from '@veloce/sdk/core';
12
12
  import { RuntimeOperation, SdkCoreModule } from '@veloce/sdk/core';
13
- import * as i5 from 'primeng/button';
13
+ import * as i2 from 'primeng/button';
14
14
  import { ButtonModule } from 'primeng/button';
15
15
  import * as i1 from 'primeng/dynamicdialog';
16
- import * as i4 from 'primeng/overlaypanel';
16
+ import * as i3 from 'primeng/overlaypanel';
17
17
  import { OverlayPanel, OverlayPanelModule } from 'primeng/overlaypanel';
18
18
  import * as i10 from 'primeng/tooltip';
19
19
  import { TooltipModule } from 'primeng/tooltip';
20
20
  import * as i7 from '@angular/forms';
21
21
  import { FormGroup, FormControl, ReactiveFormsModule, FormsModule } from '@angular/forms';
22
- import * as i6 from 'primeng/inputnumber';
22
+ import * as i5 from 'primeng/inputnumber';
23
23
  import { InputNumberModule } from 'primeng/inputnumber';
24
- import { map, filter, shareReplay, startWith, distinctUntilChanged, BehaviorSubject, Subject, combineLatest, takeUntil, noop, catchError, of, tap, finalize, switchMap, first as first$1, from } from 'rxjs';
25
- import * as i1$3 from '@veloce/core';
26
- import { ConfigurationContextMode, UITemplateComponentType, UITemplateType, EntityUtil } from '@veloce/core';
24
+ import { map, filter, shareReplay, startWith, distinctUntilChanged, BehaviorSubject, Subject, combineLatest, takeUntil, tap, finalize, switchMap, of, catchError, from, first as first$1 } from 'rxjs';
27
25
  import * as i1$1 from '@angular/router';
28
26
  import { NavigationEnd, NavigationStart, NavigationCancel, NavigationError, RouterModule } from '@angular/router';
29
- import * as i2 from 'primeng/api';
30
- import * as i4$2 from 'primeng/dropdown';
27
+ import * as i2$2 from 'primeng/api';
28
+ import { ConfigurationContextMode, UITemplateComponentType, UITemplateType, EntityUtil } from '@veloce/core';
29
+ import { HttpErrorResponse } from '@angular/common/http';
30
+ import * as i4$1 from 'primeng/dropdown';
31
31
  import { DropdownModule } from 'primeng/dropdown';
32
32
  import * as i8 from 'primeng/inputtext';
33
33
  import { InputTextModule } from 'primeng/inputtext';
34
- import * as i6$1 from 'primeng/radiobutton';
34
+ import * as i6 from 'primeng/radiobutton';
35
35
  import { RadioButtonModule } from 'primeng/radiobutton';
36
- import { first, takeUntil as takeUntil$1, take, map as map$1, switchMap as switchMap$1, tap as tap$1, catchError as catchError$1 } from 'rxjs/operators';
37
- import * as i4$3 from '@veloce/sdk/runtime';
36
+ import { first, takeUntil as takeUntil$1, take, map as map$1, switchMap as switchMap$1 } from 'rxjs/operators';
37
+ import * as i4$2 from '@veloce/sdk/runtime';
38
38
  import { RuntimeModule } from '@veloce/sdk/runtime';
39
- import * as i1$5 from 'ngx-bootstrap/tooltip';
39
+ import * as i1$3 from 'ngx-bootstrap/tooltip';
40
40
  import { TooltipModule as TooltipModule$1 } from 'ngx-bootstrap/tooltip';
41
- import { HttpErrorResponse } from '@angular/common/http';
42
41
 
43
42
  const VELOCE_FLOW_ROOT_ROUTE = 'VELOCE_FLOW_ROOT_ROUTE';
44
43
 
@@ -56,7 +55,7 @@ class FlowDialogComponent {
56
55
  }
57
56
  }
58
57
  FlowDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowDialogComponent, deps: [{ token: i1.DynamicDialogConfig }, { token: i1.DynamicDialogRef }], target: i0.ɵɵFactoryTarget.Component });
59
- FlowDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: FlowDialogComponent, selector: "vl-flow-dialog", ngImport: i0, template: "<div *ngIf=\"config.description\" class=\"description\">\n {{ config.description }}\n</div>\n\n<div class=\"form-actions\">\n <p-button\n *ngIf=\"config.secondaryButton\"\n styleClass=\"p-button-outlined button-text-bold\"\n [label]=\"config.secondaryButton!\"\n (onClick)=\"cancelHandler()\"\n ></p-button>\n <p-button\n styleClass=\"p-button p-button-filled\"\n [label]=\"config.primaryButton\"\n (onClick)=\"confirmHandler()\"\n ></p-button>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%}:host .description{flex:1;padding:0 24px 24px;font-weight:400;font-size:12px;line-height:16px;color:var(--vl-text-color-deep-accent)}:host .form-actions{border-top:1px solid var(--vl-border-color);padding:1.5rem 2.2rem;display:flex;justify-content:flex-end;width:100%;grid-gap:10px;gap:10px}\n"], components: [{ type: i5.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }], directives: [{ type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
58
+ FlowDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: FlowDialogComponent, selector: "vl-flow-dialog", ngImport: i0, template: "<div *ngIf=\"config.description\" class=\"description\">\n {{ config.description }}\n</div>\n\n<div class=\"form-actions\">\n <p-button\n *ngIf=\"config.secondaryButton\"\n styleClass=\"p-button-outlined button-text-bold\"\n [label]=\"config.secondaryButton!\"\n (onClick)=\"cancelHandler()\"\n ></p-button>\n <p-button\n styleClass=\"p-button p-button-filled\"\n [label]=\"config.primaryButton\"\n (onClick)=\"confirmHandler()\"\n ></p-button>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%}:host .description{flex:1;padding:0 24px 24px;font-weight:400;font-size:12px;line-height:16px;color:var(--vl-text-color-deep-accent)}:host .form-actions{border-top:1px solid var(--vl-border-color);padding:1.5rem 2.2rem;display:flex;justify-content:flex-end;width:100%;grid-gap:10px;gap:10px}\n"], components: [{ type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }], directives: [{ type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
60
59
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowDialogComponent, decorators: [{
61
60
  type: Component,
62
61
  args: [{
@@ -191,21 +190,20 @@ class FlowRouterService {
191
190
  this.router.navigate([flowRouteUrl, 'catalog'], { queryParams: routeSnapshot.queryParams });
192
191
  }
193
192
  }
194
- FlowRouterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRouterService, deps: [{ token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: i1$2.ContextService }], target: i0.ɵɵFactoryTarget.Injectable });
193
+ FlowRouterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRouterService, deps: [{ token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: i2$1.ContextService }], target: i0.ɵɵFactoryTarget.Injectable });
195
194
  FlowRouterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRouterService, providedIn: 'root' });
196
195
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRouterService, decorators: [{
197
196
  type: Injectable,
198
197
  args: [{ providedIn: 'root' }]
199
- }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i1$2.ContextService }]; } });
198
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i2$1.ContextService }]; } });
200
199
 
201
- class HeaderCartOverlayComponent {
202
- constructor(baseHttpService, flowConfiguration, routerService) {
203
- this.baseHttpService = baseHttpService;
200
+ class CartPreviewComponent {
201
+ constructor(flowConfiguration, routerService, productImagesService) {
204
202
  this.flowConfiguration = flowConfiguration;
205
203
  this.routerService = routerService;
204
+ this.productImagesService = productImagesService;
206
205
  this.form = new FormGroup({});
207
206
  this.shouldUpdate$ = new BehaviorSubject(true);
208
- this.imagesMap$ = new BehaviorSubject({});
209
207
  this.destroyed$ = new Subject();
210
208
  this.readonlyProductId$ = combineLatest([
211
209
  this.routerService.route$,
@@ -232,11 +230,7 @@ class HeaderCartOverlayComponent {
232
230
  this.destroyed$.complete();
233
231
  }
234
232
  getImageUrl(productId) {
235
- if (this.imagesMap$.value[productId] == null) {
236
- this.imagesMap$.next(Object.assign(Object.assign({}, this.imagesMap$.value), { [productId]: '' }));
237
- this.fetchProductImage(productId);
238
- }
239
- return this.imagesMap$.pipe(map(imagesMap => imagesMap[productId]), distinctUntilChanged());
233
+ return this.productImagesService.getImageUrl$(productId);
240
234
  }
241
235
  navigateToProductConfiguration(productId, lineItemId) {
242
236
  this.overlayPanel.hide();
@@ -263,17 +257,6 @@ class HeaderCartOverlayComponent {
263
257
  const productIds = this.products.map(product => product.id);
264
258
  this.flowConfiguration.delete(productIds);
265
259
  }
266
- fetchProductImage(productId) {
267
- this.baseHttpService
268
- .api({
269
- url: `/products/${productId}/image`,
270
- method: 'get',
271
- responseType: 'blob',
272
- errorHandler: noop,
273
- })
274
- .pipe(map(file => URL.createObjectURL(file)), catchError(() => of('')), tap(url => this.imagesMap$.next(Object.assign(Object.assign({}, this.imagesMap$.value), { [productId]: url }))), takeUntil(this.destroyed$))
275
- .subscribe();
276
- }
277
260
  updateControls(products, readonlyProductId) {
278
261
  const ids = [];
279
262
  products.forEach(item => {
@@ -299,34 +282,34 @@ class HeaderCartOverlayComponent {
299
282
  removedIds.forEach(id => this.form.removeControl(id));
300
283
  }
301
284
  }
302
- HeaderCartOverlayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: HeaderCartOverlayComponent, deps: [{ token: i1$3.BaseHttpService }, { token: i1$2.FlowConfigurationService }, { token: FlowRouterService }], target: i0.ɵɵFactoryTarget.Component });
303
- HeaderCartOverlayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: HeaderCartOverlayComponent, selector: "vl-header-cart-overlay", inputs: { products: "products" }, viewQueries: [{ propertyName: "overlayPanel", first: true, predicate: OverlayPanel, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<p-overlayPanel\n styleClass=\"navigation-settings-overlay flow-header-overlay center\"\n showTransitionOptions=\"0ms\"\n hideTransitionOptions=\"0ms\"\n>\n <ng-template pTemplate>\n <div class=\"flow-header-overlay__wrapper\" *vlLet=\"readonlyProductId$ | async as readonlyProductId\">\n <ng-container *ngIf=\"products.length > 0; else empty\">\n <h2 class=\"flow-header-overlay__title\">\n <span>Products ({{ products.length }})</span>\n <i class=\"vl-icon vl-icon-close close-icon\" (click)=\"overlayPanel.hide()\"></i>\n </h2>\n\n <div class=\"product header\">\n <span>Product</span>\n <span class=\"text-right\">Qty</span>\n <span class=\"text-right\">MRR</span>\n <span class=\"text-right\">NRR</span>\n </div>\n\n <div class=\"scrollable-wrapper\">\n <div class=\"product\" *ngFor=\"let product of products\">\n <div class=\"product__info\">\n <div class=\"product__image-wrapper\">\n <div\n *ngIf=\"getImageUrl(product.productId) | async as imageUrl; else noImage\"\n class=\"product__image\"\n [ngStyle]=\"{ 'background-image': 'url(' + imageUrl + ')' }\"\n ></div>\n </div>\n <div class=\"flex flex-column justify-content-center\">\n <div class=\"word-break\">{{ product.name }}</div>\n <div>\n <p-button\n label=\"Configure\"\n [disabled]=\"!product.configurable || readonlyProductId === product.productId\"\n styleClass=\"p-button-link p-button-sm pl-0\"\n (onClick)=\"navigateToProductConfiguration(product.productId, product.id)\"\n ></p-button>\n <p-button\n label=\"Delete\"\n [disabled]=\"readonlyProductId === product.productId\"\n styleClass=\"p-button-link p-button-sm p-button-danger pl-0 pr-0\"\n (onClick)=\"deleteHandler(product)\"\n ></p-button>\n </div>\n </div>\n </div>\n\n <span>\n <p-inputNumber\n *ngIf=\"form.controls[product.id] as control\"\n class=\"qty-control\"\n [formControl]=\"$any(control)\"\n [min]=\"1\"\n [required]=\"true\"\n (onBlur)=\"controlBlurHandler(product)\"\n ></p-inputNumber>\n </span>\n <span class=\"text-right pt-3\">$0.00</span>\n <span class=\"text-right pt-3\">$0.00</span>\n </div>\n\n <ng-template #noImage>\n <i class=\"vl-icon vl-icon-no-image no-image-icon\"></i>\n </ng-template>\n </div>\n\n <div class=\"flex justify-content-end mt-3\">\n <p-button\n label=\"Clear cart\"\n styleClass=\"p-button-link p-button-sm p-button-danger pl-0 pr-0\"\n [disabled]=\"readonlyProductId\"\n (onClick)=\"deleteAllHandler()\"\n ></p-button>\n </div>\n </ng-container>\n\n <ng-template #empty>\n <h2 class=\"flow-header-overlay__title\">\n <span>Empty Cart</span>\n <i class=\"vl-icon vl-icon-close close-icon\" (click)=\"overlayPanel.hide()\"></i>\n </h2>\n\n <span class=\"empty-state\">There are no products added to the Shopping Cart yet.</span>\n </ng-template>\n </div>\n </ng-template>\n</p-overlayPanel>\n", styles: [".flow-header-overlay__wrapper{display:flex;flex-direction:column;width:460px;max-height:600px}.flow-header-overlay__wrapper .close-icon{cursor:pointer}.flow-header-overlay__title{display:flex;justify-content:space-between;align-items:center;margin:0 0 16px}.empty-state{color:var(--vl-text-color-deep-accent)}.scrollable-wrapper{overflow:auto}.product{display:grid;grid-template-columns:auto 60px 80px 80px;padding:16px 0}.product:not(.header){border-bottom:1px solid var(--vl-border-color)}.product.header{color:var(--vl-text-color-deep-accent)}.product__info{display:flex;grid-gap:16px;gap:16px}.product__image-wrapper{flex-shrink:0;height:64px;width:64px;display:flex;justify-content:center;align-items:center;background:var(--vl-primary-nav-overlay-bg);border-radius:4px}.product__image{background-size:contain;background-repeat:no-repeat;background-position:center;height:calc(100% - 12px);width:calc(100% - 12px)}.product .qty-control ::ng-deep .p-inputnumber-input{align-self:flex-start;text-align:right;width:100%}.word-break{word-break:break-word}.no-image-icon{color:#b4d1ef;height:18px;width:18px}\n"], components: [{ type: i4.OverlayPanel, selector: "p-overlayPanel", inputs: ["dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { type: i5.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }, { type: i6.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown"] }], directives: [{ type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i3.LetDirective, selector: "[vlLet]", inputs: ["vlLet"] }, { type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }], pipes: { "async": i9.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: HeaderCartOverlayComponent, decorators: [{
285
+ CartPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CartPreviewComponent, deps: [{ token: i2$1.FlowConfigurationService }, { token: FlowRouterService }, { token: i2$1.ProductImagesService }], target: i0.ɵɵFactoryTarget.Component });
286
+ CartPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: CartPreviewComponent, selector: "vl-cart-preview", inputs: { products: "products" }, viewQueries: [{ propertyName: "overlayPanel", first: true, predicate: OverlayPanel, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<p-overlayPanel\n styleClass=\"navigation-settings-overlay flow-header-overlay center\"\n showTransitionOptions=\"0ms\"\n hideTransitionOptions=\"0ms\"\n>\n <ng-template pTemplate>\n <div class=\"flow-header-overlay__wrapper\" *vlLet=\"readonlyProductId$ | async as readonlyProductId\">\n <ng-container *ngIf=\"products.length > 0; else empty\">\n <h2 class=\"flow-header-overlay__title\">\n <span>Products ({{ products.length }})</span>\n <i class=\"vl-icon vl-icon-close close-icon\" (click)=\"overlayPanel.hide()\"></i>\n </h2>\n\n <div class=\"product header\">\n <span>Product</span>\n <span class=\"text-right\">Qty</span>\n <span class=\"text-right\">MRR</span>\n <span class=\"text-right\">NRR</span>\n </div>\n\n <div class=\"scrollable-wrapper\">\n <div class=\"product\" *ngFor=\"let product of products\">\n <div class=\"product__info\">\n <div class=\"product__image-wrapper\">\n <div\n *ngIf=\"getImageUrl(product.productId) | async as imageUrl; else noImage\"\n class=\"product__image\"\n [ngStyle]=\"{ 'background-image': 'url(' + imageUrl + ')' }\"\n ></div>\n </div>\n <div class=\"flex flex-column justify-content-center\">\n <div class=\"word-break\">{{ product.name }}</div>\n <div>\n <p-button\n label=\"Configure\"\n [disabled]=\"!product.configurable || readonlyProductId === product.productId\"\n styleClass=\"p-button-link p-button-sm pl-0\"\n (onClick)=\"navigateToProductConfiguration(product.productId, product.id)\"\n ></p-button>\n <p-button\n label=\"Delete\"\n [disabled]=\"readonlyProductId === product.productId\"\n styleClass=\"p-button-link p-button-sm p-button-danger pl-0 pr-0\"\n (onClick)=\"deleteHandler(product)\"\n ></p-button>\n </div>\n </div>\n </div>\n\n <span>\n <p-inputNumber\n *ngIf=\"form.controls[product.id] as control\"\n class=\"qty-control\"\n [formControl]=\"$any(control)\"\n [min]=\"1\"\n [required]=\"true\"\n (onBlur)=\"controlBlurHandler(product)\"\n ></p-inputNumber>\n </span>\n <span class=\"text-right pt-3\">$0.00</span>\n <span class=\"text-right pt-3\">$0.00</span>\n </div>\n\n <ng-template #noImage>\n <i class=\"vl-icon vl-icon-no-image no-image-icon\"></i>\n </ng-template>\n </div>\n\n <div class=\"flex justify-content-end mt-3\">\n <p-button\n label=\"Clear cart\"\n styleClass=\"p-button-link p-button-sm p-button-danger pl-0 pr-0\"\n [disabled]=\"readonlyProductId\"\n (onClick)=\"deleteAllHandler()\"\n ></p-button>\n </div>\n </ng-container>\n\n <ng-template #empty>\n <h2 class=\"flow-header-overlay__title\">\n <span>Empty Cart</span>\n <i class=\"vl-icon vl-icon-close close-icon\" (click)=\"overlayPanel.hide()\"></i>\n </h2>\n\n <span class=\"empty-state\">There are no products added to the Shopping Cart yet.</span>\n </ng-template>\n </div>\n </ng-template>\n</p-overlayPanel>\n", styles: [".flow-header-overlay__wrapper{display:flex;flex-direction:column;width:460px;max-height:600px}.flow-header-overlay__wrapper .close-icon{cursor:pointer}.flow-header-overlay__title{display:flex;justify-content:space-between;align-items:center;margin:0 0 16px}.empty-state{color:var(--vl-text-color-deep-accent)}.scrollable-wrapper{overflow:auto}.product{display:grid;grid-template-columns:auto 60px 80px 80px;padding:16px 0}.product:not(.header){border-bottom:1px solid var(--vl-border-color)}.product.header{color:var(--vl-text-color-deep-accent)}.product__info{display:flex;grid-gap:16px;gap:16px}.product__image-wrapper{flex-shrink:0;height:64px;width:64px;display:flex;justify-content:center;align-items:center;background:var(--vl-primary-nav-overlay-bg);border-radius:4px}.product__image{background-size:contain;background-repeat:no-repeat;background-position:center;height:calc(100% - 12px);width:calc(100% - 12px)}.product .qty-control ::ng-deep .p-inputnumber-input{align-self:flex-start;text-align:right;width:100%}.word-break{word-break:break-word}.no-image-icon{color:#b4d1ef;height:18px;width:18px}\n"], components: [{ type: i3.OverlayPanel, selector: "p-overlayPanel", inputs: ["dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }, { type: i5.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown"] }], directives: [{ type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i3$1.LetDirective, selector: "[vlLet]", inputs: ["vlLet"] }, { type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }], pipes: { "async": i9.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
287
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CartPreviewComponent, decorators: [{
305
288
  type: Component,
306
289
  args: [{
307
- selector: 'vl-header-cart-overlay',
308
- templateUrl: './cart-overlay.component.html',
309
- styleUrls: ['./cart-overlay.component.scss'],
290
+ selector: 'vl-cart-preview',
291
+ templateUrl: './cart-preview.component.html',
292
+ styleUrls: ['./cart-preview.component.scss'],
310
293
  changeDetection: ChangeDetectionStrategy.OnPush,
311
294
  }]
312
- }], ctorParameters: function () { return [{ type: i1$3.BaseHttpService }, { type: i1$2.FlowConfigurationService }, { type: FlowRouterService }]; }, propDecorators: { overlayPanel: [{
295
+ }], ctorParameters: function () { return [{ type: i2$1.FlowConfigurationService }, { type: FlowRouterService }, { type: i2$1.ProductImagesService }]; }, propDecorators: { overlayPanel: [{
313
296
  type: ViewChild,
314
297
  args: [OverlayPanel]
315
298
  }], products: [{
316
299
  type: Input
317
300
  }] } });
318
301
 
319
- class HeaderCartOverlayModule {
302
+ class CartPreviewModule {
320
303
  }
321
- HeaderCartOverlayModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: HeaderCartOverlayModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
322
- HeaderCartOverlayModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: HeaderCartOverlayModule, declarations: [HeaderCartOverlayComponent], imports: [CommonModule, ReactiveFormsModule, ButtonModule, OverlayPanelModule, LetDirectiveModule, InputNumberModule], exports: [HeaderCartOverlayComponent] });
323
- HeaderCartOverlayModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: HeaderCartOverlayModule, imports: [[CommonModule, ReactiveFormsModule, ButtonModule, OverlayPanelModule, LetDirectiveModule, InputNumberModule]] });
324
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: HeaderCartOverlayModule, decorators: [{
304
+ CartPreviewModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CartPreviewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
305
+ CartPreviewModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CartPreviewModule, declarations: [CartPreviewComponent], imports: [CommonModule, ReactiveFormsModule, ButtonModule, OverlayPanelModule, LetDirectiveModule, InputNumberModule], exports: [CartPreviewComponent] });
306
+ CartPreviewModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CartPreviewModule, imports: [[CommonModule, ReactiveFormsModule, ButtonModule, OverlayPanelModule, LetDirectiveModule, InputNumberModule]] });
307
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CartPreviewModule, decorators: [{
325
308
  type: NgModule,
326
309
  args: [{
327
- declarations: [HeaderCartOverlayComponent],
310
+ declarations: [CartPreviewComponent],
328
311
  imports: [CommonModule, ReactiveFormsModule, ButtonModule, OverlayPanelModule, LetDirectiveModule, InputNumberModule],
329
- exports: [HeaderCartOverlayComponent],
312
+ exports: [CartPreviewComponent],
330
313
  }]
331
314
  }] });
332
315
 
@@ -399,11 +382,11 @@ class FlowDialogService {
399
382
  });
400
383
  }
401
384
  }
402
- FlowDialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowDialogService, deps: [{ token: i1.DialogService }, { token: i1$2.ContextService }], target: i0.ɵɵFactoryTarget.Injectable });
385
+ FlowDialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowDialogService, deps: [{ token: i1.DialogService }, { token: i2$1.ContextService }], target: i0.ɵɵFactoryTarget.Injectable });
403
386
  FlowDialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowDialogService });
404
387
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowDialogService, decorators: [{
405
388
  type: Injectable
406
- }], ctorParameters: function () { return [{ type: i1.DialogService }, { type: i1$2.ContextService }]; } });
389
+ }], ctorParameters: function () { return [{ type: i1.DialogService }, { type: i2$1.ContextService }]; } });
407
390
 
408
391
  class FlowHeaderComponent {
409
392
  constructor(contextService, quoteDraftService, quoteApiService, sfApiService, flowConfiguration, routerService, dialogService) {
@@ -574,8 +557,8 @@ class FlowHeaderComponent {
574
557
  }, []);
575
558
  }
576
559
  }
577
- FlowHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderComponent, deps: [{ token: i1$2.ContextService }, { token: i1$2.QuoteDraftService }, { token: i1$4.QuoteApiService }, { token: i1$4.SalesforceApiService }, { token: i1$2.FlowConfigurationService }, { token: FlowRouterService }, { token: FlowDialogService }], target: i0.ɵɵFactoryTarget.Component });
578
- 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-header-cart-overlay #cart [products]=\"products\"></vl-header-cart-overlay>\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: i4.OverlayPanel, selector: "p-overlayPanel", inputs: ["dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { type: HeaderCartOverlayComponent, selector: "vl-header-cart-overlay", inputs: ["products"] }, { type: i5.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: 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.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 });
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 });
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 });
579
562
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderComponent, decorators: [{
580
563
  type: Component,
581
564
  args: [{
@@ -584,18 +567,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
584
567
  styleUrls: ['./header.component.scss'],
585
568
  changeDetection: ChangeDetectionStrategy.OnPush,
586
569
  }]
587
- }], ctorParameters: function () { return [{ type: i1$2.ContextService }, { type: i1$2.QuoteDraftService }, { type: i1$4.QuoteApiService }, { type: i1$4.SalesforceApiService }, { type: i1$2.FlowConfigurationService }, { type: FlowRouterService }, { type: FlowDialogService }]; } });
570
+ }], ctorParameters: function () { return [{ type: i2$1.ContextService }, { type: i2$1.QuoteDraftService }, { type: i1$2.QuoteApiService }, { type: i1$2.SalesforceApiService }, { type: i2$1.FlowConfigurationService }, { type: FlowRouterService }, { type: FlowDialogService }]; } });
588
571
 
589
572
  class FlowHeaderModule {
590
573
  }
591
574
  FlowHeaderModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
592
- FlowHeaderModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, declarations: [FlowHeaderComponent], imports: [CommonModule, OverlayPanelModule, LetDirectiveModule, TooltipModule, ButtonModule, HeaderCartOverlayModule], exports: [FlowHeaderComponent] });
593
- FlowHeaderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, imports: [[CommonModule, OverlayPanelModule, LetDirectiveModule, TooltipModule, ButtonModule, HeaderCartOverlayModule]] });
575
+ 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] });
576
+ FlowHeaderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, imports: [[CommonModule, OverlayPanelModule, LetDirectiveModule, TooltipModule, ButtonModule, CartPreviewModule]] });
594
577
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderModule, decorators: [{
595
578
  type: NgModule,
596
579
  args: [{
597
580
  declarations: [FlowHeaderComponent],
598
- imports: [CommonModule, OverlayPanelModule, LetDirectiveModule, TooltipModule, ButtonModule, HeaderCartOverlayModule],
581
+ imports: [CommonModule, OverlayPanelModule, LetDirectiveModule, TooltipModule, ButtonModule, CartPreviewModule],
599
582
  exports: [FlowHeaderComponent],
600
583
  }]
601
584
  }] });
@@ -654,11 +637,11 @@ class FlowService {
654
637
  this.cleanup$.next();
655
638
  }
656
639
  }
657
- FlowService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowService, deps: [{ token: i4$1.IntegrationState }, { token: FlowRouterService }, { token: i1$2.QuoteDraftService }, { token: i1$2.ConfigurationService }, { token: i1$2.FlowConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable });
640
+ FlowService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowService, deps: [{ token: i4.IntegrationState }, { token: FlowRouterService }, { token: i2$1.QuoteDraftService }, { token: i2$1.ConfigurationService }, { token: i2$1.FlowConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable });
658
641
  FlowService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowService });
659
642
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowService, decorators: [{
660
643
  type: Injectable
661
- }], ctorParameters: function () { return [{ type: i4$1.IntegrationState }, { type: FlowRouterService }, { type: i1$2.QuoteDraftService }, { type: i1$2.ConfigurationService }, { type: i1$2.FlowConfigurationService }]; } });
644
+ }], ctorParameters: function () { return [{ type: i4.IntegrationState }, { type: FlowRouterService }, { type: i2$1.QuoteDraftService }, { type: i2$1.ConfigurationService }, { type: i2$1.FlowConfigurationService }]; } });
662
645
 
663
646
  class FlowComponent {
664
647
  constructor(routerService, quoteDraftService, flowService) {
@@ -673,8 +656,8 @@ class FlowComponent {
673
656
  this.flowService.cleanup();
674
657
  }
675
658
  }
676
- FlowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowComponent, deps: [{ token: FlowRouterService }, { token: i1$2.QuoteDraftService }, { token: FlowService }], target: i0.ɵɵFactoryTarget.Component });
677
- FlowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: FlowComponent, selector: "vl-flow", ngImport: i0, template: "<vl-flow-header *ngIf=\"showHeader$ | async\"></vl-flow-header>\n\n<div class=\"flow-content\">\n <div class=\"loading-overlay\" *ngIf=\"isLoading$ | async\">\n <vl-loader label=\"LOADING\"></vl-loader>\n </div>\n\n <router-outlet></router-outlet>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%}.flow-content{flex-grow:1;position:relative;overflow:hidden}.loading-overlay{position:absolute;height:100%;width:100%;left:0;right:0;top:0;bottom:0;background-color:#ffffff80;z-index:4}\n"], components: [{ type: FlowHeaderComponent, selector: "vl-flow-header" }, { type: i3.LoaderComponent, selector: "vl-loader", inputs: ["label", "overlayVisible"] }], directives: [{ type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate"], exportAs: ["outlet"] }], pipes: { "async": i9.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
659
+ FlowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowComponent, deps: [{ token: FlowRouterService }, { token: i2$1.QuoteDraftService }, { token: FlowService }], target: i0.ɵɵFactoryTarget.Component });
660
+ FlowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: FlowComponent, selector: "vl-flow", ngImport: i0, template: "<vl-flow-header *ngIf=\"showHeader$ | async\"></vl-flow-header>\n\n<div class=\"flow-content\">\n <div class=\"loading-overlay\" *ngIf=\"isLoading$ | async\">\n <vl-loader label=\"LOADING\"></vl-loader>\n </div>\n\n <router-outlet></router-outlet>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%}.flow-content{flex-grow:1;position:relative;overflow:hidden}.loading-overlay{position:absolute;height:100%;width:100%;left:0;right:0;top:0;bottom:0;background-color:#ffffff80;z-index:4}\n"], components: [{ type: FlowHeaderComponent, selector: "vl-flow-header" }, { type: i3$1.LoaderComponent, selector: "vl-loader", inputs: ["label", "overlayVisible"] }], directives: [{ type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate"], exportAs: ["outlet"] }], pipes: { "async": i9.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
678
661
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowComponent, decorators: [{
679
662
  type: Component,
680
663
  args: [{
@@ -683,12 +666,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
683
666
  styleUrls: ['./flow.component.scss'],
684
667
  changeDetection: ChangeDetectionStrategy.OnPush,
685
668
  }]
686
- }], ctorParameters: function () { return [{ type: FlowRouterService }, { type: i1$2.QuoteDraftService }, { type: FlowService }]; } });
669
+ }], ctorParameters: function () { return [{ type: FlowRouterService }, { type: i2$1.QuoteDraftService }, { type: FlowService }]; } });
687
670
 
688
671
  class ContextGuard {
689
- constructor(router, routerService) {
672
+ constructor(router, routerService, contextService) {
690
673
  this.router = router;
691
674
  this.routerService = routerService;
675
+ this.contextService = contextService;
676
+ }
677
+ checkActivation(route) {
678
+ var _a, _b;
679
+ const { queryParams } = route;
680
+ const { accountId, quoteId, orderId } = queryParams;
681
+ const rpcMessage = window.RPC_MESSAGE;
682
+ const mode = this.getConfigurationContextMode(accountId, quoteId, orderId, rpcMessage);
683
+ // Restrict if mode is not defined
684
+ if (mode == null) {
685
+ return this.handleError(route, 'Mode is undefined');
686
+ }
687
+ const rpcMessageId = rpcMessage && ((_b = (_a = JSON.parse(rpcMessage)) === null || _a === void 0 ? void 0 : _a.quote) === null || _b === void 0 ? void 0 : _b.Id);
688
+ const headerId = accountId || quoteId || orderId || rpcMessageId || 'empty-for-test-mode';
689
+ // Allow if context is already initialized with the same headerId
690
+ if (this.contextService.isInitialized) {
691
+ const currentContext = this.contextService.resolve();
692
+ if (headerId && currentContext.headerId === headerId) {
693
+ return of(true);
694
+ }
695
+ }
696
+ // Initialize context
697
+ return this.contextService.create(headerId, mode).pipe(tap((context) => {
698
+ // Update context with queryParams
699
+ this.contextService.update(Object.assign(Object.assign({}, context), { properties: Object.assign(Object.assign({}, context.properties), (queryParams !== null && queryParams !== void 0 ? queryParams : {})) }));
700
+ }), map(() => true), catchError(e => {
701
+ const message = e instanceof HttpErrorResponse ? e.error.message : e;
702
+ return this.handleError(route, message);
703
+ }));
704
+ }
705
+ canActivate(route) {
706
+ return this.checkActivation(route);
707
+ }
708
+ canActivateChild(childRoute) {
709
+ return this.checkActivation(childRoute);
692
710
  }
693
711
  getConfigurationContextMode(accountId, quoteId, orderId, rpcMessage) {
694
712
  if (accountId) {
@@ -705,69 +723,54 @@ class ContextGuard {
705
723
  }
706
724
  return;
707
725
  }
708
- checkActivation(route) {
709
- var _a, _b;
710
- const { queryParams } = route;
711
- const { accountId, quoteId, orderId } = queryParams;
712
- const rpcMessage = window['RPC_MESSAGE'];
713
- const rpcMessageId = rpcMessage && ((_b = (_a = JSON.parse(rpcMessage)) === null || _a === void 0 ? void 0 : _a.quote) === null || _b === void 0 ? void 0 : _b.Id);
714
- const headerId = accountId || quoteId || orderId || rpcMessageId || 'empty-for-test-mode';
715
- const mode = this.getConfigurationContextMode(accountId, quoteId, orderId, rpcMessage);
716
- if (mode === void 0) {
717
- return this.reject(route, 'Mode is undefined');
718
- }
719
- const contextRouteData = {
720
- headerId,
721
- mode,
722
- };
723
- route.data = Object.assign(Object.assign({}, route.data), contextRouteData);
724
- return true;
725
- }
726
- canActivate(route) {
727
- return this.checkActivation(route);
728
- }
729
- canActivateChild(childRoute) {
730
- return this.checkActivation(childRoute);
731
- }
732
- reject(route, message) {
726
+ handleError(route, message) {
727
+ this.contextService.delete();
733
728
  const parentUrl = this.routerService.getFlowRootPath(route);
734
- this.router.navigate([parentUrl, '404'], {
735
- state: { message },
736
- });
737
- return false;
729
+ return from(this.router.navigate([parentUrl, '404'], { state: { message } })).pipe(map(() => false));
738
730
  }
739
731
  }
740
- ContextGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ContextGuard, deps: [{ token: i1$1.Router }, { token: FlowRouterService }], target: i0.ɵɵFactoryTarget.Injectable });
732
+ ContextGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ContextGuard, deps: [{ token: i1$1.Router }, { token: FlowRouterService }, { token: i2$1.ContextService }], target: i0.ɵɵFactoryTarget.Injectable });
741
733
  ContextGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ContextGuard });
742
734
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ContextGuard, decorators: [{
743
735
  type: Injectable
744
- }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: FlowRouterService }]; } });
736
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: FlowRouterService }, { type: i2$1.ContextService }]; } });
745
737
 
746
738
  class ProductUnloadGuard {
747
- constructor(contextService, quoteDraftService, configurationService, flowDialogService) {
739
+ constructor(router, contextService, quoteDraftService, configurationService, flowDialogService) {
740
+ this.router = router;
748
741
  this.contextService = contextService;
749
742
  this.quoteDraftService = quoteDraftService;
750
743
  this.configurationService = configurationService;
751
744
  this.flowDialogService = flowDialogService;
752
745
  }
753
- canDeactivate() {
746
+ canDeactivate(_, route, currentState, nextState) {
754
747
  let observable = of(true);
755
748
  if (!this.quoteDraftService.isStandalone && this.configurationService.hasUnsavedChanges) {
756
749
  observable = this.flowDialogService.showUnsavedChangesDialog().pipe(map(confirmed => !confirmed));
757
750
  }
758
- return observable.pipe(tap(unload => {
751
+ return observable.pipe(map(unload => {
759
752
  if (unload) {
760
- this.contextService.update({ properties: { productId: undefined, lineItemId: undefined } });
761
753
  this.configurationService.reset();
754
+ this.contextService.update({ properties: { productId: undefined, lineItemId: undefined } });
755
+ if (!nextState || currentState.url === nextState.url) {
756
+ return true;
757
+ }
758
+ // clear obsolete queryParams
759
+ const urlTree = this.router.parseUrl(nextState.url);
760
+ delete urlTree.queryParams.productId;
761
+ // replace url after deactivation has finished
762
+ setTimeout(() => this.router.navigateByUrl(urlTree.toString(), { replaceUrl: true }));
763
+ return true;
762
764
  }
765
+ return false;
763
766
  }));
764
767
  }
765
768
  }
766
- ProductUnloadGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ProductUnloadGuard, deps: [{ token: i1$2.ContextService }, { token: i1$2.QuoteDraftService }, { token: i1$2.ConfigurationService }, { token: FlowDialogService }], target: i0.ɵɵFactoryTarget.Injectable });
769
+ ProductUnloadGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ProductUnloadGuard, deps: [{ token: i1$1.Router }, { token: i2$1.ContextService }, { token: i2$1.QuoteDraftService }, { token: i2$1.ConfigurationService }, { token: FlowDialogService }], target: i0.ɵɵFactoryTarget.Injectable });
767
770
  ProductUnloadGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ProductUnloadGuard });
768
771
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ProductUnloadGuard, decorators: [{
769
772
  type: Injectable
770
- }], ctorParameters: function () { return [{ type: i1$2.ContextService }, { type: i1$2.QuoteDraftService }, { type: i1$2.ConfigurationService }, { type: FlowDialogService }]; } });
773
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i2$1.ContextService }, { type: i2$1.QuoteDraftService }, { type: i2$1.ConfigurationService }, { type: FlowDialogService }]; } });
771
774
 
772
775
  class RootGuard {
773
776
  constructor(router, routerService) {
@@ -897,8 +900,8 @@ class CatalogComponent {
897
900
  }));
898
901
  }
899
902
  }
900
- CatalogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CatalogComponent, deps: [{ token: i1$4.UITemplatesApiService }, { token: i1$2.ContextService }, { token: i0.ChangeDetectorRef }, { token: i3.ToastService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Component });
901
- CatalogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: CatalogComponent, selector: "vl-flow-catalog", 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.LoaderComponent, selector: "vl-loader", inputs: ["label", "overlayVisible"] }, { type: i4$1.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 });
903
+ CatalogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CatalogComponent, deps: [{ token: i1$2.UITemplatesApiService }, { token: i2$1.ContextService }, { token: i0.ChangeDetectorRef }, { token: i3$1.ToastService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Component });
904
+ CatalogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: CatalogComponent, selector: "vl-flow-catalog", 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 });
902
905
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: CatalogComponent, decorators: [{
903
906
  type: Component,
904
907
  args: [{
@@ -907,7 +910,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
907
910
  styleUrls: ['./catalog.component.scss'],
908
911
  changeDetection: ChangeDetectionStrategy.OnPush,
909
912
  }]
910
- }], ctorParameters: function () { return [{ type: i1$4.UITemplatesApiService }, { type: i1$2.ContextService }, { type: i0.ChangeDetectorRef }, { type: i3.ToastService }, { type: undefined, decorators: [{
913
+ }], ctorParameters: function () { return [{ type: i1$2.UITemplatesApiService }, { type: i2$1.ContextService }, { type: i0.ChangeDetectorRef }, { type: i3$1.ToastService }, { type: undefined, decorators: [{
911
914
  type: Optional
912
915
  }, {
913
916
  type: Inject,
@@ -979,8 +982,8 @@ class DebugComponent {
979
982
  });
980
983
  }
981
984
  }
982
- DebugComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: DebugComponent, deps: [{ token: i1$4.FlowsApiService }, { token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: i1$2.ContextService }, { token: i1$2.FlowConfigurationService }, { token: i1$2.QuoteDraftService }], target: i0.ɵɵFactoryTarget.Component });
983
- DebugComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: DebugComponent, selector: "vl-flow-debug", ngImport: i0, template: "<form [formGroup]=\"form\">\n <div class=\"fields-container\">\n <div class=\"field\">\n <label>SF Object ID</label>\n <input formControlName=\"id\" pInputText type=\"text\" />\n </div>\n\n <div class=\"field\">\n <label>SF Object Name</label>\n <p-dropdown\n appendTo=\"body\"\n formControlName=\"name\"\n [autoDisplayFirst]=\"false\"\n [options]=\"objectNames\"\n ></p-dropdown>\n </div>\n </div>\n\n <p-button\n styleClass=\"p-button-primary\"\n label=\"Run Flow\"\n [disabled]=\"!form.value.id || !selectedFlow\"\n (onClick)=\"runFlow()\"\n ></p-button>\n</form>\n\n<table>\n <thead>\n <tr>\n <th [width]=\"30\"></th>\n <th [width]=\"160\">ID</th>\n <th [width]=\"160\">Entry Path</th>\n <th>QueryParams</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let flow of flows$ | async\" (click)=\"selectedFlow = flow\">\n <td><p-radioButton [inputId]=\"flow.id\" name=\"flow\" [value]=\"flow\" [(ngModel)]=\"selectedFlow\"></p-radioButton></td>\n <td>{{ flow.id }}</td>\n <td>{{ flow.entryPath }}</td>\n <td>{{ flow.queryParamsStr }}</td>\n </tr>\n </tbody>\n</table>\n", styles: [":host{display:block;padding:24px 54px}form{display:flex;align-items:center;justify-content:space-between}.fields-container{display:flex;grid-gap:24px;gap:24px}.field{display:flex;flex-direction:column;width:200px;flex-shrink:0}:host ::ng-deep .p-dropdown{width:100%}table{width:100%;border-collapse:collapse}tr{cursor:pointer}tr:hover{background-color:#f0f5fa}th{text-align:left;font-weight:600}th,td{padding:0 10px;height:30px;border-bottom:1px solid var(--vl-border-color);margin-right:16px}\n"], components: [{ type: i4$2.Dropdown, selector: "p-dropdown", inputs: ["scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "filterPlaceholder", "filterLocale", "inputId", "selectId", "dataKey", "filterBy", "autofocus", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "virtualScroll", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaFilterLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "disabled", "options", "filterValue"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear"] }, { type: i5.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }, { type: i6$1.RadioButton, selector: "p-radioButton", inputs: ["value", "formControlName", "name", "disabled", "label", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "labelStyleClass"], outputs: ["onClick", "onFocus", "onBlur"] }], directives: [{ type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i8.InputText, selector: "[pInputText]" }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "async": i9.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
985
+ DebugComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: DebugComponent, deps: [{ token: i1$2.FlowsApiService }, { token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: i2$1.ContextService }, { token: i2$1.FlowConfigurationService }, { token: i2$1.QuoteDraftService }], target: i0.ɵɵFactoryTarget.Component });
986
+ DebugComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: DebugComponent, selector: "vl-flow-debug", ngImport: i0, template: "<form [formGroup]=\"form\">\n <div class=\"fields-container\">\n <div class=\"field\">\n <label>SF Object ID</label>\n <input formControlName=\"id\" pInputText type=\"text\" />\n </div>\n\n <div class=\"field\">\n <label>SF Object Name</label>\n <p-dropdown\n appendTo=\"body\"\n formControlName=\"name\"\n [autoDisplayFirst]=\"false\"\n [options]=\"objectNames\"\n ></p-dropdown>\n </div>\n </div>\n\n <p-button\n styleClass=\"p-button-primary\"\n label=\"Run Flow\"\n [disabled]=\"!form.value.id || !selectedFlow\"\n (onClick)=\"runFlow()\"\n ></p-button>\n</form>\n\n<table>\n <thead>\n <tr>\n <th [width]=\"30\"></th>\n <th [width]=\"160\">ID</th>\n <th [width]=\"160\">Entry Path</th>\n <th>QueryParams</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let flow of flows$ | async\" (click)=\"selectedFlow = flow\">\n <td><p-radioButton [inputId]=\"flow.id\" name=\"flow\" [value]=\"flow\" [(ngModel)]=\"selectedFlow\"></p-radioButton></td>\n <td>{{ flow.id }}</td>\n <td>{{ flow.entryPath }}</td>\n <td>{{ flow.queryParamsStr }}</td>\n </tr>\n </tbody>\n</table>\n", styles: [":host{display:block;padding:24px 54px}form{display:flex;align-items:center;justify-content:space-between}.fields-container{display:flex;grid-gap:24px;gap:24px}.field{display:flex;flex-direction:column;width:200px;flex-shrink:0}:host ::ng-deep .p-dropdown{width:100%}table{width:100%;border-collapse:collapse}tr{cursor:pointer}tr:hover{background-color:#f0f5fa}th{text-align:left;font-weight:600}th,td{padding:0 10px;height:30px;border-bottom:1px solid var(--vl-border-color);margin-right:16px}\n"], components: [{ type: i4$1.Dropdown, selector: "p-dropdown", inputs: ["scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "filterPlaceholder", "filterLocale", "inputId", "selectId", "dataKey", "filterBy", "autofocus", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "virtualScroll", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaFilterLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "disabled", "options", "filterValue"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear"] }, { type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }, { type: i6.RadioButton, selector: "p-radioButton", inputs: ["value", "formControlName", "name", "disabled", "label", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "labelStyleClass"], outputs: ["onClick", "onFocus", "onBlur"] }], directives: [{ type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i8.InputText, selector: "[pInputText]" }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "async": i9.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
984
987
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: DebugComponent, decorators: [{
985
988
  type: Component,
986
989
  args: [{
@@ -989,7 +992,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
989
992
  styleUrls: ['./debug.component.scss'],
990
993
  changeDetection: ChangeDetectionStrategy.OnPush,
991
994
  }]
992
- }], ctorParameters: function () { return [{ type: i1$4.FlowsApiService }, { type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i1$2.ContextService }, { type: i1$2.FlowConfigurationService }, { type: i1$2.QuoteDraftService }]; } });
995
+ }], ctorParameters: function () { return [{ type: i1$2.FlowsApiService }, { type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i2$1.ContextService }, { type: i2$1.FlowConfigurationService }, { type: i2$1.QuoteDraftService }]; } });
993
996
 
994
997
  const routes$1 = [{ path: '', component: DebugComponent }];
995
998
  class DebugModule {
@@ -1134,15 +1137,15 @@ class LegacyProductComponent {
1134
1137
  }), switchMap$1(runtimeContext => this.customizeContext(productId, runtimeContext)));
1135
1138
  }
1136
1139
  }
1137
- LegacyProductComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LegacyProductComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: i1$2.QuoteDraftService }, { token: i1$4.QuoteApiService }, { token: i1$2.ContextService }, { token: i4$3.RuntimeContextService }, { token: i4$3.RuntimeService }, { token: i4$3.CurrentStateService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1138
- LegacyProductComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: LegacyProductComponent, selector: "ng-component", ngImport: i0, template: "<vl-runtime #runtimeView (solutionUpdated)=\"onSolutionUpdated($event)\"></vl-runtime>\n", styles: [":host{display:block;height:100%}\n"], components: [{ type: i4$3.RuntimeComponent, selector: "vl-runtime", outputs: ["solutionUpdated"] }] });
1140
+ LegacyProductComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LegacyProductComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: i2$1.QuoteDraftService }, { token: i1$2.QuoteApiService }, { token: i2$1.ContextService }, { token: i4$2.RuntimeContextService }, { token: i4$2.RuntimeService }, { token: i4$2.CurrentStateService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1141
+ LegacyProductComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: LegacyProductComponent, selector: "ng-component", ngImport: i0, template: "<vl-runtime #runtimeView (solutionUpdated)=\"onSolutionUpdated($event)\"></vl-runtime>\n", styles: [":host{display:block;height:100%}\n"], components: [{ type: i4$2.RuntimeComponent, selector: "vl-runtime", outputs: ["solutionUpdated"] }] });
1139
1142
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LegacyProductComponent, decorators: [{
1140
1143
  type: Component,
1141
1144
  args: [{
1142
1145
  templateUrl: './legacy-product.component.html',
1143
1146
  styleUrls: ['./legacy-product.component.scss'],
1144
1147
  }]
1145
- }], ctorParameters: function () { return [{ type: i1$1.ActivatedRoute }, { type: i1$2.QuoteDraftService }, { type: i1$4.QuoteApiService }, { type: i1$2.ContextService }, { type: i4$3.RuntimeContextService }, { type: i4$3.RuntimeService }, { type: i4$3.CurrentStateService }, { type: undefined, decorators: [{
1148
+ }], ctorParameters: function () { return [{ type: i1$1.ActivatedRoute }, { type: i2$1.QuoteDraftService }, { type: i1$2.QuoteApiService }, { type: i2$1.ContextService }, { type: i4$2.RuntimeContextService }, { type: i4$2.RuntimeService }, { type: i4$2.CurrentStateService }, { type: undefined, decorators: [{
1146
1149
  type: Optional
1147
1150
  }, {
1148
1151
  type: Inject,
@@ -1152,7 +1155,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
1152
1155
  class LegacyProductModule {
1153
1156
  }
1154
1157
  LegacyProductModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LegacyProductModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1155
- LegacyProductModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LegacyProductModule, declarations: [LegacyProductComponent], imports: [CommonModule, RuntimeModule, i1$5.TooltipModule], exports: [LegacyProductComponent] });
1158
+ LegacyProductModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LegacyProductModule, declarations: [LegacyProductComponent], imports: [CommonModule, RuntimeModule, i1$3.TooltipModule], exports: [LegacyProductComponent] });
1156
1159
  LegacyProductModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LegacyProductModule, imports: [[CommonModule, RuntimeModule, TooltipModule$1.forRoot()]] });
1157
1160
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LegacyProductModule, decorators: [{
1158
1161
  type: NgModule,
@@ -1231,8 +1234,8 @@ class ProductComponent {
1231
1234
  return id;
1232
1235
  }
1233
1236
  }
1234
- ProductComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ProductComponent, deps: [{ token: i1$2.ContextService }, { token: i1$2.ConfigurationRuntimeService }, { token: i1$2.ConfigurationService }, { token: i1$2.QuoteDraftService }, { token: i2.MessageService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1235
- 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.LoaderComponent, selector: "vl-loader", inputs: ["label", "overlayVisible"] }, { type: i4$1.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 });
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 });
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 });
1236
1239
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ProductComponent, decorators: [{
1237
1240
  type: Component,
1238
1241
  args: [{
@@ -1241,7 +1244,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
1241
1244
  styleUrls: ['./product.component.scss'],
1242
1245
  changeDetection: ChangeDetectionStrategy.OnPush,
1243
1246
  }]
1244
- }], ctorParameters: function () { return [{ type: i1$2.ContextService }, { type: i1$2.ConfigurationRuntimeService }, { type: i1$2.ConfigurationService }, { type: i1$2.QuoteDraftService }, { type: i2.MessageService }, { type: undefined, decorators: [{
1247
+ }], ctorParameters: function () { return [{ type: i2$1.ContextService }, { type: i2$1.ConfigurationRuntimeService }, { type: i2$1.ConfigurationService }, { type: i2$1.QuoteDraftService }, { type: i2$2.MessageService }, { type: undefined, decorators: [{
1245
1248
  type: Optional
1246
1249
  }, {
1247
1250
  type: Inject,
@@ -1390,8 +1393,8 @@ class ShoppingCartComponent {
1390
1393
  }));
1391
1394
  }
1392
1395
  }
1393
- ShoppingCartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ShoppingCartComponent, deps: [{ token: i1$4.UITemplatesApiService }, { token: i1$2.ContextService }, { token: i0.ChangeDetectorRef }, { token: i3.ToastService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1394
- ShoppingCartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: ShoppingCartComponent, selector: "vl-flow-shopping-cart", 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.LoaderComponent, selector: "vl-loader", inputs: ["label", "overlayVisible"] }, { type: i4$1.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 });
1396
+ ShoppingCartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ShoppingCartComponent, deps: [{ token: i1$2.UITemplatesApiService }, { token: i2$1.ContextService }, { token: i0.ChangeDetectorRef }, { token: i3$1.ToastService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1397
+ ShoppingCartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: ShoppingCartComponent, selector: "vl-flow-shopping-cart", 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 });
1395
1398
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ShoppingCartComponent, decorators: [{
1396
1399
  type: Component,
1397
1400
  args: [{
@@ -1400,7 +1403,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
1400
1403
  styleUrls: ['./shopping-cart.component.scss'],
1401
1404
  changeDetection: ChangeDetectionStrategy.OnPush,
1402
1405
  }]
1403
- }], ctorParameters: function () { return [{ type: i1$4.UITemplatesApiService }, { type: i1$2.ContextService }, { type: i0.ChangeDetectorRef }, { type: i3.ToastService }, { type: undefined, decorators: [{
1406
+ }], ctorParameters: function () { return [{ type: i1$2.UITemplatesApiService }, { type: i2$1.ContextService }, { type: i0.ChangeDetectorRef }, { type: i3$1.ToastService }, { type: undefined, decorators: [{
1404
1407
  type: Optional
1405
1408
  }, {
1406
1409
  type: Inject,
@@ -1421,42 +1424,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
1421
1424
  }]
1422
1425
  }] });
1423
1426
 
1424
- class ContextResolver {
1425
- constructor(contextService, router, routerService) {
1426
- this.contextService = contextService;
1427
- this.router = router;
1428
- this.routerService = routerService;
1429
- }
1430
- handleError(route, message) {
1431
- this.contextService.delete();
1432
- const parentUrl = this.routerService.getFlowRootPath(route);
1433
- return from(this.router.navigate([parentUrl, '404'], { state: { message } }));
1434
- }
1435
- resolve(route) {
1436
- const { queryParams, data } = route;
1437
- const { uiDefinitionId } = queryParams;
1438
- const { headerId, mode } = data !== null && data !== void 0 ? data : {};
1439
- if (this.contextService.isInitialized) {
1440
- const currentContext = this.contextService.resolve();
1441
- if (headerId && currentContext.headerId === headerId) {
1442
- return of(currentContext);
1443
- }
1444
- }
1445
- return this.contextService.create(headerId, mode).pipe(tap$1((context) => {
1446
- this.contextService.update(Object.assign(Object.assign({}, context), { uiDefinitionId, properties: Object.assign(Object.assign({}, context.properties), (queryParams !== null && queryParams !== void 0 ? queryParams : {})) }));
1447
- }), catchError$1(e => {
1448
- const message = e instanceof HttpErrorResponse ? e.error.message : e;
1449
- this.handleError(route, message);
1450
- return of(null);
1451
- }));
1452
- }
1453
- }
1454
- ContextResolver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ContextResolver, deps: [{ token: i1$2.ContextService }, { token: i1$1.Router }, { token: FlowRouterService }], target: i0.ɵɵFactoryTarget.Injectable });
1455
- ContextResolver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ContextResolver });
1456
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ContextResolver, decorators: [{
1457
- type: Injectable
1458
- }], ctorParameters: function () { return [{ type: i1$2.ContextService }, { type: i1$1.Router }, { type: FlowRouterService }]; } });
1459
-
1460
1427
  class FlowResolver {
1461
1428
  constructor(router, flowsApiService, routerService) {
1462
1429
  this.router = router;
@@ -1502,11 +1469,11 @@ class FlowResolver {
1502
1469
  }));
1503
1470
  }
1504
1471
  }
1505
- FlowResolver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowResolver, deps: [{ token: i1$1.Router }, { token: i1$4.FlowsApiService }, { token: FlowRouterService }], target: i0.ɵɵFactoryTarget.Injectable });
1472
+ FlowResolver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowResolver, deps: [{ token: i1$1.Router }, { token: i1$2.FlowsApiService }, { token: FlowRouterService }], target: i0.ɵɵFactoryTarget.Injectable });
1506
1473
  FlowResolver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowResolver });
1507
1474
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowResolver, decorators: [{
1508
1475
  type: Injectable
1509
- }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i1$4.FlowsApiService }, { type: FlowRouterService }]; } });
1476
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i1$2.FlowsApiService }, { type: FlowRouterService }]; } });
1510
1477
 
1511
1478
  class QuoteResolver {
1512
1479
  constructor(router, quoteDraftService, routerService, contextService, flowConfiguration) {
@@ -1527,23 +1494,24 @@ class QuoteResolver {
1527
1494
  return this.flowConfiguration.initialize$();
1528
1495
  }
1529
1496
  resolve(route) {
1530
- const { headerId } = route.data;
1497
+ const { headerId } = this.contextService.resolve();
1531
1498
  const quote = this.quoteDraftService.quoteSnapshot;
1532
1499
  if (quote && quote.quoteId === headerId) {
1533
1500
  return of(true);
1534
1501
  }
1535
1502
  const { queryParams } = route;
1503
+ this.contextService.update({ properties: queryParams });
1536
1504
  return this.quoteDraftService.init(headerId, queryParams).pipe(switchMap(() => this.initFlow$()), catchError(e => {
1537
1505
  const message = e instanceof HttpErrorResponse ? e.error.message : e;
1538
1506
  return this.handleError(route, message);
1539
1507
  }));
1540
1508
  }
1541
1509
  }
1542
- QuoteResolver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: QuoteResolver, deps: [{ token: i1$1.Router }, { token: i1$2.QuoteDraftService }, { token: FlowRouterService }, { token: i1$2.ContextService }, { token: i1$2.FlowConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable });
1510
+ QuoteResolver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: QuoteResolver, deps: [{ token: i1$1.Router }, { token: i2$1.QuoteDraftService }, { token: FlowRouterService }, { token: i2$1.ContextService }, { token: i2$1.FlowConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable });
1543
1511
  QuoteResolver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: QuoteResolver });
1544
1512
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: QuoteResolver, decorators: [{
1545
1513
  type: Injectable
1546
- }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i1$2.QuoteDraftService }, { type: FlowRouterService }, { type: i1$2.ContextService }, { type: i1$2.FlowConfigurationService }]; } });
1514
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i2$1.QuoteDraftService }, { type: FlowRouterService }, { type: i2$1.ContextService }, { type: i2$1.FlowConfigurationService }]; } });
1547
1515
 
1548
1516
  const rootRoute = {
1549
1517
  id: VELOCE_FLOW_ROOT_ROUTE,
@@ -1566,7 +1534,7 @@ const rootRoute = {
1566
1534
  path: 'product',
1567
1535
  component: LegacyProductComponent,
1568
1536
  runGuardsAndResolvers: 'paramsOrQueryParamsChange',
1569
- resolve: { context: ContextResolver, quote: QuoteResolver },
1537
+ resolve: { quote: QuoteResolver },
1570
1538
  canActivate: [ContextGuard],
1571
1539
  },
1572
1540
  ],
@@ -1575,7 +1543,7 @@ const rootRoute = {
1575
1543
  path: 'product',
1576
1544
  component: ProductComponent,
1577
1545
  runGuardsAndResolvers: 'paramsOrQueryParamsChange',
1578
- resolve: { context: ContextResolver, quote: QuoteResolver },
1546
+ resolve: { quote: QuoteResolver },
1579
1547
  canActivate: [ContextGuard],
1580
1548
  canDeactivate: [ProductUnloadGuard],
1581
1549
  data: { showHeader: true },
@@ -1584,7 +1552,7 @@ const rootRoute = {
1584
1552
  path: 'cart',
1585
1553
  component: ShoppingCartComponent,
1586
1554
  runGuardsAndResolvers: 'paramsOrQueryParamsChange',
1587
- resolve: { context: ContextResolver, quote: QuoteResolver },
1555
+ resolve: { quote: QuoteResolver },
1588
1556
  canActivate: [ContextGuard],
1589
1557
  data: { showHeader: true },
1590
1558
  },
@@ -1592,7 +1560,7 @@ const rootRoute = {
1592
1560
  path: 'catalog',
1593
1561
  component: CatalogComponent,
1594
1562
  runGuardsAndResolvers: 'paramsOrQueryParamsChange',
1595
- resolve: { context: ContextResolver, quote: QuoteResolver },
1563
+ resolve: { quote: QuoteResolver },
1596
1564
  canActivate: [ContextGuard],
1597
1565
  data: { showHeader: true },
1598
1566
  },
@@ -1610,29 +1578,13 @@ class FlowRoutingModule {
1610
1578
  }
1611
1579
  FlowRoutingModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1612
1580
  FlowRoutingModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRoutingModule, imports: [i1$1.RouterModule, ProductModule, LegacyProductModule, ShoppingCartModule, CatalogModule], exports: [RouterModule] });
1613
- FlowRoutingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRoutingModule, providers: [
1614
- FlowRouterService,
1615
- RootGuard,
1616
- ContextGuard,
1617
- ProductUnloadGuard,
1618
- ContextResolver,
1619
- FlowResolver,
1620
- QuoteResolver,
1621
- ], imports: [[RouterModule.forChild([rootRoute]), ProductModule, LegacyProductModule, ShoppingCartModule, CatalogModule], RouterModule] });
1581
+ FlowRoutingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRoutingModule, providers: [FlowRouterService, RootGuard, ContextGuard, ProductUnloadGuard, FlowResolver, QuoteResolver], imports: [[RouterModule.forChild([rootRoute]), ProductModule, LegacyProductModule, ShoppingCartModule, CatalogModule], RouterModule] });
1622
1582
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowRoutingModule, decorators: [{
1623
1583
  type: NgModule,
1624
1584
  args: [{
1625
1585
  imports: [RouterModule.forChild([rootRoute]), ProductModule, LegacyProductModule, ShoppingCartModule, CatalogModule],
1626
1586
  exports: [RouterModule],
1627
- providers: [
1628
- FlowRouterService,
1629
- RootGuard,
1630
- ContextGuard,
1631
- ProductUnloadGuard,
1632
- ContextResolver,
1633
- FlowResolver,
1634
- QuoteResolver,
1635
- ],
1587
+ providers: [FlowRouterService, RootGuard, ContextGuard, ProductUnloadGuard, FlowResolver, QuoteResolver],
1636
1588
  }]
1637
1589
  }] });
1638
1590