import { AggregatedLoadingObservable, LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities"; import { DtoAdditionalProductConfiguration, DtoAdditionalProductRef, DtoCatalogueParams, DtoMeasureParam, DtoMiscFile, DtoMtrlApplication, DtoNote, DtoPrices, DtoProductConf, DtoProductParamsWithLang, DtoTransform } from "./CatalogueAPI.js"; import { CfgMeasureDefinition } from "./CfgMeasure.js"; import { _CfgFeatureInternal } from "./productConfiguration/CfgFeature.js"; import { _CfgOptionInternal, ProductConfigurationBubbleMode } from "./productConfiguration/CfgOption.js"; import { CfgProductConfiguration } from "./productConfiguration/CfgProductConfiguration.js"; import { ProductLoader } from "./productLoader.js"; import { SyncGroupsApplyMode } from "./syncGroups/SyncGroupsApplyMode.js"; import { SyncGroupsHandler } from "./syncGroups/SyncGroupsHandler.js"; import { CfgProductData, RootNodeSource } from "./utilitiesCatalogueData.js"; import { CfgProdConfParts } from "./utilitiesConfiguration.js"; /** * @freshRef a new pointer to the same product, backed by the same original object * @committed false is an indication that this is a potentially transient state. It could * be the expected outcome of a SyncGroups transaction, or dragging to stretch a Product. * Uncommitted notifications can be used to update for instance spinners, but should not * be sent to server or such. */ export declare type CfgProductChangeNotification = { freshRef: CfgProduct; committed: boolean; }; export declare type CfgProductSettings = { /** * In a correctly setup catalogue a select-one Feature (i.e. neither optional nor multiple) * must have exactly one Option set at a time. However, this is not enforced in Catalogue * Creator and it is not uncommon with catalogues which fails to meet this requirement. * Activating this will make setApi throw an Error if more or less than one is selected. */ strictSelectOneSelectionCount: boolean; /** * Controls if SyncGroups are applied Faster or Stricter. * * Fast - Tries to minimize the number of validates calls to the AI lowering the response times * for selecting options. Might not always give the expected result for complex products. * * Strict - Apply the SyncGroups rules in a stricter fashion to be as close to CET as possible, * which might result in longer response times and more validation calls to the API when * selecting options. * * The SDK will default to Strict, but we recommend that you try out Fast since cases where the * results differ should be rare in most real uses cases and the speedup can be quite large. */ syncGroupsApplyMode: SyncGroupsApplyMode | undefined; /** * Controls checking each Option in a Feature group for duplicate descriptions. This comparison check can * take a really long time as the Feature group grows in size. The description based keys are helpful when switching * between products with similar feature option trees while retaining the previous selections. This prevents * the UI from unnecessarily re-rendering. * * The SDK will default this to enabled. */ disableMatchOnDescription: boolean; }; /** * This enum is used internally in the SDK and is not expected by be used directly by integrators. */ export declare enum CfgProductBubbleMode { /** Stop bubbling. */ Stop = "Stop", /** * Bubble to the parent CfgProduct up the tree. * This makes the CfgProduct we we call from notify that it has changed, and the CfgProduct * above switch out the reference to this. */ OneLevel = "OneLevel", /** Bubble to the root CfgProduct. */ ToRoot = "ToRoot", /** Bubble to the root CfgProduct and turn on all optional CfgProducts on the way up. */ ToRootAndBubbleSelected = "ToRootAndBubbleSelected" } export declare type CfgPrice = { basePrice: number; listPrice: number; currency: string; fractionDigits: number; }; /** * This class is meant to only be used through CfgProduct. It should never be instantiated on its * own. Normally the internal state of this class should never be directly modified. CfgProduct is * the class that should be used and interacted with. */ export declare class _CfgProductInternal { readonly _productLoaderRaw: ProductLoader; readonly prodParams: DtoProductParamsWithLang; readonly settings: CfgProductSettings; readonly uuid: string; private readonly _rawUnit; private _rawProductData; readonly loadingObservable: AggregatedLoadingObservable; readonly parent: _CfgProductInternal | undefined; private _additionalProductRef; private readonly _syncGroupHandler; static make: (productLoaderRaw: ProductLoader, productLoaderForGroupedLoad: ProductLoader | undefined, prodParams: DtoProductParamsWithLang, settings: CfgProductSettings, optional: boolean, loadingObservable: AggregatedLoadingObservable, parent: _CfgProductInternal | undefined, root: _CfgProductInternal | undefined, additionalProductRef: DtoAdditionalProductRef | undefined, initialProductConfiguration: DtoProductConf | DtoAdditionalProductConfiguration | undefined) => Promise<_CfgProductInternal>; _initialClone: _CfgProductInternal | undefined; private constructor(); readonly root: _CfgProductInternal; private _destroyed; readonly key: string; readonly additionalProducts: CfgProduct[]; private _selected; private _configuration; private _notes; readonly changeObservable: Observable; /** * The last diff that was generated during the last validate call. * * This is used to keep track of the changes that were made to the * configuration as a result of apply constraints. */ private _lastDiff; get selected(): boolean; readonly isAdditionalProduct: boolean; /** * Please note that cloning an additional product will make the clone believe is is * an additional product, even if it has no parent and root. * Providing the parent and root of what you clone as arguments is unwise as it will * make changes you do on the clone be propagated up to the original non-clone root product. */ clone(parent?: _CfgProductInternal, root?: _CfgProductInternal): Promise<_CfgProductInternal>; /** Mark this and its descendants as destroyed and remove all listeners */ destroy: () => void; /** * Reset will reset the product to its initial state */ reset: () => Promise; /** * Internal use. Used when this product is an additional product, and * changing a parent product has made the settings for this product * change. */ _updateAdditionalProdRef(p: DtoAdditionalProductRef): void; /** * Return a DtoNode using noteRef as a key. * Throws an error if no note is found. */ getNote(noteRef: string): DtoNote; /** * noteRefs is a list of keys coming from CfgOption, CfgFeature or CfgProduct. * The keys are used to get a DtoNote[] from notes at CfgProduct. */ getNotes(noteRefs: string[]): DtoNote[]; private addNotes; get notes(): DtoNote[]; get miscFiles(): DtoMiscFile[]; get hasRootFeaturesChanged(): boolean; get description(): string | undefined; get rootNodeSources(): RootNodeSource[] | undefined; get mtrlApplications(): DtoMtrlApplication[] | undefined; get currency(): string; get fractionDigits(): number; get prices(): DtoPrices | undefined; private _measureDefinitions; get measureDefinitions(): CfgMeasureDefinition[]; private _unit; get refKey(): string | undefined; get transform(): DtoTransform | undefined; get anchor(): DtoMeasureParam | undefined; /** @throws an error if the actual unit sent by the server was not a LengthUnit */ get unit(): LengthUnit; get aggregatedPrice(): CfgPrice; get optional(): boolean; setSelected(selected: boolean, bubbleMode: CfgProductBubbleMode, interactive: boolean): Promise; get configuration(): CfgProductConfiguration; get rawProductData(): CfgProductData; /** * Please note that this relates to the visibility in the Configuration tree. * It does not affect the visibility of anything in the 3D view at all. */ get visibleIfAdditionalProduct(): boolean; /** * Please note that this relates to the visibility in the Configuration tree. * It does not affect the visibility of anything in the 3D view at all. */ get visibleIfMainProduct(): boolean; /** * Please note that this relates to the visibility in the Configuration tree. * It does not affect the visibility of anything in the 3D view at all. */ get visible(): boolean; _notifyAllOfChange: (bubbleMode: CfgProductBubbleMode, committed: boolean) => Promise; /** Called when a child (additional product or the configuration) has changed. */ private _childHasChanged; /** Called by child to tell its parent that it has changed. */ _additionalProductHasChanged: (freshRef: CfgProduct, bubbleMode: CfgProductBubbleMode, committed: boolean) => Promise; /** Called by the configuration to tell its parent that it has changed. */ _configurationHasChanged: (freshRef: CfgProductConfiguration, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise; getDtoConf: (include: CfgProdConfParts) => DtoProductConf; setDtoConf: (s: DtoProductConf, doValidate: boolean, productLoaderForGroupedLoad?: ProductLoader | undefined) => Promise; setApiSelection: (s: DtoAdditionalProductConfiguration, doValidate: boolean, productLoaderForGroupedLoad?: ProductLoader | undefined) => Promise; copyFrom: (source: _CfgProductInternal, doValidate: boolean, productLoaderForGroupedLoad?: ProductLoader | undefined) => Promise; private _setApiSelectionWithOtherProduct; /** * Clears cached stretch data which depends on the rawProductData. * This should be called when rawProductData changes, which may potentially change the measurements. */ private _clearStretchMeasurements; get syncGroupHandler(): SyncGroupsHandler | undefined; get syncGroupsVerboseLogging(): boolean; /** * Set to true to get verbose sync state changes logged to the console. */ set syncGroupsVerboseLogging(v: boolean); structureCompare: (other: _CfgProductInternal, strictOrder?: boolean, descriptionMatch?: boolean) => boolean; tryMatchSelection: (other: _CfgProductInternal, descriptionMatch?: boolean, productLoaderForGroupedLoad?: ProductLoader | undefined) => Promise; /** Only features in selected options and selected additional products. */ _getDescendantFeaturesWithCode: (code: string) => _CfgFeatureInternal[]; /** * Obtains the differences found in the last validate call. * Used to update the sync group state. * * Removes the diff from the product. */ takeDiff(): _CfgOptionInternal[] | undefined; private _revalidateInProgressToken; /** * Do a validate call for this product. * * Does not validate additional products, unless application of sync groups * on the result of the validate call results in changes in the additional * product. * * The validation result is applied on the configuration. Then additional * products are synced (unloaded, loaded etc.) Finally the changes bubble up the tree. */ _revalidate: (bubbleMode: CfgProductBubbleMode, productLoader: ProductLoader, committed: boolean) => Promise; /** * Based on this configuration find what additional products should be shown and not, unload * (i.e. destroy) those that should no longer be shown, load the new ones. */ _syncAndLoadAdditionalProducts: (productLoaderForGroupedLoad: ProductLoader, initialProductConfiguration: DtoAdditionalProductConfiguration | undefined) => Promise; private _setRawProductData; } export declare class CfgProduct { readonly _internal: _CfgProductInternal; static make(productLoader: ProductLoader, prodParams: DtoProductParamsWithLang, settings?: Partial, initialProductConfiguration?: DtoProductConf | DtoAdditionalProductConfiguration): Promise; /** * Makes an object wrapping the passed object. This is not a clone method, it is a method to * make a new outer reference. Like a shallow copy. We use this to help frameworks that are * build around using equals to detect change. */ static _makeNewRefFrom(source: _CfgProductInternal): CfgProduct; private constructor(); isBackedBySame: (other: CfgProduct) => boolean; /** * Recursively marks this and descendants as destroyed so that late events are ignored * correctly. If you destroy one shallow copy of this you destroy all. */ destroy: () => void; /** Makes a clone of this. It is disconnected from the original. */ clone: () => Promise; /** * A client side only key that should uniquely identify this product amongst other additional * products. */ get key(): string; /** * Only used when this product is in additional product. * As a product can have multiple instances of the same additional product this key exists. * It will be unique amongst child products, but not globally unique. */ get refKey(): string | undefined; get notes(): DtoNote[]; get miscFiles(): DtoMiscFile[]; get prodParams(): DtoProductParamsWithLang; get lang(): string; get catId(): DtoCatalogueParams; get partNumber(): string; get isAdditionalProduct(): boolean; /** Only used when this product is an additional product. Root products are never optional. */ get optional(): boolean; /** * Only applicable when this product is optional. If this product is not optional this is * always true. */ get selected(): boolean; /** * Please note that this relates to the visibility in the Configuration tree. * It does not affect the visibility of anything in the 3D view at all. * Visibility affects the Configuration for this Product, but any Additional Products * will not be affected. */ get visible(): boolean; /** * Only applicable when this product is optional. * Setting this does not cause a validation call as toggling an optional additional product is * assumed to always be legal. */ setSelected: (v: boolean) => Promise; /** * Functional selection is a Catalogues feature where selecting Options on Features result in that you * "jump" to another Product as a result of the Validate call. You normally do not notice that a functional * selection has occurred except for the styleNr changing. Functional selection can change which Features * from the original product call are used as root Features. This can in turn affect if serialized * configuration can be applied or not. * * The SDK can currently only apply serialized configuration if the list of root Features has not changed. * For this reason, when functional selection has happened, extracting data for external systems might work * well, but reapplying back into Stage will probably fail. */ get hasRootFeaturesChanged(): boolean; get rawProductData(): CfgProductData; get uuid(): string; get unit(): LengthUnit; get sku(): string; get styleNr(): string; /** An URL. */ get preview(): string | undefined; get description(): string | undefined; get additionalProducts(): CfgProduct[]; get configuration(): CfgProductConfiguration; get transform(): DtoTransform | undefined; get currency(): string; /** * If positive the number of fraction digits. * If negative rounding (essentially the number of zeros to the right) */ get fractionDigits(): number; get aggregatedPrice(): CfgPrice; /** * Experimental. Additional products lacks descriptions or keys that are suitably for structure * compare, so we use strict-order when trying to match the additional products. This makes * this method work nicely for different products having pretty much the same child products. */ structureCompare: (other: CfgProduct, strictOrder?: boolean, descriptionMatch?: boolean) => boolean; /** * Experimental. Additional products lacks descriptions or keys that are suitably for try * match, so we use strict-order when trying to match the additional products. This makes * this method work nicely for different products having pretty much the same child products. * This method does not propagate its selections. * This method will cause validation calls if something change. */ tryMatchSelection: (other: CfgProduct, descriptionMatch?: boolean) => Promise; /** * Gets what selections has been made on the product, recursively including product * configuration, optional products and additional products. Used when a full view of all * selections on a product is needed, such as when doing Render or Export. * @deprecated getDtoConf provides a newer format. * @see getDtoConf */ getApiSelection: () => DtoAdditionalProductConfiguration; /** * Applies the configuration (selections) in the passed object onto the product recursively * including product configuration, optional products and additional products. * @param doValidate Makes a server side validation call. These are necessary to ensure that * the right models are loaded. * @deprecated setDtoConf uses a newer format. */ setApiSelection: (configuration: DtoAdditionalProductConfiguration, doValidate?: boolean) => Promise; /** * A newer alternative version of getApiSelection. This returns the configuration (selections) * on the product, recursively including product configuration, optional products and additional * products. * This version has the following advantages over getApiSelection: * - The format is clearer, designed to be readable * - Makes less assumptions about the structure in the Product being unchanging over time. In * particular, the Feature codes are included in the data, so that changes to what Features * are used in a Product is less likely to lead to unexpected results. * - You can request ExtendedData, ProductParams and/or SyncGroupState to be included in the * result. This extra data is ignored when passed back into the API, but it can be very useful * for external applications. * The other version (getApiSelection) has the advantage of using a format directly compatible with the API:s. * @param include Includes extra data which is not an actual part of the configuration */ getDtoConf: (include?: CfgProdConfParts) => DtoProductConf; /** * A newer alternative version of setApiSelection. * @param doValidate Makes a server side validation call. These are necessary to ensure that * the right models are loaded. */ setDtoConf: (configuration: DtoProductConf, doValidate?: boolean) => Promise; listenForChange: (l: SingleArgCallback) => void; stopListenForChange: (l: SingleArgCallback) => void; stopAllListenForChange: () => void; listenForLoading: (l: SingleArgCallback) => void; stopListenForLoading: (l: SingleArgCallback) => void; stopAllListenForLoading: () => void; } //# sourceMappingURL=CfgProduct.d.ts.map