@3kles/kles-material-table-v2 21.2.0 → 21.4.0

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.
@@ -1,8 +1,8 @@
1
- import * as i15 from '@angular/common';
1
+ import * as i16 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { Pipe, InjectionToken, Injectable, input, computed, HostBinding, Directive, inject, Inject, signal, DestroyRef, Component, Optional, EventEmitter, ViewChild, effect, Injector, Output, NgModule } from '@angular/core';
5
- import * as i16 from '@angular/forms';
4
+ import { Pipe, InjectionToken, Injectable, input, computed, HostBinding, Directive, inject, Inject, signal, DestroyRef, Component, ChangeDetectorRef, ChangeDetectionStrategy, Optional, EventEmitter, ViewChild, effect, Injector, Output, NgModule } from '@angular/core';
5
+ import * as i17 from '@angular/forms';
6
6
  import { FormControl, FormGroup, FormArray, ReactiveFormsModule } from '@angular/forms';
7
7
  import * as i2 from '@angular/material/button';
8
8
  import { MatButtonModule } from '@angular/material/button';
@@ -10,17 +10,17 @@ import { MatFormFieldModule } from '@angular/material/form-field';
10
10
  import * as i1 from '@angular/material/icon';
11
11
  import { MatIconModule } from '@angular/material/icon';
12
12
  import { MatInputModule } from '@angular/material/input';
13
- import * as i18 from '@angular/material/table';
13
+ import * as i19 from '@angular/material/table';
14
14
  import { MatTableDataSource, MatTableModule, MatTable } from '@angular/material/table';
15
- import * as i19 from '@angular/cdk/table';
15
+ import * as i20 from '@angular/cdk/table';
16
16
  import { CdkTableModule } from '@angular/cdk/table';
17
- import * as i20 from '@3kles/kles-material-dynamicforms';
17
+ import * as i21 from '@3kles/kles-material-dynamicforms';
18
18
  import { componentMapper, klesFieldControlFactory, klesFieldUiFactory, GroupUiState, ArrayUiState, KlesMaterialDynamicformsModule } from '@3kles/kles-material-dynamicforms';
19
19
  import * as i4 from '@angular/material/sort';
20
20
  import { MatSortModule, MatSort } from '@angular/material/sort';
21
- import * as i21 from '@angular/cdk/drag-drop';
21
+ import * as i22 from '@angular/cdk/drag-drop';
22
22
  import { DragDropModule } from '@angular/cdk/drag-drop';
23
- import * as i22 from '@angular/material/progress-spinner';
23
+ import * as i23 from '@angular/material/progress-spinner';
24
24
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
25
25
  import { Subject, BehaviorSubject, combineLatest, startWith, of, auditTime, switchMap, concat, catchError, map, filter, take, merge, debounceTime, distinctUntilChanged, scan, concatMap, withLatestFrom, shareReplay } from 'rxjs';
26
26
  import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
@@ -38,7 +38,7 @@ class HeaderFieldPipe {
38
38
  return null;
39
39
  return {
40
40
  name: col.columnDef,
41
- ...col.headerCell.field,
41
+ ...col.headerCell?.field,
42
42
  };
43
43
  }
44
44
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: HeaderFieldPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
@@ -56,7 +56,7 @@ class CellFieldPipe {
56
56
  transform(col) {
57
57
  if (!col)
58
58
  return null;
59
- return { name: col.columnDef, canExpand: col.canExpand, ...col.cell.field };
59
+ return { name: col.columnDef, canExpand: col.canExpand, ...col.cell?.field };
60
60
  }
61
61
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: CellFieldPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
62
62
  static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.19", ngImport: i0, type: CellFieldPipe, isStandalone: true, name: "cellField" }); }
@@ -103,6 +103,7 @@ const SELECTION_SERVICE = new InjectionToken('SELECTION_SERVICE');
103
103
  const SORT_SERVICE = new InjectionToken('SORT_SERVICE');
104
104
  const SCROLLBAR_ORCHESTRATOR_SERVICE = new InjectionToken('SCROLLBAR_ORCHESTRATOR_SERVICE');
105
105
  const TABLE_SERVICE = new InjectionToken('TABLE_SERVICE');
106
+ const EMPTY_STATE_CONFIG = new InjectionToken('EMPTY_STATE_CONFIG');
106
107
 
107
108
  class ResolveNgStylePipe {
108
109
  transform(style, value, status, row, rowStatus) {
@@ -583,7 +584,15 @@ class RowFormFactory {
583
584
  controls[field.name] = control;
584
585
  uis[field.name] = ui;
585
586
  }
586
- return { formGroup: new FormGroup(controls), groupUi: new GroupUiState(uis) };
587
+ return {
588
+ formGroup: new FormGroup(controls),
589
+ groupUi: new GroupUiState(uis),
590
+ context: {
591
+ source: record,
592
+ _id: data._id,
593
+ meta,
594
+ },
595
+ };
587
596
  }
588
597
  createRows(fields, records, meta = { depth: 0, parentId: null }) {
589
598
  return records.map((r) => this.createRow(fields, r, meta));
@@ -596,10 +605,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
596
605
  args: [{ providedIn: 'root' }]
597
606
  }] });
598
607
 
608
+ class RowContextStore {
609
+ constructor() {
610
+ this.contexts = new WeakMap();
611
+ }
612
+ set(row, context) {
613
+ const current = this.contexts.get(row);
614
+ if (current) {
615
+ current.set(context);
616
+ }
617
+ else {
618
+ this.contexts.set(row, signal(context));
619
+ }
620
+ }
621
+ get(row) {
622
+ return this.contexts.get(row) ?? null;
623
+ }
624
+ updateSource(row, source) {
625
+ this.contexts.get(row)?.update((context) => context
626
+ ? {
627
+ ...context,
628
+ source,
629
+ }
630
+ : null);
631
+ }
632
+ delete(row) {
633
+ this.contexts.delete(row);
634
+ }
635
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: RowContextStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
636
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: RowContextStore }); }
637
+ }
638
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: RowContextStore, decorators: [{
639
+ type: Injectable
640
+ }] });
641
+
599
642
  class KlesForm {
600
- constructor(columnsService, rowFactory) {
643
+ constructor(columnsService, rowFactory, rowContextStore) {
601
644
  this.columnsService = columnsService;
602
645
  this.rowFactory = rowFactory;
646
+ this.rowContextStore = rowContextStore;
603
647
  this.form = new FormGroup({
604
648
  header: new FormGroup({}),
605
649
  rows: new FormArray([]),
@@ -633,10 +677,14 @@ class KlesForm {
633
677
  return this.form.get('footer');
634
678
  }
635
679
  setRows(rows) {
680
+ this.getRows().controls.forEach((row) => {
681
+ this.rowContextStore.delete(row);
682
+ });
636
683
  this.getRows().clear({ emitEvent: false });
637
684
  this.getUiRows().clear();
638
685
  rows.forEach((r) => {
639
686
  this.uiStore.set(r.formGroup, r.groupUi);
687
+ this.rowContextStore.set(r.formGroup, r.context);
640
688
  this.getRows().push(r.formGroup, { emitEvent: false });
641
689
  this.getUiRows().push(r.groupUi);
642
690
  });
@@ -644,6 +692,7 @@ class KlesForm {
644
692
  }
645
693
  insertRowAndNotify(row, index, options, notify) {
646
694
  this.uiStore.set(row.formGroup, row.groupUi);
695
+ this.rowContextStore.set(row.formGroup, row.context);
647
696
  if (index !== undefined) {
648
697
  this.getRows().insert(index, row.formGroup, options);
649
698
  this.getUiRows().insert(index, row.groupUi);
@@ -685,7 +734,9 @@ class KlesForm {
685
734
  deleteRowById(id, option) {
686
735
  const index = this.getRows().controls.findIndex((c) => c.getRawValue()._id === id);
687
736
  if (index !== -1) {
737
+ const row = this.getRows().at(index);
688
738
  this.getRows().removeAt(index, option);
739
+ this.rowContextStore.delete(row);
689
740
  this.getUiRows().removeAt(index);
690
741
  this.notifyRowsStructureChanged();
691
742
  }
@@ -708,7 +759,7 @@ class KlesForm {
708
759
  init() {
709
760
  this.columnsService.columns().forEach((column) => {
710
761
  let colCellHeader = {};
711
- if (column.headerCell.field) {
762
+ if (column.headerCell?.field) {
712
763
  const { pipeTransform, ...tmpCell } = column.headerCell.field;
713
764
  colCellHeader = _.cloneDeep(tmpCell);
714
765
  colCellHeader = { pipeTransform, ...colCellHeader };
@@ -738,12 +789,12 @@ class KlesForm {
738
789
  notifyRowsStructureChanged() {
739
790
  this.rowsStructureChangedSubject.next();
740
791
  }
741
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesForm, deps: [{ token: ColumnsService }, { token: RowFormFactory }], target: i0.ɵɵFactoryTarget.Injectable }); }
792
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesForm, deps: [{ token: ColumnsService }, { token: RowFormFactory }, { token: RowContextStore }], target: i0.ɵɵFactoryTarget.Injectable }); }
742
793
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesForm }); }
743
794
  }
744
795
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesForm, decorators: [{
745
796
  type: Injectable
746
- }], ctorParameters: () => [{ type: ColumnsService }, { type: RowFormFactory }] });
797
+ }], ctorParameters: () => [{ type: ColumnsService }, { type: RowFormFactory }, { type: RowContextStore }] });
747
798
 
748
799
  class TreeService {
749
800
  constructor() {
@@ -782,7 +833,7 @@ class TreeService {
782
833
  this.loading.delete(id);
783
834
  // this.loadingService.stop();
784
835
  // console.log( (group.getRawValue()._depth ?? 0) + 1)
785
- this.fm.insertRows(this.rowFactory.createRows(this.columnsService.columns().map((col) => ({ ...col.cell.field, name: col.columnDef })), response.items, { depth: (group.getRawValue()._depth ?? 0) + 1, parentId: id }), index + 1);
836
+ this.fm.insertRows(this.rowFactory.createRows(this.columnsService.columns().map((col) => ({ ...col.cell?.field, name: col.columnDef })), response.items, { depth: (group.getRawValue()._depth ?? 0) + 1, parentId: id }), index + 1);
786
837
  expanded.add(id);
787
838
  this._expandedIds$.next(expanded);
788
839
  }
@@ -808,10 +859,10 @@ class KlesCellComponent {
808
859
  this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : /* istanbul ignore next */ []));
809
860
  this.column = input.required(...(ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []));
810
861
  this.expandedRow = computed(() => {
811
- return (this.column().canExpand ?? false) && (this.ui().get(this.column().columnDef).value().expandedRow ?? false);
862
+ return (this.column().canExpand ?? false) && (this.ui().get(this.column().columnDef)?.value().expandedRow ?? false);
812
863
  }, ...(ngDevMode ? [{ debugName: "expandedRow" }] : /* istanbul ignore next */ []));
813
864
  this.expandedNode = computed(() => {
814
- return (this.column().canExpandNode ?? false) && (this.ui().get(this.column().columnDef).value().expandedNode ?? false);
865
+ return (this.column().canExpandNode ?? false) && (this.ui().get(this.column().columnDef)?.value().expandedNode ?? false);
815
866
  }, ...(ngDevMode ? [{ debugName: "expandedNode" }] : /* istanbul ignore next */ []));
816
867
  this.hasChildren = computed(() => {
817
868
  return this.treeService.hasChildren(this.group(), this.group().getRawValue()._depth);
@@ -957,6 +1008,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
957
1008
  }]
958
1009
  }] });
959
1010
 
1011
+ class KlesTableIntl {
1012
+ constructor() {
1013
+ this.changes = new Subject();
1014
+ this.emptyStateTitle = 'No data';
1015
+ this.emptyStateDescription = 'There are no rows to display.';
1016
+ }
1017
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesTableIntl, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1018
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesTableIntl, providedIn: 'root' }); }
1019
+ }
1020
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesTableIntl, decorators: [{
1021
+ type: Injectable,
1022
+ args: [{
1023
+ providedIn: 'root',
1024
+ }]
1025
+ }] });
1026
+
1027
+ class KlesTableEmptyStateComponent {
1028
+ constructor() {
1029
+ this.intl = inject(KlesTableIntl);
1030
+ this.changeDetectorRef = inject(ChangeDetectorRef);
1031
+ this.destroyRef = inject(DestroyRef);
1032
+ this.intl.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
1033
+ this.changeDetectorRef.markForCheck();
1034
+ });
1035
+ }
1036
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesTableEmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1037
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: KlesTableEmptyStateComponent, isStandalone: true, selector: "kles-table-empty-state", ngImport: i0, template: "<section class=\"empty-state\" role=\"status\" aria-live=\"polite\">\n <div class=\"empty-state__panel\">\n <div class=\"empty-state__visual\" aria-hidden=\"true\">\n <div class=\"empty-state__table-icon\">\n <span class=\"empty-state__table-header\"></span>\n <span></span>\n <span></span>\n <span></span>\n </div>\n\n <div class=\"empty-state__badge\">\n <mat-icon>remove</mat-icon>\n </div>\n </div>\n\n <div class=\"empty-state__content\">\n <h2 class=\"empty-state__title\">\n {{ intl.emptyStateTitle }}\n </h2>\n\n <p class=\"empty-state__description\">\n {{ intl.emptyStateDescription }}\n </p>\n </div>\n </div>\n</section>\n", styles: [":host{display:block;width:100%;height:100%;box-sizing:border-box;--kles-empty-state-accent: var(--mat-sys-primary);--kles-empty-state-accent-container: var(--mat-sys-primary-container)}.empty-state{display:grid;width:100%;height:100%;box-sizing:border-box;place-items:center}.empty-state__panel{display:flex;width:min(100%,31rem);align-items:center;justify-content:center;gap:1.25rem;color:var(--mat-sys-on-surface-variant)}.empty-state__visual{position:relative;display:grid;width:4.5rem;height:4.5rem;flex:0 0 4.5rem;place-items:center;border-radius:1.25rem;background:color-mix(in srgb,var(--kles-empty-state-accent-container) 72%,var(--mat-sys-surface))}.empty-state__table-icon{display:grid;width:2.35rem;height:2.15rem;overflow:hidden;box-sizing:border-box;grid-template-rows:.65rem repeat(3,1fr);border:.125rem solid var(--kles-empty-state-accent);border-radius:.35rem}.empty-state__table-icon span{border-top:1px solid color-mix(in srgb,var(--kles-empty-state-accent) 45%,transparent)}.empty-state__table-icon .empty-state__table-header{border-top:0;background:color-mix(in srgb,var(--kles-empty-state-accent) 24%,transparent)}.empty-state__badge{position:absolute;right:-.2rem;bottom:-.2rem;display:grid;width:1.65rem;height:1.65rem;place-items:center;border:.2rem solid var(--mat-sys-surface);border-radius:50%;color:var(--mat-sys-on-primary);background:var(--kles-empty-state-accent)}.empty-state__badge mat-icon{width:1rem;height:1rem;font-size:1rem;font-weight:700}.empty-state__content{display:grid;max-width:25rem;gap:.3rem;text-align:left}.empty-state__title{margin:0;color:var(--mat-sys-on-surface);font:var(--mat-sys-title-medium)}.empty-state__description{margin:0;font:var(--mat-sys-body-medium);line-height:1.45;text-wrap:balance}@media(max-width:37.5rem){.empty-state__panel{flex-direction:column;gap:.875rem;padding:1.25rem;text-align:center}.empty-state__content{text-align:center}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1038
+ }
1039
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: KlesTableEmptyStateComponent, decorators: [{
1040
+ type: Component,
1041
+ args: [{ selector: 'kles-table-empty-state', standalone: true, imports: [MatIconModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"empty-state\" role=\"status\" aria-live=\"polite\">\n <div class=\"empty-state__panel\">\n <div class=\"empty-state__visual\" aria-hidden=\"true\">\n <div class=\"empty-state__table-icon\">\n <span class=\"empty-state__table-header\"></span>\n <span></span>\n <span></span>\n <span></span>\n </div>\n\n <div class=\"empty-state__badge\">\n <mat-icon>remove</mat-icon>\n </div>\n </div>\n\n <div class=\"empty-state__content\">\n <h2 class=\"empty-state__title\">\n {{ intl.emptyStateTitle }}\n </h2>\n\n <p class=\"empty-state__description\">\n {{ intl.emptyStateDescription }}\n </p>\n </div>\n </div>\n</section>\n", styles: [":host{display:block;width:100%;height:100%;box-sizing:border-box;--kles-empty-state-accent: var(--mat-sys-primary);--kles-empty-state-accent-container: var(--mat-sys-primary-container)}.empty-state{display:grid;width:100%;height:100%;box-sizing:border-box;place-items:center}.empty-state__panel{display:flex;width:min(100%,31rem);align-items:center;justify-content:center;gap:1.25rem;color:var(--mat-sys-on-surface-variant)}.empty-state__visual{position:relative;display:grid;width:4.5rem;height:4.5rem;flex:0 0 4.5rem;place-items:center;border-radius:1.25rem;background:color-mix(in srgb,var(--kles-empty-state-accent-container) 72%,var(--mat-sys-surface))}.empty-state__table-icon{display:grid;width:2.35rem;height:2.15rem;overflow:hidden;box-sizing:border-box;grid-template-rows:.65rem repeat(3,1fr);border:.125rem solid var(--kles-empty-state-accent);border-radius:.35rem}.empty-state__table-icon span{border-top:1px solid color-mix(in srgb,var(--kles-empty-state-accent) 45%,transparent)}.empty-state__table-icon .empty-state__table-header{border-top:0;background:color-mix(in srgb,var(--kles-empty-state-accent) 24%,transparent)}.empty-state__badge{position:absolute;right:-.2rem;bottom:-.2rem;display:grid;width:1.65rem;height:1.65rem;place-items:center;border:.2rem solid var(--mat-sys-surface);border-radius:50%;color:var(--mat-sys-on-primary);background:var(--kles-empty-state-accent)}.empty-state__badge mat-icon{width:1rem;height:1rem;font-size:1rem;font-weight:700}.empty-state__content{display:grid;max-width:25rem;gap:.3rem;text-align:left}.empty-state__title{margin:0;color:var(--mat-sys-on-surface);font:var(--mat-sys-title-medium)}.empty-state__description{margin:0;font:var(--mat-sys-body-medium);line-height:1.45;text-wrap:balance}@media(max-width:37.5rem){.empty-state__panel{flex-direction:column;gap:.875rem;padding:1.25rem;text-align:center}.empty-state__content{text-align:center}}\n"] }]
1042
+ }], ctorParameters: () => [] });
1043
+
1044
+ class RowContextPipe {
1045
+ constructor() {
1046
+ this.store = inject(RowContextStore);
1047
+ }
1048
+ transform(row) {
1049
+ return row ? this.store.get(row) : null;
1050
+ }
1051
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: RowContextPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1052
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.19", ngImport: i0, type: RowContextPipe, isStandalone: true, name: "rowContext" }); }
1053
+ }
1054
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: RowContextPipe, decorators: [{
1055
+ type: Pipe,
1056
+ args: [{
1057
+ name: 'rowContext',
1058
+ standalone: true,
1059
+ pure: true,
1060
+ }]
1061
+ }] });
1062
+
960
1063
  class KlesTableConnectorService {
961
1064
  constructor() {
962
1065
  this._connected$ = new BehaviorSubject(false);
@@ -1153,6 +1256,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
1153
1256
  class ScrollbarService {
1154
1257
  constructor() {
1155
1258
  this.default = 'smooth';
1259
+ this.hiddenClass = 'scrollbar-hidden';
1156
1260
  }
1157
1261
  register(el) {
1158
1262
  this.element = el;
@@ -1160,18 +1264,27 @@ class ScrollbarService {
1160
1264
  unregister() {
1161
1265
  this.element = undefined;
1162
1266
  }
1267
+ setScrollbarVisible(visible) {
1268
+ this.element?.classList.toggle(this.hiddenClass, !visible);
1269
+ }
1270
+ hideScrollbar() {
1271
+ this.setScrollbarVisible(false);
1272
+ }
1273
+ showScrollbar() {
1274
+ this.setScrollbarVisible(true);
1275
+ }
1163
1276
  toTop(sb) {
1164
1277
  this.element?.scrollTo({ top: 0, behavior: sb ?? this.default });
1165
1278
  }
1166
1279
  toBottom(sb) {
1167
- const top = this.element.scrollHeight;
1280
+ const top = this.element?.scrollHeight;
1168
1281
  this.element?.scrollTo({ top, behavior: sb ?? this.default });
1169
1282
  }
1170
1283
  toLeft(sb) {
1171
1284
  this.element?.scrollTo({ left: 0, behavior: sb ?? this.default });
1172
1285
  }
1173
1286
  toRight(sb) {
1174
- const left = this.element.scrollWidth;
1287
+ const left = this.element?.scrollWidth;
1175
1288
  this.element?.scrollTo({ left, behavior: sb ?? this.default });
1176
1289
  }
1177
1290
  to(top, left, sb) {
@@ -1460,6 +1573,8 @@ class DatasourceService {
1460
1573
  this.cellValueChangeService = cellValueChangeService;
1461
1574
  this.validationService = validationService;
1462
1575
  this.destroyRef = inject(DestroyRef);
1576
+ this._isEmpty = signal(true, ...(ngDevMode ? [{ debugName: "_isEmpty" }] : /* istanbul ignore next */ []));
1577
+ this.isEmpty = this._isEmpty.asReadonly();
1463
1578
  }
1464
1579
  register() {
1465
1580
  this.createDataSource();
@@ -1479,6 +1594,7 @@ class DatasourceService {
1479
1594
  .connect()
1480
1595
  .pipe(takeUntilDestroyed(this.destroyRef))
1481
1596
  .subscribe((rows) => {
1597
+ this._isEmpty.set(rows.length === 0);
1482
1598
  this.cellValueChangeService.listen(rows, this.columnsService.getVisible());
1483
1599
  this.validationService.listen(rows, this.columnsService.getVisible());
1484
1600
  });
@@ -1496,6 +1612,8 @@ class DatasourceLazyService {
1496
1612
  this.cellValueChangeService = cellValueChangeService;
1497
1613
  this.validationService = validationService;
1498
1614
  this.destroyRef = inject(DestroyRef);
1615
+ this._isEmpty = signal(true, ...(ngDevMode ? [{ debugName: "_isEmpty" }] : /* istanbul ignore next */ []));
1616
+ this.isEmpty = this._isEmpty.asReadonly();
1499
1617
  }
1500
1618
  register() {
1501
1619
  this.createDataSource();
@@ -1515,6 +1633,7 @@ class DatasourceLazyService {
1515
1633
  .connect()
1516
1634
  .pipe(takeUntilDestroyed(this.destroyRef))
1517
1635
  .subscribe((rows) => {
1636
+ this._isEmpty.set(rows.length === 0);
1518
1637
  this.cellValueChangeService.listen(rows, this.columnsService.getVisible());
1519
1638
  this.validationService.listen(rows, this.columnsService.getVisible());
1520
1639
  });
@@ -1551,10 +1670,10 @@ class FilterService {
1551
1670
  let keyValue = data?.controls[key]?.value;
1552
1671
  const column = this.columnsService.columns().find((col) => col.columnDef === key);
1553
1672
  if (column) {
1554
- if (column.headerCell.filterPredicate) {
1673
+ if (column.headerCell?.filterPredicate) {
1555
1674
  return column.headerCell.filterPredicate(keyValue, searchString[key]) || false;
1556
1675
  }
1557
- if (keyValue != null && typeof keyValue === 'object' && column.cell.field.property) {
1676
+ if (keyValue != null && typeof keyValue === 'object' && column.cell?.field?.property) {
1558
1677
  keyValue = keyValue[column.cell.field.property];
1559
1678
  }
1560
1679
  if (searchString?.[key] && typeof searchString[key] === 'object') {
@@ -1564,7 +1683,7 @@ class FilterService {
1564
1683
  }
1565
1684
  const list = searchString[key]
1566
1685
  .map((m) => {
1567
- const subkey = column.headerCell.field?.property ?? column.cell.field.property;
1686
+ const subkey = column.headerCell?.field?.property ?? column.cell?.field?.property;
1568
1687
  if (subkey) {
1569
1688
  return m?.[subkey] ?? m;
1570
1689
  }
@@ -1576,7 +1695,7 @@ class FilterService {
1576
1695
  return keyValue != undefined && list.includes(keyValue.toString().trim().toLowerCase());
1577
1696
  }
1578
1697
  else {
1579
- const subKey = column.headerCell.field?.property ?? column.cell.field.property;
1698
+ const subKey = column.headerCell?.field?.property ?? column.cell?.field?.property;
1580
1699
  if (subKey) {
1581
1700
  searchString[key] = searchString[key][subKey];
1582
1701
  }
@@ -1713,6 +1832,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
1713
1832
  type: Injectable
1714
1833
  }], ctorParameters: () => [{ type: EventsService }] });
1715
1834
 
1835
+ class EmptyStateService {
1836
+ constructor(config) {
1837
+ this._enabled = signal(true, ...(ngDevMode ? [{ debugName: "_enabled" }] : /* istanbul ignore next */ []));
1838
+ this.enabled = this._enabled.asReadonly();
1839
+ if (typeof config === 'boolean') {
1840
+ this._enabled.set(config);
1841
+ this.component = KlesTableEmptyStateComponent;
1842
+ return;
1843
+ }
1844
+ this._enabled.set(config?.enabled ?? true);
1845
+ this.component = config?.component ?? KlesTableEmptyStateComponent;
1846
+ }
1847
+ enable() {
1848
+ this._enabled.set(true);
1849
+ }
1850
+ disable() {
1851
+ this._enabled.set(false);
1852
+ }
1853
+ toggle() {
1854
+ this._enabled.update((enabled) => !enabled);
1855
+ }
1856
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: EmptyStateService, deps: [{ token: EMPTY_STATE_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); }
1857
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: EmptyStateService }); }
1858
+ }
1859
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: EmptyStateService, decorators: [{
1860
+ type: Injectable
1861
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
1862
+ type: Inject,
1863
+ args: [EMPTY_STATE_CONFIG]
1864
+ }] }] });
1865
+
1716
1866
  class DragDropBase {
1717
1867
  constructor(config) {
1718
1868
  this.config = config;
@@ -1794,7 +1944,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
1794
1944
  }] }] });
1795
1945
 
1796
1946
  class TableComponent {
1797
- constructor(host, connectorService, loader, datasourceService, tableService, dragDropRowService, selectionService, columnsService, loadingService, paginatorService, scrollbarService, footerService, extraRowService, renderService, sortService, filterService, expandedRowStore, rowFactory, eventsService, rowService, cellService) {
1947
+ constructor(host, connectorService, loader, datasourceService, tableService, dragDropRowService, selectionService, columnsService, loadingService, paginatorService, scrollbarService, footerService, extraRowService, renderService, sortService, filterService, expandedRowStore, rowFactory, eventsService, rowService, cellService, emptyStateService) {
1798
1948
  this.host = host;
1799
1949
  this.connectorService = connectorService;
1800
1950
  this.loader = loader;
@@ -1816,14 +1966,17 @@ class TableComponent {
1816
1966
  this.eventsService = eventsService;
1817
1967
  this.rowService = rowService;
1818
1968
  this.cellService = cellService;
1969
+ this.emptyStateService = emptyStateService;
1819
1970
  this.headerHeightPx = 56;
1820
1971
  this.scrollHeightPx = 0;
1821
1972
  this.footerHeightPx = 0;
1822
1973
  this.destroyRef = inject(DestroyRef);
1974
+ this.emptyStateComponent = KlesTableEmptyStateComponent;
1823
1975
  this.columns = this.columnsService.columns;
1824
1976
  this.displayedColumns = this.columnsService.displayedColumns;
1825
1977
  this.showFooter = this.footerService.footer;
1826
1978
  this.dataSource = this.datasourceService.datasource;
1979
+ this.isEmpty = this.datasourceService.isEmpty;
1827
1980
  this.multiTemplateDataRows = this.extraRowService.multiTemplateDataRows;
1828
1981
  this.extraRows = this.extraRowService.rows;
1829
1982
  this.connectorService.connect(this);
@@ -1832,6 +1985,9 @@ class TableComponent {
1832
1985
  get isLoadingClass() {
1833
1986
  return this.loadingService.loading();
1834
1987
  }
1988
+ get isEmptyClass() {
1989
+ return this.isEmpty() && this.emptyStateService.enabled();
1990
+ }
1835
1991
  get events() {
1836
1992
  return {
1837
1993
  listen: () => this.eventsService.events$,
@@ -1857,7 +2013,7 @@ class TableComponent {
1857
2013
  create: (value, index, options) => {
1858
2014
  return this.tableService.klesForm.insertRow(this.rowFactory.createRow(this.columnsService
1859
2015
  .columns()
1860
- .map((col) => ({ ...col.cell.field, name: col.columnDef }))
2016
+ .map((col) => ({ ...col.cell?.field, name: col.columnDef }))
1861
2017
  .concat(this.extraRowService.extraColumns().map((col) => ({ ...col, name: col.columnDef }))), value), index, options).formGroup;
1862
2018
  },
1863
2019
  patch: (_id, value, options) => {
@@ -2068,8 +2224,8 @@ class TableComponent {
2068
2224
  };
2069
2225
  }
2070
2226
  }
2071
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: TableComponent, deps: [{ token: i0.ElementRef }, { token: KlesTableConnectorService }, { token: LOADER_SERVICE }, { token: DATASOURCE_SERVICE }, { token: TABLE_SERVICE }, { token: ROW_DRAG_DROP }, { token: SELECTION_SERVICE }, { token: ColumnsService }, { token: LoadingService }, { token: PaginatorService }, { token: ScrollbarService }, { token: FooterService }, { token: ExtraRowService }, { token: RenderService }, { token: SORT_SERVICE }, { token: FilterService, optional: true }, { token: ExpandedRowStore }, { token: RowFormFactory }, { token: EventsService }, { token: RowService }, { token: CellService }], target: i0.ɵɵFactoryTarget.Component }); }
2072
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: TableComponent, isStandalone: true, selector: "kles-table", host: { properties: { "class.loading": "this.isLoadingClass" } }, viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true }, { propertyName: "matSort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "formElemRef", first: true, predicate: ["form"], descendants: true, static: true }], ngImport: i0, template: "<form #form [formGroup]=\"tableService.form\" (ngSubmit)=\"submit()\">\n <!-- [fixedLayout]=\"true\" -->\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n [trackBy]=\"multiTemplateDataRows() ? null : tableService.trackBy\"\n formArrayName=\"rows\"\n cdkDropList\n [cdkDropListData]=\"tableService.form.controls.rows\"\n (cdkDropListDropped)=\"dragDropRowService.listDropped($event)\"\n [cdkDropListDisabled]=\"!dragDropRowService.enable\"\n [cdkDropListAutoScrollStep]=\"dragDropRowService.autoScrollStep\"\n [cdkDropListSortPredicate]=\"dragDropRowService.sortPredicate\"\n [cdkDropListConnectedTo]=\"dragDropRowService.connectedTo\"\n [multiTemplateDataRows]=\"multiTemplateDataRows()\"\n >\n <colgroup>\n @for (column of columns(); track column.columnDef) {\n <col [style.width]=\"column.width ?? null\" [style.minWidth]=\"column.minWidth ?? null\" [style.maxWidth]=\"column.maxWidth ?? null\" />\n }\n </colgroup>\n\n @for (column of columns(); track column.columnDef) {\n <ng-container [cdkColumnDef]=\"column.columnDef\" [sticky]=\"column.sticky ?? false\" [stickyEnd]=\"column.stickyEnd ?? false\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [appResizableColumn]=\"column\"\n [style.border-inline-end]=\"getColumnSeparator(column, 'header') ?? getStickyStartSeparator(column, 'header')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'header')\"\n [ngStyle]=\"\n column.headerCell?.style?.ngStyle\n | resolveNgStyle\n : tableService.form.get(['header', column.columnDef])?.value\n : tableService.form.get(['header', column.columnDef])?.status\n : tableService.form.controls.header.value\n : tableService.form.controls.header.status\n \"\n >\n <div class=\"cell\">\n <kles-header [header]=\"column | header\" [group]=\"tableService.form.controls.header\">\n <ng-container\n klesDynamicField\n [field]=\"column | headerField\"\n [group]=\"tableService.form.controls.header\"\n [ui]=\"tableService.ui.states.header\"\n ></ng-container>\n </kles-header>\n </div>\n </th>\n\n <td\n mat-cell\n *cdkCellDef=\"let row; let index = index; let dataIndex = dataIndex\"\n [style.border-inline-end]=\"getColumnSeparator(column, 'body') ?? getStickyStartSeparator(column, 'body')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'body')\"\n [ngStyle]=\"\n column.cell?.style?.ngStyle\n | resolveNgStyle: row.controls[column.columnDef].value : row.controls[column.columnDef].status : row.value : row.status\n \"\n (click)=\"cellService.onClick($event, row, dataIndex ?? index, column.columnDef)\"\n (dblclick)=\"cellService.onDoubleClick($event, row, dataIndex ?? index, column.columnDef)\"\n (contextmenu)=\"cellService.onContextMenu($event, row, dataIndex ?? index, column.columnDef)\"\n >\n <div class=\"cell\" [style.--align]=\"column.align\">\n <kles-cell [group]=\"row\" [ui]=\"row | uiField\" [column]=\"column\">\n <ng-container klesDynamicField [field]=\"column | cellField\" [group]=\"row\" [ui]=\"row | uiField\"></ng-container>\n </kles-cell>\n </div>\n </td>\n\n <td\n mat-footer-cell\n *matFooterCellDef\n [style.border-inline-end]=\"getColumnSeparator(column, 'footer') ?? getStickyStartSeparator(column, 'footer')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'footer')\"\n [ngStyle]=\"\n column.footerCell?.style?.ngStyle\n | resolveNgStyle\n : tableService.form.get(['footer', column.columnDef])?.value\n : tableService.form.get(['footer', column.columnDef])?.status\n : tableService.form.controls.footer.value\n : tableService.form.controls.footer.status\n \"\n >\n @if (column.footerCell) {\n <ng-container\n klesDynamicField\n [field]=\"column | footerField\"\n [group]=\"tableService.form.controls.footer\"\n [ui]=\"tableService.ui.states.footer\"\n >\n </ng-container>\n }\n </td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns(); sticky: true\"></tr>\n\n <tr\n mat-row\n *matRowDef=\"let row; let index = index; let dataIndex = dataIndex; columns: displayedColumns()\"\n cdkDrag\n [cdkDragData]=\"row\"\n (click)=\"rowService.onClick($event, row, dataIndex ?? index)\"\n (dblclick)=\"rowService.onDoubleClick($event, row, dataIndex ?? index)\"\n (contextmenu)=\"rowService.onContextMenu($event, row, dataIndex ?? index)\"\n (mouseenter)=\"rowService.onMouseEnter($event, row, dataIndex ?? index)\"\n (mouseleave)=\"rowService.onMouseLeave($event, row, dataIndex ?? index)\"\n ></tr>\n\n @if (multiTemplateDataRows()) {\n @for (extraRow of extraRows(); track extraRow) {\n @for (extraColumn of extraRow.cells; track extraColumn.columnDef) {\n <ng-container [cdkColumnDef]=\"extraColumn.columnDef\">\n <td\n mat-cell\n *cdkCellDef=\"let row\"\n [attr.colspan]=\"extraColumn.colspan | spanPipe: displayedColumns().length\"\n [attr.rowspan]=\"extraColumn.rowspan\"\n [ngStyle]=\"\n extraColumn?.style?.ngStyle\n | resolveNgStyle\n : row.controls[extraColumn.columnDef].value\n : row.controls[extraColumn.columnDef].status\n : row.value\n : row.status\n \"\n >\n <ng-container klesDynamicField [field]=\"extraColumn | extraCellField\" [group]=\"row\" [ui]=\"row | uiField\"></ng-container>\n </td>\n </ng-container>\n }\n <tr\n mat-row\n *matRowDef=\"let row; let index = index; let dataIndex = dataIndex; columns: extraRow.displayedColumns; when: extraRow.when\"\n (click)=\"rowService.onClick($event, row, dataIndex ?? index)\"\n (dblclick)=\"rowService.onDoubleClick($event, row, dataIndex ?? index)\"\n (contextmenu)=\"rowService.onContextMenu($event, row, dataIndex ?? index)\"\n (mouseenter)=\"rowService.onMouseEnter($event, row, dataIndex ?? index)\"\n (mouseleave)=\"rowService.onMouseLeave($event, row, dataIndex ?? index)\"\n ></tr>\n }\n }\n\n <tr mat-footer-row *matFooterRowDef=\"displayedColumns(); sticky: true\" [style.display]=\"showFooter() ? '' : 'none'\"></tr>\n\n <tr *matNoDataRow [attr.colspan]=\"displayedColumns().length\">\n @if (!loadingService.loading()) {\n <!--no data TODO -->\n }\n </tr>\n </table>\n</form>\n\n@if (loadingService.loading()) {\n <div class=\"table-overlay\" [style.--header-h.px]=\"headerHeightPx\" [style.--scroll-h.px]=\"scrollHeightPx\" [style.--footer-h.px]=\"footerHeightPx\">\n <mat-spinner></mat-spinner>\n </div>\n}\n", styles: [":host{--kles-table-divider-color: color-mix(in srgb, var(--mat-sys-outline-variant) 65%, transparent);--kles-table-divider-strong-color: var(--mat-sys-outline-variant);--kles-table-header-background: var(--mat-sys-surface-container-low);--kles-table-header-color: var(--mat-sys-on-surface);--kles-table-header-divider-color: var(--mat-sys-outline-variant);--kles-table-row-hover-background: color-mix(in srgb, var(--mat-sys-primary) 7%, var(--mat-sys-surface));overflow:auto;display:flex;flex-direction:column;position:relative;height:100%;--mat-form-field-filled-container-color: transparent;--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0;--mat-form-field-state-layer-color: transparent}:host(.loading){min-height:350px}form{display:flex;flex-direction:column;flex-grow:1;position:relative;overflow:auto}table{width:100%;flex-grow:1}th,td{text-wrap:pretty;white-space:normal;padding-top:2px;padding-bottom:2px;box-sizing:border-box}td{word-break:normal}th .cell,td .cell{display:flex;flex-direction:column;justify-content:var(--align, center)}th[appResizableColumn]{position:relative}th[appResizableColumn] .resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;-webkit-user-select:none;user-select:none}.table-overlay{position:absolute;inset-inline:0;top:var(--header-h, 56px);bottom:calc(var(--scroll-h, 0px) + var(--footer-h, 0px));display:grid;place-items:center;background:color-mix(in srgb,var(--mat-sys-surface-container-highest) 75%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--mat-sys-outline-variant) 30%,transparent);z-index:500}:host .mat-mdc-row{transition:background-color .12s ease}:host .mat-mdc-row:hover{background:var(--kles-table-row-hover-background)}:host .mat-mdc-table .mat-mdc-cell,:host .mat-mdc-table .mat-mdc-header-cell{border-bottom-color:var(--mat-sys-outline-variant)}:host .mat-mdc-table .mat-mdc-cell:last-child,:host .mat-mdc-table .mat-mdc-header-cell:last-child{border-right:none}:host tr.mat-mdc-footer-row td.mat-mdc-footer-cell{border-top:1px solid var(--kles-table-divider-strong-color)}:host tr.mat-mdc-row:last-of-type td.mat-mdc-cell{border-bottom:1px solid var(--kles-table-divider-color)}:host tr.mat-mdc-footer-row{font-weight:500}:host .mat-mdc-header-row,:host .mat-mdc-header-cell{background-color:var(--kles-table-header-background);color:var(--kles-table-header-color)}:host .mat-mdc-header-cell{border-bottom-color:var(--kles-table-header-divider-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i15.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i16.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i16.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i16.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i16.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i4.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i18.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i18.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i18.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i18.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i18.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i18.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i18.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i18.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i18.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i18.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i18.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i18.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "directive", type: i18.MatNoDataRow, selector: "ng-template[matNoDataRow]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: CdkTableModule }, { kind: "directive", type: i19.CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: i19.CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "ngmodule", type: KlesMaterialDynamicformsModule }, { kind: "directive", type: i20.KlesDynamicFieldDirective, selector: "[klesDynamicField]", inputs: ["field", "group", "ui", "siblingFields"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i21.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i21.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: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i22.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: ResizableColumnDirective, selector: "th[appResizableColumn]", inputs: ["appResizableColumn"] }, { kind: "component", type: KlesCellComponent, selector: "kles-cell", inputs: ["ui", "group", "column"] }, { kind: "component", type: KlesHeaderComponent, selector: "kles-header", inputs: ["header", "group"] }, { kind: "pipe", type: HeaderFieldPipe, name: "headerField" }, { kind: "pipe", type: CellFieldPipe, name: "cellField" }, { kind: "pipe", type: UiFieldPipe, name: "uiField" }, { kind: "pipe", type: FooterFieldPipe, name: "footerField" }, { kind: "pipe", type: SpanPipe, name: "spanPipe" }, { kind: "pipe", type: ExtraCellFieldPipe, name: "extraCellField" }, { kind: "pipe", type: ResolveNgStylePipe, name: "resolveNgStyle" }, { kind: "pipe", type: HeaderPipe, name: "header" }] }); }
2227
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: TableComponent, deps: [{ token: i0.ElementRef }, { token: KlesTableConnectorService }, { token: LOADER_SERVICE }, { token: DATASOURCE_SERVICE }, { token: TABLE_SERVICE }, { token: ROW_DRAG_DROP }, { token: SELECTION_SERVICE }, { token: ColumnsService }, { token: LoadingService }, { token: PaginatorService }, { token: ScrollbarService }, { token: FooterService }, { token: ExtraRowService }, { token: RenderService }, { token: SORT_SERVICE }, { token: FilterService, optional: true }, { token: ExpandedRowStore }, { token: RowFormFactory }, { token: EventsService }, { token: RowService }, { token: CellService }, { token: EmptyStateService }], target: i0.ɵɵFactoryTarget.Component }); }
2228
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: TableComponent, isStandalone: true, selector: "kles-table", host: { properties: { "class.loading": "this.isLoadingClass", "class.empty": "this.isEmptyClass" } }, viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true }, { propertyName: "matSort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "formElemRef", first: true, predicate: ["form"], descendants: true, static: true }], ngImport: i0, template: "<form #form [formGroup]=\"tableService.form\" (ngSubmit)=\"submit()\">\n <!-- [fixedLayout]=\"true\" -->\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n [trackBy]=\"multiTemplateDataRows() ? null : tableService.trackBy\"\n formArrayName=\"rows\"\n cdkDropList\n [cdkDropListData]=\"tableService.form.controls.rows\"\n (cdkDropListDropped)=\"dragDropRowService.listDropped($event)\"\n [cdkDropListDisabled]=\"!dragDropRowService.enable\"\n [cdkDropListAutoScrollStep]=\"dragDropRowService.autoScrollStep\"\n [cdkDropListSortPredicate]=\"dragDropRowService.sortPredicate\"\n [cdkDropListConnectedTo]=\"dragDropRowService.connectedTo\"\n [multiTemplateDataRows]=\"multiTemplateDataRows()\"\n >\n <colgroup>\n @for (column of columns(); track column.columnDef) {\n <col [style.width]=\"column.width ?? null\" [style.minWidth]=\"column.minWidth ?? null\" [style.maxWidth]=\"column.maxWidth ?? null\" />\n }\n </colgroup>\n\n @for (column of columns(); track column.columnDef) {\n <ng-container [cdkColumnDef]=\"column.columnDef\" [sticky]=\"column.sticky ?? false\" [stickyEnd]=\"column.stickyEnd ?? false\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [appResizableColumn]=\"column\"\n [style.border-inline-end]=\"getColumnSeparator(column, 'header') ?? getStickyStartSeparator(column, 'header')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'header')\"\n [ngStyle]=\"\n column.headerCell?.style?.ngStyle\n | resolveNgStyle\n : tableService.form.get(['header', column.columnDef])?.value\n : tableService.form.get(['header', column.columnDef])?.status\n : tableService.form.controls.header.value\n : tableService.form.controls.header.status\n \"\n >\n <div class=\"cell\">\n <kles-header [header]=\"column | header\" [group]=\"tableService.form.controls.header\">\n <ng-container\n klesDynamicField\n [field]=\"column | headerField\"\n [group]=\"tableService.form.controls.header\"\n [ui]=\"tableService.ui.states.header\"\n ></ng-container>\n </kles-header>\n </div>\n </th>\n\n <td\n mat-cell\n *cdkCellDef=\"let row; let index = index; let dataIndex = dataIndex\"\n [style.border-inline-end]=\"getColumnSeparator(column, 'body') ?? getStickyStartSeparator(column, 'body')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'body')\"\n [ngStyle]=\"\n column.cell?.style?.ngStyle\n | resolveNgStyle: row.controls[column.columnDef].value : row.controls[column.columnDef].status : row.value : row.status\n \"\n (click)=\"cellService.onClick($event, row, dataIndex ?? index, column.columnDef)\"\n (dblclick)=\"cellService.onDoubleClick($event, row, dataIndex ?? index, column.columnDef)\"\n (contextmenu)=\"cellService.onContextMenu($event, row, dataIndex ?? index, column.columnDef)\"\n >\n <div class=\"cell\" [style.--align]=\"column.align\">\n <kles-cell [group]=\"row\" [ui]=\"row | uiField\" [column]=\"column\">\n <ng-container klesDynamicField [field]=\"column | cellField\" [group]=\"row\" [ui]=\"row | uiField\" [context]=\"row | rowContext\"></ng-container>\n </kles-cell>\n </div>\n </td>\n\n <td\n mat-footer-cell\n *matFooterCellDef\n [style.border-inline-end]=\"getColumnSeparator(column, 'footer') ?? getStickyStartSeparator(column, 'footer')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'footer')\"\n [ngStyle]=\"\n column.footerCell?.style?.ngStyle\n | resolveNgStyle\n : tableService.form.get(['footer', column.columnDef])?.value\n : tableService.form.get(['footer', column.columnDef])?.status\n : tableService.form.controls.footer.value\n : tableService.form.controls.footer.status\n \"\n >\n @if (column.footerCell) {\n <ng-container\n klesDynamicField\n [field]=\"column | footerField\"\n [group]=\"tableService.form.controls.footer\"\n [ui]=\"tableService.ui.states.footer\"\n >\n </ng-container>\n }\n </td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns(); sticky: true\"></tr>\n\n <tr\n mat-row\n *matRowDef=\"let row; let index = index; let dataIndex = dataIndex; columns: displayedColumns()\"\n cdkDrag\n [cdkDragData]=\"row\"\n (click)=\"rowService.onClick($event, row, dataIndex ?? index)\"\n (dblclick)=\"rowService.onDoubleClick($event, row, dataIndex ?? index)\"\n (contextmenu)=\"rowService.onContextMenu($event, row, dataIndex ?? index)\"\n (mouseenter)=\"rowService.onMouseEnter($event, row, dataIndex ?? index)\"\n (mouseleave)=\"rowService.onMouseLeave($event, row, dataIndex ?? index)\"\n ></tr>\n\n @if (multiTemplateDataRows()) {\n @for (extraRow of extraRows(); track extraRow) {\n @for (extraColumn of extraRow.cells; track extraColumn.columnDef) {\n <ng-container [cdkColumnDef]=\"extraColumn.columnDef\">\n <td\n mat-cell\n *cdkCellDef=\"let row\"\n [attr.colspan]=\"extraColumn.colspan | spanPipe: displayedColumns().length\"\n [attr.rowspan]=\"extraColumn.rowspan\"\n [ngStyle]=\"\n extraColumn?.style?.ngStyle\n | resolveNgStyle\n : row.controls[extraColumn.columnDef].value\n : row.controls[extraColumn.columnDef].status\n : row.value\n : row.status\n \"\n >\n <ng-container klesDynamicField [field]=\"extraColumn | extraCellField\" [group]=\"row\" [ui]=\"row | uiField\" [context]=\"row | rowContext\"></ng-container>\n </td>\n </ng-container>\n }\n <tr\n mat-row\n *matRowDef=\"let row; let index = index; let dataIndex = dataIndex; columns: extraRow.displayedColumns; when: extraRow.when\"\n (click)=\"rowService.onClick($event, row, dataIndex ?? index)\"\n (dblclick)=\"rowService.onDoubleClick($event, row, dataIndex ?? index)\"\n (contextmenu)=\"rowService.onContextMenu($event, row, dataIndex ?? index)\"\n (mouseenter)=\"rowService.onMouseEnter($event, row, dataIndex ?? index)\"\n (mouseleave)=\"rowService.onMouseLeave($event, row, dataIndex ?? index)\"\n ></tr>\n }\n }\n\n <tr mat-footer-row *matFooterRowDef=\"displayedColumns(); sticky: true\" [style.display]=\"showFooter() ? '' : 'none'\"></tr>\n </table>\n</form>\n\n@if (loadingService.loading()) {\n <div class=\"table-overlay\" [style.--header-h.px]=\"headerHeightPx\" [style.--scroll-h.px]=\"scrollHeightPx\" [style.--footer-h.px]=\"footerHeightPx\">\n <mat-spinner></mat-spinner>\n </div>\n}\n\n@if (emptyStateService.enabled() && !loadingService.loading() && isEmpty()) {\n <div\n class=\"table-empty-state-overlay\"\n [style.--header-h.px]=\"headerHeightPx\"\n [style.--scroll-h.px]=\"scrollHeightPx\"\n [style.--footer-h.px]=\"footerHeightPx\"\n >\n <div class=\"table-empty-state-content\">\n <ng-container *ngComponentOutlet=\"emptyStateService.component\"></ng-container>\n </div>\n </div>\n}\n", styles: [":host{--kles-table-divider-color: color-mix(in srgb, var(--mat-sys-outline-variant) 65%, transparent);--kles-table-divider-strong-color: var(--mat-sys-outline-variant);--kles-table-header-background: var(--mat-sys-surface-container-low);--kles-table-header-color: var(--mat-sys-on-surface);--kles-table-header-divider-color: var(--mat-sys-outline-variant);--kles-table-row-hover-background: color-mix(in srgb, var(--mat-sys-primary) 7%, var(--mat-sys-surface));overflow:auto;display:flex;flex-direction:column;position:relative;height:100%;--mat-form-field-filled-container-color: transparent;--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0;--mat-form-field-state-layer-color: transparent}:host(.loading),:host(.empty){min-height:280px}form{display:flex;flex-direction:column;flex-grow:1;position:relative;overflow:auto}table{width:100%;flex-grow:1}th,td{text-wrap:pretty;white-space:normal;padding-top:2px;padding-bottom:2px;box-sizing:border-box}td{word-break:normal}th .cell,td .cell{display:flex;flex-direction:column;justify-content:var(--align, center)}th[appResizableColumn]{position:relative}th[appResizableColumn] .resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;-webkit-user-select:none;user-select:none}.table-overlay{position:absolute;inset-inline:0;top:var(--header-h, 56px);bottom:calc(var(--scroll-h, 0px) + var(--footer-h, 0px));display:grid;place-items:center;background:color-mix(in srgb,var(--mat-sys-surface-container-highest) 75%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--mat-sys-outline-variant) 30%,transparent);z-index:500}:host .mat-mdc-row{transition:background-color .12s ease}:host .mat-mdc-row:hover{background:var(--kles-table-row-hover-background)}:host .mat-mdc-table .mat-mdc-cell,:host .mat-mdc-table .mat-mdc-header-cell{border-bottom-color:var(--mat-sys-outline-variant)}:host .mat-mdc-table .mat-mdc-cell:last-child,:host .mat-mdc-table .mat-mdc-header-cell:last-child{border-right:none}:host tr.mat-mdc-footer-row td.mat-mdc-footer-cell{border-top:1px solid var(--kles-table-divider-strong-color)}:host tr.mat-mdc-row:last-of-type td.mat-mdc-cell{border-bottom:1px solid var(--kles-table-divider-color)}:host tr.mat-mdc-footer-row{font-weight:500}:host .mat-mdc-header-row,:host .mat-mdc-header-cell{background-color:var(--kles-table-header-background);color:var(--kles-table-header-color)}:host .mat-mdc-header-cell{border-bottom-color:var(--kles-table-header-divider-color)}.table-empty-state-overlay{position:absolute;inset-inline:0;top:var(--header-h, 56px);bottom:calc(var(--scroll-h, 0px) + var(--footer-h, 0px));z-index:400;overflow:hidden;background:var(--mat-sys-surface);display:grid;place-items:center}.table-empty-state-content{width:100%;height:100%}.scrollbar-hidden{scrollbar-width:none;-ms-overflow-style:none;overflow-y:hidden}.scrollbar-hidden::-webkit-scrollbar{display:none;overflow-y:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i16.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: i16.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i17.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i17.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i17.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i17.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i4.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i19.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i19.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i19.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i19.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i19.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i19.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i19.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i19.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i19.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i19.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i19.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i19.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: CdkTableModule }, { kind: "directive", type: i20.CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: i20.CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "ngmodule", type: KlesMaterialDynamicformsModule }, { kind: "directive", type: i21.KlesDynamicFieldDirective, selector: "[klesDynamicField]", inputs: ["field", "group", "ui", "siblingFields", "context"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i22.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i22.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: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i23.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: ResizableColumnDirective, selector: "th[appResizableColumn]", inputs: ["appResizableColumn"] }, { kind: "component", type: KlesCellComponent, selector: "kles-cell", inputs: ["ui", "group", "column"] }, { kind: "component", type: KlesHeaderComponent, selector: "kles-header", inputs: ["header", "group"] }, { kind: "pipe", type: HeaderFieldPipe, name: "headerField" }, { kind: "pipe", type: CellFieldPipe, name: "cellField" }, { kind: "pipe", type: UiFieldPipe, name: "uiField" }, { kind: "pipe", type: FooterFieldPipe, name: "footerField" }, { kind: "pipe", type: SpanPipe, name: "spanPipe" }, { kind: "pipe", type: ExtraCellFieldPipe, name: "extraCellField" }, { kind: "pipe", type: ResolveNgStylePipe, name: "resolveNgStyle" }, { kind: "pipe", type: HeaderPipe, name: "header" }, { kind: "pipe", type: RowContextPipe, name: "rowContext" }] }); }
2073
2229
  }
2074
2230
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: TableComponent, decorators: [{
2075
2231
  type: Component,
@@ -2098,7 +2254,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
2098
2254
  KlesCellComponent,
2099
2255
  KlesHeaderComponent,
2100
2256
  HeaderPipe,
2101
- ], template: "<form #form [formGroup]=\"tableService.form\" (ngSubmit)=\"submit()\">\n <!-- [fixedLayout]=\"true\" -->\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n [trackBy]=\"multiTemplateDataRows() ? null : tableService.trackBy\"\n formArrayName=\"rows\"\n cdkDropList\n [cdkDropListData]=\"tableService.form.controls.rows\"\n (cdkDropListDropped)=\"dragDropRowService.listDropped($event)\"\n [cdkDropListDisabled]=\"!dragDropRowService.enable\"\n [cdkDropListAutoScrollStep]=\"dragDropRowService.autoScrollStep\"\n [cdkDropListSortPredicate]=\"dragDropRowService.sortPredicate\"\n [cdkDropListConnectedTo]=\"dragDropRowService.connectedTo\"\n [multiTemplateDataRows]=\"multiTemplateDataRows()\"\n >\n <colgroup>\n @for (column of columns(); track column.columnDef) {\n <col [style.width]=\"column.width ?? null\" [style.minWidth]=\"column.minWidth ?? null\" [style.maxWidth]=\"column.maxWidth ?? null\" />\n }\n </colgroup>\n\n @for (column of columns(); track column.columnDef) {\n <ng-container [cdkColumnDef]=\"column.columnDef\" [sticky]=\"column.sticky ?? false\" [stickyEnd]=\"column.stickyEnd ?? false\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [appResizableColumn]=\"column\"\n [style.border-inline-end]=\"getColumnSeparator(column, 'header') ?? getStickyStartSeparator(column, 'header')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'header')\"\n [ngStyle]=\"\n column.headerCell?.style?.ngStyle\n | resolveNgStyle\n : tableService.form.get(['header', column.columnDef])?.value\n : tableService.form.get(['header', column.columnDef])?.status\n : tableService.form.controls.header.value\n : tableService.form.controls.header.status\n \"\n >\n <div class=\"cell\">\n <kles-header [header]=\"column | header\" [group]=\"tableService.form.controls.header\">\n <ng-container\n klesDynamicField\n [field]=\"column | headerField\"\n [group]=\"tableService.form.controls.header\"\n [ui]=\"tableService.ui.states.header\"\n ></ng-container>\n </kles-header>\n </div>\n </th>\n\n <td\n mat-cell\n *cdkCellDef=\"let row; let index = index; let dataIndex = dataIndex\"\n [style.border-inline-end]=\"getColumnSeparator(column, 'body') ?? getStickyStartSeparator(column, 'body')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'body')\"\n [ngStyle]=\"\n column.cell?.style?.ngStyle\n | resolveNgStyle: row.controls[column.columnDef].value : row.controls[column.columnDef].status : row.value : row.status\n \"\n (click)=\"cellService.onClick($event, row, dataIndex ?? index, column.columnDef)\"\n (dblclick)=\"cellService.onDoubleClick($event, row, dataIndex ?? index, column.columnDef)\"\n (contextmenu)=\"cellService.onContextMenu($event, row, dataIndex ?? index, column.columnDef)\"\n >\n <div class=\"cell\" [style.--align]=\"column.align\">\n <kles-cell [group]=\"row\" [ui]=\"row | uiField\" [column]=\"column\">\n <ng-container klesDynamicField [field]=\"column | cellField\" [group]=\"row\" [ui]=\"row | uiField\"></ng-container>\n </kles-cell>\n </div>\n </td>\n\n <td\n mat-footer-cell\n *matFooterCellDef\n [style.border-inline-end]=\"getColumnSeparator(column, 'footer') ?? getStickyStartSeparator(column, 'footer')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'footer')\"\n [ngStyle]=\"\n column.footerCell?.style?.ngStyle\n | resolveNgStyle\n : tableService.form.get(['footer', column.columnDef])?.value\n : tableService.form.get(['footer', column.columnDef])?.status\n : tableService.form.controls.footer.value\n : tableService.form.controls.footer.status\n \"\n >\n @if (column.footerCell) {\n <ng-container\n klesDynamicField\n [field]=\"column | footerField\"\n [group]=\"tableService.form.controls.footer\"\n [ui]=\"tableService.ui.states.footer\"\n >\n </ng-container>\n }\n </td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns(); sticky: true\"></tr>\n\n <tr\n mat-row\n *matRowDef=\"let row; let index = index; let dataIndex = dataIndex; columns: displayedColumns()\"\n cdkDrag\n [cdkDragData]=\"row\"\n (click)=\"rowService.onClick($event, row, dataIndex ?? index)\"\n (dblclick)=\"rowService.onDoubleClick($event, row, dataIndex ?? index)\"\n (contextmenu)=\"rowService.onContextMenu($event, row, dataIndex ?? index)\"\n (mouseenter)=\"rowService.onMouseEnter($event, row, dataIndex ?? index)\"\n (mouseleave)=\"rowService.onMouseLeave($event, row, dataIndex ?? index)\"\n ></tr>\n\n @if (multiTemplateDataRows()) {\n @for (extraRow of extraRows(); track extraRow) {\n @for (extraColumn of extraRow.cells; track extraColumn.columnDef) {\n <ng-container [cdkColumnDef]=\"extraColumn.columnDef\">\n <td\n mat-cell\n *cdkCellDef=\"let row\"\n [attr.colspan]=\"extraColumn.colspan | spanPipe: displayedColumns().length\"\n [attr.rowspan]=\"extraColumn.rowspan\"\n [ngStyle]=\"\n extraColumn?.style?.ngStyle\n | resolveNgStyle\n : row.controls[extraColumn.columnDef].value\n : row.controls[extraColumn.columnDef].status\n : row.value\n : row.status\n \"\n >\n <ng-container klesDynamicField [field]=\"extraColumn | extraCellField\" [group]=\"row\" [ui]=\"row | uiField\"></ng-container>\n </td>\n </ng-container>\n }\n <tr\n mat-row\n *matRowDef=\"let row; let index = index; let dataIndex = dataIndex; columns: extraRow.displayedColumns; when: extraRow.when\"\n (click)=\"rowService.onClick($event, row, dataIndex ?? index)\"\n (dblclick)=\"rowService.onDoubleClick($event, row, dataIndex ?? index)\"\n (contextmenu)=\"rowService.onContextMenu($event, row, dataIndex ?? index)\"\n (mouseenter)=\"rowService.onMouseEnter($event, row, dataIndex ?? index)\"\n (mouseleave)=\"rowService.onMouseLeave($event, row, dataIndex ?? index)\"\n ></tr>\n }\n }\n\n <tr mat-footer-row *matFooterRowDef=\"displayedColumns(); sticky: true\" [style.display]=\"showFooter() ? '' : 'none'\"></tr>\n\n <tr *matNoDataRow [attr.colspan]=\"displayedColumns().length\">\n @if (!loadingService.loading()) {\n <!--no data TODO -->\n }\n </tr>\n </table>\n</form>\n\n@if (loadingService.loading()) {\n <div class=\"table-overlay\" [style.--header-h.px]=\"headerHeightPx\" [style.--scroll-h.px]=\"scrollHeightPx\" [style.--footer-h.px]=\"footerHeightPx\">\n <mat-spinner></mat-spinner>\n </div>\n}\n", styles: [":host{--kles-table-divider-color: color-mix(in srgb, var(--mat-sys-outline-variant) 65%, transparent);--kles-table-divider-strong-color: var(--mat-sys-outline-variant);--kles-table-header-background: var(--mat-sys-surface-container-low);--kles-table-header-color: var(--mat-sys-on-surface);--kles-table-header-divider-color: var(--mat-sys-outline-variant);--kles-table-row-hover-background: color-mix(in srgb, var(--mat-sys-primary) 7%, var(--mat-sys-surface));overflow:auto;display:flex;flex-direction:column;position:relative;height:100%;--mat-form-field-filled-container-color: transparent;--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0;--mat-form-field-state-layer-color: transparent}:host(.loading){min-height:350px}form{display:flex;flex-direction:column;flex-grow:1;position:relative;overflow:auto}table{width:100%;flex-grow:1}th,td{text-wrap:pretty;white-space:normal;padding-top:2px;padding-bottom:2px;box-sizing:border-box}td{word-break:normal}th .cell,td .cell{display:flex;flex-direction:column;justify-content:var(--align, center)}th[appResizableColumn]{position:relative}th[appResizableColumn] .resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;-webkit-user-select:none;user-select:none}.table-overlay{position:absolute;inset-inline:0;top:var(--header-h, 56px);bottom:calc(var(--scroll-h, 0px) + var(--footer-h, 0px));display:grid;place-items:center;background:color-mix(in srgb,var(--mat-sys-surface-container-highest) 75%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--mat-sys-outline-variant) 30%,transparent);z-index:500}:host .mat-mdc-row{transition:background-color .12s ease}:host .mat-mdc-row:hover{background:var(--kles-table-row-hover-background)}:host .mat-mdc-table .mat-mdc-cell,:host .mat-mdc-table .mat-mdc-header-cell{border-bottom-color:var(--mat-sys-outline-variant)}:host .mat-mdc-table .mat-mdc-cell:last-child,:host .mat-mdc-table .mat-mdc-header-cell:last-child{border-right:none}:host tr.mat-mdc-footer-row td.mat-mdc-footer-cell{border-top:1px solid var(--kles-table-divider-strong-color)}:host tr.mat-mdc-row:last-of-type td.mat-mdc-cell{border-bottom:1px solid var(--kles-table-divider-color)}:host tr.mat-mdc-footer-row{font-weight:500}:host .mat-mdc-header-row,:host .mat-mdc-header-cell{background-color:var(--kles-table-header-background);color:var(--kles-table-header-color)}:host .mat-mdc-header-cell{border-bottom-color:var(--kles-table-header-divider-color)}\n"] }]
2257
+ RowContextPipe
2258
+ ], template: "<form #form [formGroup]=\"tableService.form\" (ngSubmit)=\"submit()\">\n <!-- [fixedLayout]=\"true\" -->\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n [trackBy]=\"multiTemplateDataRows() ? null : tableService.trackBy\"\n formArrayName=\"rows\"\n cdkDropList\n [cdkDropListData]=\"tableService.form.controls.rows\"\n (cdkDropListDropped)=\"dragDropRowService.listDropped($event)\"\n [cdkDropListDisabled]=\"!dragDropRowService.enable\"\n [cdkDropListAutoScrollStep]=\"dragDropRowService.autoScrollStep\"\n [cdkDropListSortPredicate]=\"dragDropRowService.sortPredicate\"\n [cdkDropListConnectedTo]=\"dragDropRowService.connectedTo\"\n [multiTemplateDataRows]=\"multiTemplateDataRows()\"\n >\n <colgroup>\n @for (column of columns(); track column.columnDef) {\n <col [style.width]=\"column.width ?? null\" [style.minWidth]=\"column.minWidth ?? null\" [style.maxWidth]=\"column.maxWidth ?? null\" />\n }\n </colgroup>\n\n @for (column of columns(); track column.columnDef) {\n <ng-container [cdkColumnDef]=\"column.columnDef\" [sticky]=\"column.sticky ?? false\" [stickyEnd]=\"column.stickyEnd ?? false\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [appResizableColumn]=\"column\"\n [style.border-inline-end]=\"getColumnSeparator(column, 'header') ?? getStickyStartSeparator(column, 'header')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'header')\"\n [ngStyle]=\"\n column.headerCell?.style?.ngStyle\n | resolveNgStyle\n : tableService.form.get(['header', column.columnDef])?.value\n : tableService.form.get(['header', column.columnDef])?.status\n : tableService.form.controls.header.value\n : tableService.form.controls.header.status\n \"\n >\n <div class=\"cell\">\n <kles-header [header]=\"column | header\" [group]=\"tableService.form.controls.header\">\n <ng-container\n klesDynamicField\n [field]=\"column | headerField\"\n [group]=\"tableService.form.controls.header\"\n [ui]=\"tableService.ui.states.header\"\n ></ng-container>\n </kles-header>\n </div>\n </th>\n\n <td\n mat-cell\n *cdkCellDef=\"let row; let index = index; let dataIndex = dataIndex\"\n [style.border-inline-end]=\"getColumnSeparator(column, 'body') ?? getStickyStartSeparator(column, 'body')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'body')\"\n [ngStyle]=\"\n column.cell?.style?.ngStyle\n | resolveNgStyle: row.controls[column.columnDef].value : row.controls[column.columnDef].status : row.value : row.status\n \"\n (click)=\"cellService.onClick($event, row, dataIndex ?? index, column.columnDef)\"\n (dblclick)=\"cellService.onDoubleClick($event, row, dataIndex ?? index, column.columnDef)\"\n (contextmenu)=\"cellService.onContextMenu($event, row, dataIndex ?? index, column.columnDef)\"\n >\n <div class=\"cell\" [style.--align]=\"column.align\">\n <kles-cell [group]=\"row\" [ui]=\"row | uiField\" [column]=\"column\">\n <ng-container klesDynamicField [field]=\"column | cellField\" [group]=\"row\" [ui]=\"row | uiField\" [context]=\"row | rowContext\"></ng-container>\n </kles-cell>\n </div>\n </td>\n\n <td\n mat-footer-cell\n *matFooterCellDef\n [style.border-inline-end]=\"getColumnSeparator(column, 'footer') ?? getStickyStartSeparator(column, 'footer')\"\n [style.border-inline-start]=\"getStickyEndSeparator(column, 'footer')\"\n [ngStyle]=\"\n column.footerCell?.style?.ngStyle\n | resolveNgStyle\n : tableService.form.get(['footer', column.columnDef])?.value\n : tableService.form.get(['footer', column.columnDef])?.status\n : tableService.form.controls.footer.value\n : tableService.form.controls.footer.status\n \"\n >\n @if (column.footerCell) {\n <ng-container\n klesDynamicField\n [field]=\"column | footerField\"\n [group]=\"tableService.form.controls.footer\"\n [ui]=\"tableService.ui.states.footer\"\n >\n </ng-container>\n }\n </td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns(); sticky: true\"></tr>\n\n <tr\n mat-row\n *matRowDef=\"let row; let index = index; let dataIndex = dataIndex; columns: displayedColumns()\"\n cdkDrag\n [cdkDragData]=\"row\"\n (click)=\"rowService.onClick($event, row, dataIndex ?? index)\"\n (dblclick)=\"rowService.onDoubleClick($event, row, dataIndex ?? index)\"\n (contextmenu)=\"rowService.onContextMenu($event, row, dataIndex ?? index)\"\n (mouseenter)=\"rowService.onMouseEnter($event, row, dataIndex ?? index)\"\n (mouseleave)=\"rowService.onMouseLeave($event, row, dataIndex ?? index)\"\n ></tr>\n\n @if (multiTemplateDataRows()) {\n @for (extraRow of extraRows(); track extraRow) {\n @for (extraColumn of extraRow.cells; track extraColumn.columnDef) {\n <ng-container [cdkColumnDef]=\"extraColumn.columnDef\">\n <td\n mat-cell\n *cdkCellDef=\"let row\"\n [attr.colspan]=\"extraColumn.colspan | spanPipe: displayedColumns().length\"\n [attr.rowspan]=\"extraColumn.rowspan\"\n [ngStyle]=\"\n extraColumn?.style?.ngStyle\n | resolveNgStyle\n : row.controls[extraColumn.columnDef].value\n : row.controls[extraColumn.columnDef].status\n : row.value\n : row.status\n \"\n >\n <ng-container klesDynamicField [field]=\"extraColumn | extraCellField\" [group]=\"row\" [ui]=\"row | uiField\" [context]=\"row | rowContext\"></ng-container>\n </td>\n </ng-container>\n }\n <tr\n mat-row\n *matRowDef=\"let row; let index = index; let dataIndex = dataIndex; columns: extraRow.displayedColumns; when: extraRow.when\"\n (click)=\"rowService.onClick($event, row, dataIndex ?? index)\"\n (dblclick)=\"rowService.onDoubleClick($event, row, dataIndex ?? index)\"\n (contextmenu)=\"rowService.onContextMenu($event, row, dataIndex ?? index)\"\n (mouseenter)=\"rowService.onMouseEnter($event, row, dataIndex ?? index)\"\n (mouseleave)=\"rowService.onMouseLeave($event, row, dataIndex ?? index)\"\n ></tr>\n }\n }\n\n <tr mat-footer-row *matFooterRowDef=\"displayedColumns(); sticky: true\" [style.display]=\"showFooter() ? '' : 'none'\"></tr>\n </table>\n</form>\n\n@if (loadingService.loading()) {\n <div class=\"table-overlay\" [style.--header-h.px]=\"headerHeightPx\" [style.--scroll-h.px]=\"scrollHeightPx\" [style.--footer-h.px]=\"footerHeightPx\">\n <mat-spinner></mat-spinner>\n </div>\n}\n\n@if (emptyStateService.enabled() && !loadingService.loading() && isEmpty()) {\n <div\n class=\"table-empty-state-overlay\"\n [style.--header-h.px]=\"headerHeightPx\"\n [style.--scroll-h.px]=\"scrollHeightPx\"\n [style.--footer-h.px]=\"footerHeightPx\"\n >\n <div class=\"table-empty-state-content\">\n <ng-container *ngComponentOutlet=\"emptyStateService.component\"></ng-container>\n </div>\n </div>\n}\n", styles: [":host{--kles-table-divider-color: color-mix(in srgb, var(--mat-sys-outline-variant) 65%, transparent);--kles-table-divider-strong-color: var(--mat-sys-outline-variant);--kles-table-header-background: var(--mat-sys-surface-container-low);--kles-table-header-color: var(--mat-sys-on-surface);--kles-table-header-divider-color: var(--mat-sys-outline-variant);--kles-table-row-hover-background: color-mix(in srgb, var(--mat-sys-primary) 7%, var(--mat-sys-surface));overflow:auto;display:flex;flex-direction:column;position:relative;height:100%;--mat-form-field-filled-container-color: transparent;--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0;--mat-form-field-state-layer-color: transparent}:host(.loading),:host(.empty){min-height:280px}form{display:flex;flex-direction:column;flex-grow:1;position:relative;overflow:auto}table{width:100%;flex-grow:1}th,td{text-wrap:pretty;white-space:normal;padding-top:2px;padding-bottom:2px;box-sizing:border-box}td{word-break:normal}th .cell,td .cell{display:flex;flex-direction:column;justify-content:var(--align, center)}th[appResizableColumn]{position:relative}th[appResizableColumn] .resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;-webkit-user-select:none;user-select:none}.table-overlay{position:absolute;inset-inline:0;top:var(--header-h, 56px);bottom:calc(var(--scroll-h, 0px) + var(--footer-h, 0px));display:grid;place-items:center;background:color-mix(in srgb,var(--mat-sys-surface-container-highest) 75%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--mat-sys-outline-variant) 30%,transparent);z-index:500}:host .mat-mdc-row{transition:background-color .12s ease}:host .mat-mdc-row:hover{background:var(--kles-table-row-hover-background)}:host .mat-mdc-table .mat-mdc-cell,:host .mat-mdc-table .mat-mdc-header-cell{border-bottom-color:var(--mat-sys-outline-variant)}:host .mat-mdc-table .mat-mdc-cell:last-child,:host .mat-mdc-table .mat-mdc-header-cell:last-child{border-right:none}:host tr.mat-mdc-footer-row td.mat-mdc-footer-cell{border-top:1px solid var(--kles-table-divider-strong-color)}:host tr.mat-mdc-row:last-of-type td.mat-mdc-cell{border-bottom:1px solid var(--kles-table-divider-color)}:host tr.mat-mdc-footer-row{font-weight:500}:host .mat-mdc-header-row,:host .mat-mdc-header-cell{background-color:var(--kles-table-header-background);color:var(--kles-table-header-color)}:host .mat-mdc-header-cell{border-bottom-color:var(--kles-table-header-divider-color)}.table-empty-state-overlay{position:absolute;inset-inline:0;top:var(--header-h, 56px);bottom:calc(var(--scroll-h, 0px) + var(--footer-h, 0px));z-index:400;overflow:hidden;background:var(--mat-sys-surface);display:grid;place-items:center}.table-empty-state-content{width:100%;height:100%}.scrollbar-hidden{scrollbar-width:none;-ms-overflow-style:none;overflow-y:hidden}.scrollbar-hidden::-webkit-scrollbar{display:none;overflow-y:hidden}\n"] }]
2102
2259
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: KlesTableConnectorService }, { type: undefined, decorators: [{
2103
2260
  type: Inject,
2104
2261
  args: [LOADER_SERVICE]
@@ -2119,7 +2276,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
2119
2276
  args: [SORT_SERVICE]
2120
2277
  }] }, { type: FilterService, decorators: [{
2121
2278
  type: Optional
2122
- }] }, { type: ExpandedRowStore }, { type: RowFormFactory }, { type: EventsService }, { type: RowService }, { type: CellService }], propDecorators: { table: [{
2279
+ }] }, { type: ExpandedRowStore }, { type: RowFormFactory }, { type: EventsService }, { type: RowService }, { type: CellService }, { type: EmptyStateService }], propDecorators: { table: [{
2123
2280
  type: ViewChild,
2124
2281
  args: [MatTable]
2125
2282
  }], matSort: [{
@@ -2131,6 +2288,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
2131
2288
  }], isLoadingClass: [{
2132
2289
  type: HostBinding,
2133
2290
  args: ['class.loading']
2291
+ }], isEmptyClass: [{
2292
+ type: HostBinding,
2293
+ args: ['class.empty']
2134
2294
  }] } });
