Fixes to adding members

This commit is contained in:
Peter KW 2024-04-04 11:26:39 +02:00
parent a1d2520d88
commit 9a0f855d2b
3 changed files with 104 additions and 93 deletions

View file

@ -1,4 +1,4 @@
import { NewProjMember } from "../Components/AddMember"; import { AddMemberInfo } from "../Components/AddMember";
import { ProjectRoleChange } from "../Components/ChangeRole"; import { ProjectRoleChange } from "../Components/ChangeRole";
import { projectTimes } from "../Components/GetProjectTimes"; import { projectTimes } from "../Components/GetProjectTimes";
import { ProjectMember } from "../Components/GetUsersInProject"; import { ProjectMember } from "../Components/GetUsersInProject";
@ -196,7 +196,7 @@ interface API {
): Promise<APIResponse<void>>; ): Promise<APIResponse<void>>;
addUserToProject( addUserToProject(
user: NewProjMember, addMemberInfo: AddMemberInfo,
token: string, token: string,
): Promise<APIResponse<void>>; ): Promise<APIResponse<void>>;
@ -335,18 +335,20 @@ export const api: API = {
}, },
async addUserToProject( async addUserToProject(
user: NewProjMember, addMemberInfo: AddMemberInfo,
token: string, token: string,
): Promise<APIResponse<void>> { ): Promise<APIResponse<void>> {
try { try {
const response = await fetch("/api/addUserToProject", { const response = await fetch(
method: "PUT", `/api/addUserToProject/${addMemberInfo.projectName}/?userName=${addMemberInfo.userName}`,
headers: { {
"Content-Type": "application/json", method: "PUT",
Authorization: "Bearer " + token, headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
}, },
body: JSON.stringify(user), );
});
if (!response.ok) { if (!response.ok) {
return { success: false, message: "Failed to add member" }; return { success: false, message: "Failed to add member" };

View file

@ -1,44 +1,35 @@
import { APIResponse, api } from "../API/API"; import { api } from "../API/API";
export interface NewProjMember { export interface AddMemberInfo {
username: string; userName: string;
role: string; projectName: string;
projectname: string;
} }
/** /**
* Tries to add a member to a project * Tries to add a member to a project
* @param {Object} props - A NewProjMember * @param {AddMemberInfo} props.membertoAdd - Contains user's name and project's name
* @returns {boolean} True if added, false if not * @returns {Promise<void>}
*/ */
function AddMember(props: { memberToAdd: NewProjMember }): boolean { async function AddMember(props: { memberToAdd: AddMemberInfo }): Promise<void> {
let added = false; if (props.memberToAdd.userName === "") {
if ( alert("You must choose at least one user to add");
props.memberToAdd.username === "" || return;
props.memberToAdd.role === "" ||
props.memberToAdd.projectname === ""
) {
alert("All fields must be filled before adding");
return added;
} }
api try {
.addUserToProject( const response = await api.addUserToProject(
props.memberToAdd, props.memberToAdd,
localStorage.getItem("accessToken") ?? "", localStorage.getItem("accessToken") ?? "",
) );
.then((response: APIResponse<void>) => { if (response.success) {
if (response.success) { alert(`[${props.memberToAdd.userName}] added`);
alert("Member added"); } else {
added = true; alert(`[${props.memberToAdd.userName}] not added`);
} else { console.error(response.message);
alert("Member not added"); }
console.error(response.message); } catch (error) {
} alert(`[${props.memberToAdd.userName}] not added`);
}) console.error("An error occurred during member add:", error);
.catch((error) => { }
console.error("An error occurred during member add:", error);
});
return added;
} }
export default AddMember; export default AddMember;

View file

@ -1,71 +1,86 @@
import { useState } from "react"; import { useEffect, useState } from "react";
import Button from "./Button"; import Button from "./Button";
import GetAllUsers from "./GetAllUsers"; import AddMember, { AddMemberInfo } from "./AddMember";
import AddMember, { NewProjMember } from "./AddMember";
import BackButton from "./BackButton"; import BackButton from "./BackButton";
import GetUsersInProject, { ProjectMember } from "./GetUsersInProject";
import GetAllUsers from "./GetAllUsers";
/** /**
* Provides UI for adding a member to a project. * Provides UI for adding a member to a project.
* @returns {JSX.Element} - Returns the component UI for adding a member * @returns {JSX.Element} - Returns the component UI for adding a member
*/ */
function AddUserToProject(props: { projectName: string }): JSX.Element { function AddUserToProject(props: { projectName: string }): JSX.Element {
const [name, setName] = useState(""); const [names, setNames] = useState<string[]>([]);
const [users, setUsers] = useState<string[]>([]); const [users, setUsers] = useState<string[]>([]);
const [role, setRole] = useState(""); const [usersProj, setUsersProj] = useState<ProjectMember[]>([]);
GetAllUsers({ setUsersProp: setUsers });
const handleClick = (): boolean => { // Gets all users and project members for filtering
const newMember: NewProjMember = { GetAllUsers({ setUsersProp: setUsers });
username: name, GetUsersInProject({
projectname: props.projectName, setUsersProp: setUsersProj,
role: role, projectName: props.projectName,
}; });
return AddMember({ memberToAdd: newMember }); /*
* Filters the members from users so that users who are already
* members are not shown
*/
useEffect(() => {
setUsers((prevUsers) => {
const filteredUsers = prevUsers.filter(
(user) =>
!usersProj.some((projectUser) => projectUser.Username === user),
);
return filteredUsers;
});
}, [usersProj]);
// Attempts to add all of the selected users to the project
const handleAddClick = async (): Promise<void> => {
if (names.length === 0)
alert("You have to choose at least one user to add");
for (const name of names) {
const newMember: AddMemberInfo = {
userName: name,
projectName: props.projectName,
};
await AddMember({ memberToAdd: newMember });
}
setNames([]);
location.reload();
};
// Updates the names that have been selected
const handleUserClick = (user: string): void => {
setNames((prevNames): string[] => {
if (!prevNames.includes(user)) {
return [...prevNames, user];
}
return prevNames.filter((name) => name !== user);
});
}; };
return ( return (
<div className="border-4 border-black bg-white flex flex-col items-center justify-center rounded-3xl content-center pl-20 pr-20 h-[75vh] w-[50vh]"> <div className="border-4 border-black bg-white flex flex-col items-center pt-10 rounded-3xl content-center pl-20 pr-20 h-[63vh] w-[50] overflow-auto">
<p className="pb-4 mb-2 text-center font-bold text-[18px]"> <h1 className="text-center font-bold text-[36px] pb-10">
User chosen: [{name}] {props.projectName}
</h1>
<p className="p-1 text-center font-bold text-[26px]">
Choose users to add:
</p> </p>
<p className="pb-4 mb-2 text-center font-bold text-[18px]"> <div className="border-2 border-black pl-2 pr-2 pb-2 rounded-xl text-center overflow-auto h-[26vh] w-[26vh]">
Role chosen: [{role}]
</p>
<p className="pb-4 mb-2 text-center font-bold text-[18px]">
Project chosen: [{props.projectName}]
</p>
<p className="p-1">Choose role:</p>
<div className="border-2 border-black p-2 rounded-xl text-center h-[10h] w-[16] overflow-auto">
<ul className="text-center items-center font-medium space-y-2">
<li
className="h-[10] w-[14] items-start px-2 py-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-600 hover:text-slate-100 hover:cursor-pointer"
onClick={() => {
setRole("member");
}}
>
{"Member"}
</li>
<li
className="h-[10] w-[14] items-start px-2 py-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-600 hover:text-slate-100 hover:cursor-pointer"
onClick={() => {
setRole("project_manager");
}}
>
{"Project manager"}
</li>
</ul>
</div>
<p className="p-1">Choose user:</p>
<div className="border-2 border-black p-2 rounded-xl text-center overflow-scroll h-[26vh] w-[26vh]">
<ul className="text-center font-medium space-y-2"> <ul className="text-center font-medium space-y-2">
<div></div> <div></div>
{users.map((user) => ( {users.map((user) => (
<li <li
className="items-start p-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-600 hover:text-slate-100 hover:cursor-pointer" className={
names.includes(user)
? "items-start p-1 border-2 border-transparent rounded-full bg-orange-500 hover:bg-orange-600 text-white hover:cursor-pointer ring-2 ring-black"
: "items-start p-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-400 hover:text-slate-100 hover:cursor-pointer"
}
key={user} key={user}
value={user} value={user}
onClick={() => { onClick={() => {
setName(user); handleUserClick(user);
}} }}
> >
<span>{user}</span> <span>{user}</span>
@ -73,13 +88,16 @@ function AddUserToProject(props: { projectName: string }): JSX.Element {
))} ))}
</ul> </ul>
</div> </div>
<div className="flex space-x-5 items-center justify-between"> <p className="pt-10 pb-5 underline text-center font-bold text-[18px]">
Number of users to be added: {names.length}
</p>
<div className="space-x-10 items-center">
<Button <Button
text="Add" text="Add"
onClick={(): void => { onClick={(): void => {
handleClick(); void handleAddClick();
}} }}
type="submit" type="button"
/> />
<BackButton /> <BackButton />
</div> </div>