-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Add/tld/fr extra fields dialog #14156
Conversation
@@ -56,7 +59,8 @@ export default React.createClass( { | |||
form: null, | |||
isDialogVisible: false, | |||
submissionCount: 0, | |||
phoneCountryCode: 'US' | |||
phoneCountryCode: 'US', | |||
registrantExtraInfo: false |
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.
Is this always boolean? If so, do you think it'd make it easier to understand if we prefix it with has
or needs
? If not, I think we should initialize it to null
or undefined
instead of false
|
||
handleFrSubmit( registrantExtraInfo ) { | ||
this.setState( { registrantExtraInfo } ); | ||
this.closeDialog( 'fr' ); |
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 think we never open a dialog named fr
. Did you mean isFrDialogVisible
?
I think it'd would make it more resilient to just create functions for every dialog (or use const) instead of relying on literal strings sprinkled everywhere.
4ba33a4
to
0664ca4
Compare
@mikeshelton1503: No interaction yet, but I think that screenshot implements your design if you wanted to have a look and give me design feedback, especially around the DOB. |
@umurkontaci: Thanks for catching the |
return ( | ||
<div> | ||
<Card className="registrant-extra-info__title-card"> | ||
{ this.props.translate( '.FR Registration' ) } |
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! I've found a possible matching string that has already been translated 66 times:
translate( 'Registration' )
ES Score: 10
See 1 additional suggestion in the PR translation status page
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
3e061c3
to
94423dc
Compare
Ok, I've reworked the extras form to be thinner, and moved it out of the dialog and into the details form. I've also added some "steps" logic, which is probably re-inventing a wheel, but might nonetheless be useful in #12622 if we wanted to add the privacy dialog in as another step. I've updated the screenshot to a video of the flow. We definitely need a back button. I think I've settled on how we should handle the extra details forms too, as described in the README. If we want them to be usable in both the domain details and checkouts, we need them to be super-thin, so what I'm going for now is just displaying some fields with error messages, and passing out the value in all the fields to the parent, and leaving validation, sanitation etc to them. It should be reasonably clean once we get the contact details out of the react state and into the redux state. |
checked={ 'individual' === this.state.registrantType } | ||
name="registrantType" | ||
onChange={ this.handleChangeEvent } /> | ||
<span>An individual</span> |
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.
Missing translate (a few additional occurrences below)
<FormFieldset> | ||
<FormLabel> | ||
{ this.props.translate( "Who's this domain for?" ) } | ||
</FormLabel> |
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.
Closing FormLabel should be at the end of the FormRadio element
checked={ 'individual' === this.state.registrantType } | ||
name="registrantType" | ||
onChange={ this.handleChangeEvent } /> | ||
<span>{ this.props.translate( 'An individual' ) }</span> |
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! I've found a possible matching string that has already been translated 7 times:
translate( 'Individual' )
ES Score: 13
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
There's no way to translate the |
name="registrantType" | ||
checked={ 'individual' === this.state.registrantType } | ||
onChange={ this.handleChangeEvent } /> | ||
<span>{ this.props.translate( 'An individual' ) }</span> |
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! I've found a possible matching string that has already been translated 7 times:
translate( 'Individual' )
ES Score: 13
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
Update: It's alive! All the fr-form fields are hooked up to the form's state, and in turn to contact details, which are then passed on to the purchase and validate endpoints, huzzah!: The fields on the FR form show only if they're appropriate, and the organization guess is in place too (if you put something in the organization field in the main form the fr form defaults ot organization). It doesn't actually work yet because the backend just ignores the extra fields right now, but we're nearly there! Validation and sanitation don't work, and there is some unpleasant hardwiring in there, but I'd like to punt all that to a later PR and solve it by reduxifying everything. Showing different forms and passing values and errors back and forwards is going to be so much easier with the data in a redux state (it's been getting a bit painful here. On the upside, I understand a bug I've seen a few times now where the state of components fail to show the most recent input event). It could use another look over, but It's getting late, so I'm going to mark this as "for review" now, just be on the lookout for stupidity. |
On the design front, I Italicized the 'Optional', and the date entry needs a look |
c765019
to
c14d093
Compare
} | ||
} | ||
|
||
render = () => { |
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.
render doesn't need to be bound to the instance
handleCheckboxChange = () => { | ||
this.setPrivacyProtectionSubscriptions( ! this.allDomainRegistrationsHavePrivacy() ); | ||
} | ||
|
||
closeDialog = () => { | ||
this.setState( { isDialogVisible: false } ); | ||
closeDialog( dialogKey = 'isDialogVisible' ) { |
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.
these might need to be bound to the instance like they were before, since they're using this
. just depends on how they're called..
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.
Good catch! They do need to be bound to work when passed in to the PrivacyProtection
component here
}; | ||
} | ||
|
||
componentWillMount() { | ||
componentWillMount = () => { |
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 doesn't need to be bound
this.setState( { [ event.target.name ]: event.target.value } ); | ||
} | ||
|
||
shouldComponentUpdate = ( nextProps, nextState ) => { |
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 think React.PureComponent
does basically the same :)
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.
Nearly, but not quite :( isEqual()
is a deep comparison, and PureComponent uses a shallow one https://facebook.github.io/react/docs/react-api.html#react.purecomponent.
I had to add this to break an infinite rerender caused by passing the state up out of this component and adding it to the state of it's parent. This was the point at which I decided that I had forced this too far, and need to stop and reduxify it all :)
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.
Ah, didn't realize it was deep comparison 👍
this.props.onStateChange( this.state ); | ||
} | ||
|
||
getRelevantFields( 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.
@hewsut: what does
getRelevantFields
do? I mean, I understand what it does inside the function. But I don’t see it called anywhere?
Nice catch! It captures the way the .FR fields depend on each other. I was using it on the state before passing it out at one point, but now I'm not sure - maybe we want to save everything to the database? At any rate, we will need it to handle validation (we don't care about errors in the the organization fields for individuals), but it's not being used right now. I should probably pull it out, but I don't think I will just yet unless someone objects strongly.
@deBhal Finally taking a look here. It's looking good, nice work! I noticed a few things that need some more attention:
Other than that, I'll work on updating the presentation of the date fields and there are couple other minor design improvements I'm going to make. I'll work on those changes tomorrow (Thursday). Also, just a note, I did my best to research what a VAT, SIREN, SIRET, and EU Trademark Number should look like for the placeholder text, which is what you have implemented thus far. However, we should probably have someone more familiar with those numbers review. |
id="registrantType" | ||
checked={ 'individual' === registrantType } | ||
onChange={ this.handleChangeEvent } /> | ||
<span>{ translate( 'An individual' ) }</span> |
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! I've found a possible matching string that has already been translated 7 times:
translate( 'Individual' )
ES Score: 13
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
if ( needsOnlyGoogleAppsDetails ) { | ||
// TODO: gather up tld specific stuff | ||
if ( this.state.currentStep === 'fr' ) { | ||
title = this.props.translate( '.FR Registration' ); |
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! I've found a possible matching string that has already been translated 66 times:
translate( 'Registration' )
ES Score: 10
See 1 additional suggestion in the PR translation status page
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
id="registrantType" | ||
checked={ 'individual' === registrantType } | ||
onChange={ this.handleChangeEvent } /> | ||
<span>{ translate( 'An individual' ) }</span> |
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! I've found a possible matching string that has already been translated 7 times:
translate( 'Individual' )
ES Score: 13
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
if ( needsOnlyGoogleAppsDetails ) { | ||
// TODO: gather up tld specific stuff | ||
if ( this.state.currentStep === 'fr' ) { | ||
title = this.props.translate( '.FR Registration' ); |
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! I've found a possible matching string that has already been translated 66 times:
translate( 'Registration' )
ES Score: 10
See 1 additional suggestion in the PR translation status page
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
8fd73ed
to
bcd16c0
Compare
id="registrantType" | ||
checked={ 'individual' === registrantType } | ||
onChange={ this.handleChangeEvent } /> | ||
<span>{ translate( 'An individual' ) }</span> |
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! I've found a possible matching string that has already been translated 7 times:
translate( 'Individual' )
ES Score: 13
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
if ( needsOnlyGoogleAppsDetails ) { | ||
// TODO: gather up tld specific stuff | ||
if ( this.state.currentStep === 'fr' ) { | ||
title = this.props.translate( '.FR Registration' ); |
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! I've found a possible matching string that has already been translated 66 times:
translate( 'Registration' )
ES Score: 10
See 1 additional suggestion in the PR translation status page
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
New functionality is behind domains/cctlds feature flag Thanks @mikeshelton1503, @klimeryk, @blowery, @umurkontaci, @yoavf!
bcd16c0
to
16a7b3b
Compare
value={ dobMonths } | ||
max="2" | ||
type="number" | ||
placeholder={ translate( 'MM', { |
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! I've found a possible matching string that has already been translated 11 times:
translate( 'mm', { context: 'millimeters'} )
ES Score: 11
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
id="registrantType" | ||
checked={ 'individual' === registrantType } | ||
onChange={ this.handleChangeEvent } /> | ||
<span>{ translate( 'An individual' ) }</span> |
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! I've found a possible matching string that has already been translated 7 times:
translate( 'Individual' )
ES Score: 13
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
if ( needsOnlyGoogleAppsDetails ) { | ||
// TODO: gather up tld specific stuff | ||
if ( this.state.currentStep === 'fr' ) { | ||
title = this.props.translate( '.FR Registration' ); |
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! I've found a possible matching string that has already been translated 66 times:
translate( 'Registration' )
ES Score: 10
See 1 additional suggestion in the PR translation status page
Help me improve these suggestions: react with 👎 if the suggestion doesn't make any sense, or with 👍 if it's a particularly good one (even if not implemented).
@klimeryk: I've implemented that final round of feedback and then squashed for the merge, which makes having a quick look pretty hard, so I've pushed Bullet points Fixes:
I've also dropped the unused code (into a local branch), the unnecessary check and the Thanks again for such a detailed review! I've rebased, squashed, and done a final check of everything, so I'm going to merge now. |
*/ | ||
import Card from 'components/card'; | ||
import ExtraInfoFrForm from 'components/domains/registrant-extra-info/fr-form'; | ||
import { forDomainRegistrations as getCountries } from 'lib/countries-list'; |
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.
Nice idea!
Congrats on merging this 😀 I've looked through the final version and it looked good - thanks for bearing with me! 🙇 |
I think you might have that backwards :) I really appreciate such a thoughtful review. |
This PR adds a form to support .FR extra fields for the for the domains checkout flow and contact detail editing flow as per #13890.
I've added the
domains/cctlds
feature flag, and the .FR form is behind that, so the most critical testing is that we don't break calypso with the flag off:DISABLE_FEATURES=domains/cctlds make run
Note: that the back-end will only offer .FR domains to proxied a12s, or sandboxes with the store sandbox enabled, so this is not a very community friendly PR, sorry :(
After that, we want to see:
npm run test-client client/components/domains/registrant-extra-info
(or even betternpm run test-client
)Things that are not in this PR:
Video:
And passing that data to the server: