Skip to content

Commit

Permalink
feat(theme): - add wishlist lazyload and totalItems shared field
Browse files Browse the repository at this point in the history
  • Loading branch information
bartoszherba authored and Frodigo committed Feb 17, 2022
1 parent 5855c30 commit 4c2dbcc
Show file tree
Hide file tree
Showing 19 changed files with 150 additions and 53 deletions.
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 @@ -61,3 +61,4 @@ export { default as updateCustomerEmail } from './updateCustomerEmail';
export { default as upsellProduct } from './upsellProduct';
export { default as urlResolver } from './urlResolver';
export { default as wishlist } from './wishlist';
export { default as wishlistItemsCount } from './wishlistItemsCount';
27 changes: 27 additions & 0 deletions packages/api-client/src/api/wishlistItemsCount/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ApolloQueryResult } from '@apollo/client/core';
import { CustomQuery } from '@vue-storefront/core';

import {
WishlistQuery,
} from '../../types/GraphQL';
import query from './wishlistItemsCount';
import { Context } from '../../types/context';

export default async (
context: Context,
customQuery: CustomQuery = { wishlistItemsCount: 'wishlistItemsCount' },
): Promise<ApolloQueryResult<WishlistQuery>> => {
const { wishlistItemsCount } = context.extendQuery(customQuery, {
wishlistItemsCount: {
query,
},
});
try {
return await context.client
.query<WishlistQuery>({
query: wishlistItemsCount.query,
});
} catch (error) {
throw error.graphQLErrors?.[0].message || error.networkError?.result || error;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import gql from 'graphql-tag';

export default gql`
query wishlist {
customer {
wishlists {
items_count
}
}
}
`;
4 changes: 4 additions & 0 deletions packages/api-client/src/types/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,4 +444,8 @@ export interface MagentoApiMethods {
searchParams: WishlistQueryVariables,
customQuery?: CustomQuery,
): Promise<ApolloQueryResult<WishlistQuery>>;

wishlistItemsCount(
customQuery?: CustomQuery,
): Promise<ApolloQueryResult<WishlistQuery>>;
}
6 changes: 3 additions & 3 deletions packages/composables/src/composables/useCart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,8 @@ const factoryParams: UseCartFactoryParams<Cart, CartItem, Product> = {
}
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
clear: (context: Context, _params = null) => {
context.$magento.config.state.setCartId(null);
clear: async (context: Context, _params = null) => {
context.$magento.config.state.setCartId();

return factoryParams.load(context, {});
},
Expand Down Expand Up @@ -388,7 +388,7 @@ const factoryParams: UseCartFactoryParams<Cart, CartItem, Product> = {
const apiState = context.$magento.config.state;
const { data } : any = await context.$magento.api.cartTotalQty(apiState.getCartId());

return data?.cart?.total_quantity;
return data?.cart?.total_quantity ?? 0;
},
};

Expand Down
5 changes: 2 additions & 3 deletions packages/composables/src/composables/useUser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ CustomerCreateInput

await context.$magento.api.revokeCustomerToken(params);

apiState.setCustomerToken(null);
apiState.setCartId(null);
context.cart.setCart(null);
apiState.setCustomerToken();
apiState.setCartId();
},
updateUser: async (context: Context, params) => {
Logger.debug('[Magento] Update user information', { params });
Expand Down
14 changes: 14 additions & 0 deletions packages/composables/src/composables/useWishlist/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ const factoryParams: UseWishlistFactoryParams<any, any, any> = {

return [];
},
loadItemsCount: async (context: Context, params) => {
Logger.debug('[Magento Storefront]: useWishlist.wishlistItemsCount params->', params);
const apiState = context.$magento.config.state;

if (apiState.getCustomerToken()) {
const { data } = await context.$magento.api.wishlistItemsCount();

Logger.debug('[Result]:', { data });

return data?.customer?.wishlists ?? [];
}

return [];
},
addItem: async (context, params) => {
const {
currentWishlist,
Expand Down
15 changes: 2 additions & 13 deletions packages/composables/src/factories/useCartFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,22 +159,11 @@ export const useCartFactory = <CART, CART_ITEM, PRODUCT, API extends PlatformApi
const load = async ({ customQuery } = { customQuery: undefined }) => {
Logger.debug('useCart.load');

if (cart.value) {
/**
* Triggering change for hydration purpose,
* temporary issue related with cpapi plugin
*/
loading.value = false;
error.value.load = null;
cart.value = { ...cart.value };

return;
}
try {
loading.value = true;
const loadedCart = await _factoryParams.load({ customQuery });
cart.value = loadedCart;
totalQuantity.value = loadedCart.total_quantity;
totalQuantity.value = loadedCart?.total_quantity ?? 0;
error.value.load = null;
} catch (err) {
error.value.load = err;
Expand Down Expand Up @@ -207,7 +196,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;
totalQuantity.value = 0;
} catch (err) {
error.value.clear = err;
Logger.error('useCart/clear', err);
Expand Down
40 changes: 36 additions & 4 deletions packages/composables/src/factories/useWishlistFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export interface UseWishlistFactoryParams<WISHLIST,
pageSize: number;
}>,
}>) => Promise<WISHLIST>;
loadItemsCount: (context: Context, params: ComposableFunctionArgs<{
searchParams?: Partial<{
currentPage: number;
pageSize: number;
}>,
}>) => Promise<WISHLIST>;
addItem: (
context: Context,
params: ComposableFunctionArgs<{
Expand All @@ -42,13 +48,17 @@ export interface UseWishlistFactoryParams<WISHLIST,
export const useWishlistFactory = <WISHLIST, WISHLIST_ITEM, PRODUCT, API extends PlatformApi = any>(
factoryParams: UseWishlistFactoryParams<WISHLIST, WISHLIST_ITEM, PRODUCT, API>,
) => {
const calculateWishlistTotal = (wishlists) => wishlists.reduce((prev, next) => (prev?.items_count ?? 0) + (next?.items_count ?? 0), 0);

const useWishlist = (ssrKey = 'useWishlistFactory'): UseWishlist<WISHLIST, WISHLIST_ITEM, PRODUCT, API> => {
const loading: Ref<boolean> = sharedRef<boolean>(false, `useWishlist-loading-${ssrKey}`);
const wishlist: Ref<WISHLIST> = sharedRef(null, `useWishlist-wishlist-${ssrKey}`);
const itemsCount: Ref<number> = sharedRef(0, `useWishlist-itemsCount-${ssrKey}`);
const error: Ref<UseWishlistErrors> = sharedRef({
addItem: null,
removeItem: null,
load: null,
loadItemsCount: null,
clear: null,
}, `useWishlist-error-${ssrKey}`);

Expand All @@ -65,6 +75,7 @@ export const useWishlistFactory = <WISHLIST, WISHLIST_ITEM, PRODUCT, API extends

const setWishlist = (newWishlist: WISHLIST) => {
wishlist.value = newWishlist;
itemsCount.value = newWishlist[0].items_count;
Logger.debug(`useWishlistFactory/${ssrKey}/setWishlist`, newWishlist);
};

Expand All @@ -80,6 +91,7 @@ export const useWishlistFactory = <WISHLIST, WISHLIST_ITEM, PRODUCT, API extends
});
error.value.addItem = null;
wishlist.value = updatedWishlist;
itemsCount.value = updatedWishlist.items_count;
} catch (err) {
error.value.addItem = err;
Logger.error(`useWishlist/${ssrKey}/addItem`, err);
Expand All @@ -100,6 +112,7 @@ export const useWishlistFactory = <WISHLIST, WISHLIST_ITEM, PRODUCT, API extends
});
error.value.removeItem = null;
wishlist.value = updatedWishlist;
itemsCount.value = updatedWishlist.items_count;
} catch (err) {
error.value.removeItem = err;
Logger.error(`useWishlist/${ssrKey}/removeItem`, err);
Expand All @@ -118,7 +131,9 @@ export const useWishlistFactory = <WISHLIST, WISHLIST_ITEM, PRODUCT, API extends
Logger.debug(`useWishlist/${ssrKey}/load`);
try {
loading.value = true;
wishlist.value = await _factoryParams.load(params);
const loadedWishlist = await _factoryParams.load(params);
wishlist.value = loadedWishlist;
itemsCount.value = calculateWishlistTotal(loadedWishlist);
error.value.load = null;
} catch (err) {
error.value.load = err;
Expand All @@ -128,6 +143,20 @@ export const useWishlistFactory = <WISHLIST, WISHLIST_ITEM, PRODUCT, API extends
}
};

const loadItemsCount = async (params: {
customQuery?: CustomQuery
}) => {
Logger.debug(`useWishlist/${ssrKey}/loadItemsCount`);
try {
const loadedWishlist = await _factoryParams.loadItemsCount(params);
itemsCount.value = calculateWishlistTotal(loadedWishlist);
error.value.loadItemsCount = null;
} catch (err) {
error.value.loadItemsCount = err;
Logger.error(`useWishlist/${ssrKey}/loadItemsCount`, err);
}
};

const clear = async () => {
Logger.debug(`useWishlist/${ssrKey}/clear`);

Expand All @@ -138,6 +167,7 @@ export const useWishlistFactory = <WISHLIST, WISHLIST_ITEM, PRODUCT, API extends
});
error.value.clear = null;
wishlist.value = updatedWishlist;
itemsCount.value = 0;
} catch (err) {
error.value.clear = err;
Logger.error(`useWishlist/${ssrKey}/clear`, err);
Expand All @@ -157,15 +187,17 @@ export const useWishlistFactory = <WISHLIST, WISHLIST_ITEM, PRODUCT, API extends

return {
api: _factoryParams.api,
wishlist: computed(() => wishlist.value),
wishlist,
itemsCount,
isInWishlist,
addItem,
load,
loadItemsCount,
removeItem,
clear,
setWishlist,
loading: computed(() => loading.value),
error: computed(() => error.value),
loading,
error,
};
};

Expand Down
2 changes: 1 addition & 1 deletion packages/composables/src/getters/wishlistGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const getProducts = (wishlistData: Wishlist[] | Wishlist): {
return [];
}

const reducer = (acc, curr) => [...acc, ...curr.items_v2.items.map((item) => ({
const reducer = (acc, curr) => [...acc, ...curr?.items_v2?.items.map((item) => ({
product: item.product,
quantity: item.quantity,
added_at: item.added_at,
Expand Down
7 changes: 5 additions & 2 deletions packages/composables/src/types/composables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
ComputedProperty,
CustomQuery,
} from '@vue-storefront/core';
import { ComputedRef } from '@vue/composition-api';
import { ComputedRef, Ref } from '@vue/composition-api';
import { PlatformApi } from '@vue-storefront/core/lib/src/types';
import { FetchPolicy } from './index';

Expand Down Expand Up @@ -300,6 +300,7 @@ export interface UseWishlistErrors {
addItem: Error;
removeItem: Error;
load: Error;
loadItemsCount: Error;
clear: Error;
}

Expand All @@ -310,7 +311,7 @@ export interface UseWishlist<WISHLIST,
> extends Composable<API> {
wishlist: ComputedProperty<WISHLIST>;
loading: ComputedProperty<boolean>;

itemsCount: Ref<number>;
addItem(params: ComposableFunctionArgs<{ product: PRODUCT; }>): Promise<void>;

removeItem(params: ComposableFunctionArgs<{ product: WISHLIST_ITEM; }>): Promise<void>;
Expand All @@ -322,6 +323,8 @@ export interface UseWishlist<WISHLIST,
}>,
}>): Promise<void>;

loadItemsCount(params: ComposableFunctionArgs<{}>): Promise<void>;

clear(): Promise<void>;

setWishlist: (wishlist: WISHLIST) => void;
Expand Down
13 changes: 6 additions & 7 deletions packages/theme/components/AppHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ import {
useCategory,
useCategorySearch,
useFacet,
useUser, useWishlist, wishlistGetters,
useUser, useWishlist,
} from '@vue-storefront/magento';
import {
computed,
Expand Down Expand Up @@ -220,8 +220,8 @@ export default defineComponent({
const { toggleCartSidebar, toggleWishlistSidebar, toggleLoginModal } = useUiState();
const { setTermForUrl, getFacetsFromURL, getAgnosticCatLink } = useUiHelpers();
const { isAuthenticated } = useUser();
const { totalQuantity, loadTotalQty } = useCart();
const { wishlist } = useWishlist('GlobalWishlist');
const { totalQuantity: cartTotalItems, loadTotalQty: loadCartTotalQty } = useCart();
const { itemsCount: wishlistItemsQty, loadItemsCount: loadWishlistItemsCount } = useWishlist('GlobalWishlist');
const {
result: searchResult,
search: productsSearch,
Expand All @@ -240,8 +240,7 @@ export default defineComponent({
const searchBarRef = ref(null);
const result = ref(null);
const wishlistHasProducts = computed(() => wishlistGetters.getTotalItems(wishlist.value) > 0);
const wishlistItemsQty = computed(() => wishlistGetters.getTotalItems(wishlist.value));
const wishlistHasProducts = computed(() => wishlistItemsQty.value > 0);
const accountIcon = computed(() => (isAuthenticated.value ? 'profile_fill' : 'profile'));
Expand All @@ -256,7 +255,7 @@ export default defineComponent({
};
useAsync(async () => {
await Promise.all([loadTotalQty(), categoriesListSearch({ pageSize: 20 })]);
await Promise.all([loadCartTotalQty(), loadWishlistItemsCount(), categoriesListSearch({ pageSize: 20 })]);
});
const showSearch = () => {
Expand Down Expand Up @@ -323,7 +322,7 @@ export default defineComponent({
return {
accountIcon,
cartTotalItems: totalQuantity,
cartTotalItems,
categoryTree,
closeOrFocusSearchBar,
closeSearch,
Expand Down
5 changes: 3 additions & 2 deletions packages/theme/components/CartSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,9 @@ export default defineComponent({
const tempProduct = ref();
onMounted(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
loadCart();
if (cart.value === null) {
loadCart();
}
});
const goToCheckout = async () => {
Expand Down
10 changes: 7 additions & 3 deletions packages/theme/components/LoginModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@ import {
} from '@storefront-ui/vue';
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate';
import { required, email } from 'vee-validate/dist/rules';
import { useUser, useForgotPassword, useWishlist } from '@vue-storefront/magento';
import {
useUser, useForgotPassword, useWishlist, useCart,
} from '@vue-storefront/magento';
import { useUiState } from '~/composables';
import { customerPasswordRegExp, invalidPasswordMsg } from '~/helpers/customer/regex';
Expand Down Expand Up @@ -348,7 +350,9 @@ export default defineComponent({
loading,
error: userError,
} = useUser();
const { load: loadWishlist } = useWishlist('GlobalWishlist');
const { load: loadCart } = useCart();
const { loadItemsCount } = useWishlist('GlobalWishlist');
const { request, error: forgotPasswordError, loading: forgotPasswordLoading } = useForgotPassword();
const barTitle = computed(() => {
Expand Down Expand Up @@ -439,7 +443,7 @@ export default defineComponent({
const handleLogin = async () => {
await handleForm(login)();
await loadWishlist('GlobalWishlist');
await Promise.all([loadItemsCount('GlobalWishlist'), loadCart()]);
};
const handleForgotten = async () => {
Expand Down
Loading

0 comments on commit 4c2dbcc

Please sign in to comment.