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

#525 List search: added SearchBar, added new filter to inventory #526

Merged
merged 10 commits into from
Nov 29, 2024

Conversation

az1plo
Copy link
Contributor

@az1plo az1plo commented Nov 25, 2024

What this PR does

  • Added SearchBar component for filtering lists.
  • Integrated SearchBar into the following sections:
    • Inventory
    • Shop
    • Workshop
    • Cows
    • Cellar
  • Implemented a new filter logic for the inventory to enhance usability.

How this change can be validated

  • Navigate to each section listed above and use the search bar to filter items.
  • Verify that the displayed items match the search query.

Questions or concerns about this change

  • Are there sections where the SearchBar could be removed or added?

Additional information

Screenshot 2024-11-25 113651
Screenshot 2024-11-25 113712
Screenshot 2024-11-25 113916
Screenshot 2024-11-25 113951
Screenshot 2024-11-25 114026
Screenshot 2024-11-25 113846

Copy link

vercel bot commented Nov 25, 2024

@az1plo is attempting to deploy a commit to the Jeremy Kahn's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link

vercel bot commented Nov 25, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
farmhand ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 29, 2024 6:00pm

Copy link
Owner

@jeremyckahn jeremyckahn left a comment

Choose a reason for hiding this comment

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

Thank you for the amazing work so far @az1plo! This is working really well. There are a number of UI consistency and performance issues I'd like to see addressed before merging this. Hopefully my comments aren't too onerous to deal with. Feel free to ask any followup questions here or in Discord!

Comment on lines 52 to 53
const itemName = item.name.toLowerCase()
const fermentationRecipeName = `${FERMENTED_CROP_NAME}${item.name}`.toLowerCase()
Copy link
Owner

Choose a reason for hiding this comment

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

nit: Since this is a relatively hot code path, consider optimizing it a bit:

Suggested change
const itemName = item.name.toLowerCase()
const fermentationRecipeName = `${FERMENTED_CROP_NAME}${item.name}`.toLowerCase()
const fermentationRecipeName = `${FERMENTED_CROP_NAME}${itemName}`.toLowerCase()

