Browse Source

Up wrapper api collections (#6664)

* Add getCollectionsState to ComponentWrapper

* Add DataFieldPrimitiveType to DataSourceManager module
release-docs-v0.22.7
Artur Arseniev 2 months ago
committed by GitHub
parent
commit
2f43b5cfb4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      packages/core/src/data_sources/index.ts
  2. 2
      packages/core/src/data_sources/model/ComponentWithCollectionsState.ts
  3. 12
      packages/core/src/data_sources/model/DataVariable.ts
  4. 12
      packages/core/src/data_sources/types.ts
  5. 60
      packages/core/src/dom_components/model/ComponentWrapper.ts
  6. 4
      packages/core/test/specs/dom_components/model/ComponentWrapper.ts

10
packages/core/src/data_sources/index.ts

@ -36,7 +36,14 @@ import { DataCollectionStateType } from './model/data_collection/types';
import DataRecord from './model/DataRecord'; import DataRecord from './model/DataRecord';
import DataSource from './model/DataSource'; import DataSource from './model/DataSource';
import DataSources from './model/DataSources'; import DataSources from './model/DataSources';
import { DataCollectionKeys, DataComponentTypes, DataRecordProps, DataSourceProps, DataSourcesEvents } from './types'; import {
DataCollectionKeys,
DataComponentTypes,
DataFieldPrimitiveType,
DataRecordProps,
DataSourceProps,
DataSourcesEvents,
} from './types';
export default class DataSourceManager extends ItemManagerModule<DataSourcesConfig & ModuleConfig, DataSources> { export default class DataSourceManager extends ItemManagerModule<DataSourcesConfig & ModuleConfig, DataSources> {
storageKey = 'dataSources'; storageKey = 'dataSources';
@ -44,6 +51,7 @@ export default class DataSourceManager extends ItemManagerModule<DataSourcesConf
dataComponentTypes = DataComponentTypes; dataComponentTypes = DataComponentTypes;
dataCollectionKeys = DataCollectionKeys; dataCollectionKeys = DataCollectionKeys;
dataCollectionStateTypes = DataCollectionStateType; dataCollectionStateTypes = DataCollectionStateType;
dataFieldPrimitiveType = DataFieldPrimitiveType;
dataOperationTypes = { dataOperationTypes = {
any: AnyTypeOperation, any: AnyTypeOperation,
boolean: BooleanOperation, boolean: BooleanOperation,

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

@ -82,7 +82,7 @@ export default class ComponentWithCollectionsState<DataResolverType> extends Com
this.onCollectionsStateMapUpdate(this.collectionsStateMap); this.onCollectionsStateMapUpdate(this.collectionsStateMap);
} }
protected getDataSourceItems(): DataSourceRecords { getDataSourceItems(): DataSourceRecords {
const { dataSourceProps } = this; const { dataSourceProps } = this;
if (!dataSourceProps) return []; 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') { if (variableType === 'currentItem') {
return ( return DataVariable.resolveCurrentItem(collectionItem as DataCollectionState, path) ?? defaultValue;
DataVariable.resolveCurrentItem(collectionItem as DataCollectionState, path, collectionId, em) ?? defaultValue
);
} }
const state = collectionItem as DataCollectionState; const state = collectionItem as DataCollectionState;
return state[variableType] ?? defaultValue; return state[variableType] ?? defaultValue;
} }
private static resolveCurrentItem( private static resolveCurrentItem(collectionItem: DataCollectionState, path: string | undefined) {
collectionItem: DataCollectionState,
path: string | undefined,
collectionId: string,
em: EditorModel,
) {
const currentItem = collectionItem.currentItem; const currentItem = collectionItem.currentItem;
if (!currentItem) { if (!currentItem) {
em.logError(`Current item is missing for collection: ${collectionId}`);
return; return;
} }

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

@ -86,28 +86,28 @@ export interface DataFieldSchemaBase<T = unknown> {
} }
export interface DataFieldSchemaString extends DataFieldSchemaBase<string> { export interface DataFieldSchemaString extends DataFieldSchemaBase<string> {
type: DataFieldPrimitiveType.string; type: `${DataFieldPrimitiveType.string}`;
enum?: string[]; enum?: string[];
} }
export interface DataFieldSchemaNumber extends DataFieldSchemaBase<number> { export interface DataFieldSchemaNumber extends DataFieldSchemaBase<number> {
type: DataFieldPrimitiveType.number; type: `${DataFieldPrimitiveType.number}`;
} }
export interface DataFieldSchemaBoolean extends DataFieldSchemaBase<boolean> { export interface DataFieldSchemaBoolean extends DataFieldSchemaBase<boolean> {
type: DataFieldPrimitiveType.boolean; type: `${DataFieldPrimitiveType.boolean}`;
} }
export interface DataFieldSchemaDate extends DataFieldSchemaBase<Date> { export interface DataFieldSchemaDate extends DataFieldSchemaBase<Date> {
type: DataFieldPrimitiveType.date; type: `${DataFieldPrimitiveType.date}`;
} }
export interface DataFieldSchemaJSON extends DataFieldSchemaBase<any> { export interface DataFieldSchemaJSON extends DataFieldSchemaBase<any> {
type: DataFieldPrimitiveType.json; type: `${DataFieldPrimitiveType.json}`;
} }
export interface DataFieldSchemaRelation extends DataFieldSchemaBase { export interface DataFieldSchemaRelation extends DataFieldSchemaBase {
type: DataFieldPrimitiveType.relation; type: `${DataFieldPrimitiveType.relation}`;
/** /**
* The target data source ID * 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 ComponentWithCollectionsState from '../../data_sources/model/ComponentWithCollectionsState';
import DataResolverListener from '../../data_sources/model/DataResolverListener'; import DataResolverListener from '../../data_sources/model/DataResolverListener';
import { DataVariableProps } from '../../data_sources/model/DataVariable'; 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 { DataCollectionKeys } from '../../data_sources/types';
import { attrToString } from '../../utils/dom'; import { attrToString } from '../../utils/dom';
import Component from './Component'; import Component from './Component';
@ -14,7 +14,7 @@ type ResolverCurrentItemType = string | number;
export default class ComponentWrapper extends ComponentWithCollectionsState<DataVariableProps> { export default class ComponentWrapper extends ComponentWithCollectionsState<DataVariableProps> {
dataSourceWatcher?: DataResolverListener; dataSourceWatcher?: DataResolverListener;
private _resolverCurrentItem?: ResolverCurrentItemType = 0; private _resolverCurrentItem: ResolverCurrentItemType = 0;
private _isWatchingCollectionStateMap = false; private _isWatchingCollectionStateMap = false;
get defaults() { get defaults() {
@ -133,6 +133,43 @@ export default class ComponentWrapper extends ComponentWithCollectionsState<Data
this.resolverCurrentItem = value; 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() { protected onDataSourceChange() {
this.onCollectionsStateMapUpdate(this.getCollectionsStateMap()); this.onCollectionsStateMapUpdate(this.getCollectionsStateMap());
} }
@ -156,23 +193,10 @@ export default class ComponentWrapper extends ComponentWithCollectionsState<Data
} }
private getCollectionsStateMap(): DataCollectionStateMap { private getCollectionsStateMap(): DataCollectionStateMap {
const { dataResolverPath, resolverCurrentItem, em } = this; if (!this.dataResolverPath) return {};
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;
return { return {
[collectionId]: { [DataCollectionKeys.rootData]: this.getCollectionsState(),
collectionId,
currentItem,
},
} as DataCollectionStateMap; } 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', () => { test('wrapper should handle objects as collection state', () => {
wrapper.setDataResolver(createDataResolver('contentDataSource.productsById.data')); wrapper.setDataResolver(createDataResolver('contentDataSource.productsById.data'));
wrapper.setResolverCurrentItem('product1'); wrapper.setResolverCurrentItem('product2');
const child = appendChildWithTitle('title'); 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', () => { test('wrapper should handle default data source records', () => {

Loading…
Cancel
Save