@configura/web-api 3.0.0-alpha.2 → 3.0.0-alpha.3
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/dist/CfgProduct.d.ts +22 -3
- package/dist/CfgProduct.js +41 -3
- package/dist/productConfiguration/CfgFeature.js +6 -1
- package/dist/productConfiguration/CfgOption.js +1 -1
- package/dist/syncGroups/SyncGroupsTransaction.d.ts +19 -1
- package/dist/syncGroups/SyncGroupsTransaction.js +97 -4
- package/package.json +3 -3
package/dist/CfgProduct.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { AggregatedLoadingObservable, LengthUnit, Observable, SingleArgCallback
|
|
|
2
2
|
import { DtoAdditionalProductConfiguration, DtoAdditionalProductRef, DtoCatalogueParams, DtoMeasureParam, DtoMiscFile, DtoMtrlApplication, DtoNote, DtoPrices, DtoProductConf, DtoProductParamsWithLang, DtoTransform } from "./CatalogueAPI.js";
|
|
3
3
|
import { CfgMeasureDefinition } from "./CfgMeasure.js";
|
|
4
4
|
import { _CfgFeatureInternal } from "./productConfiguration/CfgFeature.js";
|
|
5
|
-
import { ProductConfigurationBubbleMode } from "./productConfiguration/CfgOption.js";
|
|
5
|
+
import { ProductConfigurationBubbleMode, _CfgOptionInternal } from "./productConfiguration/CfgOption.js";
|
|
6
6
|
import { CfgProductConfiguration } from "./productConfiguration/CfgProductConfiguration.js";
|
|
7
7
|
import { ProductLoader } from "./productLoader.js";
|
|
8
8
|
import { SyncGroupsApplyMode } from "./syncGroups/SyncGroupsApplyMode.js";
|
|
@@ -102,6 +102,13 @@ export declare class _CfgProductInternal {
|
|
|
102
102
|
private _configuration;
|
|
103
103
|
private _notes;
|
|
104
104
|
readonly changeObservable: Observable<CfgProductChangeNotification>;
|
|
105
|
+
/**
|
|
106
|
+
* The last diff that was generated during the last validate call.
|
|
107
|
+
*
|
|
108
|
+
* This is used to keep track of the changes that were made to the
|
|
109
|
+
* configuration as a result of apply constraints.
|
|
110
|
+
*/
|
|
111
|
+
private _lastDiff;
|
|
105
112
|
get selected(): boolean;
|
|
106
113
|
readonly isAdditionalProduct: boolean;
|
|
107
114
|
/**
|
|
@@ -198,10 +205,22 @@ export declare class _CfgProductInternal {
|
|
|
198
205
|
tryMatchSelection: (other: _CfgProductInternal, descriptionMatch?: boolean, productLoaderForGroupedLoad?: ProductLoader | undefined) => Promise<boolean>;
|
|
199
206
|
/** Only features in selected options and selected additional products. */
|
|
200
207
|
_getDescendantFeaturesWithCode: (code: string) => _CfgFeatureInternal[];
|
|
208
|
+
/**
|
|
209
|
+
* Obtains the differences found in the last validate call.
|
|
210
|
+
* Used to update the sync group state.
|
|
211
|
+
*
|
|
212
|
+
* Removes the diff from the product.
|
|
213
|
+
*/
|
|
214
|
+
takeDiff(): _CfgOptionInternal[] | undefined;
|
|
201
215
|
private _revalidateInProgressToken;
|
|
202
216
|
/**
|
|
203
|
-
* Do a validate call for this product.
|
|
204
|
-
*
|
|
217
|
+
* Do a validate call for this product.
|
|
218
|
+
*
|
|
219
|
+
* Does not validate additional products, unless application of sync groups
|
|
220
|
+
* on the result of the validate call results in changes in the additional
|
|
221
|
+
* product.
|
|
222
|
+
*
|
|
223
|
+
* The validation result is applied on the configuration. Then additional
|
|
205
224
|
* products are synced (unloaded, loaded etc.) Finally the changes bubble up the tree.
|
|
206
225
|
*/
|
|
207
226
|
_revalidate: (bubbleMode: CfgProductBubbleMode, productLoader: ProductLoader, committed: boolean) => Promise<boolean>;
|
package/dist/CfgProduct.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
var _a;
|
|
2
2
|
import { AggregatedLoadingObservable, assert, assertDefined, augmentErrorMessage, compareArrays, count, Observable, toLengthUnit, } from "@configura/web-utilities";
|
|
3
3
|
import { CfgMeasureDefinition } from "./CfgMeasure.js";
|
|
4
|
-
import { ProductConfigurationBubbleMode } from "./productConfiguration/CfgOption.js";
|
|
4
|
+
import { ProductConfigurationBubbleMode, } from "./productConfiguration/CfgOption.js";
|
|
5
5
|
import { CfgProductConfiguration } from "./productConfiguration/CfgProductConfiguration.js";
|
|
6
6
|
import { collectAdditionalProductRefs } from "./productConfiguration/utilitiesProductConfiguration.js";
|
|
7
7
|
import { wrapWithCache } from "./productLoader.js";
|
|
8
8
|
import { SyncGroupsHandler } from "./syncGroups/SyncGroupsHandler.js";
|
|
9
|
+
import { generateSelectionDiff } from "./syncGroups/SyncGroupsTransaction.js";
|
|
9
10
|
import { compareCfgProductData, correctDefaultsOnCatalogueParams, isSameCatalogueParams, isSameProductRef, makeProductKey, } from "./utilitiesCatalogueData.js";
|
|
10
11
|
import { CfgProdConfParts, convertDtoProductConfToV1, isAdditionalProductConfiguration, isProductConf, } from "./utilitiesConfiguration.js";
|
|
11
12
|
function completeSettings(incompleteSettings) {
|
|
@@ -59,6 +60,13 @@ export class _CfgProductInternal {
|
|
|
59
60
|
this.additionalProducts = [];
|
|
60
61
|
this._notes = new Map();
|
|
61
62
|
this.changeObservable = new Observable();
|
|
63
|
+
/**
|
|
64
|
+
* The last diff that was generated during the last validate call.
|
|
65
|
+
*
|
|
66
|
+
* This is used to keep track of the changes that were made to the
|
|
67
|
+
* configuration as a result of apply constraints.
|
|
68
|
+
*/
|
|
69
|
+
this._lastDiff = undefined;
|
|
62
70
|
/** Mark this and its descendants as destroyed and remove all listeners */
|
|
63
71
|
this.destroy = () => {
|
|
64
72
|
this._destroyed = true;
|
|
@@ -229,6 +237,10 @@ export class _CfgProductInternal {
|
|
|
229
237
|
change = true;
|
|
230
238
|
}
|
|
231
239
|
}
|
|
240
|
+
if (sourceProduct?._lastDiff) {
|
|
241
|
+
this._lastDiff = sourceProduct._lastDiff;
|
|
242
|
+
change = true;
|
|
243
|
+
}
|
|
232
244
|
await this._syncAndLoadAdditionalProducts(productLoaderForGroupedLoad, productConfiguration);
|
|
233
245
|
const apiSelectionAdditionalProducts = productConfiguration.additionalProducts || [];
|
|
234
246
|
const additionalProducts = this.additionalProducts.slice();
|
|
@@ -337,8 +349,13 @@ export class _CfgProductInternal {
|
|
|
337
349
|
return agg;
|
|
338
350
|
}, this._configuration._internal._getFeaturesWithCode(code));
|
|
339
351
|
/**
|
|
340
|
-
* Do a validate call for this product.
|
|
341
|
-
*
|
|
352
|
+
* Do a validate call for this product.
|
|
353
|
+
*
|
|
354
|
+
* Does not validate additional products, unless application of sync groups
|
|
355
|
+
* on the result of the validate call results in changes in the additional
|
|
356
|
+
* product.
|
|
357
|
+
*
|
|
358
|
+
* The validation result is applied on the configuration. Then additional
|
|
342
359
|
* products are synced (unloaded, loaded etc.) Finally the changes bubble up the tree.
|
|
343
360
|
*/
|
|
344
361
|
this._revalidate = async (bubbleMode, productLoader, committed) => {
|
|
@@ -377,7 +394,17 @@ export class _CfgProductInternal {
|
|
|
377
394
|
if (rootFeatureRefs !== undefined) {
|
|
378
395
|
configuration._internal.populateFeatures(rootFeatureRefs);
|
|
379
396
|
}
|
|
397
|
+
const originalProduct = await this.clone();
|
|
380
398
|
await configuration._internal.setApiSelection(productData.partsData.selOptions || [], productData.partsData.constrOptions, false);
|
|
399
|
+
if (this.parent === undefined) {
|
|
400
|
+
const diff = generateSelectionDiff(originalProduct, this);
|
|
401
|
+
if (this._lastDiff && diff) {
|
|
402
|
+
this._lastDiff.push(...diff);
|
|
403
|
+
}
|
|
404
|
+
else if (diff) {
|
|
405
|
+
this._lastDiff = diff;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
381
408
|
await this._syncAndLoadAdditionalProducts(productLoader, undefined);
|
|
382
409
|
if (this._destroyed) {
|
|
383
410
|
return false;
|
|
@@ -699,6 +726,17 @@ export class _CfgProductInternal {
|
|
|
699
726
|
}
|
|
700
727
|
syncGroupHandler.verboseLogging = v;
|
|
701
728
|
}
|
|
729
|
+
/**
|
|
730
|
+
* Obtains the differences found in the last validate call.
|
|
731
|
+
* Used to update the sync group state.
|
|
732
|
+
*
|
|
733
|
+
* Removes the diff from the product.
|
|
734
|
+
*/
|
|
735
|
+
takeDiff() {
|
|
736
|
+
const diff = this._lastDiff?.filter((option) => option.selected);
|
|
737
|
+
this._lastDiff = undefined;
|
|
738
|
+
return diff;
|
|
739
|
+
}
|
|
702
740
|
}
|
|
703
741
|
_a = _CfgProductInternal;
|
|
704
742
|
_CfgProductInternal.make = async (productLoaderRaw, productLoaderForGroupedLoad, // Used when instantiating the current product
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assertDefined, compareArrays, convertLength, count, Observable, someMatch, toLengthUnit, } from "@configura/web-utilities";
|
|
2
2
|
import { CfgProduct } from "../CfgProduct.js";
|
|
3
3
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
4
4
|
import { CfgMtrlApplicationSource } from "../material/CfgMtrlApplicationSource.js";
|
|
@@ -199,6 +199,11 @@ export class _CfgFeatureInternal {
|
|
|
199
199
|
change = true;
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
+
// Triggers `pushStretch` when it is a stretch feature
|
|
203
|
+
// Fixes https://configura.atlassian.net/browse/WEB-16599
|
|
204
|
+
if (this.measureParamCodes?.length) {
|
|
205
|
+
change = true;
|
|
206
|
+
}
|
|
202
207
|
}
|
|
203
208
|
if (selectedIndex === -1) {
|
|
204
209
|
if (isAllOptionsAffectedByAnySelection) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { compareArrays, count, Observable, } from "@configura/web-utilities";
|
|
2
2
|
import { CfgProduct } from "../CfgProduct.js";
|
|
3
3
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
4
4
|
import { CfgMtrlApplicationSource } from "../material/CfgMtrlApplicationSource.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _CfgProductInternal } from "../CfgProduct.js";
|
|
2
|
+
import { _CfgOptionInternal } from "../productConfiguration/CfgOption.js";
|
|
2
3
|
import { ProductLoader } from "../productLoader.js";
|
|
3
4
|
import { SyncGroupsApplyMode } from "./SyncGroupsApplyMode.js";
|
|
4
5
|
import { CfgPath } from "./SyncGroupsPathHelper.js";
|
|
@@ -91,7 +92,7 @@ export declare class SyncGroupsTransaction {
|
|
|
91
92
|
* Apply current sync groups on those who wants to listen until there is no more to settle.
|
|
92
93
|
* @returns true if at least one Feature changed selected Option
|
|
93
94
|
*/
|
|
94
|
-
|
|
95
|
+
updateRootProduct(productToValidate: _CfgProductInternal | undefined): Promise<boolean>;
|
|
95
96
|
/**
|
|
96
97
|
* Applies the SyncState to the Product and it's AdditionalProducts (sub-products).
|
|
97
98
|
* @param productsToValidate To this all products that will need validation are added.
|
|
@@ -149,7 +150,24 @@ export declare class SyncGroupsTransaction {
|
|
|
149
150
|
private applySelectOneFeature;
|
|
150
151
|
private applySelectManyFeature;
|
|
151
152
|
private applySelectManyOption;
|
|
153
|
+
/**
|
|
154
|
+
* Applies the given diff to the transaction's sync state.
|
|
155
|
+
*/
|
|
156
|
+
applyFromDiff(diffs: _CfgOptionInternal[]): void;
|
|
157
|
+
/**
|
|
158
|
+
* Applies the new state for the given option to the transaction's sync state.
|
|
159
|
+
*/
|
|
160
|
+
private applyNewStateFor;
|
|
152
161
|
private addSyncGroupAffectedForSelectMany;
|
|
153
162
|
private hasSyncGroupAffectedForSelectMany;
|
|
154
163
|
}
|
|
164
|
+
/************************************************************************
|
|
165
|
+
* Product diffing
|
|
166
|
+
************************************************************************/
|
|
167
|
+
/**
|
|
168
|
+
* Finds all options that have changed in the new product compared to the original product.
|
|
169
|
+
*
|
|
170
|
+
* This is used to determine which options need to be updated in the sync state.
|
|
171
|
+
*/
|
|
172
|
+
export declare function generateSelectionDiff(originalProduct: _CfgProductInternal, newProduct: _CfgProductInternal): _CfgOptionInternal[] | null;
|
|
155
173
|
//# sourceMappingURL=SyncGroupsTransaction.d.ts.map
|
|
@@ -153,12 +153,15 @@ export class SyncGroupsTransaction {
|
|
|
153
153
|
// check here.
|
|
154
154
|
return false;
|
|
155
155
|
}
|
|
156
|
-
|
|
156
|
+
let anyChanges = false;
|
|
157
157
|
for (const product of productsToValidate) {
|
|
158
|
-
|
|
158
|
+
anyChanges =
|
|
159
|
+
(await product._revalidate(CfgProductBubbleMode.ToRoot, this.productLoader, true)) || anyChanges;
|
|
160
|
+
const diff = product.takeDiff();
|
|
161
|
+
if (diff)
|
|
162
|
+
this.applyFromDiff(diff);
|
|
159
163
|
}
|
|
160
|
-
|
|
161
|
-
if (revalidationResults.every((r) => !r)) {
|
|
164
|
+
if (!anyChanges) {
|
|
162
165
|
this.close();
|
|
163
166
|
return false;
|
|
164
167
|
}
|
|
@@ -486,6 +489,44 @@ export class SyncGroupsTransaction {
|
|
|
486
489
|
this.syncState.setForSelectMany(syncCode, option.code, optionSelected);
|
|
487
490
|
return true;
|
|
488
491
|
}
|
|
492
|
+
/**
|
|
493
|
+
* Applies the given diff to the transaction's sync state.
|
|
494
|
+
*/
|
|
495
|
+
applyFromDiff(diffs) {
|
|
496
|
+
for (const diff of diffs) {
|
|
497
|
+
this.applyNewStateFor(diff);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Applies the new state for the given option to the transaction's sync state.
|
|
502
|
+
*/
|
|
503
|
+
applyNewStateFor(option) {
|
|
504
|
+
const feature = option.parent;
|
|
505
|
+
const syncCode = feature.getSyncCode("push");
|
|
506
|
+
if (syncCode === undefined || syncCode === false)
|
|
507
|
+
return false;
|
|
508
|
+
switch (feature.selectionType) {
|
|
509
|
+
case SelectionType.SelectOne: {
|
|
510
|
+
if (this.affectedSelectOneSyncGroups.has(syncCode)) {
|
|
511
|
+
return false;
|
|
512
|
+
}
|
|
513
|
+
this.affectedSelectOneSyncGroups.add(syncCode);
|
|
514
|
+
this.syncState.setForSelectOne(syncCode, option.code);
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
case SelectionType.SelectMany: {
|
|
518
|
+
if (this.hasSyncGroupAffectedForSelectMany(syncCode, option)) {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
this.addSyncGroupAffectedForSelectMany(syncCode, option);
|
|
522
|
+
this.syncState.setForSelectMany(syncCode, option.code, option.selected);
|
|
523
|
+
return true;
|
|
524
|
+
}
|
|
525
|
+
case SelectionType.Group:
|
|
526
|
+
console.warn("No state to update for group: ", option.code);
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
489
530
|
addSyncGroupAffectedForSelectMany(syncCode, option) {
|
|
490
531
|
let forSyncCode = this.affectedSelectManySyncGroupsAndOptions.get(syncCode);
|
|
491
532
|
if (forSyncCode === undefined) {
|
|
@@ -498,6 +539,58 @@ export class SyncGroupsTransaction {
|
|
|
498
539
|
return this.affectedSelectManySyncGroupsAndOptions.get(syncCode)?.has(option.code) === true;
|
|
499
540
|
}
|
|
500
541
|
}
|
|
542
|
+
/************************************************************************
|
|
543
|
+
* Product diffing
|
|
544
|
+
************************************************************************/
|
|
545
|
+
/**
|
|
546
|
+
* Finds all options that have changed in the new product compared to the original product.
|
|
547
|
+
*
|
|
548
|
+
* This is used to determine which options need to be updated in the sync state.
|
|
549
|
+
*/
|
|
550
|
+
export function generateSelectionDiff(originalProduct, newProduct) {
|
|
551
|
+
const diff = generateFeaturesDiff(getFeaturesFromProduct({ initial: originalProduct, target: newProduct }));
|
|
552
|
+
return diff.length ? diff : null;
|
|
553
|
+
}
|
|
554
|
+
function generateFeaturesDiff(features) {
|
|
555
|
+
const changed = [];
|
|
556
|
+
for (const feature of features) {
|
|
557
|
+
switch (feature.target.selectionType) {
|
|
558
|
+
case SelectionType.SelectOne: {
|
|
559
|
+
const option = generateDiffForSelectOne(feature);
|
|
560
|
+
if (option)
|
|
561
|
+
changed.push(option);
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
case SelectionType.SelectMany:
|
|
565
|
+
changed.push(...generateDiffForSelectMany(feature));
|
|
566
|
+
break;
|
|
567
|
+
}
|
|
568
|
+
for (const option of getSelectedOptions(feature)) {
|
|
569
|
+
changed.push(...generateFeaturesDiff(getFeaturesFromOption(option)));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return changed;
|
|
573
|
+
}
|
|
574
|
+
function generateDiffForSelectOne({ initial, target, }) {
|
|
575
|
+
if (!target.getSyncCode("push"))
|
|
576
|
+
return null;
|
|
577
|
+
const selected = target.selectedOptions[0];
|
|
578
|
+
if (selected && initial?.selectedOptions?.[0]?.code !== selected.code) {
|
|
579
|
+
return selected._internal;
|
|
580
|
+
}
|
|
581
|
+
return null;
|
|
582
|
+
}
|
|
583
|
+
function generateDiffForSelectMany(feature) {
|
|
584
|
+
const changed = [];
|
|
585
|
+
if (!feature.target.getSyncCode("push"))
|
|
586
|
+
return changed;
|
|
587
|
+
for (const { initial, target } of getOptions(feature)) {
|
|
588
|
+
if (initial?.selected !== target.selected) {
|
|
589
|
+
changed.push(target);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
return changed;
|
|
593
|
+
}
|
|
501
594
|
function getAdditionalProducts(product) {
|
|
502
595
|
const initial = product.initial;
|
|
503
596
|
return product.target.additionalProducts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@configura/web-api",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.3",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@configura/web-utilities": "3.0.0-alpha.
|
|
26
|
+
"@configura/web-utilities": "3.0.0-alpha.3"
|
|
27
27
|
},
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "4332ed866e78584bfa40bf2d6a3258108dc4093c"
|
|
29
29
|
}
|