@one-paragon/angular-utilities 2.0.22 → 2.0.23

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.
@@ -4,7 +4,7 @@ import { shareReplay, switchAll, map, filter, tap, catchError, startWith, switch
4
4
  import * as i1 from 'rxjs';
5
5
  import { Subject, isObservable, of, ReplaySubject, filter as filter$1, first, map as map$1, Observable, combineLatest, Subscription, startWith as startWith$1, pairwise, concatMap, merge, delay, pipe, fromEvent, takeUntil as takeUntil$1, tap as tap$1, switchMap as switchMap$1, scan, timestamp } from 'rxjs';
6
6
  import { toObservable, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
7
- import { isFunction, merge as merge$1, get, sumBy, difference, intersection, groupBy, orderBy, set } from 'lodash';
7
+ import { isFunction, merge as merge$1, get, sumBy, difference, groupBy, intersection, orderBy, set } from 'lodash';
8
8
  import * as i3$2 from '@angular/material/sort';
9
9
  import { MatSort, MatSortModule } from '@angular/material/sort';
10
10
  import { CdkColumnDef } from '@angular/cdk/table';
@@ -19,7 +19,7 @@ import * as i3 from '@angular/forms';
19
19
  import { NgControl, NgForm, ControlContainer, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
20
20
  import * as i9 from '@angular/material/core';
21
21
  import { MatOption } from '@angular/material/core';
22
- import { DatePipe, CurrencyPipe, KeyValuePipe, NgTemplateOutlet, formatDate, formatCurrency, DecimalPipe, CommonModule, AsyncPipe } from '@angular/common';
22
+ import { DatePipe, CurrencyPipe, KeyValuePipe, NgTemplateOutlet, formatDate, formatCurrency, DecimalPipe, formatNumber, CommonModule, AsyncPipe } from '@angular/common';
23
23
  import { ComponentStore } from '@ngrx/component-store';
24
24
  import * as i5 from '@angular/cdk/drag-drop';
25
25
  import { moveItemInArray, DragDropModule, CdkDropList, CDK_DROP_LIST, transferArrayItem } from '@angular/cdk/drag-drop';
@@ -928,6 +928,9 @@ function parseTbSizeToPixels(size) {
928
928
  return undefined;
929
929
  }
930
930
 
931
+ function isGroupHeader(data) {
932
+ return !!data?.isGroupHeader;
933
+ }
931
934
  class KeysToDelete {
932
935
  initializationState = null;
933
936
  metaData = null;
@@ -3758,6 +3761,103 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImpor
3758
3761
  type: Injectable
3759
3762
  }], ctorParameters: () => [] });
3760
3763
 
