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

refactor(general): refactor how and where the cart is loaded #605

Merged
merged 1 commit into from
Feb 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/api-client/src/api/cartTotalQty/cartTotalQty.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import gql from 'graphql-tag';

export default gql`
query cart($cartId: String!) {
cart(cart_id:$cartId) {
total_quantity
}
}
`;
25 changes: 25 additions & 0 deletions packages/api-client/src/api/cartTotalQty/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ApolloQueryResult } from '@apollo/client/core';
import { CustomQuery } from '@vue-storefront/core';
import { CartQuery, CartQueryVariables } from '../../types/GraphQL';
import cart from './cartTotalQty';
import { Context } from '../../types/context';

export default async (
context: Context,
cartId: string,
customQuery: CustomQuery = { cart: 'cart' },
): Promise<ApolloQueryResult<CartQuery>> => {
const { cart: cartGQL } = context.extendQuery(
customQuery,
{
cart: {
query: cart,
variables: { cartId },
},
},
);
return context.client.query<CartQuery, CartQueryVariables>({
query: cartGQL.query,
variables: cartGQL.variables,
});
};
1 change: 1 addition & 0 deletions packages/api-client/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export { default as addVirtualProductsToCart } from './addVirtualProductsToCart'
export { default as applyCouponToCart } from './applyCouponToCart';
export { default as availableStores } from './availableStores';
export { default as cart } from './cart';
export { default as cartTotalQty } from './cartTotalQty';
export { default as categoryList } from './categoryList';
export { default as categorySearch } from './categorySearch';
export { default as changeCustomerPassword } from './changeCustomerPassword';
Expand Down
5 changes: 5 additions & 0 deletions packages/api-client/src/types/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ export interface MagentoApiMethods {
customQuery?: CustomQuery
): Promise<ApolloQueryResult<CartQuery>>;

cartTotalQty(
cartId: string,
customQuery?: CustomQuery
): Promise<ApolloQueryResult<CartQuery>>;

categoryList(
categoryFilter?: CategoryListQueryVariables,
customQuery?: CustomQuery
Expand Down
6 changes: 6 additions & 0 deletions packages/composables/src/composables/useCart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,12 @@ const factoryParams: UseCartFactoryParams<Cart, CartItem, Product> = {
product,
},
) => !!currentCart?.items.find((cartItem) => cartItem?.product?.uid === product.uid),
loadTotalQty: async (context: Context) => {
const apiState = context.$magento.config.state;
const { data } : any = await context.$magento.api.cartTotalQty(apiState.getCartId());

return data.cart.total_quantity;
},
};

export default useCartFactory<Cart, CartItem, Product>(factoryParams);
42 changes: 40 additions & 2 deletions packages/composables/src/factories/useCartFactory.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {
CustomQuery, UseCart, Context, FactoryParams, UseCartErrors, PlatformApi, sharedRef, Logger, configureFactoryParams, ComposableFunctionArgs,
UseCart as UseCartCore, Context, FactoryParams, UseCartErrors as UseCartErrorsCore, PlatformApi, sharedRef, Logger, configureFactoryParams, ComposableFunctionArgs,
} from '@vue-storefront/core';
import { computed, Ref } from '@vue/composition-api';
import { ComputedProperty, CustomQuery } from '@vue-storefront/core/lib/src/types';

export interface UseCartFactoryParams<CART, CART_ITEM, PRODUCT, API extends PlatformApi = any> extends FactoryParams<API> {
load: (context: Context, params: ComposableFunctionArgs<{ realCart?: boolean; }>) => Promise<CART>;
loadTotalQty: (context: Context) => Promise<number>;
addItem: (
context: Context,
params: ComposableFunctionArgs<{
Expand All @@ -27,11 +29,22 @@ export interface UseCartFactoryParams<CART, CART_ITEM, PRODUCT, API extends Plat
isInCart: (context: Context, params: { currentCart: CART; product: PRODUCT }) => boolean;
}

export interface UseCart<CART, CART_ITEM, PRODUCT, API extends PlatformApi = any> extends UseCartCore<CART, CART_ITEM, PRODUCT, API> {
totalQuantity: ComputedProperty<number>,
loadTotalQty(params: {
customQuery?: CustomQuery;
}): Promise<void>;
}
export interface UseCartErrors extends UseCartErrorsCore {
loadTotalQty: Error
}

export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi = any>(
factoryParams: UseCartFactoryParams<CART, CART_ITEM, PRODUCT, API>,
) => function useCart(): UseCart<CART, CART_ITEM, PRODUCT, API> {
const loading: Ref<boolean> = sharedRef(false, 'useCart-loading');
const cart: Ref<CART> = sharedRef(null, 'useCart-cart');
const totalQuantity: Ref<number> = sharedRef(0, 'useCart-totalQuantity');
const error: Ref<UseCartErrors> = sharedRef({
addItem: null,
removeItem: null,
Expand All @@ -40,6 +53,7 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
clear: null,
applyCoupon: null,
removeCoupon: null,
loadTotalQty: null,
}, 'useCart-error');

// eslint-disable-next-line no-underscore-dangle,@typescript-eslint/naming-convention
Expand Down Expand Up @@ -78,6 +92,7 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
});
error.value.addItem = null;
cart.value = updatedCart;
totalQuantity.value = updatedCart.total_quantity;
} catch (err) {
error.value.addItem = err;
Logger.error('useCart/addItem', err);
Expand All @@ -101,6 +116,7 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
});
error.value.removeItem = null;
cart.value = updatedCart;
totalQuantity.value = updatedCart.total_quantity;
} catch (err) {
error.value.removeItem = err;
Logger.error('useCart/removeItem', err);
Expand Down Expand Up @@ -130,6 +146,7 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
});
error.value.updateItemQty = null;
cart.value = updatedCart;
totalQuantity.value = updatedCart.total_quantity;
} catch (err) {
error.value.updateItemQty = err;
Logger.error('useCart/updateItemQty', err);
Expand All @@ -150,11 +167,14 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
loading.value = false;
error.value.load = null;
cart.value = { ...cart.value };

return;
}
try {
loading.value = true;
cart.value = await _factoryParams.load({ customQuery });
const loadedCart = await _factoryParams.load({ customQuery });
cart.value = loadedCart;
totalQuantity.value = loadedCart.total_quantity;
error.value.load = null;
} catch (err) {
error.value.load = err;
Expand All @@ -164,6 +184,21 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
}
};

