From 4497bd4e4859ce39195f27e46cc8b4253ce878c4 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 5 Oct 2022 21:55:11 +0200 Subject: [PATCH 1/5] chore: starting to wire together a TaskPage for the router Signed-off-by: blam --- plugins/scaffolder/src/next/Router/Router.tsx | 13 +++++- .../scaffolder/src/next/TaskPage/TaskPage.tsx | 33 +++++++++++++++ plugins/scaffolder/src/next/TaskPage/index.ts | 16 ++++++++ .../Stepper/Stepper.test.tsx | 7 ++-- .../TemplateWizardPage/Stepper/Stepper.tsx | 15 +++---- .../TemplateWizardPage/TemplateWizardPage.tsx | 41 ++++++++++++++----- plugins/scaffolder/src/routes.ts | 6 +++ 7 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 plugins/scaffolder/src/next/TaskPage/TaskPage.tsx create mode 100644 plugins/scaffolder/src/next/TaskPage/index.ts diff --git a/plugins/scaffolder/src/next/Router/Router.tsx b/plugins/scaffolder/src/next/Router/Router.tsx index 125a0bbbf6..c83e1a046a 100644 --- a/plugins/scaffolder/src/next/Router/Router.tsx +++ b/plugins/scaffolder/src/next/Router/Router.tsx @@ -28,8 +28,13 @@ import { import { useElementFilter } from '@backstage/core-plugin-api'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { TemplateGroupFilter } from '../TemplateListPage/TemplateGroups'; -import { nextSelectedTemplateRouteRef } from '../../routes'; +import { + nextScaffolderTaskRouteRef, + nextSelectedTemplateRouteRef, +} from '../../routes'; import { SecretsContextProvider } from '../../components/secrets/SecretsContext'; +import { TaskPage } from '../TaskPage'; +import { ErrorPage } from '@backstage/core-components'; /** * The Props for the Scaffolder Router @@ -87,7 +92,6 @@ export const Router = (props: PropsWithChildren) => { /> } /> - ) => { } /> + } /> + } + /> ); }; diff --git a/plugins/scaffolder/src/next/TaskPage/TaskPage.tsx b/plugins/scaffolder/src/next/TaskPage/TaskPage.tsx new file mode 100644 index 0000000000..ff0f4cd820 --- /dev/null +++ b/plugins/scaffolder/src/next/TaskPage/TaskPage.tsx @@ -0,0 +1,33 @@ +/* + * Copyright 2022 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 { Page, Header, Content } from '@backstage/core-components'; + +export const TaskPage = () => { + return ( + +
+ +

Hey

+
+ + ); +}; diff --git a/plugins/scaffolder/src/next/TaskPage/index.ts b/plugins/scaffolder/src/next/TaskPage/index.ts new file mode 100644 index 0000000000..b129601766 --- /dev/null +++ b/plugins/scaffolder/src/next/TaskPage/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 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. + */ +export { TaskPage } from './TaskPage'; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx index f605e9c114..12ad05ab75 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx @@ -30,7 +30,7 @@ describe('Stepper', () => { }; 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..fe055433b4 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useApiHolder } from '@backstage/core-plugin-api'; -import { JsonObject } from '@backstage/types'; +import { useApi, useApiHolder } from '@backstage/core-plugin-api'; +import { JsonObject, JsonValue } from '@backstage/types'; import { Stepper as MuiStepper, Step as MuiStep, @@ -31,6 +31,7 @@ import { createAsyncValidators } from './createAsyncValidators'; import { useTemplateSchema } from './useTemplateSchema'; import { ReviewState } from './ReviewState'; import validator from '@rjsf/validator-ajv8'; +import { scaffolderApiRef } from '../../../api'; const useStyles = makeStyles(theme => ({ backButton: { @@ -50,6 +51,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 +111,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 +159,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..f9dc97f32b 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, + nextScaffolderTaskRouteRef, + selectedTemplateRouteRef, +} from '../../routes'; +import { SecretsContext } from '../../components/secrets/SecretsContext'; +import { JsonValue } from '@backstage/types'; export interface TemplateWizardPageProps { customFieldExtensions: NextFieldExtensionOptions[]; @@ -67,17 +73,31 @@ const useTemplateParameterSchema = (templateRef: string) => { export const TemplateWizardPage = (props: TemplateWizardPageProps) => { const styles = useStyles(); const rootRef = useRouteRef(nextRouteRef); + const nextTemplateRef = useRouteRef(nextScaffolderTaskRouteRef); + 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(nextTemplateRef({ taskId })); + }; useEffect(() => { if (error) { @@ -113,6 +133,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, From bd42442fa50d26aa1b0fa47fef42463ac2045407 Mon Sep 17 00:00:00 2001 From: blam Date: Sun, 9 Oct 2022 15:20:43 +0200 Subject: [PATCH 2/5] chore: re-use the old task page for now as we want to ship something early Signed-off-by: blam --- .../src/next/TemplateWizardPage/TemplateWizardPage.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index f9dc97f32b..f545bc71b4 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -39,6 +39,7 @@ import { BackstageTheme } from '@backstage/theme'; import { nextRouteRef, nextScaffolderTaskRouteRef, + scaffolderTaskRouteRef, selectedTemplateRouteRef, } from '../../routes'; import { SecretsContext } from '../../components/secrets/SecretsContext'; @@ -73,13 +74,14 @@ const useTemplateParameterSchema = (templateRef: string) => { export const TemplateWizardPage = (props: TemplateWizardPageProps) => { const styles = useStyles(); const rootRef = useRouteRef(nextRouteRef); - const nextTemplateRef = useRouteRef(nextScaffolderTaskRouteRef); + 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, @@ -96,7 +98,7 @@ export const TemplateWizardPage = (props: TemplateWizardPageProps) => { secrets, }); - navigate(nextTemplateRef({ taskId })); + navigate(taskRoute({ taskId })); }; useEffect(() => { From 92e490d6b4165e7b5a3c5dbd608be2f74e0af5f0 Mon Sep 17 00:00:00 2001 From: blam Date: Sun, 9 Oct 2022 15:24:37 +0200 Subject: [PATCH 3/5] chore: added changeset Signed-off-by: blam --- .changeset/cuddly-ways-fail.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cuddly-ways-fail.md 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 From 698e213f8ca5d1d215909339b030f82c87e306e8 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 10 Oct 2022 14:45:00 +0200 Subject: [PATCH 4/5] chore: fixing typescript issues and getting this PR ready to ship! Signed-off-by: blam --- .../scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx | 3 +-- .../src/next/TemplateWizardPage/TemplateWizardPage.tsx | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx index fe055433b4..511b020c3c 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useApi, useApiHolder } from '@backstage/core-plugin-api'; +import { useApiHolder } from '@backstage/core-plugin-api'; import { JsonObject, JsonValue } from '@backstage/types'; import { Stepper as MuiStepper, @@ -31,7 +31,6 @@ import { createAsyncValidators } from './createAsyncValidators'; import { useTemplateSchema } from './useTemplateSchema'; import { ReviewState } from './ReviewState'; import validator from '@rjsf/validator-ajv8'; -import { scaffolderApiRef } from '../../../api'; const useStyles = makeStyles(theme => ({ backButton: { diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index f545bc71b4..b650e4a676 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -38,7 +38,6 @@ import { Stepper } from './Stepper'; import { BackstageTheme } from '@backstage/theme'; import { nextRouteRef, - nextScaffolderTaskRouteRef, scaffolderTaskRouteRef, selectedTemplateRouteRef, } from '../../routes'; From deb5da85d5647b272b797c416aa608c6174c2720 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 11 Oct 2022 11:30:09 +0100 Subject: [PATCH 5/5] chore: fixing code review comments Signed-off-by: blam --- plugins/scaffolder/src/next/Router/Router.tsx | 12 +------ .../scaffolder/src/next/TaskPage/TaskPage.tsx | 33 ------------------- plugins/scaffolder/src/next/TaskPage/index.ts | 16 --------- 3 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 plugins/scaffolder/src/next/TaskPage/TaskPage.tsx delete mode 100644 plugins/scaffolder/src/next/TaskPage/index.ts diff --git a/plugins/scaffolder/src/next/Router/Router.tsx b/plugins/scaffolder/src/next/Router/Router.tsx index c83e1a046a..ebe00fdfb8 100644 --- a/plugins/scaffolder/src/next/Router/Router.tsx +++ b/plugins/scaffolder/src/next/Router/Router.tsx @@ -28,13 +28,8 @@ import { import { useElementFilter } from '@backstage/core-plugin-api'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { TemplateGroupFilter } from '../TemplateListPage/TemplateGroups'; -import { - nextScaffolderTaskRouteRef, - nextSelectedTemplateRouteRef, -} from '../../routes'; +import { nextSelectedTemplateRouteRef } from '../../routes'; import { SecretsContextProvider } from '../../components/secrets/SecretsContext'; -import { TaskPage } from '../TaskPage'; -import { ErrorPage } from '@backstage/core-components'; /** * The Props for the Scaffolder Router @@ -100,11 +95,6 @@ export const Router = (props: PropsWithChildren) => { } /> - } /> - } - /> ); }; diff --git a/plugins/scaffolder/src/next/TaskPage/TaskPage.tsx b/plugins/scaffolder/src/next/TaskPage/TaskPage.tsx deleted file mode 100644 index ff0f4cd820..0000000000 --- a/plugins/scaffolder/src/next/TaskPage/TaskPage.tsx +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2022 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 { Page, Header, Content } from '@backstage/core-components'; - -export const TaskPage = () => { - return ( - -
- -

Hey

-
- - ); -}; diff --git a/plugins/scaffolder/src/next/TaskPage/index.ts b/plugins/scaffolder/src/next/TaskPage/index.ts deleted file mode 100644 index b129601766..0000000000 --- a/plugins/scaffolder/src/next/TaskPage/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2022 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. - */ -export { TaskPage } from './TaskPage';