Merge pull request #28211 from backstage/form-decorators-app-next

Add ApiBlueprint for form-decorators
This commit is contained in:
Ben Lambert
2025-01-14 08:38:17 +01:00
committed by GitHub
8 changed files with 160 additions and 1 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-scaffolder-react': patch
'@backstage/plugin-scaffolder': patch
---
Added support for `FormDecoratorBlueprint` to create form decorators in the Scaffolder plugin
@@ -132,6 +132,30 @@ export const Form: (
props: PropsWithChildren<ScaffolderRJSFFormProps>,
) => React_2.JSX.Element;
// @alpha
export const FormDecoratorBlueprint: ExtensionBlueprint<{
kind: 'scaffolder-form-decorator';
name: undefined;
params: {
decorator: ScaffolderFormDecorator;
};
output: ConfigurableExtensionDataRef<
ScaffolderFormDecorator,
'scaffolder.form-decorator-loader',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
formDecoratorLoader: ConfigurableExtensionDataRef<
ScaffolderFormDecorator,
'scaffolder.form-decorator-loader',
{}
>;
};
}>;
// @alpha
export const FormFieldBlueprint: ExtensionBlueprint<{
kind: 'scaffolder-form-field';
@@ -0,0 +1,41 @@
/*
* Copyright 2024 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 {
createExtensionBlueprint,
createExtensionDataRef,
} from '@backstage/frontend-plugin-api';
import { ScaffolderFormDecorator } from '../extensions';
const formDecoratorExtensionDataRef =
createExtensionDataRef<ScaffolderFormDecorator>().with({
id: 'scaffolder.form-decorator-loader',
});
/**
* @alpha
* Creates extensions that are Field Extensions for the Scaffolder
* */
export const FormDecoratorBlueprint = createExtensionBlueprint({
kind: 'scaffolder-form-decorator',
attachTo: { id: 'api:scaffolder/form-decorators', input: 'formDecorators' },
dataRefs: {
formDecoratorLoader: formDecoratorExtensionDataRef,
},
output: [formDecoratorExtensionDataRef],
*factory(params: { decorator: ScaffolderFormDecorator }) {
yield formDecoratorExtensionDataRef(params.decorator);
},
});
@@ -14,5 +14,6 @@
* limitations under the License.
*/
export * from './FormDecoratorBlueprint';
export * from './FormFieldBlueprint';
export * from './types';
+52
View File
@@ -80,6 +80,33 @@ const _default: FrontendPlugin<
factory: AnyApiFactory;
};
}>;
'api:scaffolder/form-decorators': ExtensionDefinition<{
config: {};
configInput: {};
output: ConfigurableExtensionDataRef<
AnyApiFactory,
'core.api.factory',
{}
>;
inputs: {
formDecorators: ExtensionInput<
ConfigurableExtensionDataRef<
ScaffolderFormDecorator,
'scaffolder.form-decorator-loader',
{}
>,
{
singleton: false;
optional: false;
}
>;
};
kind: 'api';
name: 'form-decorators';
params: {
factory: AnyApiFactory;
};
}>;
'page:scaffolder': ExtensionDefinition<{
kind: 'page';
name: undefined;
@@ -173,6 +200,31 @@ export class DefaultScaffolderFormDecoratorsApi
getFormDecorators(): Promise<ScaffolderFormDecorator[]>;
}
// @alpha (undocumented)
export const formDecoratorsApi: ExtensionDefinition<{
config: {};
configInput: {};
output: ConfigurableExtensionDataRef<AnyApiFactory, 'core.api.factory', {}>;
inputs: {
formDecorators: ExtensionInput<
ConfigurableExtensionDataRef<
ScaffolderFormDecorator,
'scaffolder.form-decorator-loader',
{}
>,
{
singleton: false;
optional: false;
}
>;
};
kind: 'api';
name: 'form-decorators';
params: {
factory: AnyApiFactory;
};
}>;
// @alpha (undocumented)
export const formDecoratorsApiRef: ApiRef<ScaffolderFormDecoratorsApi>;
@@ -14,8 +14,15 @@
* limitations under the License.
*/
import {
ApiBlueprint,
createApiFactory,
createExtensionInput,
} from '@backstage/frontend-plugin-api';
import { ScaffolderFormDecoratorsApi } from './types';
import { ScaffolderFormDecorator } from '@backstage/plugin-scaffolder-react/alpha';
import { formDecoratorsApiRef } from './ref';
import { FormDecoratorBlueprint } from '@backstage/plugin-scaffolder-react/alpha';
/** @alpha */
export class DefaultScaffolderFormDecoratorsApi
@@ -37,3 +44,29 @@ export class DefaultScaffolderFormDecoratorsApi
return this.options.decorators;
}
}
/** @alpha */
export const formDecoratorsApi = ApiBlueprint.makeWithOverrides({
name: 'form-decorators',
inputs: {
formDecorators: createExtensionInput([
FormDecoratorBlueprint.dataRefs.formDecoratorLoader,
]),
},
factory(originalFactory, { inputs }) {
const formDecorators = inputs.formDecorators.map(e =>
e.get(FormDecoratorBlueprint.dataRefs.formDecoratorLoader),
);
return originalFactory({
factory: createApiFactory({
api: formDecoratorsApiRef,
deps: {},
factory: () =>
DefaultScaffolderFormDecoratorsApi.create({
decorators: formDecorators,
}),
}),
});
},
});
+1 -1
View File
@@ -16,4 +16,4 @@
export { formDecoratorsApiRef } from './ref';
export type { ScaffolderFormDecoratorsApi } from './types';
export { DefaultScaffolderFormDecoratorsApi } from './FormDecoratorsApi';
export * from './FormDecoratorsApi';
+2
View File
@@ -33,6 +33,7 @@ import {
scaffolderApi,
} from './extensions';
import { formFieldsApi } from '@backstage/plugin-scaffolder-react/alpha';
import { formDecoratorsApi } from './api';
/** @alpha */
export default createFrontendPlugin({
@@ -53,6 +54,7 @@ export default createFrontendPlugin({
scaffolderApi,
scaffolderPage,
scaffolderNavItem,
formDecoratorsApi,
formFieldsApi,
repoUrlPickerFormField,
],