scaffolder: move formFields input to page extension instead of sub-page redirect

Rather than using an input redirect on the templates sub-page, keep the
formFields input on the page extension itself. The form fields are all
shared via the formFieldsApi anyway, so the sub-page only needs to read
from the API.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-03-20 13:39:17 +01:00
parent c37df0a5d7
commit 3bb9cb5b0a
2 changed files with 29 additions and 36 deletions
+15 -16
View File
@@ -195,8 +195,6 @@ const _default: OverridableFrontendPlugin<
};
}>;
'page:scaffolder': OverridableExtensionDefinition<{
kind: 'page';
name: undefined;
config: {
path: string | undefined;
title: string | undefined;
@@ -260,7 +258,21 @@ const _default: OverridableFrontendPlugin<
internal: false;
}
>;
formFields: ExtensionInput<
ConfigurableExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>,
{
singleton: false;
optional: false;
internal: false;
}
>;
};
kind: 'page';
name: undefined;
params: {
path: string;
title?: string;
@@ -561,20 +573,7 @@ const _default: OverridableFrontendPlugin<
optional: true;
}
>;
inputs: {
formFields: ExtensionInput<
ConfigurableExtensionDataRef<
() => Promise<FormField>,
'scaffolder.form-field-loader',
{}
>,
{
singleton: false;
optional: false;
internal: false;
}
>;
};
inputs: {};
kind: 'sub-page';
name: 'templates';
params: {
+14 -20
View File
@@ -34,37 +34,31 @@ import { scmIntegrationsApiRef } from '@backstage/integration-react';
import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';
import { ScaffolderClient } from '../api';
export const scaffolderPage = PageBlueprint.make({
params: {
routeRef: rootRouteRef,
path: '/create',
title: 'Create',
export const scaffolderPage = PageBlueprint.makeWithOverrides({
inputs: {
formFields: createExtensionInput([
FormFieldBlueprint.dataRefs.formFieldLoader,
]),
},
factory(originalFactory) {
return originalFactory({
routeRef: rootRouteRef,
path: '/create',
title: 'Create',
});
},
});
export const scaffolderTemplatesSubPage = SubPageBlueprint.makeWithOverrides({
name: 'templates',
inputs: {
formFields: createExtensionInput(
[FormFieldBlueprint.dataRefs.formFieldLoader],
{ replaces: [{ id: 'page:scaffolder', input: 'formFields' }] },
),
},
factory(originalFactory, { apis, inputs }) {
factory(originalFactory, { apis }) {
const formFieldsApi = apis.get(formFieldsApiRef);
return originalFactory({
path: 'templates',
title: 'Templates',
loader: async () => {
const apiFormFields = (await formFieldsApi?.loadFormFields()) ?? [];
const formFieldLoaders = inputs.formFields.map(output =>
output.get(FormFieldBlueprint.dataRefs.formFieldLoader),
);
const loadedFormFields = await Promise.all(
formFieldLoaders.map(loader => loader()),
);
const formFields = [...apiFormFields, ...loadedFormFields];
const formFields = (await formFieldsApi?.loadFormFields()) ?? [];
return import('./components/TemplatesSubPage').then(m => (
<m.TemplatesSubPage formFields={formFields} />