Merge pull request #14054 from backstage/blam/scaffolder-next-ready
feat(plugins/scaffolder/next): Re-use the old `TaskPage` for now for end-to-end experience
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Make the `/next` scaffolder work end to end with the old `TaskPage` view
|
||||
@@ -87,7 +87,6 @@ export const Router = (props: PropsWithChildren<NextRouterProps>) => {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path={nextSelectedTemplateRouteRef.path}
|
||||
element={
|
||||
|
||||
@@ -30,7 +30,7 @@ describe('Stepper', () => {
|
||||
};
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
<Stepper manifest={manifest} extensions={[]} />,
|
||||
<Stepper manifest={manifest} extensions={[]} onComplete={jest.fn()} />,
|
||||
);
|
||||
|
||||
for (const step of manifest.steps) {
|
||||
@@ -48,7 +48,7 @@ describe('Stepper', () => {
|
||||
};
|
||||
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<Stepper manifest={manifest} extensions={[]} />,
|
||||
<Stepper manifest={manifest} extensions={[]} onComplete={jest.fn()} />,
|
||||
);
|
||||
|
||||
expect(getByRole('button', { name: 'Next' })).toBeInTheDocument();
|
||||
@@ -88,7 +88,7 @@ describe('Stepper', () => {
|
||||
};
|
||||
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<Stepper manifest={manifest} extensions={[]} />,
|
||||
<Stepper manifest={manifest} extensions={[]} onComplete={jest.fn()} />,
|
||||
);
|
||||
|
||||
await fireEvent.change(getByRole('textbox', { name: 'name' }), {
|
||||
@@ -134,6 +134,7 @@ describe('Stepper', () => {
|
||||
<Stepper
|
||||
manifest={manifest}
|
||||
extensions={[{ name: 'Mock', component: MockComponent }]}
|
||||
onComplete={jest.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -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<any, any>[];
|
||||
onComplete: (values: Record<string, JsonValue>) => Promise<void>;
|
||||
}
|
||||
|
||||
// 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 (
|
||||
<>
|
||||
<MuiStepper activeStep={activeStep} alternativeLabel variant="elevation">
|
||||
@@ -161,7 +158,10 @@ export const Stepper = (props: StepperProps) => {
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<Button variant="contained" onClick={handleCreate}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => props.onComplete(formState)}
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -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<any, any>[];
|
||||
@@ -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<string, JsonValue>) => {
|
||||
const { taskId } = await scaffolderApi.scaffold({
|
||||
templateRef,
|
||||
values,
|
||||
secrets,
|
||||
});
|
||||
|
||||
navigate(taskRoute({ taskId }));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
@@ -113,6 +134,7 @@ export const TemplateWizardPage = (props: TemplateWizardPageProps) => {
|
||||
<Stepper
|
||||
manifest={manifest}
|
||||
extensions={props.customFieldExtensions}
|
||||
onComplete={onComplete}
|
||||
/>
|
||||
</InfoCard>
|
||||
)}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user