Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bulk-import): use react query to fetch repositories #2339

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/witty-socks-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@janus-idp/backstage-plugin-bulk-import": minor
---

use react query to fetch repositories
10 changes: 7 additions & 3 deletions plugins/bulk-import/src/api/BulkImportBackendClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,11 @@ const handlers = [
)
) {
return res(
ctx.status(400),
ctx.json({ message: 'Dry run for creating import jobs failed' }),
ctx.json({
message: 'Dry run for creating import jobs failed',
ok: false,
status: 404,
}),
);
}
return res(ctx.json(jobs));
Expand Down Expand Up @@ -351,9 +354,10 @@ describe('BulkImportBackendClient', () => {
),
true,
);

expect(response).toEqual({
message: 'Dry run for creating import jobs failed',
ok: false,
status: 404,
});
});
});
Expand Down
6 changes: 5 additions & 1 deletion plugins/bulk-import/src/api/BulkImportBackendClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ export class BulkImportBackendClient implements BulkImportAPI {
body: JSON.stringify(importRepositories),
},
);
return jsonResponse.json();
if (!jsonResponse.ok) {
const errorResponse = await jsonResponse.json();
throw errorResponse;
}
return jsonResponse.status === 204 ? null : await jsonResponse.json();
}

async deleteImportAction(repo: string, defaultBranch: string) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React from 'react';

import { makeStyles } from '@material-ui/core';
import { Alert, AlertTitle } from '@material-ui/lab';
import FormControl from '@mui/material/FormControl';
import { useFormikContext } from 'formik';
import { get } from 'lodash';

import { useDrawer } from '@janus-idp/shared-react';

import { AddRepositoriesFormValues, PullRequestPreviewData } from '../../types';
import { PreviewFileSidebar } from '../PreviewFile/PreviewFileSidebar';
// import HelpIcon from '@mui/icons-material/HelpOutline';
// import FormControlLabel from '@mui/material/FormControlLabel';
// import Radio from '@mui/material/Radio';
// import RadioGroup from '@mui/material/RadioGroup';
// import Tooltip from '@mui/material/Tooltip';
// import Typography from '@mui/material/Typography';
// import { useFormikContext } from 'formik';
// import { AddRepositoriesFormValues } from '../../types';
import { AddRepositoriesFormFooter } from './AddRepositoriesFormFooter';
import { AddRepositoriesTable } from './AddRepositoriesTable';

const useStyles = makeStyles(theme => ({
body: {
marginBottom: '50px',
padding: '24px',
},
approvalTool: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'left',
alignItems: 'center',
paddingTop: '24px',
paddingBottom: '24px',
paddingLeft: '16px',
backgroundColor: theme.palette.background.paper,
borderBottomStyle: 'groove',
border: theme.palette.divider,
},

approvalToolTooltip: {
paddingTop: '4px',
paddingRight: '24px',
paddingLeft: '5px',
},
}));

