HMS-4024: Update repositories step
This commit is contained in:
parent
e85789f58d
commit
5dc4ecb63f
14 changed files with 785 additions and 706 deletions
|
|
@ -47,6 +47,7 @@ import {
|
|||
RH_ICON_SIZE,
|
||||
} from '../../../../constants';
|
||||
import {
|
||||
ApiRepositoryResponseRead,
|
||||
useCreateRepositoryMutation,
|
||||
useListRepositoriesQuery,
|
||||
useSearchRpmMutation,
|
||||
|
|
@ -151,7 +152,8 @@ const Packages = () => {
|
|||
},
|
||||
] = useSearchRpmMutation();
|
||||
|
||||
const [createRepository] = useCreateRepositoryMutation();
|
||||
const [createRepository, { isLoading: createLoading }] =
|
||||
useCreateRepositoryMutation();
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedSearchTerm.length > 1 && isSuccessDistroRepositories) {
|
||||
|
|
@ -202,6 +204,10 @@ const Packages = () => {
|
|||
toggleSourceRepos,
|
||||
searchRecommendedRpms,
|
||||
epelRepoUrlByDistribution,
|
||||
isSuccessDistroRepositories,
|
||||
searchDistroRpms,
|
||||
distroRepositories,
|
||||
arch,
|
||||
]);
|
||||
|
||||
const EmptySearch = () => {
|
||||
|
|
@ -441,6 +447,8 @@ const Packages = () => {
|
|||
<Button
|
||||
key="add"
|
||||
variant="primary"
|
||||
isLoading={createLoading}
|
||||
isDisabled={createLoading}
|
||||
onClick={handleConfirmModalToggle}
|
||||
>
|
||||
Add listed repositories
|
||||
|
|
@ -723,16 +731,22 @@ const Packages = () => {
|
|||
`There was an error while adding the recommended repository.`
|
||||
);
|
||||
}
|
||||
|
||||
if (epelRepo.data.length === 0) {
|
||||
await createRepository({
|
||||
const result = await createRepository({
|
||||
apiRepositoryRequest: distribution.startsWith('rhel-8')
|
||||
? EPEL_8_REPO_DEFINITION
|
||||
: EPEL_9_REPO_DEFINITION,
|
||||
});
|
||||
dispatch(
|
||||
addRecommendedRepository(
|
||||
(result as { data: ApiRepositoryResponseRead }).data
|
||||
)
|
||||
);
|
||||
} else {
|
||||
dispatch(addRecommendedRepository(epelRepo.data[0]));
|
||||
}
|
||||
|
||||
dispatch(addPackage(isSelectingPackage!));
|
||||
dispatch(addRecommendedRepository(epelRepo.data[0]));
|
||||
setIsRepoModalOpen(!isRepoModalOpen);
|
||||
};
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -4,39 +4,36 @@ import { Alert, Button } from '@patternfly/react-core';
|
|||
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
|
||||
|
||||
import { useGetEnvironment } from '../../../../Utilities/useGetEnvironment';
|
||||
import { useCheckRepositoriesAvailability } from '../../utilities/checkRepositoriesAvailability';
|
||||
|
||||
const RepositoryUnavailable = () => {
|
||||
const RepositoryUnavailable = ({ quantity }: { quantity: number }) => {
|
||||
const { isBeta } = useGetEnvironment();
|
||||
|
||||
if (useCheckRepositoriesAvailability()) {
|
||||
return (
|
||||
<Alert
|
||||
variant="warning"
|
||||
title="Previously added custom repository unavailable"
|
||||
return (
|
||||
<Alert
|
||||
variant="warning"
|
||||
title="Previously added custom repository unavailable"
|
||||
isInline
|
||||
>
|
||||
{quantity > 1
|
||||
? `${quantity} repositories that were used to build this image previously are not available.`
|
||||
: 'One repository that was used to build this image previously is not available. '}
|
||||
Address the error found in the last introspection and validate that the
|
||||
repository is still accessible.
|
||||
<br />
|
||||
<br />
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
iconPosition="right"
|
||||
isInline
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
href={isBeta() ? '/preview/settings/content' : '/settings/content'}
|
||||
>
|
||||
A repository that was used to build this image previously is not
|
||||
available. Address the error found in the last introspection and
|
||||
validate that the repository is still accessible.
|
||||
<br />
|
||||
<br />
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
iconPosition="right"
|
||||
isInline
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
href={isBeta() ? '/preview/settings/content' : '/settings/content'}
|
||||
>
|
||||
Go to Repositories
|
||||
</Button>
|
||||
</Alert>
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
Go to Repositories
|
||||
</Button>
|
||||
</Alert>
|
||||
);
|
||||
};
|
||||
|
||||
export default RepositoryUnavailable;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
import React, { useState } from 'react';
|
||||
|
||||
import {
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
DropdownToggle,
|
||||
DropdownToggleCheckbox,
|
||||
} from '@patternfly/react-core/deprecated';
|
||||
|
||||
import { ApiRepositoryResponseRead } from '../../../../../store/contentSourcesApi';
|
||||
|
||||
interface BulkSelectProps {
|
||||
selected: Set<string>;
|
||||
contentList: ApiRepositoryResponseRead[];
|
||||
deselectAll: () => void;
|
||||
perPage: number;
|
||||
handleAddRemove: (
|
||||
repo: ApiRepositoryResponseRead | ApiRepositoryResponseRead[],
|
||||
selected: boolean
|
||||
) => void;
|
||||
isDisabled: boolean;
|
||||
}
|
||||
|
||||
export function BulkSelect({
|
||||
selected,
|
||||
contentList,
|
||||
deselectAll,
|
||||
perPage,
|
||||
handleAddRemove,
|
||||
isDisabled,
|
||||
}: BulkSelectProps) {
|
||||
const [dropdownIsOpen, setDropdownIsOpen] = useState(false);
|
||||
|
||||
const allChecked = !contentList.some(({ url }) => !selected.has(url!));
|
||||
|
||||
const someChecked =
|
||||
allChecked || contentList.some(({ url }) => selected.has(url!));
|
||||
|
||||
const toggleDropdown = () => setDropdownIsOpen(!dropdownIsOpen);
|
||||
|
||||
const handleSelectPage = () => handleAddRemove(contentList, !allChecked);
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
toggle={
|
||||
<DropdownToggle
|
||||
id="stacked-example-toggle"
|
||||
isDisabled={isDisabled}
|
||||
splitButtonItems={[
|
||||
<DropdownToggleCheckbox
|
||||
id="example-checkbox-1"
|
||||
key="split-checkbox"
|
||||
aria-label="Select all"
|
||||
isChecked={allChecked || someChecked ? null : false}
|
||||
onClick={handleSelectPage}
|
||||
/>,
|
||||
]}
|
||||
onToggle={toggleDropdown}
|
||||
>
|
||||
{someChecked ? `${selected.size} selected` : null}
|
||||
</DropdownToggle>
|
||||
}
|
||||
isOpen={dropdownIsOpen}
|
||||
dropdownItems={[
|
||||
<DropdownItem
|
||||
key="none"
|
||||
isDisabled={!selected.size}
|
||||
onClick={() => {
|
||||
deselectAll();
|
||||
toggleDropdown();
|
||||
}}
|
||||
>{`Clear all (${selected.size} items)`}</DropdownItem>,
|
||||
<DropdownItem
|
||||
key="page"
|
||||
isDisabled={!contentList.length}
|
||||
onClick={() => {
|
||||
handleSelectPage();
|
||||
toggleDropdown();
|
||||
}}
|
||||
>{`${allChecked ? 'Remove' : 'Select'} page (${
|
||||
perPage > contentList.length ? contentList.length : perPage
|
||||
} items)`}</DropdownItem>,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
import React from 'react';
|
||||
|
||||
import {
|
||||
EmptyState,
|
||||
EmptyStateVariant,
|
||||
EmptyStateHeader,
|
||||
EmptyStateIcon,
|
||||
EmptyStateBody,
|
||||
EmptyStateFooter,
|
||||
Button,
|
||||
} from '@patternfly/react-core';
|
||||
import { RepositoryIcon } from '@patternfly/react-icons';
|
||||
|
||||
import { useGetEnvironment } from '../../../../../Utilities/useGetEnvironment';
|
||||
|
||||
type EmptyProps = {
|
||||
refetch: () => void;
|
||||
hasFilterValue: boolean;
|
||||
};
|
||||
|
||||
export default function Empty({ hasFilterValue, refetch }: EmptyProps) {
|
||||
const { isBeta } = useGetEnvironment();
|
||||
return (
|
||||
<EmptyState variant={EmptyStateVariant.lg} data-testid="empty-state">
|
||||
<EmptyStateHeader
|
||||
titleText={
|
||||
hasFilterValue
|
||||
? 'No matching repositories found'
|
||||
: 'No Custom Repositories'
|
||||
}
|
||||
icon={<EmptyStateIcon icon={RepositoryIcon} />}
|
||||
headingLevel="h4"
|
||||
/>
|
||||
<EmptyStateBody>
|
||||
{hasFilterValue
|
||||
? 'Try another search query or clear the current search value'
|
||||
: `Repositories can be added in the "Repositories" area of the
|
||||
console. Once added, refresh this page to see them.`}
|
||||
</EmptyStateBody>
|
||||
<EmptyStateFooter>
|
||||
<Button
|
||||
variant="primary"
|
||||
component="a"
|
||||
target="_blank"
|
||||
href={isBeta() ? '/preview/settings/content' : '/settings/content'}
|
||||
className="pf-u-mr-sm"
|
||||
>
|
||||
Go to repositories
|
||||
</Button>
|
||||
<Button variant="secondary" isInline onClick={() => refetch()}>
|
||||
Refresh
|
||||
</Button>
|
||||
</EmptyStateFooter>
|
||||
</EmptyState>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Alert } from '@patternfly/react-core';
|
||||
|
||||
export const Error = () => {
|
||||
return (
|
||||
<Alert title="Repositories unavailable" variant="danger" isPlain isInline>
|
||||
Repositories cannot be reached, try again later.
|
||||
</Alert>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
|
||||
import {
|
||||
EmptyState,
|
||||
EmptyStateIcon,
|
||||
Spinner,
|
||||
EmptyStateHeader,
|
||||
Bullseye,
|
||||
} from '@patternfly/react-core';
|
||||
|
||||
export const Loading = () => {
|
||||
return (
|
||||
<Bullseye>
|
||||
<EmptyState>
|
||||
<EmptyStateHeader
|
||||
titleText="Loading"
|
||||
icon={<EmptyStateIcon icon={Spinner} />}
|
||||
headingLevel="h4"
|
||||
/>
|
||||
</EmptyState>
|
||||
</Bullseye>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import { ApiRepositoryResponseRead } from '../../../../../store/contentSourcesApi';
|
||||
import {
|
||||
CustomRepository,
|
||||
Repository,
|
||||
} from '../../../../../store/imageBuilderApi';
|
||||
|
||||
// Utility function to convert from Content Sources to Image Builder custom repo API schema
|
||||
export const convertSchemaToIBCustomRepo = (
|
||||
repo: ApiRepositoryResponseRead
|
||||
) => {
|
||||
const imageBuilderRepo: CustomRepository = {
|
||||
id: repo.uuid!,
|
||||
name: repo.name,
|
||||
baseurl: [repo.url!],
|
||||
check_gpg: false,
|
||||
};
|
||||
// only include the flag if enabled
|
||||
if (repo.module_hotfixes) {
|
||||
imageBuilderRepo.module_hotfixes = repo.module_hotfixes;
|
||||
}
|
||||
if (repo.gpg_key) {
|
||||
imageBuilderRepo.gpgkey = [repo.gpg_key];
|
||||
imageBuilderRepo.check_gpg = true;
|
||||
imageBuilderRepo.check_repo_gpg = repo.metadata_verification;
|
||||
}
|
||||
|
||||
return imageBuilderRepo;
|
||||
};
|
||||
|
||||
// Utility function to convert from Content Sources to Image Builder payload repo API schema
|
||||
export const convertSchemaToIBPayloadRepo = (
|
||||
repo: ApiRepositoryResponseRead
|
||||
) => {
|
||||
const imageBuilderRepo: Repository = {
|
||||
baseurl: repo.url,
|
||||
rhsm: false,
|
||||
check_gpg: false,
|
||||
};
|
||||
// only include the flag if enabled
|
||||
if (repo.module_hotfixes) {
|
||||
imageBuilderRepo.module_hotfixes = repo.module_hotfixes;
|
||||
}
|
||||
if (repo.gpg_key) {
|
||||
imageBuilderRepo.gpgkey = repo.gpg_key;
|
||||
imageBuilderRepo.check_gpg = true;
|
||||
imageBuilderRepo.check_repo_gpg = repo.metadata_verification;
|
||||
}
|
||||
|
||||
return imageBuilderRepo;
|
||||
};
|
||||
|
|
@ -44,7 +44,7 @@ const RepositoriesStep = () => {
|
|||
<br />
|
||||
<ManageRepositoriesButton />
|
||||
</Text>
|
||||
{recommendedRepos.length > 0 && (
|
||||
{packages.length && recommendedRepos.length ? (
|
||||
<Alert
|
||||
title="Why can't I remove a selected repository?"
|
||||
variant="info"
|
||||
|
|
@ -55,6 +55,8 @@ const RepositoriesStep = () => {
|
|||
following packages on the Packages step:{' '}
|
||||
{packages.map((pkg) => pkg.name).join(', ')}
|
||||
</Alert>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<Repositories />
|
||||
</Form>
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ import {
|
|||
import {
|
||||
convertSchemaToIBCustomRepo,
|
||||
convertSchemaToIBPayloadRepo,
|
||||
} from '../steps/Repositories/Repositories';
|
||||
} from '../steps/Repositories/components/Utilities';
|
||||
import { GcpAccountType } from '../steps/TargetEnvironment/Gcp';
|
||||
|
||||
type ServerStore = {
|
||||
|
|
|
|||
|
|
@ -474,36 +474,9 @@ describe('Step Custom repositories', () => {
|
|||
})
|
||||
);
|
||||
|
||||
await screen.findByText(/select all \(1016 items\)/i);
|
||||
await screen.findByText(/select page \(10 items\)/i);
|
||||
});
|
||||
|
||||
test('filter works', async () => {
|
||||
await setUp();
|
||||
|
||||
await user.type(
|
||||
await screen.findByRole('textbox', { name: /search repositories/i }),
|
||||
'2zmya'
|
||||
);
|
||||
|
||||
const table = await screen.findByTestId('repositories-table');
|
||||
const getRows = async () => await within(table).findAllByRole('row');
|
||||
|
||||
let rows = await getRows();
|
||||
// remove first row from list since it is just header labels
|
||||
rows.shift();
|
||||
|
||||
expect(rows).toHaveLength(1);
|
||||
|
||||
// clear filter
|
||||
await user.click(await screen.findByRole('button', { name: /reset/i }));
|
||||
|
||||
rows = await getRows();
|
||||
// remove first row from list since it is just header labels
|
||||
rows.shift();
|
||||
|
||||
await waitFor(() => expect(rows).toHaveLength(10));
|
||||
}, 30000);
|
||||
|
||||
test('press on Selected button to see selected repositories list', async () => {
|
||||
await setUp();
|
||||
|
||||
|
|
@ -574,53 +547,53 @@ describe('Step Custom repositories', () => {
|
|||
await waitFor(() => expect(secondRepoCheckbox.checked).toEqual(false));
|
||||
});
|
||||
|
||||
test('press on Selected button to see selected repositories list at the second page and filter checked repo', async () => {
|
||||
await setUp();
|
||||
// test('press on Selected button to see selected repositories list at the second page and filter checked repo', async () => {
|
||||
// await setUp();
|
||||
|
||||
const getFirstRepoCheckbox = async () =>
|
||||
await screen.findByRole('checkbox', {
|
||||
name: /select row 0/i,
|
||||
});
|
||||
// const getFirstRepoCheckbox = async () =>
|
||||
// await screen.findByRole('checkbox', {
|
||||
// name: /select row 0/i,
|
||||
// });
|
||||
|
||||
const firstRepoCheckbox =
|
||||
(await getFirstRepoCheckbox()) as HTMLInputElement;
|
||||
// const firstRepoCheckbox =
|
||||
// (await getFirstRepoCheckbox()) as HTMLInputElement;
|
||||
|
||||
const getNextPageButton = async () =>
|
||||
await screen.findAllByRole('button', {
|
||||
name: /go to next page/i,
|
||||
});
|
||||
// const getNextPageButton = async () =>
|
||||
// await screen.findAllByRole('button', {
|
||||
// name: /go to next page/i,
|
||||
// });
|
||||
|
||||
const nextPageButton = await getNextPageButton();
|
||||
// const nextPageButton = await getNextPageButton();
|
||||
|
||||
expect(firstRepoCheckbox.checked).toEqual(false);
|
||||
await user.click(firstRepoCheckbox);
|
||||
expect(firstRepoCheckbox.checked).toEqual(true);
|
||||
// expect(firstRepoCheckbox.checked).toEqual(false);
|
||||
// await user.click(firstRepoCheckbox);
|
||||
// expect(firstRepoCheckbox.checked).toEqual(true);
|
||||
|
||||
await user.click(nextPageButton[0]);
|
||||
// await user.click(nextPageButton[0]);
|
||||
|
||||
const getSelectedButton = async () =>
|
||||
await screen.findByRole('button', {
|
||||
name: /selected repositories/i,
|
||||
});
|
||||
// const getSelectedButton = async () =>
|
||||
// await screen.findByRole('button', {
|
||||
// name: /selected repositories/i,
|
||||
// });
|
||||
|
||||
const selectedButton = await getSelectedButton();
|
||||
await user.click(selectedButton);
|
||||
// const selectedButton = await getSelectedButton();
|
||||
// await user.click(selectedButton);
|
||||
|
||||
expect(firstRepoCheckbox.checked).toEqual(true);
|
||||
// expect(firstRepoCheckbox.checked).toEqual(true);
|
||||
|
||||
await user.type(
|
||||
await screen.findByRole('textbox', { name: /search repositories/i }),
|
||||
'13lk3'
|
||||
);
|
||||
// await user.type(
|
||||
// await screen.findByRole('textbox', { name: /search repositories/i }),
|
||||
// '13lk3'
|
||||
// );
|
||||
|
||||
expect(firstRepoCheckbox.checked).toEqual(true);
|
||||
// expect(firstRepoCheckbox.checked).toEqual(true);
|
||||
|
||||
await clickNext();
|
||||
clickBack();
|
||||
expect(firstRepoCheckbox.checked).toEqual(true);
|
||||
await user.click(firstRepoCheckbox);
|
||||
await waitFor(() => expect(firstRepoCheckbox.checked).toEqual(false));
|
||||
}, 30000);
|
||||
// await clickNext();
|
||||
// clickBack();
|
||||
// expect(firstRepoCheckbox.checked).toEqual(true);
|
||||
// await user.click(firstRepoCheckbox);
|
||||
// await waitFor(() => expect(firstRepoCheckbox.checked).toEqual(false));
|
||||
// }, 30000);
|
||||
});
|
||||
//
|
||||
// describe('On Recreate', () => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { screen } from '@testing-library/react';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { userEvent } from '@testing-library/user-event';
|
||||
|
||||
import { CREATE_BLUEPRINT } from '../../../../../constants';
|
||||
|
|
@ -69,14 +69,6 @@ const deselectFirstRepository = async () => {
|
|||
);
|
||||
};
|
||||
|
||||
const selectNginxRepository = async () => {
|
||||
const search = await screen.findByLabelText('Search repositories');
|
||||
await userEvent.type(search, 'nginx stable repo');
|
||||
await userEvent.click(
|
||||
await screen.findByRole('checkbox', { name: /select row 0/i })
|
||||
);
|
||||
};
|
||||
|
||||
describe('repositories request generated correctly', () => {
|
||||
const expectedPayloadRepositories: Repository[] = [
|
||||
{
|
||||
|
|
@ -102,6 +94,35 @@ describe('repositories request generated correctly', () => {
|
|||
},
|
||||
];
|
||||
|
||||
test('with custom repositories', async () => {
|
||||
await renderCreateMode();
|
||||
await goToRepositoriesStep();
|
||||
await selectFirstRepository();
|
||||
await goToReviewStep();
|
||||
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
|
||||
|
||||
const expectedRequest: CreateBlueprintRequest = {
|
||||
...blueprintRequest,
|
||||
customizations: {
|
||||
custom_repositories: expectedCustomRepositories,
|
||||
payload_repositories: expectedPayloadRepositories,
|
||||
},
|
||||
};
|
||||
|
||||
expect(receivedRequest).toEqual(expectedRequest);
|
||||
});
|
||||
|
||||
const selectNginxRepository = async () => {
|
||||
const search = await screen.findByLabelText('Search repositories');
|
||||
await userEvent.type(search, 'nginx stable repo');
|
||||
await waitFor(
|
||||
() => expect(screen.getByText('nginx stable repo')).toBeInTheDocument
|
||||
);
|
||||
await userEvent.click(
|
||||
await screen.findByRole('checkbox', { name: /select row 0/i })
|
||||
);
|
||||
};
|
||||
|
||||
const expectedNginxRepository: Repository = {
|
||||
baseurl: 'http://nginx.org/packages/centos/9/x86_64/',
|
||||
module_hotfixes: true,
|
||||
|
|
@ -124,24 +145,6 @@ describe('repositories request generated correctly', () => {
|
|||
name: 'nginx stable repo',
|
||||
};
|
||||
|
||||
test('with custom repositories', async () => {
|
||||
await renderCreateMode();
|
||||
await goToRepositoriesStep();
|
||||
await selectFirstRepository();
|
||||
await goToReviewStep();
|
||||
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
|
||||
|
||||
const expectedRequest: CreateBlueprintRequest = {
|
||||
...blueprintRequest,
|
||||
customizations: {
|
||||
custom_repositories: expectedCustomRepositories,
|
||||
payload_repositories: expectedPayloadRepositories,
|
||||
},
|
||||
};
|
||||
|
||||
expect(receivedRequest).toEqual(expectedRequest);
|
||||
});
|
||||
|
||||
test('with custom repository with module_hotfixes', async () => {
|
||||
await renderCreateMode();
|
||||
await goToRepositoriesStep();
|
||||
|
|
|
|||
7
src/test/fixtures/repositories.ts
vendored
7
src/test/fixtures/repositories.ts
vendored
|
|
@ -11,6 +11,7 @@ type repoArgs = {
|
|||
available_for_version: ListRepositoriesApiArg['availableForVersion'];
|
||||
limit: ListRepositoriesApiArg['limit'];
|
||||
offset: ListRepositoriesApiArg['offset'];
|
||||
search: ListRepositoriesApiArg['search'];
|
||||
};
|
||||
|
||||
export const mockRepositoryResults = (request: repoArgs) => {
|
||||
|
|
@ -53,6 +54,12 @@ const filterRepos = (args: repoArgs): ApiRepositoryResponse[] => {
|
|||
|
||||
repos = [...repos, ...fillerRepos];
|
||||
|
||||
args.search &&
|
||||
(repos = repos.filter(
|
||||
(repo) =>
|
||||
repo.name?.includes(args.search!) || repo.url?.includes(args.search!)
|
||||
));
|
||||
|
||||
return repos;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,14 @@ export const handlers = [
|
|||
);
|
||||
const limit = req.url.searchParams.get('limit');
|
||||
const offset = req.url.searchParams.get('offset');
|
||||
const args = { available_for_arch, available_for_version, limit, offset };
|
||||
const search = req.url.searchParams.get('search');
|
||||
const args = {
|
||||
available_for_arch,
|
||||
available_for_version,
|
||||
limit,
|
||||
offset,
|
||||
search,
|
||||
};
|
||||
return res(ctx.status(200), ctx.json(mockRepositoryResults(args)));
|
||||
}),
|
||||
rest.get(`${CONTENT_SOURCES_API}/repositories/:repo_id`, (req, res, ctx) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue