Skip to content

Conversation

@joelclimbsthings
Copy link
Contributor

@joelclimbsthings joelclimbsthings commented Oct 21, 2022

All Submissions:

Changes proposed in this Pull Request:

Adding the edit modal for attributes as per [the design](Show or hide this attribute in the filters section on your store’s category and shop pages).

image

Note: One complicating issue with managing attributes has to do with the product API endpoint only including the names of the various terms, which are not unique. To address this we're now fetching the terms associated with the product from the product terms endpoint, and using them to manage the adding/editing and various functionality, updating the global form data as needed. These are stored as the hydratedAttributes with the attribute-field component. I've now refactored the add-modal to address these changes as well.

Closes #34332 .

  • This PR is a very minor change/addition and does not require testing instructions (if checked you can ignore/remove the next section).

How to test the changes in this Pull Request:

  1. Checkout branch
  2. Ensure you have at least 2 attributes with options configured.
  3. Enable new products MVP feature flag
  4. Go to new products MVP screen
  5. Click the "add attribute button" at the bottom to open the add modal.
  6. Add one of the attributes, as well as 1 or two of the associated options.
  7. Click "Add" button, and ensure the attribute shows up in the attribute table.
  8. Click "Edit" button on added attribute to open the edit modal.
  9. Add another option to the attribute and click "update."
  10. Ensure the UI on the attribute section has updated with that attribute.
  11. Publish the product, but don't navigate away
  12. Refresh the page, which should just load the same product.
  13. Scroll to the bottom and ensure the updated options were persisted.
  14. Add another attribute with the add modal, but don't publish the product.
  15. Click "edit" on one of the attributes to open the edit modal.
  16. Delete the name of the attribute in the top "attribute" field, and select the other from the drop-down.
  17. It should switch the attribute field and auto populate the terms in the lower drop-down associated with this attribute.
  18. Similarly, test delete attributes and checking both checkboxes, publish the product, and ensure the changes were persisted.

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 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 plugin: woocommerce Issues related to the WooCommerce Core plugin. labels Oct 21, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Oct 26, 2022

Test Results Summary

Commit SHA: 34f5ed5

Test 🧪Passed ✅Failed 🚨Broken 🚧Skipped ⏭️Unknown ❔Total 📊Duration ⏱️
API Tests25900302620m 56s
E2E Tests186006019216m 17s

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.

@joelclimbsthings joelclimbsthings force-pushed the add/34332-add-attribute-edit branch from 7cfc628 to 3e7dfb9 Compare October 26, 2022 21:01
@joelclimbsthings joelclimbsthings self-assigned this Oct 26, 2022
@joelclimbsthings joelclimbsthings requested a review from a team October 26, 2022 21:01
@joelclimbsthings joelclimbsthings marked this pull request as ready for review October 26, 2022 21:01
@joelclimbsthings joelclimbsthings force-pushed the add/34332-add-attribute-edit branch from 3e7dfb9 to 17b5809 Compare October 27, 2022 22:34
@louwie17 louwie17 mentioned this pull request Oct 28, 2022
8 tasks
Copy link
Contributor

@louwie17 louwie17 left a comment

Choose a reason for hiding this comment

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

Hey @joelclimbsthings, thanks for tackling this!
I left some comments in the code and also noticed a couple issues while testing:

  • Neither of the Attribute or Attribute term dropdowns worked for me when trying to edit it. It would neither show new attribute terms or show any attributes when I emptied the text field
  • The edit modal allowed me to remove all the terms, but it kept attribute listed under the main attributes list. Upon save that attribute disappeared.
    I think in that instance we should also remove the attribute from the main list, and maybe notify the user that we did, maybe upon them clicking Update we show a warning - Are you sure you want to save this, removing all the attribute terms from an attribute will remove the attribute or something like that?

Also the lint task failed with 11:10 ✖ Unexpected named color "gray" color-named for the edit-attribute-modal.scss file

id: formAttr.id,
name: formAttr.name,
}
: null
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just pass in formAttr if it contains id and name already?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually went this direction since I was getting a TS error:
image

I'm not sure why this error is appearing, since I should be ensuring that id is defined with the ternary check, but the error went away when I narrowed the object. Do you know offhand why that might be happening? I wasn't sure I wanted to spend more time troubleshooting it when this solution worked.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm yeah, the number | undefined part comes from the fact that we are wrapping HydratedAttributeType with Partial in the AttributeForm type, which makes things less easy to handle (my bad).

If you change the attributes type in AttributeForm to: Array< HydratedAttributeType | { id: undefined; terms: [] } > it will more accurately represent the type and allow you to use formAttr.id ? formAttr : undefined for the value prop here.

terms: undefined,
};
} )
);
Copy link
Contributor

Choose a reason for hiding this comment

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

This also gets run after the hydratedAttributes are initial fetched, which makes the form dirty. Should we just set this as it's own function and only call it when the user updates or removes it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, the intention here was just to have the hydratedAttributes act as a proxy for the attributes in the form data, only with the terms data populated. So we can just alter this variable as we would otherwise alter the form data and get the behavior we want. It feels like it would complicate it more to have another callback that may or may not be called in conjunction with onChange.

