imported binyard stuff

This commit is contained in:
Carter 2025-03-20 11:09:33 -06:00
parent 8d2d9ea0e7
commit 906fe44ab5
5 changed files with 806 additions and 12 deletions

792
src/bin/BinYards.tsx Normal file
View file

@ -0,0 +1,792 @@
import {
AppBar,
Button,
CircularProgress,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Grid,
ListItemIcon,
ListItemText,
Menu,
MenuItem,
Tab,
Tabs,
TextField,
Theme,
Tooltip,
Typography,
useTheme
} from "@mui/material";
import { pond } from "protobuf-ts/pond";
import {
useBinYardAPI,
useSnackbar,
//useUserAPI,
usePermissionAPI,
useBinAPI,
useGlobalState
//useTeamAPI
} from "providers";
import React, { useEffect, useState } from "react";
import AddIcon from "@mui/icons-material/LibraryAdd";
import ResponsiveDialog from "common/ResponsiveDialog";
import { MoreVert, Search } from "@mui/icons-material";
import DeleteIcon from "@mui/icons-material/Delete";
import RemoveSelfIcon from "@mui/icons-material/ExitToApp";
import KeyboardArrowLeftIcon from "@mui/icons-material/KeyboardArrowLeft";
import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight";
import ObjectUsersIcon from "@mui/icons-material/SupervisedUserCircle";
import EditIcon from "@mui/icons-material/Edit";
import ShareIcon from "@mui/icons-material/Share";
import { red, blue, green } from "@mui/material/colors";
import { openSnackbar } from "providers/Snackbar";
// import { Status } from "@sentry/react";
import { binScope, binYardScope } from "models/Scope";
import ShareObject from "user/ShareObject";
import { Bin, Team, User } from "models";
import { Dictionary } from "lodash";
import ObjectUsers from "user/ObjectUsers";
import ObjectTeams from "teams/ObjectTeams";
import { GrainBag } from "models/GrainBag";
import { makeStyles } from "@mui/styles";
const parentTab = {
"&": {
margin: "0px",
marginTop: "4px",
marginLeft: "4px",
animationDuration: "10s",
background: "rgba(150, 150, 150, 0)",
borderRadius: "-5px",
borderTopLeftRadius: "6px",
borderTopRightRadius: "6px"
},
"&:hover": {
background: "linear-gradient(rgba(150, 150, 150, 0.2), rgba(150, 150, 150, 0))"
}
};
const useStyles = makeStyles((theme: Theme) => {
return ({
red: {
marginRight: 0,
paddingRight: 0,
color: red["500"],
"&:hover": {
color: red["600"]
}
},
blue: {
marginRight: 0,
paddingRight: 0,
color: blue["500"],
"&:hover": {
color: blue["600"]
}
},
green: {
marginRight: 0,
paddingRight: 0,
color: green["500"],
"&:hover": {
color: green["600"]
}
},
searchTab: {
...parentTab,
width: theme.spacing(8),
minWidth: theme.spacing(8),
left: 0,
height: "100%",
background: theme.palette.background.paper
},
searchTabExpanded: {
...parentTab,
width: theme.spacing(30),
minWidth: theme.spacing(30),
left: 0,
height: "100%",
background: theme.palette.background.paper
},
tab: {
...parentTab,
width: theme.spacing(20),
minWidth: theme.spacing(20),
left: 0,
height: "100%",
background: theme.palette.background.paper
},
smallTab: {
...parentTab,
width: theme.spacing(8),
minWidth: theme.spacing(8),
background: theme.palette.background.paper
},
selectedTab: {
borderRadius: "-5px",
borderTopLeftRadius: "6px",
borderTopRightRadius: "6px",
background: theme.palette.background.default,
"&:hover": {
background:
"linear-gradient(rgba(150, 150, 150, 0.3)," + theme.palette.background.default + " 80%)"
}
},
icon: {
display: "flex",
position: "absolute",
right: 0,
top: 6,
padding: 6,
marginRight: "2px",
width: 36,
height: 36,
borderRadius: "18px",
background: "rgba(0,0,0,0)",
"&:hover": {
background:
"radial-gradient(closest-side, rgba(150, 150, 150, 0.5) 50%, rgba(150, 150, 150, 0.5))"
}
},
tabText: {
position: "absolute",
left: theme.spacing(2),
color: "transparent",
textAlign: "left",
width: "80%",
backgroundImage: "linear-gradient(to right, white 70%, rgba(200, 200, 200, 0) 87.5%)",
backgroundClip: "text",
WebkitBackgroundClip: "text",
overflowX: "hidden",
whiteSpace: "nowrap",
top: 12
}
});
});
interface Props {
setYardFilter: React.Dispatch<React.SetStateAction<string>>;
loadBins: () => void;
loadYards: (search?: string, limit?: number, offset?: number) => void;
yardsLoading: boolean;
tab?: number;
yards?: pond.BinYardSettings[];
yardPerms?: Dictionary<pond.Permission[]>;
showTabs?: boolean;
bins: Bin[];
grainBags: GrainBag[];
setShowing: (showing: "all" | "bins" | "bags") => void;
}
export default function BinYard(props: Props) {
const { setYardFilter, loadBins, loadYards, grainBags, setShowing, yardsLoading } = props;
const binYardAPI = useBinYardAPI();
const binAPI = useBinAPI();
// const userAPI = useUserAPI();
// const teamAPI = useTeamAPI();
const [tab, setTab] = useState<number>(props.tab ? props.tab : 1);
const [showAddYard, setShowAddYard] = useState<boolean>(false);
const [addYardName, setAddYardName] = useState<string>("");
const [addYardDescription, setAddYardDescription] = useState<string>("");
const [binYards, setBinYards] = useState<pond.BinYardSettings[]>(props.yards ? props.yards : []);
const [menuAnchorEl, setMenuAnchorEl] = useState<Element | null>(null);
const [yardIndex, setYardIndex] = useState<number>(0);
const [tabClick, setTabClick] = useState<boolean>(true);
const [shareDialog, setShareDialog] = useState<boolean>(false);
const [userDialog, setUserDialog] = useState<boolean>(false);
const [teamDialog, setTeamDialog] = useState<boolean>(false);
const [openUpdateYardDialog, setOpenUpdateYardDialog] = useState(false);
const { error, warning, success } = useSnackbar();
const theme = useTheme();
const classes = useStyles();
const [leaveYardDialogOpen, setLeaveYardDialogOpen] = useState<boolean>(false);
const permissionAPI = usePermissionAPI();
const [leaving, setLeaving] = useState<boolean>(false);
const [yardPermissions, setYardPermissions] = useState<Dictionary<pond.Permission[]>>({});
const [searchSelected, setSearchSelected] = useState(false);
const [{ user, as }] = useGlobalState();
useEffect(() => {
if (props.yards && props.yardPerms) {
setBinYards(props.yards);
setYardPermissions(props.yardPerms);
return;
}
}, [props.yards, props.yardPerms]);
// useEffect(() => {
// if (props.tab && binYards.length > 1) {
// setYardFilter(binYards[props.tab - 1].key);
// }
// }, [props.tab, binYards, setYardFilter, loadYards]);
const tabChange = (i: number) => {
if (tab === i) return;
if (i === binYards.length + 2) return;
if (tabClick !== true) return;
setTab(i);
setYardFilter("");
if (i > 1 && i <= binYards.length + 1) {
setYardFilter(binYards[i - 2].key);
}
};
const submitYard = () => {
let newBinYard = pond.BinYardSettings.create();
newBinYard.name = addYardName;
newBinYard.description = addYardDescription;
newBinYard.owner = user.id();
newBinYard.userSort[user.id()] = binYards.length + 1;
binYardAPI
.addBinYard(newBinYard)
.then(_resp => {
loadYards();
setShowAddYard(false);
openSnackbar("success", "Bin Yard created :)");
})
.catch(_err => {
error("Could not add bin yard");
});
};
const updateYard = () => {
let newBinYard = binYards[yardIndex];
newBinYard.name = addYardName;
newBinYard.description = addYardDescription;
binYardAPI
.updateBinYard(newBinYard.key, newBinYard)
.then(_resp => {
loadYards();
openSnackbar("success", "Bin Yard updated");
setOpenUpdateYardDialog(false);
})
.catch(_err => {
error("Could not update bin yard");
setOpenUpdateYardDialog(false);
});
};
const yardForm = () => {
return (
<DialogContent>
<DialogContentText style={{ paddingBottom: theme.spacing(0) }}>
Bin yards allow you to organise your bins by tab. Bins created while a bin yard tab is
opened will automatically be added to that bin yard. You may also choose a yard for a bin
in the bin settings page.
</DialogContentText>
<TextField
label={"Yard Name"}
value={addYardName}
onChange={event => setAddYardName(event.target.value)}
style={{ marginTop: theme.spacing(0) }}
fullWidth
variant="outlined"
/>
<DialogContentText
style={{ paddingBottom: theme.spacing(0), paddingTop: theme.spacing(3) }}>
Bin yard description (optional):
</DialogContentText>
<TextField
label={"Description"}
value={addYardDescription}
onChange={event => setAddYardDescription(event.target.value)}
style={{ marginTop: theme.spacing(0) }}
fullWidth
variant="outlined"
/>
</DialogContent>
);
};
const addYardDialog = () => {
return (
<ResponsiveDialog open={showAddYard} onClose={() => setShowAddYard(false)}>
<DialogTitle>Create New Bin Yard</DialogTitle>
{yardForm()}
<DialogActions>
<Button
onClick={() => {
setShowAddYard(false);
}}
color="primary">
Cancel
</Button>
<Button onClick={submitYard} color="primary">
Submit
</Button>
</DialogActions>
</ResponsiveDialog>
);
};
const updateYardDialog = () => {
return (
<ResponsiveDialog open={openUpdateYardDialog} onClose={() => setOpenUpdateYardDialog(false)}>
<DialogTitle>Update Bin Yard</DialogTitle>
{yardForm()}
<DialogActions>
<Button
onClick={() => {
setOpenUpdateYardDialog(false);
}}
color="primary">
Cancel
</Button>
<Button onClick={updateYard} color="primary">
Update
</Button>
</DialogActions>
</ResponsiveDialog>
);
};
const deleteYard = (index: number) => {
let newBinYards = binYards;
binYardAPI
.removeBinYard(binYards[index].key)
.then(resp => {
newBinYards.splice(index, 1);
if (index + 1 === tab) {
tabChange(0);
} else if (index + 1 < tab) {
tabChange(tab - 1);
}
setBinYards([...newBinYards]);
})
.catch(err => {
error("Failed to delete bin yard");
});
};
const moveLeft = (index: number) => {
let key = as ? as : user.id();
if (binYards[index - 1]) {
let left = binYards[index - 1].userSort[key] ?? index - 1;
let right = binYards[index].userSort[key] ?? index;
let binLeft = binYards[index - 1];
let binRight = binYards[index];
binLeft.userSort[key] = right;
binRight.userSort[key] = left;
if (binRight.userSort[key] >= binLeft.userSort[key]) {
binLeft.userSort[key] = binRight.userSort[key] + 1;
}
let leftPromise = binYardAPI.updateBinYard(binLeft.key, binLeft, true);
let rightPromise = binYardAPI.updateBinYard(binRight.key, binRight, true);
Promise.all([leftPromise, rightPromise]).then((/*[leftResp, rightResp]*/) => {
loadYards();
if (index === tab - 1) setTab(tab - 1);
if (index === tab) setTab(tab + 1);
});
}
};
const moveRight = (index: number) => {
let key = as ? as : user.id();
if (binYards[index + 1]) {
let left = binYards[index].userSort[key] ?? index;
let right = binYards[index + 1].userSort[key] ?? index + 1;
let binLeft = binYards[index];
let binRight = binYards[index + 1];
binLeft.userSort[key] = right;
binRight.userSort[key] = left;
if (binRight.userSort[key] <= binLeft.userSort[key]) {
binRight.userSort[key] = binLeft.userSort[key] - 1;
}
let leftPromise = binYardAPI.updateBinYard(binLeft.key, binLeft, true);
let rightPromise = binYardAPI.updateBinYard(binRight.key, binRight, true);
Promise.all([leftPromise, rightPromise]).then((/*[leftResp, rightResp]*/) => {
loadYards();
if (index === tab - 1) setTab(tab + 1);
if (index === tab - 2) setTab(tab - 1);
});
}
};
const openShareDialog = () => {
setShareDialog(true);
};
const leaveYardDialog = () => {
if (!binYards[yardIndex]) return;
let label = binYards[yardIndex].name;
return (
<Dialog
open={leaveYardDialogOpen}
onClose={() => setLeaveYardDialogOpen(false)}
aria-labelledby="remove-self-from-object">
<DialogTitle id="remove-self-from-object">{"Leave " + label + "?"}</DialogTitle>
<DialogContent>
<Typography color="textSecondary" align="left" variant="subtitle1">
You will no longer be able to access {label}. You will also lose access to all bins in{" "}
{label} that you do not own.
</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setLeaveYardDialogOpen(false)} color="primary">
Cancel
</Button>
<Button onClick={leaveYard} color="primary" autoFocus>
Leave
</Button>
</DialogActions>
</Dialog>
);
};
const leaveYard = () => {
updateYardPermissions();
};
const updateYardPermissions = (users?: User[] | Team[]) => {
if (leaving) return;
setLeaving(true);
let binSuccess = true;
setLeaving(true);
binAPI.listBins(150, 0, "asc", "name", binYards[yardIndex].key).then(resp => {
resp.data.bins.forEach(bin => {
if (bin.settings) {
let scope = binScope(bin.settings?.key);
users = users
? users
: [
User.create(
pond.User.create({
settings: pond.UserSettings.create({
id: user.id()
}),
permissions: []
})
)
];
permissionAPI.updatePermissions(scope, users).catch(_ => {
binSuccess = false;
});
}
});
});
if (binSuccess) {
let scope = binYardScope(binYards[yardIndex].key);
let label = binYards[yardIndex].name;
users = users
? users
: [
User.create(
pond.User.create({
settings: pond.UserSettings.create({
id: user.id()
}),
permissions: []
})
)
];
permissionAPI
.updatePermissions(scope, users)
.then((response: any) => {
success("Successfully updated permissions for " + label);
setLeaveYardDialogOpen(false);
loadYards();
loadBins();
tabChange(0);
})
.catch((err: any) => {
err.response.data.error
? warning(err.response.data.error)
: error("Error occured when updating permissions for " + label);
setLeaveYardDialogOpen(false);
})
.finally(() => {
setLeaving(false);
});
} else {
error("Error updating permissions on one or more bins");
setLeaving(false);
}
};
const yardMenu = () => {
let permissions: pond.Permission[] = [];
if (binYards[yardIndex] === undefined) return;
if (yardPermissions[binYards[yardIndex].key] !== undefined) {
permissions = yardPermissions[binYards[yardIndex].key];
}
return (
<Menu
id="yardMenu"
anchorEl={menuAnchorEl ? menuAnchorEl : null}
open={menuAnchorEl !== null}
onClose={() => {
setMenuAnchorEl(null);
}}
disableAutoFocusItem>
{permissions.includes(pond.Permission.PERMISSION_WRITE) && (
<MenuItem
onClick={() => {
setOpenUpdateYardDialog(true);
setAddYardName(binYards[yardIndex].name);
setAddYardDescription(binYards[yardIndex].description);
setMenuAnchorEl(null);
}}
aria-label="Edit Yard"
dense>
<ListItemIcon>
<EditIcon className={classes.green} />
</ListItemIcon>
<ListItemText secondary="Edit Yard" />
</MenuItem>
)}
{permissions.includes(pond.Permission.PERMISSION_SHARE) && (
<MenuItem
onClick={() => {
setMenuAnchorEl(null);
openShareDialog();
}}
aria-label="Share Yard"
dense>
<ListItemIcon>
<ShareIcon className={classes.blue} />
</ListItemIcon>
<ListItemText secondary="Share Yard" />
</MenuItem>
)}
<MenuItem
onClick={() => {
moveLeft(yardIndex);
setMenuAnchorEl(null);
}}
aria-label="Move Left"
dense>
<ListItemIcon>
<KeyboardArrowLeftIcon />
</ListItemIcon>
<ListItemText secondary="Move Left" />
</MenuItem>
<MenuItem
onClick={() => {
moveRight(yardIndex);
setMenuAnchorEl(null);
}}
aria-label="Move Right"
dense>
<ListItemIcon>
<KeyboardArrowRightIcon />
</ListItemIcon>
<ListItemText secondary="Move Right" />
</MenuItem>
{permissions.includes(pond.Permission.PERMISSION_USERS) && (
<MenuItem
onClick={() => {
setUserDialog(true);
setMenuAnchorEl(null);
}}
aria-label="Users"
dense>
<ListItemIcon>
<ObjectUsersIcon />
</ListItemIcon>
<ListItemText secondary="Users" />
</MenuItem>
)}
{permissions.includes(pond.Permission.PERMISSION_USERS) && (
<MenuItem
onClick={() => {
setTeamDialog(true);
setMenuAnchorEl(null);
}}
aria-label="Teams"
dense>
<ListItemIcon>
<ObjectUsersIcon />
</ListItemIcon>
<ListItemText secondary="Teams" />
</MenuItem>
)}
{permissions.includes(pond.Permission.PERMISSION_SHARE) &&
permissions.includes(pond.Permission.PERMISSION_READ) &&
permissions.includes(pond.Permission.PERMISSION_USERS) &&
permissions.includes(pond.Permission.PERMISSION_WRITE) ? (
<MenuItem
onClick={() => {
deleteYard(yardIndex);
setMenuAnchorEl(null);
}}
aria-label="Delete Yard"
dense>
<ListItemIcon>
<DeleteIcon className={classes.red} />
</ListItemIcon>
<ListItemText secondary="Delete Yard" />
</MenuItem>
) : (
<MenuItem
onClick={() => {
setLeaveYardDialogOpen(true);
setMenuAnchorEl(null);
}}
aria-label="Leave Yard"
dense>
<ListItemIcon>
<RemoveSelfIcon className={classes.red} />
</ListItemIcon>
<ListItemText secondary="Leave Yard" />
</MenuItem>
)}
</Menu>
);
};
let permissions: pond.Permission[] = [];
if (binYards[yardIndex] !== undefined) {
permissions = yardPermissions[binYards[yardIndex].key] || [];
}
return (
<AppBar
position="sticky"
elevation={0}
style={props.showTabs ? {} : { visibility: "hidden", height: 0 }}>
{addYardDialog()}
{updateYardDialog()}
{yardMenu()}
{leaveYardDialog()}
{binYards[yardIndex] && (
<ShareObject
scope={binYardScope(binYards[yardIndex].key)}
label={binYards[yardIndex].name}
permissions={permissions}
isDialogOpen={shareDialog}
closeDialogCallback={() => setShareDialog(false)}
/>
)}
{binYards[yardIndex] && (
<ObjectUsers
scope={binYardScope(binYards[yardIndex].key)}
label={binYards[yardIndex].name}
permissions={permissions}
isDialogOpen={userDialog}
closeDialogCallback={() => setUserDialog(false)}
refreshCallback={() => {}}
userCallback={updateYardPermissions}
dialog={
"Updating a user's permissions for this bin yard will update the same permissions for all corresponding bins."
}
/>
)}
{binYards[yardIndex] && (
<ObjectTeams
scope={binYardScope(binYards[yardIndex].key)}
label={binYards[yardIndex].name}
permissions={permissions}
isDialogOpen={teamDialog}
closeDialogCallback={() => setTeamDialog(false)}
refreshCallback={() => {}}
userCallback={updateYardPermissions}
dialog={
"Updating a user's permissions for this bin yard will update the same permissions for all corresponding bins."
}
/>
)}
<Tabs
variant="scrollable"
scrollButtons="auto"
value={tab}
TabIndicatorProps={{ style: { background: "rgba(0,0,0,0)" } }}
onChange={(_, newValue) => {
if (+newValue > 0) {
tabChange(newValue);
}
}}>
<Tab
className={searchSelected ? classes.searchTabExpanded : classes.searchTab}
disableTouchRipple
disableFocusRipple
label={
<Grid container direction="row" wrap="nowrap" spacing={2}>
<Grid item>{yardsLoading ? <CircularProgress size={20} /> : <Search />}</Grid>
{searchSelected && (
<Grid item>
<TextField
onChange={e => {
loadYards(e.target.value);
}}
/>
</Grid>
)}
</Grid>
}
onClick={e => {
setSearchSelected(true);
}}
/>
<Tab
classes={{ root: classes.smallTab, selected: classes.selectedTab }}
style={{ marginLeft: theme.spacing(1) }}
label="All"
disableTouchRipple={true}
onClick={() => {
setShowing("all");
}}
/>
{binYards.map((n, index) => (
<Tooltip
title={
n.description ? (
<React.Fragment>
<div style={{ fontWeight: "bold" }}>{n.name}</div>
<div style={{ marginTop: theme.spacing(0.25) }}>{n.description}</div>
</React.Fragment>
) : (
n.name
)
}
key={index}>
<Tab
classes={{ root: classes.tab, selected: classes.selectedTab }}
key={index}
disableTouchRipple={true}
onClick={() => {
setShowing("bins");
}}
label={
<span>
<div className={classes.tabText}>{n.name}</div>
<MoreVert
onMouseEnter={() => setTabClick(false)}
onMouseLeave={() => setTabClick(true)}
className={classes.icon}
onClick={event => {
let target = event.currentTarget;
setMenuAnchorEl(target);
setYardIndex(index);
}}
/>
</span>
}
/>
</Tooltip>
))}
<Tab
classes={{ root: classes.smallTab, selected: classes.selectedTab }}
// fullWidth={false}
label={<AddIcon color="primary"/>}
onClick={() => setShowAddYard(true)}
disableTouchRipple={true}
/>
{/* {grainBags.length > 0 && (
<Tab
classes={{ root: classes.smallTab, selected: classes.selectedTab }}
style={{ marginLeft: theme.spacing(1) }}
label="Bags"
disableTouchRipple={true}
onClick={() => {
setShowing("bags");
}}
/>
)} */}
</Tabs>
</AppBar>
);
}

