88import * as Filters from 'lib/Filters' ;
99import { List , Map } from 'immutable' ;
1010import PropTypes from 'lib/PropTypes' ;
11- import React , { useState } from 'react' ;
11+ import React , { useEffect , useState } from 'react' ;
1212import stringCompare from 'lib/stringCompare' ;
1313import { CurrentApp } from 'context/currentApp' ;
1414
@@ -61,7 +61,8 @@ function changeConstraint(schema, currentClassName, filters, index, newConstrain
6161 class : currentClassName ,
6262 field : field ,
6363 constraint : newConstraint ,
64- compareTo : ( compareType && prevCompareTo ) ? prevCompareTo : Filters . DefaultComparisons [ compareType ] ,
64+ compareTo :
65+ compareType && prevCompareTo ? prevCompareTo : Filters . DefaultComparisons [ compareType ] ,
6566 } ) ;
6667 return filters . set ( index , newFilter ) ;
6768}
@@ -75,6 +76,97 @@ function deleteRow(filters, index) {
7576 return filters . delete ( index ) ;
7677}
7778
79+ function deleteRowDraft ( setFiltersArrayDraft , index ) {
80+ return setFiltersArrayDraft ( filtersArrayDraftState =>
81+ filtersArrayDraftState . filter ( ( _ , indexElement ) => indexElement !== index )
82+ ) ;
83+ }
84+
85+ function changeClassDraft ( setFiltersArrayDraft , index , newClassName ) {
86+ setFiltersArrayDraft ( filtersArrayDraftState =>
87+ filtersArrayDraftState . map ( ( element , indexElement ) => {
88+ if ( indexElement === index ) {
89+ return new Map ( {
90+ class : newClassName ,
91+ field : '' ,
92+ } ) ;
93+ } else {
94+ return element ;
95+ }
96+ } )
97+ ) ;
98+ }
99+
100+ function changeFieldDraft (
101+ schema ,
102+ currentClassName ,
103+ filters ,
104+ index ,
105+ newField ,
106+ fields ,
107+ setFiltersArrayDraft
108+ ) {
109+ const fieldIsValid = fields . find ( field => field === newField ) ;
110+
111+ if ( fieldIsValid ) {
112+ const newFilterDraft = new Map ( {
113+ class : currentClassName ,
114+ field : newField ,
115+ constraint : Filters . FieldConstraints [ schema [ currentClassName ] [ newField ] . type ] [ 0 ] ,
116+ compareTo : Filters . DefaultComparisons [ schema [ currentClassName ] [ newField ] . type ] ,
117+ } ) ;
118+
119+ deleteRowDraft ( setFiltersArrayDraft , index ) ;
120+ return filters . push ( newFilterDraft ) ;
121+ } else {
122+ return filters ;
123+ }
124+ }
125+
126+ function getFields ( available , currentClassName , field , currentApp , className ) {
127+ let fields = [ ] ;
128+ if ( available [ currentClassName ] ) {
129+ fields = Object . keys ( available [ currentClassName ] ) . concat ( [ ] ) ;
130+ }
131+ if ( field !== '' && fields . indexOf ( field ) < 0 ) {
132+ fields . push ( field ) ;
133+ }
134+
135+ // Get the column preference of the current class.
136+ const currentColumnPreference = currentApp . columnPreference
137+ ? currentApp . columnPreference [ className ]
138+ : null ;
139+
140+ // Check if the preference exists.
141+ if ( currentColumnPreference ) {
142+ const fieldsToSortToTop = currentColumnPreference
143+ . filter ( item => item . filterSortToTop )
144+ . map ( item => item . name ) ;
145+ // Sort the fields.
146+ fields . sort ( ( a , b ) => {
147+ // Only "a" should sorted to the top.
148+ if ( fieldsToSortToTop . includes ( a ) && ! fieldsToSortToTop . includes ( b ) ) {
149+ return - 1 ;
150+ }
151+ // Only "b" should sorted to the top.
152+ if ( ! fieldsToSortToTop . includes ( a ) && fieldsToSortToTop . includes ( b ) ) {
153+ return 1 ;
154+ }
155+ // Both should sorted to the top -> they should be sorted to the same order as in the "fieldsToSortToTop" array.
156+ if ( fieldsToSortToTop . includes ( a ) && fieldsToSortToTop . includes ( b ) ) {
157+ return fieldsToSortToTop . indexOf ( a ) - fieldsToSortToTop . indexOf ( b ) ;
158+ }
159+ return stringCompare ( a , b ) ;
160+ } ) ;
161+ }
162+ // If there's no preference: Use the default sort function.
163+ else {
164+ fields . sort ( ) ;
165+ }
166+
167+ return fields ;
168+ }
169+
78170const Filter = ( {
79171 schema,
80172 filters,
@@ -84,17 +176,38 @@ const Filter = ({
84176 onSearch,
85177 blacklist,
86178 className,
179+ setFiltersArrayDraft,
180+ filtersArrayDraft,
87181} ) => {
88182 const [ compare , setCompare ] = useState ( false ) ;
183+ const [ filtersArrayDraftLengthMemory , setFiltersArrayDraftLengthMemory ] = useState ( 0 ) ;
89184 const hasCompareTo = filters . some ( filter => filter . get ( 'compareTo' ) !== undefined ) ;
90185
91- if ( compare !== hasCompareTo ) {
186+ if ( compare !== hasCompareTo ) {
92187 setCompare ( hasCompareTo ) ;
93188 }
94189 const currentApp = React . useContext ( CurrentApp ) ;
95190 blacklist = blacklist || [ ] ;
96191 const available = Filters . findRelatedClasses ( className , allClasses , blacklist , filters ) ;
97192 const classes = Object . keys ( available ) . concat ( [ ] ) ;
193+
194+ useEffect ( ( ) => {
195+ if ( filters . size === 0 ) {
196+ setFiltersArrayDraft ( ( ) => [
197+ new Map ( {
198+ class : className ,
199+ field : '' ,
200+ } ) ,
201+ ] ) ;
202+ } else {
203+ setFiltersArrayDraft ( ( ) => [ ] ) ;
204+ }
205+ } , [ ] ) ;
206+
207+ useEffect ( ( ) => {
208+ setFiltersArrayDraftLengthMemory ( filtersArrayDraft . length ) ;
209+ } , [ filtersArrayDraft ] ) ;
210+
98211 return (
99212 < div
100213 style = { {
@@ -108,7 +221,7 @@ const Filter = ({
108221 gap : '10px' ,
109222 padding : '12px 15px 0px 15px' ,
110223 color : '#343445' ,
111- 'font-weight' : '600'
224+ 'font-weight' : '600' ,
112225 } }
113226 >
114227 < div style = { { width : '140px' } } > Class</ div >
@@ -123,45 +236,8 @@ const Filter = ({
123236 const field = filter . get ( 'field' ) ;
124237 const constraint = filter . get ( 'constraint' ) ;
125238 const compareTo = filter . get ( 'compareTo' ) ;
126- let fields = [ ] ;
127- if ( available [ currentClassName ] ) {
128- fields = Object . keys ( available [ currentClassName ] ) . concat ( [ ] ) ;
129- }
130- if ( fields . indexOf ( field ) < 0 ) {
131- fields . push ( field ) ;
132- }
239+ const fields = getFields ( available , currentClassName , field , currentApp , className ) ;
133240
134- // Get the column preference of the current class.
135- const currentColumnPreference = currentApp . columnPreference
136- ? currentApp . columnPreference [ className ]
137- : null ;
138-
139- // Check if the preference exists.
140- if ( currentColumnPreference ) {
141- const fieldsToSortToTop = currentColumnPreference
142- . filter ( item => item . filterSortToTop )
143- . map ( item => item . name ) ;
144- // Sort the fields.
145- fields . sort ( ( a , b ) => {
146- // Only "a" should sorted to the top.
147- if ( fieldsToSortToTop . includes ( a ) && ! fieldsToSortToTop . includes ( b ) ) {
148- return - 1 ;
149- }
150- // Only "b" should sorted to the top.
151- if ( ! fieldsToSortToTop . includes ( a ) && fieldsToSortToTop . includes ( b ) ) {
152- return 1 ;
153- }
154- // Both should sorted to the top -> they should be sorted to the same order as in the "fieldsToSortToTop" array.
155- if ( fieldsToSortToTop . includes ( a ) && fieldsToSortToTop . includes ( b ) ) {
156- return fieldsToSortToTop . indexOf ( a ) - fieldsToSortToTop . indexOf ( b ) ;
157- }
158- return stringCompare ( a , b ) ;
159- } ) ;
160- }
161- // If there's no preference: Use the default sort function.
162- else {
163- fields . sort ( ) ;
164- }
165241 const constraints = Filters . FieldConstraints [ schema [ currentClassName ] [ field ] . type ] . filter (
166242 c => blacklist . indexOf ( c ) < 0
167243 ) ;
@@ -206,6 +282,52 @@ const Filter = ({
206282 } ,
207283 } ) ;
208284 } ) }
285+
286+ { filtersArrayDraft . map ( ( filter , i ) => {
287+ const currentClassName = filter . get ( 'class' ) ;
288+ const field = filter . get ( 'field' ) ;
289+ const fields = getFields ( available , currentClassName , field , currentApp , className ) ;
290+
291+ return renderRow ( {
292+ classes,
293+ fields,
294+ constraints : [ 'exists' ] ,
295+ compareInfo : {
296+ type : undefined ,
297+ targetClass : null ,
298+ } ,
299+ currentClass : currentClassName ,
300+ currentField : field ,
301+ currentConstraint : 'exists' ,
302+ key : i + 'draft' + filtersArrayDraft . length ,
303+ initialFocusOnTheField :
304+ filtersArrayDraftLengthMemory === 0 ||
305+ ( filtersArrayDraftLengthMemory < filtersArrayDraft . length &&
306+ filtersArrayDraft . length - 1 === i ) ,
307+ onChangeClass : newClassName => {
308+ changeClassDraft ( setFiltersArrayDraft , i , newClassName ) ;
309+ } ,
310+ onChangeField : newField => {
311+ onChange (
312+ changeFieldDraft (
313+ schema ,
314+ currentClassName ,
315+ filters ,
316+ i ,
317+ newField ,
318+ fields ,
319+ setFiltersArrayDraft
320+ )
321+ ) ;
322+ } ,
323+ onChangeConstraint : ( ) => { } ,
324+ onChangeCompareTo : ( ) => { } ,
325+ onKeyDown : ( ) => { } ,
326+ onDeleteRow : ( ) => {
327+ deleteRowDraft ( setFiltersArrayDraft , i ) ;
328+ } ,
329+ } ) ;
330+ } ) }
209331 </ div >
210332 ) ;
211333} ;
0 commit comments