Can you elaborate on what state would cause the form to become "dirty?" We'd only be updating this when we want to update the form data.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate on what state would cause the form to become "dirty?" We'd only be updating this when we want to update the form data.

You can notice this when looking at the Update button, when you load an existing product with attributes the Update button shows as disabled initially (meaning there are no changes) and once the onChange here is called it becomes active, allowing a user to save. This could also cause issues in the future if we decide to rely more on the fieldsChanged values.

I understand the reasoning behind this and see how you need it, but it be nice if we only trigger onChange once actual changes have been made and not just for the bootstrapping of the field.

The reason for suggesting a separate callback function is because this may be difficult to handle within a useEffect, as it would be difficult to differentiate if hydratedAttributes was updated by an actual change or just the initial loading.

return allItems.filter(
( item ) =>
filteredAttributeIds.indexOf( item.id ) < 0 &&
const onlyIdsFilter = ( item: NarrowedQueryAttribute ) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this filter seems to break the select control, where I cannot search for any other attribute.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean in just in the edit modal? That's my intention here and what I assumed would be the behavior we want (unless I misunderstand). See my other comment above for more context.

Copy link
Contributor

Choose a reason for hiding this comment

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

I finally got it working, it may of been a couple things. The need for the use of the SelectControlMenuSlot to have the dropdown show correctly and I was testing this on a site that had over a 1000 of attributes, so the selected items may of not come back as part of the initial list, thus not showing up, also reasoning for just using the standard SelectControl as mentioned above.

attributeId?: number;
placeholder?: string;
disabled?: boolean;
label?: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

@joelclimbsthings
Copy link
Contributor Author

Thanks for the feedback @louwie17 , unfortunately I'll need a bit more feedback on the above for it to be actionable. I've responded to your comments, let me know what you think!

@louwie17
Copy link
Contributor

louwie17 commented Nov 1, 2022

Thanks for the feedback @louwie17 , unfortunately I'll need a bit more feedback on the above for it to be actionable. I've responded to your comments, let me know what you think!

@joelclimbsthings I left some replies to your comments, let me know if you need any extra clarification whether in Slack or here.

Also as I was testing this again I noticed one more issue, for products that make use of the custom attribute the apiFetch fails, but this in turn caused an error and a blank screen.
I know this wasn't part of the original spec, but maybe we want to show just a text field, or a simple SelectControl that allows you to create new items all the time, instead of having users type: random | anotherTerm | term3, this would be a SelectControl that only deals with text items.

@joelclimbsthings
Copy link
Contributor Author

joelclimbsthings commented Nov 2, 2022

Thanks for your feedback @louwie17 , I believe I've resolved everything. Given Jarek's design input, some of the code was no longer needed.

That said, adding support for custom attributes is a bit dicey, as it loses the uniqueness of the attribute id (always zero it seems?), and causes some type confusion. I've done my best to address it with my time today, but it feels rushed. We could also break those commits off into a separate PR to add support for custom attributes if that feels more comfortable.

Edit: I borrowed your CustomAttributeTermInput component. Felt easiest just to copy it over as I didn't want to make this PR dependent on that one necessarily, but I haven't modified the file so conflicts shouldn't be bad to resolve.

Copy link
Contributor

@louwie17 louwie17 left a comment

Choose a reason for hiding this comment

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

This is looking really good @joelclimbsthings, thanks for the hard work on this.
I just left a couple small suggestions in code and noticed one minor styling bug (the plus signing not aligning with the text):
Screen Shot 2022-11-02 at 9 05 08 AM

@joelclimbsthings joelclimbsthings force-pushed the add/34332-add-attribute-edit branch from e07560e to 556d1d2 Compare November 2, 2022 19:31
@joelclimbsthings
Copy link
Contributor Author

joelclimbsthings commented Nov 2, 2022

Thanks @louwie17 , I've rebased to resolve the conflict and addressed the issues you mentioned. Let me know what you think 🤞🏻

louwie17
louwie17 previously approved these changes Nov 2, 2022
Copy link
Contributor

@louwie17 louwie17 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 final updates @joelclimbsthings, this tested well and the code looks good! Nice work on this :)

I did notice one last thing, that a can update an attribute by removing all the terms and also updating the custom attribute to be an empty name. We probably want some validation around this?
I don't mind doing this as part of a separate PR

@joelclimbsthings
Copy link
Contributor Author

@louwie17 Had to resolve some unit test issues in one more commit. Could I get another ✅ when you get the chance?

Copy link
Contributor

@louwie17 louwie17 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 fixing the tests @joelclimbsthings, this looks good!

@joelclimbsthings joelclimbsthings merged commit 5b1296f into trunk Nov 3, 2022
@joelclimbsthings joelclimbsthings deleted the add/34332-add-attribute-edit branch November 3, 2022 15:20
@github-actions github-actions bot added this to the 7.2.0 milestone Nov 3, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Nov 3, 2022

Hi @joelclimbsthings, 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 plugin: woocommerce Issues related to the WooCommerce Core plugin.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Attributes] Edit attribute modal

4 participants