Use id as title was before

Signed-off-by: Severin Wischmann <severinwischmann@nianticlabs.com>
This commit is contained in:
Severin Wischmann
2024-11-13 13:51:30 +01:00
parent 452a2302c3
commit 5e74f87e0c
9 changed files with 65 additions and 56 deletions
@@ -26,7 +26,6 @@ describe('handleAutocompleteRequest', () => {
values: [
{
slug: 'workspace1',
uuid: '486F4F29-9B88-4BE8-9092-24BEB8A5F3B3',
},
],
},
@@ -35,9 +34,7 @@ describe('handleAutocompleteRequest', () => {
listProjectsByWorkspace: jest.fn().mockReturnValue({
iteratePages: jest.fn().mockReturnValue([
{
values: [
{ key: 'project1', uuid: '70F065E3-CE7C-487A-99B6-D81EB84E5A21' },
],
values: [{ key: 'project1' }],
},
]),
}),
@@ -47,7 +44,6 @@ describe('handleAutocompleteRequest', () => {
values: [
{
slug: 'repository1',
uuid: 'F2F0DAF7-B4D6-4694-A131-C2478A200AC5',
},
],
},
@@ -85,9 +81,7 @@ describe('handleAutocompleteRequest', () => {
});
expect(result).toEqual({
results: [
{ title: 'workspace1', id: '486F4F29-9B88-4BE8-9092-24BEB8A5F3B3' },
],
results: [{ id: 'workspace1' }],
});
});
@@ -101,9 +95,7 @@ describe('handleAutocompleteRequest', () => {
});
expect(result).toEqual({
results: [
{ title: 'project1', id: '70F065E3-CE7C-487A-99B6-D81EB84E5A21' },
],
results: [{ id: 'project1' }],
});
});
@@ -118,9 +110,7 @@ describe('handleAutocompleteRequest', () => {
});
expect(result).toEqual({
results: [
{ title: 'repository1', id: 'F2F0DAF7-B4D6-4694-A131-C2478A200AC5' },
],
results: [{ id: 'repository1' }],
});
});
@@ -134,7 +124,7 @@ describe('handleAutocompleteRequest', () => {
},
});
expect(result).toEqual({ results: [{ title: 'branch1', id: 'branch1' }] });
expect(result).toEqual({ results: [{ id: 'branch1' }] });
});
it('should throw an error when passing an invalid resource', async () => {
@@ -34,12 +34,11 @@ export async function handleAutocompleteRequest({
switch (resource) {
case 'workspaces': {
const results: { title: string; id: string }[] = [];
const results: { title?: string; id: string }[] = [];
for await (const page of client.listWorkspaces().iteratePages()) {
const slugs = [...page.values!].map(p => ({
title: p.slug!,
id: p.uuid!,
id: p.slug!,
}));
results.push(...slugs);
}
@@ -50,14 +49,13 @@ export async function handleAutocompleteRequest({
if (!context.workspace)
throw new InputError('Missing workspace context parameter');
const results: { title: string; id: string }[] = [];
const results: { title?: string; id: string }[] = [];
for await (const page of client
.listProjectsByWorkspace(context.workspace)
.iteratePages()) {
const keys = [...page.values!].map(p => ({
title: p.key!,
id: p.uuid!,
id: p.key!,
}));
results.push(...keys);
}
@@ -70,7 +68,7 @@ export async function handleAutocompleteRequest({
'Missing workspace and/or project context parameter',
);
const results: { title: string; id: string }[] = [];
const results: { title?: string; id: string }[] = [];
for await (const page of client
.listRepositoriesByWorkspace(context.workspace, {
@@ -78,8 +76,7 @@ export async function handleAutocompleteRequest({
})
.iteratePages()) {
const slugs = [...page.values!].map(p => ({
title: p.slug!,
id: p.uuid!,
id: p.slug!,
}));
results.push(...slugs);
}
@@ -92,13 +89,12 @@ export async function handleAutocompleteRequest({
'Missing workspace and/or repository context parameter',
);
const results: { title: string; id: string }[] = [];
const results: { title?: string; id: string }[] = [];
for await (const page of client
.listBranchesByRepository(context.repository, context.workspace)
.iteratePages()) {
const names = [...page.values!].map(p => ({
title: p.name!,
id: p.name!,
}));
results.push(...names);
@@ -14,22 +14,22 @@
* limitations under the License.
*/
import React from 'react';
import { BitbucketRepoPicker } from './BitbucketRepoPicker';
import { fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import {
ScaffolderApi,
scaffolderApiRef,
} from '@backstage/plugin-scaffolder-react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { act } from 'react-dom/test-utils';
import { BitbucketRepoPicker } from './BitbucketRepoPicker';
describe('BitbucketRepoPicker', () => {
const scaffolderApiMock: Partial<ScaffolderApi> = {
autocomplete: jest.fn().mockImplementation(opts =>
Promise.resolve({
results: [{ title: `${opts.resource}_example` }],
results: [{ id: `${opts.resource}_example` }],
}),
),
};
@@ -266,7 +266,7 @@ describe('BitbucketRepoPicker', () => {
// Verify that the available repos are updated
await waitFor(() =>
expect(onChange).toHaveBeenCalledWith({
availableRepos: ['repositories_example'],
availableRepos: [{ name: 'repositories_example' }],
}),
);
});
@@ -89,7 +89,7 @@ export const BitbucketRepoPicker = (
provider: 'bitbucket-cloud',
})
.then(({ results }) => {
setAvailableWorkspaces(results.map(r => r.title!));
setAvailableWorkspaces(results.map(r => r.id));
})
.catch(() => {
setAvailableWorkspaces([]);
@@ -118,7 +118,7 @@ export const BitbucketRepoPicker = (
provider: 'bitbucket-cloud',
})
.then(({ results }) => {
setAvailableProjects(results.map(r => r.title!));
setAvailableProjects(results.map(r => r.id));
})
.catch(() => {
setAvailableProjects([]);
@@ -148,7 +148,11 @@ export const BitbucketRepoPicker = (
provider: 'bitbucket-cloud',
})
.then(({ results }) => {
onChange({ availableRepos: results.map(r => r.title!) });
onChange({
availableRepos: results.map(r => {
return { name: r.id };
}),
});
})
.catch(() => {
onChange({ availableRepos: [] });
@@ -96,7 +96,11 @@ export const GitlabRepoPicker = (
provider: 'gitlab',
})
.then(({ results }) => {
onChange({ availableRepos: results.map(r => r.title!) });
onChange({
availableRepos: results.map(r => {
return { name: r.title!, id: r.id };
}),
});
})
.catch(() => {
onChange({ availableRepos: [] });
@@ -242,7 +242,11 @@ export const RepoUrlPicker = (
repoName={state.repoName}
allowedRepos={allowedRepos}
onChange={repo =>
setState(prevState => ({ ...prevState, repoName: repo }))
setState(prevState => ({
...prevState,
repoName: repo.name,
id: repo.id || '',
}))
}
rawErrors={rawErrors}
availableRepos={state.availableRepos}
@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName';
import { renderInTestApp } from '@backstage/test-utils';
import { fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { act } from 'react-dom/test-utils';
import { renderInTestApp } from '@backstage/test-utils';
import { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName';
describe('RepoUrlPickerRepoName', () => {
it('should call onChange with the first allowed repo if there is none set already', async () => {
@@ -32,7 +32,7 @@ describe('RepoUrlPickerRepoName', () => {
/>,
);
expect(onChange).toHaveBeenCalledWith('foo');
expect(onChange).toHaveBeenCalledWith({ name: 'foo' });
});
it('should render a dropdown of all the options', async () => {
@@ -78,11 +78,11 @@ describe('RepoUrlPickerRepoName', () => {
textArea.blur();
});
expect(onChange).toHaveBeenCalledWith('foo');
expect(onChange).toHaveBeenCalledWith({ name: 'foo' });
});
it('should autocomplete with provided availableRepos', async () => {
const availableRepos = ['foo', 'bar'];
const availableRepos = [{ name: 'foo' }, { name: 'bar' }];
const onChange = jest.fn();
@@ -100,11 +100,11 @@ describe('RepoUrlPickerRepoName', () => {
// Verify that available repos are shown
for (const repo of availableRepos) {
expect(getByText(repo)).toBeInTheDocument();
expect(getByText(repo.name)).toBeInTheDocument();
}
// Verify that selecting an option calls onChange
await userEvent.click(getByText(availableRepos[0]));
await userEvent.click(getByText(availableRepos[0].name));
expect(onChange).toHaveBeenCalledWith(availableRepos[0]);
});
});
@@ -13,21 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useEffect } from 'react';
import { Select, SelectItem } from '@backstage/core-components';
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
import FormControl from '@material-ui/core/FormControl';
import FormHelperText from '@material-ui/core/FormHelperText';
import Autocomplete from '@material-ui/lab/Autocomplete';
import TextField from '@material-ui/core/TextField';
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
import Autocomplete from '@material-ui/lab/Autocomplete';
import React, { useEffect } from 'react';
import { scaffolderTranslationRef } from '../../../translation';
import { AvailableRepositories } from './types';
export const RepoUrlPickerRepoName = (props: {
repoName?: string;
allowedRepos?: string[];
onChange: (host: string) => void;
onChange: (chosenRepo: AvailableRepositories) => void;
rawErrors: string[];
availableRepos?: string[];
availableRepos?: AvailableRepositories[];
}) => {
const { repoName, allowedRepos, onChange, rawErrors, availableRepos } = props;
const { t } = useTranslationRef(scaffolderTranslationRef);
@@ -37,7 +38,7 @@ export const RepoUrlPickerRepoName = (props: {
if (!repoName) {
// Set the first of the allowedRepos option if that available
if (allowedRepos?.length) {
onChange(allowedRepos[0]);
onChange({ name: allowedRepos[0] });
}
}
}, [allowedRepos, repoName, onChange]);
@@ -58,7 +59,9 @@ export const RepoUrlPickerRepoName = (props: {
native
label={t('fields.repoUrlPicker.repository.title')}
onChange={selected =>
onChange(String(Array.isArray(selected) ? selected[0] : selected))
onChange({
name: String(Array.isArray(selected) ? selected[0] : selected),
})
}
disabled={allowedRepos.length === 1}
selected={repoName}
@@ -68,9 +71,12 @@ export const RepoUrlPickerRepoName = (props: {
<Autocomplete
value={repoName}
onInputChange={(_, newValue) => {
onChange(newValue || '');
const selectedRepo = availableRepos?.find(
r => r.name === newValue,
);
onChange(selectedRepo || { name: newValue || '' });
}}
options={availableRepos || []}
options={(availableRepos || []).map(r => r.name)}
renderInput={params => (
<TextField
{...params}
@@ -13,6 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export interface AvailableRepositories {
name: string;
id?: string;
}
export interface RepoUrlPickerState {
host?: string;
owner?: string;
@@ -21,7 +26,7 @@ export interface RepoUrlPickerState {
workspace?: string;
project?: string;
id?: string;
availableRepos?: string[];
availableRepos?: AvailableRepositories[];
}
export type BaseRepoUrlPickerProps<T extends {} = {}> = T & {