@@ -2,73 +2,114 @@ const React = require('react');
2
2
const ButtonToolbar = require ( 'react-bootstrap' ) . ButtonToolbar ;
3
3
const DropdownButton = require ( 'react-bootstrap' ) . DropdownButton ;
4
4
const MenuItem = require ( 'react-bootstrap' ) . MenuItem ;
5
+ const StatusStore = require ( '../store/ddl-status-store' ) ;
5
6
const Action = require ( '../action/index-actions' ) ;
6
7
8
+ // const debug = require('debug')('mongodb-compass:indexes:create-index-field');
9
+
7
10
/**
8
11
* Current allowed types for indexes.
9
12
*/
10
13
const INDEX_TYPES = [ '1 (asc)' , '-1 (desc)' , '2dsphere' ] ;
11
14
15
+ /**
16
+ * Default values for field name and type as presented in the UI
17
+ */
18
+ const DEFAULT_FIELD = {
19
+ name : 'Select a field name' ,
20
+ type : 'Select a type'
21
+ } ;
22
+
12
23
/**
13
24
* Component for the index field form.
14
25
*/
15
26
class CreateIndexField extends React . Component {
16
27
17
- /**
18
- * The component constructor.
19
- *
20
- * @param {Object } props - The properties.
21
- */
22
28
constructor ( props ) {
23
29
super ( props ) ;
24
30
this . state = {
25
- // default titles shown in dropdown
26
- field : 'Add a Field' ,
27
- type : '1 (asc)'
31
+ hasStartedValidating : false ,
32
+ isNameValid : true ,
33
+ isTypeValid : true
28
34
} ;
29
35
}
30
36
37
+ componentDidMount ( ) {
38
+ this . _unsubscribeStatusStore = StatusStore . listen ( this . statusChanged . bind ( this ) ) ;
39
+ }
40
+
41
+ componentWillReceiveProps ( ) {
42
+ this . validate ( false ) ;
43
+ }
44
+
45
+ componentWillUnmount ( ) {
46
+ this . _unsubscribeStatusStore ( ) ;
47
+ }
48
+
31
49
/**
32
- * Create React dropdown items for each element in the given array.
33
- *
34
- * @param {Array } arr - The array of options.
50
+ * Create React dropdown items for each element in the fields array.
35
51
*
36
52
* @returns {Array } The React components for each item in the field and type dropdowns.
37
53
*/
38
- getDropdownOptions ( arr ) {
39
- return arr . map ( ( elem , index ) => ( < MenuItem key = { index } eventKey = { elem } > { elem } </ MenuItem > ) ) ;
54
+ getDropdownFields ( ) {
55
+ return this . props . fields . map ( ( elem , index ) => (
56
+ < MenuItem key = { index }
57
+ disabled = { this . props . disabledFields . some ( field => ( field === elem ) ) }
58
+ eventKey = { elem } > { elem }
59
+ </ MenuItem > ) ) ;
40
60
}
41
61
42
62
/**
43
- * Set state to selected field on field change .
63
+ * Create React dropdown items for each element in the INDEX_TYPES array .
44
64
*
45
- * @param { string } field - The selected field.
65
+ * @returns { Array } The React components for each item in the field and type dropdowns .
46
66
*/
47
- handleFieldSelect ( field ) {
48
- this . setState ( { field : field } ) ;
67
+ getDropdownTypes ( ) {
68
+ return INDEX_TYPES . map ( ( elem , index ) => ( < MenuItem key = { index } eventKey = { elem } > { elem } </ MenuItem > ) ) ;
49
69
}
50
70
51
71
/**
52
- * Fire add field action to add field and type to add index form .
72
+ * Set state to selected field on field change .
53
73
*
54
- * @param {Object } evt - The click event .
74
+ * @param {string } name - The selected name .
55
75
*/
56
- handleSubmit ( evt ) {
57
- evt . preventDefault ( ) ;
58
- evt . stopPropagation ( ) ;
59
- if ( this . state . field !== 'Add a Field' ) {
60
- Action . updateField ( this . state . field , this . state . type , 'add' ) ;
61
- this . setState ( { field : 'Add a Field' , type : '1 (asc)' } ) ;
62
- }
76
+ selectName ( name ) {
77
+ Action . updateFieldName ( this . props . idx , name ) ;
63
78
}
64
79
65
80
/**
66
81
* Set state to selected type on type change.
67
82
*
68
83
* @param {string } type - The selected type.
69
84
*/
70
- handleTypeSelect ( type ) {
71
- this . setState ( { type : type } ) ;
85
+ selectType ( type ) {
86
+ Action . updateFieldType ( this . props . idx , type ) ;
87
+ }
88
+
89
+ /**
90
+ * Remove this index field
91
+ *
92
+ * @param {object } evt The click event.
93
+ */
94
+ remove ( evt ) {
95
+ evt . preventDefault ( ) ;
96
+ evt . stopPropagation ( ) ;
97
+ Action . removeIndexField ( this . props . idx ) ;
98
+ }
99
+
100
+ statusChanged ( ) {
101
+ this . validate ( true ) ;
102
+ }
103
+
104
+ validate ( force ) {
105
+ if ( ! force && ! this . state . hasStartedValidating ) {
106
+ return ;
107
+ }
108
+ this . setState ( {
109
+ hasStartedValidating : true ,
110
+ isTypeValid : this . props . field . type !== '' ,
111
+ isNameValid : this . props . field . name !== ''
112
+ } ) ;
72
113
}
73
114
74
115
/**
@@ -77,35 +118,41 @@ class CreateIndexField extends React.Component {
77
118
* @returns {React.Component } The index field form.
78
119
*/
79
120
render ( ) {
121
+ const fieldName = this . props . field . name || DEFAULT_FIELD . name ;
122
+ const fieldType = this . props . field . type || DEFAULT_FIELD . type ;
123
+
124
+ const hasNameError = this . state . isNameValid ? '' : 'has-error' ;
125
+ const hasTypeError = this . state . isTypeValid ? '' : 'has-error' ;
126
+
80
127
return (
81
128
< div className = "form-inline row create-index-field" >
82
129
< div className = "col-md-6" >
83
130
< ButtonToolbar >
84
131
< DropdownButton
85
- title = { this . state . field }
132
+ title = { fieldName }
86
133
id = "field-name-select-dropdown"
87
- className = " create-index-field-dropdown-name"
88
- onSelect = { this . handleFieldSelect . bind ( this ) } >
89
- { this . getDropdownOptions ( this . props . fields ) }
134
+ className = { ` create-index-field-dropdown-name ${ hasNameError } ` }
135
+ onSelect = { this . selectName . bind ( this ) } >
136
+ { this . getDropdownFields ( this . props . fields ) }
90
137
</ DropdownButton >
91
138
</ ButtonToolbar >
92
139
</ div >
93
140
< div className = "col-md-4" >
94
141
< ButtonToolbar >
95
142
< DropdownButton
96
- title = { this . state . type }
143
+ title = { fieldType }
97
144
id = "field-type-select-dropdown"
98
- className = " create-index-field-dropdown-type"
99
- onSelect = { this . handleTypeSelect . bind ( this ) } >
100
- { this . getDropdownOptions ( INDEX_TYPES ) }
145
+ className = { ` create-index-field-dropdown-type ${ hasTypeError } ` }
146
+ onSelect = { this . selectType . bind ( this ) } >
147
+ { this . getDropdownTypes ( INDEX_TYPES ) }
101
148
</ DropdownButton >
102
149
</ ButtonToolbar >
103
150
</ div >
104
151
< div className = "col-md-2" >
105
- < button
106
- onClick = { this . handleSubmit . bind ( this ) }
107
- className = "btn btn-success btn-circle create-index-field-button" >
108
- < i className = "fa fa-plus " aria-hidden = "true" > </ i >
152
+ < button disabled = { this . props . isRemovable }
153
+ className = "btn btn-success btn-circle"
154
+ onClick = { this . remove . bind ( this ) } >
155
+ < i className = "fa fa-minus " aria-hidden = "true" > </ i >
109
156
</ button >
110
157
</ div >
111
158
</ div >
@@ -116,7 +163,11 @@ class CreateIndexField extends React.Component {
116
163
CreateIndexField . displayName = 'CreateIndexField' ;
117
164
118
165
CreateIndexField . propTypes = {
119
- fields : React . PropTypes . array . isRequired
166
+ fields : React . PropTypes . array . isRequired ,
167
+ field : React . PropTypes . object . isRequired ,
168
+ idx : React . PropTypes . number . isRequired ,
169
+ disabledFields : React . PropTypes . array . isRequired ,
170
+ isRemovable : React . PropTypes . bool . isRequired
120
171
} ;
121
172
122
173
module . exports = CreateIndexField ;
0 commit comments