Skip to content

Commit

Permalink
feat(bulk-import): allow user to select repositories from side panel
Browse files Browse the repository at this point in the history
Signed-off-by: Yi Cai <yicai@redhat.com>
  • Loading branch information
ciiay committed Apr 11, 2024
1 parent b357c09 commit 0f02310
Show file tree
Hide file tree
Showing 12 changed files with 862 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React, { useState } from 'react';

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

import {
Button,
Card,
Container,
Drawer,
IconButton,
makeStyles,
Typography,
} from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';
import OpenInNewIcon from '@mui/icons-material/OpenInNew';

import { AddRepositoriesData, AddRepositoriesFormValues } from '../../types';
import { filterSelectedForActiveDrawer } from '../../utils/repository-utils';
import { AddRepositoriesTableToolbar } from './AddRepositoriesTableToolbar';
import { OrganizationRepositoriesTable } from './OrganizationRepositoriesTable';

type AddRepositoriesDrawerProps = {
open: boolean;
onClose: () => void;
onSelect: (ids: number[]) => void;
title: string;
data: AddRepositoriesData;
selectedRepositoriesFormData: AddRepositoriesFormValues;
checkedRepos: number[];
};

const useStyles = makeStyles(theme => ({
createButton: {
marginRight: theme.spacing(1),
},
sidePanelfooter: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'right',
marginTop: theme.spacing(2),
position: 'fixed',
bottom: '20px',
},
}));

export const AddRepositoriesDrawer = ({
open,
onClose,
onSelect,
title,
data,
selectedRepositoriesFormData,
checkedRepos,
}: AddRepositoriesDrawerProps) => {
const classes = useStyles();
const [searchString, setSearchString] = useState<string>('');

const [selectedReposID, setSelectedReposID] =
useState<number[]>(checkedRepos);

const handleCallback = (ids: number[]) => {
setSelectedReposID(ids);
};

const handleSelecRepoFromDrawer = (selected: number[]) => {
onSelect(selected);
onClose();
};

const selectedForActiveDrawer = React.useMemo(
() => filterSelectedForActiveDrawer(data, selectedReposID),
[data?.repositories, selectedReposID],
);

return (
<Drawer anchor="right" open={open}>
<Container
style={{
padding: '20px',
height: '100%',
display: 'flex',
flexDirection: 'column',
}}
>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div>
<Typography variant="h5">{data?.name}</Typography>
<Link to={data?.url}>
{data?.url}
<OpenInNewIcon
style={{ verticalAlign: 'sub', paddingTop: '7px' }}
/>
</Link>
</div>
<div>
<IconButton onClick={onClose} className="align-right">
<CloseIcon />
</IconButton>
</div>
</div>
<Card style={{ marginTop: '20px', marginBottom: '60px' }}>
<AddRepositoriesTableToolbar
title={title}
setSearchString={setSearchString}
selectedReposFromDrawer={selectedReposID}
selectedRepositoriesFormData={selectedRepositoriesFormData}
activeOrganization={data}
/>
<OrganizationRepositoriesTable
searchString={searchString}
activeOrganization={data}
selectedRepos={selectedReposID}
updateSelectedRepos={handleCallback}
/>
</Card>
<div className={classes.sidePanelfooter}>
<span>
<Button
variant="contained"
color="primary"
onClick={() => handleSelecRepoFromDrawer(selectedReposID)}
className={classes.createButton}
disabled={selectedForActiveDrawer.length === 0}
aria-labelledby="select-from-drawer"
>
Select
</Button>
</span>
<span>
<Button
aria-labelledby="cancel-drawer-select"
variant="outlined"
onClick={onClose}
>
Cancel
</Button>
</span>
</div>
</Container>
</Drawer>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import { FormikErrors } from 'formik';

import { AddRepositoriesFormValues } from '../../types';
import { getRepositoriesSelected } from '../../utils/repository-utils';
import { AddRepositoriesData, AddRepositoriesFormValues } from '../../types';
import { RepositoriesSearchBar } from './AddRepositoriesSearchBar';

export const AddRepositoriesTableToolbar = ({
Expand All @@ -16,24 +15,29 @@ export const AddRepositoriesTableToolbar = ({
selectedRepositoriesFormData,
setFieldValue,
onPageChange,
activeOrganization,
selectedReposFromDrawer,
}: {
title: string;
setSearchString: (str: string) => void;
selectedRepositoriesFormData: AddRepositoriesFormValues;
setFieldValue: (
setFieldValue?: (
field: string,
value: any,
shouldValidate?: boolean,
) => Promise<FormikErrors<AddRepositoriesFormValues>> | Promise<void>;
onPageChange: (page: number) => void;
onPageChange?: (page: number) => void;
activeOrganization?: AddRepositoriesData;
selectedReposFromDrawer?: number[];
}) => {
const [selection, setSelection] = React.useState('repository');
const [search, setSearch] = React.useState<string>('');
const [selectedReposNumber, setSelectedReposNumber] = React.useState(0);
const handleToggle = (
_event: React.MouseEvent<HTMLElement>,
type: string,
) => {
if (type) {
if (type && setFieldValue && onPageChange) {
setSelection(type);
setFieldValue('repositoryType', type);
onPageChange(0);
Expand All @@ -45,6 +49,23 @@ export const AddRepositoriesTableToolbar = ({
setSearch(filter);
};

React.useEffect(() => {
if (activeOrganization && selectedReposFromDrawer) {
const thisSelectedReposCount = activeOrganization.repositories?.filter(
repo => selectedReposFromDrawer.includes(repo.id) && repo.id > -1,
).length;
setSelectedReposNumber(thisSelectedReposCount || 0);
} else {
setSelectedReposNumber(
selectedRepositoriesFormData.repositories?.length || 0,
);
}
}, [
selectedReposFromDrawer,
selectedRepositoriesFormData,
activeOrganization,
]);

return (
<Toolbar
sx={{
Expand All @@ -54,19 +75,21 @@ export const AddRepositoriesTableToolbar = ({
}}
>
<Typography sx={{ flex: '1 1 100%' }} variant="h5" id={title}>
{`${title} (${getRepositoriesSelected(selectedRepositoriesFormData)})`}
{`${title} (${selectedReposNumber})`}
</Typography>
<ToggleButtonGroup
size="medium"
color="primary"
value={selection}
exclusive
onChange={handleToggle}
aria-label="repository-type"
>
<ToggleButton value="repository">Repositories</ToggleButton>
<ToggleButton value="organization">Organization</ToggleButton>
</ToggleButtonGroup>
{!activeOrganization && (
<ToggleButtonGroup
size="medium"
color="primary"
value={selection}
exclusive
onChange={handleToggle}
aria-label="repository-type"
>
<ToggleButton value="repository">Repositories</ToggleButton>
<ToggleButton value="organization">Organization</ToggleButton>
</ToggleButtonGroup>
)}
<RepositoriesSearchBar value={search} onChange={handleSearch} />
</Toolbar>
);
Expand Down
Loading

0 comments on commit 0f02310

Please sign in to comment.