@finos/legend-query-builder 4.10.0 → 4.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
 - package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
 - package/lib/__lib__/QueryBuilderTesting.js +1 -0
 - package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
 - package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
 - package/lib/components/QueryBuilderResultPanel.js +44 -57
 - package/lib/components/QueryBuilderResultPanel.js.map +1 -1
 - package/lib/components/filter/QueryBuilderFilterPanel.d.ts +3 -2
 - package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
 - package/lib/components/filter/QueryBuilderFilterPanel.js +145 -8
 - package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
 - package/lib/index.css +1 -1
 - package/lib/package.json +1 -1
 - package/lib/stores/QueryBuilderResultState.d.ts +3 -0
 - package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
 - package/lib/stores/QueryBuilderResultState.js +31 -2
 - package/lib/stores/QueryBuilderResultState.js.map +1 -1
 - package/lib/stores/filter/QueryBuilderFilterState.d.ts +7 -1
 - package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
 - package/lib/stores/filter/QueryBuilderFilterState.js +27 -0
 - package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
 - package/package.json +5 -5
 - package/src/__lib__/QueryBuilderTesting.ts +1 -0
 - package/src/components/QueryBuilderResultPanel.tsx +63 -76
 - package/src/components/filter/QueryBuilderFilterPanel.tsx +239 -21
 - package/src/stores/QueryBuilderResultState.ts +36 -1
 - package/src/stores/filter/QueryBuilderFilterState.ts +40 -1
 
| 
         @@ -52,7 +52,6 @@ import { 
     | 
|
| 
       52 
52 
     | 
    
         
             
              EnumValueInstanceValue,
         
     | 
| 
       53 
53 
     | 
    
         
             
              EnumValueExplicitReference,
         
     | 
| 
       54 
54 
     | 
    
         
             
              RelationalExecutionActivities,
         
     | 
| 
       55 
     | 
    
         
            -
              getTDSRowRankByColumnInAsc,
         
     | 
| 
       56 
55 
     | 
    
         
             
            } from '@finos/legend-graph';
         
     | 
| 
       57 
56 
     | 
    
         
             
            import {
         
     | 
| 
       58 
57 
     | 
    
         
             
              ActionAlertActionType,
         
     | 
| 
         @@ -63,8 +62,6 @@ import { 
     | 
|
| 
       63 
62 
     | 
    
         
             
            import {
         
     | 
| 
       64 
63 
     | 
    
         
             
              assertErrorThrown,
         
     | 
| 
       65 
64 
     | 
    
         
             
              guaranteeNonNullable,
         
     | 
| 
       66 
     | 
    
         
            -
              isBoolean,
         
     | 
| 
       67 
     | 
    
         
            -
              type PlainObject,
         
     | 
| 
       68 
65 
     | 
    
         
             
              prettyDuration,
         
     | 
| 
       69 
66 
     | 
    
         
             
              filterByType,
         
     | 
| 
       70 
67 
     | 
    
         
             
              isValidURL,
         
     | 
| 
         @@ -420,9 +417,7 @@ const QueryBuilderGridResultContextMenu = observer( 
     | 
|
| 
       420 
417 
     | 
    
         
             
                  ),
         
     | 
| 
       421 
418 
     | 
    
         
             
                );
         
     | 
| 
       422 
419 
     | 
    
         | 
| 
       423 
     | 
    
         
            -
                const  
     | 
| 
       424 
     | 
    
         
            -
                  rowIndex: number,
         
     | 
| 
       425 
     | 
    
         
            -
                ): (string | number | boolean | null)[] => {
         
     | 
| 
      
 420 
     | 
    
         
            +
                const findSelectedCellRowData = (): string => {
         
     | 
| 
       426 
421 
     | 
    
         
             
                  if (
         
     | 
| 
       427 
422 
     | 
    
         
             
                    !tdsState.queryBuilderState.resultState.executionResult ||
         
     | 
| 
       428 
423 
     | 
    
         
             
                    !(
         
     | 
| 
         @@ -430,21 +425,31 @@ const QueryBuilderGridResultContextMenu = observer( 
     | 
|
| 
       430 
425 
     | 
    
         
             
                      TDSExecutionResult
         
     | 
| 
       431 
426 
     | 
    
         
             
                    )
         
     | 
| 
       432 
427 
     | 
    
         
             
                  ) {
         
     | 
| 
       433 
     | 
    
         
            -
                    return  
     | 
| 
      
 428 
     | 
    
         
            +
                    return '';
         
     | 
| 
       434 
429 
     | 
    
         
             
                  }
         
     | 
| 
       435 
     | 
    
         
            -
                   
     | 
| 
       436 
     | 
    
         
            -
                     
     | 
| 
       437 
     | 
    
         
            -
                       
     | 
| 
       438 
     | 
    
         
            -
             
     | 
| 
      
 430 
     | 
    
         
            +
                  const rowData = tdsState.queryBuilderState.resultState.rowData.find(
         
     | 
| 
      
 431 
     | 
    
         
            +
                    (rData) =>
         
     | 
| 
      
 432 
     | 
    
         
            +
                      rData.rowNumber ===
         
     | 
| 
      
 433 
     | 
    
         
            +
                      tdsState.queryBuilderState.resultState.selectedCells[0]?.coordinates
         
     | 
| 
      
 434 
     | 
    
         
            +
                        .rowIndex,
         
     | 
| 
       439 
435 
     | 
    
         
             
                  );
         
     | 
| 
      
 436 
     | 
    
         
            +
                  // try to get the entire row value separated by comma
         
     | 
| 
      
 437 
     | 
    
         
            +
                  // rowData is in format of {columnName: value, columnName1: value, ...., rowNumber:value}
         
     | 
| 
      
 438 
     | 
    
         
            +
                  const valueArr: (string | number | boolean | null | undefined)[] = [];
         
     | 
| 
      
 439 
     | 
    
         
            +
                  if (rowData) {
         
     | 
| 
      
 440 
     | 
    
         
            +
                    Object.entries(rowData).forEach((entry) => {
         
     | 
| 
      
 441 
     | 
    
         
            +
                      if (entry[0] !== 'rowNumber') {
         
     | 
| 
      
 442 
     | 
    
         
            +
                        valueArr.push(entry[1]);
         
     | 
| 
      
 443 
     | 
    
         
            +
                      }
         
     | 
| 
      
 444 
     | 
    
         
            +
                    });
         
     | 
| 
      
 445 
     | 
    
         
            +
                    return valueArr.join(',');
         
     | 
| 
      
 446 
     | 
    
         
            +
                  }
         
     | 
| 
      
 447 
     | 
    
         
            +
                  return '';
         
     | 
| 
       440 
448 
     | 
    
         
             
                };
         
     | 
| 
       441 
449 
     | 
    
         | 
| 
       442 
450 
     | 
    
         
             
                const handleCopyRowValue = applicationStore.guardUnhandledError(() =>
         
     | 
| 
       443 
451 
     | 
    
         
             
                  applicationStore.clipboardService.copyTextToClipboard(
         
     | 
| 
       444 
     | 
    
         
            -
                     
     | 
| 
       445 
     | 
    
         
            -
                      tdsState.queryBuilderState.resultState.selectedCells[0]?.coordinates
         
     | 
| 
       446 
     | 
    
         
            -
                        .rowIndex ?? 0,
         
     | 
| 
       447 
     | 
    
         
            -
                    ).toString(),
         
     | 
| 
      
 452 
     | 
    
         
            +
                    findSelectedCellRowData(),
         
     | 
| 
       448 
453 
     | 
    
         
             
                  ),
         
     | 
| 
       449 
454 
     | 
    
         
             
                );
         
     | 
| 
       450 
455 
     | 
    
         | 
| 
         @@ -502,18 +507,18 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       502 
507 
     | 
    
         
             
                  isString(cellValue) && isValidURL(cellValue) ? cellValue : undefined;
         
     | 
| 
       503 
508 
     | 
    
         
             
                const columnName = params.column?.getColId() ?? '';
         
     | 
| 
       504 
509 
     | 
    
         
             
                const findCoordinatesFromResultValue = (
         
     | 
| 
       505 
     | 
    
         
            -
                   
     | 
| 
      
 510 
     | 
    
         
            +
                  colName: string,
         
     | 
| 
       506 
511 
     | 
    
         
             
                  rowNumber: number,
         
     | 
| 
       507 
512 
     | 
    
         
             
                ): QueryBuilderTDSResultCellCoordinate => {
         
     | 
| 
       508 
513 
     | 
    
         
             
                  const colIndex = tdsExecutionResult.result.columns.findIndex(
         
     | 
| 
       509 
     | 
    
         
            -
                    (col) => col ===  
     | 
| 
      
 514 
     | 
    
         
            +
                    (col) => col === colName,
         
     | 
| 
       510 
515 
     | 
    
         
             
                  );
         
     | 
| 
       511 
516 
     | 
    
         
             
                  return { rowIndex: rowNumber, colIndex: colIndex };
         
     | 
| 
       512 
517 
     | 
    
         
             
                };
         
     | 
| 
       513 
518 
     | 
    
         | 
| 
       514 
519 
     | 
    
         
             
                const currentCellCoordinates = findCoordinatesFromResultValue(
         
     | 
| 
       515 
520 
     | 
    
         
             
                  columnName,
         
     | 
| 
       516 
     | 
    
         
            -
                  params. 
     | 
| 
      
 521 
     | 
    
         
            +
                  params.data.rowNumber,
         
     | 
| 
       517 
522 
     | 
    
         
             
                );
         
     | 
| 
       518 
523 
     | 
    
         
             
                const cellInFilteredResults = resultState.selectedCells.some(
         
     | 
| 
       519 
524 
     | 
    
         
             
                  (result) =>
         
     | 
| 
         @@ -521,9 +526,9 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       521 
526 
     | 
    
         
             
                    result.coordinates.rowIndex === currentCellCoordinates.rowIndex,
         
     | 
| 
       522 
527 
     | 
    
         
             
                );
         
     | 
| 
       523 
528 
     | 
    
         | 
| 
       524 
     | 
    
         
            -
                const  
     | 
| 
      
 529 
     | 
    
         
            +
                const findColumnNameFromColumnIndex = (
         
     | 
| 
       525 
530 
     | 
    
         
             
                  colIndex: number,
         
     | 
| 
       526 
     | 
    
         
            -
                ): string |  
     | 
| 
      
 531 
     | 
    
         
            +
                ): string | undefined => {
         
     | 
| 
       527 
532 
     | 
    
         
             
                  if (
         
     | 
| 
       528 
533 
     | 
    
         
             
                    !resultState.executionResult ||
         
     | 
| 
       529 
534 
     | 
    
         
             
                    !(resultState.executionResult instanceof TDSExecutionResult)
         
     | 
| 
         @@ -534,30 +539,12 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       534 
539 
     | 
    
         
             
                };
         
     | 
| 
       535 
540 
     | 
    
         | 
| 
       536 
541 
     | 
    
         
             
                const findResultValueFromCoordinates = (
         
     | 
| 
       537 
     | 
    
         
            -
                   
     | 
| 
       538 
     | 
    
         
            -
             
     | 
| 
       539 
     | 
    
         
            -
             
     | 
| 
       540 
     | 
    
         
            -
                   
     | 
| 
       541 
     | 
    
         
            -
             
     | 
| 
       542 
     | 
    
         
            -
                   
     | 
| 
       543 
     | 
    
         
            -
                    !resultState.executionResult ||
         
     | 
| 
       544 
     | 
    
         
            -
                    !(resultState.executionResult instanceof TDSExecutionResult)
         
     | 
| 
       545 
     | 
    
         
            -
                  ) {
         
     | 
| 
       546 
     | 
    
         
            -
                    return undefined;
         
     | 
| 
       547 
     | 
    
         
            -
                  }
         
     | 
| 
       548 
     | 
    
         
            -
                  if (params.columnApi.getColumnState()[colIndex]?.sort === 'asc') {
         
     | 
| 
       549 
     | 
    
         
            -
                    resultState.executionResult.result.rows.sort((a, b) =>
         
     | 
| 
       550 
     | 
    
         
            -
                      getTDSRowRankByColumnInAsc(a, b, colIndex),
         
     | 
| 
       551 
     | 
    
         
            -
                    );
         
     | 
| 
       552 
     | 
    
         
            -
                  } else if (params.columnApi.getColumnState()[colIndex]?.sort === 'desc') {
         
     | 
| 
       553 
     | 
    
         
            -
                    resultState.executionResult.result.rows.sort((a, b) =>
         
     | 
| 
       554 
     | 
    
         
            -
                      getTDSRowRankByColumnInAsc(b, a, colIndex),
         
     | 
| 
       555 
     | 
    
         
            -
                    );
         
     | 
| 
       556 
     | 
    
         
            -
                  }
         
     | 
| 
       557 
     | 
    
         
            -
                  return resultState.executionResult.result.rows[rowIndex]?.values[
         
     | 
| 
       558 
     | 
    
         
            -
                    colIndex
         
     | 
| 
       559 
     | 
    
         
            -
                  ];
         
     | 
| 
       560 
     | 
    
         
            -
                };
         
     | 
| 
      
 542 
     | 
    
         
            +
                  rowIndex: number,
         
     | 
| 
      
 543 
     | 
    
         
            +
                  colName: string,
         
     | 
| 
      
 544 
     | 
    
         
            +
                ): string | number | boolean | null | undefined =>
         
     | 
