-
Notifications
You must be signed in to change notification settings - Fork 2
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
UI update: regex checking for Project Name/Tag inputs in edit metadata modal #319
Conversation
updated hands on table
Integrate views into the user interface
Critical bug fixes
…nd tag for metadata modal. added conditional helper text that appears if user enters invalid character.
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 start. I totally agree with introducing another state variable to verify that the name
and tag
are correct. A couple thoughts and ideas...
- Instead of using
onKeyDown
andonPaste
callbacks, could we tie the check directly to theonChange
callback? It gets messy withreact-hook-form
? Here is an idea:
We are already "watching" the new name and the new tag. Could we add an effect? Something like:
useEffect(() => {
checkName(newName)
checktag(newTag)
}, [newName, newTag])
Does that make sense? We could go over it together if needed. Lot of React quirks here.
- As I think you rightly pointed out, this needed to be validated on the API too. Do you feel comfortable tackling that too? Hows your Python? Moreover, we need to run this validation when someone submits a new PEP too.
I believe there a lot in the src/components/forms/
folder that need this logic too.
Let me know if that all made sense!
Here is some reading on uesEffect
. With great power, though, comes great responsibility. useEffect
is often called useFootGun
and I try to use it as little as possible. I really like this article by Dan Abromov, one of the creators of React.
Changes addressed:
Thanks for the pointers on useEffect(). It was pretty confusing at first because it tracks the input value itself and not the key down or paste event but it seems to work pretty well. |
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 love how I sent a link to an article telling you not to use useEffect
, then proceeded to say lets use useEffect
.
I think I was totally wrong now that I am looking at it. Instead of the effect, I think we should just define the variable:
export const ProjectMetaEditForm = () => {
const nameIsBad = /[^0-9a-zA-Z_-]/.test(newName);
const tagIsBad = /[^0-9a-zA-Z_-]/.test(newTag);
return (
<div>
{ nameIsBad ? <p className = 'text-secondary pt-1' style = {{fontSize: '.75em'}}>Invalid name. Project names should only contain letters, numbers, etc etc etc </p> : null }
</div>
)
}
Because useState
triggers a rerender anyways, there's no need to tie all the to a useEffect
, so that's my bad for giving bad advice there.
Finally... do you think you could implement something similar on the other components?
@@ -252,7 +248,7 @@ export const ProjectMetaEditForm: FC<Props> = ({ | |||
<button | |||
onClick={() => mutation.mutate()} | |||
id="metadata-save-btn" | |||
disabled={(!isDirty && isValid) || mutation.isPending} | |||
disabled={(!isDirty && isValid || badName || badTag) || mutation.isPending} |
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.
Great! This is perfect.
…other components and updated error message contents and formatting. added mode: 'onChange' for formState instantation for these 3 other components.
Done, updated checks in other components |
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 -- I love that you found those react-hook-form
APIs and used them. Thats a great solution. Could we emulate that over on the edit-project-meta
form? I think thats the only one using the old system.
@@ -119,6 +119,9 @@ export const ProjectMetaEditForm: FC<Props> = ({ | |||
} | |||
}, [newPop]); | |||
|
|||
const isBadName = newName ? (/[^0-9a-zA-Z_-]/.test(newName) ? "Project Name must contain only alphanumeric characters, '-', or '_'." : null) : "Project Name must not be empty." | |||
const isBadTag = newTag ? (/[^0-9a-zA-Z_-]/.test(newTag) ? "Project Tag must contain only alphanumeric characters, '-', or '_'." : null) : "Project Tag must not be empty." |
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.
Actually, the project tag can be empty.
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 really loved what you did in the blank-project-form
component, using build in react-hook-form
API's to validate -- should we do that here?
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.
Actually, the project tag can be empty.
I tried submitting a blank tag edit on the deployed UI and it doesn't let you so I assumed we weren't supposed to allow it. Is it supposed to default to 'default' if empty?
value: /^[a-zA-Z0-9_-]+$/, | ||
message: "Project Name must contain only alphanumeric characters, '-', or '_'.", |
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 awesome, I didn't know this was possible with react-hook-form
!
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.
// instantiate form
const {
reset: resetForm,
register,
control,
watch,
setValue,
formState: { isValid, errors },
} = useForm<FromFileInputs>({
mode: 'onChange', <<<---------- had to add this for it to work
defaultValues: {
is_private: false,
pep_schema: 'pep/2.1.0',
namespace: defaultNamespace || user?.login || '',
},
});
So I added that mode: 'onChange' line to make it work but wasn't sure if it would cause lag if it started checking after every single input. Is this negligible with react/our use case or is it something we have to worry about?
<ErrorMessage errors={errors} name="project_name" render={({ message }) => message ? (<p className='text-secondary pt-1' style={{fontSize: '.75em'}}>{message}</p>) : null} /> | ||
<ErrorMessage errors={errors} name="tag" render={({ message }) => message ? (<p className='text-secondary pt-1' style={{fontSize: '.75em'}}>{message}</p>) : null} /> |
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.
Feel like I've tried to use this before with mixed results. Have you tried?
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.
Just tried it myself and it looks great! What do you think about making the error message text red? (danger
)
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.
Changes reviewed
…r message for when both name and tag are bad for all components. added sample count to project page. cleaned up project page slightly (borders, padding, etc).
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.
Looks great! We should probably change the base to merge into dev
instead of master
Inputs for Project Name and Tag will only allow alphanumeric characters, '_', and '-'. If a user attempts to type an invalid character or paste a string with an invalid character into these inputs, the input will not let them and some helper text will appear to let the user know which characters are supported.
Someone can work around this by going into browser inspect element or call the API endpoint itself with invalid characters, so we should still have some API level check for these strings.