From 17b84fb4634028ae83f70e811ebea26c40bf78bb Mon Sep 17 00:00:00 2001 From: mohamedsalem401 Date: Wed, 18 Dec 2024 04:48:27 +0200 Subject: [PATCH] Add many info to the currentItem --- .../CollectionComponent.ts | 131 +++++++++++++----- 1 file changed, 99 insertions(+), 32 deletions(-) diff --git a/packages/core/src/data_sources/model/collection_component/CollectionComponent.ts b/packages/core/src/data_sources/model/collection_component/CollectionComponent.ts index d509f0159..a2d17085a 100644 --- a/packages/core/src/data_sources/model/collection_component/CollectionComponent.ts +++ b/packages/core/src/data_sources/model/collection_component/CollectionComponent.ts @@ -3,11 +3,11 @@ import { isArray } from 'underscore'; import Component from '../../../dom_components/model/Component'; import { ComponentDefinition, ComponentOptions, ComponentProperties } from '../../../dom_components/model/types'; import { toLowerCase } from '../../../utils/mixins'; -import { ConditionDefinition, ConditionalVariableType } from '../conditional_variables/DataCondition'; +import { ConditionDefinition } from '../conditional_variables/DataCondition'; import DataSource from '../DataSource'; import { DataVariableType } from '../DataVariable'; -export const CollectionVariableType = 'collection-variable'; +export const CollectionVariableType = 'collection-component'; // Represents the type for defining a loop’s data source. type CollectionDataSource = | any[] // Direct array @@ -44,7 +44,7 @@ export default class CollectionComponent extends Component { constructor(props: CollectionDefinition & ComponentProperties, opt: ComponentOptions) { const { block, config } = props.collectionDefinition; const { dataSource } = config; - let items = []; + let items: any[] = []; switch (true) { case isArray(dataSource): items = dataSource; @@ -53,20 +53,31 @@ export default class CollectionComponent extends Component { items = dataSource.getRecords(); break; case typeof dataSource === 'object' && dataSource.type === DataVariableType: - const resolvedPath = opt.em.DataSources.fromPath(dataSource.path); - if (typeof resolvedPath[0] === 'object' && resolvedPath[0] instanceof DataSource) { - items = resolvedPath[0].getRecords(); + const pathArr = dataSource.path.split('.'); + if (pathArr.length === 1) { + const resolvedPath = opt.em.DataSources.getValue(dataSource.path, []); + const keys = Object.keys(resolvedPath); + items = keys.map(key => resolvedPath[key]); } else { - items = resolvedPath; + items = opt.em.DataSources.getValue(dataSource.path, []); } break; default: } - const components: ComponentDefinitionDefined[] = items.map((item) => resolveBlockValue(item, block)); + const components: ComponentDefinitionDefined[] = items.map((item: any, index) => resolveBlockValue({ + currentIndex: index, + firstIndex: config.startIndex, + currentItem: item, + lastIndex: config.endIndex, + collectionName: props.collectionName, + totalItems: items.length, + remainingItems: items.length - index, + }, block) + ); const conditionalCmptDef = { ...props, - type: ConditionalVariableType, + type: CollectionVariableType, components: components, dropbbable: false, }; @@ -75,35 +86,91 @@ export default class CollectionComponent extends Component { } static isComponent(el: HTMLElement) { - return toLowerCase(el.tagName) === ConditionalVariableType; + return toLowerCase(el.tagName) === CollectionVariableType; } } -function resolveBlockValue(item: any, block: any) { - const stringifiedItem = JSON.stringify(item); - const keys = Object.keys(block); - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const value = block[key]; - if (typeof value === 'object') { - if (value.type === 'parent-collection-variable') { - if (!value.path || value.path === 'item') { - block[key] = stringifiedItem; - } else { - const arr = value.path.split('.'); - if (item.get) { - block[key] = item.get?.(arr[0]); - } else { - block[key] = item[arr[0]]; +/** + * Deeply clones an object. + * @template T The type of the object to clone. + * @param {T} obj The object to clone. + * @returns {T} A deep clone of the object, or the original object if it's not an object or is null. Returns undefined if input is undefined. + */ +function deepCloneObject | null | undefined>(obj: T): T { + if (obj === null) return null as T; + if (obj === undefined) return undefined as T; + if (typeof obj !== 'object' || Array.isArray(obj)) { + return obj; // Return primitives directly + } + + const clonedObj: Record = {}; + + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + clonedObj[key] = deepCloneObject(obj[key]); + } + } + + return clonedObj as T; +} + +function resolveBlockValue(item: any, block: any): any { + const clonedBlock = deepCloneObject(block); + + if (typeof clonedBlock === 'object' && clonedBlock !== null) { + const stringifiedItem = JSON.stringify(item.currentItem); + const keys = Object.keys(clonedBlock); + + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + let value = clonedBlock[key]; + + if (typeof value === 'object') { + if (value.type === 'parent-collection-variable') { + if (value.variable_type === 'current_item') { + if (!value.path) { + clonedBlock[key] = stringifiedItem; + } else { + const pathParts = value.path.split('.'); + let resolvedValue = item.currentItem; + for (const part of pathParts) { + if (resolvedValue && typeof resolvedValue === 'object' && resolvedValue.hasOwnProperty(part)) { + resolvedValue = resolvedValue[part]; + } else { + resolvedValue = undefined; // Handle cases where the path doesn't exist + break; + } + } + clonedBlock[key] = resolvedValue; + } + } else if (value.variable_type === 'current_index') { + clonedBlock[key] = String(item.currentIndex); + } else if (value.variable_type === 'first_index') { + clonedBlock[key] = String(item.firstIndex); + } else if (value.variable_type === 'last_index') { + clonedBlock[key] = String(item.lastIndex); + } else if (value.variable_type === 'collection_name') { + clonedBlock[key] = String(item.collectionName); + } else if (value.variable_type === 'total_items') { + clonedBlock[key] = String(item.totalItems); + } else if (value.variable_type === 'remaining_items') { + clonedBlock[key] = String(item.remainingItems); } + } else if (Array.isArray(value)) { + // Handle arrays: Resolve each item in the array + clonedBlock[key] = value.map((itemInArray: any) => { + if (typeof itemInArray === 'object') { + return resolveBlockValue(item, itemInArray); + } + + return itemInArray; // Return primitive values directly + }); + } else { + clonedBlock[key] = resolveBlockValue(item, value); } - } else { - block[key] = resolveBlockValue(item, value); } } } - block['droppable'] = false; - block['draggable'] = false; - - return block; + + return clonedBlock; }