frontend/src/tasks/TaskDrawer.tsx

313 lines
8.7 KiB
TypeScript

import {
Avatar,
Box,
Card,
Drawer,
Grid2 as Grid,
IconButton,
ListItemIcon,
ListItemText,
Menu,
MenuItem,
Slider,
Theme,
Tooltip,
Typography
} from "@mui/material";
import { Done, Edit, MoreVert } from "@mui/icons-material";
import DisplayDrawer from "common/DisplayDrawer";
import { Task } from "models";
import { useEffect, useState } from "react";
import NotesIcon from "@mui/icons-material/Notes";
import DeleteIcon from "@mui/icons-material/Delete";
import Chat from "chat/Chat";
import { pond } from "protobuf-ts/pond";
import { useMobile, usePermissionAPI, useUserAPI } from "hooks";
import { getThemeType } from "theme";
import { makeStyles } from "@mui/styles";
import ObjectTeamsIcon from "@mui/icons-material/SupervisedUserCircle";
import TaskActions from "./taskActions";
import { useGlobalState } from "providers";
interface Props {
task: Task;
open: boolean;
closeCallback: (refresh: boolean) => void;
deleteTask: (task: Task) => void;
completeTask: (task: Task) => void;
keys: string[]
types: string[]
}
// interface TabPanelProps {
// children?: React.ReactNode;
// index: any;
// value: any;
// }
const useStyles = makeStyles((theme: Theme) => ({
avatar: {
color: getThemeType() === "light" ? theme.palette.common.black : theme.palette.common.white,
backgroundColor: "transparent",
width: theme.spacing(5),
height: theme.spacing(5),
border: "1px solid",
borderColor: theme.palette.divider
},
sliderRoot: {},
sliderThumb: {
height: 15,
width: 15,
marginTop: 0,
marginLeft: 0,
backgroundColor: "yellow"
},
sliderTrack: {
height: 3,
backgroundColor: "white"
},
sliderRail: {
height: 3,
backgroundColor: "white"
},
sliderValLabel: {
left: -20,
top: 40,
background: "transparent",
"& *": {
color: "#fff"
}
},
sliderMark: {
visibility: "hidden"
},
sliderMarked: {
marginTop: 25,
marginBottom: 0
},
sliderMarkLabel: {
top: -25,
left: -10
}
})
);
export default function TaskDrawer(props: Props) {
const monthList = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"June",
"July",
"Aug",
"Sept",
"Oct",
"Nov",
"Dec"
];
const { task, open, closeCallback, completeTask, deleteTask } = props;
const [month, setMonth] = useState(0);
const [day, setDay] = useState(0);
const [permissions, setPermissions] = useState<pond.Permission[]>([])
const [{user}] = useGlobalState();
// const [menuAnchorEl, setMenuAnchorEl] = useState<Element | null>(null);
const [openNote, setOpenNote] = useState(false);
const isMobile = useMobile();
const classes = useStyles();
const userAPI = useUserAPI();
const permissionAPI = usePermissionAPI();
const [worker, setWorker] = useState<pond.UserProfile>();
useEffect(() => {
permissionAPI.getPermissions(user.id(), props.keys, props.types).then(resp => {
setPermissions(pond.EvaluatePermissionsResponse.fromObject(resp.data).permissions)
})
if (task.start()) {
let date = new Date(task.start());
setMonth(date.getUTCMonth());
setDay(date.getUTCDate());
}
userAPI.getProfile(task.worker()).then(resp => {
setWorker(resp);
});
}, [user, task, userAPI, permissionAPI]);
const bodyButtons = () => {
return (
<Grid container direction="row" alignItems="center" justifyContent="space-between">
<Grid>
<Tooltip title="Task Notes">
<IconButton className={classes.avatar} onClick={() => setOpenNote(true)}>
<NotesIcon />
</IconButton>
</Tooltip>
<IconButton style={{ visibility: "hidden" }}>3</IconButton> {/** go to bin/field */}
</Grid>
<Grid>
<Tooltip title="Mark Complete">
<IconButton className={classes.avatar} onClick={() => completeTask(task)}>
<Done style={{ color: task.complete() ? "green" : "white" }} />
</IconButton>
</Tooltip>
<Tooltip title="More">
{/* <IconButton
className={classes.avatar}
onClick={event => setMenuAnchorEl(event.currentTarget)}>
<MoreVert />
</IconButton> */}
<TaskActions
markComplete={(t) => completeTask(t)}
permissions={permissions}
task={task}
removeTask={deleteTask}
refreshCallback={() => {
closeCallback(true)
}}
keys={props.keys}
types={props.types}
/>
</Tooltip>
</Grid>
</Grid>
);
};
const noteDrawer = () => {
return (
<Drawer
anchor={isMobile ? "bottom" : "right"}
open={openNote}
onClose={() => setOpenNote(false)}>
<Box height={isMobile ? "50vh" : "100vh"} padding={2}>
<Typography style={{ fontWeight: 650 }}>Notes</Typography>
<Chat type={pond.NoteType.NOTE_TYPE_TASK} parent={task.key} parentType={"task"} />
</Box>
</Drawer>
);
};
const taskCard = () => {
return (
<Card style={{ height: "35%", paddingTop: 10 }}>
<Grid container direction="row" alignItems="center">
<Grid size={2}>
<Box
style={{
border: "1px solid white",
width: "50px",
height: "50px",
borderRadius: 5,
margin: "auto",
verticalAlign: "middle",
lineHeight: "50px",
textAlign: "center"
}}>
<Typography>{monthList[month]}</Typography>
<Typography style={{ fontWeight: 750 }}>{day}</Typography>
</Box>
</Grid>
<Grid size={10}>
<Typography style={{ fontWeight: 700, fontSize: 30 }}>{task.title()}</Typography>
</Grid>
</Grid>
<Box padding={3}>{task.description()}</Box>
</Card>
);
};
const taskTime = () => {
let start = task
? new Date(task.start() + "T" + task.startTime()).valueOf()
: new Date().valueOf();
let end = task ? new Date(task.end() + "T" + task.endTime()).valueOf() : new Date().valueOf();
return (
<Box style={{ height: "30%" }}>
<Grid container direction="row" alignItems="center" style={{ height: "100%" }}>
<Grid size={3}>
<Box style={{ textAlign: "center" }}>
<Typography>{task.start()}</Typography>
<Typography>{task.startTime()}</Typography>
</Box>
</Grid>
<Grid size={6}>
<Slider
classes={{
root: classes.sliderRoot,
rail: classes.sliderRail,
track: classes.sliderTrack,
thumb: classes.sliderThumb,
valueLabel: classes.sliderValLabel,
marked: classes.sliderMarked,
mark: classes.sliderMark,
markLabel: classes.sliderMarkLabel
}}
min={start}
max={end}
value={new Date().valueOf()} />
</Grid>
<Grid size={3}>
<Box style={{ textAlign: "center" }}>
<Typography>{task.end()}</Typography>
<Typography>{task.endTime()}</Typography>
</Box>
</Grid>
</Grid>
</Box>
);
};
const assignees = () => {
return (
<Card style={{ height: "35%" }}>
<Box padding={2}>
<Typography style={{ fontWeight: 700, fontSize: 30 }}>Assigned To:</Typography>
{/* TODO: change this to get the user and display the user name and avatar */}
{worker && (
<Grid container direction="row" alignItems="center">
<Grid>
<Avatar
alt={worker.name}
src={worker.avatar && worker.avatar !== "" ? worker.avatar : undefined}
/>
</Grid>
<Grid>
<Box marginLeft={2}>{worker.name}</Box>
</Grid>
</Grid>
)}
</Box>
</Card>
);
};
const drawerBody = () => {
return (
<Box padding={2}>
{bodyButtons()}
<Box marginTop={3} style={{ height: "65vh" }}>
{taskCard()}
{taskTime()}
{assignees()}
</Box>
{/* {taskActions()} */}
{noteDrawer()}
</Box>
);
};
return (
<DisplayDrawer
width={500}
title={task.title()}
displayNext={() => {}}
displayPrev={() => {}}
drawerBody={drawerBody()}
onClose={() => {
closeCallback(false)}
}
open={open}
/>
);
}