diff --git a/.changeset/olive-rockets-drum.md b/.changeset/olive-rockets-drum.md
new file mode 100644
index 0000000000..e28ba6101a
--- /dev/null
+++ b/.changeset/olive-rockets-drum.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-scaffolder': minor
+---
+
+`MultiEntityPicker` uses `EntityDisplayName` instead of `humanizeEntityRef` to display entity.
diff --git a/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.test.tsx b/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.test.tsx
index bc0a5ed32d..4be07b139d 100644
--- a/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.test.tsx
+++ b/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.test.tsx
@@ -16,7 +16,11 @@
import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
-import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
+import {
+ CatalogApi,
+ catalogApiRef,
+ entityPresentationApiRef,
+} from '@backstage/plugin-catalog-react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { fireEvent, screen } from '@testing-library/react';
@@ -24,6 +28,7 @@ import React from 'react';
import { MultiEntityPicker } from './MultiEntityPicker';
import { MultiEntityPickerProps } from './schema';
import { ScaffolderRJSFFieldProps as FieldProps } from '@backstage/plugin-scaffolder-react';
+import { DefaultEntityPresentationApi } from '@backstage/plugin-catalog';
const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
apiVersion: 'scaffolder.backstage.io/v1beta3',
@@ -59,7 +64,15 @@ describe('', () => {
];
Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
+
{children}
);
diff --git a/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx b/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx
index 8f17bf1ea6..f8fc831976 100644
--- a/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx
+++ b/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx
@@ -25,7 +25,9 @@ import {
import { useApi } from '@backstage/core-plugin-api';
import {
catalogApiRef,
- humanizeEntityRef,
+ entityPresentationApiRef,
+ EntityDisplayName,
+ EntityRefPresentationSnapshot,
} from '@backstage/plugin-catalog-react';
import TextField from '@material-ui/core/TextField';
import FormControl from '@material-ui/core/FormControl';
@@ -64,33 +66,31 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => {
uiSchema['ui:options']?.defaultNamespace || undefined;
const catalogApi = useApi(catalogApiRef);
-
+ const entityPresentationApi = useApi(entityPresentationApiRef);
const { value: entities, loading } = useAsync(async () => {
const { items } = await catalogApi.getEntities(
catalogFilter ? { filter: catalogFilter } : undefined,
);
- return items;
+ const entityRefToPresentation = new Map<
+ string,
+ EntityRefPresentationSnapshot
+ >(
+ await Promise.all(
+ items.map(async item => {
+ const presentation = await entityPresentationApi.forEntity(item)
+ .promise;
+ return [stringifyEntityRef(item), presentation] as [
+ string,
+ EntityRefPresentationSnapshot,
+ ];
+ }),
+ ),
+ );
+ return { entities: items, entityRefToPresentation };
});
const allowArbitraryValues =
uiSchema['ui:options']?.allowArbitraryValues ?? true;
- const getLabel = useCallback(
- (ref: string) => {
- try {
- return humanizeEntityRef(
- parseEntityRef(ref, { defaultKind, defaultNamespace }),
- {
- defaultKind,
- defaultNamespace,
- },
- );
- } catch (err) {
- return ref;
- }
- },
- [defaultKind, defaultNamespace],
- );
-
const onSelect = useCallback(
(_: any, refs: (string | Entity)[], reason: AutocompleteChangeReason) => {
const values = refs
@@ -130,8 +130,8 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => {
);
useEffect(() => {
- if (entities?.length === 1) {
- onChange([stringifyEntityRef(entities[0])]);
+ if (entities?.entities?.length === 1) {
+ onChange([stringifyEntityRef(entities?.entities[0])]);
}
}, [entities, onChange]);
@@ -144,23 +144,18 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => {
formData && formData.includes(stringifyEntityRef(e)),
- ) ?? (allowArbitraryValues && formData ? formData.map(getLabel) : [])
- }
loading={loading}
onChange={onSelect}
- options={entities || []}
+ options={entities?.entities || []}
+ renderOption={option => }
getOptionLabel={option =>
// option can be a string due to freeSolo.
typeof option === 'string'
? option
- : humanizeEntityRef(option, { defaultKind, defaultNamespace })!
+ : entities?.entityRefToPresentation.get(stringifyEntityRef(option))
+ ?.entityRef!
}
autoSelect
freeSolo={allowArbitraryValues}
@@ -170,7 +165,10 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => {
label={title}
margin="dense"
helperText={description}
- FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}
+ FormHelperTextProps={{
+ margin: 'dense',
+ style: { marginLeft: 0 },
+ }}
variant="outlined"
required={required}
InputProps={{