diff --git a/api/composables.api.md b/api/composables.api.md
index 40c9c792c..72994e47f 100644
--- a/api/composables.api.md
+++ b/api/composables.api.md
@@ -140,6 +140,12 @@ export function getDefaultApiParams(): {
[composableName: string]: ShopwareSearchParams;
};
+// @beta
+export interface IInterceptorCallbackFunction {
+ // (undocumented)
+ (payload: any, rootContext?: ApplicationVueContext_2): void;
+}
+
// @beta
export const INTERCEPTOR_KEYS: {
ADD_TO_CART: string;
@@ -230,8 +236,8 @@ export interface IUseCheckout {
// @beta
export interface IUseIntercept {
broadcast: (broadcastKey: string, value?: any) => void;
- disconnect: (broadcastKey: string, method: Function) => void;
- intercept: (broadcastKey: string, method: Function) => void;
+ disconnect: (broadcastKey: string, method: IInterceptorCallbackFunction) => void;
+ intercept: (broadcastKey: string, method: IInterceptorCallbackFunction) => void;
}
// @beta
diff --git a/docs/landing/resources/api/composables.iinterceptorcallbackfunction.md b/docs/landing/resources/api/composables.iinterceptorcallbackfunction.md
new file mode 100644
index 000000000..ee2ce0a56
--- /dev/null
+++ b/docs/landing/resources/api/composables.iinterceptorcallbackfunction.md
@@ -0,0 +1,16 @@
+
+
+[Home](./index.md) > [@shopware-pwa/composables](./composables.md) > [IInterceptorCallbackFunction](./composables.iinterceptorcallbackfunction.md)
+
+## IInterceptorCallbackFunction interface
+
+> 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.
+>
+
+interface for the callback function of interceptors
+
+Signature:
+
+```typescript
+export interface IInterceptorCallbackFunction
+```
diff --git a/docs/landing/resources/api/composables.iuseintercept.disconnect.md b/docs/landing/resources/api/composables.iuseintercept.disconnect.md
index ee2c10654..91a994913 100644
--- a/docs/landing/resources/api/composables.iuseintercept.disconnect.md
+++ b/docs/landing/resources/api/composables.iuseintercept.disconnect.md
@@ -12,5 +12,5 @@ Stop listening on event
Signature:
```typescript
-disconnect: (broadcastKey: string, method: Function) => void;
+disconnect: (broadcastKey: string, method: IInterceptorCallbackFunction) => void;
```
diff --git a/docs/landing/resources/api/composables.iuseintercept.intercept.md b/docs/landing/resources/api/composables.iuseintercept.intercept.md
index 0d873c82b..3ace913ee 100644
--- a/docs/landing/resources/api/composables.iuseintercept.intercept.md
+++ b/docs/landing/resources/api/composables.iuseintercept.intercept.md
@@ -12,5 +12,5 @@ Intercept broadcasted event
Signature:
```typescript
-intercept: (broadcastKey: string, method: Function) => void;
+intercept: (broadcastKey: string, method: IInterceptorCallbackFunction) => void;
```
diff --git a/docs/landing/resources/api/composables.iuseintercept.md b/docs/landing/resources/api/composables.iuseintercept.md
index a1b45d3e9..d5988313d 100644
--- a/docs/landing/resources/api/composables.iuseintercept.md
+++ b/docs/landing/resources/api/composables.iuseintercept.md
@@ -20,6 +20,6 @@ export interface IUseIntercept
| Property | Type | Description |
| --- | --- | --- |
| [broadcast](./composables.iuseintercept.broadcast.md) | (broadcastKey: string, value?: any) => void | (BETA) Broadcast new event |
-| [disconnect](./composables.iuseintercept.disconnect.md) | (broadcastKey: string, method: Function) => void | (BETA) Stop listening on event |
-| [intercept](./composables.iuseintercept.intercept.md) | (broadcastKey: string, method: Function) => void | (BETA) Intercept broadcasted event |
+| [disconnect](./composables.iuseintercept.disconnect.md) | (broadcastKey: string, method: [IInterceptorCallbackFunction](./composables.iinterceptorcallbackfunction.md)) => void | (BETA) Stop listening on event |
+| [intercept](./composables.iuseintercept.intercept.md) | (broadcastKey: string, method: [IInterceptorCallbackFunction](./composables.iinterceptorcallbackfunction.md)) => void | (BETA) Intercept broadcasted event |
diff --git a/docs/landing/resources/api/composables.md b/docs/landing/resources/api/composables.md
index ae0e3fb92..60a61796c 100644
--- a/docs/landing/resources/api/composables.md
+++ b/docs/landing/resources/api/composables.md
@@ -18,6 +18,7 @@
| --- | --- |
| [ApplicationVueContext](./composables.applicationvuecontext.md) | (BETA) Applicatoin Context for Shopware PWA. It's an extended Vue instance. |
| [CurrentPagination](./composables.currentpagination.md) | (BETA) |
+| [IInterceptorCallbackFunction](./composables.iinterceptorcallbackfunction.md) | (BETA) interface for the callback function of interceptors |
| [IUseAddToCart](./composables.iuseaddtocart.md) | (BETA) interface for [useAddToCart](./composables.useaddtocart.md) composable |
| [IUseCart](./composables.iusecart.md) | (BETA) interface for [useCart](./composables.usecart.md) composable |
| [IUseCheckout](./composables.iusecheckout.md) | (BETA) interface for [useCheckout](./composables.usecheckout.md) composable |
diff --git a/packages/composables/__tests__/useIntercept.spec.ts b/packages/composables/__tests__/useIntercept.spec.ts
index 65484c953..37785f363 100644
--- a/packages/composables/__tests__/useIntercept.spec.ts
+++ b/packages/composables/__tests__/useIntercept.spec.ts
@@ -32,7 +32,10 @@ describe("Composables - useIntercept", () => {
const interceptedMethod = jest.fn();
intercept("my-event", interceptedMethod);
broadcast("my-event", { someParam: 123 });
- expect(interceptedMethod).toHaveBeenCalledWith({ someParam: 123 });
+ expect(interceptedMethod).toHaveBeenCalledWith(
+ { someParam: 123 },
+ rootContextMock
+ );
});
it("should not intercept disconnected event interceptor", () => {
@@ -58,8 +61,14 @@ describe("Composables - useIntercept", () => {
intercept("my-event", interceptedMethod);
intercept("my-event", secondInterceptedMethod);
broadcast("my-event", { someParam: 123 });
- expect(interceptedMethod).toHaveBeenCalledWith({ someParam: 123 });
- expect(secondInterceptedMethod).toHaveBeenCalledWith({ someParam: 123 });
+ expect(interceptedMethod).toHaveBeenCalledWith(
+ { someParam: 123 },
+ rootContextMock
+ );
+ expect(secondInterceptedMethod).toHaveBeenCalledWith(
+ { someParam: 123 },
+ rootContextMock
+ );
});
it("should not invoke any interceptor if there are no registered methods", () => {
diff --git a/packages/composables/src/hooks/useUser.ts b/packages/composables/src/hooks/useUser.ts
index 257df99f1..d734a1c6e 100644
--- a/packages/composables/src/hooks/useUser.ts
+++ b/packages/composables/src/hooks/useUser.ts
@@ -32,7 +32,11 @@ import { CustomerRegistrationParams } from "@shopware-pwa/commons/interfaces/req
import { ClientApiError } from "@shopware-pwa/commons/interfaces/errors/ApiError";
import { Country } from "@shopware-pwa/commons/interfaces/models/system/country/Country";
import { Salutation } from "@shopware-pwa/commons/interfaces/models/system/salutation/Salutation";
-import { INTERCEPTOR_KEYS, useIntercept } from "@shopware-pwa/composables";
+import {
+ IInterceptorCallbackFunction,
+ INTERCEPTOR_KEYS,
+ useIntercept,
+} from "@shopware-pwa/composables";
import { ApplicationVueContext, getApplicationContext } from "../appContext";
/**
@@ -162,7 +166,7 @@ export const useUser = (rootContext: ApplicationVueContext): IUseUser => {
await refreshUser();
}
};
- const onLogout = (fn: Function) =>
+ const onLogout = (fn: IInterceptorCallbackFunction) =>
intercept(INTERCEPTOR_KEYS.USER_LOGOUT, fn);
const refreshUser = async (): Promise => {
diff --git a/packages/composables/src/logic/useAddToCart.ts b/packages/composables/src/logic/useAddToCart.ts
index d39c5b126..7ddd8602a 100644
--- a/packages/composables/src/logic/useAddToCart.ts
+++ b/packages/composables/src/logic/useAddToCart.ts
@@ -4,6 +4,7 @@ import {
useCart,
INTERCEPTOR_KEYS,
useIntercept,
+ IInterceptorCallbackFunction,
} from "@shopware-pwa/composables";
import { ClientApiError } from "@shopware-pwa/commons/interfaces/errors/ApiError";
import { ApplicationVueContext, getApplicationContext } from "../appContext";
@@ -103,7 +104,7 @@ export const useAddToCart = (
}
};
- const onAddToCart = (fn: Function) =>
+ const onAddToCart = (fn: IInterceptorCallbackFunction) =>
intercept(INTERCEPTOR_KEYS.ADD_TO_CART, fn);
const getStock = computed(() => product && product.stock);
diff --git a/packages/composables/src/logic/useIntercept.ts b/packages/composables/src/logic/useIntercept.ts
index a0d26b631..533928a1e 100644
--- a/packages/composables/src/logic/useIntercept.ts
+++ b/packages/composables/src/logic/useIntercept.ts
@@ -36,6 +36,14 @@ export const INTERCEPTOR_KEYS = {
USER_LOGOUT: "onUserLogout",
};
+/**
+ * interface for the callback function of interceptors
+ * @beta
+ */
+export interface IInterceptorCallbackFunction {
+ (payload: any, rootContext?: ApplicationVueContext): void;
+}
+
/**
* interface for {@link useIntercept} composable
* @beta
@@ -48,11 +56,17 @@ export interface IUseIntercept {
/**
* Intercept broadcasted event
*/
- intercept: (broadcastKey: string, method: Function) => void;
+ intercept: (
+ broadcastKey: string,
+ method: IInterceptorCallbackFunction
+ ) => void;
/**
* Stop listening on event
*/
- disconnect: (broadcastKey: string, method: Function) => void;
+ disconnect: (
+ broadcastKey: string,
+ method: IInterceptorCallbackFunction
+ ) => void;
}
/**
@@ -65,34 +79,43 @@ export const useIntercept = (
): IUseIntercept => {
const { interceptors } = getApplicationContext(rootContext, "useIntercept");
- const localSunscribers: any[] = [];
+ const localSubscribers: any[] = [];
const isVueInstance: boolean = !!getCurrentInstance();
const broadcast = (broadcastKey: string, value?: any) => {
if (interceptors[broadcastKey]?.length) {
- interceptors[broadcastKey].forEach((broadcastMethod: Function) =>
- broadcastMethod(value)
+ interceptors[
+ broadcastKey
+ ].forEach((broadcastMethod: IInterceptorCallbackFunction) =>
+ broadcastMethod(value, rootContext)
);
}
};
- const intercept = (broadcastKey: string, method: Function) => {
+ const intercept = (
+ broadcastKey: string,
+ method: IInterceptorCallbackFunction
+ ) => {
if (!interceptors[broadcastKey]) interceptors[broadcastKey] = [];
interceptors[broadcastKey].push(method);
- isVueInstance && localSunscribers.push({ broadcastKey, method });
+ isVueInstance && localSubscribers.push({ broadcastKey, method });
};
- const disconnect = (broadcastKey: string, method: Function) => {
+ const disconnect = (
+ broadcastKey: string,
+ method: IInterceptorCallbackFunction
+ ) => {
interceptors[broadcastKey] =
interceptors[broadcastKey]?.filter(
- (subscribedMethod: Function) => subscribedMethod !== method
+ (subscribedMethod: IInterceptorCallbackFunction) =>
+ subscribedMethod !== method
) || [];
};
// Automatically clean listener if it was used in Vue component
isVueInstance &&
onUnmounted(() => {
- localSunscribers.forEach(({ broadcastKey, method }) => {
+ localSubscribers.forEach(({ broadcastKey, method }) => {
disconnect(broadcastKey, method);
});
});
diff --git a/packages/default-theme/src/locales/de-DE.json b/packages/default-theme/src/locales/de-DE.json
index 548742728..4c0adcf8c 100644
--- a/packages/default-theme/src/locales/de-DE.json
+++ b/packages/default-theme/src/locales/de-DE.json
@@ -177,5 +177,6 @@
"Enter promo code": "Rabattcode eingeben",
"Applied promo codes:": "Angewandte Rabattcodes:",
"Promotion code added successfully": "Rabattcode wurde erfolgreich angewendet",
- "Promotion code does not exist": "Rabattcode existiert nicht"
+ "Promotion code does not exist": "Rabattcode existiert nicht",
+ "{productName} has been added to cart.": "{productName} wurde dem Warenkorb hinzugefügt."
}
diff --git a/packages/default-theme/src/locales/en-GB.json b/packages/default-theme/src/locales/en-GB.json
index bd068cc59..142e65807 100644
--- a/packages/default-theme/src/locales/en-GB.json
+++ b/packages/default-theme/src/locales/en-GB.json
@@ -182,5 +182,6 @@
"Tap any heart next to a product to favorite.": "Tap any heart next to a product to favorite.",
"We’ll save them for you here!": "We’ll save them for you here!",
"No favourites yet": "No favourites yet",
- "Wishlist": "Wishlist"
+ "Wishlist": "Wishlist",
+ "{productName} has been added to cart.": "{productName} has been added to cart."
}
diff --git a/packages/default-theme/src/logic/index.js b/packages/default-theme/src/logic/index.js
index e444b7b1d..10401968a 100644
--- a/packages/default-theme/src/logic/index.js
+++ b/packages/default-theme/src/logic/index.js
@@ -1 +1,2 @@
export * from "@theme/logic/useLocales"
+export * from "@/logic/notifications"
diff --git a/packages/default-theme/src/logic/notifications/index.js b/packages/default-theme/src/logic/notifications/index.js
new file mode 100644
index 000000000..aa74acea8
--- /dev/null
+++ b/packages/default-theme/src/logic/notifications/index.js
@@ -0,0 +1,28 @@
+import { useNotifications } from "@shopware-pwa/composables"
+
+export const addToCartNotification = (product, rootContext) => {
+ const { pushSuccess } = useNotifications(rootContext)
+ pushSuccess(
+ rootContext.i18n.t("{productName} has been added to cart.", {
+ productName: product?.translated?.name || product?.name,
+ })
+ )
+}
+
+export const addPromotionCodeNotification = (result, rootContext) => {
+ const { pushSuccess, pushError } = useNotifications(rootContext)
+ // It's strange that success also ends up as an error in the API response
+ const err = Object.values(result.errors)[0]
+ if (err) {
+ switch (err.messageKey) {
+ case "promotion-discount-added":
+ pushSuccess(rootContext.i18n.t("Promotion code added successfully"))
+ break
+ case "promotion-not-found":
+ pushError(rootContext.i18n.t("Promotion code does not exist"))
+ break
+ default:
+ pushError(err.message.toString())
+ }
+ }
+}
diff --git a/packages/default-theme/src/plugins/notifications.js b/packages/default-theme/src/plugins/notifications.js
index a29890580..dbea09e34 100644
--- a/packages/default-theme/src/plugins/notifications.js
+++ b/packages/default-theme/src/plugins/notifications.js
@@ -1,32 +1,11 @@
+import { useIntercept, INTERCEPTOR_KEYS } from "@shopware-pwa/composables"
import {
- useIntercept,
- INTERCEPTOR_KEYS,
- useNotifications,
-} from "@shopware-pwa/composables"
+ addPromotionCodeNotification,
+ addToCartNotification,
+} from "@/logic/notifications"
-export default async ({ app }) => {
+export default ({ app }) => {
const { intercept } = useIntercept(app)
- const { pushSuccess, pushError } = useNotifications(app)
- intercept(INTERCEPTOR_KEYS.ADD_TO_CART, function ({ product }) {
- pushSuccess(
- `${product?.translated?.name || product?.name} has been added to cart.`
- )
- })
-
- intercept(INTERCEPTOR_KEYS.ADD_PROMOTION_CODE, function ({ result }) {
- // It's strange that success also ends up as an error in the API response
- const err = Object.values(result.errors)[0]
- if (err) {
- switch (err.messageKey) {
- case "promotion-discount-added":
- pushSuccess(app.i18n.t("Promotion code added successfully"))
- break
- case "promotion-not-found":
- pushError(app.i18n.t("Promotion code does not exist"))
- break
- default:
- pushError(err.message.toString())
- }
- }
- })
+ intercept(INTERCEPTOR_KEYS.ADD_TO_CART, addToCartNotification)
+ intercept(INTERCEPTOR_KEYS.ADD_PROMOTION_CODE, addPromotionCodeNotification)
}