@planeasyinc/le-angular 0.0.5 → 0.0.7

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,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, signal, Injectable, computed, Directive, input, ChangeDetectionStrategy, Component, output, forwardRef, effect, untracked, ViewContainerRef, Renderer2, ElementRef, DestroyRef, viewChild } from '@angular/core';
2
+ import { InjectionToken, inject, signal, Injectable, computed, effect, untracked, Directive, input, ChangeDetectionStrategy, Component, output, forwardRef, ViewContainerRef, Renderer2, ElementRef, DestroyRef, viewChild } from '@angular/core';
3
3
  import { HttpContextToken, HttpClient, HttpContext, HttpRequest, HttpEventType } from '@angular/common/http';
4
- import { map, filter, distinctUntilChanged, BehaviorSubject, Subject, firstValueFrom, of, tap, catchError, from, concatMap, finalize, fromEvent, takeUntil, startWith } from 'rxjs';
4
+ import { map, filter, distinctUntilChanged, BehaviorSubject, Subject, takeUntil, firstValueFrom, of, tap, catchError, from, concatMap, finalize, fromEvent, startWith } from 'rxjs';
5
5
  import { decodeJwt, UrlFragmentBuilder, normalizeConfig } from '@planeasyinc/le-core';
6
+ import { Location, JsonPipe, ViewportScroller } from '@angular/common';
6
7
  import { CdkDrag } from '@angular/cdk/drag-drop';
7
8
  import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
8
9
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@@ -10,7 +11,6 @@ import { coerceNumberProperty } from '@angular/cdk/coercion';
10
11
  import { DataSource, CdkTable, CdkColumnDef, CdkHeaderCell, CdkHeaderCellDef, CdkCell, CdkCellDef, CdkHeaderRowDef, CdkHeaderRow, CdkRow, CdkRowDef } from '@angular/cdk/table';
11
12
  import { CdkMenuTrigger, CdkMenu, CdkMenuItem } from '@angular/cdk/menu';
12
13
  import { A11yModule } from '@angular/cdk/a11y';
13
- import { JsonPipe, ViewportScroller } from '@angular/common';
14
14
  import { adaptOld } from '@planeasyinc/fe-adapters-old';
15
15
  import { adaptSections } from '@planeasyinc/fe-adapters-sections';
16
16
  import { createEngine } from '@planeasyinc/fe-core';
@@ -25,6 +25,8 @@ const IS_LIBRARY_REQUEST = new HttpContextToken(() => false);
25
25
 
26
26
  const defaultConfig = {
27
27
  apiUrl: '',
28
+ withRouting: false,
29
+ rootPath: '/',
28
30
  messages: {
29
31
  tokenEmpty: 'No token provided',
30
32
  tokenExpired: 'Your session has expired for security reasons. Please log in again to continue where you left off.',
@@ -140,8 +142,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
140
142
  type: Injectable
141
143
  }] });
142
144
 
