Minor improvements (#1924)
* Add basic tests * Test if qs is preserved * Preserve querystring * Improve import performance
This commit is contained in:
parent
fbf57bbbb1
commit
3e180c8d17
5 changed files with 50 additions and 31 deletions
|
@ -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<ExitFormDialogData>({
|
|||
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<FormsData>({});
|
||||
const blockNav = useRef(defaultValues.blockNav);
|
||||
const navAction = useRef(defaultValues.navAction);
|
||||
const navAction = useRef<typeof history.location>(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<FormData>) => {
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,14 +8,7 @@ import {
|
|||
} from "./ExitFormDialogProvider";
|
||||
|
||||
export interface UseExitFormDialogResult
|
||||
extends Pick<
|
||||
ExitFormDialogData,
|
||||
| "setEnableExitDialog"
|
||||
| "shouldBlockNavigation"
|
||||
| "setIsSubmitting"
|
||||
| "setIsSubmitDisabled"
|
||||
| "submit"
|
||||
>,
|
||||
extends Omit<ExitFormDialogData, "setIsDirty" | "setExitDialogSubmitRef">,
|
||||
WithFormId {
|
||||
setIsDirty: (isDirty: boolean) => void;
|
||||
setExitDialogSubmitRef: (submitFn: SubmitFn) => void;
|
||||
|
|
11
src/misc.ts
11
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<TEnum extends {}>(needle: string, haystack: TEnum) {
|
|||
throw new Error(`Key ${needle} not found in enum`);
|
||||
}
|
||||
|
||||
export function addressToAddressInput<T>(
|
||||
address: T & AddressFragment
|
||||
): AddressInput {
|
||||
const { id, __typename, ...rest } = address;
|
||||
return {
|
||||
...rest,
|
||||
country: findInEnum(address.country.code, CountryCode)
|
||||
};
|
||||
}
|
||||
|
||||
export function findValueInEnum<TEnum extends {}>(
|
||||
needle: string,
|
||||
haystack: TEnum
|
||||
|
|
|
@ -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<T>(
|
||||
address: T & AddressFragment
|
||||
): AddressInput {
|
||||
const { id, __typename, ...rest } = address;
|
||||
return {
|
||||
...rest,
|
||||
country: findInEnum(address.country.code, CountryCode)
|
||||
};
|
||||
}
|
||||
|
||||
export const getVariantSearchAddress = (
|
||||
order: OrderDetailsFragment
|
||||
): AddressInput => {
|
||||
|
|
Loading…
Reference in a new issue