Skip to content

Commit

Permalink
Truncate long category names in breadcrumbs
Browse files Browse the repository at this point in the history
  • Loading branch information
woodwoerk committed Sep 21, 2023
1 parent 7d83923 commit 4b034cb
Showing 1 changed file with 86 additions and 52 deletions.
138 changes: 86 additions & 52 deletions components/actions/ActionHero.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Container, Row, Col } from 'reactstrap';
import { Container, Row, Col, UncontrolledTooltip } from 'reactstrap';
import styled from 'styled-components';
import { useTheme } from 'common/theme';
import { getActionTermContext, useTranslation } from 'common/i18n';
Expand All @@ -12,6 +12,7 @@ import {
import { usePlan } from 'context/plan';

import Icon from 'components/common/Icon';
import { Category } from 'common/__generated__/graphql';

const Hero = styled.header<{ bgColor: string }>`
position: relative;
Expand Down Expand Up @@ -150,65 +151,98 @@ const ActionNumber = styled.span`
}
`;

function ActionCategories(props) {
const { categories } = props;
const theme = useTheme();
const MAX_CRUMB_LENGTH = 90;

const isIdentifierVisible = (category: Category, showIdentifiers: boolean) =>
category.categoryPage && category.identifier && showIdentifiers;

const getCategoryName = (category: Category, showIdentifiers: boolean) =>
isIdentifierVisible(category, showIdentifiers)
? `${category.identifier}. ${category.name}`
: category.name;

const getCategoryUrl = (category: Category, primaryCategory) => {
if (category.categoryPage) {
return category.categoryPage.urlPath;
}

if (primaryCategory) {
return `/actions?cat-${primaryCategory.identifier}=${category.id}`;
}

return undefined;
};

type PartialCategory = Pick<Category, 'id' | 'name'> & {
url?: string;
parent?: PartialCategory;
};

function Crumb({ category }: { category: PartialCategory }) {
const id = `crumb-${category.id}`;
const ariaId = `tt-content-${category.id}`;
const isTruncated = category.name.length > MAX_CRUMB_LENGTH;
const name = isTruncated
? `${category.name.slice(0, MAX_CRUMB_LENGTH).trim()}...`
: category.name;

return (
<>
<span id={id} aria-describedby={isTruncated ? ariaId : undefined}>
{category.url ? (
<Link href={category.url} passHref>
{name}
</Link>
) : (
name
)}
{` / `}
</span>

{isTruncated && (
<UncontrolledTooltip
target={id}
id={ariaId}
placement="top"
role="tooltip"
trigger="focus hover"
>
{category.name}
</UncontrolledTooltip>
)}
</>
);
}

function ActionCategories({ categories }: { categories: Category[] }) {
const plan = usePlan();
const showIdentifiers =
!plan.primaryActionClassification?.hideCategoryIdentifiers;
const displayCategories = [];
const primaryCT = plan.primaryActionClassification;
const primaryCatId = primaryCT?.id;

categories.forEach((cat, indx) => {
if (cat.type.id !== primaryCatId) return;
displayCategories[indx] = {};
let categoryTitle = cat.name;
if (cat.categoryPage) {
displayCategories[indx].url = cat.categoryPage.urlPath;
if (cat.identifier && showIdentifiers)
categoryTitle = `${cat.identifier}. ${cat.name}`;
} else if (primaryCT) {
displayCategories[
indx
].url = `/actions?cat-${primaryCT.identifier}=${cat.id}`;
}
displayCategories[indx].name = categoryTitle;
displayCategories[indx].id = cat.id;
if (cat.parent) {
displayCategories[indx].parent = {};
let categoryParentTitle = cat.parent.name;
if (cat.parent.categoryPage) {
displayCategories[indx].parent.url = cat.parent.categoryPage.urlPath;
if (cat.parent.identifier && showIdentifiers) {
categoryParentTitle = `${cat.parent.identifier}. ${cat.parent.name}`;
}
} else {
displayCategories[
indx
].parent.url = `/actions?cat-${primaryCT.identifier}=${cat.parent.id}`;
}
displayCategories[indx].parent.name = categoryParentTitle;
displayCategories[indx].parent.id = cat.parent.id;
}
return true;
});
const displayCategories: PartialCategory[] = categories
.filter((cat) => cat.type.id === primaryCatId)
.map((cat) => ({
id: cat.id,
name: getCategoryName(cat, showIdentifiers),
url: getCategoryUrl(cat, primaryCT),
parent: cat.parent
? {
id: cat.parent.id,
name: getCategoryName(cat.parent, showIdentifiers),
url: getCategoryUrl(cat.parent, primaryCT),
}
: undefined,
}));

return (
<CategoriesBreadcrumb>
{displayCategories.map((item) => (
<div key={item.id} className="me-3">
{item.parent && (
<span>
<Link href={item.parent.url} passHref>
{item.parent.name}
</Link>{' '}
/{' '}
</span>
)}
<Link href={item.url} passHref>
{item.name}
</Link>{' '}
/{' '}
{displayCategories.map((category) => (
<div key={category.id} className="me-3">
{category.parent && <Crumb category={category.parent} />}

<Crumb category={category} />
</div>
))}
</CategoriesBreadcrumb>
Expand Down

0 comments on commit 4b034cb

Please sign in to comment.