Merge pull request #16942 from backstage/blam/scaffolder-simplify-routing
scaffolder/next: simplify routing in the plugin
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': minor
|
||||
---
|
||||
|
||||
scaffolder/next: removing the `routeRefs` and exporting the originals on `scaffolderPlugin.routes.x` instead
|
||||
@@ -8,12 +8,9 @@
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { FormProps as FormProps_2 } from '@backstage/plugin-scaffolder-react/alpha';
|
||||
import type { FormProps as FormProps_3 } from '@rjsf/core-v5';
|
||||
import { PathParams } from '@backstage/core-plugin-api';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { default as React_2 } from 'react';
|
||||
import { RouteRef } from '@backstage/core-plugin-api';
|
||||
import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react';
|
||||
import { SubRouteRef } from '@backstage/core-plugin-api';
|
||||
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
|
||||
// @alpha @deprecated
|
||||
@@ -22,9 +19,6 @@ export type FormProps = Pick<
|
||||
'transformErrors' | 'noHtml5Validate'
|
||||
>;
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const nextRouteRef: RouteRef<undefined>;
|
||||
|
||||
// @alpha
|
||||
export type NextRouterProps = {
|
||||
components?: {
|
||||
@@ -50,16 +44,6 @@ export const NextScaffolderPage: (
|
||||
props: PropsWithChildren<NextRouterProps>,
|
||||
) => JSX.Element;
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const nextScaffolderTaskRouteRef: SubRouteRef<
|
||||
PathParams<'/tasks/:taskId'>
|
||||
>;
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const nextSelectedTemplateRouteRef: SubRouteRef<
|
||||
PathParams<'/templates/:namespace/:templateName'>
|
||||
>;
|
||||
|
||||
// @alpha (undocumented)
|
||||
export type TemplateGroupFilter = {
|
||||
title?: React_2.ReactNode;
|
||||
|
||||
@@ -425,6 +425,9 @@ export const scaffolderPlugin: BackstagePlugin<
|
||||
PathParams<'/templates/:namespace/:templateName'>
|
||||
>;
|
||||
ongoingTask: SubRouteRef<PathParams<'/tasks/:taskId'>>;
|
||||
actions: SubRouteRef<undefined>;
|
||||
listTasks: SubRouteRef<undefined>;
|
||||
edit: SubRouteRef<undefined>;
|
||||
},
|
||||
{
|
||||
registerComponent: ExternalRouteRef<undefined, true>;
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
export { NextScaffolderPage } from './plugin';
|
||||
export {
|
||||
nextRouteRef,
|
||||
nextScaffolderTaskRouteRef,
|
||||
nextSelectedTemplateRouteRef,
|
||||
type TemplateGroupFilter,
|
||||
type NextRouterProps,
|
||||
type FormProps,
|
||||
|
||||
@@ -19,7 +19,7 @@ import React from 'react';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';
|
||||
import { act, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { nextRouteRef } from '../routes';
|
||||
import { rootRouteRef } from '../../routes';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
@@ -59,7 +59,7 @@ describe('OngoingTask', () => {
|
||||
<TestApiProvider apis={[[scaffolderApiRef, mockScaffolderApi]]}>
|
||||
<OngoingTask />
|
||||
</TestApiProvider>,
|
||||
{ mountedRoutes: { '/': nextRouteRef } },
|
||||
{ mountedRoutes: { '/': rootRouteRef } },
|
||||
);
|
||||
const { getByText, getByTestId } = rendered;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
ScaffolderTaskOutput,
|
||||
useTaskEventStream,
|
||||
} from '@backstage/plugin-scaffolder-react';
|
||||
import { nextSelectedTemplateRouteRef } from '../routes';
|
||||
import { selectedTemplateRouteRef } from '../../routes';
|
||||
import { useRouteRef } from '@backstage/core-plugin-api';
|
||||
import qs from 'qs';
|
||||
import { ContextMenu } from './ContextMenu';
|
||||
@@ -45,7 +45,7 @@ export const OngoingTask = (props: {
|
||||
}) => {
|
||||
// todo(blam): check that task Id actually exists, and that it's valid. otherwise redirect to something more useful.
|
||||
const { taskId } = useParams();
|
||||
const templateRouteRef = useRouteRef(nextSelectedTemplateRouteRef);
|
||||
const templateRouteRef = useRouteRef(selectedTemplateRouteRef);
|
||||
const navigate = useNavigate();
|
||||
const taskStream = useTaskEventStream(taskId!);
|
||||
const classes = useStyles();
|
||||
|
||||
@@ -33,12 +33,12 @@ import { TemplateGroupFilter } from '../TemplateListPage/TemplateGroups';
|
||||
import { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default';
|
||||
|
||||
import {
|
||||
nextActionsRouteRef,
|
||||
nextEditRouteRef,
|
||||
nextScaffolderListTaskRouteRef,
|
||||
nextScaffolderTaskRouteRef,
|
||||
nextSelectedTemplateRouteRef,
|
||||
} from '../routes';
|
||||
actionsRouteRef,
|
||||
editRouteRef,
|
||||
scaffolderListTaskRouteRef,
|
||||
scaffolderTaskRouteRef,
|
||||
selectedTemplateRouteRef,
|
||||
} from '../../routes';
|
||||
import { ErrorPage } from '@backstage/core-components';
|
||||
import { OngoingTask } from '../OngoingTask';
|
||||
import { ActionsPage } from '../../components/ActionsPage';
|
||||
@@ -115,7 +115,7 @@ export const Router = (props: PropsWithChildren<NextRouterProps>) => {
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={nextSelectedTemplateRouteRef.path}
|
||||
path={selectedTemplateRouteRef.path}
|
||||
element={
|
||||
<SecretsContextProvider>
|
||||
<TemplateWizardPage
|
||||
@@ -127,7 +127,7 @@ export const Router = (props: PropsWithChildren<NextRouterProps>) => {
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={nextScaffolderTaskRouteRef.path}
|
||||
path={scaffolderTaskRouteRef.path}
|
||||
element={
|
||||
<TaskPageComponent
|
||||
TemplateOutputsComponent={TemplateOutputsComponent}
|
||||
@@ -135,7 +135,7 @@ export const Router = (props: PropsWithChildren<NextRouterProps>) => {
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={nextEditRouteRef.path}
|
||||
path={editRouteRef.path}
|
||||
element={
|
||||
<SecretsContextProvider>
|
||||
<TemplateEditorPage
|
||||
@@ -146,9 +146,9 @@ export const Router = (props: PropsWithChildren<NextRouterProps>) => {
|
||||
}
|
||||
/>
|
||||
|
||||
<Route path={nextActionsRouteRef.path} element={<ActionsPage />} />
|
||||
<Route path={actionsRouteRef.path} element={<ActionsPage />} />
|
||||
<Route
|
||||
path={nextScaffolderListTaskRouteRef.path}
|
||||
path={scaffolderListTaskRouteRef.path}
|
||||
element={<ListTasksPage />}
|
||||
/>
|
||||
<Route
|
||||
|
||||
@@ -30,10 +30,10 @@ import MoreVert from '@material-ui/icons/MoreVert';
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
nextActionsRouteRef,
|
||||
nextEditRouteRef,
|
||||
nextScaffolderListTaskRouteRef,
|
||||
} from '../routes';
|
||||
actionsRouteRef,
|
||||
editRouteRef,
|
||||
scaffolderListTaskRouteRef,
|
||||
} from '../../routes';
|
||||
|
||||
const useStyles = makeStyles((theme: BackstageTheme) => ({
|
||||
button: {
|
||||
@@ -50,9 +50,9 @@ export type ScaffolderPageContextMenuProps = {
|
||||
export function ContextMenu(props: ScaffolderPageContextMenuProps) {
|
||||
const classes = useStyles();
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();
|
||||
const editLink = useRouteRef(nextEditRouteRef);
|
||||
const actionsLink = useRouteRef(nextActionsRouteRef);
|
||||
const tasksLink = useRouteRef(nextScaffolderListTaskRouteRef);
|
||||
const editLink = useRouteRef(editRouteRef);
|
||||
const actionsLink = useRouteRef(actionsRouteRef);
|
||||
const tasksLink = useRouteRef(scaffolderListTaskRouteRef);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import { TemplateGroups } from './TemplateGroups';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import { errorApiRef } from '@backstage/core-plugin-api';
|
||||
import { TemplateGroup } from '@backstage/plugin-scaffolder-react/alpha';
|
||||
import { nextRouteRef } from '../routes';
|
||||
import { rootRouteRef } from '../../routes';
|
||||
|
||||
describe('TemplateGroups', () => {
|
||||
beforeEach(() => jest.clearAllMocks());
|
||||
@@ -42,7 +42,7 @@ describe('TemplateGroups', () => {
|
||||
</TestApiProvider>,
|
||||
{
|
||||
mountedRoutes: {
|
||||
'/next': nextRouteRef,
|
||||
'/create': rootRouteRef,
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -64,7 +64,7 @@ describe('TemplateGroups', () => {
|
||||
</TestApiProvider>,
|
||||
{
|
||||
mountedRoutes: {
|
||||
'/next': nextRouteRef,
|
||||
'/create': rootRouteRef,
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -85,7 +85,7 @@ describe('TemplateGroups', () => {
|
||||
</TestApiProvider>,
|
||||
{
|
||||
mountedRoutes: {
|
||||
'/next': nextRouteRef,
|
||||
'/create': rootRouteRef,
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -106,7 +106,7 @@ describe('TemplateGroups', () => {
|
||||
</TestApiProvider>,
|
||||
{
|
||||
mountedRoutes: {
|
||||
'/next': nextRouteRef,
|
||||
'/create': rootRouteRef,
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -146,7 +146,7 @@ describe('TemplateGroups', () => {
|
||||
</TestApiProvider>,
|
||||
{
|
||||
mountedRoutes: {
|
||||
'/next': nextRouteRef,
|
||||
'/create': rootRouteRef,
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -195,7 +195,7 @@ describe('TemplateGroups', () => {
|
||||
</TestApiProvider>,
|
||||
{
|
||||
mountedRoutes: {
|
||||
'/next': nextRouteRef,
|
||||
'/create': rootRouteRef,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -31,8 +31,7 @@ import {
|
||||
useRouteRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { TemplateGroup } from '@backstage/plugin-scaffolder-react/alpha';
|
||||
import { viewTechDocRouteRef } from '../../routes';
|
||||
import { nextSelectedTemplateRouteRef } from '../routes';
|
||||
import { viewTechDocRouteRef, selectedTemplateRouteRef } from '../../routes';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
/**
|
||||
@@ -56,7 +55,7 @@ export const TemplateGroups = (props: TemplateGroupsProps) => {
|
||||
const errorApi = useApi(errorApiRef);
|
||||
const app = useApp();
|
||||
const viewTechDocsLink = useRouteRef(viewTechDocRouteRef);
|
||||
const templateRoute = useRouteRef(nextSelectedTemplateRouteRef);
|
||||
const templateRoute = useRouteRef(selectedTemplateRouteRef);
|
||||
const navigate = useNavigate();
|
||||
const onSelected = useCallback(
|
||||
(template: TemplateEntityV1beta3) => {
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
TestApiProvider,
|
||||
} from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { nextRouteRef } from '../routes';
|
||||
import { rootRouteRef } from '../../routes';
|
||||
import { TemplateListPage } from './TemplateListPage';
|
||||
|
||||
describe('TemplateListPage', () => {
|
||||
@@ -63,7 +63,7 @@ describe('TemplateListPage', () => {
|
||||
>
|
||||
<TemplateListPage />
|
||||
</TestApiProvider>,
|
||||
{ mountedRoutes: { '/': nextRouteRef } },
|
||||
{ mountedRoutes: { '/': rootRouteRef } },
|
||||
);
|
||||
|
||||
expect(getByPlaceholderText('Search')).toBeInTheDocument();
|
||||
@@ -85,7 +85,7 @@ describe('TemplateListPage', () => {
|
||||
>
|
||||
<TemplateListPage />
|
||||
</TestApiProvider>,
|
||||
{ mountedRoutes: { '/': nextRouteRef } },
|
||||
{ mountedRoutes: { '/': rootRouteRef } },
|
||||
);
|
||||
|
||||
expect(getByRole('menuitem', { name: /All/ })).toBeInTheDocument();
|
||||
@@ -108,7 +108,7 @@ describe('TemplateListPage', () => {
|
||||
>
|
||||
<TemplateListPage />
|
||||
</TestApiProvider>,
|
||||
{ mountedRoutes: { '/': nextRouteRef } },
|
||||
{ mountedRoutes: { '/': rootRouteRef } },
|
||||
);
|
||||
|
||||
expect(getByText('Categories')).toBeInTheDocument();
|
||||
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
} from '@backstage/plugin-scaffolder-react';
|
||||
import { TemplateWizardPage } from './TemplateWizardPage';
|
||||
import { rootRouteRef } from '../../routes';
|
||||
import { nextRouteRef } from '../routes';
|
||||
|
||||
jest.mock('react-router-dom', () => {
|
||||
return {
|
||||
@@ -84,8 +83,7 @@ describe('TemplateWizardPage', () => {
|
||||
</ApiProvider>,
|
||||
{
|
||||
mountedRoutes: {
|
||||
'/create': nextRouteRef,
|
||||
'/create-legacy': rootRouteRef,
|
||||
'/create': rootRouteRef,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -34,11 +34,12 @@ import {
|
||||
} from '@backstage/plugin-scaffolder-react/alpha';
|
||||
import { JsonValue } from '@backstage/types';
|
||||
import { Header, Page } from '@backstage/core-components';
|
||||
|
||||
import {
|
||||
nextRouteRef,
|
||||
nextScaffolderTaskRouteRef,
|
||||
nextSelectedTemplateRouteRef,
|
||||
} from '../routes';
|
||||
rootRouteRef,
|
||||
scaffolderTaskRouteRef,
|
||||
selectedTemplateRouteRef,
|
||||
} from '../../routes';
|
||||
|
||||
export type TemplateWizardPageProps = {
|
||||
customFieldExtensions: NextFieldExtensionOptions<any, any>[];
|
||||
@@ -47,13 +48,13 @@ export type TemplateWizardPageProps = {
|
||||
};
|
||||
|
||||
export const TemplateWizardPage = (props: TemplateWizardPageProps) => {
|
||||
const rootRef = useRouteRef(nextRouteRef);
|
||||
const taskRoute = useRouteRef(nextScaffolderTaskRouteRef);
|
||||
const rootRef = useRouteRef(rootRouteRef);
|
||||
const taskRoute = useRouteRef(scaffolderTaskRouteRef);
|
||||
const { secrets } = useTemplateSecrets();
|
||||
const scaffolderApi = useApi(scaffolderApiRef);
|
||||
const navigate = useNavigate();
|
||||
const { templateName, namespace } = useRouteRefParams(
|
||||
nextSelectedTemplateRouteRef,
|
||||
selectedTemplateRouteRef,
|
||||
);
|
||||
|
||||
const templateRef = stringifyEntityRef({
|
||||
|
||||
@@ -17,4 +17,3 @@ export * from './Router';
|
||||
export * from './TemplateListPage';
|
||||
export * from './TemplateWizardPage';
|
||||
export * from './types';
|
||||
export * from './routes';
|
||||
|
||||
@@ -1,57 +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 { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api';
|
||||
|
||||
/** @alpha */
|
||||
export const nextRouteRef = createRouteRef({
|
||||
id: 'scaffolder/next',
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const nextSelectedTemplateRouteRef = createSubRouteRef({
|
||||
id: 'scaffolder/next/selected-template',
|
||||
parent: nextRouteRef,
|
||||
path: '/templates/:namespace/:templateName',
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const nextScaffolderTaskRouteRef = createSubRouteRef({
|
||||
id: 'scaffolder/next/task',
|
||||
parent: nextRouteRef,
|
||||
path: '/tasks/:taskId',
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const nextScaffolderListTaskRouteRef = createSubRouteRef({
|
||||
id: 'scaffolder/next/list-tasks',
|
||||
parent: nextRouteRef,
|
||||
path: '/tasks',
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const nextActionsRouteRef = createSubRouteRef({
|
||||
id: 'scaffolder/next/actions',
|
||||
parent: nextRouteRef,
|
||||
path: '/actions',
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const nextEditRouteRef = createSubRouteRef({
|
||||
id: 'scaffolder/next/edit',
|
||||
parent: nextRouteRef,
|
||||
path: '/edit',
|
||||
});
|
||||
@@ -60,8 +60,10 @@ import {
|
||||
viewTechDocRouteRef,
|
||||
selectedTemplateRouteRef,
|
||||
scaffolderTaskRouteRef,
|
||||
scaffolderListTaskRouteRef,
|
||||
actionsRouteRef,
|
||||
editRouteRef,
|
||||
} from './routes';
|
||||
import { nextRouteRef } from './next';
|
||||
|
||||
/**
|
||||
* The main plugin export for the scaffolder.
|
||||
@@ -91,6 +93,9 @@ export const scaffolderPlugin = createPlugin({
|
||||
root: rootRouteRef,
|
||||
selectedTemplate: selectedTemplateRouteRef,
|
||||
ongoingTask: scaffolderTaskRouteRef,
|
||||
actions: actionsRouteRef,
|
||||
listTasks: scaffolderListTaskRouteRef,
|
||||
edit: editRouteRef,
|
||||
},
|
||||
externalRoutes: {
|
||||
registerComponent: registerComponentRouteRef,
|
||||
@@ -199,6 +204,6 @@ export const NextScaffolderPage = scaffolderPlugin.provide(
|
||||
createRoutableExtension({
|
||||
name: 'NextScaffolderPage',
|
||||
component: () => import('./next/Router').then(m => m.Router),
|
||||
mountPoint: nextRouteRef,
|
||||
mountPoint: rootRouteRef,
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user