@@ -2,7 +2,7 @@ import React from 'react';
2
2
import {
3
3
prop , uniqBy , indexBy , fromPairs
4
4
} from 'ramda' ;
5
- import { ResultSet , defaultHeuristics , moveItemInArray } from '@cubejs-client/core' ;
5
+ import { ResultSet , moveItemInArray } from '@cubejs-client/core' ;
6
6
import QueryRenderer from './QueryRenderer.jsx' ;
7
7
import CubeContext from './CubeContext' ;
8
8
@@ -25,7 +25,7 @@ export default class QueryBuilder extends React.Component {
25
25
if ( Array . isArray ( props . query ) ) {
26
26
throw new Error ( 'Array of queries is not supported.' ) ;
27
27
}
28
-
28
+
29
29
return {
30
30
...nextState ,
31
31
query : {
@@ -34,12 +34,12 @@ export default class QueryBuilder extends React.Component {
34
34
} ,
35
35
} ;
36
36
}
37
-
37
+
38
38
static resolveMember ( type , { meta, query } ) {
39
39
if ( ! meta ) {
40
40
return [ ] ;
41
41
}
42
-
42
+
43
43
if ( Array . isArray ( query ) ) {
44
44
return query . reduce ( ( memo , currentQuery ) => memo . concat ( QueryBuilder . resolveMember ( type , {
45
45
meta,
@@ -63,10 +63,10 @@ export default class QueryBuilder extends React.Component {
63
63
...meta . resolveMember ( m , type )
64
64
} ) ) ;
65
65
}
66
-
66
+
67
67
static getOrderMembers ( state ) {
68
68
const { query, meta } = state ;
69
-
69
+
70
70
if ( ! meta ) {
71
71
return [ ] ;
72
72
}
@@ -88,7 +88,7 @@ export default class QueryBuilder extends React.Component {
88
88
} ) )
89
89
) ;
90
90
}
91
-
91
+
92
92
constructor ( props ) {
93
93
super ( props ) ;
94
94
@@ -100,7 +100,7 @@ export default class QueryBuilder extends React.Component {
100
100
validatedQuery : props . query ,
101
101
...props . vizState
102
102
} ;
103
-
103
+
104
104
this . mutexObj = { } ;
105
105
}
106
106
@@ -117,7 +117,7 @@ export default class QueryBuilder extends React.Component {
117
117
} else {
118
118
meta = await this . cubejsApi ( ) . meta ( ) ;
119
119
}
120
-
120
+
121
121
this . setState ( {
122
122
meta,
123
123
orderMembers : QueryBuilder . getOrderMembers ( { meta, query } ) ,
@@ -173,7 +173,7 @@ export default class QueryBuilder extends React.Component {
173
173
} ) ;
174
174
}
175
175
} ) ;
176
-
176
+
177
177
const {
178
178
meta,
179
179
query,
@@ -231,7 +231,7 @@ export default class QueryBuilder extends React.Component {
231
231
if ( sourceIndex == null || destinationIndex == null ) {
232
232
return ;
233
233
}
234
-
234
+
235
235
this . updateVizState ( {
236
236
orderMembers : moveItemInArray ( orderMembers , sourceIndex , destinationIndex )
237
237
} ) ;
@@ -252,23 +252,23 @@ export default class QueryBuilder extends React.Component {
252
252
} ;
253
253
const id = pivotConfig [ sourceAxis ] [ sourceIndex ] ;
254
254
const lastIndex = nextPivotConfig [ destinationAxis ] . length - 1 ;
255
-
255
+
256
256
if ( id === 'measures' ) {
257
257
destinationIndex = lastIndex + 1 ;
258
258
} else if ( destinationIndex >= lastIndex && nextPivotConfig [ destinationAxis ] [ lastIndex ] === 'measures' ) {
259
259
destinationIndex = lastIndex - 1 ;
260
260
}
261
-
261
+
262
262
nextPivotConfig [ sourceAxis ] . splice ( sourceIndex , 1 ) ;
263
263
nextPivotConfig [ destinationAxis ] . splice ( destinationIndex , 0 , id ) ;
264
-
264
+
265
265
this . updateVizState ( {
266
266
pivotConfig : nextPivotConfig
267
267
} ) ;
268
268
} ,
269
269
update : ( config ) => {
270
270
const { limit } = config ;
271
-
271
+
272
272
if ( limit == null ) {
273
273
this . updateVizState ( {
274
274
pivotConfig : {
@@ -299,7 +299,7 @@ export default class QueryBuilder extends React.Component {
299
299
async updateVizState ( state ) {
300
300
const { setQuery, setVizState } = this . props ;
301
301
const { query : stateQuery , pivotConfig : statePivotConfig } = this . state ;
302
-
302
+
303
303
let pivotQuery = { } ;
304
304
let finalState = this . applyStateChangeHeuristics ( state ) ;
305
305
const { order : _ , ...query } = finalState . query || stateQuery ;
@@ -385,17 +385,161 @@ export default class QueryBuilder extends React.Component {
385
385
} ;
386
386
}
387
387
388
+ defaultHeuristics ( newState ) {
389
+ const { query, sessionGranularity } = this . state ;
390
+ const defaultGranularity = sessionGranularity || 'day' ;
391
+
392
+ if ( Array . isArray ( query ) ) {
393
+ return newState ;
394
+ }
395
+
396
+ if ( newState . query ) {
397
+ const oldQuery = query ;
398
+ let newQuery = newState . query ;
399
+
400
+ const { meta } = this . state ;
401
+
402
+ if (
403
+ ( oldQuery . timeDimensions || [ ] ) . length === 1
404
+ && ( newQuery . timeDimensions || [ ] ) . length === 1
405
+ && newQuery . timeDimensions [ 0 ] . granularity
406
+ && oldQuery . timeDimensions [ 0 ] . granularity !== newQuery . timeDimensions [ 0 ] . granularity
407
+ ) {
408
+ newState = {
409
+ ...newState ,
410
+ sessionGranularity : newQuery . timeDimensions [ 0 ] . granularity
411
+ } ;
412
+ }
413
+
414
+ if (
415
+ ( ( oldQuery . measures || [ ] ) . length === 0 && ( newQuery . measures || [ ] ) . length > 0 )
416
+ || ( ( oldQuery . measures || [ ] ) . length === 1
417
+ && ( newQuery . measures || [ ] ) . length === 1
418
+ && oldQuery . measures [ 0 ] !== newQuery . measures [ 0 ] )
419
+ ) {
420
+ const defaultTimeDimension = meta . defaultTimeDimensionNameFor ( newQuery . measures [ 0 ] ) ;
421
+ newQuery = {
422
+ ...newQuery ,
423
+ timeDimensions : defaultTimeDimension
424
+ ? [
425
+ {
426
+ dimension : defaultTimeDimension ,
427
+ granularity : defaultGranularity
428
+ }
429
+ ]
430
+ : [ ]
431
+ } ;
432
+
433
+ return {
434
+ ...newState ,
435
+ pivotConfig : null ,
436
+ shouldApplyHeuristicOrder : true ,
437
+ query : newQuery ,
438
+ chartType : defaultTimeDimension ? 'line' : 'number'
439
+ } ;
440
+ }
441
+
442
+ if ( ( oldQuery . dimensions || [ ] ) . length === 0 && ( newQuery . dimensions || [ ] ) . length > 0 ) {
443
+ newQuery = {
444
+ ...newQuery ,
445
+ timeDimensions : ( newQuery . timeDimensions || [ ] ) . map ( ( td ) => ( { ...td , granularity : undefined } ) )
446
+ } ;
447
+
448
+ return {
449
+ ...newState ,
450
+ pivotConfig : null ,
451
+ shouldApplyHeuristicOrder : true ,
452
+ query : newQuery ,
453
+ chartType : 'table'
454
+ } ;
455
+ }
456
+
457
+ if ( ( oldQuery . dimensions || [ ] ) . length > 0 && ( newQuery . dimensions || [ ] ) . length === 0 ) {
458
+ newQuery = {
459
+ ...newQuery ,
460
+ timeDimensions : ( newQuery . timeDimensions || [ ] ) . map ( ( td ) => ( {
461
+ ...td ,
462
+ granularity : td . granularity || defaultGranularity
463
+ } ) )
464
+ } ;
465
+
466
+ return {
467
+ ...newState ,
468
+ pivotConfig : null ,
469
+ shouldApplyHeuristicOrder : true ,
470
+ query : newQuery ,
471
+ chartType : ( newQuery . timeDimensions || [ ] ) . length ? 'line' : 'number'
472
+ } ;
473
+ }
474
+
475
+ if (
476
+ ( ( oldQuery . dimensions || [ ] ) . length > 0 || ( oldQuery . measures || [ ] ) . length > 0 )
477
+ && ( newQuery . dimensions || [ ] ) . length === 0
478
+ && ( newQuery . measures || [ ] ) . length === 0
479
+ ) {
480
+ newQuery = {
481
+ ...newQuery ,
482
+ timeDimensions : [ ] ,
483
+ filters : [ ]
484
+ } ;
485
+
486
+ return {
487
+ ...newState ,
488
+ pivotConfig : null ,
489
+ shouldApplyHeuristicOrder : true ,
490
+ query : newQuery ,
491
+ sessionGranularity : null
492
+ } ;
493
+ }
494
+ return newState ;
495
+ }
496
+
497
+ if ( newState . chartType ) {
498
+ const newChartType = newState . chartType ;
499
+ if (
500
+ ( newChartType === 'line' || newChartType === 'area' )
501
+ && ( query . timeDimensions || [ ] ) . length === 1
502
+ && ! query . timeDimensions [ 0 ] . granularity
503
+ ) {
504
+ const [ td ] = query . timeDimensions ;
505
+ return {
506
+ ...newState ,
507
+ pivotConfig : null ,
508
+ query : {
509
+ ...query ,
510
+ timeDimensions : [ { ...td , granularity : defaultGranularity } ]
511
+ }
512
+ } ;
513
+ }
514
+
515
+ if (
516
+ ( newChartType === 'pie' || newChartType === 'table' || newChartType === 'number' )
517
+ && ( query . timeDimensions || [ ] ) . length === 1
518
+ && query . timeDimensions [ 0 ] . granularity
519
+ ) {
520
+ const [ td ] = query . timeDimensions ;
521
+ return {
522
+ ...newState ,
523
+ pivotConfig : null ,
524
+ shouldApplyHeuristicOrder : true ,
525
+ query : {
526
+ ...query ,
527
+ timeDimensions : [ { ...td , granularity : undefined } ]
528
+ }
529
+ } ;
530
+ }
531
+ }
532
+
533
+ return newState ;
534
+ }
535
+
388
536
applyStateChangeHeuristics ( newState ) {
389
- const { query, meta, sessionGranularity } = this . state ;
390
537
const { stateChangeHeuristics, disableHeuristics } = this . props ;
391
538
if ( disableHeuristics ) {
392
539
return newState ;
393
540
}
394
541
return ( stateChangeHeuristics && stateChangeHeuristics ( this . state , newState ) )
395
- || defaultHeuristics ( newState . query , query , {
396
- meta,
397
- sessionGranularity
398
- } ) ;
542
+ || this . defaultHeuristics ( newState ) ;
399
543
}
400
544
401
545
render ( ) {
0 commit comments