2021-03-11 13:59:20 +01:00
|
|
|
import React, { useEffect, useState } from 'react';
|
2021-05-07 09:14:32 +02:00
|
|
|
import projectApi from '../../store/project/api';
|
2021-03-11 13:59:20 +01:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import {
|
|
|
|
Select,
|
|
|
|
MenuItem,
|
|
|
|
TextField,
|
|
|
|
CircularProgress,
|
|
|
|
InputLabel,
|
|
|
|
FormControl,
|
|
|
|
Grid,
|
|
|
|
Button,
|
|
|
|
InputAdornment,
|
|
|
|
} from '@material-ui/core';
|
2021-06-29 10:21:54 +02:00
|
|
|
import { Search } from '@material-ui/icons';
|
2021-03-11 13:59:20 +01:00
|
|
|
import Autocomplete from '@material-ui/lab/Autocomplete';
|
|
|
|
|
|
|
|
function AddUserComponent({ roles, addUserToRole }) {
|
|
|
|
const [user, setUser] = useState();
|
|
|
|
const [role, setRole] = useState({});
|
|
|
|
const [options, setOptions] = useState([]);
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (roles.length > 0) {
|
2021-05-18 12:13:52 +02:00
|
|
|
const regularRole = roles.find(
|
|
|
|
r => r.name.toLowerCase() === 'regular'
|
|
|
|
);
|
2021-03-11 13:59:20 +01:00
|
|
|
setRole(regularRole || roles[0]);
|
|
|
|
}
|
|
|
|
}, [roles]);
|
|
|
|
|
|
|
|
const search = async q => {
|
|
|
|
if (q.length > 1) {
|
|
|
|
setLoading(true);
|
|
|
|
// TODO: Do not hard-code fetch here.
|
2021-05-07 09:14:32 +02:00
|
|
|
const users = await projectApi.searchProjectUser(q);
|
2021-03-11 13:59:20 +01:00
|
|
|
setOptions([...users]);
|
|
|
|
} else {
|
|
|
|
setOptions([]);
|
|
|
|
}
|
|
|
|
|
|
|
|
setLoading(false);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleQueryUpdate = evt => {
|
|
|
|
const q = evt.target.value;
|
|
|
|
search(q);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleSelectUser = (evt, value) => {
|
|
|
|
setOptions([]);
|
|
|
|
setUser(value);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleRoleChange = evt => {
|
|
|
|
const roleId = +evt.target.value;
|
|
|
|
const role = roles.find(r => r.id === roleId);
|
|
|
|
setRole(role);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleSubmit = async evt => {
|
|
|
|
evt.preventDefault();
|
|
|
|
await addUserToRole(user.id, role.id);
|
|
|
|
setUser(undefined);
|
|
|
|
setOptions([]);
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2021-05-18 12:59:48 +02:00
|
|
|
<Grid container justify="left" spacing={3} alignItems="flex-end">
|
2021-03-11 13:59:20 +01:00
|
|
|
<Grid item>
|
|
|
|
<Autocomplete
|
|
|
|
id="add-user-component"
|
|
|
|
style={{ width: 300 }}
|
|
|
|
noOptionsText="No users found."
|
|
|
|
onChange={handleSelectUser}
|
|
|
|
autoSelect={false}
|
|
|
|
value={user || ''}
|
|
|
|
freeSolo
|
|
|
|
getOptionSelected={() => true}
|
|
|
|
filterOptions={o => o}
|
|
|
|
getOptionLabel={option => {
|
|
|
|
if (option) {
|
2021-05-18 12:13:52 +02:00
|
|
|
return `${option.name || '(Empty name)'} <${
|
|
|
|
option.email || option.username
|
|
|
|
}>`;
|
2021-03-11 13:59:20 +01:00
|
|
|
} else return '';
|
|
|
|
}}
|
|
|
|
options={options}
|
|
|
|
loading={loading}
|
|
|
|
renderInput={params => (
|
|
|
|
<TextField
|
|
|
|
{...params}
|
|
|
|
label="User"
|
2021-05-18 12:59:48 +02:00
|
|
|
variant="outlined"
|
|
|
|
size="small"
|
2021-03-11 13:59:20 +01:00
|
|
|
name="search"
|
|
|
|
onChange={handleQueryUpdate}
|
|
|
|
InputProps={{
|
|
|
|
...params.InputProps,
|
|
|
|
startAdornment: (
|
|
|
|
<InputAdornment position="start">
|
2021-06-29 10:21:54 +02:00
|
|
|
<Search />
|
2021-03-11 13:59:20 +01:00
|
|
|
</InputAdornment>
|
|
|
|
),
|
|
|
|
endAdornment: (
|
|
|
|
<React.Fragment>
|
2021-05-18 12:13:52 +02:00
|
|
|
{loading ? (
|
|
|
|
<CircularProgress
|
|
|
|
color="inherit"
|
|
|
|
size={20}
|
|
|
|
/>
|
|
|
|
) : null}
|
2021-03-11 13:59:20 +01:00
|
|
|
{params.InputProps.endAdornment}
|
|
|
|
</React.Fragment>
|
|
|
|
),
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
/>
|
|
|
|
</Grid>
|
|
|
|
<Grid item>
|
2021-05-18 12:59:48 +02:00
|
|
|
<FormControl
|
|
|
|
variant="outlined"
|
|
|
|
size="small"
|
|
|
|
style={{ minWidth: '125px' }}
|
|
|
|
>
|
|
|
|
<InputLabel
|
|
|
|
style={{ backgroundColor: '#fff' }}
|
|
|
|
id="add-user-select-role-label"
|
|
|
|
>
|
2021-05-18 12:13:52 +02:00
|
|
|
Role
|
|
|
|
</InputLabel>
|
2021-03-11 13:59:20 +01:00
|
|
|
<Select
|
|
|
|
labelId="add-user-select-role-label"
|
|
|
|
id="add-user-select-role"
|
|
|
|
placeholder="Project role"
|
|
|
|
value={role.id || ''}
|
|
|
|
onChange={handleRoleChange}
|
|
|
|
>
|
|
|
|
{roles.map(role => (
|
|
|
|
<MenuItem key={role.id} value={role.id}>
|
|
|
|
{role.name}
|
|
|
|
</MenuItem>
|
|
|
|
))}
|
|
|
|
</Select>
|
|
|
|
</FormControl>
|
|
|
|
</Grid>
|
|
|
|
<Grid item>
|
2021-05-18 12:13:52 +02:00
|
|
|
<Button
|
|
|
|
variant="contained"
|
|
|
|
color="primary"
|
|
|
|
disabled={!user}
|
|
|
|
onClick={handleSubmit}
|
|
|
|
>
|
2021-03-11 13:59:20 +01:00
|
|
|
Add user
|
|
|
|
</Button>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
);
|
|
|
|
}
|
2021-05-18 12:13:52 +02:00
|
|
|
|
2021-03-11 13:59:20 +01:00
|
|
|
AddUserComponent.propTypes = {
|
|
|
|
roles: PropTypes.array.isRequired,
|
|
|
|
addUserToRole: PropTypes.func.isRequired,
|
|
|
|
};
|
|
|
|
|
|
|
|
export default AddUserComponent;
|