diff --git a/.changeset/silent-gifts-dream.md b/.changeset/silent-gifts-dream.md new file mode 100644 index 0000000000..f939ce8ac2 --- /dev/null +++ b/.changeset/silent-gifts-dream.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Improve performance of typing into scaffolder secret widget diff --git a/plugins/scaffolder-react/src/next/components/SecretWidget/SecretWidget.tsx b/plugins/scaffolder-react/src/next/components/SecretWidget/SecretWidget.tsx index 6b9094c199..25aec236fb 100644 --- a/plugins/scaffolder-react/src/next/components/SecretWidget/SecretWidget.tsx +++ b/plugins/scaffolder-react/src/next/components/SecretWidget/SecretWidget.tsx @@ -17,7 +17,8 @@ import { WidgetProps } from '@rjsf/utils'; import { useTemplateSecrets } from '@backstage/plugin-scaffolder-react'; import TextField from '@material-ui/core/TextField'; -import React from 'react'; +import React, { useMemo, useState } from 'react'; +import debounce from 'lodash/debounce'; /** * Secret Widget for overriding the default password input widget @@ -38,16 +39,31 @@ export const SecretWidget = ( disabled, } = props; + const [localValue, setLocalValue] = useState(secrets[name] ?? ''); + + // Memoize the debounced function so it persists across re-renders + const debouncedSetSecrets = useMemo( + () => + debounce((value: string) => { + setSecrets({ [name]: value }); + }, 300), + [setSecrets, name], + ); + + const handleChange = (e: React.ChangeEvent) => { + const newValue = e.target.value; + setLocalValue(newValue); + onChange(Array(newValue.length).fill('*').join('')); + debouncedSetSecrets(newValue); + }; + return ( { - onChange(Array(e.target.value.length).fill('*').join('')); - setSecrets({ [name]: e.target.value }); - }} - value={secrets[name] ?? ''} + onChange={handleChange} + value={localValue} type="password" autoComplete="off" required={required} diff --git a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx index fa810b9d17..dd88b9986c 100644 --- a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx +++ b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx @@ -22,7 +22,7 @@ import { SecretInput } from './SecretInput'; import { renderInTestApp } from '@backstage/test-utils'; import { Form } from '@backstage/plugin-scaffolder-react/alpha'; import validator from '@rjsf/validator-ajv8'; -import { fireEvent, act } from '@testing-library/react'; +import { fireEvent, act, waitFor } from '@testing-library/react'; describe('', () => { const SecretsComponent = () => { @@ -63,8 +63,15 @@ describe('', () => { fireEvent.change(secretInput, { target: { value: mockSecret } }); }); - const { secrets } = JSON.parse(getByTestId('current-secrets').textContent!); - - expect(secrets.myKey).toBe(mockSecret); + // Wait for the debounced update to occur + await waitFor( + () => { + const { secrets } = JSON.parse( + getByTestId('current-secrets').textContent!, + ); + expect(secrets.myKey).toBe(mockSecret); + }, + { timeout: 500 }, + ); }); });