-
Notifications
You must be signed in to change notification settings - Fork 28
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
Conversation
@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. |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this 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!
const itemName = item.name.toLowerCase() | ||
const fermentationRecipeName = `${FERMENTED_CROP_NAME}${item.name}`.toLowerCase() |
There was a problem hiding this comment.
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:
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)} /{' '} |
There was a problem hiding this comment.
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:
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} /{' '} |
There was a problem hiding this comment.
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:
Capacity: {filteredCowInventory.length} /{' '} | |
Capacity: {cowInventory.length} /{' '} |
|
||
return ( | ||
<> | ||
<h3>Capacity: {filteredCows.length} / 2</h3> |
There was a problem hiding this comment.
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:
<h3>Capacity: {filteredCows.length} / 2</h3> | |
<h3>Capacity: {numberOfCowsBreeding(cowBreedingPen)} / 2</h3> |
There was a problem hiding this comment.
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! 🙏
There was a problem hiding this comment.
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.
<input | ||
type="checkbox" | ||
disabled={isPurchaseView} | ||
checked={selectedCategories.includes(key)} | ||
onChange={() => toggleCategory(key)} | ||
/> |
There was a problem hiding this comment.
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:
className={`filter-container ${ | ||
filterVisible ? 'visible' : 'hidden' | ||
}`} |
There was a problem hiding this comment.
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:
<div className="search-bar"> | ||
<input | ||
type="text" | ||
placeholder={placeholder || 'Search...'} | ||
onChange={handleInputChange} | ||
/> | ||
</div> |
There was a problem hiding this comment.
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/
const handleInputChange = event => { | ||
onSearch(event.target.value) | ||
} |
There was a problem hiding this comment.
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):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[deleted]
There was a problem hiding this 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' } }) |
There was a problem hiding this comment.
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)
There was a problem hiding this 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' |
There was a problem hiding this comment.
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:
import TextField from '@mui/material/TextField.js' | |
import TextField from '@mui/material/TextField/index.js' |
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', | ||
} |
There was a problem hiding this comment.
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) | ||
// Проверяем заполнение всех категорий |
There was a problem hiding this comment.
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]: [], // Пустая категория |
There was a problem hiding this comment.
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. 🙏
const debouncedSearch = useDebounceCallback(value => { | ||
onSearch(value) | ||
}, 300) |
There was a problem hiding this comment.
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!
<FormControlLabel | ||
key={key} | ||
control={ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
placeholder={placeholder || 'Search...'} | ||
onChange={handleInputChange} | ||
inputProps={{ | ||
'aria-label': 'search', |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. 🙂
There was a problem hiding this 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", |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. 😕
There was a problem hiding this 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', () => { |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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.
There was a problem hiding this 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', () => { |
There was a problem hiding this comment.
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. 🙂
What this PR does
How this change can be validated
Questions or concerns about this change
Additional information