@@ -1199,28 +1199,6 @@ describe('IgxGrid - Advanced Filtering', () => {
1199
1199
expect ( GridFunctions . getAdvancedFilteringComponent ( fix ) ) . not . toBeNull ( 'Advanced Filtering dialog is not opened.' ) ;
1200
1200
} ) ) ;
1201
1201
1202
- it ( 'Should discard added group when clicking its operator line without having a single expression.' , fakeAsync ( ( ) => {
1203
- // Open Advanced Filtering dialog.
1204
- GridFunctions . clickAdvancedFilteringButton ( fix ) ;
1205
- fix . detectChanges ( ) ;
1206
-
1207
- // Add initial 'and' group.
1208
- const initialAddAndGroupBtn = GridFunctions . getAdvancedFilteringInitialAddGroupButtons ( fix ) [ 0 ] ;
1209
- initialAddAndGroupBtn . click ( ) ;
1210
- tick ( 100 ) ;
1211
- fix . detectChanges ( ) ;
1212
-
1213
- // Click operator line.
1214
- const rootOperatorLine = GridFunctions . getAdvancedFilteringTreeRootGroupOperatorLine ( fix ) ;
1215
- rootOperatorLine . click ( ) ;
1216
- tick ( 200 ) ;
1217
- fix . detectChanges ( ) ;
1218
-
1219
- // Verify group is discarded and the context menu was not opened.
1220
- expect ( GridFunctions . getAdvancedFilteringTreeRootGroup ( fix ) ) . toBeNull ( 'Group is not discarded.' ) ;
1221
- verifyContextMenuVisibility ( fix , false ) ;
1222
- } ) ) ;
1223
-
1224
1202
it ( 'Should display the adding buttons and the cancel button when trying to add a new condition/group to existing group.' ,
1225
1203
fakeAsync ( ( ) => {
1226
1204
// Apply advanced filter through API.
@@ -1396,6 +1374,272 @@ describe('IgxGrid - Advanced Filtering', () => {
1396
1374
'incorrect all children count of group with path [0]' ) ;
1397
1375
} ) ) ;
1398
1376
1377
+ describe ( 'Context Menu' , ( ) => {
1378
+ it ( 'Should discard added group when clicking its operator line without having a single expression.' , fakeAsync ( ( ) => {
1379
+ // Open Advanced Filtering dialog.
1380
+ GridFunctions . clickAdvancedFilteringButton ( fix ) ;
1381
+ fix . detectChanges ( ) ;
1382
+
1383
+ // Add initial 'and' group.
1384
+ const initialAddAndGroupBtn = GridFunctions . getAdvancedFilteringInitialAddGroupButtons ( fix ) [ 0 ] ;
1385
+ initialAddAndGroupBtn . click ( ) ;
1386
+ tick ( 100 ) ;
1387
+ fix . detectChanges ( ) ;
1388
+
1389
+ // Click operator line.
1390
+ const rootOperatorLine = GridFunctions . getAdvancedFilteringTreeRootGroupOperatorLine ( fix ) ;
1391
+ rootOperatorLine . click ( ) ;
1392
+ tick ( 200 ) ;
1393
+ fix . detectChanges ( ) ;
1394
+
1395
+ // Verify group is discarded and the context menu was not opened.
1396
+ expect ( GridFunctions . getAdvancedFilteringTreeRootGroup ( fix ) ) . toBeNull ( 'Group is not discarded.' ) ;
1397
+ verifyContextMenuVisibility ( fix , false ) ;
1398
+ } ) ) ;
1399
+
1400
+ it ( 'Selecting multiple conditions should display the (create group)/(delete filters) context menu.' , fakeAsync ( ( ) => {
1401
+ // Apply advanced filter through API.
1402
+ const tree = new FilteringExpressionsTree ( FilteringLogic . And ) ;
1403
+ tree . filteringOperands . push ( {
1404
+ fieldName : 'Downloads' , searchVal : 100 , condition : IgxNumberFilteringOperand . instance ( ) . condition ( 'greaterThan' )
1405
+ } ) ;
1406
+ const orTree = new FilteringExpressionsTree ( FilteringLogic . Or ) ;
1407
+ orTree . filteringOperands . push ( {
1408
+ fieldName : 'ProductName' , searchVal : 'angular' , condition : IgxStringFilteringOperand . instance ( ) . condition ( 'contains' ) ,
1409
+ ignoreCase : true
1410
+ } ) ;
1411
+ orTree . filteringOperands . push ( {
1412
+ fieldName : 'ProductName' , searchVal : 'script' , condition : IgxStringFilteringOperand . instance ( ) . condition ( 'contains' ) ,
1413
+ ignoreCase : true
1414
+ } ) ;
1415
+ tree . filteringOperands . push ( orTree ) ;
1416
+ grid . advancedFilteringExpressionsTree = tree ;
1417
+ fix . detectChanges ( ) ;
1418
+
1419
+ // Open Advanced Filtering dialog.
1420
+ GridFunctions . clickAdvancedFilteringButton ( fix ) ;
1421
+ fix . detectChanges ( ) ;
1422
+
1423
+ // Verify context menu is not visible.
1424
+ verifyContextMenuVisibility ( fix , false ) ;
1425
+
1426
+ // Select two chips.
1427
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 0 ] ) ;
1428
+ tick ( 400 ) ;
1429
+ fix . detectChanges ( ) ;
1430
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 1 , 1 ] ) ;
1431
+ tick ( 400 ) ;
1432
+ fix . detectChanges ( ) ;
1433
+
1434
+ // Verify context menu is visible.
1435
+ verifyContextMenuVisibility ( fix , true ) ;
1436
+ verifyContextMenuType ( fix , false ) ;
1437
+
1438
+ // Unselect one of the two selected chips.
1439
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 0 ] ) ;
1440
+ tick ( 400 ) ;
1441
+ fix . detectChanges ( ) ;
1442
+
1443
+ // Verify context menu is no longer visible.
1444
+ verifyContextMenuVisibility ( fix , false ) ;
1445
+ } ) ) ;
1446
+
1447
+ it ( 'Should create an \'and\' group from multiple selected conditions when respective context menu button is clicked.' ,
1448
+ fakeAsync ( ( ) => {
1449
+ // Apply advanced filter through API.
1450
+ const tree = new FilteringExpressionsTree ( FilteringLogic . And ) ;
1451
+ tree . filteringOperands . push ( {
1452
+ fieldName : 'Downloads' , searchVal : 100 , condition : IgxNumberFilteringOperand . instance ( ) . condition ( 'greaterThan' )
1453
+ } ) ;
1454
+ const orTree = new FilteringExpressionsTree ( FilteringLogic . Or ) ;
1455
+ orTree . filteringOperands . push ( {
1456
+ fieldName : 'ProductName' , searchVal : 'angular' , condition : IgxStringFilteringOperand . instance ( ) . condition ( 'contains' ) ,
1457
+ ignoreCase : true
1458
+ } ) ;
1459
+ orTree . filteringOperands . push ( {
1460
+ fieldName : 'ProductName' , searchVal : 'script' , condition : IgxStringFilteringOperand . instance ( ) . condition ( 'contains' ) ,
1461
+ ignoreCase : true
1462
+ } ) ;
1463
+ tree . filteringOperands . push ( orTree ) ;
1464
+ grid . advancedFilteringExpressionsTree = tree ;
1465
+ fix . detectChanges ( ) ;
1466
+
1467
+ // Open Advanced Filtering dialog.
1468
+ GridFunctions . clickAdvancedFilteringButton ( fix ) ;
1469
+ fix . detectChanges ( ) ;
1470
+
1471
+ // Verify tree layout before the creation of a new group with context menu.
1472
+ let rootGroup = GridFunctions . getAdvancedFilteringTreeRootGroup ( fix ) ; // group
1473
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , true ) . length ) . toBe ( 2 ) ;
1474
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , false ) . length ) . toBe ( 4 ) ;
1475
+
1476
+ let firstItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 0 ] ) ; // expression
1477
+ expect ( firstItem . classList . contains ( 'igx-filter-tree__expression-item' ) ) . toBe ( true ) ;
1478
+
1479
+ let secondItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 1 ] ) ; // group
1480
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , true ) . length ) . toBe ( 2 ) ;
1481
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , false ) . length ) . toBe ( 2 ) ;
1482
+
1483
+ // Select two chips.
1484
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 0 ] ) ;
1485
+ tick ( 400 ) ;
1486
+ fix . detectChanges ( ) ;
1487
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 1 , 1 ] ) ;
1488
+ tick ( 400 ) ;
1489
+ fix . detectChanges ( ) ;
1490
+
1491
+ // Click "Create And Group" in context menu.
1492
+ const buttons = GridFunctions . getAdvancedFilteringContextMenuButtons ( fix ) ;
1493
+ buttons [ 1 ] . click ( ) ;
1494
+ tick ( 100 ) ;
1495
+ fix . detectChanges ( ) ;
1496
+
1497
+ // Verify tree layout after the creation of a new group with context menu.
1498
+ rootGroup = GridFunctions . getAdvancedFilteringTreeRootGroup ( fix ) ; // group
1499
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , true ) . length ) . toBe ( 2 ) ;
1500
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , false ) . length ) . toBe ( 5 ) ;
1501
+
1502
+ firstItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 0 ] ) ; // the new group
1503
+ verifyOperatorLine ( GridFunctions . getAdvancedFilteringTreeGroupOperatorLine ( fix , [ 0 ] ) , 'and' ) ;
1504
+ expect ( firstItem . classList . contains ( 'igx-filter-tree__expression-item' ) ) . toBe ( false ) ;
1505
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( firstItem , true ) . length ) . toBe ( 2 ) ;
1506
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( firstItem , false ) . length ) . toBe ( 2 ) ;
1507
+
1508
+ secondItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 1 ] ) ; // group
1509
+ verifyOperatorLine ( GridFunctions . getAdvancedFilteringTreeGroupOperatorLine ( fix , [ 1 ] ) , 'or' ) ;
1510
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , true ) . length ) . toBe ( 1 ) ;
1511
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , false ) . length ) . toBe ( 1 ) ;
1512
+ } ) ) ;
1513
+
1514
+ it ( 'Should create an \'or\' group from multiple selected conditions when respective context menu button is clicked.' ,
1515
+ fakeAsync ( ( ) => {
1516
+ // Apply advanced filter through API.
1517
+ const tree = new FilteringExpressionsTree ( FilteringLogic . And ) ;
1518
+ tree . filteringOperands . push ( {
1519
+ fieldName : 'Downloads' , searchVal : 100 , condition : IgxNumberFilteringOperand . instance ( ) . condition ( 'greaterThan' )
1520
+ } ) ;
1521
+ const orTree = new FilteringExpressionsTree ( FilteringLogic . Or ) ;
1522
+ orTree . filteringOperands . push ( {
1523
+ fieldName : 'ProductName' , searchVal : 'angular' , condition : IgxStringFilteringOperand . instance ( ) . condition ( 'contains' ) ,
1524
+ ignoreCase : true
1525
+ } ) ;
1526
+ orTree . filteringOperands . push ( {
1527
+ fieldName : 'ProductName' , searchVal : 'script' , condition : IgxStringFilteringOperand . instance ( ) . condition ( 'contains' ) ,
1528
+ ignoreCase : true
1529
+ } ) ;
1530
+ tree . filteringOperands . push ( orTree ) ;
1531
+ grid . advancedFilteringExpressionsTree = tree ;
1532
+ fix . detectChanges ( ) ;
1533
+
1534
+ // Open Advanced Filtering dialog.
1535
+ GridFunctions . clickAdvancedFilteringButton ( fix ) ;
1536
+ fix . detectChanges ( ) ;
1537
+
1538
+ // Verify tree layout before the creation of a new group with context menu.
1539
+ let rootGroup = GridFunctions . getAdvancedFilteringTreeRootGroup ( fix ) ; // group
1540
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , true ) . length ) . toBe ( 2 ) ;
1541
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , false ) . length ) . toBe ( 4 ) ;
1542
+
1543
+ let firstItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 0 ] ) ; // expression
1544
+ expect ( firstItem . classList . contains ( 'igx-filter-tree__expression-item' ) ) . toBe ( true ) ;
1545
+
1546
+ let secondItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 1 ] ) ; // group
1547
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , true ) . length ) . toBe ( 2 ) ;
1548
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , false ) . length ) . toBe ( 2 ) ;
1549
+
1550
+ // Select two chips.
1551
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 0 ] ) ;
1552
+ tick ( 400 ) ;
1553
+ fix . detectChanges ( ) ;
1554
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 1 , 1 ] ) ;
1555
+ tick ( 400 ) ;
1556
+ fix . detectChanges ( ) ;
1557
+
1558
+ // Click "Create Or Group" in context menu.
1559
+ const buttons = GridFunctions . getAdvancedFilteringContextMenuButtons ( fix ) ;
1560
+ buttons [ 2 ] . click ( ) ;
1561
+ tick ( 100 ) ;
1562
+ fix . detectChanges ( ) ;
1563
+
1564
+ // Verify tree layout after the creation of a new group with context menu.
1565
+ rootGroup = GridFunctions . getAdvancedFilteringTreeRootGroup ( fix ) ; // group
1566
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , true ) . length ) . toBe ( 2 ) ;
1567
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , false ) . length ) . toBe ( 5 ) ;
1568
+
1569
+ firstItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 0 ] ) ; // the new group
1570
+ verifyOperatorLine ( GridFunctions . getAdvancedFilteringTreeGroupOperatorLine ( fix , [ 0 ] ) , 'or' ) ;
1571
+ expect ( firstItem . classList . contains ( 'igx-filter-tree__expression-item' ) ) . toBe ( false ) ;
1572
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( firstItem , true ) . length ) . toBe ( 2 ) ;
1573
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( firstItem , false ) . length ) . toBe ( 2 ) ;
1574
+
1575
+ secondItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 1 ] ) ; // group
1576
+ verifyOperatorLine ( GridFunctions . getAdvancedFilteringTreeGroupOperatorLine ( fix , [ 1 ] ) , 'or' ) ;
1577
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , true ) . length ) . toBe ( 1 ) ;
1578
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , false ) . length ) . toBe ( 1 ) ;
1579
+ } ) ) ;
1580
+
1581
+ it ( 'Should delete all selected conditions when the \'delete filters\' option from context menu is clicked.' ,
1582
+ fakeAsync ( ( ) => {
1583
+ // Apply advanced filter through API.
1584
+ const tree = new FilteringExpressionsTree ( FilteringLogic . And ) ;
1585
+ tree . filteringOperands . push ( {
1586
+ fieldName : 'Downloads' , searchVal : 100 , condition : IgxNumberFilteringOperand . instance ( ) . condition ( 'greaterThan' )
1587
+ } ) ;
1588
+ const orTree = new FilteringExpressionsTree ( FilteringLogic . Or ) ;
1589
+ orTree . filteringOperands . push ( {
1590
+ fieldName : 'ProductName' , searchVal : 'angular' , condition : IgxStringFilteringOperand . instance ( ) . condition ( 'contains' ) ,
1591
+ ignoreCase : true
1592
+ } ) ;
1593
+ orTree . filteringOperands . push ( {
1594
+ fieldName : 'ProductName' , searchVal : 'script' , condition : IgxStringFilteringOperand . instance ( ) . condition ( 'contains' ) ,
1595
+ ignoreCase : true
1596
+ } ) ;
1597
+ tree . filteringOperands . push ( orTree ) ;
1598
+ grid . advancedFilteringExpressionsTree = tree ;
1599
+ fix . detectChanges ( ) ;
1600
+
1601
+ // Open Advanced Filtering dialog.
1602
+ GridFunctions . clickAdvancedFilteringButton ( fix ) ;
1603
+ fix . detectChanges ( ) ;
1604
+
1605
+ // Verify tree layout before the creation of a new group with context menu.
1606
+ let rootGroup = GridFunctions . getAdvancedFilteringTreeRootGroup ( fix ) ; // group
1607
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , true ) . length ) . toBe ( 2 ) ;
1608
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , false ) . length ) . toBe ( 4 ) ;
1609
+
1610
+ let firstItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 0 ] ) ; // expression
1611
+ expect ( firstItem . classList . contains ( 'igx-filter-tree__expression-item' ) ) . toBe ( true ) ;
1612
+
1613
+ const secondItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 1 ] ) ; // group
1614
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , true ) . length ) . toBe ( 2 ) ;
1615
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( secondItem , false ) . length ) . toBe ( 2 ) ;
1616
+
1617
+ // Select two chips.
1618
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 0 ] ) ;
1619
+ tick ( 400 ) ;
1620
+ fix . detectChanges ( ) ;
1621
+ GridFunctions . clickAdvancedFilteringTreeExpressionChip ( fix , [ 1 , 1 ] ) ;
1622
+ tick ( 400 ) ;
1623
+ fix . detectChanges ( ) ;
1624
+
1625
+ // Click "Delete Filters" in context menu.
1626
+ const buttons = GridFunctions . getAdvancedFilteringContextMenuButtons ( fix ) ;
1627
+ buttons [ 3 ] . click ( ) ;
1628
+ tick ( 100 ) ;
1629
+ fix . detectChanges ( ) ;
1630
+
1631
+ // Verify tree layout after deleting some expressions with the context menu.
1632
+ rootGroup = GridFunctions . getAdvancedFilteringTreeRootGroup ( fix ) ; // group
1633
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , true ) . length ) . toBe ( 1 ) ;
1634
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( rootGroup , false ) . length ) . toBe ( 2 ) ;
1635
+
1636
+ firstItem = GridFunctions . getAdvancedFilteringTreeItem ( fix , [ 0 ] ) ; // group
1637
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( firstItem , true ) . length ) . toBe ( 1 ) ;
1638
+ expect ( GridFunctions . getAdvancedFilteringTreeChildItems ( firstItem , false ) . length ) . toBe ( 1 ) ;
1639
+ verifyExpressionChipContent ( fix , [ 0 , 0 ] , 'ProductName' , 'Contains' , 'angular' ) ;
1640
+ } ) ) ;
1641
+ } ) ;
1642
+
1399
1643
describe ( 'Localization' , ( ) => {
1400
1644
it ( 'Should correctly change resource strings for Advanced Filtering dialog.' , fakeAsync ( ( ) => {
1401
1645
fix = TestBed . createComponent ( IgxGridAdvancedFilteringComponent ) ;
@@ -1757,6 +2001,29 @@ function verifyContextMenuVisibility(fix, shouldBeVisible: boolean) {
1757
2001
expect ( contextMenuRect . width === 0 && contextMenuRect . height === 0 ) . toBe ( ! shouldBeVisible , 'incorrect context menu dimensions' ) ;
1758
2002
}
1759
2003
2004
+ /**
2005
+ * Verifies the type of the context menu (menu for specific group or menu for combining expressions).
2006
+ * If contextual group is expected, the context menu should contain buttons for operator change, ungroup and delete.
2007
+ * If contextual group is not expected, the context menu should contain buttons for creating new group by combining expressions.
2008
+ */
2009
+ function verifyContextMenuType ( fix , shouldBeContextualGroup : boolean ) {
2010
+ const contextMenuButtons = GridFunctions . getAdvancedFilteringContextMenuButtons ( fix ) ;
2011
+ expect ( GridFunctions . getAdvancedFilteringContextMenuButtonGroup ( fix ) !== null ) . toBe ( shouldBeContextualGroup ) ;
2012
+
2013
+ if ( shouldBeContextualGroup ) {
2014
+ expect ( contextMenuButtons . length ) . toBe ( 3 , 'incorrect buttons count in context menu' ) ;
2015
+ expect ( contextMenuButtons [ 0 ] . innerText . toLowerCase ( ) ) . toBe ( 'close' ) ;
2016
+ expect ( contextMenuButtons [ 1 ] . innerText . toLowerCase ( ) ) . toBe ( 'ungroup' ) ;
2017
+ expect ( contextMenuButtons [ 2 ] . innerText . toLowerCase ( ) ) . toBe ( 'delete' ) ;
2018
+ } else {
2019
+ expect ( contextMenuButtons . length ) . toBe ( 4 , 'incorrect buttons count in context menu' ) ;
2020
+ expect ( contextMenuButtons [ 0 ] . innerText . toLowerCase ( ) ) . toBe ( 'close' ) ;
2021
+ expect ( contextMenuButtons [ 1 ] . innerText . toLowerCase ( ) ) . toBe ( 'create "and" group' ) ;
2022
+ expect ( contextMenuButtons [ 2 ] . innerText . toLowerCase ( ) ) . toBe ( 'create "or" group' ) ;
2023
+ expect ( contextMenuButtons [ 3 ] . innerText . toLowerCase ( ) ) . toBe ( 'delete filters' ) ;
2024
+ }
2025
+ }
2026
+
1760
2027
function verifyEqualArrays ( firstArr : any [ ] , secondArr : any [ ] ) {
1761
2028
expect ( firstArr . length ) . toEqual ( secondArr . length , 'Array lengths mismatch.' ) ;
1762
2029
firstArr = firstArr . sort ( ) ;
0 commit comments