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:
parent
c3d53a4900
commit
a1efb63819
@ -97,6 +97,27 @@ export class DocumentsApi {
|
|||||||
name: document.name,
|
name: document.name,
|
||||||
mediaImage: document.mediaImage || '',
|
mediaImage: document.mediaImage || '',
|
||||||
relatedDocuments: this.getRelatedDocuments(document.tags),
|
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,
|
tags: document.tags,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 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 id="content-wrapper" className="w-full flex-auto flex-col">
|
||||||
<div className="mb-6 pt-8">
|
<div className="mb-6 pt-8">
|
||||||
<Breadcrumbs path={router.asPath} />
|
<Breadcrumbs document={document} />
|
||||||
</div>
|
</div>
|
||||||
<div className="min-w-0 flex-auto pb-24 lg:pb-16">
|
<div className="min-w-0 flex-auto pb-24 lg:pb-16">
|
||||||
{/*MAIN CONTENT*/}
|
{/*MAIN CONTENT*/}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ export interface ProcessedDocument {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
relatedDocuments: Record<string, RelatedDocument[]>;
|
relatedDocuments: Record<string, RelatedDocument[]>;
|
||||||
|
parentDocuments?: RelatedDocument[];
|
||||||
tags: string[];
|
tags: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,25 +1,71 @@
|
|||||||
import { ChevronRightIcon } from '@heroicons/react/24/solid';
|
import { ChevronRightIcon } from '@heroicons/react/24/solid';
|
||||||
|
import { ProcessedDocument } from '@nx/nx-dev/models-document';
|
||||||
import classNames from 'classnames';
|
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('?')
|
const cleanedPath = path.includes('?')
|
||||||
? path.slice(0, path.indexOf('?'))
|
? path.slice(0, path.indexOf('?'))
|
||||||
: path;
|
: path;
|
||||||
const pages = [
|
crumbs = [
|
||||||
...cleanedPath
|
...cleanedPath
|
||||||
.split('/')
|
.split('/')
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.map((segment, index, segments) => ({
|
.map((segment, index, segments) => {
|
||||||
name: segment.includes('#')
|
const strippedName = segment.includes('#')
|
||||||
? segment.slice(0, segment.indexOf('#'))
|
? 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
|
// We do not have dedicated page view for executors & generators
|
||||||
href: '/' + segments.slice(0, index + 1).join('/'),
|
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 <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,8 +73,8 @@ export function Breadcrumbs({ path }: { path: string }): JSX.Element {
|
|||||||
<div>
|
<div>
|
||||||
<nav className="flex" aria-labelledby="breadcrumb">
|
<nav className="flex" aria-labelledby="breadcrumb">
|
||||||
<ol role="list" className="flex items-center space-x-4">
|
<ol role="list" className="flex items-center space-x-4">
|
||||||
{pages.map((page, index) => (
|
{crumbs.map((crumb, index) => (
|
||||||
<li key={page.name.concat('-', index.toString())}>
|
<li key={crumb.id.concat('-', index.toString())}>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
{!!index && (
|
{!!index && (
|
||||||
<ChevronRightIcon
|
<ChevronRightIcon
|
||||||
@ -37,15 +83,15 @@ export function Breadcrumbs({ path }: { path: string }): JSX.Element {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<a
|
<a
|
||||||
href={page.href}
|
href={crumb.href}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'text-sm font-medium capitalize hover:text-slate-600',
|
'text-sm font-medium hover:text-slate-600',
|
||||||
page.current ? 'text-slate-600' : 'text-slate-400',
|
crumb.current ? 'text-slate-600' : 'text-slate-400',
|
||||||
!!index ? 'ml-4' : ''
|
!!index ? 'ml-4' : ''
|
||||||
)}
|
)}
|
||||||
aria-current={page.current ? 'page' : undefined}
|
aria-current={crumb.current ? 'page' : undefined}
|
||||||
>
|
>
|
||||||
{page.name.replace(/-/gi, ' ')}
|
{crumb.name}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user