const loadTotalQty = async ({ customQuery } = { customQuery: undefined }) => {
Logger.debug('useCart.loadTotalQty');

try {
loading.value = true;
totalQuantity.value = await _factoryParams.loadTotalQty({ customQuery });
error.value.loadTotalQty = null;
} catch (err) {
error.value.loadTotalQty = err;
Logger.error('useCart/loadTotalQty', err);
} finally {
loading.value = false;
}
};

const clear = async () => {
Logger.debug('useCart.clear');

Expand All @@ -172,6 +207,7 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
const updatedCart = await _factoryParams.clear({ currentCart: cart.value });
error.value.clear = null;
cart.value = updatedCart;
totalQuantity.value = updatedCart.total_quantity;
} catch (err) {
error.value.clear = err;
Logger.error('useCart/clear', err);
Expand Down Expand Up @@ -236,9 +272,11 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
api: _factoryParams.api,
setCart,
cart: computed(() => cart.value),
totalQuantity,
isInCart,
addItem,
load,
loadTotalQty,
removeItem,
clear,
updateItemQty,
Expand Down
19 changes: 5 additions & 14 deletions packages/theme/components/AppHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ import {
SfOverlay,
} from '@storefront-ui/vue';
import {
cartGetters,
categoryGetters,
useCart,
useCategory,
Expand All @@ -187,8 +186,8 @@ import {
defineComponent,
useRouter,
useContext,
useAsync,
} from '@nuxtjs/composition-api';
import { onSSR } from '@vue-storefront/core';
import { clickOutside } from '@storefront-ui/vue/src/utilities/directives/click-outside/click-outside-directive.js';
import {
mapMobileObserver,
Expand Down Expand Up @@ -221,12 +220,11 @@ export default defineComponent({
const { toggleCartSidebar, toggleWishlistSidebar, toggleLoginModal } = useUiState();
const { setTermForUrl, getFacetsFromURL, getAgnosticCatLink } = useUiHelpers();
const { isAuthenticated } = useUser();
const { cart } = useCart();
const { totalQuantity, loadTotalQty } = useCart();
const { wishlist } = useWishlist('GlobalWishlist');
const {
result: searchResult,
search: productsSearch,
// loading: productsLoading,
} = useFacet('AppHeader:Products');
const {
result: categories,
Expand All @@ -245,11 +243,6 @@ export default defineComponent({
const wishlistHasProducts = computed(() => wishlistGetters.getTotalItems(wishlist.value) > 0);
const wishlistItemsQty = computed(() => wishlistGetters.getTotalItems(wishlist.value));

const cartTotalItems = computed(() => {
const count = cartGetters.getTotalItems(cart.value);
return count ? count.toString() : null;
});

const accountIcon = computed(() => (isAuthenticated.value ? 'profile_fill' : 'profile'));

const categoryTree = computed(() => categoryGetters.getCategoryTree(categoryList.value?.[0])?.items.filter((c) => c.count > 0));
Expand All @@ -262,10 +255,8 @@ export default defineComponent({
}
};

onSSR(async () => {
await categoriesListSearch({
pageSize: 20,
});
useAsync(async () => {
await Promise.all([loadTotalQty(), categoriesListSearch({ pageSize: 20 })]);
});

const showSearch = () => {
Expand Down Expand Up @@ -332,7 +323,7 @@ export default defineComponent({

return {
accountIcon,
cartTotalItems,
cartTotalItems: totalQuantity,
categoryTree,
closeOrFocusSearchBar,
closeSearch,
Expand Down
Loading