Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into feat/VCST-2069
Browse files Browse the repository at this point in the history
  • Loading branch information
NaMax66 committed Dec 24, 2024
2 parents 206c6a4 + 46afe22 commit 35ffb85
Show file tree
Hide file tree
Showing 20 changed files with 276 additions and 77 deletions.
1 change: 1 addition & 0 deletions client-app/broadcast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export function setupBroadcastGlobalListeners() {
on(dataChangedEvent, () => {
notifications.warning({
text: t("common.messages.data_changed"),
single: true,
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ fragment fullLineItem on LineItemType {
imageUrl
selectedForCheckout
productType
showPlacedPrice
listTotal {
...money
}
product {
...fullLineItemProduct
}
Expand Down
1 change: 1 addition & 0 deletions client-app/core/api/graphql/cart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from "./mutations/addOrUpdateCartPayment";
export * from "./mutations/addOrUpdateCartShipment";
export * from "./mutations/changeCartComment";
export * from "./mutations/changeCartConfiguredItem";
export * from "./mutations/changeCartCurrency";
export * from "./mutations/changeCartItemQuantity";
export * from "./mutations/changeFullCartItemQuantity";
export * from "./mutations/changeFullCartItemsQuantity";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#import "../../fragments/fullCart.graphql"

mutation ChangeCartCurrency($command: InputChangeCartCurrencyType!) {
changeCartCurrency(command: $command) {
...fullCart
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useMutation } from "@/core/api/graphql/composables";
import { ChangeCartCurrencyDocument } from "@/core/api/graphql/types";
import { globals } from "@/core/globals";

export function useChangeCartCurrencyMutation() {
const { storeId, currencyCode, cultureName } = globals;
return useMutation(ChangeCartCurrencyDocument, {
variables: {
command: {
storeId,
cultureName,
currencyCode,
},
},
});
}
13 changes: 13 additions & 0 deletions client-app/core/api/graphql/cart/mutations/clearCart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useApolloClient } from "@vue/apollo-composable";
import { useCartMutationVariables } from "@/core/api/graphql/cart/composables";
import { useMutation } from "@/core/api/graphql/composables";
import { ClearCartDocument } from "@/core/api/graphql/types";
import { globals } from "@/core/globals";
import type { CartIdFragment, CartType } from "@/core/api/graphql/types";
import type { MaybeRef } from "vue";

Expand All @@ -12,6 +13,18 @@ export function useClearCartMutation(cart?: MaybeRef<CartIdFragment | undefined>
return result;
}

export function useClearCurrencyCartMutation() {
const { storeId, cultureName } = globals;
return useMutation(ClearCartDocument, {
variables: {
command: {
storeId,
cultureName,
},
},
});
}

/** @deprecated Use {@link useClearCartMutation} instead. */
export async function clearCart(cartId: string): Promise<CartType> {
const { mutate } = useClearCartMutation({ id: cartId });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ fragment orderLineItemFields on OrderLineItemType {
name
productId
productType
showPlacedPrice
listTotal {
...money
}
product {
id
brandName
Expand Down
138 changes: 88 additions & 50 deletions client-app/core/api/graphql/types.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions client-app/core/types/line-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export type AnyLineItemType = {
id: string;
name?: string;
}[];
showPlacedPrice?: boolean;
listTotal?: MoneyType;
};

export type VendorGroupType<T> = {
Expand Down Expand Up @@ -74,4 +76,6 @@ export type PreparedLineItemType = {
id: string;
name?: string;
}[];
showPlacedPrice?: boolean;
listTotal?: MoneyType;
};
12 changes: 12 additions & 0 deletions client-app/core/utilities/common/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ describe("getReturnUrlValue", () => {
const result = getReturnUrlValue();
expect(result).toBeNull();
});

it("should return null when returnUrl points to a different hostname", () => {
Object.defineProperty(window, "location", {
configurable: true,
value: {
href: "http://example.com?returnUrl=http://malicious.com/home",
},
});

const result = getReturnUrlValue();
expect(result).toBeNull();
});
});

describe("extractHostname", () => {
Expand Down
12 changes: 10 additions & 2 deletions client-app/core/utilities/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,16 @@ export function getBaseUrl(supportedLocales: string[]): string {
}

export function getReturnUrlValue(): string | null {
const { searchParams } = new URL(location.href);
return searchParams.get("returnUrl") || searchParams.get("ReturnUrl");
const { searchParams, origin, hostname } = new URL(location.href);
const returnUrl = searchParams.get("returnUrl") || searchParams.get("ReturnUrl");

if (returnUrl) {
const returnUrlObj = new URL(returnUrl, origin);
if (returnUrlObj.hostname === hostname) {
return returnUrl;
}
}
return null;
}

export function extractHostname(url: string) {
Expand Down
6 changes: 5 additions & 1 deletion client-app/core/utilities/line-items/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,19 @@ function prepareItemPrices(item: AnyLineItemType) {
const salePrice = "salePrice" in item ? item.salePrice : undefined;
const placedPrice = "placedPrice" in item ? item.placedPrice : undefined;
const extendedPrice = "extendedPrice" in item ? item.extendedPrice : undefined;
const listTotal = "listTotal" in item ? item.listTotal : undefined;
return {
listPrice,
salePrice,
placedPrice,
extendedPrice,
actualPrice: placedPrice ?? salePrice ?? listPrice,
listTotal,
};
}

export function prepareLineItem(item: AnyLineItemType, countInCart?: number): PreparedLineItemType {
const { listPrice, extendedPrice, actualPrice } = prepareItemPrices(item);
const { listPrice, extendedPrice, actualPrice, listTotal } = prepareItemPrices(item);

const productType = "productType" in item ? item.productType : undefined;
const isVariation = !!item.product?.masterVariation;
Expand All @@ -70,6 +72,7 @@ export function prepareLineItem(item: AnyLineItemType, countInCart?: number): Pr
listPrice,
actualPrice,
extendedPrice,
listTotal,
quantity,
inStockQuantity,
route,
Expand All @@ -83,6 +86,7 @@ export function prepareLineItem(item: AnyLineItemType, countInCart?: number): Pr
hasVariations: item.product?.hasVariations,
variations: item.product?.variations,
configurationItems: "configurationItems" in item ? item.configurationItems : undefined,
showPlacedPrice: item.showPlacedPrice,
};
}

Expand Down
19 changes: 16 additions & 3 deletions client-app/pages/account/profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,11 @@ import { useForm } from "vee-validate";
import { computed } from "vue";
import { useI18n } from "vue-i18n";
import * as yup from "yup";
import { useChangeCartCurrencyMutation } from "@/core/api/graphql";
import { useCurrency, usePageHead, useThemeContext } from "@/core/composables";
import { useLanguages } from "@/core/composables/useLanguages";
import { ProfileUpdateSuccessModal, useUser } from "@/shared/account";
import { dataChangedEvent, useBroadcast } from "@/shared/broadcast";
import { useModal } from "@/shared/modal";
const MAX_NAME_LENGTH = 64;
Expand All @@ -99,6 +101,8 @@ const { themeContext } = useThemeContext();
const { openModal } = useModal();
const { removeLocaleFromUrl, unpinLocale } = useLanguages();
const { supportedCurrencies, saveCurrencyCode } = useCurrency();
const { mutate: changeCartCurrency } = useChangeCartCurrencyMutation();
const broadcast = useBroadcast();
usePageHead({
title: computed(() => t("pages.account.profile.meta.title")),
Expand Down Expand Up @@ -137,8 +141,15 @@ function applyLanguage(): void {
removeLocaleFromUrl();
}
function applyCurrency(): void {
async function applyCurrency(): Promise<void> {
if (user.value?.contact?.currencyCode) {
await changeCartCurrency({
command: {
userId: user.value.id,
newCurrencyCode: user.value.contact.currencyCode,
},
});
const contactCurrency = supportedCurrencies.value.find((item) => item.code === user.value!.contact!.currencyCode);
if (contactCurrency) {
Expand All @@ -154,9 +165,11 @@ const onSubmit = handleSubmit(async (data) => {
openModal({
component: ProfileUpdateSuccessModal,
props: {
onClose() {
async onClose() {
applyLanguage();
applyCurrency();
await applyCurrency();
void broadcast.emit(dataChangedEvent);
location.reload();
},
Expand Down
39 changes: 30 additions & 9 deletions client-app/shared/account/composables/useSignMeIn.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { syncRefs, useAsyncState } from "@vueuse/core";
import { ref } from "vue";
import { useGetMeQuery, useMergeCartMutation } from "@/core/api/graphql";
import {
useChangeCartCurrencyMutation,
useClearCurrencyCartMutation,
useGetMeQuery,
useMergeCartMutation,
} from "@/core/api/graphql";
import { useAuth } from "@/core/composables/useAuth";
import { useCurrency } from "@/core/composables/useCurrency";
import { useLanguages } from "@/core/composables/useLanguages";
import { USER_ID_LOCAL_STORAGE } from "@/core/constants";
import { globals } from "@/core/globals";
import { TabsType, openReturnUrl, useBroadcast } from "@/shared/broadcast";
import { useShortCart } from "@/shared/cart/composables";
import type { IdentityErrorType } from "@/core/api/graphql/types";
Expand All @@ -17,6 +23,9 @@ export function useSignMeIn() {
const { mutate: mergeCart } = useMergeCartMutation();
const { unpinLocale, removeLocaleFromUrl } = useLanguages();
const { supportedCurrencies, saveCurrencyCode } = useCurrency();
const { mutate: changeCartCurrency } = useChangeCartCurrencyMutation();
const { currencyCode: currentCurencyCode } = globals;
const { mutate: clearCurrencyCart } = useClearCurrencyCartMutation();

const { isLoading: loading, execute: signIn } = useAsyncState(
async () => {
Expand All @@ -28,19 +37,31 @@ export function useSignMeIn() {
// get user that will be applied after reload.
await getMe();

if (me.value?.me) {
const currencyCode = me.value?.me?.contact?.currencyCode;

if (me.value?.me && currencyCode) {
if (cart.value?.id) {
await mergeCart({ command: { userId: me.value.me.id, secondCartId: cart.value.id } });
}
await clearCurrencyCart({
command: { userId: me.value.me.id, currencyCode: currentCurencyCode },
skipQuery: false,
});

const currencyCode = me.value.me.contact?.currencyCode;
await mergeCart({ command: { userId: me.value.me.id, secondCartId: cart.value.id } });

if (currencyCode) {
const contactCurrency = supportedCurrencies.value.find((item) => item.code === currencyCode);
if (contactCurrency) {
saveCurrencyCode(contactCurrency.code, false);
if (currencyCode !== currentCurencyCode) {
await changeCartCurrency({
command: {
userId: me.value.me.id,
newCurrencyCode: currencyCode,
},
});
}
}

const contactCurrency = supportedCurrencies.value.find((item) => item.code === currencyCode);
if (contactCurrency) {
saveCurrencyCode(contactCurrency.code, false);
}
}

void broadcast.emit(openReturnUrl, undefined, TabsType.ALL);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<VcDropdownMenu placement="bottom-end" width="7.5rem" class="h-full">
<VcDropdownMenu placement="bottom-end" width="8rem" class="h-full">
<template #trigger="{ opened }">
<button type="button" class="flex h-full items-center gap-x-1.5">
<span class="text-sm">
Expand All @@ -20,16 +20,15 @@
:key="item.code"
:active="item.code === currentCurrency.code"
color="secondary"
truncate
@click="
select(item.code);
close();
"
>
<span
class="flex size-5 shrink-0 items-center justify-center rounded-full bg-secondary-600 text-base font-bold text-additional-50"
>
{{ item.symbol }}
</span>
<template #prepend>
<VcBadge rounded color="secondary" size="lg">{{ item.symbol }}</VcBadge>
</template>

<span>{{ item.code }}</span>
</VcMenuItem>
Expand All @@ -38,12 +37,34 @@
</template>

<script setup lang="ts">
import { useChangeCartCurrencyMutation } from "@/core/api/graphql";
import { useCurrency } from "@/core/composables";
import { globals } from "@/core/globals";
import { dataChangedEvent, useBroadcast } from "@/shared/broadcast";
import { useFullCart } from "@/shared/cart";
const { currentCurrency, supportedCurrencies, saveCurrencyCode } = useCurrency();
const { cart } = useFullCart();
const { mutate: changeCartCurrency } = useChangeCartCurrencyMutation();
const broadcast = useBroadcast();
const { userId } = globals;
function select(code: string) {
async function select(code: string): Promise<void> {
if (currentCurrency.value?.code !== code) {
if (cart.value) {
await changeCartCurrency({
command: {
userId,
cartId: cart.value.id,
cartName: cart.value.name,
cartType: cart.value.type,
newCurrencyCode: code,
},
});
}
void broadcast.emit(dataChangedEvent);
saveCurrencyCode(code);
}
}
Expand Down
Loading

0 comments on commit 35ffb85

Please sign in to comment.