Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Site Editor: Prepare route registration by refactoring the site editor router #66030

Merged
merged 6 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/edit-site/src/components/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import { unlock } from '../../lock-unlock';
import { useCommonCommands } from '../../hooks/commands/use-common-commands';
import { useEditModeCommands } from '../../hooks/commands/use-edit-mode-commands';
import useInitEditedEntityFromURL from '../sync-state-with-url/use-init-edited-entity-from-url';
import useLayoutAreas from '../layout/router';
import useActiveRoute from '../layout/router';
import useSetCommandContext from '../../hooks/commands/use-set-command-context';
import { useRegisterSiteEditorRoutes } from '../site-editor-routes';

const { RouterProvider } = unlock( routerPrivateApis );
const { GlobalStylesProvider } = unlock( editorPrivateApis );
Expand All @@ -32,7 +33,8 @@ function AppLayout() {
useEditModeCommands();
useCommonCommands();
useSetCommandContext();
const route = useLayoutAreas();
useRegisterSiteEditorRoutes();
const route = useActiveRoute();

return <Layout route={ route } />;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/edit-site/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ export default function Layout( { route } ) {
const isEditorLoading = useIsSiteEditorLoading();
const [ isResizableFrameOversized, setIsResizableFrameOversized ] =
useState( false );
const { key: routeKey, areas, widths } = route;
const { name: routeKey, areas, widths } = route;
const animationRef = useMovingAnimation( {
triggerAnimationOnChange: canvasMode + '__' + routeKey,
triggerAnimationOnChange: canvasMode,
} );

const [ backgroundColor ] = useGlobalStyle( 'color.background' );
Expand Down
151 changes: 18 additions & 133 deletions packages/edit-site/src/components/layout/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,19 @@
* WordPress dependencies
*/
import { privateApis as routerPrivateApis } from '@wordpress/router';
import { __ } from '@wordpress/i18n';
import { useEffect } from '@wordpress/element';
import { useEffect, useMemo } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';
import Editor from '../editor';
import PostList from '../post-list';
import PagePatterns from '../page-patterns';
import PageTemplates from '../page-templates';
import SidebarNavigationScreen from '../sidebar-navigation-screen';
import SidebarNavigationScreenGlobalStyles from '../sidebar-navigation-screen-global-styles';
import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main';
import SidebarNavigationScreenNavigationMenus from '../sidebar-navigation-screen-navigation-menus';
import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse';
import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns';
import SidebarNavigationScreenNavigationMenu from '../sidebar-navigation-screen-navigation-menu';
import DataViewsSidebarContent from '../sidebar-dataviews';
import {
NAVIGATION_POST_TYPE,
PATTERN_TYPES,
TEMPLATE_PART_POST_TYPE,
TEMPLATE_POST_TYPE,
} from '../../utils/constants';
import { PostEdit } from '../post-edit';
import { store as editSiteStore } from '../../store';

const { useLocation, useHistory } = unlock( routerPrivateApis );

Expand Down Expand Up @@ -73,129 +61,26 @@ function useRedirectOldPaths() {
}, [ history, params ] );
}