3764
+ const supportsGroupBy = typeof Object.groupBy === 'function';
3765
+ function getGroupedData(data, groupByKeys) {
3766
+ return tbGroupBy(data, groupByKeys);
3767
+ }
3768
+ const tbGroupBy = (data, groupByKeys, level = 1, parentGroupName) => {
3769
+ const currentKey = groupByKeys[0];
3770
+ const groupedDataArr = groupData(currentKey, data, level, parentGroupName);
3771
+ const remainingGroupByKeys = groupByKeys.slice(1);
3772
+ const hasChildrenGroups = !!remainingGroupByKeys.length;
3773
+ if (hasChildrenGroups) {
3774
+ //group the children by iterating over each group and grouping it by the next keys
3775
+ const groupOfGroups = groupedDataArr.map((group) => {
3776
+ const children = group.children;
3777
+ const groupGroup = {
3778
+ groupName: group.groupName,
3779
+ uniqueName: group.uniqueName,
3780
+ key: currentKey,
3781
+ hasTheData: false,
3782
+ isGroupHeader: true,
3783
+ padding: group.padding,
3784
+ level: group.level,
3785
+ length: group.length,
3786
+ groups: tbGroupBy(children, remainingGroupByKeys, level + 1, group.groupName),
3787
+ [initIndexSymbol]: group[initIndexSymbol],
3788
+ };
3789
+ return groupGroup;
3790
+ });
3791
+ return groupOfGroups;
3792
+ }
3793
+ return groupedDataArr;
3794
+ };
3795
+ function groupData(groupByKey, groupData, level = 1, parentGroupName) {
3796
+ const groupedDataDict = supportsGroupBy ? Object.groupBy(groupData, d => d[groupByKey]) : groupBy(groupData, groupByKey);
3797
+ const groupedDataArr = Object.entries(groupedDataDict).map(([groupName, groupData]) => {
3798
+ const uniqueName = parentGroupName ? `${parentGroupName}-${groupName}` : `${groupName}`;
3799
+ return {
3800
+ isGroupHeader: true,
3801
+ groupHeaderDisplay: groupName,
3802
+ hasTheData: true,
3803
+ children: groupData,
3804
+ groupName: `tb_group_${uniqueName}`,
3805
+ padding: 1 + (20 * (level - 1)),
3806
+ key: groupByKey,
3807
+ length: groupData.length,
3808
+ uniqueName,
3809
+ level,
3810
+ [initIndexSymbol]: uniqueName,
3811
+ };
3812
+ });
3813
+ return groupedDataArr;
3814
+ }
3815
+ function updateGroupByState(groupedData, { data, groups, expanded }, firstRun) {
3816
+ if (firstRun
3817
+ || dataUpdated(data, groups, expanded)
3818
+ || groupsUpdated(groups, expanded)) {
3819
+ groupedData = groups.value.length ? getGroupedData(data.value, groups.value) : data.value;
3820
+ }
3821
+ const newDisplayData = expanded.value.length === 0
3822
+ ? groupedData
3823
+ : groupedData.map(group => mapGroupHeader(group, expanded.value.flatMap(g => g.expandedHeaders))).flat();
3824
+ return ({ displayData: newDisplayData, groupedData });
3825
+ }
3826
+ function mapGroupHeader(obj, expandedHeaders) {
3827
+ const showChildren = expandedHeaders === true || expandedHeaders.includes(obj.groupName);
3828
+ const children = !showChildren ? [] :
3829
+ obj.hasTheData ? obj.children
3830
+ : obj.groups.map(a => mapGroupHeader(a, expandedHeaders));
3831
+ return [obj, ...children].flat();
3832
+ }
3833
+ function dataUpdated(data, groups, expandedGroups) {
3834
+ return data.timestamp > groups.timestamp && data.timestamp > expandedGroups.timestamp;
3835
+ }
3836
+ function groupsUpdated(groups, expandedGroups) {
3837
+ return groups.timestamp >= expandedGroups.timestamp;
3838
+ }
3839
+ ;
3840
+ const initialGroupByState = { displayData: [], groupedData: [] };
3841
+ const getAllGroupHeaderNames = (data) => {
3842
+ const groups = getGroupHeaders(data, (d) => d.isGroupHeader);
3843
+ const a = supportsGroupBy ? Object.groupBy(groups, group => group.key) : groupBy(groups, 'key');
3844
+ return Object.entries(a).reduce((names, [key, groups]) => {
3845
+ names[key] = groups.map(g => ({ groupName: g.groupName, key: g.key }));
3846
+ return names;
3847
+ }, {});
3848
+ };
3849
+ const getAllGroupHeaderNamesByKeys = (data, keys) => {
3850
+ const groups = getGroupHeaders(data, (d) => d.isGroupHeader && keys.includes(d.key));
3851
+ return supportsGroupBy ? Object.groupBy(groups, group => group.key) : groupBy(groups, 'key');
3852
+ };
3853
+ const getGroupHeaders = (data, filterFunc, arr = []) => {
3854
+ const headers = data.filter(filterFunc);
3855
+ arr.push(...headers);
3856
+ headers.forEach(h => { if (h.hasTheData === false && !!h.groups.length)
3857
+ getGroupHeaders(h.groups, filterFunc, arr); });
3858
+ return arr;
3859
+ };
3860
+
3761
3861
  class GenericTableComponent {
3762
3862
  state = inject(TableStore);
3763
3863
  dataStore = inject(DataStore);
@@ -3932,7 +4032,7 @@ class GenericTableComponent {
3932
4032
  $isAllSelected = computed(() => {
3933
4033
  this.$selectionChange();
3934
4034
  const selected = this.$selection()?.selected;
3935
- if (!selected)
4035
+ if (!selected?.length)
3936
4036
  return false;
3937
4037
  return this.$selectableData()?.length === selected.length;
3938
4038
  });
@@ -3941,9 +4041,17 @@ class GenericTableComponent {
3941
4041
  this.$selectionChange();
3942
4042
  return !!this.$selection()?.selected.length && !this.$masterToggleChecked();
3943
4043
  });
4044
+ $paginated = computed(() => this.state.$viewType() === 'virtual paginator' || this.state.$viewType() === 'paginator');
3944
4045
  $selectableData = computed(() => {
3945
- if (this.state.$viewType() === 'virtual paginator' || this.state.$viewType() === 'paginator') {
4046
+ const isGrouped = !!this.state.$groupByKeys().length;
4047
+ this.state.$expandGroups();
4048
+ if (this.$paginated()) {
3946
4049
  const previousPageRecords = this.state.$currentPage() * this.state.$pageSize();
4050
+ if (isGrouped) {
4051
+ const onScreen = this.$dataSource().data.slice(previousPageRecords, previousPageRecords + this.state.$pageSize());
4052
+ const nested = onScreen.flatMap((group) => (group.isGroupHeader && !this.state.$getIsExpanded(group.key, group.groupName)()) ? mapGroupHeader(group, true) : []);
4053
+ return onScreen.concat(nested).filter(row => !row.isGroupHeader);
4054
+ }
3947
4055
  return this.$data().slice(previousPageRecords, previousPageRecords + this.state.$pageSize());
3948
4056
  }
3949
4057
  else if (this.state.$viewType() === 'all' || this.state.$viewType() === 'virtual all') {
@@ -3951,6 +4059,16 @@ class GenericTableComponent {
3951
4059
  }
3952
4060
  return [];
3953
4061
  });
4062
+ $selectAllMessage = computed(() => {
4063
+ if (this.$isAllSelected())
4064
+ return `Deselect all ${this.$selection().selected.length} selected`;
4065
+ const selectable = formatNumber(this.$selectableData().length, 'en-US');
4066
+ let message = `Select all ${selectable}`;
4067
+ if (this.$paginated()) {
4068
+ message += ' on this page';
4069
+ }
4070
+ return message;
4071
+ });
3954
4072
  #onSelectableDataChangeEffect = effect(() => {
3955
4073
  const selectableData = this.$selectableData();
3956
4074
  untracked(() => {
@@ -3987,16 +4105,16 @@ class GenericTableComponent {
3987
4105
  }
3988
4106
  }
3989
4107
  });
3990
- getTransform = (key, val) => {
4108
+ getTransform = (key, val) => computed(() => {
3991
4109
  if (val == undefined || val === 'null')
3992
4110
  return '';
3993
4111
  try {
3994
4112
  return createTransformer(this.state.$getMetaData(key)(), this.config, true, true)({ [`${key}`]: val });
3995
4113
  }
3996
4114
  catch (error) {
3997
- return val;
4115
+ return signal(val);
3998
4116
  }
3999
- };
4117
+ });
4000
4118
  $rowHeight = computed(() => {
4001
4119
  if (this.state.$userDefinedRowHeight()) {
4002
4120
  return this.state.$userDefinedRowHeight() + 'px';
@@ -4046,15 +4164,52 @@ class GenericTableComponent {
4046
4164
  $stickyFooter = computed(() => this.state.$props().stickyFooter || this.state.$isVirtual());
4047
4165
  $rowStyles = computed(() => this.state.$tableSettings().rowStyles || {});
4048
4166
  $rowClasses = computed(() => this.state.$tableSettings().rowClasses || {});
4167
+ allOfGroupSelected = (uniqueName) => computed(() => {
4168
+ //make sure signal is marked dirty when selection or over all data changes
4169
+ this.$selectionChange();
4170
+ this.$data();
4171
+ const header = this.$dataSource().data.find(d => isGroupHeader(d) && d.uniqueName === uniqueName);
4172
+ const children = mapGroupHeader(header, true).filter(i => !isGroupHeader(i));
4173
+ if (!children.length)
4174
+ return { containsAll: false, containsSome: false, length: 0 };
4175
+ let containsAll = true;
4176
+ let containsSome = false;
4177
+ for (var a of children) {
4178
+ const contains = this.$selection().isSelected(a);
4179
+ if (contains)
4180
+ containsSome = true;
4181
+ else
4182
+ containsAll = false;
4183
+ if (!containsAll && containsSome)
4184
+ break;
4185
+ }
4186
+ return { containsAll, containsSome, length: children.length };
4187
+ });
4188
+ toggleGroup = (uniqueName, allSelected) => {
4189
+ const header = this.$dataSource().data.find(d => isGroupHeader(d) && d.uniqueName === uniqueName);
4190
+ const children = mapGroupHeader(header, true).filter(i => !isGroupHeader(i));
4191
+ if (allSelected) {
4192
+ this.$selection().deselect(...children);
4193
+ }
4194
+ else {
4195
+ this.$selection().select(...children);
4196
+ }
4197
+ };
4198
+ toggleGroupMessage = (amountOfItems, allSelected) => {
4199
+ if (allSelected)
4200
+ return `Deselect all in this group`;
4201
+ const selectable = formatNumber(amountOfItems, 'en-US');
4202
+ return `Select all ${selectable} in this group`;
4203
+ };
4049
4204
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: GenericTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4050
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.1", type: GenericTableComponent, isStandalone: true, selector: "tb-generic-table", inputs: { $displayDataLength: { classPropertyName: "$displayDataLength", publicName: "displayDataLength", isSignal: true, isRequired: true, transformFunction: null }, $data: { classPropertyName: "$data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, $rows: { classPropertyName: "$rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, $columnInfos: { classPropertyName: "$columnInfos", publicName: "columnInfos", isSignal: true, isRequired: true, transformFunction: null }, $dataSource: { classPropertyName: "$dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, $trackBy: { classPropertyName: "$trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection$: "selection" }, viewQueries: [{ propertyName: "$headerRow", first: true, predicate: MatHeaderRowDef, descendants: true, isSignal: true }, { propertyName: "$footerRow", first: true, predicate: MatFooterRowDef, descendants: true, isSignal: true }, { propertyName: "$table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "$dropList", first: true, predicate: CdkDropList, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index; let t\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"\r\n [style.height]=\"$rowHeight()\"\r\n [style.min-height]=\"$rowHeight()\"\r\n [styler]=\"$rowStyles()\"\r\n [element]=\"row\"\r\n [conditionalClasses]=\"$rowClasses()\"\r\n />\r\n\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$6.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$6.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$6.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.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: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: FunctionPipe, name: "func" }, { kind: "directive", type: StylerDirective, selector: "[styler]", inputs: ["element", "styler"] }, { kind: "directive", type: ConditionalClassesDirective, selector: "[conditionalClasses]", inputs: ["element", "conditionalClasses"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4205
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.1", type: GenericTableComponent, isStandalone: true, selector: "tb-generic-table", inputs: { $displayDataLength: { classPropertyName: "$displayDataLength", publicName: "displayDataLength", isSignal: true, isRequired: true, transformFunction: null }, $data: { classPropertyName: "$data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, $rows: { classPropertyName: "$rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, $columnInfos: { classPropertyName: "$columnInfos", publicName: "columnInfos", isSignal: true, isRequired: true, transformFunction: null }, $dataSource: { classPropertyName: "$dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, $trackBy: { classPropertyName: "$trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection$: "selection" }, viewQueries: [{ propertyName: "$headerRow", first: true, predicate: MatHeaderRowDef, descendants: true, isSignal: true }, { propertyName: "$footerRow", first: true, predicate: MatFooterRowDef, descendants: true, isSignal: true }, { propertyName: "$table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "$dropList", first: true, predicate: CdkDropList, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\" [matTooltip]=\"$selectAllMessage()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index; let t\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n @if($hasSelectColumn())\r\n {\r\n @let contains = (allOfGroupSelected | func : row.uniqueName)();\r\n <mat-checkbox (change)=\"$event ? toggleGroup(row.uniqueName, contains.containsAll) : null\"\r\n [checked]=\"!!contains.containsAll\"\r\n [indeterminate]=\"!!contains.containsSome && !contains.containsAll\"\r\n [matTooltip]=\"toggleGroupMessage | func : contains.length : contains.containsAll\" >\r\n </mat-checkbox>\r\n }\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded())\r\n {\r\n <mat-icon>chevron_right</mat-icon>\r\n }\r\n @else\r\n {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ (getTransform | func : row.key : row.groupHeaderDisplay)() }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"\r\n [style.height]=\"$rowHeight()\"\r\n [style.min-height]=\"$rowHeight()\"\r\n [styler]=\"$rowStyles()\"\r\n [element]=\"row\"\r\n [conditionalClasses]=\"$rowClasses()\"\r\n />\r\n\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$6.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$6.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$6.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.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: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: FunctionPipe, name: "func" }, { kind: "directive", type: StylerDirective, selector: "[styler]", inputs: ["element", "styler"] }, { kind: "directive", type: ConditionalClassesDirective, selector: "[conditionalClasses]", inputs: ["element", "conditionalClasses"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4051
4206
  }
4052
4207
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: GenericTableComponent, decorators: [{
4053
4208
  type: Component,
4054
4209
  args: [{ selector: 'tb-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4055
4210
  MatTableModule, DragDropModule, MatCheckboxModule, MatButtonModule, MatIconModule, NgTemplateOutlet,
4056
4211
  MatTooltipModule, FunctionPipe, StylerDirective, ConditionalClassesDirective
4057
- ], template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index; let t\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"\r\n [style.height]=\"$rowHeight()\"\r\n [style.min-height]=\"$rowHeight()\"\r\n [styler]=\"$rowStyles()\"\r\n [element]=\"row\"\r\n [conditionalClasses]=\"$rowClasses()\"\r\n />\r\n\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"] }]
4212
+ ], template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\" [matTooltip]=\"$selectAllMessage()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index; let t\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n @if($hasSelectColumn())\r\n {\r\n @let contains = (allOfGroupSelected | func : row.uniqueName)();\r\n <mat-checkbox (change)=\"$event ? toggleGroup(row.uniqueName, contains.containsAll) : null\"\r\n [checked]=\"!!contains.containsAll\"\r\n [indeterminate]=\"!!contains.containsSome && !contains.containsAll\"\r\n [matTooltip]=\"toggleGroupMessage | func : contains.length : contains.containsAll\" >\r\n </mat-checkbox>\r\n }\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded())\r\n {\r\n <mat-icon>chevron_right</mat-icon>\r\n }\r\n @else\r\n {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ (getTransform | func : row.key : row.groupHeaderDisplay)() }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"\r\n [style.height]=\"$rowHeight()\"\r\n [style.min-height]=\"$rowHeight()\"\r\n [styler]=\"$rowStyles()\"\r\n [element]=\"row\"\r\n [conditionalClasses]=\"$rowClasses()\"\r\n />\r\n\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"] }]
4058
4213
  }] });
4059
4214
 
4060
4215
  function downloadData(data, filename, mimeType) {
@@ -4434,78 +4589,6 @@ function patchDirectiveFromState(directive, stateFilter) {
4434
4589
  }
4435
4590
  }
4436
4591
 
4437
- function getGroupedData(data, groupByKeys) {
4438
- return tbGroupBy(data, groupByKeys);
4439
- }
4440
- const tbGroupBy = (data, groupByKeys, parentGroupName) => {
4441
- const currentKey = groupByKeys[0];
4442
- const res = groupBy(data, currentKey);
4443
- const remainingGroupByKeys = groupByKeys.slice(1);
4444
- const finalGroups = !remainingGroupByKeys.length;
4445
- if (remainingGroupByKeys.length) {
4446
- Object.keys(res).forEach(key => res[key] = tbGroupBy(res[key], remainingGroupByKeys, key));
4447
- }
4448
- return Object.keys(res).map((groupName, i) => {
4449
- const uniqName = parentGroupName ? `${parentGroupName}-${groupName}` : `${groupName}`;
4450
- const groupHeaders = res[groupName]?.filter(row => row.isGroupHeader) ?? [];
4451
- return {
4452
- isGroupHeader: true,
4453
- groupHeaderDisplay: groupName,
4454
- hasTheData: finalGroups,
4455
- children: finalGroups ? res[groupName] : res[groupName].map(d => { d.padding += 20; return d; }),
4456
- groupName: `tb_group_${uniqName}`,
4457
- padding: 1,
4458
- key: currentKey,
4459
- length: groupHeaders.reduce((acc, curr) => curr.length + acc, 0) + ((res[groupName] ?? []).length - groupHeaders.length),
4460
- [initIndexSymbol]: uniqName,
4461
- };
4462
- });
4463
- };
4464
- function updateGroupByState(groupedData, { data, groups, expanded }, firstRun) {
4465
- if (firstRun
4466
- || dataUpdated(data, groups, expanded)
4467
- || groupsUpdated(groups, expanded)) {
4468
- groupedData = groups.value.length ? getGroupedData(data.value, groups.value) : data.value;
4469
- }
4470
- const newDisplayData = expanded.value.length === 0
4471
- ? groupedData
4472
- : groupedData.map(group => mapGroupHeader(group, expanded.value)).flat();
4473
- return ({ displayData: newDisplayData, groupedData });
4474
- }
4475
- function _updateGroupByState({ groupedData }, [data, groups, expanded], index) {
4476
- return updateGroupByState(groupedData, { data, groups, expanded }, index === 0);
4477
- }
4478
- function mapGroupHeader(obj, data) {
4479
- const showChildren = data.find(a => a.expandedHeaders.includes(obj.groupName));
4480
- const children = !showChildren ? [] :
4481
- obj.hasTheData ? obj.children
4482
- : obj.children.map(a => mapGroupHeader(a, data));
4483
- return [obj, ...children].flat();
4484
- }
4485
- function dataUpdated(data, groups, expandedGroups) {
4486
- return data.timestamp > groups.timestamp && data.timestamp > expandedGroups.timestamp;
4487
- }
4488
- function groupsUpdated(groups, expandedGroups) {
4489
- return groups.timestamp > expandedGroups.timestamp;
4490
- }
4491
- ;
4492
- const initialGroupByState = { displayData: [], groupedData: [] };
4493
- const getAllGroupHeaderNames = (data) => {
4494
- const groups = getGroupHeaders(data, (d) => d.isGroupHeader);
4495
- return groupBy(groups, 'key');
4496
- };
4497
- const getAllGroupHeaderNamesByKeys = (data, keys) => {
4498
- const groups = getGroupHeaders(data, (d) => d.isGroupHeader && keys.includes(d.key));
4499
- return groupBy(groups, 'key');
4500
- };
4501
- const getGroupHeaders = (data, filterFunc, arr = []) => {
4502
- const headers = data.filter(filterFunc);
4503
- arr.push(...headers);
4504
- headers.forEach(h => { if (!!h.children.length)
4505
- getGroupHeaders(h.children, filterFunc, arr); });
4506
- return arr;
4507
- };
4508
-
4509
4592
  function sortData(data, sorted) {
4510
4593
  const ordered = orderBy(data, sorted.map(r => r.active), sorted.map(r => r.direction));
4511
4594
  return ordered;
@@ -5493,11 +5576,13 @@ class TableContainerComponent {
5493
5576
  const groupHeaderHeight = this.$groupHeaderHeight();
5494
5577
  return ({ indexColumn, selectionColumn, isSticky: stickHeader, stickyFooter, groupHeaderTemplate, groupHeaderHeight });
5495
5578
  });
5496
- #initTableBuilderIfNeeded = effect(() => {
5579
+ #initTableBuilder = effect(() => {
5497
5580
  const tb = this.$tableBuilder();
5498
5581
  untracked(() => {
5499
- if (tb)
5500
- this.$tableBuilder()?.prep(this.injector);
5582
+ if (tb) {
5583
+ tb?.prep(this.injector);
5584
+ tb.container.set(this);
5585
+ }
5501
5586
  });
5502
5587
  });
