import type {CardRenderer, CardRendererParameters} from "./CardRenderers"; import {getCardComponentData} from "./cards"; import {CardItemSecondaryValue} from "./CardItemSecondaryValue"; import {__} from "../globals"; import {Color} from "./Color"; import {CardItemMainValue} from "./CardItemMainValue"; import {get, isPlainObject} from "lodash"; import {isValidElement} from "react"; import {ComponentDataType, OfferData, TestableData} from "./store"; export class CardRendererFromCardComponentDataDecorator implements CardRenderer { public cardRenderer: CardRenderer; testableType: 'filter' | 'condition'; private id: string; private partialId: string | undefined; private localData: object | undefined; constructor(cardRenderer: CardRenderer | undefined, testableType: ComponentDataType, id: string, partialId?: string, localData?: TestableData | OfferData) { this.cardRenderer = cardRenderer || this.getUnavailableCardRenderer(localData?.type); this.testableType = testableType; this.id = id; this.partialId = partialId; this.localData = localData; // Create a proxy to handle property access return new Proxy(this, { get: (target, prop, receiver) => { // If the property exists on the decorator, return it if (prop in target) { return Reflect.get(target, prop, receiver); } // Otherwise forward to the cardRenderer return Reflect.get(target.cardRenderer, prop); } }); } private getUnavailableCardRenderer(missingType?: string): CardRenderer { return { type: missingType || 'UnavailableComponent', icon: ({className}) => ( ), AboveComputedValue: () => __('Unavailable component'), ComputedValue: () => missingType || __('Not available'), BelowComputedValue: () => __('This component is currently unavailable.'), } } get icon() { return this?.cardRenderer?.icon; } get ComputedValue() { if (!this.cardRenderer.ComputedValue) { return } return (parameters: CardRendererParameters) => {this.cardRenderer.ComputedValue(this.getCardRendererParameters(parameters))} ; } get AboveComputedValue() { return (parameters) => { let aboveComputedValueCache: any const getAboveComputedValue = () => { aboveComputedValueCache = this?.cardRenderer?.AboveComputedValue?.(this.getCardRendererParameters(parameters)); return aboveComputedValueCache } const givenAboveComputedValue = getAboveComputedValue(); const isObjectLiteral = isPlainObject(givenAboveComputedValue) && !isValidElement(givenAboveComputedValue); if (typeof this.cardRenderer.AboveComputedValue !== 'function' || givenAboveComputedValue === undefined || isObjectLiteral) { return { isObjectLiteral && givenAboveComputedValue.label ? givenAboveComputedValue.label : getCardComponentData(this.testableType, this.cardRenderer.type!)?.name || __('Unavailable component') } } const aboveComputedValue = givenAboveComputedValue; if (aboveComputedValue) { if (typeof aboveComputedValue === 'string') { return {aboveComputedValue} ; } return aboveComputedValue; } }; } get prefix() { return this.cardRenderer.prefix; } private getCardRendererParameters(parameters: CardRendererParameters) { return { ...parameters, ...{ id: this.id, partialId: this.partialId, localData: this.localData, } }; } }