Browse Source

Align component wrapper resolver with collections (#6653)

release-v0.22.14
Artur Arseniev 3 months ago
committed by GitHub
parent
commit
f59e981f76
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 9
      packages/core/src/data_sources/index.ts
  2. 22
      packages/core/src/data_sources/model/DataVariable.ts
  3. 4
      packages/core/src/data_sources/types.ts
  4. 1
      packages/core/src/dom_components/constants.ts
  5. 88
      packages/core/src/dom_components/model/Component.ts
  6. 10
      packages/core/src/dom_components/model/ComponentWrapper.ts
  7. 8
      packages/core/test/specs/dom_components/model/ComponentWrapper.ts

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

@ -36,12 +36,13 @@ 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 { DataComponentTypes, DataRecordProps, DataSourceProps, DataSourcesEvents } from './types'; import { DataCollectionKeys, DataComponentTypes, 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';
events = DataSourcesEvents; events = DataSourcesEvents;
dataComponentTypes = DataComponentTypes; dataComponentTypes = DataComponentTypes;
dataCollectionKeys = DataCollectionKeys;
dataCollectionStateTypes = DataCollectionStateType; dataCollectionStateTypes = DataCollectionStateType;
dataOperationTypes = { dataOperationTypes = {
any: AnyTypeOperation, any: AnyTypeOperation,
@ -104,8 +105,8 @@ export default class DataSourceManager extends ItemManagerModule<DataSourcesConf
* @returns {any} * @returns {any}
* const value = dsm.getValue('ds_id.record_id.propName', 'defaultValue'); * const value = dsm.getValue('ds_id.record_id.propName', 'defaultValue');
*/ */
getValue(path: string | string[], defValue?: any) { getValue(path: string | string[], defValue?: any, opts?: { context?: Record<string, any> }) {
return get(this.getContext(), path, defValue); return get(opts?.context || this.getContext(), path, defValue);
} }
/** /**
@ -130,7 +131,7 @@ export default class DataSourceManager extends ItemManagerModule<DataSourcesConf
return false; return false;
} }
private getContext() { getContext() {
return this.all.reduce((acc, ds) => { return this.all.reduce((acc, ds) => {
acc[ds.id] = ds.records.reduce((accR, dr, i) => { acc[ds.id] = ds.records.reduce((accR, dr, i) => {
const dataRecord = dr; const dataRecord = dr;

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

@ -1,14 +1,8 @@
import { Model } from '../../common'; import { Model } from '../../common';
import { keyRootData } from '../../dom_components/constants';
import EditorModel from '../../editor/model/Editor'; import EditorModel from '../../editor/model/Editor';
import { DataComponentTypes } from '../types'; import { DataComponentTypes } from '../types';
import { isDataVariable } from '../utils'; import { isDataVariable } from '../utils';
import { import { DataCollectionState, DataCollectionStateMap, DataCollectionStateType } from './data_collection/types';
DataCollectionStateMap,
DataCollectionState,
DataCollectionStateType,
RootDataType,
} from './data_collection/types';
export const DataVariableType = DataComponentTypes.variable as const; export const DataVariableType = DataComponentTypes.variable as const;
@ -163,18 +157,15 @@ export default class DataVariable extends Model<DataVariableProps> {
const collectionItem = collectionsStateMap[collectionId]; const collectionItem = collectionsStateMap[collectionId];
if (!collectionItem) return defaultValue; if (!collectionItem) return defaultValue;
if (collectionId === keyRootData) {
const root = collectionItem as RootDataType;
return path ? root?.[path as keyof RootDataType] : root;
}
if (!variableType) { if (!variableType) {
em.logError(`Missing collection variable type for collection: ${collectionId}`); em.logError(`Missing collection variable type for collection: ${collectionId}`);
return defaultValue; return defaultValue;
} }
if (variableType === 'currentItem') { if (variableType === 'currentItem') {
return DataVariable.resolveCurrentItem(collectionItem as DataCollectionState, path, collectionId, em); return (
DataVariable.resolveCurrentItem(collectionItem as DataCollectionState, path, collectionId, em) ?? defaultValue
);
} }
const state = collectionItem as DataCollectionState; const state = collectionItem as DataCollectionState;
@ -190,7 +181,7 @@ export default class DataVariable extends Model<DataVariableProps> {
const currentItem = collectionItem.currentItem; const currentItem = collectionItem.currentItem;
if (!currentItem) { if (!currentItem) {
em.logError(`Current item is missing for collection: ${collectionId}`); em.logError(`Current item is missing for collection: ${collectionId}`);
return ''; return;
} }
if (currentItem.type === DataVariableType) { if (currentItem.type === DataVariableType) {
@ -199,8 +190,7 @@ export default class DataVariable extends Model<DataVariableProps> {
} }
if (path && !(currentItem as any)[path]) { if (path && !(currentItem as any)[path]) {
em.logError(`Path not found in current item: ${path} for collection: ${collectionId}`); return;
return '';
} }
return path ? (currentItem as any)[path] : currentItem; return path ? (currentItem as any)[path] : currentItem;

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

@ -22,6 +22,10 @@ export enum DataComponentTypes {
collectionItem = 'data-collection-item', collectionItem = 'data-collection-item',
} }
export enum DataCollectionKeys {
rootData = '__rootData',
}
export interface DataRecordProps extends ObjectAny { export interface DataRecordProps extends ObjectAny {
/** /**
* Record id. * Record id.

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

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

88
packages/core/src/dom_components/model/Component.ts

@ -1,60 +1,53 @@
import { Model, ModelDestroyOptions } from 'backbone';
import { import {
isUndefined, bindAll,
isFunction, forEach,
has,
isArray, isArray,
isEmpty,
isBoolean, isBoolean,
has, isEmpty,
isFunction,
isString, isString,
forEach, isUndefined,
result,
bindAll,
keys, keys,
result,
} from 'underscore'; } from 'underscore';
import { import Frame from '../../canvas/model/Frame';
shallowDiff, import { AddOptions, ExtractMethods, ObjectAny, PrevToNewIdMap, SetOptions } from '../../common';
capitalize, import CssRule, { CssRuleJSON } from '../../css_composer/model/CssRule';
isEmptyObj, import { DataCollectionStateMap } from '../../data_sources/model/data_collection/types';
isObject, import { DataCollectionKeys } from '../../data_sources/types';
toLowerCase, import { checkAndGetSyncableCollectionItemId } from '../../data_sources/utils';
escapeAltQuoteAttrValue,
escapeAttrValue,
} from '../../utils/mixins';
import StyleableModel, { import StyleableModel, {
GetStyleOpts, GetStyleOpts,
StyleProps, StyleProps,
UpdateStyleOptions, UpdateStyleOptions,
} from '../../domain_abstract/model/StyleableModel'; } from '../../domain_abstract/model/StyleableModel';
import { Model, ModelDestroyOptions } from 'backbone'; import EditorModel from '../../editor/model/Editor';
import Components from './Components'; import ItemView from '../../navigator/view/ItemView';
import Selector from '../../selector_manager/model/Selector'; import Selector from '../../selector_manager/model/Selector';
import Selectors from '../../selector_manager/model/Selectors'; import Selectors from '../../selector_manager/model/Selectors';
import Trait from '../../trait_manager/model/Trait';
import Traits from '../../trait_manager/model/Traits'; import Traits from '../../trait_manager/model/Traits';
import EditorModel from '../../editor/model/Editor'; import { TraitProperties } from '../../trait_manager/types';
import { import {
ComponentAdd, capitalize,
ComponentDefinition, escapeAltQuoteAttrValue,
ComponentDefinitionDefined, escapeAttrValue,
ComponentOptions, isEmptyObj,
ComponentProperties, isObject,
DragMode, shallowDiff,
ResetComponentsOptions, toLowerCase,
SymbolToUpOptions, } from '../../utils/mixins';
ToHTMLOptions,
} from './types';
import Frame from '../../canvas/model/Frame';
import { DomComponentsConfig } from '../config/config'; import { DomComponentsConfig } from '../config/config';
import ComponentView from '../view/ComponentView';
import { AddOptions, ExtractMethods, ObjectAny, PrevToNewIdMap, SetOptions } from '../../common';
import CssRule, { CssRuleJSON } from '../../css_composer/model/CssRule';
import Trait from '../../trait_manager/model/Trait';
import { ToolbarButtonProps } from './ToolbarButton';
import { TraitProperties } from '../../trait_manager/types';
import { ActionLabelComponents, ComponentsEvents } from '../types'; import { ActionLabelComponents, ComponentsEvents } from '../types';
import ItemView from '../../navigator/view/ItemView'; import ComponentView from '../view/ComponentView';
import Components from './Components';
import { DataWatchersOptions } from './ModelResolverWatcher';
import { import {
getSymbolMain,
getSymbolInstances, getSymbolInstances,
getSymbolMain,
getSymbolsToUpdate,
initSymbol, initSymbol,
isSymbol, isSymbol,
isSymbolMain, isSymbolMain,
@ -62,12 +55,19 @@ import {
updateSymbolCls, updateSymbolCls,
updateSymbolComps, updateSymbolComps,
updateSymbolProps, updateSymbolProps,
getSymbolsToUpdate,
} from './SymbolUtils'; } from './SymbolUtils';
import { DataWatchersOptions } from './ModelResolverWatcher'; import { ToolbarButtonProps } from './ToolbarButton';
import { DataCollectionStateMap } from '../../data_sources/model/data_collection/types'; import {
import { checkAndGetSyncableCollectionItemId } from '../../data_sources/utils'; ComponentAdd,
import { keyRootData } from '../constants'; ComponentDefinition,
ComponentDefinitionDefined,
ComponentOptions,
ComponentProperties,
DragMode,
ResetComponentsOptions,
SymbolToUpOptions,
ToHTMLOptions,
} from './types';
export interface IComponent extends ExtractMethods<Component> {} export interface IComponent extends ExtractMethods<Component> {}
export interface SetAttrOptions extends SetOptions, UpdateStyleOptions, DataWatchersOptions {} export interface SetAttrOptions extends SetOptions, UpdateStyleOptions, DataWatchersOptions {}
@ -446,7 +446,7 @@ export default class Component extends StyleableModel<ComponentProperties> {
this.emitWithEditor(ComponentsEvents.styleUpdate, this, pros); this.emitWithEditor(ComponentsEvents.styleUpdate, this, pros);
styleKeys.forEach((key) => this.emitWithEditor(`${ComponentsEvents.styleUpdateProperty}${key}`, this, pros)); styleKeys.forEach((key) => this.emitWithEditor(`${ComponentsEvents.styleUpdateProperty}${key}`, this, pros));
const parentCollectionIds = Object.keys(collectionsStateMap).filter((key) => key !== keyRootData); const parentCollectionIds = Object.keys(collectionsStateMap).filter((key) => key !== DataCollectionKeys.rootData);
if (parentCollectionIds.length === 0) return; if (parentCollectionIds.length === 0) return;

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

@ -3,8 +3,8 @@ import ComponentWithCollectionsState from '../../data_sources/model/ComponentWit
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 } from '../../data_sources/model/data_collection/types';
import { DataCollectionKeys } from '../../data_sources/types';
import { attrToString } from '../../utils/dom'; import { attrToString } from '../../utils/dom';
import { keyRootData } from '../constants';
import Component from './Component'; import Component from './Component';
import ComponentHead, { type as typeHead } from './ComponentHead'; import ComponentHead, { type as typeHead } from './ComponentHead';
import Components from './Components'; import Components from './Components';
@ -160,15 +160,19 @@ export default class ComponentWrapper extends ComponentWithCollectionsState<Data
const dsm = em.DataSources; const dsm = em.DataSources;
if (!dataResolverPath) return {}; if (!dataResolverPath) return {};
const collectionId = DataCollectionKeys.rootData;
const allItems = this.getDataSourceItems() as any; const allItems = this.getDataSourceItems() as any;
const selectedItems = isNumber(resolverCurrentItem) const currentItem = isNumber(resolverCurrentItem)
? allItems[resolverCurrentItem] ? allItems[resolverCurrentItem]
: isString(resolverCurrentItem) : isString(resolverCurrentItem)
? dsm.getValue(`${dataResolverPath}.${resolverCurrentItem}`) ? dsm.getValue(`${dataResolverPath}.${resolverCurrentItem}`)
: allItems; : allItems;
return { return {
[keyRootData]: selectedItems, [collectionId]: {
collectionId,
currentItem,
},
} as DataCollectionStateMap; } as DataCollectionStateMap;
} }

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

@ -1,7 +1,7 @@
import { DataRecord, DataSourceManager } from '../../../../src'; import { DataRecord, DataSourceManager } from '../../../../src';
import { DataCollectionStateType } from '../../../../src/data_sources/model/data_collection/types';
import { DataVariableProps, DataVariableType } from '../../../../src/data_sources/model/DataVariable'; import { DataVariableProps, DataVariableType } from '../../../../src/data_sources/model/DataVariable';
import { DataComponentTypes } from '../../../../src/data_sources/types'; import { DataCollectionKeys, DataComponentTypes } from '../../../../src/data_sources/types';
import { keyRootData } from '../../../../src/dom_components/constants';
import Component from '../../../../src/dom_components/model/Component'; import Component from '../../../../src/dom_components/model/Component';
import ComponentHead from '../../../../src/dom_components/model/ComponentHead'; import ComponentHead from '../../../../src/dom_components/model/ComponentHead';
import ComponentWrapper from '../../../../src/dom_components/model/ComponentWrapper'; import ComponentWrapper from '../../../../src/dom_components/model/ComponentWrapper';
@ -10,6 +10,7 @@ import EditorModel from '../../../../src/editor/model/Editor';
import { setupTestEditor } from '../../../common'; import { setupTestEditor } from '../../../common';
describe('ComponentWrapper', () => { describe('ComponentWrapper', () => {
const keyRootData = DataCollectionKeys.rootData;
let em: Editor; let em: Editor;
beforeEach(() => { beforeEach(() => {
@ -101,13 +102,14 @@ describe('ComponentWrapper', () => {
type: 'default', type: 'default',
title: { title: {
type: DataComponentTypes.variable, type: DataComponentTypes.variable,
variableType: DataCollectionStateType.currentItem,
collectionId: keyRootData, collectionId: keyRootData,
path, path,
}, },
components: { components: {
tagName: 'span', tagName: 'span',
type: DataComponentTypes.variable, type: DataComponentTypes.variable,
dataResolver: { collectionId: keyRootData, path }, dataResolver: { collectionId: keyRootData, variableType: DataCollectionStateType.currentItem, path },
}, },
})[0]; })[0];

Loading…
Cancel
Save