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

Show advanced search filter tags in search overview #1891

Closed
16 tasks done
chillu opened this issue Jul 13, 2017 · 22 comments
Closed
16 tasks done

Show advanced search filter tags in search overview #1891

chillu opened this issue Jul 13, 2017 · 22 comments

Comments

@chillu
Copy link
Member

chillu commented Jul 13, 2017

Acceptance Criteria

  • I can tell that advanced search filters have been applied without expanding the advanced search view. These filters show in the search term input (e.g. Type: RedirectorPage)
  • I can remove readonly search filter "tags" in the search term input (through touch and keyboard)
  • Removing filters updates the search results
  • Readonly search filter "tags" work with multiple select fields
  • Readonly search filter "tags" show dates and numbers in the correct locale formatting
  • Applies to ModelAdmin, AssetAdmin, Pages and any GridField implementations

Notes

Design preview (for context):

image

Related

Subtasks

  • Create a <Tag /> component based of ReactStrap's <Badge />.
  • Create a <TagList /> component grouping a list of <Tag /> together and providing a compact view.
  • Add entries to the Pattern Lib for <Tag /> and <TagList />
  • Wire TagList with Search so it can link up with the fields provided by via the formSchemaURL.
  • Adjust Search Layout and style to work with the Search Tags
  • Make the tags deletable with backspace
  • Handle search tag click
  • Update unit test.
  • Draft README for new Tag components.
  • UX Review

PRs

@clarkepaul
Copy link
Contributor

Search results in pages look pretty weird with the blue background and it doesn't work well with the sorting of columns.
image

@newleeland newleeland self-assigned this Nov 7, 2017
@newleeland
Copy link

newleeland commented Nov 12, 2017

@newleeland
Copy link

newleeland commented Feb 26, 2018

@clarkepaul
Copy link
Contributor

The version within the tab has weird spacing without showing where the actions would be. I think we need to rethink the title of search part as there are two approaches and we need to be clear which one we take.

  1. If after a search you are viewing a new gridfield of results (eg a new search result model) then we wouldn't show the actions of the original girdfield and in the example with tabs we wouldn't need to see the search icon anymore.
  2. Alternatively if after a search you are viewing the same gridfield but filtered then we shouldn't see the title "Search results".

@newleeland newleeland removed their assignment Feb 27, 2018
@newleeland
Copy link

newleeland commented Mar 13, 2018

Search Results of Files/Models/Files (Show in a new view)
https://invis.io/FTG16IYV5KB#/283335179_POC_CMS_Search_Model_Results_C2

Search Results of Gridfields (Show in same view)
https://invis.io/FTG16IYV5KB#/284539430_POC_CMS_Search_Gridfield_Results_C2

  • After I search, I can see what was searched in the search bar and filters under advance
  • I can easily insert a new term and search again.
  • I can remove filters and results would adjust to the new parameters.
  • I can sort results through the column headers

Related

#1777

@chillu
Copy link
Member Author

chillu commented Mar 25, 2018

Renamed this issue from "Pages search should show filter criteria and highlight search filters" to "Show advanced search filter tags in search overview"

@chillu chillu changed the title Pages search should show filter criteria and highlight search filters Show advanced search filter tags in search overview Mar 25, 2018
@maxime-rainville maxime-rainville self-assigned this Jul 24, 2018
@maxime-rainville
Copy link
Contributor

maxime-rainville commented Jul 24, 2018

My thinking here is we need a separate component for rendering the search tags.

The search tag will reflect what the current search results are showing. So if you add some value to a search field but don't trigger a search, the tags won't be added.

Equally, if you dismiss a tag, the a search will be the only filter value updated will be dismissed tag. Let's say you type in a new search term, but don't hit enter. You dismiss an existing tag. A new search is triggered, but your the old keyword.

<SearchTag /> component

<SearchTag 
    fieldName="nameOfField" 
    fieldLabel="Name of Field" 
    fieldValue="Value"
    onDismiss={this.onDimiss} />

The field label must be read from the Form Builder somehow. Alternatively, we could pass a reference to the form builder and have SearchTag figure out itself what its label should be.

On dismiss needs to pass back what the fieldName is the parent can know what should be dismiss.

