Skip to content
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

feat: add search to Team list #4174

Merged
merged 18 commits into from
Jan 29, 2025
Merged

Conversation

RODO94
Copy link
Contributor

@RODO94 RODO94 commented Jan 21, 2025

What does this PR do?

This PR introduces a SearchBox component which pulls in a set of records and search keys, and outputs the results using a setState function.

This is tied into the larger epic here: https://trello.com/c/7av8lsVr/3160-epic-as-an-editor-i-want-to-have-a-way-to-organise-my-flows-so-that-i-can-easily-find-what-im-looking-for

I am using the useSearch hook developed and PoC'd here: #3462

Although I took a slightly different approach to the PoC, due to the way my page was rendering and having to render a list in a parent component.

Copy link

github-actions bot commented Jan 21, 2025

Removed vultr server and associated DNS entries

const debouncedSearch = useMemo(
() =>
debounce((recordsToUpdate: T[]) => {
setRecords(recordsToUpdate);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted there to be a slight delay when processing the results so you don't receive nothing when you start typing. Iterated around doing this around search instead but found this to be the most robust with the other rendering going on. It felt nicer to let search run when things change and then wait to pull the results out of that after the 500ms

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hit a similar conclusion with the Search/index.ts component - it would be nice to have debounce be part of the hook but I couldn't find a way to get it to work and render as expected.

I don't think the setup here is quite correct though - this looks like it's setting the records (cheap!) on the debounce vs running the search (expensive).

If you take a look at the file mentioned above I think the order of operations is -

  • Form value changes
  • formik.handleSubmit() is called
  • This debounces the search, based on the pattern
  • search(pattern) updates the results variable

If I add a console.log() I see the search firing on each keystroke.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not met this so directly, but I have switched this so the search sits in the debounce!

My difficulty was in how to handle the adding of results to the setRecords state dispatch

@RODO94 RODO94 marked this pull request as ready for review January 22, 2025 16:46
@RODO94 RODO94 requested a review from a team January 22, 2025 17:37
Copy link
Contributor

@DafyddLlyr DafyddLlyr left a 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 to take a second look at.

The structure is good, but the implementation is a little unclear. Fundamentally the responsibility of this component is to handle the search term, run the search, and then update it's parent's state.

Something like this will probably get you closer to what you're looking for here -

// When the search is reset, display the full list
useEffect(() => {
  if (!formik.values.pattern) setRecords(records)
}, [formik.values.pattern, setRecords, records]);

// When results are updated, update parent state with the filtered records
useEffect(() => {
  if (!results.length) return;
  const filteredRecords = results.map(result => result.item);
  setRecords(filteredRecords)
}, [results, setRecords]);

editor.planx.uk/src/pages/Team.tsx Outdated Show resolved Hide resolved
editor.planx.uk/src/pages/Team.tsx Outdated Show resolved Hide resolved
editor.planx.uk/src/pages/Team.tsx Outdated Show resolved Hide resolved
editor.planx.uk/src/pages/Team.tsx Outdated Show resolved Hide resolved
editor.planx.uk/src/pages/Team.tsx Show resolved Hide resolved
editor.planx.uk/src/ui/shared/SearchBox/SearchBox.tsx Outdated Show resolved Hide resolved
editor.planx.uk/src/ui/shared/SearchBox/SearchBox.tsx Outdated Show resolved Hide resolved
const debouncedSearch = useMemo(
() =>
debounce((recordsToUpdate: T[]) => {
setRecords(recordsToUpdate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hit a similar conclusion with the Search/index.ts component - it would be nice to have debounce be part of the hook but I couldn't find a way to get it to work and render as expected.

I don't think the setup here is quite correct though - this looks like it's setting the records (cheap!) on the debounce vs running the search (expensive).

If you take a look at the file mentioned above I think the order of operations is -

  • Form value changes
  • formik.handleSubmit() is called
  • This debounces the search, based on the pattern
  • search(pattern) updates the results variable

If I add a console.log() I see the search firing on each keystroke.

editor.planx.uk/src/ui/shared/SearchBox/SearchBox.tsx Outdated Show resolved Hide resolved
editor.planx.uk/src/ui/shared/SearchBox/SearchBox.tsx Outdated Show resolved Hide resolved
@ianjon3s ianjon3s force-pushed the ian/team-page-rebuild branch from fb24317 to 024214c Compare January 24, 2025 14:41
Copy link
Contributor

@DafyddLlyr DafyddLlyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much clearer and simpler 👍 Thanks for picking up the suggested changes so far.

I'm still hitting this issue when running locally -
image

I'm pretty sure it's as you're describing - we're passing in but also updating records within this component and triggering the loop. Taking a closer look at this now - it might be that the parent needs to keep an original and filtered list, not the search box itself.

I'll post an update here when I have one or maybe we can stay on after standup and debug 👍

editor.planx.uk/src/ui/editor/SimpleMenu.tsx Outdated Show resolved Hide resolved
editor.planx.uk/src/ui/editor/SimpleMenu.tsx Outdated Show resolved Hide resolved
<Box sx={{ position: "relative" }}>
<Input
sx={{
borderColor: (theme) => theme.palette.border.input,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry - should have been clearer here - I was specifically referring to the border colour that doesn't match.

image image

This is actually inconsistent in a few places in the Editor atm and I'm keen not to introduce any more (cc @ianjon3s)

image

<Box sx={{ position: "relative" }}>
<Input
sx={{
borderColor: (theme) => theme.palette.border.input,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spinner is great btw 👌

editor.planx.uk/src/ui/shared/SearchBox/SearchBox.tsx Outdated Show resolved Hide resolved
}: SearchBoxProps<T>) => {
const [isSearching, setIsSearching] = useState(false);
const [searchedTerm, setSearchedTerm] = useState<string>();
const [originalRecords] = useState(records);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This originalRecords variable is kept in place to handle behaviour for when we run setRecords(newRecords) for a searched term - this updates records in the parent component and triggers a re-render, but originalRecords is only set on mount and not reset when the components re-render, so it acts as a proper original version of the list.

Records as an immutable prop works differently since it will be updated when the Parent component is re-rendered, like when setRecords(newRecords) is triggered

@ianjon3s
Copy link
Contributor

Good catch on the input border consistency @DafyddLlyr , something I've been meaning to address.

The input borders used in the editor modal are deliberately left lower contrast due to the density and close-proximity of input groupings, and when used on a single/isolated input (especially against a white background) the same border shade is too low-contrast to be effective, hence the darker border shade for the filters setup.

What's needed is a consistent border shade that works in both instances, looking at your examples it seems we already have a style used for data and select inputs that would be a universal fit. I'll go through and update to this in a separate PR.

Copy link
Contributor

@DafyddLlyr DafyddLlyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

@RODO94 RODO94 merged commit 91a3328 into ian/team-page-rebuild Jan 29, 2025
10 checks passed
@RODO94 RODO94 deleted the rory/search-flow-list-V02 branch January 29, 2025 09:18
RODO94 added a commit that referenced this pull request Jan 29, 2025
RODO94 added a commit that referenced this pull request Jan 30, 2025
RODO94 added a commit that referenced this pull request Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants