Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ export interface BreadcrumbsProps extends HTMLAttributes<HTMLElement> {
* `onAction` for a plain link.
*/
onAction?: (id: Key) => void;
/**
* Maximum width in pixels for each crumb's label text. Labels longer than
* this truncate with an ellipsis. Omit to never truncate.
*/
maxItemWidth?: number;
}

const ELLIPSIS_ID = '__breadcrumbs_ellipsis__';
Expand Down Expand Up @@ -177,20 +182,22 @@ const Divider = ({
const CrumbLabel = ({
item,
size,
maxItemWidth,
}: {
item: BreadcrumbItemType;
size: BreadcrumbsSize;
maxItemWidth?: number;
}) => {
const Icon = item.icon;

return (
<span
className={cx(
'tw:flex tw:items-center tw:whitespace-nowrap',
sizes[size].gap
)}>
<span className={cx('tw:flex tw:min-w-0 tw:items-center', sizes[size].gap)}>
{Icon && <Icon className={cx('tw:shrink-0', sizes[size].icon)} />}
{item.label}
<span
className="tw:truncate"
style={maxItemWidth ? { maxWidth: maxItemWidth } : undefined}>
{item.label}
</span>
</span>
);
};
Expand Down Expand Up @@ -241,6 +248,7 @@ export const Breadcrumbs = ({
autoCollapse = false,
className,
onAction,
maxItemWidth,
'aria-label': ariaLabel = 'Breadcrumb',
...props
}: BreadcrumbsProps) => {
Expand Down Expand Up @@ -327,17 +335,25 @@ export const Breadcrumbs = ({
className={cx(linkClassName, styles[type].link, padding)}
href={onAction ? undefined : item.href}
onPress={() => onAction?.(item.id)}>
<CrumbLabel item={item} size={size} />
<CrumbLabel
item={item}
maxItemWidth={maxItemWidth}
size={size}
/>
</AriaLink>
) : (
<span
aria-current={isCurrent ? 'page' : undefined}
className={cx(
'tw:flex tw:items-center',
'tw:flex tw:min-w-0 tw:items-center',
padding,
isCurrent ? styles[type].current : 'tw:text-quaternary'
)}>
<CrumbLabel item={item} size={size} />
<CrumbLabel
item={item}
maxItemWidth={maxItemWidth}
size={size}
/>
</span>
)}
{!isCurrent && <Divider divider={divider} size={size} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,37 +44,43 @@ const getTabStyles = ({
}: AriaTabRenderProps) => ({
'button-brand': cx(
'tw:outline-focus-ring',
isSelected ? 'tw:font-semibold' : 'tw:font-medium',
isFocusVisible && 'tw:outline-2 tw:-outline-offset-2',
(isSelected || isHovered) &&
'tw:bg-brand-primary_alt tw:text-brand-secondary'
),
'button-gray': cx(
'tw:outline-focus-ring',
isSelected ? 'tw:font-semibold' : 'tw:font-medium',
isHovered && 'tw:bg-primary_hover tw:text-secondary',
isFocusVisible && 'tw:outline-2 tw:-outline-offset-2',
isSelected && 'tw:bg-active tw:text-secondary'
),
'button-border': cx(
'tw:outline-focus-ring',
isSelected ? 'tw:font-semibold' : 'tw:font-medium',
(isSelected || isHovered) &&
'tw:bg-primary_alt tw:text-secondary tw:shadow-sm',
isFocusVisible && 'tw:outline-2 tw:-outline-offset-2'
),
'button-minimal': cx(
'tw:rounded-lg tw:outline-focus-ring',
isSelected ? 'tw:font-semibold' : 'tw:font-medium',
isHovered && 'tw:text-secondary',
isFocusVisible && 'tw:outline-2 tw:-outline-offset-2',
isSelected &&
'tw:bg-primary_alt tw:text-secondary tw:shadow-xs tw:ring-1 tw:ring-primary tw:ring-inset'
),
underline: cx(
'tw:rounded-none tw:border-b-2 tw:border-transparent tw:outline-focus-ring',
isSelected ? 'tw:font-semibold' : 'tw:font-medium',
(isSelected || isHovered) &&
'tw:border-fg-brand-primary_alt tw:text-brand-secondary',
isFocusVisible && 'tw:outline-2 tw:-outline-offset-2'
),
line: cx(
'tw:rounded-none tw:border-l-2 tw:border-transparent tw:outline-focus-ring',
isSelected ? 'tw:font-semibold' : 'tw:font-medium',
(isSelected || isHovered) &&
'tw:border-fg-brand-primary_alt tw:text-brand-secondary',
isFocusVisible && 'tw:outline-2 tw:-outline-offset-2'
Expand All @@ -83,20 +89,20 @@ const getTabStyles = ({

const sizes = {
sm: {
'button-brand': 'tw:text-sm tw:font-semibold tw:py-2 tw:px-3',
'button-gray': 'tw:text-sm tw:font-semibold tw:py-2 tw:px-3',
'button-border': 'tw:text-sm tw:font-semibold tw:py-2 tw:px-3',
'button-minimal': 'tw:text-sm tw:font-semibold tw:py-2 tw:px-3',
underline: 'tw:text-sm tw:font-semibold tw:px-1 tw:pb-2.5 tw:pt-0',
line: 'tw:text-sm tw:font-semibold tw:pl-2.5 tw:pr-3 tw:py-0.5',
'button-brand': 'tw:text-sm tw:py-2 tw:px-3',
'button-gray': 'tw:text-sm tw:py-2 tw:px-3',
'button-border': 'tw:text-sm tw:py-2 tw:px-3',
'button-minimal': 'tw:text-sm tw:py-2 tw:px-3',
underline: 'tw:text-sm tw:px-1 tw:pb-2.5 tw:pt-0',
line: 'tw:text-sm tw:pl-2.5 tw:pr-3 tw:py-0.5',
},
md: {
'button-brand': 'tw:text-md tw:font-semibold tw:py-2.5 tw:px-3',
'button-gray': 'tw:text-md tw:font-semibold tw:py-2.5 tw:px-3',
'button-border': 'tw:text-md tw:font-semibold tw:py-2.5 tw:px-3',
'button-minimal': 'tw:text-md tw:font-semibold tw:py-2.5 tw:px-3',
underline: 'tw:text-md tw:font-semibold tw:px-1 tw:pb-2.5 tw:pt-0',
line: 'tw:text-md tw:font-semibold tw:pr-3.5 tw:pl-3 tw:py-1',
'button-brand': 'tw:text-md tw:py-2.5 tw:px-3',
'button-gray': 'tw:text-md tw:py-2.5 tw:px-3',
'button-border': 'tw:text-md tw:py-2.5 tw:px-3',
'button-minimal': 'tw:text-md tw:py-2.5 tw:px-3',
underline: 'tw:text-md tw:px-1 tw:pb-2.5 tw:pt-0',
line: 'tw:text-md tw:pr-3.5 tw:pl-3 tw:py-1',
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/

import {
Button,
ButtonUtility,
Card,
Skeleton,
Typography,
Expand All @@ -28,7 +28,7 @@ import { getShortRelativeTime } from '../../../utils/date-time/DateTimeUtils';
import { ArchiveItem, ArchiveViewProps } from './ArchiveView.interface';

const ArchiveRowSkeleton: FC = () => (
<div className="tw:flex tw:items-center tw:gap-4 tw:px-4 tw:py-3 tw:border-b tw:border-secondary">
<div className="tw:flex tw:items-center tw:gap-4 tw:px-4 tw:py-3 tw:border-b tw:border-secondary tw:last:border-0">
<Skeleton
className="tw:shrink-0"
height="32px"
Expand Down Expand Up @@ -59,7 +59,7 @@ const ArchiveRow: FC<ArchiveRowProps> = ({ item, onDelete, onRestore }) => {

return (
<div
className="tw:flex tw:items-center tw:gap-4 tw:px-4 tw:py-3 tw:border-b tw:border-secondary"
className="tw:flex tw:items-center tw:gap-4 tw:px-4 tw:py-3 tw:border-b tw:border-secondary tw:last:border-0"
data-testid={`archive-row-${item.id}`}>
<div
className={classNames(
Expand Down Expand Up @@ -94,22 +94,22 @@ const ArchiveRow: FC<ArchiveRowProps> = ({ item, onDelete, onRestore }) => {
</div>

<div className="tw:flex tw:items-center tw:gap-2 tw:shrink-0">
<Button
color="secondary"
<ButtonUtility
color="tertiary"
data-testid="restore-btn"
iconLeading={RefreshCcw01}
icon={<RefreshCcw01 size={20} />}
size="sm"
onPress={() => onRestore(item)}>
{t('label.restore')}
</Button>
<Button
color="secondary-destructive"
tooltip={t('label.restore')}
onClick={() => onRestore(item)}
/>
<ButtonUtility
color="tertiary"
data-testid="delete-btn"
iconLeading={Trash01}
icon={<Trash01 size={20} />}
size="sm"
onPress={() => onDelete(item)}>
{t('label.delete')}
</Button>
tooltip={t('label.delete')}
onClick={() => onDelete(item)}
/>
</div>
</div>
);
Expand All @@ -123,7 +123,7 @@ const ArchiveView: FC<ArchiveViewProps> = ({
}) => {
if (isLoading) {
return (
<Card className="tw:flex tw:flex-col tw:overflow-hidden tw:h-[calc(100vh-378px)]">
<Card className="tw:flex tw:flex-col tw:overflow-hidden">
Comment thread
Rohit0301 marked this conversation as resolved.
Outdated
{Array.from({ length: 8 }).map((_, idx) => (
<ArchiveRowSkeleton key={idx} />
))}
Expand All @@ -140,9 +140,7 @@ const ArchiveView: FC<ArchiveViewProps> = ({
}

return (
<div
className="tw:flex tw:flex-1 tw:flex-col tw:overflow-y-auto tw:h-[calc(100vh-378px)]"
data-testid="archive-view">
<div data-testid="archive-view">
{data.map((item) => (
<ArchiveRow
item={item}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
User03,
} from '@untitledui/icons';
import { AxiosError } from 'axios';
import { cloneDeep, isEmpty, isUndefined, toString, uniqBy } from 'lodash';
import { cloneDeep, isUndefined, toString, uniqBy } from 'lodash';
import { FC, useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
Expand All @@ -58,7 +58,6 @@ import { EntityStatus } from '../../../generated/entity/data/glossaryTerm';
import { EntityReference } from '../../../generated/entity/type';
import { useCurrentUserPreferences } from '../../../hooks/currentUserStore/useCurrentUserStore';
import { useApplicationStore } from '../../../hooks/useApplicationStore';
import { useClipboard } from '../../../hooks/useClipBoard';
import { useEntityRules } from '../../../hooks/useEntityRules';
import { useFqn } from '../../../hooks/useFqn';
import {
Expand All @@ -75,6 +74,7 @@ import DomainSelectableList from '../../common/DomainSelectableList/DomainSelect
import HeaderBreadcrumb from '../../common/HeaderBreadcrumb/HeaderBreadcrumb.component';
import { OwnerLabel } from '../../common/OwnerLabel/OwnerLabel.component';
import { UserTeamSelectableList } from '../../common/UserTeamSelectableList/UserTeamSelectableList.component';
import CopyLinkButton from '../../CopyLinkButton/CopyLinkButton.component';
import { ArticleDetailHeaderProps } from './ArticleDetailHeader.interface';

const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
Expand All @@ -100,10 +100,8 @@ const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
const { entityRules } = useEntityRules(EntityType.KNOWLEDGE_PAGE);
const { currentUser } = useApplicationStore();
const USERId = currentUser?.id ?? '';
const [copyTooltip, setCopyTooltip] = useState<string>('');
const [isFollowLoading, setIsFollowLoading] = useState(false);
const [voteLoading, setVoteLoading] = useState<QueryVoteType | null>(null);
const { onCopyToClipBoard } = useClipboard(window.location.href);
const {
preferences: { recentlyViewedQuickLinks },
} = useCurrentUserPreferences();
Expand Down Expand Up @@ -192,12 +190,6 @@ const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
navigate(contextCenterClassBase.getArticleVersionPath(fqn, version));
};

const handleShare = async () => {
await onCopyToClipBoard();
setCopyTooltip(t('message.link-copy-to-clipboard'));
setTimeout(() => setCopyTooltip(''), 2000);
};

const handleFollowClick = async () => {
setIsFollowLoading(true);
await onFollowChange();
Expand Down Expand Up @@ -349,7 +341,7 @@ const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
<div className="tw:flex tw:gap-4 tw:items-stretch tw:w-full tw:max-w-[60%] tw:pr-3">
<div className="h:full tw:w-auto tw:shrink-0 tw:bg-gray-100 tw:rounded-xl tw:flex tw:items-center tw:p-2">
<File06
className="tw:text-gray-500"
className="tw:text-quaternary"
height={40}
strokeWidth={1.2}
style={{ verticalAlign: 'middle', flexShrink: 0 }}
Expand All @@ -373,14 +365,14 @@ const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
<Tooltip title={t('label.domain')}>
<TooltipTrigger className="tw:leading-0">
<Globe01
className="tw:h-4 tw:w-4 tw:shrink-0 tw:text-fg-disabled"
className="tw:h-4 tw:w-4 tw:shrink-0 tw:text-quaternary"
size={16}
/>
</TooltipTrigger>
</Tooltip>
<Typography
className={
firstDomain ? 'tw:text-primary-900' : 'tw:text-gray-400'
firstDomain ? 'tw:text-primary-900' : 'tw:text-quaternary'
}
data-testid="domain-link"
size="text-sm"
Expand Down Expand Up @@ -422,7 +414,7 @@ const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
<Tooltip title={t('label.owner-plural')}>
<TooltipTrigger className="tw:leading-0">
<User03
className="tw:h-4 tw:w-4 tw:shrink-0 tw:text-fg-disabled"
className="tw:h-4 tw:w-4 tw:shrink-0 tw:text-quaternary"
size={16}
/>
</TooltipTrigger>
Expand All @@ -440,7 +432,7 @@ const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
</div>
) : (
<Typography
className="tw:text-gray-400"
className="tw:text-quaternary"
size="text-sm"
weight="regular">
{t('label.no-entity', { entity: t('label.owner') })}
Expand Down Expand Up @@ -605,22 +597,13 @@ const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
</TooltipTrigger>
</Tooltip>

<Tooltip
isOpen={isEmpty(copyTooltip) ? undefined : true}
title={
isEmpty(copyTooltip)
? t('label.copy-item', { item: t('label.url') })
: copyTooltip
}>
<TooltipTrigger>
<ButtonUtility
color="secondary"
data-testid="share-btn"
icon={<Copy06 height={20} width={20} />}
onClick={handleShare}
/>
</TooltipTrigger>
</Tooltip>
<CopyLinkButton
className="tw:w-8 tw:h-8"
color="secondary"
testId="share-btn"
url={window.location.href}>
<Copy06 height={20} width={20} />
</CopyLinkButton>

{permissions?.Delete && (
<Dropdown.Root>
Expand Down Expand Up @@ -670,7 +653,7 @@ const ArticleDetailHeader: FC<ArticleDetailHeaderProps> = ({
entityTitle={getKnowledgePageName(knowledgePage, t)}
isDeleting={isDeleting}
message={t('message.soft-delete-message-for-entity', {
entity: getKnowledgePageName(knowledgePage, t),
entity: t('label.article').toLowerCase(),
})}
open={isDeleteModalOpen}
onCancel={() => setIsDeleteModalOpen(false)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ function RecentItem({
ellipsis
as="span"
className="tw:min-w-0 tw:flex-1 tw:text-secondary"
size="text-xs">
size="text-xs"
weight='medium'>
{item.title}
</Typography>
<Typography
Expand Down Expand Up @@ -149,7 +150,7 @@ const ContextKnowledgePillarCard: FC<ContextKnowledgePillarCardProps> = ({
as="div"
className="tw:text-primary"
size="text-sm"
weight="medium">
weight="semibold">
{title}
</Typography>
<Typography as="div" className="tw:text-quaternary" size="text-xs">
Expand Down
Loading
Loading