Skip to content

feat: add search highlight/expand and "no tags" message [FC-0036] - #799

Merged
xitij2000 merged 1 commit into
openedx:masterfrom
open-craft:rpenido/fal-3615-ux-refinements-from-sandbox-round-3
Feb 2, 2024
Merged

feat: add search highlight/expand and "no tags" message [FC-0036]#799
xitij2000 merged 1 commit into
openedx:masterfrom
open-craft:rpenido/fal-3615-ux-refinements-from-sandbox-round-3

Conversation

@rpenido

@rpenido rpenido commented Jan 16, 2024

Copy link
Copy Markdown
Contributor

Description

This PR makes minor improvements in the search taxonomy UI.

  • It expands taxonomies that match the search and highlight the search term.
  • Add "No tag found with search term '....'" message.

tag-search

Suporting Information

Testing instructions

Open the tagging drawer and check the search responses to different queries


Private-ref: FAL-3615

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Jan 16, 2024
@openedx-webhooks

openedx-webhooks commented Jan 16, 2024

Copy link
Copy Markdown

Thanks for the pull request, @rpenido! Please note that it may take us up to several weeks or months to complete a review and merge your PR.

Feel free to add as much of the following information to the ticket as you can:

  • supporting documentation
  • Open edX discussion forum threads
  • timeline information ("this must be merged by XX date", and why that is)
  • partner information ("this is a course on edx.org")
  • any other information that can help Product understand the context for the PR

All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here.

Please let us know once your PR is ready for our review and all tests are green.

Comment on lines +55 to +57
useEffect(() => {
setNumPages(1);
}
}, [searchTerm]);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This hook will be called every time searchTerm changes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So initially we had this as a useEffect, however we opted for this approach instead after a discussion on a previous PR, since React discourages the use of useEffect in this manner as it causes extra re-renders: https://react.dev/learn/you-might-not-need-an-effect#resetting-all-state-when-a-prop-changes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the docs! I didn't know that this was the recommended way.
Reverted: 62022b5

