feat: EntityListComponent now uses Catalog Presentation API

Signed-off-by: NIKUNJ LALITKUMAR HUDKA <nikunjhudka123@gmail.com>
This commit is contained in:
NIKUNJ LALITKUMAR HUDKA
2024-04-19 09:46:44 -03:00
parent 4eeb3ed7fc
commit dbde8c0d6f
3 changed files with 118 additions and 52 deletions
+1
View File
@@ -78,6 +78,7 @@
"@backstage/cli": "workspace:^",
"@backstage/core-app-api": "workspace:^",
"@backstage/dev-utils": "workspace:^",
"@backstage/plugin-catalog": "workspace:^",
"@backstage/test-utils": "workspace:^",
"@testing-library/dom": "^10.0.0",
"@testing-library/jest-dom": "^6.0.0",
@@ -14,11 +14,15 @@
* limitations under the License.
*/
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
import { useApp } from '@backstage/core-plugin-api';
import {
Entity,
CompoundEntityRef,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { useApi, useApp } from '@backstage/core-plugin-api';
import {
EntityRefLink,
humanizeEntityRef,
entityPresentationApiRef,
} from '@backstage/plugin-catalog-react';
import Collapse from '@material-ui/core/Collapse';
import IconButton from '@material-ui/core/IconButton';
@@ -38,12 +42,6 @@ const useStyles = makeStyles(theme => ({
},
}));
function sortEntities(entities: Array<CompoundEntityRef | Entity>) {
return entities.sort((a, b) =>
humanizeEntityRef(a).localeCompare(humanizeEntityRef(b)),
);
}
/**
* Props for {@link EntityListComponent}.
*
@@ -78,7 +76,7 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
const app = useApp();
const classes = useStyles();
const entityPresentationApi = useApi(entityPresentationApiRef);
const [expandedUrls, setExpandedUrls] = useState<string[]>([]);
const handleClick = (url: string) => {
@@ -87,6 +85,17 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
);
};
function sortEntities(entities: Array<CompoundEntityRef | Entity>) {
return entities.sort((a, b) =>
entityPresentationApi
.forEntity(stringifyEntityRef(a))
.snapshot.entityRef.localeCompare(
entityPresentationApi.forEntity(stringifyEntityRef(b)).snapshot
.entityRef,
),
);
}
return (
<List>
{firstListItem}
@@ -129,7 +138,11 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
);
return (
<ListItem
key={humanizeEntityRef(entity)}
key={
entityPresentationApi.forEntity(
stringifyEntityRef(entity),
).snapshot.entityRef
}
className={classes.nested}
{...(withLinks
? {
@@ -140,7 +153,13 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
: {})}
>
<ListItemIcon>{Icon && <Icon />}</ListItemIcon>
<ListItemText primary={humanizeEntityRef(entity)} />
<ListItemText
primary={
entityPresentationApi.forEntity(
stringifyEntityRef(entity),
).snapshot.entityRef
}
/>
</ListItem>
);
})}
@@ -14,14 +14,22 @@
* limitations under the License.
*/
import { renderInTestApp } from '@backstage/test-utils';
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
import { act, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { AnalyzeResult } from '../../api';
import { StepPrepareSelectLocations } from './StepPrepareSelectLocations';
import {
CatalogApi,
catalogApiRef,
entityPresentationApiRef,
} from '@backstage/plugin-catalog-react';
import { DefaultEntityPresentationApi } from '@backstage/plugin-catalog';
import { Entity } from '@backstage/catalog-model';
describe('<StepPrepareSelectLocations />', () => {
let entities: Entity[];
const analyzeResult = {
type: 'locations',
locations: [
@@ -53,17 +61,43 @@ describe('<StepPrepareSelectLocations />', () => {
],
} as Extract<AnalyzeResult, { type: 'locations' }>;
const catalogApi: jest.Mocked<CatalogApi> = {
getLocationById: jest.fn(),
getEntityByName: jest.fn(),
getEntities: jest.fn(async () => ({ items: entities })),
addLocation: jest.fn(),
getLocationByRef: jest.fn(),
removeEntityByUid: jest.fn(),
} as any;
let Wrapper: React.ComponentType<React.PropsWithChildren<{}>>;
beforeEach(() => {
jest.resetAllMocks();
catalogApi.getEntities.mockResolvedValue({ items: entities });
Wrapper = ({ children }: { children?: React.ReactNode }) => (
<TestApiProvider
apis={[
[catalogApiRef, catalogApi],
[
entityPresentationApiRef,
DefaultEntityPresentationApi.create({ catalogApi }),
],
]}
>
{children}
</TestApiProvider>
);
});
it('renders display locations to be added', async () => {
await renderInTestApp(
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>,
<Wrapper>
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>
</Wrapper>,
);
expect(screen.getByText('url-1')).toBeInTheDocument();
@@ -96,11 +130,13 @@ describe('<StepPrepareSelectLocations />', () => {
} as Extract<AnalyzeResult, { type: 'locations' }>;
await renderInTestApp(
<StepPrepareSelectLocations
analyzeResult={analyzeResultWithExistingLocation}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>,
<Wrapper>
<StepPrepareSelectLocations
analyzeResult={analyzeResultWithExistingLocation}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>
</Wrapper>,
);
expect(screen.getByText(/my-target/)).toBeInTheDocument();
@@ -112,11 +148,13 @@ describe('<StepPrepareSelectLocations />', () => {
it('should select and deselect all', async () => {
await renderInTestApp(
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>,
<Wrapper>
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>
</Wrapper>,
);
const checkboxes = screen.getAllByRole('checkbox');
@@ -144,15 +182,17 @@ describe('<StepPrepareSelectLocations />', () => {
it('should preselect prepared locations', async () => {
await renderInTestApp(
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
prepareResult={{
...analyzeResult,
locations: [...analyzeResult.locations.slice(0, 1)],
}}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>,
<Wrapper>
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
prepareResult={{
...analyzeResult,
locations: [...analyzeResult.locations.slice(0, 1)],
}}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>
</Wrapper>,
);
const checkboxes = screen.getAllByRole('checkbox');
@@ -164,11 +204,13 @@ describe('<StepPrepareSelectLocations />', () => {
it('should select items', async () => {
await renderInTestApp(
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>,
<Wrapper>
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={() => undefined}
onGoBack={() => undefined}
/>
</Wrapper>,
);
const checkboxes = screen.getAllByRole('checkbox');
@@ -193,11 +235,13 @@ describe('<StepPrepareSelectLocations />', () => {
const onGoBack = jest.fn();
await renderInTestApp(
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={() => undefined}
onGoBack={onGoBack}
/>,
<Wrapper>
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={() => undefined}
onGoBack={onGoBack}
/>
</Wrapper>,
);
await act(async () => {
@@ -211,11 +255,13 @@ describe('<StepPrepareSelectLocations />', () => {
const onPrepare = jest.fn();
await renderInTestApp(
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={onPrepare}
onGoBack={() => undefined}
/>,
<Wrapper>
<StepPrepareSelectLocations
analyzeResult={analyzeResult}
onPrepare={onPrepare}
onGoBack={() => undefined}
/>
</Wrapper>,
);
const checkboxes = screen.getAllByRole('checkbox');