2135
2295
 
2136
2296
  function isDestroyable(value) {
@@ -2271,7 +2431,7 @@ class SortService extends AbstractSortService {
2271
2431
  return data.sort((a, b) => {
2272
2432
  let valueA;
2273
2433
  let valueB;
2274
- if (column?.headerCell.sortPredicate) {
2434
+ if (column?.headerCell?.sortPredicate) {
2275
2435
  valueA = column?.headerCell.sortPredicate(a);
2276
2436
  valueB = column?.headerCell.sortPredicate(b);
2277
2437
  }
@@ -2279,7 +2439,7 @@ class SortService extends AbstractSortService {
2279
2439
  valueA = this.sortingDataAccessor(a, active);
2280
2440
  valueB = this.sortingDataAccessor(b, active);
2281
2441
  if (column) {
2282
- const key = column.cell?.field.property;
2442
+ const key = column.cell?.field?.property;
2283
2443
  if (key) {
2284
2444
  valueA = valueA?.[key];
2285
2445
  valueB = valueB?.[key];
@@ -2382,7 +2542,7 @@ class InfiniteScrollTableComponent {
2382
2542
  }
2383
2543
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InfiniteScrollTableComponent, decorators: [{
2384
2544
  type: Component,
2385
- args: [{ selector: 'kles-infinite-scroll-table', standalone: true, imports: [CommonModule, TableComponent, ScrollingModule], template: "<!-- <cdk-virtual-scroll-viewport itemSize=\"48\">\n <kles-table></kles-table>\n</cdk-virtual-scroll-viewport> -->\n" }]
2545
+ args: [{ selector: 'kles-infinite-scroll-table', standalone: true, imports: [CommonModule, ScrollingModule], template: "<!-- <cdk-virtual-scroll-viewport itemSize=\"48\">\n <kles-table></kles-table>\n</cdk-virtual-scroll-viewport> -->\n" }]
2386
2546
  }], ctorParameters: () => [] });
2387
2547
 
2388
2548
  class SelectionLoaderService {
@@ -3173,6 +3333,7 @@ class LinesService {
3173
3333
  this.eventsService = eventsService;
3174
3334
  this.destroyRef = inject(DestroyRef);
3175
3335
  this._loaded = new EventEmitter();
3336
+ this._loading = new EventEmitter();
3176
3337
  }
3177
3338
  register() {
3178
3339
  this.load();
@@ -3183,6 +3344,9 @@ class LinesService {
3183
3344
  loaded() {
3184
3345
  return this._loaded;
3185
3346
  }
3347
+ loading() {
3348
+ return this._loading;
3349
+ }
3186
3350
  load() {
3187
3351
  this.loader
3188
3352
  .load()
@@ -3190,6 +3354,7 @@ class LinesService {
3190
3354
  .subscribe((response) => {
3191
3355
  if (response.loading) {
3192
3356
  this.eventsService.emit('loadStart');
3357
+ this._loading.next();
3193
3358
  }
3194
3359
  else {
3195
3360
  if (response.error) {
@@ -3201,7 +3366,7 @@ class LinesService {
3201
3366
  else {
3202
3367
  this.fm.setRows(this.rowFactory.createRows(this.columnsService
3203
3368
  .columns()
3204
- .map((col) => ({ ...col.cell.field, name: col.columnDef }))
3369
+ .map((col) => ({ ...col.cell?.field, name: col.columnDef }))
3205
3370
  .concat(this.extraRowService.extraColumns().map((col) => ({ ...col, name: col.columnDef }))), response.items ?? []));
3206
3371
  this._total = response.items?.length ?? 0;
3207
3372
  this._loaded.next();
@@ -3236,6 +3401,7 @@ class LinesLazyService {
3236
3401
  this.destroyRef = inject(DestroyRef);
3237
3402
  this._refresh$ = new Subject();
3238
3403
  this._loaded = new EventEmitter();
3404
+ this._loading = new EventEmitter();
3239
3405
  }
3240
3406
  register() {
3241
3407
  this.load();
@@ -3246,6 +3412,9 @@ class LinesLazyService {
3246
3412
  loaded() {
3247
3413
  return this._loaded;
3248
3414
  }
3415
+ loading() {
3416
+ return this._loading;
3417
+ }
3249
3418
  refresh() {
3250
3419
  this._refresh$.next();
3251
3420
  }
@@ -3255,6 +3424,7 @@ class LinesLazyService {
3255
3424
  .pipe(takeUntilDestroyed(this.destroyRef))
3256
3425
  .subscribe((response) => {
3257
3426
  if (response.loading) {
3427
+ this._loading.next();
3258
3428
  this.eventsService.emit('loadStart');
3259
3429
  }
3260
3430
  else {
@@ -3267,7 +3437,7 @@ class LinesLazyService {
3267
3437
  else {
3268
3438
  this.fm.setRows(this.rowFactory.createRows(this.columnsService
3269
3439
  .columns()
3270
- .map((col) => ({ ...col.cell.field, name: col.columnDef }))
3440
+ .map((col) => ({ ...col.cell?.field, name: col.columnDef }))
3271
3441
  .concat(this.extraRowService.extraColumns().map((col) => ({ ...col, name: col.columnDef }))), response.items));
3272
3442
  this.paginatorService.setlength(response.total ?? 0);
3273
3443
  this._total = response.total ?? 0;
@@ -3395,6 +3565,13 @@ class ScrollbarOrchestratorService {
3395
3565
  .pipe(takeUntilDestroyed(this.destroyRef))
3396
3566
  .subscribe(() => {
3397
3567
  this.scrollbarService.toTop('instant');
3568
+ this.scrollbarService.showScrollbar();
3569
+ });
3570
+ this.linesService
3571
+ .loading()
3572
+ .pipe(takeUntilDestroyed(this.destroyRef))
3573
+ .subscribe(() => {
3574
+ this.scrollbarService.hideScrollbar();
3398
3575
  });
3399
3576
  this.paginatorService
3400
3577
  ?.pageChanged()
@@ -3440,6 +3617,13 @@ class ScrollbarLazyOrchestratorService {
3440
3617
  .pipe(takeUntilDestroyed(this.destroyRef))
3441
3618
  .subscribe(() => {
3442
3619
  this.scrollbarService.toTop('instant');
3620
+ this.scrollbarService.showScrollbar();
3621
+ });
3622
+ this.linesService
3623
+ .loading()
3624
+ .pipe(takeUntilDestroyed(this.destroyRef))
3625
+ .subscribe(() => {
3626
+ this.scrollbarService.hideScrollbar();
3443
3627
  });
3444
3628
  }
3445
3629
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: ScrollbarLazyOrchestratorService, deps: [{ token: LINES_SERVICE }, { token: ScrollbarService }], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -3458,7 +3642,7 @@ class DynamicTableLoaderDirective {
3458
3642
  this.viewContainerRef = viewContainerRef;
3459
3643
  this.tableConfig = input.required({ ...(ngDevMode ? { debugName: "tableConfig" } : /* istanbul ignore next */ {}), transform: (v) => {
3460
3644
  v.columns = v.columns.map((col) => {
3461
- if (col.headerCell.field) {
3645
+ if (col.headerCell?.field) {
3462
3646
  col.headerCell.field.subscriptSizing = col.headerCell.field.subscriptSizing ?? 'dynamic';
3463
3647
  }
3464
3648
  return { ...col, separator: col.separator ?? v.columnSeparator ?? false };
@@ -3508,7 +3692,9 @@ class DynamicTableLoaderDirective {
3508
3692
  }
3509
3693
  }
3510
3694
  initInjector() {
3511
- const storeProviders = [SortStore, FilterStore, ...(this.tableConfig().paginator ? [PaginatorStore] : []), ExpandedRowStore];
3695
+ const storeProviders = [RowContextStore, SortStore, FilterStore, ...(this.tableConfig().paginator ? [PaginatorStore] : []), ExpandedRowStore];
3696
+ const emptyState = this.tableConfig().emptyState;
3697
+ const emptyStateIntl = typeof emptyState === 'object' && emptyState !== null ? emptyState.intl : undefined;
3512
3698
  const configProviders = [
3513
3699
  {
3514
3700
  provide: COLUMNS,
@@ -3554,6 +3740,18 @@ class DynamicTableLoaderDirective {
3554
3740
  },
3555
3741
  ]
3556
3742
  : []),
3743
+ {
3744
+ provide: EMPTY_STATE_CONFIG,
3745
+ useValue: emptyState,
3746
+ },
3747
+ ...(emptyStateIntl
3748
+ ? [
3749
+ {
3750
+ provide: KlesTableIntl,
3751
+ useClass: emptyStateIntl,
3752
+ },
3753
+ ]
3754
+ : []),
3557
3755
  ];
3558
3756
  const orchestratorProviders = [
3559
3757
  LoadingOrchestratorService,
@@ -3588,6 +3786,7 @@ class DynamicTableLoaderDirective {
3588
3786
  TreeService,
3589
3787
  RenderService,
3590
3788
  ExtraRowService,
3789
+ EmptyStateService,
3591
3790
  LoadingService,
3592
3791
  KlesForm,
3593
3792
  ColumnsService,
@@ -3846,5 +4045,5 @@ var AlignCell;
3846
4045
  * Generated bundle index. Do not edit.
3847
4046
  */
3848
4047
 
3849
- export { AlignCell, COLUMNS, DATASOURCE_SERVICE, DRAG_DROP_CONFIG, EXTRA_ROWS, FOOTER, HEADER_SERVICE, KlesMaterialTableModule, KlesTableComponent, LINES_SERVICE, LOADER_CONFIG, LOADER_SERVICE, PAGINATOR_CONFIG, ROW_DRAG_DROP, SCROLLBAR_ORCHESTRATOR_SERVICE, SELECTION_CONFIG, SELECTION_SERVICE, SORT_CONFIG, SORT_SERVICE, Span, TABLE_SERVICE, TableComponent, linesLazyLoader, linesLoader, selectionConfig };
4048
+ export { AlignCell, COLUMNS, DATASOURCE_SERVICE, DRAG_DROP_CONFIG, EMPTY_STATE_CONFIG, EXTRA_ROWS, FOOTER, HEADER_SERVICE, KlesMaterialTableModule, KlesTableComponent, KlesTableEmptyStateComponent, KlesTableIntl, LINES_SERVICE, LOADER_CONFIG, LOADER_SERVICE, PAGINATOR_CONFIG, ROW_DRAG_DROP, SCROLLBAR_ORCHESTRATOR_SERVICE, SELECTION_CONFIG, SELECTION_SERVICE, SORT_CONFIG, SORT_SERVICE, Span, TABLE_SERVICE, TableComponent, linesLazyLoader, linesLoader, selectionConfig };
3850
4049
  //# sourceMappingURL=3kles-kles-material-table-v2.mjs.map