diff --git a/packages/scene-composer/src/components/StateManager.tsx b/packages/scene-composer/src/components/StateManager.tsx index e935ae9cf..a2fea8bda 100644 --- a/packages/scene-composer/src/components/StateManager.tsx +++ b/packages/scene-composer/src/components/StateManager.tsx @@ -4,14 +4,6 @@ import { ThreeEvent } from '@react-three/fiber'; import ab2str from 'arraybuffer-to-string'; import { combineProviders, DataStream, ProviderWithViewport, TimeSeriesData } from '@iot-app-kit/core'; -import useLifecycleLogging from '../logger/react-logger/hooks/useLifecycleLogging'; -import { - AdditionalComponentData, - ExternalLibraryConfig, - KnownComponentType, - KnownSceneProperty, - SceneComposerInternalProps, -} from '../interfaces'; import { setDracoDecoder, setFeatureConfig, @@ -20,24 +12,32 @@ import { setMetricRecorder, setTwinMakerSceneMetadataModule, } from '../common/GlobalSettings'; -import { useSceneComposerId } from '../common/sceneComposerIdContext'; -import { IAnchorComponentInternal, ICameraComponentInternal, RootState, useStore, useViewOptionState } from '../store'; -import { createStandardUriModifier } from '../utils/uriModifiers'; -import sceneDocumentSnapshotCreator from '../utils/sceneDocumentSnapshotCreator'; -import { SceneLayout } from '../layouts/SceneLayout'; -import { findComponentByType } from '../utils/nodeUtils'; -import { applyDataBindingTemplate } from '../utils/dataBindingTemplateUtils'; -import { combineTimeSeriesData, convertDataStreamsToDataInput } from '../utils/dataStreamUtils'; -import useActiveCamera from '../hooks/useActiveCamera'; -import useMatterportViewer from '../hooks/useMatterportViewer'; -import { getCameraSettings } from '../utils/cameraUtils'; import { MATTERPORT_ACCESS_TOKEN, MATTERPORT_APPLICATION_KEY, MATTERPORT_ERROR, MATTERPORT_SECRET_ARN, } from '../common/constants'; -import { DisplayMessageCategory, IEntityBindingComponentInternal } from '../store/internalInterfaces'; +import { DisplayMessageCategory } from '../store/internalInterfaces'; +import { useSceneComposerId } from '../common/sceneComposerIdContext'; +import useActiveCamera from '../hooks/useActiveCamera'; +import useMatterportViewer from '../hooks/useMatterportViewer'; +import { + AdditionalComponentData, + ExternalLibraryConfig, + KnownComponentType, + KnownSceneProperty, + SceneComposerInternalProps, +} from '../interfaces'; +import { SceneLayout } from '../layouts/SceneLayout'; +import useLifecycleLogging from '../logger/react-logger/hooks/useLifecycleLogging'; +import { ICameraComponentInternal, RootState, useStore, useViewOptionState } from '../store'; +import { getCameraSettings } from '../utils/cameraUtils'; +import { getAdditionalComponentData } from '../utils/eventDataUtils'; +import { combineTimeSeriesData, convertDataStreamsToDataInput } from '../utils/dataStreamUtils'; +import { findComponentByType } from '../utils/nodeUtils'; +import sceneDocumentSnapshotCreator from '../utils/sceneDocumentSnapshotCreator'; +import { createStandardUriModifier } from '../utils/uriModifiers'; import IntlProvider from './IntlProvider'; import { LoadingProgress } from './three-fiber/LoadingProgress'; @@ -150,32 +150,8 @@ const StateManager: React.FC = ({ if (onSelectionChanged) { const node = getSceneNodeByRef(selectedSceneNodeRef); const componentTypes = node?.components.map((component) => component.type) ?? []; + const additionalComponentData: AdditionalComponentData[] = getAdditionalComponentData(node, dataBindingTemplate); - const tagComponent = findComponentByType(node, KnownComponentType.Tag) as IAnchorComponentInternal; - const entityBindingComponent = findComponentByType( - node, - KnownComponentType.EntityBinding, - ) as IEntityBindingComponentInternal; - const additionalComponentData: AdditionalComponentData[] = []; - if (tagComponent) { - additionalComponentData.push({ - chosenColor: tagComponent.chosenColor, - navLink: tagComponent.navLink, - dataBindingContext: !tagComponent.valueDataBinding?.dataBindingContext - ? undefined - : applyDataBindingTemplate(tagComponent.valueDataBinding, dataBindingTemplate), - }); - } - // Add entityID info part of additional component data - // We assumed IDataBindingMap will have only one mapping as data binding - // will always have only one entity data. - if (entityBindingComponent) { - additionalComponentData.push({ - dataBindingContext: !entityBindingComponent?.valueDataBinding?.dataBindingContext - ? undefined - : entityBindingComponent?.valueDataBinding.dataBindingContext, - }); - } onSelectionChanged({ componentTypes, nodeRef: selectedSceneNodeRef, diff --git a/packages/scene-composer/src/components/panels/AddComponentMenu.spec.tsx b/packages/scene-composer/src/components/panels/AddComponentMenu.spec.tsx index ea280249f..6c3e2b71a 100644 --- a/packages/scene-composer/src/components/panels/AddComponentMenu.spec.tsx +++ b/packages/scene-composer/src/components/panels/AddComponentMenu.spec.tsx @@ -93,7 +93,7 @@ describe('AddComponentMenu', () => { ], }); render(); - const addButton = screen.getByTestId('add-component-data-binding'); + const addButton = screen.getByTestId('add-component-entity-binding'); act(() => { fireEvent.pointerUp(addButton); @@ -105,7 +105,7 @@ describe('AddComponentMenu', () => { valueDataBinding: { dataBindingContext: '' }, }); expect(mockMetricRecorder.recordClick).toBeCalledTimes(1); - expect(mockMetricRecorder.recordClick).toBeCalledWith('add-component-data-binding'); + expect(mockMetricRecorder.recordClick).toBeCalledWith('add-component-entity-binding'); }); it('should add no addition binding to data binding component when clicked', () => { @@ -118,11 +118,11 @@ describe('AddComponentMenu', () => { ], }); render(); - expect(screen.getByTestId('add-component-data-binding')).not.toBeNull(); - screen.getByTestId('add-component-data-binding').click(); + expect(screen.getByTestId('add-component-entity-binding')).not.toBeNull(); + screen.getByTestId('add-component-entity-binding').click(); fireEvent.mouseOver(screen.getByTestId('add-component')); expect(addComponentInternal).not.toBeCalled(); - expect(mockMetricRecorder.recordClick).not.toBeCalledWith('add-component-data-binding'); + expect(mockMetricRecorder.recordClick).not.toBeCalledWith('add-component-entity-binding'); }); it('should not see add data binding item when feature is not enabled', () => { diff --git a/packages/scene-composer/src/components/panels/AddComponentMenu.tsx b/packages/scene-composer/src/components/panels/AddComponentMenu.tsx index 9d5f9b687..1ba1e108d 100644 --- a/packages/scene-composer/src/components/panels/AddComponentMenu.tsx +++ b/packages/scene-composer/src/components/panels/AddComponentMenu.tsx @@ -21,7 +21,7 @@ interface AddComponentMenuProps { enum ObjectTypes { Component = 'add-component', Overlay = 'add-component-overlay', - DataBinding = 'add-component-data-binding', + EntityBinding = 'add-component-entity-binding', } type AddComponentMenuItem = ToolbarItemOptions & { @@ -31,12 +31,12 @@ type AddComponentMenuItem = ToolbarItemOptions & { const labelStrings: { [key in ObjectTypes]: MessageDescriptor } = defineMessages({ [ObjectTypes.Component]: { defaultMessage: 'Add component', description: 'Menu Item label' }, [ObjectTypes.Overlay]: { defaultMessage: 'Overlay', description: 'Menu Item label' }, - [ObjectTypes.DataBinding]: { defaultMessage: 'Add entity binding', description: 'Menu Item label' }, + [ObjectTypes.EntityBinding]: { defaultMessage: 'Add entity binding', description: 'Menu Item label' }, }); const textStrings = defineMessages({ [ObjectTypes.Overlay]: { defaultMessage: 'Add overlay', description: 'Menu Item' }, - [ObjectTypes.DataBinding]: { defaultMessage: 'Add entity binding', description: 'Menu Item' }, + [ObjectTypes.EntityBinding]: { defaultMessage: 'Add entity binding', description: 'Menu Item' }, }); export const AddComponentMenu: React.FC = ({ onSelect }) => { @@ -76,10 +76,10 @@ export const AddComponentMenu: React.FC = ({ onSelect }) }, ] : []; - const addDataBindingItem = entityBindingComponentEnabled + const addEntityBindingItem = entityBindingComponentEnabled ? [ { - uuid: ObjectTypes.DataBinding, + uuid: ObjectTypes.EntityBinding, isDisabled: isEntityBindingComponent, }, ] @@ -91,7 +91,7 @@ export const AddComponentMenu: React.FC = ({ onSelect }) uuid: ObjectTypes.Component, }, ...addOverlayItem, - ...addDataBindingItem, + ...addEntityBindingItem, ].map(mapToMenuItem); }, [selectedSceneNodeRef, selectedSceneNode, isOverlayComponent, isTagComponent, entityBindingComponentEnabled]); @@ -114,7 +114,7 @@ export const AddComponentMenu: React.FC = ({ onSelect }) addComponentInternal(selectedSceneNodeRef, component); }, [selectedSceneNodeRef, selectedSceneNode]); - const handleAddDataBinding = useCallback(() => { + const handleAddEntityBinding = useCallback(() => { if (!selectedSceneNodeRef) return; const entityBindingComponent = findComponentByType(selectedSceneNode, KnownComponentType.EntityBinding); @@ -142,8 +142,8 @@ export const AddComponentMenu: React.FC = ({ onSelect }) type='action-select' onClick={({ uuid }) => { switch (uuid) { - case ObjectTypes.DataBinding: - handleAddDataBinding(); + case ObjectTypes.EntityBinding: + handleAddEntityBinding(); break; case ObjectTypes.Overlay: handleAddOverlay(); diff --git a/packages/scene-composer/src/components/panels/ComponentEditMenu.tsx b/packages/scene-composer/src/components/panels/ComponentEditMenu.tsx index efa19d2e8..f1e809cc3 100644 --- a/packages/scene-composer/src/components/panels/ComponentEditMenu.tsx +++ b/packages/scene-composer/src/components/panels/ComponentEditMenu.tsx @@ -9,7 +9,7 @@ import { KnownComponentType } from '../../interfaces'; import { ToolbarItem } from '../toolbars/common/ToolbarItem'; import { getGlobalSettings } from '../../common/GlobalSettings'; import { Component } from '../../models/SceneModels'; -import { IEntityBindingComponentInternal, ISceneComponentInternal } from '../../store/internalInterfaces'; +import { ISceneComponentInternal } from '../../store/internalInterfaces'; import { generateUUID } from '../../utils/mathUtils'; interface ComponentEditMenuProps { @@ -128,7 +128,7 @@ export const ComponentEditMenu: React.FC = ({ nodeRef, c } }, [nodeRef, currentComponent]); - const handleRemoveAllDataBinding = useCallback(() => { + const handleRemoveEntityBinding = useCallback(() => { if (currentComponent.type == KnownComponentType.EntityBinding) { removeComponent(nodeRef, currentComponent.ref); return; @@ -149,7 +149,7 @@ export const ComponentEditMenu: React.FC = ({ nodeRef, c handleAddDataBinding(); break; case ObjectTypes.RemoveEntityBinding: - handleRemoveAllDataBinding(); + handleRemoveEntityBinding(); break; case ObjectTypes.RemoveOverlay: removeComponent(nodeRef, currentComponent.ref); diff --git a/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/DataOverlayComponent.tsx b/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/DataOverlayComponent.tsx index 4f036784c..1e4d9ad38 100644 --- a/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/DataOverlayComponent.tsx +++ b/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/DataOverlayComponent.tsx @@ -1,7 +1,7 @@ import React, { ReactElement, useContext, useRef } from 'react'; import { Html } from '@react-three/drei'; import { useFrame } from '@react-three/fiber'; -import { Object3D } from 'three'; +import { Group } from 'three'; import { ISceneNodeInternal } from '../../../store'; import { sceneComposerIdContext } from '../../../common/sceneComposerIdContext'; @@ -18,7 +18,7 @@ export interface DataOverlayComponentProps { export const DataOverlayComponent = ({ node, component }: DataOverlayComponentProps): ReactElement => { const sceneComposerId = useContext(sceneComposerIdContext); const htmlRef = useRef(null); - const groupRef = useRef(); + const groupRef = useRef(); const getOffsetFromTag = () => { const tagComponent: IAnchorComponentInternal | undefined = node.components.find( diff --git a/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/DataOverlayContainer.tsx b/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/DataOverlayContainer.tsx index 6ad750d2f..2e5245ba5 100644 --- a/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/DataOverlayContainer.tsx +++ b/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/DataOverlayContainer.tsx @@ -5,6 +5,7 @@ import { Component } from '../../../models/SceneModels'; import { useStore, useViewOptionState } from '../../../store'; import { sceneComposerIdContext } from '../../../common/sceneComposerIdContext'; import useCallbackWhenNotPanning from '../../../hooks/useCallbackWhenNotPanning'; +import { applyDataBindingTemplate } from '../../../utils/dataBindingTemplateUtils'; import { DataOverlayRows } from './DataOverlayRows'; import { @@ -35,6 +36,10 @@ export const DataOverlayContainer = ({ component, node }: DataOverlayContainerPr const componentVisible = useViewOptionState(sceneComposerId).componentVisibilities[subType]; const initialVisibilitySkipped = useRef(false); + const onWidgetClick = useStore(sceneComposerId)((state) => state.getEditorConfig().onWidgetClick); + const isViewing = useStore(sceneComposerId)((state) => state.isViewing()); + const dataBindingTemplate = useStore(sceneComposerId)((state) => state.dataBindingTemplate); + // TODO: config.isPinned is not supported in milestone 1 // const [visible, setVisible] = useState(component.config?.isPinned || componentVisible); const [visible, setVisible] = useState(componentVisible); @@ -58,12 +63,34 @@ export const DataOverlayContainer = ({ component, node }: DataOverlayContainerPr // Same behavior as other components to select node when clicked on the panel const [onPointerDown, onPointerUp] = useCallbackWhenNotPanning( (e) => { + // Anchor only has special onClick handling in viewing mode + if (isViewing) { + if (onWidgetClick) { + const dataBindingContexts: unknown[] = []; + component.valueDataBindings.forEach((item) => { + if (item.valueDataBinding) { + dataBindingContexts.push(applyDataBindingTemplate(item.valueDataBinding, dataBindingTemplate)); + } + }); + const componentTypes = node.components.map((component) => component.type) ?? []; + onWidgetClick({ + componentTypes, + nodeRef: node.ref, + additionalComponentData: [ + { + dataBindingContexts, + }, + ], + }); + } + } + e.stopPropagation(); if (selectedSceneNodeRef !== node.ref) { setSelectedSceneNodeRef(node.ref); } }, - [selectedSceneNodeRef, node.ref], + [selectedSceneNodeRef, node.ref, onWidgetClick], ); const onClickCloseButton = useCallback( diff --git a/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/__tests__/DataOverlayComponentSnap.spec.tsx b/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/__tests__/DataOverlayComponentSnap.spec.tsx index 30faea75c..cd376f67a 100644 --- a/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/__tests__/DataOverlayComponentSnap.spec.tsx +++ b/packages/scene-composer/src/components/three-fiber/DataOverlayComponent/__tests__/DataOverlayComponentSnap.spec.tsx @@ -1,8 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; import { BoxGeometry, Group, Mesh } from 'three'; -import { Canvas } from '@react-three/fiber'; -import ReactThreeTestRenderer from '@react-three/test-renderer'; import { DataOverlayComponent } from '../DataOverlayComponent'; import { Component } from '../../../../models/SceneModels'; diff --git a/packages/scene-composer/src/interfaces/components.ts b/packages/scene-composer/src/interfaces/components.ts index 34c108acc..a019d8e71 100644 --- a/packages/scene-composer/src/interfaces/components.ts +++ b/packages/scene-composer/src/interfaces/components.ts @@ -81,10 +81,15 @@ export interface ITagData { export interface IEntityBindingInfo { dataBindingContext?: unknown; } + +export interface IDataOverlayInfo { + dataBindingContexts?: unknown[]; +} + /** * Type that can be represented by different additional component data types such as ITagData | IFutureComponentData */ -export type AdditionalComponentData = ITagData | IEntityBindingInfo; +export type AdditionalComponentData = ITagData | IEntityBindingInfo | IDataOverlayInfo; /** * Callback signature for selection of with Widgets. diff --git a/packages/scene-composer/src/utils/eventDataUtils.spec.ts b/packages/scene-composer/src/utils/eventDataUtils.spec.ts new file mode 100644 index 000000000..fad009811 --- /dev/null +++ b/packages/scene-composer/src/utils/eventDataUtils.spec.ts @@ -0,0 +1,205 @@ +import { AdditionalComponentData, KnownComponentType, IDataBindingTemplate } from '../interfaces'; +import { + IAnchorComponentInternal, + IDataOverlayComponentInternal, + IEntityBindingComponentInternal, + ISceneNodeInternal, + ISubModelRefComponentInternal, +} from '../store'; + +import { getAdditionalComponentData } from './eventDataUtils'; + +describe('eventDataUtils', () => { + let mockDataBindingTemplate: IDataBindingTemplate; + let node: ISceneNodeInternal; + + beforeEach(() => { + mockDataBindingTemplate = { + sel_entity1: 'my_entity_id', + sel_comp1: 'my_component_name', + fakeKey1Template: 'fakeKey1Value', + fakeKey2Template: 'fakeKey2Value', + }; + + node = { + ref: 'test-ref', + name: 'node', + childRefs: [], + transformConstraint: {}, + properties: {}, + components: [], + transform: { + position: [1, 1, 1], + rotation: [1, 1, 1], + scale: [1, 1, 1], + }, + }; + }); + + it('should return additional component data correctly', () => { + const entityComponent: IEntityBindingComponentInternal = { + ref: 'entityBindRef', + type: KnownComponentType.EntityBinding, + valueDataBinding: { + dataBindingContext: { + entityId: 'myEntityId', + }, + }, + }; + + const tagComponent: IAnchorComponentInternal = { + ref: 'tagBindRef', + type: KnownComponentType.Tag, + valueDataBinding: { + dataBindingContext: { + entityId: 'sel_entity1', + componentName: 'sel_comp1', + propertyName: 'myProperty', + }, + }, + chosenColor: 'color string', + navLink: { + destination: 'destination string', + }, + }; + + const datatOverlayComponent: IDataOverlayComponentInternal = { + ref: 'dataOverlayRef', + type: KnownComponentType.DataOverlay, + valueDataBindings: [ + { + valueDataBinding: { + dataBindingContext: { + entityId: 'sel_entity1', + componentName: 'sel_comp1', + propertyName: 'myProperty', + }, + }, + bindingName: 'myBindNameOne', + }, + { + valueDataBinding: { + dataBindingContext: { + entityId: 'myEntityOne', + componentName: 'myComponentOne', + propertyName: 'myPropertyTwo', + }, + }, + bindingName: 'myBindNameOne', + }, + ], + subType: 'TextAnnotation', + dataRows: [], + }; + + const unboundComponent: ISubModelRefComponentInternal = { + ref: 'skippableRef', + type: KnownComponentType.SubModelRef, + selector: 0, + }; + + node.components.push(entityComponent); + node.components.push(tagComponent); + node.components.push(datatOverlayComponent); + node.components.push(unboundComponent); + + const expectedResult: AdditionalComponentData[] = [ + { + dataBindingContext: { + entityId: 'myEntityId', + }, + }, + { + chosenColor: 'color string', + dataBindingContext: { + entityId: 'my_entity_id', + componentName: 'my_component_name', + propertyName: 'myProperty', + }, + navLink: { + destination: 'destination string', + }, + }, + { + dataBindingContexts: [ + { + entityId: 'my_entity_id', + componentName: 'my_component_name', + propertyName: 'myProperty', + }, + { + entityId: 'myEntityOne', + componentName: 'myComponentOne', + propertyName: 'myPropertyTwo', + }, + ], + }, + {}, + ]; + + const result = getAdditionalComponentData(node, mockDataBindingTemplate); + expect(result).toEqual(expectedResult); + }); + + it('should return empty component data if node undefined', () => { + const result = getAdditionalComponentData(undefined, mockDataBindingTemplate); + expect(result).toEqual([]); + }); + + it('should return undefined for undefined bindings', () => { + const entityComponent: IEntityBindingComponentInternal = { + ref: 'entityBindRef', + type: KnownComponentType.EntityBinding, + valueDataBinding: {}, + }; + + const tagComponent: IAnchorComponentInternal = { + ref: 'tagBindRef', + type: KnownComponentType.Tag, + valueDataBinding: {}, + chosenColor: 'color string', + navLink: { + destination: 'destination string', + }, + }; + + const datatOverlayComponent: IDataOverlayComponentInternal = { + ref: 'dataOverlayRef', + type: KnownComponentType.DataOverlay, + valueDataBindings: [], + subType: 'TextAnnotation', + dataRows: [], + }; + + const skippableComponent: ISubModelRefComponentInternal = { + ref: 'skippableRef', + type: KnownComponentType.SubModelRef, + selector: 0, + }; + + node.components.push(entityComponent); + node.components.push(tagComponent); + node.components.push(datatOverlayComponent); + node.components.push(skippableComponent); + + const expectedResult: AdditionalComponentData[] = [ + { + dataBindingContext: undefined, + }, + { + chosenColor: 'color string', + dataBindingContext: undefined, + navLink: { + destination: 'destination string', + }, + }, + { + dataBindingContexts: [], + }, + {}, + ]; + + const result = getAdditionalComponentData(node, mockDataBindingTemplate); + expect(result).toEqual(expectedResult); + }); +}); diff --git a/packages/scene-composer/src/utils/eventDataUtils.ts b/packages/scene-composer/src/utils/eventDataUtils.ts new file mode 100644 index 000000000..6aeb12bce --- /dev/null +++ b/packages/scene-composer/src/utils/eventDataUtils.ts @@ -0,0 +1,79 @@ +import { + IAnchorComponentInternal, + IEntityBindingComponentInternal, + IDataOverlayComponentInternal, + ISceneNodeInternal, +} from '../store'; +import { + IDataOverlayInfo, + ITagData, + IEntityBindingInfo, + IDataBindingTemplate, + KnownComponentType, + AdditionalComponentData, +} from '../interfaces'; + +import { applyDataBindingTemplate } from './dataBindingTemplateUtils'; + +export const getBindingsFromTag = ( + component: IAnchorComponentInternal, + dataBindingTemplate: IDataBindingTemplate | undefined, +): ITagData => { + return { + chosenColor: component.chosenColor, + navLink: component.navLink, + dataBindingContext: !component.valueDataBinding?.dataBindingContext + ? undefined + : applyDataBindingTemplate(component.valueDataBinding, dataBindingTemplate), + }; +}; + +export const getBindingsFromEntityBinding = (component: IEntityBindingComponentInternal): IEntityBindingInfo => { + return { + dataBindingContext: !component?.valueDataBinding?.dataBindingContext + ? undefined + : component?.valueDataBinding.dataBindingContext, + }; +}; + +export const getBindingsFromDataOverlay = ( + component: IDataOverlayComponentInternal, + dataBindingTemplate: IDataBindingTemplate | undefined, +): IDataOverlayInfo => { + const dataBindingContexts: unknown[] = []; + component.valueDataBindings.forEach((item) => { + if (item.valueDataBinding) { + dataBindingContexts.push(applyDataBindingTemplate(item.valueDataBinding, dataBindingTemplate)); + } + }); + return { dataBindingContexts }; +}; + +export const getAdditionalComponentData = ( + node: ISceneNodeInternal | undefined, + dataBindingTemplate: IDataBindingTemplate | undefined, +): AdditionalComponentData[] => { + const additionalComponentData: AdditionalComponentData[] = []; + + node?.components.forEach((component) => { + const type = component.type; + + switch (type) { + case KnownComponentType.Tag: + additionalComponentData.push(getBindingsFromTag(component as IAnchorComponentInternal, dataBindingTemplate)); + break; + case KnownComponentType.EntityBinding: + additionalComponentData.push(getBindingsFromEntityBinding(component as IEntityBindingComponentInternal)); + break; + case KnownComponentType.DataOverlay: + additionalComponentData.push( + getBindingsFromDataOverlay(component as IDataOverlayComponentInternal, dataBindingTemplate), + ); + break; + default: + additionalComponentData.push({}); + break; + } + }); + return additionalComponentData; +}; diff --git a/packages/scene-composer/tests/StateManager.spec.tsx b/packages/scene-composer/tests/StateManager.spec.tsx index ddc81643f..cf0ab8cc2 100644 --- a/packages/scene-composer/tests/StateManager.spec.tsx +++ b/packages/scene-composer/tests/StateManager.spec.tsx @@ -16,7 +16,7 @@ jest.doMock('@iot-app-kit/core', () => { }); import * as React from 'react'; -import renderer, { act } from 'react-test-renderer'; +import { act, create } from 'react-test-renderer'; import str2ab from 'string-to-arraybuffer'; import StateManager from '../src/components/StateManager'; @@ -105,7 +105,7 @@ describe('StateManager', () => { let container; await act(async () => { - container = renderer.create( + container = create( { let container; await act(async () => { - container = renderer.create( + container = create( { let container; await act(async () => { - container = renderer.create( + container = create( { let container; await act(async () => { - container = renderer.create( + container = create( { let container; await act(async () => { - container = renderer.create( + container = create( { let container; await act(async () => { - container = renderer.create( + container = create( { let container; await act(async () => { - container = renderer.create( + container = create( { let container; await act(async () => { - container = renderer.create( + container = create( { }); await act(async () => { - renderer.create( + create( { }); await act(async () => { - renderer.create( + create( { }); await act(async () => { - renderer.create( + create( { let container; await act(async () => { - container = renderer.create( + container = create( { // not called when selection is not changed let container; await act(async () => { - container = renderer.create( + container = create(