Skip to content

Commit

Permalink
Feature/estimation result (#52)
Browse files Browse the repository at this point in the history
* #41: add functionality to calculate and store voting result to backend

* #41: minor changes

* #41: draft for adding the final result (backend)

* #41: added WebSocket message for final result

* #41 extended function to show the average voted complexity for tasks + fixed/refactured some code

Co-authored-by: diiinesh <63147290+diiinesh@users.noreply.github.com>
Co-authored-by: sarahffm <sarahboeckel999@gmail.com>

* #41 fixed some errors after merge

Co-authored-by: diiinesh <63147290+diiinesh@users.noreply.github.com>
Co-authored-by: sarahffm <sarahboeckel999@gmail.com>

* Implemented function to submit finalValue

Co-authored-by: diiinesh <63147290+diiinesh@users.noreply.github.com>
Co-authored-by: sarahffm <sarahboeckel999@gmail.com>

* #41: store finalValue in TaskStore + cleanup

* #41: send finalValue to backend + cleanup

* impl. function to show cloesd tasks ratings + accept finalValue from sockets

* #41: added Result to SessionStatus

* #41: fixed reload data on refresh of Result

* #41: Implemented checkmark for closed/finished tasks

* fix imports

* #41: added headers to some requests

* #41: fixed elements shown to wrong user + cleanup

* #41: removed CertificatePassword

* #41: fixed bugs + cleanup

* #41: default value for final result

Co-authored-by: sarahffm <sarahboeckel999@gmail.com>
Co-authored-by: sarahffm <58327878+sarahffm@users.noreply.github.com>
Co-authored-by: diiinesh <63147290+diiinesh@users.noreply.github.com>
  • Loading branch information
4 people authored Jan 4, 2023
1 parent 183cd36 commit 386c5de
Show file tree
Hide file tree
Showing 24 changed files with 476 additions and 102 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import axios from "axios";
import { useRouter } from "next/router";
import { FunctionComponent, useEffect, useState } from "react";
import { baseUrl, serviceUrl } from "../../../../../Constants/url";
import { ITask } from "../../../../../Interfaces/ITask";
import { EstimationType } from "../../../../../Types/EstimationType";
import { Role } from "../../../../../Types/Role";
import { Status } from "../../../../../Types/Status";
import { Center } from "../../../../Globals/Center";
import { useAuthStore } from "../../../Authentication/Stores/AuthStore";
Expand All @@ -16,21 +16,22 @@ interface EstimationProps {
}

export const Estimation: FunctionComponent<EstimationProps> = ({ id }) => {
const { findOpenTask, tasks, userAlreadyVoted } = useTaskStore();
const { findOpenTask, tasks, userAlreadyVoted, findEvaluatedTask } = useTaskStore();
const { complexity, effort, risk, resetStore } = useEstimationStore();

const { userId, token } = useAuthStore();
const { userId, token, role } = useAuthStore();

const columns = new Array<String>();

const [doVote, setDoVote] = useState<boolean>(true);

const task = findOpenTask();
const openTask = findOpenTask();
const evaluatedTask = findEvaluatedTask();
const averageComplexity = findEvaluatedTask()?.result?.complexityAverage;

let alreadyVoted = false;

if (task) {
alreadyVoted = userAlreadyVoted(userId as string, task.id);
if (openTask) {
alreadyVoted = userAlreadyVoted(userId as string, openTask.id);
}

useEffect(() => {
Expand All @@ -39,7 +40,8 @@ export const Estimation: FunctionComponent<EstimationProps> = ({ id }) => {
} else {
setDoVote(true);
}
}, [task, alreadyVoted]);
}, [alreadyVoted]);


for (const type in EstimationType) {
columns.push(type);
Expand Down Expand Up @@ -67,11 +69,42 @@ export const Estimation: FunctionComponent<EstimationProps> = ({ id }) => {
});

if (result.status == 201) {
// finally remove task from store
// setDoVote to render the vote again button
setDoVote(false);
// finally reset the estimation buttons to 1
resetStore();
}
};

const submitFinalResultToRestApi = async () => {
const evaluatedTask = findEvaluatedTask();

if (evaluatedTask && evaluatedTask.result !== undefined) {

const hasDefaultValue = evaluatedTask.result.finalValue ? false : true;

let res = { amountOfVotes: 0, complexityAverage: averageComplexity, finalValue: hasDefaultValue ? 1 : evaluatedTask.result.finalValue };

const url = baseUrl + serviceUrl + id + "/task/status";

const result = await axios({
method: "put",
url: url,
data: { id: evaluatedTask.id, status: Status.Ended, result: res },
headers: {
Accept: "application/json",
"Content-Type": " application/json",
Authorization: `Bearer ${token}`,
}
});

if (result.status == 200) {
// reset the estimation buttons to 1
resetStore();
}
}
}

