Skip to content

Commit

Permalink
feat(composer): add hook to convert data bindings to queries
Browse files Browse the repository at this point in the history
  • Loading branch information
sheilaXu committed Jul 27, 2023
1 parent 9bb99f0 commit 1e68022
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
42 changes: 42 additions & 0 deletions packages/scene-composer/src/hooks/useBindingQueries.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { renderHook } from '@testing-library/react';

import { useStore } from '../store';

import useBindingQueries from './useBindingQueries';

describe('useBindingQueries', () => {
const mockProvider = {
createQuery: jest.fn(),
};

beforeEach(() => {
useStore('default').setState({
getEditorConfig: jest.fn().mockReturnValue({ valueDataBindingProvider: mockProvider }),
});
});

it('should return undefined when bindings are empty', () => {
const queries = renderHook(() => useBindingQueries([])).result.current.queries;

expect(queries).toBeUndefined();
});

it('should return queries for each binding in the matching order', () => {
const expectedQueries = [{ entityId: 'AA' }, undefined, { entityId: 'BB' }];
const bindings = [
{ dataBindingContext: { entityId: 'AA' } },
{ dataBindingContext: { entityId: 'CC' } },
{ dataBindingContext: { entityId: 'BB' } },
];
mockProvider.createQuery.mockImplementation((binding) => {
const id = binding.dataBindingContext.entityId;
if (id === 'AA' || id === 'BB') {
return { entityId: id };
}
return undefined;
});
const queries = renderHook(() => useBindingQueries(bindings)).result.current.queries;

expect(queries).toEqual(expectedQueries);
});
});
37 changes: 37 additions & 0 deletions packages/scene-composer/src/hooks/useBindingQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useMemo } from 'react';
import { Query, TimeSeriesData } from '@iot-app-kit/core';
import { isEmpty } from 'lodash';

import { useSceneComposerId } from '../common/sceneComposerIdContext';
import { IValueDataBinding } from '../interfaces';
import { useStore } from '../store';

/**
* Create query objects for data bindings.
*
* @param bindings the data bindings to create query object
* @returns `queries` as an array of query objects for each data binding in the same order.
* If the query object cannot be created for any of the bindings,
* undefined will be returned in the result array at the same index.
*/
const useBindingQueries = (
bindings: IValueDataBinding[],
): // TODO: add data type for static data when available
{ queries: (Query<TimeSeriesData[]> | undefined)[] | undefined } => {
const sceneComposerId = useSceneComposerId();
const valueDataBindingProvider = useStore(sceneComposerId)(
(state) => state.getEditorConfig().valueDataBindingProvider,
);

const queries = useMemo(() => {
if (isEmpty(bindings) || !valueDataBindingProvider) {
return undefined;
}

return bindings.map((binding: IValueDataBinding) => valueDataBindingProvider.createQuery(binding));
}, [bindings]);

return { queries };
};

export default useBindingQueries;

0 comments on commit 1e68022

Please sign in to comment.