Skip to content

Commit

Permalink
Merge pull request #388 from keen/chore/logic-refactor
Browse files Browse the repository at this point in the history
Chore/logic refactor
  • Loading branch information
maciejrybaniec authored Aug 13, 2020
2 parents da6720e + 9cfcd2a commit 487c27d
Show file tree
Hide file tree
Showing 34 changed files with 368 additions and 247 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Provider } from 'react-redux';
import { render as rtlRender, fireEvent } from '@testing-library/react';
import { render as rtlRender, fireEvent, act } from '@testing-library/react';
import configureStore from 'redux-mock-store';

import EventCollection from './EventCollection';
Expand Down Expand Up @@ -31,6 +31,8 @@ const render = (storeState: any = {}, overProps: any = {}) => {
};
};

jest.useFakeTimers();

test('allows user to select event collection', () => {
const storeState = {
events: {
Expand Down Expand Up @@ -87,6 +89,10 @@ test('allows user to search event collection', () => {
const input = getByTestId('dropable-container-input');
fireEvent.change(input, { target: { value: 'logins' } });

act(() => {
jest.runAllTimers();
});

expect(queryByText('purchases')).not.toBeInTheDocument();
expect(getByText('logins')).toBeInTheDocument();
});
Expand All @@ -107,5 +113,9 @@ test('renders empty search results', () => {
const input = getByTestId('dropable-container-input');
fireEvent.change(input, { target: { value: 'purchases' } });

act(() => {
jest.runAllTimers();
});

expect(getByText(text.emptySearchResults)).toBeInTheDocument();
});
11 changes: 3 additions & 8 deletions lib/js/app/queryCreator/components/Filters/Filters.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, useEffect, useState, useRef } from 'react';
import React, { FC, useEffect, useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { useSelector } from 'react-redux';

Expand All @@ -15,7 +15,7 @@ import { SearchContext } from '../../contexts';
import { createTree } from '../../utils/createTree';
import { setOperator, setDefaultValue } from './utils';

import { SEARCH_EXPAND_TIME, AND_OPERATOR } from './constants';
import { AND_OPERATOR } from './constants';
import { SCHEMA_PROPS } from '../../constants';

import { AppState, Filter as FilterType } from '../../types';
Expand Down Expand Up @@ -48,7 +48,6 @@ const Filters: FC<Props> = ({
}) => {
const [searchPropertiesPhrase, setSearchPhrase] = useState(null);
const [expandTree, setTreeExpand] = useState(false);
const expandTrigger = useRef(null);

const {
schema: collectionSchema,
Expand All @@ -64,18 +63,14 @@ const Filters: FC<Props> = ({
}>(
schemaList,
(searchResult, phrase) => {
if (expandTrigger.current) clearTimeout(expandTrigger.current);
if (phrase) {
const searchTree = {};
searchResult.forEach(({ path, type }) => {
searchTree[path] = type;
});
setSearchPhrase(phrase);
setPropertiesTree(createTree(searchTree));

expandTrigger.current = setTimeout(() => {
setTreeExpand(true);
}, SEARCH_EXPAND_TIME);
setTreeExpand(true);
} else {
setTreeExpand(false);
setPropertiesTree(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@ export const Container = styled.div`

export const DropdownContent = styled.div`
width: 285px;
max-height: 300px;
overflow-y: scroll;
`;
2 changes: 0 additions & 2 deletions lib/js/app/queryCreator/components/Filters/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { Property, Operator } from '../../types';

import { getCurrentDate } from './utils';

export const SEARCH_EXPAND_TIME = 300;

export const DATA_TYPES = {
string: 'String',
num: 'Number',
Expand Down
7 changes: 1 addition & 6 deletions lib/js/app/queryCreator/components/GroupBy/GroupBy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ const GroupBy: FC<Props> = ({ collection }) => {
const [propertiesTree, setPropertiesTree] = useState(null);
const [searchPropertiesPhrase, setSearchPhrase] = useState(null);
const [expandTree, setTreeExpand] = useState(false);
const expandTrigger = useRef(null);

const dispatch = useDispatch();
const groups: string[] = useSelector((state: AppState) => {
Expand Down Expand Up @@ -86,18 +85,14 @@ const GroupBy: FC<Props> = ({ collection }) => {
}>(
schemaList,
(searchResult, phrase) => {
if (expandTrigger.current) clearTimeout(expandTrigger.current);
if (phrase) {
const searchTree = {};
searchResult.forEach(({ path, type }) => {
searchTree[path] = type;
});
setSearchPhrase(phrase);
setPropertiesTree(createTree(searchTree));

expandTrigger.current = setTimeout(() => {
setTreeExpand(true);
}, 300);
setTreeExpand(true);
} else {
setTreeExpand(false);
setPropertiesTree(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ export const Container = styled.div`

export const DropdownContent = styled.div`
width: 285px;
max-height: 300px;
overflow-y: scroll;
`;

export const StyledPropertyItem = styled(PropertyItem)`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { render as rtlRender, fireEvent } from '@testing-library/react';
import { render as rtlRender, fireEvent, act } from '@testing-library/react';

import PropertiesTree from './PropertiesTree';

Expand All @@ -18,6 +18,8 @@ const render = (overProps: any = {}) => {
};
};

jest.useFakeTimers();

test('allows user to select nested property', () => {
const properties = {
category: ['category', 'string'],
Expand Down Expand Up @@ -53,6 +55,11 @@ test('renders properties from all tree levels', () => {
const {
wrapper: { getByText },
} = render({ properties, expanded: true });

act(() => {
jest.runAllTimers();
});

const property = getByText('name');

expect(property).toBeInTheDocument();
Expand All @@ -74,6 +81,10 @@ test('expands all properties tree levels', () => {
} = render({ properties });
rerender(<PropertiesTree {...props} expanded={true} />);

act(() => {
jest.runAllTimers();
});

const property = getByText('name');

expect(property).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React, { FC } from 'react';
import React, { FC, useRef, useEffect } from 'react';
import {
FixedSizeTree as Tree,
FixedSizeNodeComponentProps,
} from 'react-vtree';

import { TreeLevel } from './components';
import { TreeLeaf, TreeNode } from './components';
import { createTreeWalker, getPropertyPath, getPropertyType } from './utils';

import PropertyTreeItem from '../PropertyTreeItem';
import { getPropertyType, getPropertyPath } from './utils';
import { LIST_HEIGHT, ELEMENT_HEIGHT } from './constants';

import { PADDING } from './constants';
import { TreeData } from './types';

type Props = {
/** Properties tree */
Expand All @@ -18,45 +22,69 @@ type Props = {
expanded?: boolean;
};

const Node: FC<FixedSizeNodeComponentProps<TreeData>> = ({
data: { name, isLeaf, schemaMeta, deepnessLevel },
isOpen,
style,
toggle,
treeData,
}) => {
const { activeProperty, onSelectProperty } = treeData;

return (
<div style={style}>
{isLeaf ? (
<TreeLeaf
isActive={activeProperty === getPropertyPath(schemaMeta)}
propertyName={name}
onClick={onSelectProperty}
deepnessLevel={deepnessLevel}
propertyType={getPropertyType(schemaMeta)}
propertyPath={getPropertyPath(schemaMeta)}
/>
) : (
<TreeNode
name={name}
isOpen={isOpen}
deepnessLevel={deepnessLevel}
onClick={toggle}
/>
)}
</div>
);
};

const PropertiesTree: FC<Props> = ({
expanded,
onClick,
activeProperty,
properties,
}) => {
const keys = Object.keys(properties);
const treeRef = useRef(null);
const expandTrigger = useRef(null);

useEffect(() => {
if (expandTrigger.current) clearTimeout(expandTrigger.current);
if (treeRef.current) {
treeRef.current.recomputeTree({
refreshNodes: true,
useDefaultOpenness: true,
});
}
}, [expanded, treeRef]);

return (
<div data-testid="properties-tree">
{keys.map((key) => {
if (Array.isArray(properties[key])) {
return (
<PropertyTreeItem
key={key}
padding={PADDING}
propertyName={key}
propertyPath={getPropertyPath(properties[key] as string[])}
type={getPropertyType(properties[key] as string[])}
isActive={
activeProperty === getPropertyPath(properties[key] as string[])
}
onClick={(e, propertyPath) => onClick(e, propertyPath)}
/>
);
} else {
return (
<TreeLevel
key={key}
level={1}
onClick={onClick}
header={key}
activeProperty={activeProperty}
expanded={expanded}
properties={properties[key] as Record<string, any>}
/>
);
}
})}
<Tree
ref={treeRef}
treeWalker={createTreeWalker(properties, expanded)}
itemData={{ activeProperty, onSelectProperty: onClick }}
itemSize={ELEMENT_HEIGHT}
height={LIST_HEIGHT}
width="100%"
>
{Node}
</Tree>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import { colors } from '@keen.io/colors';

export const Container = styled.div<{
isActive?: boolean;
padding: number;
}>`
position: relative;
display: flex;
font-family: Lato Regular, sans-serif;
font-size: 14px;
color: ${colors.blue[500]};
padding-left: ${(props) => props.padding}px;
padding-right: 15px;
padding-top: 10px;
padding-bottom: 10px;
width: 100%;
box-sizing: border-box;
cursor: pointer;
transition: background 0.2s linear;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import React from 'react';
import { render as rtlRender, fireEvent } from '@testing-library/react';

import PropertyTreeItem from './PropertyTreeItem';
import TreeLeaf from './TreeLeaf';

const render = (overProps: any = {}) => {
const props = {
onClick: jest.fn(),
type: 'datetime',
padding: 15,
propertyType: 'datetime',
deepnessLevel: 1,
propertyName: 'clicks',
propertyPath: 'users.cliks',
...overProps,
};

const wrapper = rtlRender(<PropertyTreeItem {...props} />);
const wrapper = rtlRender(<TreeLeaf {...props} />);

return {
props,
Expand All @@ -27,7 +27,7 @@ test('shows the property type', () => {
props,
} = render();

expect(getByText(props.type)).toBeInTheDocument();
expect(getByText(props.propertyType)).toBeInTheDocument();
});

test('allows user to select property', () => {
Expand Down
Loading

0 comments on commit 487c27d

Please sign in to comment.