785 lines
No EOL
24 KiB
TypeScript
785 lines
No EOL
24 KiB
TypeScript
import {
|
|
AppBar,
|
|
Button,
|
|
CircularProgress,
|
|
Dialog,
|
|
DialogActions,
|
|
DialogContent,
|
|
DialogContentText,
|
|
DialogTitle,
|
|
Grid2 as Grid,
|
|
Grid2,
|
|
ListItemIcon,
|
|
ListItemText,
|
|
Menu,
|
|
MenuItem,
|
|
Tab,
|
|
TextField,
|
|
Theme,
|
|
Tooltip,
|
|
Typography,
|
|
useTheme
|
|
} from "@mui/material";
|
|
import { pond } from "protobuf-ts/pond";
|
|
import {
|
|
useBinYardAPI,
|
|
useSnackbar,
|
|
usePermissionAPI,
|
|
useBinAPI,
|
|
useGlobalState
|
|
} 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 { binScope, binYardScope } from "models/Scope";
|
|
import ShareObject from "user/ShareObject";
|
|
import { Bin, Team, User } from "models";
|
|
import { Dictionary, transform } from "lodash";
|
|
import ObjectUsers from "user/ObjectUsers";
|
|
import ObjectTeams from "teams/ObjectTeams";
|
|
import { GrainBag } from "models/GrainBag";
|
|
import { makeStyles } from "@mui/styles";
|
|
import DraggableTabs from "common/DraggableTabs";
|
|
import CancelSubmit from "common/CancelSubmit";
|
|
|
|
const parentTab = {
|
|
"&": {
|
|
margin: "0px",
|
|
marginTop: "4px",
|
|
marginLeft: "4px",
|
|
animationDuration: "10s",
|
|
transform: "0.3s ease-in-out",
|
|
// transition: transform 0.3s ease-in-out,
|
|
// 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,
|
|
color: theme.palette.text.primary,
|
|
transform: "0.3s ease-in-out",
|
|
},
|
|
smallTab: {
|
|
...parentTab,
|
|
width: theme.spacing(8),
|
|
minWidth: theme.spacing(8),
|
|
transform: "0.3s ease-in-out",
|
|
// background: theme.palette.background.paper
|
|
},
|
|
selectedTab: {
|
|
borderRadius: "-5px",
|
|
borderTopLeftRadius: "6px",
|
|
borderTopRightRadius: "6px",
|
|
background: theme.palette.background.default,
|
|
fontWeight: 1000,
|
|
transform: "0.3s ease-in-out",
|
|
// "linear-gradient(rgba(150, 150, 150, 0.3),"
|
|
// + theme.palette.background.default + " 80%)"
|
|
"&: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",
|
|
marginTop: "auto",
|
|
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: "auto",
|
|
bottom: "auto"
|
|
}
|
|
});
|
|
});
|
|
|
|
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, /*gainBags,*/ setShowing, yardsLoading } = props;
|
|
const binYardAPI = useBinYardAPI();
|
|
const binAPI = useBinAPI();
|
|
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();
|
|
const [addingYard, setAddingYard] = useState(false)
|
|
|
|
useEffect(() => {
|
|
if (props.yards && props.yardPerms) {
|
|
setBinYards(props.yards);
|
|
setYardPermissions(props.yardPerms);
|
|
return;
|
|
}
|
|
}, [props.yards, props.yardPerms]);
|
|
|
|
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 = () => {
|
|
if (addingYard) return
|
|
setAddingYard(true)
|
|
let newBinYard = pond.BinYardSettings.create();
|
|
newBinYard.name = addYardName;
|
|
newBinYard.description = addYardDescription;
|
|
newBinYard.owner = user.id();
|
|
binYardAPI
|
|
.addBinYard(newBinYard, as)
|
|
.then(resp => {
|
|
// loadYards();
|
|
let newYards = [...binYards]
|
|
newYards.push(newBinYard)
|
|
setBinYards(newYards)
|
|
setShowAddYard(false);
|
|
newBinYard.key = resp.data.yard
|
|
|
|
let newYardPermissions: Dictionary<pond.Permission[]> = { ...yardPermissions };
|
|
newYardPermissions[newBinYard.key] = [
|
|
pond.Permission.PERMISSION_READ,
|
|
pond.Permission.PERMISSION_SHARE,
|
|
pond.Permission.PERMISSION_USERS,
|
|
pond.Permission.PERMISSION_WRITE
|
|
];
|
|
setYardPermissions(newYardPermissions)
|
|
openSnackbar("success", "Bin Yard created :)");
|
|
})
|
|
.catch(_err => {
|
|
error("Could not add bin yard");
|
|
}).finally(() => {
|
|
setAddingYard(false)
|
|
});
|
|
};
|
|
|
|
const updateYard = () => {
|
|
let newBinYard = binYards[yardIndex];
|
|
newBinYard.name = addYardName;
|
|
newBinYard.description = addYardDescription;
|
|
binYardAPI
|
|
.updateBinYard(newBinYard.key, newBinYard, undefined, as)
|
|
.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>
|
|
<CancelSubmit
|
|
submitDisabled={addingYard}
|
|
onCancel={() => setShowAddYard(false)}
|
|
onSubmit={submitYard}
|
|
/>
|
|
</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, as)
|
|
.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 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."
|
|
}
|
|
/>
|
|
)}
|
|
<DraggableTabs
|
|
variant="scrollable"
|
|
scrollButtons="auto"
|
|
sx={{ background: theme.palette.background.paper }}
|
|
value={tab}
|
|
TabIndicatorProps={{ style: { background: "rgba(0,0,0,0)" } }}
|
|
onChange={(_, newValue) => {
|
|
// if (+newValue > 0) {
|
|
tabChange(newValue);
|
|
// }
|
|
}}
|
|
startNode={
|
|
<>
|
|
<Tab
|
|
className={searchSelected ? classes.searchTabExpanded : classes.searchTab}
|
|
disableTouchRipple
|
|
disableFocusRipple
|
|
draggable={false}
|
|
label={
|
|
<Grid container direction="row" wrap="nowrap" spacing={2}>
|
|
<Grid>{yardsLoading ? <CircularProgress size={20} /> : <Search />}</Grid>
|
|
{searchSelected && (
|
|
<Grid>
|
|
<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"
|
|
draggable={false}
|
|
disableTouchRipple={true}
|
|
onClick={() => {
|
|
setShowing("all");
|
|
}}
|
|
/>
|
|
</>
|
|
}
|
|
endNode={
|
|
<>
|
|
<Tab
|
|
classes={{ root: classes.smallTab, selected: classes.selectedTab }}
|
|
label={<AddIcon color="primary"/>}
|
|
onClick={() => setShowAddYard(true)}
|
|
disableTouchRipple={true}
|
|
/>
|
|
</>
|
|
}
|
|
>
|
|
{/* <Tab
|
|
classes={{ root: classes.smallTab, selected: classes.selectedTab }}
|
|
style={{ marginLeft: theme.spacing(1) }}
|
|
label="All"
|
|
draggable={false}
|
|
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={n.name}
|
|
>
|
|
<Tab
|
|
classes={{ root: classes.tab, selected: classes.selectedTab }}
|
|
key={index}
|
|
sx={{
|
|
textAlign: "left",
|
|
}}
|
|
disableTouchRipple={true}
|
|
onClick={() => {
|
|
setShowing("bins");
|
|
}}
|
|
label={
|
|
<Grid2 container spacing={3.5} >
|
|
<Grid2>
|
|
{n.name}
|
|
</Grid2>
|
|
<Grid2 alignItems={"center"}>
|
|
<MoreVert
|
|
onMouseEnter={() => setTabClick(false)}
|
|
onMouseLeave={() => setTabClick(true)}
|
|
className={classes.icon}
|
|
onClick={event => {
|
|
let target = event.currentTarget;
|
|
setMenuAnchorEl(target);
|
|
setYardIndex(index);
|
|
}}
|
|
/>
|
|
</Grid2>
|
|
</Grid2>
|
|
}
|
|
/>
|
|
</Tooltip>
|
|
))}
|
|
{/* {grainBags.length > 0 && (
|
|
<Tab
|
|
classes={{ root: classes.smallTab, selected: classes.selectedTab }}
|
|
style={{ marginLeft: theme.spacing(1) }}
|
|
label="Bags"
|
|
disableTouchRipple={true}
|
|
onClick={() => {
|
|
setShowing("bags");
|
|
}}
|
|
/>
|
|
)} */}
|
|
</DraggableTabs>
|
|
</AppBar>
|
|
);
|
|
} |