From b0d1d809e6c096ebabeb42884d5bddc5c7cc8e95 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 15:48:18 +0100 Subject: [PATCH] scaffolder: initial support for new frontend system Signed-off-by: Patrik Oldsberg --- .changeset/grumpy-poets-study.md | 5 ++ plugins/scaffolder/api-report-alpha.md | 31 ++++++++ plugins/scaffolder/package.json | 6 +- plugins/scaffolder/src/alpha.ts | 23 ------ plugins/scaffolder/src/alpha.tsx | 103 +++++++++++++++++++++++++ yarn.lock | 2 + 6 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 .changeset/grumpy-poets-study.md delete mode 100644 plugins/scaffolder/src/alpha.ts create mode 100644 plugins/scaffolder/src/alpha.tsx diff --git a/.changeset/grumpy-poets-study.md b/.changeset/grumpy-poets-study.md new file mode 100644 index 0000000000..9925f2f87a --- /dev/null +++ b/.changeset/grumpy-poets-study.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Added basic support for the new frontend system, exported from the `/alpha` subpath. diff --git a/plugins/scaffolder/api-report-alpha.md b/plugins/scaffolder/api-report-alpha.md index 6a1e0648a4..c8824d42da 100644 --- a/plugins/scaffolder/api-report-alpha.md +++ b/plugins/scaffolder/api-report-alpha.md @@ -5,19 +5,50 @@ ```ts /// +import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ComponentType } from 'react'; import { Entity } from '@backstage/catalog-model'; +import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; import type { FormProps as FormProps_2 } from '@rjsf/core'; import { FormProps as FormProps_3 } from '@backstage/plugin-scaffolder-react'; import { JSX as JSX_2 } from 'react'; import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; +import { PathParams } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; +import { RouteRef } from '@backstage/frontend-plugin-api'; +import { SubRouteRef } from '@backstage/frontend-plugin-api'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react'; +// @alpha (undocumented) +const _default: BackstagePlugin< + { + root: RouteRef; + selectedTemplate: SubRouteRef< + PathParams<'/templates/:namespace/:templateName'> + >; + ongoingTask: SubRouteRef>; + actions: SubRouteRef; + listTasks: SubRouteRef; + edit: SubRouteRef; + }, + { + registerComponent: ExternalRouteRef; + viewTechDoc: ExternalRouteRef< + { + name: string; + kind: string; + namespace: string; + }, + true + >; + } +>; +export default _default; + // @alpha @deprecated export type FormProps = Pick< FormProps_2, diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 690af2f971..8652c380ba 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -10,13 +10,13 @@ }, "exports": { ".": "./src/index.ts", - "./alpha": "./src/alpha.ts", + "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, "typesVersions": { "*": { "alpha": [ - "src/alpha.ts" + "src/alpha.tsx" ], "package.json": [ "package.json" @@ -48,9 +48,11 @@ "dependencies": { "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", + "@backstage/core-compat-api": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/integration-react": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", diff --git a/plugins/scaffolder/src/alpha.ts b/plugins/scaffolder/src/alpha.ts deleted file mode 100644 index 92ec945de4..0000000000 --- a/plugins/scaffolder/src/alpha.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2023 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 { - type FormProps, - type TemplateListPageProps, - type TemplateWizardPageProps, -} from './next'; - -export * from './legacy'; diff --git a/plugins/scaffolder/src/alpha.tsx b/plugins/scaffolder/src/alpha.tsx new file mode 100644 index 0000000000..152745eec1 --- /dev/null +++ b/plugins/scaffolder/src/alpha.tsx @@ -0,0 +1,103 @@ +/* + * Copyright 2023 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 { + createApiExtension, + createApiFactory, + createNavItemExtension, + createPageExtension, + createPlugin, + discoveryApiRef, + fetchApiRef, + identityApiRef, +} from '@backstage/frontend-plugin-api'; +import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; +import { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; +import { scmIntegrationsApiRef } from '@backstage/integration-react'; +import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderClient } from './api'; +import { + registerComponentRouteRef, + rootRouteRef, + viewTechDocRouteRef, + selectedTemplateRouteRef, + scaffolderTaskRouteRef, + scaffolderListTaskRouteRef, + actionsRouteRef, + editRouteRef, +} from './routes'; + +export { + type FormProps, + type TemplateListPageProps, + type TemplateWizardPageProps, +} from './next'; + +export * from './legacy'; + +const scaffolderApi = createApiExtension({ + factory: createApiFactory({ + api: scaffolderApiRef, + deps: { + discoveryApi: discoveryApiRef, + scmIntegrationsApi: scmIntegrationsApiRef, + fetchApi: fetchApiRef, + identityApi: identityApiRef, + }, + factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) => + new ScaffolderClient({ + discoveryApi, + scmIntegrationsApi, + fetchApi, + identityApi, + }), + }), +}); + +const scaffolderPage = createPageExtension({ + routeRef: convertLegacyRouteRef(rootRouteRef), + defaultPath: '/create', + loader: () => + import('./components/Router').then(m => compatWrapper()), +}); + +const scaffolderNavItem = createNavItemExtension({ + routeRef: convertLegacyRouteRef(rootRouteRef), + title: 'Create...', + icon: CreateComponentIcon, +}); + +/** @alpha */ +export default createPlugin({ + id: 'scaffolder', + routes: { + root: convertLegacyRouteRef(rootRouteRef), + selectedTemplate: convertLegacyRouteRef(selectedTemplateRouteRef), + ongoingTask: convertLegacyRouteRef(scaffolderTaskRouteRef), + actions: convertLegacyRouteRef(actionsRouteRef), + listTasks: convertLegacyRouteRef(scaffolderListTaskRouteRef), + edit: convertLegacyRouteRef(editRouteRef), + }, + externalRoutes: { + registerComponent: convertLegacyRouteRef(registerComponentRouteRef), + viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), + }, + extensions: [scaffolderApi, scaffolderPage, scaffolderNavItem], +}); diff --git a/yarn.lock b/yarn.lock index ef4f1cbc43..41d7365fe7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8328,10 +8328,12 @@ __metadata: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-app-api": "workspace:^" + "@backstage/core-compat-api": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/integration-react": "workspace:^" "@backstage/plugin-catalog": "workspace:^"