if (!userId) {
return <>You are currently not logged in!</>;
}
Expand All @@ -82,8 +115,46 @@ export const Estimation: FunctionComponent<EstimationProps> = ({ id }) => {

const user = "me";

const renderEstimationForTask = (task: ITask) => {
return (
const renderVoting = () => {
if (openTask) {
if (doVote) {
return (
renderEstimationForTask(openTask)
)
}
else {
return (
renderVoteAgainButton()
)
}
}
else if (evaluatedTask) {
return (
renderComplexityAverageAndFinalValueChoice()
)
}
else {
return (
renderWaitForLobbyhostMessage()
)
}
};

const renderComplexityAverageAndFinalValueChoice = () => (
<div>
<>
Average Complexity for the task &nbsp;
&apos;{findEvaluatedTask()?.title}&apos;: &nbsp;
</>
<strong>
{`${averageComplexity}`}
</strong>
{(role === Role.Admin && evaluatedTask) ? renderFinalValueChoice(evaluatedTask) : <></>}
</div>
);

const renderEstimationForTask = (task: ITask) => (
<Center>
<>
<strong className={defaultPadding}>
How would you rate this task?
Expand All @@ -106,6 +177,8 @@ export const Estimation: FunctionComponent<EstimationProps> = ({ id }) => {
key={"estimationBar" + type}
// @ts-ignore
type={EstimationType[type] as EstimationType}
isFinal={false}
taskId={task.id}
/>
</div>
))}
Expand All @@ -121,44 +194,71 @@ export const Estimation: FunctionComponent<EstimationProps> = ({ id }) => {
</div>
</>
</>
);
};
</Center>
);

const renderVoting = () => {
return (
<Center>
{task ? (
doVote ? (
renderEstimationForTask(task)
) : (
<div className="flex justify-center">
<button
onClick={() => {
setDoVote(true);
}}
className={
"border-b-blue-700 bg-blue-500 hover:bg-blue-700 text-white font-bold m-2 p-2 rounded "
}
>
I want to vote again!
</button>
</div>
)
) : (
<strong className={defaultPadding}>
Please wait for your lobby host to create a task!
</strong>
)}
</Center>
);
};
const renderFinalValueChoice = (task: ITask) => (
<Center>
<>
<strong className={defaultPadding}>
Choose final value for the Complexity
</strong>
<>
<div
key={"estimationColumn" + "Complexity"}
className={
"flex flex-row justify-between items-center " + defaultPadding
}
style={{
background: "#f1f4f6",
}}
>
<p style={{ color: "#404b56" }}>
Complexity:
</p>
<EstimationBar
key={"estimationBar" + "Complexity"}
// @ts-ignore
type={EstimationType["Complexity"] as EstimationType}
isFinal={true}
taskId={task.id}
/>
</div>
<div className="flex justify-center">
<button
onClick={() => submitFinalResultToRestApi()}
className={
"border-b-blue-700 bg-blue-500 hover:bg-blue-700 text-white font-bold m-2 p-2 rounded "
}
>
Submit
</button>
</div>
</>
</>
</Center>
);

return renderVoting();
const renderVoteAgainButton = () => (
<div className="flex justify-center">
<button
onClick={() => {
setDoVote(true);
}}
className={
"border-b-blue-700 bg-blue-500 hover:bg-blue-700 text-white font-bold m-2 p-2 rounded "
}
>
I want to vote again
</button>
</div>
);

/*
return userHasAlreadyVoted
? renderViewWhenUserHasAlreadyVoted()
: renderVoting();
const renderWaitForLobbyhostMessage = () => (
<strong className={defaultPadding}>
Please wait for your lobby host to create a task!
</strong>
);

*/
return renderVoting();
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { EstimationValue } from "./EstimationButton";
import { useEstimationStore } from "../Stores/EstimationStore";
import { EstimationType } from "../../../../../Types/EstimationType";

export const EstimationBar: FunctionComponent<{ type: EstimationType }> = ({
type,
export const EstimationBar: FunctionComponent<{ type: EstimationType; isFinal: boolean; taskId: String; }> = ({
type, isFinal, taskId
}) => {
const state = useEstimationStore();

Expand All @@ -28,6 +28,8 @@ export const EstimationBar: FunctionComponent<{ type: EstimationType }> = ({
gridColumn={validValues.indexOf(item) * 2 + 2}
isActive={item == state[type] ? true : false}
parentType={type}
isFinal={isFinal}
taskId={taskId}
/>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ import {
convertTypeToColorIfActive,
EstimationType,
} from "../../../../../Types/EstimationType";
import { useTaskStore } from "../../Tasks/Stores/TaskStore";
import { useEstimationStore } from "../Stores/EstimationStore";

export const EstimationValue: FunctionComponent<{
value: number;
gridColumn: number;
isActive: boolean;
parentType: EstimationType;
}> = ({ value, gridColumn, isActive, parentType }) => {
isFinal: boolean;
taskId: String;
}> = ({ value, gridColumn, isActive, parentType, isFinal, taskId }) => {
const { setValue } = useEstimationStore();
const { setFinalComplexity } = useTaskStore();

return (
<>
Expand All @@ -26,6 +30,9 @@ export const EstimationValue: FunctionComponent<{
background: convertTypeToColorIfActive(parentType, isActive),
}}
onClick={() => {
if (isFinal) {
setFinalComplexity(taskId, value);
}
setValue(parentType, value);
}}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react";
import { FunctionComponent } from "react";
interface CheckboxPoperties {
size: string;
backgroundColor: string;
accentColor: string;
}
export const Checkbox: FunctionComponent<CheckboxPoperties> = ({
size,
backgroundColor,
accentColor,
}) => {
const style = { width: size, height: size };
return (
<svg
className="checkmark"
xmlns="http://www.w3.org/2000/svg"
style={style}
viewBox="0 0 52 52"
>
<circle
className="checkmark__circle"
cx="26"
cy="26"
r="25"
fill={backgroundColor}
/>
<path
className="checkmark__check"
d="M14.1 27.2l7.1 7.2 16.7-16.8"
stroke={accentColor}
fill="none"
strokeWidth="6"
/>
</svg>
);
};
Loading

0 comments on commit 386c5de

Please sign in to comment.