A frontend library that helps other Backstage plugins interact with the catalog through React components, hooks, and utilities.
—
React hooks for accessing and managing entity data, providing both synchronous and asynchronous patterns for entity loading and state management.
Hook for accessing the current entity from the nearest EntityProvider context.
/**
* Accesses the current entity from context
* @returns Object containing the current entity
* @throws Error if used outside EntityProvider
*/
function useEntity<TEntity extends Entity = Entity>(): { entity: TEntity };Usage Examples:
import { useEntity } from '@backstage/plugin-catalog-react';
function EntityDetails() {
const { entity } = useEntity();
return (
<div>
<h2>{entity.metadata.name}</h2>
<p>Kind: {entity.kind}</p>
<p>Namespace: {entity.metadata.namespace}</p>
</div>
);
}
// With typed entity
function ComponentDetails() {
const { entity } = useEntity<ComponentEntity>();
// entity is now typed as ComponentEntity
return <div>Type: {entity.spec.type}</div>;
}Hook for accessing entity data with async loading state, error handling, and refresh capabilities.
/**
* Accesses entity with async loading state management
* @returns Object containing entity, loading state, error, and refresh function
*/
function useAsyncEntity<TEntity extends Entity = Entity>(): EntityLoadingStatus<TEntity>;
interface EntityLoadingStatus<TEntity extends Entity = Entity> {
/** The loaded entity (undefined while loading or on error) */
entity?: TEntity;
/** Whether the entity is currently being loaded */
loading: boolean;
/** Error that occurred during loading (if any) */
error?: Error;
/** Function to refresh/reload the entity */
refresh?: VoidFunction;
}Usage Examples:
import { useAsyncEntity } from '@backstage/plugin-catalog-react';
function AsyncEntityDisplay() {
const { entity, loading, error, refresh } = useAsyncEntity();
if (loading) return <div>Loading entity...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!entity) return <div>No entity found</div>;
return (
<div>
<h2>{entity.metadata.name}</h2>
<button onClick={refresh}>Refresh</button>
</div>
);
}Context providers for supplying entity data to child components.
/**
* Provides entity context to child components
* @param props - Provider configuration
* @returns Provider component
*/
function EntityProvider(props: EntityProviderProps): JSX.Element;
interface EntityProviderProps {
/** Child components that will receive entity context */
children: ReactNode;
/** Entity to provide in context */
entity?: Entity;
}
/**
* Provides async entity context with loading states
* @param props - Async provider configuration
* @returns Async provider component
*/
function AsyncEntityProvider(props: AsyncEntityProviderProps): JSX.Element;
interface AsyncEntityProviderProps {
/** Child components that will receive async entity context */
children: ReactNode;
/** Entity to provide (undefined while loading) */
entity?: Entity;
/** Whether entity is currently loading */
loading: boolean;
/** Error that occurred during loading */
error?: Error;
/** Function to refresh the entity */
refresh?: VoidFunction;
}Usage Examples:
import { EntityProvider, AsyncEntityProvider } from '@backstage/plugin-catalog-react';
// Basic entity provider
function EntityPage({ entity }: { entity: Entity }) {
return (
<EntityProvider entity={entity}>
<EntityDetails />
<EntityRelations />
</EntityProvider>
);
}
// Async entity provider
function AsyncEntityPage({ entityRef }: { entityRef: string }) {
const { entity, loading, error, refresh } = useAsyncEntityLoad(entityRef);
return (
<AsyncEntityProvider
entity={entity}
loading={loading}
error={error}
refresh={refresh}
>
<EntityDetails />
</AsyncEntityProvider>
);
}Hook for managing entity lists with filtering, loading states, and query parameters.
/**
* Manages entity list state with filtering and loading
* @returns Entity list context with filters, entities, and update functions
*/
function useEntityList<
EntityFilters extends DefaultEntityFilters = DefaultEntityFilters
>(): EntityListContextProps<EntityFilters>;
interface EntityListContextProps<EntityFilters> {
/** Current filter configuration */
filters: EntityFilters;
/** Filtered entities for display */
entities: Entity[];
/** Raw entities from backend before frontend filtering */
backendEntities: Entity[];
/** Function to update filter configuration */
updateFilters: (
update: Partial<EntityFilters> | ((current: EntityFilters) => EntityFilters)
) => void;
/** Current query parameters from URL */
queryParameters: Partial<Record<keyof EntityFilters, string | string[]>>;
/** Whether entities are currently loading */
loading: boolean;
/** Error that occurred during loading */
error?: Error;
}
interface DefaultEntityFilters {
kind?: EntityKindFilter;
type?: EntityTypeFilter;
user?: UserListFilter | EntityUserFilter;
owners?: EntityOwnerFilter;
lifecycles?: EntityLifecycleFilter;
tags?: EntityTagFilter;
text?: EntityTextFilter;
orphan?: EntityOrphanFilter;
error?: EntityErrorFilter;
namespace?: EntityNamespaceFilter;
}Usage Examples:
import { useEntityList, EntityListProvider } from '@backstage/plugin-catalog-react';
function EntityListPage() {
const {
entities,
filters,
updateFilters,
loading,
error
} = useEntityList();
return (
<div>
<EntitySearchBar />
<EntityKindPicker />
<EntityTypePicker />
{loading && <div>Loading...</div>}
{error && <div>Error: {error.message}</div>}
<EntityTable
title="Entities"
entities={entities}
columns={defaultColumns}
/>
</div>
);
}
// With custom filters
function CustomEntityList() {
const { entities, updateFilters } = useEntityList();
const handleKindChange = (kind: string) => {
updateFilters({ kind: new EntityKindFilter(kind) });
};
return (
<div>
<select onChange={(e) => handleKindChange(e.target.value)}>
<option value="">All Kinds</option>
<option value="component">Components</option>
<option value="api">APIs</option>
</select>
<EntityTable
title="Filtered Entities"
entities={entities}
columns={defaultColumns}
/>
</div>
);
}Context provider for entity list functionality.
/**
* Provides entity list context to child components
* @param props - Provider configuration with initial filters
* @returns Entity list provider component
*/
function EntityListProvider(props: {
children: ReactNode;
/** Initial filter configuration */
filters?: Partial<DefaultEntityFilters>;
}): JSX.Element;
/** Context for entity list state */
const EntityListContext: React.Context<EntityListContextProps<DefaultEntityFilters> | undefined>;Additional hooks for specific entity-related functionality.
/**
* Hook for entity type filtering functionality
* @returns Entity type filter state and utilities
*/
function useEntityTypeFilter(): {
availableTypes: string[];
selectedTypes: string[];
setSelectedTypes: (types: string[]) => void;
};
/**
* Hook for fetching entities related to the current entity
* @param entity - Base entity to find relations for
* @param relationFilter - Filter for relation types and kinds
* @returns Related entities with loading state
*/
function useRelatedEntities(
entity: Entity,
relationFilter: { type?: string; kind?: string }
): {
entities: Entity[] | undefined;
loading: boolean;
error: Error | undefined;
};
/**
* Hook for starred entities management
* @returns Starred entities state and toggle functions
*/
function useStarredEntities(): {
starredEntities: Set<string>;
toggleStarredEntity: (entityRef: string) => Promise<void>;
isStarredEntity: (entityRef: string) => boolean;
};
/**
* Hook for individual starred entity state
* @param entityRef - Entity reference to check/toggle
* @returns Starred state and toggle function for specific entity
*/
function useStarredEntity(entityRef: string): {
isStarred: boolean;
toggleStarred: () => Promise<void>;
};
/**
* Hook for entity ownership checking
* @returns Ownership checking utilities
*/
function useEntityOwnership(): {
loading: boolean;
isOwnedEntity: (entity: Entity) => boolean;
};Usage Examples:
import {
useRelatedEntities,
useStarredEntities,
useEntityOwnership
} from '@backstage/plugin-catalog-react';
function EntityRelations() {
const { entity } = useEntity();
const { entities: relatedApis, loading } = useRelatedEntities(
entity,
{ type: 'apiProvidedBy', kind: 'api' }
);
if (loading) return <div>Loading related APIs...</div>;
return (
<div>
<h3>Provided APIs</h3>
{relatedApis?.map(api => (
<EntityRefLink key={api.metadata.name} entityRef={api} />
))}
</div>
);
}
function StarredEntityButton() {
const { entity } = useEntity();
const { isStarredEntity, toggleStarredEntity } = useStarredEntities();
const entityRef = `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`;
return (
<button onClick={() => toggleStarredEntity(entityRef)}>
{isStarredEntity(entityRef) ? '⭐ Starred' : '☆ Star'}
</button>
);
}Install with Tessl CLI
npx tessl i tessl/npm-backstage--plugin-catalog-react