diff --git a/src/lib/context/estimation.tsx b/src/lib/context/estimation.tsx index 1f576c4..4985b80 100644 --- a/src/lib/context/estimation.tsx +++ b/src/lib/context/estimation.tsx @@ -141,14 +141,28 @@ export const EstimationContextProvider = (props: PropsWithChildren) => { ); }; - const updateTicket = async ({ id, name, content }: EditTicketRequest) => { + const updateTicket = async ({ + id, + name, + content, + estimate, + }: EditTicketRequest) => { const editedTicket = currentSessionData?.tickets.find((x) => x.id === id); if (!editedTicket) { return; } - editedTicket.name = name; - editedTicket.content = content; + if (name !== undefined) { + editedTicket.name = name; + } + + if (content !== undefined) { + editedTicket.content = content; + } + + if (estimate !== undefined) { + editedTicket.estimate = estimate; + } const newTicketsValue = currentSessionData?.tickets.map((x) => JSON.stringify(x), diff --git a/src/lib/types/entityModels.ts b/src/lib/types/entityModels.ts index 2249e4d..db12118 100644 --- a/src/lib/types/entityModels.ts +++ b/src/lib/types/entityModels.ts @@ -12,6 +12,7 @@ interface EstimationSessionTicket { id: string; name: string; content: string; + estimate?: string; } interface SessionState { diff --git a/src/lib/types/requestModels.ts b/src/lib/types/requestModels.ts index 675d05b..9f220dd 100644 --- a/src/lib/types/requestModels.ts +++ b/src/lib/types/requestModels.ts @@ -1,9 +1,10 @@ interface CreateTicketRequest { name: string; content: string; + estimate?: string; } -interface EditTicketRequest extends CreateTicketRequest { +interface EditTicketRequest extends Partial { id: string; } diff --git a/src/main.tsx b/src/main.tsx index 3e9ddba..54e0fb6 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -43,10 +43,12 @@ const authenticatedRoute = createRoute({ }, component: () => { return ( - <> +
- - +
+ +
+
); }, }); diff --git a/src/pages/Estimation/Estimation.tsx b/src/pages/Estimation/Estimation.tsx index 4f56c1c..7b66422 100644 --- a/src/pages/Estimation/Estimation.tsx +++ b/src/pages/Estimation/Estimation.tsx @@ -4,10 +4,11 @@ import { getRouteApi } from '@tanstack/react-router'; import TaskSidebar from './components/TaskSidebar'; import VoteSelection from './components/VoteSelection'; import VoteList from './components/VoteList'; -import { Button, ButtonColor, Drawer } from '../../components'; +import { Drawer } from '../../components'; import EditTicketForm from './components/EditTicketForm'; import PlayerList from './components/PlayerList'; import HtmlEmbed from '../../components/HtmlEmbed'; +import EstimationResult from './components/EstimationResult'; const fibonacciSequence = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 100]; @@ -44,7 +45,7 @@ const Estimation: React.FC = () => { } = estimationState; return ( -
+
{ -
- -
+ { + await updateTicket({ + id: currentTicket.id, + estimate, + }); + + await setActiveTicket(currentTicket.id); + }} + /> ) : (

Select a task to see the details and estimate.

diff --git a/src/pages/Estimation/components/EditTicketForm.tsx b/src/pages/Estimation/components/EditTicketForm.tsx index 153b96d..748ad78 100644 --- a/src/pages/Estimation/components/EditTicketForm.tsx +++ b/src/pages/Estimation/components/EditTicketForm.tsx @@ -6,6 +6,7 @@ import * as yup from 'yup'; interface EditTicketFormData { name: string; + estimate?: string; content: string; } @@ -21,6 +22,7 @@ const EditTicketForm: React.FC = ({ const form = useForm({ defaultValues: initialData ?? { name: '', + estimate: '', content: '', }, onSubmit: async ({ value }) => { @@ -58,6 +60,18 @@ const EditTicketForm: React.FC = ({ /> )} + + {(field) => ( + field.handleChange(e.target.value)} + errors={field.state.meta.errors} + /> + )} + {(field) => ( Promise; + onSetEstimate: (estimate: string) => Promise; +} + +const EstimationResult: React.FC = ({ + className, + revealed, + votes, + setRevealed, + onSetEstimate, +}) => { + const form = useForm({ + defaultValues: { + estimate: '', + }, + onSubmit: async ({ value }) => { + await onSetEstimate(value.estimate); + }, + validators: { + onChange: yup.object({ + estimate: yup.string().label('Estimate').max(10).required(), + }), + }, + validatorAdapter: yupValidator(), + }); + + if (!revealed) { + return votes.length > 0 ? ( +
+ +
+ ) : null; + } + + const numericVotes = votes + .map((vote) => parseFloat(vote.estimate)) + .filter((vote) => !isNaN(vote)); + + const averageVote = + numericVotes.length > 0 + ? numericVotes.reduce((sum, vote) => sum + vote, 0) / numericVotes.length + : null; + + return ( +
+ {averageVote !== null && ( +
+ Average Vote: {averageVote.toFixed(2)} +
+ )} + +
{ + e.preventDefault(); + e.stopPropagation(); + form.handleSubmit(); + }} + > + + {(field) => ( + field.handleChange(e.target.value)} + errors={field.state.meta.errors} + /> + )} + + [state.canSubmit]}> + {([canSubmit]) => ( + + )} + +
+
+ ); +}; + +export default EstimationResult; diff --git a/src/pages/Estimation/components/TaskSidebar.tsx b/src/pages/Estimation/components/TaskSidebar.tsx index b850f99..1f89cbc 100644 --- a/src/pages/Estimation/components/TaskSidebar.tsx +++ b/src/pages/Estimation/components/TaskSidebar.tsx @@ -25,6 +25,7 @@ const TaskSidebar: React.FC = ({ onSelectTicket(item)} onEdit={() => onEditTicket(item.id)} /> diff --git a/src/pages/Estimation/components/VoteList.tsx b/src/pages/Estimation/components/VoteList.tsx index 6ce77da..bbf619c 100644 --- a/src/pages/Estimation/components/VoteList.tsx +++ b/src/pages/Estimation/components/VoteList.tsx @@ -10,7 +10,9 @@ interface VoteListProps { const VoteList: React.FC = ({ className, votes, revealed }) => { return (
-

Player Votes

+ {votes.length > 0 && ( +

Player Votes

+ )} (