style={{
minHeight: '44px',
}}
{tagPages.isLoading ? (

@rpenido rpenido Jan 16, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed tagPages from an array to an object that consolidates all pages. More info in the hook

Comment on lines -25 to -32
* @returns {{
* hasMorePages: boolean,
* tagPages: {
* isLoading: boolean,
* isError: boolean,
* data: TagListData[],
* }[],
* }}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removing the return type makes it be inferred from the function return

const preLoadedData = new Map();

dataPages.forEach(result => {
const newTags = dataPages.map(result => {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This makes the newTags be correctly inferred from the return type.

Comment on lines +87 to +94
const flatTagPages = {
isLoading: tagPages.some(page => page.isLoading),
isError: tagPages.some(page => page.isError),
isSuccess: tagPages.every(page => page.isSuccess),
data: tagPages.flatMap(page => page.data),
};

return { hasMorePages, tagPages: flatTagPages };

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I made this change trying to simplify the component side.

Also, I'm not sure why, a new tagPages is being generated every render (I don't think this useMemo is don't its job).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you mean every time the searchTerm changes when you say every render? I can't remember if this issue was happening before.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Every render. I got that when I added a useEffect with tagPages in the dependency array and updated an state in the hook. It caused a render loop. But I don't think this is a problem now.

@rpenido
rpenido marked this pull request as draft January 16, 2024 21:19
@rpenido
rpenido requested a review from yusuf-musleh January 16, 2024 21:19

@yusuf-musleh yusuf-musleh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@rpenido Great work! It works well upon testing it. I left a few comments/suggestions.

Comment on lines +55 to +57
useEffect(() => {
setNumPages(1);
}
}, [searchTerm]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So initially we had this as a useEffect, however we opted for this approach instead after a discussion on a previous PR, since React discourages the use of useEffect in this manner as it causes extra re-renders: https://react.dev/learn/you-might-not-need-an-effect#resetting-all-state-when-a-prop-changes

const parts = text.split(new RegExp(`(${highlight})`, 'gi'));
return (
<span>
{parts.map((part) => (part.toLowerCase() === highlight.toLowerCase() ? <span className="bg-accent-b">{part}</span> : part))}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This needs to have a unique key attribute, there are warnings in the console when I perform a search.

@rpenido rpenido Jan 17, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed here: b574cf5 !

Comment on lines +59 to 84
useEffect(() => {
if (tagPages.isSuccess) {
if (searchTerm) {
const expandAll = tagPages.data.reduce(
(acc, tagData) => ({
...acc,
[tagData.value]: !!tagData.childCount,
}),
{},
);
setDropdownStates(expandAll);
} else {
setDropdownStates({});
}
}
}, [searchTerm, tagPages.isSuccess]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I could be mistaken if this is the right approach, but I think this could also be achieved without the use of useEffect, if you use the condition from the previous code that checks of the searchTerm has changed and add the logic there. Here is a semi-working solution just to get the idea across:

  const [prevSearchTerm, setPrevSearchTerm] = useState(searchTerm);

  // Reset the page and tags state when search term changes
  // and store search term to compare
  if (prevSearchTerm !== searchTerm) {
    setPrevSearchTerm(searchTerm);
    setNumPages(1);

    if (tagPages.isSuccess) {
      if (searchTerm) {
        const expandAll = tagPages.data.reduce(
          (acc, tagData) => ({
            ...acc,
            [tagData.value]: !!tagData.childCount,
          }),
          {},
        );
        setDropdownStates(expandAll);
      } else {
        setDropdownStates({});
      }
    }
  }

This code doesn't correctly expand all the tags, just a demonstration for what I mean, but needs adjustments if this is the route we want to take.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm afraid of this path because it could run this code before the API return (tagPages.isSuccess === False) and will not run again when the isSuccess changes.

Comment on lines +87 to +94
const flatTagPages = {
isLoading: tagPages.some(page => page.isLoading),
isError: tagPages.some(page => page.isError),
isSuccess: tagPages.every(page => page.isSuccess),
data: tagPages.flatMap(page => page.data),
};

return { hasMorePages, tagPages: flatTagPages };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you mean every time the searchTerm changes when you say every render? I can't remember if this issue was happening before.


import { useTaxonomyTagsData } from './data/apiHooks';

const HighlightedText = ({ text, highlight }) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I like the yellow highlighted text! It familiar to how chrome matches things you search on. However I double checked with the Figma design, it seems like it includes "bolding" of the matching text instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed here: 99ec77d

@rpenido
rpenido force-pushed the rpenido/fal-3615-ux-refinements-from-sandbox-round-3 branch 2 times, most recently from fa54099 to 1d44c8a Compare January 17, 2024 18:23
@codecov

codecov Bot commented Jan 17, 2024

Copy link
Copy Markdown

Codecov Report

Attention: 3 lines in your changes are missing coverage. Please review.

Comparison is base (49d4fd4) 90.58% compared to head (74a1684) 90.58%.

Files Patch % Lines
...ontent-tags-drawer/ContentTagsDropDownSelector.jsx 90.90% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master     #799   +/-   ##
=======================================
  Coverage   90.58%   90.58%           
=======================================
  Files         511      511           
  Lines        8879     8902   +23     
  Branches     1912     1919    +7     
=======================================
+ Hits         8043     8064   +21     
- Misses        811      813    +2     
  Partials       25       25           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@rpenido
rpenido force-pushed the rpenido/fal-3615-ux-refinements-from-sandbox-round-3 branch from 1d44c8a to 979d585 Compare January 17, 2024 18:37
@rpenido
rpenido marked this pull request as ready for review January 17, 2024 18:46
@rpenido rpenido changed the title fix: add search highlight/expand and "no tags" message fix: add search highlight/expand and "no tags" message [FC-0036] Jan 17, 2024
@rpenido
rpenido requested a review from yusuf-musleh January 18, 2024 13:18
@rpenido

rpenido commented Jan 18, 2024

Copy link
Copy Markdown
Contributor Author

Could you take another look here @yusuf-musleh?

@yusuf-musleh yusuf-musleh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍 @rpenido Looks good to me!

  • I tested this: Testing it out locally, its working well
  • I read through the code
  • I checked for accessibility issues
  • Includes documentation
  • I made sure any change in configuration variables is reflected in the corresponding client's configuration-secure repository.

@xitij2000 xitij2000 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good!

@rpenido

rpenido commented Jan 31, 2024

Copy link
Copy Markdown
Contributor Author

Rebased @xitij2000!

@xitij2000

Copy link
Copy Markdown
Contributor

Rebased @xitij2000!

One small thing, I should have noticed this before. I don't think "fix" is the correct category for this change. It is definitely a feature. Please update the PR title and commit message, and I will merge it. Sorry for not noticing this sooner.

@rpenido rpenido changed the title fix: add search highlight/expand and "no tags" message [FC-0036] feat: add search highlight/expand and "no tags" message [FC-0036] Feb 2, 2024
@rpenido
rpenido force-pushed the rpenido/fal-3615-ux-refinements-from-sandbox-round-3 branch from bcd501f to 74a1684 Compare February 2, 2024 12:21
@rpenido

rpenido commented Feb 2, 2024

Copy link
Copy Markdown
Contributor Author

You're right @xitij2000! Thank you!
Changed the title and squashed the commits changing the messsage.

@xitij2000
xitij2000 merged commit 24c48bc into openedx:master Feb 2, 2024
@openedx-webhooks

Copy link
Copy Markdown

@rpenido 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future.

@xitij2000
xitij2000 deleted the rpenido/fal-3615-ux-refinements-from-sandbox-round-3 branch February 2, 2024 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

open-source-contribution PR author is not from Axim or 2U

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants