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

Improve integration of Custom Views in tabular pages #3275

Merged
merged 4 commits into from
Oct 18, 2023

Conversation

CarlosCortizasCT
Copy link
Contributor

Summary

Improve integration of Custom Views in tabular pages

Description

The initial implementation for integrating the upcoming Custom Views feature in tabular pages components only allowed to provide a single locator for the page, where this kind are supposed to have different exclusive sections (which also have different URLs) so it does not support specifying a locator for an specific tab and this is something needed.

In this PR we refactor the integration so tab page components consumers can provide a map of the locators based on the actual URL (the same mapping it's used for deciding which tab content to render).

// BEFORE
<TabularMainPage
  title="Product"
  customViewLocatorCode="products.product_variant_details.general">

// AFTER
<TabularMainPage
  title="Product"
  customViewLocatorCodes={{
    'products.product_variant_details.general': `${match.url}`,
    'products.product_variant_details.variants': `${match.url}/variants`,
    'products.product_variant_details.search': `${match.url}/search`
  }}
>

@changeset-bot
Copy link

changeset-bot bot commented Oct 17, 2023

🦋 Changeset detected

Latest commit: 114760f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 36 packages
Name Type
@commercetools-frontend/application-components Minor
@commercetools-frontend/application-shell Minor
@commercetools-frontend/codemod Minor
@commercetools-frontend/mc-scripts Minor
@commercetools-applications/merchant-center-template-starter-typescript Minor
@commercetools-applications/merchant-center-template-starter Minor
@commercetools-applications/merchant-center-custom-view-template-starter-typescript Minor
@commercetools-local/playground Minor
@commercetools-local/visual-testing-app Minor
@commercetools-website/components-playground Minor
@commercetools-frontend/cypress Minor
@commercetools-backend/eslint-config-node Minor
@commercetools-backend/express Minor
@commercetools-backend/loggers Minor
@commercetools-frontend/actions-global Minor
@commercetools-frontend/application-config Minor
@commercetools-frontend/application-shell-connectors Minor
@commercetools-frontend/assets Minor
@commercetools-frontend/babel-preset-mc-app Minor
@commercetools-frontend/browser-history Minor
@commercetools-frontend/constants Minor
@commercetools-frontend/create-mc-app Minor
@commercetools-frontend/eslint-config-mc-app Minor
@commercetools-frontend/i18n Minor
@commercetools-frontend/jest-preset-mc-app Minor
@commercetools-frontend/jest-stylelint-runner Minor
@commercetools-frontend/l10n Minor
@commercetools-frontend/mc-dev-authentication Minor
@commercetools-frontend/mc-html-template Minor
@commercetools-frontend/notifications Minor
@commercetools-frontend/permissions Minor
@commercetools-frontend/react-notifications Minor
@commercetools-frontend/sdk Minor
@commercetools-frontend/sentry Minor
@commercetools-frontend/url-utils Minor
@commercetools-website/custom-applications Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Oct 17, 2023

Deploy preview for merchant-center-application-kit ready!

✅ Preview
https://merchant-center-application-2yi73ebdf-commercetools.vercel.app
https://appkit-sha-6eaf62f32b327ba3380d6b5f604b6223c252f383.commercetools.vercel.app
https://appkit-pr-3275.commercetools.vercel.app

Built with commit 114760f.
This pull request is being automatically deployed with vercel-action

Copy link
Member

@emmenko emmenko left a comment

Choose a reason for hiding this comment

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

Ah good catch! I like the idea! 💯

Comment on lines 12 to 27
const [currentCustomViewLocatorCode, setCurrentCustomViewLocatorCode] =
useState<string>();

useEffect(() => {
const customViewLocator = Object.entries(customViewLocatorCodes).find(
([, locator]) => {
return matchPath(location.pathname, {
// strip the search, otherwise the path won't match
path: pathWithoutSearch(locator),
exact: false,
strict: false,
});
}
);
setCurrentCustomViewLocatorCode(customViewLocator?.[0]);
}, [customViewLocatorCodes, location]);
Copy link
Member

Choose a reason for hiding this comment

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

Are the state and the effect needed here? 🤔

Suggested change
const [currentCustomViewLocatorCode, setCurrentCustomViewLocatorCode] =
useState<string>();
useEffect(() => {
const customViewLocator = Object.entries(customViewLocatorCodes).find(
([, locator]) => {
return matchPath(location.pathname, {
// strip the search, otherwise the path won't match
path: pathWithoutSearch(locator),
exact: false,
strict: false,
});
}
);
setCurrentCustomViewLocatorCode(customViewLocator?.[0]);
}, [customViewLocatorCodes, location]);
const customViewLocator = Object.entries(customViewLocatorCodes).find(
([, locator]) => {
return matchPath(location.pathname, {
// strip the search, otherwise the path won't match
path: pathWithoutSearch(locator),
exact: false,
strict: false,
});
}
);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. I agree that works as well.

My reasoning for using the useEffect is to reduce the number of matchings needed. Using it, we would be calculating the actual locator only if the location changes (given the mapping object is the same between renders). On the other hand, if we don't use the effect, every time the consumer of this hooks is re/rendered, we will trigger again the calculation.

Maybe this is a micro-optimization, but it also looked natural to me using the useEffect hook.

Anyway, if you prefer not using it, I can get rid of it.

Copy link
Member

Choose a reason for hiding this comment

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

Using useEffect, useState etc is always a bit tricky as you need to be careful of potential re-renders. In particular with useEffect there is always a risk of ending up in an infinite loop.

If it's not absolutely necessary, I would keep it simple.

As for the "optimizations", matching a path or multiple ones is really a "cheap" operation (you can see the implementation of matchPath, it's just simple JS).
However, if you really do want to optimize the calculation I would suggest to use useMemo as it's more suited for this use case.

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 don't see the potential of an infinite loop here and I'm used to avoiding lists iterations whenever I can, but I agree here it's a non-worthy optimization as the list won't ever be too large.

Refactored here: c94cb17

Copy link
Member

@emmenko emmenko left a comment

Choose a reason for hiding this comment

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

💯 Thanks

@CarlosCortizasCT CarlosCortizasCT merged commit 669a46b into main Oct 18, 2023
14 checks passed
@CarlosCortizasCT CarlosCortizasCT deleted the cm-refactor-tabular-pages-custom-views branch October 18, 2023 10:17
@ct-changesets ct-changesets bot mentioned this pull request Oct 18, 2023
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.

2 participants