fix(nx-dev): breadcrumb casing (#29032)

Fixes the breadcrumb component to show actual page titles instead of
just capitalizing the url segments
This commit is contained in:
Isaac Mann 2024-11-21 17:20:33 -05:00 committed by GitHub
parent c3d53a4900
commit a1efb63819
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 94 additions and 26 deletions

View File

@ -97,6 +97,27 @@ export class DocumentsApi {
name: document.name,
mediaImage: document.mediaImage || '',
relatedDocuments: this.getRelatedDocuments(document.tags),
parentDocuments: path.map((segment, index): RelatedDocument => {
const parentPath = path.slice(0, index + 1).join('/');
const parentDocument =
this.manifest[this.getManifestKey(parentPath)] || null;
if (!parentDocument) {
return {
id: segment,
name: '',
description: '',
file: '',
path: '/' + path.slice(0, index + 1).join('/'),
};
}
return {
id: parentDocument.id,
name: parentDocument.name,
description: parentDocument.description,
file: parentDocument.file,
path: parentDocument.path,
};
}),
tags: document.tags,
};
}

View File

@ -101,7 +101,7 @@ export function DocViewer({
<div className="mx-auto w-full grow items-stretch px-4 sm:px-6 lg:px-8 2xl:max-w-6xl">
<div id="content-wrapper" className="w-full flex-auto flex-col">
<div className="mb-6 pt-8">
<Breadcrumbs path={router.asPath} />
<Breadcrumbs document={document} />
</div>
<div className="min-w-0 flex-auto pb-24 lg:pb-16">
{/*MAIN CONTENT*/}

View File

@ -29,6 +29,7 @@ export interface ProcessedDocument {
id: string;
name: string;
relatedDocuments: Record<string, RelatedDocument[]>;
parentDocuments?: RelatedDocument[];
tags: string[];
}

View File

@ -1,25 +1,71 @@
import { ChevronRightIcon } from '@heroicons/react/24/solid';
import { ProcessedDocument } from '@nx/nx-dev/models-document';
import classNames from 'classnames';
export function Breadcrumbs({ path }: { path: string }): JSX.Element {
interface Crumb {
id: string;
name: string;
href: string;
current: boolean;
}
const sectionNames: Record<string, string> = {
ci: 'CI',
'extending-nx': 'Extending Nx',
'nx-api': 'Nx API',
};
const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
export function Breadcrumbs({
document,
path,
}: {
document?: ProcessedDocument;
path?: string;
}): JSX.Element {
let crumbs: Crumb[] = [];
if (path) {
const cleanedPath = path.includes('?')
? path.slice(0, path.indexOf('?'))
: path;
const pages = [
crumbs = [
...cleanedPath
.split('/')
.filter(Boolean)
.map((segment, index, segments) => ({
name: segment.includes('#')
.map((segment, index, segments) => {
const strippedName = segment.includes('#')
? segment.slice(0, segment.indexOf('#'))
: segment,
: segment;
const name =
sectionNames[strippedName] ||
strippedName.split('-').map(capitalize).join(' ');
return {
id: segment,
name,
// We do not have dedicated page view for executors & generators
href: '/' + segments.slice(0, index + 1).join('/'),
current: '/' + segments.slice(0, index + 1).join('/') === cleanedPath,
})),
current:
'/' + segments.slice(0, index + 1).join('/') === cleanedPath,
};
}),
];
}
if (pages.length === 1) {
if (document && document.parentDocuments) {
crumbs = document.parentDocuments.map((parentDocument, index) => ({
id: parentDocument.id,
name:
parentDocument.name ||
sectionNames[parentDocument.id] ||
parentDocument.id.split('-').map(capitalize).join(' '),
href: parentDocument.path,
current: index + 1 === document.parentDocuments?.length,
}));
}
if (crumbs.length < 2) {
return <></>;
}
@ -27,8 +73,8 @@ export function Breadcrumbs({ path }: { path: string }): JSX.Element {
<div>
<nav className="flex" aria-labelledby="breadcrumb">
<ol role="list" className="flex items-center space-x-4">
{pages.map((page, index) => (
<li key={page.name.concat('-', index.toString())}>
{crumbs.map((crumb, index) => (
<li key={crumb.id.concat('-', index.toString())}>
<div className="flex items-center">
{!!index && (
<ChevronRightIcon
@ -37,15 +83,15 @@ export function Breadcrumbs({ path }: { path: string }): JSX.Element {
/>
)}
<a
href={page.href}
href={crumb.href}
className={classNames(
'text-sm font-medium capitalize hover:text-slate-600',
page.current ? 'text-slate-600' : 'text-slate-400',
'text-sm font-medium hover:text-slate-600',
crumb.current ? 'text-slate-600' : 'text-slate-400',
!!index ? 'ml-4' : ''
)}
aria-current={page.current ? 'page' : undefined}
aria-current={crumb.current ? 'page' : undefined}
>
{page.name.replace(/-/gi, ' ')}
{crumb.name}
</a>
</div>
</li>