@configura/web-api 2.0.0-alpha.9 → 2.1.0-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/.eslintrc.json +1 -14
- package/dist/CatalogueAPI.d.ts +103 -32
- package/dist/CatalogueAPI.js +62 -6
- package/dist/CfgProduct.d.ts +90 -14
- package/dist/CfgProduct.js +266 -56
- package/dist/CfgReferencePathHelper.d.ts +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/io/CfgHistoryManager.d.ts +33 -1
- package/dist/io/CfgHistoryManager.js +68 -6
- package/dist/io/CfgHistoryToProdConfConnector.d.ts +11 -10
- package/dist/io/CfgHistoryToProdConfConnector.js +32 -38
- package/dist/io/CfgIOManager.d.ts +5 -0
- package/dist/io/CfgIOManager.js +20 -1
- package/dist/io/CfgIOProdConfConnector.d.ts +17 -18
- package/dist/io/CfgIOProdConfConnector.js +52 -58
- package/dist/io/CfgIOWarningSupplier.d.ts +4 -0
- package/dist/io/CfgIOWarningSupplier.js +1 -0
- package/dist/io/CfgObservableStateToProdConfConnector.d.ts +4 -4
- package/dist/io/CfgObservableStateToProdConfConnector.js +3 -3
- package/dist/io/CfgWindowMessageManager.js +4 -0
- package/dist/io/CfgWindowMessageToProdConfConnector.d.ts +4 -4
- package/dist/io/CfgWindowMessageToProdConfConnector.js +3 -3
- package/dist/productConfiguration/CfgFeature.d.ts +12 -7
- package/dist/productConfiguration/CfgFeature.js +33 -14
- package/dist/productConfiguration/CfgOption.d.ts +16 -10
- package/dist/productConfiguration/CfgOption.js +46 -18
- package/dist/productConfiguration/CfgProductConfiguration.d.ts +27 -16
- package/dist/productConfiguration/CfgProductConfiguration.js +53 -29
- package/dist/productConfiguration/filters.d.ts +6 -4
- package/dist/productConfiguration/filters.js +94 -23
- package/dist/productConfiguration/productParamsGenerator.d.ts +3 -3
- package/dist/productConfiguration/utilitiesProductConfiguration.d.ts +1 -1
- package/dist/productConfiguration/utilitiesProductConfiguration.js +11 -4
- package/dist/productLoader.d.ts +3 -3
- package/dist/productLoader.js +1 -1
- package/dist/syncGroups/SyncGroupsHandler.d.ts +9 -2
- package/dist/syncGroups/SyncGroupsHandler.js +15 -4
- package/dist/syncGroups/SyncGroupsState.d.ts +5 -1
- package/dist/syncGroups/SyncGroupsState.js +44 -2
- package/dist/syncGroups/SyncGroupsTransaction.js +34 -21
- package/dist/tasks/TaskHandler.d.ts +2 -2
- package/dist/tasks/TaskHandler.js +2 -1
- package/dist/tests/testData/dummyProductForTest.d.ts +2 -2
- package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.js +14 -9
- package/dist/tests/testData/testDataCachedGetProduct.js +2 -0
- package/dist/tests/testData/testDataCachedPostValidate.js +2 -0
- package/dist/tests/testData/testDataProductAggregatedPrice.js +3 -1
- package/dist/tests/testData/testDataUpcharge.js +2 -0
- package/dist/utilitiesCatalogueData.d.ts +14 -9
- package/dist/utilitiesCatalogueData.js +7 -0
- package/dist/utilitiesCataloguePermission.d.ts +4 -4
- package/dist/utilitiesConfiguration.d.ts +29 -0
- package/dist/utilitiesConfiguration.js +200 -0
- package/dist/utilitiesNumericValues.js +13 -8
- package/package.json +3 -3
- package/dist/ConfigurationConverter.d.ts +0 -5
- package/dist/ConfigurationConverter.js +0 -72
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DtoProductConf } from "../CatalogueAPI.js";
|
|
2
|
+
import { CfgProdConfParts } from "../utilitiesConfiguration.js";
|
|
2
3
|
import { CfgIOProdConfConnector, CfgProdConfMessage, CfgProdConfMessageVersions } from "./CfgIOProdConfConnector.js";
|
|
3
4
|
import { CfgWindowMessageManager } from "./CfgWindowMessageManager.js";
|
|
4
5
|
/**
|
|
5
6
|
* Instantiating this will make Stage send product configuration changes using the post message-API.
|
|
6
7
|
* It will also make Stage listen for incoming product configuration update messages.
|
|
7
8
|
* This can be used to communicate in and out of an iframe for example.
|
|
8
|
-
* @param doValidate Run server side product validation for incoming
|
|
9
9
|
* @param sendVersions What versions of the productConfiguration shall be sent? Multiple can be selected
|
|
10
10
|
* @param includeExtendedDataInSend Only for version 2.0. Includes unit and groupCode.
|
|
11
11
|
* @param includeProdParamsInSend Only for version 2.0. Includes product params, in both main and additional products.
|
|
12
12
|
*/
|
|
13
13
|
export declare class CfgWindowMessageToProdConfConnector extends CfgIOProdConfConnector<CfgProdConfMessage> {
|
|
14
14
|
private _sendVersions;
|
|
15
|
-
constructor(manager: CfgWindowMessageManager,
|
|
16
|
-
protected makeSendData(conf:
|
|
15
|
+
constructor(manager: CfgWindowMessageManager, _sendVersions?: CfgProdConfMessageVersions, includeInSend?: CfgProdConfParts);
|
|
16
|
+
protected makeSendData(conf: DtoProductConf, initial: boolean): CfgProdConfMessage;
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=CfgWindowMessageToProdConfConnector.d.ts.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
+
import { CfgProdConfParts } from "../utilitiesConfiguration.js";
|
|
1
2
|
import { CfgIOProdConfConnector, CfgProdConfMessageVersions, } from "./CfgIOProdConfConnector.js";
|
|
2
3
|
/**
|
|
3
4
|
* Instantiating this will make Stage send product configuration changes using the post message-API.
|
|
4
5
|
* It will also make Stage listen for incoming product configuration update messages.
|
|
5
6
|
* This can be used to communicate in and out of an iframe for example.
|
|
6
|
-
* @param doValidate Run server side product validation for incoming
|
|
7
7
|
* @param sendVersions What versions of the productConfiguration shall be sent? Multiple can be selected
|
|
8
8
|
* @param includeExtendedDataInSend Only for version 2.0. Includes unit and groupCode.
|
|
9
9
|
* @param includeProdParamsInSend Only for version 2.0. Includes product params, in both main and additional products.
|
|
10
10
|
*/
|
|
11
11
|
export class CfgWindowMessageToProdConfConnector extends CfgIOProdConfConnector {
|
|
12
|
-
constructor(manager,
|
|
13
|
-
super(manager,
|
|
12
|
+
constructor(manager, _sendVersions = CfgProdConfMessageVersions.V2dot0, includeInSend = CfgProdConfParts.NoExtra) {
|
|
13
|
+
super(manager, includeInSend);
|
|
14
14
|
this._sendVersions = _sendVersions;
|
|
15
15
|
}
|
|
16
16
|
makeSendData(conf, initial) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
-
import { DtoFeature,
|
|
2
|
+
import { DtoFeature, DtoFeatureConf, DtoNote, DtoSelectedOption, DtoSyncGroup, DtoSyncGroupMethods } from "../CatalogueAPI.js";
|
|
3
3
|
import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
4
4
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
5
5
|
import { SyncCode } from "../syncGroups/SyncGroupsHandler.js";
|
|
@@ -32,13 +32,13 @@ export declare type FeatureChangeNotification = {
|
|
|
32
32
|
*/
|
|
33
33
|
export declare class _CfgFeatureInternal {
|
|
34
34
|
readonly rawFeature: DtoFeature;
|
|
35
|
-
private readonly
|
|
36
|
-
|
|
35
|
+
private readonly rawFeatures;
|
|
36
|
+
private _key;
|
|
37
37
|
readonly parent: _CfgProductConfigurationInternal | _CfgOptionInternal;
|
|
38
38
|
readonly parentConfiguration: _CfgProductConfigurationInternal;
|
|
39
39
|
readonly parentProduct: _CfgProductInternal;
|
|
40
40
|
readonly rootProduct: _CfgProductInternal;
|
|
41
|
-
constructor(rawFeature: DtoFeature,
|
|
41
|
+
constructor(rawFeature: DtoFeature, rawFeatures: DtoFeature[], _key: string, // Unique amongst siblings
|
|
42
42
|
parent: _CfgProductConfigurationInternal | _CfgOptionInternal, parentConfiguration: _CfgProductConfigurationInternal, parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal);
|
|
43
43
|
readonly selectionType: SelectionType;
|
|
44
44
|
private _options;
|
|
@@ -48,10 +48,14 @@ export declare class _CfgFeatureInternal {
|
|
|
48
48
|
readonly changeObservable: Observable<FeatureChangeNotification>;
|
|
49
49
|
get code(): string;
|
|
50
50
|
get groupCode(): string | undefined;
|
|
51
|
+
get key(): string;
|
|
52
|
+
set key(k: string);
|
|
53
|
+
get notes(): DtoNote[];
|
|
51
54
|
get isUseNumericValue(): boolean;
|
|
52
55
|
get numericValue(): number | undefined;
|
|
53
56
|
setNumericValue: (val: number) => Promise<boolean>;
|
|
54
57
|
get description(): string;
|
|
58
|
+
get omitOnOrder(): boolean;
|
|
55
59
|
get syncGroup(): DtoSyncGroup | undefined;
|
|
56
60
|
/**
|
|
57
61
|
* @return one of the following, in order:
|
|
@@ -99,7 +103,7 @@ export declare class _CfgFeatureInternal {
|
|
|
99
103
|
* as nonexisting children can not call their parent.
|
|
100
104
|
*/
|
|
101
105
|
_childHasChanged: (childOption: _CfgOptionInternal, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise<void>;
|
|
102
|
-
getDtoConf: (includeExtendedData: boolean) =>
|
|
106
|
+
getDtoConf: (includeExtendedData: boolean) => DtoFeatureConf;
|
|
103
107
|
setApiSelection: (apiOptionSelectionMap: {
|
|
104
108
|
[index: string]: DtoSelectedOption;
|
|
105
109
|
} | undefined) => Promise<boolean>;
|
|
@@ -124,11 +128,10 @@ export declare class _CfgFeatureInternal {
|
|
|
124
128
|
* @throws Will throw if options have not yet been generated.
|
|
125
129
|
*/
|
|
126
130
|
private _freshRefAllOptions;
|
|
127
|
-
_freshRefDescendants(): void;
|
|
128
131
|
}
|
|
129
132
|
export declare class CfgFeature {
|
|
130
133
|
readonly _internal: _CfgFeatureInternal;
|
|
131
|
-
static make(rawFeature: DtoFeature,
|
|
134
|
+
static make(rawFeature: DtoFeature, rawFeatures: DtoFeature[], key: string, parent: _CfgProductConfigurationInternal | _CfgOptionInternal, parentConfiguration: _CfgProductConfigurationInternal, parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal): CfgFeature;
|
|
132
135
|
/**
|
|
133
136
|
* Makes an object wrapping the passed object. This is not a clone method,
|
|
134
137
|
* it is a method to make a new outer reference. Like a shallow copy.
|
|
@@ -148,6 +151,7 @@ export declare class CfgFeature {
|
|
|
148
151
|
get key(): string;
|
|
149
152
|
get code(): string;
|
|
150
153
|
get groupCode(): string | undefined;
|
|
154
|
+
get notes(): DtoNote[];
|
|
151
155
|
/**
|
|
152
156
|
* If true the options in the feature is selected by both sending its code and numeric value
|
|
153
157
|
* when selecting.
|
|
@@ -162,6 +166,7 @@ export declare class CfgFeature {
|
|
|
162
166
|
setNumericValue: (val: number) => Promise<boolean>;
|
|
163
167
|
get unit(): LengthUnit;
|
|
164
168
|
get description(): string;
|
|
169
|
+
get omitOnOrder(): boolean;
|
|
165
170
|
get hasUpcharge(): boolean | undefined;
|
|
166
171
|
get selectedOptions(): CfgOption[];
|
|
167
172
|
/** Are all ancestors up to the CfgProductConfiguration selected? */
|
|
@@ -62,11 +62,11 @@ function doFreshRefOption(options, optionInternal, committed, beforeNotify) {
|
|
|
62
62
|
* should be used and interacted with.
|
|
63
63
|
*/
|
|
64
64
|
export class _CfgFeatureInternal {
|
|
65
|
-
constructor(rawFeature,
|
|
65
|
+
constructor(rawFeature, rawFeatures, _key, // Unique amongst siblings
|
|
66
66
|
parent, parentConfiguration, parentProduct, rootProduct) {
|
|
67
67
|
this.rawFeature = rawFeature;
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
68
|
+
this.rawFeatures = rawFeatures;
|
|
69
|
+
this._key = _key;
|
|
70
70
|
this.parent = parent;
|
|
71
71
|
this.parentConfiguration = parentConfiguration;
|
|
72
72
|
this.parentProduct = parentProduct;
|
|
@@ -114,6 +114,7 @@ export class _CfgFeatureInternal {
|
|
|
114
114
|
}
|
|
115
115
|
yield this._notifyAllOfChange(bubbleMode, committed);
|
|
116
116
|
});
|
|
117
|
+
// Keep in sync with stripExtendedDataFromDtoFeatureConf
|
|
117
118
|
this.getDtoConf = (includeExtendedData) => {
|
|
118
119
|
const result = {
|
|
119
120
|
code: this.code,
|
|
@@ -128,6 +129,12 @@ export class _CfgFeatureInternal {
|
|
|
128
129
|
}
|
|
129
130
|
return result;
|
|
130
131
|
};
|
|
132
|
+
// DtoFeatureConf is the newer more easily readable format for configuration. As
|
|
133
|
+
// the API:s are still using the older format (and will for the forseeable future) we need
|
|
134
|
+
// to support both formats. The new format can be converted to the old, but not the other
|
|
135
|
+
// way around. For that reason the get-method above uses the new format, and the set-method
|
|
136
|
+
// below the old format. As these functions are meant to only be used internally this should't
|
|
137
|
+
// cause too much confusion.
|
|
131
138
|
this.setApiSelection = (apiOptionSelectionMap) => __awaiter(this, void 0, void 0, function* () {
|
|
132
139
|
const selectionType = this.selectionType;
|
|
133
140
|
const isGroup = selectionType === SelectionType.Group;
|
|
@@ -407,6 +414,16 @@ export class _CfgFeatureInternal {
|
|
|
407
414
|
get groupCode() {
|
|
408
415
|
return this.rawFeature.groupCode;
|
|
409
416
|
}
|
|
417
|
+
get key() {
|
|
418
|
+
return this._key;
|
|
419
|
+
}
|
|
420
|
+
set key(k) {
|
|
421
|
+
this._key = k;
|
|
422
|
+
}
|
|
423
|
+
get notes() {
|
|
424
|
+
var _a;
|
|
425
|
+
return this.parentProduct.getNotes((_a = this.rawFeature.noteRefs) !== null && _a !== void 0 ? _a : []);
|
|
426
|
+
}
|
|
410
427
|
get isUseNumericValue() {
|
|
411
428
|
return this.rawFeature.numericOrder;
|
|
412
429
|
}
|
|
@@ -430,6 +447,9 @@ export class _CfgFeatureInternal {
|
|
|
430
447
|
get description() {
|
|
431
448
|
return this.rawFeature.description;
|
|
432
449
|
}
|
|
450
|
+
get omitOnOrder() {
|
|
451
|
+
return this.rawFeature.omitOnOrder === true;
|
|
452
|
+
}
|
|
433
453
|
get syncGroup() {
|
|
434
454
|
return this.rawFeature.syncGroup;
|
|
435
455
|
}
|
|
@@ -512,7 +532,7 @@ export class _CfgFeatureInternal {
|
|
|
512
532
|
const hasDuplicateDescription = someMatch(this.rawFeature.options, (l, r) => {
|
|
513
533
|
return l.description.toLowerCase() === r.description.toLowerCase();
|
|
514
534
|
});
|
|
515
|
-
this._options = this.rawFeature.options.map((o) => CfgOption.make(o, this.
|
|
535
|
+
this._options = this.rawFeature.options.map((o) => CfgOption.make(o, this.rawFeatures, hasDuplicateDescription, this, this.parentConfiguration, this.parentProduct, this.rootProduct));
|
|
516
536
|
}
|
|
517
537
|
return this._options;
|
|
518
538
|
}
|
|
@@ -536,14 +556,6 @@ export class _CfgFeatureInternal {
|
|
|
536
556
|
});
|
|
537
557
|
}
|
|
538
558
|
}
|
|
539
|
-
_freshRefDescendants() {
|
|
540
|
-
const options = this._options || [];
|
|
541
|
-
for (let i = 0; i < options.length; i++) {
|
|
542
|
-
const optionInternal = options[i]._internal;
|
|
543
|
-
optionInternal._freshRefDescendants();
|
|
544
|
-
options[i] = CfgOption._makeNewRefFrom(optionInternal);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
559
|
}
|
|
548
560
|
export class CfgFeature {
|
|
549
561
|
/**
|
|
@@ -571,8 +583,8 @@ export class CfgFeature {
|
|
|
571
583
|
this.listenForChange = (l) => this._internal.changeObservable.listen(l);
|
|
572
584
|
this.stopListenForChange = (l) => this._internal.changeObservable.stopListen(l);
|
|
573
585
|
}
|
|
574
|
-
static make(rawFeature,
|
|
575
|
-
return new this(new _CfgFeatureInternal(rawFeature,
|
|
586
|
+
static make(rawFeature, rawFeatures, key, parent, parentConfiguration, parentProduct, rootProduct) {
|
|
587
|
+
return new this(new _CfgFeatureInternal(rawFeature, rawFeatures, key, parent, parentConfiguration, parentProduct, rootProduct));
|
|
576
588
|
}
|
|
577
589
|
/**
|
|
578
590
|
* Makes an object wrapping the passed object. This is not a clone method,
|
|
@@ -591,6 +603,7 @@ export class CfgFeature {
|
|
|
591
603
|
get selectionType() {
|
|
592
604
|
return this._internal.selectionType;
|
|
593
605
|
}
|
|
606
|
+
// Unique amongst siblings. Can change. Only use for presentation layer i.e. React.
|
|
594
607
|
get key() {
|
|
595
608
|
return this._internal.key;
|
|
596
609
|
}
|
|
@@ -600,6 +613,9 @@ export class CfgFeature {
|
|
|
600
613
|
get groupCode() {
|
|
601
614
|
return this._internal.groupCode;
|
|
602
615
|
}
|
|
616
|
+
get notes() {
|
|
617
|
+
return this._internal.notes;
|
|
618
|
+
}
|
|
603
619
|
/**
|
|
604
620
|
* If true the options in the feature is selected by both sending its code and numeric value
|
|
605
621
|
* when selecting.
|
|
@@ -617,6 +633,9 @@ export class CfgFeature {
|
|
|
617
633
|
get description() {
|
|
618
634
|
return this._internal.description;
|
|
619
635
|
}
|
|
636
|
+
get omitOnOrder() {
|
|
637
|
+
return this._internal.omitOnOrder;
|
|
638
|
+
}
|
|
620
639
|
get hasUpcharge() {
|
|
621
640
|
return this._internal.hasUpcharge;
|
|
622
641
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
-
import { DtoFeature, DtoOption,
|
|
2
|
+
import { DtoFeature, DtoMiscFile, DtoNote, DtoOption, DtoOptionConf, DtoSelectedOption } from "../CatalogueAPI.js";
|
|
3
3
|
import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
4
4
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
5
5
|
import { NumericValuesSelection } from "../utilitiesNumericValues.js";
|
|
@@ -60,20 +60,23 @@ export declare enum ProductConfigurationBubbleMode {
|
|
|
60
60
|
*/
|
|
61
61
|
export declare class _CfgOptionInternal {
|
|
62
62
|
readonly rawOption: DtoOption;
|
|
63
|
-
private readonly
|
|
63
|
+
private readonly rawFeatures;
|
|
64
64
|
readonly parent: _CfgFeatureInternal;
|
|
65
65
|
readonly parentConfiguration: _CfgProductConfigurationInternal;
|
|
66
66
|
readonly parentProduct: _CfgProductInternal;
|
|
67
67
|
readonly rootProduct: _CfgProductInternal;
|
|
68
|
-
constructor(rawOption: DtoOption,
|
|
68
|
+
constructor(rawOption: DtoOption, rawFeatures: DtoFeature[], siblingHasDuplicateDescription: boolean, parent: _CfgFeatureInternal, parentConfiguration: _CfgProductConfigurationInternal, parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal);
|
|
69
69
|
private _features;
|
|
70
70
|
private _mtrlApplications;
|
|
71
71
|
readonly key: string;
|
|
72
|
+
private _upcharge;
|
|
72
73
|
private _numericValue;
|
|
73
74
|
readonly allowedNumericValues: NumericValuesSelection | undefined;
|
|
74
75
|
isAllowedNumericValue(val: number): boolean;
|
|
75
76
|
readonly changeObservable: Observable<OptionChangeNotification>;
|
|
76
77
|
get code(): string;
|
|
78
|
+
get notes(): DtoNote[];
|
|
79
|
+
get miscFiles(): DtoMiscFile[];
|
|
77
80
|
get isUseNumericValue(): boolean;
|
|
78
81
|
get numericValue(): number | undefined;
|
|
79
82
|
setNumericValue(val: number, doSelectOption: boolean): Promise<boolean>;
|
|
@@ -84,22 +87,22 @@ export declare class _CfgOptionInternal {
|
|
|
84
87
|
get ancestorsSelected(): boolean;
|
|
85
88
|
get mtrlApplications(): CfgMtrlApplication[];
|
|
86
89
|
get thumbnail(): string | undefined;
|
|
87
|
-
|
|
88
|
-
get
|
|
90
|
+
private _calculateUpcharge;
|
|
91
|
+
get upcharge(): number;
|
|
92
|
+
get priceChangeAtSelectChange(): number;
|
|
89
93
|
get features(): CfgFeature[];
|
|
90
94
|
/** Called by child to tell its parent that it has changed. */
|
|
91
95
|
_childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise<void>;
|
|
92
|
-
getDtoConf: (includeExtendedData: boolean) =>
|
|
96
|
+
getDtoConf: (includeExtendedData: boolean) => DtoOptionConf;
|
|
93
97
|
setApiSelection: (apiOptionSelection: DtoSelectedOption | undefined) => Promise<boolean>;
|
|
94
98
|
structureCompare: (other: _CfgOptionInternal, strictOrder?: boolean, descriptionMatch?: boolean) => boolean;
|
|
95
99
|
tryMatchSelection: (other: CfgOption, descriptionMatch?: boolean) => Promise<boolean>;
|
|
96
100
|
keyMatch: (other: _CfgOptionInternal, descriptionMatch?: boolean) => boolean;
|
|
97
101
|
_getFeaturesWithCode: (code: string) => _CfgFeatureInternal[];
|
|
98
|
-
_freshRefDescendants(): void;
|
|
99
102
|
}
|
|
100
103
|
export declare class CfgOption {
|
|
101
104
|
readonly _internal: _CfgOptionInternal;
|
|
102
|
-
static make(rawOption: DtoOption,
|
|
105
|
+
static make(rawOption: DtoOption, rawFeatures: DtoFeature[], siblingHasDuplicateDescription: boolean, parent: _CfgFeatureInternal, parentConfiguration: _CfgProductConfigurationInternal, parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal): CfgOption;
|
|
103
106
|
/**
|
|
104
107
|
* Makes an object wrapping the passed object. This is not a clone method,
|
|
105
108
|
* it is a method to make a new outer reference. Like a shallow copy.
|
|
@@ -114,10 +117,13 @@ export declare class CfgOption {
|
|
|
114
117
|
private constructor();
|
|
115
118
|
isBackedBySame: (other: CfgOption) => boolean;
|
|
116
119
|
get parentProduct(): CfgProduct;
|
|
120
|
+
get parent(): CfgFeature;
|
|
117
121
|
get rootProduct(): CfgProduct;
|
|
118
122
|
get rawOption(): DtoOption;
|
|
119
123
|
get key(): string;
|
|
120
124
|
get code(): string;
|
|
125
|
+
get notes(): DtoNote[];
|
|
126
|
+
get miscFiles(): DtoMiscFile[];
|
|
121
127
|
get isUseNumericValue(): boolean;
|
|
122
128
|
get numericValue(): number | undefined;
|
|
123
129
|
setNumericValue: (val: number, doSelectOption: boolean) => Promise<boolean>;
|
|
@@ -143,8 +149,8 @@ export declare class CfgOption {
|
|
|
143
149
|
*/
|
|
144
150
|
setSelected: (on: boolean) => Promise<boolean>;
|
|
145
151
|
get thumbnail(): string | undefined;
|
|
146
|
-
get upcharge(): number
|
|
147
|
-
get priceChangeAtSelectChange(): number
|
|
152
|
+
get upcharge(): number;
|
|
153
|
+
get priceChangeAtSelectChange(): number;
|
|
148
154
|
get features(): CfgFeature[];
|
|
149
155
|
listenForChange: (l: SingleArgCallback<OptionChangeNotification>) => void;
|
|
150
156
|
stopListenForChange: (l: SingleArgCallback<OptionChangeNotification>) => void;
|
|
@@ -80,9 +80,9 @@ function doesChildrenShareOptionsCode(features) {
|
|
|
80
80
|
* the class that should be used and interacted with.
|
|
81
81
|
*/
|
|
82
82
|
export class _CfgOptionInternal {
|
|
83
|
-
constructor(rawOption,
|
|
83
|
+
constructor(rawOption, rawFeatures, siblingHasDuplicateDescription, parent, parentConfiguration, parentProduct, rootProduct) {
|
|
84
84
|
this.rawOption = rawOption;
|
|
85
|
-
this.
|
|
85
|
+
this.rawFeatures = rawFeatures;
|
|
86
86
|
this.parent = parent;
|
|
87
87
|
this.parentConfiguration = parentConfiguration;
|
|
88
88
|
this.parentProduct = parentProduct;
|
|
@@ -132,7 +132,19 @@ export class _CfgOptionInternal {
|
|
|
132
132
|
}
|
|
133
133
|
return result;
|
|
134
134
|
};
|
|
135
|
+
// DtoOptionConf is the newer more easily readable format for configuration. As
|
|
136
|
+
// the API:s are still using the older format (and will for the forseeable future) we need
|
|
137
|
+
// to support both formats. The new format can be converted to the old, but not the other
|
|
138
|
+
// way around. For that reason the get-method above uses the new format, and the set-method
|
|
139
|
+
// below the old format. As these functions are meant to only be used internally this should't
|
|
140
|
+
// cause too much confusion.
|
|
135
141
|
this.setApiSelection = (apiOptionSelection) => __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
let change = false;
|
|
143
|
+
const upcharge = this._calculateUpcharge();
|
|
144
|
+
if (this._upcharge !== upcharge) {
|
|
145
|
+
change = true;
|
|
146
|
+
this._upcharge = upcharge;
|
|
147
|
+
}
|
|
136
148
|
let features;
|
|
137
149
|
if (apiOptionSelection === undefined) {
|
|
138
150
|
features = this._features || []; // All already generated children
|
|
@@ -140,7 +152,10 @@ export class _CfgOptionInternal {
|
|
|
140
152
|
else {
|
|
141
153
|
features = this.features; // This will generate all children
|
|
142
154
|
}
|
|
143
|
-
|
|
155
|
+
if ((yield Promise.all(features.map((f) => f._internal.setApiSelection(apiOptionSelection ? apiOptionSelection.next : undefined)))).some((b) => b)) {
|
|
156
|
+
change = true;
|
|
157
|
+
}
|
|
158
|
+
return change;
|
|
144
159
|
});
|
|
145
160
|
this.structureCompare = (other, strictOrder = true, descriptionMatch = false) => this.keyMatch(other, descriptionMatch) &&
|
|
146
161
|
compareArrays(this.features, other.features, (l, r) => l._internal.structureCompare(r._internal, strictOrder, descriptionMatch), strictOrder);
|
|
@@ -174,6 +189,7 @@ export class _CfgOptionInternal {
|
|
|
174
189
|
this.key =
|
|
175
190
|
this.description +
|
|
176
191
|
(this.description === "" || siblingHasDuplicateDescription ? this.code : "");
|
|
192
|
+
this._upcharge = this._calculateUpcharge();
|
|
177
193
|
const rawRanges = rawOption.codeRanges;
|
|
178
194
|
if (rawRanges === undefined || rawRanges.length === 0) {
|
|
179
195
|
if (this.isUseNumericValue) {
|
|
@@ -200,6 +216,14 @@ export class _CfgOptionInternal {
|
|
|
200
216
|
get code() {
|
|
201
217
|
return this.rawOption.code;
|
|
202
218
|
}
|
|
219
|
+
get notes() {
|
|
220
|
+
var _a;
|
|
221
|
+
return this.parentProduct.getNotes((_a = this.rawOption.noteRefs) !== null && _a !== void 0 ? _a : []);
|
|
222
|
+
}
|
|
223
|
+
get miscFiles() {
|
|
224
|
+
var _a;
|
|
225
|
+
return (_a = this.rawOption.miscFiles) !== null && _a !== void 0 ? _a : [];
|
|
226
|
+
}
|
|
203
227
|
get isUseNumericValue() {
|
|
204
228
|
return this.parent.isUseNumericValue;
|
|
205
229
|
}
|
|
@@ -272,18 +296,21 @@ export class _CfgOptionInternal {
|
|
|
272
296
|
get thumbnail() {
|
|
273
297
|
return this.rawOption.material || getMtrlPreview(this.mtrlApplications);
|
|
274
298
|
}
|
|
275
|
-
|
|
299
|
+
_calculateUpcharge() {
|
|
276
300
|
let upcharge = this.rawOption.upcharge || 0;
|
|
277
301
|
const priceCodes = this.rawOption.priceCodes || [];
|
|
278
302
|
const prices = this.rootProduct.prices;
|
|
279
303
|
upcharge += recursivelyGetPriceCodeValue(priceCodes, prices) || 0;
|
|
280
304
|
return upcharge;
|
|
281
305
|
}
|
|
306
|
+
get upcharge() {
|
|
307
|
+
return this._upcharge;
|
|
308
|
+
}
|
|
282
309
|
get priceChangeAtSelectChange() {
|
|
283
310
|
if (!this.parent.hasUpcharge) {
|
|
284
|
-
return
|
|
311
|
+
return 0;
|
|
285
312
|
}
|
|
286
|
-
const upcharge = this.
|
|
313
|
+
const upcharge = this._upcharge || 0;
|
|
287
314
|
const isSelected = this.parent.isSelected(this);
|
|
288
315
|
if (this.parent.selectionType === SelectionType.SelectMany) {
|
|
289
316
|
return isSelected ? -upcharge : upcharge;
|
|
@@ -299,12 +326,12 @@ export class _CfgOptionInternal {
|
|
|
299
326
|
}
|
|
300
327
|
return upcharge - (selectedOptions[0].upcharge || 0);
|
|
301
328
|
}
|
|
302
|
-
return
|
|
329
|
+
return 0;
|
|
303
330
|
}
|
|
304
331
|
get features() {
|
|
305
332
|
if (this._features === undefined) {
|
|
306
333
|
const allRefs = this.rawOption.featureRefs || [];
|
|
307
|
-
const features = syncCfgFeatures(allRefs, [], this.
|
|
334
|
+
const features = syncCfgFeatures(allRefs, [], this.rawFeatures, this, this.parentConfiguration, this.parentProduct, this.rootProduct);
|
|
308
335
|
if (doesChildrenShareOptionsCode(features)) {
|
|
309
336
|
throw new Error("Stage does not yet properly support Options that has multiple sub-features with overlapping option codes.");
|
|
310
337
|
}
|
|
@@ -312,14 +339,6 @@ export class _CfgOptionInternal {
|
|
|
312
339
|
}
|
|
313
340
|
return this._features;
|
|
314
341
|
}
|
|
315
|
-
_freshRefDescendants() {
|
|
316
|
-
const features = this._features || [];
|
|
317
|
-
for (let i = 0; i < features.length; i++) {
|
|
318
|
-
const featureInternal = features[i]._internal;
|
|
319
|
-
featureInternal._freshRefDescendants();
|
|
320
|
-
features[i] = CfgFeature._makeNewRefFrom(featureInternal);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
342
|
}
|
|
324
343
|
export class CfgOption {
|
|
325
344
|
/**
|
|
@@ -343,8 +362,8 @@ export class CfgOption {
|
|
|
343
362
|
this.listenForChange = (l) => this._internal.changeObservable.listen(l);
|
|
344
363
|
this.stopListenForChange = (l) => this._internal.changeObservable.stopListen(l);
|
|
345
364
|
}
|
|
346
|
-
static make(rawOption,
|
|
347
|
-
return new this(new _CfgOptionInternal(rawOption,
|
|
365
|
+
static make(rawOption, rawFeatures, siblingHasDuplicateDescription, parent, parentConfiguration, parentProduct, rootProduct) {
|
|
366
|
+
return new this(new _CfgOptionInternal(rawOption, rawFeatures, siblingHasDuplicateDescription, parent, parentConfiguration, parentProduct, rootProduct));
|
|
348
367
|
}
|
|
349
368
|
/**
|
|
350
369
|
* Makes an object wrapping the passed object. This is not a clone method,
|
|
@@ -357,6 +376,9 @@ export class CfgOption {
|
|
|
357
376
|
get parentProduct() {
|
|
358
377
|
return CfgProduct._makeNewRefFrom(this._internal.parentProduct);
|
|
359
378
|
}
|
|
379
|
+
get parent() {
|
|
380
|
+
return CfgFeature._makeNewRefFrom(this._internal.parent);
|
|
381
|
+
}
|
|
360
382
|
get rootProduct() {
|
|
361
383
|
return CfgProduct._makeNewRefFrom(this._internal.rootProduct);
|
|
362
384
|
}
|
|
@@ -369,6 +391,12 @@ export class CfgOption {
|
|
|
369
391
|
get code() {
|
|
370
392
|
return this._internal.code;
|
|
371
393
|
}
|
|
394
|
+
get notes() {
|
|
395
|
+
return this._internal.notes;
|
|
396
|
+
}
|
|
397
|
+
get miscFiles() {
|
|
398
|
+
return this._internal.miscFiles;
|
|
399
|
+
}
|
|
372
400
|
get isUseNumericValue() {
|
|
373
401
|
return this._internal.isUseNumericValue;
|
|
374
402
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LengthUnit, LengthValue, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
-
import { DtoFeature,
|
|
2
|
+
import { DtoFeature, DtoFeatureConf, DtoFeatureRef, DtoSelectedOption } from "../CatalogueAPI.js";
|
|
3
3
|
import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
4
4
|
import { CfgFeature, _CfgFeatureInternal } from "./CfgFeature.js";
|
|
5
5
|
import { ProductConfigurationBubbleMode } from "./CfgOption.js";
|
|
@@ -17,27 +17,29 @@ export declare type StretchMap = Map<string, {
|
|
|
17
17
|
* modified. CfgProductConfiguration is the class that should be used and interacted with.
|
|
18
18
|
*/
|
|
19
19
|
export declare class _CfgProductConfigurationInternal {
|
|
20
|
-
readonly allRawFeatures: DtoFeature[];
|
|
21
20
|
readonly parentProduct: _CfgProductInternal;
|
|
22
21
|
readonly rootProduct: _CfgProductInternal;
|
|
23
|
-
|
|
22
|
+
private readonly _initialRootFeatureRefs;
|
|
23
|
+
static _makeUninitialized(rootFeatureRefs: DtoFeatureRef[], rawFeatures: DtoFeature[], // Flat packed. All the features that can currently appear anyplace in the selection tree.
|
|
24
24
|
parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal): _CfgProductConfigurationInternal;
|
|
25
25
|
private constructor();
|
|
26
26
|
readonly key = "~";
|
|
27
27
|
private _rootFeatureRefs;
|
|
28
|
+
readonly accumulatedRawFeatures: DtoFeature[];
|
|
28
29
|
private _features;
|
|
29
30
|
readonly stretchReferenceLengthsByMeasureParamCode: StretchMap;
|
|
30
31
|
readonly changeObservable: Observable<ProductConfigurationChangeNotification>;
|
|
31
32
|
get rootFeatureRefs(): DtoFeatureRef[];
|
|
32
33
|
get features(): CfgFeature[];
|
|
33
34
|
private _notifyAllOfChange;
|
|
34
|
-
_freshRefDescendants(): void;
|
|
35
35
|
/** Called by child to tell its parent that it has changed. */
|
|
36
36
|
_childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise<void>;
|
|
37
|
-
getDtoConf: (includeExtendedData: boolean) =>
|
|
37
|
+
getDtoConf: (includeExtendedData: boolean) => DtoFeatureConf[];
|
|
38
|
+
getApiSelection: () => DtoSelectedOption[];
|
|
38
39
|
/**
|
|
39
40
|
* When used internally the notifications are taken care off by the caller, but if set from
|
|
40
41
|
* outside we want notifications to bubble all the way to the root.
|
|
42
|
+
* This method will not cause validation calls. Data is assumed to already be validated.
|
|
41
43
|
*/
|
|
42
44
|
setApiSelection: (selectedOptions: DtoSelectedOption[], bubbleToRoot: boolean) => Promise<boolean>;
|
|
43
45
|
structureCompare: (other: _CfgProductConfigurationInternal, strictOrder: boolean, descriptionMatch: boolean) => boolean;
|
|
@@ -48,7 +50,22 @@ export declare class _CfgProductConfigurationInternal {
|
|
|
48
50
|
tryMatchSelection: (other: _CfgProductConfigurationInternal, descriptionMatch: boolean | undefined, validate: boolean) => Promise<boolean>;
|
|
49
51
|
/** Only selected features. */
|
|
50
52
|
_getFeaturesWithCode: (code: string) => _CfgFeatureInternal[];
|
|
51
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Extends the list of loaded potentially used features. Will warn for but ignore duplicates.
|
|
55
|
+
* Returns true if a change happened.
|
|
56
|
+
*/
|
|
57
|
+
addRawFeatures: (rawFeatures: DtoFeature[], warnForDuplicates: boolean) => boolean;
|
|
58
|
+
private _hasRootFeaturesChanged;
|
|
59
|
+
/**
|
|
60
|
+
* True if what root Features are used is not the same as at initial load.
|
|
61
|
+
* This means that functional selection has happened.
|
|
62
|
+
*/
|
|
63
|
+
get hasRootFeaturesChanged(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Populates _features based on the passed @param rootFeatureRefs .
|
|
66
|
+
* @return true if a change happened.
|
|
67
|
+
*/
|
|
68
|
+
populateFeatures: (rootFeatureRefs: DtoFeatureRef[]) => boolean;
|
|
52
69
|
setStretchReferenceLength: (measureParamCode: string, referenceLength: number | undefined, unit: LengthUnit) => Promise<boolean>;
|
|
53
70
|
}
|
|
54
71
|
export declare class CfgProductConfiguration {
|
|
@@ -58,7 +75,7 @@ export declare class CfgProductConfiguration {
|
|
|
58
75
|
* CfgProductConfiguration, but is not properly initialized until the initDone-callback
|
|
59
76
|
* has been called.
|
|
60
77
|
*/
|
|
61
|
-
static make(initSuccess: (c: CfgProductConfiguration) => void, initFail: (error: Error) => void, rootFeatureRefs: DtoFeatureRef[],
|
|
78
|
+
static make(initSuccess: (c: CfgProductConfiguration) => void, initFail: (error: Error) => void, rootFeatureRefs: DtoFeatureRef[], rawFeatures: DtoFeature[], // Flat packed. All the features that can currently appear anyplace in the selection tree.
|
|
62
79
|
apiSelection: DtoSelectedOption[], parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal): CfgProductConfiguration;
|
|
63
80
|
/**
|
|
64
81
|
* Makes an object wrapping the passed object. This is not a clone method, it is a method to
|
|
@@ -78,11 +95,11 @@ export declare class CfgProductConfiguration {
|
|
|
78
95
|
get rootProduct(): CfgProduct;
|
|
79
96
|
get key(): string;
|
|
80
97
|
/**
|
|
81
|
-
* Every (unprocessed) feature
|
|
82
|
-
*
|
|
98
|
+
* Every (unprocessed) feature that is currently loaded for this product. This can be extended
|
|
99
|
+
* by validation calls. What features are actually used is controlled by rootFeatureRefs and what
|
|
83
100
|
* options are selected.
|
|
84
101
|
*/
|
|
85
|
-
get
|
|
102
|
+
get rawFeatures(): DtoFeature[];
|
|
86
103
|
/** What features are used in the root of this. This can change with new validate calls. */
|
|
87
104
|
get rootFeatureRefs(): DtoFeatureRef[];
|
|
88
105
|
/** The root features at the root of the selection tree. */
|
|
@@ -94,12 +111,6 @@ export declare class CfgProductConfiguration {
|
|
|
94
111
|
* This method will cause validation calls.
|
|
95
112
|
*/
|
|
96
113
|
tryMatchSelection: (other: CfgProductConfiguration, descriptionMatch?: boolean) => Promise<boolean>;
|
|
97
|
-
getApiSelection: () => DtoSelectedOption[];
|
|
98
|
-
/**
|
|
99
|
-
* This method does not propagate its selections.
|
|
100
|
-
* This method will not cause validation calls. Data is assumed to already be validated.
|
|
101
|
-
*/
|
|
102
|
-
setApiSelection: (selectedOptions: DtoSelectedOption[]) => Promise<boolean>;
|
|
103
114
|
/**
|
|
104
115
|
* Set how stretched a certain measure should be measureParamCode is the measure to be
|
|
105
116
|
* stretched referenceLength is a value relative to the initial length of the measure. If the
|