Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Convert all products edit to TypeScript #9782

Open
wants to merge 13 commits into
base: trunk
Choose a base branch
from

Conversation

Sidsector9
Copy link
Member

@Sidsector9 Sidsector9 commented Jun 11, 2023

Fixes woocommerce/woocommerce#42363

Testing

Automated Tests

  • Changes in this PR are covered by Automated Tests.

    • Unit tests
    • E2E tests
  • Do not include in the Testing Notes

WooCommerce Visibility

  • WooCommerce Core
  • Feature plugin
  • Experimental

@Sidsector9 Sidsector9 changed the title [WIP] upkeep/9524: migrate to typescript upkeep/9524: migrate to typescript Jun 12, 2023
@nielslange nielslange added type: enhancement The issue is a request for an enhancement. type: refactor The issue/PR is related to refactoring. block: all products Issues related to the all products block. labels Jun 14, 2023
@nielslange nielslange requested review from a team and danieldudzic and removed request for a team June 14, 2023 13:12
Copy link
Member

@nielslange nielslange 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 your contribution, @Sidsector9. I requested a review from the corresponding team. While quickly looking over the PR, I noticed one section, that should be changed. I left a comment in the corresponding section.

debouncedSpeak: PropTypes.func.isRequired,
};

class Editor extends Component< EditorProps, EditorState > {
Copy link
Member

Choose a reason for hiding this comment

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

While briefly looking at your changes, I noticed that this file is still using a class component. Now that we're touching this file, we should convert it to a functional component. Could you take care of that?

Copy link
Member Author

Choose a reason for hiding this comment

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

@nielslange I've moved from class to functional component.

@nielslange nielslange removed their request for review June 19, 2023 09:06
Copy link
Contributor

@kmanijak kmanijak 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 contributing! I left a couple of comments related to the code as well as to the behavior of All Products block.

I would also suggest adding some testing steps to the PR description to showcase how did you check that this block preserves the behavior from before the refactor. It also makes it easier for us to confirm it works the same on our end, thanks!

template: [ string, object? ][];
templateLock: boolean;
allowedBlocks: Array< string >;
renderAppender?: undefined | boolean;
Copy link
Contributor

Choose a reason for hiding this comment

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

Considering the property is optional, it can be implicitly undefined hence you can just define it as optional boolean:

Suggested change
renderAppender?: undefined | boolean;
renderAppender?: boolean;

blockMap = getBlockMap( 'woocommerce/all-products' );
export default function Edit( props: Props ): JSX.Element {
const [ isEditing, setIsEditing ] = useState< boolean >( false );
const [ , setInnerBlocks ] = useState< BlockInstance[] | boolean >( false );
Copy link
Contributor

Choose a reason for hiding this comment

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

To preserve the logic, I believe the initial state should be an empty array as per previous implementation:

	state = {
		isEditing: false,
		innerBlocks: [],
	};

Also, could you shed more light on why there's just a setInnerBlocks function in use, but no innerBlocks value like:

Suggested change
const [ , setInnerBlocks ] = useState< BlockInstance[] | boolean >( false );
const [ innerBlocks, setInnerBlocks ] = useState< BlockInstance[] | boolean >( false );


getTitle = () => {
const { innerBlocks } = useSelect( ( select ) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I see the component logic is based on the value returned from useSelect, while it should be based on the value from useState. I think it's related to the question from the previous comment about why the innerBlocks from useState is not in use.

const { innerBlocks } = this.state;
replaceInnerBlocks( block.clientId, innerBlocks, false );
this.togglePreview();
replaceInnerBlocks( clientId, innerBlocks, false );
Copy link
Contributor

Choose a reason for hiding this comment

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

When you use Cancel button on the UI and go back to edit mode, the previous state is preserved. It may be related to using innerBlocks from useSelect rather than useState.

Steps to reproduce:

  1. Go to Edit mode of All Products
  2. Add some additional Products Elements
  3. Click "Cancel"
  4. In the preview mode there's no newly added elements
  5. Go to Edit mode again
  6. All the added elements are there while the edit mode should reflect the preview state

Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about renaming the file to save.jsx considering it returns JSX component?

}, [] );

const { replaceInnerBlocks } = useDispatch( 'core/block-editor' );
const debouncedSpeak = useDebounce( speak );
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason we cannot use the debouncedSpeak provided through the props as it was before, but rather create a new one?

Copy link
Member Author

Choose a reason for hiding this comment

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

@kmanijak Let me know if I've understood it incorrectly. Previously, debouncedSpeak was the props added by the withSpokenMessages HOC and I've replaced that with the useDebounce hook. Is that not correct?

Copy link
Contributor

Choose a reason for hiding this comment

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

Previously, debouncedSpeak was the props added by the withSpokenMessages HOC and I've replaced that with the useDebounce hook. Is that not correct?

Oh, I didn't spot that. But I think we could stick to keep using withSpokenMessages which is used across multiple blocks. Is there a reason to replace it with a custom implementation?

@Sidsector9 Sidsector9 requested a review from kmanijak June 28, 2023 08:23
Copy link
Contributor

@kmanijak kmanijak left a comment

Choose a reason for hiding this comment

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

I tried to test the All Products block and after modifying the content All Products turns into some unexpected state:

allprod-hidden-content.mov

Also, as I mentioned in the previous iteration:

I would also suggest adding some testing steps to the PR description to showcase how did you check that this block preserves the behavior from before the refactor. It also makes it easier for us to confirm it works the same on our end, thanks!

Even though this PR doesn't add a new feature it helps us and other colleagues to make sure the changes don't introduce any regressions, so I'd appreciate if you add some testing steps to the PR description. Here are some examples of PR introducing a similar change (conversion to TypeScript) with the testing steps included:

Please let me know if you have some questions 🙌

}, [] );

const { replaceInnerBlocks } = useDispatch( 'core/block-editor' );
const debouncedSpeak = useDebounce( speak );
Copy link
Contributor

Choose a reason for hiding this comment

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

Previously, debouncedSpeak was the props added by the withSpokenMessages HOC and I've replaced that with the useDebounce hook. Is that not correct?

Oh, I didn't spot that. But I think we could stick to keep using withSpokenMessages which is used across multiple blocks. Is there a reason to replace it with a custom implementation?

Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about renaming this file to save.jsx as it returns JSX content?

@samueljseay samueljseay changed the title upkeep/9524: migrate to typescript Convert all products edit to TypeScript Nov 14, 2023
@samueljseay samueljseay added the status: stale Stale issues and PRs have had no updates for 60 days. label Nov 14, 2023
@kmanijak
Copy link
Contributor

kmanijak commented Dec 7, 2023

Hi @Sidsector9!

It’s been a while since we heard from you. I’d like you to know that this weekend (8-9 December) WooCommerce Blocks repo will be migrated to WooCommerce monorepo. However, open PRs won’t be migrated.

That means open PRs have to be merged by the end of this week or otherwise, you’ll have to open/recreate a new PR in a monorepo post-migration if you’re interested in finalizing this contribution.

Thanks!

@kmanijak kmanijak removed the type: enhancement The issue is a request for an enhancement. label Dec 7, 2023
@danieldudzic danieldudzic removed their request for review December 26, 2023 22:16
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
block: all products Issues related to the all products block. status: stale Stale issues and PRs have had no updates for 60 days. team: Kirigami & Origami type: community contribution type: refactor The issue/PR is related to refactoring.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Convert edit.js to edit.tsx and replace propTypes with TypeScript definitions
4 participants