bways-grid 0.0.19 → 0.0.20

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.
@@ -330,11 +330,35 @@ class CellComponent {
330
330
  }
331
331
  }
332
332
  if (!isNaN(num) && isFinite(num)) {
333
- // Use en-US for standard thousands separators
334
- return num.toLocaleString('en-US', {
335
- minimumFractionDigits: 0,
336
- maximumFractionDigits: 2
337
- });
333
+ const format = this.column.numberFormat || 'comma';
334
+ if (format === 'no-comma') {
335
+ return num.toLocaleString('en-US', {
336
+ useGrouping: false,
337
+ minimumFractionDigits: 0,
338
+ maximumFractionDigits: 2
339
+ });
340
+ }
341
+ else if (format === 'currency') {
342
+ return num.toLocaleString('en-US', {
343
+ style: 'currency',
344
+ currency: 'USD',
345
+ minimumFractionDigits: 0,
346
+ maximumFractionDigits: 2
347
+ });
348
+ }
349
+ else if (format === 'integer') {
350
+ return num.toLocaleString('en-US', {
351
+ minimumFractionDigits: 0,
352
+ maximumFractionDigits: 0
353
+ });
354
+ }
355
+ else {
356
+ // default / 'comma'
357
+ return num.toLocaleString('en-US', {
358
+ minimumFractionDigits: 0,
359
+ maximumFractionDigits: 2
360
+ });
361
+ }
338
362
  }
339
363
  return v;
340
364
  }
@@ -675,7 +699,9 @@ class HeaderMenuComponent {
675
699
  autosize = new EventEmitter();
676
700
  group = new EventEmitter();
677
701
  chooseColumns = new EventEmitter();
702
+ formatChange = new EventEmitter();
678
703
  showPinSubmenu = false;
704
+ showFormatSubmenu = false;
679
705
  get isGrouped() {
680
706
  return !!this.column && this.groupModel.includes(this.column.field);
681
707
  }
@@ -713,8 +739,14 @@ class HeaderMenuComponent {
713
739
  this.chooseColumns.emit();
714
740
  this.onClose();
715
741
  }
742
+ onFormatChange(format) {
743
+ if (this.column) {
744
+ this.formatChange.emit({ field: this.column.field, format });
745
+ }
746
+ this.onClose();
747
+ }
716
748
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: HeaderMenuComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
717
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: HeaderMenuComponent, isStandalone: true, selector: "ug-header-menu", inputs: { column: "column", isOpen: "isOpen", position: "position", groupModel: "groupModel" }, outputs: { closeMenu: "closeMenu", sort: "sort", pin: "pin", autosize: "autosize", group: "group", chooseColumns: "chooseColumns" }, ngImport: i0, template: `
749
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: HeaderMenuComponent, isStandalone: true, selector: "ug-header-menu", inputs: { column: "column", isOpen: "isOpen", position: "position", groupModel: "groupModel" }, outputs: { closeMenu: "closeMenu", sort: "sort", pin: "pin", autosize: "autosize", group: "group", chooseColumns: "chooseColumns", formatChange: "formatChange" }, ngImport: i0, template: `
718
750
  <div class="ug-header-menu-backdrop" *ngIf="isOpen" (click)="onClose()"></div>
719
751
  <div class="ug-header-menu-panel" *ngIf="isOpen" [style.top.px]="position.y" [style.left.px]="position.x">
720
752
 
@@ -764,6 +796,34 @@ class HeaderMenuComponent {
764
796
 
765
797
  <div class="ug-menu-separator"></div>
766
798
 
799
+ <!-- Number Formatting (Submenu trigger) -->
800
+ <div class="ug-menu-item ug-has-submenu" (mouseenter)="showFormatSubmenu = true" (mouseleave)="showFormatSubmenu = false">
801
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
802
+ <span>Number Formatting</span>
803
+ <svg class="ug-menu-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
804
+
805
+ <div class="ug-submenu" *ngIf="showFormatSubmenu">
806
+ <div class="ug-menu-item" (click)="onFormatChange('comma')">
807
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" [style.visibility]="(!column?.numberFormat || column?.numberFormat === 'comma') ? 'visible' : 'hidden'"><path d="M20 6L9 17l-5-5"/></svg>
808
+ <span>Comma (1,234.56)</span>
809
+ </div>
810
+ <div class="ug-menu-item" (click)="onFormatChange('no-comma')">
811
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" [style.visibility]="column?.numberFormat === 'no-comma' ? 'visible' : 'hidden'"><path d="M20 6L9 17l-5-5"/></svg>
812
+ <span>No Comma (1234.56)</span>
813
+ </div>
814
+ <div class="ug-menu-item" (click)="onFormatChange('currency')">
815
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" [style.visibility]="column?.numberFormat === 'currency' ? 'visible' : 'hidden'"><path d="M20 6L9 17l-5-5"/></svg>
816
+ <span>Currency ($1,234.56)</span>
817
+ </div>
818
+ <div class="ug-menu-item" (click)="onFormatChange('integer')">
819
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" [style.visibility]="column?.numberFormat === 'integer' ? 'visible' : 'hidden'"><path d="M20 6L9 17l-5-5"/></svg>
820
+ <span>Integer (1,235)</span>
821
+ </div>
822
+ </div>
823
+ </div>
824
+
825
+ <div class="ug-menu-separator"></div>
826
+
767
827
  <!-- Grouping -->
768
828
  <div class="ug-menu-item" (click)="onGroup()">
769
829
  <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 3H3v18h18V3zM3 9h18M9 21V9"/></svg>
@@ -833,6 +893,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
833
893
 
834
894
  <div class="ug-menu-separator"></div>
835
895
 
896
+ <!-- Number Formatting (Submenu trigger) -->
897
+ <div class="ug-menu-item ug-has-submenu" (mouseenter)="showFormatSubmenu = true" (mouseleave)="showFormatSubmenu = false">
898
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
899
+ <span>Number Formatting</span>
900
+ <svg class="ug-menu-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
901
+
902
+ <div class="ug-submenu" *ngIf="showFormatSubmenu">
903
+ <div class="ug-menu-item" (click)="onFormatChange('comma')">
904
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" [style.visibility]="(!column?.numberFormat || column?.numberFormat === 'comma') ? 'visible' : 'hidden'"><path d="M20 6L9 17l-5-5"/></svg>
905
+ <span>Comma (1,234.56)</span>
906
+ </div>
907
+ <div class="ug-menu-item" (click)="onFormatChange('no-comma')">
908
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" [style.visibility]="column?.numberFormat === 'no-comma' ? 'visible' : 'hidden'"><path d="M20 6L9 17l-5-5"/></svg>
909
+ <span>No Comma (1234.56)</span>
910
+ </div>
911
+ <div class="ug-menu-item" (click)="onFormatChange('currency')">
912
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" [style.visibility]="column?.numberFormat === 'currency' ? 'visible' : 'hidden'"><path d="M20 6L9 17l-5-5"/></svg>
913
+ <span>Currency ($1,234.56)</span>
914
+ </div>
915
+ <div class="ug-menu-item" (click)="onFormatChange('integer')">
916
+ <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" [style.visibility]="column?.numberFormat === 'integer' ? 'visible' : 'hidden'"><path d="M20 6L9 17l-5-5"/></svg>
917
+ <span>Integer (1,235)</span>
918
+ </div>
919
+ </div>
920
+ </div>
921
+
922
+ <div class="ug-menu-separator"></div>
923
+
836
924
  <!-- Grouping -->
837
925
  <div class="ug-menu-item" (click)="onGroup()">
838
926
  <svg class="ug-menu-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 3H3v18h18V3zM3 9h18M9 21V9"/></svg>
@@ -869,6 +957,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
869
957
  type: Output
870
958
  }], chooseColumns: [{
871
959
  type: Output
960
+ }], formatChange: [{
961
+ type: Output
872
962
  }] } });
873
963
 
874
964
  class ChooseColumnsComponent {
@@ -1183,6 +1273,25 @@ class ColumnToolPanelComponent {
1183
1273
  pivotColumnsInternal = [];
1184
1274
  searchQuery = '';
1185
1275
  openDropdownField = null;
1276
+ isColumnsExpanded = true;
1277
+ isRowGroupsExpanded = true;
1278
+ isPivotColumnsExpanded = true;
1279
+ isValuesExpanded = true;
1280
+ toggleColumnsExpanded() {
1281
+ this.isColumnsExpanded = !this.isColumnsExpanded;
1282
+ }
1283
+ toggleRowGroupsExpanded() {
1284
+ this.isRowGroupsExpanded = !this.isRowGroupsExpanded;
1285
+ }
1286
+ togglePivotColumnsExpanded() {
1287
+ this.isPivotColumnsExpanded = !this.isPivotColumnsExpanded;
1288
+ }
1289
+ toggleValuesExpanded() {
1290
+ this.isValuesExpanded = !this.isValuesExpanded;
1291
+ }
1292
+ getSelectedColumnsCount() {
1293
+ return this.columns.filter(c => !c.hide).length;
1294
+ }
1186
1295
  ngOnChanges(changes) {
1187
1296
  if (changes['columns']) {
1188
1297
  this.applySearch();
@@ -1367,7 +1476,7 @@ class ColumnToolPanelComponent {
1367
1476
  }
1368
1477
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ColumnToolPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1369
1478
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: ColumnToolPanelComponent, isStandalone: true, selector: "ug-column-tool-panel", inputs: { columns: "columns", groupModel: "groupModel", valuesModel: "valuesModel", pivotMode: "pivotMode", pivotColumns: "pivotColumns" }, outputs: { columnsUpdated: "columnsUpdated", groupModelChanged: "groupModelChanged", valuesModelChanged: "valuesModelChanged", pivotModeChanged: "pivotModeChanged", pivotModelChanged: "pivotModelChanged", exportExcelClicked: "exportExcelClicked" }, usesOnChanges: true, ngImport: i0, template: `
1370
- <div class="ug-ctp-wrapper" cdkDropListGroup>
1479
+ <div class="ug-ctp-wrapper" cdkDropListGroup cdkScrollable>
1371
1480
  <!-- Pivot Mode Toggle -->
1372
1481
  <div class="ug-ctp-pivot-mode">
1373
1482
  <label class="ug-switch">
@@ -1378,112 +1487,129 @@ class ColumnToolPanelComponent {
1378
1487
  </div>
1379
1488
 
1380
1489
  <!-- Column List Section -->
1381
- <div class="ug-ctp-columns-section">
1382
- <div class="ug-ctp-search">
1383
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
1384
- <input type="text" placeholder="Search..." [(ngModel)]="searchQuery" (ngModelChange)="applySearch()" />
1490
+ <div class="ug-ctp-group">
1491
+ <div class="ug-ctp-group-header clickable" (click)="toggleColumnsExpanded()">
1492
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="9" y1="3" x2="9" y2="21"></line><line x1="15" y1="3" x2="15" y2="21"></line></svg>
1493
+ <span class="ug-ctp-section-title">Columns ({{ getSelectedColumnsCount() }}/{{ columns.length }})</span>
1494
+ <svg class="ug-ctp-chevron" [class.collapsed]="!isColumnsExpanded" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1385
1495
  </div>
1496
+
1497
+ <div class="ug-ctp-section-content" [style.display]="isColumnsExpanded ? 'block' : 'none'">
1498
+ <div class="ug-ctp-search">
1499
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
1500
+ <input type="text" placeholder="Search..." [(ngModel)]="searchQuery" (ngModelChange)="applySearch()" />
1501
+ </div>
1386
1502
 
1387
- <div class="ug-ctp-select-all" style="padding: 8px 12px; border-bottom: 1px solid var(--ug-border-color, #e2e8f0); display: flex; align-items: center; gap: 8px; cursor: pointer;" (click)="toggleAllColumns()">
1388
- <input type="checkbox" [checked]="isAllColumnsSelected()" [indeterminate]="isSomeColumnsSelected() && !isAllColumnsSelected()" style="pointer-events: none;" />
1389
- <span style="font-weight: 500; font-size: 13px;">Select All</span>
1390
- </div>
1503
+ <div class="ug-ctp-select-all" style="padding: 8px 12px; border-bottom: 1px solid var(--ug-border-color, #e2e8f0); display: flex; align-items: center; gap: 8px; cursor: pointer;" (click)="toggleAllColumns()">
1504
+ <input type="checkbox" [checked]="isAllColumnsSelected()" [indeterminate]="isSomeColumnsSelected() && !isAllColumnsSelected()" style="pointer-events: none;" />
1505
+ <span style="font-weight: 500; font-size: 13px;">Select All</span>
1506
+ </div>
1391
1507
 
1392
- <div
1393
- class="ug-ctp-list"
1394
- id="colList"
1395
- cdkDropList
1396
- [cdkDropListData]="displayColumns"
1397
- [cdkDropListConnectedTo]="['groupList', 'valueList', 'pivotList']"
1398
- (cdkDropListDropped)="onDrop($event)">
1399
1508
  <div
1400
- class="ug-ctp-item"
1401
- *ngFor="let col of displayColumns"
1402
- cdkDrag
1403
- [cdkDragData]="col">
1404
- <input type="checkbox" [checked]="!col.hide" (change)="toggleVisibility(col)" />
1405
- <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1406
- <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1509
+ class="ug-ctp-list"
1510
+ id="colList"
1511
+ cdkDropList
1512
+ [cdkDropListData]="displayColumns"
1513
+ [cdkDropListConnectedTo]="['groupList', 'valueList', 'pivotList']"
1514
+ (cdkDropListDropped)="onDrop($event)">
1515
+ <div
1516
+ class="ug-ctp-item"
1517
+ *ngFor="let col of displayColumns"
1518
+ cdkDrag
1519
+ [cdkDragData]="col">
1520
+ <input type="checkbox" [checked]="!col.hide" (change)="toggleVisibility(col)" />
1521
+ <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1522
+ <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1523
+ </div>
1407
1524
  </div>
1408
1525
  </div>
1409
1526
  </div>
1410
1527
 
1411
1528
  <!-- Row Groups -->
1412
1529
  <div class="ug-ctp-group">
1413
- <div class="ug-ctp-group-header">
1530
+ <div class="ug-ctp-group-header clickable" (click)="toggleRowGroupsExpanded()">
1414
1531
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line></svg>
1415
- <span>Row Groups</span>
1532
+ <span class="ug-ctp-section-title">Row Groups ({{ groupColumns.length }})</span>
1533
+ <svg class="ug-ctp-chevron" [class.collapsed]="!isRowGroupsExpanded" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1416
1534
  </div>
1417
- <div
1418
- class="ug-ctp-dropzone"
1419
- id="groupList"
1420
- cdkDropList
1421
- [cdkDropListData]="groupColumns"
1422
- [cdkDropListConnectedTo]="['colList', 'pivotList', 'valueList']"
1423
- (cdkDropListDropped)="onGroupDrop($event)"
1424
- [class.empty]="groupColumns.length === 0">
1425
- <div *ngIf="groupColumns.length === 0">Drag here to set row groups</div>
1426
- <div class="ug-ctp-item" *ngFor="let col of groupColumns" cdkDrag [cdkDragData]="col">
1427
- <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1428
- <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1429
- <span class="ug-ctp-remove" (click)="removeGroup(col)" style="margin-left:auto;cursor:pointer;">&times;</span>
1535
+ <div class="ug-ctp-section-content" [style.display]="isRowGroupsExpanded ? 'block' : 'none'">
1536
+ <div
1537
+ class="ug-ctp-dropzone"
1538
+ id="groupList"
1539
+ cdkDropList
1540
+ [cdkDropListData]="groupColumns"
1541
+ [cdkDropListConnectedTo]="['colList', 'pivotList', 'valueList']"
1542
+ (cdkDropListDropped)="onGroupDrop($event)"
1543
+ [class.empty]="groupColumns.length === 0">
1544
+ <div *ngIf="groupColumns.length === 0">Drag here to set row groups</div>
1545
+ <div class="ug-ctp-item" *ngFor="let col of groupColumns" cdkDrag [cdkDragData]="col">
1546
+ <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1547
+ <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1548
+ <span class="ug-ctp-remove" (click)="removeGroup(col)" style="margin-left:auto;cursor:pointer;">&times;</span>
1549
+ </div>
1430
1550
  </div>
1431
1551
  </div>
1432
1552
  </div>
1433
1553
 
1434
1554
  <!-- Pivot Columns -->
1435
1555
  <div class="ug-ctp-group" *ngIf="pivotMode">
1436
- <div class="ug-ctp-group-header">
1556
+ <div class="ug-ctp-group-header clickable" (click)="togglePivotColumnsExpanded()">
1437
1557
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12V7H5a2 2 0 0 1 0-4h14v4"/><path d="M3 5v14a2 2 0 0 0 2 2h16v-5"/><path d="M18 12H3"/></svg>
1438
- <span>Pivot Columns</span>
1558
+ <span class="ug-ctp-section-title">Pivot Columns ({{ pivotColumnsInternal.length }})</span>
1559
+ <svg class="ug-ctp-chevron" [class.collapsed]="!isPivotColumnsExpanded" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1439
1560
  </div>
1440
- <div
1441
- class="ug-ctp-dropzone"
1442
- id="pivotList"
1443
- cdkDropList
1444
- [cdkDropListData]="pivotColumnsInternal"
1445
- [cdkDropListConnectedTo]="['colList', 'groupList', 'valueList']"
1446
- (cdkDropListDropped)="onPivotDrop($event)"
1447
- [class.empty]="pivotColumnsInternal.length === 0">
1448
- <div *ngIf="pivotColumnsInternal.length === 0">Drag here to pivot</div>
1449
- <div class="ug-ctp-item" *ngFor="let col of pivotColumnsInternal" cdkDrag [cdkDragData]="col">
1450
- <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1451
- <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1452
- <span class="ug-ctp-remove" (click)="removePivot(col)" style="margin-left:auto;cursor:pointer;">&times;</span>
1561
+ <div class="ug-ctp-section-content" [style.display]="isPivotColumnsExpanded ? 'block' : 'none'">
1562
+ <div
1563
+ class="ug-ctp-dropzone"
1564
+ id="pivotList"
1565
+ cdkDropList
1566
+ [cdkDropListData]="pivotColumnsInternal"
1567
+ [cdkDropListConnectedTo]="['colList', 'groupList', 'valueList']"
1568
+ (cdkDropListDropped)="onPivotDrop($event)"
1569
+ [class.empty]="pivotColumnsInternal.length === 0">
1570
+ <div *ngIf="pivotColumnsInternal.length === 0">Drag here to pivot</div>
1571
+ <div class="ug-ctp-item" *ngFor="let col of pivotColumnsInternal" cdkDrag [cdkDragData]="col">
1572
+ <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1573
+ <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1574
+ <span class="ug-ctp-remove" (click)="removePivot(col)" style="margin-left:auto;cursor:pointer;">&times;</span>
1575
+ </div>
1453
1576
  </div>
1454
1577
  </div>
1455
1578
  </div>
1456
1579
 
1457
1580
  <!-- Values -->
1458
1581
  <div class="ug-ctp-group">
1459
- <div class="ug-ctp-group-header">
1582
+ <div class="ug-ctp-group-header clickable" (click)="toggleValuesExpanded()">
1460
1583
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 7 4 4 20 4 20 7"></polyline><line x1="9" y1="20" x2="15" y2="20"></line><line x1="12" y1="4" x2="12" y2="20"></line></svg>
1461
- <span>Values</span>
1584
+ <span class="ug-ctp-section-title">Values ({{ valueColumns.length }})</span>
1585
+ <svg class="ug-ctp-chevron" [class.collapsed]="!isValuesExpanded" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1462
1586
  </div>
1463
- <div
1464
- class="ug-ctp-dropzone"
1465
- id="valueList"
1466
- cdkDropList
1467
- [cdkDropListData]="valueColumns"
1468
- [cdkDropListConnectedTo]="['colList', 'groupList', 'pivotList']"
1469
- (cdkDropListDropped)="onValueDrop($event)"
1470
- [class.empty]="valueColumns.length === 0">
1471
- <div *ngIf="valueColumns.length === 0">Drag here to aggregate</div>
1472
- <div class="ug-ctp-item" *ngFor="let vCol of valueColumns" cdkDrag [cdkDragData]="vCol">
1473
- <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1474
- <div class="ug-ctp-agg-selector" (click)="toggleAggDropdown(vCol.field)">
1475
- <span class="ug-ctp-item-name"><b>{{ vCol.aggFunc }}</b>({{ getColumnHeader(vCol.field) }})</span>
1476
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1477
- </div>
1478
- <span class="ug-ctp-remove" (click)="removeValue(vCol.field)" style="margin-left:auto;cursor:pointer;">&times;</span>
1479
-
1480
- <!-- Dropdown Menu -->
1481
- <div class="ug-ctp-agg-menu" *ngIf="openDropdownField === vCol.field">
1482
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'sum'" (click)="setAggFunc(vCol, 'sum')">sum</div>
1483
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'min'" (click)="setAggFunc(vCol, 'min')">min</div>
1484
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'max'" (click)="setAggFunc(vCol, 'max')">max</div>
1485
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'count'" (click)="setAggFunc(vCol, 'count')">count</div>
1486
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'avg'" (click)="setAggFunc(vCol, 'avg')">avg</div>
1587
+ <div class="ug-ctp-section-content" [style.display]="isValuesExpanded ? 'block' : 'none'">
1588
+ <div
1589
+ class="ug-ctp-dropzone"
1590
+ id="valueList"
1591
+ cdkDropList
1592
+ [cdkDropListData]="valueColumns"
1593
+ [cdkDropListConnectedTo]="['colList', 'groupList', 'pivotList']"
1594
+ (cdkDropListDropped)="onValueDrop($event)"
1595
+ [class.empty]="valueColumns.length === 0">
1596
+ <div *ngIf="valueColumns.length === 0">Drag here to aggregate</div>
1597
+ <div class="ug-ctp-item" *ngFor="let vCol of valueColumns" cdkDrag [cdkDragData]="vCol">
1598
+ <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1599
+ <div class="ug-ctp-agg-selector" (click)="toggleAggDropdown(vCol.field)">
1600
+ <span class="ug-ctp-item-name"><b>{{ vCol.aggFunc }}</b>({{ getColumnHeader(vCol.field) }})</span>
1601
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1602
+ </div>
1603
+ <span class="ug-ctp-remove" (click)="removeValue(vCol.field)" style="margin-left:auto;cursor:pointer;">&times;</span>
1604
+
1605
+ <!-- Dropdown Menu -->
1606
+ <div class="ug-ctp-agg-menu" *ngIf="openDropdownField === vCol.field">
1607
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'sum'" (click)="setAggFunc(vCol, 'sum')">sum</div>
1608
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'min'" (click)="setAggFunc(vCol, 'min')">min</div>
1609
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'max'" (click)="setAggFunc(vCol, 'max')">max</div>
1610
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'count'" (click)="setAggFunc(vCol, 'count')">count</div>
1611
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'avg'" (click)="setAggFunc(vCol, 'avg')">avg</div>
1612
+ </div>
1487
1613
  </div>
1488
1614
  </div>
1489
1615
  </div>
@@ -1499,12 +1625,12 @@ class ColumnToolPanelComponent {
1499
1625
  </button>
1500
1626
  </div>
1501
1627
  </div>
1502
- `, isInline: true, styles: [".ug-ctp-wrapper{display:flex;flex-direction:column;height:100%;font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px);color:var(--ug-color, #181d1f)}.ug-ctp-pivot-mode{display:flex;align-items:center;padding:12px 16px;border-bottom:1px solid var(--ug-border-color);gap:12px}.ug-switch{position:relative;display:inline-block;width:34px;height:20px}.ug-switch input{opacity:0;width:0;height:0}.ug-slider{position:absolute;cursor:pointer;inset:0;background-color:var(--ug-border-color);transition:.4s}.ug-slider:before{position:absolute;content:\"\";height:14px;width:14px;left:3px;bottom:3px;background-color:#fff;transition:.4s}input:checked+.ug-slider{background-color:var(--ug-primary-color)}input:checked+.ug-slider:before{transform:translate(14px)}.ug-slider.round{border-radius:34px}.ug-slider.round:before{border-radius:50%}.ug-ctp-columns-section{flex:1;display:flex;flex-direction:column;border-bottom:1px solid var(--ug-border-color);min-height:200px}.ug-ctp-search{padding:12px;position:relative;display:flex;align-items:center}.ug-ctp-search svg{position:absolute;left:20px;color:var(--ug-icon-color)}.ug-ctp-search input{width:100%;padding:6px 8px 6px 28px;border:1px solid var(--ug-border-color);border-radius:4px;font-family:var(--ug-font-family, inherit);font-size:var(--ug-font-size, inherit);background-color:var(--ug-bg-color);color:var(--ug-color)}.ug-ctp-search input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ctp-list{flex:1;overflow-y:auto;padding:0 12px 12px}.ug-ctp-item{display:flex;align-items:center;padding:6px 8px;background:var(--ug-bg-color);border:1px solid transparent;border-radius:4px;margin-bottom:2px}.ug-ctp-item:hover{background:var(--ug-row-hover-bg)}.ug-ctp-item input[type=checkbox]{accent-color:var(--ug-primary-color);cursor:pointer}.ug-drag-handle{color:var(--ug-icon-color);cursor:grab;margin:0 8px}.ug-ctp-item-name{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.cdk-drag-preview{box-sizing:border-box;background:var(--ug-bg-color);border:1px solid var(--ug-border-color);border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;display:flex;align-items:center;padding:6px 8px;font-family:var(--ug-font-family);font-size:var(--ug-font-size);color:var(--ug-color)}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,0,1)}.ug-ctp-group{border-bottom:1px solid var(--ug-border-color)}.ug-ctp-group-header{display:flex;align-items:center;padding:12px 16px;gap:8px;font-family:var(--ug-font-family, sans-serif);font-weight:var(--ug-header-font-weight, 500);font-size:var(--ug-font-size, 13px);color:var(--ug-header-color);background-color:var(--ug-header-bg)}.ug-ctp-dropzone{min-height:80px;padding:12px 16px;background-color:var(--ug-bg-color);font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px)}.ug-ctp-dropzone.empty{display:flex;align-items:center;justify-content:center;color:var(--ug-icon-color);font-style:italic;border:1px dashed var(--ug-border-color);margin:12px;border-radius:4px}.ug-ctp-item{position:relative}.ug-ctp-agg-selector{display:flex;align-items:center;gap:4px;cursor:pointer;padding:2px 4px;border-radius:4px;flex:1;overflow:hidden}.ug-ctp-agg-selector:hover{background:#0000000d}.ug-ctp-agg-selector b{color:var(--ug-primary-color);margin-right:2px}.ug-ctp-agg-menu{position:absolute;top:100%;left:24px;background:#fff;border:1px solid var(--ug-border-color);border-radius:4px;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;z-index:100;min-width:120px;padding:4px 0}.ug-ctp-agg-option{padding:6px 12px;cursor:pointer;font-size:13px}.ug-ctp-agg-option:hover{background:#f1f5f9}.ug-ctp-agg-option.selected{background:#e0f2fe;color:#0369a1;font-weight:500}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1628
+ `, isInline: true, styles: [".ug-ctp-wrapper{display:flex;flex-direction:column;height:100%;font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px);color:var(--ug-color, #181d1f);overflow-y:auto}.ug-ctp-pivot-mode{display:flex;align-items:center;padding:12px 16px;border-bottom:1px solid var(--ug-border-color);gap:12px}.ug-switch{position:relative;display:inline-block;width:34px;height:20px}.ug-switch input{opacity:0;width:0;height:0}.ug-slider{position:absolute;cursor:pointer;inset:0;background-color:var(--ug-border-color);transition:.4s}.ug-slider:before{position:absolute;content:\"\";height:14px;width:14px;left:3px;bottom:3px;background-color:#fff;transition:.4s}input:checked+.ug-slider{background-color:var(--ug-primary-color)}input:checked+.ug-slider:before{transform:translate(14px)}.ug-slider.round{border-radius:34px}.ug-slider.round:before{border-radius:50%}.ug-ctp-columns-section{display:flex;flex-direction:column;border-bottom:1px solid var(--ug-border-color)}.ug-ctp-search{padding:12px;position:relative;display:flex;align-items:center}.ug-ctp-search svg{position:absolute;left:20px;color:var(--ug-icon-color)}.ug-ctp-search input{width:100%;padding:6px 8px 6px 28px;border:1px solid var(--ug-border-color);border-radius:4px;font-family:var(--ug-font-family, inherit);font-size:var(--ug-font-size, inherit);background-color:var(--ug-bg-color);color:var(--ug-color)}.ug-ctp-search input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ctp-list{padding:0 12px 12px;max-height:280px;overflow-y:auto}.ug-ctp-list::-webkit-scrollbar{width:6px}.ug-ctp-list::-webkit-scrollbar-track{background:transparent}.ug-ctp-list::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.ug-ctp-list::-webkit-scrollbar-thumb:hover{background:#94a3b8}.ug-ctp-item{display:flex;align-items:center;padding:6px 8px;background:var(--ug-bg-color);border:1px solid transparent;border-radius:4px;margin-bottom:2px}.ug-ctp-item:hover{background:var(--ug-row-hover-bg)}.ug-ctp-item input[type=checkbox]{accent-color:var(--ug-primary-color);cursor:pointer}.ug-drag-handle{color:var(--ug-icon-color);cursor:grab;margin:0 8px}.ug-ctp-item-name{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.cdk-drag-preview{box-sizing:border-box;background:var(--ug-bg-color);border:1px solid var(--ug-border-color);border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;display:flex;align-items:center;padding:6px 8px;font-family:var(--ug-font-family);font-size:var(--ug-font-size);color:var(--ug-color)}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,0,1)}.ug-ctp-group{border-bottom:1px solid var(--ug-border-color)}.ug-ctp-group-header{display:flex;align-items:center;padding:12px 16px;gap:8px;font-family:var(--ug-font-family, sans-serif);font-weight:var(--ug-header-font-weight, 500);font-size:var(--ug-font-size, 13px);color:var(--ug-header-color);background-color:var(--ug-header-bg);-webkit-user-select:none;user-select:none;transition:background-color .2s ease}.ug-ctp-group-header.clickable{cursor:pointer}.ug-ctp-group-header.clickable:hover{background-color:var(--ug-row-hover-bg, #f1f5f9)}.ug-ctp-section-title{font-weight:600;color:var(--ug-color, #1e293b);flex:1}.ug-ctp-chevron{color:var(--ug-icon-color, #64748b);transition:transform .2s cubic-bezier(.4,0,.2,1)}.ug-ctp-chevron.collapsed{transform:rotate(-90deg)}.ug-ctp-dropzone{max-height:180px;overflow-y:auto;min-height:60px;padding:12px 16px;background-color:var(--ug-bg-color);font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px)}.ug-ctp-dropzone::-webkit-scrollbar{width:6px}.ug-ctp-dropzone::-webkit-scrollbar-track{background:transparent}.ug-ctp-dropzone::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.ug-ctp-dropzone::-webkit-scrollbar-thumb:hover{background:#94a3b8}.ug-ctp-dropzone.empty{display:flex;align-items:center;justify-content:center;color:var(--ug-icon-color);font-style:italic;border:1px dashed var(--ug-border-color);margin:8px 12px;border-radius:4px;min-height:48px}.ug-ctp-item{position:relative}.ug-ctp-agg-selector{display:flex;align-items:center;gap:4px;cursor:pointer;padding:2px 4px;border-radius:4px;flex:1;overflow:hidden}.ug-ctp-agg-selector:hover{background:#0000000d}.ug-ctp-agg-selector b{color:var(--ug-primary-color);margin-right:2px}.ug-ctp-agg-menu{position:absolute;top:100%;left:24px;background:#fff;border:1px solid var(--ug-border-color);border-radius:4px;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;z-index:100;min-width:120px;padding:4px 0}.ug-ctp-agg-option{padding:6px 12px;cursor:pointer;font-size:13px}.ug-ctp-agg-option:hover{background:#f1f5f9}.ug-ctp-agg-option.selected{background:#e0f2fe;color:#0369a1;font-weight:500}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3.ɵɵCdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: ScrollingModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1503
1629
  }
1504
1630
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: ColumnToolPanelComponent, decorators: [{
1505
1631
  type: Component,
1506
- args: [{ selector: 'ug-column-tool-panel', standalone: true, imports: [CommonModule, FormsModule, DragDropModule], template: `
1507
- <div class="ug-ctp-wrapper" cdkDropListGroup>
1632
+ args: [{ selector: 'ug-column-tool-panel', standalone: true, imports: [CommonModule, FormsModule, DragDropModule, ScrollingModule], template: `
1633
+ <div class="ug-ctp-wrapper" cdkDropListGroup cdkScrollable>
1508
1634
  <!-- Pivot Mode Toggle -->
1509
1635
  <div class="ug-ctp-pivot-mode">
1510
1636
  <label class="ug-switch">
@@ -1515,112 +1641,129 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
1515
1641
  </div>
1516
1642
 
1517
1643
  <!-- Column List Section -->
1518
- <div class="ug-ctp-columns-section">
1519
- <div class="ug-ctp-search">
1520
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
1521
- <input type="text" placeholder="Search..." [(ngModel)]="searchQuery" (ngModelChange)="applySearch()" />
1644
+ <div class="ug-ctp-group">
1645
+ <div class="ug-ctp-group-header clickable" (click)="toggleColumnsExpanded()">
1646
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="9" y1="3" x2="9" y2="21"></line><line x1="15" y1="3" x2="15" y2="21"></line></svg>
1647
+ <span class="ug-ctp-section-title">Columns ({{ getSelectedColumnsCount() }}/{{ columns.length }})</span>
1648
+ <svg class="ug-ctp-chevron" [class.collapsed]="!isColumnsExpanded" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1522
1649
  </div>
1650
+
1651
+ <div class="ug-ctp-section-content" [style.display]="isColumnsExpanded ? 'block' : 'none'">
1652
+ <div class="ug-ctp-search">
1653
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
1654
+ <input type="text" placeholder="Search..." [(ngModel)]="searchQuery" (ngModelChange)="applySearch()" />
1655
+ </div>
1523
1656
 
1524
- <div class="ug-ctp-select-all" style="padding: 8px 12px; border-bottom: 1px solid var(--ug-border-color, #e2e8f0); display: flex; align-items: center; gap: 8px; cursor: pointer;" (click)="toggleAllColumns()">
1525
- <input type="checkbox" [checked]="isAllColumnsSelected()" [indeterminate]="isSomeColumnsSelected() && !isAllColumnsSelected()" style="pointer-events: none;" />
1526
- <span style="font-weight: 500; font-size: 13px;">Select All</span>
1527
- </div>
1657
+ <div class="ug-ctp-select-all" style="padding: 8px 12px; border-bottom: 1px solid var(--ug-border-color, #e2e8f0); display: flex; align-items: center; gap: 8px; cursor: pointer;" (click)="toggleAllColumns()">
1658
+ <input type="checkbox" [checked]="isAllColumnsSelected()" [indeterminate]="isSomeColumnsSelected() && !isAllColumnsSelected()" style="pointer-events: none;" />
1659
+ <span style="font-weight: 500; font-size: 13px;">Select All</span>
1660
+ </div>
1528
1661
 
1529
- <div
1530
- class="ug-ctp-list"
1531
- id="colList"
1532
- cdkDropList
1533
- [cdkDropListData]="displayColumns"
1534
- [cdkDropListConnectedTo]="['groupList', 'valueList', 'pivotList']"
1535
- (cdkDropListDropped)="onDrop($event)">
1536
1662
  <div
1537
- class="ug-ctp-item"
1538
- *ngFor="let col of displayColumns"
1539
- cdkDrag
1540
- [cdkDragData]="col">
1541
- <input type="checkbox" [checked]="!col.hide" (change)="toggleVisibility(col)" />
1542
- <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1543
- <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1663
+ class="ug-ctp-list"
1664
+ id="colList"
1665
+ cdkDropList
1666
+ [cdkDropListData]="displayColumns"
1667
+ [cdkDropListConnectedTo]="['groupList', 'valueList', 'pivotList']"
1668
+ (cdkDropListDropped)="onDrop($event)">
1669
+ <div
1670
+ class="ug-ctp-item"
1671
+ *ngFor="let col of displayColumns"
1672
+ cdkDrag
1673
+ [cdkDragData]="col">
1674
+ <input type="checkbox" [checked]="!col.hide" (change)="toggleVisibility(col)" />
1675
+ <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1676
+ <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1677
+ </div>
1544
1678
  </div>
1545
1679
  </div>
1546
1680
  </div>
1547
1681
 
1548
1682
  <!-- Row Groups -->
1549
1683
  <div class="ug-ctp-group">
1550
- <div class="ug-ctp-group-header">
1684
+ <div class="ug-ctp-group-header clickable" (click)="toggleRowGroupsExpanded()">
1551
1685
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line></svg>
1552
- <span>Row Groups</span>
1686
+ <span class="ug-ctp-section-title">Row Groups ({{ groupColumns.length }})</span>
1687
+ <svg class="ug-ctp-chevron" [class.collapsed]="!isRowGroupsExpanded" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1553
1688
  </div>
1554
- <div
1555
- class="ug-ctp-dropzone"
1556
- id="groupList"
1557
- cdkDropList
1558
- [cdkDropListData]="groupColumns"
1559
- [cdkDropListConnectedTo]="['colList', 'pivotList', 'valueList']"
1560
- (cdkDropListDropped)="onGroupDrop($event)"
1561
- [class.empty]="groupColumns.length === 0">
1562
- <div *ngIf="groupColumns.length === 0">Drag here to set row groups</div>
1563
- <div class="ug-ctp-item" *ngFor="let col of groupColumns" cdkDrag [cdkDragData]="col">
1564
- <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1565
- <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1566
- <span class="ug-ctp-remove" (click)="removeGroup(col)" style="margin-left:auto;cursor:pointer;">&times;</span>
1689
+ <div class="ug-ctp-section-content" [style.display]="isRowGroupsExpanded ? 'block' : 'none'">
1690
+ <div
1691
+ class="ug-ctp-dropzone"
1692
+ id="groupList"
1693
+ cdkDropList
1694
+ [cdkDropListData]="groupColumns"
1695
+ [cdkDropListConnectedTo]="['colList', 'pivotList', 'valueList']"
1696
+ (cdkDropListDropped)="onGroupDrop($event)"
1697
+ [class.empty]="groupColumns.length === 0">
1698
+ <div *ngIf="groupColumns.length === 0">Drag here to set row groups</div>
1699
+ <div class="ug-ctp-item" *ngFor="let col of groupColumns" cdkDrag [cdkDragData]="col">
1700
+ <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1701
+ <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1702
+ <span class="ug-ctp-remove" (click)="removeGroup(col)" style="margin-left:auto;cursor:pointer;">&times;</span>
1703
+ </div>
1567
1704
  </div>
1568
1705
  </div>
1569
1706
  </div>
1570
1707
 
1571
1708
  <!-- Pivot Columns -->
1572
1709
  <div class="ug-ctp-group" *ngIf="pivotMode">
1573
- <div class="ug-ctp-group-header">
1710
+ <div class="ug-ctp-group-header clickable" (click)="togglePivotColumnsExpanded()">
1574
1711
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12V7H5a2 2 0 0 1 0-4h14v4"/><path d="M3 5v14a2 2 0 0 0 2 2h16v-5"/><path d="M18 12H3"/></svg>
1575
- <span>Pivot Columns</span>
1712
+ <span class="ug-ctp-section-title">Pivot Columns ({{ pivotColumnsInternal.length }})</span>
1713
+ <svg class="ug-ctp-chevron" [class.collapsed]="!isPivotColumnsExpanded" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1576
1714
  </div>
1577
- <div
1578
- class="ug-ctp-dropzone"
1579
- id="pivotList"
1580
- cdkDropList
1581
- [cdkDropListData]="pivotColumnsInternal"
1582
- [cdkDropListConnectedTo]="['colList', 'groupList', 'valueList']"
1583
- (cdkDropListDropped)="onPivotDrop($event)"
1584
- [class.empty]="pivotColumnsInternal.length === 0">
1585
- <div *ngIf="pivotColumnsInternal.length === 0">Drag here to pivot</div>
1586
- <div class="ug-ctp-item" *ngFor="let col of pivotColumnsInternal" cdkDrag [cdkDragData]="col">
1587
- <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1588
- <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1589
- <span class="ug-ctp-remove" (click)="removePivot(col)" style="margin-left:auto;cursor:pointer;">&times;</span>
1715
+ <div class="ug-ctp-section-content" [style.display]="isPivotColumnsExpanded ? 'block' : 'none'">
1716
+ <div
1717
+ class="ug-ctp-dropzone"
1718
+ id="pivotList"
1719
+ cdkDropList
1720
+ [cdkDropListData]="pivotColumnsInternal"
1721
+ [cdkDropListConnectedTo]="['colList', 'groupList', 'valueList']"
1722
+ (cdkDropListDropped)="onPivotDrop($event)"
1723
+ [class.empty]="pivotColumnsInternal.length === 0">
1724
+ <div *ngIf="pivotColumnsInternal.length === 0">Drag here to pivot</div>
1725
+ <div class="ug-ctp-item" *ngFor="let col of pivotColumnsInternal" cdkDrag [cdkDragData]="col">
1726
+ <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1727
+ <span class="ug-ctp-item-name">{{ col.headerName || col.field }}</span>
1728
+ <span class="ug-ctp-remove" (click)="removePivot(col)" style="margin-left:auto;cursor:pointer;">&times;</span>
1729
+ </div>
1590
1730
  </div>
1591
1731
  </div>
1592
1732
  </div>
1593
1733
 
1594
1734
  <!-- Values -->
1595
1735
  <div class="ug-ctp-group">
1596
- <div class="ug-ctp-group-header">
1736
+ <div class="ug-ctp-group-header clickable" (click)="toggleValuesExpanded()">
1597
1737
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 7 4 4 20 4 20 7"></polyline><line x1="9" y1="20" x2="15" y2="20"></line><line x1="12" y1="4" x2="12" y2="20"></line></svg>
1598
- <span>Values</span>
1738
+ <span class="ug-ctp-section-title">Values ({{ valueColumns.length }})</span>
1739
+ <svg class="ug-ctp-chevron" [class.collapsed]="!isValuesExpanded" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1599
1740
  </div>
1600
- <div
1601
- class="ug-ctp-dropzone"
1602
- id="valueList"
1603
- cdkDropList
1604
- [cdkDropListData]="valueColumns"
1605
- [cdkDropListConnectedTo]="['colList', 'groupList', 'pivotList']"
1606
- (cdkDropListDropped)="onValueDrop($event)"
1607
- [class.empty]="valueColumns.length === 0">
1608
- <div *ngIf="valueColumns.length === 0">Drag here to aggregate</div>
1609
- <div class="ug-ctp-item" *ngFor="let vCol of valueColumns" cdkDrag [cdkDragData]="vCol">
1610
- <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1611
- <div class="ug-ctp-agg-selector" (click)="toggleAggDropdown(vCol.field)">
1612
- <span class="ug-ctp-item-name"><b>{{ vCol.aggFunc }}</b>({{ getColumnHeader(vCol.field) }})</span>
1613
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1614
- </div>
1615
- <span class="ug-ctp-remove" (click)="removeValue(vCol.field)" style="margin-left:auto;cursor:pointer;">&times;</span>
1616
-
1617
- <!-- Dropdown Menu -->
1618
- <div class="ug-ctp-agg-menu" *ngIf="openDropdownField === vCol.field">
1619
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'sum'" (click)="setAggFunc(vCol, 'sum')">sum</div>
1620
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'min'" (click)="setAggFunc(vCol, 'min')">min</div>
1621
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'max'" (click)="setAggFunc(vCol, 'max')">max</div>
1622
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'count'" (click)="setAggFunc(vCol, 'count')">count</div>
1623
- <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'avg'" (click)="setAggFunc(vCol, 'avg')">avg</div>
1741
+ <div class="ug-ctp-section-content" [style.display]="isValuesExpanded ? 'block' : 'none'">
1742
+ <div
1743
+ class="ug-ctp-dropzone"
1744
+ id="valueList"
1745
+ cdkDropList
1746
+ [cdkDropListData]="valueColumns"
1747
+ [cdkDropListConnectedTo]="['colList', 'groupList', 'pivotList']"
1748
+ (cdkDropListDropped)="onValueDrop($event)"
1749
+ [class.empty]="valueColumns.length === 0">
1750
+ <div *ngIf="valueColumns.length === 0">Drag here to aggregate</div>
1751
+ <div class="ug-ctp-item" *ngFor="let vCol of valueColumns" cdkDrag [cdkDragData]="vCol">
1752
+ <svg class="ug-drag-handle" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" cdkDragHandle><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
1753
+ <div class="ug-ctp-agg-selector" (click)="toggleAggDropdown(vCol.field)">
1754
+ <span class="ug-ctp-item-name"><b>{{ vCol.aggFunc }}</b>({{ getColumnHeader(vCol.field) }})</span>
1755
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1756
+ </div>
1757
+ <span class="ug-ctp-remove" (click)="removeValue(vCol.field)" style="margin-left:auto;cursor:pointer;">&times;</span>
1758
+
1759
+ <!-- Dropdown Menu -->
1760
+ <div class="ug-ctp-agg-menu" *ngIf="openDropdownField === vCol.field">
1761
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'sum'" (click)="setAggFunc(vCol, 'sum')">sum</div>
1762
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'min'" (click)="setAggFunc(vCol, 'min')">min</div>
1763
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'max'" (click)="setAggFunc(vCol, 'max')">max</div>
1764
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'count'" (click)="setAggFunc(vCol, 'count')">count</div>
1765
+ <div class="ug-ctp-agg-option" [class.selected]="vCol.aggFunc === 'avg'" (click)="setAggFunc(vCol, 'avg')">avg</div>
1766
+ </div>
1624
1767
  </div>
1625
1768
  </div>
1626
1769
  </div>
@@ -1636,7 +1779,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
1636
1779
  </button>
1637
1780
  </div>
1638
1781
  </div>
1639
- `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [".ug-ctp-wrapper{display:flex;flex-direction:column;height:100%;font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px);color:var(--ug-color, #181d1f)}.ug-ctp-pivot-mode{display:flex;align-items:center;padding:12px 16px;border-bottom:1px solid var(--ug-border-color);gap:12px}.ug-switch{position:relative;display:inline-block;width:34px;height:20px}.ug-switch input{opacity:0;width:0;height:0}.ug-slider{position:absolute;cursor:pointer;inset:0;background-color:var(--ug-border-color);transition:.4s}.ug-slider:before{position:absolute;content:\"\";height:14px;width:14px;left:3px;bottom:3px;background-color:#fff;transition:.4s}input:checked+.ug-slider{background-color:var(--ug-primary-color)}input:checked+.ug-slider:before{transform:translate(14px)}.ug-slider.round{border-radius:34px}.ug-slider.round:before{border-radius:50%}.ug-ctp-columns-section{flex:1;display:flex;flex-direction:column;border-bottom:1px solid var(--ug-border-color);min-height:200px}.ug-ctp-search{padding:12px;position:relative;display:flex;align-items:center}.ug-ctp-search svg{position:absolute;left:20px;color:var(--ug-icon-color)}.ug-ctp-search input{width:100%;padding:6px 8px 6px 28px;border:1px solid var(--ug-border-color);border-radius:4px;font-family:var(--ug-font-family, inherit);font-size:var(--ug-font-size, inherit);background-color:var(--ug-bg-color);color:var(--ug-color)}.ug-ctp-search input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ctp-list{flex:1;overflow-y:auto;padding:0 12px 12px}.ug-ctp-item{display:flex;align-items:center;padding:6px 8px;background:var(--ug-bg-color);border:1px solid transparent;border-radius:4px;margin-bottom:2px}.ug-ctp-item:hover{background:var(--ug-row-hover-bg)}.ug-ctp-item input[type=checkbox]{accent-color:var(--ug-primary-color);cursor:pointer}.ug-drag-handle{color:var(--ug-icon-color);cursor:grab;margin:0 8px}.ug-ctp-item-name{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.cdk-drag-preview{box-sizing:border-box;background:var(--ug-bg-color);border:1px solid var(--ug-border-color);border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;display:flex;align-items:center;padding:6px 8px;font-family:var(--ug-font-family);font-size:var(--ug-font-size);color:var(--ug-color)}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,0,1)}.ug-ctp-group{border-bottom:1px solid var(--ug-border-color)}.ug-ctp-group-header{display:flex;align-items:center;padding:12px 16px;gap:8px;font-family:var(--ug-font-family, sans-serif);font-weight:var(--ug-header-font-weight, 500);font-size:var(--ug-font-size, 13px);color:var(--ug-header-color);background-color:var(--ug-header-bg)}.ug-ctp-dropzone{min-height:80px;padding:12px 16px;background-color:var(--ug-bg-color);font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px)}.ug-ctp-dropzone.empty{display:flex;align-items:center;justify-content:center;color:var(--ug-icon-color);font-style:italic;border:1px dashed var(--ug-border-color);margin:12px;border-radius:4px}.ug-ctp-item{position:relative}.ug-ctp-agg-selector{display:flex;align-items:center;gap:4px;cursor:pointer;padding:2px 4px;border-radius:4px;flex:1;overflow:hidden}.ug-ctp-agg-selector:hover{background:#0000000d}.ug-ctp-agg-selector b{color:var(--ug-primary-color);margin-right:2px}.ug-ctp-agg-menu{position:absolute;top:100%;left:24px;background:#fff;border:1px solid var(--ug-border-color);border-radius:4px;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;z-index:100;min-width:120px;padding:4px 0}.ug-ctp-agg-option{padding:6px 12px;cursor:pointer;font-size:13px}.ug-ctp-agg-option:hover{background:#f1f5f9}.ug-ctp-agg-option.selected{background:#e0f2fe;color:#0369a1;font-weight:500}\n"] }]
1782
+ `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [".ug-ctp-wrapper{display:flex;flex-direction:column;height:100%;font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px);color:var(--ug-color, #181d1f);overflow-y:auto}.ug-ctp-pivot-mode{display:flex;align-items:center;padding:12px 16px;border-bottom:1px solid var(--ug-border-color);gap:12px}.ug-switch{position:relative;display:inline-block;width:34px;height:20px}.ug-switch input{opacity:0;width:0;height:0}.ug-slider{position:absolute;cursor:pointer;inset:0;background-color:var(--ug-border-color);transition:.4s}.ug-slider:before{position:absolute;content:\"\";height:14px;width:14px;left:3px;bottom:3px;background-color:#fff;transition:.4s}input:checked+.ug-slider{background-color:var(--ug-primary-color)}input:checked+.ug-slider:before{transform:translate(14px)}.ug-slider.round{border-radius:34px}.ug-slider.round:before{border-radius:50%}.ug-ctp-columns-section{display:flex;flex-direction:column;border-bottom:1px solid var(--ug-border-color)}.ug-ctp-search{padding:12px;position:relative;display:flex;align-items:center}.ug-ctp-search svg{position:absolute;left:20px;color:var(--ug-icon-color)}.ug-ctp-search input{width:100%;padding:6px 8px 6px 28px;border:1px solid var(--ug-border-color);border-radius:4px;font-family:var(--ug-font-family, inherit);font-size:var(--ug-font-size, inherit);background-color:var(--ug-bg-color);color:var(--ug-color)}.ug-ctp-search input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ctp-list{padding:0 12px 12px;max-height:280px;overflow-y:auto}.ug-ctp-list::-webkit-scrollbar{width:6px}.ug-ctp-list::-webkit-scrollbar-track{background:transparent}.ug-ctp-list::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.ug-ctp-list::-webkit-scrollbar-thumb:hover{background:#94a3b8}.ug-ctp-item{display:flex;align-items:center;padding:6px 8px;background:var(--ug-bg-color);border:1px solid transparent;border-radius:4px;margin-bottom:2px}.ug-ctp-item:hover{background:var(--ug-row-hover-bg)}.ug-ctp-item input[type=checkbox]{accent-color:var(--ug-primary-color);cursor:pointer}.ug-drag-handle{color:var(--ug-icon-color);cursor:grab;margin:0 8px}.ug-ctp-item-name{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.cdk-drag-preview{box-sizing:border-box;background:var(--ug-bg-color);border:1px solid var(--ug-border-color);border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;display:flex;align-items:center;padding:6px 8px;font-family:var(--ug-font-family);font-size:var(--ug-font-size);color:var(--ug-color)}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,0,1)}.ug-ctp-group{border-bottom:1px solid var(--ug-border-color)}.ug-ctp-group-header{display:flex;align-items:center;padding:12px 16px;gap:8px;font-family:var(--ug-font-family, sans-serif);font-weight:var(--ug-header-font-weight, 500);font-size:var(--ug-font-size, 13px);color:var(--ug-header-color);background-color:var(--ug-header-bg);-webkit-user-select:none;user-select:none;transition:background-color .2s ease}.ug-ctp-group-header.clickable{cursor:pointer}.ug-ctp-group-header.clickable:hover{background-color:var(--ug-row-hover-bg, #f1f5f9)}.ug-ctp-section-title{font-weight:600;color:var(--ug-color, #1e293b);flex:1}.ug-ctp-chevron{color:var(--ug-icon-color, #64748b);transition:transform .2s cubic-bezier(.4,0,.2,1)}.ug-ctp-chevron.collapsed{transform:rotate(-90deg)}.ug-ctp-dropzone{max-height:180px;overflow-y:auto;min-height:60px;padding:12px 16px;background-color:var(--ug-bg-color);font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px)}.ug-ctp-dropzone::-webkit-scrollbar{width:6px}.ug-ctp-dropzone::-webkit-scrollbar-track{background:transparent}.ug-ctp-dropzone::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.ug-ctp-dropzone::-webkit-scrollbar-thumb:hover{background:#94a3b8}.ug-ctp-dropzone.empty{display:flex;align-items:center;justify-content:center;color:var(--ug-icon-color);font-style:italic;border:1px dashed var(--ug-border-color);margin:8px 12px;border-radius:4px;min-height:48px}.ug-ctp-item{position:relative}.ug-ctp-agg-selector{display:flex;align-items:center;gap:4px;cursor:pointer;padding:2px 4px;border-radius:4px;flex:1;overflow:hidden}.ug-ctp-agg-selector:hover{background:#0000000d}.ug-ctp-agg-selector b{color:var(--ug-primary-color);margin-right:2px}.ug-ctp-agg-menu{position:absolute;top:100%;left:24px;background:#fff;border:1px solid var(--ug-border-color);border-radius:4px;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;z-index:100;min-width:120px;padding:4px 0}.ug-ctp-agg-option{padding:6px 12px;cursor:pointer;font-size:13px}.ug-ctp-agg-option:hover{background:#f1f5f9}.ug-ctp-agg-option.selected{background:#e0f2fe;color:#0369a1;font-weight:500}\n"] }]
1640
1783
  }], propDecorators: { columns: [{
1641
1784
  type: Input
1642
1785
  }], groupModel: [{
@@ -3221,14 +3364,6 @@ class UltraGridComponent {
3221
3364
  }
3222
3365
  }
3223
3366
  }
3224
- else {
3225
- // Default: aggregate all numeric columns if Values panel is empty
3226
- for (const col of this.columns) {
3227
- if (!aggregations[col.field] && this.isNumericColumn(col.field)) {
3228
- aggregations[col.field] = 'sum';
3229
- }
3230
- }
3231
- }
3232
3367
  if (hasFilter || hasSort || this.groupModel.length > 0 || this.conditionFilters.size > 0) {
3233
3368
  if (this.sortingWorker) {
3234
3369
  this.sortingWorker.postMessage({
@@ -3239,7 +3374,7 @@ class UltraGridComponent {
3239
3374
  groupModel: this.groupModel,
3240
3375
  groupStateMap: stateMapObj,
3241
3376
  aggregations: aggregations,
3242
- groupIncludeFooter: !!this.config.groupIncludeFooter,
3377
+ groupIncludeFooter: !!this.config.groupIncludeFooter || this.valuesModel.length > 0,
3243
3378
  pivotMode: !!this.config.pivotMode,
3244
3379
  pivotColumns: this.pivotColumns
3245
3380
  });
@@ -3266,7 +3401,7 @@ class UltraGridComponent {
3266
3401
  this.refreshFlattener();
3267
3402
  }
3268
3403
  refreshFlattener() {
3269
- this._unpaginatedLocalData = this.flattener.flatten(this._localTreeData, this.groupStateMap, !!this.config.groupIncludeFooter);
3404
+ this._unpaginatedLocalData = this.flattener.flatten(this._localTreeData, this.groupStateMap, !!this.config.groupIncludeFooter || this.valuesModel.length > 0);
3270
3405
  this.totalCount = this._unpaginatedLocalData.length;
3271
3406
  this.updatePaginationForLocalData();
3272
3407
  this.cdr.markForCheck();
@@ -3316,7 +3451,7 @@ class UltraGridComponent {
3316
3451
  this.sortingWorker.postMessage({
3317
3452
  action: 'FLATTEN_ONLY',
3318
3453
  groupStateMap: stateObj,
3319
- groupIncludeFooter: !!this.config.groupIncludeFooter
3454
+ groupIncludeFooter: !!this.config.groupIncludeFooter || this.valuesModel.length > 0
3320
3455
  });
3321
3456
  }
3322
3457
  else {
@@ -3620,6 +3755,16 @@ class UltraGridComponent {
3620
3755
  onMenuSort(event) {
3621
3756
  this.onSortChanged(event);
3622
3757
  }
3758
+ onMenuFormatChange(event) {
3759
+ this.columns = this.columns.map(c => {
3760
+ if (c.field === event.field) {
3761
+ return { ...c, numberFormat: event.format };
3762
+ }
3763
+ return c;
3764
+ });
3765
+ this.updateVisibleColumns();
3766
+ this.cdr.markForCheck();
3767
+ }
3623
3768
  onMenuPin(event) {
3624
3769
  const col = this.columns.find(c => c.field === event.field);
3625
3770
  if (col) {
@@ -3943,7 +4088,8 @@ class UltraGridComponent {
3943
4088
  (pin)="onMenuPin($event)"
3944
4089
  (autosize)="onMenuAutosize($event)"
3945
4090
  (group)="onMenuGroup($event)"
3946
- (chooseColumns)="onMenuChooseColumns()">
4091
+ (chooseColumns)="onMenuChooseColumns()"
4092
+ (formatChange)="onMenuFormatChange($event)">
3947
4093
  </ug-header-menu>
3948
4094
 
3949
4095
  <ug-header-filter
@@ -3963,7 +4109,7 @@ class UltraGridComponent {
3963
4109
  (closePanel)="isChooseColumnsOpen = false">
3964
4110
  </ug-choose-columns>
3965
4111
  </div>
3966
- `, isInline: true, styles: ["@charset \"UTF-8\";bways-grid{display:block;height:100%;width:100%;--ug-border-color: rgba(221, 226, 235, .4);--ug-bg-color: transparent;--ug-header-bg: rgba(255, 255, 255, .25);--ug-pinned-header-bg: rgba(255, 255, 255, .85);--ug-header-color: #3f332f;--ug-header-hover-bg: rgba(255, 255, 255, .4);--ug-pinned-header-hover-bg: rgba(255, 255, 255, .95);--ug-row-bg: rgba(255, 255, 255, .15);--ug-pinned-row-bg: rgba(255, 255, 255, .85);--ug-pinned-blur: blur(12px);--ug-row-hover-bg: rgba(216, 48, 24, .05);--ug-pinned-row-hover-bg: rgba(255, 240, 240, .95);--ug-row-selected-bg: rgba(216, 48, 24, .15);--ug-pinned-row-selected-bg: rgba(255, 220, 220, .95);--ug-primary-color: #d83018;--ug-panel-bg: #ffffff;--ug-footer-bg: rgba(255, 255, 255, .25);--ug-footer-color: #554440;--ug-icon-color: #7b6d69;--ug-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif;--ug-font-size: 13px;--ug-header-font-weight: 600}.ug-wrapper{display:flex;flex-direction:row;height:100%;width:100%;border:1px solid var(--ug-border-color);background-color:var(--ug-bg-color);background-image:url(\"data:image/svg+xml;utf8,<svg viewBox='0 0 800 800' xmlns='http://www.w3.org/2000/svg'><g fill='rgba(0,0,0,0.02)'><path transform='translate(150,150) scale(1.6)' d='M-20 -30c0-10 40-10 40 0v60c0 10-40 10-40 0z M-20 -10c0 10 40 10 40 0 M-20 10c0 10 40 10 40 0'/><path transform='translate(600,250) scale(1.8)' d='M-40 10a30 30 0 0 1 50-10 40 40 0 0 1 30 60h-80a20 20 0 0 1 0-50z'/><g transform='translate(350,550) scale(1.7)'><circle cx='0' cy='-20' r='10'/><circle cx='-30' cy='10' r='8'/><circle cx='30' cy='10' r='8'/><path d='M0 -20l-30 30m30-30l30 30' stroke='rgba(0,0,0,0.02)' stroke-width='4'/></g><path transform='translate(700,700) scale(1.4)' d='M-20 -30c0-10 40-10 40 0v60c0 10-40 10-40 0z M-20 -10c0 10 40 10 40 0 M-20 10c0 10 40 10 40 0'/><path transform='translate(100,600) scale(1.5)' d='M-40 10a30 30 0 0 1 50-10 40 40 0 0 1 30 60h-80a20 20 0 0 1 0-50z'/><g transform='translate(450,100) scale(1.3)'><circle cx='0' cy='-20' r='10'/><circle cx='-30' cy='10' r='8'/><circle cx='30' cy='10' r='8'/><path d='M0 -20l-30 30m30-30l30 30' stroke='rgba(0,0,0,0.02)' stroke-width='4'/></g></g></svg>\"),radial-gradient(circle at 10% 20%,#fdf5f5 0%,transparent 60%),radial-gradient(circle at 80% 10%,#eefbf6 0%,transparent 60%),radial-gradient(circle at 50% 80%,#f9f5f0,#f1efe9);background-size:800px 800px,100% 100%,100% 100%,100% 100%;background-position:center;background-repeat:repeat,no-repeat,no-repeat,no-repeat;box-sizing:border-box;font-family:var(--ug-font-family);font-size:var(--ug-font-size);color:var(--ug-header-color);overflow:hidden;backdrop-filter:blur(8px)}.ug-main{display:flex;flex-direction:column;flex:1;min-width:0;overflow:hidden}.ug-body{flex:1;overflow:hidden;position:relative}.ug-viewport{height:100%;width:100%;overflow:auto}.ug-ssr-container{height:100%;width:100%;overflow:hidden}.ug-status-bar{display:flex;align-items:center;padding:0 16px;min-height:48px;border-top:1px solid var(--ug-border-color);font-weight:500;font-size:13px;color:var(--ug-header-color);background-color:var(--ug-footer-bg)}.ug-cc-overlay-container{position:fixed;z-index:1002}bways-grid.ag-theme-alpine-dark{--ug-border-color: #334155;--ug-bg-color: #1e293b;--ug-header-bg: #0f172a;--ug-pinned-header-bg: #0f172a;--ug-header-color: #e2e8f0;--ug-header-hover-bg: #1e293b;--ug-pinned-header-hover-bg: #1e293b;--ug-row-bg: #1e293b;--ug-pinned-row-bg: #1e293b;--ug-pinned-blur: none;--ug-row-hover-bg: #334155;--ug-pinned-row-hover-bg: #334155;--ug-row-selected-bg: #0f172a;--ug-pinned-row-selected-bg: #0f172a;--ug-primary-color: #60a5fa;--ug-footer-bg: #0f172a;--ug-footer-color: #94a3b8;--ug-icon-color: #94a3b8}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i3$1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i3$1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i3$1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: HeaderComponent, selector: "ug-header", inputs: ["columns", "sortModel", "isAllSelected"], outputs: ["sortChanged", "columnsReordered", "columnResized", "headerCheckboxClicked", "menuClicked", "filterClicked"] }, { kind: "component", type: RowComponent, selector: "ug-row", inputs: ["columns", "row", "rowHeight", "isExpanded", "selectionVersion"], outputs: ["groupToggled"] }, { kind: "component", type: PaginationComponent, selector: "ug-pagination", inputs: ["totalCount", "pageSize", "currentPage"], outputs: ["pageChanged", "pageSizeChanged"] }, { kind: "component", type: HeaderMenuComponent, selector: "ug-header-menu", inputs: ["column", "isOpen", "position", "groupModel"], outputs: ["closeMenu", "sort", "pin", "autosize", "group", "chooseColumns"] }, { kind: "component", type: ChooseColumnsComponent, selector: "ug-choose-columns", inputs: ["columns"], outputs: ["columnsChanged", "closePanel"] }, { kind: "component", type: HeaderFilterComponent, selector: "ug-header-filter", inputs: ["column", "isOpen", "position", "uniqueValues", "activeFilterSet"], outputs: ["closeFilter", "filterApplied"] }, { kind: "component", type: SideBarComponent, selector: "ug-side-bar", inputs: ["columns", "rowData", "activeFilters", "conditionFilters", "groupModel", "valuesModel", "pivotMode", "pivotColumns", "toolPanels", "savedReportNames", "activeTab"], outputs: ["columnsUpdated", "groupModelUpdated", "valuesModelUpdated", "pivotModeUpdated", "pivotModelUpdated", "exportExcelClicked", "filterApplied", "conditionFilterChanged", "clearAllFilters", "saveReportRequested", "importReportRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
4112
+ `, isInline: true, styles: ["@charset \"UTF-8\";bways-grid{display:block;height:100%;width:100%;--ug-border-color: rgba(221, 226, 235, .4);--ug-bg-color: transparent;--ug-header-bg: rgba(255, 255, 255, .25);--ug-pinned-header-bg: rgba(255, 255, 255, .85);--ug-header-color: #3f332f;--ug-header-hover-bg: rgba(255, 255, 255, .4);--ug-pinned-header-hover-bg: rgba(255, 255, 255, .95);--ug-row-bg: rgba(255, 255, 255, .15);--ug-pinned-row-bg: rgba(255, 255, 255, .85);--ug-pinned-blur: blur(12px);--ug-row-hover-bg: rgba(216, 48, 24, .05);--ug-pinned-row-hover-bg: rgba(255, 240, 240, .95);--ug-row-selected-bg: rgba(216, 48, 24, .15);--ug-pinned-row-selected-bg: rgba(255, 220, 220, .95);--ug-primary-color: #d83018;--ug-panel-bg: #ffffff;--ug-footer-bg: rgba(255, 255, 255, .25);--ug-footer-color: #554440;--ug-icon-color: #7b6d69;--ug-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif;--ug-font-size: 13px;--ug-header-font-weight: 600}.ug-wrapper{display:flex;flex-direction:row;height:100%;width:100%;border:1px solid var(--ug-border-color);background-color:var(--ug-bg-color);background-image:url(\"data:image/svg+xml;utf8,<svg viewBox='0 0 800 800' xmlns='http://www.w3.org/2000/svg'><g fill='rgba(0,0,0,0.02)'><path transform='translate(150,150) scale(1.6)' d='M-20 -30c0-10 40-10 40 0v60c0 10-40 10-40 0z M-20 -10c0 10 40 10 40 0 M-20 10c0 10 40 10 40 0'/><path transform='translate(600,250) scale(1.8)' d='M-40 10a30 30 0 0 1 50-10 40 40 0 0 1 30 60h-80a20 20 0 0 1 0-50z'/><g transform='translate(350,550) scale(1.7)'><circle cx='0' cy='-20' r='10'/><circle cx='-30' cy='10' r='8'/><circle cx='30' cy='10' r='8'/><path d='M0 -20l-30 30m30-30l30 30' stroke='rgba(0,0,0,0.02)' stroke-width='4'/></g><path transform='translate(700,700) scale(1.4)' d='M-20 -30c0-10 40-10 40 0v60c0 10-40 10-40 0z M-20 -10c0 10 40 10 40 0 M-20 10c0 10 40 10 40 0'/><path transform='translate(100,600) scale(1.5)' d='M-40 10a30 30 0 0 1 50-10 40 40 0 0 1 30 60h-80a20 20 0 0 1 0-50z'/><g transform='translate(450,100) scale(1.3)'><circle cx='0' cy='-20' r='10'/><circle cx='-30' cy='10' r='8'/><circle cx='30' cy='10' r='8'/><path d='M0 -20l-30 30m30-30l30 30' stroke='rgba(0,0,0,0.02)' stroke-width='4'/></g></g></svg>\"),radial-gradient(circle at 10% 20%,#fdf5f5 0%,transparent 60%),radial-gradient(circle at 80% 10%,#eefbf6 0%,transparent 60%),radial-gradient(circle at 50% 80%,#f9f5f0,#f1efe9);background-size:800px 800px,100% 100%,100% 100%,100% 100%;background-position:center;background-repeat:repeat,no-repeat,no-repeat,no-repeat;box-sizing:border-box;font-family:var(--ug-font-family);font-size:var(--ug-font-size);color:var(--ug-header-color);overflow:hidden;backdrop-filter:blur(8px)}.ug-main{display:flex;flex-direction:column;flex:1;min-width:0;overflow:hidden}.ug-body{flex:1;overflow:hidden;position:relative}.ug-viewport{height:100%;width:100%;overflow:auto}.ug-ssr-container{height:100%;width:100%;overflow:hidden}.ug-status-bar{display:flex;align-items:center;padding:0 16px;min-height:48px;border-top:1px solid var(--ug-border-color);font-weight:500;font-size:13px;color:var(--ug-header-color);background-color:var(--ug-footer-bg)}.ug-cc-overlay-container{position:fixed;z-index:1002}bways-grid.ag-theme-alpine-dark{--ug-border-color: #334155;--ug-bg-color: #1e293b;--ug-header-bg: #0f172a;--ug-pinned-header-bg: #0f172a;--ug-header-color: #e2e8f0;--ug-header-hover-bg: #1e293b;--ug-pinned-header-hover-bg: #1e293b;--ug-row-bg: #1e293b;--ug-pinned-row-bg: #1e293b;--ug-pinned-blur: none;--ug-row-hover-bg: #334155;--ug-pinned-row-hover-bg: #334155;--ug-row-selected-bg: #0f172a;--ug-pinned-row-selected-bg: #0f172a;--ug-primary-color: #60a5fa;--ug-footer-bg: #0f172a;--ug-footer-color: #94a3b8;--ug-icon-color: #94a3b8}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i3$1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i3$1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i3$1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: HeaderComponent, selector: "ug-header", inputs: ["columns", "sortModel", "isAllSelected"], outputs: ["sortChanged", "columnsReordered", "columnResized", "headerCheckboxClicked", "menuClicked", "filterClicked"] }, { kind: "component", type: RowComponent, selector: "ug-row", inputs: ["columns", "row", "rowHeight", "isExpanded", "selectionVersion"], outputs: ["groupToggled"] }, { kind: "component", type: PaginationComponent, selector: "ug-pagination", inputs: ["totalCount", "pageSize", "currentPage"], outputs: ["pageChanged", "pageSizeChanged"] }, { kind: "component", type: HeaderMenuComponent, selector: "ug-header-menu", inputs: ["column", "isOpen", "position", "groupModel"], outputs: ["closeMenu", "sort", "pin", "autosize", "group", "chooseColumns", "formatChange"] }, { kind: "component", type: ChooseColumnsComponent, selector: "ug-choose-columns", inputs: ["columns"], outputs: ["columnsChanged", "closePanel"] }, { kind: "component", type: HeaderFilterComponent, selector: "ug-header-filter", inputs: ["column", "isOpen", "position", "uniqueValues", "activeFilterSet"], outputs: ["closeFilter", "filterApplied"] }, { kind: "component", type: SideBarComponent, selector: "ug-side-bar", inputs: ["columns", "rowData", "activeFilters", "conditionFilters", "groupModel", "valuesModel", "pivotMode", "pivotColumns", "toolPanels", "savedReportNames", "activeTab"], outputs: ["columnsUpdated", "groupModelUpdated", "valuesModelUpdated", "pivotModeUpdated", "pivotModelUpdated", "exportExcelClicked", "filterApplied", "conditionFilterChanged", "clearAllFilters", "saveReportRequested", "importReportRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3967
4113
  }
3968
4114
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: UltraGridComponent, decorators: [{
3969
4115
  type: Component,
@@ -4081,7 +4227,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
4081
4227
  (pin)="onMenuPin($event)"
4082
4228
  (autosize)="onMenuAutosize($event)"
4083
4229
  (group)="onMenuGroup($event)"
4084
- (chooseColumns)="onMenuChooseColumns()">
4230
+ (chooseColumns)="onMenuChooseColumns()"
4231
+ (formatChange)="onMenuFormatChange($event)">
4085
4232
  </ug-header-menu>
4086
4233
 
4087
4234
  <ug-header-filter