1- import React , { useEffect , useState } from 'react' ;
1+ import React , { useCallback , useEffect , useState } from 'react' ;
22import { Button , Col , Form , Input , Modal , Row , TimePicker } from 'antd' ;
33import { Moment } from 'moment/moment' ;
44import moment from 'moment' ;
@@ -25,116 +25,128 @@ interface TimeRangeModalProps {
2525 onClose : ( ) => void ;
2626}
2727
28- export default observer ( function TimeRangeModal ( {
29- taskTime,
30- visible,
31- onClose,
32- } : TimeRangeModalProps ) {
33- const [ valid , setValid ] = useState < boolean > ( false ) ;
34- const [ description , setDescription ] = useState < string > ( '' ) ;
35- const [ timeRange , setTimeRange ] = useState < Undefined < ITimeRangeModel > > ( ) ;
36- const timeInProgress = ! taskTime ?. time . end ;
28+ const TimeRangeModal = observer (
29+ ( { taskTime, visible, onClose } : TimeRangeModalProps ) => {
30+ const [ valid , setValid ] = useState < boolean > ( false ) ;
31+ const [ description , setDescription ] = useState < string > ( '' ) ;
32+ const [ timeRange , setTimeRange ] = useState < Undefined < ITimeRangeModel > > ( ) ;
33+ const timeInProgress = ! taskTime ?. time . end ;
3734
38- useEffect ( ( ) => {
39- setValid (
40- ! ! timeRange ?. start ||
41- ! ! (
42- timeRange ?. start &&
43- timeRange ?. end &&
44- isBefore ( timeRange ?. start , timeRange ?. end )
45- )
46- ) ;
47- } , [ timeRange ] ) ;
35+ const handleOk = useCallback ( ( ) => {
36+ if ( taskTime ?. task && timeRange ?. start ) {
37+ const { task, index } = taskTime ;
38+ timeRange . description = description ;
39+ tasksStore . setTime ( task , index , timeRange ) ;
40+ }
41+ onClose ( ) ;
42+ } , [ description , onClose , taskTime , timeRange ] ) ;
4843
49- useEffect ( ( ) => {
50- if ( taskTime ) {
51- setTimeRange ( { ...taskTime . time } ) ;
52- setDescription ( taskTime . time . description || '' ) ;
53- }
54- } , [ taskTime ] ) ;
44+ useEffect ( ( ) => {
45+ function keyupHandler ( e : KeyboardEvent ) {
46+ // Hotkey: Ctrl+Enter
47+ if ( e . ctrlKey && e . key === 'Enter' ) {
48+ handleOk ( ) ;
49+ }
50+ }
5551
56- function handleOk ( ) {
57- if ( taskTime ?. task && timeRange ?. start ) {
58- const { task, index } = taskTime ;
59- if ( description ) {
60- timeRange . description = description ;
52+ document . addEventListener ( 'keyup' , keyupHandler ) ;
53+ return ( ) => {
54+ document . removeEventListener ( 'keyup' , keyupHandler ) ;
55+ } ;
56+ } , [ handleOk ] ) ;
57+
58+ useEffect ( ( ) => {
59+ setValid (
60+ ! ! timeRange ?. start ||
61+ ! ! (
62+ timeRange ?. start &&
63+ timeRange ?. end &&
64+ isBefore ( timeRange ?. start , timeRange ?. end )
65+ )
66+ ) ;
67+ } , [ timeRange ] ) ;
68+
69+ useEffect ( ( ) => {
70+ if ( taskTime ) {
71+ setTimeRange ( { ...taskTime . time } ) ;
72+ setDescription ( taskTime . time . description || '' ) ;
6173 }
62- tasksStore . setTime ( task , index , timeRange ) ;
63- }
64- onClose ( ) ;
65- }
74+ } , [ taskTime ] ) ;
6675
67- function handleDelete ( ) {
68- if ( taskTime ) {
69- tasksStore . deleteTime ( taskTime . task , taskTime . index ) ;
76+ function handleDelete ( ) {
77+ if ( taskTime ) {
78+ tasksStore . deleteTime ( taskTime . task , taskTime . index ) ;
79+ }
80+ onClose ( ) ;
7081 }
71- onClose ( ) ;
72- }
7382
74- function handleCancel ( ) {
75- onClose ( ) ;
76- }
83+ function handleCancel ( ) {
84+ onClose ( ) ;
85+ }
7786
78- function onChange ( field : RangeField ) {
79- return ( value : Moment | null ) => {
80- const newTimeRange = {
81- ...timeRange ,
82- [ field ] : value ?. toDate ( ) || undefined ,
87+ function onChange ( field : RangeField ) {
88+ return ( value : Moment | null ) => {
89+ const newTimeRange = {
90+ ...timeRange ,
91+ [ field ] : value ?. toDate ( ) || undefined ,
92+ } ;
93+ setTimeRange ( newTimeRange as ITimeRangeModel ) ;
8394 } ;
84- setTimeRange ( newTimeRange as ITimeRangeModel ) ;
85- } ;
95+ }
96+
97+ return (
98+ < Modal
99+ title = "Edit time range"
100+ visible = { visible }
101+ okButtonProps = { { disabled : ! valid } }
102+ onOk = { handleOk }
103+ onCancel = { handleCancel }
104+ okText = "Save"
105+ >
106+ < Form colon >
107+ < Form . Item label = "Task" >
108+ < div > { taskTime ?. task . title } </ div >
109+ </ Form . Item >
110+ < Form . Item label = "Description" >
111+ < Input
112+ placeholder = "Type description..."
113+ value = { description }
114+ onChange = { ( e ) => setDescription ( e . target . value ) }
115+ />
116+ </ Form . Item >
117+ < Row >
118+ < Col span = { 8 } >
119+ < Form . Item label = "Start" labelCol = { { span : 24 } } >
120+ < TimePicker
121+ format = "HH:mm"
122+ value = { timeRange ?. start && moment ( timeRange ?. start ) }
123+ onChange = { onChange ( RangeField . start ) }
124+ />
125+ </ Form . Item >
126+ </ Col >
127+ < Col span = { 8 } >
128+ < Form . Item label = "End" labelCol = { { span : 24 } } >
129+ < TimePicker
130+ format = "HH:mm"
131+ value = { timeRange ?. end && moment ( timeRange ?. end ) }
132+ onChange = { onChange ( RangeField . end ) }
133+ disabled = { timeInProgress }
134+ />
135+ </ Form . Item >
136+ </ Col >
137+ < Col span = { 8 } >
138+ < Form . Item label = "Duration" labelCol = { { span : 24 } } >
139+ < TimeRangeDuration timeRange = { timeRange } />
140+ </ Form . Item >
141+ </ Col >
142+ </ Row >
143+ < Button icon = { < DeleteFilled /> } onClick = { handleDelete } >
144+ Remove
145+ </ Button >
146+ </ Form >
147+ </ Modal >
148+ ) ;
86149 }
150+ ) ;
87151
88- return (
89- < Modal
90- title = "Edit time range"
91- visible = { visible }
92- okButtonProps = { { disabled : ! valid } }
93- onOk = { handleOk }
94- onCancel = { handleCancel }
95- okText = "Save"
96- >
97- < Form colon >
98- < Form . Item label = "Task" >
99- < div > { taskTime ?. task . title } </ div >
100- </ Form . Item >
101- < Form . Item label = "Description" >
102- < Input
103- placeholder = "Type description..."
104- value = { description }
105- onChange = { ( e ) => setDescription ( e . target . value ) }
106- />
107- </ Form . Item >
108- < Row >
109- < Col span = { 8 } >
110- < Form . Item label = "Start" labelCol = { { span : 24 } } >
111- < TimePicker
112- format = "HH:mm"
113- value = { timeRange ?. start && moment ( timeRange ?. start ) }
114- onChange = { onChange ( RangeField . start ) }
115- />
116- </ Form . Item >
117- </ Col >
118- < Col span = { 8 } >
119- < Form . Item label = "End" labelCol = { { span : 24 } } >
120- < TimePicker
121- format = "HH:mm"
122- value = { timeRange ?. end && moment ( timeRange ?. end ) }
123- onChange = { onChange ( RangeField . end ) }
124- disabled = { timeInProgress }
125- />
126- </ Form . Item >
127- </ Col >
128- < Col span = { 8 } >
129- < Form . Item label = "Duration" labelCol = { { span : 24 } } >
130- < TimeRangeDuration timeRange = { timeRange } />
131- </ Form . Item >
132- </ Col >
133- </ Row >
134- < Button icon = { < DeleteFilled /> } onClick = { handleDelete } >
135- Remove
136- </ Button >
137- </ Form >
138- </ Modal >
139- ) ;
140- } ) ;
152+ export default TimeRangeModal ;
0 commit comments