-
Notifications
You must be signed in to change notification settings - Fork 2k
Dashboard v2: implement breadcrumbs #103294
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
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Breadcrumbs as BreadcrumbsComponent } from '@automattic/components/src/breadcrumbs'; | ||
import { useMatches } from '@tanstack/react-router'; | ||
import type { BreadcrumbItemProps } from '@automattic/components/src/breadcrumbs/types'; | ||
|
||
export default function Breadcrumbs() { | ||
const matches = useMatches(); | ||
|
||
const items = [] as BreadcrumbItemProps[]; | ||
|
||
let hasParent = false; | ||
matches.forEach( ( match ) => { | ||
if ( match.loaderData?.breadcrumbItemLabel || hasParent ) { | ||
items.push( { | ||
label: match.loaderData?.breadcrumbItemLabel || '', | ||
href: match.pathname, | ||
} ); | ||
hasParent = true; | ||
} | ||
} ); | ||
|
||
return <BreadcrumbsComponent items={ items } />; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import { | |
redirect, | ||
createLazyRoute, | ||
} from '@tanstack/react-router'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { fetchTwoStep } from '../data'; | ||
import NotFound from './404'; | ||
import UnknownError from './500'; | ||
|
@@ -22,6 +23,7 @@ import type { AppConfig } from './context'; | |
|
||
interface RouteContext { | ||
config?: AppConfig; | ||
breadcrumbItemLabel?: string; | ||
} | ||
|
||
const rootRoute = createRootRoute( { component: Root } ); | ||
|
@@ -107,8 +109,12 @@ const sitePerformanceRoute = createRoute( { | |
const siteSettingsRoute = createRoute( { | ||
getParentRoute: () => siteRoute, | ||
path: 'settings', | ||
loader: ( { params: { siteSlug } } ) => | ||
queryClient.ensureQueryData( siteSettingsQuery( siteSlug ) ), | ||
loader: async ( { params: { siteSlug } } ) => { | ||
await queryClient.ensureQueryData( siteSettingsQuery( siteSlug ) ); | ||
return { | ||
breadcrumbItemLabel: __( 'Settings' ), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does this have to be in the loader? Can't it be added as route meta or something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It needs to call BTW as per docs, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is my conclusion after spending a day reading the docs and consulting with AI 🥲 but I'm open if you have better ideas! This is literally my first project with TanStack stack. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
But if you really want, you could create a function that maps a route to a label: function getRouteBreadcrumbLabel( route ) {
switch ( route.path ) {
case 'setting': return __( 'Settings' );
}
} The loader function doesn't seem meant for this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you point me to the designs for this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The design is not available yet in v2 actually. I just wanted to prepare for this case in case we want to bring this pattern to v2 😬 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think yeah we can try to put that in
I was afraid the translation might not be ready yet when we construct the routing, but I'm happy to be wrong. I can try. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, imo we shouldn't think about use cases that might not exist. If for now a simple link with a slash works, then imo that's good for now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For |
||
}; | ||
}, | ||
} ).lazy( () => | ||
import( '../sites/settings' ).then( ( d ) => | ||
createLazyRoute( 'site-settings' )( { | ||
|
@@ -118,10 +124,8 @@ const siteSettingsRoute = createRoute( { | |
); | ||
|
||
const siteSettingsSubscriptionGiftingRoute = createRoute( { | ||
getParentRoute: () => siteRoute, | ||
path: 'settings/subscription-gifting', | ||
loader: ( { params: { siteSlug } } ) => | ||
queryClient.ensureQueryData( siteSettingsQuery( siteSlug ) ), | ||
getParentRoute: () => siteSettingsRoute, | ||
path: 'subscription-gifting', | ||
} ).lazy( () => | ||
import( '../sites/settings-subscription-gifting' ).then( ( d ) => | ||
createLazyRoute( 'site-settings-subscription-gifting' )( { | ||
|
@@ -292,8 +296,7 @@ const createRouteTree = ( config: AppConfig ) => { | |
siteOverviewRoute, | ||
siteDeploymentsRoute, | ||
sitePerformanceRoute, | ||
siteSettingsRoute, | ||
siteSettingsSubscriptionGiftingRoute, | ||
siteSettingsRoute.addChildren( [ siteSettingsSubscriptionGiftingRoute ] ), | ||
] ) | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How difficult is it to just create the breadcrumb links ourselves? In this case, it looks like there will only ever be a single breadcrumb link, looking at the designs, so this doesn't seem that complex to add a single
{link} /
above the header?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly initially thought about that... but then why are we creating a full-blown
<Breadcrumbs />
DS component if it's never going to be used beyond the above simple case? That thinking made me end up trying to come up with a more general breadcrumbs system 🥲Even if we have to hardcode the router link, we will need to copy-paste the styles from the
<Breadcrumbs />
component. Not sure if that's a good idea design-wise 🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if we're only ever going to add one link then we can remove that component eventually. I don't think we should necessarily import styles from Calypso components, we should focus on using
@wordpress
styles with limited customisation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, this is not what I anticipated; I thought the idea is to make use of the reusable DS components. I'll see what I can do next week; it's getting late for me 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or I can try to pass something to the link's
onClick
props and see if I can properly call TanStack router navigation with it.wp-calypso/packages/components/src/breadcrumbs/index.tsx
Line 45 in bb42801
I'd love to get input from @ntsekouras as the component author 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently Breadcrumbs was created for the hosting dashboard, but I don't have more information than that, so ignore my comments for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For start that what I'd try to do personally, just for now. Or it might had to do with the path (relative/full, etc..).
Breadcrumbs
will be part of the PageHeader component, that will land soon. My plan was to implement what this PR does, after the merge of PageHeader and try to see if we can make it work witha
tags, but if it can't, we'll add support in the Breadcrumbs component to pass the element we want instead ofa
( in this caseLink
). This was mentioned in the Breadcrumbs PR already.So, for me the important part here is to create the functionality to retrieve the proper breadcrumb items and for now we could just use directly a Link and not the Breadcrumbs if not possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened a PR for this: #103321
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you do want to shortcut #103321 you can implement the
onClick
handler like