@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
package/dist/CatalogueAPI.d.ts
CHANGED
|
@@ -80,8 +80,9 @@ export interface ErrorResponse {
|
|
|
80
80
|
code: number;
|
|
81
81
|
eventId?: string;
|
|
82
82
|
}
|
|
83
|
-
/** ExportFormat -
|
|
84
|
-
export declare type ExportFormat = "fbx" | "dwg" | "cmdrw" | "cmfav" | "cmsym";
|
|
83
|
+
/** ExportFormat - Format of the exported product, identical to the format's file extension. */
|
|
84
|
+
export declare type ExportFormat = "glb" | "gltf" | "fbx" | "dwg" | "cmdrw" | "cmfav" | "cmsym";
|
|
85
|
+
export declare const exportFormatNames: ExportFormat[];
|
|
85
86
|
/** ExportRequest */
|
|
86
87
|
export interface ExportRequest {
|
|
87
88
|
format: ExportFormat;
|
|
@@ -102,6 +103,7 @@ export interface ExportStatus {
|
|
|
102
103
|
}
|
|
103
104
|
/** ExportStatusStatus - WIP */
|
|
104
105
|
export declare type ExportStatusStatus = "pending" | "running" | "finished" | "failed";
|
|
106
|
+
export declare const exportStatusStatusNames: ExportStatusStatus[];
|
|
105
107
|
/** Feature */
|
|
106
108
|
export interface Feature {
|
|
107
109
|
code: string;
|
|
@@ -338,6 +340,8 @@ export interface ProductData {
|
|
|
338
340
|
depth?: string;
|
|
339
341
|
description?: string;
|
|
340
342
|
height?: string;
|
|
343
|
+
hideIfMainProduct?: boolean;
|
|
344
|
+
hideIfAdditionalProduct?: boolean;
|
|
341
345
|
length?: string;
|
|
342
346
|
mtrlApplications?: Array<MtrlApplication>;
|
|
343
347
|
additionalProductRefs?: Array<AdditionalProductRef>;
|
|
@@ -379,6 +383,7 @@ export interface RefreshSessionTokenResponse {
|
|
|
379
383
|
}
|
|
380
384
|
/** RenderFormat */
|
|
381
385
|
export declare type RenderFormat = "jpg" | "png";
|
|
386
|
+
export declare const renderFormatNames: RenderFormat[];
|
|
382
387
|
/** RenderRequest */
|
|
383
388
|
export interface RenderRequest {
|
|
384
389
|
width: number;
|
|
@@ -402,6 +407,7 @@ export interface RenderStatus {
|
|
|
402
407
|
}
|
|
403
408
|
/** RenderStatusStatus - WIP */
|
|
404
409
|
export declare type RenderStatusStatus = "pending" | "running" | "finished" | "failed";
|
|
410
|
+
export declare const renderStatusStatusNames: RenderStatusStatus[];
|
|
405
411
|
/** SelectedOption */
|
|
406
412
|
export interface SelectedOption {
|
|
407
413
|
code: string;
|
|
@@ -422,6 +428,7 @@ export interface SyncGroup {
|
|
|
422
428
|
}
|
|
423
429
|
/** SyncGroupMethods */
|
|
424
430
|
export declare type SyncGroupMethods = "pull" | "push" | "twoWay";
|
|
431
|
+
export declare const syncGroupMethodsNames: SyncGroupMethods[];
|
|
425
432
|
/** TargetCameraArgs */
|
|
426
433
|
export interface TargetCameraArgs {
|
|
427
434
|
location?: Point;
|
package/dist/CatalogueAPI.js
CHANGED
|
@@ -9,6 +9,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
10
|
});
|
|
11
11
|
};
|
|
12
|
+
export const exportFormatNames = [
|
|
13
|
+
"glb",
|
|
14
|
+
"gltf",
|
|
15
|
+
"fbx",
|
|
16
|
+
"dwg",
|
|
17
|
+
"cmdrw",
|
|
18
|
+
"cmfav",
|
|
19
|
+
"cmsym",
|
|
20
|
+
];
|
|
21
|
+
export const exportStatusStatusNames = [
|
|
22
|
+
"pending",
|
|
23
|
+
"running",
|
|
24
|
+
"finished",
|
|
25
|
+
"failed",
|
|
26
|
+
];
|
|
27
|
+
export const renderFormatNames = ["jpg", "png"];
|
|
28
|
+
export const renderStatusStatusNames = [
|
|
29
|
+
"pending",
|
|
30
|
+
"running",
|
|
31
|
+
"finished",
|
|
32
|
+
"failed",
|
|
33
|
+
];
|
|
34
|
+
export const syncGroupMethodsNames = ["pull", "push", "twoWay"];
|
|
12
35
|
export class APIError extends Error {
|
|
13
36
|
}
|
|
14
37
|
export class CatalogueAPI {
|
package/dist/CfgMeasure.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Measurement, ValueWithUnit } from "./CatalogueAPI";
|
|
1
|
+
import { Measurement, ValueWithUnit } from "./CatalogueAPI.js";
|
|
2
2
|
/**
|
|
3
3
|
* Measures can be used to Anchor items (Models or Additional Products).
|
|
4
4
|
*
|
|
@@ -19,7 +19,7 @@ export declare type CfgMeasurePriority = {
|
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
21
21
|
* This class strips the Measurement of things that are not actually used or relevant
|
|
22
|
-
* to Stage, specifically anchoring and stretching.
|
|
22
|
+
* to Stage, specifically anchoring and stretching. Measurements can also contain
|
|
23
23
|
* volume and area, but these are ignored. Here Measures are used to define defaults
|
|
24
24
|
* such as its preferences when dealing with ambiguity or its default value.
|
|
25
25
|
*/
|
package/dist/CfgMeasure.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This class strips the Measurement of things that are not actually used or relevant
|
|
3
|
-
* to Stage, specifically anchoring and stretching.
|
|
3
|
+
* to Stage, specifically anchoring and stretching. Measurements can also contain
|
|
4
4
|
* volume and area, but these are ignored. Here Measures are used to define defaults
|
|
5
5
|
* such as its preferences when dealing with ambiguity or its default value.
|
|
6
6
|
*/
|
package/dist/CfgProduct.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ import { AggregatedLoadingObservable, LengthUnit, Observable, SingleArgCallback
|
|
|
2
2
|
import { AdditionalProductConfiguration, CatalogueParams, MeasureParam, MtrlApplication, Prices, Transform } from "./CatalogueAPI.js";
|
|
3
3
|
import { CfgMeasureDefinition } from "./CfgMeasure.js";
|
|
4
4
|
import { _CfgFeatureInternal } from "./productConfiguration/CfgFeature.js";
|
|
5
|
-
import { ProductConfigurationBubbleMode } from "./productConfiguration/CfgOption.js";
|
|
6
|
-
import { CfgProductConfiguration } from "./productConfiguration/CfgProductConfiguration.js";
|
|
5
|
+
import { ProductConfigurationBubbleMode, _CfgOptionInternal } from "./productConfiguration/CfgOption.js";
|
|
6
|
+
import { CfgProductConfiguration, _CfgProductConfigurationInternal } from "./productConfiguration/CfgProductConfiguration.js";
|
|
7
7
|
import { ProductLoader } from "./productLoader.js";
|
|
8
|
+
import { SyncGroupsApplyMode } from "./syncGroups/SyncGroupsApplyMode.js";
|
|
9
|
+
import { SyncGroupsHandler } from "./syncGroups/SyncGroupsHandler.js";
|
|
8
10
|
import { CfgProductData, RootNodeSource } from "./utilitiesCatalogueData.js";
|
|
9
11
|
export declare type CfgProductChangeNotification = {
|
|
10
12
|
freshRef: CfgProduct;
|
|
@@ -24,6 +26,12 @@ export declare type CfgProductSettings = {
|
|
|
24
26
|
* believe is a rare use case.
|
|
25
27
|
*/
|
|
26
28
|
strictSetApiSelectionMatch: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Controls if SyncGroups are applied Fast or Strict. Fast keeps the number of validate calls
|
|
31
|
+
* to the server down, Strict is closer to how CET works. We recommend you use Fast as cases
|
|
32
|
+
* where the results differ should be rare in real use cases.
|
|
33
|
+
*/
|
|
34
|
+
syncGroupsApplyMode: SyncGroupsApplyMode | undefined;
|
|
27
35
|
};
|
|
28
36
|
/**
|
|
29
37
|
* This enum is used internally in the SDK and is not expected by be used directly by integrators.
|
|
@@ -48,6 +56,12 @@ export declare type CfgPrice = {
|
|
|
48
56
|
currency: string;
|
|
49
57
|
fractionDigits: number;
|
|
50
58
|
};
|
|
59
|
+
export declare type CfgPathSegment = string;
|
|
60
|
+
export declare type CfgPath = CfgPathSegment[];
|
|
61
|
+
export declare type RevalidateResult = {
|
|
62
|
+
wasAborted: boolean;
|
|
63
|
+
requestDidValidate: boolean;
|
|
64
|
+
};
|
|
51
65
|
/**
|
|
52
66
|
* This class is meant to only be used through CfgProduct. It should never be instantiated on its
|
|
53
67
|
* own. Normally the internal state of this class should never be directly modified. CfgProduct is
|
|
@@ -68,6 +82,7 @@ export declare class _CfgProductInternal {
|
|
|
68
82
|
readonly parent: _CfgProductInternal | undefined;
|
|
69
83
|
readonly transform: Transform | undefined;
|
|
70
84
|
anchor: MeasureParam | undefined;
|
|
85
|
+
private readonly _syncGroupHandler;
|
|
71
86
|
static make: (productLoaderRaw: ProductLoader, productLoaderForGroupedLoad: ProductLoader | undefined, lang: string, catId: CatalogueParams, partNumber: string, settings: CfgProductSettings, optional: boolean, loadingObservable: AggregatedLoadingObservable, refKey: string | undefined, refDescription: string | undefined, parent: _CfgProductInternal | undefined, root: _CfgProductInternal | undefined, transform: Transform | undefined, anchor: MeasureParam | undefined) => Promise<_CfgProductInternal>;
|
|
72
87
|
private constructor();
|
|
73
88
|
readonly root: _CfgProductInternal;
|
|
@@ -97,6 +112,21 @@ export declare class _CfgProductInternal {
|
|
|
97
112
|
setSelected(v: boolean, bubbleMode: CfgProductBubbleMode): Promise<boolean>;
|
|
98
113
|
get configuration(): CfgProductConfiguration;
|
|
99
114
|
get rawProductData(): CfgProductData;
|
|
115
|
+
/**
|
|
116
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
117
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
118
|
+
*/
|
|
119
|
+
get visibleIfAdditionalProduct(): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
122
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
123
|
+
*/
|
|
124
|
+
get visibleIfMainProduct(): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
127
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
128
|
+
*/
|
|
129
|
+
get visible(): boolean;
|
|
100
130
|
_notifyAllOfChange: (bubbleMode: CfgProductBubbleMode) => Promise<void>;
|
|
101
131
|
/** Called when a child (additional product or the configuration) has changed. */
|
|
102
132
|
private _childHasChanged;
|
|
@@ -106,6 +136,15 @@ export declare class _CfgProductInternal {
|
|
|
106
136
|
_configurationHasChanged: (freshRef: CfgProductConfiguration, bubbleMode: ProductConfigurationBubbleMode) => Promise<void>;
|
|
107
137
|
getApiSelection: () => AdditionalProductConfiguration;
|
|
108
138
|
setApiSelection: (s: AdditionalProductConfiguration, doValidate: boolean, productLoaderForGroupedLoad?: ProductLoader | undefined) => Promise<boolean>;
|
|
139
|
+
copyFrom: (otherProduct: _CfgProductInternal, doValidate: boolean, productLoaderForGroupedLoad?: ProductLoader | undefined) => Promise<boolean>;
|
|
140
|
+
private _setApiSelectionWithOtherProduct;
|
|
141
|
+
get syncGroupHandler(): SyncGroupsHandler | undefined;
|
|
142
|
+
get path(): CfgPath;
|
|
143
|
+
getFromPath(path: CfgPath): _CfgProductInternal | _CfgProductConfigurationInternal | _CfgFeatureInternal | _CfgOptionInternal;
|
|
144
|
+
getProductFromPath(path: CfgPath): _CfgProductInternal;
|
|
145
|
+
getProductConfigurationFromPath(path: CfgPath): _CfgProductConfigurationInternal;
|
|
146
|
+
getFeatureFromPath(path: CfgPath): _CfgFeatureInternal;
|
|
147
|
+
getOptionFromPath(path: CfgPath): _CfgOptionInternal;
|
|
109
148
|
structureCompare: (other: _CfgProductInternal, strictOrder?: boolean, descriptionMatch?: boolean) => boolean;
|
|
110
149
|
tryMatchSelection: (other: _CfgProductInternal, descriptionMatch?: boolean, productLoaderForGroupedLoad?: ProductLoader | undefined) => Promise<boolean>;
|
|
111
150
|
/** Only features in selected options and selected additional products. */
|
|
@@ -116,7 +155,7 @@ export declare class _CfgProductInternal {
|
|
|
116
155
|
* product in isolation. The validation result is applied on the configuration. Then additional
|
|
117
156
|
* products are synced (unloaded, loaded etc.) Finally the changes bubble up the tree.
|
|
118
157
|
*/
|
|
119
|
-
_revalidate: (bubbleMode: CfgProductBubbleMode, productLoader: ProductLoader) => Promise<
|
|
158
|
+
_revalidate: (bubbleMode: CfgProductBubbleMode, productLoader: ProductLoader) => Promise<RevalidateResult>;
|
|
120
159
|
/**
|
|
121
160
|
* Based on this configuration find what additional products should be shown and not, unload
|
|
122
161
|
* (i.e. destroy) those that should no longer be shown, load the new ones.
|
|
@@ -128,7 +167,7 @@ export declare class CfgProduct {
|
|
|
128
167
|
static make(productLoader: ProductLoader, lang: string, catId: CatalogueParams, partNumber: string, settings?: Partial<CfgProductSettings>): Promise<CfgProduct>;
|
|
129
168
|
/**
|
|
130
169
|
* Makes an object wrapping the passed object. This is not a clone method, it is a method to
|
|
131
|
-
* make a new outer reference. Like a shallow copy
|
|
170
|
+
* make a new outer reference. Like a shallow copy. We use this to help frameworks that are
|
|
132
171
|
* build around using equals to detect change.
|
|
133
172
|
*/
|
|
134
173
|
static _makeNewRefFrom(source: _CfgProductInternal): CfgProduct;
|
|
@@ -163,6 +202,13 @@ export declare class CfgProduct {
|
|
|
163
202
|
* always true.
|
|
164
203
|
*/
|
|
165
204
|
get selected(): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
207
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
208
|
+
* Visibility is affects the Configuration for this Product, but any Additional Products
|
|
209
|
+
* will not be affected.
|
|
210
|
+
*/
|
|
211
|
+
get visible(): boolean;
|
|
166
212
|
/**
|
|
167
213
|
* Only applicable when this product is optional.
|
|
168
214
|
* Setting this does not cause a validation call as toggling an optional additional product is
|
package/dist/CfgProduct.js
CHANGED
|
@@ -9,16 +9,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { AggregatedLoadingObservable, compareArrays, count, Observable, toLengthUnit, } from "@configura/web-utilities";
|
|
11
11
|
import { CfgMeasureDefinition } from "./CfgMeasure.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { _CfgFeatureInternal } from "./productConfiguration/CfgFeature.js";
|
|
13
|
+
import { ProductConfigurationBubbleMode, _CfgOptionInternal, } from "./productConfiguration/CfgOption.js";
|
|
14
|
+
import { CfgProductConfiguration, _CfgProductConfigurationInternal, } from "./productConfiguration/CfgProductConfiguration.js";
|
|
14
15
|
import { collectAdditionalProductRefs } from "./productConfiguration/utilitiesProductConfiguration.js";
|
|
15
16
|
import { wrapWithCache } from "./productLoader.js";
|
|
16
|
-
import {
|
|
17
|
+
import { SyncGroupsHandler } from "./syncGroups/SyncGroupsHandler.js";
|
|
18
|
+
import { comparePricesObjects, correctDefaultsOnCatalogueParams, isSameProductRef, makeProductKey, } from "./utilitiesCatalogueData.js";
|
|
17
19
|
function completeSettings(incompleteSettings) {
|
|
18
20
|
var _a, _b;
|
|
19
21
|
return {
|
|
20
22
|
strictSelectOneSelectionCount: (_a = incompleteSettings === null || incompleteSettings === void 0 ? void 0 : incompleteSettings.strictSelectOneSelectionCount) !== null && _a !== void 0 ? _a : false,
|
|
21
23
|
strictSetApiSelectionMatch: (_b = incompleteSettings === null || incompleteSettings === void 0 ? void 0 : incompleteSettings.strictSetApiSelectionMatch) !== null && _b !== void 0 ? _b : false,
|
|
24
|
+
syncGroupsApplyMode: incompleteSettings === null || incompleteSettings === void 0 ? void 0 : incompleteSettings.syncGroupsApplyMode,
|
|
22
25
|
};
|
|
23
26
|
}
|
|
24
27
|
/**
|
|
@@ -50,7 +53,7 @@ function isDescriptionMatch(l, r) {
|
|
|
50
53
|
* the class that should be used and interacted with.
|
|
51
54
|
*/
|
|
52
55
|
export class _CfgProductInternal {
|
|
53
|
-
constructor(initSuccess, initFail, _productLoaderRaw, lang, catId, partNumber, settings, optional, selected, rootFeatureRefs, allRawFeatures, uuid, _rawUnit, _rawProductData, apiSelection, loadingObservable, refKey, refDescription, parent, root, transform, anchor) {
|
|
56
|
+
constructor(initSuccess, initFail, _productLoaderRaw, lang, catId, partNumber, settings, optional, selected, rootFeatureRefs, allRawFeatures, uuid, _rawUnit, _rawProductData, apiSelection, loadingObservable, refKey, refDescription, parent, root, transform, anchor, _syncGroupHandler) {
|
|
54
57
|
this._productLoaderRaw = _productLoaderRaw;
|
|
55
58
|
this.lang = lang;
|
|
56
59
|
this.catId = catId;
|
|
@@ -65,6 +68,7 @@ export class _CfgProductInternal {
|
|
|
65
68
|
this.parent = parent;
|
|
66
69
|
this.transform = transform;
|
|
67
70
|
this.anchor = anchor;
|
|
71
|
+
this._syncGroupHandler = _syncGroupHandler;
|
|
68
72
|
this._destroyed = false;
|
|
69
73
|
this.additionalProducts = [];
|
|
70
74
|
this.changeObservable = new Observable();
|
|
@@ -120,6 +124,9 @@ export class _CfgProductInternal {
|
|
|
120
124
|
// The revalidate call will continue the bubble
|
|
121
125
|
yield this._revalidate(CfgProductBubbleMode.ToRootAndBubbleSelected, this._productLoaderRaw);
|
|
122
126
|
return;
|
|
127
|
+
case ProductConfigurationBubbleMode.BubbleSelected:
|
|
128
|
+
yield this._childHasChanged(CfgProductBubbleMode.ToRootAndBubbleSelected);
|
|
129
|
+
return;
|
|
123
130
|
case ProductConfigurationBubbleMode.Validate:
|
|
124
131
|
// The revalidate call will continue the bubble
|
|
125
132
|
yield this._revalidate(CfgProductBubbleMode.ToRoot, this._productLoaderRaw);
|
|
@@ -145,13 +152,26 @@ export class _CfgProductInternal {
|
|
|
145
152
|
additionalProducts: this.additionalProducts.map((additionalProduct) => additionalProduct.getApiSelection()),
|
|
146
153
|
});
|
|
147
154
|
this.setApiSelection = (s, doValidate, productLoaderForGroupedLoad) => __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
return this._setApiSelectionWithOtherProduct(s, doValidate, productLoaderForGroupedLoad, undefined);
|
|
156
|
+
});
|
|
157
|
+
this.copyFrom = (otherProduct, doValidate, productLoaderForGroupedLoad) => __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
return yield this._setApiSelectionWithOtherProduct(otherProduct.getApiSelection(), doValidate, productLoaderForGroupedLoad, otherProduct);
|
|
159
|
+
});
|
|
160
|
+
this._setApiSelectionWithOtherProduct = (s, doValidate, productLoaderForGroupedLoad, sourceProduct) => __awaiter(this, void 0, void 0, function* () {
|
|
148
161
|
// Wrap with cache will make getProduct for this function call use the same server call
|
|
149
162
|
// for the same product with the same params. Used for getProduct (when a new additional
|
|
150
163
|
// product is loaded) and postValidate.
|
|
151
164
|
productLoaderForGroupedLoad =
|
|
152
165
|
productLoaderForGroupedLoad || wrapWithCache(this._productLoaderRaw);
|
|
166
|
+
let change = false;
|
|
167
|
+
if (sourceProduct !== undefined) {
|
|
168
|
+
this._rawProductData = sourceProduct.rawProductData;
|
|
169
|
+
change = true; // We can not know if this is an actual change, so we assume it is
|
|
170
|
+
}
|
|
153
171
|
const configurationChange = yield this.configuration._internal.setApiSelection(s.selOptions, false);
|
|
154
|
-
|
|
172
|
+
if (configurationChange) {
|
|
173
|
+
change = true;
|
|
174
|
+
}
|
|
155
175
|
if (this.optional) {
|
|
156
176
|
if (yield this.setSelected(s.selected !== false, CfgProductBubbleMode.Stop)) {
|
|
157
177
|
change = true;
|
|
@@ -165,8 +185,14 @@ export class _CfgProductInternal {
|
|
|
165
185
|
if (apiSelectionAdditionalProductsCount !== additionalProductsCount) {
|
|
166
186
|
throw new Error(`Additional products are not same length. This product: "${this.key}". This product additional products count: ${additionalProductsCount}. Passed apiSelection additional products count: ${apiSelectionAdditionalProductsCount}`);
|
|
167
187
|
}
|
|
168
|
-
|
|
169
|
-
|
|
188
|
+
const sourceProductAdditionalProducts = sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.additionalProducts;
|
|
189
|
+
if (sourceProductAdditionalProducts &&
|
|
190
|
+
additionalProductsCount !== sourceProductAdditionalProducts.length) {
|
|
191
|
+
throw new Error(`Passed sourceProduct does not have the same number of additional products as this.`);
|
|
192
|
+
}
|
|
193
|
+
if ((yield Promise.all(apiSelectionAdditionalProducts.map((apiSelectionAdditionalProduct, index) => {
|
|
194
|
+
var _a;
|
|
195
|
+
const refKey = apiSelectionAdditionalProduct.refKey;
|
|
170
196
|
if (refKey === undefined) {
|
|
171
197
|
throw new Error("Additional product api configurations must have refKey.");
|
|
172
198
|
}
|
|
@@ -174,8 +200,16 @@ export class _CfgProductInternal {
|
|
|
174
200
|
if (i === -1) {
|
|
175
201
|
throw new Error(`Additional product not found. This product: "${this.key}". refKey of not found additional product: "${refKey}"`);
|
|
176
202
|
}
|
|
203
|
+
let sourceProductAdditionalProduct = undefined;
|
|
204
|
+
if (sourceProductAdditionalProducts !== undefined) {
|
|
205
|
+
sourceProductAdditionalProduct =
|
|
206
|
+
(_a = sourceProductAdditionalProducts.find((a) => refKey === a.refKey)) === null || _a === void 0 ? void 0 : _a._internal;
|
|
207
|
+
if (sourceProductAdditionalProduct === undefined) {
|
|
208
|
+
throw new Error("Additional product not found in sourceProduct");
|
|
209
|
+
}
|
|
210
|
+
}
|
|
177
211
|
const additionalProduct = additionalProducts.splice(i, 1)[0]; // Splicing like this is okay because this is done synchronous. The setCon. is what is async.
|
|
178
|
-
return additionalProduct._internal.
|
|
212
|
+
return additionalProduct._internal._setApiSelectionWithOtherProduct(apiSelectionAdditionalProduct, doValidate, productLoaderForGroupedLoad, sourceProductAdditionalProduct);
|
|
179
213
|
}))).some((b) => b)) {
|
|
180
214
|
change = true;
|
|
181
215
|
}
|
|
@@ -270,6 +304,7 @@ export class _CfgProductInternal {
|
|
|
270
304
|
this._revalidateInProgressToken = token;
|
|
271
305
|
try {
|
|
272
306
|
const response = yield productLoader.postValidate(Object.assign(Object.assign({ lang: this.lang }, correctDefaultsOnCatalogueParams(this.catId)), { partNumber: this.partNumber }), { selOptions: configuration.getApiSelection() });
|
|
307
|
+
const requestDidValidate = response.validated;
|
|
273
308
|
// The revalidateInProgressToken is used to know if some other revalidate
|
|
274
309
|
// call has happened after this call, thereby making this call obsolete.
|
|
275
310
|
// This is a bit crude in that it does not actually cancel previous validate
|
|
@@ -278,7 +313,7 @@ export class _CfgProductInternal {
|
|
|
278
313
|
// of all, the heavy work happens on the server, and that work will not be
|
|
279
314
|
// cancelled even if we would cancel the call.
|
|
280
315
|
if (this._revalidateInProgressToken !== token) {
|
|
281
|
-
return
|
|
316
|
+
return { wasAborted: true, requestDidValidate };
|
|
282
317
|
}
|
|
283
318
|
// After a successful validate-call we will always assume there
|
|
284
319
|
// is a change. It would be possible to compare relevant parts
|
|
@@ -286,7 +321,7 @@ export class _CfgProductInternal {
|
|
|
286
321
|
// syndAndLoad, however the code comparing productData would be fragile
|
|
287
322
|
// and likely to break if new data-fields were added.
|
|
288
323
|
if (this._destroyed) {
|
|
289
|
-
return
|
|
324
|
+
return { wasAborted: true, requestDidValidate };
|
|
290
325
|
}
|
|
291
326
|
const { productData, rootFeatureRefs } = response;
|
|
292
327
|
const pricesUpdated = !comparePricesObjects(this.prices, productData.partsData.prices);
|
|
@@ -301,10 +336,10 @@ export class _CfgProductInternal {
|
|
|
301
336
|
yield configuration._internal.setApiSelection(productData.partsData.selOptions || [], false);
|
|
302
337
|
yield this._syncAndLoadAdditionalProducts(productLoader);
|
|
303
338
|
if (this._destroyed) {
|
|
304
|
-
return
|
|
339
|
+
return { wasAborted: true, requestDidValidate };
|
|
305
340
|
}
|
|
306
341
|
yield this._notifyAllOfChange(bubbleMode);
|
|
307
|
-
return
|
|
342
|
+
return { wasAborted: false, requestDidValidate };
|
|
308
343
|
}
|
|
309
344
|
catch (e) {
|
|
310
345
|
throw e;
|
|
@@ -322,7 +357,14 @@ export class _CfgProductInternal {
|
|
|
322
357
|
const additionalProductRefs = [
|
|
323
358
|
...(productData.additionalProductRefs || []),
|
|
324
359
|
...collectAdditionalProductRefs(configuration),
|
|
325
|
-
]
|
|
360
|
+
]
|
|
361
|
+
.reduce((a, c) => {
|
|
362
|
+
if (a.every((p) => !isSameProductRef(p, c))) {
|
|
363
|
+
a.push(c);
|
|
364
|
+
}
|
|
365
|
+
return a;
|
|
366
|
+
}, [])
|
|
367
|
+
.map((prodRef, originalIndex) => ({
|
|
326
368
|
prodRef,
|
|
327
369
|
originalIndex,
|
|
328
370
|
}));
|
|
@@ -368,7 +410,7 @@ export class _CfgProductInternal {
|
|
|
368
410
|
this.loadingObservable.stopChildLoading(token);
|
|
369
411
|
}
|
|
370
412
|
});
|
|
371
|
-
this.root = root
|
|
413
|
+
this.root = root !== null && root !== void 0 ? root : this;
|
|
372
414
|
this.key = makeProductKey(catId, refKey || partNumber);
|
|
373
415
|
this._selected = optional ? selected : undefined;
|
|
374
416
|
this.isAdditionalProduct = parent !== undefined;
|
|
@@ -380,9 +422,10 @@ export class _CfgProductInternal {
|
|
|
380
422
|
clone(parent, root) {
|
|
381
423
|
return __awaiter(this, void 0, void 0, function* () {
|
|
382
424
|
const product = yield new Promise((initSuccess, initFail) => {
|
|
425
|
+
var _a;
|
|
383
426
|
const p = new _CfgProductInternal(() => {
|
|
384
427
|
initSuccess(p);
|
|
385
|
-
}, initFail, this._productLoaderRaw, this.lang, this.catId, this.partNumber, this.settings, this.optional, this.selected, this._configuration.rootFeatureRefs, this._configuration.allRawFeatures, this.uuid, this._rawUnit, this._rawProductData, this.configuration.getApiSelection(), new AggregatedLoadingObservable(), this.refKey, this.refDescription, parent, root, this.transform, this.anchor);
|
|
428
|
+
}, initFail, this._productLoaderRaw, this.lang, this.catId, this.partNumber, this.settings, this.optional, this.selected, this._configuration.rootFeatureRefs, this._configuration.allRawFeatures, this.uuid, this._rawUnit, this._rawProductData, this.configuration.getApiSelection(), new AggregatedLoadingObservable(), this.refKey, this.refDescription, parent, root, this.transform, this.anchor, (_a = this._syncGroupHandler) === null || _a === void 0 ? void 0 : _a.clone());
|
|
386
429
|
});
|
|
387
430
|
for (const additionalProduct of this.additionalProducts) {
|
|
388
431
|
product.additionalProducts.push(CfgProduct._makeNewRefFrom(yield additionalProduct._internal.clone(product, root || product)));
|
|
@@ -471,6 +514,85 @@ export class _CfgProductInternal {
|
|
|
471
514
|
get rawProductData() {
|
|
472
515
|
return this._rawProductData;
|
|
473
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
519
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
520
|
+
*/
|
|
521
|
+
get visibleIfAdditionalProduct() {
|
|
522
|
+
return this.rawProductData.hideIfAdditionalProduct !== true;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
526
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
527
|
+
*/
|
|
528
|
+
get visibleIfMainProduct() {
|
|
529
|
+
return this.rawProductData.hideIfMainProduct !== true;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
533
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
534
|
+
*/
|
|
535
|
+
get visible() {
|
|
536
|
+
return this.isAdditionalProduct
|
|
537
|
+
? this.visibleIfAdditionalProduct
|
|
538
|
+
: this.visibleIfMainProduct;
|
|
539
|
+
}
|
|
540
|
+
get syncGroupHandler() {
|
|
541
|
+
return this.root._syncGroupHandler;
|
|
542
|
+
}
|
|
543
|
+
get path() {
|
|
544
|
+
if (this.parent === undefined || this.refKey === undefined) {
|
|
545
|
+
return [];
|
|
546
|
+
}
|
|
547
|
+
return [...this.parent.path, "p", this.refKey];
|
|
548
|
+
}
|
|
549
|
+
getFromPath(path) {
|
|
550
|
+
path = path.slice();
|
|
551
|
+
const s = path.shift();
|
|
552
|
+
switch (s) {
|
|
553
|
+
case undefined:
|
|
554
|
+
return this;
|
|
555
|
+
case "p":
|
|
556
|
+
const refKey = path.shift();
|
|
557
|
+
const additionalProduct = this.additionalProducts.find((p) => p.refKey === refKey);
|
|
558
|
+
if (additionalProduct === undefined) {
|
|
559
|
+
throw new Error(`Additional product not found "p, ${refKey}, ${path.join(", ")}"`);
|
|
560
|
+
}
|
|
561
|
+
return additionalProduct._internal.getFromPath(path);
|
|
562
|
+
case "c":
|
|
563
|
+
return this.configuration._internal.getFromPath(path);
|
|
564
|
+
default:
|
|
565
|
+
throw new Error(`Unexpected path segment ${s}`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
getProductFromPath(path) {
|
|
569
|
+
const p = this.getFromPath(path);
|
|
570
|
+
if (p instanceof _CfgProductInternal) {
|
|
571
|
+
return p;
|
|
572
|
+
}
|
|
573
|
+
throw new Error(`Path did not lead to a Product "${p.path.join(", ")}"`);
|
|
574
|
+
}
|
|
575
|
+
getProductConfigurationFromPath(path) {
|
|
576
|
+
const c = this.getFromPath(path);
|
|
577
|
+
if (c instanceof _CfgProductConfigurationInternal) {
|
|
578
|
+
return c;
|
|
579
|
+
}
|
|
580
|
+
throw new Error(`Path did not lead to a ProductConfiguration "${c.path.join(", ")}"`);
|
|
581
|
+
}
|
|
582
|
+
getFeatureFromPath(path) {
|
|
583
|
+
const f = this.getFromPath(path);
|
|
584
|
+
if (f instanceof _CfgFeatureInternal) {
|
|
585
|
+
return f;
|
|
586
|
+
}
|
|
587
|
+
throw new Error(`Path did not lead to a Feature "${f.path.join(", ")}"`);
|
|
588
|
+
}
|
|
589
|
+
getOptionFromPath(path) {
|
|
590
|
+
const o = this.getFromPath(path);
|
|
591
|
+
if (o instanceof _CfgOptionInternal) {
|
|
592
|
+
return o;
|
|
593
|
+
}
|
|
594
|
+
throw new Error(`Path did not lead to a Option "${o.path.join(", ")}"`);
|
|
595
|
+
}
|
|
474
596
|
}
|
|
475
597
|
_CfgProductInternal.make = (productLoaderRaw, productLoaderForGroupedLoad, // Used when instantiating the current product
|
|
476
598
|
lang, catId, partNumber, settings, optional, loadingObservable, refKey, refDescription, parent, root, transform, anchor) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -479,6 +601,7 @@ lang, catId, partNumber, settings, optional, loadingObservable, refKey, refDescr
|
|
|
479
601
|
// at this initial load.
|
|
480
602
|
productLoaderForGroupedLoad =
|
|
481
603
|
productLoaderForGroupedLoad || wrapWithCache(productLoaderRaw);
|
|
604
|
+
const syncGroupHandler = root === undefined ? SyncGroupsHandler.make(settings.syncGroupsApplyMode) : undefined;
|
|
482
605
|
const productResponse = yield productLoaderForGroupedLoad.getProduct(Object.assign(Object.assign({ lang }, correctDefaultsOnCatalogueParams(catId)), { partNumber }));
|
|
483
606
|
const { productData, rootFeatureRefs, features: allRawFeatures, uuid, unit, } = productResponse;
|
|
484
607
|
const product = yield new Promise((initSuccess, initFail) => {
|
|
@@ -487,9 +610,11 @@ lang, catId, partNumber, settings, optional, loadingObservable, refKey, refDescr
|
|
|
487
610
|
// But we can not set the api selection synchronously. And the product configuration needs "this". So we use this callback.
|
|
488
611
|
// Feel free to find a nicer more readable solution :)
|
|
489
612
|
initSuccess(p);
|
|
490
|
-
}, initFail, productLoaderRaw, lang, catId, partNumber, settings, optional, !optional, rootFeatureRefs, allRawFeatures, uuid, unit, productData, productData.partsData.selOptions || [], loadingObservable, refKey, refDescription, parent, root, transform, anchor);
|
|
613
|
+
}, initFail, productLoaderRaw, lang, catId, partNumber, settings, optional, !optional, rootFeatureRefs, allRawFeatures, uuid, unit, productData, productData.partsData.selOptions || [], loadingObservable, refKey, refDescription, parent, root, transform, anchor, syncGroupHandler);
|
|
491
614
|
});
|
|
492
615
|
yield product._syncAndLoadAdditionalProducts(productLoaderForGroupedLoad);
|
|
616
|
+
// Product is guaranteed to be root
|
|
617
|
+
yield (syncGroupHandler === null || syncGroupHandler === void 0 ? void 0 : syncGroupHandler.init(product, productLoaderForGroupedLoad));
|
|
493
618
|
return product;
|
|
494
619
|
});
|
|
495
620
|
export class CfgProduct {
|
|
@@ -545,7 +670,7 @@ export class CfgProduct {
|
|
|
545
670
|
}
|
|
546
671
|
/**
|
|
547
672
|
* Makes an object wrapping the passed object. This is not a clone method, it is a method to
|
|
548
|
-
* make a new outer reference. Like a shallow copy
|
|
673
|
+
* make a new outer reference. Like a shallow copy. We use this to help frameworks that are
|
|
549
674
|
* build around using equals to detect change.
|
|
550
675
|
*/
|
|
551
676
|
static _makeNewRefFrom(source) {
|
|
@@ -589,6 +714,15 @@ export class CfgProduct {
|
|
|
589
714
|
get selected() {
|
|
590
715
|
return this._internal.selected;
|
|
591
716
|
}
|
|
717
|
+
/**
|
|
718
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
719
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
720
|
+
* Visibility is affects the Configuration for this Product, but any Additional Products
|
|
721
|
+
* will not be affected.
|
|
722
|
+
*/
|
|
723
|
+
get visible() {
|
|
724
|
+
return this._internal.visible;
|
|
725
|
+
}
|
|
592
726
|
get rawProductData() {
|
|
593
727
|
return this._internal.rawProductData;
|
|
594
728
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export * from "./productConfiguration/CfgProductConfiguration.js";
|
|
|
11
11
|
export * from "./productConfiguration/filters.js";
|
|
12
12
|
export * from "./productConfiguration/productParamsGenerator.js";
|
|
13
13
|
export * from "./productLoader.js";
|
|
14
|
+
export * from "./syncGroups/SyncGroupsApplyMode.js";
|
|
15
|
+
export * from "./syncGroups/SyncGroupsHandler.js";
|
|
14
16
|
export * from "./tasks/formats.js";
|
|
15
17
|
export * from "./tasks/TaskHandler.js";
|
|
16
18
|
export * from "./utilitiesCatalogueData.js";
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,8 @@ export * from "./productConfiguration/CfgProductConfiguration.js";
|
|
|
11
11
|
export * from "./productConfiguration/filters.js";
|
|
12
12
|
export * from "./productConfiguration/productParamsGenerator.js";
|
|
13
13
|
export * from "./productLoader.js";
|
|
14
|
+
export * from "./syncGroups/SyncGroupsApplyMode.js";
|
|
15
|
+
export * from "./syncGroups/SyncGroupsHandler.js";
|
|
14
16
|
export * from "./tasks/formats.js";
|
|
15
17
|
export * from "./tasks/TaskHandler.js";
|
|
16
18
|
export * from "./utilitiesCatalogueData.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
-
import { Feature, SelectedOption } from "../CatalogueAPI.js";
|
|
3
|
-
import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
2
|
+
import { Feature, SelectedOption, SyncGroup } from "../CatalogueAPI.js";
|
|
3
|
+
import { CfgPath, CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
4
4
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
5
5
|
import { CfgOption, ProductConfigurationBubbleMode, _CfgOptionInternal } from "./CfgOption.js";
|
|
6
6
|
import { _CfgProductConfigurationInternal } from "./CfgProductConfiguration.js";
|
|
@@ -49,6 +49,7 @@ export declare class _CfgFeatureInternal {
|
|
|
49
49
|
get isUseNumericValue(): boolean;
|
|
50
50
|
get numericValue(): number | undefined;
|
|
51
51
|
setNumericValue: (val: number) => Promise<boolean>;
|
|
52
|
+
get syncGroup(): SyncGroup | undefined;
|
|
52
53
|
get description(): string;
|
|
53
54
|
/**
|
|
54
55
|
* The MeasureParam class is re-used for different purposes. In Features it is used
|
|
@@ -66,8 +67,20 @@ export declare class _CfgFeatureInternal {
|
|
|
66
67
|
*/
|
|
67
68
|
private get isAllOptionsAffectedByAnySelection();
|
|
68
69
|
get preview(): string | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
72
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
73
|
+
*/
|
|
69
74
|
get visibleIfAdditionalProduct(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
77
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
78
|
+
*/
|
|
70
79
|
get visibleIfMainProduct(): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
82
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
83
|
+
*/
|
|
71
84
|
get visible(): boolean;
|
|
72
85
|
get options(): CfgOption[];
|
|
73
86
|
private _notifyAllOfChange;
|
|
@@ -83,6 +96,8 @@ export declare class _CfgFeatureInternal {
|
|
|
83
96
|
setApiSelection: (apiOptionSelectionMap: {
|
|
84
97
|
[index: string]: SelectedOption;
|
|
85
98
|
} | undefined) => Promise<boolean>;
|
|
99
|
+
get path(): CfgPath;
|
|
100
|
+
getFromPath(path: CfgPath): _CfgFeatureInternal | _CfgOptionInternal;
|
|
86
101
|
/** Pushes to refresh stretch. Does not cause validation. */
|
|
87
102
|
pushStretch: () => Promise<boolean>;
|
|
88
103
|
structureCompare: (other: _CfgFeatureInternal, strictOrder?: boolean, descriptionMatch?: boolean) => boolean;
|
|
@@ -148,6 +163,8 @@ export declare class CfgFeature {
|
|
|
148
163
|
get preview(): string | undefined;
|
|
149
164
|
get options(): CfgOption[];
|
|
150
165
|
/**
|
|
166
|
+
* Please note that this relates to the visibility in the Configuration tree.
|
|
167
|
+
* It does not affect the visibility of anything in the 3D view at all.
|
|
151
168
|
* Visibility is not inherited. If this is hidden the children
|
|
152
169
|
* of this Feature might still be visible, depending on their settings.
|
|
153
170
|
*/
|