import React, { useState } from 'react'; import styled from 'styled-components'; import { BffCatalogEntity } from '@redocly/theme/core/types'; import { JsonViewer } from '@redocly/theme/components/JsonViewer/JsonViewer'; import { capitalize, isPlainObject } from '@redocly/theme/core/utils'; import { useThemeHooks } from '@redocly/theme/core/hooks'; import { CatalogEntityInfoBar } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityInfoBar'; import { ShowMoreButton } from '@redocly/theme/components/Catalog/CatalogEntity/ShowMoreButton'; const MAX_INITIAL_ITEMS = 4; export type CatalogEntityMetadataProps = { entity: BffCatalogEntity; }; /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ function renderMetadataValue(value: any): React.JSX.Element { if (isPlainObject(value)) { return ; } if (Array.isArray(value)) { return ( {value.map((item, index) => (
{isPlainObject(item) ? ( ) : ( {String(item)} )}
))}
); } return {String(value)}; } export function CatalogEntityMetadata({ entity }: CatalogEntityMetadataProps) { const { useTranslate } = useThemeHooks(); const { translate } = useTranslate(); const { schema, sdl, ...metadata } = entity.metadata || {}; const metadataToShow = Object.entries(metadata).filter( ([key]) => !(entity.type === 'api-description' && key === 'descriptionFile'), ); const [isOn, setIsOn] = useState(false); const hasMoreItems = metadataToShow.length > MAX_INITIAL_ITEMS; const visibleMetadata = isOn ? metadataToShow : metadataToShow.slice(0, MAX_INITIAL_ITEMS); if (!metadataToShow.length) { return null; } return ( {translate('catalog.entity.metadata.title')} {visibleMetadata.map(([key, value]) => ( {capitalize(key)}:} rightContent={{renderMetadataValue(value)}} hoverEffect={false} isCodeBlock={isPlainObject(value) || Array.isArray(value)} /> ))} {hasMoreItems && ( setIsOn(!isOn)} isExpanded={isOn}> {isOn ? 'Show less' : 'Show more'} )} ); } const JsonViewerWrapper = styled(JsonViewer)` text-align: left; `; const MetadataWrapper = styled.div` display: flex; flex-direction: column; border-radius: var(--border-radius); background-color: var(--catalog-metadata-bg-color); transition: all 0.2s ease-in-out; margin-bottom: var(--spacing-base); `; const Label = styled.span` font-weight: var(--font-weight-medium); color: var(--catalog-metadata-label-color); `; const Value = styled.span` color: var(--catalog-metadata-value-color); font-weight: var(--font-weight-medium); `; const ArrayWrapper = styled.div` display: flex; flex-direction: column; `; const Heading = styled.h2` margin-bottom: var(--spacing-sm); margin-top: 0; font-size: var(--catalog-metadata-heading-size); `;