Skip to content
Merged
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
47 changes: 39 additions & 8 deletions web-ui/src/components/member_selector/MemberSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@ import {
Avatar,
Card,
CardHeader, Collapse,
Divider,
IconButton,
List,
ListItem,
ListItemAvatar,
ListItemText,
ListItemAvatar, ListItemIcon,
ListItemText, Menu, MenuItem,
Tooltip,
Typography
} from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
import RemoveIcon from "@mui/icons-material/Remove";
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import HighlightOffIcon from "@mui/icons-material/HighlightOff";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import {getAvatarURL} from "../../api/api";

import "./MemberSelector.css";
import MemberSelectorDialog from "./member_selector_dialog/MemberSelectorDialog";
import Divider from "@mui/material/Divider";

import "./MemberSelector.css";

const propTypes = {
onChange: PropTypes.func,
Expand All @@ -33,6 +36,7 @@ const MemberSelector = ({ onChange, listHeight, className, style }) => {
const [selectedMembers, setSelectedMembers] = useState([]);
const [dialogOpen, setDialogOpen] = useState(false);
const [expanded, setExpanded] = useState(true);
const [menuAnchor, setMenuAnchor] = useState(null);

useEffect(() => {
if (onChange) {
Expand All @@ -53,6 +57,10 @@ const MemberSelector = ({ onChange, listHeight, className, style }) => {
setSelectedMembers(selected);
}, [selectedMembers]);

const clearMembers = useCallback(() => {
setSelectedMembers([]);
}, []);

return (
<>
<Card
Expand All @@ -71,11 +79,34 @@ const MemberSelector = ({ onChange, listHeight, className, style }) => {
</div>
}
action={
<Tooltip title="Add members" arrow>
<IconButton style={{ margin: "4px 8px 0 0" }} onClick={() => setDialogOpen(true)}>
<AddIcon/>
<>
<Tooltip title="Add members" arrow>
<IconButton style={{ margin: "4px 8px 0 0" }} onClick={() => setDialogOpen(true)}>
<AddIcon/>
</IconButton>
</Tooltip>
<IconButton style={{ margin: "4px 8px 0 0" }} onClick={(event) => setMenuAnchor(event.currentTarget)}>
<MoreVertIcon/>
</IconButton>
</Tooltip>
<Menu
anchorEl={menuAnchor}
open={!!menuAnchor}
onClose={() => setMenuAnchor(null)}
>
<MenuItem
onClick={() => {
setMenuAnchor(null);
clearMembers();
}}
disabled={!selectedMembers.length}
>
<ListItemIcon>
<HighlightOffIcon fontSize="small"/>
</ListItemIcon>
<ListItemText>Remove all</ListItemText>
</MenuItem>
</Menu>
</>
}
/>
<Collapse in={expanded}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,27 @@ exports[`renders correctly 1`] = `
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
<button
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeMedium css-78trlr-MuiButtonBase-root-MuiIconButton-root"
style="margin: 4px 8px 0px 0px;"
tabindex="0"
type="button"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root"
data-testid="MoreVertIcon"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2m0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2"
/>
</svg>
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
</div>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import {AppContext} from "../../../context/AppContext";
import {
selectCsrfToken,
selectCurrentMembers,
selectGuilds,
selectGuilds, selectMappedUserRoles, selectRoles,
selectSkills, selectSubordinates, selectSupervisors, selectTeamMembersBySupervisorId,
selectTeams
selectTeams,
} from "../../../context/selectors";
import {UPDATE_TOAST} from "../../../context/actions";
import {getMembersByTeam} from "../../../api/team";
Expand All @@ -50,6 +50,7 @@ const FilterType = Object.freeze({
TEAM: "Team",
TITLE: "Title",
LOCATION: "Location",
ROLE: "Role",
SKILL: "Skill",
MANAGER: "Manager",
});
Expand Down Expand Up @@ -135,6 +136,13 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => {
label: (location) => location,
equals: (location1, location2) => location1 === location2
};
case FilterType.ROLE:
const roles = selectRoles(state);
return {
options: roles,
label: (role) => role.role,
equals: (role1, role2) => role1.id === role2.id
};
case FilterType.SKILL:
let skills = selectSkills(state);
return {
Expand Down Expand Up @@ -211,6 +219,12 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => {
case FilterType.LOCATION:
filteredMemberList = filteredMemberList.filter(member => member.location === filter);
break;
case FilterType.ROLE:
const mappedUserRoles = selectMappedUserRoles(state);
filteredMemberList = filteredMemberList.filter(member =>
member.id in mappedUserRoles && mappedUserRoles[member.id].has(filter.role)
);
break;
case FilterType.SKILL:
const skillId = filter.id;
const skillRes = await getSkillMembers(skillId, csrf);
Expand Down Expand Up @@ -382,7 +396,7 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => {
/>
</FormGroup>
<Divider/>
<List dense role="list" sx={{ maxHeight: "80vh", overflow: "auto" }}>
<List dense role="list" sx={{ height: "85%", overflowY: "scroll" }}>
{selectableMembers.map(member => (
<ListItem
key={member.id}
Expand All @@ -405,6 +419,7 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => {
</ListItem>
))}
</List>
<Divider/>
</DialogContent>
</Dialog>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,12 @@ exports[`MemberSelectorDialog > renders correctly 1`] = `
class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
/>
<ul
class="MuiList-root MuiList-padding MuiList-dense css-2ltt2v-MuiList-root"
class="MuiList-root MuiList-padding MuiList-dense css-1vjk1cp-MuiList-root"
role="list"
/>
<hr
class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
/>
</div>
</div>
</div>
Expand Down
21 changes: 21 additions & 0 deletions web-ui/src/pages/__snapshots__/TeamSkillReportPage.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,27 @@ exports[`renders correctly 1`] = `
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
<button
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeMedium css-78trlr-MuiButtonBase-root-MuiIconButton-root"
style="margin: 4px 8px 0px 0px;"
tabindex="0"
type="button"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root"
data-testid="MoreVertIcon"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2m0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2"
/>
</svg>
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
</div>
</div>
<div
Expand Down