@configura/web-api 1.5.0-alpha.0 → 1.6.1-alpha.0
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/CatalogueAPI.d.ts +9 -2
- package/dist/CatalogueAPI.js +23 -0
- package/dist/CfgMeasure.d.ts +2 -2
- package/dist/CfgMeasure.js +1 -1
- package/dist/CfgProduct.d.ts +50 -4
- package/dist/CfgProduct.js +151 -17
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/productConfiguration/CfgFeature.d.ts +19 -2
- package/dist/productConfiguration/CfgFeature.js +57 -6
- package/dist/productConfiguration/CfgOption.d.ts +12 -1
- package/dist/productConfiguration/CfgOption.js +29 -2
- package/dist/productConfiguration/CfgProductConfiguration.d.ts +4 -2
- package/dist/productConfiguration/CfgProductConfiguration.js +17 -0
- package/dist/productLoader.d.ts +1 -1
- package/dist/syncGroups/SyncGroupsApplier.d.ts +20 -0
- package/dist/syncGroups/SyncGroupsApplier.js +519 -0
- package/dist/syncGroups/SyncGroupsApplyMode.d.ts +15 -0
- package/dist/syncGroups/SyncGroupsApplyMode.js +15 -0
- package/dist/syncGroups/SyncGroupsHandler.d.ts +30 -0
- package/dist/syncGroups/SyncGroupsHandler.js +71 -0
- package/dist/syncGroups/SyncGroupsState.d.ts +20 -0
- package/dist/syncGroups/SyncGroupsState.js +61 -0
- package/dist/syncGroups/SyncGroupsTransaction.d.ts +50 -0
- package/dist/syncGroups/SyncGroupsTransaction.js +106 -0
- package/dist/tasks/TaskHandler.js +4 -3
- package/dist/tasks/formats.d.ts +1 -3
- package/dist/tasks/formats.js +3 -4
- package/dist/tests/testData/dummyProductForTest.d.ts +2 -2
- package/dist/tests/testData/dummyProductForTest.js +1 -1
- package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.d.ts +3 -3
- package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.js +27 -98
- package/dist/tests/testData/testDataCachedGetProduct.js +8 -19
- package/dist/tests/testData/testDataOptions.d.ts +13 -0
- package/dist/tests/testData/testDataOptions.js +60 -0
- package/dist/tests/testData/testDataProductAggregatedPrice.d.ts +3 -3
- package/dist/tests/testData/testDataProductAggregatedPrice.js +14 -25
- package/dist/tests/testData/testDataUpcharge.js +16 -48
- package/dist/utilitiesCatalogueData.d.ts +7 -1
- package/dist/utilitiesCatalogueData.js +102 -0
- package/dist/utilitiesNumericValues.d.ts +1 -1
- package/package.json +3 -3
|
@@ -11,6 +11,7 @@ import { compareArrays, convertLength, count, Observable, someMatch, toLengthUni
|
|
|
11
11
|
import { CfgProduct } from "../CfgProduct.js";
|
|
12
12
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
13
13
|
import { CfgMtrlApplicationSource } from "../material/CfgMtrlApplicationSource.js";
|
|
14
|
+
import { wrapWithCache } from "../productLoader.js";
|
|
14
15
|
import { CfgOption, ProductConfigurationBubbleMode } from "./CfgOption.js";
|
|
15
16
|
import { _CfgProductConfigurationInternal } from "./CfgProductConfiguration.js";
|
|
16
17
|
import { getMtrlPreview } from "./utilitiesProductConfiguration.js";
|
|
@@ -306,6 +307,15 @@ export class _CfgFeatureInternal {
|
|
|
306
307
|
* Using a validate bubbleMode will cause validation calls to the server.
|
|
307
308
|
*/
|
|
308
309
|
this.selectOption = (optionInternal, on, bubbleMode) => __awaiter(this, void 0, void 0, function* () {
|
|
310
|
+
if (bubbleMode ===
|
|
311
|
+
ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups) {
|
|
312
|
+
const product = this.rootProduct;
|
|
313
|
+
const syncGroupHandler = product.syncGroupHandler;
|
|
314
|
+
if (syncGroupHandler === undefined) {
|
|
315
|
+
throw new Error(`No sync group handler when bubble mode ${ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups}`);
|
|
316
|
+
}
|
|
317
|
+
return yield syncGroupHandler.selectOption(product, optionInternal.path, on, wrapWithCache(product._productLoaderRaw));
|
|
318
|
+
}
|
|
309
319
|
if (!on) {
|
|
310
320
|
if (this.selectionType === SelectionType.Group) {
|
|
311
321
|
throw new Error(`Multiple features are always selected and are not user selectable. Feature key: "${this.key}".`);
|
|
@@ -357,11 +367,18 @@ export class _CfgFeatureInternal {
|
|
|
357
367
|
if (isAllOptionsAffectedByAnySelection) {
|
|
358
368
|
this._freshRefAllOptions();
|
|
359
369
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
370
|
+
let nextLevelBubbleMode = bubbleMode;
|
|
371
|
+
if (!on) {
|
|
372
|
+
// If this was a deselect action we shall not bubble selected, that is, we shall not
|
|
373
|
+
// select the ancestors if this action was deselect.
|
|
374
|
+
if (bubbleMode === ProductConfigurationBubbleMode.ValidateAndBubbleSelected) {
|
|
375
|
+
nextLevelBubbleMode = ProductConfigurationBubbleMode.Validate;
|
|
376
|
+
}
|
|
377
|
+
else if (bubbleMode === ProductConfigurationBubbleMode.BubbleSelected) {
|
|
378
|
+
nextLevelBubbleMode = ProductConfigurationBubbleMode.ToRoot;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
yield this._notifyAllOfChange(nextLevelBubbleMode);
|
|
365
382
|
return isActualChange;
|
|
366
383
|
});
|
|
367
384
|
this.isSelected = (option) => this.selectionType === SelectionType.Group ||
|
|
@@ -412,6 +429,9 @@ export class _CfgFeatureInternal {
|
|
|
412
429
|
}
|
|
413
430
|
return value;
|
|
414
431
|
}
|
|
432
|
+
get syncGroup() {
|
|
433
|
+
return this.rawFeature.syncGroup;
|
|
434
|
+
}
|
|
415
435
|
get description() {
|
|
416
436
|
return this.rawFeature.description;
|
|
417
437
|
}
|
|
@@ -450,12 +470,24 @@ export class _CfgFeatureInternal {
|
|
|
450
470
|
get preview() {
|
|
451
471
|
return getMtrlPreview(this._mtrlApplications);
|
|
452
472
|
}
|
|
473
|
+
/**
|
|
474
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
475
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
476
|
+
*/
|
|
453
477
|
get visibleIfAdditionalProduct() {
|
|
454
478
|
return this.rawFeature.hideIfAdditionalProduct !== true;
|
|
455
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
482
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
483
|
+
*/
|
|
456
484
|
get visibleIfMainProduct() {
|
|
457
485
|
return this.rawFeature.hideIfMainProduct !== true;
|
|
458
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
489
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
490
|
+
*/
|
|
459
491
|
get visible() {
|
|
460
492
|
return this.parentProduct.isAdditionalProduct
|
|
461
493
|
? this.visibleIfAdditionalProduct
|
|
@@ -470,6 +502,23 @@ export class _CfgFeatureInternal {
|
|
|
470
502
|
}
|
|
471
503
|
return this._options;
|
|
472
504
|
}
|
|
505
|
+
get path() {
|
|
506
|
+
return [...this.parent.path, this.code];
|
|
507
|
+
}
|
|
508
|
+
getFromPath(path) {
|
|
509
|
+
path = path.slice();
|
|
510
|
+
const s = path.shift();
|
|
511
|
+
switch (s) {
|
|
512
|
+
case undefined:
|
|
513
|
+
return this;
|
|
514
|
+
default:
|
|
515
|
+
const option = this.options.find((o) => o.code === s);
|
|
516
|
+
if (option === undefined) {
|
|
517
|
+
throw new Error(`Option not found ${s}, ${path.join(", ")}`);
|
|
518
|
+
}
|
|
519
|
+
return option._internal.getFromPath(path);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
473
522
|
/**
|
|
474
523
|
* Make fresh references to all options on this feature.
|
|
475
524
|
* Also includes currently selected options.
|
|
@@ -519,7 +568,7 @@ export class CfgFeature {
|
|
|
519
568
|
* Calling this will cause a validation call to the server.
|
|
520
569
|
*/
|
|
521
570
|
this.selectOption = (option, on) => __awaiter(this, void 0, void 0, function* () {
|
|
522
|
-
return yield this._internal.selectOption(option._internal, on, ProductConfigurationBubbleMode.
|
|
571
|
+
return yield this._internal.selectOption(option._internal, on, ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups);
|
|
523
572
|
});
|
|
524
573
|
this.isSelected = (option) => this._internal.isSelected(option._internal);
|
|
525
574
|
this.listenForChange = (l) => this._internal.changeObservable.listen(l);
|
|
@@ -588,6 +637,8 @@ export class CfgFeature {
|
|
|
588
637
|
return this._internal.options;
|
|
589
638
|
}
|
|
590
639
|
/**
|
|
640
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
641
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
591
642
|
* Visibility is not inherited. If this is hidden the children
|
|
592
643
|
* of this Feature might still be visible, depending on their settings.
|
|
593
644
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
2
|
import { Feature, Option, SelectedOption } from "../CatalogueAPI.js";
|
|
3
|
-
import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
3
|
+
import { CfgPath, CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
4
4
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
5
5
|
import { NumericValuesSelection } from "../utilitiesNumericValues.js";
|
|
6
6
|
import { CfgFeature, _CfgFeatureInternal } from "./CfgFeature.js";
|
|
@@ -9,6 +9,10 @@ export declare type OptionChangeNotification = {
|
|
|
9
9
|
freshRef: CfgOption;
|
|
10
10
|
};
|
|
11
11
|
export declare enum ProductConfigurationBubbleMode {
|
|
12
|
+
/**
|
|
13
|
+
* If this is select it will turns on all ancestors all the way up.
|
|
14
|
+
*/
|
|
15
|
+
BubbleSelected = "BubbleSelected",
|
|
12
16
|
/**
|
|
13
17
|
* Bubble to the closest CfgProduct, let it revalidate, then that will continue
|
|
14
18
|
* the bubble after validate.
|
|
@@ -20,6 +24,11 @@ export declare enum ProductConfigurationBubbleMode {
|
|
|
20
24
|
* So with this mode it is possible to select an option where its parents are not selected.
|
|
21
25
|
*/
|
|
22
26
|
ValidateAndBubbleSelected = "ValidateAndBubbleSelected",
|
|
27
|
+
/**
|
|
28
|
+
* Like ValidateAndBubbleSelected, but SyncGroups are applied after
|
|
29
|
+
* ValidateAndBubbleSelected has been done
|
|
30
|
+
*/
|
|
31
|
+
ValidateAndBubbleSelectedAndApplySyncGroups = "ValidateAndBubbleSelectedAndApplySyncGroups",
|
|
23
32
|
/**
|
|
24
33
|
* Stop bubbling
|
|
25
34
|
* This mode supports internal functionality and is not expected to be used by integrators.
|
|
@@ -81,6 +90,8 @@ export declare class _CfgOptionInternal {
|
|
|
81
90
|
_childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode) => Promise<void>;
|
|
82
91
|
getApiSelection: () => SelectedOption;
|
|
83
92
|
setApiSelection: (apiOptionSelection: SelectedOption | undefined) => Promise<boolean>;
|
|
93
|
+
get path(): CfgPath;
|
|
94
|
+
getFromPath(path: CfgPath): _CfgFeatureInternal | _CfgOptionInternal;
|
|
84
95
|
structureCompare: (other: _CfgOptionInternal, strictOrder?: boolean, descriptionMatch?: boolean) => boolean;
|
|
85
96
|
tryMatchSelection: (other: CfgOption, descriptionMatch?: boolean) => Promise<boolean>;
|
|
86
97
|
keyMatch: (other: _CfgOptionInternal, descriptionMatch?: boolean) => boolean;
|
|
@@ -17,6 +17,10 @@ import { CfgFeature, SelectionType } from "./CfgFeature.js";
|
|
|
17
17
|
import { getMtrlPreview, syncCfgFeatures } from "./utilitiesProductConfiguration.js";
|
|
18
18
|
export var ProductConfigurationBubbleMode;
|
|
19
19
|
(function (ProductConfigurationBubbleMode) {
|
|
20
|
+
/**
|
|
21
|
+
* If this is select it will turns on all ancestors all the way up.
|
|
22
|
+
*/
|
|
23
|
+
ProductConfigurationBubbleMode["BubbleSelected"] = "BubbleSelected";
|
|
20
24
|
/**
|
|
21
25
|
* Bubble to the closest CfgProduct, let it revalidate, then that will continue
|
|
22
26
|
* the bubble after validate.
|
|
@@ -28,6 +32,11 @@ export var ProductConfigurationBubbleMode;
|
|
|
28
32
|
* So with this mode it is possible to select an option where its parents are not selected.
|
|
29
33
|
*/
|
|
30
34
|
ProductConfigurationBubbleMode["ValidateAndBubbleSelected"] = "ValidateAndBubbleSelected";
|
|
35
|
+
/**
|
|
36
|
+
* Like ValidateAndBubbleSelected, but SyncGroups are applied after
|
|
37
|
+
* ValidateAndBubbleSelected has been done
|
|
38
|
+
*/
|
|
39
|
+
ProductConfigurationBubbleMode["ValidateAndBubbleSelectedAndApplySyncGroups"] = "ValidateAndBubbleSelectedAndApplySyncGroups";
|
|
31
40
|
/**
|
|
32
41
|
* Stop bubbling
|
|
33
42
|
* This mode supports internal functionality and is not expected to be used by integrators.
|
|
@@ -93,7 +102,8 @@ export class _CfgOptionInternal {
|
|
|
93
102
|
features[i] = freshRef;
|
|
94
103
|
// In CfgOption we let stop bubble slip through. This is because CfgOption is sort of
|
|
95
104
|
// a semi level. Like Feature + Option together constitutes one level.
|
|
96
|
-
if (bubbleMode === ProductConfigurationBubbleMode.ValidateAndBubbleSelected
|
|
105
|
+
if (bubbleMode === ProductConfigurationBubbleMode.ValidateAndBubbleSelected ||
|
|
106
|
+
bubbleMode === ProductConfigurationBubbleMode.BubbleSelected) {
|
|
97
107
|
// selectOption takes care of the bubble
|
|
98
108
|
yield this.parent.selectOption(this, true, bubbleMode);
|
|
99
109
|
}
|
|
@@ -300,6 +310,23 @@ export class _CfgOptionInternal {
|
|
|
300
310
|
}
|
|
301
311
|
return this._features;
|
|
302
312
|
}
|
|
313
|
+
get path() {
|
|
314
|
+
return [...this.parent.path, this.code];
|
|
315
|
+
}
|
|
316
|
+
getFromPath(path) {
|
|
317
|
+
path = path.slice();
|
|
318
|
+
const s = path.shift();
|
|
319
|
+
switch (s) {
|
|
320
|
+
case undefined:
|
|
321
|
+
return this;
|
|
322
|
+
default:
|
|
323
|
+
const feature = this.features.find((o) => o.code === s);
|
|
324
|
+
if (feature === undefined) {
|
|
325
|
+
throw new Error(`Feature not found ${s}, ${path.join(", ")}`);
|
|
326
|
+
}
|
|
327
|
+
return feature._internal.getFromPath(path);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
303
330
|
_freshRefDescendants() {
|
|
304
331
|
const features = this._features || [];
|
|
305
332
|
for (let i = 0; i < features.length; i++) {
|
|
@@ -326,7 +353,7 @@ export class CfgOption {
|
|
|
326
353
|
* Calling this will cause a validation call to the server.
|
|
327
354
|
*/
|
|
328
355
|
this.setSelected = (on) => __awaiter(this, void 0, void 0, function* () {
|
|
329
|
-
return yield this._internal.parent.selectOption(this._internal, on, ProductConfigurationBubbleMode.
|
|
356
|
+
return yield this._internal.parent.selectOption(this._internal, on, ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups);
|
|
330
357
|
});
|
|
331
358
|
this.listenForChange = (l) => this._internal.changeObservable.listen(l);
|
|
332
359
|
this.stopListenForChange = (l) => this._internal.changeObservable.stopListen(l);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
2
|
import { Feature, FeatureRef, SelectedOption } from "../CatalogueAPI.js";
|
|
3
|
-
import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
3
|
+
import { CfgPath, CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
4
4
|
import { CfgFeature, _CfgFeatureInternal } from "./CfgFeature.js";
|
|
5
|
-
import { ProductConfigurationBubbleMode } from "./CfgOption.js";
|
|
5
|
+
import { ProductConfigurationBubbleMode, _CfgOptionInternal } from "./CfgOption.js";
|
|
6
6
|
export declare type ProductConfigurationChangeNotification = {
|
|
7
7
|
freshRef: CfgProductConfiguration;
|
|
8
8
|
};
|
|
@@ -43,6 +43,8 @@ export declare class _CfgProductConfigurationInternal {
|
|
|
43
43
|
* outside we want notifications to bubble all the way to the root.
|
|
44
44
|
*/
|
|
45
45
|
setApiSelection: (selectedOptions: SelectedOption[], bubbleToRoot: boolean) => Promise<boolean>;
|
|
46
|
+
get path(): CfgPath;
|
|
47
|
+
getFromPath(path: CfgPath): _CfgProductConfigurationInternal | _CfgFeatureInternal | _CfgOptionInternal;
|
|
46
48
|
structureCompare: (other: _CfgProductConfigurationInternal, strictOrder?: boolean, descriptionMatch?: boolean) => boolean;
|
|
47
49
|
/**
|
|
48
50
|
* When used internally the notifications are taken care off by the caller, but if set from
|
|
@@ -215,6 +215,23 @@ export class _CfgProductConfigurationInternal {
|
|
|
215
215
|
features[i] = CfgFeature._makeNewRefFrom(featureInternal);
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
|
+
get path() {
|
|
219
|
+
return [...this.parentProduct.path, "c"];
|
|
220
|
+
}
|
|
221
|
+
getFromPath(path) {
|
|
222
|
+
path = path.slice();
|
|
223
|
+
const s = path.shift();
|
|
224
|
+
switch (s) {
|
|
225
|
+
case undefined:
|
|
226
|
+
return this;
|
|
227
|
+
default:
|
|
228
|
+
const feature = this.features.find((f) => f.code === s);
|
|
229
|
+
if (feature === undefined) {
|
|
230
|
+
throw new Error(`Feature not found ${s}, ${path.join(", ")}`);
|
|
231
|
+
}
|
|
232
|
+
return feature._internal.getFromPath(path);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
218
235
|
}
|
|
219
236
|
export class CfgProductConfiguration {
|
|
220
237
|
/**
|
package/dist/productLoader.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GetProductParams, PostValidateParams, ValidateRequest } from "./CatalogueAPI";
|
|
1
|
+
import { GetProductParams, PostValidateParams, ValidateRequest } from "./CatalogueAPI.js";
|
|
2
2
|
import { CfgProductResponse, CfgValidateResponse } from "./utilitiesCatalogueData.js";
|
|
3
3
|
export declare type GetProduct = (params: GetProductParams) => Promise<CfgProductResponse>;
|
|
4
4
|
export declare type PostValidate = (params: PostValidateParams, body: ValidateRequest) => Promise<CfgValidateResponse>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SyncGroup } from "../CatalogueAPI.js";
|
|
2
|
+
import { _CfgOptionInternal } from "../productConfiguration/CfgOption.js";
|
|
3
|
+
import { SyncCode } from "./SyncGroupsHandler.js";
|
|
4
|
+
import { SyncGroupsTransaction } from "./SyncGroupsTransaction.js";
|
|
5
|
+
export declare class SyncGroupsApplier {
|
|
6
|
+
/**
|
|
7
|
+
* At load of a new product this is used to move it into a synced state
|
|
8
|
+
*/
|
|
9
|
+
static init(transaction: SyncGroupsTransaction): Promise<boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* At an active select of an option this is the entry point
|
|
12
|
+
*/
|
|
13
|
+
static selectOption(transaction: SyncGroupsTransaction, option: _CfgOptionInternal, on: boolean): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* @returns undefined if the @syncGroup is undefined, false if
|
|
16
|
+
* the @mustSupport is not fulfilled or the syncCode if all is ok
|
|
17
|
+
*/
|
|
18
|
+
static getSyncCode(syncGroup: SyncGroup | undefined, mustSupport: "push" | "pull"): SyncCode | undefined | false;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=SyncGroupsApplier.d.ts.map
|