diff --git a/.changeset/angry-trees-relax.md b/.changeset/angry-trees-relax.md index 23d5704cbd..761d7db854 100644 --- a/.changeset/angry-trees-relax.md +++ b/.changeset/angry-trees-relax.md @@ -2,7 +2,7 @@ '@backstage/plugin-scaffolder': patch --- -Enabling the customization of the last page in the scaffolder template. +Enabling the customization of the last step in the scaffolder template. To override the content you have to do the next: diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/LastStepForm.tsx b/plugins/scaffolder/src/components/MultistepJsonForm/LastStepForm.tsx index 3ee6609c73..04ac867a23 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/LastStepForm.tsx +++ b/plugins/scaffolder/src/components/MultistepJsonForm/LastStepForm.tsx @@ -16,9 +16,9 @@ import { Box, Button, Paper, Typography } from '@material-ui/core'; import React from 'react'; import { Content, StructuredMetadataTable } from '@backstage/core-components'; -import { Step } from './types'; import { UiSchema } from '@rjsf/core'; import { JsonObject } from '@backstage/types'; +import { Step } from '../types'; /** * The props for the Last Step in scaffolder template form. diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx index bf85210eee..0c54e84ead 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx +++ b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx @@ -28,13 +28,13 @@ import { } from '@backstage/core-plugin-api'; import { FormProps, IChangeEvent, withTheme } from '@rjsf/core'; import { Theme as MuiTheme } from '@rjsf/material-ui'; -import React, { useState } from 'react'; +import React, { ComponentType, useState } from 'react'; import { transformSchemaToProps } from './schema'; import cloneDeep from 'lodash/cloneDeep'; import * as fieldOverrides from './FieldOverrides'; import { LayoutOptions } from '../../layouts'; -import { Step } from './types'; -import { useScaffolderPluginOptions } from '../../options'; +import { LastStepFormProps, Step } from '../types'; +import { LastStepForm } from './LastStepForm'; const Form = withTheme(MuiTheme); @@ -56,6 +56,7 @@ export type MultistepJsonFormProps = { fields?: FormProps['fields']; finishButtonLabel?: string; layouts: LayoutOptions[]; + LastStepFormComponent?: ComponentType; }; /** @@ -73,6 +74,7 @@ export const MultistepJsonForm = (props: MultistepJsonFormProps) => { widgets, finishButtonLabel, layouts, + LastStepFormComponent, } = props; const [activeStep, setActiveStep] = useState(0); const [disableButtons, setDisableButtons] = useState(false); @@ -140,7 +142,7 @@ export const MultistepJsonForm = (props: MultistepJsonFormProps) => { } }; - const { lastStepFormComponent } = useScaffolderPluginOptions(); + const LastStepFormElement = LastStepFormComponent ?? LastStepForm; return ( <> @@ -184,16 +186,17 @@ export const MultistepJsonForm = (props: MultistepJsonFormProps) => { ); })} - {activeStep === steps.length && - lastStepFormComponent({ - disableButtons, - handleBack, - handleCreate, - handleReset, - finishButtonLabel, - formData, - steps, - })} + {activeStep === steps.length && ( + + )} ); }; diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/index.ts b/plugins/scaffolder/src/components/MultistepJsonForm/index.ts index 262bd0447f..784dd7c1b9 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/index.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/index.ts @@ -17,4 +17,3 @@ export { MultistepJsonForm } from './MultistepJsonForm'; export type { MultistepJsonFormProps } from './MultistepJsonForm'; export { lastStepFormComponent, LastStepForm } from './LastStepForm'; export type { LastStepFormProps } from './LastStepForm'; -export type { Step } from './types'; diff --git a/plugins/scaffolder/src/components/Router.tsx b/plugins/scaffolder/src/components/Router.tsx index 021d73f5e9..a27d16644e 100644 --- a/plugins/scaffolder/src/components/Router.tsx +++ b/plugins/scaffolder/src/components/Router.tsx @@ -15,7 +15,7 @@ */ import React, { ComponentType, useEffect } from 'react'; -import { Routes, Route, useOutlet, Navigate } from 'react-router'; +import { Navigate, Route, Routes, useOutlet } from 'react-router'; import { Entity } from '@backstage/catalog-model'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { ScaffolderPage } from './ScaffolderPage'; @@ -26,10 +26,10 @@ import { SecretsContextProvider } from './secrets/SecretsContext'; import { TemplateEditorPage } from './TemplateEditorPage'; import { - FieldExtensionOptions, - FIELD_EXTENSION_WRAPPER_KEY, - FIELD_EXTENSION_KEY, DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS, + FIELD_EXTENSION_KEY, + FIELD_EXTENSION_WRAPPER_KEY, + FieldExtensionOptions, } from '../extensions'; import { useElementFilter, @@ -46,6 +46,7 @@ import { } from '../routes'; import { ListTasksPage } from './ListTasksPage'; import { LayoutOptions, LAYOUTS_KEY, LAYOUTS_WRAPPER_KEY } from '../layouts'; +import { LastStepFormProps } from './types'; /** * The props for the entrypoint `ScaffolderPage` component the plugin. @@ -53,6 +54,7 @@ import { LayoutOptions, LAYOUTS_KEY, LAYOUTS_WRAPPER_KEY } from '../layouts'; */ export type RouterProps = { components?: { + LastStepFormComponent?: ComponentType; TemplateCardComponent?: | ComponentType<{ template: TemplateEntityV1beta3 }> | undefined; @@ -82,7 +84,8 @@ export type RouterProps = { export const Router = (props: RouterProps) => { const { groups, components = {}, defaultPreviewTemplate } = props; - const { TemplateCardComponent, TaskPageComponent } = components; + const { LastStepFormComponent, TemplateCardComponent, TaskPageComponent } = + components; const outlet = useOutlet(); const TaskPageElement = TaskPageComponent ?? TaskPage; @@ -155,6 +158,7 @@ export const Router = (props: RouterProps) => { element={ diff --git a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx index 9eba61b53b..6d4eef328f 100644 --- a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx +++ b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx @@ -16,7 +16,7 @@ import { LinearProgress } from '@material-ui/core'; import { IChangeEvent } from '@rjsf/core'; import qs from 'qs'; -import React, { useCallback, useContext, useState } from 'react'; +import React, { ComponentType, useCallback, useContext, useState } from 'react'; import { Navigate, useNavigate } from 'react-router'; import useAsync from 'react-use/lib/useAsync'; import { scaffolderApiRef } from '../../api'; @@ -40,6 +40,7 @@ import { } from '@backstage/core-plugin-api'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { LayoutOptions } from '../../layouts'; +import { LastStepFormProps } from '../types'; const useTemplateParameterSchema = (templateRef: string) => { const scaffolderApi = useApi(scaffolderApiRef); @@ -51,9 +52,11 @@ const useTemplateParameterSchema = (templateRef: string) => { }; export const TemplatePage = ({ + LastStepFormComponent, customFieldExtensions = [], layouts = [], }: { + LastStepFormComponent?: ComponentType; customFieldExtensions?: FieldExtensionOptions[]; layouts?: LayoutOptions[]; }) => { @@ -144,6 +147,7 @@ export const TemplatePage = ({ titleTypographyProps={{ component: 'h2' }} > , 'schema'>>; + +export type LastStepFormProps = { + disableButtons: boolean; + finishButtonLabel?: string; + formData: Record; + handleBack: () => void; + handleCreate: () => void; + handleReset: () => void; + onFinish?: () => Promise; + steps: Step[]; +};