-
Notifications
You must be signed in to change notification settings - Fork 1.9k
React client TypeScript fixes, QueryBuilder improvements #2196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2196 +/- ##
==========================================
+ Coverage 55.73% 55.75% +0.01%
==========================================
Files 118 118
Lines 8635 8641 +6
Branches 1888 1888
==========================================
+ Hits 4813 4818 +5
- Misses 3443 3444 +1
Partials 379 379
Continue to review full report at Codecov.
|
c7ade66 to
1e2a2b2
Compare
Updates TypeScript types to be more accurate (and fix some mistakes), adding PropTypes for non-typescript safety. Refactoring updateVizState to be more consistent and easier to understand, updating orderMember handling to be less problematic and use a single source of truth. Convert to a fully uncontrolled component to follow react best practices and prevent unexpected behavior.
|
Not sure why that integration test failed, but obviously nothing to do with this PR |
|
I'll resolve conflicts once the PR is reviewed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @SteffeyDev! Thanks for a great PR!
As I can see it introduces breaking changes which we cannot accept. However, we're ok with deprecating things but keeping them backward compatible for now.
Also, maybe you could consider splitting the PR? It'll make it easier to review and accept the changes.
As for PropTypes not sure if need it as we'll end up maintaining both index.d.ts and prop-types definitions. Moreover, all modern IDEs will take the TS definitions we have into account even for non-TS projects.
What do you think?
|
Concerning PropTypes, I think it's just a safer option, but definitely not needed. If you don't include them, there's always a risk that someone using an older editor might pass in invalid options, which causes internal issues and then that user gets frustrated because it looks like it is the component's fault, not theirs. Up to you as a maintainer. |
|
After giving it some thought, I think I've found a way to make it backwards compatible with minimal consequences. I could get to work on that. While I'm doing that, I might also go ahead and split this into a few PRs. It will take a lot of time, but I understand why. Here would be the 5 resulting PRs:
Before I spend all the time on these, are any of these PRs that you would reject or have no interest in? I'll only spend the time on PRs that will be accepted (potentially after discussion and modifications). |
|
@SteffeyDev, we're definitely willing to accept all of the PRs. But again, the main concern is that all changes to the API must be backward compatible. Thanks for your time! |
|
@vasilev-alex I created #2261, #2262, and #2263. Do you want me to create a PR for adding PropTypes, or do you not want to have the burden of maintaining PropTypes? Makes little difference to me. Once those are merged in, I'll work on the bigger PR, which is converting to uncontrolled. That needs to build on top of these three. |
|
@SteffeyDev nice! Let's go without PropTypes for now. |
Check List
Description of Changes Made
TypeScript type updates
I tried using cube.js react client in a typescript project, and found a number of issues with the provided typescript types. In many cases, the types were not specific enough to be used in a strict typescript project, but in others the types were simply incorrect. The included changes were necessary for me to use it in my project, where I use a I have created QueryBuilder wrapper similar to that in the playground, but strongly typed. I have also modified the types to support the QueryBuilder changes I made, as described below.
QueryBuilder Improvements
Convert to uncontrolled
I ran into some issues while making other improvements, and realized that it was because the QueryBuilder was neither fully controller nor uncontrolled, and was using the React anti-pattern of unconditionally copying props to state. Following the recommendations in that article and based on my experience as a React developer, I decided to make QueryBuilder uncontrolled. This means that QueryBuilder controls it's own state, and can't be modified from the outside save for in specific ways that are allowed through props.
This involved removing the
query,setQuery,vizState, andsetVizStateprops, and adding theinitialVizStateandonVizStateChangedprops. From my analysis, the most common use case for accessing thevizStateoutside of the query editor is to save the editor state in persistent storage. These two new props allow for setting up a QueryBuilder component from a saved state and then listening for changes to save back. I'm using this in my app to save thevizStateto a database so I can persist the QueryBuilder state across reloads.I also added the
defaultQueryanddefaultChartTypeprops, so that ifinitialVizStateis empty, it will pick up the default values for those.defaultChartTypewas listed in the documentation before, but wasn't actually implemented until now.Refactor
orderMembersAnother issue I ran into was the interop between
query.orderandorderMembers. Whenever the query changed,orderMemberspotentially needed to be updated, and every timeorderMemberschanged, the query might need to be updated. This relationship made reasoning about the various state changes difficult, and especially saving/restoring state and reloads.I refactored the QueryBuilder so that
orderMembersis calculated on demand in thenrendermethod based on theavailableDimensions,availableMeasures, andquery.order. Then, I changedupdateOrderso that it just modified thequery.orderand sent it through the normal query update path. This makesquery.orderthe single source of truth, and removes any difficulties with maintaining the relationship betweenquery.orderandorderMembers.Add
errorrender propI noticed that if
dryRunfailed, the error was logged to the console but not shown to the user. Instead of ignoring and letting thequerycall report the same error, I changed it so thatdryRunerrors are reported to the rendered function in theerrorprop. This is mostly useful whenwrapWithQueryRendereris false, as when it is true, the QueryRenderer will produce the same error and overwrite with it's ownerrorprop (by design).Add PropTypes
I added PropTypes so that non-typescript users can enjoy the benefit of prop type checking as well. This should be a lot safer and prevent unexpected props from being passed in.'
Summary
I know this is a lot, but I believe it makes the QueryBuilder a lot simpler to reason about, easier for fluent React developers like myself to pick it up and use it, and easier for future open source contributors to understand and add to the code.
I did not update the example React dashboard app and other docs yet with these changes, as I wanted to get approval and resolve all issues before I spent the time updating those. Once this is approved, I will go through and update the docs and examples to support these new props, and make sure the example react dashboard app still works.
As always, I'm hoping for good discussions and will readily make changes to address all concerns. I look forward to working with the cube.js development team on these changes, and if it goes well, would most likely invest more time into the project in the future.