145
+ class LeNavigationService {
146
+ location = inject(Location);
147
+ config = inject(CONFIG_TOKEN);
148
+ _node = signal(null);
149
+ node = this._node.asReadonly();
150
+ constructor() {
151
+ effect((onCleanup) => {
152
+ if (!this.config.withRouting)
153
+ return;
154
+ const unregister = this.location.onUrlChange((url, state) => {
155
+ this._node.set(state.node ?? null);
156
+ });
157
+ onCleanup(() => {
158
+ unregister();
159
+ });
160
+ });
161
+ }
162
+ navigate(node) {
163
+ if (!this.config.withRouting)
164
+ return;
165
+ const path = this.mapNodeToLocationPath(node);
166
+ this.location.go(`/v2/${path}`, undefined, { node });
167
+ }
168
+ mapNodeToLocationPath(node) {
169
+ let pathChunks = [];
170
+ let query = '';
171
+ if (node.type === 'table') {
172
+ pathChunks.push(node?.title || node?.dataSource?.entity);
173
+ if (node?.dataSource?.params) {
174
+ query = Object.entries(node.dataSource.params).map(entry => entry.join('=')).join('&');
175
+ }
176
+ }
177
+ if (node.type === 'form') {
178
+ pathChunks.push('details', node.controlSource?.kind, node.controlSource?.entity, node.controlSource?.params?.className, node.controlSource?.params?.address, node.controlSource?.params?.mode);
179
+ }
180
+ const path = pathChunks.filter(v => !!v).join('/');
181
+ return query ? `${path}?${query}` : path;
182
+ }
183
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
184
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeNavigationService });
185
+ }
186
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeNavigationService, decorators: [{
187
+ type: Injectable
188
+ }], ctorParameters: () => [] });
189
+
143
190
  class LEDataService {
144
191
  apiService = inject(LEApiService);
192
+ leNavigationService = inject(LeNavigationService);
145
193
  _config = signal(null);
146
194
  _view = signal(null);
147
195
  _parentPath = signal([]);
@@ -150,8 +198,22 @@ class LEDataService {
150
198
  parentPath = this._parentPath.asReadonly();
151
199
  config = this._config.asReadonly();
152
200
  customCss = this._customCss.asReadonly();
201
+ constructor() {
202
+ effect(() => {
203
+ const node = this.leNavigationService.node();
204
+ if (!node)
205
+ return;
206
+ untracked(() => {
207
+ const view = this.view();
208
+ if (node.id === view.id)
209
+ return;
210
+ this._view.set(node);
211
+ });
212
+ });
213
+ }
153
214
  setView(node) {
154
215
  this._view.set(node);
216
+ this.leNavigationService.navigate(node);
155
217
  }
156
218
  requestConfig(force) {
157
219
  if (this._config() && !force) {
@@ -163,7 +225,7 @@ class LEDataService {
163
225
  this._config.set(normalizedConfig);
164
226
  this._customCss.set(config.custom_css);
165
227
  const initialView = this.getInitialView(normalizedConfig);
166
- this._view.set(initialView.node);
228
+ this.setView(initialView.node);
167
229
  this._parentPath.set(initialView.path);
168
230
  },
169
231
  error: (err) => {
@@ -186,16 +248,14 @@ class LEDataService {
186
248
  }
187
249
  }
188
250
  getNodeById(id, node = this._config()) {
189
- if (node?.id) {
190
- if (node.id === id) {
191
- return node;
192
- }
193
- if ('children' in node) {
194
- for (const child of node.children) {
195
- const childNode = this.getNodeById(id, child);
196
- if (childNode) {
197
- return childNode;
198
- }
251
+ if (node.id === id) {
252
+ return node;
253
+ }
254
+ if ('children' in node && node.children.length) {
255
+ for (const child of node.children) {
256
+ const target = this.getNodeById(id, child);
257
+ if (target) {
258
+ return target;
199
259
  }
200
260
  }
201
261
  }
@@ -222,7 +282,7 @@ class LEDataService {
222
282
  }
223
283
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LEDataService, decorators: [{
224
284
  type: Injectable
225
- }] });
285
+ }], ctorParameters: () => [] });
226
286
 
227
287
  class LEFiltersService {
228
288
  _shown = signal(false);
@@ -771,13 +831,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
771
831
 
772
832
  class ReferenceTemplate {
773
833
  data = input.required();
834
+ attribute = input.required();
835
+ metadata = input.required();
836
+ reference = computed(() => {
837
+ const data = this.data();
838
+ return {
839
+ text: this.generateText(data),
840
+ href: this.generateLink(data),
841
+ };
842
+ });
843
+ onClick(event) {
844
+ event.stopImmediatePropagation();
845
+ }
846
+ generateText(data) {
847
+ if (data && data.ref) {
848
+ return data.ref.display_name || data.ref.object_id;
849
+ }
850
+ return '';
851
+ }
852
+ generateLink(data) {
853
+ if (data && data.ref) {
854
+ const href = `/details/object/${data.ref.class_name}/${data.ref.resource}%2523${data.ref.class_name}%253A${data.ref.class_version}%253A${data.ref.object_id}%253A${data.ref.object_version}`;
855
+ return data.ref?.address ? `${href}?address=${data.ref.address}` : href;
856
+ }
857
+ }
774
858
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ReferenceTemplate, deps: [], target: i0.ɵɵFactoryTarget.Component });
775
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: ReferenceTemplate, isStandalone: true, selector: "ng-component", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `<span class="le-table-template le-template-reference"></span>`, isInline: true });
859
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ReferenceTemplate, isStandalone: true, selector: "ng-component", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, attribute: { classPropertyName: "attribute", publicName: "attribute", isSignal: true, isRequired: true, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
860
+ <span class="le-table-template le-template-reference">
861
+ @if (reference(); as reference) {
862
+ @if (reference.href) {
863
+ <a
864
+ [href]="reference.href"
865
+ [attr.aria-label]="reference.text"
866
+ (click)="onClick($event)"
867
+ target="_blank"
868
+ >{{ reference.text }}</a
869
+ >
870
+ } @else {
871
+ {{ reference.text }}
872
+ }
873
+ }
874
+ </span>
875
+ `, isInline: true });
776
876
  }
777
877
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ReferenceTemplate, decorators: [{
778
878
  type: Component,
779
879
  args: [{
780
- template: `<span class="le-table-template le-template-reference"></span>`,
880
+ template: `
881
+ <span class="le-table-template le-template-reference">
882
+ @if (reference(); as reference) {
883
+ @if (reference.href) {
884
+ <a
885
+ [href]="reference.href"
886
+ [attr.aria-label]="reference.text"
887
+ (click)="onClick($event)"
888
+ target="_blank"
889
+ >{{ reference.text }}</a
890
+ >
891
+ } @else {
892
+ {{ reference.text }}
893
+ }
894
+ }
895
+ </span>
896
+ `,
781
897
  }]
782
898
  }] });
783
899
 
@@ -814,6 +930,8 @@ class TableViewCellDirective {
814
930
  componentRef;
815
931
  type = input();
816
932
  data = input.required();
933
+ column = input();
934
+ metadata = input();
817
935
  constructor() {
818
936
  this.setEffects();
819
937
  }
@@ -821,6 +939,8 @@ class TableViewCellDirective {
821
939
  effect(() => {
822
940
  const type = this.type();
823
941
  const data = this.data();
942
+ const column = this.column();
943
+ const metadata = this.metadata();
824
944
  untracked(() => {
825
945
  const component = (type && TABLE_CELL_TEMPLATES[type]) || TABLE_CELL_TEMPLATES['StringTemplate'];
826
946
  if (this.componentRef) {
@@ -828,11 +948,19 @@ class TableViewCellDirective {
828
948
  }
829
949
  this.componentRef = this.vcr.createComponent(component);
830
950
  this.componentRef?.setInput('data', data);
951
+ if (type === 'ReferenceTemplate') {
952
+ if (column) {
953
+ this.componentRef?.setInput('attribute', column);
954
+ }
955
+ if (metadata) {
956
+ this.componentRef?.setInput('metadata', metadata);
957
+ }
958
+ }
831
959
  });
832
960
  });
833
961
  }
834
962
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TableViewCellDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
835
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.21", type: TableViewCellDirective, isStandalone: true, selector: "[tableViewCell]", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
963
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.21", type: TableViewCellDirective, isStandalone: true, selector: "[tableViewCell]", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
836
964
  }
837
965
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TableViewCellDirective, decorators: [{
838
966
  type: Directive,
@@ -882,6 +1010,10 @@ class TableViewComponent {
882
1010
  constructor() {
883
1011
  this.setEffects();
884
1012
  }
1013
+ ngOnDestroy() {
1014
+ this._cancelRequest$.next();
1015
+ this._cancelRequest$.complete();
1016
+ }
885
1017
  onPageChange(pageChange) {
886
1018
  this._pageSize.set(pageChange.pageSize);
887
1019
  this._pageIndex.set(pageChange.pageIndex);
@@ -936,7 +1068,9 @@ class TableViewComponent {
936
1068
  getTableData(node, ctx) {
937
1069
  this._isLoading.set(true);
938
1070
  this._cancelRequest$.next();
939
- this.buildRequest(node, ctx).subscribe({
1071
+ this.buildRequest(node, ctx)
1072
+ .pipe(takeUntil(this._cancelRequest$))
1073
+ .subscribe({
940
1074
  next: (response) => {
941
1075
  this.handleTableDataSuccessResponse(response);
942
1076
  },
@@ -1038,7 +1172,7 @@ class TableViewComponent {
1038
1172
  });
1039
1173
  }
1040
1174
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TableViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1041
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: TableViewComponent, isStandalone: true, selector: "table-view", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"le-toolbar\">\n @if (node(); as node) {\n <h2>{{ node?.title }}</h2>\n\n\n <span class=\"spacer\"></span>\n\n @if (filters().length) {\n <button class=\"le-button\" (click)=\"onFiltersClick($event)\">Filters</button>\n }\n\n @if (node.actions?.tableActions) {\n <table-view-actions\n [actions]=\"node.actions!.tableActions\"\n (actionClicked)=\"onToolbarActionClick($event)\"\n ></table-view-actions>\n }\n }\n</div>\n\n@if (pageSize()) {\n <table-view-pagination\n [pageSize]=\"pageSize()\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [entriesCount]=\"entriesCount()\"\n (pageChange)=\"onPageChange($event)\"\n ></table-view-pagination>\n}\n\n<div class=\"le-table-container\">\n @if (displayedColumns().length) {\n <table cdk-table [dataSource]=\"data()\" class=\"le-table\" [class.le-table--loading]=\"isLoading()\">\n @for (column of columns(); track column) {\n <ng-container [cdkColumnDef]=\"column.key\">\n <th\n class=\"le-table-header-cell\"\n cdk-header-cell\n *cdkHeaderCellDef\n [tabindex]=\"sortColumnKeys().has(column.key) ? 0 : -1\"\n [class.le-table-header-cell--sortable]=\"sortColumnKeys().has(column.key)\"\n (click)=\"sortColumnKeys().has(column.key) && onSortClick($event, column)\"\n >\n <div class=\"le-cell-content\">\n <ng-template\n tableViewCell\n [data]=\"column.label\"\n [type]=\"column.column_format?.headerTemplate\"\n ></ng-template>\n\n @if (sortColumnKeys().has(column.key)) {\n <div class=\"le-sort-container\">\n @if (sortMap().has(column.key)) {\n <div class=\"le-sort-icon\">\n <i\n class=\"le-sort-arrow\"\n [class.le-sort-arrow--asc]=\"sortMap().get(column.key) === 'asc'\"\n [class.le-sort-arrow--desc]=\"sortMap().get(column.key) === 'desc'\"\n ></i>\n </div>\n\n <div class=\"le-sort-order\">\n @if (sortOrder().has(column.key)) {\n <span>\n {{ sortOrder().get(column.key) }}\n </span>\n }\n </div>\n } @else {\n<!-- <div class=\"le-sort-icon le-sort-icon&#45;&#45;unfold\">-->\n<!-- <span>&#8645;</span>-->\n<!-- </div>-->\n\n <le-icon name=\"sort\" class=\"le-sort-icon le-sort-icon--unfold\"></le-icon>\n }\n </div>\n }\n </div>\n </th>\n\n <td class=\"le-table-cell\" cdk-cell *cdkCellDef=\"let row\">\n <ng-template\n tableViewCell\n [data]=\"row[column.key]\"\n [type]=\"column.column_format?.cellTemplate\"\n ></ng-template>\n </td>\n </ng-container>\n }\n\n <tr cdk-header-row class=\"le-header-row\" *cdkHeaderRowDef=\"displayedColumns()\"></tr>\n <tr\n cdk-row\n class=\"le-table-row\"\n [tabindex]=\"0\"\n [class.le-table-row--clickable]=\"hasRowClickAction()\"\n *cdkRowDef=\"let row; columns: displayedColumns()\"\n (click)=\"onRowClick(row)\"\n ></tr>\n </table>\n }\n</div>\n\n@if (data().count === 0) {\n @if (isLoading()) {\n <app-loading-view [headerHeight]=\"65\" [rowCount]=\"pageSize() || 10\"></app-loading-view>\n } @else {\n <div class=\"no-entities\">\n <span>No Entities</span>\n </div>\n }\n}\n", dependencies: [{ kind: "component", type: CdkTable, selector: "cdk-table, table[cdk-table]", inputs: ["trackBy", "dataSource", "multiTemplateDataRows", "fixedLayout"], outputs: ["contentChanged"], exportAs: ["cdkTable"] }, { kind: "directive", type: CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: CdkHeaderCell, selector: "cdk-header-cell, th[cdk-header-cell]" }, { kind: "directive", type: CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: CdkCell, selector: "cdk-cell, td[cdk-cell]" }, { kind: "directive", type: CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "component", type: CdkHeaderRow, selector: "cdk-header-row, tr[cdk-header-row]" }, { kind: "component", type: CdkRow, selector: "cdk-row, tr[cdk-row]" }, { kind: "directive", type: CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "component", type: TableViewPaginationComponent, selector: "table-view-pagination", inputs: ["pageSize", "pageSizeOptions", "entriesCount"], outputs: ["pageChange"] }, { kind: "component", type: LoadingViewComponent, selector: "app-loading-view", inputs: ["headerHeight", "rowHeight", "rowCount"] }, { kind: "component", type: TableViewActions, selector: "table-view-actions", inputs: ["actions"], outputs: ["actionClicked"] }, { kind: "directive", type: TableViewCellDirective, selector: "[tableViewCell]", inputs: ["type", "data"] }, { kind: "component", type: LeIconComponent, selector: "le-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1175
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: TableViewComponent, isStandalone: true, selector: "table-view", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"le-toolbar\">\n @if (node(); as node) {\n <h2>{{ node?.title }}</h2>\n\n\n <span class=\"spacer\"></span>\n\n @if (filters().length) {\n <button class=\"le-button\" (click)=\"onFiltersClick($event)\">Filters</button>\n }\n\n @if (node.actions?.tableActions) {\n <table-view-actions\n [actions]=\"node.actions!.tableActions\"\n (actionClicked)=\"onToolbarActionClick($event)\"\n ></table-view-actions>\n }\n }\n</div>\n\n@if (pageSize()) {\n <table-view-pagination\n [pageSize]=\"pageSize()\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [entriesCount]=\"entriesCount()\"\n (pageChange)=\"onPageChange($event)\"\n ></table-view-pagination>\n}\n\n<div class=\"le-table-container\">\n @if (displayedColumns().length) {\n <table cdk-table [dataSource]=\"data()\" class=\"le-table\" [class.le-table--loading]=\"isLoading()\">\n @for (column of columns(); track column) {\n <ng-container [cdkColumnDef]=\"column.key\">\n <th\n class=\"le-table-header-cell\"\n cdk-header-cell\n *cdkHeaderCellDef\n [tabindex]=\"sortColumnKeys().has(column.key) ? 0 : -1\"\n [class.le-table-header-cell--sortable]=\"sortColumnKeys().has(column.key)\"\n (click)=\"sortColumnKeys().has(column.key) && onSortClick($event, column)\"\n >\n <div class=\"le-cell-content\">\n <ng-template\n tableViewCell\n [data]=\"column.label\"\n [type]=\"column.column_format?.headerTemplate\"\n ></ng-template>\n\n @if (sortColumnKeys().has(column.key)) {\n <div class=\"le-sort-container\">\n @if (sortMap().has(column.key)) {\n <div class=\"le-sort-icon\">\n <i\n class=\"le-sort-arrow\"\n [class.le-sort-arrow--asc]=\"sortMap().get(column.key) === 'asc'\"\n [class.le-sort-arrow--desc]=\"sortMap().get(column.key) === 'desc'\"\n ></i>\n </div>\n\n <div class=\"le-sort-order\">\n @if (sortOrder().has(column.key)) {\n <span>\n {{ sortOrder().get(column.key) }}\n </span>\n }\n </div>\n } @else {\n <le-icon name=\"sort\" class=\"le-sort-icon le-sort-icon--unfold\"></le-icon>\n }\n </div>\n }\n </div>\n </th>\n\n <td class=\"le-table-cell\" cdk-cell *cdkCellDef=\"let row\">\n <ng-template\n tableViewCell\n [data]=\"row[column.key]\"\n [type]=\"column.column_format?.cellTemplate\"\n [column]=\"column\"\n [metadata]=\"row._metadata\"\n ></ng-template>\n </td>\n </ng-container>\n }\n\n <tr cdk-header-row class=\"le-header-row\" *cdkHeaderRowDef=\"displayedColumns()\"></tr>\n <tr\n cdk-row\n class=\"le-table-row\"\n [tabindex]=\"0\"\n [class.le-table-row--clickable]=\"hasRowClickAction()\"\n *cdkRowDef=\"let row; columns: displayedColumns()\"\n (click)=\"onRowClick(row)\"\n ></tr>\n </table>\n }\n</div>\n\n@if (data().count === 0) {\n @if (isLoading()) {\n <app-loading-view [headerHeight]=\"65\" [rowCount]=\"pageSize() || 10\"></app-loading-view>\n } @else {\n <div class=\"no-entities\">\n <span>No Entities</span>\n </div>\n }\n}\n", dependencies: [{ kind: "component", type: CdkTable, selector: "cdk-table, table[cdk-table]", inputs: ["trackBy", "dataSource", "multiTemplateDataRows", "fixedLayout"], outputs: ["contentChanged"], exportAs: ["cdkTable"] }, { kind: "directive", type: CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: CdkHeaderCell, selector: "cdk-header-cell, th[cdk-header-cell]" }, { kind: "directive", type: CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: CdkCell, selector: "cdk-cell, td[cdk-cell]" }, { kind: "directive", type: CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "component", type: CdkHeaderRow, selector: "cdk-header-row, tr[cdk-header-row]" }, { kind: "component", type: CdkRow, selector: "cdk-row, tr[cdk-row]" }, { kind: "directive", type: CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "component", type: TableViewPaginationComponent, selector: "table-view-pagination", inputs: ["pageSize", "pageSizeOptions", "entriesCount"], outputs: ["pageChange"] }, { kind: "component", type: LoadingViewComponent, selector: "app-loading-view", inputs: ["headerHeight", "rowHeight", "rowCount"] }, { kind: "component", type: TableViewActions, selector: "table-view-actions", inputs: ["actions"], outputs: ["actionClicked"] }, { kind: "directive", type: TableViewCellDirective, selector: "[tableViewCell]", inputs: ["type", "data", "column", "metadata"] }, { kind: "component", type: LeIconComponent, selector: "le-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1042
1176
  }
1043
1177
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TableViewComponent, decorators: [{
1044
1178
  type: Component,
@@ -1058,7 +1192,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
1058
1192
  TableViewActions,
1059
1193
  TableViewCellDirective,
1060
1194
  LeIconComponent,
1061
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"le-toolbar\">\n @if (node(); as node) {\n <h2>{{ node?.title }}</h2>\n\n\n <span class=\"spacer\"></span>\n\n @if (filters().length) {\n <button class=\"le-button\" (click)=\"onFiltersClick($event)\">Filters</button>\n }\n\n @if (node.actions?.tableActions) {\n <table-view-actions\n [actions]=\"node.actions!.tableActions\"\n (actionClicked)=\"onToolbarActionClick($event)\"\n ></table-view-actions>\n }\n }\n</div>\n\n@if (pageSize()) {\n <table-view-pagination\n [pageSize]=\"pageSize()\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [entriesCount]=\"entriesCount()\"\n (pageChange)=\"onPageChange($event)\"\n ></table-view-pagination>\n}\n\n<div class=\"le-table-container\">\n @if (displayedColumns().length) {\n <table cdk-table [dataSource]=\"data()\" class=\"le-table\" [class.le-table--loading]=\"isLoading()\">\n @for (column of columns(); track column) {\n <ng-container [cdkColumnDef]=\"column.key\">\n <th\n class=\"le-table-header-cell\"\n cdk-header-cell\n *cdkHeaderCellDef\n [tabindex]=\"sortColumnKeys().has(column.key) ? 0 : -1\"\n [class.le-table-header-cell--sortable]=\"sortColumnKeys().has(column.key)\"\n (click)=\"sortColumnKeys().has(column.key) && onSortClick($event, column)\"\n >\n <div class=\"le-cell-content\">\n <ng-template\n tableViewCell\n [data]=\"column.label\"\n [type]=\"column.column_format?.headerTemplate\"\n ></ng-template>\n\n @if (sortColumnKeys().has(column.key)) {\n <div class=\"le-sort-container\">\n @if (sortMap().has(column.key)) {\n <div class=\"le-sort-icon\">\n <i\n class=\"le-sort-arrow\"\n [class.le-sort-arrow--asc]=\"sortMap().get(column.key) === 'asc'\"\n [class.le-sort-arrow--desc]=\"sortMap().get(column.key) === 'desc'\"\n ></i>\n </div>\n\n <div class=\"le-sort-order\">\n @if (sortOrder().has(column.key)) {\n <span>\n {{ sortOrder().get(column.key) }}\n </span>\n }\n </div>\n } @else {\n<!-- <div class=\"le-sort-icon le-sort-icon&#45;&#45;unfold\">-->\n<!-- <span>&#8645;</span>-->\n<!-- </div>-->\n\n <le-icon name=\"sort\" class=\"le-sort-icon le-sort-icon--unfold\"></le-icon>\n }\n </div>\n }\n </div>\n </th>\n\n <td class=\"le-table-cell\" cdk-cell *cdkCellDef=\"let row\">\n <ng-template\n tableViewCell\n [data]=\"row[column.key]\"\n [type]=\"column.column_format?.cellTemplate\"\n ></ng-template>\n </td>\n </ng-container>\n }\n\n <tr cdk-header-row class=\"le-header-row\" *cdkHeaderRowDef=\"displayedColumns()\"></tr>\n <tr\n cdk-row\n class=\"le-table-row\"\n [tabindex]=\"0\"\n [class.le-table-row--clickable]=\"hasRowClickAction()\"\n *cdkRowDef=\"let row; columns: displayedColumns()\"\n (click)=\"onRowClick(row)\"\n ></tr>\n </table>\n }\n</div>\n\n@if (data().count === 0) {\n @if (isLoading()) {\n <app-loading-view [headerHeight]=\"65\" [rowCount]=\"pageSize() || 10\"></app-loading-view>\n } @else {\n <div class=\"no-entities\">\n <span>No Entities</span>\n </div>\n }\n}\n" }]
1195
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"le-toolbar\">\n @if (node(); as node) {\n <h2>{{ node?.title }}</h2>\n\n\n <span class=\"spacer\"></span>\n\n @if (filters().length) {\n <button class=\"le-button\" (click)=\"onFiltersClick($event)\">Filters</button>\n }\n\n @if (node.actions?.tableActions) {\n <table-view-actions\n [actions]=\"node.actions!.tableActions\"\n (actionClicked)=\"onToolbarActionClick($event)\"\n ></table-view-actions>\n }\n }\n</div>\n\n@if (pageSize()) {\n <table-view-pagination\n [pageSize]=\"pageSize()\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [entriesCount]=\"entriesCount()\"\n (pageChange)=\"onPageChange($event)\"\n ></table-view-pagination>\n}\n\n<div class=\"le-table-container\">\n @if (displayedColumns().length) {\n <table cdk-table [dataSource]=\"data()\" class=\"le-table\" [class.le-table--loading]=\"isLoading()\">\n @for (column of columns(); track column) {\n <ng-container [cdkColumnDef]=\"column.key\">\n <th\n class=\"le-table-header-cell\"\n cdk-header-cell\n *cdkHeaderCellDef\n [tabindex]=\"sortColumnKeys().has(column.key) ? 0 : -1\"\n [class.le-table-header-cell--sortable]=\"sortColumnKeys().has(column.key)\"\n (click)=\"sortColumnKeys().has(column.key) && onSortClick($event, column)\"\n >\n <div class=\"le-cell-content\">\n <ng-template\n tableViewCell\n [data]=\"column.label\"\n [type]=\"column.column_format?.headerTemplate\"\n ></ng-template>\n\n @if (sortColumnKeys().has(column.key)) {\n <div class=\"le-sort-container\">\n @if (sortMap().has(column.key)) {\n <div class=\"le-sort-icon\">\n <i\n class=\"le-sort-arrow\"\n [class.le-sort-arrow--asc]=\"sortMap().get(column.key) === 'asc'\"\n [class.le-sort-arrow--desc]=\"sortMap().get(column.key) === 'desc'\"\n ></i>\n </div>\n\n <div class=\"le-sort-order\">\n @if (sortOrder().has(column.key)) {\n <span>\n {{ sortOrder().get(column.key) }}\n </span>\n }\n </div>\n } @else {\n <le-icon name=\"sort\" class=\"le-sort-icon le-sort-icon--unfold\"></le-icon>\n }\n </div>\n }\n </div>\n </th>\n\n <td class=\"le-table-cell\" cdk-cell *cdkCellDef=\"let row\">\n <ng-template\n tableViewCell\n [data]=\"row[column.key]\"\n [type]=\"column.column_format?.cellTemplate\"\n [column]=\"column\"\n [metadata]=\"row._metadata\"\n ></ng-template>\n </td>\n </ng-container>\n }\n\n <tr cdk-header-row class=\"le-header-row\" *cdkHeaderRowDef=\"displayedColumns()\"></tr>\n <tr\n cdk-row\n class=\"le-table-row\"\n [tabindex]=\"0\"\n [class.le-table-row--clickable]=\"hasRowClickAction()\"\n *cdkRowDef=\"let row; columns: displayedColumns()\"\n (click)=\"onRowClick(row)\"\n ></tr>\n </table>\n }\n</div>\n\n@if (data().count === 0) {\n @if (isLoading()) {\n <app-loading-view [headerHeight]=\"65\" [rowCount]=\"pageSize() || 10\"></app-loading-view>\n } @else {\n <div class=\"no-entities\">\n <span>No Entities</span>\n </div>\n }\n}\n" }]
1062
1196
  }], ctorParameters: () => [] });
1063
1197
 
1064
1198
  const isSectionsSchema = (raw) => {
@@ -1426,6 +1560,7 @@ class FormViewComponent {
1426
1560
  _sections = signal([]);
1427
1561
  _topLevelControls = signal([]);
1428
1562
  _engine = signal(null);
1563
+ _cancelRequest$ = new Subject();
1429
1564
  _actionHandlers = {
1430
1565
  invoke: (action) => {
1431
1566
  const engine = this._engine();
@@ -1526,11 +1661,14 @@ class FormViewComponent {
1526
1661
  };
1527
1662
  });
1528
1663
  constructor() {
1529
- effect(() => {
1664
+ effect((onCleanup) => {
1530
1665
  const node = this.node();
1531
1666
  if (node) {
1532
- this.getFormData(node).subscribe();
1667
+ this.getFormData(node).pipe(takeUntil(this._cancelRequest$)).subscribe();
1533
1668
  }
1669
+ onCleanup(() => {
1670
+ this._cancelRequest$.next();
1671
+ });
1534
1672
  });
1535
1673
  effect(() => {
1536
1674
  const form = this._form();
@@ -1888,18 +2026,18 @@ class LeContainerComponent {
1888
2026
  if (!(path.length && sidebar))
1889
2027
  return;
1890
2028
  untracked(() => {
1891
- path.forEach(node => {
2029
+ path.forEach((node) => {
1892
2030
  sidebar.setExpanded(node);
1893
2031
  });
1894
2032
  });
1895
2033
  });
1896
2034
  }
1897
2035
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1898
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: LeContainerComponent, isStandalone: true, selector: "le-container", providers: [LEDataService, LEApiService, LEFiltersService], viewQueries: [{ propertyName: "sidebar", first: true, predicate: SidebarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (data(); as data) {\n <le-sidebar\n [config]=\"data.config\"\n [view]=\"data.view\"\n (selectionChange)=\"onSelectionChange($event)\"\n >\n <le-filters>\n <le-node [node]=\"data.view\"></le-node>\n </le-filters>\n </le-sidebar>\n}\n", dependencies: [{ kind: "component", type: SidebarComponent, selector: "le-sidebar", inputs: ["config", "view"], outputs: ["selectionChange"] }, { kind: "component", type: NodeComponent, selector: "le-node", inputs: ["node"] }, { kind: "component", type: FiltersComponent, selector: "le-filters" }] });
2036
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: LeContainerComponent, isStandalone: true, selector: "le-container", providers: [LEDataService, LEApiService, LEFiltersService, LeNavigationService], viewQueries: [{ propertyName: "sidebar", first: true, predicate: SidebarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (data(); as data) {\n <le-sidebar\n [config]=\"data.config\"\n [view]=\"data.view\"\n (selectionChange)=\"onSelectionChange($event)\"\n >\n <le-filters>\n <le-node [node]=\"data.view\"></le-node>\n </le-filters>\n </le-sidebar>\n}\n", dependencies: [{ kind: "component", type: SidebarComponent, selector: "le-sidebar", inputs: ["config", "view"], outputs: ["selectionChange"] }, { kind: "component", type: NodeComponent, selector: "le-node", inputs: ["node"] }, { kind: "component", type: FiltersComponent, selector: "le-filters" }] });
1899
2037
  }
1900
2038
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeContainerComponent, decorators: [{
1901
2039
  type: Component,
1902
- args: [{ selector: 'le-container', imports: [SidebarComponent, NodeComponent, FiltersComponent], providers: [LEDataService, LEApiService, LEFiltersService], template: "@if (data(); as data) {\n <le-sidebar\n [config]=\"data.config\"\n [view]=\"data.view\"\n (selectionChange)=\"onSelectionChange($event)\"\n >\n <le-filters>\n <le-node [node]=\"data.view\"></le-node>\n </le-filters>\n </le-sidebar>\n}\n" }]
2040
+ args: [{ selector: 'le-container', imports: [SidebarComponent, NodeComponent, FiltersComponent], providers: [LEDataService, LEApiService, LEFiltersService, LeNavigationService], template: "@if (data(); as data) {\n <le-sidebar\n [config]=\"data.config\"\n [view]=\"data.view\"\n (selectionChange)=\"onSelectionChange($event)\"\n >\n <le-filters>\n <le-node [node]=\"data.view\"></le-node>\n </le-filters>\n </le-sidebar>\n}\n" }]
1903
2041
  }], ctorParameters: () => [] });
1904
2042
 
1905
2043
  const provideConfig = (config) => {