-
Notifications
You must be signed in to change notification settings - Fork 167
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
MR Permissions - Group and Project dropdown issues #3219
MR Permissions - Group and Project dropdown issues #3219
Conversation
@@ -88,7 +88,7 @@ const TypeaheadSelect: React.FunctionComponent<TypeaheadSelectProps> = ({ | |||
noOptionsFoundMessage = defaultNoOptionsFoundMessage, | |||
isCreatable = false, | |||
isCreateOptionOnTop = false, | |||
createOptionMessage = defaultCreateOptionMessage, | |||
createOptionMessage = defaultSelectOptionMessage, |
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 didn't propagate the change of this name variable into the code. Let me know if it's needed ( I started but then decided that it will just be a bunch of places instead of just a label change, as we need it on the UI)
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 should still call it defaultCreateOptionMessage
so we're not disrupting things too much in here, we just need to pass a different value for createOptionMessage
where we render this component in RoleBindingPermissionsNameInput
.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #3219 +/- ##
==========================================
+ Coverage 85.39% 85.49% +0.09%
==========================================
Files 1277 1280 +3
Lines 28082 28229 +147
Branches 7487 7558 +71
==========================================
+ Hits 23980 24133 +153
+ Misses 4102 4096 -6
... and 32 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
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.
A few things here @YuliaKrimerman . There's one thing I'd love to get @jeff-phillips-18 's opinion on - and if we can't get that settled within the week we should probably exclude it from this issue and open a followup issue for just that focus bug that isn't a MR blocker.
@@ -69,7 +69,7 @@ export interface TypeaheadSelectProps extends Omit<SelectProps, 'toggle' | 'onSe | |||
} | |||
|
|||
const defaultNoOptionsFoundMessage = (filter: string) => `No results found for "${filter}"`; | |||
const defaultCreateOptionMessage = (newValue: string) => `Create "${newValue}"`; | |||
const defaultSelectOptionMessage = (newValue: string) => `Select "${newValue}"`; |
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.
@YuliaKrimerman we need to not change this for all consumers of TypeaheadSelect, only our usage in RoleBindingPermissionsNameInput
. Can you please undo this change and instead use the createOptionMessage
prop to override it in that usage only?
@@ -88,7 +88,7 @@ const TypeaheadSelect: React.FunctionComponent<TypeaheadSelectProps> = ({ | |||
noOptionsFoundMessage = defaultNoOptionsFoundMessage, | |||
isCreatable = false, | |||
isCreateOptionOnTop = false, | |||
createOptionMessage = defaultCreateOptionMessage, | |||
createOptionMessage = defaultSelectOptionMessage, |
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 should still call it defaultCreateOptionMessage
so we're not disrupting things too much in here, we just need to pass a different value for createOptionMessage
where we render this component in RoleBindingPermissionsNameInput
.
@@ -248,12 +246,17 @@ const TypeaheadSelect: React.FunctionComponent<TypeaheadSelectProps> = ({ | |||
}; | |||
|
|||
const onTextInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => { | |||
setFilterValue(value || ''); | |||
setFilterValue(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'm curious if removing this was necessary?
if (selected && value !== selected.content) { | ||
// Clear the selection when the input value changes | ||
if (onSelect) { | ||
onSelect(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.
This seems possibly undesirable, the selection shouldn't change until the user clicks another option. I assume this was to fix the value being duplicated when there's a selected option that has a space and you type in the input? I wonder if there's another way to fix that.
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 @YuliaKrimerman I think we should remove these lines, I troubleshooted a little and I think maybe the problem is outside this component. If you console.log selectOptions
in RoleBindingPermissionsNameInput
you'll see that actually when that option gets duplicated it is really being added in the list of options we pass down here. So it's something strange we're doing out there. It's also very strange that it only seems to happen for items that have a space in them.
I think it has something to do with these lines in RoleBindingPermissionsNameInput
:
if (value && !typeAhead.includes(value)) {
selectOptions.push({ value, content: value });
}
Ah -- it's because of the namespaceToProjectDisplayName
thing we do there. When you select a project that includes spaces, that's a display name like "savitha MR test", which is what ends up in our selectOptions
and is selected as our value
there. But the typeAhead
array is actual project names, like "savitha-mr-test". So the above lines are triggering adding the option to the list because it thinks it's missing.
I think the fix is to change the above line to:
if (value && !selectOptions.some((option) => option.value === value)) {
selectOptions.push({ value, content: 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.
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.
Addressed all other comments and kept the original implementation for this, let me know if it's ok to keep it, or if we want to take out this issue for the future.
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.
@YuliaKrimerman with your other change in place to remove the selectOptions.push
code, I tried removing the lines you added here (clear the selection when the input value changes) and it seems to behave like I would expect. I'm not seeing the above duplicates. Can you try removing this now and see if it works for you?
openMenu(); | ||
setTimeout(() => { | ||
textInputRef.current?.focus(); | ||
}, 100); | ||
} else if (isFiltering) { | ||
closeMenu(); | ||
} | ||
setTimeout(() => { | ||
textInputRef.current?.focus(); | ||
}, 100); | ||
}; |
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 change seems reasonable to me and does fix the focus issue, but I'm curious if @jeff-phillips-18 has an opinion on it since he wrote this code in #3094.
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 at this, I would say it is ok to remove the timeout, but in the <Select>
component below, add parameter:
shouldFocusFirstItemOnOpen={false}
This will keep focus on the input when the user clicks.
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.
@jeff-phillips-18 what about the removal of the closeMenu()
call here? I don't think I'm seeing the menu close when clicking the input anyway, I wonder if that's getting counteracted in the existing code. I don't see a problem with this part of the diff as-is, just wanted to make sure.
@@ -401,6 +403,7 @@ const TypeaheadSelect: React.FunctionComponent<TypeaheadSelectProps> = ({ | |||
onSelect={handleSelect} | |||
onOpenChange={(open) => !open && closeMenu()} | |||
toggle={toggle} | |||
shouldFocusFirstItemOnOpen={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.
Added as suggested from Jeff
if (value && !typeAhead.includes(value)) { | ||
selectOptions.push({ value, content: 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.
Removed the code that was adding the current value to selectOptions
if it wasn't in typeAhead
. This ensures that custom items don't persist in the dropdown.
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 fair point, I guess removing this entirely solves that as well
@@ -68,6 +64,18 @@ const RoleBindingPermissionsNameInput: React.FC<RoleBindingPermissionsNameInputP | |||
} | |||
}} | |||
placeholder={placeholderText} | |||
createOptionMessage={(newValue) => `Select "${newValue}"`} | |||
filterFunction={(filterValue, options) => { |
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.
Added this filterFunction in order to achieve the requirement It filters the existing options based on the input and adds a new option with the exact input value if no matches are found.
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 don't see any different behavior here when I try removing this filterFunction
. With or without it, I'm actually seeing that if I click the new option that doesn't match any select items, it doesn't remain selected in the dropdown. I think that's because we still need it to be one of the selectOptions
passed above for it to show as selected.
I also notice that with this filterFunction
in place, if you type text that doesn't even partially match any other options, it gets shown as the sole option without the "Select ___" text. So I think we don't want this filterFunction
and we need to fix the issue some other way.
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.
@YuliaKrimerman I think I figured it out - Try this. Remove this filterFunction
, and above where you removed the other code, add this:
// If we've selected an option that doesn't exist via isCreatable, include it in the options so it remains selected
if (!selectOptions.some((option) => option.value === value)) {
selectOptions.push({ value, content: value });
}
That ensures that our "newly created" item is in the list once it is selected, but disappears from the list if it is deselected.
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.
Sorry for the roundabout comments, I have a solution for the problem I identified here:
@@ -68,6 +64,18 @@ const RoleBindingPermissionsNameInput: React.FC<RoleBindingPermissionsNameInputP | |||
} | |||
}} | |||
placeholder={placeholderText} | |||
createOptionMessage={(newValue) => `Select "${newValue}"`} | |||
filterFunction={(filterValue, options) => { |
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.
@YuliaKrimerman I think I figured it out - Try this. Remove this filterFunction
, and above where you removed the other code, add this:
// If we've selected an option that doesn't exist via isCreatable, include it in the options so it remains selected
if (!selectOptions.some((option) => option.value === value)) {
selectOptions.push({ value, content: value });
}
That ensures that our "newly created" item is in the list once it is selected, but disappears from the list if it is deselected.
@YuliaKrimerman without the code I proposed, when I type "istio" and click the "Select 'istio'" option, the dropdown appears as if nothing is selected even though the I do notice the issue you pointed out with my suggestion, it's because I forgot to make sure // If we've selected an option that doesn't exist via isCreatable, include it in the options so it remains selected
if (value && !selectOptions.some((option) => option.value === value)) {
selectOptions.push({ value, content: value });
} |
@mturley Yep, you're right, now it works good. Pushed the latests and ready for re-review |
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.
Perfect, thanks @YuliaKrimerman !!
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: mturley The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
RHOAIENG-12025
Description
How Has This Been Tested?
Tested on the UI
Test Impact
One test change to update the Create to Select . Also When changing the label to select I didn't change all the variable names of that label so they are still mostly shown as "create ...." in the code and not as select (except at the original line)
Request review criteria:
Self checklist (all need to be checked):
If you have UI changes:
After the PR is posted & before it merges:
main