5503
5588
  #initializeTableSettingsFromTableBuilderAndPersistedStateEffect = effect(() => {
@@ -5809,36 +5894,37 @@ class TableBuilder {
5809
5894
  #$metaData;
5810
5895
  #$data;
5811
5896
  #$settings;
5897
+ container = signal(undefined);
5812
5898
  $metaData = computed(() => this.$initialized() ? this.#$metaData() : undefined);
5813
5899
  $settings = computed(() => this.$initialized() ? this.#$settings() : undefined);
5814
- $metaNeedsPrep = signal(false);
5815
- $dataIsObservable = signal(false);
5816
- $settingsIsObservable = signal(false);
5817
- $needsPrep = computed(() => this.$dataIsObservable() || this.$metaNeedsPrep() || this.$settingsIsObservable());
5900
+ #$metaNeedsPrep = signal(false);
5901
+ #$dataIsObservable = signal(false);
5902
+ #$settingsIsObservable = signal(false);
5903
+ #$needsPrep = computed(() => this.#$dataIsObservable() || this.#$metaNeedsPrep() || this.#$settingsIsObservable());
5818
5904
  $initialized = signal(false);
5819
5905
  constructor(data, metaData, settings = new GeneralTableSettings()) {
5820
5906
  this.data = data;
5821
5907
  this.metaData = metaData;
5822
5908
  this.settings = settings;
5823
5909
  if (isObservable(data)) {
5824
- this.$dataIsObservable.set(true);
5910
+ this.#$dataIsObservable.set(true);
5825
5911
  }
5826
5912
  else {
5827
5913
  this.#$data = isSignal(data) ? data : signal(data);
5828
5914
  }
5829
5915
  if (isObservable(metaData) || !metaData) {
5830
- this.$metaNeedsPrep.set(true);
5916
+ this.#$metaNeedsPrep.set(true);
5831
5917
  }
5832
5918
  else {
5833
5919
  this.#$metaData = isSignal(metaData) ? metaData : signal(metaData);
5834
5920
  }
5835
5921
  if (isObservable(settings)) {
5836
- this.$settingsIsObservable.set(true);
5922
+ this.#$settingsIsObservable.set(true);
5837
5923
  }
5838
5924
  else {
5839
5925
  this.#$settings = isSignal(settings) ? settings : signal(settings);
5840
5926
  }
5841
- if (!this.$needsPrep()) {
5927
+ if (!this.#$needsPrep()) {
5842
5928
  this.$initialized.set(true);
5843
5929
  }
5844
5930
  else {
@@ -5851,13 +5937,13 @@ class TableBuilder {
5851
5937
  }
5852
5938
  }
5853
5939
  prep(injector) {
5854
- if (this.$settingsIsObservable()) {
5940
+ if (this.#$settingsIsObservable()) {
5855
5941
  this.#$settings = toSignal(this.settings, { injector, requireSync: true });
5856
5942
  }
5857
- if (this.$dataIsObservable()) {
5943
+ if (this.#$dataIsObservable()) {
5858
5944
  this.#$data = toSignal(this.data, { injector, initialValue: [] });
5859
5945
  }
5860
- if (this.$metaNeedsPrep()) {
5946
+ if (this.#$metaNeedsPrep()) {
5861
5947
  if (this.metaData) {
5862
5948
  this.#$metaData = toSignal(this.metaData, { injector, initialValue: [] });
5863
5949
  }