diff --git a/src/components/Form/ExitFormDialogProvider.tsx b/src/components/Form/ExitFormDialogProvider.tsx index 82381187e..591600e54 100644 --- a/src/components/Form/ExitFormDialogProvider.tsx +++ b/src/components/Form/ExitFormDialogProvider.tsx @@ -14,6 +14,7 @@ export interface ExitFormDialogData { shouldBlockNavigation: () => boolean; setIsSubmitting: (value: boolean) => void; submit: () => SubmitPromise; + leave: () => void; setIsSubmitDisabled: (value: boolean) => void; } @@ -41,6 +42,7 @@ export const ExitFormDialogContext = React.createContext({ shouldBlockNavigation: () => false, setIsSubmitting: () => undefined, submit: () => Promise.resolve([]), + leave: () => undefined, setIsSubmitDisabled: () => undefined }); @@ -69,9 +71,9 @@ export function useExitFormDialogProvider() { const isSubmitting = useRef(defaultValues.isSubmitting); const formsData = useRef({}); const blockNav = useRef(defaultValues.blockNav); - const navAction = useRef(defaultValues.navAction); + const navAction = useRef(defaultValues.navAction); const enableExitDialog = useRef(defaultValues.enableExitDialog); - const currentPath = useRef(window.location.pathname); + const currentLocation = useRef(history.location); const setIsSubmitting = (value: boolean) => { setEnableExitDialog(!value); @@ -91,8 +93,8 @@ export function useExitFormDialogProvider() { formsData.current = defaultValues.formsData; }; - const setCurrentPath = (newPath: string) => { - currentPath.current = newPath; + const setCurrentLocation = (newLocation: typeof history.location) => { + currentLocation.current = newLocation; }; const setFormData = (id: symbol, newData: Partial) => { @@ -156,10 +158,10 @@ export function useExitFormDialogProvider() { return blockNav.current; }; - const isOnlyQuerying = transition => - // wee need to compare to current path and not window location + const isOnlyQuerying = (transition: typeof history.location) => + // We need to compare to current path and not window location // so it works with browser back button as well - transition.pathname === currentPath.current; + transition.pathname === currentLocation.current.pathname; const handleNavigationBlock = () => { const unblock = history.block(transition => { @@ -179,7 +181,7 @@ export function useExitFormDialogProvider() { } setStateDefaultValues(); - setCurrentPath(transition.pathname); + setCurrentLocation(transition); return null; }); @@ -192,10 +194,10 @@ export function useExitFormDialogProvider() { setBlockNav(false); setDefaultFormsData(); - setCurrentPath(navAction.current.pathname); + setCurrentLocation(navAction.current); // because our useNavigator navigate action may be blocked // by exit dialog we want to avoid using it doing this transition - routerHistory.push(navAction.current.pathname); + routerHistory.push(navAction.current.pathname + navAction.current.search); setStateDefaultValues(); }; @@ -250,7 +252,8 @@ export function useExitFormDialogProvider() { setExitDialogSubmitRef: setSubmitRef, setIsSubmitting, submit: handleSubmit, - setIsSubmitDisabled + setIsSubmitDisabled, + leave: handleLeave }; return { diff --git a/src/components/Form/useExitFormDialog.test.tsx b/src/components/Form/useExitFormDialog.test.tsx index ae09e03ed..c634e1ea6 100644 --- a/src/components/Form/useExitFormDialog.test.tsx +++ b/src/components/Form/useExitFormDialog.test.tsx @@ -150,4 +150,27 @@ describe("useExitFormDialog", () => { expect(result.current.exit.shouldBlockNavigation()).toBe(true); expect(result.current.history.location.pathname).toBe(initialPath); }); + + it("navigates to full url with querystring", async () => { + // Given + const submitFn = jest.fn(() => Promise.resolve([])); + const { result } = setup(submitFn); + const qs = "?param=value"; + const targetPathWithQs = targetPath + qs; + + // When + act(() => { + result.current.form.change({ + target: { name: "field", value: "something" } + }); + }); + act(() => { + result.current.history.push(targetPathWithQs); + result.current.exit.leave(); + }); + + // Then + expect(result.current.history.location.pathname).toBe(targetPath); + expect(result.current.history.location.search).toBe(qs); + }); }); diff --git a/src/components/Form/useExitFormDialog.ts b/src/components/Form/useExitFormDialog.ts index 901fe4c69..fc14221ae 100644 --- a/src/components/Form/useExitFormDialog.ts +++ b/src/components/Form/useExitFormDialog.ts @@ -8,14 +8,7 @@ import { } from "./ExitFormDialogProvider"; export interface UseExitFormDialogResult - extends Pick< - ExitFormDialogData, - | "setEnableExitDialog" - | "shouldBlockNavigation" - | "setIsSubmitting" - | "setIsSubmitDisabled" - | "submit" - >, + extends Omit, WithFormId { setIsDirty: (isDirty: boolean) => void; setExitDialogSubmitRef: (submitFn: SubmitFn) => void; diff --git a/src/misc.ts b/src/misc.ts index e206ddd30..30588dc78 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -13,7 +13,6 @@ import { IntlShape } from "react-intl"; import { MultiAutocompleteChoiceType } from "./components/MultiAutocompleteSelectField"; import { AddressType, AddressTypeInput } from "./customers/types"; -import { AddressFragment } from "./graphql"; import { commonStatusMessages, errorMessages, @@ -397,16 +396,6 @@ export function findInEnum(needle: string, haystack: TEnum) { throw new Error(`Key ${needle} not found in enum`); } -export function addressToAddressInput( - address: T & AddressFragment -): AddressInput { - const { id, __typename, ...rest } = address; - return { - ...rest, - country: findInEnum(address.country.code, CountryCode) - }; -} - export function findValueInEnum( needle: string, haystack: TEnum diff --git a/src/orders/utils/data.ts b/src/orders/utils/data.ts index e3685381b..210246761 100644 --- a/src/orders/utils/data.ts +++ b/src/orders/utils/data.ts @@ -1,5 +1,6 @@ import { IMoney, subtractMoney } from "@saleor/components/Money"; import { + AddressFragment, AddressInput, CountryCode, FulfillmentStatus, @@ -12,7 +13,7 @@ import { WarehouseFragment } from "@saleor/graphql"; import { FormsetData } from "@saleor/hooks/useFormset"; -import { addressToAddressInput } from "@saleor/misc"; +import { findInEnum } from "@saleor/misc"; import { LineItemData, @@ -300,6 +301,16 @@ export const isStockError = ( return isQuantityLargerThanAvailable || isError; }; +export function addressToAddressInput( + address: T & AddressFragment +): AddressInput { + const { id, __typename, ...rest } = address; + return { + ...rest, + country: findInEnum(address.country.code, CountryCode) + }; +} + export const getVariantSearchAddress = ( order: OrderDetailsFragment ): AddressInput => {