Skip to content
Snippets Groups Projects
Commit 370a64bc authored by Bernard Roland (Student Com20)'s avatar Bernard Roland (Student Com20)
Browse files

Added the ability to quickly change the task status

parent 51dbc22e
No related branches found
No related tags found
No related merge requests found
import { useEffect, useState } from 'react';
import Tag from '../Tag';
import './tag.scss';
interface Props<Tag> {
label: Tag;
icon?: string;
color?: string;
possible: Tag[];
onChange: (value: Tag) => any;
}
export default function EditableTag<Tag extends string>({ label, icon, color, possible, onChange }: Props<Tag>) {
const [open, setOpen] = useState(false)
useEffect(() => {
if (open) {
const onClick = () => setOpen(false);
document.addEventListener('click', onClick);
return () => {
document.removeEventListener('click', onClick);
}
}
}, [open]);
return (
<span className={'tag-wrapper' + (open ? ' open' : '')} onClick={() => setOpen(!open)}>
<Tag label={label} icon={icon} color={color} />
<div className="tag-dropdown">
{
possible.filter(item => item !== label).map(item => (
<span className="tag-item" onClick={() => onChange(item)}>
{item}
</span>
))
}
</div>
</span>
);
}
@use 'styles/settings.scss' as s;
.tag-wrapper {
display: inline-flex;
flex-flow: column;
align-items: flex-start;
cursor: pointer;
position: relative;
z-index: 2000;
&.open {
.tag-dropdown {
opacity: 1;
transform: translateY(80%);
visibility: visible;
}
.icon {
transform: rotate(180deg);
}
}
.tag-dropdown {
position: absolute;
bottom: 0;
left: 0;
transform: translateY(75%);
background: s.$background-white;
z-index: 2000;
border-radius: 5px;
white-space: nowrap;
box-shadow: 0 0 5px rgba(s.$black, 0.05);
visibility: hidden;
opacity: 0;
.tag-item {
padding: 10px 20px;
display: block;
color: s.$text;
border-radius: 5px;
min-width: 100px;
&:hover {
box-shadow: 0 0 10px rgba(s.$black, 0.1);
}
}
}
}
...@@ -17,7 +17,6 @@ export default function Tag({ label, icon, color }: Props) { ...@@ -17,7 +17,6 @@ export default function Tag({ label, icon, color }: Props) {
)} )}
{label} {label}
</span> </span>
); );
} }
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
* { * {
transition: s.$transition; transition: s.$transition;
transition-property: transform, opacity, color, background, box-shadow, stroke; transition-property: transform, opacity, color, background, box-shadow, stroke, visibility;
font-family: s.$body-font; font-family: s.$body-font;
margin: 0; margin: 0;
padding: 0; padding: 0;
......
...@@ -5,23 +5,23 @@ import { useHistory, useParams } from 'react-router'; ...@@ -5,23 +5,23 @@ import { useHistory, useParams } from 'react-router';
import { getTeam } from 'adapters/team'; import { getTeam } from 'adapters/team';
import { AssignedUser } from 'adapters/user'; import { AssignedUser } from 'adapters/user';
import { StatusColors } from 'adapters/common'; import { StatusColors, Status } from 'adapters/common';
import { getLoggedInUser } from 'adapters/auth'; import { getLoggedInUser } from 'adapters/auth';
import { getProject, Project } from 'adapters/project'; import { getProject, Project } from 'adapters/project';
import { getTask, getTaskAssignees, Task, updateTask } from 'adapters/task'; import { getTask, getTaskAssignees, Task, updateTask } from 'adapters/task';
import Tag from 'components/ui/Tag';
import LongText from 'components/ui/LongText'; import LongText from 'components/ui/LongText';
import Tabs from 'components/navigation/Tabs'; import Tabs from 'components/navigation/Tabs';
import DetailGrid from 'components/layout/DetailGrid'; import DetailGrid from 'components/layout/DetailGrid';
import LoadingScreen from 'components/ui/LoadingScreen'; import LoadingScreen from 'components/ui/LoadingScreen';
import ButtonLink from 'components/navigation/ButtonLink'; import ButtonLink from 'components/navigation/ButtonLink';
import AssignForm from 'components/forms/AssignForm';
import EditableTag from 'components/ui/EditableTag';
import TaskAssignees from './TaskAssignees'; import TaskAssignees from './TaskAssignees';
import TaskComments from './TaskComments'; import TaskComments from './TaskComments';
import './task-detail.scss'; import './task-detail.scss';
import AssignForm from 'components/forms/AssignForm';
export interface Params { export interface Params {
taskId: string; taskId: string;
...@@ -72,6 +72,19 @@ export default function TaskDetail() { ...@@ -72,6 +72,19 @@ export default function TaskDetail() {
} }
}, [taskId, userId, assignment]); }, [taskId, userId, assignment]);
const onStatusChange = useCallback((status: Status) => {
if (task) {
updateTask(task.id, {
status: status,
}).then(() => {
setTask({
...task,
status: status
});
});
}
}, [task]);
if (task) { if (task) {
return ( return (
<div className={'tasks-detail-page theme-' + task.color}> <div className={'tasks-detail-page theme-' + task.color}>
...@@ -79,7 +92,12 @@ export default function TaskDetail() { ...@@ -79,7 +92,12 @@ export default function TaskDetail() {
arrow_back arrow_back
</Link> </Link>
<div className="content-container"> <div className="content-container">
<Tag label={task.status} color={StatusColors.get(task.status)} /> <EditableTag
label={task.status}
color={StatusColors.get(task.status)}
possible={Object.values(Status)}
onChange={onStatusChange}
/>
<h1>{task.name}</h1> <h1>{task.name}</h1>
<div className="description-container"> <div className="description-container">
<LongText text={task.text} /> <LongText text={task.text} />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment