From 899b98b6be2b44f096c4528eb76d3934162120de Mon Sep 17 00:00:00 2001 From: "Planoetscher Daniel (Student Com20)" <daniel.planoetscher@stud-inf.unibz.it> Date: Wed, 19 May 2021 14:37:32 +0200 Subject: [PATCH] add assignees to task --- .../forms/TaskForm/AssigneesForm.tsx | 83 +++++++++++++++++++ .../forms/TaskForm/RequirementsForm.tsx | 4 +- .../src/components/forms/TaskForm/index.tsx | 26 +++++- 3 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 client/src/components/forms/TaskForm/AssigneesForm.tsx diff --git a/client/src/components/forms/TaskForm/AssigneesForm.tsx b/client/src/components/forms/TaskForm/AssigneesForm.tsx new file mode 100644 index 0000000..4fd0238 --- /dev/null +++ b/client/src/components/forms/TaskForm/AssigneesForm.tsx @@ -0,0 +1,83 @@ +import { TaskAssignment } from "adapters/task"; +import { useCallback, useEffect, useState } from "react"; +import { possibleMember } from "."; +import Popup from 'components/ui/Popup'; +import Button from 'components/ui/Button'; + +interface Props { + assignees: TaskAssignment[]; + setAssignees: Function; + members: possibleMember[] +} + + +export default function AssgineesForm({ assignees, setAssignees, members }: Props) { + + const [possibleMembers, setPossibleMembers] = useState<possibleMember[]>([]); + const [addNew, setAddNew] = useState(false); + const [selectedMember, setSelectedMember] = useState<string>(''); + const [selectedTime, setSelectedTime] = useState<string>(''); + + useEffect(() => { + setPossibleMembers(members.filter(member => !assignees.find(r => r.user === member.id))); + }, [members, assignees, setAssignees]) + + + const addAssignee = useCallback(() => { + if (selectedTime && selectedMember) { + setAssignees((state: any) => [...state, { user: selectedMember, time: selectedTime }]); + setAddNew(false); + setSelectedMember(''); + setSelectedTime(''); + + } + }, [setAssignees, selectedMember, selectedTime]) + + + const removeAssignee = useCallback((member: string) => { + setAssignees((state: any) => state.filter((r: any) => r.user !== member)); + }, [setAssignees]) + + return ( + <> + <div className="requirements-field"> + { + assignees.map((assignee) => ( + <div className="requirement" key={assignee.user}> + <h2>{members.find(member => member.id === assignee.user)?.label}</h2> + <div>{assignee.time}</div> + <div onClick={() => removeAssignee(assignee.user)}>delete</div> + </div> + )) + } + { + possibleMembers.length > 0 && ( + <div className="add-btn" onClick={() => setAddNew(true)}> + new + </div> + ) + } + </div> + { + addNew && ( + <Popup onClose={() => setAddNew(false)}> + <select onChange={(e) => setSelectedMember(e.target.value)}> + <option value="">Please select a user</option> + { + possibleMembers.map((member) => ( + <option value={member.id} key={member.id}>{member.label}</option> + )) + } + </select> + <input type="number" min={1} onChange={(e) => setSelectedTime(e.target.value)} /> + <Button type="submit" onClick={addAssignee}> + Add the assignee + </Button> + </Popup> + + ) + } + </> + ) + +} \ No newline at end of file diff --git a/client/src/components/forms/TaskForm/RequirementsForm.tsx b/client/src/components/forms/TaskForm/RequirementsForm.tsx index ac94857..197d287 100644 --- a/client/src/components/forms/TaskForm/RequirementsForm.tsx +++ b/client/src/components/forms/TaskForm/RequirementsForm.tsx @@ -1,5 +1,5 @@ import { TaskRequirement } from 'adapters/task'; -import { FormEvent, useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { possibleRole } from '.'; import Popup from 'components/ui/Popup'; import Button from 'components/ui/Button'; @@ -35,7 +35,7 @@ export default function RequirementsForm({ roles, requirements, setRequirements const removeRequirement = useCallback((role: string) => { - setRequirements((state: any) => state.filter((r: any) => r.id === role)); + setRequirements((state: any) => state.filter((r: any) => r.role !== role)); }, [setRequirements]) return ( diff --git a/client/src/components/forms/TaskForm/index.tsx b/client/src/components/forms/TaskForm/index.tsx index 9b7babd..a487c60 100644 --- a/client/src/components/forms/TaskForm/index.tsx +++ b/client/src/components/forms/TaskForm/index.tsx @@ -6,8 +6,9 @@ import TextInput from 'components/ui/TextInput'; import Picker from 'emoji-picker-react'; import { getProjectTasks, Project } from 'adapters/project'; import CheckboxGroup from 'components/ui/CheckboxGroup'; -import { getTeam, getTeamRoles } from 'adapters/team'; +import { getTeam, getTeamMembers, getTeamRoles, TeamMember } from 'adapters/team'; import RequirementsForm from './RequirementsForm'; +import AssgineesForm from './AssigneesForm'; interface Props { task?: Task; @@ -51,6 +52,10 @@ export interface possibleRole { id: string; label: string; } +export interface possibleMember { + id: string; + label: string; +} export default function TaskForm({ task, onSubmit, project }: Props) { const [name, setName] = useState(task?.name); @@ -60,10 +65,12 @@ export default function TaskForm({ task, onSubmit, project }: Props) { const [error, setError] = useState(''); const [tasks, setTasks] = useState(task?.dependencies); const [requirements, setRequirements] = useState(task?.requirements ?? []); + const [assignees, setAssignees] = useState(task?.assigned ?? []); const allPriorities = Object.values(Priority); const [allTasks, setAllTasks] = useState<Task[]>([]); const [allRoles, setAllRoles] = useState<possibleRole[]>([]); + const [allMembers, setAllMembers] = useState<possibleMember[]>([]); useEffect(() => { getProjectTasks(project.id).then((tasks) => { @@ -72,12 +79,20 @@ export default function TaskForm({ task, onSubmit, project }: Props) { project.teams.forEach((teamId) => { getTeam(teamId).then(team => { getTeamRoles(teamId).then((roles) => { - setAllRoles(state => [...state, ...roles.map(role => { + setAllRoles(roles.map(role => { return { id: role.id, label: team.name + ': ' + role.name } - })]); + })); + }) + getTeamMembers(teamId).then((members) => { + setAllMembers(members.map(member => { + return { + id: member.id, + label: team.name + ': ' + (member.realname ?? member.username) + } + })); }) }) }) @@ -139,6 +154,11 @@ export default function TaskForm({ task, onSubmit, project }: Props) { <RequirementsForm setRequirements={setRequirements} roles={allRoles} requirements={requirements ?? []} /> ) } + { + allMembers.length > 0 && ( + <AssgineesForm members={allMembers} setAssignees={setAssignees} assignees={assignees} /> + ) + } </form> ) -- GitLab