User Autocomplete

Why?

You want to be able to look up a user by name, and then select them (either to add them to something, or to visit a profile)


How?

This component has 2 different forms (depending on whether you're using a computer or a mobile device/tablet - this is because Ant Design AutoComplete inputs are very slow on mobile).

It works by using a (debounced) input from the user to search as a prefix on the user's name, and then returns a list of users that match.

Here's the code:

const [debouncedText] = useDebounce(searchText, 200)
const nameSearch = functions.httpsCallable('elastic-nameSuggest')
useEffect(() => {
  let ignore = false
  async function fetchData() {
    const optionSearch = await nameSearch({
      input: debouncedText,
      managedBy,
    })
      .then((result) => {
        console.log({ result })
        if (result.data && result.data.hits && result.data.hits.hits) {
          const options = []

          const results = result.data.suggest['name-suggest'][0].options
          results.forEach((one) => {
            options.push({
              text: one._source['Full Name'][0],
              data: one._source,
              value: one._id,
              User: one._source?.User,
            })
          })
          result.data.hits.hits
            .filter((hit) => hit._score > 0)
            .forEach((one) => {
              if (
                options.filter((item) => item.value === one._id).length === 0
              ) {
                options.push({
                  text: one._source['Full Name']?.[0],
                  data: one._source,
                  value: one._id,
                  User: one._source?.User,
                })
              }
            })
          return options.filter((item) => !organisation?.Admin[item.User])
        }
      })
      .catch((error) => console.log('autocomplete error', error))
    if (!ignore) setMemberOptions(optionSearch)
  }

  if (debouncedText) fetchData()
  else setMemberOptions([])
  return () => {
    ignore = true
  }
}, [debouncedText])

Useful props:

dontDoStuffOnBlur:

This is a boolean that stops the component from doing anything when the input is blurred (i.e. when you click away from the input).

Otherwise, this component will return a "new user" with _id = "new"

explicityAddNewPerson:

This controls whether the first option in the list is "Add new person" or not.