added the sites page and all other required imports for it to work, also fixed the map card

This commit is contained in:
csawatzky 2025-04-03 12:54:00 -06:00
parent c5afdc2c3d
commit 3990dfbf4f
14 changed files with 1595 additions and 21 deletions

319
src/jobsite/SiteActions.tsx Normal file
View file

@ -0,0 +1,319 @@
import {
Button,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
ListItemIcon,
ListItemText,
Menu,
MenuItem,
TextField,
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 ShareObjectIcon from "@mui/icons-material/Share";
import ObjectUsersIcon from "@mui/icons-material/AccountCircle";
import ObjectTeamsIcon from "@mui/icons-material/SupervisedUserCircle";
import { pond } from "protobuf-ts/pond";
import React, { useState } from "react";
import ObjectUsers from "user/ObjectUsers";
import RemoveSelfFromObject from "user/RemoveSelfFromObject";
import ShareObject from "user/ShareObject";
import { isOffline } from "utils/environment";
import ObjectTeams from "teams/ObjectTeams";
import { siteScope, Site } from "models";
import ResponsiveDialog from "common/ResponsiveDialog";
import { useSiteAPI } from "providers";
import { useSnackbar } from "hooks";
import GroupSettingsIcon from "@mui/icons-material/Settings";
import { makeStyles } from "@mui/styles";
const useStyles = makeStyles((theme: Theme) => ({
shareIcon: {
color: blue["500"],
"&:hover": {
color: blue["600"]
}
},
removeIcon: {
color: "var(--status-alert)"
},
red: {
color: "var(--status-alert)"
}
}));
interface Props {
site: Site;
permissions: pond.Permission[];
refreshCallback: () => void;
}
interface OpenState {
share: boolean;
users: boolean;
teams: boolean;
settings: boolean;
removeSelf: boolean;
}
export default function SiteActions(props: Props) {
const classes = useStyles();
const { site, permissions, refreshCallback } = props;
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const [siteDialog, setSiteDialog] = useState(false);
const [deleteConfirmation, setDeleteConfirmation] = useState(false);
const siteAPI = useSiteAPI();
const [siteName, setSiteName] = useState(site.siteName());
const [update, setUpdate] = useState(false);
const { openSnack } = useSnackbar();
const [openState, setOpenState] = useState<OpenState>({
share: false,
users: false,
teams: false,
settings: false,
removeSelf: false
});
const groupMenu = () => {
const canShare = permissions.includes(pond.Permission.PERMISSION_SHARE);
const canManageUsers = permissions.includes(pond.Permission.PERMISSION_USERS);
return (
<Menu
id="groupMenu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
keepMounted
disableAutoFocusItem>
{!isOffline() && canShare && (
<MenuItem
dense
onClick={() => {
setOpenState({ ...openState, share: true });
setAnchorEl(null);
}}>
<ListItemIcon>
<ShareObjectIcon className={classes.shareIcon} />
</ListItemIcon>
<ListItemText primary="Share" />
</MenuItem>
)}
{!isOffline() && canManageUsers && (
<MenuItem
dense
onClick={() => {
setOpenState({ ...openState, users: true });
setAnchorEl(null);
}}>
<ListItemIcon>
<ObjectUsersIcon />
</ListItemIcon>
<ListItemText primary="Users" />
</MenuItem>
)}
{!isOffline() && canManageUsers && (
<MenuItem
dense
onClick={() => {
setOpenState({ ...openState, teams: true });
setAnchorEl(null);
}}>
<ListItemIcon>
<ObjectTeamsIcon />
</ListItemIcon>
<ListItemText primary="Teams" />
</MenuItem>
)}
<MenuItem
dense
onClick={() => {
setOpenState({ ...openState, removeSelf: true });
setAnchorEl(null);
}}>
<ListItemIcon>
<RemoveSelfIcon className={classes.red} />
</ListItemIcon>
<ListItemText primary="Leave" />
</MenuItem>
</Menu>
);
};
const dialogs = () => {
const key = site.key();
const label = site.siteName();
return (
<React.Fragment>
<ShareObject
scope={siteScope(key)}
label={label}
permissions={permissions}
isDialogOpen={openState.share}
closeDialogCallback={() => setOpenState({ ...openState, share: false })}
/>
<ObjectUsers
scope={siteScope(key)}
label={label}
permissions={permissions}
isDialogOpen={openState.users}
closeDialogCallback={() => setOpenState({ ...openState, users: false })}
refreshCallback={refreshCallback}
/>
<RemoveSelfFromObject
scope={siteScope(key)}
label={label}
isDialogOpen={openState.removeSelf}
closeDialogCallback={() => setOpenState({ ...openState, removeSelf: false })}
/>
{dialogForSite()}
{deleteDialog()}
</React.Fragment>
);
};
const closeSiteDialog = () => {
setSiteDialog(false);
setUpdate(false);
};
const updateSite = () => {
let newSite = site;
newSite.settings.siteName = siteName;
siteAPI
.updateSite(newSite.key(), newSite.settings)
.then(resp => {
openSnack("Site Updated");
closeSiteDialog();
})
.catch(err => {
openSnack("Could Not Update Site");
closeSiteDialog();
});
};
//deletes a site from the DB and removes the coordinates of that site from the array
const deleteSite = () => {
siteAPI
.removeSite(site.key())
.then(resp => {
openSnack("Site has been removed");
closeSiteDialog();
})
.catch(err => {
openSnack("Site could not be removed");
});
};
const openUpdate = () => {
setUpdate(true);
setSiteDialog(true);
};
const deleteDialog = () => {
return (
<ResponsiveDialog
fullWidth
open={deleteConfirmation}
onClose={() => {
setDeleteConfirmation(false);
}}>
<DialogTitle>Delete Site</DialogTitle>
<DialogContent>Are you sure you wish to delete {site.siteName()}</DialogContent>
<DialogActions>
<Button
onClick={() => {
setDeleteConfirmation(false);
}}
color="primary">
Cancel
</Button>
<Button onClick={deleteSite} style={{ color: "red" }}>
Confirm
</Button>
</DialogActions>
</ResponsiveDialog>
);
};
//dialog the renders the forms for creating a new site
const dialogForSite = () => {
return (
<ResponsiveDialog fullWidth fullScreen={false} open={siteDialog} onClose={closeSiteDialog}>
<DialogTitle>Enter Name of Site</DialogTitle>
<DialogContent>
<TextField
value={siteName}
color="primary"
autoFocus
margin="dense"
id="name"
label="Site Name"
type="text"
fullWidth
onChange={e => setSiteName(e.target.value)}
/>
</DialogContent>
{update ? (
<DialogActions>
<Button
onClick={() => {
setDeleteConfirmation(true);
}}
style={{ color: "red" }}>
Delete Site
</Button>
<Button onClick={updateSite} color="primary">
Update Site
</Button>
</DialogActions>
) : (
<DialogActions>
<Button onClick={closeSiteDialog} color="primary">
Cancel
</Button>
{/* <Button onClick={saveSite} color="primary" disabled={siteName === ""}>
Add Site
</Button> */}
</DialogActions>
)}
</ResponsiveDialog>
);
};
return (
<React.Fragment>
{permissions.includes(pond.Permission.PERMISSION_WRITE) && (
<Tooltip title="Jobsite Settings">
<IconButton
onClick={() => {
openUpdate();
}}>
<GroupSettingsIcon />
</IconButton>
</Tooltip>
)}
<IconButton
aria-owns={anchorEl ? "groupMenu" : undefined}
aria-haspopup="true"
onClick={(event: React.MouseEvent<HTMLButtonElement>) => setAnchorEl(event.currentTarget)}>
<MoreIcon />
</IconButton>
{groupMenu()}
{dialogs()}
<ObjectTeams
scope={siteScope(site.key())}
label="Teams"
permissions={permissions}
isDialogOpen={openState.teams}
refreshCallback={refreshCallback}
closeDialogCallback={() => setOpenState({ ...openState, teams: false })}
/>
</React.Fragment>
);
}