diff --git a/plugins/scaffolder-react/src/hooks/useCustomFieldExtensions.ts b/plugins/scaffolder-react/src/hooks/useCustomFieldExtensions.ts index 9b794a3662..7e0aafd53f 100644 --- a/plugins/scaffolder-react/src/hooks/useCustomFieldExtensions.ts +++ b/plugins/scaffolder-react/src/hooks/useCustomFieldExtensions.ts @@ -20,19 +20,16 @@ import { FIELD_EXTENSION_WRAPPER_KEY, } from '../extensions/keys'; -type Extension = Omit & { validation?: unknown } - /** * Hook that returns all custom field extensions from the current outlet. * @public */ export const useCustomFieldExtensions = < - TComponentDataType = FieldExtensionOptions + TComponentDataType = FieldExtensionOptions, >( outlet: React.ReactNode, - defaultScaffolderFieldExtensions: Extension[] = [] ) => { - const customFieldExtensions = useElementFilter(outlet, elements => + return useElementFilter(outlet, elements => elements .selectByComponentData({ key: FIELD_EXTENSION_WRAPPER_KEY, @@ -40,15 +37,5 @@ export const useCustomFieldExtensions = < .findComponentData({ key: FIELD_EXTENSION_KEY, }), - ) as FieldExtensionOptions[]; - - return [ - ...customFieldExtensions, - ...defaultScaffolderFieldExtensions.filter( - ({ name }) => - !customFieldExtensions.some( - customFieldExtension => customFieldExtension.name === name, - ), - ), - ]; + ); }; diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 638a1fb41c..6bd3ec8c71 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useAnalytics, useApiHolder, useRouteRefParams } from '@backstage/core-plugin-api'; +import { useAnalytics, useApiHolder } from '@backstage/core-plugin-api'; import { JsonValue } from '@backstage/types'; import { Stepper as MuiStepper, @@ -34,7 +34,6 @@ import { useTemplateSchema } from '../../hooks/useTemplateSchema'; import { useFormDataFromQuery } from '../../hooks/useFormDataFromQuery'; import validator from '@rjsf/validator-ajv6'; - const useStyles = makeStyles(theme => ({ backButton: { marginRight: theme.spacing(1), @@ -64,7 +63,7 @@ export type StepperProps = { onComplete: (values: Record) => Promise; initialFormState?: Record; ReviewStateWrapper?: (props: ReviewStateProps) => JSX.Element; -} +}; // TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly // which is what we're using here as the default types, it needs to depend on @rjsf/core-v5 because diff --git a/plugins/scaffolder/src/components/Router.tsx b/plugins/scaffolder/src/components/Router.tsx index ae14e7491b..6a2da406e0 100644 --- a/plugins/scaffolder/src/components/Router.tsx +++ b/plugins/scaffolder/src/components/Router.tsx @@ -93,7 +93,16 @@ export const Router = (props: RouterProps) => { const outlet = useOutlet(); const TaskPageElement = TaskPageComponent ?? TaskPage; - const fieldExtensions = useCustomFieldExtensions(outlet, DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS); + const customFieldExtensions = useCustomFieldExtensions(outlet); + const fieldExtensions = [ + ...customFieldExtensions, + ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter( + ({ name }) => + !customFieldExtensions.some( + customFieldExtension => customFieldExtension.name === name, + ), + ), + ] as FieldExtensionOptions[]; // todo(blam): this should also be moved to a hook in -react const customLayouts = useElementFilter(outlet, elements => diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index 2f3cd6b385..2b1eccc711 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -49,16 +49,10 @@ export { EmbeddedScaffolderWorkflow, type EmbeddedScaffolderWorkflowProps, type WorkflowProps, - type ReviewStateProps, - type ParsedTemplateSchema, } from './next'; -export type { NextRouterProps } from './next'; -export type { TemplateGroupFilter } from './next'; export { nextRouteRef, nextScaffolderTaskRouteRef, nextSelectedTemplateRouteRef, - type TemplateGroupFilter, - type NextRouterProps, type FormProps, } from './next'; diff --git a/plugins/scaffolder/src/next/EmbeddedScaffolderWorkflow/EmbeddedScaffolderWorkflow.test.tsx b/plugins/scaffolder/src/next/EmbeddedScaffolderWorkflow/EmbeddedScaffolderWorkflow.test.tsx index ef35f0caef..62b3c96718 100644 --- a/plugins/scaffolder/src/next/EmbeddedScaffolderWorkflow/EmbeddedScaffolderWorkflow.test.tsx +++ b/plugins/scaffolder/src/next/EmbeddedScaffolderWorkflow/EmbeddedScaffolderWorkflow.test.tsx @@ -23,8 +23,10 @@ import { import { act, fireEvent } from '@testing-library/react'; import React from 'react'; import { EmbeddedScaffolderWorkflow } from './EmbeddedScaffolderWorkflow'; -import { scaffolderApiRef } from '../../api'; -import { ScaffolderApi } from '../../types'; +import { + scaffolderApiRef, + type ScaffolderApi, +} from '@backstage/plugin-scaffolder-react'; import { analyticsApiRef } from '@backstage/core-plugin-api'; const scaffolderApiMock: jest.Mocked = { @@ -80,6 +82,7 @@ describe('', () => { initialFormState={{ name: 'prefilled-name', }} + customFieldExtensions={[]} frontPage={ <>

Security Insights

diff --git a/plugins/scaffolder/src/next/EmbeddedScaffolderWorkflow/EmbeddedScaffolderWorkflow.tsx b/plugins/scaffolder/src/next/EmbeddedScaffolderWorkflow/EmbeddedScaffolderWorkflow.tsx index 2d3b053bf7..32b616274c 100644 --- a/plugins/scaffolder/src/next/EmbeddedScaffolderWorkflow/EmbeddedScaffolderWorkflow.tsx +++ b/plugins/scaffolder/src/next/EmbeddedScaffolderWorkflow/EmbeddedScaffolderWorkflow.tsx @@ -18,22 +18,21 @@ import React, { useState, useCallback } from 'react'; import type { ReactNode } from 'react'; import type { JsonValue } from '@backstage/types'; import { EmbeddableWorkflow, type WorkflowProps } from '../Workflow/Workflow'; -import { FormProps, useCustomFieldExtensions } from '@backstage/plugin-scaffolder-react'; +import { FormProps } from '@backstage/plugin-scaffolder-react'; import { Box, Button } from '@material-ui/core'; -import { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default'; /** * @alpha */ export type EmbeddedScaffolderWorkflowProps = Omit< WorkflowProps, - 'customFieldExtensions' | 'onComplete' + 'onComplete' | 'FormProps' > & { customExtensionsElement?: React.ReactNode; initialFormState?: Record; onComplete: (values: Record) => Promise; onError(error: Error | undefined): JSX.Element | null; - FormProps: FormProps + FormProps?: FormProps; frontPage: ReactNode; finishPage: ReactNode; } & Partial>; @@ -51,7 +50,6 @@ type OnCompleteArgs = Parameters[0]; export function EmbeddedScaffolderWorkflow({ namespace, templateName, - customExtensionsElement = <>, frontPage, finishPage, onComplete = async (_values: OnCompleteArgs) => void 0, @@ -60,9 +58,10 @@ export function EmbeddedScaffolderWorkflow({ description, ReviewStateWrapper, initialFormState, + customFieldExtensions, + FormProps: formProps = {}, }: EmbeddedScaffolderWorkflowProps): JSX.Element { const [display, setDisplay] = useState('front'); - const fieldExtensions = useCustomFieldExtensions(customExtensionsElement, DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS); const startTemplate = useCallback(() => setDisplay('workflow'), []); @@ -92,9 +91,10 @@ export function EmbeddedScaffolderWorkflow({ templateName={templateName} onComplete={onWorkFlowComplete} onError={onError} - customFieldExtensions={fieldExtensions} + customFieldExtensions={customFieldExtensions} ReviewStateWrapper={ReviewStateWrapper} initialFormState={initialFormState} + FormProps={formProps} /> ), finish: ( diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index b4df2c5833..eb23284649 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -30,7 +30,8 @@ import { import useAsync from 'react-use/lib/useAsync'; import { JsonValue } from '@backstage/types'; import { FormProps } from '@backstage/plugin-scaffolder-react'; -import { nextRouteRef, scaffolderTaskRouteRef, selectedTemplateRouteRef } from '../../routes'; +import { nextRouteRef } from '../routes'; +import { scaffolderTaskRouteRef, selectedTemplateRouteRef } from '../../routes'; import { Header, Page } from '@backstage/core-components'; import { Workflow } from '../Workflow/Workflow'; diff --git a/plugins/scaffolder/src/next/Workflow/Workflow.tsx b/plugins/scaffolder/src/next/Workflow/Workflow.tsx index eaeac163a7..7acc29c10f 100644 --- a/plugins/scaffolder/src/next/Workflow/Workflow.tsx +++ b/plugins/scaffolder/src/next/Workflow/Workflow.tsx @@ -67,6 +67,7 @@ export interface WorkflowProps { export const Workflow = ({ ReviewStateWrapper = ReviewState, + FormProps = {}, ...props }: WorkflowProps): JSX.Element | null => { const styles = useStyles(); @@ -111,7 +112,7 @@ export const Workflow = ({ manifest={manifest} extensions={props.customFieldExtensions} onComplete={props.onComplete} - FormProps={props.FormProps} + FormProps={FormProps} initialFormState={props.initialFormState} ReviewStateWrapper={ReviewStateWrapper} />