-
Notifications
You must be signed in to change notification settings - Fork 27
Bug 1897276: Vsphere provider creation/edition certificate validation #845
Conversation
🚀 Deployed Preview: http://konveyor-forklift-ui-pr-845-preview.surge.sh ✨ Compare with current main branch: http://konveyor-forklift-ui-preview.surge.sh |
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.
Looking good, but there are a few state things we can clean up here.
Also, I wonder if we should be showing other certificate details in addition to just the fingerprint, like issuer and expiration date. That would give the user more info to go by to know if the cert is valid. @vconzola what do you think? I left a similar comment on slide 7 of the mockup. The cert details could be in a little info box and the checkbox could say something more generic like "I trust the authenticity of this certificate" if we are showing more details.
|
||
function assertIsCertificate( | ||
certificate: ITLSCertificate | ||
): asserts certificate is ITLSCertificate { |
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.
whoa!! I was not aware of this TypeScript feature, I really wish I had discovered this sooner! That's really nice. I think we could use it in a few places where we have logic based on providerType and mappingType with a lot of as
assertions. Future cleanup :)
|
||
const [isCertificateValid, setCertificateValid] = React.useState(false); | ||
|
||
const { status, error, data } = useQuery<ITLSCertificate, Error>( |
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.
As you suggested on Slack, I do think we should probably move this stuff to a useCertificateQuery
hook so we're not cluttering this component. assertIsCertificate
and getCertificate
could be moved into there. I think we should also have the query result as a single variable instead of destructuring it, so we can use certificateQuery.status
instead of status
so the usage is more readable below.
inputProps={{ | ||
onFocus: () => setCertificateQueryFlag(false), | ||
onBlur: () => { | ||
setHostname(forms.vsphere.fields.hostname.value); |
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 can simplify things and reduce the amount of state we're using here.
- I think we should define
isCertificateValid
as a required field in thevsphere
section ofuseAddProviderFormState
rather than in its ownuseState
. We may also be able to just remove thefingerprint
andfingerprintFilename
fields from there, but we'd need to pass the fingerprint data (from the query) as an additional param when we callmutateProvider
(which comes fromuseCreateProviderMutation
andusePatchProviderMutation
). In general I think it is helpful to have theuseFormState
stuff match the form fields we display as much as possible so we can leverage all its built in stuff. - By default (without the custom
onBlur
here), thefields.hostname.isTouched
boolean will not be true until the blur event happens (because that's what triggers the validation errors to appear). Currently the validation on the hostname field is broken here because you're not callingsetIsTouched
in your customonBlur
. But I think we can restore the default behavior by removing the customonBlur
andisCertificateQueryEnabled
state entirely, because:- If we replace the
setCertificateQueryFlag(false)
inonFocus
withfields.hostname.setIsTouched(false)
, we can usefields.hostname.isTouched
as our value for whether the query should be enabled.
- If we replace the
- If we do that, we also don't need the
hostname
/setHostname
state, because we already havefields.hostname.value
.
So in short, I think all we really need is the isCertificateValid
to be part of the form state (so isFormValid
works properly), and to manage the isTouched
value of the hostname field as our indicator of whether the query should run, and we can get rid of all the other new state you've introduced here. Everything below that uses isCertificateValid
can use fields.isCertificateValid.value
, and your useCertificateQuery
can take fields.hostname.value
as a hostname param and fields.hostname.isTouched
as an enabled
param.
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.
Thank you for your thorough review.
With latest commit is as close I could get to the expected behavior.
The reason I keep using a state hostname is to make benefit of having a button triggering the fetch and avoid trying to fetch the certificate at each key stroke when hostname is entering.
) : null} | ||
{fields?.username ? ( | ||
{fields?.username && status === 'success' && isCertificateValid ? ( |
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.
Per the mockups, this field should still be rendered, but just disabled if the certificate checkbox is unchecked.
@@ -299,47 +376,14 @@ export const AddEditProviderModal: React.FunctionComponent<IAddEditProviderModal | |||
fieldId="username" | |||
/> | |||
) : null} | |||
{fields?.password ? ( | |||
{fields?.password && status === 'success' && isCertificateValid ? ( |
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.
Same here.
@mturley I really like that idea. I think it'd be more helpful to the user than just seeing the fingerprint. @gildub Lemme update the mockups this afternoon and send them to you. |
Another note: when it comes time to deal with editing, I think we just need to be sure to modify
|
One more thought: @vconzola was mentioning that it might be weird to have the cert fetch on blur, because what if the user types and doesn't click away from the field because the rest of them are disabled, and they are confused about why nothing is happening? We could have a custom Edit: onChange, not onBlur Edit 2: hmm, we'd also have to set |
For reference, these are the default text field props that you have to replicate if you override them with additional custom behavior. We should document that better in lib-ui maybe. export const getTextFieldProps = (
field: IValidatedFormField<string> | IValidatedFormField<string | undefined>
): Pick<TextInputProps | TextAreaProps, 'value' | 'onChange' | 'onBlur' | 'validated'> => ({
value: field.value,
onChange: field.setValue,
onBlur: () => field.setIsTouched(true),
validated: field.isValid ? 'default' : 'error',
}); |
In reply of your latest comment in regards of |
No, those are just the default values provided by |
@vconzola, please review. |
@gildub that's quite strange. Looking into it now |
See slack for my findings :) |
Valid bug 1897276 |
@vconzola, per your question on Slack,
Moving the focus between different parts of the modal could be done but what about moving the hostname to be after the other input fields? |
Having the hostname is really weird and unusual. So I reverted it. |
Hey Gilles. I pushed a few commits here, feel free to revert if you need to, but I had it working in troubleshooting so I figured I may as well commit.
|
Mike, That's great, no need to revert ! Thanks for troubleshooting the validation field issue. Fixing it will be great although we'll a fair amount of testing to do ;) I added a patch to mock |
@seanforyou23 @gildub are we happy with this? |
@mturley, I'm happy with this now. |
Discussing things with Mike S, I pushed a few more commits to surface error messages from fetching the certificate all the way to the UI. I think we can merge this and follow up in another PR perhaps, but the main thing remaining here I think is that if the certificate request fails, the button should reappear so it can be retried. |
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 to merge, we can address the above in a followup.
Followup issue: https://github.com/konveyor/forklift-ui/issues/868 |
Hmm... CI is failing on |
@seanforyou23 @gildub I'm pretty baffled as to why this error is coming up when running tests in CI but not locally. Any ideas? |
@mturley, yeah I know, really frustrating I already looked at it and I've no idea why. |
@mturley, I've started investigation... |
…ble/disable state on the Verify button
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
I was able to reproduce CI error locally using Ubuntu image and following same pipeline. Also I worked around the error itself by using scrollIntoView with |
Good find, thanks @gildub ! The ref solution is interesting, I guess that just means something is different about that global document in jsdom or something like that. Glad it's working! |
Addresses #833