export const AddRepositories = ({ error }: { error: any }) => {
const styles = useStyles();
const { openDrawer, setOpenDrawer, drawerData } = useDrawer();
const { setFieldValue, values } =
useFormikContext<AddRepositoriesFormValues>();

const closeDrawer = () => {
setOpenDrawer(false);
};

const handleSave = (pullRequest: PullRequestPreviewData, _event: any) => {
Object.keys(pullRequest).forEach(pr => {
setFieldValue(
`repositories.${pr}.catalogInfoYaml.prTemplate`,
pullRequest[pr],
);
});
setOpenDrawer(false);
};

return (
<>
<FormControl fullWidth>
<div className={styles.body}>
{error && (
<div style={{ paddingBottom: '10px' }}>
<Alert severity="error">
<AlertTitle>{get(error, 'name') || 'Error occured'}</AlertTitle>
{get(error, 'err') || 'Failed to create pull request'}
</Alert>
</div>
)}
{/*
// Enable this when ServiceNow approval tool is supported
<span className={styles.approvalTool}>
<Typography fontSize="16px" fontWeight="500">
Approval tool
</Typography>
<Tooltip
placement="top"
title="When adding a new repository, it requires approval. Once the PR is approved or the ServiceNow ticket is closed, the repositories will be added to the Catalog page."
>
<span className={styles.approvalToolTooltip}>
<HelpIcon fontSize="small" />
</span>
</Tooltip>
<RadioGroup
id="approval-tool"
data-testid="approval-tool"
row
name="approvalTool"
value={values.approvalTool}
onChange={(_event, value: string) => {
setFieldValue('approvalTool', value);
}}
>
<FormControlLabel value="git" control={<Radio />} label="Git" />
<FormControlLabel
value="servicenow"
control={<Radio />}
label="ServiceNow"
disabled
/>
</RadioGroup>
</span> */}
<AddRepositoriesTable title="Selected repositories" />
</div>
<br />
</FormControl>
<AddRepositoriesFormFooter />
{openDrawer && (
<PreviewFileSidebar
open={openDrawer}
onClose={closeDrawer}
data={drawerData}
repositoryType={values.repositoryType}
handleSave={handleSave}
/>
)}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const AddRepositoriesDrawer = ({
}: {
open: boolean;
onClose: () => void;
onSelect: (repos: AddedRepositories, drawerOrgName: string) => void;
onSelect: (repos: AddedRepositories) => void;
title: string;
orgData: AddRepositoryData;
}) => {
Expand All @@ -75,7 +75,7 @@ export const AddRepositoriesDrawer = ({
};

const handleSelectRepoFromDrawer = (selected: AddedRepositories) => {
onSelect(selected, orgData?.orgName || '');
onSelect(selected);
const newStatus = { ...(status?.errors || {}) };
Object.keys(newStatus).forEach(s => {
if (!Object.keys(selected).find(sel => sel === s)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import { BrowserRouter as Router } from 'react-router-dom';
import { configApiRef, identityApiRef } from '@backstage/core-plugin-api';
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { render, screen } from '@testing-library/react';
import { useFormikContext } from 'formik';

import { useDrawer } from '@janus-idp/shared-react';

import { bulkImportApiRef } from '../../api/BulkImportBackendClient';
import { mockGetImportJobs, mockGetRepositories } from '../../mocks/mockData';
import { ImportJobStatus, RepositorySelection } from '../../types';
import { AddRepositoriesForm } from './AddRepositoriesForm';
import {
ImportJobStatus,
OrgAndRepoResponse,
RepositorySelection,
} from '../../types';
import { AddRepositories } from './AddRepositories';

jest.mock('formik', () => ({
...jest.requireActual('formik'),
Expand Down Expand Up @@ -44,6 +49,16 @@ jest.mock('@material-ui/core', () => ({
},
}));

const createTestQueryClient = () =>
new QueryClient({
defaultOptions: {
queries: {
retry: false, // Disable retries for testing
},
},
});
let queryClient: QueryClient;

class MockBulkImportApi {
async getImportAction(
repo: string,
Expand All @@ -53,6 +68,13 @@ class MockBulkImportApi {
i => i.repository.url === repo,
) as ImportJobStatus;
}
async dataFetcher(
_pageNo: number,
_size: number,
_searchString: string,
): Promise<OrgAndRepoResponse> {
return mockGetRepositories;
}
}

const mockBulkImportApi = new MockBulkImportApi();
Expand All @@ -70,9 +92,10 @@ beforeEach(() => {
},
setFieldValue: jest.fn(),
});
queryClient = createTestQueryClient();
});

describe('AddRepsositoriesForm', () => {
describe('AddRepositoriesForm', () => {
it('should render the repositories list with the footer', async () => {
(useDrawer as jest.Mock).mockImplementation(initial => ({
initial,
Expand All @@ -97,7 +120,9 @@ describe('AddRepsositoriesForm', () => {
],
]}
>
<AddRepositoriesForm error={null} />
<QueryClientProvider client={queryClient}>
<AddRepositories error={null} />
</QueryClientProvider>
</TestApiProvider>
</Router>,
);
Expand Down Expand Up @@ -134,9 +159,9 @@ describe('AddRepsositoriesForm', () => {
],
]}
>
<AddRepositoriesForm
error={{ message: 'error', title: 'error occurred' }}
/>
<QueryClientProvider client={queryClient}>
<AddRepositories error={{ err: 'error occurred' }} />
</QueryClientProvider>
</TestApiProvider>
</Router>,
);
Expand Down
Loading
Loading