View file

@ -42,6 +42,7 @@ export function ImgIcon(props: Props) {
src={src}
color="transparent"
style={style}
loading="lazy"
/>
</Icon>
);

View file

@ -81,6 +81,7 @@ import { GrainBag } from "models/GrainBag";
import { getThemeType } from "theme/themeType";
import GrainBagSettings from "grainBag/grainBagSettings";
import GrainBagList from "grainBag/grainBagList";
import BinYards from "bin/BinYards";
// import { useHistory } from "react-router";
const useStyles = makeStyles((theme: Theme) => {
@ -1315,7 +1316,7 @@ export default function Bins(props: Props) {
return (
<Box>
{addALertsDialog()}
{/* <BinYard
<BinYards
yards={yards}
yardsLoading={yardsLoading}
yardPerms={yardPermissions}
@ -1330,7 +1331,7 @@ export default function Bins(props: Props) {
setShowing={(val: "all" | "bins" | "bags") => {
setShowing(val);
}}
/> */}
/>
<Box height={1}>
<Box
paddingY={isMobile || props.insert ? 0.5 : 1}

View file

@ -123,7 +123,7 @@ export default function ShareObject(props: Props) {
resp.data.bins.forEach(bin => {
if (bin.settings) {
let newScope = binScope(bin.settings?.key);
permissionAPI.shareObjectByKey(newScope, teamKey, sharedPermissions).catch(err => {
permissionAPI.shareObjectByKey(newScope, teamKey, sharedPermissions).catch(_err => {
successBins = false;
});
}
@ -143,7 +143,7 @@ export default function ShareObject(props: Props) {
resp.data.gates.forEach(gate => {
if (gate) {
let newScope = { key: gate.key, kind: "gate" } as Scope;
permissionAPI.shareObjectByKey(newScope, teamKey, sharedPermissions).catch(err => {
permissionAPI.shareObjectByKey(newScope, teamKey, sharedPermissions).catch(_err => {
successGates = false;
});
}
@ -205,7 +205,7 @@ export default function ShareObject(props: Props) {
);
setShareableLinks(rShareableLinks);
})
.catch((error: any) => {
.catch((_error: any) => {
setShareableLinks([]);
console.log("Error occured while loading shareable links");
})
@ -228,10 +228,10 @@ export default function ShareObject(props: Props) {
const expiration = isNewLinkInfinite ? getNeverExpires() : newLinkExpiration.toISOString();
permissionAPI
.addShareableLink(scope, expiration)
.then((response: any) => {
.then((_response: any) => {
loadShareableLinks();
})
.catch((error: any) => {
.catch((_error: any) => {
console.log("Error occured while creating shareable link");
});
};
@ -239,10 +239,10 @@ export default function ShareObject(props: Props) {
const revokeShareableLink = (code: string) => {
permissionAPI
.removeShareableLink(scope, code)
.then((response: any) => {
.then((_response: any) => {
loadShareableLinks();
})
.catch((error: any) => {
.catch((_error: any) => {
console.log("Error occured while removing the shareable link");
});
};
@ -297,7 +297,7 @@ export default function ShareObject(props: Props) {
setSharedPermissions(updatedSharedPermissions);
};
const changeTab = (event: any, newTab: number) => {
const changeTab = (_event: any, newTab: number) => {
setTab(newTab);
};

View file

@ -324,7 +324,7 @@ export default function Editor(props: Props) {
setMouseDown(true);
};
const mouseUp = (e: any) => {
const mouseUp = (_e: any) => {
setMouseDown(false);
if (mode === Mode.NORMAL && selected !== undefined) {
let state = [...moveOrigin];
@ -522,7 +522,7 @@ export default function Editor(props: Props) {
};
const drawBlocks = (context: CanvasRenderingContext2D) => {
blocks.forEach((block, index) => {
blocks.forEach(block => {
if (block.draw) block.draw(context, cameraOffsetX, cameraOffsetY, scale);
});
selected.forEach(block => {