import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import type { CatalogEntityVersionHistoryGroup } from '@redocly/theme/core/types';
import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';
import { CheckmarkOutlineIcon } from '@redocly/theme/icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon';
import { NavaidMilitaryIcon } from '@redocly/theme/icons/NavaidMilitaryIcon/NavaidMilitaryIcon';
import { Link } from '@redocly/theme/components/Link/Link';
import { Tag } from '@redocly/theme/components/Tag/Tag';
import { useThemeHooks } from '@redocly/theme/core/hooks';
import { ShowMoreButton } from '@redocly/theme/components/Catalog/CatalogEntity/ShowMoreButton';
import { CatalogEntityRevisionItem } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityRevisionItem';
import { buildRevisionUrl } from '@redocly/theme/core/utils';
import { VERSION_NOT_SPECIFIED } from '@redocly/theme/core/constants';
const MAX_INITIAL_REVISIONS = 5;
const MAX_REVISIONS = 20;
export type CatalogEntityVersionItemProps = {
group: CatalogEntityVersionHistoryGroup;
basePath: string;
isExpanded: boolean;
onToggle: (version: string) => void;
};
export function CatalogEntityVersionItem({
group,
basePath,
isExpanded,
onToggle,
}: CatalogEntityVersionItemProps): React.ReactElement {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const [showAllRevisions, setShowAllRevisions] = useState(false);
const revisions = group.revisions || [];
const hasRevisions = revisions.length > 0;
const hasMoreThanMax = revisions.length > MAX_INITIAL_REVISIONS;
const hasMoreThanLimit = revisions.length > MAX_REVISIONS;
const displayedRevisions = showAllRevisions
? revisions.slice(0, MAX_REVISIONS)
: revisions.slice(0, MAX_INITIAL_REVISIONS);
useEffect(() => {
if (!isExpanded) {
setShowAllRevisions(false);
}
}, [isExpanded]);
const isNotSpecifiedVersion = group.version === VERSION_NOT_SPECIFIED;
const singleRevisionLink = buildRevisionUrl(basePath, group.singleRevisionDate, group.version);
const versionTitle = isNotSpecifiedVersion
? `${translate('catalog.history.version.label', 'Version')}:\u00a0${translate('catalog.history.version.notSpecified', 'not specified')}`
: `${translate('catalog.history.version.label', 'Version')}:\u00a0${group.version}`;
const versionButton = (
hasRevisions && onToggle(group.version)}
$isCurrent={group.isCurrent}
>
{group.isCurrent ? (
) : (
)}
{versionTitle}
{group.isDefaultVersion && (
{translate('catalog.history.version.default', 'default')}
)}
{!isNotSpecifiedVersion && {group.date}}
{hasRevisions && (
{isExpanded ? (
) : (
)}
)}
);
return (
{singleRevisionLink ? {versionButton} : versionButton}
{hasRevisions && isExpanded && (
{displayedRevisions.map((revisionItem) => (
))}
{hasMoreThanLimit && showAllRevisions && (
{translate(
'catalog.history.revisions.limitMessage',
'Older revisions are not stored.',
)}
)}
{hasMoreThanMax && (
setShowAllRevisions(!showAllRevisions)}
isExpanded={showAllRevisions}
>
{showAllRevisions
? translate('catalog.history.revisions.showLess', 'Show less')
: translate('catalog.history.revisions.showMore', {
defaultValue: 'Show more',
count: Math.min(
revisions.length - MAX_INITIAL_REVISIONS,
MAX_REVISIONS - MAX_INITIAL_REVISIONS,
),
})}
)}
)}
);
}
const VersionButton = styled.button<{
$isCurrent?: boolean;
}>`
all: unset;
display: flex;
align-items: center;
width: calc(100% - var(--catalog-history-sidebar-version-icon-margin-right));
padding: var(--catalog-history-sidebar-version-header-padding);
cursor: pointer;
border-radius: var(--catalog-history-sidebar-version-header-border-radius);
transition: 0.2s ease;
text-decoration: none;
color: inherit;
background-color: 'transparent';
&:hover {
background-color: var(--catalog-history-sidebar-version-header-bg-color-hover);
}
${({ $isCurrent }) =>
!$isCurrent &&
`
&:hover ${VersionIcon} {
background-color: var(--color-static-white);
}
`}
`;
const VersionIcon = styled.div<{ $isCurrent?: boolean }>`
display: flex;
align-items: center;
justify-content: center;
width: var(--catalog-history-sidebar-version-icon-size);
height: var(--catalog-history-sidebar-version-icon-size);
flex-shrink: 0;
border-radius: 50%;
background-color: ${({ $isCurrent }) =>
$isCurrent
? 'var(--color-primary-base, var(--color-blueberry-6))'
: 'var(--catalog-avatar-bg-color)'};
transition: background-color 0.2s ease;
margin-right: var(--catalog-history-sidebar-version-icon-margin-right);
svg path {
transition: fill 0.2s ease;
}
`;
const VersionInfo = styled.div`
display: flex;
flex-direction: column;
align-items: flex-start;
gap: var(--catalog-history-sidebar-version-info-gap);
`;
const VersionTitleRow = styled.div`
display: flex;
align-items: center;
gap: var(--spacing-xs, 8px);
`;
const VersionTitle = styled.span`
font-family: var(--catalog-history-sidebar-version-title-font-family);
font-size: var(--catalog-history-sidebar-version-title-font-size);
font-weight: var(--catalog-history-sidebar-version-title-font-weight);
line-height: var(--catalog-history-sidebar-version-title-line-height);
color: var(--catalog-history-sidebar-version-title-color);
flex-shrink: 1;
min-width: 0;
overflow-wrap: break-word;
word-break: break-word;
`;
const VersionDate = styled.span`
font-family: var(--catalog-history-sidebar-version-date-font-family);
font-size: var(--catalog-history-sidebar-version-date-font-size);
font-weight: var(--catalog-history-sidebar-version-date-font-weight);
line-height: var(--catalog-history-sidebar-version-date-line-height);
color: var(--catalog-history-sidebar-version-date-color);
`;
const ChevronIcon = styled.div`
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-left: auto;
`;
const RevisionsList = styled.ul`
list-style: none;
margin: 0;
padding: 0;
padding-left: var(--catalog-history-sidebar-revisions-padding-left);
padding-bottom: var(--catalog-history-sidebar-revisions-padding-bottom);
position: relative;
&::before {
content: '';
position: absolute;
left: 22px;
top: 0;
bottom: var(--catalog-history-sidebar-revisions-padding-bottom);
width: 1px;
background-color: var(
--catalog-history-sidebar-revision-line-color,
var(--border-color-secondary)
);
}
`;
const RevisionsLimitMessage = styled.div`
padding: var(--catalog-history-sidebar-revision-item-padding);
margin-left: calc(-1 * var(--catalog-history-sidebar-revisions-padding-left));
padding-left: var(--catalog-history-sidebar-revisions-padding-left);
font-family: var(--catalog-history-sidebar-revision-name-font-family);
font-size: var(--font-size-sm);
font-weight: var(--catalog-history-sidebar-revision-name-font-weight);
line-height: var(--catalog-history-sidebar-revision-name-line-height);
color: var(--catalog-history-sidebar-revisions-limit-message-color);
text-align: center;
`;