bways-grid 0.0.10 → 0.0.12

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.
@@ -170,6 +170,7 @@ class HeaderComponent {
170
170
  [class.ug-pinned-right]="col.pinned === 'right'"
171
171
  [style.left.px]="col._leftOffset"
172
172
  [style.right.px]="col._rightOffset"
173
+ [style.flex-grow]="isLast ? 1 : 0"
173
174
  >
174
175
  <div class="ug-header-checkbox" *ngIf="col.headerCheckboxSelection" (click)="onHeaderCheckboxClick($event)">
175
176
  <input type="checkbox" [checked]="isAllSelected" />
@@ -204,7 +205,7 @@ class HeaderComponent {
204
205
  </div>
205
206
  </div>
206
207
  </div>
207
- `, isInline: true, styles: ["ug-header{display:block;background-color:var(--ug-header-bg);border-bottom:1px solid var(--ug-border-color);position:sticky;top:0;z-index:10;color:var(--ug-header-color);font-weight:var(--ug-header-font-weight)}.ug-header-row{display:inline-flex;min-width:100%;height:48px}.ug-header-cell{display:flex;align-items:center;padding:0 0 0 16px;box-sizing:border-box;position:relative;-webkit-user-select:none;user-select:none;background-color:var(--ug-header-bg);transition:background-color .2s;flex-shrink:0;flex-grow:1}.ug-header-cell:hover{background-color:var(--ug-header-hover-bg)}.ug-pinned-left{position:sticky;z-index:2;border-right:1px solid var(--ug-border-color)}.ug-pinned-right{position:sticky;z-index:2;border-left:1px solid var(--ug-border-color)}.ug-header-checkbox{margin-right:12px;display:flex;align-items:center}.ug-header-checkbox input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--ug-primary-color)}.ug-header-cell-label{flex:1;display:flex;align-items:center;overflow:hidden;white-space:nowrap;height:100%}.ug-header-cell-label.sortable{cursor:pointer}.ug-header-cell-label span{overflow:hidden;text-overflow:ellipsis}.ug-sort-icon{margin-left:6px;display:flex;align-items:center;color:var(--ug-icon-color)}.ug-header-menu-icon,.ug-header-filter-icon{padding:0 4px;cursor:pointer;color:var(--ug-icon-color);display:flex;align-items:center;opacity:0;transition:opacity .2s}.ug-header-menu-icon{padding-right:8px}.ug-header-cell:hover .ug-header-menu-icon,.ug-header-cell:hover .ug-header-filter-icon{opacity:1}.ug-header-divider{width:1px;height:50%;background-color:var(--ug-border-color);margin-right:2px}.ug-resize-handle{position:absolute;right:0;top:0;bottom:0;width:5px;cursor:col-resize;background-color:transparent;z-index:1}.ug-resize-handle:hover,.ug-resize-handle:active{background-color:var(--ug-primary-color)}.ug-hide-resizer{display:none!important}.cdk-drag-preview{box-sizing:border-box;background-color:var(--ug-header-bg);border:1px solid var(--ug-border-color);box-shadow:0 4px 6px -1px #0000001a;display:flex;align-items:center;padding:0 16px;font-weight:var(--ug-header-font-weight);color:var(--ug-header-color);font-size:var(--ug-font-size);font-family:var(--ug-font-family)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\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: 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.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: ColumnResizeDirective, selector: "[ugColumnResize]", inputs: ["ugColumnResize"], outputs: ["resizeEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
208
+ `, isInline: true, styles: ["ug-header{display:block;background-color:var(--ug-header-bg);border-bottom:1px solid var(--ug-border-color);position:sticky;top:0;z-index:10;color:var(--ug-header-color);font-weight:var(--ug-header-font-weight)}.ug-header-row{display:inline-flex;min-width:100%;height:48px}.ug-header-cell{display:flex;align-items:center;padding:0 0 0 16px;box-sizing:border-box;position:relative;-webkit-user-select:none;user-select:none;background-color:var(--ug-header-bg);transition:background-color .2s;flex-shrink:0;flex-grow:0}.ug-header-cell:hover{background-color:var(--ug-header-hover-bg)}.ug-pinned-left{position:sticky;z-index:2;border-right:1px solid var(--ug-border-color)}.ug-pinned-right{position:sticky;z-index:2;border-left:1px solid var(--ug-border-color)}.ug-header-checkbox{margin-right:12px;display:flex;align-items:center}.ug-header-checkbox input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--ug-primary-color)}.ug-header-cell-label{flex:1;display:flex;align-items:center;overflow:hidden;white-space:nowrap;height:100%}.ug-header-cell-label.sortable{cursor:pointer}.ug-header-cell-label span{overflow:hidden;text-overflow:ellipsis}.ug-sort-icon{margin-left:6px;display:flex;align-items:center;color:var(--ug-icon-color)}.ug-header-menu-icon,.ug-header-filter-icon{padding:0 4px;cursor:pointer;color:var(--ug-icon-color);display:flex;align-items:center;opacity:0;transition:opacity .2s}.ug-header-menu-icon{padding-right:8px}.ug-header-cell:hover .ug-header-menu-icon,.ug-header-cell:hover .ug-header-filter-icon{opacity:1}.ug-header-divider{width:1px;height:50%;background-color:var(--ug-border-color);margin-right:2px}.ug-resize-handle{position:absolute;right:0;top:0;bottom:0;width:5px;cursor:col-resize;background-color:transparent;z-index:1}.ug-resize-handle:hover,.ug-resize-handle:active{background-color:var(--ug-primary-color)}.ug-hide-resizer{display:none!important}.cdk-drag-preview{box-sizing:border-box;background-color:var(--ug-header-bg);border:1px solid var(--ug-border-color);box-shadow:0 4px 6px -1px #0000001a;display:flex;align-items:center;padding:0 16px;font-weight:var(--ug-header-font-weight);color:var(--ug-header-color);font-size:var(--ug-font-size);font-family:var(--ug-font-family)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\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: 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.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: ColumnResizeDirective, selector: "[ugColumnResize]", inputs: ["ugColumnResize"], outputs: ["resizeEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
208
209
  }
209
210
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: HeaderComponent, decorators: [{
210
211
  type: Component,
@@ -222,6 +223,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
222
223
  [class.ug-pinned-right]="col.pinned === 'right'"
223
224
  [style.left.px]="col._leftOffset"
224
225
  [style.right.px]="col._rightOffset"
226
+ [style.flex-grow]="isLast ? 1 : 0"
225
227
  >
226
228
  <div class="ug-header-checkbox" *ngIf="col.headerCheckboxSelection" (click)="onHeaderCheckboxClick($event)">
227
229
  <input type="checkbox" [checked]="isAllSelected" />
@@ -256,7 +258,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
256
258
  </div>
257
259
  </div>
258
260
  </div>
259
- `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: ["ug-header{display:block;background-color:var(--ug-header-bg);border-bottom:1px solid var(--ug-border-color);position:sticky;top:0;z-index:10;color:var(--ug-header-color);font-weight:var(--ug-header-font-weight)}.ug-header-row{display:inline-flex;min-width:100%;height:48px}.ug-header-cell{display:flex;align-items:center;padding:0 0 0 16px;box-sizing:border-box;position:relative;-webkit-user-select:none;user-select:none;background-color:var(--ug-header-bg);transition:background-color .2s;flex-shrink:0;flex-grow:1}.ug-header-cell:hover{background-color:var(--ug-header-hover-bg)}.ug-pinned-left{position:sticky;z-index:2;border-right:1px solid var(--ug-border-color)}.ug-pinned-right{position:sticky;z-index:2;border-left:1px solid var(--ug-border-color)}.ug-header-checkbox{margin-right:12px;display:flex;align-items:center}.ug-header-checkbox input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--ug-primary-color)}.ug-header-cell-label{flex:1;display:flex;align-items:center;overflow:hidden;white-space:nowrap;height:100%}.ug-header-cell-label.sortable{cursor:pointer}.ug-header-cell-label span{overflow:hidden;text-overflow:ellipsis}.ug-sort-icon{margin-left:6px;display:flex;align-items:center;color:var(--ug-icon-color)}.ug-header-menu-icon,.ug-header-filter-icon{padding:0 4px;cursor:pointer;color:var(--ug-icon-color);display:flex;align-items:center;opacity:0;transition:opacity .2s}.ug-header-menu-icon{padding-right:8px}.ug-header-cell:hover .ug-header-menu-icon,.ug-header-cell:hover .ug-header-filter-icon{opacity:1}.ug-header-divider{width:1px;height:50%;background-color:var(--ug-border-color);margin-right:2px}.ug-resize-handle{position:absolute;right:0;top:0;bottom:0;width:5px;cursor:col-resize;background-color:transparent;z-index:1}.ug-resize-handle:hover,.ug-resize-handle:active{background-color:var(--ug-primary-color)}.ug-hide-resizer{display:none!important}.cdk-drag-preview{box-sizing:border-box;background-color:var(--ug-header-bg);border:1px solid var(--ug-border-color);box-shadow:0 4px 6px -1px #0000001a;display:flex;align-items:center;padding:0 16px;font-weight:var(--ug-header-font-weight);color:var(--ug-header-color);font-size:var(--ug-font-size);font-family:var(--ug-font-family)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
261
+ `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: ["ug-header{display:block;background-color:var(--ug-header-bg);border-bottom:1px solid var(--ug-border-color);position:sticky;top:0;z-index:10;color:var(--ug-header-color);font-weight:var(--ug-header-font-weight)}.ug-header-row{display:inline-flex;min-width:100%;height:48px}.ug-header-cell{display:flex;align-items:center;padding:0 0 0 16px;box-sizing:border-box;position:relative;-webkit-user-select:none;user-select:none;background-color:var(--ug-header-bg);transition:background-color .2s;flex-shrink:0;flex-grow:0}.ug-header-cell:hover{background-color:var(--ug-header-hover-bg)}.ug-pinned-left{position:sticky;z-index:2;border-right:1px solid var(--ug-border-color)}.ug-pinned-right{position:sticky;z-index:2;border-left:1px solid var(--ug-border-color)}.ug-header-checkbox{margin-right:12px;display:flex;align-items:center}.ug-header-checkbox input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--ug-primary-color)}.ug-header-cell-label{flex:1;display:flex;align-items:center;overflow:hidden;white-space:nowrap;height:100%}.ug-header-cell-label.sortable{cursor:pointer}.ug-header-cell-label span{overflow:hidden;text-overflow:ellipsis}.ug-sort-icon{margin-left:6px;display:flex;align-items:center;color:var(--ug-icon-color)}.ug-header-menu-icon,.ug-header-filter-icon{padding:0 4px;cursor:pointer;color:var(--ug-icon-color);display:flex;align-items:center;opacity:0;transition:opacity .2s}.ug-header-menu-icon{padding-right:8px}.ug-header-cell:hover .ug-header-menu-icon,.ug-header-cell:hover .ug-header-filter-icon{opacity:1}.ug-header-divider{width:1px;height:50%;background-color:var(--ug-border-color);margin-right:2px}.ug-resize-handle{position:absolute;right:0;top:0;bottom:0;width:5px;cursor:col-resize;background-color:transparent;z-index:1}.ug-resize-handle:hover,.ug-resize-handle:active{background-color:var(--ug-primary-color)}.ug-hide-resizer{display:none!important}.cdk-drag-preview{box-sizing:border-box;background-color:var(--ug-header-bg);border:1px solid var(--ug-border-color);box-shadow:0 4px 6px -1px #0000001a;display:flex;align-items:center;padding:0 16px;font-weight:var(--ug-header-font-weight);color:var(--ug-header-color);font-size:var(--ug-font-size);font-family:var(--ug-font-family)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
260
262
  }], propDecorators: { columns: [{
261
263
  type: Input
262
264
  }], sortModel: [{
@@ -380,7 +382,7 @@ class CellComponent {
380
382
  </div>
381
383
  </ng-template>
382
384
  </div>
383
- `, isInline: true, styles: ["ug-cell{display:flex;align-items:center;padding:0 16px;overflow:hidden;text-overflow:ellipsis;flex-shrink:0;flex-grow:1;white-space:nowrap;box-sizing:border-box;height:100%}.ug-cell-wrapper{display:flex;align-items:center;width:100%;height:100%;overflow:hidden}.ug-cell-checkbox{margin-right:12px;display:flex;align-items:center}.ug-cell-checkbox input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--ug-primary-color)}.ug-cell-content{overflow:hidden;text-overflow:ellipsis;width:100%;display:flex;align-items:center;gap:6px}.ug-group-caret{cursor:pointer;display:flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:4px;color:var(--ug-text-color);opacity:.7;transition:opacity .2s}.ug-group-caret:hover{opacity:1}.ug-group-count{font-size:.85em;opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
385
+ `, isInline: true, styles: ["ug-cell{display:flex;align-items:center;padding:0 16px;overflow:hidden;text-overflow:ellipsis;flex-shrink:0;flex-grow:0;white-space:nowrap;box-sizing:border-box;height:100%}.ug-cell-wrapper{display:flex;align-items:center;width:100%;height:100%;overflow:hidden}.ug-cell-checkbox{margin-right:12px;display:flex;align-items:center}.ug-cell-checkbox input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--ug-primary-color)}.ug-cell-content{overflow:hidden;text-overflow:ellipsis;width:100%;display:flex;align-items:center;gap:6px}.ug-group-caret{cursor:pointer;display:flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:4px;color:var(--ug-text-color);opacity:.7;transition:opacity .2s}.ug-group-caret:hover{opacity:1}.ug-group-count{font-size:.85em;opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
384
386
  }
385
387
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: CellComponent, decorators: [{
386
388
  type: Component,
@@ -420,7 +422,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
420
422
  </div>
421
423
  </ng-template>
422
424
  </div>
423
- `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: ["ug-cell{display:flex;align-items:center;padding:0 16px;overflow:hidden;text-overflow:ellipsis;flex-shrink:0;flex-grow:1;white-space:nowrap;box-sizing:border-box;height:100%}.ug-cell-wrapper{display:flex;align-items:center;width:100%;height:100%;overflow:hidden}.ug-cell-checkbox{margin-right:12px;display:flex;align-items:center}.ug-cell-checkbox input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--ug-primary-color)}.ug-cell-content{overflow:hidden;text-overflow:ellipsis;width:100%;display:flex;align-items:center;gap:6px}.ug-group-caret{cursor:pointer;display:flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:4px;color:var(--ug-text-color);opacity:.7;transition:opacity .2s}.ug-group-caret:hover{opacity:1}.ug-group-count{font-size:.85em;opacity:.6}\n"] }]
425
+ `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: ["ug-cell{display:flex;align-items:center;padding:0 16px;overflow:hidden;text-overflow:ellipsis;flex-shrink:0;flex-grow:0;white-space:nowrap;box-sizing:border-box;height:100%}.ug-cell-wrapper{display:flex;align-items:center;width:100%;height:100%;overflow:hidden}.ug-cell-checkbox{margin-right:12px;display:flex;align-items:center}.ug-cell-checkbox input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--ug-primary-color)}.ug-cell-content{overflow:hidden;text-overflow:ellipsis;width:100%;display:flex;align-items:center;gap:6px}.ug-group-caret{cursor:pointer;display:flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:4px;color:var(--ug-text-color);opacity:.7;transition:opacity .2s}.ug-group-caret:hover{opacity:1}.ug-group-count{font-size:.85em;opacity:.6}\n"] }]
424
426
  }], propDecorators: { column: [{
425
427
  type: Input
426
428
  }], row: [{
@@ -461,7 +463,7 @@ class RowComponent {
461
463
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: RowComponent, isStandalone: true, selector: "ug-row", inputs: { columns: "columns", row: "row", rowHeight: "rowHeight", isExpanded: "isExpanded", selectionVersion: "selectionVersion" }, outputs: { groupToggled: "groupToggled" }, host: { properties: { "class.ug-row-selected": "this.isSelected", "class.ug-row-group-footer": "this.isGroupFooter", "style.height.px": "this.height" } }, ngImport: i0, template: `
462
464
  <div class="ug-row-cells">
463
465
  <ug-cell
464
- *ngFor="let col of columns; let isFirst = first; trackBy: trackByField"
466
+ *ngFor="let col of columns; let isFirst = first; let isLast = last; trackBy: trackByField"
465
467
  [column]="col"
466
468
  [row]="row"
467
469
  [isSelected]="$any(row)?.selected"
@@ -475,7 +477,8 @@ class RowComponent {
475
477
  [class.ug-pinned-left]="col.pinned === 'left'"
476
478
  [class.ug-pinned-right]="col.pinned === 'right'"
477
479
  [style.left.px]="col._leftOffset"
478
- [style.right.px]="col._rightOffset">
480
+ [style.right.px]="col._rightOffset"
481
+ [style.flex-grow]="isLast ? 1 : 0">
479
482
  </ug-cell>
480
483
  </div>
481
484
  `, isInline: true, styles: ["ug-row{display:inline-flex;min-width:100%;border-bottom:1px solid var(--ug-border-color);background-color:var(--ug-row-bg);box-sizing:border-box;transition:background-color .2s}ug-row:hover{background-color:var(--ug-row-hover-bg)}ug-row.ug-row-selected{background-color:var(--ug-row-selected-bg)}ug-row.ug-row-group-footer{background-color:var(--ug-group-footer-bg, #f8f9fa);font-weight:600;border-top:1px solid var(--ug-border-color);border-bottom:2px solid var(--ug-border-color)}ug-row.ug-row-group-footer:hover{background-color:var(--ug-group-footer-bg, #f8f9fa)}.ug-row-cells{display:flex;width:100%;height:100%}.ug-cell-hide{display:none!important}ug-cell.ug-pinned-left{position:sticky;z-index:1;border-right:1px solid var(--ug-border-color);background-color:inherit}ug-cell.ug-pinned-right{position:sticky;z-index:1;border-left:1px solid var(--ug-border-color);background-color:inherit}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: CellComponent, selector: "ug-cell", inputs: ["column", "row", "isSelected", "isFirstColumn", "groupExpanded"], outputs: ["groupToggleClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
@@ -485,7 +488,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
485
488
  args: [{ selector: 'ug-row', standalone: true, imports: [CommonModule, CellComponent], template: `
486
489
  <div class="ug-row-cells">
487
490
  <ug-cell
488
- *ngFor="let col of columns; let isFirst = first; trackBy: trackByField"
491
+ *ngFor="let col of columns; let isFirst = first; let isLast = last; trackBy: trackByField"
489
492
  [column]="col"
490
493
  [row]="row"
491
494
  [isSelected]="$any(row)?.selected"
@@ -499,7 +502,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
499
502
  [class.ug-pinned-left]="col.pinned === 'left'"
500
503
  [class.ug-pinned-right]="col.pinned === 'right'"
501
504
  [style.left.px]="col._leftOffset"
502
- [style.right.px]="col._rightOffset">
505
+ [style.right.px]="col._rightOffset"
506
+ [style.flex-grow]="isLast ? 1 : 0">
503
507
  </ug-cell>
504
508
  </div>
505
509
  `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: ["ug-row{display:inline-flex;min-width:100%;border-bottom:1px solid var(--ug-border-color);background-color:var(--ug-row-bg);box-sizing:border-box;transition:background-color .2s}ug-row:hover{background-color:var(--ug-row-hover-bg)}ug-row.ug-row-selected{background-color:var(--ug-row-selected-bg)}ug-row.ug-row-group-footer{background-color:var(--ug-group-footer-bg, #f8f9fa);font-weight:600;border-top:1px solid var(--ug-border-color);border-bottom:2px solid var(--ug-border-color)}ug-row.ug-row-group-footer:hover{background-color:var(--ug-group-footer-bg, #f8f9fa)}.ug-row-cells{display:flex;width:100%;height:100%}.ug-cell-hide{display:none!important}ug-cell.ug-pinned-left{position:sticky;z-index:1;border-right:1px solid var(--ug-border-color);background-color:inherit}ug-cell.ug-pinned-right{position:sticky;z-index:1;border-left:1px solid var(--ug-border-color);background-color:inherit}\n"] }]
@@ -1653,11 +1657,12 @@ class FilterToolPanelComponent {
1653
1657
  rowData = [];
1654
1658
  activeFilters = new Map();
1655
1659
  conditionFilters = new Map();
1660
+ savedReportNames = [];
1656
1661
  filterApplied = new EventEmitter();
1657
1662
  conditionFilterChanged = new EventEmitter();
1658
1663
  clearAllFilters = new EventEmitter();
1659
- saveFiltersRequested = new EventEmitter();
1660
- filtersImported = new EventEmitter();
1664
+ saveReportRequested = new EventEmitter();
1665
+ loadReportRequested = new EventEmitter();
1661
1666
  sections = [];
1662
1667
  _loadedFields = new Set();
1663
1668
  constructor(cdr) {
@@ -1924,27 +1929,22 @@ class FilterToolPanelComponent {
1924
1929
  trackByField(index, section) {
1925
1930
  return section.column.field;
1926
1931
  }
1927
- onFileSelected(event) {
1928
- const file = event.target.files?.[0];
1929
- if (!file)
1930
- return;
1931
- const reader = new FileReader();
1932
- reader.onload = (e) => {
1933
- try {
1934
- const json = JSON.parse(e.target?.result);
1935
- this.filtersImported.emit(json);
1936
- // Reset input so importing same file again triggers change
1937
- event.target.value = '';
1938
- }
1939
- catch (err) {
1940
- console.error('Failed to parse filter JSON:', err);
1941
- alert('Invalid filter file format.');
1942
- }
1943
- };
1944
- reader.readAsText(file);
1932
+ onSaveReportPrompt() {
1933
+ const name = prompt('Enter a name for this report:');
1934
+ if (name && name.trim()) {
1935
+ this.saveReportRequested.emit(name.trim());
1936
+ }
1937
+ }
1938
+ onLoadReportSelected(event) {
1939
+ const select = event.target;
1940
+ const name = select.value;
1941
+ if (name) {
1942
+ this.loadReportRequested.emit(name);
1943
+ select.value = ''; // Reset so it can be re-selected if needed
1944
+ }
1945
1945
  }
1946
1946
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: FilterToolPanelComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1947
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: FilterToolPanelComponent, isStandalone: true, selector: "ug-filter-tool-panel", inputs: { columns: "columns", rowData: "rowData", activeFilters: "activeFilters", conditionFilters: "conditionFilters" }, outputs: { filterApplied: "filterApplied", conditionFilterChanged: "conditionFilterChanged", clearAllFilters: "clearAllFilters", saveFiltersRequested: "saveFiltersRequested", filtersImported: "filtersImported" }, usesOnChanges: true, ngImport: i0, template: `
1947
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: FilterToolPanelComponent, isStandalone: true, selector: "ug-filter-tool-panel", inputs: { columns: "columns", rowData: "rowData", activeFilters: "activeFilters", conditionFilters: "conditionFilters", savedReportNames: "savedReportNames" }, outputs: { filterApplied: "filterApplied", conditionFilterChanged: "conditionFilterChanged", clearAllFilters: "clearAllFilters", saveReportRequested: "saveReportRequested", loadReportRequested: "loadReportRequested" }, usesOnChanges: true, ngImport: i0, template: `
1948
1948
  <div class="ug-ftp-wrapper">
1949
1949
  <!-- Global Toolbar -->
1950
1950
  <div class="ug-ftp-toolbar">
@@ -1963,15 +1963,15 @@ class FilterToolPanelComponent {
1963
1963
 
1964
1964
  <div style="flex: 1"></div>
1965
1965
 
1966
- <button class="ug-ftp-btn" (click)="saveFiltersRequested.emit()" title="Save Filters to JSON">
1966
+ <button class="ug-ftp-btn" (click)="onSaveReportPrompt()" title="Save Filters as Report">
1967
1967
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path><polyline points="17 21 17 13 7 13 7 21"></polyline><polyline points="7 3 7 8 15 8"></polyline></svg>
1968
1968
  Save
1969
1969
  </button>
1970
- <button class="ug-ftp-btn" (click)="fileInput.click()" title="Import Filters from JSON">
1971
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
1972
- Import
1973
- </button>
1974
- <input #fileInput type="file" accept=".json" style="display: none" (change)="onFileSelected($event)">
1970
+
1971
+ <select class="ug-ftp-toolbar-select" (change)="onLoadReportSelected($event)" title="Load Saved Report">
1972
+ <option value="" disabled selected>Load</option>
1973
+ <option *ngFor="let name of savedReportNames" [value]="name">{{ name }}</option>
1974
+ </select>
1975
1975
  </div>
1976
1976
 
1977
1977
  <!-- Column Filter Sections -->
@@ -2068,7 +2068,7 @@ class FilterToolPanelComponent {
2068
2068
  </div>
2069
2069
  </div>
2070
2070
  </div>
2071
- `, isInline: true, styles: [".ug-ftp-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-header-color, #181d1f)}.ug-ftp-toolbar{display:flex;align-items:center;gap:4px;padding:8px 10px;border-bottom:1px solid var(--ug-border-color);background-color:var(--ug-header-bg);flex-wrap:wrap}.ug-ftp-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color);color:var(--ug-header-color);font-family:inherit;font-size:11px;cursor:pointer;transition:all .15s ease;white-space:nowrap}.ug-ftp-btn:hover{background:var(--ug-row-hover-bg);border-color:var(--ug-primary-color);color:var(--ug-primary-color)}.ug-ftp-btn:disabled{opacity:.4;cursor:default;pointer-events:none}.ug-ftp-btn-clear{margin-left:auto}.ug-ftp-sections{flex:1;overflow-y:auto;overflow-x:hidden}.ug-ftp-section{border-bottom:1px solid var(--ug-border-color)}.ug-ftp-section-header{display:flex;align-items:center;padding:10px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;gap:8px;background-color:var(--ug-bg-color);transition:background-color .15s}.ug-ftp-section-header:hover{background-color:var(--ug-row-hover-bg)}.ug-ftp-section-header.active-filter{font-weight:600}.ug-ftp-caret{transition:transform .2s ease;color:var(--ug-icon-color);flex-shrink:0}.ug-ftp-caret.expanded{transform:rotate(90deg)}.ug-ftp-section-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ug-ftp-active-dot{width:8px;height:8px;border-radius:50%;background-color:var(--ug-primary-color);flex-shrink:0}.ug-ftp-section-body{padding:0 12px 12px;background-color:var(--ug-bg-color)}.ug-ftp-condition-block{display:flex;flex-direction:column;gap:6px;margin-bottom:10px;padding:10px;border:1px solid var(--ug-border-color);border-radius:4px;background:var(--ug-header-bg)}.ug-ftp-cond-select{width:100%;padding:5px 8px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, sans-serif);font-size:12px;background-color:var(--ug-bg-color);color:var(--ug-header-color);cursor:pointer;box-sizing:border-box}.ug-ftp-cond-select:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-cond-input{width:100%;padding:5px 8px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, sans-serif);font-size:12px;background-color:var(--ug-bg-color);color:var(--ug-header-color);box-sizing:border-box}.ug-ftp-cond-input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-operator-row{display:flex;align-items:center;gap:16px;padding:4px 0}.ug-ftp-radio{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;cursor:pointer;color:var(--ug-header-color)}.ug-ftp-radio input[type=radio]{accent-color:var(--ug-primary-color);cursor:pointer}.ug-ftp-search{position:relative;display:flex;align-items:center;margin-bottom:8px}.ug-ftp-search svg{position:absolute;left:8px;color:var(--ug-icon-color);pointer-events:none}.ug-ftp-search input{width:100%;padding:5px 8px 5px 26px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, inherit);font-size:var(--ug-font-size, 12px);background-color:var(--ug-bg-color);color:var(--ug-header-color);box-sizing:border-box}.ug-ftp-search input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-values{border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color)}.ug-ftp-viewport{height:200px}.ug-ftp-item{display:flex;align-items:center;gap:8px;padding:4px 8px;cursor:pointer;font-size:12px;transition:background-color .1s}.ug-ftp-item:hover{background-color:var(--ug-row-hover-bg)}.ug-ftp-item input[type=checkbox]{accent-color:var(--ug-primary-color);cursor:pointer;width:14px;height:14px;flex-shrink:0}.ug-ftp-item span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ug-ftp-select-all{border-bottom:1px solid var(--ug-border-color);font-weight:500;padding:6px 8px}.ug-ftp-empty{padding:16px;text-align:center;color:var(--ug-icon-color);font-style:italic;font-size:12px}\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.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { 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: 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2071
+ `, isInline: true, styles: [".ug-ftp-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-header-color, #181d1f)}.ug-ftp-toolbar{display:flex;align-items:center;gap:4px;padding:8px 10px;border-bottom:1px solid var(--ug-border-color);background-color:var(--ug-header-bg);flex-wrap:wrap}.ug-ftp-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color);color:var(--ug-header-color);font-family:inherit;font-size:11px;cursor:pointer;transition:all .15s ease;white-space:nowrap}.ug-ftp-btn:hover{background:var(--ug-row-hover-bg);border-color:var(--ug-primary-color);color:var(--ug-primary-color)}.ug-ftp-btn:disabled{opacity:.4;cursor:default;pointer-events:none}.ug-ftp-btn-clear{margin-left:auto}.ug-ftp-toolbar-select{padding:3px 6px;border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color);color:var(--ug-header-color);font-family:inherit;font-size:11px;cursor:pointer;outline:none;transition:all .15s ease;max-width:120px}.ug-ftp-toolbar-select:hover{border-color:var(--ug-primary-color)}.ug-ftp-sections{flex:1;overflow-y:auto;overflow-x:hidden}.ug-ftp-section{border-bottom:1px solid var(--ug-border-color)}.ug-ftp-section-header{display:flex;align-items:center;padding:10px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;gap:8px;background-color:var(--ug-bg-color);transition:background-color .15s}.ug-ftp-section-header:hover{background-color:var(--ug-row-hover-bg)}.ug-ftp-section-header.active-filter{font-weight:600}.ug-ftp-caret{transition:transform .2s ease;color:var(--ug-icon-color);flex-shrink:0}.ug-ftp-caret.expanded{transform:rotate(90deg)}.ug-ftp-section-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ug-ftp-active-dot{width:8px;height:8px;border-radius:50%;background-color:var(--ug-primary-color);flex-shrink:0}.ug-ftp-section-body{padding:0 12px 12px;background-color:var(--ug-bg-color)}.ug-ftp-condition-block{display:flex;flex-direction:column;gap:6px;margin-bottom:10px;padding:10px;border:1px solid var(--ug-border-color);border-radius:4px;background:var(--ug-header-bg)}.ug-ftp-cond-select{width:100%;padding:5px 8px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, sans-serif);font-size:12px;background-color:var(--ug-bg-color);color:var(--ug-header-color);cursor:pointer;box-sizing:border-box}.ug-ftp-cond-select:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-cond-input{width:100%;padding:5px 8px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, sans-serif);font-size:12px;background-color:var(--ug-bg-color);color:var(--ug-header-color);box-sizing:border-box}.ug-ftp-cond-input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-operator-row{display:flex;align-items:center;gap:16px;padding:4px 0}.ug-ftp-radio{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;cursor:pointer;color:var(--ug-header-color)}.ug-ftp-radio input[type=radio]{accent-color:var(--ug-primary-color);cursor:pointer}.ug-ftp-search{position:relative;display:flex;align-items:center;margin-bottom:8px}.ug-ftp-search svg{position:absolute;left:8px;color:var(--ug-icon-color);pointer-events:none}.ug-ftp-search input{width:100%;padding:5px 8px 5px 26px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, inherit);font-size:var(--ug-font-size, 12px);background-color:var(--ug-bg-color);color:var(--ug-header-color);box-sizing:border-box}.ug-ftp-search input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-values{border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color)}.ug-ftp-viewport{height:200px}.ug-ftp-item{display:flex;align-items:center;gap:8px;padding:4px 8px;cursor:pointer;font-size:12px;transition:background-color .1s}.ug-ftp-item:hover{background-color:var(--ug-row-hover-bg)}.ug-ftp-item input[type=checkbox]{accent-color:var(--ug-primary-color);cursor:pointer;width:14px;height:14px;flex-shrink:0}.ug-ftp-item span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ug-ftp-select-all{border-bottom:1px solid var(--ug-border-color);font-weight:500;padding:6px 8px}.ug-ftp-empty{padding:16px;text-align:center;color:var(--ug-icon-color);font-style:italic;font-size:12px}\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.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { 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: 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2072
2072
  }
2073
2073
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: FilterToolPanelComponent, decorators: [{
2074
2074
  type: Component,
@@ -2091,15 +2091,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
2091
2091
 
2092
2092
  <div style="flex: 1"></div>
2093
2093
 
2094
- <button class="ug-ftp-btn" (click)="saveFiltersRequested.emit()" title="Save Filters to JSON">
2094
+ <button class="ug-ftp-btn" (click)="onSaveReportPrompt()" title="Save Filters as Report">
2095
2095
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path><polyline points="17 21 17 13 7 13 7 21"></polyline><polyline points="7 3 7 8 15 8"></polyline></svg>
2096
2096
  Save
2097
2097
  </button>
2098
- <button class="ug-ftp-btn" (click)="fileInput.click()" title="Import Filters from JSON">
2099
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
2100
- Import
2101
- </button>
2102
- <input #fileInput type="file" accept=".json" style="display: none" (change)="onFileSelected($event)">
2098
+
2099
+ <select class="ug-ftp-toolbar-select" (change)="onLoadReportSelected($event)" title="Load Saved Report">
2100
+ <option value="" disabled selected>Load</option>
2101
+ <option *ngFor="let name of savedReportNames" [value]="name">{{ name }}</option>
2102
+ </select>
2103
2103
  </div>
2104
2104
 
2105
2105
  <!-- Column Filter Sections -->
@@ -2196,7 +2196,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
2196
2196
  </div>
2197
2197
  </div>
2198
2198
  </div>
2199
- `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [".ug-ftp-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-header-color, #181d1f)}.ug-ftp-toolbar{display:flex;align-items:center;gap:4px;padding:8px 10px;border-bottom:1px solid var(--ug-border-color);background-color:var(--ug-header-bg);flex-wrap:wrap}.ug-ftp-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color);color:var(--ug-header-color);font-family:inherit;font-size:11px;cursor:pointer;transition:all .15s ease;white-space:nowrap}.ug-ftp-btn:hover{background:var(--ug-row-hover-bg);border-color:var(--ug-primary-color);color:var(--ug-primary-color)}.ug-ftp-btn:disabled{opacity:.4;cursor:default;pointer-events:none}.ug-ftp-btn-clear{margin-left:auto}.ug-ftp-sections{flex:1;overflow-y:auto;overflow-x:hidden}.ug-ftp-section{border-bottom:1px solid var(--ug-border-color)}.ug-ftp-section-header{display:flex;align-items:center;padding:10px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;gap:8px;background-color:var(--ug-bg-color);transition:background-color .15s}.ug-ftp-section-header:hover{background-color:var(--ug-row-hover-bg)}.ug-ftp-section-header.active-filter{font-weight:600}.ug-ftp-caret{transition:transform .2s ease;color:var(--ug-icon-color);flex-shrink:0}.ug-ftp-caret.expanded{transform:rotate(90deg)}.ug-ftp-section-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ug-ftp-active-dot{width:8px;height:8px;border-radius:50%;background-color:var(--ug-primary-color);flex-shrink:0}.ug-ftp-section-body{padding:0 12px 12px;background-color:var(--ug-bg-color)}.ug-ftp-condition-block{display:flex;flex-direction:column;gap:6px;margin-bottom:10px;padding:10px;border:1px solid var(--ug-border-color);border-radius:4px;background:var(--ug-header-bg)}.ug-ftp-cond-select{width:100%;padding:5px 8px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, sans-serif);font-size:12px;background-color:var(--ug-bg-color);color:var(--ug-header-color);cursor:pointer;box-sizing:border-box}.ug-ftp-cond-select:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-cond-input{width:100%;padding:5px 8px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, sans-serif);font-size:12px;background-color:var(--ug-bg-color);color:var(--ug-header-color);box-sizing:border-box}.ug-ftp-cond-input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-operator-row{display:flex;align-items:center;gap:16px;padding:4px 0}.ug-ftp-radio{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;cursor:pointer;color:var(--ug-header-color)}.ug-ftp-radio input[type=radio]{accent-color:var(--ug-primary-color);cursor:pointer}.ug-ftp-search{position:relative;display:flex;align-items:center;margin-bottom:8px}.ug-ftp-search svg{position:absolute;left:8px;color:var(--ug-icon-color);pointer-events:none}.ug-ftp-search input{width:100%;padding:5px 8px 5px 26px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, inherit);font-size:var(--ug-font-size, 12px);background-color:var(--ug-bg-color);color:var(--ug-header-color);box-sizing:border-box}.ug-ftp-search input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-values{border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color)}.ug-ftp-viewport{height:200px}.ug-ftp-item{display:flex;align-items:center;gap:8px;padding:4px 8px;cursor:pointer;font-size:12px;transition:background-color .1s}.ug-ftp-item:hover{background-color:var(--ug-row-hover-bg)}.ug-ftp-item input[type=checkbox]{accent-color:var(--ug-primary-color);cursor:pointer;width:14px;height:14px;flex-shrink:0}.ug-ftp-item span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ug-ftp-select-all{border-bottom:1px solid var(--ug-border-color);font-weight:500;padding:6px 8px}.ug-ftp-empty{padding:16px;text-align:center;color:var(--ug-icon-color);font-style:italic;font-size:12px}\n"] }]
2199
+ `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [".ug-ftp-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-header-color, #181d1f)}.ug-ftp-toolbar{display:flex;align-items:center;gap:4px;padding:8px 10px;border-bottom:1px solid var(--ug-border-color);background-color:var(--ug-header-bg);flex-wrap:wrap}.ug-ftp-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color);color:var(--ug-header-color);font-family:inherit;font-size:11px;cursor:pointer;transition:all .15s ease;white-space:nowrap}.ug-ftp-btn:hover{background:var(--ug-row-hover-bg);border-color:var(--ug-primary-color);color:var(--ug-primary-color)}.ug-ftp-btn:disabled{opacity:.4;cursor:default;pointer-events:none}.ug-ftp-btn-clear{margin-left:auto}.ug-ftp-toolbar-select{padding:3px 6px;border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color);color:var(--ug-header-color);font-family:inherit;font-size:11px;cursor:pointer;outline:none;transition:all .15s ease;max-width:120px}.ug-ftp-toolbar-select:hover{border-color:var(--ug-primary-color)}.ug-ftp-sections{flex:1;overflow-y:auto;overflow-x:hidden}.ug-ftp-section{border-bottom:1px solid var(--ug-border-color)}.ug-ftp-section-header{display:flex;align-items:center;padding:10px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;gap:8px;background-color:var(--ug-bg-color);transition:background-color .15s}.ug-ftp-section-header:hover{background-color:var(--ug-row-hover-bg)}.ug-ftp-section-header.active-filter{font-weight:600}.ug-ftp-caret{transition:transform .2s ease;color:var(--ug-icon-color);flex-shrink:0}.ug-ftp-caret.expanded{transform:rotate(90deg)}.ug-ftp-section-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ug-ftp-active-dot{width:8px;height:8px;border-radius:50%;background-color:var(--ug-primary-color);flex-shrink:0}.ug-ftp-section-body{padding:0 12px 12px;background-color:var(--ug-bg-color)}.ug-ftp-condition-block{display:flex;flex-direction:column;gap:6px;margin-bottom:10px;padding:10px;border:1px solid var(--ug-border-color);border-radius:4px;background:var(--ug-header-bg)}.ug-ftp-cond-select{width:100%;padding:5px 8px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, sans-serif);font-size:12px;background-color:var(--ug-bg-color);color:var(--ug-header-color);cursor:pointer;box-sizing:border-box}.ug-ftp-cond-select:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-cond-input{width:100%;padding:5px 8px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, sans-serif);font-size:12px;background-color:var(--ug-bg-color);color:var(--ug-header-color);box-sizing:border-box}.ug-ftp-cond-input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-operator-row{display:flex;align-items:center;gap:16px;padding:4px 0}.ug-ftp-radio{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;cursor:pointer;color:var(--ug-header-color)}.ug-ftp-radio input[type=radio]{accent-color:var(--ug-primary-color);cursor:pointer}.ug-ftp-search{position:relative;display:flex;align-items:center;margin-bottom:8px}.ug-ftp-search svg{position:absolute;left:8px;color:var(--ug-icon-color);pointer-events:none}.ug-ftp-search input{width:100%;padding:5px 8px 5px 26px;border:1px solid var(--ug-border-color);border-radius:3px;font-family:var(--ug-font-family, inherit);font-size:var(--ug-font-size, 12px);background-color:var(--ug-bg-color);color:var(--ug-header-color);box-sizing:border-box}.ug-ftp-search input:focus{outline:none;border-color:var(--ug-primary-color)}.ug-ftp-values{border:1px solid var(--ug-border-color);border-radius:3px;background:var(--ug-bg-color)}.ug-ftp-viewport{height:200px}.ug-ftp-item{display:flex;align-items:center;gap:8px;padding:4px 8px;cursor:pointer;font-size:12px;transition:background-color .1s}.ug-ftp-item:hover{background-color:var(--ug-row-hover-bg)}.ug-ftp-item input[type=checkbox]{accent-color:var(--ug-primary-color);cursor:pointer;width:14px;height:14px;flex-shrink:0}.ug-ftp-item span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ug-ftp-select-all{border-bottom:1px solid var(--ug-border-color);font-weight:500;padding:6px 8px}.ug-ftp-empty{padding:16px;text-align:center;color:var(--ug-icon-color);font-style:italic;font-size:12px}\n"] }]
2200
2200
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { columns: [{
2201
2201
  type: Input
2202
2202
  }], rowData: [{
@@ -2205,15 +2205,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
2205
2205
  type: Input
2206
2206
  }], conditionFilters: [{
2207
2207
  type: Input
2208
+ }], savedReportNames: [{
2209
+ type: Input
2208
2210
  }], filterApplied: [{
2209
2211
  type: Output
2210
2212
  }], conditionFilterChanged: [{
2211
2213
  type: Output
2212
2214
  }], clearAllFilters: [{
2213
2215
  type: Output
2214
- }], saveFiltersRequested: [{
2216
+ }], saveReportRequested: [{
2215
2217
  type: Output
2216
- }], filtersImported: [{
2218
+ }], loadReportRequested: [{
2217
2219
  type: Output
2218
2220
  }] } });
2219
2221
 
@@ -2226,6 +2228,7 @@ class SideBarComponent {
2226
2228
  valuesModel = [];
2227
2229
  pivotMode = false;
2228
2230
  pivotColumns = [];
2231
+ savedReportNames = [];
2229
2232
  columnsUpdated = new EventEmitter();
2230
2233
  groupModelUpdated = new EventEmitter();
2231
2234
  valuesModelUpdated = new EventEmitter();
@@ -2235,8 +2238,8 @@ class SideBarComponent {
2235
2238
  filterApplied = new EventEmitter();
2236
2239
  conditionFilterChanged = new EventEmitter();
2237
2240
  clearAllFilters = new EventEmitter();
2238
- saveFiltersRequested = new EventEmitter();
2239
- filtersImported = new EventEmitter();
2241
+ saveReportRequested = new EventEmitter();
2242
+ loadReportRequested = new EventEmitter();
2240
2243
  activeTab = 'columns'; // Open by default for demo parity
2241
2244
  cdr = inject(ChangeDetectorRef);
2242
2245
  toggleTab(tab) {
@@ -2281,7 +2284,7 @@ class SideBarComponent {
2281
2284
  this.pivotModelUpdated.emit(model);
2282
2285
  }
2283
2286
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SideBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2284
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: SideBarComponent, isStandalone: true, selector: "ug-side-bar", inputs: { columns: "columns", rowData: "rowData", activeFilters: "activeFilters", conditionFilters: "conditionFilters", groupModel: "groupModel", valuesModel: "valuesModel", pivotMode: "pivotMode", pivotColumns: "pivotColumns" }, outputs: { columnsUpdated: "columnsUpdated", groupModelUpdated: "groupModelUpdated", valuesModelUpdated: "valuesModelUpdated", pivotModeUpdated: "pivotModeUpdated", pivotModelUpdated: "pivotModelUpdated", exportExcelClicked: "exportExcelClicked", filterApplied: "filterApplied", conditionFilterChanged: "conditionFilterChanged", clearAllFilters: "clearAllFilters", saveFiltersRequested: "saveFiltersRequested", filtersImported: "filtersImported" }, ngImport: i0, template: `
2287
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: SideBarComponent, isStandalone: true, selector: "ug-side-bar", inputs: { columns: "columns", rowData: "rowData", activeFilters: "activeFilters", conditionFilters: "conditionFilters", groupModel: "groupModel", valuesModel: "valuesModel", pivotMode: "pivotMode", pivotColumns: "pivotColumns", savedReportNames: "savedReportNames" }, outputs: { columnsUpdated: "columnsUpdated", groupModelUpdated: "groupModelUpdated", valuesModelUpdated: "valuesModelUpdated", pivotModeUpdated: "pivotModeUpdated", pivotModelUpdated: "pivotModelUpdated", exportExcelClicked: "exportExcelClicked", filterApplied: "filterApplied", conditionFilterChanged: "conditionFilterChanged", clearAllFilters: "clearAllFilters", saveReportRequested: "saveReportRequested", loadReportRequested: "loadReportRequested" }, ngImport: i0, template: `
2285
2288
  <div class="ug-side-bar-wrapper">
2286
2289
  <!-- Content Area -->
2287
2290
  <div class="ug-side-bar-content" *ngIf="activeTab">
@@ -2314,11 +2317,12 @@ class SideBarComponent {
2314
2317
  [rowData]="rowData"
2315
2318
  [activeFilters]="activeFilters"
2316
2319
  [conditionFilters]="conditionFilters"
2320
+ [savedReportNames]="savedReportNames"
2317
2321
  (filterApplied)="onFilterApplied($event)"
2318
2322
  (conditionFilterChanged)="onConditionFilterChanged($event)"
2319
2323
  (clearAllFilters)="onClearAllFilters()"
2320
- (saveFiltersRequested)="saveFiltersRequested.emit()"
2321
- (filtersImported)="filtersImported.emit($event)">
2324
+ (saveReportRequested)="saveReportRequested.emit($event)"
2325
+ (loadReportRequested)="loadReportRequested.emit($event)">
2322
2326
  </ug-filter-tool-panel>
2323
2327
  </div>
2324
2328
  </div>
@@ -2340,7 +2344,7 @@ class SideBarComponent {
2340
2344
  </div>
2341
2345
  </div>
2342
2346
  </div>
2343
- `, isInline: true, styles: [".ug-side-bar-wrapper{display:flex;flex-direction:row;height:100%;background-color:var(--ug-panel-bg);border-left:1px solid var(--ug-border-color);font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px);color:var(--ug-header-color)}.ug-side-bar-content{display:flex;flex-direction:column;width:250px;height:100%;border-right:1px solid var(--ug-border-color)}.ug-side-bar-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--ug-border-color);background-color:var(--ug-header-bg)}.ug-side-bar-title{font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px);font-weight:var(--ug-header-font-weight, 500);color:var(--ug-header-color)}.ug-side-bar-close{cursor:pointer;color:var(--ug-icon-color);display:flex;align-items:center;justify-content:center}.ug-side-bar-close:hover{color:var(--ug-primary-color)}.ug-side-bar-body{flex:1;overflow-y:auto;overflow-x:hidden;background-color:var(--ug-panel-bg)}.ug-side-bar-toolbar{display:flex;flex-direction:column;width:40px;height:100%;background-color:var(--ug-header-bg);padding-top:8px;gap:8px;align-items:center}.ug-side-bar-tab{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:8px 4px;cursor:pointer;color:var(--ug-icon-color);border-left:2px solid transparent;width:100%;box-sizing:border-box}.ug-side-bar-tab span{writing-mode:vertical-rl;transform:rotate(180deg);margin-top:12px;font-family:var(--ug-font-family, sans-serif);font-weight:var(--ug-header-font-weight, 500);font-size:var(--ug-font-size, 13px);letter-spacing:.5px}.ug-side-bar-tab:hover{color:var(--ug-primary-color);background-color:var(--ug-row-hover-bg)}.ug-side-bar-tab.active{color:var(--ug-primary-color);background-color:var(--ug-panel-bg);border-left:2px solid var(--ug-primary-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ColumnToolPanelComponent, selector: "ug-column-tool-panel", inputs: ["columns", "groupModel", "valuesModel", "pivotMode", "pivotColumns"], outputs: ["columnsUpdated", "groupModelChanged", "valuesModelChanged", "pivotModeChanged", "pivotModelChanged", "exportExcelClicked"] }, { kind: "component", type: FilterToolPanelComponent, selector: "ug-filter-tool-panel", inputs: ["columns", "rowData", "activeFilters", "conditionFilters"], outputs: ["filterApplied", "conditionFilterChanged", "clearAllFilters", "saveFiltersRequested", "filtersImported"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2347
+ `, isInline: true, styles: [".ug-side-bar-wrapper{display:flex;flex-direction:row;height:100%;background-color:var(--ug-panel-bg);border-left:1px solid var(--ug-border-color);font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px);color:var(--ug-header-color)}.ug-side-bar-content{display:flex;flex-direction:column;width:250px;height:100%;border-right:1px solid var(--ug-border-color)}.ug-side-bar-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--ug-border-color);background-color:var(--ug-header-bg)}.ug-side-bar-title{font-family:var(--ug-font-family, sans-serif);font-size:var(--ug-font-size, 13px);font-weight:var(--ug-header-font-weight, 500);color:var(--ug-header-color)}.ug-side-bar-close{cursor:pointer;color:var(--ug-icon-color);display:flex;align-items:center;justify-content:center}.ug-side-bar-close:hover{color:var(--ug-primary-color)}.ug-side-bar-body{flex:1;overflow-y:auto;overflow-x:hidden;background-color:var(--ug-panel-bg)}.ug-side-bar-toolbar{display:flex;flex-direction:column;width:40px;height:100%;background-color:var(--ug-header-bg);padding-top:8px;gap:8px;align-items:center}.ug-side-bar-tab{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:8px 4px;cursor:pointer;color:var(--ug-icon-color);border-left:2px solid transparent;width:100%;box-sizing:border-box}.ug-side-bar-tab span{writing-mode:vertical-rl;transform:rotate(180deg);margin-top:12px;font-family:var(--ug-font-family, sans-serif);font-weight:var(--ug-header-font-weight, 500);font-size:var(--ug-font-size, 13px);letter-spacing:.5px}.ug-side-bar-tab:hover{color:var(--ug-primary-color);background-color:var(--ug-row-hover-bg)}.ug-side-bar-tab.active{color:var(--ug-primary-color);background-color:var(--ug-panel-bg);border-left:2px solid var(--ug-primary-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ColumnToolPanelComponent, selector: "ug-column-tool-panel", inputs: ["columns", "groupModel", "valuesModel", "pivotMode", "pivotColumns"], outputs: ["columnsUpdated", "groupModelChanged", "valuesModelChanged", "pivotModeChanged", "pivotModelChanged", "exportExcelClicked"] }, { kind: "component", type: FilterToolPanelComponent, selector: "ug-filter-tool-panel", inputs: ["columns", "rowData", "activeFilters", "conditionFilters", "savedReportNames"], outputs: ["filterApplied", "conditionFilterChanged", "clearAllFilters", "saveReportRequested", "loadReportRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2344
2348
  }
2345
2349
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SideBarComponent, decorators: [{
2346
2350
  type: Component,
@@ -2377,11 +2381,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
2377
2381
  [rowData]="rowData"
2378
2382
  [activeFilters]="activeFilters"
2379
2383
  [conditionFilters]="conditionFilters"
2384
+ [savedReportNames]="savedReportNames"
2380
2385
  (filterApplied)="onFilterApplied($event)"
2381
2386
  (conditionFilterChanged)="onConditionFilterChanged($event)"
2382
2387
  (clearAllFilters)="onClearAllFilters()"
2383
- (saveFiltersRequested)="saveFiltersRequested.emit()"
2384
- (filtersImported)="filtersImported.emit($event)">
2388
+ (saveReportRequested)="saveReportRequested.emit($event)"
2389
+ (loadReportRequested)="loadReportRequested.emit($event)">
2385
2390
  </ug-filter-tool-panel>
2386
2391
  </div>
2387
2392
  </div>
@@ -2420,6 +2425,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
2420
2425
  type: Input
2421
2426
  }], pivotColumns: [{
2422
2427
  type: Input
2428
+ }], savedReportNames: [{
2429
+ type: Input
2423
2430
  }], columnsUpdated: [{
2424
2431
  type: Output
2425
2432
  }], groupModelUpdated: [{
@@ -2438,9 +2445,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
2438
2445
  type: Output
2439
2446
  }], clearAllFilters: [{
2440
2447
  type: Output
2441
- }], saveFiltersRequested: [{
2448
+ }], saveReportRequested: [{
2442
2449
  type: Output
2443
- }], filtersImported: [{
2450
+ }], loadReportRequested: [{
2444
2451
  type: Output
2445
2452
  }] } });
2446
2453
 
@@ -2673,6 +2680,12 @@ class UltraGridComponent {
2673
2680
  pageSize = 100;
2674
2681
  rowClicked = new EventEmitter();
2675
2682
  sortChanged = new EventEmitter();
2683
+ selectionChanged = new EventEmitter();
2684
+ getSelectedRows() {
2685
+ if (!this._mappedRowData)
2686
+ return [];
2687
+ return this._mappedRowData.filter(row => row.selected).map(row => row.data);
2688
+ }
2676
2689
  isBrowser;
2677
2690
  visibleColumns = [];
2678
2691
  sortModel = [];
@@ -2705,6 +2718,7 @@ class UltraGridComponent {
2705
2718
  conditionFilters = new Map();
2706
2719
  isChooseColumnsOpen = false;
2707
2720
  chooseColumnsPosition = { x: 0, y: 0 };
2721
+ savedReportNames = [];
2708
2722
  destroy$ = new Subject();
2709
2723
  sortingWorker;
2710
2724
  sortingWorkerUrl;
@@ -2733,6 +2747,9 @@ class UltraGridComponent {
2733
2747
  this.fetchServerPage(1);
2734
2748
  }
2735
2749
  }
2750
+ if (this.isBrowser) {
2751
+ this.loadSavedReportNames();
2752
+ }
2736
2753
  }
2737
2754
  get selectedRowsCount() {
2738
2755
  if (!this._mappedRowData)
@@ -3272,6 +3289,7 @@ class UltraGridComponent {
3272
3289
  }
3273
3290
  this.selectionVersion++;
3274
3291
  this.cdr.markForCheck();
3292
+ this.selectionChanged.emit(this.getSelectedRows());
3275
3293
  }
3276
3294
  onPageSizeChanged(size) {
3277
3295
  this.pageSize = size;
@@ -3355,6 +3373,7 @@ class UltraGridComponent {
3355
3373
  this.selectionVersion++;
3356
3374
  this.rowClicked.emit(row);
3357
3375
  this.cdr.markForCheck();
3376
+ this.selectionChanged.emit(this.getSelectedRows());
3358
3377
  }
3359
3378
  getPlaceholderRow(index) {
3360
3379
  return {
@@ -3369,7 +3388,13 @@ class UltraGridComponent {
3369
3388
  }
3370
3389
  onHeaderMenuClicked(event) {
3371
3390
  this.activeMenuColumn = event.column;
3372
- this.menuPosition = { x: event.event.clientX, y: event.event.clientY };
3391
+ let x = event.event.clientX;
3392
+ const y = event.event.clientY;
3393
+ const panelWidth = 250;
3394
+ if (typeof window !== 'undefined' && (x + panelWidth > window.innerWidth)) {
3395
+ x = Math.max(0, window.innerWidth - panelWidth - 20);
3396
+ }
3397
+ this.menuPosition = { x, y };
3373
3398
  this.isMenuOpen = true;
3374
3399
  this.cdr.markForCheck();
3375
3400
  }
@@ -3422,7 +3447,13 @@ class UltraGridComponent {
3422
3447
  onMenuChooseColumns() {
3423
3448
  this.isChooseColumnsOpen = true;
3424
3449
  // Position it slightly shifted from the menu icon
3425
- this.chooseColumnsPosition = { x: this.menuPosition.x + 20, y: this.menuPosition.y + 20 };
3450
+ let x = this.menuPosition.x + 20;
3451
+ const y = this.menuPosition.y + 20;
3452
+ const panelWidth = 250;
3453
+ if (typeof window !== 'undefined' && (x + panelWidth > window.innerWidth)) {
3454
+ x = Math.max(0, window.innerWidth - panelWidth - 20);
3455
+ }
3456
+ this.chooseColumnsPosition = { x, y };
3426
3457
  this.isMenuOpen = false;
3427
3458
  this.cdr.markForCheck();
3428
3459
  }
@@ -3439,7 +3470,13 @@ class UltraGridComponent {
3439
3470
  }
3440
3471
  onHeaderFilterClicked(event) {
3441
3472
  this.activeFilterColumn = event.column;
3442
- this.filterPosition = { x: event.event.clientX, y: event.event.clientY };
3473
+ let x = event.event.clientX;
3474
+ const y = event.event.clientY;
3475
+ const panelWidth = 300;
3476
+ if (typeof window !== 'undefined' && (x + panelWidth > window.innerWidth)) {
3477
+ x = Math.max(0, window.innerWidth - panelWidth - 20);
3478
+ }
3479
+ this.filterPosition = { x, y };
3443
3480
  this.isFilterOpen = true;
3444
3481
  // Calculate unique values based on un-paginated / un-filtered raw data
3445
3482
  const uniqueSet = new Set();
@@ -3532,8 +3569,23 @@ class UltraGridComponent {
3532
3569
  }
3533
3570
  this.applyLocalData();
3534
3571
  }
3535
- // --- Save / Import Filters ---
3536
- handleSaveFilters() {
3572
+ // --- Save / Import Filters natively to LocalStorage ---
3573
+ loadSavedReportNames() {
3574
+ if (!this.isBrowser)
3575
+ return;
3576
+ try {
3577
+ const stored = localStorage.getItem('ug-saved-reports');
3578
+ if (stored) {
3579
+ const parsed = JSON.parse(stored);
3580
+ this.savedReportNames = Object.keys(parsed);
3581
+ this.cdr.markForCheck();
3582
+ }
3583
+ }
3584
+ catch (e) { }
3585
+ }
3586
+ handleSaveReport(reportName) {
3587
+ if (!reportName)
3588
+ return;
3537
3589
  const state = {
3538
3590
  activeFilters: {},
3539
3591
  conditionFilters: {}
@@ -3548,19 +3600,40 @@ class UltraGridComponent {
3548
3600
  if (this.conditionFilters.size > 0) {
3549
3601
  state.conditionFilters = Object.fromEntries(this.conditionFilters);
3550
3602
  }
3551
- const json = JSON.stringify(state, null, 2);
3552
- const blob = new Blob([json], { type: 'application/json' });
3553
- const url = URL.createObjectURL(blob);
3554
- const link = document.createElement('a');
3555
- link.href = url;
3556
- link.download = `grid-filters-${new Date().toISOString().slice(0, 10)}.json`;
3557
- link.click();
3558
- URL.revokeObjectURL(url);
3603
+ if (this.isBrowser) {
3604
+ try {
3605
+ const stored = localStorage.getItem('ug-saved-reports');
3606
+ const reports = stored ? JSON.parse(stored) : {};
3607
+ reports[reportName] = state;
3608
+ localStorage.setItem('ug-saved-reports', JSON.stringify(reports));
3609
+ this.loadSavedReportNames();
3610
+ console.log(`Report '${reportName}' saved successfully locally.`);
3611
+ }
3612
+ catch (err) {
3613
+ console.error('Failed to save report locally.', err);
3614
+ }
3615
+ }
3559
3616
  }
3560
- handleImportFilters(data) {
3617
+ handleLoadReport(reportName) {
3618
+ if (!reportName || !this.isBrowser)
3619
+ return;
3620
+ try {
3621
+ const stored = localStorage.getItem('ug-saved-reports');
3622
+ if (stored) {
3623
+ const reports = JSON.parse(stored);
3624
+ const data = reports[reportName];
3625
+ if (data) {
3626
+ this.applyImportedFilters(data);
3627
+ }
3628
+ }
3629
+ }
3630
+ catch (err) {
3631
+ console.error('Error loading report locally.', err);
3632
+ }
3633
+ }
3634
+ applyImportedFilters(data) {
3561
3635
  if (!data)
3562
3636
  return;
3563
- console.log('Importing filters:', data);
3564
3637
  try {
3565
3638
  // Restore activeFilters (Record -> Map<string, Set>)
3566
3639
  // Important: We create a NEW Map instance to trigger Output/Input change detection
@@ -3572,7 +3645,6 @@ class UltraGridComponent {
3572
3645
  }
3573
3646
  this.activeFilters = newActiveFilters;
3574
3647
  // Restore conditionFilters (Object -> Map)
3575
- // Important: We create a NEW Map instance to trigger Output/Input change detection
3576
3648
  if (data.conditionFilters) {
3577
3649
  this.conditionFilters = new Map(Object.entries(data.conditionFilters));
3578
3650
  }
@@ -3583,15 +3655,15 @@ class UltraGridComponent {
3583
3655
  this.currentPage = 1;
3584
3656
  this.applyLocalData();
3585
3657
  this.cdr.markForCheck();
3586
- console.log('Filters imported and applied successfully.');
3658
+ console.log('Filters loaded and applied successfully.');
3587
3659
  }
3588
3660
  catch (err) {
3589
- console.error('Error applying imported filters:', err);
3590
- alert('Error applying filters. Please ensure the file format is correct.');
3661
+ console.error('Error applying loaded filters:', err);
3662
+ alert('Error loading report. Please ensure local storage data is not corrupted.');
3591
3663
  }
3592
3664
  }
3593
3665
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: UltraGridComponent, deps: [{ token: PLATFORM_ID }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: GridFlattenerService }, { token: ExcelExportService }], target: i0.ɵɵFactoryTarget.Component });
3594
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: UltraGridComponent, isStandalone: true, selector: "bways-grid", inputs: { columns: "columns", rowData: "rowData", serverDataSource: "serverDataSource", config: "config", pagination: "pagination", pageSize: "pageSize", groupModel: "groupModel", valuesModel: "valuesModel", pivotColumns: "pivotColumns" }, outputs: { rowClicked: "rowClicked", sortChanged: "sortChanged" }, usesOnChanges: true, ngImport: i0, template: `
3666
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: UltraGridComponent, isStandalone: true, selector: "bways-grid", inputs: { columns: "columns", rowData: "rowData", serverDataSource: "serverDataSource", config: "config", pagination: "pagination", pageSize: "pageSize", groupModel: "groupModel", valuesModel: "valuesModel", pivotColumns: "pivotColumns" }, outputs: { rowClicked: "rowClicked", sortChanged: "sortChanged", selectionChanged: "selectionChanged" }, usesOnChanges: true, ngImport: i0, template: `
3595
3667
  <div class="ug-wrapper" [ngClass]="config.theme || 'ag-theme-alpine'">
3596
3668
 
3597
3669
  <div class="ug-main">
@@ -3665,6 +3737,7 @@ class UltraGridComponent {
3665
3737
  [valuesModel]="valuesModel"
3666
3738
  [pivotMode]="!!config.pivotMode"
3667
3739
  [pivotColumns]="pivotColumns"
3740
+ [savedReportNames]="savedReportNames"
3668
3741
  (columnsUpdated)="onSideBarColumnsUpdated($event)"
3669
3742
  (groupModelUpdated)="onSideBarGroupModelUpdated($event)"
3670
3743
  (valuesModelUpdated)="onValuesModelUpdated($event)"
@@ -3674,8 +3747,8 @@ class UltraGridComponent {
3674
3747
  (filterApplied)="onFilterApplied($event)"
3675
3748
  (conditionFilterChanged)="onConditionFilterChanged($event)"
3676
3749
  (clearAllFilters)="onClearAllFilters()"
3677
- (saveFiltersRequested)="handleSaveFilters()"
3678
- (filtersImported)="handleImportFilters($event)">
3750
+ (saveReportRequested)="handleSaveReport($event)"
3751
+ (loadReportRequested)="handleLoadReport($event)">
3679
3752
  </ug-side-bar>
3680
3753
 
3681
3754
  </div>
@@ -3711,7 +3784,7 @@ class UltraGridComponent {
3711
3784
  (closePanel)="isChooseColumnsOpen = false">
3712
3785
  </ug-choose-columns>
3713
3786
  </div>
3714
- `, 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-header-color: #3f332f;--ug-header-hover-bg: rgba(255, 255, 255, .4);--ug-row-bg: rgba(255, 255, 255, .15);--ug-row-hover-bg: rgba(216, 48, 24, .05);--ug-row-selected-bg: rgba(216, 48, 24, .15);--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-header-color: #e2e8f0;--ug-header-hover-bg: #1e293b;--ug-row-bg: #1e293b;--ug-row-hover-bg: #334155;--ug-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"], outputs: ["columnsUpdated", "groupModelUpdated", "valuesModelUpdated", "pivotModeUpdated", "pivotModelUpdated", "exportExcelClicked", "filterApplied", "conditionFilterChanged", "clearAllFilters", "saveFiltersRequested", "filtersImported"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3787
+ `, 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-header-color: #3f332f;--ug-header-hover-bg: rgba(255, 255, 255, .4);--ug-row-bg: rgba(255, 255, 255, .15);--ug-row-hover-bg: rgba(216, 48, 24, .05);--ug-row-selected-bg: rgba(216, 48, 24, .15);--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-header-color: #e2e8f0;--ug-header-hover-bg: #1e293b;--ug-row-bg: #1e293b;--ug-row-hover-bg: #334155;--ug-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", "savedReportNames"], outputs: ["columnsUpdated", "groupModelUpdated", "valuesModelUpdated", "pivotModeUpdated", "pivotModelUpdated", "exportExcelClicked", "filterApplied", "conditionFilterChanged", "clearAllFilters", "saveReportRequested", "loadReportRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3715
3788
  }
3716
3789
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: UltraGridComponent, decorators: [{
3717
3790
  type: Component,
@@ -3799,6 +3872,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
3799
3872
  [valuesModel]="valuesModel"
3800
3873
  [pivotMode]="!!config.pivotMode"
3801
3874
  [pivotColumns]="pivotColumns"
3875
+ [savedReportNames]="savedReportNames"
3802
3876
  (columnsUpdated)="onSideBarColumnsUpdated($event)"
3803
3877
  (groupModelUpdated)="onSideBarGroupModelUpdated($event)"
3804
3878
  (valuesModelUpdated)="onValuesModelUpdated($event)"
@@ -3808,8 +3882,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
3808
3882
  (filterApplied)="onFilterApplied($event)"
3809
3883
  (conditionFilterChanged)="onConditionFilterChanged($event)"
3810
3884
  (clearAllFilters)="onClearAllFilters()"
3811
- (saveFiltersRequested)="handleSaveFilters()"
3812
- (filtersImported)="handleImportFilters($event)">
3885
+ (saveReportRequested)="handleSaveReport($event)"
3886
+ (loadReportRequested)="handleLoadReport($event)">
3813
3887
  </ug-side-bar>
3814
3888
 
3815
3889
  </div>
@@ -3865,6 +3939,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
3865
3939
  type: Output
3866
3940
  }], sortChanged: [{
3867
3941
  type: Output
3942
+ }], selectionChanged: [{
3943
+ type: Output
3868
3944
  }], groupModel: [{
3869
3945
  type: Input
3870
3946
  }], valuesModel: [{