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:^"