Pluralize dashboard breadcrumbs if appropriate (#3832)

Closes #3483.

This PR refactors and simplifies breadcrumb text pluralization. The redesigned
dashboard added a view that shows the user a list of all pods, deployments, etc.
in a namespace. The breadcrumb navigation text needed to be tweaked to correctly
pluralize the resource type selected.
This commit is contained in:
Carol A. Scott 2019-12-16 16:31:45 -08:00 committed by GitHub
parent aec0f6b6df
commit 43c394aa97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 6 deletions

View File

@ -73,14 +73,19 @@ class BreadcrumbHeader extends React.Component {
}
}
renderBreadcrumbSegment(segment, shouldPluralizeFirstSegment) {
renderBreadcrumbSegment(segment, numCrumbs, index) {
let isMeshResource = isResource(segment);
if (isMeshResource) {
if (!shouldPluralizeFirstSegment) {
return friendlyTitle(segment).singular;
if (numCrumbs === 1 || index !== 0) {
// If the segment is a K8s resource type, it should be pluralized if
// the complete breadcrumb group describes a single-word list of
// resources ("Namespaces") OR if the breadcrumb group describes a list
// of resources within a specific namespace ("Namespace > linkerd >
// Deployments")
return this.segmentToFriendlyTitle(segment, true);
}
return this.segmentToFriendlyTitle(segment, true);
return friendlyTitle(segment).singular;
}
return this.segmentToFriendlyTitle(segment, false);
}
@ -88,12 +93,11 @@ class BreadcrumbHeader extends React.Component {
render() {
let prefix = this.props.pathPrefix;
let breadcrumbs = this.convertURLToBreadcrumbs(this.props.location.pathname.replace(prefix, ""));
let shouldPluralizeFirstSegment = breadcrumbs.length === 1;
return breadcrumbs.map((pathSegment, index) => {
return (
<span key={pathSegment.segment}>
{this.renderBreadcrumbSegment(pathSegment.segment, shouldPluralizeFirstSegment && index === 0)}
{this.renderBreadcrumbSegment(pathSegment.segment, breadcrumbs.length, index)}
{ index < breadcrumbs.length - 1 ? " > " : null }
</span>
);

View File

@ -26,4 +26,84 @@ describe('Tests for <BreadcrumbHeader>', () => {
const crumbs = component.find("span");
expect(crumbs).toHaveLength(3);
});
it("renders correct breadcrumb text for top-level pages [Namespaces]", () => {
loc.pathname = "/namespaces";
const component = mount(
<BrowserRouter>
<BreadcrumbHeader
location={loc}
pathPrefix="" />
</BrowserRouter>
);
const crumbs = component.find("span");
expect(crumbs).toHaveLength(1);
const crumbText = crumbs.reduce((acc, crumb) => {
acc+= crumb.text();
return acc;
}, "")
expect(crumbText).toEqual("Namespaces");
});
it("renders correct breadcrumb text for top-level pages [Control Plane]",
() => {
loc.pathname = "/controlplane";
const component = mount(
<BrowserRouter>
<BreadcrumbHeader
location={loc}
pathPrefix="" />
</BrowserRouter>
);
const crumbs = component.find("span");
expect(crumbs).toHaveLength(1);
const crumbText = crumbs.reduce((acc, crumb) => {
acc+= crumb.text();
return acc;
}, "")
expect(crumbText).toEqual("Control Plane");
});
it(`renders correct breadcrumb text for resource list page
[Namespace > emojivoto > Deployments`, () => {
loc.pathname = "/namespaces/emojivoto/deployments";
const component = mount(
<BrowserRouter>
<BreadcrumbHeader
location={loc}
pathPrefix="" />
</BrowserRouter>
);
const crumbs = component.find("span");
expect(crumbs).toHaveLength(3);
const crumbText = crumbs.reduce((acc, crumb) => {
acc+= crumb.text();
return acc;
}, "")
expect(crumbText).toEqual("Namespace > emojivoto > Deployments")
});
it(`renders correct breadcrumb text for resource detail page
[Namespace > emojivoto > deployment/web`, () => {
loc.pathname = "/namespaces/emojivoto/deployments/web";
const component = mount(
<BrowserRouter>
<BreadcrumbHeader
location={loc}
pathPrefix="" />
</BrowserRouter>
);
const crumbs = component.find("span");
expect(crumbs).toHaveLength(3);
const crumbText = crumbs.reduce((acc, crumb) => {
acc+= crumb.text();
return acc;
}, "")
expect(crumbText).toEqual("Namespace > emojivoto > deployment/web")
});
});