Skip to content

Commit

Permalink
fix: simplify sync between tabs for shopping lists (#1489)
Browse files Browse the repository at this point in the history
## Description

Simplify sync between tabs for shopping lists

## References
### Jira-link:

https://virtocommerce.atlassian.net/browse/VCST-2394

### Artifact URL:

https://vc3prerelease.blob.core.windows.net/packages/vc-theme-b2b-vue-2.12.0-pr-1489-4643-464348e5.zip
  • Loading branch information
Andrew-Orlov authored Dec 17, 2024
1 parent a809af6 commit 39c76d1
Show file tree
Hide file tree
Showing 12 changed files with 29 additions and 80 deletions.
10 changes: 9 additions & 1 deletion client-app/broadcast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
passwordExpiredEvent,
reloadAndOpenMainPage,
graphqlErrorEvent,
dataChangedEvent,
} from "@/shared/broadcast";
import { useNotifications } from "@/shared/notification";

Expand All @@ -32,6 +33,8 @@ export function setupBroadcastGlobalListeners() {

installed = true;

const { t } = globals.i18n.global;

const { client } = useApolloClient();
const router = useRouter();
const { on } = useBroadcast();
Expand Down Expand Up @@ -83,7 +86,6 @@ export function setupBroadcastGlobalListeners() {
throw error;
});
on(unhandledErrorEvent, () => {
const { t } = globals.i18n.global;
notifications.error({
duration: DEFAULT_NOTIFICATION_DURATION,
group: "UnhandledError",
Expand All @@ -105,4 +107,10 @@ export function setupBroadcastGlobalListeners() {
location.href = `/change-password?returnUrl=${pathname + search + hash}`;
}
});

on(dataChangedEvent, () => {
notifications.warning({
text: t("common.messages.data_changed"),
});
});
}
4 changes: 2 additions & 2 deletions client-app/pages/account/list-details.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ import { useGoogleAnalytics, useHistoricalEvents, usePageHead } from "@/core/com
import { PAGE_LIMIT } from "@/core/constants";
import { globals } from "@/core/globals";
import { prepareLineItem } from "@/core/utilities";
import { productsInWishlistEvent, useBroadcast } from "@/shared/broadcast";
import { dataChangedEvent, useBroadcast } from "@/shared/broadcast";
import { useShortCart, getItemsForAddBulkItemsToCartResultsModal } from "@/shared/cart";
import { ProductSkeletonGrid } from "@/shared/catalog";
import { BackButtonInHeader } from "@/shared/layout";
Expand Down Expand Up @@ -313,7 +313,7 @@ function openDeleteProductModal(values: string[]): void {
async onResult(): Promise<void> {
const previousPagesCount = pagesCount.value;
void broadcast.emit(productsInWishlistEvent, [{ productId: item.productId, inWishlist: false }]);
void broadcast.emit(dataChangedEvent);
wishlistItems.value = wishlistItems.value?.filter((listItem) => listItem.id !== item.id);
Expand Down
1 change: 0 additions & 1 deletion client-app/shared/broadcast/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from "./composables";
export * from "./types";
export * from "./utils";
1 change: 0 additions & 1 deletion client-app/shared/broadcast/types/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion client-app/shared/broadcast/utils/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
* broadcast.emit(testEvent, 123); // Error
*/

export const dataChangedEvent = "data_changed" as string;
export const pageReloadEvent = "page_reload" as string;
export const userReloadEvent = "user_reload" as string;
export const userBeforeUnauthorizeEvent = "user_before_unauthorize" as string;
export const userLockedEvent = "user_locked" as string;
export const cartReloadEvent = "cart_reload" as string;
export const productsInWishlistEvent = "products_in_wishlist" as string;
export const unauthorizedErrorEvent = "unauthorized_error" as string;
export const unhandledErrorEvent = "unhandled_error" as string;
export const openReturnUrl = "open_return_url" as string;
Expand Down
12 changes: 0 additions & 12 deletions client-app/shared/catalog/composables/useProduct.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { ref, computed, readonly } from "vue";
import { getProduct } from "@/core/api/graphql/catalog";
import { Logger } from "@/core/utilities";
import { productsInWishlistEvent, useBroadcast } from "@/shared/broadcast";
import type { GetProductQuery } from "@/core/api/graphql/types";
import type { ProductInWishlistEventDataType } from "@/shared/broadcast";
import type { Ref } from "vue";

export function useProduct() {
const fetching: Ref<boolean> = ref(true);
const product: Ref<GetProductQuery["product"] | undefined> = ref();

const broadcast = useBroadcast();

async function fetchProduct(id: string) {
fetching.value = true;
try {
Expand All @@ -24,14 +20,6 @@ export function useProduct() {
}
}

broadcast.on(productsInWishlistEvent, (eventItems: ProductInWishlistEventDataType[]) => {
eventItems.forEach(({ productId, inWishlist }) => {
if (product.value && product.value.id === productId) {
product.value = { ...product.value, inWishlist };
}
});
});

return {
fetchProduct,
fetching: readonly(fetching),
Expand Down
13 changes: 0 additions & 13 deletions client-app/shared/catalog/composables/useProducts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ import {
rangeFacetToCommonFacet,
termFacetToCommonFacet,
} from "@/core/utilities";
import { productsInWishlistEvent, useBroadcast } from "@/shared/broadcast";
import { useModal } from "@/shared/modal";
import type { FiltersDisplayOrderType, ProductsFiltersType, ProductsSearchParamsType } from "../types";
import type { Product, RangeFacet, TermFacet } from "@/core/api/graphql/types";
import type { FacetItemType, FacetValueItemType } from "@/core/types";
import type { ProductInWishlistEventDataType } from "@/shared/broadcast";
import type { Ref } from "vue";
import BranchesModal from "@/shared/fulfillmentCenters/components/branches-modal.vue";

Expand All @@ -41,7 +39,6 @@ export function useProducts(
withImages = config.image_carousel_in_product_card_enabled,
withZeroPrice = config.zero_price_product_enabled,
} = options;
const broadcast = useBroadcast();
const { openModal } = useModal();

const localStorageInStock = useLocalStorage<boolean>(IN_STOCK_PRODUCTS_LOCAL_STORAGE, true);
Expand Down Expand Up @@ -313,16 +310,6 @@ export function useProducts(
}
}

broadcast.on(productsInWishlistEvent, (eventItems: ProductInWishlistEventDataType[]) => {
eventItems.forEach(({ productId, inWishlist }) => {
const { index, product } = productsById.value[productId] ?? {};

if (product) {
products.value.splice(index, 1, { ...product, inWishlist });
}
});
});

const currentPage = ref(1);

function updateCurrentPage(page: number) {
Expand Down
33 changes: 1 addition & 32 deletions client-app/shared/catalog/composables/useRelatedProducts.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
import { ref, computed, readonly, shallowRef, triggerRef } from "vue";
import { ref, computed, readonly, shallowRef } from "vue";
import { searchRelatedProducts } from "@/core/api/graphql/catalog";
import { Logger } from "@/core/utilities";
import { productsInWishlistEvent, useBroadcast } from "@/shared/broadcast";
import type { RelatedProductsSearchParamsType } from "@/core/api/graphql/catalog";
import type { Product } from "@/core/api/graphql/types";
import type { ProductInWishlistEventDataType } from "@/shared/broadcast";

export function useRelatedProducts() {
const broadcast = useBroadcast();

const loading = ref(true);
const relatedProducts = shallowRef<Product[]>([]);

const productsById = computed(() =>
relatedProducts.value.reduce(
(result, product, index) => {
result[product.id] = { index, product };
return result;
},
{} as Record<string, { index: number; product: Product }>,
),
);

async function fetchRelatedProducts(params: RelatedProductsSearchParamsType) {
loading.value = true;
try {
Expand All @@ -35,23 +21,6 @@ export function useRelatedProducts() {
}
}

broadcast.on(productsInWishlistEvent, (eventItems: ProductInWishlistEventDataType[]) => {
let trigger = false;

eventItems.forEach(({ productId, inWishlist }) => {
const { index, product } = productsById.value[productId] ?? {};

if (product) {
relatedProducts.value.splice(index, 1, { ...product, inWishlist });
trigger = true;
}
});

if (trigger) {
triggerRef(relatedProducts);
}
});

return {
fetchRelatedProducts,
loading: readonly(loading),
Expand Down
24 changes: 10 additions & 14 deletions client-app/shared/wishlists/components/add-to-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
<VcProductActionsButton
color="danger"
:icon-size="iconSize"
:active="product.inWishlist"
:active="inWishList"
:disabled="!isAuthenticated"
:tooltip-text="tooltipText"
@click="openAddToListModal"
/>
</template>

<script setup lang="ts">
import { computed } from "vue";
import { computed, toRef } from "vue";
import { useI18n } from "vue-i18n";
import { useUser } from "@/shared/account/composables";
import { productsInWishlistEvent, TabsType, useBroadcast } from "@/shared/broadcast";
import { dataChangedEvent, TabsType, useBroadcast } from "@/shared/broadcast";
import { useModal } from "@/shared/modal";
import AddToWishlistsModal from "./add-to-wishlists-modal.vue";
import type { Product } from "@/core/api/graphql/types";
Expand All @@ -30,6 +30,9 @@ const { openModal } = useModal();
const { isAuthenticated } = useUser();
const broadcast = useBroadcast();
const product = toRef(props, "product");
const inWishList = computed(() => product.value.inWishlist);
const tooltipText = computed<string>(() => {
if (!isAuthenticated.value) {
return t("common.messages.wishlists_available_for_authorized");
Expand All @@ -49,17 +52,10 @@ function openAddToListModal() {
component: AddToWishlistsModal,
props: {
product: props.product,
onResult: (isInLists: boolean) => {
void broadcast.emit(
productsInWishlistEvent,
[
{
productId: props.product.id,
inWishlist: isInLists,
},
],
TabsType.ALL,
);
onResult: (inWishLists: boolean) => {
product.value.inWishlist = inWishLists;
void broadcast.emit(dataChangedEvent, TabsType.ALL);
},
},
});
Expand Down
3 changes: 2 additions & 1 deletion locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@
"password_new_same_old": "Ihr aktuelles Passwort und das neue Passwort müssen unterschiedlich sein.",
"blocked": "Sie wurden blockiert. Sie können keine Informationen abrufen oder Bestellungen aufgeben. Für weitere Details ",
"password_about_expire": "Ihr Passwort läuft in {value} Tag(en) ab. Bitte setzen Sie ein neues Passwort im Profil.",
"password_expired": "Ihr Passwort ist abgelaufen"
"password_expired": "Ihr Passwort ist abgelaufen",
"data_changed": "Die Daten wurden in einem der anderen Tabs geändert. Bitte aktualisieren Sie die Seite, um die aktuellen Daten anzuzeigen."
},
"placeholders": {
"enter_value": "Bitte geben Sie einen Wert ein",
Expand Down
3 changes: 2 additions & 1 deletion locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@
"password_new_same_old": "Your current password and new password must be different.",
"blocked": "You have been blocked. You can not reach any information or create the order. For more details please ",
"password_about_expire": "Your password is about to expire in {value} day(s). Please set a new password in profile.",
"password_expired": "Your password is expired"
"password_expired": "Your password is expired",
"data_changed": "The data has been modified on one of the other tabs. Please refresh the page to display the current data."
},
"placeholders": {
"enter_value": "Please enter a value",
Expand Down
3 changes: 2 additions & 1 deletion locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@
"password_new_same_old": "Votre mot de passe actuel et votre nouveau mot de passe doivent être différents.",
"blocked": "Vous avez été bloqué. Vous ne pouvez pas accéder à des informations ou créer la commande. Pour plus de détails, veuillez ",
"password_about_expire": "Votre mot de passe expirera dans {value} jour(s). Veuillez définir un nouveau mot de passe dans votre profil.",
"password_expired": "Votre mot de passe a expiré"
"password_expired": "Votre mot de passe a expiré",
"data_changed": "Les données ont été modifiées dans l'un des autres onglets. Veuillez actualiser la page pour afficher les données actuelles."
},
"placeholders": {
"enter_value": "Veuillez entrer une valeur",
Expand Down

0 comments on commit 39c76d1

Please sign in to comment.