Merge pull request #24405 from Nikunj0601/backup-backup/EntityListComponent-uses-CatalogAPI
feat(EntityListComponent): use EntityPresentationApi instead of humanizeEntityRef to display entity
This commit is contained in:
@@ -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,16 @@
|
||||
* 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 } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
EntityDisplayName,
|
||||
EntityRefLink,
|
||||
humanizeEntityRef,
|
||||
entityPresentationApiRef,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import Collapse from '@material-ui/core/Collapse';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
@@ -38,12 +43,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}.
|
||||
*
|
||||
@@ -76,9 +75,8 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
|
||||
withLinks = false,
|
||||
} = props;
|
||||
|
||||
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}
|
||||
@@ -124,12 +133,9 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
|
||||
>
|
||||
<List component="div" disablePadding dense>
|
||||
{sortEntities(r.entities).map(entity => {
|
||||
const Icon = app.getSystemIcon(
|
||||
`kind:${entity.kind.toLocaleLowerCase('en-US')}`,
|
||||
);
|
||||
return (
|
||||
<ListItem
|
||||
key={humanizeEntityRef(entity)}
|
||||
key={stringifyEntityRef(entity)}
|
||||
className={classes.nested}
|
||||
{...(withLinks
|
||||
? {
|
||||
@@ -139,8 +145,9 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
<ListItemIcon>{Icon && <Icon />}</ListItemIcon>
|
||||
<ListItemText primary={humanizeEntityRef(entity)} />
|
||||
<ListItemText
|
||||
primary={<EntityDisplayName entityRef={entity} />}
|
||||
/>
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
|
||||
+86
-40
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user