-
Notifications
You must be signed in to change notification settings - Fork 2
[CDX-272] Shopify Feature Toggle #193
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
Conversation
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.
Pull Request Overview
This PR introduces a useShopifyDefaults feature flag that enables Shopify-specific configurations for the CioPlp component. When enabled, it provides default implementations for callbacks and URL helpers tailored to Shopify's cart API and routing conventions.
Key Changes:
- Added a new
getShopifyDefaults()utility function that returns Shopify-specific implementations foronAddToCart,onProductCardClick, andsetUrl - Introduced the
useShopifyDefaultsboolean prop toCioPlpProviderthat applies these defaults when enabled - Custom callbacks and URL helpers can still override the Shopify defaults through the normal prop mechanism
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/utils/shopifyDefaults.ts | New utility function providing Shopify-specific default implementations for cart operations, product navigation, and URL handling |
| src/utils/index.ts | Exports the new shopifyDefaults utility |
| src/types.ts | Adds useShopifyDefaults boolean prop to CioPlpProviderProps interface |
| src/stories/components/CioPlp/CioPlpProps.md | Documentation for the new useShopifyDefaults prop with usage examples |
| src/stories/components/CioPlp/CioPlp.stories.tsx | Storybook control definition for the useShopifyDefaults prop |
| src/hooks/useCioPlpProvider.ts | Integrates Shopify defaults into the provider, applying them before custom callbacks/urlHelpers in the merge order |
| spec/utils/shopifyDefaults.test.ts | Comprehensive test coverage for the Shopify defaults utility functions |
| spec/hooks/useCioPlpProvider/useCioPlpProvider.test.js | Tests verifying the integration of Shopify defaults with the provider hook |
| spec/components/CioPlp/CioPlp.test.jsx | Component-level tests ensuring the feature flag works correctly through the full component tree |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
LGTM, just some docs lints. We may want to also include SPA-rendering since this is a toggle, but that can be a future story
|
|
||
| --- | ||
|
|
||
| When enabled, this prop applies Shopify specific default configurations for callbacks and URL helpers. Custom callbacks and URL helpers can still override these defaults. |
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 not specify which configurations. In the near future, we may want to also have itemFieldGetter defaults
| **Example Usage:** | ||
|
|
||
| ```jsx | ||
| <CioPlp apiKey='your-api-key' useShopifyDefaults /> | ||
| ``` | ||
|
|
||
| **Overriding Shopify defaults:** | ||
|
|
||
| ```jsx | ||
| <CioPlp | ||
| apiKey='your-api-key' | ||
| useShopifyDefaults | ||
| callbacks={{ | ||
| onAddToCart: (event, item) => { | ||
| // Your custom implementation | ||
| console.log('Custom add to cart', item); | ||
| }, | ||
| }} | ||
| /> | ||
| ``` |
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.
Unnecessary imo, it doesn't add enough value to justify the space it takes in the docs
Code Review Results✅ StrengthsWell-structured feature with comprehensive tests covering integration, unit, and override scenarios. 🚨 Critical Issues[File: // Current (broken):
expect(getByText("custom-callback")).toBeInTheDocument();
it("renders CioPlp with hideGroups set to true on the client", async () => {
// Should be:
expect(getByText("custom-callback")).toBeInTheDocument();
});
it("renders CioPlp with hideGroups set to true on the client", async () => {[File: // Current:
const modifiedUrl = url.replace("/group_id", "/collections");
// Should be:
const modifiedUrl = url.replace(/\/group_id/g, "/collections");
|
Code Review Results✅ StrengthsWell-tested feature toggle implementation with comprehensive test coverage including edge cases for callback overrides and TypeScript type safety. 🚨 Critical IssuesNone
|
Code Review Results✅ StrengthsWell-structured implementation with comprehensive test coverage, clear separation of concerns, and proper TypeScript typing throughout the new feature. 🚨 Critical Issues[File: setUrl(url: string) {
const modifiedUrl = url.replace(/\/group_id\//g, '/collections/');
if (typeof window !== 'undefined') {
window.location.href = modifiedUrl;
}
}[File: const contextValue = useMemo(
(): PlpContextValue => {
const shopifyDefaultsValue = useShopifyDefaults ? shopifyDefaults : EMPTY_SHOPIFY_DEFAULTS;
return {
cioClient,
cioClientOptions,
setCioClientOptions,
staticRequestConfigs,
itemFieldGetters: { ...defaultGetters, ...itemFieldGetters },
formatters: { ...defaultFormatters, ...formatters },
callbacks: { ...shopifyDefaultsValue.callbacks, ...callbacks },
urlHelpers: { ...defaultUrlHelpers, ...shopifyDefaultsValue.urlHelpers, ...urlHelpers },
renderOverrides: { ...renderOverrides },
};
},
[
cioClient,
cioClientOptions,
itemFieldGetters,
formatters,
callbacks,
urlHelpers,
renderOverrides,
staticRequestConfigs,
useShopifyDefaults, // Replace shopifyDefaultsValue with useShopifyDefaults
],
);
|
Code Review Results✅ StrengthsComprehensive test coverage with unit tests for all Shopify default callbacks and URL helpers, clear API design with proper TypeScript types, and well-structured separation of concerns. 🚨 Critical Issues[File: [File:
|
src/hooks/useCioPlpProvider.ts
Outdated
| formatters: { ...defaultFormatters, ...formatters }, | ||
| callbacks: { ...callbacks }, | ||
| urlHelpers: { ...defaultUrlHelpers, ...urlHelpers }, | ||
| callbacks: { ...shopifyDefaultsValue.callbacks, ...callbacks }, |
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.
How about we spread it like this:
| callbacks: { ...shopifyDefaultsValue.callbacks, ...callbacks }, | |
| callbacks: { ...(useShopifyDefaults && shopifyDefaults.callbacks), ...callbacks }, |
This way, we will not have to define shopifyDefaultsValue or maintain the EMPTY_SHOPIFY_DEFAULTS object
Code Review Results✅ StrengthsComprehensive test coverage with unit tests for all Shopify default functions, proper integration tests verifying prop propagation, and well-structured code with clear separation of concerns. 🚨 Critical Issues[File: Fix: Use a global regex replacement: const modifiedUrl = url.replace(/\/group_id/g, '/collections');[File: Fix: Consider returning the promise or providing user feedback: return fetch('/cart/add.js', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: shopifyId,
quantity: 1,
}),
}).catch((error) => {
console.error('Failed to add item to cart:', error);
// Consider: throw error or provide user notification
});
|
Code Review Results✅ StrengthsWell-structured feature implementation with comprehensive test coverage and clear documentation. 🚨 Critical Issues[File: Recommendation: Use a more robust replacement approach or use const modifiedUrl = url.replaceAll('/group_id', '/collections');Alternatively, if you only want to replace it in the pathname (not in query strings), use a regex with proper constraints: const urlObj = new URL(url);
urlObj.pathname = urlObj.pathname.replace(/\/group_id(\/|$)/g, '/collections$1');
window.location.href = urlObj.href;[File: Issue: Before this PR, if no selector was provided, the code would attempt Recommendation: Improve the error message to be more helpful: if (!containerElement) {
console.error(
`CioPlp: No elements found. ${
!containerSelector
? 'Please provide a selector or enable useShopifyDefaults to use the default selector.'
: `No elements found for selector: ${containerSelector}`
}`
);
return;
}
|
HHHindawy
left a comment
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.
LGTM!
Code Review Results✅ StrengthsWell-structured feature implementation with comprehensive test coverage, clear documentation, and proper TypeScript type definitions. 🚨 Critical IssuesNone
|
Definition of Done
Don't forget tests!
Pull Request Checklist
Before you submit a pull request, please make sure you have to following:
PR Type
What kind of change does this PR introduce?