-
-
Notifications
You must be signed in to change notification settings - Fork 144
Conversation
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.
🎉 Very nice! This looks good to me. Thank you very much for the thorough PR and the complete tests. There are just a few comments, mostly on code style conventions.
@@ -1,6 +1,7 @@ | |||
{ | |||
"src/components/Checklist.react.js": { | |||
"description": "Checklist is a component that encapsulates several checkboxes.\nThe values and labels of the checklist is specified in the `options`\nproperty and the checked items are specified with the `values` property.\nEach checkbox is rendered as an input with a surrounding label.", | |||
"displayName": "Checklist", |
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.
Interesting, I wonder why displayName
started appearing recently. Maybe a new version of react-docgen
?
package-lock.json
Outdated
"async-each": "1.0.1", | ||
"glob-parent": "2.0.0", | ||
"inherits": "2.0.3", | ||
"is-bin |
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.
👍 thanks for adding this
src/components/Location.react.js
Outdated
@@ -1,39 +1,85 @@ | |||
import {Component, PropTypes} from 'react'; | |||
/* global window:true */ | |||
|
|||
/** | |||
* Update and track the current window.location object through the window.history state |
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.
Maybe we can update this a little bit so that it's more readable to the Python devs who don't know much about this stuff, like:
Update and track window.location (the URL) object through the window.history state.
Use in conjunction with thedash_core_components.Link
object to make apps with multiple pages.
* The name of the prop in window.location and in the component's prop | ||
* | ||
* @returns {boolean} | ||
* Returns true if the prop with fieldName is different and the window state needs to be updated |
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.
👍 Very nice comment, thanks for this!
src/components/Location.react.js
Outdated
const checkExistsUpdateWindowLocation = (fieldName) => { | ||
const propVal = props[fieldName]; | ||
|
||
if (!propVal && window.location[fieldName] && setProps) { // Prop is undefined? |
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.
we use stronger checks for undefined
here like R.type(propVal) == 'Undefined'
or even !R.has(props, propVal)
(http://ramdajs.com/docs/#type, http://ramdajs.com/docs/#has)
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.
It's actually a null in some cases (pathname when the page first loads, e.g.), so will update to (R.type(propVal) === 'Undefined' || propVal === null)
if you prefer. I think that's why the original code had !propVal
.
/** href in window.location - e.g., "/my/full/pathname?myargument=1#myhash" */ | ||
href: PropTypes.string, | ||
|
||
/** Refresh the page when the location is updated? */ |
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.
👍 very nice, thanks for adding these
test/test_integration.py
Outdated
output=Output(component_id='test-pathname', component_property='children'), | ||
inputs=[Input(component_id='test-location', component_property='pathname')]) | ||
def update_location_on_page(pathname): | ||
assert isinstance(pathname, str) |
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.
I believe that these asserts won't actually fail the test as the dash app is run in a subprocess in these tests. They'll still cause the callback to fail (which might implicitly break other assertions in the main process) but in either case we might want to put this assertion out of this context
test/test_integration.py
Outdated
|
||
self.startServer(app=app) | ||
|
||
def _waiter(): |
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.
👍 - this is great. can we move this to test/utils.py
so that we can reuse it elsewhere?
|
||
# Check that pathname is updated through a Button click via props | ||
self.driver.find_element_by_id('test-button').click() | ||
time.sleep(1) # Need to wait for the callback to fire TODO is there a better way to wait? |
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.
There isn't really, besides using a wait_for
with whatever you are waiting for
time.sleep(1) # Need to wait for the callback to fire TODO is there a better way to wait? | ||
|
||
self.snapshot('link -- /new/pathname?testQuery=testValue') | ||
self.assertEqual(self.driver.find_element_by_id('test-pathname').text, '/new/pathname') |
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.
for example, you should be able to remove the time.sleep
and replace it with a wait_for
here and place the snapshot below the assertions
Could you open up a new issue about this? My guess is that we are OK here. I believe that the main use for |
…ramda for type checking; batch updates for setProps vs each field sequentially
@mjclawar - Let me know when you're ready for another review! |
All set for another review. |
@chriddyp had to push a change to uncomment the rest of the test suite. I think all the changes you requested should be in there now! |
Thanks! It looks like tests are failing because of some dependency mismatched. I'll make a separate PR to lock down these versions in tests |
Thanks -- wasn't sure why the tests were failing on CircleCI. Happy new year! 🎉 |
…ramda for type checking; batch updates for setProps vs each field sequentially
… 81-location-url-parameters
Rebased. |
Tests passed! 🎉 Thank you @mjclawar , this was a great PR 🍻 |
@chriddyp do you have an expected timeline for getting this published as the next version/how do you typically approach publishing for the dash packages? Thanks! |
Hey @mjclawar - Thanks for the reminder! I just published |
Description
This PR adds
search
,hash
andhref
props to thedcc.Location
component (in addition to the already-existingpathname
) to better mimic thewindow.location
API.This addresses #81, with the caveat that
dcc.Link
does not have any changes to props that would allow a user to directly updatesearch
independently ofhash
(e.g., usingdcc.Link(href="?testQuery=testValue")
will wipehash
fromdcc.Location
. Note that this is the same behavior aswindow.location
, so should be considered "correct", but it seemed like updatingdcc.Link
should be a different issue.Implementation
dcc.Location
pretty much extends the previouspathname
-specificupdateLocation
approach. The only major difference is that ifhref
changes in props compared to previous props and compared towindow.location.href
,href
takes precedent over the combination of${pathname}${searchVal}${hashVal}
(see here)..idea/
, but can remove that if needed.package-lock.json
Tests added
This adds tests for
![peek 2017-12-21 09-31](https://user-images.githubusercontent.com/16123745/34261540-6be36d46-e637-11e7-9ea8-24ae8e2966a1.gif)
html.A
tags,dcc.Link
, andhtml.Button
clicks interacting with the updateddcc.Location
component.