1
- import React from 'react' ;
1
+ import React , { useEffect , useState } from 'react' ;
2
2
import PropTypes from 'prop-types' ;
3
3
4
4
import {
@@ -20,168 +20,164 @@ import { Settings } from '../settings';
20
20
import { linkifyDecorator } from './decorators' ;
21
21
22
22
23
+ const EditWidgetModal = ( props ) => {
24
+ const {
25
+ onSave,
26
+ onClose,
27
+ isOpen,
28
+ data,
29
+ } = props ;
23
30
24
- export class EditWidgetModal extends React . Component {
25
- static propTypes = {
26
- onSave : PropTypes . func ,
27
- onClose : PropTypes . func ,
28
- isOpen : PropTypes . bool ,
29
- data : PropTypes . object ,
30
- } ;
31
-
32
- constructor ( props ) {
33
- super ( props ) ;
34
- this . state = {
35
- widgetType : null ,
36
- title : props . data . title ,
37
- params : props . data . params ,
38
- weight : props . data . weight ,
39
- isTitleValid : true ,
40
- areParamsFilled : true ,
41
- componentLoaded : false ,
42
- } ;
43
- }
44
-
31
+ const [ widgetType , setWidgetType ] = useState ( { } ) ;
32
+ const [ title , setTitle ] = useState ( ) ;
33
+ const [ weight , setWeight ] = useState ( ) ;
45
34
46
- onNameChange = ( name ) => {
47
- this . setState ( { name } ) ;
48
- }
35
+ // TODO: move the widget params to their own component to better handle validation?
36
+ const [ componentLoaded , setComponentLoaded ] = useState ( false ) ;
37
+ const [ params , setParams ] = useState ( ) ;
49
38
50
- onExpiryDateChange = ( expiryStr ) => {
51
- this . setState ( { expiryDate : expiryStr } ) ;
52
- }
39
+ const [ isTitleValid , setIsTitleValid ] = useState ( title !== '' ) ;
40
+ const [ saveButtonDisabled , setSaveButtonDisabled ] = useState ( false ) ;
53
41
54
- onSave = ( ) => {
42
+ const onSaveModal = ( ) => {
55
43
const updatedWidget = {
56
- title : this . state . title ,
57
- params : this . state . params ,
58
- weight : parseInt ( this . state . weight ) ,
44
+ title : title ,
45
+ params : params ,
46
+ weight : parseInt ( weight ) || 0 , // 400 if this is null
59
47
type : 'widget' ,
60
- widget : this . props . data . widget
48
+ widget : data . widget
61
49
}
62
- this . props . onSave ( updatedWidget ) ;
63
- this . setState ( {
64
- widgetType : null ,
65
- title : '' ,
66
- params : { } ,
67
- weight : 0 ,
68
- isTitleValid : false ,
69
- areParamsFilled : false
70
- } ) ;
71
- }
50
+ onSave ( updatedWidget ) ;
72
51
73
- onClose = ( ) => {
74
- this . setState ( {
75
- title : '' ,
76
- params : { } ,
77
- weight : 0 ,
78
- isTitleValid : false ,
79
- areParamsFilled : false ,
80
- } ) ;
81
- this . props . onClose ( ) ;
52
+ setTitle ( '' ) ;
53
+ setParams ( { } ) ;
54
+ setWeight ( 0 ) ;
55
+ setIsTitleValid ( false ) ;
56
+ setWidgetType ( { } ) ;
82
57
}
83
58
84
- onTitleChange = ( value ) => {
85
- this . setState ( { title : value , isTitleValid : ( value !== '' ) } ) ;
59
+ const onCloseModal = ( ) => {
60
+ setTitle ( '' ) ;
61
+ setParams ( { } ) ;
62
+ setWeight ( 0 ) ;
63
+ setIsTitleValid ( false ) ;
64
+ setWidgetType ( { } ) ;
65
+ onClose ( ) ;
86
66
}
87
67
88
- onWeightChange = ( value ) => {
89
- this . setState ( { weight : value } ) ;
90
- }
91
-
92
- onParamChange = ( value , event ) => {
93
- const params = this . state . params ;
94
- let areParamsFilled = true ;
95
- if ( event ) {
96
- params [ event . target . name ] = value ;
97
- }
98
- this . setState ( { params : params } ) ;
99
- this . state . widgetType . params . forEach ( widgetParam => {
100
- if ( ( widgetParam . required ) && ( ! params [ widgetParam . name ] ) ) {
101
- areParamsFilled = false ;
102
- }
68
+ useEffect ( ( ) => {
69
+ setTitle ( data . title ) ;
70
+ setWeight ( data ? data . weight : 0 ) ;
71
+ setParams ( data . params || { } ) ;
72
+ } , [ data ] )
73
+
74
+ useEffect ( ( ) => {
75
+ let validCheck = ( title !== '' )
76
+ setIsTitleValid ( validCheck ) ;
77
+ if ( validCheck ) { setSaveButtonDisabled ( false ) }
78
+ else { setSaveButtonDisabled ( true ) }
79
+ } , [ title ] )
80
+
81
+ const onParamChange = ( value , event ) => {
82
+ setParams ( {
83
+ ...params ,
84
+ [ event . target . name ] : value
103
85
} ) ;
104
- this . setState ( { areParamsFilled : areParamsFilled } ) ;
105
86
}
106
87
107
- componentDidMount ( ) {
88
+ useEffect ( ( ) => {
108
89
HttpClient . get ( [ Settings . serverUrl , 'widget' , 'types' ] , { 'type' : 'widget' } )
109
- . then ( response => HttpClient . handleResponse ( response ) )
110
- . then ( data => {
111
- data . types . forEach ( type => {
112
- if ( type . id == this . props . data . widget ) {
113
- this . setState ( { widgetType : type } ) ;
114
- this . setState ( { componentLoaded : true } ) ;
115
- }
116
- } ) ;
90
+ . then ( response => HttpClient . handleResponse ( response ) )
91
+ . then ( typesData => {
92
+ typesData . types . forEach ( type => {
93
+ if ( type . id == data . widget ) {
94
+ setWidgetType ( type ) ;
95
+ setComponentLoaded ( true ) ;
96
+ }
117
97
} ) ;
118
- }
119
-
120
- render ( ) {
121
- const { widgetType, componentLoaded } = this . state ;
122
- return (
123
- < Modal
124
- variant = { ModalVariant . small }
125
- title = "Edit widget"
126
- isOpen = { this . props . isOpen }
127
- onClose = { this . onClose }
128
- actions = { [
129
- < Button key = "save" variant = "primary" onClick = { this . onSave } > Save</ Button > ,
130
- < Button key = "cancel" variant = "link" onClick = { this . onClose } > Cancel</ Button >
131
- ] }
132
- >
133
- < Form >
134
- < FormGroup label = "Title" fieldId = "widget-title" validated = { this . isTitleValid } isRequired >
135
- < TextInput type = "text" id = "widget-title" name = "widget-title" value = { this . state . title } onChange = { ( _event , value ) => this . onTitleChange ( value ) } validated = { this . state . isTitleValid } isRequired />
136
- { this . state . isTitleValid !== true && (
137
- < FormHelperText >
138
- < HelperText >
139
- < HelperTextItem icon = { < ExclamationCircleIcon /> } variant = "error" >
140
- Please enter a title for this widget
141
- </ HelperTextItem >
142
- </ HelperText >
143
- </ FormHelperText >
144
- ) }
145
- </ FormGroup >
146
- < FormGroup label = "Weight" fieldId = "widget-weight" >
147
- < TextInput type = "number" id = "widget-weight" name = "widget-weight" value = { this . state . weight } onChange = { ( _event , value ) => this . onWeightChange ( value ) } />
98
+ } ) ;
99
+ } , [ data ?. widget ] )
100
+
101
+
102
+ return (
103
+ < Modal
104
+ variant = { ModalVariant . small }
105
+ title = "Edit widget"
106
+ isOpen = { isOpen }
107
+ onClose = { onCloseModal }
108
+ actions = { [
109
+ < Button key = "save" variant = "primary" onClick = { onSaveModal } isDisabled = { saveButtonDisabled } > Save</ Button > ,
110
+ < Button key = "cancel" variant = "link" onClick = { onCloseModal } > Cancel</ Button >
111
+ ] }
112
+ >
113
+ < Form >
114
+ < FormGroup label = "Title" fieldId = "widget-title" validated = { isTitleValid . toString ( ) } isRequired >
115
+ < TextInput type = "text" id = "widget-title" name = "widget-title" value = { title } onChange = { ( _event , value ) => setTitle ( value ) } validated = { isTitleValid . toString ( ) } isRequired />
116
+ { isTitleValid !== true && (
148
117
< FormHelperText >
149
118
< HelperText >
150
- < HelperTextItem variant = "default " >
151
- How widgets are ordered on the dashboard
119
+ < HelperTextItem icon = { < ExclamationCircleIcon /> } variant = "error " >
120
+ Please enter a title for this widget
152
121
</ HelperTextItem >
153
122
</ HelperText >
154
123
</ FormHelperText >
155
- </ FormGroup >
156
- { componentLoaded ? widgetType . params . map ( param => (
157
- < React . Fragment key = { param . name } >
158
- < FormGroup
159
- label = { param . name }
160
- fieldId = { param . name }
161
- isRequired = { param . required } >
162
- < TextInput
163
- value = { this . state . params [ param . name ] }
164
- type = { ( param . type === 'integer' || param . type === 'float' ) ? 'number' : 'text' }
165
- id = { param . name }
166
- aria-describedby = { `${ param . name } -helper` }
167
- name = { param . name }
168
- onChange = { ( event , value ) => this . onParamChange ( value , event ) }
169
- isRequired = { param . required }
170
- />
171
- < FormHelperText >
172
- < HelperText >
173
- < HelperTextItem variant = "default" >
174
- < Linkify componentDecorator = { linkifyDecorator } >
175
- { param . description }
176
- </ Linkify >
177
- </ HelperTextItem >
178
- </ HelperText >
179
- </ FormHelperText >
180
- </ FormGroup >
181
- </ React . Fragment >
182
- ) ) : '' }
183
- </ Form >
184
- </ Modal >
185
- ) ;
186
- }
124
+ ) }
125
+ </ FormGroup >
126
+ < FormGroup label = "Weight" fieldId = "widget-weight" >
127
+ < TextInput type = "number" id = "widget-weight" name = "widget-weight" value = { weight } onChange = { ( _event , value ) => setWeight ( value ) } />
128
+ < FormHelperText >
129
+ < HelperText >
130
+ < HelperTextItem variant = "default" >
131
+ How widgets are ordered on the dashboard
132
+ </ HelperTextItem >
133
+ </ HelperText >
134
+ </ FormHelperText >
135
+ </ FormGroup >
136
+ { componentLoaded ? widgetType ?. params . map ( param => (
137
+ < React . Fragment key = { param . name } >
138
+ < FormGroup
139
+ label = { param . name }
140
+ fieldId = { param . name }
141
+ isRequired = { param . required }
142
+ // TODO this validation hook isn't working in main branch right now
143
+ // TODO some cool things we could do here,
144
+ // applying the param default if the user empties a required field
145
+ // validated={
146
+ // (param.required && (params[param.name] !== '')).toString()
147
+ // }
148
+ >
149
+ < TextInput
150
+ value = { params [ param . name ] }
151
+ type = { ( param . type === 'integer' || param . type === 'float' ) ? 'number' : 'text' }
152
+ id = { param . name }
153
+ aria-describedby = { `${ param . name } -helper` }
154
+ name = { param . name }
155
+ onChange = { ( event , value ) => onParamChange ( value , event ) }
156
+ isRequired = { param . required }
157
+ />
158
+ < FormHelperText >
159
+ < HelperText >
160
+ < HelperTextItem variant = "default" >
161
+ < Linkify componentDecorator = { linkifyDecorator } >
162
+ { param . description }
163
+ </ Linkify >
164
+ </ HelperTextItem >
165
+ </ HelperText >
166
+ </ FormHelperText >
167
+ </ FormGroup >
168
+ </ React . Fragment >
169
+ ) ) : '' }
170
+ </ Form >
171
+ </ Modal >
172
+ ) ;
173
+
187
174
}
175
+
176
+ EditWidgetModal . propTypes = {
177
+ onSave : PropTypes . func ,
178
+ onClose : PropTypes . func ,
179
+ isOpen : PropTypes . bool ,
180
+ data : PropTypes . object ,
181
+ }
182
+
183
+ export default EditWidgetModal ;
0 commit comments