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

refactor: upgrade AutocompleteJS to v1 & update related code (Top Navigation Desktop Only) #1781

Merged
merged 14 commits into from
Nov 1, 2023

Conversation

thecristen
Copy link
Collaborator

Asana Tickets:

Backend highlights

Important

Our search box (both old and new) works by sending a POST request to our /search/query endpoint, which in turn does some processing and then encodes and sends a rather complex queries request to Algolia.

Before, the shaping the requests data for sending to Algolia was mostly being done with a mess of JS class functions, and finished in the backend in the SearchController. Now, this work is all shifted to the backend, to keep the frontend JS simpler. This is mostly achieved though the new Algolia.Query.Request module.


Note

This PR introduces our first Phoenix-based functional component.

<.algolia_autocomplete /> is intended to be reused wherever we'll need a search box. While it depends on LiveView under the hood to handle instantiation via a phx-hook object, it's a simpler component with no lifecycle or state. When mounted, it automatically calls setupAlgoliaAutocomplete().


Frontend highlights

Warning

There's a lot of JS here, but almost all of it is just here to correctly specify the many parameters supported by the autocomplete-js library.

Because of this, I tried to be careful with unit testing. We can assume the library itself is adequately tested, so the tests included here focus on portions that are unique to our particular implementation.


Note

Three "sources" are searchable in the header search box

  • geolocation (prompts user browser to share location),
  • locations in general (calls a backend endpoint that makes the request to AWS Location Service)
  • our actual Algolia indexes (calls the backend endpoint noted in the "Backend highlights" section above)

None of this is newly implemented here, we're reusing endpoints and helper functions and templates as much as possible.


Warning

The autocomplete-js library typings are a bit chaotic.

Dealing with multiple sources (which each return results of different sorts of object) made typing more complicated still. Fighting with TypeScript was a big part of this work; I tried my best!


Visually, I aimed to keep everything as close to our current implementation as possible. I built off the library's default theme to help me achieve that, so there's some custom CSS based on that.


I tweaked the current header navigation and integration testing code to ensure compatibility.


General checks

  • Are the changes organized into self-contained commits with descriptive and well-formatted commit messages? This is a good practice that can facilitate easier reviews.
  • Testing. Do the changes include relevant passing updates to tests? This includes updating screenshots. Preferably tests are run locally to verify that there are no test failures created by these changes, before opening a PR.
  • Tech debt. Have you checked for tech debt you can address in the area you're working in? This can be a good time to address small issues, or create Asana tickets for larger issues.

New UI, or substantial UI changes

  • Cross-browser compatibility is less of an issue now that we're no longer supporting IE, but changes still need to work as expected in Safari, Chrome, and Firefox.
  • Are interactive elements accessible? This includes at minimum having relevant keyboard interactions and visible focus, but can also include verification with screen reader testing.
  • Other accessibility checks such as sufficient color constrast, or whether the layout holds up at 200% zoom level.

@thecristen thecristen requested a review from a team as a code owner October 24, 2023 19:48
@thecristen thecristen requested a review from i0sea October 24, 2023 19:48
@thecristen thecristen added the dev-green Deploy to dev-green label Oct 24, 2023
@thecristen thecristen temporarily deployed to dev-green October 24, 2023 19:50 — with GitHub Actions Inactive
@kotva006
Copy link
Contributor

Will using a live view make writing front end tests harder? Is this something we need to mock when rendering component tests?

@@ -177,7 +177,7 @@ function _fileIcon(hit) {
}
}

function _contentIcon(hit) {
export function _contentIcon(hit) {
Copy link
Contributor

@kotva006 kotva006 Oct 26, 2023

Choose a reason for hiding this comment

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

nit-pick: For consistency this function should not start with an _ if it is being exported

@thecristen
Copy link
Collaborator Author

Will using a live view make writing front end tests harder? Is this something we need to mock when rendering component tests?

@kotva006 Probably not. Did you see the tests this PR has and do you think another type of test is needed?

In this (relatively simple) case, the frontend test operates on HTML that's presumed already-generated from the backend, and assesses whether instantiating the frontend library on it works as expected. And the backend test checks for expected generated markup. And the integration test covers the is-it-present-if-you-go-visit-the-page piece.

For a more complex component that leverages more of LiveView's features around handling events and updating state and interacting with the server, I imagine those tests will be more (if not entirely) on the Elixir-side, using various tooling that comes with LiveView. 🤷🏼‍♀️

@thecristen thecristen temporarily deployed to dev-green October 26, 2023 17:42 — with GitHub Actions Inactive
@thecristen thecristen temporarily deployed to dev-green October 27, 2023 15:31 — with GitHub Actions Inactive
This will increase the clickable area of links and buttons.
@thecristen thecristen temporarily deployed to dev-green October 27, 2023 16:50 — with GitHub Actions Inactive
return Object.keys(x).includes("_content_type");
}

export const getItemType = (item: Item): string => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This function doesn't seem to be used anywhere

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

nice! will remove

Copy link
Contributor

@kotva006 kotva006 left a comment

Choose a reason for hiding this comment

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

Looks Good

@thecristen thecristen merged commit ee26428 into master Nov 1, 2023
20 of 23 checks passed
@thecristen thecristen deleted the cbj/header-autocomplete branch November 1, 2023 15:26
@thecristen thecristen removed the dev-green Deploy to dev-green label Nov 2, 2023
Copy link

sentry-io bot commented Nov 5, 2023

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ SyntaxError: JSON Parse error: Unexpected identifier "undefined" <anonymous>(ts/ui/autocomplete/sources/getLocat... View Issue

Did you find this useful? React with a 👍 or 👎

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