Merge pull request #28945 from Nikunj0601/feat/ui-disabled-picker
feature: Allow passing `disabled` attribute to all pickers
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': minor
|
||||
---
|
||||
|
||||
Allowed passing `ui:disabled` for disabling the input field of all the pickers.
|
||||
@@ -261,6 +261,73 @@ describe('<EntityPicker />', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ui:disabled EntityPicker', () => {
|
||||
beforeEach(() => {
|
||||
uiSchema = {
|
||||
'ui:options': {
|
||||
catalogFilter: [
|
||||
{
|
||||
kind: ['Group'],
|
||||
'metadata.name': 'test-entity',
|
||||
},
|
||||
{
|
||||
kind: ['User'],
|
||||
'metadata.name': 'test-entity',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
props = {
|
||||
onChange,
|
||||
schema,
|
||||
required: true,
|
||||
uiSchema,
|
||||
rawErrors,
|
||||
formData,
|
||||
} as unknown as FieldProps<any>;
|
||||
|
||||
catalogApi.getEntities.mockResolvedValue({ items: entities });
|
||||
});
|
||||
it('Prevents user from modifying input when ui:disabled is true', async () => {
|
||||
props.uiSchema = { 'ui:disabled': true };
|
||||
props.formData = 'component:default/myentity';
|
||||
|
||||
await renderInTestApp(
|
||||
<Wrapper>
|
||||
<EntityPicker {...props} />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
// Expect input to be disabled
|
||||
expect(input).toBeDisabled();
|
||||
expect(input).toHaveValue('component:default/myentity');
|
||||
});
|
||||
|
||||
it('Allows user to edit when ui:disabled is false', async () => {
|
||||
props.uiSchema = { 'ui:disabled': false };
|
||||
props.formData = 'component:default/myentity';
|
||||
|
||||
await renderInTestApp(
|
||||
<Wrapper>
|
||||
<EntityPicker {...props} />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
expect(input).not.toBeDisabled();
|
||||
|
||||
fireEvent.change(input, {
|
||||
target: { value: 'component:default/mynewentity' },
|
||||
});
|
||||
fireEvent.blur(input);
|
||||
|
||||
expect(input).toHaveValue('component:default/mynewentity');
|
||||
expect(onChange).toHaveBeenCalledWith('component:default/mynewentity');
|
||||
});
|
||||
});
|
||||
|
||||
describe('catalogFilter should take precedence over allowedKinds', () => {
|
||||
beforeEach(() => {
|
||||
uiSchema = {
|
||||
|
||||
@@ -73,6 +73,7 @@ export const EntityPicker = (props: EntityPickerProps) => {
|
||||
const defaultKind = uiSchema['ui:options']?.defaultKind;
|
||||
const defaultNamespace =
|
||||
uiSchema['ui:options']?.defaultNamespace || undefined;
|
||||
const isDisabled = uiSchema?.['ui:disabled'] ?? false;
|
||||
|
||||
const catalogApi = useApi(catalogApiRef);
|
||||
const entityPresentationApi = useApi(entityPresentationApiRef);
|
||||
@@ -185,9 +186,10 @@ export const EntityPicker = (props: EntityPickerProps) => {
|
||||
>
|
||||
<Autocomplete
|
||||
disabled={
|
||||
required &&
|
||||
!allowArbitraryValues &&
|
||||
entities?.catalogEntities.length === 1
|
||||
isDisabled ||
|
||||
(required &&
|
||||
!allowArbitraryValues &&
|
||||
entities?.catalogEntities.length === 1)
|
||||
}
|
||||
id={idSchema?.$id}
|
||||
value={selectedEntity}
|
||||
@@ -212,6 +214,7 @@ export const EntityPicker = (props: EntityPickerProps) => {
|
||||
FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}
|
||||
variant="outlined"
|
||||
required={required}
|
||||
disabled={isDisabled}
|
||||
InputProps={params.InputProps}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -45,6 +45,8 @@ export const EntityTagsPicker = (props: EntityTagsPickerProps) => {
|
||||
const kinds = uiSchema['ui:options']?.kinds;
|
||||
const showCounts = uiSchema['ui:options']?.showCounts;
|
||||
const helperText = uiSchema['ui:options']?.helperText;
|
||||
const isDisabled = uiSchema?.['ui:disabled'] ?? false;
|
||||
|
||||
const { t } = useTranslationRef(scaffolderTranslationRef);
|
||||
|
||||
const { loading, value: existingTags } = useAsync(async () => {
|
||||
@@ -101,6 +103,7 @@ export const EntityTagsPicker = (props: EntityTagsPickerProps) => {
|
||||
freeSolo
|
||||
filterSelectedOptions
|
||||
onChange={setTags}
|
||||
disabled={isDisabled}
|
||||
value={formData || []}
|
||||
inputValue={inputValue}
|
||||
loading={loading}
|
||||
@@ -113,6 +116,7 @@ export const EntityTagsPicker = (props: EntityTagsPickerProps) => {
|
||||
<TextField
|
||||
{...params}
|
||||
label={t('fields.entityTagsPicker.title')}
|
||||
disabled={isDisabled}
|
||||
onChange={e => setInputValue(e.target.value)}
|
||||
error={inputError}
|
||||
helperText={helperText ?? t('fields.entityTagsPicker.description')}
|
||||
|
||||
@@ -407,6 +407,38 @@ describe('<MultiEntityPicker />', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ui:disabled MultiEntityPicker', () => {
|
||||
beforeEach(() => {
|
||||
uiSchema = {
|
||||
'ui:options': {
|
||||
allowArbitraryValues: true,
|
||||
},
|
||||
'ui:disabled': true,
|
||||
};
|
||||
props = {
|
||||
onChange,
|
||||
schema,
|
||||
required: true,
|
||||
uiSchema,
|
||||
rawErrors,
|
||||
formData,
|
||||
} as unknown as FieldProps<any>;
|
||||
|
||||
catalogApi.getEntities.mockResolvedValue({ items: entities });
|
||||
});
|
||||
it('Prevents user from modifying input when ui:disabled is true', async () => {
|
||||
props.formData = ['component/default:myentity'];
|
||||
await renderInTestApp(
|
||||
<Wrapper>
|
||||
<MultiEntityPicker {...props} />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
expect(input).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Optional MultiEntityPicker', () => {
|
||||
beforeEach(() => {
|
||||
uiSchema = {
|
||||
|
||||
@@ -61,10 +61,12 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => {
|
||||
formData,
|
||||
idSchema,
|
||||
} = props;
|
||||
|
||||
const catalogFilter = buildCatalogFilter(uiSchema);
|
||||
const defaultKind = uiSchema['ui:options']?.defaultKind;
|
||||
const defaultNamespace =
|
||||
uiSchema['ui:options']?.defaultNamespace || undefined;
|
||||
const isDisabled = uiSchema?.['ui:disabled'] ?? false;
|
||||
const [noOfItemsSelected, setNoOfItemsSelected] = useState(0);
|
||||
|
||||
const catalogApi = useApi(catalogApiRef);
|
||||
@@ -151,7 +153,10 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => {
|
||||
multiple
|
||||
filterSelectedOptions
|
||||
disabled={
|
||||
required && !allowArbitraryValues && entities?.entities?.length === 1
|
||||
isDisabled ||
|
||||
(required &&
|
||||
!allowArbitraryValues &&
|
||||
entities?.entities?.length === 1)
|
||||
}
|
||||
id={idSchema?.$id}
|
||||
defaultValue={formData}
|
||||
@@ -175,6 +180,7 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => {
|
||||
<TextField
|
||||
{...params}
|
||||
label={title}
|
||||
disabled={isDisabled}
|
||||
margin="dense"
|
||||
helperText={description}
|
||||
FormHelperTextProps={{
|
||||
|
||||
@@ -26,6 +26,7 @@ import { ScaffolderRJSFFieldProps as FieldProps } from '@backstage/plugin-scaffo
|
||||
import React from 'react';
|
||||
import { OwnerPicker } from './OwnerPicker';
|
||||
import { DefaultEntityPresentationApi } from '@backstage/plugin-catalog';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
|
||||
const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
|
||||
apiVersion: 'backstage.io/v1beta1',
|
||||
@@ -114,6 +115,73 @@ describe('<OwnerPicker />', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ui:disabled OwnerPicker', () => {
|
||||
beforeEach(() => {
|
||||
uiSchema = {
|
||||
'ui:options': {
|
||||
catalogFilter: [
|
||||
{
|
||||
kind: ['Group'],
|
||||
'metadata.name': 'test-entity',
|
||||
},
|
||||
{
|
||||
kind: ['User'],
|
||||
'metadata.name': 'test-entity',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
props = {
|
||||
onChange,
|
||||
schema,
|
||||
required: true,
|
||||
uiSchema,
|
||||
rawErrors,
|
||||
formData,
|
||||
} as unknown as FieldProps<any>;
|
||||
|
||||
catalogApi.getEntities.mockResolvedValue({ items: entities });
|
||||
});
|
||||
it('Prevents user from modifying input when ui:disabled is true', async () => {
|
||||
props.uiSchema = { 'ui:disabled': true };
|
||||
props.formData = 'group:default/myentity';
|
||||
|
||||
await renderInTestApp(
|
||||
<Wrapper>
|
||||
<OwnerPicker {...props} />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
// Expect input to be disabled
|
||||
expect(input).toBeDisabled();
|
||||
expect(input).toHaveValue('group:default/myentity');
|
||||
});
|
||||
|
||||
it('Allows user to edit when ui:disabled is false', async () => {
|
||||
props.uiSchema = { 'ui:disabled': false };
|
||||
props.formData = 'group:default/myentity';
|
||||
|
||||
await renderInTestApp(
|
||||
<Wrapper>
|
||||
<OwnerPicker {...props} />
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
expect(input).not.toBeDisabled();
|
||||
|
||||
fireEvent.change(input, {
|
||||
target: { value: 'group:default/mynewentity' },
|
||||
});
|
||||
fireEvent.blur(input);
|
||||
|
||||
expect(input).toHaveValue('group:default/mynewentity');
|
||||
expect(onChange).toHaveBeenCalledWith('group:default/mynewentity');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with allowedKinds', () => {
|
||||
beforeEach(() => {
|
||||
uiSchema = { 'ui:options': { allowedKinds: ['User'] } };
|
||||
|
||||
+26
-1
@@ -20,7 +20,13 @@ import {
|
||||
scaffolderApiRef,
|
||||
} from '@backstage/plugin-scaffolder-react';
|
||||
import { BitbucketRepoBranchPicker } from './BitbucketRepoBranchPicker';
|
||||
import { act, fireEvent, render, waitFor } from '@testing-library/react';
|
||||
import {
|
||||
act,
|
||||
fireEvent,
|
||||
render,
|
||||
waitFor,
|
||||
screen,
|
||||
} from '@testing-library/react';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
@@ -44,6 +50,25 @@ describe('BitbucketRepoBranchPicker', () => {
|
||||
expect(getByRole('textbox')).toHaveValue('main');
|
||||
});
|
||||
|
||||
it('input field disabled', () => {
|
||||
render(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<BitbucketRepoBranchPicker
|
||||
onChange={jest.fn()}
|
||||
isDisabled
|
||||
state={{ branch: 'main' }}
|
||||
rawErrors={[]}
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
// Expect input to be disabled
|
||||
expect(input).toBeDisabled();
|
||||
expect(input).toHaveValue('main');
|
||||
});
|
||||
|
||||
it('calls onChange when the input field changes', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
|
||||
+8
-1
@@ -36,6 +36,7 @@ export const BitbucketRepoBranchPicker = ({
|
||||
state,
|
||||
rawErrors,
|
||||
accessToken,
|
||||
isDisabled,
|
||||
required,
|
||||
}: BaseRepoBranchPickerProps<{
|
||||
accessToken?: string;
|
||||
@@ -86,9 +87,15 @@ export const BitbucketRepoBranchPicker = ({
|
||||
onChange={(_, newValue) => {
|
||||
onChange({ branch: newValue || '' });
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
options={availableBranches}
|
||||
renderInput={params => (
|
||||
<TextField {...params} label="Branch" required={required} />
|
||||
<TextField
|
||||
{...params}
|
||||
label="Branch"
|
||||
disabled={isDisabled}
|
||||
required={required}
|
||||
/>
|
||||
)}
|
||||
freeSolo
|
||||
autoSelect
|
||||
|
||||
+18
-1
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
|
||||
import { DefaultRepoBranchPicker } from './DefaultRepoBranchPicker';
|
||||
|
||||
@@ -33,6 +33,23 @@ describe('DefaultRepoBranchPicker', () => {
|
||||
expect(getByRole('textbox')).toHaveValue('main');
|
||||
});
|
||||
|
||||
it('input field disabled', () => {
|
||||
render(
|
||||
<DefaultRepoBranchPicker
|
||||
onChange={jest.fn()}
|
||||
isDisabled
|
||||
state={{ branch: 'main' }}
|
||||
rawErrors={[]}
|
||||
/>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
// Expect input to be disabled
|
||||
expect(input).toBeDisabled();
|
||||
expect(input).toHaveValue('main');
|
||||
});
|
||||
|
||||
it('calls onChange when the input field changes', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ export const DefaultRepoBranchPicker = ({
|
||||
onChange,
|
||||
state,
|
||||
rawErrors,
|
||||
isDisabled,
|
||||
required,
|
||||
}: BaseRepoBranchPickerProps) => {
|
||||
const { branch } = state;
|
||||
@@ -45,6 +46,7 @@ export const DefaultRepoBranchPicker = ({
|
||||
<TextField
|
||||
id="branchInput"
|
||||
label="Branch"
|
||||
disabled={isDisabled}
|
||||
onChange={e => onChange({ branch: e.target.value })}
|
||||
value={branch}
|
||||
/>
|
||||
|
||||
+26
-1
@@ -20,7 +20,13 @@ import {
|
||||
scaffolderApiRef,
|
||||
} from '@backstage/plugin-scaffolder-react';
|
||||
import { GitHubRepoBranchPicker } from './GitHubRepoBranchPicker';
|
||||
import { act, fireEvent, render, waitFor } from '@testing-library/react';
|
||||
import {
|
||||
act,
|
||||
fireEvent,
|
||||
render,
|
||||
waitFor,
|
||||
screen,
|
||||
} from '@testing-library/react';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
@@ -44,6 +50,25 @@ describe('GitHubRepoBranchPicker', () => {
|
||||
expect(getByRole('textbox')).toHaveValue('main');
|
||||
});
|
||||
|
||||
it('input field disabled', () => {
|
||||
render(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<GitHubRepoBranchPicker
|
||||
onChange={jest.fn()}
|
||||
isDisabled
|
||||
state={{ branch: 'main' }}
|
||||
rawErrors={[]}
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
// Expect input to be disabled
|
||||
expect(input).toBeDisabled();
|
||||
expect(input).toHaveValue('main');
|
||||
});
|
||||
|
||||
it('calls onChange when the input field changes', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
|
||||
+8
-1
@@ -36,6 +36,7 @@ export const GitHubRepoBranchPicker = ({
|
||||
state,
|
||||
rawErrors,
|
||||
accessToken,
|
||||
isDisabled,
|
||||
required,
|
||||
}: BaseRepoBranchPickerProps<{
|
||||
accessToken?: string;
|
||||
@@ -86,9 +87,15 @@ export const GitHubRepoBranchPicker = ({
|
||||
onChange={(_, newValue) => {
|
||||
onChange({ branch: newValue || '' });
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
options={availableBranches}
|
||||
renderInput={params => (
|
||||
<TextField {...params} label="Branch" required={required} />
|
||||
<TextField
|
||||
{...params}
|
||||
label="Branch"
|
||||
disabled={isDisabled}
|
||||
required={required}
|
||||
/>
|
||||
)}
|
||||
freeSolo
|
||||
autoSelect
|
||||
|
||||
+35
-1
@@ -31,7 +31,7 @@ import {
|
||||
useTemplateSecrets,
|
||||
ScaffolderRJSFField,
|
||||
} from '@backstage/plugin-scaffolder-react';
|
||||
import { act, fireEvent } from '@testing-library/react';
|
||||
import { act, fireEvent, screen } from '@testing-library/react';
|
||||
import { RepoBranchPicker } from './RepoBranchPicker';
|
||||
|
||||
describe('RepoBranchPicker', () => {
|
||||
@@ -92,6 +92,40 @@ describe('RepoBranchPicker', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should disable the picker when ui:disabled', async () => {
|
||||
const onSubmit = jest.fn();
|
||||
|
||||
await renderInTestApp(
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
[scmIntegrationsApiRef, mockIntegrationsApi],
|
||||
[scmAuthApiRef, {}],
|
||||
[scaffolderApiRef, {}],
|
||||
]}
|
||||
>
|
||||
<SecretsContextProvider>
|
||||
<Form
|
||||
validator={validator}
|
||||
schema={{ type: 'string' }}
|
||||
uiSchema={{ 'ui:field': 'RepoBranchPicker', 'ui:disabled': true }}
|
||||
fields={{
|
||||
RepoBranchPicker:
|
||||
RepoBranchPicker as ScaffolderRJSFField<string>,
|
||||
}}
|
||||
onSubmit={onSubmit}
|
||||
formContext={{
|
||||
formData: { repoUrl: 'github.com' },
|
||||
}}
|
||||
/>
|
||||
</SecretsContextProvider>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
expect(input).toBeDisabled();
|
||||
});
|
||||
|
||||
it('should render properly with title and description', async () => {
|
||||
const { getByText } = await renderInTestApp(
|
||||
<TestApiProvider
|
||||
|
||||
@@ -133,6 +133,7 @@ export const RepoBranchPicker = (props: RepoBranchPickerProps) => {
|
||||
uiSchema?.['ui:options']?.requestUserCredentials?.secretsKey &&
|
||||
secrets[uiSchema['ui:options'].requestUserCredentials.secretsKey]
|
||||
}
|
||||
isDisabled={uiSchema?.['ui:disabled'] ?? false}
|
||||
required={required}
|
||||
/>
|
||||
);
|
||||
@@ -146,6 +147,7 @@ export const RepoBranchPicker = (props: RepoBranchPickerProps) => {
|
||||
uiSchema?.['ui:options']?.requestUserCredentials?.secretsKey &&
|
||||
secrets[uiSchema['ui:options'].requestUserCredentials.secretsKey]
|
||||
}
|
||||
isDisabled={uiSchema?.['ui:disabled'] ?? false}
|
||||
required={required}
|
||||
/>
|
||||
);
|
||||
@@ -155,6 +157,7 @@ export const RepoBranchPicker = (props: RepoBranchPickerProps) => {
|
||||
onChange={updateLocalState}
|
||||
state={state}
|
||||
rawErrors={rawErrors}
|
||||
isDisabled={uiSchema?.['ui:disabled'] ?? false}
|
||||
required={required}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -26,5 +26,6 @@ export type BaseRepoBranchPickerProps<T extends {} = {}> = T & {
|
||||
onChange: (state: RepoBranchPickerState) => void;
|
||||
state: RepoBranchPickerState;
|
||||
rawErrors: string[];
|
||||
isDisabled?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
|
||||
@@ -30,6 +30,23 @@ describe('AzureRepoPicker', () => {
|
||||
expect(allInputs).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('disables input fields when isDisabled is true', async () => {
|
||||
const { getAllByRole } = await renderInTestApp(
|
||||
<AzureRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{}}
|
||||
isDisabled
|
||||
/>,
|
||||
);
|
||||
|
||||
const allInputs = getAllByRole('textbox');
|
||||
|
||||
allInputs.forEach(input => {
|
||||
expect(input).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('org field', () => {
|
||||
it('calls onChange when the organisation changes', async () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
@@ -35,6 +35,7 @@ export const AzureRepoPicker = (
|
||||
rawErrors,
|
||||
state,
|
||||
onChange,
|
||||
isDisabled,
|
||||
} = props;
|
||||
const { t } = useTranslationRef(scaffolderTranslationRef);
|
||||
|
||||
@@ -63,7 +64,7 @@ export const AzureRepoPicker = (
|
||||
onChange={s =>
|
||||
onChange({ organization: String(Array.isArray(s) ? s[0] : s) })
|
||||
}
|
||||
disabled={allowedOrganizations.length === 1}
|
||||
disabled={isDisabled || allowedOrganizations.length === 1}
|
||||
selected={organization}
|
||||
items={organizationItems}
|
||||
/>
|
||||
@@ -77,6 +78,7 @@ export const AzureRepoPicker = (
|
||||
label={t('fields.azureRepoPicker.organization.title')}
|
||||
onChange={e => onChange({ organization: e.target.value })}
|
||||
helperText={t('fields.azureRepoPicker.organization.description')}
|
||||
disabled={isDisabled}
|
||||
value={organization}
|
||||
/>
|
||||
)}
|
||||
@@ -94,7 +96,7 @@ export const AzureRepoPicker = (
|
||||
onChange={s =>
|
||||
onChange({ project: String(Array.isArray(s) ? s[0] : s) })
|
||||
}
|
||||
disabled={allowedProject.length === 1}
|
||||
disabled={isDisabled || allowedProject.length === 1}
|
||||
selected={project}
|
||||
items={projectItems}
|
||||
/>
|
||||
@@ -108,6 +110,7 @@ export const AzureRepoPicker = (
|
||||
label={t('fields.azureRepoPicker.project.title')}
|
||||
onChange={e => onChange({ project: e.target.value })}
|
||||
value={project}
|
||||
disabled={isDisabled}
|
||||
helperText={t('fields.azureRepoPicker.project.description')}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -271,4 +271,50 @@ describe('BitbucketRepoPicker', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('BitbucketRepoPicker - isDisabled', () => {
|
||||
it('disables workspace and project inputs when isDisabled is true', async () => {
|
||||
const { getAllByRole } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<BitbucketRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{
|
||||
host: 'bitbucket.org',
|
||||
workspace: 'testWorkspace',
|
||||
project: 'testProject',
|
||||
}}
|
||||
isDisabled
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const inputs = getAllByRole('textbox');
|
||||
expect(inputs).toHaveLength(2);
|
||||
expect(inputs[0]).toBeDisabled();
|
||||
expect(inputs[1]).toBeDisabled();
|
||||
});
|
||||
|
||||
it('does not disable workspace and project inputs when isDisabled is false', async () => {
|
||||
const { getAllByRole } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<BitbucketRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{
|
||||
host: 'bitbucket.org',
|
||||
workspace: 'testWorkspace',
|
||||
project: 'testProject',
|
||||
}}
|
||||
isDisabled={false}
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const inputs = getAllByRole('textbox');
|
||||
expect(inputs).toHaveLength(2);
|
||||
expect(inputs[0]).not.toBeDisabled();
|
||||
expect(inputs[1]).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,6 +49,7 @@ export const BitbucketRepoPicker = (
|
||||
rawErrors,
|
||||
state,
|
||||
accessToken,
|
||||
isDisabled,
|
||||
} = props;
|
||||
const { t } = useTranslationRef(scaffolderTranslationRef);
|
||||
|
||||
@@ -176,7 +177,7 @@ export const BitbucketRepoPicker = (
|
||||
onChange={s =>
|
||||
onChange({ workspace: String(Array.isArray(s) ? s[0] : s) })
|
||||
}
|
||||
disabled={allowedOwners.length === 1}
|
||||
disabled={isDisabled || allowedOwners.length === 1}
|
||||
selected={workspace}
|
||||
items={ownerItems}
|
||||
/>
|
||||
@@ -191,9 +192,11 @@ export const BitbucketRepoPicker = (
|
||||
<TextField
|
||||
{...params}
|
||||
label={t('fields.bitbucketRepoPicker.workspaces.inputTitle')}
|
||||
disabled={isDisabled}
|
||||
required
|
||||
/>
|
||||
)}
|
||||
disabled={isDisabled}
|
||||
freeSolo
|
||||
autoSelect
|
||||
/>
|
||||
@@ -215,7 +218,7 @@ export const BitbucketRepoPicker = (
|
||||
onChange={s =>
|
||||
onChange({ project: String(Array.isArray(s) ? s[0] : s) })
|
||||
}
|
||||
disabled={allowedProjects.length === 1}
|
||||
disabled={isDisabled || allowedProjects.length === 1}
|
||||
selected={project}
|
||||
items={projectItems}
|
||||
/>
|
||||
@@ -226,10 +229,12 @@ export const BitbucketRepoPicker = (
|
||||
onChange({ project: newValue || '' });
|
||||
}}
|
||||
options={availableProjects}
|
||||
disabled={isDisabled}
|
||||
renderInput={params => (
|
||||
<TextField
|
||||
{...params}
|
||||
label={t('fields.bitbucketRepoPicker.project.inputTitle')}
|
||||
disabled={isDisabled}
|
||||
required
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -20,6 +20,23 @@ import { fireEvent } from '@testing-library/react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
|
||||
describe('GerritRepoPicker', () => {
|
||||
it('disables input fields when isDisabled is true', async () => {
|
||||
const { getAllByRole } = await renderInTestApp(
|
||||
<GerritRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{}}
|
||||
isDisabled
|
||||
/>,
|
||||
);
|
||||
|
||||
const allInputs = getAllByRole('textbox');
|
||||
|
||||
allInputs.forEach(input => {
|
||||
expect(input).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('owner input field', () => {
|
||||
it('calls onChange when the owner input changes', async () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
@@ -21,7 +21,7 @@ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
||||
import { scaffolderTranslationRef } from '../../../translation';
|
||||
|
||||
export const GerritRepoPicker = (props: BaseRepoUrlPickerProps) => {
|
||||
const { onChange, rawErrors, state } = props;
|
||||
const { onChange, rawErrors, state, isDisabled } = props;
|
||||
const { t } = useTranslationRef(scaffolderTranslationRef);
|
||||
const { workspace, owner } = state;
|
||||
return (
|
||||
@@ -32,6 +32,7 @@ export const GerritRepoPicker = (props: BaseRepoUrlPickerProps) => {
|
||||
label={t('fields.gerritRepoPicker.owner.title')}
|
||||
onChange={e => onChange({ owner: e.target.value })}
|
||||
helperText={t('fields.gerritRepoPicker.owner.description')}
|
||||
disabled={isDisabled}
|
||||
value={owner}
|
||||
/>
|
||||
</FormControl>
|
||||
@@ -44,6 +45,7 @@ export const GerritRepoPicker = (props: BaseRepoUrlPickerProps) => {
|
||||
id="parentInput"
|
||||
label={t('fields.gerritRepoPicker.parent.title')}
|
||||
onChange={e => onChange({ workspace: e.target.value })}
|
||||
disabled={isDisabled}
|
||||
value={workspace}
|
||||
helperText={t('fields.gerritRepoPicker.parent.description')}
|
||||
/>
|
||||
|
||||
@@ -20,6 +20,22 @@ import { fireEvent } from '@testing-library/react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
|
||||
describe('GiteaRepoPicker', () => {
|
||||
it('disables input fields when isDisabled is true', async () => {
|
||||
const { getAllByRole } = await renderInTestApp(
|
||||
<GiteaRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{}}
|
||||
isDisabled
|
||||
/>,
|
||||
);
|
||||
|
||||
const allInputs = getAllByRole('textbox');
|
||||
|
||||
allInputs.forEach(input => {
|
||||
expect(input).toBeDisabled();
|
||||
});
|
||||
});
|
||||
describe('owner input field', () => {
|
||||
it('calls onChange when the owner input changes', async () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
@@ -28,7 +28,7 @@ export const GiteaRepoPicker = (
|
||||
allowedRepos?: string[];
|
||||
}>,
|
||||
) => {
|
||||
const { allowedOwners = [], state, onChange, rawErrors } = props;
|
||||
const { allowedOwners = [], state, onChange, rawErrors, isDisabled } = props;
|
||||
const { t } = useTranslationRef(scaffolderTranslationRef);
|
||||
const ownerItems: SelectItem[] = allowedOwners
|
||||
? allowedOwners.map(i => ({ label: i, value: i }))
|
||||
@@ -55,7 +55,7 @@ export const GiteaRepoPicker = (
|
||||
),
|
||||
})
|
||||
}
|
||||
disabled={allowedOwners.length === 1}
|
||||
disabled={isDisabled || allowedOwners.length === 1}
|
||||
selected={owner}
|
||||
items={ownerItems}
|
||||
/>
|
||||
@@ -70,6 +70,7 @@ export const GiteaRepoPicker = (
|
||||
label={t('fields.giteaRepoPicker.owner.inputTitle')}
|
||||
onChange={e => onChange({ owner: e.target.value })}
|
||||
helperText={t('fields.giteaRepoPicker.owner.description')}
|
||||
disabled={isDisabled}
|
||||
value={owner}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -170,4 +170,38 @@ describe('GithubRepoPicker', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GithubRepoPicker - isDisabled', () => {
|
||||
it('disables all inputs when isDisabled is true', async () => {
|
||||
const { getByLabelText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<GithubRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{ repoName: 'repo' }}
|
||||
isDisabled
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const ownerInput = getByLabelText(/owner/i);
|
||||
expect(ownerInput).toBeDisabled();
|
||||
});
|
||||
|
||||
it('does not disable inputs when isDisabled is false', async () => {
|
||||
const { getByLabelText } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<GithubRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{ repoName: 'repo' }}
|
||||
isDisabled={false}
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const ownerInput = getByLabelText(/owner/i);
|
||||
expect(ownerInput).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -34,7 +34,14 @@ export const GithubRepoPicker = (
|
||||
accessToken?: string;
|
||||
}>,
|
||||
) => {
|
||||
const { allowedOwners = [], rawErrors, state, onChange, accessToken } = props;
|
||||
const {
|
||||
allowedOwners = [],
|
||||
rawErrors,
|
||||
state,
|
||||
onChange,
|
||||
accessToken,
|
||||
isDisabled,
|
||||
} = props;
|
||||
const { t } = useTranslationRef(scaffolderTranslationRef);
|
||||
const ownerItems: SelectItem[] = allowedOwners
|
||||
? allowedOwners.map(i => ({ label: i, value: i }))
|
||||
@@ -110,7 +117,7 @@ export const GithubRepoPicker = (
|
||||
onChange={s =>
|
||||
onChange({ owner: String(Array.isArray(s) ? s[0] : s) })
|
||||
}
|
||||
disabled={allowedOwners.length === 1}
|
||||
disabled={isDisabled || allowedOwners.length === 1}
|
||||
selected={owner}
|
||||
items={ownerItems}
|
||||
/>
|
||||
@@ -126,10 +133,12 @@ export const GithubRepoPicker = (
|
||||
<TextField
|
||||
{...params}
|
||||
label={t('fields.githubRepoPicker.owner.inputTitle')}
|
||||
disabled={isDisabled}
|
||||
required
|
||||
/>
|
||||
)}
|
||||
freeSolo
|
||||
disabled={isDisabled}
|
||||
autoSelect
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -31,6 +31,73 @@ describe('GitlabRepoPicker', () => {
|
||||
}),
|
||||
),
|
||||
};
|
||||
|
||||
describe('GitlabRepoPicker - isDisabled', () => {
|
||||
it('disables owner input when isDisabled is true', async () => {
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<GitlabRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{ repoName: 'repo' }}
|
||||
isDisabled
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
expect(getByRole('textbox')).toBeDisabled();
|
||||
});
|
||||
|
||||
it('does not disable owner input when isDisabled is false', async () => {
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<GitlabRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{ repoName: 'repo' }}
|
||||
isDisabled={false}
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
expect(getByRole('textbox')).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('disables select input when allowedOwners are provided and isDisabled is true', async () => {
|
||||
const allowedOwners = ['owner1', 'owner2'];
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<GitlabRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{ repoName: 'repo' }}
|
||||
allowedOwners={allowedOwners}
|
||||
isDisabled
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
expect(getByRole('combobox')).toBeDisabled();
|
||||
});
|
||||
|
||||
it('does not disable select input when allowedOwners are provided and isDisabled is false', async () => {
|
||||
const allowedOwners = ['owner1', 'owner2'];
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, scaffolderApiMock]]}>
|
||||
<GitlabRepoPicker
|
||||
onChange={jest.fn()}
|
||||
rawErrors={[]}
|
||||
state={{ repoName: 'repo' }}
|
||||
allowedOwners={allowedOwners}
|
||||
isDisabled={false}
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
expect(getByRole('combobox')).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('owner field', () => {
|
||||
it('renders a select if there is a list of allowed owners', async () => {
|
||||
const allowedOwners = ['owner1', 'owner2'];
|
||||
|
||||
@@ -33,7 +33,14 @@ export const GitlabRepoPicker = (
|
||||
accessToken?: string;
|
||||
}>,
|
||||
) => {
|
||||
const { allowedOwners = [], state, onChange, rawErrors, accessToken } = props;
|
||||
const {
|
||||
allowedOwners = [],
|
||||
state,
|
||||
onChange,
|
||||
rawErrors,
|
||||
accessToken,
|
||||
isDisabled,
|
||||
} = props;
|
||||
const [availableGroups, setAvailableGroups] = useState<
|
||||
{ title: string; id: string }[]
|
||||
>([]);
|
||||
@@ -128,7 +135,7 @@ export const GitlabRepoPicker = (
|
||||
),
|
||||
})
|
||||
}
|
||||
disabled={allowedOwners.length === 1}
|
||||
disabled={isDisabled || allowedOwners.length === 1}
|
||||
selected={owner}
|
||||
items={ownerItems}
|
||||
/>
|
||||
@@ -147,10 +154,12 @@ export const GitlabRepoPicker = (
|
||||
<TextField
|
||||
{...params}
|
||||
label={t('fields.gitlabRepoPicker.owner.title')}
|
||||
disabled={isDisabled}
|
||||
required
|
||||
/>
|
||||
)}
|
||||
freeSolo
|
||||
disabled={isDisabled}
|
||||
autoSelect
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -119,6 +119,36 @@ describe('RepoUrlPicker', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should disable the picker when ui:disabled', async () => {
|
||||
const onSubmit = jest.fn();
|
||||
const { getAllByRole } = await renderInTestApp(
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
[scmIntegrationsApiRef, mockIntegrationsApi],
|
||||
[scmAuthApiRef, {}],
|
||||
[scaffolderApiRef, mockScaffolderApi],
|
||||
]}
|
||||
>
|
||||
<SecretsContextProvider>
|
||||
<Form
|
||||
validator={validator}
|
||||
schema={{ type: 'string' }}
|
||||
uiSchema={{ 'ui:field': 'RepoUrlPicker', 'ui:disabled': true }}
|
||||
fields={{
|
||||
RepoUrlPicker: RepoUrlPicker as ScaffolderRJSFField<string>,
|
||||
}}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
</SecretsContextProvider>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const [ownerInput, repoInput] = getAllByRole('textbox');
|
||||
|
||||
expect(ownerInput).toBeDisabled();
|
||||
expect(repoInput).toBeDisabled();
|
||||
});
|
||||
|
||||
it('should render properly with allowedHosts', async () => {
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<TestApiProvider
|
||||
|
||||
@@ -77,7 +77,10 @@ export const RepoUrlPicker = (
|
||||
() => uiSchema?.['ui:options']?.allowedRepos ?? [],
|
||||
[uiSchema],
|
||||
);
|
||||
|
||||
const isDisabled = useMemo(
|
||||
() => uiSchema?.['ui:disabled'] ?? false,
|
||||
[uiSchema],
|
||||
);
|
||||
const { owner, organization, project, repoName } = state;
|
||||
|
||||
useEffect(() => {
|
||||
@@ -179,6 +182,7 @@ export const RepoUrlPicker = (
|
||||
hosts={allowedHosts}
|
||||
onChange={host => setState(prevState => ({ ...prevState, host }))}
|
||||
rawErrors={rawErrors}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
{hostType === 'github' && (
|
||||
<GithubRepoPicker
|
||||
@@ -186,6 +190,7 @@ export const RepoUrlPicker = (
|
||||
onChange={updateLocalState}
|
||||
rawErrors={rawErrors}
|
||||
state={state}
|
||||
isDisabled={isDisabled}
|
||||
accessToken={
|
||||
uiSchema?.['ui:options']?.requestUserCredentials?.secretsKey &&
|
||||
secrets[uiSchema['ui:options'].requestUserCredentials.secretsKey]
|
||||
@@ -198,6 +203,7 @@ export const RepoUrlPicker = (
|
||||
allowedRepos={allowedRepos}
|
||||
rawErrors={rawErrors}
|
||||
state={state}
|
||||
isDisabled={isDisabled}
|
||||
onChange={updateLocalState}
|
||||
/>
|
||||
)}
|
||||
@@ -207,6 +213,7 @@ export const RepoUrlPicker = (
|
||||
rawErrors={rawErrors}
|
||||
state={state}
|
||||
onChange={updateLocalState}
|
||||
isDisabled={isDisabled}
|
||||
accessToken={
|
||||
uiSchema?.['ui:options']?.requestUserCredentials?.secretsKey &&
|
||||
secrets[uiSchema['ui:options'].requestUserCredentials.secretsKey]
|
||||
@@ -220,6 +227,7 @@ export const RepoUrlPicker = (
|
||||
rawErrors={rawErrors}
|
||||
state={state}
|
||||
onChange={updateLocalState}
|
||||
isDisabled={isDisabled}
|
||||
accessToken={
|
||||
uiSchema?.['ui:options']?.requestUserCredentials?.secretsKey &&
|
||||
secrets[uiSchema['ui:options'].requestUserCredentials.secretsKey]
|
||||
@@ -232,6 +240,7 @@ export const RepoUrlPicker = (
|
||||
allowedProject={allowedProjects}
|
||||
rawErrors={rawErrors}
|
||||
state={state}
|
||||
isDisabled={isDisabled}
|
||||
onChange={updateLocalState}
|
||||
/>
|
||||
)}
|
||||
@@ -240,6 +249,7 @@ export const RepoUrlPicker = (
|
||||
rawErrors={rawErrors}
|
||||
state={state}
|
||||
onChange={updateLocalState}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
)}
|
||||
<RepoUrlPickerRepoName
|
||||
@@ -251,6 +261,7 @@ export const RepoUrlPicker = (
|
||||
repoName: repo.id || repo.name,
|
||||
}))
|
||||
}
|
||||
isDisabled={isDisabled}
|
||||
rawErrors={rawErrors}
|
||||
availableRepos={state.availableRepos}
|
||||
/>
|
||||
|
||||
@@ -100,4 +100,31 @@ describe('RepoUrlPickerHostField', () => {
|
||||
|
||||
expect(listbox.getAllByRole('option')).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('disables the host select when isDisabled is true', async () => {
|
||||
const mockOnChange = jest.fn();
|
||||
const mockScaffolderApi = {
|
||||
getIntegrationsList: jest.fn().mockResolvedValue({
|
||||
integrations: [
|
||||
{ host: 'github.com', title: 'github.com', type: 'github' },
|
||||
{ host: 'gitlab.com', title: 'gitlab.com', type: 'gitlab' },
|
||||
],
|
||||
}),
|
||||
};
|
||||
|
||||
const { getByTestId } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[scaffolderApiRef, mockScaffolderApi]]}>
|
||||
<RepoUrlPickerHost
|
||||
hosts={['github.com', 'gitlab.com']}
|
||||
onChange={mockOnChange}
|
||||
rawErrors={[]}
|
||||
isDisabled
|
||||
/>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
const selectElement = getByTestId('host-select').querySelector('select');
|
||||
|
||||
expect(selectElement).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,8 +28,9 @@ export const RepoUrlPickerHost = (props: {
|
||||
hosts?: string[];
|
||||
onChange: (host: string) => void;
|
||||
rawErrors: string[];
|
||||
isDisabled?: boolean;
|
||||
}) => {
|
||||
const { host, hosts, onChange, rawErrors } = props;
|
||||
const { host, hosts, onChange, rawErrors, isDisabled } = props;
|
||||
const { t } = useTranslationRef(scaffolderTranslationRef);
|
||||
const scaffolderApi = useApi(scaffolderApiRef);
|
||||
|
||||
@@ -75,7 +76,7 @@ export const RepoUrlPickerHost = (props: {
|
||||
>
|
||||
<Select
|
||||
native
|
||||
disabled={hosts?.length === 1}
|
||||
disabled={isDisabled || hosts?.length === 1}
|
||||
label={t('fields.repoUrlPicker.host.title')}
|
||||
onChange={s => onChange(String(Array.isArray(s) ? s[0] : s))}
|
||||
selected={host}
|
||||
|
||||
@@ -107,4 +107,43 @@ describe('RepoUrlPickerRepoName', () => {
|
||||
await userEvent.click(getByText(availableRepos[0].name));
|
||||
expect(onChange).toHaveBeenCalledWith(availableRepos[0]);
|
||||
});
|
||||
|
||||
it('should disable the repo selection when isDisabled is true', async () => {
|
||||
const allowedRepos = ['foo', 'bar'];
|
||||
const onChange = jest.fn();
|
||||
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<RepoUrlPickerRepoName
|
||||
onChange={onChange}
|
||||
allowedRepos={allowedRepos}
|
||||
rawErrors={[]}
|
||||
isDisabled
|
||||
/>,
|
||||
);
|
||||
|
||||
// Find the select element
|
||||
const selectElement = getByRole('combobox');
|
||||
|
||||
// Ensure it's disabled
|
||||
expect(selectElement).toBeDisabled();
|
||||
});
|
||||
|
||||
it('should disable the text input when no options are passed and isDisabled is true', async () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
const { getByRole } = await renderInTestApp(
|
||||
<RepoUrlPickerRepoName
|
||||
onChange={onChange}
|
||||
allowedRepos={[]}
|
||||
rawErrors={[]}
|
||||
isDisabled
|
||||
/>,
|
||||
);
|
||||
|
||||
// Find the text input (autocomplete)
|
||||
const textInput = getByRole('textbox');
|
||||
|
||||
// Ensure it's disabled
|
||||
expect(textInput).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,8 +29,16 @@ export const RepoUrlPickerRepoName = (props: {
|
||||
onChange: (chosenRepo: AvailableRepositories) => void;
|
||||
rawErrors: string[];
|
||||
availableRepos?: AvailableRepositories[];
|
||||
isDisabled?: boolean;
|
||||
}) => {
|
||||
const { repoName, allowedRepos, onChange, rawErrors, availableRepos } = props;
|
||||
const {
|
||||
repoName,
|
||||
allowedRepos,
|
||||
onChange,
|
||||
rawErrors,
|
||||
availableRepos,
|
||||
isDisabled,
|
||||
} = props;
|
||||
const { t } = useTranslationRef(scaffolderTranslationRef);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -63,7 +71,7 @@ export const RepoUrlPickerRepoName = (props: {
|
||||
name: String(Array.isArray(selected) ? selected[0] : selected),
|
||||
})
|
||||
}
|
||||
disabled={allowedRepos.length === 1}
|
||||
disabled={isDisabled || allowedRepos.length === 1}
|
||||
selected={repoName}
|
||||
items={repoItems}
|
||||
/>
|
||||
@@ -86,6 +94,7 @@ export const RepoUrlPickerRepoName = (props: {
|
||||
)}
|
||||
freeSolo
|
||||
autoSelect
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
)}
|
||||
<FormHelperText>
|
||||
|
||||
@@ -32,4 +32,5 @@ export type BaseRepoUrlPickerProps<T extends {} = {}> = T & {
|
||||
onChange: (state: RepoUrlPickerState) => void;
|
||||
state: RepoUrlPickerState;
|
||||
rawErrors: string[];
|
||||
isDisabled?: boolean;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user