diff --git a/api/composables.api.md b/api/composables.api.md index fa28562bf..2426917b7 100644 --- a/api/composables.api.md +++ b/api/composables.api.md @@ -143,6 +143,7 @@ export function getDefaultApiParams(): { // @beta export const INTERCEPTOR_KEYS: { ADD_TO_CART: string; + ADD_PROMOTION_CODE: string; ERROR: string; USER_LOGOUT: string; }; @@ -164,33 +165,39 @@ export interface IUseAddToCart { // @beta export interface IUseCart { // (undocumented) - addProduct: ({ id, quantity }: { + addProduct: ({ id, quantity, }: { id: string; quantity?: number; - }) => void; + }) => Promise; + // (undocumented) + addPromotionCode: (promotionCode: string) => Promise; // (undocumented) - cart: Readonly>>; + appliedPromotionCodes: ComputedRef; // (undocumented) - cartItems: Readonly>>; + cart: ComputedRef; + // (undocumented) + cartItems: ComputedRef; // (undocumented) changeProductQuantity: ({ id, quantity, }: { id: string; quantity: number; }) => void; // (undocumented) - count: Readonly>>; + count: ComputedRef; // (undocumented) - error: Readonly>>; + error: ComputedRef; // (undocumented) - loading: Readonly>>; + loading: ComputedRef; // (undocumented) refreshCart: () => void; // (undocumented) + removeItem: ({ id }: LineItem) => Promise; + // @deprecated (undocumented) removeProduct: ({ id }: Partial) => void; // (undocumented) - subtotal: Readonly>>; + subtotal: ComputedRef; // (undocumented) - totalPrice: Readonly>>; + totalPrice: ComputedRef; } // @beta diff --git a/docs/guide/FEATURELIST.md b/docs/guide/FEATURELIST.md index cc8caeee9..653a1a14b 100644 --- a/docs/guide/FEATURELIST.md +++ b/docs/guide/FEATURELIST.md @@ -79,7 +79,7 @@ sidebar: auto * Go to Checkout button ### Checkout / Payment - + * Add/Remove promotion codes * Select shipping address * Select billing address * Select payment & shipping method diff --git a/docs/landing/resources/api/composables.interceptor_keys.md b/docs/landing/resources/api/composables.interceptor_keys.md index 604fb7e3e..1866465db 100644 --- a/docs/landing/resources/api/composables.interceptor_keys.md +++ b/docs/landing/resources/api/composables.interceptor_keys.md @@ -14,6 +14,7 @@ Keys used accross composables with the description of incommint parameters. ```typescript INTERCEPTOR_KEYS: { ADD_TO_CART: string; + ADD_PROMOTION_CODE: string; ERROR: string; USER_LOGOUT: string; } diff --git a/docs/landing/resources/api/composables.iusecart.addproduct.md b/docs/landing/resources/api/composables.iusecart.addproduct.md index 4d9e45643..48a792165 100644 --- a/docs/landing/resources/api/composables.iusecart.addproduct.md +++ b/docs/landing/resources/api/composables.iusecart.addproduct.md @@ -10,8 +10,8 @@ Signature: ```typescript -addProduct: ({ id, quantity }: { +addProduct: ({ id, quantity, }: { id: string; quantity?: number; - }) => void; + }) => Promise; ``` diff --git a/docs/landing/resources/api/composables.iusecart.addpromotioncode.md b/docs/landing/resources/api/composables.iusecart.addpromotioncode.md new file mode 100644 index 000000000..322bbf8d6 --- /dev/null +++ b/docs/landing/resources/api/composables.iusecart.addpromotioncode.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [@shopware-pwa/composables](./composables.md) > [IUseCart](./composables.iusecart.md) > [addPromotionCode](./composables.iusecart.addpromotioncode.md) + +## IUseCart.addPromotionCode property + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Signature: + +```typescript +addPromotionCode: (promotionCode: string) => Promise; +``` diff --git a/docs/landing/resources/api/composables.iusecart.appliedpromotioncodes.md b/docs/landing/resources/api/composables.iusecart.appliedpromotioncodes.md new file mode 100644 index 000000000..1c12f3621 --- /dev/null +++ b/docs/landing/resources/api/composables.iusecart.appliedpromotioncodes.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [@shopware-pwa/composables](./composables.md) > [IUseCart](./composables.iusecart.md) > [appliedPromotionCodes](./composables.iusecart.appliedpromotioncodes.md) + +## IUseCart.appliedPromotionCodes property + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Signature: + +```typescript +appliedPromotionCodes: ComputedRef; +``` diff --git a/docs/landing/resources/api/composables.iusecart.cart.md b/docs/landing/resources/api/composables.iusecart.cart.md index 00b2f3ac7..79b1f4794 100644 --- a/docs/landing/resources/api/composables.iusecart.cart.md +++ b/docs/landing/resources/api/composables.iusecart.cart.md @@ -10,5 +10,5 @@ Signature: ```typescript -cart: Readonly>>; +cart: ComputedRef; ``` diff --git a/docs/landing/resources/api/composables.iusecart.cartitems.md b/docs/landing/resources/api/composables.iusecart.cartitems.md index a4796bf7e..8cf7a2b83 100644 --- a/docs/landing/resources/api/composables.iusecart.cartitems.md +++ b/docs/landing/resources/api/composables.iusecart.cartitems.md @@ -10,5 +10,5 @@ Signature: ```typescript -cartItems: Readonly>>; +cartItems: ComputedRef; ``` diff --git a/docs/landing/resources/api/composables.iusecart.count.md b/docs/landing/resources/api/composables.iusecart.count.md index f390e4cf6..8893bc55d 100644 --- a/docs/landing/resources/api/composables.iusecart.count.md +++ b/docs/landing/resources/api/composables.iusecart.count.md @@ -10,5 +10,5 @@ Signature: ```typescript -count: Readonly>>; +count: ComputedRef; ``` diff --git a/docs/landing/resources/api/composables.iusecart.error.md b/docs/landing/resources/api/composables.iusecart.error.md index 529b18b6c..5b79d49cf 100644 --- a/docs/landing/resources/api/composables.iusecart.error.md +++ b/docs/landing/resources/api/composables.iusecart.error.md @@ -10,5 +10,5 @@ Signature: ```typescript -error: Readonly>>; +error: ComputedRef; ``` diff --git a/docs/landing/resources/api/composables.iusecart.loading.md b/docs/landing/resources/api/composables.iusecart.loading.md index 124bd2f78..544b981c5 100644 --- a/docs/landing/resources/api/composables.iusecart.loading.md +++ b/docs/landing/resources/api/composables.iusecart.loading.md @@ -10,5 +10,5 @@ Signature: ```typescript -loading: Readonly>>; +loading: ComputedRef; ``` diff --git a/docs/landing/resources/api/composables.iusecart.md b/docs/landing/resources/api/composables.iusecart.md index 2798ec013..cf5dab8e0 100644 --- a/docs/landing/resources/api/composables.iusecart.md +++ b/docs/landing/resources/api/composables.iusecart.md @@ -19,15 +19,18 @@ export interface IUseCart | Property | Type | Description | | --- | --- | --- | -| [addProduct](./composables.iusecart.addproduct.md) | ({ id, quantity }: { id: string; quantity?: number; }) => void | (BETA) | -| [cart](./composables.iusecart.cart.md) | Readonly<Ref<Readonly<Cart>>> | (BETA) | -| [cartItems](./composables.iusecart.cartitems.md) | Readonly<Ref<Readonly<LineItem\[\]>>> | (BETA) | +| [addProduct](./composables.iusecart.addproduct.md) | ({ id, quantity, }: { id: string; quantity?: number; }) => Promise<void> | (BETA) | +| [addPromotionCode](./composables.iusecart.addpromotioncode.md) | (promotionCode: string) => Promise<void> | (BETA) | +| [appliedPromotionCodes](./composables.iusecart.appliedpromotioncodes.md) | ComputedRef<LineItem\[\]> | (BETA) | +| [cart](./composables.iusecart.cart.md) | ComputedRef<Cart> | (BETA) | +| [cartItems](./composables.iusecart.cartitems.md) | ComputedRef<LineItem\[\]> | (BETA) | | [changeProductQuantity](./composables.iusecart.changeproductquantity.md) | ({ id, quantity, }: { id: string; quantity: number; }) => void | (BETA) | -| [count](./composables.iusecart.count.md) | Readonly<Ref<Readonly<number>>> | (BETA) | -| [error](./composables.iusecart.error.md) | Readonly<Ref<Readonly<string>>> | (BETA) | -| [loading](./composables.iusecart.loading.md) | Readonly<Ref<Readonly<boolean>>> | (BETA) | +| [count](./composables.iusecart.count.md) | ComputedRef<number> | (BETA) | +| [error](./composables.iusecart.error.md) | ComputedRef<string> | (BETA) | +| [loading](./composables.iusecart.loading.md) | ComputedRef<boolean> | (BETA) | | [refreshCart](./composables.iusecart.refreshcart.md) | () => void | (BETA) | +| [removeItem](./composables.iusecart.removeitem.md) | ({ id }: LineItem) => Promise<void> | (BETA) | | [removeProduct](./composables.iusecart.removeproduct.md) | ({ id }: Partial<Product>) => void | (BETA) | -| [subtotal](./composables.iusecart.subtotal.md) | Readonly<Ref<Readonly<number>>> | (BETA) | -| [totalPrice](./composables.iusecart.totalprice.md) | Readonly<Ref<Readonly<number>>> | (BETA) | +| [subtotal](./composables.iusecart.subtotal.md) | ComputedRef<number> | (BETA) | +| [totalPrice](./composables.iusecart.totalprice.md) | ComputedRef<number> | (BETA) | diff --git a/docs/landing/resources/api/composables.iusecart.removeitem.md b/docs/landing/resources/api/composables.iusecart.removeitem.md new file mode 100644 index 000000000..3427a1dd0 --- /dev/null +++ b/docs/landing/resources/api/composables.iusecart.removeitem.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [@shopware-pwa/composables](./composables.md) > [IUseCart](./composables.iusecart.md) > [removeItem](./composables.iusecart.removeitem.md) + +## IUseCart.removeItem property + +> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Signature: + +```typescript +removeItem: ({ id }: LineItem) => Promise; +``` diff --git a/docs/landing/resources/api/composables.iusecart.removeproduct.md b/docs/landing/resources/api/composables.iusecart.removeproduct.md index ab539e54c..caa25c736 100644 --- a/docs/landing/resources/api/composables.iusecart.removeproduct.md +++ b/docs/landing/resources/api/composables.iusecart.removeproduct.md @@ -7,6 +7,11 @@ > This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. > +> Warning: This API is now obsolete. +> +> use removeItem method instead +> + Signature: ```typescript diff --git a/docs/landing/resources/api/composables.iusecart.subtotal.md b/docs/landing/resources/api/composables.iusecart.subtotal.md index a5ced03e4..0fcaf2d7c 100644 --- a/docs/landing/resources/api/composables.iusecart.subtotal.md +++ b/docs/landing/resources/api/composables.iusecart.subtotal.md @@ -10,5 +10,5 @@ Signature: ```typescript -subtotal: Readonly>>; +subtotal: ComputedRef; ``` diff --git a/docs/landing/resources/api/composables.iusecart.totalprice.md b/docs/landing/resources/api/composables.iusecart.totalprice.md index c5d12bbdc..e0a2db96a 100644 --- a/docs/landing/resources/api/composables.iusecart.totalprice.md +++ b/docs/landing/resources/api/composables.iusecart.totalprice.md @@ -10,5 +10,5 @@ Signature: ```typescript -totalPrice: Readonly>>; +totalPrice: ComputedRef; ``` diff --git a/packages/commons/interfaces/cart/CartItemType.ts b/packages/commons/interfaces/cart/CartItemType.ts index 086bc1daa..59125a772 100644 --- a/packages/commons/interfaces/cart/CartItemType.ts +++ b/packages/commons/interfaces/cart/CartItemType.ts @@ -1,3 +1,6 @@ +/** + * @deprecated use LineItemType instead + */ export enum CartItemType { PRODUCT = "product", CREDIT = "credit", diff --git a/packages/commons/interfaces/models/checkout/cart/line-item/LineItem.ts b/packages/commons/interfaces/models/checkout/cart/line-item/LineItem.ts index a8a15d330..2b7613db1 100644 --- a/packages/commons/interfaces/models/checkout/cart/line-item/LineItem.ts +++ b/packages/commons/interfaces/models/checkout/cart/line-item/LineItem.ts @@ -6,14 +6,19 @@ import { PriceDefinitionInterface } from "../price/PriceDefinitionInterface"; import { QuantityInformation } from "./QuantityInformation"; /** - * @alpha + * @beta + */ +export type LineItemType = "product" | "promotion" | "custom" | "credit"; + +/** + * @beta */ export interface LineItem { id: string; referencedId: string | null; label: string | null; quantity: number; - type: string; + type: LineItemType; payload: []; priceDefinition: PriceDefinitionInterface | null; price: CalculatedPrice | null; diff --git a/packages/composables/__tests__/useCart.spec.ts b/packages/composables/__tests__/useCart.spec.ts index 643d44c09..715d4e461 100644 --- a/packages/composables/__tests__/useCart.spec.ts +++ b/packages/composables/__tests__/useCart.spec.ts @@ -7,6 +7,7 @@ import VueCompositionApi, { } from "@vue/composition-api"; Vue.use(VueCompositionApi); +import { LineItem } from "@shopware-pwa/commons/interfaces/models/checkout/cart/line-item/LineItem"; import { useCart } from "@shopware-pwa/composables"; import * as shopwareClient from "@shopware-pwa/shopware-6-client"; @@ -139,6 +140,31 @@ describe("Composables - useCart", () => { expect(subtotal.value).toEqual(123); }); }); + describe("appliedPromotionCodes", () => { + it("should be empty array on not loaded cart", () => { + stateCart.value = null; + const { appliedPromotionCodes } = useCart(rootContextMock); + expect(appliedPromotionCodes.value).toEqual([]); + }); + + it("should return an array", () => { + stateCart.value = {}; + const { appliedPromotionCodes } = useCart(rootContextMock); + expect(appliedPromotionCodes.value).toEqual([]); + }); + + it("should return only promotion items", () => { + stateCart.value = { + lineItems: [ + { quantity: 2, type: "product" }, + { quantity: 3, type: "product" }, + { quantity: 1, type: "promotion" }, + ], + }; + const { appliedPromotionCodes } = useCart(rootContextMock); + expect(appliedPromotionCodes.value.length).toEqual(1); + }); + }); }); describe("methods", () => { @@ -212,6 +238,45 @@ describe("Composables - useCart", () => { }); }); + describe("addPromotionCode", () => { + it("should add promotion code to cart", async () => { + const { appliedPromotionCodes, addPromotionCode } = useCart( + rootContextMock + ); + expect(appliedPromotionCodes.value).toEqual([]); + mockedShopwareClient.addPromotionCode.mockResolvedValueOnce({ + lineItems: [{ quantity: 1, type: "promotion" }], + } as any); + await addPromotionCode("test-code"); + expect(appliedPromotionCodes.value.length).toEqual(1); + }); + }); + + describe("removeItem", () => { + it("should remove promotion code from cart", async () => { + const { appliedPromotionCodes, removeItem } = useCart(rootContextMock); + stateCart.value = { + lineItems: [{ quantity: 1, type: "promotion" }], + }; + expect(appliedPromotionCodes.value.length).toEqual(1); + mockedShopwareClient.removeCartItem.mockResolvedValueOnce({ + lineItems: [], + } as any); + await removeItem({ id: "qwe" } as LineItem); + expect(appliedPromotionCodes.value.length).toEqual(0); + }); + + it("should invoke client with correct params", async () => { + const { removeProduct } = useCart(rootContextMock); + mockedShopwareClient.removeCartItem.mockResolvedValueOnce({} as any); + await removeProduct({ id: "qwe" }); + expect(mockedShopwareClient.removeCartItem).toBeCalledWith( + "qwe", + rootContextMock.$shopwareApiInstance + ); + }); + }); + describe("changeProductQuantity", () => { it("should change product quantity in cart", async () => { const { count, changeProductQuantity } = useCart(rootContextMock); diff --git a/packages/composables/src/hooks/useCart/index.ts b/packages/composables/src/hooks/useCart/index.ts index af8065726..5a4d1497c 100644 --- a/packages/composables/src/hooks/useCart/index.ts +++ b/packages/composables/src/hooks/useCart/index.ts @@ -1,7 +1,8 @@ -import { ref, Ref, computed } from "@vue/composition-api"; +import { ref, Ref, computed, ComputedRef } from "@vue/composition-api"; import { getCart, addProductToCart, + addPromotionCode, removeCartItem, changeCartItemQuantity, } from "@shopware-pwa/shopware-6-client"; @@ -9,8 +10,13 @@ import { ClientApiError } from "@shopware-pwa/commons/interfaces/errors/ApiError import { Cart } from "@shopware-pwa/commons/interfaces/models/checkout/cart/Cart"; import { Product } from "@shopware-pwa/commons/interfaces/models/content/product/Product"; import { LineItem } from "@shopware-pwa/commons/interfaces/models/checkout/cart/line-item/LineItem"; -import { getApplicationContext } from "@shopware-pwa/composables"; +import { + getApplicationContext, + INTERCEPTOR_KEYS, + useIntercept, +} from "@shopware-pwa/composables"; import { ApplicationVueContext } from "../../appContext"; +import { deprecationWarning } from "@shopware-pwa/commons"; /** * interface for {@link useCart} composable @@ -18,9 +24,17 @@ import { ApplicationVueContext } from "../../appContext"; * @beta */ export interface IUseCart { - addProduct: ({ id, quantity }: { id: string; quantity?: number }) => void; - cart: Readonly>>; - cartItems: Readonly>>; + addProduct: ({ + id, + quantity, + }: { + id: string; + quantity?: number; + }) => Promise; + addPromotionCode: (promotionCode: string) => Promise; + appliedPromotionCodes: ComputedRef; + cart: ComputedRef; + cartItems: ComputedRef; changeProductQuantity: ({ id, quantity, @@ -28,13 +42,17 @@ export interface IUseCart { id: string; quantity: number; }) => void; - count: Readonly>>; - error: Readonly>>; - loading: Readonly>>; + count: ComputedRef; + error: ComputedRef; + loading: ComputedRef; refreshCart: () => void; + removeItem: ({ id }: LineItem) => Promise; + /** + * @deprecated use removeItem method instead + */ removeProduct: ({ id }: Partial) => void; - totalPrice: Readonly>>; - subtotal: Readonly>>; + totalPrice: ComputedRef; + subtotal: ComputedRef; } /** @@ -47,6 +65,7 @@ export const useCart = (rootContext: ApplicationVueContext): IUseCart => { rootContext, "useCart" ); + const { broadcast } = useIntercept(rootContext); const loading: Ref = ref(false); const error: Ref = ref(null); @@ -75,17 +94,42 @@ export const useCart = (rootContext: ApplicationVueContext): IUseCart => { vuexStore.commit("SET_CART", result); } - async function removeProduct({ id }: Product) { + async function removeItem({ id }: LineItem) { const result = await removeCartItem(id, apiInstance); vuexStore.commit("SET_CART", result); } + // TODO: remove in 1.0 + async function removeProduct({ id }: Product) { + deprecationWarning({ + methodName: "removeProduct", + newMethodName: "removeItem", + packageName: "composables", + }); + return removeItem({ id } as LineItem); + } + async function changeProductQuantity({ id, quantity }: any) { const result = await changeCartItemQuantity(id, quantity, apiInstance); vuexStore.commit("SET_CART", result); } - const cart: Readonly>> = computed(() => { + async function sumbitPromotionCode(promotionCode: string) { + const result = await addPromotionCode(promotionCode, apiInstance); + vuexStore.commit("SET_CART", result); + broadcast(INTERCEPTOR_KEYS.ADD_PROMOTION_CODE, { + result, + promotionCode, + }); + } + + const appliedPromotionCodes = computed(() => { + return cartItems.value.filter( + (cartItem: LineItem) => cartItem.type === "promotion" + ); + }); + + const cart: ComputedRef = computed(() => { return vuexStore.getters.getCart; }); @@ -116,6 +160,8 @@ export const useCart = (rootContext: ApplicationVueContext): IUseCart => { return { addProduct, + addPromotionCode: sumbitPromotionCode, + appliedPromotionCodes, cart, cartItems, changeProductQuantity, @@ -124,6 +170,7 @@ export const useCart = (rootContext: ApplicationVueContext): IUseCart => { loading, refreshCart, removeProduct, + removeItem, totalPrice, subtotal, }; diff --git a/packages/composables/src/logic/useIntercept.ts b/packages/composables/src/logic/useIntercept.ts index a4cf96c9e..a0d26b631 100644 --- a/packages/composables/src/logic/useIntercept.ts +++ b/packages/composables/src/logic/useIntercept.ts @@ -15,6 +15,11 @@ export const INTERCEPTOR_KEYS = { * As a parameter passes product added to cart and quantity. */ ADD_TO_CART: "addToCart", + /** + * Broadcasted by useCart composable on successful submitPromotionCode method invocation. + * As a parameter passes used promotion code and response result. + */ + ADD_PROMOTION_CODE: "addPromotionCode", /** * Broadcasted through application in case of important error. * Can be used to connect to external service collectiong logs. diff --git a/packages/default-theme/components/SwCart.vue b/packages/default-theme/components/SwCart.vue index 0afaa8bac..d924c0a45 100644 --- a/packages/default-theme/components/SwCart.vue +++ b/packages/default-theme/components/SwCart.vue @@ -119,10 +119,14 @@ export default { () => isSidebarOpen.value && isComponentMounted.value ) + const getCartProducts = computed(() => { + return cartItems.value.filter((cartItem) => cartItem.type === "product") + }) + return { isSidebarOpen: sidebarState, toggleSidebar, - cartItems, + cartItems: getCartProducts, count, totalPrice, removeProduct, diff --git a/packages/default-theme/components/SwPromoCode.vue b/packages/default-theme/components/SwPromoCode.vue new file mode 100644 index 000000000..04f12d5cf --- /dev/null +++ b/packages/default-theme/components/SwPromoCode.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/packages/default-theme/components/SwPromoCodeItem.vue b/packages/default-theme/components/SwPromoCodeItem.vue new file mode 100644 index 000000000..5e174efd3 --- /dev/null +++ b/packages/default-theme/components/SwPromoCodeItem.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/packages/default-theme/components/checkout/sidebar/SidebarOrderSummary.vue b/packages/default-theme/components/checkout/sidebar/SidebarOrderSummary.vue index 3edcd9ef3..9d944b0f3 100644 --- a/packages/default-theme/components/checkout/sidebar/SidebarOrderSummary.vue +++ b/packages/default-theme/components/checkout/sidebar/SidebarOrderSummary.vue @@ -26,15 +26,7 @@ :value="totalPrice | price" class="sf-property--full-width sf-property--large property" /> -
- - -
+
import { SfHeading, - SfCircleIcon, SfProperty, SfDivider, SfCharacteristic, } from "@storefront-ui/vue" import { useCart } from "@shopware-pwa/composables" -import SwInput from "@/components/atoms/SwInput" +import SwPromoCode from "@/components/SwPromoCode" export default { name: "SidebarOrderSummary", components: { SfHeading, - SfCircleIcon, SfProperty, SfDivider, SfCharacteristic, - SwInput, + SwPromoCode, }, setup(props, { root }) { const { count, totalPrice, subtotal } = useCart(root) @@ -84,8 +74,6 @@ export default { }, data() { return { - promoCode: "", - showPromoCode: false, characteristics: [ { title: this.$t("Safety"), @@ -135,19 +123,4 @@ export default { margin: var(--spacer-base) 0; } } -.promo-code { - display: flex; - justify-content: space-between; - align-items: flex-start; - padding: var(--spacer-lg) 0 var(--spacer-base) 0; - &__circle-icon { - --button-size: 2rem; - --icon-size: 0.6875rem; - } - &__input { - --input-background: var(--c-white); - flex: 1; - margin: 0 var(--spacer-lg) 0 0; - } -} diff --git a/packages/default-theme/components/checkout/summary/OrderItem.vue b/packages/default-theme/components/checkout/summary/OrderItem.vue index 53fd4e826..23205a127 100644 --- a/packages/default-theme/components/checkout/summary/OrderItem.vue +++ b/packages/default-theme/components/checkout/summary/OrderItem.vue @@ -1,7 +1,11 @@