return (
<TabPanel value={currentTab} index={index}>
<h3>
Capacity: {integerString(cellarInventory.length)} /{' '}
Capacity: {integerString(filteredKegs.length)} /{' '}
Copy link
Owner

Choose a reason for hiding this comment

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

It seems that this should be reverted to:

Suggested change
Capacity: {integerString(filteredKegs.length)} /{' '}
Capacity: {integerString(cellarInventory.length)} /{' '}

This text represents how much space the player has left to make recipes, and that won't change as they filter down the list.

@@ -105,98 +122,142 @@ export const CowPenContextMenu = ({
</Tabs>
<TabPanel value={currentTab} index={0}>
<h3>
Capacity: {cowInventory.length} /{' '}
Capacity: {filteredCowInventory.length} /{' '}
Copy link
Owner

Choose a reason for hiding this comment

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

Let's revert this as well to keep the information being displayed accurate:

Suggested change
Capacity: {filteredCowInventory.length} /{' '}
Capacity: {cowInventory.length} /{' '}


return (
<>
<h3>Capacity: {filteredCows.length} / 2</h3>
Copy link
Owner

Choose a reason for hiding this comment

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

To keep the label accurate:

Suggested change
<h3>Capacity: {filteredCows.length} / 2</h3>
<h3>Capacity: {numberOfCowsBreeding(cowBreedingPen)} / 2</h3>

Copy link
Owner

Choose a reason for hiding this comment

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

Thank you for updating the tests! 🙏

Copy link
Owner

Choose a reason for hiding this comment

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

I'd like to see this updated to use the section order that is used prior to this PR. With this PR, it seems to be:

  • Upgrades
  • Seeds
  • Mined Resources
  • Foraged Items
  • Field Tools
  • Crops
  • Crafted Items
  • Animal Supplies
  • Animal Products

But I'd like to see this revert to:

  • Crops
  • Seeds
  • Foraged Items
  • Field Tools
  • Animal Products
  • Animal Supplies
  • Crafted Items
  • Mined Resources

Also, let's drop the new "Upgrades" section from here to maintain consistent behavior. This should keep the most frequently-accessed items towards the top of the page.

Comment on lines 151 to 156
<input
type="checkbox"
disabled={isPurchaseView}
checked={selectedCategories.includes(key)}
onChange={() => toggleCategory(key)}
/>
Copy link
Owner

Choose a reason for hiding this comment

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

In order to maintain consistency with the overall MUI theme, let's use MUI Checkboxes here:

Comment on lines 143 to 145
className={`filter-container ${
filterVisible ? 'visible' : 'hidden'
}`}
Copy link
Owner

Choose a reason for hiding this comment

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

Consider leveraging MUI Accordion instead of a custom implementation to maintain UI consistency:

Comment on lines 11 to 17
<div className="search-bar">
<input
type="text"
placeholder={placeholder || 'Search...'}
onChange={handleInputChange}
/>
</div>
Copy link
Owner

Choose a reason for hiding this comment

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

Let's use a MUI Text Field here to maintain UI consistency: https://mui.com/material-ui/react-text-field/

Comment on lines 6 to 8
const handleInputChange = event => {
onSearch(event.target.value)
}
Copy link
Owner

Choose a reason for hiding this comment

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

I noticed that searching can be a little sluggish, so let's debounce the input to keep the UI responsive. I'd recommend considering these options (and installing the packages as necessary):

Copy link

@luke-createdbyhumans luke-createdbyhumans left a comment

Choose a reason for hiding this comment

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

[deleted]

Copy link
Collaborator

@lstebner lstebner left a comment

Choose a reason for hiding this comment

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

sorry i'm re-posting my comments from my personal account because i was logged in to the wrong account at first

i didn't have time to fully review yet, but one thing did stand out to me and i'm also seeing that when the search input is not in the left column (like when searching the kitchen or the shop) it needs some more horizontal padding to line up with the other items in that view.

it's great to see this PR though! i'll look at it more closely when i can

)
expect(searchBar).toBeInTheDocument()

fireEvent.change(searchBar, { target: { value: 'apple' } })
Copy link
Collaborator

Choose a reason for hiding this comment

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

if possible, we should use userEvent.type instead of fireEvent. note: it requires an await. docs here https://github.com/testing-library/user-event (i'm only going to leave this comment here, but i see fireEvent in some other tests that i think could be updated as well)

Copy link
Owner

@jeremyckahn jeremyckahn left a comment

Choose a reason for hiding this comment

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

Great work @az1plo! There's just a few more things to tighten up before this can be merged. I think we're almost there!

@@ -1,18 +1,28 @@
import React from 'react'
import PropTypes from 'prop-types'
import { useDebounceCallback } from 'usehooks-ts'
import TextField from '@mui/material/TextField.js'
Copy link
Owner

Choose a reason for hiding this comment

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

This import appears to be broken: https://vercel.com/jeremy-kahns-projects-98e6f140/farmhand/Fd1vDBBPZuNxA1FywnBNj9cqnp4a?utm_medium=email&utm_source=notifications&filter=errors#L141

I think this needs to be:

Suggested change
import TextField from '@mui/material/TextField.js'
import TextField from '@mui/material/TextField/index.js'

src/components/Inventory/Inventory.js Outdated Show resolved Hide resolved
Comment on lines 18 to 27
export const categoryIds = {
CROPS: 'CROPS',
SEEDS: 'SEEDS',
FORAGED_ITEMS: 'FORAGED_ITEMS',
FIELD_TOOLS: 'FIELD_TOOLS',
ANIMAL_PRODUCTS: 'ANIMAL_PRODUCTS',
ANIMAL_SUPPLIES: 'ANIMAL_SUPPLIES',
CRAFTED_ITEMS: 'CRAFTED_ITEMS',
MINED_RESOURCES: 'MINED_RESOURCES',
}
Copy link
Owner

Choose a reason for hiding this comment

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

Since we are depending on the insertion order of these keys, let's use a Map instead of a plain object here. It's likely that this implementation would work as expected, but it's not necessarily obvious that the key order matters (because it usually doesn't for a plain Object). Using a Map would more clearly indicate to future readers of this code that the key order is significant (and perhaps a comment describing as much to really drive the point home).

renderedItems = component.find(Item)
expect(renderedItems).toHaveLength(1)
expect(renderedItems.props().item.id).toBe(carrot.id)
// Проверяем заполнение всех категорий
Copy link
Owner

Choose a reason for hiding this comment

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

Could this comment be translated to English for consistency?

[categoryIds.ANIMAL_PRODUCTS]: [testItem({ id: 'milk-1' })],
[categoryIds.ANIMAL_SUPPLIES]: [testItem({ id: 'cow-feed' })],
[categoryIds.CRAFTED_ITEMS]: [testItem({ id: carrotSoup.id })],
[categoryIds.UPGRADES]: [], // Пустая категория
Copy link
Owner

Choose a reason for hiding this comment

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

This comment as well, please. 🙏

Comment on lines +8 to +10
const debouncedSearch = useDebounceCallback(value => {
onSearch(value)
}, 300)
Copy link
Owner

Choose a reason for hiding this comment

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

Thank you for making this change!

Comment on lines 120 to 122
<FormControlLabel
key={key}
control={
Copy link
Owner

Choose a reason for hiding this comment

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

Let's adjust this to keep each option on its own line:

Suggested change
<FormControlLabel
key={key}
control={
<FormControlLabel
sx={{ display: 'block' }}
key={key}
control={

Before:

Screenshot of before CSS adjustment

After:

Screenshot of after CSS adjustment

placeholder={placeholder || 'Search...'}
onChange={handleInputChange}
inputProps={{
'aria-label': 'search',
Copy link
Owner

Choose a reason for hiding this comment

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

❤️


expect(onSearchMock).toHaveBeenCalledTimes(1)
expect(onSearchMock).toHaveBeenCalledWith('test query')
// Проверяем debounce
Copy link
Owner

Choose a reason for hiding this comment

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

Let's translate this comment to English as well. 🙂

Copy link
Owner

@jeremyckahn jeremyckahn left a comment

Choose a reason for hiding this comment

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

Thanks for the latest changes @az1plo! There's a few small test-related issues to iron out, but the application code is looking good. 🙂

package.json Outdated
@@ -73,6 +73,7 @@
"eslint-plugin-react-hooks": "^2.5.0",
"git-branch-is": "^4.0.0",
"husky": "^4.2.3",
"jest": "^29.7.0",
Copy link
Owner

Choose a reason for hiding this comment

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

Let remove the inclusion of Jest here. This project uses Vitest, so this package isn't necessary.

Copy link
Owner

Choose a reason for hiding this comment

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

It looks like this still needs to be reverted out of this PR.

CRAFTED_ITEMS: 'CRAFTED_ITEMS',
MINED_RESOURCES: 'MINED_RESOURCES',
}
// Using Map to preserve the key order
Copy link
Owner

Choose a reason for hiding this comment

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

❤️

const { container } = render(
<Inventory items={items} selectedCategories={[]} />
)
console.log(container.innerHTML)
Copy link
Owner

Choose a reason for hiding this comment

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

Let's remove this to keep test output clean.

Copy link
Owner

Choose a reason for hiding this comment

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

It looks like there are two test failures happening in this file. These will need to be resolved before this can be merged.


This would have been caught by the CI system, but it appears that the tests aren't being run for this PR. It's not clear why that is, as all the configuration and GitHub Actions setup seems correct. Since GitHub doesn't appear to be cooperating, you'll have to run the tests manually, locally. 😕

Copy link
Owner

@jeremyckahn jeremyckahn left a comment

Choose a reason for hiding this comment

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

I pushed fdef440 to address the test failures, so we should be good there.

Just a few more test-related items to address and this will be good to merge!


test('divides into type categories', () => {
Copy link
Owner

Choose a reason for hiding this comment

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

This test seems valuable. Would you mind reverting this removal (and make any necessary updates to make it pass)?

package.json Outdated
@@ -73,6 +73,7 @@
"eslint-plugin-react-hooks": "^2.5.0",
"git-branch-is": "^4.0.0",
"husky": "^4.2.3",
"jest": "^29.7.0",
Copy link
Owner

Choose a reason for hiding this comment

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

It looks like this still needs to be reverted out of this PR.

Copy link
Owner

@jeremyckahn jeremyckahn left a comment

Choose a reason for hiding this comment

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

Great work @az1plo! This looks and works great. Approved! 👏

I'm going to merge this now, but I'm going to hold off on releasing it to Production because I'd like to get #527 merged ahead of the next release. Releasing the changes together will result in less update churn for players. I should have a fix in for that soon and will announce the release on Discord.

Thanks again for the amazing contribution! 🙌

expect(
sortItems([
describe('Categorizing items', () => {
test('divides items into type categories', () => {
Copy link
Owner

Choose a reason for hiding this comment

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

Awesome! Thanks for adding this. 🙂

@jeremyckahn jeremyckahn merged commit 0e0be98 into jeremyckahn:develop Nov 29, 2024
3 checks passed
jeremyckahn added a commit that referenced this pull request Nov 29, 2024
jeremyckahn added a commit that referenced this pull request Dec 1, 2024
jeremyckahn added a commit that referenced this pull request Dec 1, 2024
* chore(tsconfig): set moduleResolution: node

* fix(#527): enable cow renaming

* fix(#526): improve flakey inventory test

* refactor(#527): use usehooks-ts implementation of isMounted
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.

4 participants