frontend/src/group/GroupActions.tsx
2025-04-24 14:48:32 -06:00

199 lines
5.8 KiB
TypeScript

import {
IconButton,
ListItemIcon,
ListItemText,
Menu,
MenuItem,
Theme,
Tooltip
} from "@mui/material";
import { blue } from "@mui/material/colors";
import RemoveSelfIcon from "@mui/icons-material/ExitToApp";
import MoreIcon from "@mui/icons-material/MoreVert";
import GroupSettingsIcon from "@mui/icons-material/Settings";
import ShareObjectIcon from "@mui/icons-material/Share";
import ObjectUsersIcon from "@mui/icons-material/AccountCircle";
import ObjectTeamsIcon from "@mui/icons-material/SupervisedUserCircle";
import GroupSettings from "group/GroupSettings";
import { Device, Group, groupScope } from "models";
import { pond } from "protobuf-ts/pond";
import { useState } from "react";
import ObjectUsers from "user/ObjectUsers";
import RemoveSelfFromObject from "user/RemoveSelfFromObject";
import ShareObject from "user/ShareObject";
import { isOffline } from "utils/environment";
import { makeStyles } from "@mui/styles";
import ObjectTeams from "teams/ObjectTeams";
const useStyles = makeStyles((_theme: Theme) => {
return ({
shareIcon: {
color: blue["500"],
"&:hover": {
color: blue["600"]
}
},
removeIcon: {
color: "var(--status-alert)"
},
red: {
color: "var(--status-alert)"
}
});
});
interface Props {
group: Group;
devices: Device[];
permissions: pond.Permission[];
refreshCallback: () => void;
removeCallback?: () => void;
}
export default function GroupActions(props: Props) {
const classes = useStyles();
const { group, permissions, refreshCallback, devices, removeCallback } = props;
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const [groupSettingsOpen, setGroupSettingsOpen] = useState(false);
const [shareOpen, setShareOpen] = useState(false);
const [usersOpen, setUsersOpen] = useState(false);
const [teamsOpen, setTeamsOpen] = useState(false);
const [removeSelfOpen, setRemoveSelfOpen] = useState(false);
const groupMenu = () => {
const canShare = permissions.includes(pond.Permission.PERMISSION_SHARE);
const canManageUsers = permissions.includes(pond.Permission.PERMISSION_USERS);
const canTeams = canManageUsers;
return (
<Menu
id="groupMenu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
keepMounted
disableAutoFocusItem>
{!isOffline() && canShare && (
<MenuItem
dense
onClick={() => {
setShareOpen(true);
setAnchorEl(null);
}}
>
<ListItemIcon>
<ShareObjectIcon className={classes.shareIcon} />
</ListItemIcon>
<ListItemText primary="Share" />
</MenuItem>
)}
{!isOffline() && canManageUsers && (
<MenuItem
dense
onClick={() => {
setUsersOpen(true);
setAnchorEl(null);
}}
>
<ListItemIcon>
<ObjectUsersIcon />
</ListItemIcon>
<ListItemText primary="Users" />
</MenuItem>
)}
{!isOffline() && canTeams && (
<MenuItem
dense
onClick={() => {
setTeamsOpen(true);
setAnchorEl(null);
}}
>
<ListItemIcon>
<ObjectTeamsIcon />
</ListItemIcon>
<ListItemText primary="Teams" />
</MenuItem>
)}
<MenuItem
dense
onClick={() => {
setRemoveSelfOpen(true);
setAnchorEl(null);
}}
>
<ListItemIcon>
<RemoveSelfIcon className={classes.red} />
</ListItemIcon>
<ListItemText primary="Leave" />
</MenuItem>
</Menu>
);
};
const dialogs = () => {
const hasWritePermission = permissions.includes(pond.Permission.PERMISSION_WRITE);
const key = group.id().toString();
const label = group.name();
return (
<>
<GroupSettings
mode="update"
initialGroup={group}
canEdit={hasWritePermission}
isDialogOpen={groupSettingsOpen}
refreshCallback={refreshCallback}
closeDialogCallback={() => setGroupSettingsOpen(false)}
removeGroupCallback={removeCallback}
groupDevices={devices}
/>
<ShareObject
scope={groupScope(key)}
label={label}
permissions={permissions}
isDialogOpen={shareOpen}
closeDialogCallback={() => setShareOpen(false)}
/>
<ObjectUsers
scope={groupScope(key)}
label={label}
permissions={permissions}
isDialogOpen={usersOpen}
closeDialogCallback={() => setUsersOpen(false)}
refreshCallback={refreshCallback}
/>
<ObjectTeams
scope={groupScope(key)}
label={label}
permissions={permissions}
isDialogOpen={teamsOpen}
closeDialogCallback={() => setTeamsOpen(false)}
refreshCallback={refreshCallback}
/>
<RemoveSelfFromObject
scope={groupScope(key)}
label={label}
isDialogOpen={removeSelfOpen}
closeDialogCallback={() => setRemoveSelfOpen(false)}
/>
</>
);
};
return (
<>
<Tooltip title="Group Settings">
<IconButton onClick={() => setGroupSettingsOpen(true)}>
<GroupSettingsIcon />
</IconButton>
</Tooltip>
<IconButton
aria-owns={anchorEl ? "groupMenu" : undefined}
aria-haspopup="true"
onClick={(event: React.MouseEvent<HTMLButtonElement>) => setAnchorEl(event.currentTarget)}>
<MoreIcon />
</IconButton>
{groupMenu()}
{dialogs()}
</>
);
}