diff --git a/.changeset/eight-steaks-chew.md b/.changeset/eight-steaks-chew.md new file mode 100644 index 0000000000..4651d3fb8c --- /dev/null +++ b/.changeset/eight-steaks-chew.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': minor +'@backstage/plugin-scaffolder': minor +--- + +Added support for `FormFieldBlueprint` to create field extensions in the Scaffolder plugin diff --git a/packages/scaffolder-internal/.eslintrc.js b/packages/scaffolder-internal/.eslintrc.js new file mode 100644 index 0000000000..e487f765b2 --- /dev/null +++ b/packages/scaffolder-internal/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/scaffolder-internal/README.md b/packages/scaffolder-internal/README.md new file mode 100644 index 0000000000..e7e6abeb57 --- /dev/null +++ b/packages/scaffolder-internal/README.md @@ -0,0 +1,3 @@ +# @internal/scaffolder + +This is an internal package used by the other scaffolder packages. It does not get published to NPM, but instead inlined into consuming packages due to the `backstage.inline` flag in `package.json`. diff --git a/packages/scaffolder-internal/catalog-info.yaml b/packages/scaffolder-internal/catalog-info.yaml new file mode 100644 index 0000000000..c2c2c013d3 --- /dev/null +++ b/packages/scaffolder-internal/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: internal-scaffolder + title: '@internal/scaffolder' +spec: + lifecycle: experimental + type: backstage-web-library + owner: maintainers diff --git a/packages/scaffolder-internal/package.json b/packages/scaffolder-internal/package.json new file mode 100644 index 0000000000..a046ddc86b --- /dev/null +++ b/packages/scaffolder-internal/package.json @@ -0,0 +1,32 @@ +{ + "name": "@internal/scaffolder", + "version": "0.0.1", + "backstage": { + "role": "web-library", + "inline": true + }, + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/scaffolder-internal" + }, + "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], + "scripts": { + "lint": "backstage-cli package lint", + "test": "backstage-cli package test" + }, + "dependencies": { + "@backstage/plugin-scaffolder-react": "workspace:^", + "zod": "^3.22.4" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + } +} diff --git a/packages/scaffolder-internal/src/index.ts b/packages/scaffolder-internal/src/index.ts new file mode 100644 index 0000000000..a5728f2ff6 --- /dev/null +++ b/packages/scaffolder-internal/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 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 * from './wiring'; diff --git a/packages/scaffolder-internal/src/wiring/InternalFormField.ts b/packages/scaffolder-internal/src/wiring/InternalFormField.ts new file mode 100644 index 0000000000..5d7bf1ee7d --- /dev/null +++ b/packages/scaffolder-internal/src/wiring/InternalFormField.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2024 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 { OpaqueType } from '@internal/opaque'; +import { z } from 'zod'; + +import { FormFieldExtensionData } from '@backstage/plugin-scaffolder-react/alpha'; + +/** @alpha */ +export interface FormField { + readonly $$type: '@backstage/scaffolder/FormField'; +} + +/** @alpha */ +export const OpaqueFormField = OpaqueType.create<{ + public: FormField; + versions: FormFieldExtensionData & { + readonly version: 'v1'; + }; +}>({ type: '@backstage/scaffolder/FormField', versions: ['v1'] }); diff --git a/packages/scaffolder-internal/src/wiring/index.ts b/packages/scaffolder-internal/src/wiring/index.ts new file mode 100644 index 0000000000..c85755bccf --- /dev/null +++ b/packages/scaffolder-internal/src/wiring/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 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 { OpaqueFormField, type FormField } from './InternalFormField'; diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index b0906070ff..5da8acead2 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -62,6 +62,7 @@ "@backstage/catalog-model": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-permission-react": "workspace:^", "@backstage/plugin-scaffolder-common": "workspace:^", diff --git a/plugins/scaffolder-react/report-alpha.api.md b/plugins/scaffolder-react/report-alpha.api.md index b9f0569714..75c6d08e32 100644 --- a/plugins/scaffolder-react/report-alpha.api.md +++ b/plugins/scaffolder-react/report-alpha.api.md @@ -7,10 +7,15 @@ import { ApiHolder } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; +import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; import { Dispatch } from 'react'; +import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; +import { FieldExtensionComponentProps } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; +import { FieldSchema } from '@backstage/plugin-scaffolder-react'; import { FieldValidation } from '@rjsf/utils'; +import { FormField } from '@internal/scaffolder'; import { FormProps } from '@backstage/plugin-scaffolder-react'; import { IconComponent } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; @@ -34,6 +39,7 @@ import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; import { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common'; import { UiSchema } from '@rjsf/utils'; import { WidgetProps } from '@rjsf/utils'; +import { z } from 'zod'; // @alpha (undocumented) export type BackstageOverrides = Overrides & { @@ -57,6 +63,12 @@ export const createAsyncValidators: ( // @alpha export const createFieldValidation: () => FieldValidation; +// @alpha +export function createFormField< + TReturnValue extends z.ZodType, + TUiOptions extends z.ZodType, +>(opts: FormFieldExtensionData): FormField; + // @alpha export const DefaultTemplateOutputs: (props: { output?: ScaffolderTaskOutput; @@ -76,6 +88,49 @@ export const Form: ( props: PropsWithChildren, ) => React_2.JSX.Element; +// @alpha +export const FormFieldBlueprint: ExtensionBlueprint<{ + kind: 'scaffolder-form-field'; + name: undefined; + params: { + field: () => Promise; + }; + output: ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { + formFieldLoader: ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >; + }; +}>; + +// @alpha (undocumented) +export type FormFieldExtensionData< + TReturnValue extends z.ZodType = z.ZodType, + TUiOptions extends z.ZodType = z.ZodType, +> = { + name: string; + component: ( + props: FieldExtensionComponentProps< + z.output, + z.output + >, + ) => JSX.Element | null; + validation?: CustomFieldValidator< + z.output, + z.output + >; + schema?: FieldSchema, z.output>; +}; + // @alpha (undocumented) export type FormValidation = { [name: string]: FieldValidation | FormValidation; @@ -320,6 +375,7 @@ export type WorkflowProps = { // Warnings were encountered during analysis: // +// src/next/blueprints/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "FormFieldExtensionData". // src/next/components/ScaffolderField/ScaffolderField.d.ts:7:5 - (ae-undocumented) Missing documentation for "rawDescription". // src/next/components/ScaffolderField/ScaffolderField.d.ts:8:5 - (ae-undocumented) Missing documentation for "errors". // src/next/components/ScaffolderField/ScaffolderField.d.ts:9:5 - (ae-undocumented) Missing documentation for "rawErrors". diff --git a/plugins/scaffolder-react/report.api.md b/plugins/scaffolder-react/report.api.md index 0fcb3fbf04..cf5f08dae8 100644 --- a/plugins/scaffolder-react/report.api.md +++ b/plugins/scaffolder-react/report.api.md @@ -6,7 +6,7 @@ /// import { ApiHolder } from '@backstage/core-plugin-api'; -import { ApiRef } from '@backstage/core-plugin-api'; +import { ApiRef } from '@backstage/frontend-plugin-api'; import { ComponentType } from 'react'; import { CustomValidator } from '@rjsf/utils'; import { ElementType } from 'react'; @@ -44,6 +44,7 @@ import { TemplatesType } from '@rjsf/utils'; import { UIOptionsType } from '@rjsf/utils'; import { UiSchema } from '@rjsf/utils'; import { ValidatorType } from '@rjsf/utils'; +import { z } from 'zod'; // @public export type Action = { @@ -125,6 +126,18 @@ export interface FieldExtensionUiSchema 'ui:options'?: TUiOptions & UIOptionsType; } +// @public +export interface FieldSchema { + // (undocumented) + readonly schema: CustomFieldExtensionSchema; + // (undocumented) + readonly TProps: FieldExtensionComponentProps; + // @deprecated (undocumented) + readonly type: FieldExtensionComponentProps; + // @deprecated (undocumented) + readonly uiOptionsType: TUiOptions; +} + // @public export type FormProps = Pick< FormProps_2, @@ -168,6 +181,15 @@ export type LogEvent = { taskId: string; }; +// @public (undocumented) +export function makeFieldSchema< + TReturnType extends z.ZodType, + TUiOptions extends z.ZodType, +>(options: { + output: (zImpl: typeof z) => TReturnType; + uiOptions?: (zImpl: typeof z) => TUiOptions; +}): FieldSchema, z.output>; + // @public export type ReviewStepProps = { disableButtons: boolean; @@ -566,6 +588,11 @@ export const useTemplateSecrets: () => ScaffolderUseTemplateSecrets; // src/layouts/createScaffolderLayout.d.ts:17:5 - (ae-undocumented) Missing documentation for "component". // src/secrets/SecretsContext.d.ts:14:5 - (ae-undocumented) Missing documentation for "setSecrets". // src/secrets/SecretsContext.d.ts:15:5 - (ae-undocumented) Missing documentation for "secrets". +// src/utils.d.ts:4:1 - (ae-undocumented) Missing documentation for "makeFieldSchema". +// src/utils.d.ts:15:5 - (ae-undocumented) Missing documentation for "type". +// src/utils.d.ts:17:5 - (ae-undocumented) Missing documentation for "uiOptionsType". +// src/utils.d.ts:18:5 - (ae-undocumented) Missing documentation for "schema". +// src/utils.d.ts:19:5 - (ae-undocumented) Missing documentation for "TProps". // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/scaffolder-react/src/api/ref.ts b/plugins/scaffolder-react/src/api/ref.ts index 3dee426b09..4cf50d377b 100644 --- a/plugins/scaffolder-react/src/api/ref.ts +++ b/plugins/scaffolder-react/src/api/ref.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createApiRef } from '@backstage/core-plugin-api'; +import { createApiRef } from '@backstage/frontend-plugin-api'; import { ScaffolderApi } from './types'; /** @public */ diff --git a/plugins/scaffolder-react/src/index.ts b/plugins/scaffolder-react/src/index.ts index 70560cc694..e73df50fce 100644 --- a/plugins/scaffolder-react/src/index.ts +++ b/plugins/scaffolder-react/src/index.ts @@ -21,3 +21,4 @@ export * from './secrets'; export * from './api'; export * from './hooks'; export * from './layouts'; +export * from './utils'; diff --git a/plugins/scaffolder-react/src/next/blueprints/FormFieldBlueprint.tsx b/plugins/scaffolder-react/src/next/blueprints/FormFieldBlueprint.tsx new file mode 100644 index 0000000000..e99adcba82 --- /dev/null +++ b/plugins/scaffolder-react/src/next/blueprints/FormFieldBlueprint.tsx @@ -0,0 +1,56 @@ +/* + * Copyright 2024 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 { + createExtensionBlueprint, + createExtensionDataRef, +} from '@backstage/frontend-plugin-api'; +import { z } from 'zod'; + +import { OpaqueFormField, FormField } from '@internal/scaffolder'; +import { FormFieldExtensionData } from './types'; + +const formFieldExtensionDataRef = createExtensionDataRef< + () => Promise +>().with({ + id: 'scaffolder.form-field-loader', +}); + +/** + * @alpha + * Creates extensions that are Field Extensions for the Scaffolder + * */ +export const FormFieldBlueprint = createExtensionBlueprint({ + kind: 'scaffolder-form-field', + attachTo: { id: 'api:scaffolder/form-fields', input: 'formFields' }, + dataRefs: { + formFieldLoader: formFieldExtensionDataRef, + }, + output: [formFieldExtensionDataRef], + *factory(params: { field: () => Promise }) { + yield formFieldExtensionDataRef(params.field); + }, +}); + +/** + * @alpha + * Used to create a form field binding with typechecking for compliance + */ +export function createFormField< + TReturnValue extends z.ZodType, + TUiOptions extends z.ZodType, +>(opts: FormFieldExtensionData): FormField { + return OpaqueFormField.createInstance('v1', opts); +} diff --git a/plugins/scaffolder-react/src/next/blueprints/index.ts b/plugins/scaffolder-react/src/next/blueprints/index.ts new file mode 100644 index 0000000000..165c583ac8 --- /dev/null +++ b/plugins/scaffolder-react/src/next/blueprints/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2024 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 * from './FormFieldBlueprint'; +export * from './types'; diff --git a/plugins/scaffolder-react/src/next/blueprints/types.ts b/plugins/scaffolder-react/src/next/blueprints/types.ts new file mode 100644 index 0000000000..eccf7e4606 --- /dev/null +++ b/plugins/scaffolder-react/src/next/blueprints/types.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2024 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 { z } from 'zod'; +import { + CustomFieldValidator, + FieldExtensionComponentProps, + FieldSchema, +} from '@backstage/plugin-scaffolder-react'; + +/** @alpha */ +export type FormFieldExtensionData< + TReturnValue extends z.ZodType = z.ZodType, + TUiOptions extends z.ZodType = z.ZodType, +> = { + name: string; + component: ( + props: FieldExtensionComponentProps< + z.output, + z.output + >, + ) => JSX.Element | null; + validation?: CustomFieldValidator< + z.output, + z.output + >; + schema?: FieldSchema, z.output>; +}; diff --git a/plugins/scaffolder-react/src/next/index.ts b/plugins/scaffolder-react/src/next/index.ts index 2c9c1706f0..07f4565166 100644 --- a/plugins/scaffolder-react/src/next/index.ts +++ b/plugins/scaffolder-react/src/next/index.ts @@ -17,3 +17,4 @@ export * from './components'; export * from './lib'; export * from './hooks'; export * from './overridableComponents'; +export * from './blueprints'; diff --git a/plugins/scaffolder-react/src/utils.ts b/plugins/scaffolder-react/src/utils.ts new file mode 100644 index 0000000000..63a62fe3fc --- /dev/null +++ b/plugins/scaffolder-react/src/utils.ts @@ -0,0 +1,60 @@ +/* + * Copyright 2024 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 zodToJsonSchema from 'zod-to-json-schema'; +import { JSONSchema7 } from 'json-schema'; +import { z } from 'zod'; +import { + CustomFieldExtensionSchema, + FieldExtensionComponentProps, +} from './extensions'; + +/** @public */ +export function makeFieldSchema< + TReturnType extends z.ZodType, + TUiOptions extends z.ZodType, +>(options: { + output: (zImpl: typeof z) => TReturnType; + uiOptions?: (zImpl: typeof z) => TUiOptions; +}): FieldSchema, z.output> { + const { output, uiOptions } = options; + return { + TProps: undefined as any, + schema: { + returnValue: zodToJsonSchema(output(z)) as JSONSchema7, + uiOptions: uiOptions && (zodToJsonSchema(uiOptions(z)) as JSONSchema7), + }, + + // These will be removed - just here for backwards compat whilst we're moving across + type: undefined as any, + uiOptionsType: undefined as any, + }; +} + +/** + * @public + * FieldSchema encapsulates a JSONSchema7 along with the + * matching FieldExtensionComponentProps type for a field extension. + */ +export interface FieldSchema { + /** @deprecated use TProps instead */ + readonly type: FieldExtensionComponentProps; + /** @deprecated will be removed */ + readonly uiOptionsType: TUiOptions; + + readonly schema: CustomFieldExtensionSchema; + readonly TProps: FieldExtensionComponentProps; +} diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index a777f742c4..86fa96ede2 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -30,7 +30,7 @@ "sideEffects": false, "exports": { ".": "./src/index.ts", - "./alpha": "./src/alpha.tsx", + "./alpha": "./src/alpha/index.ts", "./package.json": "./package.json" }, "main": "src/index.ts", @@ -38,7 +38,7 @@ "typesVersions": { "*": { "alpha": [ - "src/alpha.tsx" + "src/alpha/index.ts" ], "package.json": [ "package.json" diff --git a/plugins/scaffolder/report-alpha.api.md b/plugins/scaffolder/report-alpha.api.md index b71bbb1395..051bfee955 100644 --- a/plugins/scaffolder/report-alpha.api.md +++ b/plugins/scaffolder/report-alpha.api.md @@ -3,16 +3,21 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// + import { AnyApiFactory } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { ExtensionInput } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; +import { FormField } from '@internal/scaffolder'; import type { FormProps as FormProps_2 } from '@rjsf/core'; import { FormProps as FormProps_3 } from '@backstage/plugin-scaffolder-react'; import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; +import { JSX as JSX_2 } from 'react'; import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; import { PathParams } from '@backstage/core-plugin-api'; import { default as React_2 } from 'react'; @@ -69,11 +74,7 @@ const _default: FrontendPlugin< path?: string | undefined; }; output: - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > + | ConfigurableExtensionDataRef | ConfigurableExtensionDataRef | ConfigurableExtensionDataRef< RouteRef, @@ -110,6 +111,48 @@ const _default: FrontendPlugin< routeRef: RouteRef; }; }>; + 'scaffolder-form-field:scaffolder/repo-url-picker': ExtensionDefinition<{ + kind: 'scaffolder-form-field'; + name: 'repo-url-picker'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >; + inputs: {}; + params: { + field: () => Promise; + }; + }>; + 'api:scaffolder/form-fields': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: { + formFields: ExtensionInput< + ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >, + { + singleton: false; + optional: false; + } + >; + }; + kind: 'api'; + name: 'form-fields'; + params: { + factory: AnyApiFactory; + }; + }>; } >; export default _default; @@ -315,12 +358,12 @@ export type TemplateWizardPageProps = { // Warnings were encountered during analysis: // -// src/alpha.d.ts:5:15 - (ae-undocumented) Missing documentation for "_default". -// src/next/TemplateEditorPage/CustomFieldExplorer.d.ts:4:1 - (ae-undocumented) Missing documentation for "ScaffolderCustomFieldExplorerClassKey". -// src/next/TemplateEditorPage/TemplateEditor.d.ts:6:1 - (ae-undocumented) Missing documentation for "ScaffolderTemplateEditorClassKey". -// src/next/TemplateEditorPage/TemplateFormPreviewer.d.ts:4:1 - (ae-undocumented) Missing documentation for "ScaffolderTemplateFormPreviewerClassKey". -// src/next/TemplateListPage/TemplateListPage.d.ts:7:1 - (ae-undocumented) Missing documentation for "TemplateListPageProps". -// src/next/TemplateWizardPage/TemplateWizardPage.d.ts:6:1 - (ae-undocumented) Missing documentation for "TemplateWizardPageProps". +// src/alpha/components/TemplateEditorPage/CustomFieldExplorer.d.ts:4:1 - (ae-undocumented) Missing documentation for "ScaffolderCustomFieldExplorerClassKey". +// src/alpha/components/TemplateEditorPage/TemplateEditor.d.ts:6:1 - (ae-undocumented) Missing documentation for "ScaffolderTemplateEditorClassKey". +// src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.d.ts:4:1 - (ae-undocumented) Missing documentation for "ScaffolderTemplateFormPreviewerClassKey". +// src/alpha/components/TemplateListPage/TemplateListPage.d.ts:7:1 - (ae-undocumented) Missing documentation for "TemplateListPageProps". +// src/alpha/components/TemplateWizardPage/TemplateWizardPage.d.ts:6:1 - (ae-undocumented) Missing documentation for "TemplateWizardPageProps". +// src/alpha/plugin.d.ts:3:15 - (ae-undocumented) Missing documentation for "_default". // src/translation.d.ts:2:22 - (ae-undocumented) Missing documentation for "scaffolderTranslationRef". // (No @packageDocumentation comment for this package) diff --git a/plugins/scaffolder/report.api.md b/plugins/scaffolder/report.api.md index 8c60eda7f5..1adaa8f167 100644 --- a/plugins/scaffolder/report.api.md +++ b/plugins/scaffolder/report.api.md @@ -19,6 +19,7 @@ import { FetchApi } from '@backstage/core-plugin-api'; import { FieldExtensionComponent as FieldExtensionComponent_2 } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionComponentProps as FieldExtensionComponentProps_2 } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionOptions as FieldExtensionOptions_2 } from '@backstage/plugin-scaffolder-react'; +import { FieldSchema as FieldSchema_2 } from '@backstage/plugin-scaffolder-react'; import { FieldValidation } from '@rjsf/utils'; import { FormProps } from '@backstage/plugin-scaffolder-react'; import { IdentityApi } from '@backstage/core-plugin-api'; @@ -174,15 +175,8 @@ export type FieldExtensionComponentProps< // @public @deprecated (undocumented) export type FieldExtensionOptions = FieldExtensionOptions_2; -// @public -export interface FieldSchema { - // (undocumented) - readonly schema: CustomFieldExtensionSchema_2; - // (undocumented) - readonly type: FieldExtensionComponentProps_2; - // (undocumented) - readonly uiOptionsType: TUiOptions; -} +// @public @deprecated (undocumented) +export interface FieldSchema extends FieldSchema_2 {} // @public @deprecated (undocumented) export type LayoutOptions = LayoutOptions_2; @@ -196,7 +190,7 @@ export type ListActionsResponse = ListActionsResponse_2; // @public @deprecated (undocumented) export type LogEvent = LogEvent_2; -// @public +// @public @deprecated (undocumented) export function makeFieldSchemaFromZod< TReturnSchema extends z.ZodType, TUiOptionsSchema extends z.ZodType = z.ZodType, @@ -443,7 +437,7 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent_2< >; // @public (undocumented) -export const RepoUrlPickerFieldSchema: FieldSchema< +export const RepoUrlPickerFieldSchema: FieldSchema_2< string, { allowedHosts?: string[] | undefined; @@ -469,7 +463,7 @@ export const RepoUrlPickerFieldSchema: FieldSchema< } >; -// @public +// @public @deprecated export type RepoUrlPickerUiOptions = typeof RepoUrlPickerFieldSchema.uiOptionsType; @@ -689,9 +683,8 @@ export const useTemplateSecrets: () => ScaffolderUseTemplateSecrets_2; // src/components/fields/OwnedEntityPicker/schema.d.ts:4:22 - (ae-undocumented) Missing documentation for "OwnedEntityPickerFieldSchema". // src/components/fields/OwnerPicker/schema.d.ts:4:22 - (ae-undocumented) Missing documentation for "OwnerPickerFieldSchema". // src/components/fields/RepoUrlPicker/schema.d.ts:4:22 - (ae-undocumented) Missing documentation for "RepoUrlPickerFieldSchema". -// src/components/fields/utils.d.ts:9:5 - (ae-undocumented) Missing documentation for "schema". -// src/components/fields/utils.d.ts:10:5 - (ae-undocumented) Missing documentation for "type". -// src/components/fields/utils.d.ts:11:5 - (ae-undocumented) Missing documentation for "uiOptionsType". +// src/components/fields/utils.d.ts:7:1 - (ae-undocumented) Missing documentation for "FieldSchema". +// src/components/fields/utils.d.ts:15:1 - (ae-undocumented) Missing documentation for "makeFieldSchemaFromZod". // src/deprecated.d.ts:7:22 - (ae-undocumented) Missing documentation for "rootRouteRef". // src/deprecated.d.ts:12:22 - (ae-undocumented) Missing documentation for "createScaffolderFieldExtension". // src/deprecated.d.ts:17:22 - (ae-undocumented) Missing documentation for "ScaffolderFieldExtensions". diff --git a/plugins/scaffolder/src/alpha.tsx b/plugins/scaffolder/src/alpha.tsx deleted file mode 100644 index d7def54d25..0000000000 --- a/plugins/scaffolder/src/alpha.tsx +++ /dev/null @@ -1,113 +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. - */ - -import React from 'react'; -import { - createApiFactory, - createFrontendPlugin, - discoveryApiRef, - fetchApiRef, - identityApiRef, - ApiBlueprint, - PageBlueprint, - NavItemBlueprint, -} from '@backstage/frontend-plugin-api'; -import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; -import { - compatWrapper, - convertLegacyRouteRef, - convertLegacyRouteRefs, -} 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, - type ScaffolderCustomFieldExplorerClassKey, - type ScaffolderTemplateEditorClassKey, - type ScaffolderTemplateFormPreviewerClassKey, -} from './next'; - -export { scaffolderTranslationRef } from './translation'; - -const scaffolderApi = ApiBlueprint.make({ - params: { - 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 = PageBlueprint.make({ - params: { - routeRef: convertLegacyRouteRef(rootRouteRef), - defaultPath: '/create', - loader: () => - import('./components/Router').then(m => compatWrapper()), - }, -}); - -const scaffolderNavItem = NavItemBlueprint.make({ - params: { - routeRef: convertLegacyRouteRef(rootRouteRef), - title: 'Create...', - icon: CreateComponentIcon, - }, -}); - -/** @alpha */ -export default createFrontendPlugin({ - id: 'scaffolder', - routes: convertLegacyRouteRefs({ - root: rootRouteRef, - selectedTemplate: selectedTemplateRouteRef, - ongoingTask: scaffolderTaskRouteRef, - actions: actionsRouteRef, - listTasks: scaffolderListTaskRouteRef, - edit: editRouteRef, - }), - externalRoutes: convertLegacyRouteRefs({ - registerComponent: registerComponentRouteRef, - viewTechDoc: viewTechDocRouteRef, - }), - extensions: [scaffolderApi, scaffolderPage, scaffolderNavItem], -}); diff --git a/plugins/scaffolder/src/alpha/api.tsx b/plugins/scaffolder/src/alpha/api.tsx new file mode 100644 index 0000000000..06364cd6e9 --- /dev/null +++ b/plugins/scaffolder/src/alpha/api.tsx @@ -0,0 +1,46 @@ +/* + * Copyright 2024 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 { + ApiBlueprint, + createApiFactory, + discoveryApiRef, + fetchApiRef, + identityApiRef, +} from '@backstage/frontend-plugin-api'; +import { scmIntegrationsApiRef } from '@backstage/integration-react'; +import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderClient } from '../api'; + +export const scaffolderApi = ApiBlueprint.make({ + params: { + factory: createApiFactory({ + api: scaffolderApiRef, + deps: { + discoveryApi: discoveryApiRef, + scmIntegrationsApi: scmIntegrationsApiRef, + fetchApi: fetchApiRef, + identityApi: identityApiRef, + }, + factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) => + new ScaffolderClient({ + discoveryApi, + scmIntegrationsApi, + fetchApi, + identityApi, + }), + }), + }, +}); diff --git a/plugins/scaffolder/src/alpha/api/FormFieldsApi.ts b/plugins/scaffolder/src/alpha/api/FormFieldsApi.ts new file mode 100644 index 0000000000..35141463d5 --- /dev/null +++ b/plugins/scaffolder/src/alpha/api/FormFieldsApi.ts @@ -0,0 +1,63 @@ +/* + * Copyright 2024 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 { + ApiBlueprint, + createApiFactory, + createExtensionInput, +} from '@backstage/frontend-plugin-api'; +import { formFieldsApiRef } from './ref'; +import { ScaffolderFormFieldsApi } from './types'; +import { FormFieldBlueprint } from '@backstage/plugin-scaffolder-react/alpha'; +import { FormField, OpaqueFormField } from '@internal/scaffolder'; + +class DefaultScaffolderFormFieldsApi implements ScaffolderFormFieldsApi { + constructor( + private readonly formFieldLoaders: Array<() => Promise> = [], + ) {} + + async getFormFields() { + const formFields = await Promise.all( + this.formFieldLoaders.map(loader => loader()), + ); + + const internalFormFields = formFields.map(OpaqueFormField.toInternal); + + return internalFormFields; + } +} + +export const formFieldsApi = ApiBlueprint.makeWithOverrides({ + name: 'form-fields', + inputs: { + formFields: createExtensionInput([ + FormFieldBlueprint.dataRefs.formFieldLoader, + ]), + }, + factory(originalFactory, { inputs }) { + const formFieldLoaders = inputs.formFields.map(e => + e.get(FormFieldBlueprint.dataRefs.formFieldLoader), + ); + + return originalFactory({ + factory: createApiFactory({ + api: formFieldsApiRef, + deps: {}, + factory: () => new DefaultScaffolderFormFieldsApi(formFieldLoaders), + }), + }); + }, +}); diff --git a/plugins/scaffolder/src/alpha/api/index.ts b/plugins/scaffolder/src/alpha/api/index.ts new file mode 100644 index 0000000000..bbc30ef50b --- /dev/null +++ b/plugins/scaffolder/src/alpha/api/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2024 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 { formFieldsApiRef } from './ref'; +export type { ScaffolderFormFieldsApi } from './types'; diff --git a/plugins/scaffolder/src/alpha/api/ref.ts b/plugins/scaffolder/src/alpha/api/ref.ts new file mode 100644 index 0000000000..52bc44e674 --- /dev/null +++ b/plugins/scaffolder/src/alpha/api/ref.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2024 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 { createApiRef } from '@backstage/frontend-plugin-api'; +import { ScaffolderFormFieldsApi } from './types'; + +export const formFieldsApiRef = createApiRef({ + id: 'plugin.scaffolder.form-fields', +}); diff --git a/plugins/scaffolder/src/alpha/api/types.ts b/plugins/scaffolder/src/alpha/api/types.ts new file mode 100644 index 0000000000..81f08b18e2 --- /dev/null +++ b/plugins/scaffolder/src/alpha/api/types.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2024 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 { FormFieldExtensionData } from '@backstage/plugin-scaffolder-react/alpha'; + +export interface ScaffolderFormFieldsApi { + getFormFields(): Promise; +} diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldExplorer.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldExplorer.tsx similarity index 99% rename from plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldExplorer.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldExplorer.tsx index 4516537f32..daa014078d 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldExplorer.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldExplorer.tsx @@ -34,7 +34,7 @@ import { TemplateEditorForm } from './TemplateEditorForm'; import validator from '@rjsf/validator-ajv8'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; /** @public */ export type ScaffolderCustomFieldExplorerClassKey = diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldPlaygroud.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldPlaygroud.tsx similarity index 99% rename from plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldPlaygroud.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldPlaygroud.tsx index 6964fe3364..3b6fe53d8e 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldPlaygroud.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldPlaygroud.tsx @@ -37,7 +37,7 @@ import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { Form } from '@backstage/plugin-scaffolder-react/alpha'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; import { TemplateEditorForm } from './TemplateEditorForm'; const useStyles = makeStyles( diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldsPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldsPage.tsx similarity index 93% rename from plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldsPage.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldsPage.tsx index f168306d86..2d13847339 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldsPage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldsPage.tsx @@ -22,8 +22,8 @@ import { useRouteRef } from '@backstage/core-plugin-api'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; -import { editRouteRef } from '../../routes'; -import { scaffolderTranslationRef } from '../../translation'; +import { editRouteRef } from '../../../routes'; +import { scaffolderTranslationRef } from '../../../translation'; import { CustomFieldExplorer } from './CustomFieldExplorer'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DirectoryEditorContext.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DirectoryEditorContext.tsx similarity index 99% rename from plugins/scaffolder/src/next/TemplateEditorPage/DirectoryEditorContext.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DirectoryEditorContext.tsx index 70c7d43e0b..ebc5ab10ba 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DirectoryEditorContext.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DirectoryEditorContext.tsx @@ -20,7 +20,7 @@ import React, { createContext, ReactNode, useContext, useEffect } from 'react'; import { TemplateDirectoryAccess, TemplateFileAccess, -} from '../../lib/filesystem'; +} from '../../../lib/filesystem'; const MAX_SIZE = 1024 * 1024; const MAX_SIZE_MESSAGE = 'This file is too large to be displayed'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunContext.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunContext.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunContext.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunContext.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunContext.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunContext.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunContext.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunContext.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.tsx index 12521e3f3f..070a7aaec8 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.tsx @@ -27,7 +27,7 @@ import { useDryRun } from '../DryRunContext'; import { DryRunResultsList } from './DryRunResultsList'; import { DryRunResultsView } from './DryRunResultsView'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../../translation'; +import { scaffolderTranslationRef } from '../../../../translation'; const useStyles = makeStyles(theme => ({ header: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx index 9f44933466..8305577990 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx @@ -27,9 +27,9 @@ import DeleteIcon from '@material-ui/icons/Delete'; import DownloadIcon from '@material-ui/icons/GetApp'; import React from 'react'; import { useDryRun } from '../DryRunContext'; -import { downloadBlob } from '../../../lib/download'; +import { downloadBlob } from '../../../../lib/download'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../../translation'; +import { scaffolderTranslationRef } from '../../../../translation'; const useStyles = makeStyles(theme => ({ root: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx index 7de248dd56..422cd6faa9 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx @@ -26,11 +26,11 @@ import CodeMirror from '@uiw/react-codemirror'; import React, { useEffect, useMemo, useState } from 'react'; import { useDryRun } from '../DryRunContext'; import { DryRunResultsSplitView } from './DryRunResultsSplitView'; -import { FileBrowser } from '../../../components/FileBrowser'; +import { FileBrowser } from '../../../../components/FileBrowser'; import { TaskPageLinks } from './TaskPageLinks'; import { TaskStatusStepper } from './TaskStatusStepper'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../../translation'; +import { scaffolderTranslationRef } from '../../../../translation'; const useStyles = makeStyles({ root: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/IconLink.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/IconLink.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx similarity index 98% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx index 7696051950..ec7d734ca4 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx @@ -32,7 +32,7 @@ import useInterval from 'react-use/esm/useInterval'; import humanizeDuration from 'humanize-duration'; import classNames from 'classnames'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../../translation'; +import { scaffolderTranslationRef } from '../../../../translation'; const useStyles = makeStyles((theme: Theme) => createStyles({ diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/index.ts b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/index.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/index.ts rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/index.ts diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditor.tsx similarity index 98% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditor.tsx index 573415c36d..48501e6c6f 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditor.tsx @@ -21,7 +21,7 @@ import type { LayoutOptions, } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; -import { TemplateDirectoryAccess } from '../../lib/filesystem'; +import { TemplateDirectoryAccess } from '../../../lib/filesystem'; import { DirectoryEditorProvider } from './DirectoryEditorContext'; import { TemplateEditorToolbar } from './TemplateEditorToolbar'; import { TemplateEditorBrowser } from './TemplateEditorBrowser'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.test.tsx similarity index 95% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.test.tsx index cec311a5cd..958548a131 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.test.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.test.tsx @@ -17,7 +17,7 @@ import { renderInTestApp } from '@backstage/test-utils'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { MockFileSystemAccess } from '../../lib/filesystem/MockFileSystemAccess'; +import { MockFileSystemAccess } from '../../../lib/filesystem/MockFileSystemAccess'; import { DirectoryEditorProvider } from './DirectoryEditorContext'; import { TemplateEditorBrowser } from './TemplateEditorBrowser'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.tsx similarity index 96% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.tsx index d725c93e65..b478502f6e 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.tsx @@ -23,9 +23,9 @@ import RefreshIcon from '@material-ui/icons/Refresh'; import SaveIcon from '@material-ui/icons/Save'; import React from 'react'; import { useDirectoryEditor } from './DirectoryEditorContext'; -import { FileBrowser } from '../../components/FileBrowser'; +import { FileBrowser } from '../../../components/FileBrowser'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; const useStyles = makeStyles( theme => ({ diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorForm.tsx similarity index 99% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorForm.tsx index 53bda6f286..56ebaabb83 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorForm.tsx @@ -34,7 +34,8 @@ import { } from '@backstage/plugin-scaffolder-react/alpha'; import { useDryRun } from './DryRunContext'; import { useDirectoryEditor } from './DirectoryEditorContext'; -import { scaffolderTranslationRef } from '../../translation'; + +import { scaffolderTranslationRef } from '../../../translation'; const useStyles = makeStyles({ containerWrapper: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorIntro.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorIntro.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorIntro.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorIntro.tsx index 465f780a2f..c65ef569a6 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorIntro.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorIntro.tsx @@ -22,9 +22,9 @@ import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined'; import { makeStyles } from '@material-ui/core/styles'; -import { WebFileSystemAccess } from '../../lib/filesystem'; +import { WebFileSystemAccess } from '../../../lib/filesystem'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; const useStyles = makeStyles(theme => ({ introText: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorPage.tsx similarity index 90% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorPage.tsx index 0dddeba370..8d71db2551 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorPage.tsx @@ -15,7 +15,9 @@ */ import React from 'react'; import { Content, Header, Page } from '@backstage/core-components'; -import { WebFileSystemAccess } from '../../lib/filesystem'; + +import { WebFileSystemAccess } from '../../../lib/filesystem'; + import { TemplateEditorIntro } from './TemplateEditorIntro'; import { ScaffolderPageContextMenu } from '@backstage/plugin-scaffolder-react/alpha'; import { useNavigate } from 'react-router-dom'; @@ -27,11 +29,11 @@ import { rootRouteRef, scaffolderListTaskRouteRef, templateFormRouteRef, -} from '../../routes'; +} from '../../../routes'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; -import { WebFileSystemStore } from '../../lib/filesystem/WebFileSystemAccess'; -import { createExampleTemplate } from '../../lib/filesystem/createExampleTemplate'; +import { scaffolderTranslationRef } from '../../../translation'; +import { WebFileSystemStore } from '../../../lib/filesystem/WebFileSystemAccess'; +import { createExampleTemplate } from '../../../lib/filesystem/createExampleTemplate'; export function TemplateEditorPage() { const navigate = useNavigate(); diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorTextArea.tsx similarity index 98% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorTextArea.tsx index 350543a866..34788f6cb1 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorTextArea.tsx @@ -30,7 +30,7 @@ import CodeMirror from '@uiw/react-codemirror'; import React, { useMemo } from 'react'; import { useDirectoryEditor } from './DirectoryEditorContext'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; const useStyles = makeStyles(theme => ({ container: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorToolbar.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx similarity index 98% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorToolbar.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx index 1d89616964..a33915ae01 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorToolbar.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx @@ -34,7 +34,7 @@ import DescriptionIcon from '@material-ui/icons/Description'; import { Link } from '@backstage/core-components'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; -import { ActionPageContent } from '../../components/ActionsPage/ActionsPage'; +import { ActionPageContent } from '../../../components/ActionsPage/ActionsPage'; import { CustomFieldPlaygroud } from './CustomFieldPlaygroud'; const useStyles = makeStyles( diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx similarity index 95% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPage.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx index c79688c8b7..b1f98878ad 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx @@ -28,8 +28,8 @@ import { FieldExtensionOptions, } from '@backstage/plugin-scaffolder-react'; -import { editRouteRef } from '../../routes'; -import { scaffolderTranslationRef } from '../../translation'; +import { editRouteRef } from '../../../routes'; +import { scaffolderTranslationRef } from '../../../translation'; import { TemplateFormPreviewer } from './TemplateFormPreviewer'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.tsx similarity index 99% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.tsx index e0c40a98be..ca4ae8d8d6 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.tsx @@ -42,7 +42,7 @@ import { TemplateEditorToolbar } from './TemplateEditorToolbar'; import { TemplateEditorForm } from './TemplateEditorForm'; import { TemplateEditorTextArea } from './TemplateEditorTextArea'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; const EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI parameters: diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplatePage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplatePage.tsx similarity index 94% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplatePage.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplatePage.tsx index b34f1445f4..b70ceba163 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplatePage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplatePage.tsx @@ -25,8 +25,11 @@ import { type LayoutOptions, } from '@backstage/plugin-scaffolder-react'; -import { scaffolderTranslationRef } from '../../translation'; -import { WebFileSystemAccess, WebFileSystemStore } from '../../lib/filesystem'; +import { scaffolderTranslationRef } from '../../../translation'; +import { + WebFileSystemAccess, + WebFileSystemStore, +} from '../../../lib/filesystem'; import { TemplateEditor } from './TemplateEditor'; import { makeStyles } from '@material-ui/core/styles'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/index.ts b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/index.ts rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts diff --git a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx rename to plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.tsx diff --git a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx similarity index 99% rename from plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx index 2ad0752cc8..ba00845577 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx @@ -25,7 +25,7 @@ import { TestApiProvider, } from '@backstage/test-utils'; import React from 'react'; -import { rootRouteRef } from '../../routes'; +import { rootRouteRef } from '../../../routes'; import { TemplateListPage } from './TemplateListPage'; describe('TemplateListPage', () => { diff --git a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx similarity index 98% rename from plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx rename to plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx index 4c95027af7..8d0c73f0a7 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx @@ -50,14 +50,14 @@ import { scaffolderListTaskRouteRef, selectedTemplateRouteRef, viewTechDocRouteRef, -} from '../../routes'; +} from '../../../routes'; import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react'; import { TranslationFunction, useTranslationRef, } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; /** * @alpha diff --git a/plugins/scaffolder/src/next/TemplateListPage/index.ts b/plugins/scaffolder/src/alpha/components/TemplateListPage/index.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateListPage/index.ts rename to plugins/scaffolder/src/alpha/components/TemplateListPage/index.ts diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.test.tsx similarity index 99% rename from plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.test.tsx index 2639e8149c..689a96b95d 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.test.tsx @@ -28,7 +28,7 @@ import { SecretsContextProvider, } from '@backstage/plugin-scaffolder-react'; import { TemplateWizardPage } from './TemplateWizardPage'; -import { rootRouteRef } from '../../routes'; +import { rootRouteRef } from '../../../routes'; import { ANNOTATION_EDIT_URL } from '@backstage/catalog-model'; import { CatalogApi } from '@backstage/catalog-client'; import { catalogApiRef } from '@backstage/plugin-catalog-react'; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx rename to plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.tsx index 0524b99f8f..b5e24a7d52 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.tsx @@ -44,9 +44,9 @@ import { rootRouteRef, scaffolderTaskRouteRef, selectedTemplateRouteRef, -} from '../../routes'; +} from '../../../routes'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; import { TemplateWizardPageContextMenu } from './TemplateWizardPageContextMenu'; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPageContextMenu.tsx b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPageContextMenu.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPageContextMenu.tsx rename to plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPageContextMenu.tsx index 50e406112a..80274cef55 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPageContextMenu.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPageContextMenu.tsx @@ -25,7 +25,7 @@ import Edit from '@material-ui/icons/Edit'; import MoreVert from '@material-ui/icons/MoreVert'; import React, { useState } from 'react'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; const useStyles = makeStyles(theme => ({ button: { diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/index.ts b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/index.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/index.ts rename to plugins/scaffolder/src/alpha/components/TemplateWizardPage/index.ts diff --git a/plugins/scaffolder/src/next/index.ts b/plugins/scaffolder/src/alpha/components/index.ts similarity index 100% rename from plugins/scaffolder/src/next/index.ts rename to plugins/scaffolder/src/alpha/components/index.ts diff --git a/plugins/scaffolder/src/next/types.ts b/plugins/scaffolder/src/alpha/components/types.ts similarity index 100% rename from plugins/scaffolder/src/next/types.ts rename to plugins/scaffolder/src/alpha/components/types.ts diff --git a/plugins/scaffolder/src/alpha/extensions.tsx b/plugins/scaffolder/src/alpha/extensions.tsx new file mode 100644 index 0000000000..191dcf407c --- /dev/null +++ b/plugins/scaffolder/src/alpha/extensions.tsx @@ -0,0 +1,52 @@ +/* + * 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 { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; +import { + NavItemBlueprint, + PageBlueprint, +} from '@backstage/frontend-plugin-api'; +import React from 'react'; +import { rootRouteRef } from '../routes'; +import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; +import { FormFieldBlueprint } from '@backstage/plugin-scaffolder-react/alpha'; + +export const scaffolderPage = PageBlueprint.make({ + params: { + routeRef: convertLegacyRouteRef(rootRouteRef), + defaultPath: '/create', + loader: () => + import('../components/Router').then(m => compatWrapper()), + }, +}); + +export const scaffolderNavItem = NavItemBlueprint.make({ + params: { + routeRef: convertLegacyRouteRef(rootRouteRef), + title: 'Create...', + icon: CreateComponentIcon, + }, +}); + +export const repoUrlPickerFormField = FormFieldBlueprint.make({ + name: 'repo-url-picker', + params: { + field: () => import('./fields/RepoUrlPicker').then(m => m.RepoUrlPicker), + }, +}); diff --git a/plugins/scaffolder/src/alpha/fields/RepoUrlPicker.ts b/plugins/scaffolder/src/alpha/fields/RepoUrlPicker.ts new file mode 100644 index 0000000000..add8408b2d --- /dev/null +++ b/plugins/scaffolder/src/alpha/fields/RepoUrlPicker.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2024 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 { createFormField } from '@backstage/plugin-scaffolder-react/alpha'; +import { RepoUrlPicker as Component } from '../../components/fields/RepoUrlPicker/RepoUrlPicker'; +import { + RepoUrlPickerFieldSchema, + repoPickerValidation, +} from '../../components'; + +export const RepoUrlPicker = createFormField({ + component: Component, + name: 'RepoUrlPicker', + validation: repoPickerValidation, + schema: RepoUrlPickerFieldSchema, +}); diff --git a/plugins/scaffolder/src/alpha/index.ts b/plugins/scaffolder/src/alpha/index.ts new file mode 100644 index 0000000000..bd3104a274 --- /dev/null +++ b/plugins/scaffolder/src/alpha/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2024 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, + type ScaffolderCustomFieldExplorerClassKey, + type ScaffolderTemplateEditorClassKey, + type ScaffolderTemplateFormPreviewerClassKey, +} from './components'; + +export { scaffolderTranslationRef } from '../translation'; + +export { default } from './plugin'; diff --git a/plugins/scaffolder/src/alpha/plugin.tsx b/plugins/scaffolder/src/alpha/plugin.tsx new file mode 100644 index 0000000000..54e375e875 --- /dev/null +++ b/plugins/scaffolder/src/alpha/plugin.tsx @@ -0,0 +1,59 @@ +/* + * Copyright 2024 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 { convertLegacyRouteRefs } from '@backstage/core-compat-api'; +import { createFrontendPlugin } from '@backstage/frontend-plugin-api'; +import { + rootRouteRef, + actionsRouteRef, + editRouteRef, + registerComponentRouteRef, + scaffolderListTaskRouteRef, + scaffolderTaskRouteRef, + selectedTemplateRouteRef, + viewTechDocRouteRef, +} from '../routes'; +import { scaffolderApi } from './api'; +import { + repoUrlPickerFormField, + scaffolderNavItem, + scaffolderPage, +} from './extensions'; +import { formFieldsApi } from './api/FormFieldsApi'; + +/** @alpha */ +export default createFrontendPlugin({ + id: 'scaffolder', + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + selectedTemplate: selectedTemplateRouteRef, + ongoingTask: scaffolderTaskRouteRef, + actions: actionsRouteRef, + listTasks: scaffolderListTaskRouteRef, + edit: editRouteRef, + }), + externalRoutes: convertLegacyRouteRefs({ + registerComponent: registerComponentRouteRef, + viewTechDoc: viewTechDocRouteRef, + }), + extensions: [ + scaffolderApi, + scaffolderPage, + scaffolderNavItem, + formFieldsApi, + repoUrlPickerFormField, + ], +}); diff --git a/plugins/scaffolder/src/components/Router/Router.test.tsx b/plugins/scaffolder/src/components/Router/Router.test.tsx index 8c301b55fb..c062c723cf 100644 --- a/plugins/scaffolder/src/components/Router/Router.test.tsx +++ b/plugins/scaffolder/src/components/Router/Router.test.tsx @@ -25,9 +25,9 @@ import { createScaffolderLayout, ScaffolderLayouts, } from '@backstage/plugin-scaffolder-react'; -import { TemplateListPage, TemplateWizardPage } from '../../next'; +import { TemplateListPage, TemplateWizardPage } from '../../alpha/components'; -jest.mock('../../next', () => ({ +jest.mock('../../alpha/components', () => ({ TemplateWizardPage: jest.fn(() => null), TemplateListPage: jest.fn(() => null), })); diff --git a/plugins/scaffolder/src/components/Router/Router.tsx b/plugins/scaffolder/src/components/Router/Router.tsx index 385a5f9fad..e79d930795 100644 --- a/plugins/scaffolder/src/components/Router/Router.tsx +++ b/plugins/scaffolder/src/components/Router/Router.tsx @@ -51,14 +51,14 @@ import { TemplateListPageProps, TemplateWizardPageProps, } from '@backstage/plugin-scaffolder/alpha'; -import { TemplateListPage, TemplateWizardPage } from '../../next'; +import { TemplateListPage, TemplateWizardPage } from '../../alpha/components'; import { OngoingTask } from '../OngoingTask'; import { TemplatePage, TemplateFormPage, TemplateEditorPage, CustomFieldsPage, -} from '../../next/TemplateEditorPage'; +} from '../../alpha/components/TemplateEditorPage'; /** * The Props for the Scaffolder Router diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index e653be9178..3c9ca9c2ca 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -28,7 +28,7 @@ import { GerritRepoPicker } from './GerritRepoPicker'; import { RepoUrlPickerHost } from './RepoUrlPickerHost'; import { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName'; import { parseRepoPickerUrl, serializeRepoPickerUrl } from './utils'; -import { RepoUrlPickerProps } from './schema'; +import { RepoUrlPickerFieldSchema } from './schema'; import { RepoUrlPickerState } from './types'; import useDebounce from 'react-use/esm/useDebounce'; import { useTemplateSecrets } from '@backstage/plugin-scaffolder-react'; @@ -44,7 +44,9 @@ export { RepoUrlPickerSchema } from './schema'; * * @public */ -export const RepoUrlPicker = (props: RepoUrlPickerProps) => { +export const RepoUrlPicker = ( + props: typeof RepoUrlPickerFieldSchema.TProps, +) => { const { uiSchema, onChange, rawErrors, formData, schema } = props; const [state, setState] = useState( parseRepoPickerUrl(formData), diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts index 2ec72bc5a6..ff307f2ffe 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts @@ -13,84 +13,86 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { z } from 'zod'; -import { makeFieldSchemaFromZod } from '../utils'; + +import { makeFieldSchema } from '@backstage/plugin-scaffolder-react'; /** * @public */ -export const RepoUrlPickerFieldSchema = makeFieldSchemaFromZod( - z.string(), - z.object({ - allowedHosts: z - .array(z.string()) - .optional() - .describe('List of allowed SCM platform hosts'), - allowedOrganizations: z - .array(z.string()) - .optional() - .describe('List of allowed organizations in the given SCM platform'), - allowedOwners: z - .array(z.string()) - .optional() - .describe('List of allowed owners in the given SCM platform'), - allowedProjects: z - .array(z.string()) - .optional() - .describe('List of allowed projects in the given SCM platform'), - allowedRepos: z - .array(z.string()) - .optional() - .describe('List of allowed repos in the given SCM platform'), - requestUserCredentials: z - .object({ - secretsKey: z - .string() - .describe( - 'Key used within the template secrets context to store the credential', - ), - additionalScopes: z - .object({ - gitea: z - .array(z.string()) - .optional() - .describe('Additional Gitea scopes to request'), - gerrit: z - .array(z.string()) - .optional() - .describe('Additional Gerrit scopes to request'), - github: z - .array(z.string()) - .optional() - .describe('Additional GitHub scopes to request'), - gitlab: z - .array(z.string()) - .optional() - .describe('Additional GitLab scopes to request'), - bitbucket: z - .array(z.string()) - .optional() - .describe('Additional BitBucket scopes to request'), - azure: z - .array(z.string()) - .optional() - .describe('Additional Azure scopes to request'), - }) - .optional() - .describe('Additional permission scopes to request'), - }) - .optional() - .describe( - 'If defined will request user credentials to auth against the given SCM platform', - ), - }), -); +export const RepoUrlPickerFieldSchema = makeFieldSchema({ + output: z => z.string(), + uiOptions: z => + z.object({ + allowedHosts: z + .array(z.string()) + .optional() + .describe('List of allowed SCM platform hosts'), + allowedOrganizations: z + .array(z.string()) + .optional() + .describe('List of allowed organizations in the given SCM platform'), + allowedOwners: z + .array(z.string()) + .optional() + .describe('List of allowed owners in the given SCM platform'), + allowedProjects: z + .array(z.string()) + .optional() + .describe('List of allowed projects in the given SCM platform'), + allowedRepos: z + .array(z.string()) + .optional() + .describe('List of allowed repos in the given SCM platform'), + requestUserCredentials: z + .object({ + secretsKey: z + .string() + .describe( + 'Key used within the template secrets context to store the credential', + ), + additionalScopes: z + .object({ + gitea: z + .array(z.string()) + .optional() + .describe('Additional Gitea scopes to request'), + gerrit: z + .array(z.string()) + .optional() + .describe('Additional Gerrit scopes to request'), + github: z + .array(z.string()) + .optional() + .describe('Additional GitHub scopes to request'), + gitlab: z + .array(z.string()) + .optional() + .describe('Additional GitLab scopes to request'), + bitbucket: z + .array(z.string()) + .optional() + .describe('Additional BitBucket scopes to request'), + azure: z + .array(z.string()) + .optional() + .describe('Additional Azure scopes to request'), + }) + .optional() + .describe('Additional permission scopes to request'), + }) + .optional() + .describe( + 'If defined will request user credentials to auth against the given SCM platform', + ), + }), +}); /** * The input props that can be specified under `ui:options` for the * `RepoUrlPicker` field extension. * * @public + * @deprecated this will be removed as it's no longer used */ export type RepoUrlPickerUiOptions = typeof RepoUrlPickerFieldSchema.uiOptionsType; diff --git a/plugins/scaffolder/src/components/fields/utils.ts b/plugins/scaffolder/src/components/fields/utils.ts index 7b59f1da90..4ec9de2d99 100644 --- a/plugins/scaffolder/src/components/fields/utils.ts +++ b/plugins/scaffolder/src/components/fields/utils.ts @@ -16,27 +16,21 @@ import { JSONSchema7 } from 'json-schema'; import { z } from 'zod'; import zodToJsonSchema from 'zod-to-json-schema'; -import { - CustomFieldExtensionSchema, - FieldExtensionComponentProps, -} from '@backstage/plugin-scaffolder-react'; +import { FieldSchema as FieldSchemaType } from '@backstage/plugin-scaffolder-react'; /** * @public - * FieldSchema encapsulates a JSONSchema7 along with the - * matching FieldExtensionComponentProps type for a field extension. + * @deprecated - import from {@link @backstage/plugin-scaffolder-react#FieldSchema} instead */ -export interface FieldSchema { - readonly schema: CustomFieldExtensionSchema; - readonly type: FieldExtensionComponentProps; - readonly uiOptionsType: TUiOptions; -} +export interface FieldSchema extends FieldSchemaType {} /** * @public + * @deprecated use `makeFieldSchema` instead * Utility function to convert zod return and UI options schemas to a * CustomFieldExtensionSchema with FieldExtensionComponentProps type inference */ + export function makeFieldSchemaFromZod< TReturnSchema extends z.ZodType, TUiOptionsSchema extends z.ZodType = z.ZodType, @@ -58,5 +52,6 @@ export function makeFieldSchemaFromZod< }, type: null as any, uiOptionsType: null as any, + TProps: undefined as any, }; } diff --git a/plugins/scaffolder/src/overridableComponents.ts b/plugins/scaffolder/src/overridableComponents.ts index 99e9556003..3059d4523a 100644 --- a/plugins/scaffolder/src/overridableComponents.ts +++ b/plugins/scaffolder/src/overridableComponents.ts @@ -16,9 +16,9 @@ import { Overrides } from '@material-ui/core/styles/overrides'; import { StyleRules } from '@material-ui/core/styles/withStyles'; -import { ScaffolderTemplateEditorClassKey } from './next/TemplateEditorPage/TemplateEditor'; -import { ScaffolderTemplateFormPreviewerClassKey } from './next/TemplateEditorPage/TemplateFormPreviewer'; -import { ScaffolderCustomFieldExplorerClassKey } from './next/TemplateEditorPage/CustomFieldExplorer'; +import { ScaffolderTemplateEditorClassKey } from './alpha/components/TemplateEditorPage/TemplateEditor'; +import { ScaffolderTemplateFormPreviewerClassKey } from './alpha/components/TemplateEditorPage/TemplateFormPreviewer'; +import { ScaffolderCustomFieldExplorerClassKey } from './alpha/components/TemplateEditorPage/CustomFieldExplorer'; /** @public */ export type ScaffolderReactComponentsNameToClassKey = { diff --git a/yarn.lock b/yarn.lock index 1aab23e1bc..e97917da44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7200,6 +7200,7 @@ __metadata: "@backstage/core-app-api": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" @@ -9947,6 +9948,16 @@ __metadata: languageName: unknown linkType: soft +"@internal/scaffolder@workspace:packages/scaffolder-internal": + version: 0.0.0-use.local + resolution: "@internal/scaffolder@workspace:packages/scaffolder-internal" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/plugin-scaffolder-react": "workspace:^" + zod: ^3.22.4 + languageName: unknown + linkType: soft + "@ioredis/commands@npm:^1.1.1": version: 1.1.1 resolution: "@ioredis/commands@npm:1.1.1"