diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index d87ebff860..17391aedfa 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -43,7 +43,21 @@ "@backstage/version-bridge": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", - "@material-ui/lab": "4.0.0-alpha.57" + "@material-ui/lab": "4.0.0-alpha.57", + "@rjsf/core": "^3.2.1", + "@rjsf/core-v5": "npm:@rjsf/core@^5.0.0-beta.14", + "@rjsf/material-ui": "^3.2.1", + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@^5.0.0-beta.14", + "@rjsf/utils": "^5.0.0-beta.14", + "@rjsf/validator-ajv6": "^5.0.0-beta.14", + "@types/json-schema": "^7.0.9", + "classnames": "^2.2.6", + "json-schema": "^0.4.0", + "json-schema-library": "^7.3.9", + "lodash": "^4.17.21", + "qs": "^6.9.4", + "zod": "~3.18.0", + "zod-to-json-schema": "~3.18.0" }, "peerDependencies": { "@types/react": "^16.13.1 || ^17.0.0", diff --git a/plugins/scaffolder/src/extensions/index.tsx b/plugins/scaffolder-react/src/extensions/index.tsx similarity index 70% rename from plugins/scaffolder/src/extensions/index.tsx rename to plugins/scaffolder-react/src/extensions/index.tsx index 2b3126ac58..093c68c172 100644 --- a/plugins/scaffolder/src/extensions/index.tsx +++ b/plugins/scaffolder-react/src/extensions/index.tsx @@ -20,12 +20,8 @@ import { CustomFieldValidator, FieldExtensionOptions, FieldExtensionComponentProps, - NextCustomFieldValidator, - NextFieldExtensionOptions, - NextFieldExtensionComponentProps, } from './types'; import { Extension, attachComponentData } from '@backstage/core-plugin-api'; -import { UIOptionsType } from '@rjsf/utils'; export const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1'; export const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1'; @@ -63,32 +59,6 @@ export function createScaffolderFieldExtension< }; } -/** - * Method for creating field extensions that can be used in the scaffolder - * frontend form. - * @alpha - */ -export function createNextScaffolderFieldExtension< - TReturnValue = unknown, - TInputProps extends UIOptionsType = {}, ->( - options: NextFieldExtensionOptions, -): Extension> { - return { - expose() { - const FieldExtensionDataHolder: any = () => null; - - attachComponentData( - FieldExtensionDataHolder, - FIELD_EXTENSION_KEY, - options, - ); - - return FieldExtensionDataHolder; - }, - }; -} - /** * The Wrapping component for defining fields extensions inside * @@ -109,9 +79,4 @@ export type { CustomFieldValidator, FieldExtensionOptions, FieldExtensionComponentProps, - NextCustomFieldValidator, - NextFieldExtensionOptions, - NextFieldExtensionComponentProps, }; - -export { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from './default'; diff --git a/plugins/scaffolder/src/extensions/types.ts b/plugins/scaffolder-react/src/extensions/types.ts similarity index 64% rename from plugins/scaffolder/src/extensions/types.ts rename to plugins/scaffolder-react/src/extensions/types.ts index 5e133c676b..a2a1a8d69c 100644 --- a/plugins/scaffolder/src/extensions/types.ts +++ b/plugins/scaffolder-react/src/extensions/types.ts @@ -21,9 +21,7 @@ import { UiSchema as UiSchemaV5, FieldValidation as FieldValidationV5, } from '@rjsf/utils'; -import { PropsWithChildren } from 'react'; import { JSONSchema7 } from 'json-schema'; -import { JsonObject } from '@backstage/types'; /** * Field validation type for Custom Field Extensions. @@ -78,46 +76,3 @@ export interface FieldExtensionComponentProps< 'ui:options'?: TUiOptions; }; } - -/** - * Type for Field Extension Props for RJSF v5 - * - * @alpha - */ -export interface NextFieldExtensionComponentProps< - TFieldReturnValue, - TUiOptions = {}, -> extends PropsWithChildren> { - uiSchema?: UiSchemaV5 & { - 'ui:options'?: TUiOptions & UIOptionsType; - }; -} - -/** - * Field validation type for Custom Field Extensions. - * - * @alpha - */ -export type NextCustomFieldValidator = ( - data: TFieldReturnValue, - field: FieldValidationV5, - context: { apiHolder: ApiHolder; formData: JsonObject }, -) => void | Promise; - -/** - * Type for the Custom Field Extension with the - * name and components and validation function. - * - * @alpha - */ -export type NextFieldExtensionOptions< - TFieldReturnValue = unknown, - TInputProps = unknown, -> = { - name: string; - component: ( - props: NextFieldExtensionComponentProps, - ) => JSX.Element | null; - validation?: NextCustomFieldValidator; - schema?: CustomFieldExtensionSchema; -}; diff --git a/plugins/scaffolder-react/src/index.ts b/plugins/scaffolder-react/src/index.ts index 3121231047..42a2cebb19 100644 --- a/plugins/scaffolder-react/src/index.ts +++ b/plugins/scaffolder-react/src/index.ts @@ -15,3 +15,6 @@ */ export * from './routes'; +export * from './extensions'; + +export * from './next'; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/ReviewState.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/ReviewState.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/ReviewState.test.tsx rename to plugins/scaffolder-react/src/next/components/Stepper/ReviewState.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/Stepper/ReviewState.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/ReviewState.tsx rename to plugins/scaffolder-react/src/next/components/Stepper/ReviewState.tsx diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx rename to plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx similarity index 96% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx rename to plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index e285c21c6f..72079d6f91 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -29,14 +29,14 @@ import { import { type IChangeEvent, withTheme } from '@rjsf/core-v5'; import { ErrorSchema, FieldValidation } from '@rjsf/utils'; import React, { useCallback, useMemo, useState } from 'react'; -import { NextFieldExtensionOptions } from '../../../extensions'; +import { NextFieldExtensionOptions } from '../../extensions'; import { TemplateParameterSchema } from '../../../types'; import { createAsyncValidators } from './createAsyncValidators'; -import { useTemplateSchema } from './useTemplateSchema'; +import { useTemplateSchema } from '../../hooks/useTemplateSchema'; import { ReviewState } from './ReviewState'; import validator from '@rjsf/validator-ajv6'; -import { selectedTemplateRouteRef } from '@backstage/plugin-scaffolder-react'; -import { useFormData } from './useFormData'; +import { selectedTemplateRouteRef } from '../../../routes'; +import { useFormData } from '../../hooks/useFormData'; import { FormProps } from '../../types'; const useStyles = makeStyles(theme => ({ @@ -66,6 +66,9 @@ export type StepperProps = { // of the re-writing we're doing. Once we've migrated, we can import this the exact same as before. const Form = withTheme(require('@rjsf/material-ui-v5').Theme); +/** + * @alpha + */ export const Stepper = (props: StepperProps) => { const { templateName } = useRouteRefParams(selectedTemplateRouteRef); const analytics = useAnalytics(); diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/createAsyncValidators.test.ts b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/createAsyncValidators.test.ts rename to plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/createAsyncValidators.ts b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/createAsyncValidators.ts rename to plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/index.ts b/plugins/scaffolder-react/src/next/components/Stepper/index.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/index.ts rename to plugins/scaffolder-react/src/next/components/Stepper/index.ts diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/schema.test.ts b/plugins/scaffolder-react/src/next/components/Stepper/schema.test.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/schema.test.ts rename to plugins/scaffolder-react/src/next/components/Stepper/schema.test.ts diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/schema.ts b/plugins/scaffolder-react/src/next/components/Stepper/schema.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/schema.ts rename to plugins/scaffolder-react/src/next/components/Stepper/schema.ts diff --git a/plugins/scaffolder-react/src/next/components/index.ts b/plugins/scaffolder-react/src/next/components/index.ts new file mode 100644 index 0000000000..5532563e28 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { Stepper } from './Stepper'; diff --git a/plugins/scaffolder-react/src/next/extensions/index.tsx b/plugins/scaffolder-react/src/next/extensions/index.tsx new file mode 100644 index 0000000000..7bbf7d4112 --- /dev/null +++ b/plugins/scaffolder-react/src/next/extensions/index.tsx @@ -0,0 +1,59 @@ +/* + * Copyright 2021 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 { + NextCustomFieldValidator, + NextFieldExtensionOptions, + NextFieldExtensionComponentProps, +} from './types'; +import { Extension, attachComponentData } from '@backstage/core-plugin-api'; +import { UIOptionsType } from '@rjsf/utils'; +import { FieldExtensionComponent } from '../../extensions'; + +export const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1'; +export const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1'; + +/** + * Method for creating field extensions that can be used in the scaffolder + * frontend form. + * @alpha + */ +export function createNextScaffolderFieldExtension< + TReturnValue = unknown, + TInputProps extends UIOptionsType = {}, +>( + options: NextFieldExtensionOptions, +): Extension> { + return { + expose() { + const FieldExtensionDataHolder: any = () => null; + + attachComponentData( + FieldExtensionDataHolder, + FIELD_EXTENSION_KEY, + options, + ); + + return FieldExtensionDataHolder; + }, + }; +} + +export type { + NextCustomFieldValidator, + NextFieldExtensionOptions, + NextFieldExtensionComponentProps, +}; diff --git a/plugins/scaffolder-react/src/next/extensions/types.ts b/plugins/scaffolder-react/src/next/extensions/types.ts new file mode 100644 index 0000000000..27778b0420 --- /dev/null +++ b/plugins/scaffolder-react/src/next/extensions/types.ts @@ -0,0 +1,68 @@ +/* + * Copyright 2021 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 { ApiHolder } from '@backstage/core-plugin-api'; +import { + UIOptionsType, + FieldProps as FieldPropsV5, + UiSchema as UiSchemaV5, + FieldValidation as FieldValidationV5, +} from '@rjsf/utils'; +import { PropsWithChildren } from 'react'; +import { JsonObject } from '@backstage/types'; +import { CustomFieldExtensionSchema } from '../../extensions'; + +/** + * Type for Field Extension Props for RJSF v5 + * + * @alpha + */ +export interface NextFieldExtensionComponentProps< + TFieldReturnValue, + TUiOptions = {}, +> extends PropsWithChildren> { + uiSchema?: UiSchemaV5 & { + 'ui:options'?: TUiOptions & UIOptionsType; + }; +} + +/** + * Field validation type for Custom Field Extensions. + * + * @alpha + */ +export type NextCustomFieldValidator = ( + data: TFieldReturnValue, + field: FieldValidationV5, + context: { apiHolder: ApiHolder; formData: JsonObject }, +) => void | Promise; + +/** + * Type for the Custom Field Extension with the + * name and components and validation function. + * + * @alpha + */ +export type NextFieldExtensionOptions< + TFieldReturnValue = unknown, + TInputProps = unknown, +> = { + name: string; + component: ( + props: NextFieldExtensionComponentProps, + ) => JSX.Element | null; + validation?: NextCustomFieldValidator; + schema?: CustomFieldExtensionSchema; +}; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useFormData.ts b/plugins/scaffolder-react/src/next/hooks/useFormData.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useFormData.ts rename to plugins/scaffolder-react/src/next/hooks/useFormData.ts diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useTemplateSchema.test.tsx b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useTemplateSchema.test.tsx rename to plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useTemplateSchema.ts b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useTemplateSchema.ts rename to plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts diff --git a/plugins/scaffolder-react/src/next/index.ts b/plugins/scaffolder-react/src/next/index.ts new file mode 100644 index 0000000000..aa46a7a6cd --- /dev/null +++ b/plugins/scaffolder-react/src/next/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './components'; +export * from './extensions'; diff --git a/plugins/scaffolder-react/src/types.ts b/plugins/scaffolder-react/src/types.ts new file mode 100644 index 0000000000..b61d59e88d --- /dev/null +++ b/plugins/scaffolder-react/src/types.ts @@ -0,0 +1,15 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index aece4e427e..75da592bba 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -35,7 +35,7 @@ import { import { scaffolderApiRef } from '../../api'; import useAsync from 'react-use/lib/useAsync'; import { makeStyles } from '@material-ui/core'; -import { Stepper } from './Stepper'; +import { Stepper } from '@backstage/plugin-scaffolder-react'; import { BackstageTheme } from '@backstage/theme'; import { nextRouteRef, diff --git a/yarn.lock b/yarn.lock index 0ad909a7a2..827fa3423a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7470,10 +7470,24 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 + "@rjsf/core": ^3.2.1 + "@rjsf/core-v5": "npm:@rjsf/core@^5.0.0-beta.14" + "@rjsf/material-ui": ^3.2.1 + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@^5.0.0-beta.14" + "@rjsf/utils": ^5.0.0-beta.14 + "@rjsf/validator-ajv6": ^5.0.0-beta.14 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 + "@types/json-schema": ^7.0.9 + classnames: ^2.2.6 + json-schema: ^0.4.0 + json-schema-library: ^7.3.9 + lodash: ^4.17.21 + qs: ^6.9.4 + zod: ~3.18.0 + zod-to-json-schema: ~3.18.0 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 react: ^16.13.1 || ^17.0.0