Deployed here: https://query-builder-react-ts.herokuapp.com/
- Install dependencies:
npm install - Run on
localhost:3000:npm run - Run tests:
npm run test - View test coverage report:
npm test -- --coverage --watchAll=false
heroku logingit push heroku branchname:master
- ReactJS used with Typescript
- Project initialized using
create-react-appwith the Typescript template react-selectis used for dropdowns
1.MultiValueInputSelector:
- An input box which can have multiple values
- Unlike a multi-select dropdown, values are individually typed and added by the user. There's no dropdown
- Currently supports only
numberas input type. Can easily extend to add support for other types. - For type number, accepts a rule of
minandmaxnumbers. - Extra rules can be passed, and handled by extending the code, without changing the existing code.
- Accepts props:
interface Props { values?: Array<number>, onChange?: (newRhs: Array<number>) => void, type: "number", // can add support for other types later rules?: rulesType }`
2.QueryBuilder:
- A component which can create multiple queries, each having 3 attributes:
LHS,Operator&RHS LHS&Operatorare dropdowns with multiple options.- The
RHScan be of multiple types:"text" | "number" | "multi-select-list" | "multi-select-numbers-in-a-range" - The types and possible values for
Operator&RHSare different for each possible value inLHS. - The component accepts a config which specifies the different possible values for
LHS, and the possible values forOperator&RHSfor thatLHS. (The config for the current implementation is at:queryConfig/queryConfig.tsx) - When
RHStype ismulti-select-list, a JSON file can be provided, which is used to provide options to the dropdown - When
RHStype ismulti-select-numbers-in-a-range, the custom componentMultiValueInputSelectoris used. - Any new functionality can be added first in the config, and then the code can be extended to provide support for it.
- Types for the config file:
interface Operator { value: string; text: string; } export interface Row { label: string, operators: Array<Operator>; rhs: { type: "text" | "number" | "multi-select-list" | "multi-select-numbers-in-a-range"; config?: string; } } // This is the type the provided config should follow export interface ConfigType { [key: string]: Row; }
- Queries can be saved with a name (in the localStorage)
- Saved queries can be applied later.
- Using
react-testing-librarywithjestfor unit and integration tests. - Most of the tests are integration tests with some unit tests in important places.
- The philosophy behind
react-testing-librarymakes sense to me, testing from the user's perspective. Testing the rendered output based on user's actions instead of only testing the internal implementation.
Testing:
- The code written for the tests can be improved. Currrently there is some redundancy around the way tests are written
- I might have missed some edge cases.
- Can write some accessibilty tests with
jest-axe
Styles:
- Can separate presentational compoenents into their own.
- Can use the styles-components approach. I haven't put much efforts into managing the styles. Most styles are dumped into
SavedQuries.csswithout much though. - Can make some components configurable for their styles.
- UI is not responsive right now. Fixed widths are given to most elements. Should be fixed.
Functionality:
- Validations can be done in a better way. Currently only the
MultiValueInputSelectorcomponent has proper validations. Some central level validation schema can be setup. (I like https://github.com/jquense/yup). - The UX around saving a named query can be improved. Currently when user clicks on
Save for later, it's not very apparent that the query gets saved. - Functionality for removing saved queries can be added.
Code:
- Types that are common across multiple files can be managed in a better way.