| 
      
 545 
     | 
    
         
            +
                  resultState.rowData.find((data) => data.rowNumber === rowIndex)![
         
     | 
| 
      
 546 
     | 
    
         
            +
                    colName
         
     | 
| 
      
 547 
     | 
    
         
            +
                  ] as string | number | boolean | null | undefined;
         
     | 
| 
       561 
548 
     | 
    
         | 
| 
       562 
549 
     | 
    
         
             
                const isCoordinatesSelected = (
         
     | 
| 
       563 
550 
     | 
    
         
             
                  resultCoordinate: QueryBuilderTDSResultCellCoordinate,
         
     | 
| 
         @@ -574,12 +561,12 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       574 
561 
     | 
    
         
             
                  if (event.shiftKey) {
         
     | 
| 
       575 
562 
     | 
    
         
             
                    const coordinates = findCoordinatesFromResultValue(
         
     | 
| 
       576 
563 
     | 
    
         
             
                      columnName,
         
     | 
| 
       577 
     | 
    
         
            -
                      params. 
     | 
| 
      
 564 
     | 
    
         
            +
                      params.data.rowNumber,
         
     | 
| 
       578 
565 
     | 
    
         
             
                    );
         
     | 
| 
       579 
     | 
    
         
            -
                    const actualValue = findResultValueFromCoordinates( 
     | 
| 
      
 566 
     | 
    
         
            +
                    const actualValue = findResultValueFromCoordinates(
         
     | 
| 
       580 
567 
     | 
    
         
             
                      coordinates.rowIndex,
         
     | 
| 
       581 
     | 
    
         
            -
                       
     | 
| 
       582 
     | 
    
         
            -
                     
     | 
| 
      
 568 
     | 
    
         
            +
                      columnName,
         
     | 
| 
      
 569 
     | 
    
         
            +
                    );
         
     | 
| 
       583 
570 
     | 
    
         
             
                    resultState.addSelectedCell({
         
     | 
| 
       584 
571 
     | 
    
         
             
                      value: actualValue,
         
     | 
| 
       585 
572 
     | 
    
         
             
                      columnName: columnName,
         
     | 
| 
         @@ -593,12 +580,12 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       593 
580 
     | 
    
         
             
                    resultState.setSelectedCells([]);
         
     | 
| 
       594 
581 
     | 
    
         
             
                    const coordinates = findCoordinatesFromResultValue(
         
     | 
| 
       595 
582 
     | 
    
         
             
                      columnName,
         
     | 
| 
       596 
     | 
    
         
            -
                      params. 
     | 
| 
      
 583 
     | 
    
         
            +
                      params.data.rowNumber,
         
     | 
| 
       597 
584 
     | 
    
         
             
                    );
         
     | 
| 
       598 
     | 
    
         
            -
                    const actualValue = findResultValueFromCoordinates( 
     | 
| 
      
 585 
     | 
    
         
            +
                    const actualValue = findResultValueFromCoordinates(
         
     | 
| 
       599 
586 
     | 
    
         
             
                      coordinates.rowIndex,
         
     | 
| 
       600 
     | 
    
         
            -
                       
     | 
| 
       601 
     | 
    
         
            -
                     
     | 
| 
      
 587 
     | 
    
         
            +
                      columnName,
         
     | 
| 
      
 588 
     | 
    
         
            +
                    );
         
     | 
| 
       602 
589 
     | 
    
         
             
                    resultState.setSelectedCells([
         
     | 
| 
       603 
590 
     | 
    
         
             
                      {
         
     | 
| 
       604 
591 
     | 
    
         
             
                        value: actualValue,
         
     | 
| 
         @@ -612,14 +599,14 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       612 
599 
     | 
    
         
             
                  if (event.button === 2) {
         
     | 
| 
       613 
600 
     | 
    
         
             
                    const coordinates = findCoordinatesFromResultValue(
         
     | 
| 
       614 
601 
     | 
    
         
             
                      columnName,
         
     | 
| 
       615 
     | 
    
         
            -
                      params. 
     | 
| 
      
 602 
     | 
    
         
            +
                      params.data.rowNumber,
         
     | 
| 
       616 
603 
     | 
    
         
             
                    );
         
     | 
| 
       617 
604 
     | 
    
         
             
                    const isInSelected = isCoordinatesSelected(coordinates);
         
     | 
| 
       618 
605 
     | 
    
         
             
                    if (!isInSelected) {
         
     | 
| 
       619 
     | 
    
         
            -
                      const actualValue = findResultValueFromCoordinates( 
     | 
| 
      
 606 
     | 
    
         
            +
                      const actualValue = findResultValueFromCoordinates(
         
     | 
| 
       620 
607 
     | 
    
         
             
                        coordinates.rowIndex,
         
     | 
| 
       621 
     | 
    
         
            -
                         
     | 
| 
       622 
     | 
    
         
            -
                       
     | 
| 
      
 608 
     | 
    
         
            +
                        columnName,
         
     | 
| 
      
 609 
     | 
    
         
            +
                      );
         
     | 
| 
       623 
610 
     | 
    
         
             
                      resultState.setSelectedCells([
         
     | 
| 
       624 
611 
     | 
    
         
             
                        {
         
     | 
| 
       625 
612 
     | 
    
         
             
                          value: actualValue,
         
     | 
| 
         @@ -649,7 +636,7 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       649 
636 
     | 
    
         
             
                    const firstCorner = results.coordinates;
         
     | 
| 
       650 
637 
     | 
    
         
             
                    const secondCorner = findCoordinatesFromResultValue(
         
     | 
| 
       651 
638 
     | 
    
         
             
                      columnName,
         
     | 
| 
       652 
     | 
    
         
            -
                      params. 
     | 
| 
      
 639 
     | 
    
         
            +
                      params.data.rowNumber,
         
     | 
| 
       653 
640 
     | 
    
         
             
                    );
         
     | 
| 
       654 
641 
     | 
    
         | 
| 
       655 
642 
     | 
    
         
             
                    resultState.setSelectedCells([results]);
         
     | 
| 
         @@ -661,11 +648,13 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       661 
648 
     | 
    
         | 
| 
       662 
649 
     | 
    
         
             
                    for (let x = minRow; x <= maxRow; x++) {
         
     | 
| 
       663 
650 
     | 
    
         
             
                      for (let y = minCol; y <= maxCol; y++) {
         
     | 
| 
       664 
     | 
    
         
            -
                        const actualValue = findResultValueFromCoordinates( 
     | 
| 
       665 
     | 
    
         
            -
             
     | 
| 
      
 651 
     | 
    
         
            +
                        const actualValue = findResultValueFromCoordinates(
         
     | 
| 
      
 652 
     | 
    
         
            +
                          x,
         
     | 
| 
      
 653 
     | 
    
         
            +
                          findColumnNameFromColumnIndex(y) as string,
         
     | 
| 
      
 654 
     | 
    
         
            +
                        );
         
     | 
| 
       666 
655 
     | 
    
         
             
                        const valueAndColumnId = {
         
     | 
| 
       667 
656 
     | 
    
         
             
                          value: actualValue,
         
     | 
| 
       668 
     | 
    
         
            -
                          columnName:  
     | 
| 
      
 657 
     | 
    
         
            +
                          columnName: findColumnNameFromColumnIndex(y),
         
     | 
| 
       669 
658 
     | 
    
         
             
                          coordinates: {
         
     | 
| 
       670 
659 
     | 
    
         
             
                            rowIndex: x,
         
     | 
| 
       671 
660 
     | 
    
         
             
                            colIndex: y,
         
     | 
| 
         @@ -684,7 +673,6 @@ const QueryResultCellRenderer = observer( 
     | 
|
| 
       684 
673 
     | 
    
         
             
                      }
         
     | 
| 
       685 
674 
     | 
    
         
             
                    }
         
     | 
| 
       686 
675 
     | 
    
         
             
                  }
         
     | 
| 
       687 
     | 
    
         
            -
             
     | 
| 
       688 
676 
     | 
    
         
             
                  resultState.setMouseOverCell(resultState.selectedCells[0] ?? null);
         
     | 
| 
       689 
677 
     | 
    
         
             
                };
         
     | 
| 
       690 
678 
     | 
    
         | 
| 
         @@ -741,20 +729,6 @@ const QueryBuilderGridResult = observer( 
     | 
|
| 
       741 
729 
     | 
    
         | 
| 
       742 
730 
     | 
    
         
             
                const resultState = queryBuilderState.resultState;
         
     | 
| 
       743 
731 
     | 
    
         | 
| 
       744 
     | 
    
         
            -
                const rowData = executionResult.result.rows.map((_row, rowIdx) => {
         
     | 
| 
       745 
     | 
    
         
            -
                  const row: PlainObject = {};
         
     | 
| 
       746 
     | 
    
         
            -
                  const cols = executionResult.result.columns;
         
     | 
| 
       747 
     | 
    
         
            -
                  _row.values.forEach((value, colIdx) => {
         
     | 
| 
       748 
     | 
    
         
            -
                    // `ag-grid` shows `false` value as empty string so we have
         
     | 
| 
       749 
     | 
    
         
            -
                    // call `.toString()` to avoid this behavior.
         
     | 
| 
       750 
     | 
    
         
            -
                    // See https://github.com/finos/legend-studio/issues/1008
         
     | 
| 
       751 
     | 
    
         
            -
                    row[cols[colIdx] as string] = isBoolean(value) ? String(value) : value;
         
     | 
| 
       752 
     | 
    
         
            -
                  });
         
     | 
| 
       753 
     | 
    
         
            -
             
     | 
| 
       754 
     | 
    
         
            -
                  row.rowNumber = rowIdx;
         
     | 
| 
       755 
     | 
    
         
            -
                  return row;
         
     | 
| 
       756 
     | 
    
         
            -
                });
         
     | 
| 
       757 
     | 
    
         
            -
             
     | 
| 
       758 
732 
     | 
    
         
             
                return (
         
     | 
| 
       759 
733 
     | 
    
         
             
                  <div className="query-builder__result__values__table">
         
     | 
| 
       760 
734 
     | 
    
         
             
                    <div
         
     | 
| 
         @@ -763,7 +737,20 @@ const QueryBuilderGridResult = observer( 
     | 
|
| 
       763 
737 
     | 
    
         
             
                      )}
         
     | 
| 
       764 
738 
     | 
    
         
             
                    >
         
     | 
| 
       765 
739 
     | 
    
         
             
                      <DataGrid
         
     | 
| 
       766 
     | 
    
         
            -
                        rowData={ 
     | 
| 
      
 740 
     | 
    
         
            +
                        rowData={queryBuilderState.resultState.getRowData()}
         
     | 
| 
      
 741 
     | 
    
         
            +
                        onSortChanged={(params) => {
         
     | 
| 
      
 742 
     | 
    
         
            +
                          const sortedData: Record<
         
     | 
| 
      
 743 
     | 
    
         
            +
                            string,
         
     | 
| 
      
 744 
     | 
    
         
            +
                            string | number | boolean | null
         
     | 
| 
      
 745 
     | 
    
         
            +
                          >[] = [];
         
     | 
| 
      
 746 
     | 
    
         
            +
                          params.api.forEachNodeAfterFilterAndSort((node, index) => {
         
     | 
| 
      
 747 
     | 
    
         
            +
                            node.rowIndex = index;
         
     | 
| 
      
 748 
     | 
    
         
            +
                            // rowNumber has to be manually updated after sorting the column
         
     | 
| 
      
 749 
     | 
    
         
            +
                            node.data.rowNumber = index;
         
     | 
| 
      
 750 
     | 
    
         
            +
                            sortedData.push(node.data);
         
     | 
| 
      
 751 
     | 
    
         
            +
                          });
         
     | 
| 
      
 752 
     | 
    
         
            +
                          queryBuilderState.resultState.setRowData(sortedData);
         
     | 
| 
      
 753 
     | 
    
         
            +
                        }}
         
     | 
| 
       767 
754 
     | 
    
         
             
                        gridOptions={{
         
     | 
| 
       768 
755 
     | 
    
         
             
                          suppressScrollOnNewData: true,
         
     | 
| 
       769 
756 
     | 
    
         
             
                          getRowId: (data) => data.data.rowNumber,
         
     | 
| 
         @@ -113,6 +113,7 @@ import { 
     | 
|
| 
       113 
113 
     | 
    
         
             
            import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
         
     | 
| 
       114 
114 
     | 
    
         
             
            import { getPropertyChainName } from '../../stores/QueryBuilderPropertyEditorState.js';
         
     | 
| 
       115 
115 
     | 
    
         
             
            import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../graph/QueryBuilderMetaModelConst.js';
         
     | 
| 
      
 116 
     | 
    
         
            +
            import { buildPropertyExpressionChain } from '../../stores/QueryBuilderValueSpecificationBuilderHelper.js';
         
     | 
| 
       116 
117 
     | 
    
         | 
| 
       117 
118 
     | 
    
         
             
            const isCollectionProperty = (
         
     | 
| 
       118 
119 
     | 
    
         
             
              propertyExpression: AbstractPropertyExpression,
         
     | 
| 
         @@ -151,7 +152,7 @@ const isCollectionProperty = ( 
     | 
|
| 
       151 
152 
     | 
    
         
             
            export const buildFilterTreeWithExists = (
         
     | 
| 
       152 
153 
     | 
    
         
             
              propertyExpression: AbstractPropertyExpression,
         
     | 
| 
       153 
154 
     | 
    
         
             
              filterState: QueryBuilderFilterState,
         
     | 
| 
       154 
     | 
    
         
            -
              targetDropNode?:  
     | 
| 
      
 155 
     | 
    
         
            +
              targetDropNode?: QueryBuilderFilterTreeNodeData,
         
     | 
| 
       155 
156 
     | 
    
         
             
            ): void => {
         
     | 
| 
       156 
157 
     | 
    
         
             
              // 1. Decompose property expression
         
     | 
| 
       157 
158 
     | 
    
         
             
              const expressions: (AbstractPropertyExpression | SimpleFunctionExpression)[] =
         
     | 
| 
         @@ -294,7 +295,21 @@ export const buildFilterTreeWithExists = ( 
     | 
|
| 
       294 
295 
     | 
    
         
             
                            .value.path,
         
     | 
| 
       295 
296 
     | 
    
         
             
                    );
         
     | 
| 
       296 
297 
     | 
    
         
             
                    if (parentPropertyChainIndex >= 0) {
         
     | 
| 
       297 
     | 
    
         
            -
                      parentNode  
     | 
| 
      
 298 
     | 
    
         
            +
                      // Here we choose parentNode based on what the type of targetDropNode
         
     | 
| 
      
 299 
     | 
    
         
            +
                      // 1. QueryBuilderFilterTreeConditionNodeData: In this case we would want to
         
     | 
| 
      
 300 
     | 
    
         
            +
                      // add a new group condition from the targetDropNode and add new exists node
         
     | 
| 
      
 301 
     | 
    
         
            +
                      // getting created as it's child so the parent would be the new group node
         
     | 
| 
      
 302 
     | 
    
         
            +
                      // 2. QueryBuilderFilterTreeGroupNodeData: Parent node would be same as
         
     | 
| 
      
 303 
     | 
    
         
            +
                      // targetDropNode
         
     | 
| 
      
 304 
     | 
    
         
            +
                      // 3. QueryBuilderFilterTreeBlankConditionNodeData: parentNode would be the
         
     | 
| 
      
 305 
     | 
    
         
            +
                      // parent of the targetDropNode. At the end we would deelete this blank node
         
     | 
| 
      
 306 
     | 
    
         
            +
                      // that got created.
         
     | 
| 
      
 307 
     | 
    
         
            +
                      parentNode =
         
     | 
| 
      
 308 
     | 
    
         
            +
                        targetDropNode instanceof QueryBuilderFilterTreeConditionNodeData
         
     | 
| 
      
 309 
     | 
    
         
            +
                          ? filterState.newGroupConditionFromNode(targetDropNode)
         
     | 
| 
      
 310 
     | 
    
         
            +
                          : targetDropNode instanceof QueryBuilderFilterTreeGroupNodeData
         
     | 
| 
      
 311 
     | 
    
         
            +
                          ? targetDropNode
         
     | 
| 
      
 312 
     | 
    
         
            +
                          : filterState.getParentNode(targetDropNode);
         
     | 
| 
       298 
313 
     | 
    
         
             
                      existsLambdaPropertyChains = existsLambdaPropertyChains.slice(
         
     | 
| 
       299 
314 
     | 
    
         
             
                        parentPropertyChainIndex + 1,
         
     | 
| 
       300 
315 
     | 
    
         
             
                      );
         
     | 
| 
         @@ -303,7 +318,12 @@ export const buildFilterTreeWithExists = ( 
     | 
|
| 
       303 
318 
     | 
    
         
             
                      );
         
     | 
| 
       304 
319 
     | 
    
         
             
                    }
         
     | 
| 
       305 
320 
     | 
    
         
             
                  } else if (!parentId) {
         
     | 
| 
       306 
     | 
    
         
            -
                    parentNode = 
     | 
| 
      
 321 
     | 
    
         
            +
                    parentNode =
         
     | 
| 
      
 322 
     | 
    
         
            +
                      targetDropNode instanceof QueryBuilderFilterTreeConditionNodeData
         
     | 
| 
      
 323 
     | 
    
         
            +
                        ? filterState.newGroupConditionFromNode(targetDropNode)
         
     | 
| 
      
 324 
     | 
    
         
            +
                        : targetDropNode instanceof QueryBuilderFilterTreeGroupNodeData
         
     | 
| 
      
 325 
     | 
    
         
            +
                        ? targetDropNode
         
     | 
| 
      
 326 
     | 
    
         
            +
                        : filterState.getParentNode(targetDropNode);
         
     | 
| 
       307 
327 
     | 
    
         
             
                  }
         
     | 
| 
       308 
328 
     | 
    
         
             
                }
         
     | 
| 
       309 
329 
     | 
    
         
             
              }
         
     | 
| 
         @@ -332,6 +352,127 @@ export const buildFilterTreeWithExists = ( 
     | 
|
| 
       332 
352 
     | 
    
         
             
                filterConditionState,
         
     | 
| 
       333 
353 
     | 
    
         
             
              );
         
     | 
| 
       334 
354 
     | 
    
         
             
              filterState.addNodeFromNode(treeNode, parentNode);
         
     | 
| 
      
 355 
     | 
    
         
            +
              if (targetDropNode instanceof QueryBuilderFilterTreeBlankConditionNodeData) {
         
     | 
| 
      
 356 
     | 
    
         
            +
                filterState.removeNodeAndPruneBranch(targetDropNode);
         
     | 
| 
      
 357 
     | 
    
         
            +
              }
         
     | 
| 
      
 358 
     | 
    
         
            +
            };
         
     | 
| 
      
 359 
     | 
    
         
            +
             
     | 
| 
      
 360 
     | 
    
         
            +
            export const buildPropertyExpressionFromExistsNode = (
         
     | 
| 
      
 361 
     | 
    
         
            +
              filterState: QueryBuilderFilterState,
         
     | 
| 
      
 362 
     | 
    
         
            +
              existsNode: QueryBuilderFilterTreeExistsNodeData,
         
     | 
| 
      
 363 
     | 
    
         
            +
              node: QueryBuilderFilterTreeConditionNodeData,
         
     | 
| 
      
 364 
     | 
    
         
            +
            ): AbstractPropertyExpression => {
         
     | 
| 
      
 365 
     | 
    
         
            +
              let nodeParent = filterState.getParentNode(node);
         
     | 
| 
      
 366 
     | 
    
         
            +
              let existsLambdaParameterNames: string[] = [];
         
     | 
| 
      
 367 
     | 
    
         
            +
              let existsLambdaExpressions: AbstractPropertyExpression[] = [];
         
     | 
| 
      
 368 
     | 
    
         
            +
              existsLambdaExpressions.push(
         
     | 
| 
      
 369 
     | 
    
         
            +
                node.condition.propertyExpressionState.propertyExpression,
         
     | 
| 
      
 370 
     | 
    
         
            +
              );
         
     | 
| 
      
 371 
     | 
    
         
            +
              existsLambdaParameterNames.push(
         
     | 
| 
      
 372 
     | 
    
         
            +
                nodeParent?.lambdaParameterName ?? filterState.lambdaParameterName,
         
     | 
| 
      
 373 
     | 
    
         
            +
              );
         
     | 
| 
      
 374 
     | 
    
         
            +
              while (nodeParent && nodeParent.id !== existsNode.id) {
         
     | 
| 
      
 375 
     | 
    
         
            +
                if (nodeParent instanceof QueryBuilderFilterTreeExistsNodeData) {
         
     | 
| 
      
 376 
     | 
    
         
            +
                  existsLambdaExpressions.push(
         
     | 
| 
      
 377 
     | 
    
         
            +
                    nodeParent.propertyExpressionState.propertyExpression,
         
     | 
| 
      
 378 
     | 
    
         
            +
                  );
         
     | 
| 
      
 379 
     | 
    
         
            +
                  existsLambdaParameterNames.push(
         
     | 
| 
      
 380 
     | 
    
         
            +
                    nodeParent.lambdaParameterName ?? filterState.lambdaParameterName,
         
     | 
| 
      
 381 
     | 
    
         
            +
                  );
         
     | 
| 
      
 382 
     | 
    
         
            +
                }
         
     | 
| 
      
 383 
     | 
    
         
            +
                nodeParent = filterState.getParentNode(nodeParent);
         
     | 
| 
      
 384 
     | 
    
         
            +
              }
         
     | 
| 
      
 385 
     | 
    
         
            +
              if (nodeParent?.id === existsNode.id) {
         
     | 
| 
      
 386 
     | 
    
         
            +
                existsLambdaExpressions.push(
         
     | 
| 
      
 387 
     | 
    
         
            +
                  existsNode.propertyExpressionState.propertyExpression,
         
     | 
| 
      
 388 
     | 
    
         
            +
                );
         
     | 
| 
      
 389 
     | 
    
         
            +
                existsLambdaParameterNames.push(
         
     | 
| 
      
 390 
     | 
    
         
            +
                  existsNode.lambdaParameterName ?? filterState.lambdaParameterName,
         
     | 
| 
      
 391 
     | 
    
         
            +
                );
         
     | 
| 
      
 392 
     | 
    
         
            +
              }
         
     | 
| 
      
 393 
     | 
    
         
            +
              existsLambdaParameterNames = existsLambdaParameterNames.reverse();
         
     | 
| 
      
 394 
     | 
    
         
            +
              existsLambdaExpressions = existsLambdaExpressions.reverse();
         
     | 
| 
      
 395 
     | 
    
         
            +
             
     | 
| 
      
 396 
     | 
    
         
            +
              const initialPropertyExpression = guaranteeNonNullable(
         
     | 
| 
      
 397 
     | 
    
         
            +
                existsLambdaExpressions[0],
         
     | 
| 
      
 398 
     | 
    
         
            +
              );
         
     | 
| 
      
 399 
     | 
    
         
            +
              existsLambdaParameterNames = existsLambdaParameterNames.slice(1);
         
     | 
| 
      
 400 
     | 
    
         
            +
              existsLambdaExpressions = existsLambdaExpressions.slice(1);
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
              let flattenedPropertyExpressionChain = new AbstractPropertyExpression('');
         
     | 
| 
      
 403 
     | 
    
         
            +
              flattenedPropertyExpressionChain.func = initialPropertyExpression.func;
         
     | 
| 
      
 404 
     | 
    
         
            +
              flattenedPropertyExpressionChain.parametersValues = [
         
     | 
| 
      
 405 
     | 
    
         
            +
                ...initialPropertyExpression.parametersValues,
         
     | 
| 
      
 406 
     | 
    
         
            +
              ];
         
     | 
| 
      
 407 
     | 
    
         
            +
              for (const exp of existsLambdaExpressions) {
         
     | 
| 
      
 408 
     | 
    
         
            +
                // when rebuilding the property expression chain, disregard the initial variable that starts the chain
         
     | 
| 
      
 409 
     | 
    
         
            +
                const expressions: (
         
     | 
| 
      
 410 
     | 
    
         
            +
                  | AbstractPropertyExpression
         
     | 
| 
      
 411 
     | 
    
         
            +
                  | SimpleFunctionExpression
         
     | 
| 
      
 412 
     | 
    
         
            +
                )[] = [];
         
     | 
| 
      
 413 
     | 
    
         
            +
                let currentExpression: ValueSpecification = exp;
         
     | 
| 
      
 414 
     | 
    
         
            +
                while (
         
     | 
| 
      
 415 
     | 
    
         
            +
                  currentExpression instanceof AbstractPropertyExpression ||
         
     | 
| 
      
 416 
     | 
    
         
            +
                  (currentExpression instanceof SimpleFunctionExpression &&
         
     | 
| 
      
 417 
     | 
    
         
            +
                    matchFunctionName(
         
     | 
| 
      
 418 
     | 
    
         
            +
                      currentExpression.functionName,
         
     | 
| 
      
 419 
     | 
    
         
            +
                      QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
         
     | 
| 
      
 420 
     | 
    
         
            +
                    ))
         
     | 
| 
      
 421 
     | 
    
         
            +
                ) {
         
     | 
| 
      
 422 
     | 
    
         
            +
                  if (currentExpression instanceof SimpleFunctionExpression) {
         
     | 
| 
      
 423 
     | 
    
         
            +
                    const functionExpression = new SimpleFunctionExpression(
         
     | 
| 
      
 424 
     | 
    
         
            +
                      extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE),
         
     | 
| 
      
 425 
     | 
    
         
            +
                    );
         
     | 
| 
      
 426 
     | 
    
         
            +
                    functionExpression.parametersValues.unshift(
         
     | 
| 
      
 427 
     | 
    
         
            +
                      guaranteeNonNullable(currentExpression.parametersValues[1]),
         
     | 
| 
      
 428 
     | 
    
         
            +
                    );
         
     | 
| 
      
 429 
     | 
    
         
            +
                    expressions.push(functionExpression);
         
     | 
| 
      
 430 
     | 
    
         
            +
                  } else if (currentExpression instanceof AbstractPropertyExpression) {
         
     | 
| 
      
 431 
     | 
    
         
            +
                    const propertyExp = new AbstractPropertyExpression('');
         
     | 
| 
      
 432 
     | 
    
         
            +
                    propertyExp.func = currentExpression.func;
         
     | 
| 
      
 433 
     | 
    
         
            +
                    // NOTE: we must retain the rest of the parameters as those are derived property parameters
         
     | 
| 
      
 434 
     | 
    
         
            +
                    propertyExp.parametersValues =
         
     | 
| 
      
 435 
     | 
    
         
            +
                      currentExpression.parametersValues.length > 1
         
     | 
| 
      
 436 
     | 
    
         
            +
                        ? currentExpression.parametersValues.slice(1)
         
     | 
| 
      
 437 
     | 
    
         
            +
                        : [];
         
     | 
| 
      
 438 
     | 
    
         
            +
                    expressions.push(propertyExp);
         
     | 
| 
      
 439 
     | 
    
         
            +
                  }
         
     | 
| 
      
 440 
     | 
    
         
            +
                  currentExpression = guaranteeNonNullable(
         
     | 
| 
      
 441 
     | 
    
         
            +
                    currentExpression.parametersValues[0],
         
     | 
| 
      
 442 
     | 
    
         
            +
                  );
         
     | 
| 
      
 443 
     | 
    
         
            +
                }
         
     | 
| 
      
 444 
     | 
    
         
            +
                assertTrue(
         
     | 
| 
      
 445 
     | 
    
         
            +
                  expressions.length > 0,
         
     | 
| 
      
 446 
     | 
    
         
            +
                  `Can't process exists() expression: exists() usage with non-chain property expression is not supported`,
         
     | 
| 
      
 447 
     | 
    
         
            +
                );
         
     | 
| 
      
 448 
     | 
    
         
            +
                for (let i = 0; i < expressions.length - 1; ++i) {
         
     | 
| 
      
 449 
     | 
    
         
            +
                  (
         
     | 
| 
      
 450 
     | 
    
         
            +
                    expressions[i] as AbstractPropertyExpression | SimpleFunctionExpression
         
     | 
| 
      
 451 
     | 
    
         
            +
                  ).parametersValues.unshift(
         
     | 
| 
      
 452 
     | 
    
         
            +
                    expressions[i + 1] as
         
     | 
| 
      
 453 
     | 
    
         
            +
                      | AbstractPropertyExpression
         
     | 
| 
      
 454 
     | 
    
         
            +
                      | SimpleFunctionExpression,
         
     | 
| 
      
 455 
     | 
    
         
            +
                  );
         
     | 
| 
      
 456 
     | 
    
         
            +
                }
         
     | 
| 
      
 457 
     | 
    
         
            +
                (
         
     | 
| 
      
 458 
     | 
    
         
            +
                  expressions[expressions.length - 1] as
         
     | 
| 
      
 459 
     | 
    
         
            +
                    | AbstractPropertyExpression
         
     | 
| 
      
 460 
     | 
    
         
            +
                    | SimpleFunctionExpression
         
     | 
| 
      
 461 
     | 
    
         
            +
                ).parametersValues.unshift(flattenedPropertyExpressionChain);
         
     | 
| 
      
 462 
     | 
    
         
            +
                flattenedPropertyExpressionChain = guaranteeType(
         
     | 
| 
      
 463 
     | 
    
         
            +
                  expressions[0],
         
     | 
| 
      
 464 
     | 
    
         
            +
                  AbstractPropertyExpression,
         
     | 
| 
      
 465 
     | 
    
         
            +
                  `Can't process exists() expression: can't flatten to a property expression`,
         
     | 
| 
      
 466 
     | 
    
         
            +
                );
         
     | 
| 
      
 467 
     | 
    
         
            +
              }
         
     | 
| 
      
 468 
     | 
    
         
            +
              return guaranteeType(
         
     | 
| 
      
 469 
     | 
    
         
            +
                buildPropertyExpressionChain(
         
     | 
| 
      
 470 
     | 
    
         
            +
                  flattenedPropertyExpressionChain,
         
     | 
| 
      
 471 
     | 
    
         
            +
                  filterState.queryBuilderState,
         
     | 
| 
      
 472 
     | 
    
         
            +
                  existsNode.lambdaParameterName ?? filterState.lambdaParameterName,
         
     | 
| 
      
 473 
     | 
    
         
            +
                ),
         
     | 
| 
      
 474 
     | 
    
         
            +
                AbstractPropertyExpression,
         
     | 
| 
      
 475 
     | 
    
         
            +
              );
         
     | 
| 
       335 
476 
     | 
    
         
             
            };
         
     | 
| 
       336 
477 
     | 
    
         | 
| 
       337 
478 
     | 
    
         
             
            /**
         
     | 
| 
         @@ -340,7 +481,7 @@ export const buildFilterTreeWithExists = ( 
     | 
|
| 
       340 
481 
     | 
    
         
             
            const buildFilterTree = (
         
     | 
| 
       341 
482 
     | 
    
         
             
              propertyExpression: AbstractPropertyExpression,
         
     | 
| 
       342 
483 
     | 
    
         
             
              filterState: QueryBuilderFilterState,
         
     | 
| 
       343 
     | 
    
         
            -
              targetDropNode?:  
     | 
| 
      
 484 
     | 
    
         
            +
              targetDropNode?: QueryBuilderFilterTreeNodeData | undefined,
         
     | 
| 
       344 
485 
     | 
    
         
             
            ): void => {
         
     | 
| 
       345 
486 
     | 
    
         
             
              if (isCollectionProperty(propertyExpression)) {
         
     | 
| 
       346 
487 
     | 
    
         
             
                const propertyChainName = getPropertyChainName(
         
     | 
| 
         @@ -383,12 +524,88 @@ const buildFilterTree = ( 
     | 
|
| 
       383 
524 
     | 
    
         
             
                  undefined,
         
     | 
| 
       384 
525 
     | 
    
         
             
                  filterConditionState,
         
     | 
| 
       385 
526 
     | 
    
         
             
                );
         
     | 
| 
       386 
     | 
    
         
            -
                 
     | 
| 
       387 
     | 
    
         
            -
             
     | 
| 
       388 
     | 
    
         
            -
             
     | 
| 
       389 
     | 
    
         
            -
             
     | 
| 
       390 
     | 
    
         
            -
             
     | 
| 
       391 
     | 
    
         
            -
                 
     | 
| 
      
 527 
     | 
    
         
            +
                // Check if there are any exists node present in the parent nodes of the target.
         
     | 
| 
      
 528 
     | 
    
         
            +
                // This would change the way we build the filter tree
         
     | 
| 
      
 529 
     | 
    
         
            +
                let cn: QueryBuilderFilterTreeNodeData | undefined = targetDropNode;
         
     | 
| 
      
 530 
     | 
    
         
            +
                let existsNode: QueryBuilderFilterTreeExistsNodeData | undefined =
         
     | 
| 
      
 531 
     | 
    
         
            +
                  undefined;
         
     | 
| 
      
 532 
     | 
    
         
            +
                let parentId = targetDropNode?.parentId;
         
     | 
| 
      
 533 
     | 
    
         
            +
                while (parentId) {
         
     | 
| 
      
 534 
     | 
    
         
            +
                  cn = filterState.nodes.get(parentId);
         
     | 
| 
      
 535 
     | 
    
         
            +
                  parentId = cn?.parentId;
         
     | 
| 
      
 536 
     | 
    
         
            +
                  if (cn instanceof QueryBuilderFilterTreeExistsNodeData) {
         
     | 
| 
      
 537 
     | 
    
         
            +
                    existsNode = cn;
         
     | 
| 
      
 538 
     | 
    
         
            +
                  }
         
     | 
| 
      
 539 
     | 
    
         
            +
                }
         
     | 
| 
      
 540 
     | 
    
         
            +
                if (cn instanceof QueryBuilderFilterTreeExistsNodeData) {
         
     | 
| 
      
 541 
     | 
    
         
            +
                  existsNode = cn;
         
     | 
| 
      
 542 
     | 
    
         
            +
                }
         
     | 
| 
      
 543 
     | 
    
         
            +
                if (targetDropNode instanceof QueryBuilderFilterTreeGroupNodeData) {
         
     | 
| 
      
 544 
     | 
    
         
            +
                  if (existsNode) {
         
     | 
| 
      
 545 
     | 
    
         
            +
                    filterState.newGroupConditionFromNode(
         
     | 
| 
      
 546 
     | 
    
         
            +
                      existsNode,
         
     | 
| 
      
 547 
     | 
    
         
            +
                      treeNode,
         
     | 
| 
      
 548 
     | 
    
         
            +
                      targetDropNode.groupOperation,
         
     | 
| 
      
 549 
     | 
    
         
            +
                    );
         
     | 
| 
      
 550 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 551 
     | 
    
         
            +
                    filterState.addNodeFromNode(treeNode, targetDropNode);
         
     | 
| 
      
 552 
     | 
    
         
            +
                  }
         
     | 
| 
      
 553 
     | 
    
         
            +
                } else if (
         
     | 
| 
      
 554 
     | 
    
         
            +
                  targetDropNode instanceof QueryBuilderFilterTreeBlankConditionNodeData
         
     | 
| 
      
 555 
     | 
    
         
            +
                ) {
         
     | 
| 
      
 556 
     | 
    
         
            +
                  if (existsNode) {
         
     | 
| 
      
 557 
     | 
    
         
            +
                    filterState.queryBuilderState.applicationStore.notificationService.notifyError(
         
     | 
| 
      
 558 
     | 
    
         
            +
                      `Can't drag and drop here: property expression of target and source doesn't match`,
         
     | 
| 
      
 559 
     | 
    
         
            +
                    );
         
     | 
| 
      
 560 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 561 
     | 
    
         
            +
                    filterState.replaceBlankNodeWithNode(treeNode, targetDropNode);
         
     | 
| 
      
 562 
     | 
    
         
            +
                  }
         
     | 
| 
      
 563 
     | 
    
         
            +
                } else if (
         
     | 
| 
      
 564 
     | 
    
         
            +
                  existsNode &&
         
     | 
| 
      
 565 
     | 
    
         
            +
                  targetDropNode instanceof QueryBuilderFilterTreeExistsNodeData
         
     | 
| 
      
 566 
     | 
    
         
            +
                ) {
         
     | 
| 
      
 567 
     | 
    
         
            +
                  filterState.newGroupConditionFromNode(existsNode, treeNode);
         
     | 
| 
      
 568 
     | 
    
         
            +
                } else if (
         
     | 
| 
      
 569 
     | 
    
         
            +
                  targetDropNode instanceof QueryBuilderFilterTreeConditionNodeData
         
     | 
| 
      
 570 
     | 
    
         
            +
                ) {
         
     | 
| 
      
 571 
     | 
    
         
            +
                  const parentNode = filterState.getParentNode(targetDropNode);
         
     | 
| 
      
 572 
     | 
    
         
            +
                  if (
         
     | 
| 
      
 573 
     | 
    
         
            +
                    existsNode &&
         
     | 
| 
      
 574 
     | 
    
         
            +
                    parentNode instanceof QueryBuilderFilterTreeExistsNodeData &&
         
     | 
| 
      
 575 
     | 
    
         
            +
                    parentNode.childrenIds.length === 1
         
     | 
| 
      
 576 
     | 
    
         
            +
                  ) {
         
     | 
| 
      
 577 
     | 
    
         
            +
                    filterState.newGroupConditionFromNode(
         
     | 
| 
      
 578 
     | 
    
         
            +
                      existsNode,
         
     | 
| 
      
 579 
     | 
    
         
            +
                      treeNode,
         
     | 
| 
      
 580 
     | 
    
         
            +
                      QUERY_BUILDER_GROUP_OPERATION.AND,
         
     | 
| 
      
 581 
     | 
    
         
            +
                    );
         
     | 
| 
      
 582 
     | 
    
         
            +
                  } else if (
         
     | 
| 
      
 583 
     | 
    
         
            +
                    existsNode &&
         
     | 
| 
      
 584 
     | 
    
         
            +
                    parentNode instanceof QueryBuilderFilterTreeGroupNodeData
         
     | 
| 
      
 585 
     | 
    
         
            +
                  ) {
         
     | 
| 
      
 586 
     | 
    
         
            +
                    const propertyExpression1 = buildPropertyExpressionFromExistsNode(
         
     | 
| 
      
 587 
     | 
    
         
            +
                      filterState,
         
     | 
| 
      
 588 
     | 
    
         
            +
                      existsNode,
         
     | 
| 
      
 589 
     | 
    
         
            +
                      targetDropNode,
         
     | 
| 
      
 590 
     | 
    
         
            +
                    );
         
     | 
| 
      
 591 
     | 
    
         
            +
                    filterState.removeNodeAndPruneBranch(targetDropNode);
         
     | 
| 
      
 592 
     | 
    
         
            +
                    filterState.newGroupConditionFromNode(
         
     | 
| 
      
 593 
     | 
    
         
            +
                      existsNode,
         
     | 
| 
      
 594 
     | 
    
         
            +
                      treeNode,
         
     | 
| 
      
 595 
     | 
    
         
            +
                      parentNode.groupOperation,
         
     | 
| 
      
 596 
     | 
    
         
            +
                    );
         
     | 
| 
      
 597 
     | 
    
         
            +
                    const newParentNode = filterState.getParentNode(treeNode);
         
     | 
| 
      
 598 
     | 
    
         
            +
                    buildFilterTreeWithExists(
         
     | 
| 
      
 599 
     | 
    
         
            +
                      propertyExpression1,
         
     | 
| 
      
 600 
     | 
    
         
            +
                      filterState,
         
     | 
| 
      
 601 
     | 
    
         
            +
                      newParentNode,
         
     | 
| 
      
 602 
     | 
    
         
            +
                    );
         
     | 
| 
      
 603 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 604 
     | 
    
         
            +
                    filterState.newGroupWithConditionFromNode(treeNode, targetDropNode);
         
     | 
| 
      
 605 
     | 
    
         
            +
                  }
         
     | 
| 
      
 606 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 607 
     | 
    
         
            +
                  filterState.addNodeFromNode(treeNode, undefined);
         
     | 
| 
      
 608 
     | 
    
         
            +
                }
         
     | 
| 
       392 
609 
     | 
    
         
             
              }
         
     | 
| 
       393 
610 
     | 
    
         
             
            };
         
     | 
| 
       394 
611 
     | 
    
         | 
| 
         @@ -604,7 +821,12 @@ const QueryBuilderFilterConditionEditor = observer( 
     | 
|
| 
       604 
821 
     | 
    
         
             
                };
         
     | 
| 
       605 
822 
     | 
    
         | 
| 
       606 
823 
     | 
    
         
             
                return (
         
     | 
| 
       607 
     | 
    
         
            -
                  <div 
     | 
| 
      
 824 
     | 
    
         
            +
                  <div
         
     | 
| 
      
 825 
     | 
    
         
            +
                    className="query-builder-filter-tree__node__label__content dnd__entry__container"
         
     | 
| 
      
 826 
     | 
    
         
            +
                    data-testid={
         
     | 
| 
      
 827 
     | 
    
         
            +
                      QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FILTER_TREE_CONDITION_NODE_CONTENT
         
     | 
| 
      
 828 
     | 
    
         
            +
                    }
         
     | 
| 
      
 829 
     | 
    
         
            +
                  >
         
     | 
| 
       608 
830 
     | 
    
         
             
                    <PanelEntryDropZonePlaceholder
         
     | 
| 
       609 
831 
     | 
    
         
             
                      isDragOver={isDragOver}
         
     | 
| 
       610 
832 
     | 
    
         
             
                      label="Add New Logical Group"
         
     | 
| 
         @@ -845,21 +1067,17 @@ const QueryBuilderFilterTreeNodeContainer = observer( 
     | 
|
| 
       845 
1067 
     | 
    
         
             
                          node,
         
     | 
| 
       846 
1068 
     | 
    
         
             
                        );
         
     | 
| 
       847 
1069 
     | 
    
         
             
                      } else if (node instanceof QueryBuilderFilterTreeConditionNodeData) {
         
     | 
| 
       848 
     | 
    
         
            -
                         
     | 
| 
       849 
     | 
    
         
            -
                           
     | 
| 
       850 
     | 
    
         
            -
             
     | 
| 
       851 
     | 
    
         
            -
                            filterConditionState,
         
     | 
| 
       852 
     | 
    
         
            -
                          ),
         
     | 
| 
      
 1070 
     | 
    
         
            +
                        buildFilterTree(
         
     | 
| 
      
 1071 
     | 
    
         
            +
                          filterConditionState.propertyExpressionState.propertyExpression,
         
     | 
| 
      
 1072 
     | 
    
         
            +
                          filterState,
         
     | 
| 
       853 
1073 
     | 
    
         
             
                          node,
         
     | 
| 
       854 
1074 
     | 
    
         
             
                        );
         
     | 
| 
       855 
1075 
     | 
    
         
             
                      } else if (
         
     | 
| 
       856 
1076 
     | 
    
         
             
                        node instanceof QueryBuilderFilterTreeBlankConditionNodeData
         
     | 
| 
       857 
1077 
     | 
    
         
             
                      ) {
         
     | 
| 
       858 
     | 
    
         
            -
                         
     | 
| 
       859 
     | 
    
         
            -
                           
     | 
| 
       860 
     | 
    
         
            -
             
     | 
| 
       861 
     | 
    
         
            -
                            filterConditionState,
         
     | 
| 
       862 
     | 
    
         
            -
                          ),
         
     | 
| 
      
 1078 
     | 
    
         
            +
                        buildFilterTree(
         
     | 
| 
      
 1079 
     | 
    
         
            +
                          filterConditionState.propertyExpressionState.propertyExpression,
         
     | 
| 
      
 1080 
     | 
    
         
            +
                          filterState,
         
     | 
| 
       863 
1081 
     | 
    
         
             
                          node,
         
     | 
| 
       864 
1082 
     | 
    
         
             
                        );
         
     | 
| 
       865 
1083 
     | 
    
         
             
                      }
         
     | 
| 
         @@ -17,14 +17,15 @@ 
     | 
|
| 
       17 
17 
     | 
    
         
             
            import { action, flow, makeObservable, observable } from 'mobx';
         
     | 
| 
       18 
18 
     | 
    
         
             
            import {
         
     | 
| 
       19 
19 
     | 
    
         
             
              type GeneratorFn,
         
     | 
| 
      
 20 
     | 
    
         
            +
              type ContentType,
         
     | 
| 
       20 
21 
     | 
    
         
             
              assertErrorThrown,
         
     | 
| 
       21 
22 
     | 
    
         
             
              LogEvent,
         
     | 
| 
       22 
23 
     | 
    
         
             
              guaranteeNonNullable,
         
     | 
| 
       23 
     | 
    
         
            -
              type ContentType,
         
     | 
| 
       24 
24 
     | 
    
         
             
              downloadFileUsingDataURI,
         
     | 
| 
       25 
25 
     | 
    
         
             
              ActionState,
         
     | 
| 
       26 
26 
     | 
    
         
             
              StopWatch,
         
     | 
| 
       27 
27 
     | 
    
         
             
              getContentTypeFileExtension,
         
     | 
| 
      
 28 
     | 
    
         
            +
              isBoolean,
         
     | 
| 
       28 
29 
     | 
    
         
             
            } from '@finos/legend-shared';
         
     | 
| 
       29 
30 
     | 
    
         
             
            import type { QueryBuilderState } from './QueryBuilderState.js';
         
     | 
| 
       30 
31 
     | 
    
         
             
            import {
         
     | 
| 
         @@ -37,6 +38,7 @@ import { 
     | 
|
| 
       37 
38 
     | 
    
         
             
              buildRawLambdaFromLambdaFunction,
         
     | 
| 
       38 
39 
     | 
    
         
             
              reportGraphAnalytics,
         
     | 
| 
       39 
40 
     | 
    
         
             
              extractExecutionResultValues,
         
     | 
| 
      
 41 
     | 
    
         
            +
              TDSExecutionResult,
         
     | 
| 
       40 
42 
     | 
    
         
             
            } from '@finos/legend-graph';
         
     | 
| 
       41 
43 
     | 
    
         
             
            import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
         
     | 
| 
       42 
44 
     | 
    
         
             
            import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
         
     | 
| 
         @@ -81,6 +83,7 @@ export class QueryBuilderResultState { 
     | 
|
| 
       81 
83 
     | 
    
         
             
              latestRunHashCode?: string | undefined;
         
     | 
| 
       82 
84 
     | 
    
         
             
              queryRunPromise: Promise<ExecutionResult> | undefined = undefined;
         
     | 
| 
       83 
85 
     | 
    
         
             
              isQueryUsageViewerOpened = false;
         
     | 
| 
      
 86 
     | 
    
         
            +
              rowData: Record<string, string | number | boolean | null>[] = [];
         
     | 
| 
       84 
87 
     | 
    
         | 
| 
       85 
88 
     | 
    
         
             
              selectedCells: QueryBuilderTDSResultCellData[];
         
     | 
| 
       86 
89 
     | 
    
         
             
              mousedOverCell: QueryBuilderTDSResultCellData | null = null;
         
     | 
| 
         @@ -110,6 +113,8 @@ export class QueryBuilderResultState { 
     | 
|
| 
       110 
113 
     | 
    
         
             
                  setQueryRunPromise: action,
         
     | 
| 
       111 
114 
     | 
    
         
             
                  setIsQueryUsageViewerOpened: action,
         
     | 
| 
       112 
115 
     | 
    
         
             
                  exportData: flow,
         
     | 
| 
      
 116 
     | 
    
         
            +
                  getRowData: action,
         
     | 
| 
      
 117 
     | 
    
         
            +
                  setRowData: action,
         
     | 
| 
       113 
118 
     | 
    
         
             
                  runQuery: flow,
         
     | 
| 
       114 
119 
     | 
    
         
             
                  cancelQuery: flow,
         
     | 
| 
       115 
120 
     | 
    
         
             
                  generatePlan: flow,
         
     | 
| 
         @@ -124,6 +129,36 @@ export class QueryBuilderResultState { 
     | 
|
| 
       124 
129 
     | 
    
         
             
                );
         
     | 
| 
       125 
130 
     | 
    
         
             
              }
         
     | 
| 
       126 
131 
     | 
    
         | 
| 
      
 132 
     | 
    
         
            +
              getRowData(): Record<string, string | number | boolean | null>[] {
         
     | 
| 
      
 133 
     | 
    
         
            +
                if (
         
     | 
| 
      
 134 
     | 
    
         
            +
                  this.executionResult &&
         
     | 
| 
      
 135 
     | 
    
         
            +
                  this.executionResult instanceof TDSExecutionResult
         
     | 
| 
      
 136 
     | 
    
         
            +
                ) {
         
     | 
| 
      
 137 
     | 
    
         
            +
                  const data = this.executionResult.result.rows.map((_row, rowIdx) => {
         
     | 
| 
      
 138 
     | 
    
         
            +
                    const row: Record<string, string | number | boolean | null> = {};
         
     | 
| 
      
 139 
     | 
    
         
            +
                    const cols = (this.executionResult as TDSExecutionResult).result
         
     | 
| 
      
 140 
     | 
    
         
            +
                      .columns;
         
     | 
| 
      
 141 
     | 
    
         
            +
                    _row.values.forEach((value, colIdx) => {
         
     | 
| 
      
 142 
     | 
    
         
            +
                      // `ag-grid` shows `false` value as empty string so we have
         
     | 
| 
      
 143 
     | 
    
         
            +
                      // call `.toString()` to avoid this behavior.
         
     | 
| 
      
 144 
     | 
    
         
            +
                      // See https://github.com/finos/legend-studio/issues/1008
         
     | 
| 
      
 145 
     | 
    
         
            +
                      row[cols[colIdx] as string] = isBoolean(value)
         
     | 
| 
      
 146 
     | 
    
         
            +
                        ? String(value)
         
     | 
| 
      
 147 
     | 
    
         
            +
                        : value;
         
     | 
| 
      
 148 
     | 
    
         
            +
                    });
         
     | 
| 
      
 149 
     | 
    
         
            +
                    row.rowNumber = rowIdx;
         
     | 
| 
      
 150 
     | 
    
         
            +
                    return row;
         
     | 
| 
      
 151 
     | 
    
         
            +
                  });
         
     | 
| 
      
 152 
     | 
    
         
            +
                  this.rowData = data;
         
     | 
| 
      
 153 
     | 
    
         
            +
                  return data;
         
     | 
| 
      
 154 
     | 
    
         
            +
                }
         
     | 
| 
      
 155 
     | 
    
         
            +
                return [];
         
     | 
| 
      
 156 
     | 
    
         
            +
              }
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
              setRowData(val: Record<string, string | number | boolean | null>[]): void {
         
     | 
| 
      
 159 
     | 
    
         
            +
                this.rowData = val;
         
     | 
| 
      
 160 
     | 
    
         
            +
              }
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
       127 
162 
     | 
    
         
             
              setIsSelectingCells(val: boolean): void {
         
     | 
| 
       128 
163 
     | 
    
         
             
                this.isSelectingCells = val;
         
     | 
| 
       129 
164 
     | 
    
         
             
              }
         
     |