Skip to content

Conversation

@louwie17
Copy link
Contributor

@louwie17 louwie17 commented Aug 19, 2022

All Submissions:

Changes proposed in this Pull Request:

Adds a new Category dropdown field that includes a nested tree for the categories.

Changes done as part of this

  • (Part of Update/experimental select control #34620 now ) Update experimental select control component to return more callbacks from downshift and allow the option to keep the dropdown open when an item is selected.
  • (part of Add/crud get total count selector #34613 now ) Added getItemsTotalCount to the crud data store, allowing us to use it for categories - getProductCategoriesTotalCount
  • (will also be part of a separate PR ) Add a new Category dropdown to the MVP product page (this includes several new components).

Addresses: #34029

Kapture.2022-09-02.at.14.52.41.mp4

How to test the changes in this Pull Request:

Should match these designs: 5sAIeTRd9Yp7nSCT33BAWz-fi-5175%3A105193

  1. Load this branch and enable the new-product-management-experience feature flag by using the WCA Test Helper (Tools > WCA Test Helper > Features) and refresh the page.
  2. Create some categories under Product > Categories
  3. Click the Products > Add New (MVP) button and notice the new category field dropdown.
  4. Start searching in the dropdown field and make sure your created categories show up
  5. See if categories are correctly sorted by popularity first and then alphabetical order (popularity is by how many products its being used).
  6. Select one of the child categories, it should auto select the parents but allow you to un-select the parents
  7. You should also be able to use your keyboard by using your up and down arrows, currently I have the selected item highlighted by setting it to bold and have closed parents automatically open if they have children.

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully run tests with your changes locally?
  • Have you created a changelog file for each project being changed, ie pnpm changelog add --filter=<project>?

FOR PR REVIEWER ONLY:

  • I have reviewed that everything is sanitized/escaped appropriately for any SQL or XSS injection possibilities. I made sure Linting is not ignored or disabled.

@github-actions github-actions bot added focus: react admin package: @woocommerce/components issues related to @woocommerce/components package: @woocommerce/data issues related to @woocommerce/data plugin: woocommerce Issues related to the WooCommerce Core plugin. labels Aug 19, 2022
@louwie17 louwie17 force-pushed the add/34_category_field branch from 273c3bc to 17508af Compare August 19, 2022 20:05
@github-actions
Copy link
Contributor

github-actions bot commented Aug 19, 2022

Test Results Summary

Commit SHA: 9f4db44

Test 🧪Passed ✅Failed 🚨Broken 🚧Skipped ⏭️Unknown ❔Total 📊Duration ⏱️
API Tests18800201900m 50s
E2E Tests186003018919m 35s

To view the full API test report, click here.
To view the full E2E test report, click here.
To view all test reports, visit the WooCommerce Test Reports Dashboard.

box-sizing: border-box;
display: none;
z-index: 10;
margin-top: $gap-smaller;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mostly spacing it seems from spaces to tabs, this is what my prettier did. The only addition is:

z-index: 10;
margin-top: $gap-smaller;

);
if ( clearSearchOnSelect ) {
onInputChange( '' );
setInputValue( '' );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Optionally clear the input value upon selection.
Not sure if we want to separate InputBlur from this, and do clear in for that? I guess play around with it and see what feels natural.

isOpen: keepMenuOpenOnSelect ? true : false,
highlightedIndex: state.highlightedIndex,
inputValue: '',
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added to handle the keepMenuOpenOnSelect option

getMenuProps: getMenuPropsType;
getToggleButtonProps: getToggleButtonPropsType;
selectItem: ( item: ItemType ) => void;
setInputValue: ( value: string ) => void;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exposed these extra functions from downshifts library.

UPDATE_ITEM_ERROR = 'UPDATE_ITEM_ERROR',
UPDATE_ITEM_SUCCESS = 'UPDATE_ITEM_SUCCESS',
GET_ITEMS_TOTAL_COUNT_SUCCESS = 'GET_ITEMS_TOTAL_COUNT_SUCCESS',
GET_ITEMS_TOTAL_COUNT_ERROR = 'GET_ITEMS_TOTAL_COUNT_ERROR',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All the changes within the crud data store revolve around adding the getItemsTotalCount support, it should be more or less self explanatory.

@@ -0,0 +1,43 @@
/**
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Simple component that shows the Create "new category" item in the list.

) }
>
{ children.map( ( child ) => (
<CategoryFieldItem
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We continue to nest this element as long as the categories contains more children.
Allowing us to form the tree like data structure.

const selectedIds = value.map( ( item ) => item.id );
let selectControlItems = categoriesSelectList;
// Add the add new button if search value does not exist.
if (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This logic might be slightly dirty, I wasn't sure what the other easier method would be, but this only handles adding or removing the Create "new category" item from the list.

const selected = ( value || [] ).map( ( cat ) => ( {
value: cat.id.toString(),
label: cat.name,
} ) );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately the SelectControl doesn't allow us to pass in any kind of object yet, so have to convert it to the value/label object it prefers.

categoryTreeKeyValues[
parseInt( item.value, 10 )
]?.parentID === 0 ||
item.value === 'add-new'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In order for the selection to work well and the keyboard selection. We had to pass in the entire list of categories to the component, this includes all the children as well.
But
We don't want to display all of them in the top list, so we filter out all the children here.

You can see that for the CategoryFieldItem we actually pass in:

categoryTreeKeyValues[
  parseInt(
    item.value,
    10
  )
]

This is for the same reason as above, this actually returns us a tree like object that contains children.

value={ categoryName }
onChange={ setCategoryName }
/>
<SelectControl
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This SelectControl should follow a similar format as the way it's used in category-field.tsx.
There is one main difference that we make use of Popover here to display the menu. This is in order to display the dropdown without part of it being hidden by the modal window.
I had to make use of <Popover.Slot /> for this also, this is set in category-field.tsx under the Modal component.

@@ -0,0 +1,286 @@
/**
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most of the function comments should explain what this is doing, but this is a custom category search hook to encapsulate most of the logic surround the tree generation of categories, which includes a recursive function that would retrieve any missing parents if necessary.
This hook is both used in category-field.tsx and create-category-modal.tsx.

@louwie17 louwie17 marked this pull request as ready for review September 2, 2022 18:39
@louwie17 louwie17 requested a review from a team September 2, 2022 18:39
@louwie17 louwie17 force-pushed the add/34_category_field branch 2 times, most recently from ac47ff2 to 940af37 Compare September 12, 2022 11:32
@louwie17 louwie17 force-pushed the add/34_category_field branch from 940af37 to f2ac82f Compare September 28, 2022 17:05
@louwie17 louwie17 force-pushed the add/34_category_field branch from f2ac82f to 5ee1b23 Compare October 12, 2022 12:48
@louwie17
Copy link
Contributor Author

@mdperez86 thanks for the initial look, this should be ready for a re-review.

@louwie17 louwie17 force-pushed the add/34_category_field branch from 9aaf42d to 36820dc Compare October 13, 2022 14:31
Move search logic to useCategorySearch hook

Add initial add new category logic

Add parent category field to add new category modal

Adding some debug changes

Update category control to make use of internal selectItem function of select control

Add changelogs

Update pagesize back to 100

Add placeholder

Empty placeholder

Fix input and icon sizes

Fix input underline

Add max height and scroll to category dropdown

Add sorting of category items

Auto open parents when traversing up the tree using arrow keys

Add several comments

Add some initial unit tests for the category field component

Add tests for useCategorySearch hook and fixed minor bug

Update styling and autoselect parent if child is selected

Fix styling issues for the select control dropdown inside a modal

Fix issue with creating new category with parent

Add function comment and fixed border styling

Prune out create new category logic

Fix minor css issue with border

Revert some of the select control changes and make use of the custom type

Fix up some styling changes
@louwie17 louwie17 force-pushed the add/34_category_field branch from 36820dc to 9f4db44 Compare October 13, 2022 18:47
Copy link
Contributor

@mdperez86 mdperez86 left a comment

Choose a reason for hiding this comment

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

Such a hard work here. Great job!!!

@louwie17 louwie17 merged commit c55c91d into trunk Oct 14, 2022
@louwie17 louwie17 deleted the add/34_category_field branch October 14, 2022 12:05
@github-actions github-actions bot added this to the 7.2.0 milestone Oct 14, 2022
@github-actions
Copy link
Contributor

Hi @louwie17, thanks for merging this pull request. Please take a look at these follow-up tasks you may need to perform:

  • Add the release: add testing instructions label

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

Labels

package: @woocommerce/components issues related to @woocommerce/components package: @woocommerce/data issues related to @woocommerce/data plugin: woocommerce Issues related to the WooCommerce Core plugin.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants