From 6e9f46e8eb3cedb18ebaec8a01d12c17f075f863 Mon Sep 17 00:00:00 2001 From: Filip Sobol Date: Tue, 12 Apr 2022 20:38:43 +0200 Subject: [PATCH] feat!: make `loading` and `error` properties readonly in the `useWishlist` composable --- docs/.vuepress/config.js | 3 +- packages/theme/composables/index.ts | 2 +- .../composables/useUiNotification/index.ts | 5 + .../theme/composables/useWishlist/index.ts | 54 ++++--- .../composables/useWishlist/useWishlist.ts | 151 ++++++++++++------ 5 files changed, 139 insertions(+), 76 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 9a3bfd809..f82b31a6a 100755 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -95,7 +95,8 @@ module.exports = { ['/api-reference/magento-theme.useaddresses', 'useAddresses()'], ['/api-reference/magento-theme.usecontent', 'useContent()'], ['/api-reference/magento-theme.usecategory', 'useCategory()'], - ] + ['/api-reference/magento-theme.usewishlist', 'useWishlist()'], + ], }, { title: 'API methods', diff --git a/packages/theme/composables/index.ts b/packages/theme/composables/index.ts index 431784bb8..67a125275 100644 --- a/packages/theme/composables/index.ts +++ b/packages/theme/composables/index.ts @@ -14,7 +14,7 @@ export { default as useConfig } from './useConfig'; export { default as useStore } from './useStore'; export { default as useCurrency } from './useCurrency'; export { default as useExternalCheckout } from './useExternalCheckout'; -export { default as useWishlist } from './useWishlist'; +export * from './useWishlist'; export { default as useUser } from './useUser'; export { default as useGuestUser } from './useGuestUser'; export { default as useForgotPassword } from './useForgotPassword'; diff --git a/packages/theme/composables/useUiNotification/index.ts b/packages/theme/composables/useUiNotification/index.ts index 350b99f05..dc0726377 100644 --- a/packages/theme/composables/useUiNotification/index.ts +++ b/packages/theme/composables/useUiNotification/index.ts @@ -24,6 +24,7 @@ const timeToLive = 3000; const useUiNotification = () => { const { app } = useContext(); + // @ts-ignore const cookieMessage = app.$vsf.$magento.config.state.getMessage(); const send = (notification: UiNotification) => { @@ -34,6 +35,7 @@ const useUiNotification = () => { if (index !== -1) state.notifications.splice(index, 1); + // @ts-ignore app.$vsf.$magento.config.state.removeMessage(); }; @@ -57,7 +59,10 @@ const useUiNotification = () => { }; if (cookieMessage) { + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument send(cookieMessage); + // @ts-ignore app.$vsf.$magento.config.state.removeMessage(); } diff --git a/packages/theme/composables/useWishlist/index.ts b/packages/theme/composables/useWishlist/index.ts index 85c8795ed..daca92802 100644 --- a/packages/theme/composables/useWishlist/index.ts +++ b/packages/theme/composables/useWishlist/index.ts @@ -1,15 +1,26 @@ -import { ref, useContext } from '@nuxtjs/composition-api'; +import { readonly, ref, useContext } from '@nuxtjs/composition-api'; +import { findItemOnWishlist } from '~/composables/useWishlist/helpers'; import { Logger } from '~/helpers/logger'; -import { CustomQuery } from '~/composables/types'; import { useCustomerStore } from '~/stores/customer'; -import { findItemOnWishlist } from '~/composables/useWishlist/helpers'; -import { UseWishlist, UseWishlistErrors, Wishlist } from '~/composables/useWishlist/useWishlist'; - -export const useWishlist = (): UseWishlist => { +import type { Wishlist } from '~/modules/GraphQL/types'; +import type { + UseWishlistAddItemParams, + UseWishlistErrors, + UseWishlistInterface, + UseWishlistIsInWishlistParams, + UseWishlistLoadParams, + UseWishlistRemoveItemParams, +} from '~/composables/useWishlist/useWishlist'; + +/** + * The `useWishlist()` composable allows loading and manipulating wishlist of the current user. + * + * See the {@link UseWishlistInterface} page for more information. + */ +export function useWishlist(): UseWishlistInterface { const customerStore = useCustomerStore(); const { app } = useContext(); const loading = ref(false); - const wishlist = ref(customerStore.wishlist); // eslint-disable-next-line @typescript-eslint/restrict-plus-operands const calculateWishlistTotal = (wishlists) => wishlists.reduce((prev, next) => (prev?.items_count ?? 0) + (next?.items_count ?? 0), 0); const error = ref({ @@ -20,14 +31,8 @@ export const useWishlist = (): UseWishlist => { loadItemsCount: null, }); - const load = async (params: { - searchParams?: Partial<{ - currentPage: number; - pageSize: number; - }>, - customQuery?: CustomQuery, - // eslint-disable-next-line consistent-return - }) => { + // eslint-disable-next-line consistent-return + const load = async (params: UseWishlistLoadParams) => { Logger.debug('useWishlist/load'); try { @@ -58,7 +63,7 @@ export const useWishlist = (): UseWishlist => { } }; - const isInWishlist = ({ product }) => { + const isInWishlist = ({ product }: UseWishlistIsInWishlistParams) => { Logger.debug('useWishlist/isInWishlist', product); const wishlistProduct = findItemOnWishlist(customerStore.wishlist, product); @@ -71,7 +76,7 @@ export const useWishlist = (): UseWishlist => { Logger.debug('useWishlist/setWishlist', newWishlist); }; - const removeItem = async ({ product, params }) => { + const removeItem = async ({ product, customQuery }: UseWishlistRemoveItemParams) => { Logger.debug('useWishlist/removeItem', product); try { @@ -79,14 +84,14 @@ export const useWishlist = (): UseWishlist => { Logger.debug('[Magento Storefront]: useWishlist.removeItem params->', { currentWishlist: customerStore.wishlist, product, - customQuery: params?.customQuery, + customQuery, }); const itemOnWishlist = findItemOnWishlist(customerStore.wishlist, product); const { data } = await app.context.$vsf.$magento.api.removeProductsFromWishlist({ id: '0', items: [itemOnWishlist.id], - }, params?.customQuery); + }, customQuery); Logger.debug('[Result]:', { data }); error.value.removeItem = null; @@ -130,7 +135,7 @@ export const useWishlist = (): UseWishlist => { }; // eslint-disable-next-line consistent-return - const addItem = async ({ product, customQuery }) => { + const addItem = async ({ product, customQuery }: UseWishlistAddItemParams) => { Logger.debug('useWishlist/addItem', product); try { @@ -151,7 +156,6 @@ export const useWishlist = (): UseWishlist => { if (itemOnWishlist) { return await removeItem({ product, - params: {}, }); } @@ -252,7 +256,6 @@ export const useWishlist = (): UseWishlist => { }; return { - wishlist, loadItemsCount, isInWishlist, addItem, @@ -260,9 +263,10 @@ export const useWishlist = (): UseWishlist => { removeItem, clear, setWishlist, - loading, - error, + loading: readonly(loading), + error: readonly(error), }; -}; +} export default useWishlist; +export * from './useWishlist'; diff --git a/packages/theme/composables/useWishlist/useWishlist.ts b/packages/theme/composables/useWishlist/useWishlist.ts index b7aab7ece..364699bc5 100644 --- a/packages/theme/composables/useWishlist/useWishlist.ts +++ b/packages/theme/composables/useWishlist/useWishlist.ts @@ -1,54 +1,107 @@ -import { Ref } from '@nuxtjs/composition-api'; -import { ComposableFunctionArgs } from '~/composables/types'; -import { - Maybe, ProductInterface, Scalars, WishlistItem, WishlistItems, -} from '~/modules/GraphQL/types'; - -export interface Wishlist { - /** The unique ID for a `Wishlist` object */ - id?: Maybe; - /** @deprecated Use field `items_v2` from type `Wishlist` instead */ - items?: Maybe>>; - /** The number of items in the wish list */ - items_count?: Maybe; - /** An array of items in the customer's wish list */ - items_v2?: Maybe; - /** An encrypted code that Magento uses to link to the wish list */ - sharing_code?: Maybe; - /** The time of the last modification to the wish list */ - updated_at?: Maybe; -} +import type { Ref, DeepReadonly } from '@nuxtjs/composition-api'; +import type { ComposableFunctionArgs } from '~/composables/types'; +import type { Wishlist, ProductInterface } from '~/modules/GraphQL/types'; +/** + * Errors that occured in the `useWishlist` composable + */ export interface UseWishlistErrors { - addItem: Error; - removeItem: Error; - load: Error; - clear: Error; - loadItemsCount: Error; + addItem: Error | null; + removeItem: Error | null; + load: Error | null; + clear: Error | null; + loadItemsCount: Error | null; } + +/** + * Parameters accepted by the `loadItemsCount` method in the `useWishlist` composable + */ +export type UseWishlistLoadItemsCountParams = ComposableFunctionArgs<{ + // TODO: Add type +}>; + +/** + * Parameters accepted by the `isInWishlist` method in the `useWishlist` composable + */ +export type UseWishlistIsInWishlistParams = { product: ProductInterface }; + +/** + * Parameters accepted by the `addItem` method in the `useWishlist` composable + */ +export type UseWishlistAddItemParams = ComposableFunctionArgs<{ + product: any; // TODO: add product interface +}>; + +/** + * Parameters accepted by the `load` method in the `useWishlist` composable + */ +export type UseWishlistLoadParams = ComposableFunctionArgs<{ + searchParams?: Partial<{ + currentPage: number; + pageSize: number; + }> +}>; + /** - * TODO: add types - */ -export type UseWishlist = { - wishlist: Ref, - loadItemsCount(params: ComposableFunctionArgs<{}>): Promise; - isInWishlist: (params: { product: ProductInterface }) => boolean; - addItem: ( - params: ComposableFunctionArgs<{ - product: any; // TODO: add product intrface - }>) => Promise; - load: (params: ComposableFunctionArgs<{ - searchParams?: Partial<{ - currentPage: number; - pageSize: number; - }>, - }>) => Promise; - removeItem: ( - params: ComposableFunctionArgs<{ - product: any; // TODO: add product intrface - }>) => Promise; - clear: (params: { currentWishlist: any }) => Promise; - setWishlist: (newWishlist: Wishlist) => void; - loading: Ref - error: Ref; + * Parameters accepted by the `removeItem` method in the `useWishlist` composable + */ +export type UseWishlistRemoveItemParams = ComposableFunctionArgs<{ + product: any; // TODO: add product interface +}>; + +/** + * Parameters accepted by the `clear` method in the `useWishlist` composable + */ +export type UseWishlistClearParams = { + currentWishlist: any; // TODO: Add type }; + +/** + * Represents the data returned from and functions available in the `useWishlist()` composable. + */ +export interface UseWishlistInterface { + /** + * Returns a total number of items added to the wishlist of the current user + */ + loadItemsCount(params: UseWishlistLoadItemsCountParams): Promise; + + /** + * Checks if given product is in the wishlist of the current user + */ + isInWishlist(params: UseWishlistIsInWishlistParams): boolean; + + /** + * Adds product to the wishlist of the current user + */ + addItem(params: UseWishlistAddItemParams): Promise; + + /** + * Fetches wishlist of the current customer + */ + load(params: UseWishlistLoadParams): Promise; // TODO: Why this method returns a Wishlist but others dont? + + /** + * Removes product from the wishlist of the current user + */ + removeItem(params: UseWishlistRemoveItemParams): Promise; + + /** + * Removes all products from the wishlist of the current user + */ + clear(params: UseWishlistClearParams): Promise; + + /** + * Overrides the wishlist of the current user + */ + setWishlist(newWishlist: Wishlist): void; + + /** + * Indicates whether any of the methods is in progress + */ + loading: DeepReadonly>; + + /** + * Contains errors from any of the composable methods + */ + error: DeepReadonly>; +}