Merge pull request #26781 from stephenglass/secret-widget-perf
perf: improve performance of scaffolder secret widget
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-react': patch
|
||||
---
|
||||
|
||||
Improve performance of typing into scaffolder secret widget
|
||||
@@ -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<HTMLInputElement>) => {
|
||||
const newValue = e.target.value;
|
||||
setLocalValue(newValue);
|
||||
onChange(Array(newValue.length).fill('*').join(''));
|
||||
debouncedSetSecrets(newValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<TextField
|
||||
id={title}
|
||||
label={title}
|
||||
aria-describedby={title}
|
||||
onChange={e => {
|
||||
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}
|
||||
|
||||
@@ -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('<SecretInput />', () => {
|
||||
const SecretsComponent = () => {
|
||||
@@ -63,8 +63,15 @@ describe('<SecretInput />', () => {
|
||||
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 },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user