@configura/web-api 1.6.1 → 2.0.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/dist/CatalogueAPI.d.ts +200 -156
- package/dist/CatalogueAPI.js +23 -10
- package/dist/CfgMeasure.d.ts +3 -3
- package/dist/CfgProduct.d.ts +31 -21
- package/dist/CfgProduct.js +77 -46
- package/dist/CfgReferencePathHelper.d.ts +14 -0
- package/dist/CfgReferencePathHelper.js +13 -0
- package/dist/ConfigurationConverter.d.ts +5 -0
- package/dist/ConfigurationConverter.js +72 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/io/CfgHistoryManager.d.ts +51 -0
- package/dist/io/CfgHistoryManager.js +82 -0
- package/dist/io/CfgHistoryToProdConfConnector.d.ts +21 -0
- package/dist/io/CfgHistoryToProdConfConnector.js +56 -0
- package/dist/io/CfgIOManager.d.ts +49 -0
- package/dist/io/CfgIOManager.js +115 -0
- package/dist/io/CfgIOProdConfConnector.d.ts +53 -0
- package/dist/io/CfgIOProdConfConnector.js +141 -0
- package/dist/io/CfgObservableStateManager.d.ts +22 -0
- package/dist/io/CfgObservableStateManager.js +65 -0
- package/dist/io/CfgObservableStateToProdConfConnector.d.ts +15 -0
- package/dist/io/CfgObservableStateToProdConfConnector.js +16 -0
- package/dist/io/CfgWindowEventManager.d.ts +22 -0
- package/dist/io/CfgWindowEventManager.js +38 -0
- package/dist/io/CfgWindowMessageManager.d.ts +41 -0
- package/dist/io/CfgWindowMessageManager.js +84 -0
- package/dist/io/CfgWindowMessageToProdConfConnector.d.ts +17 -0
- package/dist/io/CfgWindowMessageToProdConfConnector.js +18 -0
- package/dist/io/index.d.ts +9 -0
- package/dist/io/index.js +8 -0
- package/dist/material/CfgMtrlApplication.d.ts +2 -2
- package/dist/productConfiguration/CfgFeature.d.ts +11 -12
- package/dist/productConfiguration/CfgFeature.js +37 -28
- package/dist/productConfiguration/CfgOption.d.ts +9 -8
- package/dist/productConfiguration/CfgOption.js +20 -30
- package/dist/productConfiguration/CfgProductConfiguration.d.ts +17 -20
- package/dist/productConfiguration/CfgProductConfiguration.js +14 -16
- package/dist/productConfiguration/filters.d.ts +4 -4
- package/dist/productConfiguration/productParamsGenerator.d.ts +4 -4
- package/dist/productConfiguration/productParamsGenerator.js +5 -5
- package/dist/productConfiguration/utilitiesProductConfiguration.d.ts +3 -3
- package/dist/productLoader.d.ts +3 -3
- package/dist/syncGroups/SyncGroupsHandler.js +3 -2
- package/dist/syncGroups/SyncGroupsTransaction.js +1 -1
- package/dist/tasks/TaskHandler.d.ts +7 -8
- package/dist/tasks/TaskHandler.js +4 -5
- package/dist/tasks/formats.d.ts +4 -4
- package/dist/tasks/formats.js +3 -3
- package/dist/tests/testData/dummyProductForTest.d.ts +2 -2
- package/dist/tests/testData/dummyProductForTest.js +3 -7
- package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.d.ts +2 -2
- package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.js +1 -1
- package/dist/tests/testData/testDataCachedGetProduct.d.ts +2 -2
- package/dist/tests/testData/testDataCachedGetProduct.js +1 -1
- package/dist/tests/testData/testDataCachedPostValidate.js +1 -1
- package/dist/tests/testData/testDataOptions.d.ts +4 -4
- package/dist/tests/testData/testDataProductAggregatedPrice.d.ts +3 -3
- package/dist/tests/testData/testDataProductAggregatedPrice.js +1 -1
- package/dist/tests/testData/testDataUpcharge.js +1 -1
- package/dist/utilitiesCatalogueData.d.ts +25 -23
- package/dist/utilitiesCatalogueData.js +10 -8
- package/dist/utilitiesCataloguePermission.d.ts +8 -13
- package/dist/utilitiesCataloguePermission.js +7 -11
- package/dist/utilitiesNumericValues.d.ts +3 -3
- package/package.json +3 -3
|
@@ -35,25 +35,25 @@ function getOptionFilter(option1) {
|
|
|
35
35
|
return (option2) => option2._internal === option1;
|
|
36
36
|
}
|
|
37
37
|
/** Returns a fresh reference for the option at the given index */
|
|
38
|
-
function doFreshRefOptionAtIndex(options, index, beforeNotify) {
|
|
38
|
+
function doFreshRefOptionAtIndex(options, index, committed, beforeNotify) {
|
|
39
39
|
const freshRef = CfgOption._makeNewRefFrom(options[index]._internal);
|
|
40
40
|
options[index] = freshRef;
|
|
41
41
|
if (beforeNotify) {
|
|
42
42
|
beforeNotify(freshRef);
|
|
43
43
|
}
|
|
44
|
-
freshRef._internal.changeObservable.notifyAll({ freshRef });
|
|
44
|
+
freshRef._internal.changeObservable.notifyAll({ freshRef, committed });
|
|
45
45
|
return freshRef;
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* Returns a fresh reference for the given option.
|
|
49
49
|
* @throws Throws an error if the option is not found in options.
|
|
50
50
|
*/
|
|
51
|
-
function doFreshRefOption(options, optionInternal, beforeNotify) {
|
|
51
|
+
function doFreshRefOption(options, optionInternal, committed, beforeNotify) {
|
|
52
52
|
const i = options.findIndex(getOptionFilter(optionInternal));
|
|
53
53
|
if (i === -1) {
|
|
54
54
|
throw new Error("Did not find the option in options");
|
|
55
55
|
}
|
|
56
|
-
return doFreshRefOptionAtIndex(options, i, beforeNotify);
|
|
56
|
+
return doFreshRefOptionAtIndex(options, i, committed, beforeNotify);
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
59
|
* This class is meant to only be used through CfgFeature. It should
|
|
@@ -83,17 +83,17 @@ export class _CfgFeatureInternal {
|
|
|
83
83
|
}
|
|
84
84
|
return yield option.setNumericValue(val, true);
|
|
85
85
|
});
|
|
86
|
-
this._notifyAllOfChange = (bubbleMode) => __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
this._notifyAllOfChange = (bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
|
|
87
87
|
if (bubbleMode === ProductConfigurationBubbleMode.Stop) {
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
|
-
const parent = this.parent;
|
|
91
90
|
const freshRef = CfgFeature._makeNewRefFrom(this);
|
|
92
|
-
this.changeObservable.notifyAll({ freshRef });
|
|
91
|
+
this.changeObservable.notifyAll({ freshRef, committed });
|
|
92
|
+
const parent = this.parent;
|
|
93
93
|
if (parent !== undefined) {
|
|
94
94
|
yield parent._childHasChanged(freshRef, bubbleMode === ProductConfigurationBubbleMode.OneLevel
|
|
95
95
|
? ProductConfigurationBubbleMode.Stop
|
|
96
|
-
: bubbleMode);
|
|
96
|
+
: bubbleMode, committed);
|
|
97
97
|
}
|
|
98
98
|
});
|
|
99
99
|
/**
|
|
@@ -101,23 +101,30 @@ export class _CfgFeatureInternal {
|
|
|
101
101
|
* @throws Will throw if options have not yet been generated. This should be impossible
|
|
102
102
|
* as nonexisting children can not call their parent.
|
|
103
103
|
*/
|
|
104
|
-
this._childHasChanged = (childOption, bubbleMode) => __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
this._childHasChanged = (childOption, bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
|
|
105
105
|
const options = this._options;
|
|
106
106
|
if (options === undefined) {
|
|
107
107
|
throw Error("Child says it changed, but no children has actually been generated");
|
|
108
108
|
}
|
|
109
|
-
const freshRef = doFreshRefOption(options, childOption);
|
|
109
|
+
const freshRef = doFreshRefOption(options, childOption, committed);
|
|
110
110
|
const selectedOptions = this._selectedOptions;
|
|
111
111
|
const i = selectedOptions.findIndex(getOptionFilter(childOption));
|
|
112
112
|
if (i !== -1) {
|
|
113
113
|
selectedOptions[i] = freshRef;
|
|
114
114
|
}
|
|
115
|
-
yield this._notifyAllOfChange(bubbleMode);
|
|
115
|
+
yield this._notifyAllOfChange(bubbleMode, committed);
|
|
116
116
|
});
|
|
117
|
-
this.
|
|
118
|
-
const result = {
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
this.getDtoConf = (includeExtendedData) => {
|
|
118
|
+
const result = {
|
|
119
|
+
code: this.code,
|
|
120
|
+
};
|
|
121
|
+
if (includeExtendedData) {
|
|
122
|
+
result.groupCode = this.groupCode;
|
|
123
|
+
result.unit = this.unit;
|
|
124
|
+
}
|
|
125
|
+
const selectedOptions = this._selectedOptions;
|
|
126
|
+
if (0 < selectedOptions.length) {
|
|
127
|
+
result.options = selectedOptions.map((o) => o._internal.getDtoConf(includeExtendedData));
|
|
121
128
|
}
|
|
122
129
|
return result;
|
|
123
130
|
};
|
|
@@ -126,6 +133,7 @@ export class _CfgFeatureInternal {
|
|
|
126
133
|
const isGroup = selectionType === SelectionType.Group;
|
|
127
134
|
const isSelectOne = selectionType === SelectionType.SelectOne;
|
|
128
135
|
const isAllOptionsAffectedByAnySelection = this.isAllOptionsAffectedByAnySelection;
|
|
136
|
+
const committed = true;
|
|
129
137
|
let options;
|
|
130
138
|
if (apiOptionSelectionMap === undefined) {
|
|
131
139
|
options = this._options || []; // Already generated children (all or none)
|
|
@@ -160,7 +168,7 @@ export class _CfgFeatureInternal {
|
|
|
160
168
|
this._selectedOptions.push(option);
|
|
161
169
|
}
|
|
162
170
|
else {
|
|
163
|
-
doFreshRefOptionAtIndex(options, i, (freshRef) => this._selectedOptions.push(freshRef));
|
|
171
|
+
doFreshRefOptionAtIndex(options, i, committed, (freshRef) => this._selectedOptions.push(freshRef));
|
|
164
172
|
}
|
|
165
173
|
change = true;
|
|
166
174
|
}
|
|
@@ -169,7 +177,7 @@ export class _CfgFeatureInternal {
|
|
|
169
177
|
if (selectedIndex !== -1) {
|
|
170
178
|
this._selectedOptions.splice(selectedIndex, 1);
|
|
171
179
|
if (!isAllOptionsAffectedByAnySelection) {
|
|
172
|
-
doFreshRefOptionAtIndex(options, i);
|
|
180
|
+
doFreshRefOptionAtIndex(options, i, committed);
|
|
173
181
|
}
|
|
174
182
|
change = true;
|
|
175
183
|
}
|
|
@@ -192,7 +200,7 @@ export class _CfgFeatureInternal {
|
|
|
192
200
|
}
|
|
193
201
|
if (change) {
|
|
194
202
|
if (isAllOptionsAffectedByAnySelection) {
|
|
195
|
-
this._freshRefAllOptions();
|
|
203
|
+
this._freshRefAllOptions(committed);
|
|
196
204
|
}
|
|
197
205
|
if (selectionType === SelectionType.SelectOne) {
|
|
198
206
|
yield this.pushStretch();
|
|
@@ -203,7 +211,7 @@ export class _CfgFeatureInternal {
|
|
|
203
211
|
// if multiple descendants are affected by the setApiSelection. Therefore
|
|
204
212
|
// we use OneLevel to make this feature notify and the parent update its
|
|
205
213
|
// reference.
|
|
206
|
-
yield this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel);
|
|
214
|
+
yield this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, committed);
|
|
207
215
|
}
|
|
208
216
|
return change;
|
|
209
217
|
});
|
|
@@ -285,7 +293,7 @@ export class _CfgFeatureInternal {
|
|
|
285
293
|
// if multiple descendants are affected by the tryMatchSelection. Therefore
|
|
286
294
|
// we use OneLevel to make this feature notify and the parent update its
|
|
287
295
|
// reference.
|
|
288
|
-
yield this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel);
|
|
296
|
+
yield this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, true);
|
|
289
297
|
}
|
|
290
298
|
return change;
|
|
291
299
|
});
|
|
@@ -315,6 +323,7 @@ export class _CfgFeatureInternal {
|
|
|
315
323
|
const isAllOptionsAffectedByAnySelection = this.isAllOptionsAffectedByAnySelection;
|
|
316
324
|
const index = selectedOptions.findIndex(getOptionFilter(optionInternal));
|
|
317
325
|
const isActualChange = (index === -1) === on;
|
|
326
|
+
const committed = true;
|
|
318
327
|
if (this.selectionType !== SelectionType.Group) {
|
|
319
328
|
if (on) {
|
|
320
329
|
// Calling this.options will populate (generate) all Options if they have not yet
|
|
@@ -324,7 +333,7 @@ export class _CfgFeatureInternal {
|
|
|
324
333
|
let removeOption = selectedOptions.shift();
|
|
325
334
|
while (removeOption !== undefined) {
|
|
326
335
|
if (!isAllOptionsAffectedByAnySelection) {
|
|
327
|
-
doFreshRefOption(options, removeOption._internal);
|
|
336
|
+
doFreshRefOption(options, removeOption._internal, committed);
|
|
328
337
|
}
|
|
329
338
|
removeOption = selectedOptions.shift();
|
|
330
339
|
}
|
|
@@ -333,7 +342,7 @@ export class _CfgFeatureInternal {
|
|
|
333
342
|
selectedOptions.push(CfgOption._makeNewRefFrom(optionInternal));
|
|
334
343
|
}
|
|
335
344
|
else {
|
|
336
|
-
doFreshRefOption(options, optionInternal, (freshRef) => selectedOptions.push(freshRef));
|
|
345
|
+
doFreshRefOption(options, optionInternal, committed, (freshRef) => selectedOptions.push(freshRef));
|
|
337
346
|
}
|
|
338
347
|
if (this.selectionType === SelectionType.SelectOne) {
|
|
339
348
|
yield this.pushStretch();
|
|
@@ -348,12 +357,12 @@ export class _CfgFeatureInternal {
|
|
|
348
357
|
// safely ignore if undefined.
|
|
349
358
|
const options = this._options;
|
|
350
359
|
if (options !== undefined) {
|
|
351
|
-
doFreshRefOption(options, optionInternal);
|
|
360
|
+
doFreshRefOption(options, optionInternal, committed);
|
|
352
361
|
}
|
|
353
362
|
}
|
|
354
363
|
}
|
|
355
364
|
if (isAllOptionsAffectedByAnySelection) {
|
|
356
|
-
this._freshRefAllOptions();
|
|
365
|
+
this._freshRefAllOptions(committed);
|
|
357
366
|
}
|
|
358
367
|
}
|
|
359
368
|
let nextLevelBubbleMode = bubbleMode;
|
|
@@ -367,7 +376,7 @@ export class _CfgFeatureInternal {
|
|
|
367
376
|
nextLevelBubbleMode = ProductConfigurationBubbleMode.ToRoot;
|
|
368
377
|
}
|
|
369
378
|
}
|
|
370
|
-
yield this._notifyAllOfChange(nextLevelBubbleMode);
|
|
379
|
+
yield this._notifyAllOfChange(nextLevelBubbleMode, committed);
|
|
371
380
|
return isActualChange;
|
|
372
381
|
});
|
|
373
382
|
this.isSelected = (option) => this.selectionType === SelectionType.Group ||
|
|
@@ -441,7 +450,7 @@ export class _CfgFeatureInternal {
|
|
|
441
450
|
return false;
|
|
442
451
|
}
|
|
443
452
|
/**
|
|
444
|
-
* The
|
|
453
|
+
* The DtoMeasureParam class is re-used for different purposes. In Features it is used
|
|
445
454
|
* to indicate which stretch measures inside Models shall be affected by this state
|
|
446
455
|
* of this Feature. Hence only the code property is used.
|
|
447
456
|
*/
|
|
@@ -512,14 +521,14 @@ export class _CfgFeatureInternal {
|
|
|
512
521
|
* Also includes currently selected options.
|
|
513
522
|
* @throws Will throw if options have not yet been generated.
|
|
514
523
|
*/
|
|
515
|
-
_freshRefAllOptions() {
|
|
524
|
+
_freshRefAllOptions(committed) {
|
|
516
525
|
const options = this._options;
|
|
517
526
|
const selectedOptions = this._selectedOptions;
|
|
518
527
|
if (options === undefined) {
|
|
519
528
|
throw new Error("We expect all options to be generated at freshref");
|
|
520
529
|
}
|
|
521
530
|
for (let i = 0; i < options.length; i++) {
|
|
522
|
-
doFreshRefOptionAtIndex(options, i, (freshRef) => {
|
|
531
|
+
doFreshRefOptionAtIndex(options, i, committed, (freshRef) => {
|
|
523
532
|
const selectedIndex = selectedOptions.findIndex(getOptionFilter(freshRef._internal));
|
|
524
533
|
if (selectedIndex !== -1) {
|
|
525
534
|
selectedOptions[selectedIndex] = freshRef;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
-
import {
|
|
2
|
+
import { DtoConfOption, DtoFeature, DtoOption, 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";
|
|
@@ -7,6 +7,7 @@ import { CfgFeature, _CfgFeatureInternal } from "./CfgFeature.js";
|
|
|
7
7
|
import { _CfgProductConfigurationInternal } from "./CfgProductConfiguration.js";
|
|
8
8
|
export declare type OptionChangeNotification = {
|
|
9
9
|
freshRef: CfgOption;
|
|
10
|
+
committed: boolean;
|
|
10
11
|
};
|
|
11
12
|
export declare enum ProductConfigurationBubbleMode {
|
|
12
13
|
/**
|
|
@@ -58,13 +59,13 @@ export declare enum ProductConfigurationBubbleMode {
|
|
|
58
59
|
* the class that should be used and interacted with.
|
|
59
60
|
*/
|
|
60
61
|
export declare class _CfgOptionInternal {
|
|
61
|
-
readonly rawOption:
|
|
62
|
+
readonly rawOption: DtoOption;
|
|
62
63
|
private readonly allRawFeatures;
|
|
63
64
|
readonly parent: _CfgFeatureInternal;
|
|
64
65
|
readonly parentConfiguration: _CfgProductConfigurationInternal;
|
|
65
66
|
readonly parentProduct: _CfgProductInternal;
|
|
66
67
|
readonly rootProduct: _CfgProductInternal;
|
|
67
|
-
constructor(rawOption:
|
|
68
|
+
constructor(rawOption: DtoOption, allRawFeatures: DtoFeature[], siblingHasDuplicateDescription: boolean, parent: _CfgFeatureInternal, parentConfiguration: _CfgProductConfigurationInternal, parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal);
|
|
68
69
|
private _features;
|
|
69
70
|
private _mtrlApplications;
|
|
70
71
|
readonly key: string;
|
|
@@ -87,9 +88,9 @@ export declare class _CfgOptionInternal {
|
|
|
87
88
|
get priceChangeAtSelectChange(): number | undefined;
|
|
88
89
|
get features(): CfgFeature[];
|
|
89
90
|
/** Called by child to tell its parent that it has changed. */
|
|
90
|
-
_childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode) => Promise<void>;
|
|
91
|
-
|
|
92
|
-
setApiSelection: (apiOptionSelection:
|
|
91
|
+
_childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise<void>;
|
|
92
|
+
getDtoConf: (includeExtendedData: boolean) => DtoConfOption;
|
|
93
|
+
setApiSelection: (apiOptionSelection: DtoSelectedOption | undefined) => Promise<boolean>;
|
|
93
94
|
structureCompare: (other: _CfgOptionInternal, strictOrder?: boolean, descriptionMatch?: boolean) => boolean;
|
|
94
95
|
tryMatchSelection: (other: CfgOption, descriptionMatch?: boolean) => Promise<boolean>;
|
|
95
96
|
keyMatch: (other: _CfgOptionInternal, descriptionMatch?: boolean) => boolean;
|
|
@@ -98,7 +99,7 @@ export declare class _CfgOptionInternal {
|
|
|
98
99
|
}
|
|
99
100
|
export declare class CfgOption {
|
|
100
101
|
readonly _internal: _CfgOptionInternal;
|
|
101
|
-
static make(rawOption:
|
|
102
|
+
static make(rawOption: DtoOption, allRawFeatures: DtoFeature[], siblingHasDuplicateDescription: boolean, parent: _CfgFeatureInternal, parentConfiguration: _CfgProductConfigurationInternal, parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal): CfgOption;
|
|
102
103
|
/**
|
|
103
104
|
* Makes an object wrapping the passed object. This is not a clone method,
|
|
104
105
|
* it is a method to make a new outer reference. Like a shallow copy.
|
|
@@ -114,7 +115,7 @@ export declare class CfgOption {
|
|
|
114
115
|
isBackedBySame: (other: CfgOption) => boolean;
|
|
115
116
|
get parentProduct(): CfgProduct;
|
|
116
117
|
get rootProduct(): CfgProduct;
|
|
117
|
-
get rawOption():
|
|
118
|
+
get rawOption(): DtoOption;
|
|
118
119
|
get key(): string;
|
|
119
120
|
get code(): string;
|
|
120
121
|
get isUseNumericValue(): boolean;
|
|
@@ -89,7 +89,7 @@ export class _CfgOptionInternal {
|
|
|
89
89
|
this.rootProduct = rootProduct;
|
|
90
90
|
this.changeObservable = new Observable();
|
|
91
91
|
/** Called by child to tell its parent that it has changed. */
|
|
92
|
-
this._childHasChanged = (freshRef, bubbleMode) => __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
this._childHasChanged = (freshRef, bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
|
|
93
93
|
const features = this._features;
|
|
94
94
|
if (features === undefined) {
|
|
95
95
|
throw Error("Child says it changed, but no children has actually been generated");
|
|
@@ -107,40 +107,30 @@ export class _CfgOptionInternal {
|
|
|
107
107
|
yield this.parent.selectOption(this, true, bubbleMode);
|
|
108
108
|
}
|
|
109
109
|
else {
|
|
110
|
-
yield this.parent._childHasChanged(this, bubbleMode);
|
|
110
|
+
yield this.parent._childHasChanged(this, bubbleMode, committed);
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
|
-
this.
|
|
114
|
-
const { features, isUseNumericValue, code, numericValue } = this;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
let anyItems = false;
|
|
118
|
-
for (const selectionTree of selectionTrees) {
|
|
119
|
-
if (selectionTree === undefined) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
for (const key of Object.keys(selectionTree)) {
|
|
123
|
-
if (mergedSelectionTree[key] !== undefined) {
|
|
124
|
-
console.warn(`The key (${key}) is already used in the selection tree. Option key: "${this.key}".`);
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
mergedSelectionTree[key] = selectionTree[key];
|
|
128
|
-
anyItems = true;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (isUseNumericValue && numericValue === undefined) {
|
|
132
|
-
throw new Error("numeric Sku feature with option without numeric value");
|
|
113
|
+
this.getDtoConf = (includeExtendedData) => {
|
|
114
|
+
const { features, isUseNumericValue, code, selected, numericValue } = this;
|
|
115
|
+
if (!selected) {
|
|
116
|
+
throw new Error("Currently only useable on selected options. Selected in the result is for future use.");
|
|
133
117
|
}
|
|
134
|
-
const
|
|
118
|
+
const result = {
|
|
135
119
|
code,
|
|
136
|
-
|
|
137
|
-
? { value: numericValue, unit: this.unit }
|
|
138
|
-
: undefined,
|
|
120
|
+
selected, // For future use
|
|
139
121
|
};
|
|
140
|
-
if (
|
|
141
|
-
|
|
122
|
+
if (isUseNumericValue) {
|
|
123
|
+
if (numericValue === undefined) {
|
|
124
|
+
throw new Error("numeric Sku feature with option without numeric value");
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
result.numericValue = { value: numericValue, unit: this.unit };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (0 < features.length) {
|
|
131
|
+
result.features = features.map((f) => f._internal.getDtoConf(includeExtendedData));
|
|
142
132
|
}
|
|
143
|
-
return
|
|
133
|
+
return result;
|
|
144
134
|
};
|
|
145
135
|
this.setApiSelection = (apiOptionSelection) => __awaiter(this, void 0, void 0, function* () {
|
|
146
136
|
let features;
|
|
@@ -241,7 +231,7 @@ export class _CfgOptionInternal {
|
|
|
241
231
|
}
|
|
242
232
|
else {
|
|
243
233
|
if (change) {
|
|
244
|
-
yield this.parent._childHasChanged(this, ProductConfigurationBubbleMode.
|
|
234
|
+
yield this.parent._childHasChanged(this, ProductConfigurationBubbleMode.Stop, false);
|
|
245
235
|
}
|
|
246
236
|
}
|
|
247
237
|
return change;
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
-
import {
|
|
1
|
+
import { LengthUnit, LengthValue, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
+
import { DtoConfFeature, DtoFeature, 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";
|
|
6
6
|
export declare type ProductConfigurationChangeNotification = {
|
|
7
7
|
freshRef: CfgProductConfiguration;
|
|
8
|
-
|
|
9
|
-
export declare type LengthValue = {
|
|
10
|
-
length: number;
|
|
11
|
-
unit: LengthUnit;
|
|
8
|
+
committed: boolean;
|
|
12
9
|
};
|
|
13
10
|
export declare type StretchMap = Map<string, {
|
|
14
11
|
def: LengthValue | undefined;
|
|
@@ -20,10 +17,10 @@ export declare type StretchMap = Map<string, {
|
|
|
20
17
|
* modified. CfgProductConfiguration is the class that should be used and interacted with.
|
|
21
18
|
*/
|
|
22
19
|
export declare class _CfgProductConfigurationInternal {
|
|
23
|
-
readonly allRawFeatures:
|
|
20
|
+
readonly allRawFeatures: DtoFeature[];
|
|
24
21
|
readonly parentProduct: _CfgProductInternal;
|
|
25
22
|
readonly rootProduct: _CfgProductInternal;
|
|
26
|
-
static _makeUninitialized(rootFeatureRefs:
|
|
23
|
+
static _makeUninitialized(rootFeatureRefs: DtoFeatureRef[], allRawFeatures: DtoFeature[], // Flat packed. All the features that can appear anyplace in the selection tree.
|
|
27
24
|
parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal): _CfgProductConfigurationInternal;
|
|
28
25
|
private constructor();
|
|
29
26
|
readonly key = "~";
|
|
@@ -31,18 +28,18 @@ export declare class _CfgProductConfigurationInternal {
|
|
|
31
28
|
private _features;
|
|
32
29
|
readonly stretchReferenceLengthsByMeasureParamCode: StretchMap;
|
|
33
30
|
readonly changeObservable: Observable<ProductConfigurationChangeNotification>;
|
|
34
|
-
get rootFeatureRefs():
|
|
31
|
+
get rootFeatureRefs(): DtoFeatureRef[];
|
|
35
32
|
get features(): CfgFeature[];
|
|
36
33
|
private _notifyAllOfChange;
|
|
37
34
|
_freshRefDescendants(): void;
|
|
38
35
|
/** Called by child to tell its parent that it has changed. */
|
|
39
|
-
_childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode) => Promise<void>;
|
|
40
|
-
|
|
36
|
+
_childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise<void>;
|
|
37
|
+
getDtoConf: (includeExtendedData: boolean) => DtoConfFeature[];
|
|
41
38
|
/**
|
|
42
39
|
* When used internally the notifications are taken care off by the caller, but if set from
|
|
43
40
|
* outside we want notifications to bubble all the way to the root.
|
|
44
41
|
*/
|
|
45
|
-
setApiSelection: (selectedOptions:
|
|
42
|
+
setApiSelection: (selectedOptions: DtoSelectedOption[], bubbleToRoot: boolean) => Promise<boolean>;
|
|
46
43
|
structureCompare: (other: _CfgProductConfigurationInternal, strictOrder: boolean, descriptionMatch: boolean) => boolean;
|
|
47
44
|
/**
|
|
48
45
|
* When used internally the notifications are taken care off by the caller, but if set from
|
|
@@ -51,8 +48,8 @@ export declare class _CfgProductConfigurationInternal {
|
|
|
51
48
|
tryMatchSelection: (other: _CfgProductConfigurationInternal, descriptionMatch: boolean | undefined, validate: boolean) => Promise<boolean>;
|
|
52
49
|
/** Only selected features. */
|
|
53
50
|
_getFeaturesWithCode: (code: string) => _CfgFeatureInternal[];
|
|
54
|
-
populateFeatures: (rootFeatureRefs:
|
|
55
|
-
setStretchReferenceLength: (measureParamCode: string, referenceLength: number | undefined, unit: LengthUnit
|
|
51
|
+
populateFeatures: (rootFeatureRefs: DtoFeatureRef[]) => void;
|
|
52
|
+
setStretchReferenceLength: (measureParamCode: string, referenceLength: number | undefined, unit: LengthUnit) => Promise<boolean>;
|
|
56
53
|
}
|
|
57
54
|
export declare class CfgProductConfiguration {
|
|
58
55
|
readonly _internal: _CfgProductConfigurationInternal;
|
|
@@ -61,8 +58,8 @@ export declare class CfgProductConfiguration {
|
|
|
61
58
|
* CfgProductConfiguration, but is not properly initialized until the initDone-callback
|
|
62
59
|
* has been called.
|
|
63
60
|
*/
|
|
64
|
-
static make(initSuccess: (c: CfgProductConfiguration) => void, initFail: (error: Error) => void, rootFeatureRefs:
|
|
65
|
-
apiSelection:
|
|
61
|
+
static make(initSuccess: (c: CfgProductConfiguration) => void, initFail: (error: Error) => void, rootFeatureRefs: DtoFeatureRef[], allRawFeatures: DtoFeature[], // Flat packed. All the features that can appear anyplace in the selection tree.
|
|
62
|
+
apiSelection: DtoSelectedOption[], parentProduct: _CfgProductInternal, rootProduct: _CfgProductInternal): CfgProductConfiguration;
|
|
66
63
|
/**
|
|
67
64
|
* Makes an object wrapping the passed object. This is not a clone method, it is a method to
|
|
68
65
|
* make a new outer reference. Like a shallow copy.
|
|
@@ -85,9 +82,9 @@ export declare class CfgProductConfiguration {
|
|
|
85
82
|
* product load. What features are actually used is controlled by rootFeatureRefs and what
|
|
86
83
|
* options are selected.
|
|
87
84
|
*/
|
|
88
|
-
get allRawFeatures():
|
|
85
|
+
get allRawFeatures(): DtoFeature[];
|
|
89
86
|
/** What features are used in the root of this. This can change with new validate calls. */
|
|
90
|
-
get rootFeatureRefs():
|
|
87
|
+
get rootFeatureRefs(): DtoFeatureRef[];
|
|
91
88
|
/** The root features at the root of the selection tree. */
|
|
92
89
|
get features(): CfgFeature[];
|
|
93
90
|
structureCompare: (other: CfgProductConfiguration, strictOrder?: boolean, descriptionMatch?: boolean) => boolean;
|
|
@@ -97,12 +94,12 @@ export declare class CfgProductConfiguration {
|
|
|
97
94
|
* This method will cause validation calls.
|
|
98
95
|
*/
|
|
99
96
|
tryMatchSelection: (other: CfgProductConfiguration, descriptionMatch?: boolean) => Promise<boolean>;
|
|
100
|
-
getApiSelection: () =>
|
|
97
|
+
getApiSelection: () => DtoSelectedOption[];
|
|
101
98
|
/**
|
|
102
99
|
* This method does not propagate its selections.
|
|
103
100
|
* This method will not cause validation calls. Data is assumed to already be validated.
|
|
104
101
|
*/
|
|
105
|
-
setApiSelection: (selectedOptions:
|
|
102
|
+
setApiSelection: (selectedOptions: DtoSelectedOption[]) => Promise<boolean>;
|
|
106
103
|
/**
|
|
107
104
|
* Set how stretched a certain measure should be measureParamCode is the measure to be
|
|
108
105
|
* stretched referenceLength is a value relative to the initial length of the measure. If the
|
|
@@ -7,8 +7,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { compareArrays, count, isLengthUnit, Observable, toError, toLengthUnit, } from "@configura/web-utilities";
|
|
10
|
+
import { compareArrays, count, isEqualLength, isLengthUnit, Observable, toError, toLengthUnit, } from "@configura/web-utilities";
|
|
11
11
|
import { CfgProduct } from "../CfgProduct.js";
|
|
12
|
+
import { convertDtoConfFeaturesToSelOptions } from "../ConfigurationConverter.js";
|
|
12
13
|
import { CfgFeature } from "./CfgFeature.js";
|
|
13
14
|
import { ProductConfigurationBubbleMode } from "./CfgOption.js";
|
|
14
15
|
import { syncCfgFeatures } from "./utilitiesProductConfiguration.js";
|
|
@@ -27,7 +28,7 @@ export class _CfgProductConfigurationInternal {
|
|
|
27
28
|
this._rootFeatureRefs = [];
|
|
28
29
|
this._features = [];
|
|
29
30
|
this.changeObservable = new Observable();
|
|
30
|
-
this._notifyAllOfChange = (bubbleMode) => __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
this._notifyAllOfChange = (bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
|
|
31
32
|
if (bubbleMode === ProductConfigurationBubbleMode.Stop) {
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
@@ -35,27 +36,26 @@ export class _CfgProductConfigurationInternal {
|
|
|
35
36
|
const parent = this.parentProduct;
|
|
36
37
|
this.changeObservable.notifyAll({
|
|
37
38
|
freshRef,
|
|
39
|
+
committed,
|
|
38
40
|
});
|
|
39
41
|
if (parent === undefined) {
|
|
40
42
|
return;
|
|
41
43
|
}
|
|
42
44
|
yield parent._configurationHasChanged(freshRef, bubbleMode === ProductConfigurationBubbleMode.OneLevel
|
|
43
45
|
? ProductConfigurationBubbleMode.Stop
|
|
44
|
-
: bubbleMode);
|
|
46
|
+
: bubbleMode, committed);
|
|
45
47
|
});
|
|
46
48
|
/** Called by child to tell its parent that it has changed. */
|
|
47
|
-
this._childHasChanged = (freshRef, bubbleMode) => __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
this._childHasChanged = (freshRef, bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
|
|
48
50
|
const features = this._features;
|
|
49
51
|
const i = features.findIndex((a) => a.isBackedBySame(freshRef));
|
|
50
52
|
if (i === -1) {
|
|
51
53
|
throw Error("Child feature not found");
|
|
52
54
|
}
|
|
53
55
|
features[i] = freshRef;
|
|
54
|
-
yield this._notifyAllOfChange(bubbleMode);
|
|
55
|
-
});
|
|
56
|
-
this.getApiSelection = () => this._features.map((f) => {
|
|
57
|
-
return { code: "!~!", next: f._internal.getApiSelection() };
|
|
56
|
+
yield this._notifyAllOfChange(bubbleMode, committed);
|
|
58
57
|
});
|
|
58
|
+
this.getDtoConf = (includeExtendedData) => this._features.map((f) => f._internal.getDtoConf(includeExtendedData));
|
|
59
59
|
/**
|
|
60
60
|
* When used internally the notifications are taken care off by the caller, but if set from
|
|
61
61
|
* outside we want notifications to bubble all the way to the root.
|
|
@@ -70,7 +70,7 @@ export class _CfgProductConfigurationInternal {
|
|
|
70
70
|
if (change) {
|
|
71
71
|
yield this._notifyAllOfChange(bubbleToRoot
|
|
72
72
|
? ProductConfigurationBubbleMode.ToRoot
|
|
73
|
-
: ProductConfigurationBubbleMode.OneLevel);
|
|
73
|
+
: ProductConfigurationBubbleMode.OneLevel, true);
|
|
74
74
|
}
|
|
75
75
|
return change;
|
|
76
76
|
});
|
|
@@ -102,7 +102,7 @@ export class _CfgProductConfigurationInternal {
|
|
|
102
102
|
if (change) {
|
|
103
103
|
yield this._notifyAllOfChange(validate
|
|
104
104
|
? ProductConfigurationBubbleMode.Validate
|
|
105
|
-
: ProductConfigurationBubbleMode.OneLevel);
|
|
105
|
+
: ProductConfigurationBubbleMode.OneLevel, true);
|
|
106
106
|
}
|
|
107
107
|
return change;
|
|
108
108
|
});
|
|
@@ -115,7 +115,7 @@ export class _CfgProductConfigurationInternal {
|
|
|
115
115
|
this._rootFeatureRefs = rootFeatureRefs;
|
|
116
116
|
this._features = syncCfgFeatures(rootFeatureRefs, this._features, this.allRawFeatures, this, this, this.parentProduct, this.rootProduct);
|
|
117
117
|
};
|
|
118
|
-
this.setStretchReferenceLength = (measureParamCode, referenceLength, unit
|
|
118
|
+
this.setStretchReferenceLength = (measureParamCode, referenceLength, unit) => __awaiter(this, void 0, void 0, function* () {
|
|
119
119
|
if (measureParamCode === "") {
|
|
120
120
|
return false;
|
|
121
121
|
}
|
|
@@ -141,14 +141,12 @@ export class _CfgProductConfigurationInternal {
|
|
|
141
141
|
});
|
|
142
142
|
}
|
|
143
143
|
else {
|
|
144
|
-
if (stretchReferenceLength.current
|
|
144
|
+
if (isEqualLength(stretchReferenceLength.current, referenceLengthWithUnit)) {
|
|
145
145
|
return false;
|
|
146
146
|
}
|
|
147
147
|
stretchReferenceLength.current = referenceLengthWithUnit;
|
|
148
148
|
}
|
|
149
|
-
|
|
150
|
-
yield this._notifyAllOfChange(ProductConfigurationBubbleMode.ToRoot);
|
|
151
|
-
}
|
|
149
|
+
yield this._notifyAllOfChange(ProductConfigurationBubbleMode.ToRoot, false);
|
|
152
150
|
return true;
|
|
153
151
|
});
|
|
154
152
|
/* eslint-disable */
|
|
@@ -235,7 +233,7 @@ export class CfgProductConfiguration {
|
|
|
235
233
|
*/
|
|
236
234
|
this.tryMatchSelection = (other, descriptionMatch = false // Match on case insensitive description, not code
|
|
237
235
|
) => __awaiter(this, void 0, void 0, function* () { return yield this._internal.tryMatchSelection(other._internal, descriptionMatch, true); });
|
|
238
|
-
this.getApiSelection = () => this._internal.
|
|
236
|
+
this.getApiSelection = () => convertDtoConfFeaturesToSelOptions(this._internal.getDtoConf(false), true);
|
|
239
237
|
/**
|
|
240
238
|
* This method does not propagate its selections.
|
|
241
239
|
* This method will not cause validation calls. Data is assumed to already be validated.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Filters, Matches } from "@configura/web-utilities";
|
|
2
|
-
import {
|
|
3
|
-
export declare function applyCatalogueFilters(filters: Filters<
|
|
2
|
+
import { DtoCatalogueParamsWithoutCid, DtoLevel, DtoProductRef } from "../CatalogueAPI.js";
|
|
3
|
+
export declare function applyCatalogueFilters<T extends DtoCatalogueParamsWithoutCid>(filters: Filters<DtoCatalogueParamsWithoutCid>, catalogues: T[]): [Matches<DtoCatalogueParamsWithoutCid>, T[]];
|
|
4
4
|
export interface ProductRefParams {
|
|
5
5
|
partNr: string;
|
|
6
6
|
}
|
|
7
|
-
export declare function applyProductRefFilters(filters: Filters<ProductRefParams>, productRefs:
|
|
7
|
+
export declare function applyProductRefFilters(filters: Filters<ProductRefParams>, productRefs: DtoProductRef[]): [Matches<ProductRefParams>, DtoProductRef[]];
|
|
8
8
|
/**
|
|
9
9
|
* Clones the table of content levels tree.
|
|
10
10
|
* Filters to only include passed products.
|
|
@@ -12,5 +12,5 @@ export declare function applyProductRefFilters(filters: Filters<ProductRefParams
|
|
|
12
12
|
* @param prdRefsFilter Products not in this array are removed
|
|
13
13
|
* @param showEmpty Shall empty levels be shown?
|
|
14
14
|
*/
|
|
15
|
-
export declare function cloneFilterSortLevels(levels:
|
|
15
|
+
export declare function cloneFilterSortLevels(levels: DtoLevel[], prdRefsFilter: DtoProductRef[], showEmpty: boolean, doSort?: boolean): DtoLevel[] | undefined;
|
|
16
16
|
//# sourceMappingURL=filters.d.ts.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { Filters } from "@configura/web-utilities";
|
|
2
|
-
import {
|
|
2
|
+
import { CatalogueAPI, DtoApplicationAreasResponse, DtoCatalogueParams, DtoCatalogueParamsWithLang } from "../CatalogueAPI.js";
|
|
3
3
|
import { CfgProduct, CfgProductSettings } from "../CfgProduct.js";
|
|
4
4
|
import { ProductRefParams } from "./filters.js";
|
|
5
5
|
export interface GeneratedProductConfiguration {
|
|
6
|
-
applicationAreasResponse:
|
|
6
|
+
applicationAreasResponse: DtoApplicationAreasResponse;
|
|
7
7
|
catalogueCount: number;
|
|
8
8
|
catalogueIndex: number;
|
|
9
|
-
catalogueParams:
|
|
9
|
+
catalogueParams: DtoCatalogueParamsWithLang;
|
|
10
10
|
getProductDuration: number;
|
|
11
11
|
product: CfgProduct;
|
|
12
12
|
productCount: number;
|
|
13
13
|
productIndex: number;
|
|
14
14
|
}
|
|
15
|
-
export declare function generateProductConfigurations(api: CatalogueAPI, lang: string, catalogues:
|
|
15
|
+
export declare function generateProductConfigurations(api: CatalogueAPI, lang: string, catalogues: DtoCatalogueParams[], filters: Filters<ProductRefParams>, settings?: Partial<CfgProductSettings>): AsyncIterableIterator<GeneratedProductConfiguration | Error>;
|
|
16
16
|
//# sourceMappingURL=productParamsGenerator.d.ts.map
|
|
@@ -17,19 +17,19 @@ export function generateProductConfigurations(api, lang, catalogues, filters, se
|
|
|
17
17
|
return __asyncGenerator(this, arguments, function* generateProductConfigurations_1() {
|
|
18
18
|
const catalogueCount = catalogues.length;
|
|
19
19
|
const catalogueEntries = catalogues.entries();
|
|
20
|
-
for (const [catalogueIndex,
|
|
21
|
-
const
|
|
20
|
+
for (const [catalogueIndex, catalogueParamsWithoutLang] of catalogueEntries) {
|
|
21
|
+
const catalogueParams = Object.assign(Object.assign({}, catalogueParamsWithoutLang), { lang });
|
|
22
22
|
try {
|
|
23
23
|
const [applicationAreasResponse, toc] = yield __await(Promise.all([
|
|
24
|
-
api.getApplicationAreas(
|
|
25
|
-
api.getTocFlat(
|
|
24
|
+
api.getApplicationAreas(catalogueParams),
|
|
25
|
+
api.getTocFlat(catalogueParams),
|
|
26
26
|
]));
|
|
27
27
|
const [, productRefs] = applyProductRefFilters(filters, (toc === null || toc === void 0 ? void 0 : toc.prdRefs) || []);
|
|
28
28
|
const productCount = productRefs.length;
|
|
29
29
|
const productEntries = productRefs.entries();
|
|
30
30
|
for (const [productIndex, prdRef] of productEntries) {
|
|
31
31
|
const startTime = performance.now();
|
|
32
|
-
const product = yield __await(CfgProduct.make(api,
|
|
32
|
+
const product = yield __await(CfgProduct.make(api, Object.assign(Object.assign({}, catalogueParams), { partNumber: prdRef.partNr }), settings));
|
|
33
33
|
const getProductDuration = performance.now() - startTime;
|
|
34
34
|
yield yield __await({
|
|
35
35
|
applicationAreasResponse,
|