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 d9804a8cba..0a0fcfdc2b 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,
+ EntityRefPresentationSnapshot,
+ EntityDisplayName,
} from '@backstage/plugin-catalog-react';
import TextField from '@material-ui/core/TextField';
import FormControl from '@material-ui/core/FormControl';
@@ -64,40 +66,35 @@ 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 primaryTitles: string[] = [];
+ for (const item of items) {
+ const entityPresentation = (await entityPresentationApi.forEntity(item)
+ ?.promise) as EntityRefPresentationSnapshot[];
+ entityPresentation.map(e => primaryTitles.push(e.primaryTitle));
+ }
+
+ return { items, primaryTitles };
});
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
.map(ref => {
if (typeof ref !== 'string') {
// if ref does not exist: pass 'undefined' to trigger validation for required value
- return ref ? stringifyEntityRef(ref as Entity) : undefined;
+ return ref
+ ? entityPresentationApi.forEntity(ref, {
+ defaultKind,
+ defaultNamespace,
+ }).snapshot.entityRef
+ : undefined;
}
if (reason === 'blur' || reason === 'create-option') {
// Add in default namespace, etc.
@@ -126,14 +123,21 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => {
onChange(values);
},
- [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],
+ [
+ onChange,
+ formData,
+ defaultKind,
+ defaultNamespace,
+ allowArbitraryValues,
+ entityPresentationApi,
+ ],
);
useEffect(() => {
- if (entities?.length === 1) {
- onChange([stringifyEntityRef(entities[0])]);
+ if (entities?.items?.length === 1) {
+ onChange([stringifyEntityRef(entities.items[0])]);
}
- }, [entities, onChange]);
+ }, [entities?.items, onChange]);
return (
{
formData && formData.includes(stringifyEntityRef(e)),
- ) ?? (allowArbitraryValues && formData ? formData.map(getLabel) : [])
+ ) ??
+ (allowArbitraryValues && formData
+ ? entities?.primaryTitles || []
+ : [])
}
loading={loading}
onChange={onSelect}
- options={entities || []}
+ options={entities?.items || []}
+ renderOption={option => }
getOptionLabel={option =>
// option can be a string due to freeSolo.
typeof option === 'string'
? option
- : humanizeEntityRef(option, { defaultKind, defaultNamespace })!
+ : entityPresentationApi.forEntity(option, {
+ defaultKind,
+ defaultNamespace,
+ }).snapshot.entityRef!
}
autoSelect
freeSolo={allowArbitraryValues}
@@ -170,7 +181,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={params.InputProps}