ral-facilities / datagateway

DataGateway is a portal that supports discovery and access large science facilities data. It is developed as a plugin for SciGateway
Apache License 2.0
9 stars 5 forks source link

Keep search history for logged in users #1471

Open agbeltran opened 1 year ago

agbeltran commented 1 year ago

Description: It would be useful, especially for users who are logged in, to keep the history (with a configurable number of search strings) of the searchers that they performed.

Acceptance criteria:

MRichards99 commented 1 year ago

Stumbled across this issue and starting thinking about how this would work, ended up with a couple of unanswered questions. For the purposes of scoping out this issue, I thought I'd paste them here

@louise-davies maybe you could help keep my curiosity at bay?

louise-davies commented 1 year ago

@MRichards99 it depends on what we mean by "keep" a search history. There's a few things we could potentially do

  1. leverage browser autocompleting (see https://www.w3schools.com/html/html_forms.asp) - once you submit a form then a browser will "remember" previously submitted values. This persists across browser refreshes, but is locked to a single browser (although might "migrate" across PCs if a user is logged into their browser a la Google or Mozilla accounts)
  2. store in the app - then yes, we could store this in Redux or perhaps even just local component state or something, but this would be info lost on refresh or browser change.
  3. Use localstorage, similar to the first solution but again doesn't persist across browsers but persists across refreshes. Means we can make our own UI though unlike the 1st solution, but that's also a downside as we have to code it rather than rely on the browser.
  4. Store it on the server, which is the ultimate "user can restore their history across PCs and browsers"
    • in this case, storing it in the topcat DB makes sense

I would assume we'd have an autocomplete field if we're implementing it ourselves like how google does it, or if we go with 1 then it's the browsers that determine the UI.

MRichards99 commented 1 year ago

@louise-davies I feel like option 4 is the most complete implementation of the functionality but not sure whether it's overkill or not (I'm not familar with a typical DataGateway user so I'm not sure). I've been having a go with option 1 to see how that might work, mainly as it sounded the least daunting.

I've been playing around with the autocomplete attribute on the search text field (mainly looking at https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) and I can get autocomplete to work when using one of the standard values (e.g. name which displays my name as I'm logged into my Google account on Chrome):

image

To use non-standard values, it looks like you set autocomplete="on" and then the autofill is done based on the name of the input. That's what I understand from playing around with the example on w3schools (https://www.w3schools.com/tags/att_autocomplete.asp). I tried to recreate this in DataGateway but couldn't make it fully work. The closest I got was setting the name to fname (the name of the input from the w3schools example) and I managed to get the submitted values while playing around with the online example:

Code

return (
    <TextField
      className="tour-search-textfield"
      id="filled-search"
      name="fname"
      label={t('searchBox.search_text')}
      type="search"
      margin="normal"
      value={searchText}
      onChange={handleChange}
      onKeyDown={handleKeyDown}
      fullWidth
      variant="outlined"
      color="secondary"
      inputProps={{
        'aria-label': t('searchBox.search_text_arialabel'),
      }}
      autoComplete="on"
    />
  );

Result image

If I change the name of the TextField to something like recent-search, I can't get the autofill to work.

Have you got any suggestions?

louise-davies commented 1 year ago

@MRichards99 the latter case is what we want - you don't actually need to set the autocomplete field at all, just having a name on the input is what matters as we aren;t any of the autocomplete types (like address, email or name). I think though that in order for the browser to "remember" submissions, we have to add a name to the input, surround the input in a form and have a button with type submit also in the form (from https://stackoverflow.com/a/68661046/7458681). event.preventDefault() stops the browser from reloading the page as it normally does with form tags. This snippet below works for me (i.e. pressing enter or clicking the button does nothing, but the browser remembers the string)

<form
    onSubmit={(event) => {
       event.preventDefault();
    }}
>
   <TextField name="dg-search" />
   <button type="submit" />
</form>

I also just added the type="submit" to the search button, a name to the search input, and wrapped id='container-searchbox' with a form with event.preventDefault onSubmit in searchBoxContainer and it works 🎉

MRichards99 commented 1 year ago

Ah ok, I'll try that on Friday to see if I can get that to work!

Could we work out which approach should be used to implement this issue? As I've got interested in this issue, I think it's something I want to have a go at implementing.