Skip to content

Commit

Permalink
Prevent router prompt when using a block with subroutes in a form (#3281
Browse files Browse the repository at this point in the history
)
  • Loading branch information
johnnyomair authored Jan 28, 2025
1 parent e65a401 commit bd562d3
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 7 deletions.
7 changes: 7 additions & 0 deletions .changeset/cool-masks-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@comet/admin": minor
---

Add `disableForcePromptRoute` option to `StackSwitch`

This can be useful when a navigation in a switch shouldn't trigger a prompt, e.g., when navigating inside a block.
5 changes: 5 additions & 0 deletions .changeset/sour-dodos-count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@comet/blocks-admin": patch
---

Prevent router prompt when using a block with subroutes in a form
8 changes: 5 additions & 3 deletions packages/admin/admin/src/stack/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
useRef,
useState,
} from "react";
import { matchPath, RouteComponentProps, useHistory, useLocation, useRouteMatch } from "react-router";
import { matchPath, Route, RouteComponentProps, useHistory, useLocation, useRouteMatch } from "react-router";
import { v4 as uuid } from "uuid";

import { ForcePromptRoute } from "../router/ForcePromptRoute";
Expand All @@ -26,6 +26,7 @@ interface IProps {
initialPage?: string;
title?: ReactNode;
children: Array<ReactElement<IStackPageProps>>;
disableForcePromptRoute?: boolean;
}

export const StackSwitchApiContext = createContext<IStackSwitchApi>({
Expand Down Expand Up @@ -196,13 +197,14 @@ const StackSwitchInner: RefForwardingComponent<IStackSwitchApi, IProps & IHookPr
if (matchPath(location.pathname, { path })) {
routeMatched = true;
}
const RouteComponent = props.disableForcePromptRoute ? Route : ForcePromptRoute;
return (
<ForcePromptRoute path={path}>
<RouteComponent path={path}>
{(routeProps: RouteComponentProps<IRouteParams>) => {
if (!routeProps.match) return null;
return renderRoute(page, routeProps);
}}
</ForcePromptRoute>
</RouteComponent>
);
})}
{!routeMatched && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ export function createBlocksBlock<AdditionalItemFields extends Record<string, un

return (
<>
<StackSwitch>
<StackSwitch disableForcePromptRoute>
<StackPage name="main">
<StackSwitchApiContext.Consumer>
{(stackApi) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export function createColumnsBlock<T extends BlockInterface>({

return (
<>
<StackSwitch initialPage="list">
<StackSwitch initialPage="list" disableForcePromptRoute>
<StackPage name="list">
<BlocksFinalForm<{ layout: ColumnsBlockLayout; columns: number }>
onSubmit={({ layout, columns }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ export const createCompositeBlock = <Options extends CreateCompositeBlockOptions
};

return (
<StackSwitch>
<StackSwitch disableForcePromptRoute>
{[
<StackPage name="initial" key="initial">
{Object.entries(groups).map(([groupKey, group]) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export function createListBlock<T extends BlockInterface, AdditionalItemFields e

return (
<SelectPreviewComponent>
<StackSwitch>
<StackSwitch disableForcePromptRoute>
<StackPage name="table">
<StackSwitchApiContext.Consumer>
{(stackApi) => {
Expand Down
39 changes: 39 additions & 0 deletions storybook/src/blocks-admin/BlockInFinalForm.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Field, FinalForm, SaveBoundary } from "@comet/admin";
import { AdminComponentRoot, createFinalFormBlock, createListBlock } from "@comet/blocks-admin";
import { ExternalLinkBlock } from "@comet/cms-admin";

import { dndProviderDecorator } from "../dnd.decorator";
import { snackbarDecorator } from "../docs/components/Snackbar/snackbar.decorator";
import { storyRouterDecorator } from "../story-router.decorator";

export default {
decorators: [snackbarDecorator(), storyRouterDecorator(), dndProviderDecorator()],
};

export const BlockInFinalFormWithSaveBoundary = () => {
const LinkListBlock = createListBlock({ name: "LinkList", block: ExternalLinkBlock });
const FinalFormLinkListBlock = createFinalFormBlock(LinkListBlock);

return (
<SaveBoundary>
<FinalForm mode="edit" onSubmit={() => {}} initialValues={{ links: LinkListBlock.defaultValues() }}>
<AdminComponentRoot>
<Field name="links" component={FinalFormLinkListBlock} fullWidth />
</AdminComponentRoot>
</FinalForm>
</SaveBoundary>
);
};

export const BlockInFinalFormWithoutSaveBoundary = () => {
const LinkListBlock = createListBlock({ name: "LinkList", block: ExternalLinkBlock });
const FinalFormLinkListBlock = createFinalFormBlock(LinkListBlock);

return (
<FinalForm mode="edit" onSubmit={() => {}} initialValues={{ links: LinkListBlock.defaultValues() }}>
<AdminComponentRoot>
<Field name="links" component={FinalFormLinkListBlock} fullWidth />
</AdminComponentRoot>
</FinalForm>
);
};

0 comments on commit bd562d3

Please sign in to comment.