I'm thinking of using the Badge component as the underlying component of SearchTag.

Complications

  • How do we handle the case where there's lots of tags? If you have too many tags your search term will be pushed off the visible area.
  • The position of the search term is currently controlled with padding to make sure it doesn't overlap with the Search icon or the buttons. Of the top of my head, my idea would be to measure the size of the search tag list and adjust the padding-left of the input accordingly.
  • I'm thinking of the search field is under a certain width, we probably should not display the tags.
  • Do we want to add a props that enables/disables search tags?

@chillu
Copy link
Member Author

chillu commented Jul 24, 2018

@maxime-rainville Thanks for your thoughts on this! Generally agree that we need a new component. It's probably not as specific as a "search tag". Please check out the CCers recent work on tagfield, might be something to reuse or harmonise? https://github.com/silverstripe/silverstripe-tagfield

@newleeland Can you please go through Max's "complications"?

@clarkepaul
Copy link
Contributor

@chillu Jared is away for the week, I've had a chat and will do my best to fill any gaps or questions.

@maxime-rainville
Copy link
Contributor

maxime-rainville commented Jul 25, 2018

Reusing SilverStripe Tag

I had a look at silverstripe/tag. I don't think I can reuse anything there to be honest. Their TagField is mostly just a slight extension of the react-select. While that's a pretty cool plugin, getting it to work in our search context would be a bit of a mission.

I might be able to write the style for the tag in a generic way that could be reapplied to the react-select tags, but that's about it.

edit
Actually, react-select as a pretty cool component replacement gimmick that could be use to inject our own generic Tag/Label component into it. https://react-select.com/components#replaceable-components

Handling large number of Search Filters

I had a meeting with @clarkepaul and we touch on how to handle the use case where there's lots of tags to display in the search box. We touch on a few ideas

Scrolling through the filters and search term

Paul mentioned that there original idea was that you would be able to scroll through the text box using your cursor and the tag would drop off on the left as if they were text. I explained this would be very difficult to achieve, because the tags themselves are not text that can be put in an input field. The ability to use the left/right arrow keys to go through a long input field value is native to the browser and it's not something we can highjack.

Multiple lines search field

Looking at how rich select component handles this use case, most of them just add an extra row of entry when the list of tags gets bigger than the width of the component.
image

That would probably look weird in the context of our search box.

Summary view of filters

Another way we could handle this, is to display a summary view once the number of active search filters gets bigger than certain width. I found an example of a search component doing this the other day, but for the life of me can't find it anymore. It looked something like this (my apologies to designers and UX experts everywhere).

too-many-filters

@clarkepaul
Copy link
Contributor

@maxime-rainville design wise it looks really good ;). Normally I would prefer if the overflow was scrollable as a standard field normally is, but I can understand that technically that might not be an option.

In principle I'm on board with the compact view, and it could be clickable to trigger the filter panel opening.

Do you think you can find a good way to trigger the filter summary? eg, when it consumes more than 60% of the field width.

@maxime-rainville
Copy link
Contributor

I'm thinking of doing new <Tag /> and <TagList /> components. A TagList could contain a list of Tags and accept a maxWidth prop. If the list goes beyond the provided max-width, it switches to the compack view.

Clicking on the compact view would be equivalent to clicking on the 'Show Filters' button.

That's probably enough for me to get started. I wouldn't mind having a proper mock up the compact view thought.

@chillu
Copy link
Member Author

chillu commented Jul 25, 2018

I had a look at silverstripe/tag. I don't think I can reuse anything there to be honest. Their TagField is mostly just a slight extension of the react-select. While that's a pretty cool plugin, getting it to work in our search context would be a bit of a mission.

This is also used in TreeDropdownField. We have two existing uses, why would we approach the third one (search tags) differently?

Multiple lines search field: That would probably look weird in the context of our search box.

Why? I think that's acceptable, particularly given that only a small fraction of users will ever see this view. "Summary view of filters" is nicer, but also more unplanned implementation complexity. I'll have a talk to Paul.

@chillu
Copy link
Member Author

chillu commented Jul 25, 2018

