11import React from 'react'
2- import { Layer , Form , TextArea , Button , Box , FormField } from 'grommet'
2+ import { Layer , Form , TextArea , Button , Box , FormField , MaskedInput } from 'grommet'
33import { Checkmark , Trash } from 'grommet-icons'
44import { gql , useMutation } from '@apollo/client'
55import { useFormik } from 'formik'
66import * as Yup from 'yup'
7+ import styled from 'styled-components'
8+ import { Duration } from 'luxon'
79import useSelectedProjectId from '../../hooks/useSelectedProjectId'
10+ import { formatDuration , timerRunning } from '../../helpers/tasks'
11+
12+ const TimeFormField = styled ( FormField ) `
13+ flex-direction: row;
14+ > label {
15+ flex-grow: 2;
16+ display: flex;
17+ align-items: center;
18+ justify-content: flex-end;
19+ font-weight: 600;
20+ }
21+ `
22+
23+ const TimeMaskedInput = styled ( MaskedInput ) `
24+ width: 100px;
25+ &:disabled {
26+ opacity: ${ ( { theme } ) => theme . textInput . disabled . opacity
27+ }
28+ `
29+
830
931const CREATE_TASK = gql `
1032 mutation CreateTaskMutation($projectId:ID!, $description: String!) {
@@ -36,15 +58,45 @@ const validationSchema = Yup.object().shape({
3658 . required ( 'Required' )
3759} )
3860
61+ const createInitialValues = ( task ) => {
62+ if ( ! task ) return { time : '00:00' }
63+
64+ const { description } = task
65+ const time = formatDuration ( task . time * 1000 )
66+ return {
67+ description,
68+ time
69+ }
70+ }
71+
72+ const formattedDurationToSeconds = ( stringDuration ) => {
73+ const [ hours , minutes ] = stringDuration . split ( ':' )
74+ return Duration . fromObject ( { hours, minutes } ) . as ( 'seconds' )
75+ }
76+
3977function TaskModal ( { onClose, onTaskSaved, onTaskDeleted, task } ) {
4078 const [ createTask ] = useMutation ( CREATE_TASK )
4179 const [ updateTask ] = useMutation ( UPDATE_TASK )
4280 const [ deleteTask ] = useMutation ( DELETE_TASK )
4381
82+ const updateVars = ( task , formValues ) => {
83+ const { description, time } = formValues
84+ const { id : taskId } = task
85+
86+ return {
87+ variables : {
88+ taskId,
89+ description,
90+ ...( timerRunning ( task . timerStatus ) ? { } : { time : formattedDurationToSeconds ( time ) } )
91+ }
92+ }
93+ }
94+
95+ const createVars = ( { description, time } ) => ( { projectId, description, time } )
96+
4497 const projectId = useSelectedProjectId ( )
45- const onSubmit = async ( { description } ) => {
46- const variables = { variables : { ...( task ? { taskId : task . id } : { projectId } ) , description } }
47- task ? await updateTask ( variables ) : await createTask ( variables )
98+ const onSubmit = async ( values ) => {
99+ task ? await updateTask ( updateVars ( task , values ) ) : await createTask ( createVars ( values ) )
48100 onClose ( )
49101 onTaskSaved ( )
50102 }
@@ -53,7 +105,7 @@ function TaskModal({ onClose, onTaskSaved, onTaskDeleted, task }) {
53105 onClose ( )
54106 onTaskDeleted ( )
55107 }
56- const form = useFormik ( { initialValues : task || { } , validationSchema, onSubmit } )
108+ const form = useFormik ( { initialValues : createInitialValues ( task ) , validationSchema, onSubmit } )
57109
58110 return (
59111 < Layer
@@ -66,6 +118,26 @@ function TaskModal({ onClose, onTaskSaved, onTaskDeleted, task }) {
66118 < TextArea onChange = { form . handleChange } placeholder = 'Type the task description' rows = { 4 } name = 'description' value = { form . values . description } />
67119 </ FormField >
68120
121+ < TimeFormField error = { form . touched . time && form . errors . time } label = 'Duration' >
122+ < TimeMaskedInput
123+ onChange = { form . handleChange }
124+ placeholder = '00:00'
125+ name = 'time'
126+ value = { form . values . time }
127+ disabled = { task && timerRunning ( task . timerStatus ) }
128+ mask = { [
129+ { length : [ 1 , 2 ] , regexp : / ^ [ 0 - 9 ] * $ / , placeholder : 'hh' } ,
130+ { fixed : ':' } ,
131+ {
132+ length : 2 ,
133+ options : [ '00' , '05' , '10' , '15' , '30' , '45' ] ,
134+ regexp : / ^ [ 0 - 5 ] [ 0 - 9 ] $ | ^ [ 0 - 9 ] $ / ,
135+ placeholder : 'mm' ,
136+ } ,
137+ ] }
138+ />
139+ </ TimeFormField >
140+
69141 < Box justify = 'between' direction = 'row' >
70142 { task && (
71143 < Button
0 commit comments