diff --git a/.changeset/cuddly-ways-fail.md b/.changeset/cuddly-ways-fail.md new file mode 100644 index 0000000000..bb1b356036 --- /dev/null +++ b/.changeset/cuddly-ways-fail.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Make the `/next` scaffolder work end to end with the old `TaskPage` view diff --git a/plugins/scaffolder/src/next/Router/Router.tsx b/plugins/scaffolder/src/next/Router/Router.tsx index 125a0bbbf6..ebe00fdfb8 100644 --- a/plugins/scaffolder/src/next/Router/Router.tsx +++ b/plugins/scaffolder/src/next/Router/Router.tsx @@ -87,7 +87,6 @@ export const Router = (props: PropsWithChildren) => { /> } /> - { }; const { getByText } = await renderInTestApp( - , + , ); for (const step of manifest.steps) { @@ -48,7 +48,7 @@ describe('Stepper', () => { }; const { getByRole } = await renderInTestApp( - , + , ); expect(getByRole('button', { name: 'Next' })).toBeInTheDocument(); @@ -88,7 +88,7 @@ describe('Stepper', () => { }; const { getByRole } = await renderInTestApp( - , + , ); await fireEvent.change(getByRole('textbox', { name: 'name' }), { @@ -134,6 +134,7 @@ describe('Stepper', () => { , ); diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx index 97f21111d3..511b020c3c 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import { useApiHolder } from '@backstage/core-plugin-api'; -import { JsonObject } from '@backstage/types'; +import { JsonObject, JsonValue } from '@backstage/types'; import { Stepper as MuiStepper, Step as MuiStep, @@ -50,6 +50,7 @@ const useStyles = makeStyles(theme => ({ export interface StepperProps { manifest: TemplateParameterSchema; extensions: NextFieldExtensionOptions[]; + onComplete: (values: Record) => Promise; } // TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly @@ -109,10 +110,6 @@ export const Stepper = (props: StepperProps) => { setFormState(current => ({ ...current, ...formData })); }; - const handleCreate = () => { - // TODO(blam): Create the template in a modal with the ability to view the logs etc. - }; - return ( <> @@ -161,7 +158,10 @@ export const Stepper = (props: StepperProps) => { > Back - diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index f6739e6389..b650e4a676 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useEffect } from 'react'; +import React, { useContext, useEffect } from 'react'; import { Page, Header, @@ -23,7 +23,7 @@ import { MarkdownContent, } from '@backstage/core-components'; import { NextFieldExtensionOptions } from '../../extensions'; -import { Navigate } from 'react-router'; +import { Navigate, useNavigate } from 'react-router'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { errorApiRef, @@ -36,7 +36,13 @@ import useAsync from 'react-use/lib/useAsync'; import { makeStyles } from '@material-ui/core'; import { Stepper } from './Stepper'; import { BackstageTheme } from '@backstage/theme'; -import { nextRouteRef, selectedTemplateRouteRef } from '../../routes'; +import { + nextRouteRef, + scaffolderTaskRouteRef, + selectedTemplateRouteRef, +} from '../../routes'; +import { SecretsContext } from '../../components/secrets/SecretsContext'; +import { JsonValue } from '@backstage/types'; export interface TemplateWizardPageProps { customFieldExtensions: NextFieldExtensionOptions[]; @@ -67,17 +73,32 @@ const useTemplateParameterSchema = (templateRef: string) => { export const TemplateWizardPage = (props: TemplateWizardPageProps) => { const styles = useStyles(); const rootRef = useRouteRef(nextRouteRef); + const taskRoute = useRouteRef(scaffolderTaskRouteRef); + const { secrets } = useContext(SecretsContext) ?? {}; + const scaffolderApi = useApi(scaffolderApiRef); + const navigate = useNavigate(); const { templateName, namespace } = useRouteRefParams( selectedTemplateRouteRef, ); + + const templateRef = stringifyEntityRef({ + kind: 'Template', + namespace, + name: templateName, + }); + const errorApi = useApi(errorApiRef); - const { loading, manifest, error } = useTemplateParameterSchema( - stringifyEntityRef({ - kind: 'Template', - namespace, - name: templateName, - }), - ); + const { loading, manifest, error } = useTemplateParameterSchema(templateRef); + + const onComplete = async (values: Record) => { + const { taskId } = await scaffolderApi.scaffold({ + templateRef, + values, + secrets, + }); + + navigate(taskRoute({ taskId })); + }; useEffect(() => { if (error) { @@ -113,6 +134,7 @@ export const TemplateWizardPage = (props: TemplateWizardPageProps) => { )} diff --git a/plugins/scaffolder/src/routes.ts b/plugins/scaffolder/src/routes.ts index 2ef6583b08..5e2d191443 100644 --- a/plugins/scaffolder/src/routes.ts +++ b/plugins/scaffolder/src/routes.ts @@ -65,6 +65,12 @@ export const scaffolderTaskRouteRef = createSubRouteRef({ path: '/tasks/:taskId', }); +export const nextScaffolderTaskRouteRef = createSubRouteRef({ + id: 'scaffolder/next/task', + parent: nextRouteRef, + path: '/tasks/:taskId', +}); + export const scaffolderListTaskRouteRef = createSubRouteRef({ id: 'scaffolder/list-tasks', parent: rootRouteRef,