diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx
index b78d3add9e..00508593f5 100644
--- a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx
+++ b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import { type EntityFilterQuery } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
@@ -32,7 +33,15 @@ describe('', () => {
const onChange = jest.fn();
const schema = {};
const required = false;
- let uiSchema: { 'ui:options': { allowedKinds?: string[] } };
+ let uiSchema: {
+ 'ui:options': {
+ allowedKinds?: string[];
+ defaultKind?: string;
+ allowArbitraryValues?: boolean;
+ defaultNamespace?: string | false;
+ catalogFilter?: EntityFilterQuery;
+ };
+ };
const rawErrors: string[] = [];
const formData = undefined;
@@ -63,7 +72,7 @@ describe('', () => {
afterEach(() => jest.resetAllMocks());
- describe('without allowedKinds', () => {
+ describe('without catalogFilter and allowedKinds', () => {
beforeEach(() => {
uiSchema = { 'ui:options': {} };
props = {
@@ -108,7 +117,7 @@ describe('', () => {
catalogApi.getEntities.mockResolvedValue({ items: entities });
});
- it('searches for users and groups', async () => {
+ it('searches for users', async () => {
await renderInTestApp(
@@ -122,4 +131,93 @@ describe('', () => {
});
});
});
+
+ describe('with catalogFilter', () => {
+ beforeEach(() => {
+ uiSchema = {
+ 'ui:options': {
+ catalogFilter: [
+ {
+ kind: ['Group'],
+ 'spec.type': 'team',
+ },
+ ],
+ },
+ };
+ props = {
+ onChange,
+ schema,
+ required,
+ uiSchema,
+ rawErrors,
+ formData,
+ } as unknown as FieldProps;
+
+ catalogApi.getEntities.mockResolvedValue({ items: entities });
+ });
+
+ it('searches for group entities of type team', async () => {
+ await renderInTestApp(
+
+
+ ,
+ );
+
+ expect(catalogApi.getEntities).toHaveBeenCalledWith({
+ filter: [
+ {
+ kind: ['Group'],
+ 'spec.type': 'team',
+ },
+ ],
+ });
+ });
+ });
+
+ describe('catalogFilter should take precedence over allowedKinds', () => {
+ beforeEach(() => {
+ uiSchema = {
+ 'ui:options': {
+ allowedKinds: ['User'],
+ catalogFilter: [
+ {
+ kind: ['Group', 'User'],
+ },
+ {
+ 'spec.type': ['team', 'business-unit'],
+ },
+ ],
+ },
+ };
+ props = {
+ onChange,
+ schema,
+ required,
+ uiSchema,
+ rawErrors,
+ formData,
+ } as unknown as FieldProps;
+
+ catalogApi.getEntities.mockResolvedValue({ items: entities });
+ });
+
+ it('searches for users and groups or teams and business units', async () => {
+ await renderInTestApp(
+
+
+ ,
+ );
+
+ expect(catalogApi.getEntities).toHaveBeenCalledWith({
+ filter: [
+ {
+ kind: ['Group', 'User'],
+ },
+ {
+ 'spec.type': ['team', 'business-unit'],
+ },
+ ],
+ });
+ });
+ });
});
diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx
index 1c4c356906..5c69e73e12 100644
--- a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx
+++ b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx
@@ -33,14 +33,16 @@ export const OwnerPicker = (props: OwnerPickerProps) => {
} = props;
const defaultNamespace = uiSchema['ui:options']?.defaultNamespace;
+ const allowedKinds = uiSchema['ui:options']?.allowedKinds;
+
+ const catalogFilter = uiSchema['ui:options']?.catalogFilter || {
+ kind: allowedKinds || ['Group', 'User'],
+ };
const ownerUiSchema = {
...uiSchema,
'ui:options': {
- allowedKinds: (uiSchema['ui:options']?.allowedKinds || [
- 'Group',
- 'User',
- ]) as string[],
+ catalogFilter,
defaultKind: 'Group',
allowArbitraryValues:
uiSchema['ui:options']?.allowArbitraryValues ?? true,
diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts
index 56edef1343..4e9ca8ca31 100644
--- a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts
+++ b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts
@@ -15,6 +15,7 @@
*/
import { z } from 'zod';
import { makeFieldSchemaFromZod } from '../utils';
+import { entityQueryFilterExpressionSchema } from '../EntityPicker/schema';
/**
* @public
@@ -39,6 +40,11 @@ export const OwnerPickerFieldSchema = makeFieldSchemaFromZod(
.describe(
'The default namespace. Options with this namespace will not be prefixed.',
),
+ catalogFilter: z
+ .array(entityQueryFilterExpressionSchema)
+ .or(entityQueryFilterExpressionSchema)
+ .optional()
+ .describe('List of key-value filter expression for entities'),
}),
);