In terms of react-select use, we'd need to:

  • Allow free-form text without trying to match tags (that might be the hardest)
  • Build tags based on search metadata
  • Hook into the tag deletion events (re-trigger search)
  • Remove tags on deletion (they're not reselectable)

In exchange, we get:

  • Less implementation duplication
  • Built-in keyboard accessibility
  • Same styles for "tag" component (in the component, rather than just reusing global CSS)
  • Consistency in search box styling (e.g. close button)

Might or might not be worth the tradeoff, but should be investigated

@ScopeyNZ
Copy link
Contributor

Allow free-form text without trying to match tags (that might be the hardest)

react-select allows you to completely define what to do when it's trying to find options for a given search. While it's a slightly convoluted solution, returning with an empty response will prevent the component from trying to match tags.

As an aside - react-select itself is really extensible and is well maintained. It has a few architectural quirks (imo) but they're about to release a 2.0. Might be worth looking at that too - although that might be creating more work if we have to update the other two usages of react-select too...

@maxime-rainville
Copy link
Contributor

React-select vs custom implementation

While the look of our search box and of the react select component is similar, I think the functionality is actually quite different:

  • the drop down display a sub-form while react-select displays a list of item.
  • our X Mark hides the field while their X mark clears the search.
  • Our input field is an actual search box that expect a proper term to be added and will keep displaying that term, while their input field will auto-add tags.
  • I'll have to high jack most of their logic to remove/hide tag to wire it with the form.

I'm not inimitably familiar with how react-select is implemented, so maybe all this stuff is easy. But to me this sounds like these two components are trying to do different things.

If we decide to use react-select, pretty much everything I did for the search component will have to be scraped.

Displaying the search field over two lines

From what I can see of the mock up, it look it was designed so it would be same height has the Profile link on the left nav.

If you spread it over two lines, it won't aligned. Also a lot of the icons attached to the box might get in the way.

Again, apologies to designers and UX expert everywhere (I'm racking up a lot of bad karma with these guys today)

multiline search

In terms of implementation time, I guess the compact view and the multi line solution would be about equivalent.

@newleeland
Copy link

This is Work in progress design guide for advance search interactions:
https://invis.io/YGGYS6HDMRK#/310647254_Search

@maxime-rainville
Copy link
Contributor

So I've created the following components:

  • <Tag /> which renders an individual tag. It accepts a deletable props that will add a X mark.
  • <TagList /> which accepts a tags array props and will build a list of <Tag>
  • <CompactTagList/> which extends <TagList> and accepts a maxSize props. If the rendered is wider than the provided max size, compact list will automatically switch to a summary view instead.
  • <SummaryTag /> which uses <Tag/> to display a number with the filter icons.

This videos showcases the various components https://youtu.be/SrYNF1q_rTY

  • The first part displays a bunch of tags individually.
  • The second part display 2 Tag Lists ... one with deletable turned on and one with deletable off.
  • The third part displays two compact tag list ... one below its max size and one above its max size.

@maxime-rainville
Copy link
Contributor

I got the tag hooked into the search field:

  • tags will be updated as you change your search criteria
  • if you run out of space, the tags will be swapped with the summary view
  • the padding on the input will automatically be updated to match the space occupied by tags

https://youtu.be/hoc9KonKLU8

The tags don't do anything yet however.

@maxime-rainville
Copy link
Contributor

The tags can now be interacted with:

  • clicking the main body of a tag will open the filters and focus on it.
  • clicking a tag's X mark removes the tag and refresh the search.

I also fix the resizing logic to work in all browsers.

https://youtu.be/Z4eWEtO80e0

I still need to add logic to handle non-generic search fields, which is probably not going to be trivial. I figure there's probably another day of work in this.

@maxime-rainville
Copy link
Contributor

https://youtu.be/IJoE6fdaI70

I've adjusted the logic so different fields will generate different tags:

  • Select field tags will display the selected value as shown to the use in the drop down (as opposed the the underlying system value).
  • Multi select field tags will display a comma separated list of selected values.
  • Boolean field won't display a value, just the tag.
  • Composite fields will try to display a representation of the children field.
  • DateField will render the date using the locale specified on the field.

I've also added some logic so developers can customise how the tags are rendered.

@maxime-rainville
Copy link
Contributor

Got my PRs lined up. Still need to write the doc, but otherwise it's ready for peer review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants