diff --git a/plugins/scaffolder-react/api-report.md b/plugins/scaffolder-react/api-report.md index 81259772b5..07d92530cb 100644 --- a/plugins/scaffolder-react/api-report.md +++ b/plugins/scaffolder-react/api-report.md @@ -6,6 +6,7 @@ /// import { ApiHolder } from '@backstage/core-plugin-api'; +import { Dispatch } from 'react'; import { Extension } from '@backstage/core-plugin-api'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { FieldProps } from '@rjsf/core'; @@ -20,13 +21,12 @@ import { PathParams } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; +import { SetStateAction } from 'react'; import { SubRouteRef } from '@backstage/core-plugin-api'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { UIOptionsType } from '@rjsf/utils'; import { UiSchema } from '@rjsf/utils'; -// Warning: (ae-missing-release-tag) "actionsRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const actionsRouteRef: SubRouteRef; @@ -64,8 +64,6 @@ export type CustomFieldValidator = ( }, ) => void | Promise; -// Warning: (ae-missing-release-tag) "editRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const editRouteRef: SubRouteRef; @@ -75,14 +73,10 @@ export const extractSchemaFromStep: (inputStep: JsonObject) => { schema: JsonObject; }; -// Warning: (ae-missing-release-tag) "FIELD_EXTENSION_KEY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1'; -// Warning: (ae-missing-release-tag) "FIELD_EXTENSION_WRAPPER_KEY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1'; // @public @@ -118,8 +112,6 @@ export type FormProps = Pick< 'transformErrors' | 'noHtml5Validate' >; -// Warning: (ae-missing-release-tag) "legacySelectedTemplateRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public @deprecated (undocumented) export const legacySelectedTemplateRouteRef: SubRouteRef< PathParams<'/templates/:templateName'> @@ -162,9 +154,7 @@ export type NextFieldExtensionOptions< // @alpha (undocumented) export const nextRouteRef: RouteRef; -// Warning: (ae-missing-release-tag) "nextScaffolderTaskRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @alpha (undocumented) export const nextScaffolderTaskRouteRef: SubRouteRef< PathParams<'/tasks/:taskId'> >; @@ -174,29 +164,41 @@ export const nextSelectedTemplateRouteRef: SubRouteRef< PathParams<'/templates/:namespace/:templateName'> >; -// Warning: (ae-missing-release-tag) "registerComponentRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @alpha +export interface ParsedTemplateSchema { + // (undocumented) + description?: string; + // (undocumented) + mergedSchema: JsonObject; + // (undocumented) + schema: JsonObject; + // (undocumented) + title: string; + // (undocumented) + uiSchema: UiSchema; +} + // @public (undocumented) export const registerComponentRouteRef: ExternalRouteRef; -// Warning: (ae-forgotten-export) The symbol "ReviewStateProps" needs to be exported by the entry point index.d.ts -// // @alpha export const ReviewState: (props: ReviewStateProps) => JSX.Element; +// @alpha +export type ReviewStateProps = { + schemas: ParsedTemplateSchema[]; + formState: JsonObject; +}; + // @public (undocumented) export const rootRouteRef: RouteRef; // @public export const ScaffolderFieldExtensions: React_2.ComponentType; -// Warning: (ae-missing-release-tag) "scaffolderListTaskRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const scaffolderListTaskRouteRef: SubRouteRef; -// Warning: (ae-missing-release-tag) "scaffolderTaskRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const scaffolderTaskRouteRef: SubRouteRef>; @@ -205,11 +207,17 @@ export const selectedTemplateRouteRef: SubRouteRef< PathParams<'/templates/:namespace/:templateName'> >; -// Warning: (ae-forgotten-export) The symbol "StepperProps" needs to be exported by the entry point index.d.ts -// -// @alpha (undocumented) +// @alpha export const Stepper: (props: StepperProps) => JSX.Element; +// @alpha +export type StepperProps = { + manifest: TemplateParameterSchema; + extensions: NextFieldExtensionOptions[]; + onComplete: (values: Record) => Promise; + FormProps?: FormProps; +}; + // @alpha export const TemplateCard: (props: TemplateCardProps) => JSX.Element; @@ -221,6 +229,21 @@ export interface TemplateCardProps { template: TemplateEntityV1beta3; } +// @alpha +export const TemplateGroup: (props: TemplateGroupProps) => JSX.Element; + +// @alpha +export interface TemplateGroupProps { + // (undocumented) + components?: { + CardComponent?: React_2.ComponentType; + }; + // (undocumented) + templates: TemplateEntityV1beta3[]; + // (undocumented) + title: React_2.ReactNode; +} + // @public export type TemplateParameterSchema = { title: string; @@ -232,8 +255,17 @@ export type TemplateParameterSchema = { }>; }; -// Warning: (ae-missing-release-tag) "viewTechDocRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @alpha +export const useFormData: () => [ + Record, + Dispatch>>, +]; + +// @alpha +export const useTemplateSchema: (manifest: TemplateParameterSchema) => { + steps: ParsedTemplateSchema[]; +}; + // @public (undocumented) export const viewTechDocRouteRef: ExternalRouteRef< { diff --git a/plugins/scaffolder-react/src/extensions/index.tsx b/plugins/scaffolder-react/src/extensions/index.tsx index 093c68c172..94bf8bad14 100644 --- a/plugins/scaffolder-react/src/extensions/index.tsx +++ b/plugins/scaffolder-react/src/extensions/index.tsx @@ -23,12 +23,19 @@ import { } from './types'; import { Extension, attachComponentData } from '@backstage/core-plugin-api'; +/** + * The key used to store the field extension data for the `` component + * @public + */ export const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1'; +/** + * The key used to store the field extension data for any `` component + * @public + */ export const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1'; /** * A type used to wrap up the FieldExtension to embed the ReturnValue and the InputProps - * * @public */ export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null; diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index 9b69a898f2..52ad80c4c2 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -19,13 +19,17 @@ import { JsonObject } from '@backstage/types'; import { Draft07 as JSONSchema } from 'json-schema-library'; import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; -interface ReviewStateProps { +/** + * The props for the {@link ReviewState} component. + * @alpha + */ +export type ReviewStateProps = { schemas: ParsedTemplateSchema[]; formState: JsonObject; -} +}; /** - * The ReviewState component used by the Stepper + * The component used by the {@link Stepper} to render the review step. * @alpha */ export const ReviewState = (props: ReviewStateProps) => { diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/index.ts b/plugins/scaffolder-react/src/next/components/ReviewState/index.ts index c94d73ec35..1bde4685d8 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/index.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { ReviewState } from './ReviewState'; +export { ReviewState, type ReviewStateProps } from './ReviewState'; diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 79c6e4fc92..8ff4646d1c 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -54,6 +54,10 @@ const useStyles = makeStyles(theme => ({ }, })); +/** + * The Props for {@link Stepper} component + * @alpha + */ export type StepperProps = { manifest: TemplateParameterSchema; extensions: NextFieldExtensionOptions[]; @@ -67,6 +71,7 @@ export type StepperProps = { const Form = withTheme(require('@rjsf/material-ui-v5').Theme); /** + * The `Stepper` component is the Wizard that is rendered when a user selects a template * @alpha */ export const Stepper = (props: StepperProps) => { diff --git a/plugins/scaffolder-react/src/next/components/Stepper/index.ts b/plugins/scaffolder-react/src/next/components/Stepper/index.ts index 5532563e28..daa47f078e 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/index.ts +++ b/plugins/scaffolder-react/src/next/components/Stepper/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { Stepper } from './Stepper'; +export { Stepper, type StepperProps } from './Stepper'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx index 67b50ba8d6..b1e94b7b8e 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx @@ -83,7 +83,7 @@ const useStyles = makeStyles(theme => ({ })); /** - * The Props for the Template Card component + * The Props for the {@link TemplateCard} component * @alpha */ export interface TemplateCardProps { @@ -92,7 +92,7 @@ export interface TemplateCardProps { } /** - * The Template Card component that is rendered in a list for each template + * The `TemplateCard` component that is rendered in a list for each template * @alpha */ export const TemplateCard = (props: TemplateCardProps) => { diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/index.ts b/plugins/scaffolder-react/src/next/components/TemplateCard/index.ts index 99af0cbb50..529aa938e4 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/index.ts +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/index.ts @@ -13,5 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { TemplateCard } from './TemplateCard'; -export type { TemplateCardProps } from './TemplateCard'; +export { TemplateCard, type TemplateCardProps } from './TemplateCard'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateGroup/TemplateGroup.tsx b/plugins/scaffolder-react/src/next/components/TemplateGroup/TemplateGroup.tsx index b45d0947f4..74d9242041 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateGroup/TemplateGroup.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateGroup/TemplateGroup.tsx @@ -25,6 +25,10 @@ import { Typography } from '@material-ui/core'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { TemplateCardProps, TemplateCard } from '../TemplateCard'; +/** + * The props for the {@link TemplateGroup} component. + * @alpha + */ export interface TemplateGroupProps { templates: TemplateEntityV1beta3[]; title: React.ReactNode; @@ -33,6 +37,10 @@ export interface TemplateGroupProps { }; } +/** + * The `TemplateGroup` component is used to display a group of templates with a title. + * @alpha + */ export const TemplateGroup = (props: TemplateGroupProps) => { const { templates, title, components: { CardComponent } = {} } = props; const titleComponent = diff --git a/plugins/scaffolder-react/src/next/components/TemplateGroup/index.ts b/plugins/scaffolder-react/src/next/components/TemplateGroup/index.ts index 1515e12e45..3fd27c84ed 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateGroup/index.ts +++ b/plugins/scaffolder-react/src/next/components/TemplateGroup/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { TemplateGroup } from './TemplateGroup'; +export { TemplateGroup, type TemplateGroupProps } from './TemplateGroup'; diff --git a/plugins/scaffolder-react/src/next/hooks/index.ts b/plugins/scaffolder-react/src/next/hooks/index.ts new file mode 100644 index 0000000000..ba79bf0e9a --- /dev/null +++ b/plugins/scaffolder-react/src/next/hooks/index.ts @@ -0,0 +1,20 @@ +/* + * 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 { useFormData } from './useFormData'; +export { + useTemplateSchema, + type ParsedTemplateSchema, +} from './useTemplateSchema'; diff --git a/plugins/scaffolder-react/src/next/hooks/useFormData.ts b/plugins/scaffolder-react/src/next/hooks/useFormData.ts index 1500216688..0939630d1d 100644 --- a/plugins/scaffolder-react/src/next/hooks/useFormData.ts +++ b/plugins/scaffolder-react/src/next/hooks/useFormData.ts @@ -17,6 +17,10 @@ import qs from 'qs'; import { useState } from 'react'; +/** + * This hook is used to get the formData from the query string. + * @alpha + */ export const useFormData = () => { return useState>(() => { const query = qs.parse(window.location.search, { diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts index 733c8960b9..2b2e48cf68 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts @@ -19,6 +19,10 @@ import { UiSchema } from '@rjsf/utils'; import { TemplateParameterSchema } from '../../types'; import { extractSchemaFromStep } from '../lib'; +/** + * This is the parsed template schema that is returned from the {@link useTemplateSchema} hook. + * @alpha + */ export interface ParsedTemplateSchema { uiSchema: UiSchema; mergedSchema: JsonObject; @@ -27,6 +31,12 @@ export interface ParsedTemplateSchema { description?: string; } +/** + * This hook will parse the template schema and return the steps with the + * parsed schema and uiSchema. Filtering out any steps or properties that + * are not enabled with feature flags. + * @alpha + */ export const useTemplateSchema = ( manifest: TemplateParameterSchema, ): { steps: ParsedTemplateSchema[] } => { diff --git a/plugins/scaffolder-react/src/next/index.ts b/plugins/scaffolder-react/src/next/index.ts index 29992c26d5..a18649f506 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 './extensions'; export * from './types'; export * from './lib'; +export * from './hooks'; diff --git a/plugins/scaffolder-react/src/next/lib/schema.ts b/plugins/scaffolder-react/src/next/lib/schema.ts index 4c647bc045..e8b819be4b 100644 --- a/plugins/scaffolder-react/src/next/lib/schema.ts +++ b/plugins/scaffolder-react/src/next/lib/schema.ts @@ -99,8 +99,8 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { } /** - * @alpha * Takes a step from a Backstage Template Manifest and converts it to a JSON Schema and UI Schema for rjsf + * @alpha */ export const extractSchemaFromStep = ( inputStep: JsonObject, @@ -112,8 +112,8 @@ export const extractSchemaFromStep = ( }; /** - * @alpha * Creates a field validation object for use in react jsonschema form + * @alpha */ export const createFieldValidation = (): FieldValidation => { const fieldValidation: FieldValidation = { diff --git a/plugins/scaffolder-react/src/routes.ts b/plugins/scaffolder-react/src/routes.ts index 7451a3a943..e8a003cfc1 100644 --- a/plugins/scaffolder-react/src/routes.ts +++ b/plugins/scaffolder-react/src/routes.ts @@ -19,11 +19,13 @@ import { createSubRouteRef, } from '@backstage/core-plugin-api'; +/** @public */ export const registerComponentRouteRef = createExternalRouteRef({ id: 'register-component', optional: true, }); +/** @public */ export const viewTechDocRouteRef = createExternalRouteRef({ id: 'view-techdoc', optional: true, @@ -37,6 +39,7 @@ export const rootRouteRef = createRouteRef({ /** * @deprecated This is the old template route, can be deleted before next major release + * @public */ export const legacySelectedTemplateRouteRef = createSubRouteRef({ id: 'scaffolder/legacy/selected-template', @@ -63,30 +66,35 @@ export const nextSelectedTemplateRouteRef = createSubRouteRef({ path: '/templates/:namespace/:templateName', }); +/** @public */ export const scaffolderTaskRouteRef = createSubRouteRef({ id: 'scaffolder/task', parent: rootRouteRef, path: '/tasks/:taskId', }); +/** @alpha */ export const nextScaffolderTaskRouteRef = createSubRouteRef({ id: 'scaffolder/next/task', parent: nextRouteRef, path: '/tasks/:taskId', }); +/** @public */ export const scaffolderListTaskRouteRef = createSubRouteRef({ id: 'scaffolder/list-tasks', parent: rootRouteRef, path: '/tasks', }); +/** @public */ export const actionsRouteRef = createSubRouteRef({ id: 'scaffolder/actions', parent: rootRouteRef, path: '/actions', }); +/** @public */ export const editRouteRef = createSubRouteRef({ id: 'scaffolder/edit', parent: rootRouteRef, diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index 9f993d2a13..28064721c5 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -87,23 +87,28 @@ import { /** * @alpha + * @deprecated Please import from `@backstage/plugin-scaffolder-react` instead */ const nextRouteRef = nextRouteRefTemp; /** * @alpha + * @deprecated Please import from `@backstage/plugin-scaffolder-react` instead */ const nextSelectedTemplateRouteRef = nextSelectedTemplateRouteRefTemp; /** * @alpha + * @deprecated Please import from `@backstage/plugin-scaffolder-react` instead */ const createNextScaffolderFieldExtension = createNextScaffolderFieldExtensionTemp; /** * @alpha + * @deprecated Please import from `@backstage/plugin-scaffolder-react` instead */ type NextCustomFieldValidator = NextCustomFieldValidatorTemp; /** * @alpha + * @deprecated Please import from `@backstage/plugin-scaffolder-react` instead */ type NextFieldExtensionOptions< TFieldReturnValue = unknown, @@ -111,6 +116,7 @@ type NextFieldExtensionOptions< > = NextFieldExtensionOptionsTemp; /** * @alpha + * @deprecated Please import from `@backstage/plugin-scaffolder-react` instead */ type NextFieldExtensionComponentProps< TFieldReturnValue, @@ -118,6 +124,7 @@ type NextFieldExtensionComponentProps< > = NextFieldExtensionComponentPropsTemp; /** * @alpha + * @deprecated Please import from `@backstage/plugin-scaffolder-react` instead */ type FormProps = FormPropsTemp;