From 6ed42b764ceb163da691cfcfe5eecc662753737e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Vit=C3=A1sek?= Date: Tue, 18 Mar 2025 11:26:20 +0100 Subject: [PATCH 1/6] feat: add TemplateDetailButton to CardHeader and update tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ladislav Vitásek --- .changeset/honest-ties-worry.md | 5 ++ plugins/home/report.api.md | 3 +- plugins/scaffolder-react/report-alpha.api.md | 1 + .../TemplateCard/CardHeader.test.tsx | 48 ++++++++++++++- .../components/TemplateCard/CardHeader.tsx | 9 ++- .../TemplateCard/TemplateCard.test.tsx | 49 ++++++--------- .../TemplateCard/TemplateDetailButton.tsx | 61 +++++++++++++++++++ plugins/scaffolder-react/src/translation.ts | 3 + 8 files changed, 143 insertions(+), 36 deletions(-) create mode 100644 .changeset/honest-ties-worry.md create mode 100644 plugins/scaffolder-react/src/next/components/TemplateCard/TemplateDetailButton.tsx diff --git a/.changeset/honest-ties-worry.md b/.changeset/honest-ties-worry.md new file mode 100644 index 0000000000..74d8c591c1 --- /dev/null +++ b/.changeset/honest-ties-worry.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Scaffolding - Template card - button to show template entity detail diff --git a/plugins/home/report.api.md b/plugins/home/report.api.md index ef5a0d5a7a..eacf1a99a9 100644 --- a/plugins/home/report.api.md +++ b/plugins/home/report.api.md @@ -50,8 +50,7 @@ export const ComponentAccordion: (props: { expanded?: boolean; Content: () => JSX.Element; Actions?: () => JSX.Element; - Settings?: () => JSX./** @public */ - Element; + Settings?: () => JSX.Element; ContextProvider?: (props: any) => JSX.Element; }) => JSX_2.Element; diff --git a/plugins/scaffolder-react/report-alpha.api.md b/plugins/scaffolder-react/report-alpha.api.md index b007fa7d49..fbd539f96e 100644 --- a/plugins/scaffolder-react/report-alpha.api.md +++ b/plugins/scaffolder-react/report-alpha.api.md @@ -347,6 +347,7 @@ export const scaffolderReactTranslationRef: TranslationRef< readonly 'templateCategoryPicker.title': 'Categories'; readonly 'templateCard.noDescription': 'No description'; readonly 'templateCard.chooseButtonText': 'Choose'; + readonly 'cardHeader.detailBtnTitle': 'Show template entity details'; readonly 'templateOutputs.title': 'Text Output'; } >; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx index 9ae2a507dd..3c7eef5f8d 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx @@ -24,12 +24,21 @@ import { renderInTestApp, TestApiProvider, } from '@backstage/test-utils'; -import { starredEntitiesApiRef } from '@backstage/plugin-catalog-react'; +import { + entityRouteRef, + starredEntitiesApiRef, +} from '@backstage/plugin-catalog-react'; import { DefaultStarredEntitiesApi } from '@backstage/plugin-catalog'; import Observable from 'zen-observable'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; +const mountedRoutes = { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, +}; + describe('CardHeader', () => { it('should select the correct theme from the theme provider from the header', async () => { // Can't really test what we want here. @@ -64,6 +73,7 @@ describe('CardHeader', () => { /> , + mountedRoutes, ); expect(mockTheme.getPageTheme).toHaveBeenCalledWith({ themeId: 'service' }); @@ -93,6 +103,7 @@ describe('CardHeader', () => { }} /> , + mountedRoutes, ); expect(getByText('service')).toBeInTheDocument(); @@ -118,6 +129,7 @@ describe('CardHeader', () => { , + mountedRoutes, ); const favorite = getByRole('button', { name: 'Add to favorites' }); @@ -129,6 +141,38 @@ describe('CardHeader', () => { ); }); + it('renders TemplateDetailButton with link to entity page', async () => { + const { getByTitle } = await renderInTestApp( + + + , + mountedRoutes, + ); + + const detailButton = getByTitle('Show template entity details'); + const link = detailButton.querySelector('a'); + expect(link).toBeInTheDocument(); + }); + it('should render the name of the entity', async () => { const { getByText } = await renderInTestApp( { }} /> , + mountedRoutes, ); expect(getByText('bob')).toBeInTheDocument(); @@ -182,6 +227,7 @@ describe('CardHeader', () => { }} /> , + mountedRoutes, ); expect(getByText('Iamtitle')).toBeInTheDocument(); diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx index 467d26ce76..5e5c6fe8bf 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx @@ -15,10 +15,11 @@ */ import React from 'react'; -import { Theme, makeStyles, useTheme } from '@material-ui/core/styles'; +import { makeStyles, Theme, useTheme } from '@material-ui/core/styles'; import { ItemCardHeader } from '@backstage/core-components'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { FavoriteEntity } from '@backstage/plugin-catalog-react'; +import { TemplateDetailButton } from './TemplateDetailButton.tsx'; const useStyles = makeStyles< Theme, @@ -66,7 +67,11 @@ export const CardHeader = (props: CardHeaderProps) => {
{type}
- + +
); diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx index 673f1e4a9e..e25952131b 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx @@ -33,6 +33,12 @@ import { permissionApiRef } from '@backstage/plugin-permission-react'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { SWRConfig } from 'swr'; +const mountedRoutes = { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, +}; + describe('TemplateCard', () => { it('should render the card title', async () => { const mockTemplate: TemplateEntityV1beta3 = { @@ -59,6 +65,7 @@ describe('TemplateCard', () => { > , + mountedRoutes, ); expect(getByText('bob')).toBeInTheDocument(); @@ -89,6 +96,7 @@ describe('TemplateCard', () => { > , + mountedRoutes, ); const description = getByText('hello'); @@ -121,6 +129,7 @@ describe('TemplateCard', () => { > , + mountedRoutes, ); expect(getByText('No description')).toBeInTheDocument(); @@ -151,6 +160,7 @@ describe('TemplateCard', () => { > , + mountedRoutes, ); expect(queryByTestId('template-card-separator')).toBeInTheDocument(); @@ -187,6 +197,7 @@ describe('TemplateCard', () => { > , + mountedRoutes, ); for (const tag of mockTemplate.metadata.tags!) { @@ -227,11 +238,7 @@ describe('TemplateCard', () => { > , - { - mountedRoutes: { - '/catalog/:kind/:namespace/:name': entityRouteRef, - }, - }, + mountedRoutes, ); expect(queryByTestId('template-card-separator')).toBeInTheDocument(); @@ -272,11 +279,7 @@ describe('TemplateCard', () => { > , - { - mountedRoutes: { - '/catalog/:kind/:namespace/:name': entityRouteRef, - }, - }, + mountedRoutes, ); expect(queryByTestId('template-card-separator')).toBeInTheDocument(); @@ -321,11 +324,7 @@ describe('TemplateCard', () => { > , - { - mountedRoutes: { - '/catalog/:kind/:namespace/:name': entityRouteRef, - }, - }, + mountedRoutes, ); expect(queryByTestId('template-card-separator')).not.toBeInTheDocument(); @@ -364,17 +363,13 @@ describe('TemplateCard', () => { > , - { - mountedRoutes: { - '/catalog/:kind/:namespace/:name': entityRouteRef, - }, - }, + mountedRoutes, ); expect(getByRole('link', { name: /.*my-test-user$/ })).toBeInTheDocument(); expect(getByRole('link', { name: /.*my-test-user$/ })).toHaveAttribute( 'href', - '/catalog/group/default/my-test-user', + '/catalog/default/group/my-test-user', ); }); @@ -404,11 +399,7 @@ describe('TemplateCard', () => { > , - { - mountedRoutes: { - '/catalog/:kind/:namespace/:name': entityRouteRef, - }, - }, + mountedRoutes, ); expect(getByRole('button', { name: 'Choose' })).toBeInTheDocument(); @@ -448,11 +439,7 @@ describe('TemplateCard', () => { , - { - mountedRoutes: { - '/catalog/:kind/:namespace/:name': entityRouteRef, - }, - }, + mountedRoutes, ); expect(queryByText('Choose')).toBeNull(); diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateDetailButton.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateDetailButton.tsx new file mode 100644 index 0000000000..1a352d8967 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateDetailButton.tsx @@ -0,0 +1,61 @@ +/* + * 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 React from 'react'; +import Tooltip from '@material-ui/core/Tooltip'; +import IconButton from '@material-ui/core/IconButton'; +import Typography from '@material-ui/core/Typography'; +import DescriptionIcon from '@material-ui/icons/Description'; +import { Link } from '@backstage/core-components'; +import { + entityRouteParams, + entityRouteRef, +} from '@backstage/plugin-catalog-react'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; +import { scaffolderReactTranslationRef } from '../../../translation'; +import { useTranslationRef } from '@backstage/frontend-plugin-api'; + +export interface TemplateDetailButtonProps { + template: Entity; +} + +export const TemplateDetailButton = ({ + template, +}: TemplateDetailButtonProps) => { + const catalogEntityRoute = useRouteRef(entityRouteRef); + const { t } = useTranslationRef(scaffolderReactTranslationRef); + const entityRef = stringifyEntityRef(template); + + return ( + + + + + + + + + + ); +}; diff --git a/plugins/scaffolder-react/src/translation.ts b/plugins/scaffolder-react/src/translation.ts index f490b52064..c097d78e3e 100644 --- a/plugins/scaffolder-react/src/translation.ts +++ b/plugins/scaffolder-react/src/translation.ts @@ -44,6 +44,9 @@ export const scaffolderReactTranslationRef = createTranslationRef({ noDescription: 'No description', chooseButtonText: 'Choose', }, + cardHeader: { + detailBtnTitle: 'Show template entity details', + }, templateOutputs: { title: 'Text Output', }, From 609a3a123e8fae38cd45874d1bbda5722d975eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Vit=C3=A1sek?= Date: Tue, 18 Mar 2025 12:28:30 +0100 Subject: [PATCH 2/6] test fix + button system icon as default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ladislav Vitásek --- .../TemplateCard/TemplateDetailButton.tsx | 7 +++++-- .../TemplateListPage.test.tsx | 21 +++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateDetailButton.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateDetailButton.tsx index 1a352d8967..6ecfc2a1e9 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateDetailButton.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateDetailButton.tsx @@ -23,7 +23,7 @@ import { entityRouteParams, entityRouteRef, } from '@backstage/plugin-catalog-react'; -import { useRouteRef } from '@backstage/core-plugin-api'; +import { useApp, useRouteRef } from '@backstage/core-plugin-api'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { scaffolderReactTranslationRef } from '../../../translation'; import { useTranslationRef } from '@backstage/frontend-plugin-api'; @@ -39,6 +39,9 @@ export const TemplateDetailButton = ({ const { t } = useTranslationRef(scaffolderReactTranslationRef); const entityRef = stringifyEntityRef(template); + const app = useApp(); + const TemplateIcon = app.getSystemIcon('kind:template') || DescriptionIcon; + return ( - + diff --git a/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx index 01274cf6a6..03175786b1 100644 --- a/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx @@ -17,6 +17,7 @@ import { DefaultStarredEntitiesApi } from '@backstage/plugin-catalog'; import { catalogApiRef, + entityRouteRef, starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; @@ -30,6 +31,13 @@ import React from 'react'; import { rootRouteRef } from '../../../routes'; import { TemplateListPage } from './TemplateListPage'; +const mountedRoutes = { + mountedRoutes: { + '/': rootRouteRef, + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, +}; + describe('TemplateListPage', () => { const mockCatalogApi = catalogApiMock({ entities: [ @@ -60,7 +68,7 @@ describe('TemplateListPage', () => { > , - { mountedRoutes: { '/': rootRouteRef } }, + mountedRoutes, ); expect(getByPlaceholderText('Search')).toBeInTheDocument(); @@ -82,7 +90,7 @@ describe('TemplateListPage', () => { > , - { mountedRoutes: { '/': rootRouteRef } }, + mountedRoutes, ); expect(getByRole('menuitem', { name: /All/ })).toBeInTheDocument(); @@ -105,7 +113,7 @@ describe('TemplateListPage', () => { > , - { mountedRoutes: { '/': rootRouteRef } }, + mountedRoutes, ); expect(getByText('Categories')).toBeInTheDocument(); @@ -127,7 +135,7 @@ describe('TemplateListPage', () => { > , - { mountedRoutes: { '/': rootRouteRef } }, + mountedRoutes, ); expect(getByText('Owner')).toBeInTheDocument(); @@ -150,6 +158,7 @@ describe('TemplateListPage', () => { > , + mountedRoutes, ); expect(getByText('Tags')).toBeInTheDocument(); @@ -172,7 +181,7 @@ describe('TemplateListPage', () => { > , - { mountedRoutes: { '/': rootRouteRef } }, + mountedRoutes, ); expect(queryByTestId('menu-button')).toBeInTheDocument(); }); @@ -199,7 +208,7 @@ describe('TemplateListPage', () => { }} /> , - { mountedRoutes: { '/': rootRouteRef } }, + mountedRoutes, ); expect(queryByTestId('menu-button')).not.toBeInTheDocument(); }); From 5aab8e24e651cbc8505fe7a770c8fc8ccb092ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Vit=C3=A1sek?= Date: Tue, 18 Mar 2025 14:37:34 +0100 Subject: [PATCH 3/6] fix: restore missing translations in scaffolderReactTranslationRef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ladislav Vitásek --- plugins/scaffolder-react/report-alpha.api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder-react/report-alpha.api.md b/plugins/scaffolder-react/report-alpha.api.md index fbd539f96e..ad9f31480a 100644 --- a/plugins/scaffolder-react/report-alpha.api.md +++ b/plugins/scaffolder-react/report-alpha.api.md @@ -332,10 +332,9 @@ export type ScaffolderReactTemplateCategoryPickerClassKey = 'root' | 'label'; export const scaffolderReactTranslationRef: TranslationRef< 'scaffolder-react', { - readonly 'workflow.noDescription': 'No description'; readonly 'passwordWidget.content': 'This widget is insecure. Please use [`ui:field: Secret`](https://backstage.io/docs/features/software-templates/writing-templates/#using-secrets) instead of `ui:widget: password`'; - readonly 'scaffolderPageContextMenu.createLabel': 'Create'; readonly 'scaffolderPageContextMenu.moreLabel': 'more'; + readonly 'scaffolderPageContextMenu.createLabel': 'Create'; readonly 'scaffolderPageContextMenu.editorLabel': 'Manage Templates'; readonly 'scaffolderPageContextMenu.actionsLabel': 'Installed Actions'; readonly 'scaffolderPageContextMenu.tasksLabel': 'Task List'; @@ -349,6 +348,7 @@ export const scaffolderReactTranslationRef: TranslationRef< readonly 'templateCard.chooseButtonText': 'Choose'; readonly 'cardHeader.detailBtnTitle': 'Show template entity details'; readonly 'templateOutputs.title': 'Text Output'; + readonly 'workflow.noDescription': 'No description'; } >; From 99e95a6c3870bd251d36d5ecf78450666fb07fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Vit=C3=A1sek?= Date: Wed, 19 Mar 2025 08:32:12 +0100 Subject: [PATCH 4/6] new generated file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ladislav Vitásek --- plugins/scaffolder-react/report-alpha.api.md | 524 ----------------- plugins/scaffolder-react/report.api.md | 567 ------------------- 2 files changed, 1091 deletions(-) delete mode 100644 plugins/scaffolder-react/report-alpha.api.md delete mode 100644 plugins/scaffolder-react/report.api.md diff --git a/plugins/scaffolder-react/report-alpha.api.md b/plugins/scaffolder-react/report-alpha.api.md deleted file mode 100644 index ad9f31480a..0000000000 --- a/plugins/scaffolder-react/report-alpha.api.md +++ /dev/null @@ -1,524 +0,0 @@ -## API Report File for "@backstage/plugin-scaffolder-react" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { AnyApiFactory } from '@backstage/frontend-plugin-api'; -import { AnyApiRef } from '@backstage/core-plugin-api'; -import { ApiHolder } from '@backstage/core-plugin-api'; -import { ApiRef } from '@backstage/frontend-plugin-api'; -import { ComponentType } from 'react'; -import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; -import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; -import { Dispatch } from 'react'; -import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; -import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; -import { ExtensionInput } from '@backstage/frontend-plugin-api'; -import { FieldExtensionComponentProps } from '@backstage/plugin-scaffolder-react'; -import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; -import { FieldSchema } from '@backstage/plugin-scaffolder-react'; -import { FieldValidation } from '@rjsf/utils'; -import { FormField } from '@internal/scaffolder'; -import { FormProps } from '@backstage/plugin-scaffolder-react'; -import { IconComponent } from '@backstage/core-plugin-api'; -import { JsonObject } from '@backstage/types'; -import { JsonValue } from '@backstage/types'; -import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { Overrides } from '@material-ui/core/styles/overrides'; -import { PropsWithChildren } from 'react'; -import { default as React_2 } from 'react'; -import { ReactElement } from 'react'; -import { ReactNode } from 'react'; -import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; -import { ScaffolderRJSFFormProps } from '@backstage/plugin-scaffolder-react'; -import { ScaffolderStep } from '@backstage/plugin-scaffolder-react'; -import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; -import { SetStateAction } from 'react'; -import { StyleRules } from '@material-ui/core/styles/withStyles'; -import { TaskStep } from '@backstage/plugin-scaffolder-common'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react'; -import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; -import { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { TranslationRef } from '@backstage/core-plugin-api/alpha'; -import { UiSchema } from '@rjsf/utils'; -import { WidgetProps } from '@rjsf/utils'; -import { z } from 'zod'; - -// @alpha (undocumented) -export type BackstageOverrides = Overrides & { - [Name in keyof ScaffolderReactComponentsNameToClassKey]?: Partial< - StyleRules - >; -}; - -// @alpha (undocumented) -export type BackstageTemplateStepperClassKey = - | 'backButton' - | 'footer' - | 'formWrapper'; - -// @alpha (undocumented) -export const createAsyncValidators: ( - rootSchema: JsonObject, - validators: Record< - string, - undefined | CustomFieldValidator - >, - context: { - apiHolder: ApiHolder; - }, -) => (formData: JsonObject) => Promise; - -// @alpha -export const createFieldValidation: () => FieldValidation; - -// @alpha -export function createFormField< - TReturnValue extends z.ZodType, - TUiOptions extends z.ZodType, ->(opts: FormFieldExtensionData): FormField; - -// @alpha -export function createScaffolderFormDecorator< - TInputSchema extends { - [key in string]: (zImpl: typeof z) => z.ZodType; - } = { - [key in string]: (zImpl: typeof z) => z.ZodType; - }, - TDeps extends { - [key in string]: AnyApiRef; - } = { - [key in string]: AnyApiRef; - }, - TInput extends JsonObject = { - [key in keyof TInputSchema]: z.infer>; - }, ->(options: { - id: string; - schema?: { - input?: TInputSchema; - }; - deps?: TDeps; - decorator: ( - ctx: ScaffolderFormDecoratorContext, - deps: TDeps extends { - [key in string]: AnyApiRef; - } - ? { - [key in keyof TDeps]: TDeps[key]['T']; - } - : never, - ) => Promise; -}): ScaffolderFormDecorator; - -// @alpha -export const DefaultTemplateOutputs: (props: { - output?: ScaffolderTaskOutput; -}) => React_2.JSX.Element | null; - -// @alpha (undocumented) -export const EmbeddableWorkflow: (props: WorkflowProps) => React_2.JSX.Element; - -// @alpha -export const extractSchemaFromStep: (inputStep: JsonObject) => { - uiSchema: UiSchema; - schema: JsonObject; -}; - -// @alpha -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'; - name: undefined; - params: { - field: () => Promise; - }; - output: ConfigurableExtensionDataRef< - () => Promise, - 'scaffolder.form-field-loader', - {} - >; - inputs: {}; - config: {}; - configInput: {}; - dataRefs: { - formFieldLoader: ConfigurableExtensionDataRef< - () => Promise, - 'scaffolder.form-field-loader', - {} - >; - }; -}>; - -// @alpha (undocumented) -export type FormFieldExtensionData< - TReturnValue extends z.ZodType = z.ZodType, - TUiOptions extends z.ZodType = z.ZodType, -> = { - name: string; - component: ( - props: FieldExtensionComponentProps< - z.output, - z.output - >, - ) => JSX.Element | null; - validation?: CustomFieldValidator< - z.output, - z.output - >; - schema?: FieldSchema, z.output>; -}; - -// @alpha (undocumented) -export const formFieldsApi: ExtensionDefinition<{ - config: {}; - configInput: {}; - output: ConfigurableExtensionDataRef; - inputs: { - formFields: ExtensionInput< - ConfigurableExtensionDataRef< - () => Promise, - 'scaffolder.form-field-loader', - {} - >, - { - singleton: false; - optional: false; - } - >; - }; - kind: 'api'; - name: 'form-fields'; - params: { - factory: AnyApiFactory; - }; -}>; - -// @alpha @deprecated (undocumented) -export const formFieldsApiRef: ApiRef; - -// @alpha (undocumented) -export type FormValidation = { - [name: string]: FieldValidation | FormValidation; -}; - -// @alpha -export interface ParsedTemplateSchema { - // (undocumented) - description?: string; - // (undocumented) - mergedSchema: JsonObject; - // (undocumented) - schema: JsonObject; - // (undocumented) - title: string; - // (undocumented) - uiSchema: UiSchema; -} - -// @alpha -export const ReviewState: (props: ReviewStateProps) => React_2.JSX.Element; - -// @alpha -export type ReviewStateProps = { - schemas: ParsedTemplateSchema[]; - formState: JsonObject; -}; - -// @alpha -export const ScaffolderField: ( - props: PropsWithChildren, -) => React_2.JSX.Element; - -// @alpha -export interface ScaffolderFieldProps { - // (undocumented) - disabled?: boolean; - // (undocumented) - displayLabel?: boolean; - // (undocumented) - errors?: ReactElement; - // (undocumented) - help?: ReactElement; - // (undocumented) - rawDescription?: string; - // (undocumented) - rawErrors?: string[]; - // (undocumented) - rawHelp?: string; - // (undocumented) - required?: boolean; -} - -// @alpha (undocumented) -export type ScaffolderFormDecorator = { - readonly $$type: '@backstage/scaffolder/FormDecorator'; - readonly id: string; - readonly TInput: TInput; -}; - -// @alpha (undocumented) -export type ScaffolderFormDecoratorContext< - TInput extends JsonObject = JsonObject, -> = { - input: TInput; - formState: Record; - setFormState: ( - fn: (currentState: Record) => Record, - ) => void; - setSecrets: ( - fn: (currentState: Record) => Record, - ) => void; -}; - -// @alpha @deprecated (undocumented) -export interface ScaffolderFormFieldsApi { - // (undocumented) - getFormFields(): Promise; -} - -// @alpha (undocumented) -export function ScaffolderPageContextMenu( - props: ScaffolderPageContextMenuProps, -): React_2.JSX.Element | null; - -// @alpha (undocumented) -export type ScaffolderPageContextMenuProps = { - onEditorClicked?: () => void; - onActionsClicked?: () => void; - onTasksClicked?: () => void; - onCreateClicked?: () => void; -}; - -// @alpha (undocumented) -export type ScaffolderReactComponentsNameToClassKey = { - ScaffolderReactTemplateCategoryPicker: ScaffolderReactTemplateCategoryPickerClassKey; - BackstageTemplateStepper: BackstageTemplateStepperClassKey; -}; - -// @alpha (undocumented) -export type ScaffolderReactTemplateCategoryPickerClassKey = 'root' | 'label'; - -// @alpha (undocumented) -export const scaffolderReactTranslationRef: TranslationRef< - 'scaffolder-react', - { - readonly 'passwordWidget.content': 'This widget is insecure. Please use [`ui:field: Secret`](https://backstage.io/docs/features/software-templates/writing-templates/#using-secrets) instead of `ui:widget: password`'; - readonly 'scaffolderPageContextMenu.moreLabel': 'more'; - readonly 'scaffolderPageContextMenu.createLabel': 'Create'; - readonly 'scaffolderPageContextMenu.editorLabel': 'Manage Templates'; - readonly 'scaffolderPageContextMenu.actionsLabel': 'Installed Actions'; - readonly 'scaffolderPageContextMenu.tasksLabel': 'Task List'; - readonly 'stepper.backButtonText': 'Back'; - readonly 'stepper.createButtonText': 'Create'; - readonly 'stepper.reviewButtonText': 'Review'; - readonly 'stepper.stepIndexLabel': 'Step {{index, number}}'; - readonly 'stepper.nextButtonText': 'Next'; - readonly 'templateCategoryPicker.title': 'Categories'; - readonly 'templateCard.noDescription': 'No description'; - readonly 'templateCard.chooseButtonText': 'Choose'; - readonly 'cardHeader.detailBtnTitle': 'Show template entity details'; - readonly 'templateOutputs.title': 'Text Output'; - readonly 'workflow.noDescription': 'No description'; - } ->; - -// @alpha -export const SecretWidget: ( - props: Pick< - WidgetProps, - 'name' | 'onChange' | 'schema' | 'required' | 'disabled' - >, -) => React_2.JSX.Element; - -// @alpha -export const Stepper: (stepperProps: StepperProps) => React_2.JSX.Element; - -// @alpha -export type StepperProps = { - manifest: TemplateParameterSchema; - extensions: FieldExtensionOptions[]; - templateName?: string; - formProps?: FormProps; - initialState?: Record; - onCreate: (values: Record) => Promise; - components?: { - ReviewStepComponent?: ComponentType; - ReviewStateComponent?: (props: ReviewStateProps) => JSX.Element; - backButtonText?: ReactNode; - createButtonText?: ReactNode; - reviewButtonText?: ReactNode; - }; - layouts?: LayoutOptions[]; -}; - -// @alpha -export const TaskLogStream: (props: { - logs: { - [k: string]: string[]; - }; -}) => React_2.JSX.Element; - -// @alpha -export const TaskSteps: (props: TaskStepsProps) => React_2.JSX.Element; - -// @alpha -export interface TaskStepsProps { - // (undocumented) - activeStep?: number; - // (undocumented) - isComplete?: boolean; - // (undocumented) - isError?: boolean; - // (undocumented) - steps: (TaskStep & ScaffolderStep)[]; -} - -// @alpha -export const TemplateCard: (props: TemplateCardProps) => React_2.JSX.Element; - -// @alpha -export interface TemplateCardProps { - // (undocumented) - additionalLinks?: { - icon: IconComponent; - text: string; - url: string; - }[]; - // (undocumented) - onSelected?: (template: TemplateEntityV1beta3) => void; - // (undocumented) - template: TemplateEntityV1beta3; -} - -// @alpha -export const TemplateCategoryPicker: () => React_2.JSX.Element | null; - -// @alpha -export const TemplateGroup: ( - props: TemplateGroupProps, -) => React_2.JSX.Element | null; - -// @alpha -export interface TemplateGroupProps { - // (undocumented) - components?: { - CardComponent?: React_2.ComponentType; - }; - // (undocumented) - onSelected: (template: TemplateEntityV1beta3) => void; - // (undocumented) - templates: { - template: TemplateEntityV1beta3; - additionalLinks?: { - icon: IconComponent; - text: string; - url: string; - }[]; - }[]; - // (undocumented) - title: React_2.ReactNode; -} - -// @alpha (undocumented) -export const TemplateGroups: ( - props: TemplateGroupsProps, -) => React_2.JSX.Element | null; - -// @alpha (undocumented) -export interface TemplateGroupsProps { - // (undocumented) - additionalLinksForEntity?: (template: TemplateEntityV1beta3) => { - icon: IconComponent; - text: string; - url: string; - }[]; - // (undocumented) - groups: TemplateGroupFilter[]; - // (undocumented) - onTemplateSelected?: (template: TemplateEntityV1beta3) => void; - // (undocumented) - TemplateCardComponent?: React_2.ComponentType<{ - template: TemplateEntityV1beta3; - }>; - // (undocumented) - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; -} - -// @alpha -export const useFilteredSchemaProperties: ( - manifest: TemplateParameterSchema | undefined, -) => TemplateParameterSchema | undefined; - -// @alpha -export const useFormDataFromQuery: ( - initialState?: Record, -) => [Record, Dispatch>>]; - -// @alpha (undocumented) -export const useTemplateParameterSchema: (templateRef: string) => { - manifest?: TemplateParameterSchema; - loading: boolean; - error?: Error; -}; - -// @alpha -export const useTemplateSchema: (manifest: TemplateParameterSchema) => { - steps: ParsedTemplateSchema[]; - presentation?: TemplatePresentationV1beta3; -}; - -// @alpha (undocumented) -export const Workflow: (workflowProps: WorkflowProps) => JSX.Element | null; - -// @alpha (undocumented) -export type WorkflowProps = { - title?: string; - description?: string; - namespace: string; - templateName: string; - components?: { - ReviewStepComponent?: React_2.ComponentType; - }; - onError(error: Error | undefined): JSX.Element | null; -} & Pick< - StepperProps, - | 'extensions' - | 'formProps' - | 'components' - | 'onCreate' - | 'initialState' - | 'layouts' ->; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/scaffolder-react/report.api.md b/plugins/scaffolder-react/report.api.md deleted file mode 100644 index d62a2b43d4..0000000000 --- a/plugins/scaffolder-react/report.api.md +++ /dev/null @@ -1,567 +0,0 @@ -## API Report File for "@backstage/plugin-scaffolder-react" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ApiHolder } from '@backstage/core-plugin-api'; -import { ApiRef } from '@backstage/frontend-plugin-api'; -import { ComponentType } from 'react'; -import { CustomValidator } from '@rjsf/utils'; -import { ElementType } from 'react'; -import { ErrorSchema } from '@rjsf/utils'; -import { ErrorTransformer } from '@rjsf/utils'; -import { Experimental_DefaultFormStateBehavior } from '@rjsf/utils'; -import { Extension } from '@backstage/core-plugin-api'; -import { FieldValidation } from '@rjsf/utils'; -import Form from '@rjsf/core'; -import { FormContextType } from '@rjsf/utils'; -import { FormEvent } from 'react'; -import type { FormProps as FormProps_2 } from '@rjsf/core'; -import { GenericObjectType } from '@rjsf/utils'; -import { HTMLAttributes } from 'react'; -import { IChangeEvent } from '@rjsf/core'; -import { IdSchema } from '@rjsf/utils'; -import { JsonObject } from '@backstage/types'; -import { JSONSchema7 } from 'json-schema'; -import { JsonValue } from '@backstage/types'; -import { Observable } from '@backstage/types'; -import { PropsWithChildren } from 'react'; -import { default as React_2 } from 'react'; -import { ReactNode } from 'react'; -import { Ref } from 'react'; -import { Registry } from '@rjsf/utils'; -import { RegistryWidgetsType } from '@rjsf/utils'; -import { RJSFSchema } from '@rjsf/utils'; -import { RJSFValidationError } from '@rjsf/utils'; -import { StrictRJSFSchema } from '@rjsf/utils'; -import { TaskSpec } from '@backstage/plugin-scaffolder-common'; -import { TaskStep } from '@backstage/plugin-scaffolder-common'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { TemplatesType } from '@rjsf/utils'; -import { UIOptionsType } from '@rjsf/utils'; -import { UiSchema } from '@rjsf/utils'; -import { ValidatorType } from '@rjsf/utils'; -import { z } from 'zod'; - -// @public -export type Action = { - id: string; - description?: string; - schema?: { - input?: JSONSchema7; - output?: JSONSchema7; - }; - examples?: ActionExample[]; -}; - -// @public -export type ActionExample = { - description: string; - example: string; -}; - -// @public -export function createScaffolderFieldExtension< - TReturnValue = unknown, - TInputProps extends UIOptionsType = {}, ->( - options: FieldExtensionOptions, -): Extension>; - -// @public -export function createScaffolderLayout( - options: LayoutOptions, -): Extension>; - -// @public -export type CustomFieldExtensionSchema = { - returnValue: JSONSchema7; - uiOptions?: JSONSchema7; -}; - -// @public -export type CustomFieldValidator = ( - data: TFieldReturnValue, - field: FieldValidation, - context: { - apiHolder: ApiHolder; - formData: JsonObject; - schema: JsonObject; - uiSchema?: FieldExtensionUiSchema; - }, -) => void | Promise; - -// @public -export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null; - -// @public -export interface FieldExtensionComponentProps< - TFieldReturnValue, - TUiOptions = {}, -> extends PropsWithChildren> { - // (undocumented) - uiSchema: FieldExtensionUiSchema; -} - -// @public -export type FieldExtensionOptions< - TFieldReturnValue = unknown, - TUiOptions = unknown, -> = { - name: string; - component: ( - props: FieldExtensionComponentProps, - ) => JSX.Element | null; - validation?: CustomFieldValidator; - schema?: CustomFieldExtensionSchema; -}; - -// @public -export interface FieldExtensionUiSchema - extends UiSchema { - // (undocumented) - 'ui:options'?: TUiOptions & UIOptionsType; -} - -// @public -export interface FieldSchema { - // (undocumented) - readonly schema: CustomFieldExtensionSchema; - // (undocumented) - readonly TOutput: TReturn; - // (undocumented) - readonly TProps: FieldExtensionComponentProps; - // @deprecated (undocumented) - readonly type: FieldExtensionComponentProps; - // @deprecated (undocumented) - readonly uiOptionsType: TUiOptions; -} - -// @public -export type FormProps = Pick< - FormProps_2, - | 'transformErrors' - | 'noHtml5Validate' - | 'uiSchema' - | 'formContext' - | 'omitExtraData' - | 'liveOmit' ->; - -// @public -export type LayoutComponent<_TInputProps> = () => null; - -// @public -export interface LayoutOptions

{ - // (undocumented) - component: LayoutTemplate

; - // (undocumented) - name: string; -} - -// @public -export type LayoutTemplate = NonNullable< - FormProps_2['uiSchema'] ->['ui:ObjectFieldTemplate']; - -// @public -export type ListActionsResponse = Array; - -// @public -export type LogEvent = { - type: 'log' | 'completion' | 'cancelled' | 'recovered'; - body: { - message: string; - stepId?: string; - status?: ScaffolderTaskStatus; - }; - createdAt: string; - id: string; - taskId: string; -}; - -// @public (undocumented) -export function makeFieldSchema< - TReturnType extends z.ZodType, - TUiOptions extends z.ZodType, ->(options: { - output: (zImpl: typeof z) => TReturnType; - uiOptions?: (zImpl: typeof z) => TUiOptions; -}): FieldSchema, z.output>; - -// @public -export type ReviewStepProps = { - disableButtons: boolean; - formData: JsonObject; - handleBack: () => void; - handleReset: () => void; - handleCreate: () => void; - steps: { - uiSchema: UiSchema; - mergedSchema: JsonObject; - schema: JsonObject; - }[]; -}; - -// @public -export interface ScaffolderApi { - // (undocumented) - autocomplete?(options: { - token: string; - provider: string; - resource: string; - context?: Record; - }): Promise<{ - results: { - title?: string; - id: string; - }[]; - }>; - cancelTask(taskId: string): Promise; - // (undocumented) - dryRun?(options: ScaffolderDryRunOptions): Promise; - // (undocumented) - getIntegrationsList( - options: ScaffolderGetIntegrationsListOptions, - ): Promise; - // (undocumented) - getTask(taskId: string): Promise; - // (undocumented) - getTemplateParameterSchema( - templateRef: string, - ): Promise; - listActions(): Promise; - // (undocumented) - listTasks?(options: { - filterByOwnership: 'owned' | 'all'; - limit?: number; - offset?: number; - }): Promise<{ - tasks: ScaffolderTask[]; - totalTasks?: number; - }>; - retry?(taskId: string): Promise; - scaffold( - options: ScaffolderScaffoldOptions, - ): Promise; - // (undocumented) - streamLogs(options: ScaffolderStreamLogsOptions): Observable; -} - -// @public (undocumented) -export const scaffolderApiRef: ApiRef; - -// @public (undocumented) -export interface ScaffolderDryRunOptions { - // (undocumented) - directoryContents: { - path: string; - base64Content: string; - }[]; - // (undocumented) - secrets?: Record; - // (undocumented) - template: JsonValue; - // (undocumented) - values: JsonObject; -} - -// @public (undocumented) -export interface ScaffolderDryRunResponse { - // (undocumented) - directoryContents: Array<{ - path: string; - base64Content: string; - executable: boolean; - }>; - // (undocumented) - log: Array>; - // (undocumented) - output: ScaffolderTaskOutput; - // (undocumented) - steps: TaskStep[]; -} - -// @public -export const ScaffolderFieldExtensions: React.ComponentType< - React.PropsWithChildren<{}> ->; - -// @public -export interface ScaffolderGetIntegrationsListOptions { - // (undocumented) - allowedHosts: string[]; -} - -// @public -export interface ScaffolderGetIntegrationsListResponse { - // (undocumented) - integrations: { - type: string; - title: string; - host: string; - }[]; -} - -// @public -export const ScaffolderLayouts: React_2.ComponentType< - React_2.PropsWithChildren<{}> ->; - -// @public (undocumented) -export type ScaffolderOutputLink = { - title?: string; - icon?: string; - url?: string; - entityRef?: string; -}; - -// @public (undocumented) -export type ScaffolderOutputText = { - title?: string; - icon?: string; - content?: string; - default?: boolean; -}; - -// @public -export type ScaffolderRJSFField< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, -> = ComponentType>; - -// @public -export interface ScaffolderRJSFFieldProps< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, -> extends GenericObjectType, - Pick< - HTMLAttributes, - Exclude< - keyof HTMLAttributes, - 'onBlur' | 'onFocus' | 'onChange' - > - > { - autofocus?: boolean; - disabled: boolean; - errorSchema?: ErrorSchema; - formContext?: F; - formData?: T; - hideError?: boolean; - idPrefix?: string; - idSchema: IdSchema; - idSeparator?: string; - name: string; - onBlur: (id: string, value: any) => void; - onChange: ( - newFormData: T | undefined, - es?: ErrorSchema, - id?: string, - ) => any; - onFocus: (id: string, value: any) => void; - rawErrors: string[]; - readonly: boolean; - registry: Registry; - required?: boolean; - schema: S; - uiSchema: UiSchema; -} - -// @public -export interface ScaffolderRJSFFormProps< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, -> { - acceptcharset?: string; - action?: string; - autoComplete?: string; - children?: ReactNode; - className?: string; - customValidate?: CustomValidator; - disabled?: boolean; - enctype?: string; - experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior; - extraErrors?: ErrorSchema; - fields?: ScaffolderRJSFRegistryFieldsType; - focusOnFirstError?: boolean | ((error: RJSFValidationError) => void); - formContext?: F; - formData?: T; - id?: string; - idPrefix?: string; - idSeparator?: string; - _internalFormWrapper?: ElementType; - liveOmit?: boolean; - liveValidate?: boolean; - method?: string; - name?: string; - noHtml5Validate?: boolean; - // @deprecated - noValidate?: boolean; - omitExtraData?: boolean; - onBlur?: (id: string, data: any) => void; - onChange?: (data: IChangeEvent, id?: string) => void; - onError?: (errors: RJSFValidationError[]) => void; - onFocus?: (id: string, data: any) => void; - onSubmit?: (data: IChangeEvent, event: FormEvent) => void; - readonly?: boolean; - ref?: Ref>; - schema: S; - showErrorList?: false | 'top' | 'bottom'; - tagName?: ElementType; - target?: string; - templates?: Partial, 'ButtonTemplates'>> & { - ButtonTemplates?: Partial['ButtonTemplates']>; - }; - transformErrors?: ErrorTransformer; - translateString?: Registry['translateString']; - uiSchema?: UiSchema; - validator: ValidatorType; - widgets?: RegistryWidgetsType; -} - -// @public -export type ScaffolderRJSFRegistryFieldsType< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, -> = { - [name: string]: ScaffolderRJSFField; -}; - -// @public -export interface ScaffolderScaffoldOptions { - // (undocumented) - secrets?: Record; - // (undocumented) - templateRef: string; - // (undocumented) - values: Record; -} - -// @public -export interface ScaffolderScaffoldResponse { - // (undocumented) - taskId: string; -} - -// @public -export type ScaffolderStep = { - id: string; - status: ScaffolderTaskStatus; - endedAt?: string; - startedAt?: string; -}; - -// @public -export interface ScaffolderStreamLogsOptions { - // (undocumented) - after?: number; - // (undocumented) - isTaskRecoverable?: boolean; - // (undocumented) - taskId: string; -} - -// @public -export type ScaffolderTask = { - id: string; - spec: TaskSpec; - status: 'failed' | 'completed' | 'processing' | 'open' | 'cancelled'; - lastHeartbeatAt: string; - createdAt: string; -}; - -// @public (undocumented) -export type ScaffolderTaskOutput = { - links?: ScaffolderOutputLink[]; - text?: ScaffolderOutputText[]; -} & { - [key: string]: unknown; -}; - -// @public -export type ScaffolderTaskStatus = - | 'cancelled' - | 'completed' - | 'failed' - | 'open' - | 'processing' - | 'skipped'; - -// @public -export interface ScaffolderUseTemplateSecrets { - // (undocumented) - secrets: Record; - // (undocumented) - setSecrets: (input: Record) => void; -} - -// @public -export const SecretsContextProvider: ( - props: PropsWithChildren<{ - initialSecrets?: Record; - }>, -) => React_2.JSX.Element; - -// @public -export type TaskStream = { - cancelled: boolean; - loading: boolean; - error?: Error; - stepLogs: { - [stepId in string]: string[]; - }; - completed: boolean; - task?: ScaffolderTask; - steps: { - [stepId in string]: ScaffolderStep; - }; - output?: ScaffolderTaskOutput; -}; - -// @public (undocumented) -export type TemplateGroupFilter = { - title?: React.ReactNode; - filter: (entity: TemplateEntityV1beta3) => boolean; -}; - -// @public -export type TemplateParameterSchema = { - title: string; - description?: string; - presentation?: TemplatePresentationV1beta3; - steps: Array<{ - title: string; - description?: string; - schema: JsonObject; - }>; - EXPERIMENTAL_formDecorators?: { - id: string; - input?: JsonObject; - }[]; -}; - -// @public -export const useCustomFieldExtensions: < - TComponentDataType = FieldExtensionOptions, ->( - outlet: React.ReactNode, -) => TComponentDataType[]; - -// @public -export const useCustomLayouts: >( - outlet: React.ReactNode, -) => TComponentDataType[]; - -// @public -export const useTaskEventStream: (taskId: string) => TaskStream; - -// @public -export const useTemplateSecrets: () => ScaffolderUseTemplateSecrets; - -// (No @packageDocumentation comment for this package) -``` From 1bf0867dee0196985d988e38301ba911247316a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Vit=C3=A1sek?= Date: Wed, 19 Mar 2025 08:38:37 +0100 Subject: [PATCH 5/6] feat: add usage documentation for backstage-cli config:docs command and create new configuration files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ladislav Vitásek --- plugins/scaffolder-react/report-alpha.api.md | 524 +++++++++++++++++ plugins/scaffolder-react/report.api.md | 567 +++++++++++++++++++ 2 files changed, 1091 insertions(+) create mode 100644 plugins/scaffolder-react/report-alpha.api.md create mode 100644 plugins/scaffolder-react/report.api.md diff --git a/plugins/scaffolder-react/report-alpha.api.md b/plugins/scaffolder-react/report-alpha.api.md new file mode 100644 index 0000000000..ad9f31480a --- /dev/null +++ b/plugins/scaffolder-react/report-alpha.api.md @@ -0,0 +1,524 @@ +## API Report File for "@backstage/plugin-scaffolder-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { AnyApiFactory } from '@backstage/frontend-plugin-api'; +import { AnyApiRef } from '@backstage/core-plugin-api'; +import { ApiHolder } from '@backstage/core-plugin-api'; +import { ApiRef } from '@backstage/frontend-plugin-api'; +import { ComponentType } from 'react'; +import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; +import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; +import { Dispatch } from 'react'; +import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; +import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { ExtensionInput } from '@backstage/frontend-plugin-api'; +import { FieldExtensionComponentProps } from '@backstage/plugin-scaffolder-react'; +import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; +import { FieldSchema } from '@backstage/plugin-scaffolder-react'; +import { FieldValidation } from '@rjsf/utils'; +import { FormField } from '@internal/scaffolder'; +import { FormProps } from '@backstage/plugin-scaffolder-react'; +import { IconComponent } from '@backstage/core-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { JsonValue } from '@backstage/types'; +import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; +import { Overrides } from '@material-ui/core/styles/overrides'; +import { PropsWithChildren } from 'react'; +import { default as React_2 } from 'react'; +import { ReactElement } from 'react'; +import { ReactNode } from 'react'; +import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderRJSFFormProps } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderStep } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; +import { SetStateAction } from 'react'; +import { StyleRules } from '@material-ui/core/styles/withStyles'; +import { TaskStep } from '@backstage/plugin-scaffolder-common'; +import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react'; +import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; +import { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { TranslationRef } from '@backstage/core-plugin-api/alpha'; +import { UiSchema } from '@rjsf/utils'; +import { WidgetProps } from '@rjsf/utils'; +import { z } from 'zod'; + +// @alpha (undocumented) +export type BackstageOverrides = Overrides & { + [Name in keyof ScaffolderReactComponentsNameToClassKey]?: Partial< + StyleRules + >; +}; + +// @alpha (undocumented) +export type BackstageTemplateStepperClassKey = + | 'backButton' + | 'footer' + | 'formWrapper'; + +// @alpha (undocumented) +export const createAsyncValidators: ( + rootSchema: JsonObject, + validators: Record< + string, + undefined | CustomFieldValidator + >, + context: { + apiHolder: ApiHolder; + }, +) => (formData: JsonObject) => Promise; + +// @alpha +export const createFieldValidation: () => FieldValidation; + +// @alpha +export function createFormField< + TReturnValue extends z.ZodType, + TUiOptions extends z.ZodType, +>(opts: FormFieldExtensionData): FormField; + +// @alpha +export function createScaffolderFormDecorator< + TInputSchema extends { + [key in string]: (zImpl: typeof z) => z.ZodType; + } = { + [key in string]: (zImpl: typeof z) => z.ZodType; + }, + TDeps extends { + [key in string]: AnyApiRef; + } = { + [key in string]: AnyApiRef; + }, + TInput extends JsonObject = { + [key in keyof TInputSchema]: z.infer>; + }, +>(options: { + id: string; + schema?: { + input?: TInputSchema; + }; + deps?: TDeps; + decorator: ( + ctx: ScaffolderFormDecoratorContext, + deps: TDeps extends { + [key in string]: AnyApiRef; + } + ? { + [key in keyof TDeps]: TDeps[key]['T']; + } + : never, + ) => Promise; +}): ScaffolderFormDecorator; + +// @alpha +export const DefaultTemplateOutputs: (props: { + output?: ScaffolderTaskOutput; +}) => React_2.JSX.Element | null; + +// @alpha (undocumented) +export const EmbeddableWorkflow: (props: WorkflowProps) => React_2.JSX.Element; + +// @alpha +export const extractSchemaFromStep: (inputStep: JsonObject) => { + uiSchema: UiSchema; + schema: JsonObject; +}; + +// @alpha +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'; + name: undefined; + params: { + field: () => Promise; + }; + output: ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { + formFieldLoader: ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >; + }; +}>; + +// @alpha (undocumented) +export type FormFieldExtensionData< + TReturnValue extends z.ZodType = z.ZodType, + TUiOptions extends z.ZodType = z.ZodType, +> = { + name: string; + component: ( + props: FieldExtensionComponentProps< + z.output, + z.output + >, + ) => JSX.Element | null; + validation?: CustomFieldValidator< + z.output, + z.output + >; + schema?: FieldSchema, z.output>; +}; + +// @alpha (undocumented) +export const formFieldsApi: ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef; + inputs: { + formFields: ExtensionInput< + ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >, + { + singleton: false; + optional: false; + } + >; + }; + kind: 'api'; + name: 'form-fields'; + params: { + factory: AnyApiFactory; + }; +}>; + +// @alpha @deprecated (undocumented) +export const formFieldsApiRef: ApiRef; + +// @alpha (undocumented) +export type FormValidation = { + [name: string]: FieldValidation | FormValidation; +}; + +// @alpha +export interface ParsedTemplateSchema { + // (undocumented) + description?: string; + // (undocumented) + mergedSchema: JsonObject; + // (undocumented) + schema: JsonObject; + // (undocumented) + title: string; + // (undocumented) + uiSchema: UiSchema; +} + +// @alpha +export const ReviewState: (props: ReviewStateProps) => React_2.JSX.Element; + +// @alpha +export type ReviewStateProps = { + schemas: ParsedTemplateSchema[]; + formState: JsonObject; +}; + +// @alpha +export const ScaffolderField: ( + props: PropsWithChildren, +) => React_2.JSX.Element; + +// @alpha +export interface ScaffolderFieldProps { + // (undocumented) + disabled?: boolean; + // (undocumented) + displayLabel?: boolean; + // (undocumented) + errors?: ReactElement; + // (undocumented) + help?: ReactElement; + // (undocumented) + rawDescription?: string; + // (undocumented) + rawErrors?: string[]; + // (undocumented) + rawHelp?: string; + // (undocumented) + required?: boolean; +} + +// @alpha (undocumented) +export type ScaffolderFormDecorator = { + readonly $$type: '@backstage/scaffolder/FormDecorator'; + readonly id: string; + readonly TInput: TInput; +}; + +// @alpha (undocumented) +export type ScaffolderFormDecoratorContext< + TInput extends JsonObject = JsonObject, +> = { + input: TInput; + formState: Record; + setFormState: ( + fn: (currentState: Record) => Record, + ) => void; + setSecrets: ( + fn: (currentState: Record) => Record, + ) => void; +}; + +// @alpha @deprecated (undocumented) +export interface ScaffolderFormFieldsApi { + // (undocumented) + getFormFields(): Promise; +} + +// @alpha (undocumented) +export function ScaffolderPageContextMenu( + props: ScaffolderPageContextMenuProps, +): React_2.JSX.Element | null; + +// @alpha (undocumented) +export type ScaffolderPageContextMenuProps = { + onEditorClicked?: () => void; + onActionsClicked?: () => void; + onTasksClicked?: () => void; + onCreateClicked?: () => void; +}; + +// @alpha (undocumented) +export type ScaffolderReactComponentsNameToClassKey = { + ScaffolderReactTemplateCategoryPicker: ScaffolderReactTemplateCategoryPickerClassKey; + BackstageTemplateStepper: BackstageTemplateStepperClassKey; +}; + +// @alpha (undocumented) +export type ScaffolderReactTemplateCategoryPickerClassKey = 'root' | 'label'; + +// @alpha (undocumented) +export const scaffolderReactTranslationRef: TranslationRef< + 'scaffolder-react', + { + readonly 'passwordWidget.content': 'This widget is insecure. Please use [`ui:field: Secret`](https://backstage.io/docs/features/software-templates/writing-templates/#using-secrets) instead of `ui:widget: password`'; + readonly 'scaffolderPageContextMenu.moreLabel': 'more'; + readonly 'scaffolderPageContextMenu.createLabel': 'Create'; + readonly 'scaffolderPageContextMenu.editorLabel': 'Manage Templates'; + readonly 'scaffolderPageContextMenu.actionsLabel': 'Installed Actions'; + readonly 'scaffolderPageContextMenu.tasksLabel': 'Task List'; + readonly 'stepper.backButtonText': 'Back'; + readonly 'stepper.createButtonText': 'Create'; + readonly 'stepper.reviewButtonText': 'Review'; + readonly 'stepper.stepIndexLabel': 'Step {{index, number}}'; + readonly 'stepper.nextButtonText': 'Next'; + readonly 'templateCategoryPicker.title': 'Categories'; + readonly 'templateCard.noDescription': 'No description'; + readonly 'templateCard.chooseButtonText': 'Choose'; + readonly 'cardHeader.detailBtnTitle': 'Show template entity details'; + readonly 'templateOutputs.title': 'Text Output'; + readonly 'workflow.noDescription': 'No description'; + } +>; + +// @alpha +export const SecretWidget: ( + props: Pick< + WidgetProps, + 'name' | 'onChange' | 'schema' | 'required' | 'disabled' + >, +) => React_2.JSX.Element; + +// @alpha +export const Stepper: (stepperProps: StepperProps) => React_2.JSX.Element; + +// @alpha +export type StepperProps = { + manifest: TemplateParameterSchema; + extensions: FieldExtensionOptions[]; + templateName?: string; + formProps?: FormProps; + initialState?: Record; + onCreate: (values: Record) => Promise; + components?: { + ReviewStepComponent?: ComponentType; + ReviewStateComponent?: (props: ReviewStateProps) => JSX.Element; + backButtonText?: ReactNode; + createButtonText?: ReactNode; + reviewButtonText?: ReactNode; + }; + layouts?: LayoutOptions[]; +}; + +// @alpha +export const TaskLogStream: (props: { + logs: { + [k: string]: string[]; + }; +}) => React_2.JSX.Element; + +// @alpha +export const TaskSteps: (props: TaskStepsProps) => React_2.JSX.Element; + +// @alpha +export interface TaskStepsProps { + // (undocumented) + activeStep?: number; + // (undocumented) + isComplete?: boolean; + // (undocumented) + isError?: boolean; + // (undocumented) + steps: (TaskStep & ScaffolderStep)[]; +} + +// @alpha +export const TemplateCard: (props: TemplateCardProps) => React_2.JSX.Element; + +// @alpha +export interface TemplateCardProps { + // (undocumented) + additionalLinks?: { + icon: IconComponent; + text: string; + url: string; + }[]; + // (undocumented) + onSelected?: (template: TemplateEntityV1beta3) => void; + // (undocumented) + template: TemplateEntityV1beta3; +} + +// @alpha +export const TemplateCategoryPicker: () => React_2.JSX.Element | null; + +// @alpha +export const TemplateGroup: ( + props: TemplateGroupProps, +) => React_2.JSX.Element | null; + +// @alpha +export interface TemplateGroupProps { + // (undocumented) + components?: { + CardComponent?: React_2.ComponentType; + }; + // (undocumented) + onSelected: (template: TemplateEntityV1beta3) => void; + // (undocumented) + templates: { + template: TemplateEntityV1beta3; + additionalLinks?: { + icon: IconComponent; + text: string; + url: string; + }[]; + }[]; + // (undocumented) + title: React_2.ReactNode; +} + +// @alpha (undocumented) +export const TemplateGroups: ( + props: TemplateGroupsProps, +) => React_2.JSX.Element | null; + +// @alpha (undocumented) +export interface TemplateGroupsProps { + // (undocumented) + additionalLinksForEntity?: (template: TemplateEntityV1beta3) => { + icon: IconComponent; + text: string; + url: string; + }[]; + // (undocumented) + groups: TemplateGroupFilter[]; + // (undocumented) + onTemplateSelected?: (template: TemplateEntityV1beta3) => void; + // (undocumented) + TemplateCardComponent?: React_2.ComponentType<{ + template: TemplateEntityV1beta3; + }>; + // (undocumented) + templateFilter?: (entity: TemplateEntityV1beta3) => boolean; +} + +// @alpha +export const useFilteredSchemaProperties: ( + manifest: TemplateParameterSchema | undefined, +) => TemplateParameterSchema | undefined; + +// @alpha +export const useFormDataFromQuery: ( + initialState?: Record, +) => [Record, Dispatch>>]; + +// @alpha (undocumented) +export const useTemplateParameterSchema: (templateRef: string) => { + manifest?: TemplateParameterSchema; + loading: boolean; + error?: Error; +}; + +// @alpha +export const useTemplateSchema: (manifest: TemplateParameterSchema) => { + steps: ParsedTemplateSchema[]; + presentation?: TemplatePresentationV1beta3; +}; + +// @alpha (undocumented) +export const Workflow: (workflowProps: WorkflowProps) => JSX.Element | null; + +// @alpha (undocumented) +export type WorkflowProps = { + title?: string; + description?: string; + namespace: string; + templateName: string; + components?: { + ReviewStepComponent?: React_2.ComponentType; + }; + onError(error: Error | undefined): JSX.Element | null; +} & Pick< + StepperProps, + | 'extensions' + | 'formProps' + | 'components' + | 'onCreate' + | 'initialState' + | 'layouts' +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/scaffolder-react/report.api.md b/plugins/scaffolder-react/report.api.md new file mode 100644 index 0000000000..d62a2b43d4 --- /dev/null +++ b/plugins/scaffolder-react/report.api.md @@ -0,0 +1,567 @@ +## API Report File for "@backstage/plugin-scaffolder-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ApiHolder } from '@backstage/core-plugin-api'; +import { ApiRef } from '@backstage/frontend-plugin-api'; +import { ComponentType } from 'react'; +import { CustomValidator } from '@rjsf/utils'; +import { ElementType } from 'react'; +import { ErrorSchema } from '@rjsf/utils'; +import { ErrorTransformer } from '@rjsf/utils'; +import { Experimental_DefaultFormStateBehavior } from '@rjsf/utils'; +import { Extension } from '@backstage/core-plugin-api'; +import { FieldValidation } from '@rjsf/utils'; +import Form from '@rjsf/core'; +import { FormContextType } from '@rjsf/utils'; +import { FormEvent } from 'react'; +import type { FormProps as FormProps_2 } from '@rjsf/core'; +import { GenericObjectType } from '@rjsf/utils'; +import { HTMLAttributes } from 'react'; +import { IChangeEvent } from '@rjsf/core'; +import { IdSchema } from '@rjsf/utils'; +import { JsonObject } from '@backstage/types'; +import { JSONSchema7 } from 'json-schema'; +import { JsonValue } from '@backstage/types'; +import { Observable } from '@backstage/types'; +import { PropsWithChildren } from 'react'; +import { default as React_2 } from 'react'; +import { ReactNode } from 'react'; +import { Ref } from 'react'; +import { Registry } from '@rjsf/utils'; +import { RegistryWidgetsType } from '@rjsf/utils'; +import { RJSFSchema } from '@rjsf/utils'; +import { RJSFValidationError } from '@rjsf/utils'; +import { StrictRJSFSchema } from '@rjsf/utils'; +import { TaskSpec } from '@backstage/plugin-scaffolder-common'; +import { TaskStep } from '@backstage/plugin-scaffolder-common'; +import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { TemplatesType } from '@rjsf/utils'; +import { UIOptionsType } from '@rjsf/utils'; +import { UiSchema } from '@rjsf/utils'; +import { ValidatorType } from '@rjsf/utils'; +import { z } from 'zod'; + +// @public +export type Action = { + id: string; + description?: string; + schema?: { + input?: JSONSchema7; + output?: JSONSchema7; + }; + examples?: ActionExample[]; +}; + +// @public +export type ActionExample = { + description: string; + example: string; +}; + +// @public +export function createScaffolderFieldExtension< + TReturnValue = unknown, + TInputProps extends UIOptionsType = {}, +>( + options: FieldExtensionOptions, +): Extension>; + +// @public +export function createScaffolderLayout( + options: LayoutOptions, +): Extension>; + +// @public +export type CustomFieldExtensionSchema = { + returnValue: JSONSchema7; + uiOptions?: JSONSchema7; +}; + +// @public +export type CustomFieldValidator = ( + data: TFieldReturnValue, + field: FieldValidation, + context: { + apiHolder: ApiHolder; + formData: JsonObject; + schema: JsonObject; + uiSchema?: FieldExtensionUiSchema; + }, +) => void | Promise; + +// @public +export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null; + +// @public +export interface FieldExtensionComponentProps< + TFieldReturnValue, + TUiOptions = {}, +> extends PropsWithChildren> { + // (undocumented) + uiSchema: FieldExtensionUiSchema; +} + +// @public +export type FieldExtensionOptions< + TFieldReturnValue = unknown, + TUiOptions = unknown, +> = { + name: string; + component: ( + props: FieldExtensionComponentProps, + ) => JSX.Element | null; + validation?: CustomFieldValidator; + schema?: CustomFieldExtensionSchema; +}; + +// @public +export interface FieldExtensionUiSchema + extends UiSchema { + // (undocumented) + 'ui:options'?: TUiOptions & UIOptionsType; +} + +// @public +export interface FieldSchema { + // (undocumented) + readonly schema: CustomFieldExtensionSchema; + // (undocumented) + readonly TOutput: TReturn; + // (undocumented) + readonly TProps: FieldExtensionComponentProps; + // @deprecated (undocumented) + readonly type: FieldExtensionComponentProps; + // @deprecated (undocumented) + readonly uiOptionsType: TUiOptions; +} + +// @public +export type FormProps = Pick< + FormProps_2, + | 'transformErrors' + | 'noHtml5Validate' + | 'uiSchema' + | 'formContext' + | 'omitExtraData' + | 'liveOmit' +>; + +// @public +export type LayoutComponent<_TInputProps> = () => null; + +// @public +export interface LayoutOptions

{ + // (undocumented) + component: LayoutTemplate

; + // (undocumented) + name: string; +} + +// @public +export type LayoutTemplate = NonNullable< + FormProps_2['uiSchema'] +>['ui:ObjectFieldTemplate']; + +// @public +export type ListActionsResponse = Array; + +// @public +export type LogEvent = { + type: 'log' | 'completion' | 'cancelled' | 'recovered'; + body: { + message: string; + stepId?: string; + status?: ScaffolderTaskStatus; + }; + createdAt: string; + id: string; + taskId: string; +}; + +// @public (undocumented) +export function makeFieldSchema< + TReturnType extends z.ZodType, + TUiOptions extends z.ZodType, +>(options: { + output: (zImpl: typeof z) => TReturnType; + uiOptions?: (zImpl: typeof z) => TUiOptions; +}): FieldSchema, z.output>; + +// @public +export type ReviewStepProps = { + disableButtons: boolean; + formData: JsonObject; + handleBack: () => void; + handleReset: () => void; + handleCreate: () => void; + steps: { + uiSchema: UiSchema; + mergedSchema: JsonObject; + schema: JsonObject; + }[]; +}; + +// @public +export interface ScaffolderApi { + // (undocumented) + autocomplete?(options: { + token: string; + provider: string; + resource: string; + context?: Record; + }): Promise<{ + results: { + title?: string; + id: string; + }[]; + }>; + cancelTask(taskId: string): Promise; + // (undocumented) + dryRun?(options: ScaffolderDryRunOptions): Promise; + // (undocumented) + getIntegrationsList( + options: ScaffolderGetIntegrationsListOptions, + ): Promise; + // (undocumented) + getTask(taskId: string): Promise; + // (undocumented) + getTemplateParameterSchema( + templateRef: string, + ): Promise; + listActions(): Promise; + // (undocumented) + listTasks?(options: { + filterByOwnership: 'owned' | 'all'; + limit?: number; + offset?: number; + }): Promise<{ + tasks: ScaffolderTask[]; + totalTasks?: number; + }>; + retry?(taskId: string): Promise; + scaffold( + options: ScaffolderScaffoldOptions, + ): Promise; + // (undocumented) + streamLogs(options: ScaffolderStreamLogsOptions): Observable; +} + +// @public (undocumented) +export const scaffolderApiRef: ApiRef; + +// @public (undocumented) +export interface ScaffolderDryRunOptions { + // (undocumented) + directoryContents: { + path: string; + base64Content: string; + }[]; + // (undocumented) + secrets?: Record; + // (undocumented) + template: JsonValue; + // (undocumented) + values: JsonObject; +} + +// @public (undocumented) +export interface ScaffolderDryRunResponse { + // (undocumented) + directoryContents: Array<{ + path: string; + base64Content: string; + executable: boolean; + }>; + // (undocumented) + log: Array>; + // (undocumented) + output: ScaffolderTaskOutput; + // (undocumented) + steps: TaskStep[]; +} + +// @public +export const ScaffolderFieldExtensions: React.ComponentType< + React.PropsWithChildren<{}> +>; + +// @public +export interface ScaffolderGetIntegrationsListOptions { + // (undocumented) + allowedHosts: string[]; +} + +// @public +export interface ScaffolderGetIntegrationsListResponse { + // (undocumented) + integrations: { + type: string; + title: string; + host: string; + }[]; +} + +// @public +export const ScaffolderLayouts: React_2.ComponentType< + React_2.PropsWithChildren<{}> +>; + +// @public (undocumented) +export type ScaffolderOutputLink = { + title?: string; + icon?: string; + url?: string; + entityRef?: string; +}; + +// @public (undocumented) +export type ScaffolderOutputText = { + title?: string; + icon?: string; + content?: string; + default?: boolean; +}; + +// @public +export type ScaffolderRJSFField< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any, +> = ComponentType>; + +// @public +export interface ScaffolderRJSFFieldProps< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any, +> extends GenericObjectType, + Pick< + HTMLAttributes, + Exclude< + keyof HTMLAttributes, + 'onBlur' | 'onFocus' | 'onChange' + > + > { + autofocus?: boolean; + disabled: boolean; + errorSchema?: ErrorSchema; + formContext?: F; + formData?: T; + hideError?: boolean; + idPrefix?: string; + idSchema: IdSchema; + idSeparator?: string; + name: string; + onBlur: (id: string, value: any) => void; + onChange: ( + newFormData: T | undefined, + es?: ErrorSchema, + id?: string, + ) => any; + onFocus: (id: string, value: any) => void; + rawErrors: string[]; + readonly: boolean; + registry: Registry; + required?: boolean; + schema: S; + uiSchema: UiSchema; +} + +// @public +export interface ScaffolderRJSFFormProps< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any, +> { + acceptcharset?: string; + action?: string; + autoComplete?: string; + children?: ReactNode; + className?: string; + customValidate?: CustomValidator; + disabled?: boolean; + enctype?: string; + experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior; + extraErrors?: ErrorSchema; + fields?: ScaffolderRJSFRegistryFieldsType; + focusOnFirstError?: boolean | ((error: RJSFValidationError) => void); + formContext?: F; + formData?: T; + id?: string; + idPrefix?: string; + idSeparator?: string; + _internalFormWrapper?: ElementType; + liveOmit?: boolean; + liveValidate?: boolean; + method?: string; + name?: string; + noHtml5Validate?: boolean; + // @deprecated + noValidate?: boolean; + omitExtraData?: boolean; + onBlur?: (id: string, data: any) => void; + onChange?: (data: IChangeEvent, id?: string) => void; + onError?: (errors: RJSFValidationError[]) => void; + onFocus?: (id: string, data: any) => void; + onSubmit?: (data: IChangeEvent, event: FormEvent) => void; + readonly?: boolean; + ref?: Ref>; + schema: S; + showErrorList?: false | 'top' | 'bottom'; + tagName?: ElementType; + target?: string; + templates?: Partial, 'ButtonTemplates'>> & { + ButtonTemplates?: Partial['ButtonTemplates']>; + }; + transformErrors?: ErrorTransformer; + translateString?: Registry['translateString']; + uiSchema?: UiSchema; + validator: ValidatorType; + widgets?: RegistryWidgetsType; +} + +// @public +export type ScaffolderRJSFRegistryFieldsType< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any, +> = { + [name: string]: ScaffolderRJSFField; +}; + +// @public +export interface ScaffolderScaffoldOptions { + // (undocumented) + secrets?: Record; + // (undocumented) + templateRef: string; + // (undocumented) + values: Record; +} + +// @public +export interface ScaffolderScaffoldResponse { + // (undocumented) + taskId: string; +} + +// @public +export type ScaffolderStep = { + id: string; + status: ScaffolderTaskStatus; + endedAt?: string; + startedAt?: string; +}; + +// @public +export interface ScaffolderStreamLogsOptions { + // (undocumented) + after?: number; + // (undocumented) + isTaskRecoverable?: boolean; + // (undocumented) + taskId: string; +} + +// @public +export type ScaffolderTask = { + id: string; + spec: TaskSpec; + status: 'failed' | 'completed' | 'processing' | 'open' | 'cancelled'; + lastHeartbeatAt: string; + createdAt: string; +}; + +// @public (undocumented) +export type ScaffolderTaskOutput = { + links?: ScaffolderOutputLink[]; + text?: ScaffolderOutputText[]; +} & { + [key: string]: unknown; +}; + +// @public +export type ScaffolderTaskStatus = + | 'cancelled' + | 'completed' + | 'failed' + | 'open' + | 'processing' + | 'skipped'; + +// @public +export interface ScaffolderUseTemplateSecrets { + // (undocumented) + secrets: Record; + // (undocumented) + setSecrets: (input: Record) => void; +} + +// @public +export const SecretsContextProvider: ( + props: PropsWithChildren<{ + initialSecrets?: Record; + }>, +) => React_2.JSX.Element; + +// @public +export type TaskStream = { + cancelled: boolean; + loading: boolean; + error?: Error; + stepLogs: { + [stepId in string]: string[]; + }; + completed: boolean; + task?: ScaffolderTask; + steps: { + [stepId in string]: ScaffolderStep; + }; + output?: ScaffolderTaskOutput; +}; + +// @public (undocumented) +export type TemplateGroupFilter = { + title?: React.ReactNode; + filter: (entity: TemplateEntityV1beta3) => boolean; +}; + +// @public +export type TemplateParameterSchema = { + title: string; + description?: string; + presentation?: TemplatePresentationV1beta3; + steps: Array<{ + title: string; + description?: string; + schema: JsonObject; + }>; + EXPERIMENTAL_formDecorators?: { + id: string; + input?: JsonObject; + }[]; +}; + +// @public +export const useCustomFieldExtensions: < + TComponentDataType = FieldExtensionOptions, +>( + outlet: React.ReactNode, +) => TComponentDataType[]; + +// @public +export const useCustomLayouts: >( + outlet: React.ReactNode, +) => TComponentDataType[]; + +// @public +export const useTaskEventStream: (taskId: string) => TaskStream; + +// @public +export const useTemplateSecrets: () => ScaffolderUseTemplateSecrets; + +// (No @packageDocumentation comment for this package) +``` From fedb6a94f38c47a8385d4b102a506d820b709399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 21 Mar 2025 14:40:51 +0100 Subject: [PATCH 6/6] fix reports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/home/report.api.md | 3 ++- plugins/scaffolder-react/report-alpha.api.md | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/home/report.api.md b/plugins/home/report.api.md index eacf1a99a9..ef5a0d5a7a 100644 --- a/plugins/home/report.api.md +++ b/plugins/home/report.api.md @@ -50,7 +50,8 @@ export const ComponentAccordion: (props: { expanded?: boolean; Content: () => JSX.Element; Actions?: () => JSX.Element; - Settings?: () => JSX.Element; + Settings?: () => JSX./** @public */ + Element; ContextProvider?: (props: any) => JSX.Element; }) => JSX_2.Element; diff --git a/plugins/scaffolder-react/report-alpha.api.md b/plugins/scaffolder-react/report-alpha.api.md index ad9f31480a..fbd539f96e 100644 --- a/plugins/scaffolder-react/report-alpha.api.md +++ b/plugins/scaffolder-react/report-alpha.api.md @@ -332,9 +332,10 @@ export type ScaffolderReactTemplateCategoryPickerClassKey = 'root' | 'label'; export const scaffolderReactTranslationRef: TranslationRef< 'scaffolder-react', { + readonly 'workflow.noDescription': 'No description'; readonly 'passwordWidget.content': 'This widget is insecure. Please use [`ui:field: Secret`](https://backstage.io/docs/features/software-templates/writing-templates/#using-secrets) instead of `ui:widget: password`'; - readonly 'scaffolderPageContextMenu.moreLabel': 'more'; readonly 'scaffolderPageContextMenu.createLabel': 'Create'; + readonly 'scaffolderPageContextMenu.moreLabel': 'more'; readonly 'scaffolderPageContextMenu.editorLabel': 'Manage Templates'; readonly 'scaffolderPageContextMenu.actionsLabel': 'Installed Actions'; readonly 'scaffolderPageContextMenu.tasksLabel': 'Task List'; @@ -348,7 +349,6 @@ export const scaffolderReactTranslationRef: TranslationRef< readonly 'templateCard.chooseButtonText': 'Choose'; readonly 'cardHeader.detailBtnTitle': 'Show template entity details'; readonly 'templateOutputs.title': 'Text Output'; - readonly 'workflow.noDescription': 'No description'; } >;