@veloceapps/sdk 3.1.18 → 3.1.19
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.
- package/bundles/veloce-sdk-core.umd.js +212 -68
- package/bundles/veloce-sdk-core.umd.js.map +1 -1
- package/bundles/veloce-sdk-runtime.umd.js +5 -6
- package/bundles/veloce-sdk-runtime.umd.js.map +1 -1
- package/bundles/veloce-sdk.umd.js +52 -38
- package/bundles/veloce-sdk.umd.js.map +1 -1
- package/core/modules/flow-configuration/services/flow-configuration.service.d.ts +11 -17
- package/core/services/quote-draft.service.d.ts +41 -7
- package/esm2015/core/modules/configuration/services/configuration.service.js +3 -3
- package/esm2015/core/modules/flow-configuration/services/flow-configuration.service.js +43 -49
- package/esm2015/core/services/quote-draft.service.js +138 -22
- package/esm2015/runtime/components/ui-runtime/runtime.component.js +2 -2
- package/esm2015/runtime/execution/directives/section-script.directive.js +2 -2
- package/esm2015/runtime/services/cart.service.js +2 -3
- package/esm2015/runtime/services/section.service.js +1 -1
- package/esm2015/src/components/header/header.component.js +23 -19
- package/esm2015/src/components/header/header.types.js +1 -1
- package/esm2015/src/pages/legacy-product/legacy-product.component.js +4 -4
- package/esm2015/src/pages/product/product.component.js +8 -5
- package/esm2015/src/resolvers/flow.resolver.js +8 -4
- package/esm2015/src/resolvers/quote.resolver.js +4 -11
- package/esm2015/src/services/flow.service.js +6 -5
- package/fesm2015/veloce-sdk-core.js +177 -66
- package/fesm2015/veloce-sdk-core.js.map +1 -1
- package/fesm2015/veloce-sdk-runtime.js +3 -4
- package/fesm2015/veloce-sdk-runtime.js.map +1 -1
- package/fesm2015/veloce-sdk.js +44 -39
- package/fesm2015/veloce-sdk.js.map +1 -1
- package/package.json +1 -1
- package/runtime/services/cart.service.d.ts +1 -1
- package/src/components/header/header.component.d.ts +5 -2
- package/src/components/header/header.types.d.ts +0 -1
- package/src/pages/product/product.component.d.ts +1 -0
- package/src/resolvers/flow.resolver.d.ts +3 -1
- package/src/resolvers/quote.resolver.d.ts +0 -1
package/fesm2015/veloce-sdk.js
CHANGED
@@ -406,6 +406,8 @@ class FlowHeaderComponent {
|
|
406
406
|
this.mode = ctx.mode;
|
407
407
|
this.objectName = ctx.mode.toLowerCase();
|
408
408
|
this.contextProperties = ctx.properties;
|
409
|
+
this.assetPriceLists = this.quoteDraftService.assetPriceLists;
|
410
|
+
this.activePriceList$ = this.quoteDraftService.activePriceList$;
|
409
411
|
this.status$ = this.contextService.resolve$().pipe(map(context => { var _a; return (_a = context.properties.Status) !== null && _a !== void 0 ? _a : ''; }));
|
410
412
|
this.isEditMode$ = this.quoteDraftService.isEditMode$();
|
411
413
|
this.products$ = this.flowConfiguration.get().pipe(map(lineItems => this.generateProducts(lineItems)));
|
@@ -426,10 +428,10 @@ class FlowHeaderComponent {
|
|
426
428
|
get isQuoteMode() {
|
427
429
|
return this.mode === ConfigurationContextMode.QUOTE;
|
428
430
|
}
|
429
|
-
back() {
|
430
|
-
const
|
431
|
-
if (
|
432
|
-
window.VELO_BACK_FN.apply(null, [
|
431
|
+
back(objectId) {
|
432
|
+
const targetId = objectId !== null && objectId !== void 0 ? objectId : this.contextService.resolve().headerId;
|
433
|
+
if (targetId) {
|
434
|
+
window.VELO_BACK_FN.apply(null, [targetId]);
|
433
435
|
}
|
434
436
|
}
|
435
437
|
getSalesforceObjectLink(objectId) {
|
@@ -463,18 +465,16 @@ class FlowHeaderComponent {
|
|
463
465
|
this.dialogService.showEmptyCartDialog().subscribe();
|
464
466
|
return;
|
465
467
|
}
|
466
|
-
const quoteDraft = this.quoteDraftService.
|
468
|
+
const quoteDraft = this.quoteDraftService.quoteDraft;
|
467
469
|
if (!quoteDraft) {
|
468
470
|
return;
|
469
471
|
}
|
470
472
|
this.isSaveInProgress$.next(true);
|
471
473
|
this.quoteApiService
|
472
474
|
.upsertQuote(quoteDraft)
|
473
|
-
.pipe(tap(() => {
|
474
|
-
|
475
|
-
|
476
|
-
this.back();
|
477
|
-
}
|
475
|
+
.pipe(tap(({ quoteId }) => {
|
476
|
+
this.quoteDraftService.hasUnsavedChanges = false;
|
477
|
+
this.back(quoteId);
|
478
478
|
}), finalize(() => this.isSaveInProgress$.next(false)))
|
479
479
|
.subscribe();
|
480
480
|
}
|
@@ -487,16 +487,22 @@ class FlowHeaderComponent {
|
|
487
487
|
this.dialogService.showAccountSubmitFailureDialog();
|
488
488
|
return;
|
489
489
|
}
|
490
|
-
const quoteDraft = this.quoteDraftService.
|
490
|
+
const quoteDraft = this.quoteDraftService.quoteDraft;
|
491
491
|
if (!quoteDraft) {
|
492
492
|
return;
|
493
493
|
}
|
494
494
|
this.isSubmitInProgress$.next(true);
|
495
495
|
this.quoteApiService
|
496
496
|
.submitQuote(quoteDraft)
|
497
|
-
.pipe(switchMap(() => this.quoteApiService.getQuoteDraft(quoteDraft.quoteId)), tap(updatedQuoteDraft =>
|
497
|
+
.pipe(switchMap(() => this.quoteApiService.getQuoteDraft(quoteDraft.quoteId)), tap(updatedQuoteDraft => {
|
498
|
+
this.contextService.update({ properties: updatedQuoteDraft.context.properties });
|
499
|
+
this.quoteDraftService.hasUnsavedChanges = false;
|
500
|
+
}), finalize(() => this.isSubmitInProgress$.next(false)), takeUntil(this.destroyed$))
|
498
501
|
.subscribe();
|
499
502
|
}
|
503
|
+
selectPriceList(priceListId) {
|
504
|
+
this.quoteDraftService.updateActivePriceList(priceListId);
|
505
|
+
}
|
500
506
|
queryName$(objectName, id) {
|
501
507
|
if (!id) {
|
502
508
|
return of('');
|
@@ -509,19 +515,17 @@ class FlowHeaderComponent {
|
|
509
515
|
return this.sfApiService.query(searchRequest, objectName).pipe(map(result => { var _a, _b; return (_b = (_a = result[0]) === null || _a === void 0 ? void 0 : _a.Name) !== null && _b !== void 0 ? _b : ''; }), takeUntil(this.destroyed$));
|
510
516
|
}
|
511
517
|
populateObjectDetails() {
|
512
|
-
var _a
|
518
|
+
var _a;
|
513
519
|
const accountId = this.isAccountMode ? this.contextProperties.Id : this.contextProperties.AccountId;
|
514
520
|
const opportunityId = this.contextProperties.OpportunityId;
|
515
521
|
const quoteId = this.isQuoteMode ? this.contextProperties.Id : undefined;
|
516
522
|
const quoteName = this.isQuoteMode ? this.contextProperties.Name : undefined;
|
517
523
|
const quoteNumber = this.isQuoteMode ? (_a = this.contextProperties.QuoteNumber) === null || _a === void 0 ? void 0 : _a.replace(/^0+/, '') : undefined;
|
518
|
-
const priceListName = (_b = this.quoteDraftService.quotePriceList) === null || _b === void 0 ? void 0 : _b.name;
|
519
524
|
this.objectDetails$.next(Object.assign(Object.assign({}, this.objectDetails$.value), { accountId,
|
520
525
|
opportunityId,
|
521
526
|
quoteId,
|
522
527
|
quoteName,
|
523
|
-
quoteNumber
|
524
|
-
priceListName }));
|
528
|
+
quoteNumber }));
|
525
529
|
this.queryName$('Account', accountId).subscribe(accountName => this.objectDetails$.next(Object.assign(Object.assign({}, this.objectDetails$.value), { accountName })));
|
526
530
|
this.queryName$('Opportunity', opportunityId).subscribe(opportunityName => this.objectDetails$.next(Object.assign(Object.assign({}, this.objectDetails$.value), { opportunityName })));
|
527
531
|
}
|
@@ -558,7 +562,7 @@ class FlowHeaderComponent {
|
|
558
562
|
}
|
559
563
|
}
|
560
564
|
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\"> 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 });
|
565
|
+
FlowHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: FlowHeaderComponent, selector: "vl-flow-header", ngImport: i0, template: "<div class=\"flow-info\" *vlLet=\"objectDetails$ | async as details\">\n <nav class=\"nav-item nav-back\" (click)=\"back()\">\n <i class=\"nav-icon vl-icon vl-icon-arrow-left\"></i>\n\n <span> Back </span>\n <span *ngIf=\"objectName\" class=\"object-name\"> To {{ objectName }}</span>\n </nav>\n\n <ng-container *ngIf=\"isAccountMode\">\n <span class=\"dot-separator\"></span>\n\n <span>Account name</span>\n\n <nav class=\"account-name\" [pTooltip]=\"contextProperties.Name ?? ''\" tooltipPosition=\"bottom\" [showDelay]=\"1000\">\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(contextProperties.Id)\">{{ contextProperties.Name }}</a>\n </nav>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span class=\"dot-separator\"></span>\n\n <span>Quote #{{ details.quoteNumber }}</span>\n\n <span class=\"dot-separator\"></span>\n\n <nav class=\"nav-item\" (click)=\"quoteDetails.toggle($event)\">\n <span>{{ status$ | async }}</span>\n\n <i *ngIf=\"!quoteDetails.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"quoteDetails.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <p-overlayPanel styleClass=\"navigation-settings-overlay flow-header-overlay center\" #quoteDetails>\n <ng-template pTemplate>\n <div class=\"flow-header-overlay__wrapper\">\n <h2 class=\"flow-header-overlay__title\">\n <span>Quote Information</span>\n <i class=\"vl-icon vl-icon-close close-icon\" (click)=\"quoteDetails.hide()\"></i>\n </h2>\n\n <ul class=\"info-list\">\n <li class=\"info-list__row\">\n <span>Account Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.accountId)\">\n <span>{{ details.accountName }}</span>\n </a>\n </li>\n <li class=\"info-list__row\">\n <span>Opportunity Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.opportunityId)\">\n <span>{{ details.opportunityName }}</span>\n </a>\n </li>\n <li class=\"info-list__row\">\n <span>Quote Name:</span>\n <a target=\"_blank\" [href]=\"getSalesforceObjectLink(details.quoteId)\">\n <span>{{ details.quoteName }}</span>\n </a>\n </li>\n </ul>\n </div>\n </ng-template>\n </p-overlayPanel>\n </ng-container>\n</div>\n\n<div class=\"flow-navigation\">\n <nav class=\"nav-item\" [ngClass]=\"{ active: isCatalogRoute$ | async }\" (click)=\"navigateToCatalog()\">Catalog</nav>\n <nav class=\"nav-item disabled\" [ngClass]=\"{ active: isConfigurationRoute$ | async }\">Configurator</nav>\n <ng-container *vlLet=\"products$ | async as products\">\n <nav class=\"nav-item\" [ngClass]=\"{ active: isCartRoute$ | async }\" (click)=\"navigateToShoppingCart()\">\n Shopping Cart ({{ products.length }})\n </nav>\n\n <nav class=\"nav-popover-toggle active\" (click)=\"cart?.overlayPanel?.toggle($event)\">\n <i *ngIf=\"!cart?.overlayPanel?.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"cart?.overlayPanel?.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <vl-cart-preview #cart [products]=\"products\"></vl-cart-preview>\n </ng-container>\n</div>\n\n<div class=\"flow-controls\" *vlLet=\"objectDetails$ | async as details\">\n <ng-container *vlLet=\"activePriceList$ | async as priceList\">\n <ng-container *ngIf=\"isAccountMode ?? assetPriceLists.length > 1\">\n <nav class=\"nav-item\" (click)=\"priceListsOverlay?.toggle($event)\">\n <span>{{ priceList.name }}</span>\n <i *ngIf=\"!priceListsOverlay?.overlayVisible\" class=\"vl-icon vl-icon-chevron-down icon-with-margin\"></i>\n <i *ngIf=\"priceListsOverlay?.overlayVisible\" class=\"vl-icon vl-icon-chevron-up icon-with-margin\"></i>\n </nav>\n\n <p-overlayPanel styleClass=\"price-list-overlay\" #priceListsOverlay>\n <ng-template pTemplate>\n <span\n *ngFor=\"let option of assetPriceLists\"\n class=\"price-list-option\"\n [class.active]=\"priceList.id === option.id\"\n (click)=\"selectPriceList(option.id); priceListsOverlay.hide()\"\n >{{ option.name }}</span\n >\n </ng-template>\n </p-overlayPanel>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span>{{ priceList.name }}</span>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"isQuoteMode\">\n <span *ngIf=\"contextProperties.StartDate\">{{ contextProperties.StartDate | date: 'MM.dd.yyyy' }}</span>\n\n <span class=\"slash-separator\"></span>\n\n <span>MRR: <span class=\"font-semibold\">$0.00</span></span>\n <span>NRR: <span class=\"font-semibold\">$0.00</span></span>\n </ng-container>\n\n <ng-container *vlLet=\"isCartRoute$ | async as isCartRoute\">\n <p-button\n styleClass=\"p-button-outlined\"\n label=\"Generate Doc\"\n [disabled]=\"!isCartRoute\"\n tooltipPosition=\"bottom\"\n [showDelay]=\"300\"\n [pTooltip]=\"isCartRoute ? '' : disabledActionButtonTooltip\"\n ></p-button>\n\n <p-button\n *vlLet=\"isSaveInProgress$ | async as isSaveInProgress\"\n class=\"save-button\"\n styleClass=\"p-button-outlined\"\n [label]=\"isSaveInProgress ? 'Saving' : 'Save to Quote'\"\n (onClick)=\"saveButtonClickHandler()\"\n [loading]=\"isSaveInProgress\"\n ></p-button>\n\n <p-button\n *vlLet=\"isSubmitInProgress$ | async as isSubmitInProgress\"\n class=\"submit-button\"\n styleClass=\"p-button\"\n [label]=\"isSubmitInProgress ? 'Submitting' : 'Submit For Approval'\"\n [disabled]=\"!isCartRoute\"\n tooltipPosition=\"bottom\"\n [showDelay]=\"300\"\n [pTooltip]=\"isCartRoute ? '' : disabledActionButtonTooltip\"\n (onClick)=\"submitButtonClickHandler()\"\n [loading]=\"isSubmitInProgress\"\n ></p-button>\n </ng-container>\n</div>\n", styles: [":host{display:flex;align-items:center;height:48px;width:100%;background-color:var(--vl-primary-color);color:#fff;padding:0 32px;flex-shrink:0}::ng-deep .p-overlaypanel.flow-header-overlay .p-overlaypanel-content{background-color:#fff;padding:16px}::ng-deep .p-overlaypanel.flow-header-overlay.left:before{left:6px!important}::ng-deep .p-overlaypanel.flow-header-overlay.right:before{right:6px!important}::ng-deep .p-overlaypanel.flow-header-overlay.left .p-overlaypanel-content{margin-left:-16px}::ng-deep .p-overlaypanel.flow-header-overlay.right .p-overlaypanel-content{margin-right:-16px}::ng-deep .p-overlaypanel.flow-header-overlay:before{background-color:#fff}::ng-deep .p-overlaypanel.price-list-overlay .p-overlaypanel-content{border-radius:5px;border-color:var(--vl-border-color);padding:0;display:flex;flex-direction:column;max-height:140px;overflow:auto}:host ::ng-deep .p-button{padding:5px 15px;font-size:12px}:host ::ng-deep .p-button{color:var(--vl-primary-color);background-color:#fff;border-color:#fff}:host ::ng-deep .p-button:enabled:hover{background-color:var(--vl-primary-color);color:#fff;border-color:#fff}:host ::ng-deep .p-button.p-button-outlined{background-color:var(--vl-primary-color);color:#fff;border-color:#fff}:host ::ng-deep .p-button.p-button-outlined:enabled:hover{color:var(--vl-primary-color);background-color:#fff;border-color:#fff}:host ::ng-deep .p-button .p-button-label{white-space:nowrap}:host ::ng-deep .save-button .p-button{width:120px}:host ::ng-deep .submit-button .p-button{width:160px}.vl-icon{display:inline-block}.flow-info{flex-shrink:0;display:flex;grid-gap:8px;gap:8px;align-items:center}.flow-info .nav-popover-toggle{margin-left:-8px}.flow-info .object-name{text-transform:capitalize}.flow-info .nav-back{font-weight:bold}.flow-info .nav-item:not(.disabled):hover,.flow-info .nav-popover-toggle:not(.disabled):hover{opacity:.6}nav{display:flex;align-items:center;cursor:pointer;padding:4px 0}nav.disabled{opacity:.6;cursor:default}nav .nav-icon{margin-right:10px}nav .icon-with-margin{margin:0 4px}nav a{color:#fff}nav.account-name{margin-left:4px;display:block;max-width:200px;overflow:hidden;text-overflow:ellipsis}nav.nav-popover-toggle{width:24px;display:flex;justify-content:center}nav.nav-popover-toggle i{pointer-events:none;margin:0}nav i{pointer-events:none}.dot-separator:after{content:\"\";display:block;width:4px;height:4px;border-radius:50%;background:#fff}.slash-separator:after{content:\"\";display:block;background:#fff;width:1px;height:16px}.flow-header-overlay__wrapper{width:360px}.flow-header-overlay__wrapper .close-icon{cursor:pointer}.flow-header-overlay__wrapper .info-list{list-style:none;padding:0;font-size:12px}.flow-header-overlay__wrapper .info-list__row{padding:8px 0;display:flex;justify-content:space-between}.flow-header-overlay__wrapper .info-list__row a{text-align:right}.flow-header-overlay__title{display:flex;justify-content:space-between;align-items:center;margin:0 0 24px}.flow-navigation{flex-grow:1;display:flex;grid-gap:16px;gap:16px;justify-content:center;font-weight:600}.flow-navigation .cart-nav-container{display:flex}.flow-navigation .nav-popover-toggle{margin-left:-14px}.flow-navigation .nav-item,.flow-navigation .nav-popover-toggle{opacity:.6}.flow-navigation .nav-item.active,.flow-navigation .nav-item:not(.disabled):hover,.flow-navigation .nav-popover-toggle.active,.flow-navigation .nav-popover-toggle:not(.disabled):hover{opacity:1}.price-list-option{padding:8px;color:var(--vl-primary-color);cursor:pointer}.price-list-option.active,.price-list-option:hover{background:var(--vl-secondary-nav-bg)}.flow-controls{flex-shrink:0;display:flex;align-items:center;grid-gap:8px;gap:8px}\n"], components: [{ type: i3.OverlayPanel, selector: "p-overlayPanel", inputs: ["dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { type: CartPreviewComponent, selector: "vl-cart-preview", inputs: ["products"] }, { type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }], directives: [{ type: i3$1.LetDirective, selector: "[vlLet]", inputs: ["vlLet"] }, { type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i9.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i9.AsyncPipe, "date": i9.DatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
562
566
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowHeaderComponent, decorators: [{
|
563
567
|
type: Component,
|
564
568
|
args: [{
|
@@ -596,8 +600,8 @@ class FlowService {
|
|
596
600
|
this.integrationState
|
597
601
|
.listen$(FlowAction.FLOW_CONFIGURE_PRODUCT)
|
598
602
|
.pipe(takeUntil(this.cleanup$), tap(payload => {
|
599
|
-
var _a, _b
|
600
|
-
const productId = (_a = payload.productId) !== null && _a !== void 0 ? _a : (
|
603
|
+
var _a, _b;
|
604
|
+
const productId = (_a = payload.productId) !== null && _a !== void 0 ? _a : (_b = this.quoteDraftService.currentState.find(li => li.id === payload.lineItemId)) === null || _b === void 0 ? void 0 : _b.productId;
|
601
605
|
if (productId) {
|
602
606
|
this.flowRouterService.navigateToProductConfiguration(productId, payload.lineItemId);
|
603
607
|
}
|
@@ -617,7 +621,7 @@ class FlowService {
|
|
617
621
|
if (!lineItem) {
|
618
622
|
return of(undefined);
|
619
623
|
}
|
620
|
-
const currentState = this.
|
624
|
+
const currentState = this.quoteDraftService.currentState;
|
621
625
|
const isNewLineItem = currentState.every(li => li.id !== lineItem.id);
|
622
626
|
let updatedState;
|
623
627
|
if (isNewLineItem) {
|
@@ -626,7 +630,8 @@ class FlowService {
|
|
626
630
|
else {
|
627
631
|
updatedState = currentState.map(li => (li.id === lineItem.id ? lineItem : li));
|
628
632
|
}
|
629
|
-
|
633
|
+
this.quoteDraftService.setCurrentLineItemState(updatedState);
|
634
|
+
return this.flowConfigurationService.calculate$();
|
630
635
|
}), tap(() => {
|
631
636
|
this.configurationService.hasUnsavedChanges = false;
|
632
637
|
this.flowRouterService.navigateToShoppingCart();
|
@@ -1044,7 +1049,7 @@ class LegacyProductComponent {
|
|
1044
1049
|
this.destroyed$ = new Subject();
|
1045
1050
|
}
|
1046
1051
|
ngOnInit() {
|
1047
|
-
this.quoteDraftService.
|
1052
|
+
this.quoteDraftService.quoteDraft$
|
1048
1053
|
.pipe(first(), takeUntil$1(this.destroyed$))
|
1049
1054
|
.subscribe(quote => this.init(quote, this.route.snapshot.queryParams));
|
1050
1055
|
this.runtimeService.onSolutionStopEvent.pipe(take(1)).subscribe(lineItem => this.onSolutionStop(lineItem));
|
@@ -1060,7 +1065,7 @@ class LegacyProductComponent {
|
|
1060
1065
|
lineItem.actionCode = (_a = lineItem.actionCode) !== null && _a !== void 0 ? _a : 'ADD';
|
1061
1066
|
}
|
1062
1067
|
onSolutionCancel() {
|
1063
|
-
this.quoteDraftService.
|
1068
|
+
this.quoteDraftService.quoteDraft$.pipe(first(), takeUntil$1(this.destroyed$)).subscribe(quote => {
|
1064
1069
|
window['VELO_BACK_FN'].apply(null, [quote.quoteId]);
|
1065
1070
|
});
|
1066
1071
|
}
|
@@ -1073,7 +1078,7 @@ class LegacyProductComponent {
|
|
1073
1078
|
this.runtimeService.updateRuntime(states);
|
1074
1079
|
}
|
1075
1080
|
onSolutionStop(lineItem) {
|
1076
|
-
this.quoteDraftService.
|
1081
|
+
this.quoteDraftService.quoteDraft$.pipe(first(), takeUntil$1(this.destroyed$)).subscribe(quote => {
|
1077
1082
|
const quoteToUpsert = Object.assign(Object.assign({}, quote), { context: this.contextService.resolve(), currentState: [...(this.currentStateService.currentState || []).filter(li => li.id !== lineItem.id), lineItem] });
|
1078
1083
|
this.quoteApiService
|
1079
1084
|
.upsertQuote(quoteToUpsert)
|
@@ -1178,7 +1183,7 @@ class ProductComponent {
|
|
1178
1183
|
this.state$ = new BehaviorSubject({ loading: true, failure: false });
|
1179
1184
|
}
|
1180
1185
|
ngOnInit() {
|
1181
|
-
this.quoteDraftService.
|
1186
|
+
this.quoteDraftService.quoteDraft$.pipe(first$1(), takeUntil(this.destroy$)).subscribe(quote => this.init(quote));
|
1182
1187
|
}
|
1183
1188
|
ngOnDestroy() {
|
1184
1189
|
this.destroy$.next();
|
@@ -1204,14 +1209,15 @@ class ProductComponent {
|
|
1204
1209
|
return;
|
1205
1210
|
}
|
1206
1211
|
const lineItemId = this.getLineItemId(quote, productId, contextProperties.lineItemId);
|
1207
|
-
const currentStateItem =
|
1208
|
-
const { offeringId } = currentStateItem !== null && currentStateItem !== void 0 ? currentStateItem : {};
|
1212
|
+
const currentStateItem = quote.currentState.find(({ id }) => id === lineItemId);
|
1209
1213
|
if (currentStateItem) {
|
1210
1214
|
this.configurationService.updateCurrentStates({
|
1211
1215
|
configurableRamp: currentStateItem,
|
1212
1216
|
currentState: quote.currentState,
|
1217
|
+
asset: this.getAsset(quote, currentStateItem),
|
1213
1218
|
});
|
1214
1219
|
}
|
1220
|
+
const { offeringId } = currentStateItem !== null && currentStateItem !== void 0 ? currentStateItem : {};
|
1215
1221
|
this.runtimeService
|
1216
1222
|
.init({ productId, offeringId })
|
1217
1223
|
.pipe(tap(context => (this.uiDefinition = context === null || context === void 0 ? void 0 : context.uiDefinition)), switchMap(() => this.customize(productId)), switchMap(() => this.configurationService.configure()), tap(() => this.state$.next({ loading: false, failure: false })), catchError(error => {
|
@@ -1233,6 +1239,9 @@ class ProductComponent {
|
|
1233
1239
|
}
|
1234
1240
|
return id;
|
1235
1241
|
}
|
1242
|
+
getAsset(quote, lineItem) {
|
1243
|
+
return quote.initialState.find(a => a.id === lineItem.openOrderLineItemId || a.id === lineItem.assetId);
|
1244
|
+
}
|
1236
1245
|
}
|
1237
1246
|
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
1247
|
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 });
|
@@ -1425,10 +1434,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
|
|
1425
1434
|
}] });
|
1426
1435
|
|
1427
1436
|
class FlowResolver {
|
1428
|
-
constructor(router, flowsApiService, routerService) {
|
1437
|
+
constructor(router, flowsApiService, routerService, contextService) {
|
1429
1438
|
this.router = router;
|
1430
1439
|
this.flowsApiService = flowsApiService;
|
1431
1440
|
this.routerService = routerService;
|
1441
|
+
this.contextService = contextService;
|
1432
1442
|
}
|
1433
1443
|
handleError(route, message, queryParams) {
|
1434
1444
|
const parentUrl = this.routerService.getFlowRootPath(route);
|
@@ -1453,6 +1463,8 @@ class FlowResolver {
|
|
1453
1463
|
const { queryParams: flowQueryParams, entryPath } = properties;
|
1454
1464
|
const isProductFlow = entryPath.includes('/product');
|
1455
1465
|
const mergedParams = Object.assign(Object.assign(Object.assign({}, queryParams), flowQueryParams), Object.assign({}, (isProductFlow && { standalone: true })));
|
1466
|
+
const contextProperties = Object.entries(mergedParams).reduce((trunk, [key, value]) => (Object.assign(Object.assign({}, trunk), { [key]: String(value) })), {});
|
1467
|
+
this.contextService.update({ properties: contextProperties });
|
1456
1468
|
const parentUrl = this.routerService.getFlowRootPath(route);
|
1457
1469
|
const entryUrl = String(entryPath !== null && entryPath !== void 0 ? entryPath : '')
|
1458
1470
|
.split('/')
|
@@ -1469,11 +1481,11 @@ class FlowResolver {
|
|
1469
1481
|
}));
|
1470
1482
|
}
|
1471
1483
|
}
|
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 });
|
1484
|
+
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 }, { token: i2$1.ContextService }], target: i0.ɵɵFactoryTarget.Injectable });
|
1473
1485
|
FlowResolver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowResolver });
|
1474
1486
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FlowResolver, decorators: [{
|
1475
1487
|
type: Injectable
|
1476
|
-
}], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i1$2.FlowsApiService }, { type: FlowRouterService }]; } });
|
1488
|
+
}], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i1$2.FlowsApiService }, { type: FlowRouterService }, { type: i2$1.ContextService }]; } });
|
1477
1489
|
|
1478
1490
|
class QuoteResolver {
|
1479
1491
|
constructor(router, quoteDraftService, routerService, contextService, flowConfiguration) {
|
@@ -1487,21 +1499,14 @@ class QuoteResolver {
|
|
1487
1499
|
const parentUrl = this.routerService.getFlowRootPath(route);
|
1488
1500
|
return from(this.router.navigate([parentUrl, '404'], { state: { message } }));
|
1489
1501
|
}
|
1490
|
-
initFlow$() {
|
1491
|
-
if (this.quoteDraftService.isStandalone) {
|
1492
|
-
return of(undefined);
|
1493
|
-
}
|
1494
|
-
return this.flowConfiguration.initialize$();
|
1495
|
-
}
|
1496
1502
|
resolve(route) {
|
1497
1503
|
const { headerId } = this.contextService.resolve();
|
1498
|
-
const quote = this.quoteDraftService.
|
1504
|
+
const quote = this.quoteDraftService.quoteDraft;
|
1499
1505
|
if (quote && quote.quoteId === headerId) {
|
1500
1506
|
return of(true);
|
1501
1507
|
}
|
1502
1508
|
const { queryParams } = route;
|
1503
|
-
this.
|
1504
|
-
return this.quoteDraftService.init(headerId, queryParams).pipe(switchMap(() => this.initFlow$()), catchError(e => {
|
1509
|
+
return this.quoteDraftService.init(headerId, queryParams).pipe(catchError(e => {
|
1505
1510
|
const message = e instanceof HttpErrorResponse ? e.error.message : e;
|
1506
1511
|
return this.handleError(route, message);
|
1507
1512
|
}));
|