diff --git a/.changeset/strong-schools-fix.md b/.changeset/strong-schools-fix.md new file mode 100644 index 0000000000..117d33a3eb --- /dev/null +++ b/.changeset/strong-schools-fix.md @@ -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 diff --git a/plugins/scaffolder-react/report-alpha.api.md b/plugins/scaffolder-react/report-alpha.api.md index 4f9f86d1ac..4cddb48602 100644 --- a/plugins/scaffolder-react/report-alpha.api.md +++ b/plugins/scaffolder-react/report-alpha.api.md @@ -132,6 +132,30 @@ export const Form: ( props: PropsWithChildren, ) => 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'; diff --git a/plugins/scaffolder-react/src/next/blueprints/FormDecoratorBlueprint.tsx b/plugins/scaffolder-react/src/next/blueprints/FormDecoratorBlueprint.tsx new file mode 100644 index 0000000000..436b1df85c --- /dev/null +++ b/plugins/scaffolder-react/src/next/blueprints/FormDecoratorBlueprint.tsx @@ -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().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); + }, +}); diff --git a/plugins/scaffolder-react/src/next/blueprints/index.ts b/plugins/scaffolder-react/src/next/blueprints/index.ts index 165c583ac8..d9d0d2e0b3 100644 --- a/plugins/scaffolder-react/src/next/blueprints/index.ts +++ b/plugins/scaffolder-react/src/next/blueprints/index.ts @@ -14,5 +14,6 @@ * limitations under the License. */ +export * from './FormDecoratorBlueprint'; export * from './FormFieldBlueprint'; export * from './types'; diff --git a/plugins/scaffolder/report-alpha.api.md b/plugins/scaffolder/report-alpha.api.md index e272b57655..7623350d96 100644 --- a/plugins/scaffolder/report-alpha.api.md +++ b/plugins/scaffolder/report-alpha.api.md @@ -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; } +// @alpha (undocumented) +export const formDecoratorsApi: ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef; + 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; diff --git a/plugins/scaffolder/src/alpha/api/FormDecoratorsApi.ts b/plugins/scaffolder/src/alpha/api/FormDecoratorsApi.ts index 13c4b6d1a2..41bf91dba0 100644 --- a/plugins/scaffolder/src/alpha/api/FormDecoratorsApi.ts +++ b/plugins/scaffolder/src/alpha/api/FormDecoratorsApi.ts @@ -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, + }), + }), + }); + }, +}); diff --git a/plugins/scaffolder/src/alpha/api/index.ts b/plugins/scaffolder/src/alpha/api/index.ts index 07d4b65a3b..b6161dd252 100644 --- a/plugins/scaffolder/src/alpha/api/index.ts +++ b/plugins/scaffolder/src/alpha/api/index.ts @@ -16,4 +16,4 @@ export { formDecoratorsApiRef } from './ref'; export type { ScaffolderFormDecoratorsApi } from './types'; -export { DefaultScaffolderFormDecoratorsApi } from './FormDecoratorsApi'; +export * from './FormDecoratorsApi'; diff --git a/plugins/scaffolder/src/alpha/plugin.tsx b/plugins/scaffolder/src/alpha/plugin.tsx index 44ec1f5d4c..e281f51b0f 100644 --- a/plugins/scaffolder/src/alpha/plugin.tsx +++ b/plugins/scaffolder/src/alpha/plugin.tsx @@ -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, ],