Merge pull request #10201 from backstage/rugvip/use-entity
catalog-react: remove deprecated loading state of useEntity
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': minor
|
||||
---
|
||||
|
||||
**BREAKING**: The `useEntity` hook no longer returns loading or error states, and will throw an error if the entity is not immediately available. In practice this means that `useEntity` can only be used in contexts where the entity is guaranteed to have been loaded, for example inside an `EntityLayout`. To access the loading state of the entity, use `useAsyncEntity` instead.
|
||||
@@ -472,9 +472,6 @@ export function useAsyncEntity<
|
||||
// @public
|
||||
export function useEntity<TEntity extends Entity = Entity>(): {
|
||||
entity: TEntity;
|
||||
loading: boolean;
|
||||
error?: Error;
|
||||
refresh?: VoidFunction;
|
||||
};
|
||||
|
||||
// @public
|
||||
|
||||
@@ -16,19 +16,21 @@
|
||||
|
||||
import React from 'react';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { useEntity, EntityProvider, AsyncEntityProvider } from './useEntity';
|
||||
import {
|
||||
useEntity,
|
||||
useAsyncEntity,
|
||||
EntityProvider,
|
||||
AsyncEntityProvider,
|
||||
} from './useEntity';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
|
||||
describe('EntityProvider', () => {
|
||||
it('should provide no entity', async () => {
|
||||
describe('useEntity', () => {
|
||||
it('should throw if no entity is provided', async () => {
|
||||
const { result } = renderHook(() => useEntity(), {
|
||||
wrapper: ({ children }) => <EntityProvider children={children} />,
|
||||
});
|
||||
|
||||
expect(result.current.entity).toBe(undefined);
|
||||
expect(result.current.loading).toBe(true);
|
||||
expect(result.current.error).toBe(undefined);
|
||||
expect(result.current.refresh).toBe(undefined);
|
||||
expect(result.error?.message).toMatch(/entity has not been loaded/);
|
||||
});
|
||||
|
||||
it('should provide an entity', async () => {
|
||||
@@ -40,15 +42,12 @@ describe('EntityProvider', () => {
|
||||
});
|
||||
|
||||
expect(result.current.entity).toBe(entity);
|
||||
expect(result.current.loading).toBe(false);
|
||||
expect(result.current.error).toBe(undefined);
|
||||
expect(result.current.refresh).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('AsyncEntityProvider', () => {
|
||||
describe('useAsyncEntity', () => {
|
||||
it('should provide no entity', async () => {
|
||||
const { result } = renderHook(() => useEntity(), {
|
||||
const { result } = renderHook(() => useAsyncEntity(), {
|
||||
wrapper: ({ children }) => (
|
||||
<AsyncEntityProvider loading={false} children={children} />
|
||||
),
|
||||
@@ -63,7 +62,7 @@ describe('AsyncEntityProvider', () => {
|
||||
it('should provide an entity', async () => {
|
||||
const entity = { kind: 'MyEntity' } as Entity;
|
||||
const refresh = () => {};
|
||||
const { result } = renderHook(() => useEntity(), {
|
||||
const { result } = renderHook(() => useAsyncEntity(), {
|
||||
wrapper: ({ children }) => (
|
||||
<AsyncEntityProvider
|
||||
loading={false}
|
||||
@@ -82,7 +81,7 @@ describe('AsyncEntityProvider', () => {
|
||||
|
||||
it('should provide an error', async () => {
|
||||
const error = new Error('oh no');
|
||||
const { result } = renderHook(() => useEntity(), {
|
||||
const { result } = renderHook(() => useAsyncEntity(), {
|
||||
wrapper: ({ children }) => (
|
||||
<AsyncEntityProvider
|
||||
loading={false}
|
||||
|
||||
@@ -103,12 +103,6 @@ export const EntityProvider = ({ entity, children }: EntityProviderProps) => (
|
||||
*/
|
||||
export function useEntity<TEntity extends Entity = Entity>(): {
|
||||
entity: TEntity;
|
||||
/** @deprecated use {@link useAsyncEntity} instead */
|
||||
loading: boolean;
|
||||
/** @deprecated use {@link useAsyncEntity} instead */
|
||||
error?: Error;
|
||||
/** @deprecated use {@link useAsyncEntity} instead */
|
||||
refresh?: VoidFunction;
|
||||
} {
|
||||
const versionedHolder =
|
||||
useVersionedContext<{ 1: EntityLoadingStatus }>('entity-context');
|
||||
@@ -123,18 +117,12 @@ export function useEntity<TEntity extends Entity = Entity>(): {
|
||||
}
|
||||
|
||||
if (!value.entity) {
|
||||
// Once we have removed the additional fields from being returned we can drop this deprecation
|
||||
// and move to the error instead.
|
||||
// throw new Error('useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead.');
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'DEPRECATION: useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead. This warning will be replaced with an error in future releases.',
|
||||
throw new Error(
|
||||
'useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead.',
|
||||
);
|
||||
}
|
||||
|
||||
const { entity, loading, error, refresh } = value;
|
||||
return { entity: entity as TEntity, loading, error, refresh };
|
||||
return { entity: value.entity as TEntity };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
import { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { useEntityPermission } from './useEntityPermission';
|
||||
import { useEntity } from './useEntity';
|
||||
import { useAsyncEntity } from './useEntity';
|
||||
import { usePermission } from '@backstage/plugin-permission-react';
|
||||
|
||||
jest.mock('./useEntity', () => ({
|
||||
...jest.requireActual('./useEntity'),
|
||||
useEntity: jest.fn(),
|
||||
useAsyncEntity: jest.fn(),
|
||||
}));
|
||||
jest.mock('@backstage/plugin-permission-react', () => ({
|
||||
...jest.requireActual('@backstage/plugin-permission-react'),
|
||||
usePermission: jest.fn(),
|
||||
}));
|
||||
const useEntityMock = useEntity as jest.Mock;
|
||||
const useEntityMock = useAsyncEntity as jest.Mock;
|
||||
const usePermissionMock = usePermission as jest.Mock;
|
||||
|
||||
describe('useEntityPermission', () => {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { Permission } from '@backstage/plugin-permission-common';
|
||||
import { usePermission } from '@backstage/plugin-permission-react';
|
||||
import { useEntity } from './useEntity';
|
||||
import { useAsyncEntity } from './useEntity';
|
||||
|
||||
/**
|
||||
* A thin wrapper around the
|
||||
@@ -35,7 +35,11 @@ export function useEntityPermission(permission: Permission): {
|
||||
allowed: boolean;
|
||||
error?: Error;
|
||||
} {
|
||||
const { entity, loading: loadingEntity, error: entityError } = useEntity();
|
||||
const {
|
||||
entity,
|
||||
loading: loadingEntity,
|
||||
error: entityError,
|
||||
} = useAsyncEntity();
|
||||
const {
|
||||
allowed,
|
||||
loading: loadingPermission,
|
||||
|
||||
Reference in New Issue
Block a user