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'}
/>
)}
);
}