Browse Source

add resolverCurrentItem

pages-datasources
mohamedsalem401 1 year ago
parent
commit
7df0c9f9a8
  1. 4
      packages/core/src/data_sources/model/ComponentWithCollectionsState.ts
  2. 39
      packages/core/src/data_sources/model/DataVariable.ts
  3. 6
      packages/core/src/data_sources/model/data_collection/types.ts
  4. 1
      packages/core/src/dom_components/constants.ts
  5. 70
      packages/core/src/dom_components/model/ComponentWrapper.ts
  6. 3
      packages/core/test/specs/dom_components/model/ComponentWrapper.ts

4
packages/core/src/data_sources/model/ComponentWithCollectionsState.ts

@ -11,6 +11,8 @@ import { isArray } from 'underscore';
export type DataVariableMap = Record<string, DataVariableProps>;
export type DataSourceRecords = DataVariableProps[] | DataVariableMap;
export default class ComponentWithCollectionsState<DataResolverType> extends Component {
collectionsStateMap: DataCollectionStateMap = {};
dataSourceWatcher?: DataResolverListener;
@ -98,7 +100,7 @@ export default class ComponentWithCollectionsState<DataResolverType> 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: {

39
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<DataVariableProps> {
);
}
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<DataVariableProps> {
path: string | undefined,
collectionId: string,
em: EditorModel,
): unknown {
) {
const currentItem = collectionItem.currentItem;
if (!currentItem) {
em.logError(`Current item is missing for collection: ${collectionId}`);

6
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> | ObjectAny;
export type DataCollectionStateMap = {
[key: string]: DataCollectionState;
} & {
__pages?: { [DataCollectionStateType.currentItem]: DataCollectionState };
[keyRootData]?: RootDataType;
};
export interface ComponentDataCollectionProps extends ComponentDefinition {

1
packages/core/src/dom_components/constants.ts

@ -0,0 +1 @@
export const keyRootData = '__rootData';

70
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<DataVariableProps> {
dataSourceWatcher?: DataResolverListener;
_resolverCurrentItem: ResolverCurrentItemType;
get defaults() {
return {
@ -40,13 +43,13 @@ export default class ComponentWrapper extends ComponentWithCollectionsState<Data
};
}
constructor(props: any, opt: any) {
constructor(props: ComponentProperties = {}, opt: ComponentOptions) {
super(props, opt);
const hasDataResolver = this.getDataResolver();
this.syncComponentsCollectionState();
if (hasDataResolver) {
this.syncComponentsCollectionState();
this.onCollectionsStateMapUpdate(this.getCollectionsStateMap());
}
}
@ -119,6 +122,15 @@ export default class ComponentWrapper extends ComponentWithCollectionsState<Data
this.onCollectionsStateMapUpdate(collectionsStateMap);
}
get resolverCurrentItem() {
return this._resolverCurrentItem;
}
set resolverCurrentItem(value: ResolverCurrentItemType) {
this._resolverCurrentItem = value;
this.onCollectionsStateMapUpdate(this.getCollectionsStateMap());
}
protected listenToPropsChange() {
this.on(`change:dataResolver`, () => {
this.onCollectionsStateMapUpdate(this.getCollectionsStateMap());
@ -128,43 +140,23 @@ export default class ComponentWrapper extends ComponentWithCollectionsState<Data
this.listenToDataSource();
}
private getCollectionsStateMapForItem(items: DataVariableProps[] | DataVariableMap, key: number | string) {
const totalItems = Object.keys(items).length;
let item: DataVariableProps = (items as any)[key];
const numericKey = typeof key === 'string' ? Object.keys(items).indexOf(key) : key;
const offset = numericKey - 0;
const remainingItems = totalItems - (1 + offset);
const collectionState = {
collectionId: keyRootData,
currentIndex: numericKey,
currentItem: item,
currentKey: key,
startIndex: 0,
endIndex: totalItems - 1,
totalItems: totalItems,
remainingItems,
};
private getCollectionsStateMap(): DataCollectionStateMap {
const { dataSourcePath, resolverCurrentItem } = this;
return collectionState;
}
if (!dataSourcePath) return {};
private getCollectionsStateMap(): DataCollectionStateMap {
const path = this.dataSourcePath;
if (!path) return this.collectionsStateMap;
const items = this.getDataSourceItems();
const pages = [];
const length = Object.keys(items).length;
for (let index = 0; index <= length; index++) {
const key = this.getItemKey(items, index);
const collectionsStateMap = this.getCollectionsStateMapForItem(items, key);
pages.push(collectionsStateMap);
}
const collectionsStateMap = {
__pages: { currentItem: pages },
};
if (!isUndefined(resolverCurrentItem)) {
const selected = items[resolverCurrentItem as keyof DataSourceRecords];
return {
[keyRootData]: selected,
} as DataCollectionStateMap;
}
return collectionsStateMap as any;
return {
[keyRootData]: items,
} as DataCollectionStateMap;
}
__postAdd() {

3
packages/core/test/specs/dom_components/model/ComponentWrapper.ts

@ -2,7 +2,8 @@ import { DataSourceManager, DataSource, DataRecord } from '../../../../src';
import { DataVariableProps, DataVariableType } from '../../../../src/data_sources/model/DataVariable';
import Component from '../../../../src/dom_components/model/Component';
import ComponentHead from '../../../../src/dom_components/model/ComponentHead';
import ComponentWrapper, { keyRootData } from '../../../../src/dom_components/model/ComponentWrapper';
import ComponentWrapper from '../../../../src/dom_components/model/ComponentWrapper';
import { keyRootData } from '../../../../src/dom_components/constants';
import Editor from '../../../../src/editor';
import EditorModel from '../../../../src/editor/model/Editor';
import { setupTestEditor } from '../../../common';

Loading…
Cancel
Save