diff --git a/packages/core/src/data_sources/model/ComponentWithCollectionsState.ts b/packages/core/src/data_sources/model/ComponentWithCollectionsState.ts index bcb90c511..ea308df5e 100644 --- a/packages/core/src/data_sources/model/ComponentWithCollectionsState.ts +++ b/packages/core/src/data_sources/model/ComponentWithCollectionsState.ts @@ -11,6 +11,8 @@ import { isArray } from 'underscore'; export type DataVariableMap = Record; +export type DataSourceRecords = DataVariableProps[] | DataVariableMap; + export default class ComponentWithCollectionsState extends Component { collectionsStateMap: DataCollectionStateMap = {}; dataSourceWatcher?: DataResolverListener; @@ -98,7 +100,7 @@ export default class ComponentWithCollectionsState extends Com return clone; } - protected listDataSourceItems(dataSource: DataSource | DataVariableProps): DataVariableProps[] | DataVariableMap { + protected listDataSourceItems(dataSource: DataSource | DataVariableProps): DataSourceRecords { const em = this.em; switch (true) { case isObject(dataSource) && dataSource instanceof DataSource: { diff --git a/packages/core/src/data_sources/model/DataVariable.ts b/packages/core/src/data_sources/model/DataVariable.ts index c7f195fcc..e34318e01 100644 --- a/packages/core/src/data_sources/model/DataVariable.ts +++ b/packages/core/src/data_sources/model/DataVariable.ts @@ -1,7 +1,13 @@ import { Model } from '../../common'; +import { keyRootData } from '../../dom_components/constants'; import EditorModel from '../../editor/model/Editor'; import { isDataVariable } from '../utils'; -import { DataCollectionStateMap, DataCollectionState, DataCollectionStateType } from './data_collection/types'; +import { + DataCollectionStateMap, + DataCollectionState, + DataCollectionStateType, + RootDataType, +} from './data_collection/types'; export const DataVariableType = 'data-variable' as const; @@ -134,36 +140,45 @@ export default class DataVariable extends Model { ); } - private resolveCollectionVariable(): unknown { + private resolveCollectionVariable() { const { em, collectionsStateMap } = this; return DataVariable.resolveCollectionVariable(this.attributes, { em, collectionsStateMap }); } static resolveCollectionVariable( - dataResolverProps: { + { + collectionId = '', + variableType, + path, + defaultValue = '', + }: { collectionId?: string; variableType?: DataCollectionStateType; path?: string; defaultValue?: string; }, - opts: DataVariableOptions, - ): unknown { - const { collectionId = '', variableType, path, defaultValue = '' } = dataResolverProps; - const { em, collectionsStateMap } = opts; - + { em, collectionsStateMap }: DataVariableOptions, + ) { if (!collectionsStateMap) return defaultValue; const collectionItem = collectionsStateMap[collectionId]; if (!collectionItem) return defaultValue; if (!variableType) { + if (collectionId === keyRootData) { + const rootData = collectionItem as RootDataType; + return path ? rootData[path as keyof RootDataType] : rootData; + } + em.logError(`Missing collection variable type for collection: ${collectionId}`); return defaultValue; } - return variableType === 'currentItem' - ? DataVariable.resolveCurrentItem(collectionItem, path, collectionId, em) - : collectionItem[variableType]; + if (variableType === 'currentItem') { + return DataVariable.resolveCurrentItem(collectionItem, path, collectionId, em); + } + + return collectionItem[variableType] ?? defaultValue; } private static resolveCurrentItem( @@ -171,7 +186,7 @@ export default class DataVariable extends Model { path: string | undefined, collectionId: string, em: EditorModel, - ): unknown { + ) { const currentItem = collectionItem.currentItem; if (!currentItem) { em.logError(`Current item is missing for collection: ${collectionId}`); diff --git a/packages/core/src/data_sources/model/data_collection/types.ts b/packages/core/src/data_sources/model/data_collection/types.ts index 2d9b82bfa..c050cf8f1 100644 --- a/packages/core/src/data_sources/model/data_collection/types.ts +++ b/packages/core/src/data_sources/model/data_collection/types.ts @@ -1,6 +1,8 @@ import { DataCollectionType, keyCollectionDefinition } from './constants'; import { ComponentDefinition } from '../../../dom_components/model/types'; import { DataVariableProps } from '../DataVariable'; +import { keyRootData } from '../../../dom_components/constants'; +import { ObjectAny } from '../../../common'; export type DataCollectionDataSource = DataVariableProps; @@ -26,10 +28,12 @@ export interface DataCollectionState { [DataCollectionStateType.remainingItems]: number; } +export type RootDataType = Array | ObjectAny; + export type DataCollectionStateMap = { [key: string]: DataCollectionState; } & { - __pages?: { [DataCollectionStateType.currentItem]: DataCollectionState }; + [keyRootData]?: RootDataType; }; export interface ComponentDataCollectionProps extends ComponentDefinition { diff --git a/packages/core/src/dom_components/constants.ts b/packages/core/src/dom_components/constants.ts new file mode 100644 index 000000000..6b5aa1bbc --- /dev/null +++ b/packages/core/src/dom_components/constants.ts @@ -0,0 +1 @@ +export const keyRootData = '__rootData'; diff --git a/packages/core/src/dom_components/model/ComponentWrapper.ts b/packages/core/src/dom_components/model/ComponentWrapper.ts index de29df06e..83b5557a8 100644 --- a/packages/core/src/dom_components/model/ComponentWrapper.ts +++ b/packages/core/src/dom_components/model/ComponentWrapper.ts @@ -1,19 +1,22 @@ -import { isArray, isUndefined } from 'underscore'; +import { isUndefined } from 'underscore'; import { attrToString } from '../../utils/dom'; import Component from './Component'; import ComponentHead, { type as typeHead } from './ComponentHead'; -import { ToHTMLOptions } from './types'; +import { ComponentOptions, ComponentProperties, ToHTMLOptions } from './types'; import Components from './Components'; import DataResolverListener from '../../data_sources/model/DataResolverListener'; import { DataVariableProps } from '../../data_sources/model/DataVariable'; import { DataCollectionStateMap } from '../../data_sources/model/data_collection/types'; -import ComponentWithCollectionsState, { DataVariableMap } from '../../data_sources/model/ComponentWithCollectionsState'; - -export const keyRootData = '__rootData'; +import ComponentWithCollectionsState, { + DataSourceRecords, +} from '../../data_sources/model/ComponentWithCollectionsState'; +import { keyRootData } from '../constants'; +type ResolverCurrentItemType = string | number | undefined; export default class ComponentWrapper extends ComponentWithCollectionsState { dataSourceWatcher?: DataResolverListener; + _resolverCurrentItem: ResolverCurrentItemType; get defaults() { return { @@ -40,13 +43,13 @@ export default class ComponentWrapper extends ComponentWithCollectionsState { this.onCollectionsStateMapUpdate(this.getCollectionsStateMap()); @@ -128,43 +140,23 @@ export default class ComponentWrapper extends ComponentWithCollectionsState