@@ -51,6 +51,14 @@ const types = {
5151 'timediff_gt' : 'Later Than' ,
5252 'exists' : 'Exists' ,
5353 'nexists' : 'Doesn\'t Exist' ,
54+ 'search' : 'Search' ,
55+ } ;
56+
57+ const searchConditions = {
58+ 'any' : 'Any' ,
59+ 'all' : 'All' ,
60+ 'any2any' : 'Any2Any' ,
61+ 'all2any' : 'All2Any' ,
5462} ;
5563
5664export default class Criteria extends React . Component {
@@ -67,30 +75,163 @@ export default class Criteria extends React.Component {
6775 disabled : false ,
6876 }
6977
70- handleChangeKey ( oldKey , key ) {
78+ handleChangeSearchCondition ( key , condition ) {
79+ const { data, onChange } = this . props ;
80+
81+ return onChange ( {
82+ ...data ,
83+ [ key ] : {
84+ ...data [ key ] ,
85+ condition,
86+ } ,
87+ } ) ;
88+ }
89+
90+
91+ handleChangeSearchItemKey ( key , oldItemKey , itemKey ) {
7192 const { onChange } = this . props ;
7293
73- const data = { ...this . props . data } ;
74- delete data [ oldKey ] ;
94+ if ( oldItemKey !== itemKey ) {
95+ const data = { ...this . props . data } ;
96+ const dataItem = { ...data [ key ] . pattern } ;
97+ delete dataItem [ oldItemKey ] ;
98+
99+ return onChange ( {
100+ ...data ,
101+ [ key ] : {
102+ ...data [ key ] ,
103+ pattern : {
104+ ...dataItem ,
105+ [ itemKey ] : {
106+ ...data [ key ] . pattern [ oldItemKey ] ,
107+ } ,
108+ } ,
109+ } ,
110+ } ) ;
111+ }
112+ return onChange ( this . props . data ) ;
113+
114+ }
115+
116+ handleChangeSearchPattern ( key , itemKey , pattern ) {
117+ const { data, onChange } = this . props ;
75118
76119 return onChange ( {
77120 ...data ,
78- [ key ] : this . props . data [ oldKey ] ,
121+ [ key ] : {
122+ ...data [ key ] ,
123+ pattern : {
124+ ...data [ key ] . pattern ,
125+ [ itemKey ] : {
126+ ...data [ key ] . pattern [ itemKey ] ,
127+ pattern,
128+ } ,
129+ } ,
130+ } ,
79131 } ) ;
80132 }
81133
82- handleChangeType ( key , type ) {
134+ handleChangeSearchType ( key , itemKey , type ) {
83135 const { data, onChange } = this . props ;
84136
85137 return onChange ( {
86138 ...data ,
87139 [ key ] : {
88140 ...data [ key ] ,
89- type,
141+ pattern : {
142+ ...data [ key ] . pattern ,
143+ [ itemKey ] : {
144+ ...data [ key ] . pattern [ itemKey ] ,
145+ type,
146+ } ,
147+ } ,
90148 } ,
91149 } ) ;
92150 }
93151
152+ handleAddSearchPatternItem ( key ) {
153+ const { data, onChange } = this . props ;
154+
155+ return onChange ( {
156+ ...data ,
157+ [ key ] : {
158+ ...data [ key ] ,
159+ pattern : {
160+ ...data [ key ] . pattern ,
161+ [ '' ] : {
162+ type : Object . keys ( types ) [ 0 ] ,
163+ } ,
164+ } ,
165+ } ,
166+ } ) ;
167+ }
168+
169+ handleRemoveSearchPatternItem ( key , itemKey ) {
170+ const { onChange } = this . props ;
171+
172+ const data = { ...this . props . data } ;
173+ const dataPattern = { ...this . props . data [ key ] . pattern } ;
174+ delete dataPattern [ itemKey ] ;
175+
176+ return onChange ( {
177+ ...data ,
178+ [ key ] : {
179+ ...data [ key ] ,
180+ pattern : {
181+ ...dataPattern ,
182+ } ,
183+ } ,
184+ } ) ;
185+ }
186+
187+ handleChangeKey ( oldKey , key ) {
188+ const { onChange } = this . props ;
189+
190+ if ( oldKey !== key ) {
191+ const data = { ...this . props . data } ;
192+ delete data [ oldKey ] ;
193+
194+ return onChange ( {
195+ ...data ,
196+ [ key ] : this . props . data [ oldKey ] ,
197+ } ) ;
198+ }
199+ return onChange ( this . props . data ) ;
200+ }
201+
202+ handleChangeType ( key , type ) {
203+ const { data, onChange } = this . props ;
204+
205+ if ( type === 'search' ) {
206+ // save default values for search criteria
207+ return onChange ( {
208+ ...data ,
209+ [ key ] : {
210+ ...data [ key ] ,
211+ type,
212+ condition : 'all' ,
213+ pattern : {
214+ [ '' ] : {
215+ type : Object . keys ( types ) [ 0 ] ,
216+ } ,
217+ } ,
218+ } ,
219+ } ) ;
220+ }
221+ else {
222+ // reset pattern from object to empty string if type != 'search'
223+ this . handleChangePattern ( key , '' ) ;
224+ return onChange ( {
225+ ...data ,
226+ [ key ] : {
227+ ...data [ key ] ,
228+ type,
229+ pattern : '' ,
230+ } ,
231+ } ) ;
232+ }
233+ }
234+
94235 handleChangePattern ( key , pattern ) {
95236 const { data, onChange } = this . props ;
96237
@@ -131,16 +272,23 @@ export default class Criteria extends React.Component {
131272 return (
132273 < div { ...props } className = { cx ( style . component , flat && [ 'st2-auto-form--flat' , style . flat ] , className ) } >
133274 < div >
134- { _ . map ( data , ( { type, pattern } , key ) => (
275+ { _ . map ( data , ( { type, pattern, condition } , key ) => (
135276 < div className = { style . line } key = { key } >
136- < AutoFormCombobox
137- className = { style . entity }
138- disabled = { disabled }
139- data = { key }
140- spec = { spec }
141- onChange = { ( value ) => this . handleChangeKey ( key , value ) }
142- />
277+ < div className = { style . criteriaLabel } >
278+ < AutoFormCombobox
279+ name = 'Key'
280+ className = { style . entity }
281+ disabled = { disabled }
282+ data = { key }
283+ spec = { spec }
284+ onChange = { ( value ) => this . handleChangeKey ( key , value ) }
285+ />
286+ { disabled ? null :
287+ < i className = { cx ( 'icon-cross' , style . remove ) } onClick = { ( ) => this . handleRemove ( key ) } />
288+ }
289+ </ div >
143290 < AutoFormSelect
291+ name = 'Type'
144292 className = { style . entity }
145293 disabled = { disabled }
146294 data = { type }
@@ -150,28 +298,84 @@ export default class Criteria extends React.Component {
150298 } }
151299 onChange = { ( value ) => this . handleChangeType ( key , value ) }
152300 />
153- < AutoFormInput
154- className = { style . entity }
155- disabled = { disabled }
156- data = { pattern }
157- spec = { {
158- required : true ,
159- } }
160- onChange = { ( value ) => this . handleChangePattern ( key , value ) }
161- />
162- { disabled ? null :
163- < i className = { cx ( 'icon-cross' , style . remove ) } onClick = { ( ) => this . handleRemove ( key ) } />
164- }
301+ { type === 'search' ? (
302+ < >
303+ < AutoFormSelect
304+ name = 'Condition'
305+ className = { style . entity }
306+ disabled = { disabled }
307+ data = { condition }
308+ spec = { {
309+ required : true ,
310+ enum : searchConditions ,
311+ } }
312+ onChange = { ( value ) => this . handleChangeSearchCondition ( key , value ) }
313+ />
314+ < div className = { style . break } />
315+ < h5 > Search Patterns < i className = { cx ( 'icon-plus' , style . remove ) } onClick = { ( ) => this . handleAddSearchPatternItem ( key ) } /> </ h5 >
316+ < div className = { style . break } />
317+ { _ . map ( pattern , ( { type, pattern } , itemKey ) => (
318+ < div style = { { display : 'flex' } } key = { itemKey } >
319+ < AutoFormCombobox
320+ name = { 'Item name' }
321+ className = { style . entity }
322+ disabled = { disabled }
323+ data = { itemKey }
324+ spec = { {
325+ required : true ,
326+ enum : [ ] ,
327+ } }
328+ onChange = { ( value ) => this . handleChangeSearchItemKey ( key , itemKey , value ) }
329+ />
330+ < AutoFormSelect
331+ name = { 'Type' }
332+ className = { style . entity }
333+ disabled = { disabled }
334+ data = { type }
335+ spec = { {
336+ required : true ,
337+ enum : types ,
338+ } }
339+ onChange = { ( value ) => this . handleChangeSearchType ( key , itemKey , value ) }
340+ />
341+ < AutoFormInput
342+ name = { 'Pattern' }
343+ className = { style . entity }
344+ disabled = { disabled }
345+ data = { pattern || '' }
346+ spec = { {
347+ required : true ,
348+ } }
349+ onChange = { ( value ) => this . handleChangeSearchPattern ( key , itemKey , value ) }
350+ />
351+ < i
352+ className = { cx ( 'icon-cross' , style . remove , style . subPatternRemove ) } onClick = { ( ) => this . handleRemoveSearchPatternItem ( key , itemKey ) }
353+ />
354+ </ div >
355+ ) ) }
356+ </ >
357+ ) : (
358+ < AutoFormInput
359+ name = { 'Pattern' }
360+ className = { style . entity }
361+ disabled = { disabled }
362+ data = { pattern }
363+ spec = { {
364+ required : true ,
365+ } }
366+ onChange = { ( value ) => this . handleChangePattern ( key , value ) }
367+ />
368+ ) }
165369 </ div >
166370 ) ) }
167371 </ div >
168372 { disabled ? null : (
169373 < div className = { style . buttons } >
170374 < input
171- type = " button"
172- className = " st2-forms__button st2-forms__button--small"
375+ type = ' button'
376+ className = ' st2-forms__button st2-forms__button--small'
173377 onClick = { ( ) => this . handleAdd ( ) }
174- value = " Add criteria"
378+ value = ' Add criteria'
175379 />
176380 </ div >
177381 ) }
0 commit comments