mirror of https://github.com/artf/grapesjs.git
10 changed files with 252 additions and 111 deletions
@ -0,0 +1,91 @@ |
|||
import { CollectionVariableDefinition } from '../../../../test/specs/dom_components/model/ComponentTypes'; |
|||
import { Model } from '../../../common'; |
|||
import EditorModel from '../../../editor/model/Editor'; |
|||
import DataVariable, { DataVariableType } from '../DataVariable'; |
|||
import { keyInnerCollectionState } from './constants'; |
|||
import { CollectionsStateMap } from './types'; |
|||
|
|||
export default class CollectionVariable extends Model<CollectionVariableDefinition> { |
|||
em: EditorModel; |
|||
collectionsStateMap: CollectionsStateMap; |
|||
dataVariable?: DataVariable; |
|||
|
|||
constructor( |
|||
attrs: CollectionVariableDefinition, |
|||
options: { |
|||
em: EditorModel; |
|||
collectionsStateMap: CollectionsStateMap; |
|||
}, |
|||
) { |
|||
super(attrs, options); |
|||
this.em = options.em; |
|||
this.collectionsStateMap = options.collectionsStateMap; |
|||
if (!this.collectionsStateMap) { |
|||
throw new Error('collectionsStateMap is required'); |
|||
} |
|||
|
|||
this.updateDataVariable(); |
|||
} |
|||
|
|||
getDataValue() { |
|||
const { resolvedValue } = this.updateDataVariable(); |
|||
|
|||
if (resolvedValue?.type === DataVariableType) { |
|||
return this.dataVariable!.getDataValue(); |
|||
} |
|||
return resolvedValue; |
|||
} |
|||
|
|||
private updateDataVariable() { |
|||
const resolvedValue = resolveCollectionVariable( |
|||
this.attributes as CollectionVariableDefinition, |
|||
this.collectionsStateMap, |
|||
); |
|||
|
|||
let dataVariable; |
|||
if (resolvedValue?.type === DataVariableType) { |
|||
dataVariable = new DataVariable(resolvedValue, { em: this.em }); |
|||
this.dataVariable = dataVariable; |
|||
} |
|||
|
|||
return { resolvedValue, dataVariable }; |
|||
} |
|||
|
|||
destroy() { |
|||
return this.dataVariable?.destroy?.() || super.destroy(); |
|||
} |
|||
} |
|||
|
|||
function resolveCollectionVariable( |
|||
collectionVariableDefinition: CollectionVariableDefinition, |
|||
collectionsStateMap: CollectionsStateMap, |
|||
) { |
|||
const { collection_name = keyInnerCollectionState, variable_type, path } = collectionVariableDefinition; |
|||
const collectionItem = collectionsStateMap[collection_name]; |
|||
if (!collectionItem) { |
|||
throw new Error(`Collection not found: ${collection_name}`); |
|||
} |
|||
if (!variable_type) { |
|||
throw new Error(`Missing collection variable type for collection: ${collection_name}`); |
|||
} |
|||
|
|||
if (variable_type === 'current_item') { |
|||
const valueIsDataVariable = collectionItem.current_item?.type === DataVariableType; |
|||
if (valueIsDataVariable) { |
|||
const currentItem_path = collectionItem.current_item.path; |
|||
const resolvedPath = currentItem_path ? `${currentItem_path}.${path}` : path; |
|||
return { |
|||
...collectionItem.current_item, |
|||
path: resolvedPath, |
|||
}; |
|||
} else if (!!path) { |
|||
if (!collectionItem.current_item?.[path]) { |
|||
throw new Error(`Path not found in current item: ${path} for collection: ${collection_name}`); |
|||
} |
|||
|
|||
return collectionItem.current_item[path]; |
|||
} |
|||
} |
|||
|
|||
return collectionItem[variable_type]; |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
export const CollectionComponentType = 'collection-component'; |
|||
export const keyCollectionDefinition = 'collectionDefinition'; |
|||
export const keyInnerCollectionState = 'innerCollectionState'; |
|||
export const CollectionVariableType = 'parent-collection-variable'; |
|||
@ -0,0 +1,34 @@ |
|||
import { CollectionComponentType } from './constants'; |
|||
|
|||
import { ComponentDefinition } from '../../../dom_components/model/types'; |
|||
import { CollectionVariableDefinition } from '../../../../test/specs/dom_components/model/ComponentTypes'; |
|||
import { DataVariableDefinition } from '../DataVariable'; |
|||
import { ConditionDefinition } from '../conditional_variables/DataCondition'; |
|||
|
|||
type CollectionDataSource = any[] | DataVariableDefinition | CollectionVariableDefinition; |
|||
type CollectionConfig = { |
|||
start_index?: number; |
|||
end_index?: number | ConditionDefinition; |
|||
dataSource: CollectionDataSource; |
|||
}; |
|||
|
|||
export type CollectionState = { |
|||
current_index: number; |
|||
start_index: number; |
|||
current_item: any; |
|||
end_index: number; |
|||
collection_name?: string; |
|||
total_items: number; |
|||
remaining_items: number; |
|||
}; |
|||
|
|||
export type CollectionsStateMap = { |
|||
[key: string]: CollectionState; |
|||
}; |
|||
|
|||
export type CollectionDefinition = { |
|||
type: typeof CollectionComponentType; |
|||
collection_name?: string; |
|||
config: CollectionConfig; |
|||
block: ComponentDefinition; |
|||
}; |
|||
Loading…
Reference in new issue