import React, { JSX, useEffect } from 'react'; import type { CatalogEntityConfig } from '@redocly/config'; import { BffCatalogEntity, BffCatalogEntityList } from '@redocly/theme/core/types'; import { useThemeHooks, useCatalogEntities, useCatalogEntityDetails, } from '@redocly/theme/core/hooks'; import { ArrowDownIcon } from '@redocly/theme/icons/ArrowDownIcon/ArrowDownIcon'; import { CatalogCardView } from '@redocly/theme/components/Catalog/CatalogCardView/CatalogCardView'; import { CatalogTableView } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTableView'; import { HighlightContext } from '@redocly/theme/components/Catalog/CatalogHighlight'; import { LoadMore } from '@redocly/theme/components/LoadMore/LoadMore'; import { CatalogEntitiesEmptyState } from '@redocly/theme/components/Catalog/CatalogEntitiesEmptyState'; export type CatalogEntitiesProps = { catalogConfig: CatalogEntityConfig; excludedEntities?: CatalogEntityConfig['excludes']; filterQuery: string; entitiesTypes: string[]; searchQuery: string; viewMode: string; setEntitiesCounter: (counter: number) => void; initialEntitiesList?: BffCatalogEntityList; sortOption: string | null; handleSortClick: (sortKey: string, direction: 'asc' | 'desc') => void; isColumnSorted: (sortKey: string, direction: 'asc' | 'desc') => boolean; }; const LOAD_MORE_THRESHOLD = 10; export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element { const { catalogConfig, excludedEntities, filterQuery, entitiesTypes, sortOption, searchQuery, viewMode, setEntitiesCounter, handleSortClick, isColumnSorted, } = props; const { getEntityDetailsLink } = useCatalogEntityDetails({ catalogConfig, }); const { useTelemetry, useFetchCatalogEntities } = useThemeHooks(); const telemetry = useTelemetry(); const { initialFilter } = useCatalogEntities({ entitiesTypes, excludedEntities, }); const { items: entities, query, total, } = useFetchCatalogEntities( { limit: LOAD_MORE_THRESHOLD, filter: initialFilter && filterQuery ? `(${initialFilter}) AND (${filterQuery})` : initialFilter || filterQuery, sort: sortOption || (viewMode === 'table' ? 'updated_at' : 'type,title'), search: searchQuery, }, props.initialEntitiesList, ); const onRowClick = (entity: BffCatalogEntity) => { if (searchQuery) { telemetry.sendCatalogEntitiesListSearchResultClickedMessage([ { id: entity.id, object: 'catalog_entity', uri: getEntityDetailsLink(entity), query: searchQuery, entityKey: entity.key, entityType: entity.type, }, ]); } }; const shouldShowLoadMore = query.hasNextPage || (query.isPlaceholderData && entities && entities.length >= LOAD_MORE_THRESHOLD); useEffect(() => { setEntitiesCounter(total || 0); }, [total, setEntitiesCounter]); if (!query.isPending && (!entities || entities.length === 0)) { return ; } return ( {viewMode === 'cards' ? ( ) : ( entities={entities} catalogConfig={catalogConfig} currentSortOption={sortOption} handleSortClick={handleSortClick} isColumnSorted={isColumnSorted} onRowClick={onRowClick} /> )} {shouldShowLoadMore && ( } onClick={query.fetchNextPage} disabled={query.isFetchingNextPage} blinking={query.isFetchingNextPage} label={query.isFetchingNextPage ? 'Loading...' : 'Load More'} /> )} ); }