Merge pull request #31253 from drodil/nfs_scaffolder_fields

feat(scaffolder): add missing form fields for the nfs
This commit is contained in:
Ben Lambert
2025-09-26 13:38:38 +02:00
committed by GitHub
32 changed files with 462 additions and 32 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Added missing form fields for the new frontend system.
+120
View File
@@ -226,6 +226,126 @@ const _default: OverridableFrontendPlugin<
routeRef?: RouteRef;
};
}>;
'scaffolder-form-field:scaffolder/entity-name-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'entity-name-picker';
config: {};
configInput: {};
output: ExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>;
inputs: {};
params: {
field: () => Promise<FormField>;
};
}>;
'scaffolder-form-field:scaffolder/entity-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'entity-picker';
config: {};
configInput: {};
output: ExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>;
inputs: {};
params: {
field: () => Promise<FormField>;
};
}>;
'scaffolder-form-field:scaffolder/entity-tags-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'entity-tags-picker';
config: {};
configInput: {};
output: ExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>;
inputs: {};
params: {
field: () => Promise<FormField>;
};
}>;
'scaffolder-form-field:scaffolder/multi-entity-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'multi-entity-picker';
config: {};
configInput: {};
output: ExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>;
inputs: {};
params: {
field: () => Promise<FormField>;
};
}>;
'scaffolder-form-field:scaffolder/my-groups-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'my-groups-picker';
config: {};
configInput: {};
output: ExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>;
inputs: {};
params: {
field: () => Promise<FormField>;
};
}>;
'scaffolder-form-field:scaffolder/owned-entity-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'owned-entity-picker';
config: {};
configInput: {};
output: ExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>;
inputs: {};
params: {
field: () => Promise<FormField>;
};
}>;
'scaffolder-form-field:scaffolder/owner-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'owner-picker';
config: {};
configInput: {};
output: ExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>;
inputs: {};
params: {
field: () => Promise<FormField>;
};
}>;
'scaffolder-form-field:scaffolder/repo-branch-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'repo-branch-picker';
config: {};
configInput: {};
output: ExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>;
inputs: {};
params: {
field: () => Promise<FormField>;
};
}>;
'scaffolder-form-field:scaffolder/repo-url-picker': ExtensionDefinition<{
kind: 'scaffolder-form-field';
name: 'repo-url-picker';
+2 -2
View File
@@ -404,11 +404,11 @@ export const repoPickerValidation: (
export const RepoUrlPickerFieldExtension: FieldExtensionComponent_2<
string,
{
allowedHosts?: string[] | undefined;
allowedOrganizations?: string[] | undefined;
allowedOwners?: string[] | undefined;
allowedProjects?: string[] | undefined;
allowedRepos?: string[] | undefined;
allowedHosts?: string[] | undefined;
requestUserCredentials?:
| {
secretsKey: string;
@@ -431,11 +431,11 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent_2<
export const RepoUrlPickerFieldSchema: FieldSchema_2<
string,
{
allowedHosts?: string[] | undefined;
allowedOrganizations?: string[] | undefined;
allowedOwners?: string[] | undefined;
allowedProjects?: string[] | undefined;
allowedRepos?: string[] | undefined;
allowedHosts?: string[] | undefined;
requestUserCredentials?:
| {
secretsKey: string;
+64 -3
View File
@@ -19,13 +19,13 @@ import {
convertLegacyRouteRef,
} from '@backstage/core-compat-api';
import {
NavItemBlueprint,
PageBlueprint,
ApiBlueprint,
createExtensionInput,
discoveryApiRef,
fetchApiRef,
identityApiRef,
createExtensionInput,
NavItemBlueprint,
PageBlueprint,
} from '@backstage/frontend-plugin-api';
import { rootRouteRef } from '../routes';
import CreateComponentIcon from '@material-ui/icons/AddCircleOutline';
@@ -72,6 +72,67 @@ export const repoUrlPickerFormField = FormFieldBlueprint.make({
},
});
export const entityNamePickerFormField = FormFieldBlueprint.make({
name: 'entity-name-picker',
params: {
field: () =>
import('./fields/EntityNamePicker').then(m => m.EntityNamePicker),
},
});
export const entityPickerFormField = FormFieldBlueprint.make({
name: 'entity-picker',
params: {
field: () => import('./fields/EntityPicker').then(m => m.EntityPicker),
},
});
export const ownerPickerFormField = FormFieldBlueprint.make({
name: 'owner-picker',
params: {
field: () => import('./fields/OwnerPicker').then(m => m.OwnerPicker),
},
});
export const entityTagsPickerFormField = FormFieldBlueprint.make({
name: 'entity-tags-picker',
params: {
field: () =>
import('./fields/EntityTagsPicker').then(m => m.EntityTagsPicker),
},
});
export const multiEntityPickerFormField = FormFieldBlueprint.make({
name: 'multi-entity-picker',
params: {
field: () =>
import('./fields/MultiEntityPicker').then(m => m.MultiEntityPicker),
},
});
export const myGroupsPickerFormField = FormFieldBlueprint.make({
name: 'my-groups-picker',
params: {
field: () => import('./fields/MyGroupsPicker').then(m => m.MyGroupsPicker),
},
});
export const ownedEntityPickerFormField = FormFieldBlueprint.make({
name: 'owned-entity-picker',
params: {
field: () =>
import('./fields/OwnedEntityPicker').then(m => m.OwnedEntityPicker),
},
});
export const repoBranchPickerFormField = FormFieldBlueprint.make({
name: 'repo-branch-picker',
params: {
field: () =>
import('./fields/RepoBranchPicker').then(m => m.RepoBranchPicker),
},
});
export const scaffolderApi = ApiBlueprint.make({
params: defineParams =>
defineParams({
@@ -0,0 +1,28 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import {
EntityNamePicker as Component,
EntityNamePickerFieldSchema,
entityNamePickerValidation,
} from '../../components/fields/EntityNamePicker';
export const EntityNamePicker = createFormField({
component: Component,
name: 'EntityNamePicker',
validation: entityNamePickerValidation,
schema: EntityNamePickerFieldSchema,
});
@@ -0,0 +1,26 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import {
EntityPicker as Component,
EntityPickerFieldSchema,
} from '../../components/fields/EntityPicker';
export const EntityPicker = createFormField({
component: Component,
name: 'EntityPicker',
schema: EntityPickerFieldSchema,
});
@@ -0,0 +1,26 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import {
EntityTagsPicker as Component,
EntityTagsPickerFieldSchema,
} from '../../components/fields/EntityTagsPicker';
export const EntityTagsPicker = createFormField({
component: Component,
name: 'EntityTagsPicker',
schema: EntityTagsPickerFieldSchema,
});
@@ -0,0 +1,26 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import {
MultiEntityPicker as Component,
MultiEntityPickerFieldSchema,
} from '../../components/fields/MultiEntityPicker';
export const MultiEntityPicker = createFormField({
component: Component,
name: 'MultiEntityPicker',
schema: MultiEntityPickerFieldSchema,
});
@@ -0,0 +1,26 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import {
MyGroupsPicker as Component,
MyGroupsPickerFieldSchema,
} from '../../components/fields/MyGroupsPicker';
export const MyGroupsPicker = createFormField({
component: Component,
name: 'MyGroupsPicker',
schema: MyGroupsPickerFieldSchema,
});
@@ -0,0 +1,26 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import {
OwnedEntityPicker as Component,
OwnedEntityPickerFieldSchema,
} from '../../components/fields/OwnedEntityPicker';
export const OwnedEntityPicker = createFormField({
component: Component,
name: 'OwnedEntityPicker',
schema: OwnedEntityPickerFieldSchema,
});
@@ -0,0 +1,26 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import {
OwnerPicker as Component,
OwnerPickerFieldSchema,
} from '../../components/fields/OwnerPicker';
export const OwnerPicker = createFormField({
component: Component,
name: 'OwnerPicker',
schema: OwnerPickerFieldSchema,
});
@@ -0,0 +1,26 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import {
RepoBranchPicker as Component,
RepoBranchPickerFieldSchema,
} from '../../components/fields/RepoBranchPicker';
export const RepoBranchPicker = createFormField({
component: Component,
name: 'RepoBranchPicker',
schema: RepoBranchPickerFieldSchema,
});
@@ -1,5 +1,5 @@
/*
* Copyright 2024 The Backstage Authors
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,11 +14,11 @@
* limitations under the License.
*/
import { createFormField } from '@backstage/plugin-scaffolder-react/alpha';
import { RepoUrlPicker as Component } from '../../components/fields/RepoUrlPicker/RepoUrlPicker';
import {
RepoUrlPickerFieldSchema,
repoPickerValidation,
} from '../../components';
RepoUrlPicker as Component,
RepoUrlPickerFieldSchema,
} from '../../components/fields/RepoUrlPicker';
export const RepoUrlPicker = createFormField({
component: Component,
+18 -2
View File
@@ -17,10 +17,10 @@
import { convertLegacyRouteRefs } from '@backstage/core-compat-api';
import { createFrontendPlugin } from '@backstage/frontend-plugin-api';
import {
rootRouteRef,
actionsRouteRef,
editRouteRef,
registerComponentRouteRef,
rootRouteRef,
scaffolderListTaskRouteRef,
scaffolderTaskRouteRef,
selectedTemplateRouteRef,
@@ -28,10 +28,18 @@ import {
viewTechDocRouteRef,
} from '../routes';
import {
entityNamePickerFormField,
entityPickerFormField,
entityTagsPickerFormField,
multiEntityPickerFormField,
myGroupsPickerFormField,
ownedEntityPickerFormField,
ownerPickerFormField,
repoBranchPickerFormField,
repoUrlPickerFormField,
scaffolderApi,
scaffolderNavItem,
scaffolderPage,
scaffolderApi,
} from './extensions';
import { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
import { formFieldsApi } from '@backstage/plugin-scaffolder-react/alpha';
@@ -73,5 +81,13 @@ export default createFrontendPlugin({
formDecoratorsApi,
formFieldsApi,
repoUrlPickerFormField,
entityNamePickerFormField,
entityPickerFormField,
ownerPickerFormField,
entityTagsPickerFormField,
multiEntityPickerFormField,
myGroupsPickerFormField,
ownedEntityPickerFormField,
repoBranchPickerFormField,
],
});
@@ -13,4 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { EntityNamePicker } from './EntityNamePicker';
export { entityNamePickerValidation } from './validation';
export { EntityNamePickerFieldSchema } from './schema';
@@ -15,7 +15,7 @@
*/
import { makeFieldSchema } from '@backstage/plugin-scaffolder-react';
const EntityNamePickerFieldSchema = makeFieldSchema({
export const EntityNamePickerFieldSchema = makeFieldSchema({
output: z => z.string(),
});
@@ -13,4 +13,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { EntityPicker } from './EntityPicker';
export { EntityPickerFieldSchema, type EntityPickerUiOptions } from './schema';
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { EntityTagsPicker } from './EntityTagsPicker';
export {
EntityTagsPickerFieldSchema,
type EntityTagsPickerUiOptions,
@@ -46,7 +46,6 @@ export type EntityTagsPickerProps = typeof EntityTagsPickerFieldSchema.TProps;
/**
* The input props that can be specified under `ui:options` for the
* `EntityTagsPicker` field extension.
*
* @public
*/
export type EntityTagsPickerUiOptions = NonNullable<
@@ -14,6 +14,7 @@
* limitations under the License.
*/
export { MultiEntityPicker } from './MultiEntityPicker';
export {
MultiEntityPickerFieldSchema,
type MultiEntityPickerUiOptions,
@@ -14,6 +14,7 @@
* limitations under the License.
*/
export { MyGroupsPicker } from './MyGroupsPicker';
export {
MyGroupsPickerSchema,
type MyGroupsPickerUiOptions,
@@ -36,7 +36,6 @@ export type MyGroupsPickerUiOptions = NonNullable<
/**
* Props for the MyGroupsPicker.
* @public
*/
export type MyGroupsPickerProps = typeof MyGroupsPickerFieldSchema.TProps;
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { OwnedEntityPicker } from './OwnedEntityPicker';
export {
OwnedEntityPickerFieldSchema,
type OwnedEntityPickerUiOptions,
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EntityPickerFieldSchema } from '../EntityPicker/schema';
import { EntityPickerFieldSchema } from '../EntityPicker';
/**
* @public
@@ -23,7 +23,6 @@ export const OwnedEntityPickerFieldSchema = EntityPickerFieldSchema;
/**
* The input props that can be specified under `ui:options` for the
* `OwnedEntityPicker` field extension.
*
* @public
*/
export type OwnedEntityPickerUiOptions = NonNullable<
@@ -13,4 +13,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { OwnerPicker } from './OwnerPicker';
export { OwnerPickerFieldSchema, type OwnerPickerUiOptions } from './schema';
@@ -54,7 +54,6 @@ export const OwnerPickerFieldSchema = makeFieldSchema({
/**
* The input props that can be specified under `ui:options` for the
* `OwnerPicker` field extension.
*
* @public
*/
export type OwnerPickerUiOptions = NonNullable<
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { RepoBranchPicker } from './RepoBranchPicker';
export {
RepoBranchPickerFieldSchema,
type RepoBranchPickerUiOptions,
@@ -15,9 +15,6 @@
*/
import { makeFieldSchema } from '@backstage/plugin-scaffolder-react';
/**
* @public
*/
export const RepoBranchPickerFieldSchema = makeFieldSchema({
output: z => z.string(),
uiOptions: z =>
@@ -69,8 +66,6 @@ export const RepoBranchPickerFieldSchema = makeFieldSchema({
/**
* The input props that can be specified under `ui:options` for the
* `RepoBranchPicker` field extension.
*
* @public
*/
export type RepoBranchPickerUiOptions = NonNullable<
(typeof RepoBranchPickerFieldSchema.TProps.uiSchema)['ui:options']
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { RepoUrlPicker } from './RepoUrlPicker';
export {
RepoUrlPickerFieldSchema,
type RepoUrlPickerUiOptions,
@@ -22,7 +22,6 @@ import { scmIntegrationsApiRef } from '@backstage/integration-react';
* The validation function for the `repoUrl` that is returned from the
* field extension. Ensures that you have all the required fields filled for
* the different providers that exist.
*
* @public
*/
export const repoPickerValidation = (
@@ -13,11 +13,4 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './EntityPicker';
export * from './OwnerPicker';
export * from './RepoUrlPicker';
export * from './OwnedEntityPicker';
export * from './EntityTagsPicker';
export * from './MyGroupsPicker';
export { type FieldSchema, makeFieldSchemaFromZod } from './utils';
+27 -1
View File
@@ -14,7 +14,33 @@
* limitations under the License.
*/
export * from './fields';
export type { RepoUrlPickerUiOptions } from './fields';
export {
EntityPickerFieldSchema,
type EntityPickerUiOptions,
} from './fields/EntityPicker';
export {
EntityTagsPickerFieldSchema,
type EntityTagsPickerUiOptions,
} from './fields/EntityTagsPicker';
export {
MyGroupsPickerFieldSchema,
MyGroupsPickerSchema,
type MyGroupsPickerUiOptions,
} from './fields/MyGroupsPicker';
export {
OwnedEntityPickerFieldSchema,
type OwnedEntityPickerUiOptions,
} from './fields/OwnedEntityPicker';
export {
OwnerPickerFieldSchema,
type OwnerPickerUiOptions,
} from './fields/OwnerPicker';
export {
repoPickerValidation,
RepoUrlPickerFieldSchema,
type RepoUrlPickerUiOptions,
} from './fields/RepoUrlPicker';
export { TemplateTypePicker } from './TemplateTypePicker';