Skip to content

Commit

Permalink
fix(bulk-import): bulk import ux improvements (#2124)
Browse files Browse the repository at this point in the history
  • Loading branch information
debsmita1 authored Sep 10, 2024
1 parent d1e48db commit 8fa16ff
Show file tree
Hide file tree
Showing 48 changed files with 2,164 additions and 1,357 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ export const AddRepositoriesDrawer = ({
orgData: AddRepositoryData;
}) => {
const classes = useStyles();
const { values } = useFormikContext<AddRepositoriesFormValues>();
const { values, status, setStatus } =
useFormikContext<AddRepositoriesFormValues>();
const [searchString, setSearchString] = useState<string>('');
const [selectedRepos, setSelectedRepos] = useState<AddedRepositories>({});

Expand All @@ -75,6 +76,13 @@ export const AddRepositoriesDrawer = ({

const handleSelectRepoFromDrawer = (selected: AddedRepositories) => {
onSelect(selected, orgData?.orgName || '');
const newStatus = { ...(status?.errors || {}) };
Object.keys(newStatus).forEach(s => {
if (!Object.keys(selected).find(sel => sel === s)) {
delete newStatus[s];
}
});
setStatus({ ...status, errors: newStatus });
onClose();
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';

import { configApiRef, identityApiRef } from '@backstage/core-plugin-api';
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';

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';

jest.mock('formik', () => ({
...jest.requireActual('formik'),
useFormikContext: jest.fn(),
}));

jest.mock('./AddRepositoriesForm', () => ({
...jest.requireActual('./AddRepositoriesForm'),
useStyles: jest.fn().mockReturnValue({
body: 'body',
approvalTool: 'approvaltool',
approvalToolTooltip: 'approvalToolTooltip',
}),
}));

jest.mock('@janus-idp/shared-react', () => ({
...jest.requireActual('@janus-idp/shared-react'),
useDrawer: jest.fn(),
}));

jest.mock('@material-ui/core', () => ({
...jest.requireActual('@material-ui/core'),
makeStyles: () => () => {
return {
body: 'body',
approvalTool: 'approvaltool',
approvalToolTooltip: 'approvalToolTooltip',
};
},
}));

class MockBulkImportApi {
async getImportAction(
repo: string,
_defaultBranch: string,
): Promise<ImportJobStatus | Response> {
return mockGetImportJobs.find(
i => i.repository.url === repo,
) as ImportJobStatus;
}
}

const mockBulkImportApi = new MockBulkImportApi();

const mockIdentityApi = {
getBackstageIdentity: jest
.fn()
.mockResolvedValue({ userEntityRef: 'user:default/testuser' }),
};

beforeEach(() => {
(useFormikContext as jest.Mock).mockReturnValue({
values: {
repositoryType: RepositorySelection.Repository,
},
setFieldValue: jest.fn(),
});
});

describe('AddRepsositoriesForm', () => {
it('should render the repositories list with the footer', async () => {
(useDrawer as jest.Mock).mockImplementation(initial => ({
initial,
setOpenDrawer: jest.fn(),
setDrawerData: jest.fn(),
}));
render(
<Router>
<TestApiProvider
apis={[
[identityApiRef, mockIdentityApi],
[bulkImportApiRef, mockBulkImportApi],
[
configApiRef,
new MockConfigApi({
catalog: {
import: {
entityFilename: 'test.yaml',
},
},
}),
],
]}
>
<AddRepositoriesForm error={null} />
</TestApiProvider>
</Router>,
);
expect(
screen.getByText('Selected repositories (0)', { exact: false }),
).toBeInTheDocument();
expect(screen.getByTestId('add-repository-footer')).toBeInTheDocument();

expect(screen.queryByTestId('preview-pullrequest-sidebar')).toBeFalsy();
});

it('should show any load errors', async () => {
(useDrawer as jest.Mock).mockReturnValue({
openDrawer: true,
drawerData: mockGetRepositories.repositories[0],
setOpenDrawer: jest.fn(),
setDrawerData: jest.fn(),
});
render(
<Router>
<TestApiProvider
apis={[
[identityApiRef, mockIdentityApi],
[bulkImportApiRef, mockBulkImportApi],
[
configApiRef,
new MockConfigApi({
catalog: {
import: {
entityFilename: 'test.yaml',
},
},
}),
],
]}
>
<AddRepositoriesForm
error={{ message: 'error', title: 'error occurred' }}
/>
</TestApiProvider>
</Router>,
);
expect(screen.getByText('error occurred')).toBeTruthy();
expect(
screen.getByText('Selected repositories (0)', { exact: false }),
).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from 'react';

import { WarningPanel } from '@backstage/core-components';

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

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';
Expand Down Expand Up @@ -47,18 +51,34 @@ export const AddRepositoriesForm = ({
error: { message: string; title: string } | null;
}) => {
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' }}>
<WarningPanel
message={error?.message}
title={error?.title}
severity="error"
/>
<Alert severity="error">
<AlertTitle>{error?.title}</AlertTitle>
{error?.message}
</Alert>
</div>
)}
{/*
Expand Down Expand Up @@ -99,6 +119,15 @@ export const AddRepositoriesForm = ({
<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 @@ -2,8 +2,7 @@ import React from 'react';

import { Link } from '@backstage/core-components';

import { makeStyles } from '@material-ui/core';
import Button from '@mui/material/Button';
import { Button, makeStyles } from '@material-ui/core';
import CircularProgress from '@mui/material/CircularProgress';
import Tooltip from '@mui/material/Tooltip';
import { useFormikContext } from 'formik';
Expand Down Expand Up @@ -36,7 +35,7 @@ const useStyles = makeStyles(theme => ({
paddingTop: '24px',
paddingBottom: '24px',
paddingLeft: '24px',
backgroundColor: theme.palette.background.paper,
backgroundColor: theme.palette.background.default,
width: '100%',
borderTopStyle: 'groove',
border: theme.palette.divider,
Expand Down Expand Up @@ -68,6 +67,7 @@ export const AddRepositoriesFormFooter = () => {
const submitButton = (
<Button
variant="contained"
color="primary"
onClick={handleSubmit as any}
className={styles.createButton}
disabled={disableCreate || isSubmitting}
Expand All @@ -80,7 +80,7 @@ export const AddRepositoriesFormFooter = () => {
);

return (
<div className={styles.footer}>
<div className={styles.footer} data-testid="add-repository-footer">
{toolTipTitle ? (
<Tooltip classes={{ tooltip: styles.tooltip }} title={toolTipTitle}>
<span>{submitButton}</span>
Expand Down
Loading

0 comments on commit 8fa16ff

Please sign in to comment.