Browse Source

Add getCollectionsState to ComponentWrapper

up-wrapper-api-collections
Artur Arseniev 2 months ago
parent
commit
616656c16e
  1. 2
      packages/core/src/data_sources/model/ComponentWithCollectionsState.ts
  2. 12
      packages/core/src/data_sources/model/DataVariable.ts
  3. 12
      packages/core/src/data_sources/types.ts
  4. 60
      packages/core/src/dom_components/model/ComponentWrapper.ts
  5. 4
      packages/core/test/specs/dom_components/model/ComponentWrapper.ts

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

@ -82,7 +82,7 @@ export default class ComponentWithCollectionsState<DataResolverType> extends Com
this.onCollectionsStateMapUpdate(this.collectionsStateMap);
}
protected getDataSourceItems(): DataSourceRecords {
getDataSourceItems(): DataSourceRecords {
const { dataSourceProps } = this;
if (!dataSourceProps) return [];

12
packages/core/src/data_sources/model/DataVariable.ts

@ -163,24 +163,16 @@ export default class DataVariable extends Model<DataVariableProps> {
}
if (variableType === 'currentItem') {
return (
DataVariable.resolveCurrentItem(collectionItem as DataCollectionState, path, collectionId, em) ?? defaultValue
);
return DataVariable.resolveCurrentItem(collectionItem as DataCollectionState, path) ?? defaultValue;
}
const state = collectionItem as DataCollectionState;
return state[variableType] ?? defaultValue;
}
private static resolveCurrentItem(
collectionItem: DataCollectionState,
path: string | undefined,
collectionId: string,
em: EditorModel,
) {
private static resolveCurrentItem(collectionItem: DataCollectionState, path: string | undefined) {
const currentItem = collectionItem.currentItem;
if (!currentItem) {
em.logError(`Current item is missing for collection: ${collectionId}`);
return;
}

12
packages/core/src/data_sources/types.ts

@ -86,28 +86,28 @@ export interface DataFieldSchemaBase<T = unknown> {
}
export interface DataFieldSchemaString extends DataFieldSchemaBase<string> {
type: DataFieldPrimitiveType.string;
type: `${DataFieldPrimitiveType.string}`;
enum?: string[];
}
export interface DataFieldSchemaNumber extends DataFieldSchemaBase<number> {
type: DataFieldPrimitiveType.number;
type: `${DataFieldPrimitiveType.number}`;
}
export interface DataFieldSchemaBoolean extends DataFieldSchemaBase<boolean> {
type: DataFieldPrimitiveType.boolean;
type: `${DataFieldPrimitiveType.boolean}`;
}
export interface DataFieldSchemaDate extends DataFieldSchemaBase<Date> {
type: DataFieldPrimitiveType.date;
type: `${DataFieldPrimitiveType.date}`;
}
export interface DataFieldSchemaJSON extends DataFieldSchemaBase<any> {
type: DataFieldPrimitiveType.json;
type: `${DataFieldPrimitiveType.json}`;
}
export interface DataFieldSchemaRelation extends DataFieldSchemaBase {
type: DataFieldPrimitiveType.relation;
type: `${DataFieldPrimitiveType.relation}`;
/**
* The target data source ID
*/

60
packages/core/src/dom_components/model/ComponentWrapper.ts

@ -1,8 +1,8 @@
import { isNumber, isString, isUndefined } from 'underscore';
import { all, isArray, isNumber, isUndefined } from 'underscore';
import ComponentWithCollectionsState from '../../data_sources/model/ComponentWithCollectionsState';
import DataResolverListener from '../../data_sources/model/DataResolverListener';
import { DataVariableProps } from '../../data_sources/model/DataVariable';
import { DataCollectionStateMap } from '../../data_sources/model/data_collection/types';
import { DataCollectionStateMap, DataCollectionStateType } from '../../data_sources/model/data_collection/types';
import { DataCollectionKeys } from '../../data_sources/types';
import { attrToString } from '../../utils/dom';
import Component from './Component';
@ -14,7 +14,7 @@ type ResolverCurrentItemType = string | number;
export default class ComponentWrapper extends ComponentWithCollectionsState<DataVariableProps> {
dataSourceWatcher?: DataResolverListener;
private _resolverCurrentItem?: ResolverCurrentItemType = 0;
private _resolverCurrentItem: ResolverCurrentItemType = 0;
private _isWatchingCollectionStateMap = false;
get defaults() {
@ -133,6 +133,43 @@ export default class ComponentWrapper extends ComponentWithCollectionsState<Data
this.resolverCurrentItem = value;
}
getCollectionsState() {
const collectionId = `${DataCollectionKeys.rootData}`;
const { dataResolverPath, resolverCurrentItem } = this;
const result = { collectionId };
if (!dataResolverPath) return result;
let prevItem: Record<string, any> | undefined;
let currentItem: Record<string, any> | undefined;
let nextItem: Record<string, any> | undefined;
const allItems: Record<string, any> | Record<string, any>[] = this.getDataSourceItems();
const allItemsArray = isArray(allItems) ? allItems : Object.values(allItems || {});
let currentIndex = resolverCurrentItem;
if (isNumber(resolverCurrentItem)) {
currentItem = allItemsArray[resolverCurrentItem];
prevItem = allItemsArray[resolverCurrentItem - 1];
nextItem = allItemsArray[resolverCurrentItem + 1];
} else {
const entries = Object.entries(allItems).map(([id, value]) => ({ id, ...value }));
const idx = entries.findIndex((it) => it?.id === resolverCurrentItem);
currentIndex = idx;
currentItem = allItemsArray[idx];
prevItem = allItemsArray[idx - 1];
nextItem = allItemsArray[idx + 1];
}
return {
...result,
prevItem,
nextItem,
[DataCollectionStateType.currentItem]: currentItem,
[DataCollectionStateType.currentIndex]: currentIndex,
[DataCollectionStateType.totalItems]: allItemsArray.length,
};
}
protected onDataSourceChange() {
this.onCollectionsStateMapUpdate(this.getCollectionsStateMap());
}
@ -156,23 +193,10 @@ export default class ComponentWrapper extends ComponentWithCollectionsState<Data
}
private getCollectionsStateMap(): DataCollectionStateMap {
const { dataResolverPath, resolverCurrentItem, em } = this;
const dsm = em.DataSources;
if (!dataResolverPath) return {};
const collectionId = DataCollectionKeys.rootData;
const allItems = this.getDataSourceItems() as any;
const currentItem = isNumber(resolverCurrentItem)
? allItems[resolverCurrentItem]
: isString(resolverCurrentItem)
? dsm.getValue(`${dataResolverPath}.${resolverCurrentItem}`)
: allItems;
if (!this.dataResolverPath) return {};
return {
[collectionId]: {
collectionId,
currentItem,
},
[DataCollectionKeys.rootData]: this.getCollectionsState(),
} as DataCollectionStateMap;
}

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

@ -137,10 +137,10 @@ describe('ComponentWrapper', () => {
test('wrapper should handle objects as collection state', () => {
wrapper.setDataResolver(createDataResolver('contentDataSource.productsById.data'));
wrapper.setResolverCurrentItem('product1');
wrapper.setResolverCurrentItem('product2');
const child = appendChildWithTitle('title');
expect(child.get('title')).toBe(productsById.product1.title);
expect(child.get('title')).toBe(productsById.product2.title);
});
test('wrapper should handle default data source records', () => {

Loading…
Cancel
Save