From 3c684fdb9c0a39e27f8472bd6b7e0c7eb76a327f Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Tue, 3 Aug 2021 21:34:21 +0200 Subject: [PATCH] fix(catalog-import): migrate to the new react-hook-form version Signed-off-by: Dominik Henneke --- plugins/catalog-import/api-report.md | 8 ++--- .../src/components/ImportStepper/defaults.tsx | 30 ++++++++++------- .../StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx | 23 +++++++------ .../AutocompleteTextField.tsx | 11 +++---- .../PreparePullRequestForm.test.tsx | 8 ++--- .../PreparePullRequestForm.tsx | 5 --- .../StepPrepareCreatePullRequest.test.tsx | 27 ++++++++------- .../StepPrepareCreatePullRequest.tsx | 11 ++++--- .../catalog-import/src/components/helpers.ts | 33 +++++++++++++++++++ 9 files changed, 95 insertions(+), 61 deletions(-) create mode 100644 plugins/catalog-import/src/components/helpers.ts diff --git a/plugins/catalog-import/api-report.md b/plugins/catalog-import/api-report.md index 708ee84fd0..8466749243 100644 --- a/plugins/catalog-import/api-report.md +++ b/plugins/catalog-import/api-report.md @@ -9,7 +9,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { ConfigApi } from '@backstage/core-plugin-api'; -import { Control } from 'react-hook-form'; +import { Controller } from 'react-hook-form'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { EntityName } from '@backstage/catalog-model'; @@ -23,9 +23,8 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { SubmitHandler } from 'react-hook-form'; import { TextFieldProps } from '@material-ui/core/TextField/TextField'; import { UnpackNestedValue } from 'react-hook-form'; -import { UseControllerOptions } from 'react-hook-form'; -import { UseFormMethods } from 'react-hook-form'; -import { UseFormOptions } from 'react-hook-form'; +import { UseFormProps } from 'react-hook-form'; +import { UseFormReturn } from 'react-hook-form'; // Warning: (ae-missing-release-tag) "AnalyzeResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -53,7 +52,6 @@ export const AutocompleteTextField: ({ name, options, required, - control, errors, rules, loading, diff --git a/plugins/catalog-import/src/components/ImportStepper/defaults.tsx b/plugins/catalog-import/src/components/ImportStepper/defaults.tsx index 054fd99895..a5ae352d5a 100644 --- a/plugins/catalog-import/src/components/ImportStepper/defaults.tsx +++ b/plugins/catalog-import/src/components/ImportStepper/defaults.tsx @@ -14,6 +14,7 @@ * limitations under the License. */ +import { ConfigApi } from '@backstage/core-plugin-api'; import { Box, Checkbox, @@ -25,6 +26,7 @@ import { } from '@material-ui/core'; import React from 'react'; import { BackButton } from '../Buttons'; +import { asInputRef } from '../helpers'; import { StepFinishImportLocation } from '../StepFinishImportLocation'; import { StepInitAnalyzeUrl } from '../StepInitAnalyzeUrl'; import { @@ -34,7 +36,6 @@ import { import { StepPrepareSelectLocations } from '../StepPrepareSelectLocations'; import { StepReviewLocation } from '../StepReviewLocation'; import { ImportFlows, ImportState } from '../useImportState'; -import { ConfigApi } from '@backstage/core-plugin-api'; export type StepperProviderOpts = { pullRequest?: { @@ -186,7 +187,7 @@ export function defaultGenerateStepper( defaultBody={body} renderFormFields={({ values, - control, + setValue, errors, groupsLoading, groups, @@ -198,25 +199,31 @@ export function defaultGenerateStepper( @@ -241,7 +249,6 @@ export function defaultGenerateStepper( {!values.useCodeowners && ( { if (value) { - control.setValue('owner', ''); + setValue('owner', ''); } }} /> diff --git a/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx b/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx index f24c67e496..75910db5a2 100644 --- a/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx +++ b/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx @@ -14,13 +14,14 @@ * limitations under the License. */ +import { errorApiRef, useApi } from '@backstage/core-plugin-api'; import { FormHelperText, Grid, TextField } from '@material-ui/core'; import React, { useCallback, useState } from 'react'; import { useForm } from 'react-hook-form'; import { AnalyzeResult, catalogImportApiRef } from '../../api'; import { NextButton } from '../Buttons'; +import { asInputRef } from '../helpers'; import { ImportFlows, PrepareResult } from '../useImportState'; -import { errorApiRef, useApi } from '@backstage/core-plugin-api'; type FormData = { url: string; @@ -123,15 +124,17 @@ export const StepInitAnalyzeUrl = ({ return (
- (typeof value === 'string' && - value.match(/^http[s]?:\/\//) !== null) || - 'Must start with http:// or https://.', - }, - })} + {...asInputRef( + register('url', { + required: true, + validate: { + httpsValidator: (value: any) => + (typeof value === 'string' && + value.match(/^http[s]?:\/\//) !== null) || + 'Must start with http:// or https://.', + }, + }), + )} fullWidth id="url" label="Repository URL" diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx index ed14913dd7..a2da75edd4 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx @@ -18,14 +18,13 @@ import { CircularProgress, TextField } from '@material-ui/core'; import { TextFieldProps } from '@material-ui/core/TextField/TextField'; import { Autocomplete } from '@material-ui/lab'; import React from 'react'; -import { Control, Controller, FieldErrors } from 'react-hook-form'; +import { Controller, FieldErrors } from 'react-hook-form'; type Props = { name: TFieldValue; options: string[]; required?: boolean; - control?: Control>; errors?: FieldErrors>; rules?: React.ComponentProps['rules']; @@ -42,7 +41,6 @@ export const AutocompleteTextField = ({ name, options, required, - control, errors, rules, loading = false, @@ -54,16 +52,17 @@ export const AutocompleteTextField = ({ return ( ( + render={({ field: { onChange } }) => ( , value: string | null) => + onChange(value) + } renderInput={params => ( ', () => { @@ -29,7 +30,7 @@ describe('', () => { defaultValues={{ main: 'default' }} render={({ register }) => ( <> - + {' '} )} @@ -54,10 +55,9 @@ describe('', () => { render={({ register }) => ( <> @@ -85,9 +85,9 @@ describe('', () => { render={({ errors, register }) => ( <> {errors.main && ( diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.tsx index 05c804d4f2..14cd21bae6 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.tsx @@ -55,10 +55,6 @@ export const PreparePullRequestForm = < onSubmit, render, }: Props) => { -<<<<<<< HEAD - const { handleSubmit, watch, control, register, errors } = - useForm({ mode: 'onTouched', defaultValues }); -======= const { handleSubmit, watch, @@ -66,7 +62,6 @@ export const PreparePullRequestForm = < register, formState: { errors }, } = useForm({ mode: 'onTouched', defaultValues }); ->>>>>>> chore: fixing up some migrations return ( diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx index d6014b329c..08b8177291 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx @@ -20,6 +20,7 @@ import { act, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; import { AnalyzeResult, catalogImportApiRef } from '../../api'; +import { asInputRef } from '../helpers'; import { generateEntities, StepPrepareCreatePullRequest, @@ -91,10 +92,10 @@ describe('', () => { renderFormFields={({ register }) => { return ( <> - - - - + + + + ); }} @@ -132,19 +133,17 @@ describe('', () => { renderFormFields={({ register }) => { return ( <> - - + + ); @@ -222,10 +221,10 @@ spec: renderFormFields={({ register }) => { return ( <> - - - - + + + + ); }} diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx index 41db6f600c..0f298c7202 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx @@ -15,6 +15,7 @@ */ import { Entity } from '@backstage/catalog-model'; +import { useApi } from '@backstage/core-plugin-api'; import { catalogApiRef, formatEntityRefTitle, @@ -22,7 +23,7 @@ import { import { Box, FormHelperText, Grid, Typography } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import React, { useCallback, useState } from 'react'; -import { UnpackNestedValue, UseFormMethods } from 'react-hook-form'; +import { FieldErrors, UnpackNestedValue, UseFormReturn } from 'react-hook-form'; import { useAsync } from 'react-use'; import YAML from 'yaml'; import { AnalyzeResult, catalogImportApiRef } from '../../api'; @@ -32,7 +33,6 @@ import { PrepareResult } from '../useImportState'; import { PreparePullRequestForm } from './PreparePullRequestForm'; import { PreviewCatalogInfoComponent } from './PreviewCatalogInfoComponent'; import { PreviewPullRequestComponent } from './PreviewPullRequestComponent'; -import { useApi } from '@backstage/core-plugin-api'; const useStyles = makeStyles(theme => ({ previewCard: { @@ -63,7 +63,8 @@ type Props = { defaultBody: string; renderFormFields: ( - props: Pick, 'errors' | 'register' | 'control'> & { + props: Pick, 'register' | 'setValue'> & { + errors: FieldErrors; values: UnpackNestedValue; groups: string[]; groupsLoading: boolean; @@ -192,13 +193,13 @@ export const StepPrepareCreatePullRequest = ({ analyzeResult.generatedEntities[0]?.metadata?.name || '', useCodeowners: false, }} - render={({ values, errors, control, register }) => ( + render={({ values, errors, register, setValue }) => ( <> {renderFormFields({ values, errors, register, - control, + setValue, groups: groups ?? [], groupsLoading, })} diff --git a/plugins/catalog-import/src/components/helpers.ts b/plugins/catalog-import/src/components/helpers.ts new file mode 100644 index 0000000000..4240186459 --- /dev/null +++ b/plugins/catalog-import/src/components/helpers.ts @@ -0,0 +1,33 @@ +/* + * 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 { UseFormRegisterReturn } from 'react-hook-form'; + +/** + * A helper that converts the result of a render('name', opts) to make it compatible with material-ui. + * + * See also https://github.com/react-hook-form/react-hook-form/issues/4629#issuecomment-815840872 + * TODO: remove when updating to material-ui v5 (https://github.com/mui-org/material-ui/pull/23174) + * + * @param renderResult - the result of a render('name', opts) + */ +export function asInputRef(renderResult: UseFormRegisterReturn) { + const { ref, ...rest } = renderResult; + return { + inputRef: ref, + ...rest, + }; +}