export default function useLayoutAreas() {
export default function useActiveRoute() {
youknowriad marked this conversation as resolved.
Show resolved Hide resolved
const { params } = useLocation();
const { postType, postId, path, layout, isCustom, canvas, quickEdit } =
params;
const hasEditCanvasMode = canvas === 'edit';
useRedirectOldPaths();

// Page list
if ( postType === 'page' ) {
const isListLayout = layout === 'list' || ! layout;
const showQuickEdit = quickEdit && ! isListLayout;
return {
key: 'pages',
areas: {
sidebar: (
<SidebarNavigationScreen
title={ __( 'Pages' ) }
backPath={ {} }
content={ <DataViewsSidebarContent /> }
/>
),
content: <PostList postType={ postType } />,
preview: ! showQuickEdit &&
( isListLayout || hasEditCanvasMode ) && <Editor />,
mobile: hasEditCanvasMode ? (
<Editor />
) : (
<PostList postType={ postType } />
),
edit: showQuickEdit && (
<PostEdit postType={ postType } postId={ postId } />
),
},
widths: {
content: isListLayout ? 380 : undefined,
edit: showQuickEdit ? 380 : undefined,
},
};
}

// Templates
if ( postType === TEMPLATE_POST_TYPE ) {
const isListLayout = isCustom !== 'true' && layout === 'list';
return {
key: 'templates',
areas: {
sidebar: (
<SidebarNavigationScreenTemplatesBrowse backPath={ {} } />
),
content: <PageTemplates />,
preview: ( isListLayout || hasEditCanvasMode ) && <Editor />,
mobile: hasEditCanvasMode ? <Editor /> : <PageTemplates />,
},
widths: {
content: isListLayout ? 380 : undefined,
},
};
}

// Patterns
if (
[ TEMPLATE_PART_POST_TYPE, PATTERN_TYPES.user ].includes( postType )
) {
return {
key: 'patterns',
areas: {
sidebar: <SidebarNavigationScreenPatterns backPath={ {} } />,
content: <PagePatterns />,
mobile: hasEditCanvasMode ? <Editor /> : <PagePatterns />,
preview: hasEditCanvasMode && <Editor />,
},
};
}

// Styles
if ( path === '/wp_global_styles' ) {
return {
key: 'styles',
areas: {
sidebar: (
<SidebarNavigationScreenGlobalStyles backPath={ {} } />
),
preview: <Editor />,
mobile: hasEditCanvasMode && <Editor />,
},
};
}

// Navigation
if ( postType === NAVIGATION_POST_TYPE ) {
if ( postId ) {
const routes = useSelect( ( select ) => {
return unlock( select( editSiteStore ) ).getRoutes();
}, [] );
return useMemo( () => {
const matchedRoute = routes.find( ( route ) => route.match( params ) );
if ( ! matchedRoute ) {
return {
key: 'navigation',
areas: {
sidebar: (
<SidebarNavigationScreenNavigationMenu
backPath={ { postType: NAVIGATION_POST_TYPE } }
/>
),
preview: <Editor />,
mobile: hasEditCanvasMode && <Editor />,
},
key: 404,
areas: {},
widths: {},
};
}

return {
key: 'navigation',
areas: {
sidebar: (
<SidebarNavigationScreenNavigationMenus backPath={ {} } />
),
preview: <Editor />,
mobile: hasEditCanvasMode && <Editor />,
},
name: matchedRoute.name,
areas: matchedRoute.areas,
widths: matchedRoute.widths,
};
}

// Fallback shows the home page preview
return {
key: 'default',
areas: {
sidebar: <SidebarNavigationScreenMain />,
preview: <Editor />,
mobile: hasEditCanvasMode && <Editor />,
},
};
}, [ routes, params ] );
}
4 changes: 2 additions & 2 deletions packages/edit-site/src/components/posts-app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
*/
import useInitEditedEntityFromURL from '../sync-state-with-url/use-init-edited-entity-from-url';
import Layout from '../layout';
import useLayoutAreas from './router';
import useActiveRoute from './router';
import { unlock } from '../../lock-unlock';

const { RouterProvider } = unlock( routerPrivateApis );
Expand All @@ -21,7 +21,7 @@ const { GlobalStylesProvider } = unlock( editorPrivateApis );
function PostsLayout() {
// This ensures the edited entity id and type are initialized properly.
useInitEditedEntityFromURL();
const route = useLayoutAreas();
const route = useActiveRoute();
return <Layout route={ route } />;
}

Expand Down
6 changes: 3 additions & 3 deletions packages/edit-site/src/components/posts-app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import PostList from '../post-list';

const { useLocation } = unlock( routerPrivateApis );

export default function useLayoutAreas() {
export default function useActiveRoute() {
const { params = {} } = useLocation();
const { postType, layout, canvas } = params;
const labels = useSelect(
Expand All @@ -31,7 +31,7 @@ export default function useLayoutAreas() {
if ( [ 'post' ].includes( postType ) ) {
const isListLayout = layout === 'list' || ! layout;
return {
key: 'posts-list',
name: 'posts-list',
areas: {
sidebar: (
<SidebarNavigationScreen
Expand Down Expand Up @@ -59,7 +59,7 @@ export default function useLayoutAreas() {

// Fallback shows the home page preview
return {
key: 'default',
name: 'default',
areas: {
sidebar: <SidebarNavigationScreenMain />,
preview: <Editor isPostsList />,
Expand Down
17 changes: 17 additions & 0 deletions packages/edit-site/src/components/site-editor-routes/home-edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Internal dependencies
*/
import Editor from '../editor';
import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main';

export const homeEditRoute = {
name: 'home-edit',
match: ( params ) => {
return params.canvas === 'edit';
},
areas: {
sidebar: <SidebarNavigationScreenMain />,
preview: <Editor />,
mobile: <Editor />,
},
};
16 changes: 16 additions & 0 deletions packages/edit-site/src/components/site-editor-routes/home-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Internal dependencies
*/
import Editor from '../editor';
import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main';

export const homeViewRoute = {
name: 'home-view',
match: ( params ) => {
return params.canvas !== 'edit';
},
areas: {
sidebar: <SidebarNavigationScreenMain />,
preview: <Editor />,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had forgotten why this didn't have a mobile area until I reviewed the layout component. Prepared #66309 to document when each area is present. It also prevents the edit area from being rendered if the canvas mode is edit.

},
};
60 changes: 60 additions & 0 deletions packages/edit-site/src/components/site-editor-routes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* WordPress dependencies
*/
import { useRegistry, useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';

/**
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';
import { store as siteEditorStore } from '../../store';
import { homeViewRoute } from './home-view';
import { homeEditRoute } from './home-edit';
import { navigationViewRoute } from './navigation-view';
import { navigationEditRoute } from './navigation-edit';
import { navigationItemEditRoute } from './navigation-item-edit';
import { navigationItemViewRoute } from './navigation-item-view';
import { stylesEditRoute } from './styles-edit';
import { stylesViewRoute } from './styles-view';
import { patternsEditRoute } from './patterns-edit';
import { patternsViewRoute } from './patterns-view';
import { templatesEditRoute } from './templates-edit';
import { templatesListViewRoute } from './templates-list-view';
import { templatesViewRoute } from './templates-view';
import { pagesViewRoute } from './pages-view';
import { pagesEditRoute } from './pages-edit';
import { pagesListViewRoute } from './pages-list-view';
import { pagesListViewQuickEditRoute } from './pages-list-view-quick-edit';
import { pagesViewQuickEditRoute } from './pages-view-quick-edit';

const routes = [
pagesListViewQuickEditRoute,
pagesListViewRoute,
pagesViewQuickEditRoute,
pagesViewRoute,
pagesEditRoute,
templatesEditRoute,
templatesListViewRoute,
templatesViewRoute,
patternsViewRoute,
patternsEditRoute,
stylesViewRoute,
stylesEditRoute,
navigationItemViewRoute,
navigationItemEditRoute,
navigationViewRoute,
navigationEditRoute,
homeViewRoute,
homeEditRoute,
];

export function useRegisterSiteEditorRoutes() {
const registry = useRegistry();
const { registerRoute } = unlock( useDispatch( siteEditorStore ) );
useEffect( () => {
registry.batch( () => {
routes.forEach( registerRoute );
} );
}, [ registry, registerRoute ] );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Internal dependencies
*/
import { NAVIGATION_POST_TYPE } from '../../utils/constants';
import Editor from '../editor';
import SidebarNavigationScreenNavigationMenus from '../sidebar-navigation-screen-navigation-menus';

export const navigationEditRoute = {
name: 'navigation-edit',
match: ( params ) => {
return (
params.postType === NAVIGATION_POST_TYPE &&
! params.postId &&
params.canvas === 'edit'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the canvas mode really warrant a separate route? Aside from the mobile view it still renders the same sidebar and the same <Editor /> component. The canvas mode is managed by the canvasMode state in the data store and synced by the useSyncCanvasModeWithURL.

In my view the canvas mode should be eventually managed only at one place; either:
a) in the route handler, which passes the mode down as <Editor canvasMode={ params.canvas } /> prop;
b) inside the <Editor /> component which reads the mode from the URL itself. This setup is very similar to how you would work with "minor" query params like order=asc or search=foo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No disagreement, the main reason for the route is "mobile". I don't know how to handle it otherwise. For mobile, these routes render different things depending on the canvasMode. Not entirely sure how to handle it.

Aside: I would love to remove that duplicate state as well and only rely on the url but that is a separate large effort IMO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this is worth revisiting, although I should point out that I like the rigidity of the current proposal: other than the match predicate, everything else is static data, making the whole thing IMO very easy to keep track of. It's more difficult for surprising behaviour to creep in, especially once we start considering third-party use. (Note that this remark doesn't imply that addressing the mobile view in a smarter way would necessarily go against the principle.)

);
},
areas: {
sidebar: <SidebarNavigationScreenNavigationMenus backPath={ {} } />,
preview: <Editor />,
mobile: <Editor />,
},
};
Loading
Loading