Use a versioned context for useEntityList
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Use a versioned context for `useEntityList`, to better work with mixed `@backstage/plugin-catalog-react` versions.
|
||||
@@ -322,7 +322,7 @@ export const EntityLifecyclePicker: (props: {
|
||||
initialFilter?: string[];
|
||||
}) => JSX_2.Element;
|
||||
|
||||
// @public
|
||||
// @public @deprecated
|
||||
export const EntityListContext: Context<
|
||||
EntityListContextProps<any> | undefined
|
||||
>;
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
|
||||
import { PropsWithChildren, useCallback, useMemo, useState } from 'react';
|
||||
import { createVersionedValueMap } from '@backstage/version-bridge';
|
||||
import {
|
||||
DefaultEntityFilters,
|
||||
EntityListContext,
|
||||
EntityListContextProps,
|
||||
NewEntityListContext,
|
||||
OldEntityListContext,
|
||||
} from './hooks/useEntityListProvider';
|
||||
|
||||
/**
|
||||
@@ -81,8 +83,18 @@ export function MockEntityListContextProvider<
|
||||
);
|
||||
|
||||
return (
|
||||
<EntityListContext.Provider value={resolvedValue}>
|
||||
<NewEntityListContext.Provider
|
||||
value={createVersionedValueMap({ 1: resolvedValue })}
|
||||
>
|
||||
{children}
|
||||
</EntityListContext.Provider>
|
||||
</NewEntityListContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new context for entity listing and filtering.
|
||||
*
|
||||
* @public
|
||||
* @deprecated Please use `EntityListProvider` and `EntityListProvider` instead.
|
||||
*/
|
||||
export const EntityListContext = OldEntityListContext;
|
||||
|
||||
@@ -24,11 +24,7 @@ export type {
|
||||
EntityProviderProps,
|
||||
AsyncEntityProviderProps,
|
||||
} from './useEntity';
|
||||
export {
|
||||
EntityListContext,
|
||||
EntityListProvider,
|
||||
useEntityList,
|
||||
} from './useEntityListProvider';
|
||||
export { EntityListProvider, useEntityList } from './useEntityListProvider';
|
||||
export type {
|
||||
DefaultEntityFilters,
|
||||
EntityListContextProps,
|
||||
|
||||
@@ -42,7 +42,13 @@ import {
|
||||
} from '../filters';
|
||||
import { createDeferred } from '@backstage/types';
|
||||
import { EntityListPagination } from '../types';
|
||||
import { EntityListProvider, useEntityList } from './useEntityListProvider';
|
||||
import {
|
||||
EntityListContextProps,
|
||||
EntityListProvider,
|
||||
NewEntityListContext,
|
||||
useEntityList,
|
||||
} from './useEntityListProvider';
|
||||
import { createVersionedValueMap } from '@backstage/version-bridge';
|
||||
|
||||
const entities: Entity[] = [
|
||||
{
|
||||
@@ -1048,3 +1054,59 @@ describe(`<EntityListProvider pagination={{ mode: 'offset' }} />`, () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('versioned context', () => {
|
||||
it('should work explicitly with new versioned contexts', () => {
|
||||
const value: EntityListContextProps<any> = {
|
||||
filters: {},
|
||||
entities: [],
|
||||
backendEntities: [],
|
||||
updateFilters: jest.fn(),
|
||||
queryParameters: {},
|
||||
loading: true,
|
||||
limit: 277,
|
||||
setLimit: jest.fn(),
|
||||
setOffset: jest.fn(),
|
||||
paginationMode: 'none',
|
||||
};
|
||||
|
||||
const { result } = renderHook(() => useEntityList(), {
|
||||
wrapper: ({ children }) => {
|
||||
const InitialFiltersWrapper = (f: PropsWithChildren<{}>) => {
|
||||
const { updateFilters } = useEntityList();
|
||||
useMountEffect(() => {
|
||||
updateFilters({
|
||||
kind: new EntityKindFilter('component', 'Component'),
|
||||
});
|
||||
});
|
||||
return <>{f.children}</>;
|
||||
};
|
||||
|
||||
return (
|
||||
<MemoryRouter initialEntries={['/catalog']}>
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
[configApiRef, mockApis.config()],
|
||||
[catalogApiRef, mockCatalogApi],
|
||||
[identityApiRef, mockIdentityApi],
|
||||
[storageApiRef, mockApis.storage()],
|
||||
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
|
||||
[alertApiRef, { post: jest.fn() }],
|
||||
[translationApiRef, mockApis.translation()],
|
||||
[errorApiRef, { error$: jest.fn(), post: jest.fn() }],
|
||||
]}
|
||||
>
|
||||
<NewEntityListContext.Provider
|
||||
value={createVersionedValueMap({ 1: value })}
|
||||
>
|
||||
<InitialFiltersWrapper>{children}</InitialFiltersWrapper>
|
||||
</NewEntityListContext.Provider>
|
||||
</TestApiProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.current.limit).toBe(277);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
import { QueryEntitiesResponse } from '@backstage/catalog-client';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
createVersionedContext,
|
||||
createVersionedValueMap,
|
||||
useVersionedContext,
|
||||
} from '@backstage/version-bridge';
|
||||
import { compact, isEqual } from 'lodash';
|
||||
import qs from 'qs';
|
||||
import {
|
||||
@@ -122,11 +127,17 @@ export type EntityListContextProps<
|
||||
paginationMode: PaginationMode;
|
||||
};
|
||||
|
||||
// This context has support for multiple concurrent versions of this package.
|
||||
// It is currently used in parallel with the old context in order to provide
|
||||
// a smooth transition, but will eventually be the only context we use.
|
||||
export const NewEntityListContext = createVersionedContext<{
|
||||
1: EntityListContextProps<any>;
|
||||
}>('entity-list-context');
|
||||
|
||||
/**
|
||||
* Creates new context for entity listing and filtering.
|
||||
* @public
|
||||
*/
|
||||
export const EntityListContext = createContext<
|
||||
export const OldEntityListContext = createContext<
|
||||
EntityListContextProps<any> | undefined
|
||||
>(undefined);
|
||||
|
||||
@@ -487,9 +498,13 @@ export const EntityListProvider = <EntityFilters extends DefaultEntityFilters>(
|
||||
);
|
||||
|
||||
return (
|
||||
<EntityListContext.Provider value={value}>
|
||||
{props.children}
|
||||
</EntityListContext.Provider>
|
||||
<OldEntityListContext.Provider value={value}>
|
||||
<NewEntityListContext.Provider
|
||||
value={createVersionedValueMap({ 1: value })}
|
||||
>
|
||||
{props.children}
|
||||
</NewEntityListContext.Provider>
|
||||
</OldEntityListContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -500,8 +515,22 @@ export const EntityListProvider = <EntityFilters extends DefaultEntityFilters>(
|
||||
export function useEntityList<
|
||||
EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,
|
||||
>(): EntityListContextProps<EntityFilters> {
|
||||
const context = useContext(EntityListContext);
|
||||
if (!context)
|
||||
throw new Error('useEntityList must be used within EntityListProvider');
|
||||
return context;
|
||||
const versionedHolder = useVersionedContext<{
|
||||
1: EntityListContextProps<any>;
|
||||
}>('entity-list-context');
|
||||
const oldContext = useContext(OldEntityListContext);
|
||||
|
||||
if (versionedHolder) {
|
||||
const value = versionedHolder.atVersion(1);
|
||||
if (!value) {
|
||||
throw new Error('EntityListContext v1 not available');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
if (oldContext) {
|
||||
return oldContext;
|
||||
}
|
||||
|
||||
throw new Error('useEntityList must be used within EntityListProvider');
|
||||
}
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
import { PropsWithChildren, useCallback, useMemo, useState } from 'react';
|
||||
import {
|
||||
DefaultEntityFilters,
|
||||
EntityListContext,
|
||||
EntityListContextProps,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { createVersionedValueMap } from '@backstage/version-bridge';
|
||||
import { NewEntityListContext } from '../hooks/useEntityListProvider';
|
||||
|
||||
/**
|
||||
* Simplifies testing of code that uses the entity list hooks.
|
||||
@@ -82,8 +83,10 @@ export function MockEntityListContextProvider<
|
||||
);
|
||||
|
||||
return (
|
||||
<EntityListContext.Provider value={resolvedValue}>
|
||||
<NewEntityListContext.Provider
|
||||
value={createVersionedValueMap({ 1: resolvedValue })}
|
||||
>
|
||||
{children}
|
||||
</EntityListContext.Provider>
|
||||
</NewEntityListContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user