@planeasyinc/le-angular 0.0.24 → 0.0.26

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,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, signal, Injectable, computed, effect, untracked, Directive, input, ChangeDetectionStrategy, Component, output, forwardRef, ViewContainerRef, Injector, Renderer2, ElementRef, DestroyRef, viewChild } from '@angular/core';
2
+ import { InjectionToken, inject, signal, Injectable, computed, effect, untracked, Directive, input, Pipe, ChangeDetectionStrategy, Component, output, forwardRef, ViewContainerRef, Injector, Renderer2, ElementRef, DestroyRef, viewChild } from '@angular/core';
3
3
  import { HttpContextToken, HttpClient, HttpContext, HttpRequest, HttpEventType } from '@angular/common/http';
4
- import { map, filter, distinctUntilChanged, Subject, takeUntil, BehaviorSubject, firstValueFrom, of, tap, catchError, switchMap, from, concatMap, finalize, fromEvent, startWith } from 'rxjs';
4
+ import { map, Subject, firstValueFrom, distinctUntilChanged, takeUntil, BehaviorSubject, of, filter, tap, catchError, switchMap, from, concatMap, finalize, fromEvent, startWith } from 'rxjs';
5
5
  import { decodeJwt, UrlFragmentBuilder, normalizeConfig } from '@planeasyinc/le-core';
6
- import { Location, UpperCasePipe, JsonPipe, DatePipe, ViewportScroller } from '@angular/common';
6
+ import { Location, NgTemplateOutlet, UpperCasePipe, JsonPipe, DatePipe, ViewportScroller } from '@angular/common';
7
7
  import { CdkDrag } from '@angular/cdk/drag-drop';
8
8
  import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
9
9
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@@ -138,10 +138,13 @@ class LEApiService {
138
138
  return url;
139
139
  }
140
140
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LEApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
141
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LEApiService });
141
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LEApiService, providedIn: 'root' });
142
142
  }
143
143
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LEApiService, decorators: [{
144
- type: Injectable
144
+ type: Injectable,
145
+ args: [{
146
+ providedIn: 'root',
147
+ }]
145
148
  }] });
146
149
 
147
150
  class LeNavigationService {
@@ -197,17 +200,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
197
200
  type: Injectable
198
201
  }], ctorParameters: () => [] });
199
202
 
200
- class LEDataService {
203
+ class LeApiConfigService {
201
204
  apiService = inject(LEApiService);
202
- leNavigationService = inject(LeNavigationService);
203
205
  _config = signal(null);
206
+ _externalViewChange = new Subject();
207
+ config = this._config.asReadonly();
208
+ externalViewChange = this._externalViewChange.asObservable();
209
+ async requestConfig() {
210
+ try {
211
+ const config = await firstValueFrom(this.apiService.getConfig());
212
+ const normalizedConfig = normalizeConfig({ type: 'section', ...config });
213
+ this._config.set(normalizedConfig);
214
+ return normalizedConfig;
215
+ }
216
+ catch (error) {
217
+ console.error(error);
218
+ }
219
+ }
220
+ setView(node) {
221
+ this._externalViewChange.next(node);
222
+ }
223
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeApiConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
224
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeApiConfigService, providedIn: 'root' });
225
+ }
226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeApiConfigService, decorators: [{
227
+ type: Injectable,
228
+ args: [{
229
+ providedIn: 'root',
230
+ }]
231
+ }] });
232
+
233
+ class LeViewService {
234
+ leNavigationService = inject(LeNavigationService);
235
+ configService = inject(LeApiConfigService);
204
236
  _view = signal(null);
205
237
  _parentPath = signal([]);
206
238
  _customCss = signal(null);
207
239
  view = this._view.asReadonly();
208
240
  parentPath = this._parentPath.asReadonly();
209
- config = this._config.asReadonly();
210
241
  customCss = this._customCss.asReadonly();
242
+ init(node) {
243
+ const initialView = this.getInitialView(node);
244
+ this._customCss.set(node.custom_css);
245
+ this._parentPath.set(initialView.path);
246
+ this.setView(initialView.node);
247
+ }
211
248
  registerEffects() {
212
249
  effect(() => {
213
250
  const node = this.leNavigationService.node();
@@ -228,39 +265,13 @@ class LEDataService {
228
265
  this.leNavigationService.navigate(node);
229
266
  }
230
267
  }
231
- requestConfig(force) {
232
- if (this._config() && !force) {
233
- return;
234
- }
235
- this.apiService.getConfig().subscribe({
236
- next: (config) => {
237
- const normalizedConfig = normalizeConfig({ type: 'section', ...config });
238
- this._config.set(normalizedConfig);
239
- this._customCss.set(config.custom_css);
240
- const initialView = this.getInitialView(normalizedConfig);
241
- this.setView(initialView.node);
242
- this._parentPath.set(initialView.path);
243
- },
244
- error: (err) => {
245
- console.error(err);
246
- },
247
- });
248
- }
249
- request(method, url, body) {
250
- return this.apiService
251
- .request(method, url, body)
252
- .pipe(filter((event) => HttpEventType.Response === event.type));
253
- }
254
- getObjectByClassName(className) {
255
- return this.apiService.getObject(className);
256
- }
257
268
  navigateByNodeId(id) {
258
269
  const node = this.getNodeById(id);
259
270
  if (node) {
260
271
  this.setView(node);
261
272
  }
262
273
  }
263
- getNodeById(id, node = this._config()) {
274
+ getNodeById(id, node = this.configService.config()) {
264
275
  if (!node)
265
276
  return null;
266
277
  if (node.id === id) {
@@ -292,10 +303,10 @@ class LEDataService {
292
303
  }
293
304
  throw new Error(`${node.type} is not a section`);
294
305
  }
295
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LEDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
296
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LEDataService });
306
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeViewService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
307
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeViewService });
297
308
  }
298
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LEDataService, decorators: [{
309
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeViewService, decorators: [{
299
310
  type: Injectable
300
311
  }] });
301
312
 
@@ -407,6 +418,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
407
418
  }]
408
419
  }] });
409
420
 
421
+ class IsParentMenuPipe {
422
+ transform(node) {
423
+ return node.type === 'section' && node.isParentMenu;
424
+ }
425
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: IsParentMenuPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
426
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.21", ngImport: i0, type: IsParentMenuPipe, isStandalone: true, name: "isParentMenu" });
427
+ }
428
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: IsParentMenuPipe, decorators: [{
429
+ type: Pipe,
430
+ args: [{
431
+ name: 'isParentMenu',
432
+ }]
433
+ }] });
434
+
410
435
  const close = {
411
436
  name: 'close',
412
437
  viewBox: '0 -960 960 960',
@@ -447,12 +472,22 @@ const info = {
447
472
  ],
448
473
  };
449
474
 
475
+ const download$1 = {
476
+ name: 'download',
477
+ viewBox: '0 -960 960 960',
478
+ content: [
479
+ 'M480-320 280-520l56-58 104 104v-326h80v326l104-104 56 58-200 200ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z',
480
+ ],
481
+ };
482
+ // <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M480-320 280-520l56-58 104 104v-326h80v326l104-104 56 58-200 200ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z"/></svg>
483
+
450
484
  const ICONS_MAP = {
451
485
  chevron: chevron,
452
486
  'arrow-down': arrowDown,
453
487
  sort: sort,
454
488
  close: close,
455
- info: info
489
+ info: info,
490
+ download: download$1,
456
491
  };
457
492
 
458
493
  class LeIconComponent {
@@ -573,11 +608,19 @@ class SidebarComponent {
573
608
  element.style.transform = 'none';
574
609
  }
575
610
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
576
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SidebarComponent, isStandalone: true, selector: "le-sidebar", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, ngImport: i0, template: "<div leDrawerContainer>\n <aside leDrawer [opened]=\"isDrawerOpen()\" [width]=\"width()\" [hideOnClose]=\"isSmallScreen()\">\n <h3 class=\"le-sidebar-title\">\n <button\n class=\"le-sidebar-toggle\"\n (click)=\"onDrawerToggleClick($event)\"\n (keydown.enter)=\"onDrawerToggleClick($event)\"\n >\n @if (isDrawerOpen()) {\n {{ config().title }}\n }\n\n <le-icon name=\"chevron\"></le-icon>\n </button>\n </h3>\n\n @if (isDrawerOpen()) {\n <menu>\n @for (item of menu(); track item) {\n @if (isSection(item)) {\n <a\n class=\"le-menu-item\"\n tabindex=\"0\"\n [class.le-menu-item--expanded]=\"expanded().has(item)\"\n (click)=\"toggleExpanded($event, item)\"\n (keydown.enter)=\"toggleExpanded($event, item)\"\n >\n <div class=\"le-menu-title\">\n {{ item.title }}\n </div>\n\n <le-icon class=\"le-menu-chevron\" name=\"chevron\"></le-icon>\n </a>\n\n <div class=\"le-menu-group\" [class.le-menu-group--expanded]=\"expanded().has(item)\">\n @for (child of item.children; track child) {\n @if (isSection(child)) {\n <a\n class=\"le-menu-item\"\n [tabindex]=\"expanded().has(item) ? 0 : -1\"\n [class.le-menu-item--expanded]=\"expanded().has(child)\"\n (click)=\"toggleExpanded($event, child)\"\n (keydown.enter)=\"toggleExpanded($event, child)\"\n >\n <div class=\"le-menu-title\">\n {{ child.title }}\n </div>\n\n <le-icon class=\"le-menu-chevron\" name=\"chevron\"></le-icon>\n </a>\n\n <div class=\"le-menu-group\" [class.le-menu-group--expanded]=\"expanded().has(child)\">\n @for (grandchild of child.children; track grandchild) {\n <a\n [tabindex]=\"expanded().has(child) ? 0 : -1\"\n class=\"le-menu-item\"\n [class.le-menu-item--selected]=\"view().id === grandchild.id\"\n (click)=\"onSidebarItemClick($event, grandchild)\"\n (keydown.enter)=\"onSidebarItemClick($event, grandchild)\"\n >\n <div class=\"le-menu-title\">\n {{ grandchild.title }}\n </div>\n </a>\n }\n </div>\n } @else {\n <a\n [tabindex]=\"expanded().has(item) ? 0 : -1\"\n class=\"le-menu-item\"\n [class.le-menu-item--selected]=\"view().id === child.id\"\n (click)=\"onSidebarItemClick($event, child)\"\n (keydown.enter)=\"onSidebarItemClick($event, child)\"\n >\n <div class=\"le-menu-title\">\n {{ child.title }}\n </div>\n </a>\n }\n }\n </div>\n } @else {\n <a\n tabindex=\"0\"\n class=\"le-menu-item\"\n [class.le-menu-item--selected]=\"view().id === item.id\"\n (click)=\"onSidebarItemClick($event, item)\"\n (keydown.enter)=\"onSidebarItemClick($event, item)\"\n >\n <div class=\"le-menu-title\">\n {{ item.title }}\n </div>\n </a>\n }\n }\n </menu>\n\n <div class=\"le-drawer-resizer\" cdkDrag (cdkDragMoved)=\"onDragMoved($event)\">\n <span class=\"le-drag-icon\">\u283F</span>\n </div>\n }\n </aside>\n\n <main leDrawerContent>\n <ng-content></ng-content>\n </main>\n</div>\n", dependencies: [{ kind: "directive", type: DrawerContentDirective, selector: "[leDrawerContent]" }, { kind: "directive", type: DrawerContainerDirective, selector: "[leDrawerContainer]" }, { kind: "directive", type: LeDrawerDirective, selector: "[leDrawer]", inputs: ["opened", "width", "hideOnClose", "type"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: LeIconComponent, selector: "le-icon", inputs: ["name", "size"] }] });
611
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SidebarComponent, isStandalone: true, selector: "le-sidebar", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, ngImport: i0, template: "<div leDrawerContainer>\n <aside leDrawer [opened]=\"isDrawerOpen()\" [width]=\"width()\" [hideOnClose]=\"isSmallScreen()\">\n <h3 class=\"le-sidebar-title\">\n <button\n class=\"le-sidebar-toggle\"\n (click)=\"onDrawerToggleClick($event)\"\n (keydown.enter)=\"onDrawerToggleClick($event)\"\n >\n @if (isDrawerOpen()) {\n {{ config().title }}\n }\n\n <le-icon name=\"chevron\"></le-icon>\n </button>\n </h3>\n\n @if (isDrawerOpen()) {\n <menu>\n @for (item of menu(); track item) {\n @if (item | isParentMenu) {\n <ng-container *ngTemplateOutlet=\"navParentTemplate; context: { node: item }\"></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"navChildTemplate; context: { node: item }\"></ng-container>\n }\n }\n </menu>\n\n <div class=\"le-drawer-resizer\" cdkDrag (cdkDragMoved)=\"onDragMoved($event)\">\n <span class=\"le-drag-icon\">\u283F</span>\n </div>\n }\n </aside>\n\n <main leDrawerContent>\n <ng-content></ng-content>\n </main>\n</div>\n\n<ng-template #navParentTemplate let-node=\"node\" let-parent=\"parent\">\n <a\n class=\"le-menu-item\"\n [tabindex]=\"!!parent && (expanded().has(parent) ? 0 : -1) || 0\"\n [class.le-menu-item--expanded]=\"expanded().has(node)\"\n (click)=\"toggleExpanded($event, node)\"\n (keydown.enter)=\"toggleExpanded($event, node)\"\n >\n <div class=\"le-menu-title\">\n {{ node.title }}\n </div>\n\n <le-icon class=\"le-menu-chevron\" name=\"chevron\"></le-icon>\n </a>\n\n <div class=\"le-menu-group\" [class.le-menu-group--expanded]=\"expanded().has(node)\">\n @for (child of node.children; track child) {\n @if (child | isParentMenu) {\n <ng-container *ngTemplateOutlet=\"navParentTemplate; context: { node: child, parent: node }\"></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"navChildTemplate; context: { node: child, parent: node }\"></ng-container>\n }\n }\n </div>\n</ng-template>\n\n<ng-template #navChildTemplate let-node=\"node\" let-parent=\"parent\">\n <a\n [tabindex]=\"!!parent && (expanded().has(parent) ? 0 : -1) || 0\"\n class=\"le-menu-item\"\n [class.le-menu-item--selected]=\"view().id === node.id\"\n (click)=\"onSidebarItemClick($event, node)\"\n (keydown.enter)=\"onSidebarItemClick($event, node)\"\n >\n <div class=\"le-menu-title\">\n {{ node.title }}\n </div>\n </a>\n</ng-template>\n", dependencies: [{ kind: "directive", type: DrawerContentDirective, selector: "[leDrawerContent]" }, { kind: "directive", type: DrawerContainerDirective, selector: "[leDrawerContainer]" }, { kind: "directive", type: LeDrawerDirective, selector: "[leDrawer]", inputs: ["opened", "width", "hideOnClose", "type"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: LeIconComponent, selector: "le-icon", inputs: ["name", "size"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: IsParentMenuPipe, name: "isParentMenu" }] });
577
612
  }
578
613
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SidebarComponent, decorators: [{
579
614
  type: Component,
580
- args: [{ selector: 'le-sidebar', imports: [DrawerContentDirective, DrawerContainerDirective, LeDrawerDirective, CdkDrag, LeIconComponent], template: "<div leDrawerContainer>\n <aside leDrawer [opened]=\"isDrawerOpen()\" [width]=\"width()\" [hideOnClose]=\"isSmallScreen()\">\n <h3 class=\"le-sidebar-title\">\n <button\n class=\"le-sidebar-toggle\"\n (click)=\"onDrawerToggleClick($event)\"\n (keydown.enter)=\"onDrawerToggleClick($event)\"\n >\n @if (isDrawerOpen()) {\n {{ config().title }}\n }\n\n <le-icon name=\"chevron\"></le-icon>\n </button>\n </h3>\n\n @if (isDrawerOpen()) {\n <menu>\n @for (item of menu(); track item) {\n @if (isSection(item)) {\n <a\n class=\"le-menu-item\"\n tabindex=\"0\"\n [class.le-menu-item--expanded]=\"expanded().has(item)\"\n (click)=\"toggleExpanded($event, item)\"\n (keydown.enter)=\"toggleExpanded($event, item)\"\n >\n <div class=\"le-menu-title\">\n {{ item.title }}\n </div>\n\n <le-icon class=\"le-menu-chevron\" name=\"chevron\"></le-icon>\n </a>\n\n <div class=\"le-menu-group\" [class.le-menu-group--expanded]=\"expanded().has(item)\">\n @for (child of item.children; track child) {\n @if (isSection(child)) {\n <a\n class=\"le-menu-item\"\n [tabindex]=\"expanded().has(item) ? 0 : -1\"\n [class.le-menu-item--expanded]=\"expanded().has(child)\"\n (click)=\"toggleExpanded($event, child)\"\n (keydown.enter)=\"toggleExpanded($event, child)\"\n >\n <div class=\"le-menu-title\">\n {{ child.title }}\n </div>\n\n <le-icon class=\"le-menu-chevron\" name=\"chevron\"></le-icon>\n </a>\n\n <div class=\"le-menu-group\" [class.le-menu-group--expanded]=\"expanded().has(child)\">\n @for (grandchild of child.children; track grandchild) {\n <a\n [tabindex]=\"expanded().has(child) ? 0 : -1\"\n class=\"le-menu-item\"\n [class.le-menu-item--selected]=\"view().id === grandchild.id\"\n (click)=\"onSidebarItemClick($event, grandchild)\"\n (keydown.enter)=\"onSidebarItemClick($event, grandchild)\"\n >\n <div class=\"le-menu-title\">\n {{ grandchild.title }}\n </div>\n </a>\n }\n </div>\n } @else {\n <a\n [tabindex]=\"expanded().has(item) ? 0 : -1\"\n class=\"le-menu-item\"\n [class.le-menu-item--selected]=\"view().id === child.id\"\n (click)=\"onSidebarItemClick($event, child)\"\n (keydown.enter)=\"onSidebarItemClick($event, child)\"\n >\n <div class=\"le-menu-title\">\n {{ child.title }}\n </div>\n </a>\n }\n }\n </div>\n } @else {\n <a\n tabindex=\"0\"\n class=\"le-menu-item\"\n [class.le-menu-item--selected]=\"view().id === item.id\"\n (click)=\"onSidebarItemClick($event, item)\"\n (keydown.enter)=\"onSidebarItemClick($event, item)\"\n >\n <div class=\"le-menu-title\">\n {{ item.title }}\n </div>\n </a>\n }\n }\n </menu>\n\n <div class=\"le-drawer-resizer\" cdkDrag (cdkDragMoved)=\"onDragMoved($event)\">\n <span class=\"le-drag-icon\">\u283F</span>\n </div>\n }\n </aside>\n\n <main leDrawerContent>\n <ng-content></ng-content>\n </main>\n</div>\n" }]
615
+ args: [{ selector: 'le-sidebar', imports: [
616
+ DrawerContentDirective,
617
+ DrawerContainerDirective,
618
+ LeDrawerDirective,
619
+ CdkDrag,
620
+ LeIconComponent,
621
+ NgTemplateOutlet,
622
+ IsParentMenuPipe,
623
+ ], template: "<div leDrawerContainer>\n <aside leDrawer [opened]=\"isDrawerOpen()\" [width]=\"width()\" [hideOnClose]=\"isSmallScreen()\">\n <h3 class=\"le-sidebar-title\">\n <button\n class=\"le-sidebar-toggle\"\n (click)=\"onDrawerToggleClick($event)\"\n (keydown.enter)=\"onDrawerToggleClick($event)\"\n >\n @if (isDrawerOpen()) {\n {{ config().title }}\n }\n\n <le-icon name=\"chevron\"></le-icon>\n </button>\n </h3>\n\n @if (isDrawerOpen()) {\n <menu>\n @for (item of menu(); track item) {\n @if (item | isParentMenu) {\n <ng-container *ngTemplateOutlet=\"navParentTemplate; context: { node: item }\"></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"navChildTemplate; context: { node: item }\"></ng-container>\n }\n }\n </menu>\n\n <div class=\"le-drawer-resizer\" cdkDrag (cdkDragMoved)=\"onDragMoved($event)\">\n <span class=\"le-drag-icon\">\u283F</span>\n </div>\n }\n </aside>\n\n <main leDrawerContent>\n <ng-content></ng-content>\n </main>\n</div>\n\n<ng-template #navParentTemplate let-node=\"node\" let-parent=\"parent\">\n <a\n class=\"le-menu-item\"\n [tabindex]=\"!!parent && (expanded().has(parent) ? 0 : -1) || 0\"\n [class.le-menu-item--expanded]=\"expanded().has(node)\"\n (click)=\"toggleExpanded($event, node)\"\n (keydown.enter)=\"toggleExpanded($event, node)\"\n >\n <div class=\"le-menu-title\">\n {{ node.title }}\n </div>\n\n <le-icon class=\"le-menu-chevron\" name=\"chevron\"></le-icon>\n </a>\n\n <div class=\"le-menu-group\" [class.le-menu-group--expanded]=\"expanded().has(node)\">\n @for (child of node.children; track child) {\n @if (child | isParentMenu) {\n <ng-container *ngTemplateOutlet=\"navParentTemplate; context: { node: child, parent: node }\"></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"navChildTemplate; context: { node: child, parent: node }\"></ng-container>\n }\n }\n </div>\n</ng-template>\n\n<ng-template #navChildTemplate let-node=\"node\" let-parent=\"parent\">\n <a\n [tabindex]=\"!!parent && (expanded().has(parent) ? 0 : -1) || 0\"\n class=\"le-menu-item\"\n [class.le-menu-item--selected]=\"view().id === node.id\"\n (click)=\"onSidebarItemClick($event, node)\"\n (keydown.enter)=\"onSidebarItemClick($event, node)\"\n >\n <div class=\"le-menu-title\">\n {{ node.title }}\n </div>\n </a>\n</ng-template>\n" }]
581
624
  }], ctorParameters: () => [] });
582
625
 
583
626
  class ChartViewComponent {
@@ -653,10 +696,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
653
696
  ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<cdk-tree [dataSource]=\"source()\" [treeControl]=\"treeControl\">\n <!-- Tree node template for leaf nodes -->\n <cdk-nested-tree-node *cdkTreeNodeDef=\"let node\" class=\"le-tree-node\">\n <div class=\"le-tree-row\">\n <b>{{node.label | uppercase}}</b>: &nbsp;&nbsp;&nbsp; {{node.value}}\n </div>\n </cdk-nested-tree-node>\n\n <!-- Tree node template for expandable nodes -->\n <cdk-nested-tree-node *cdkTreeNodeDef=\"let node; when: hasChild\" class=\"le-tree-node\">\n\n <a class=\"le-tree-row\" [class.le-tree-row--expanded]=\"treeControl.isExpanded(node)\" [attr.aria-label]=\"'Toggle ' + node.label\" cdkTreeNodeToggle>\n <b>{{node.label | uppercase}}</b>:\n\n <le-icon class=\"le-tree-chevron\" name=\"chevron\"></le-icon>\n </a>\n\n <div [class.le-tree-invisible]=\"!treeControl.isExpanded(node)\">\n <ng-container cdkTreeNodeOutlet></ng-container>\n </div>\n </cdk-nested-tree-node>\n</cdk-tree>\n" }]
654
697
  }] });
655
698
 
656
- class StringTemplate {
699
+ class BaseTemplate {
657
700
  data = input.required();
658
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: StringTemplate, deps: [], target: i0.ɵɵFactoryTarget.Component });
659
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: StringTemplate, 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-string">{{ data() ?? '–' }}</span>`, isInline: true });
701
+ attribute = input.required();
702
+ metadata = input.required();
703
+ clicked = output();
704
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: BaseTemplate, deps: [], target: i0.ɵɵFactoryTarget.Directive });
705
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.21", type: BaseTemplate, isStandalone: true, 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 } }, outputs: { clicked: "clicked" }, ngImport: i0 });
706
+ }
707
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: BaseTemplate, decorators: [{
708
+ type: Directive
709
+ }] });
710
+
711
+ class StringTemplate extends BaseTemplate {
712
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: StringTemplate, deps: null, target: i0.ɵɵFactoryTarget.Component });
713
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.21", type: StringTemplate, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `<span class="le-table-template le-template-string">{{ data() ?? '–' }}</span>`, isInline: true });
660
714
  }
661
715
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: StringTemplate, decorators: [{
662
716
  type: Component,
@@ -665,11 +719,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
665
719
  }]
666
720
  }] });
667
721
 
668
- class ReferenceTemplate {
669
- data = input.required();
670
- attribute = input.required();
671
- metadata = input.required();
672
- clicked = output();
722
+ class ReferenceTemplate extends BaseTemplate {
673
723
  reference = computed(() => {
674
724
  const ref = this.data()?.ref;
675
725
  return {
@@ -680,7 +730,10 @@ class ReferenceTemplate {
680
730
  onClick(event) {
681
731
  event.preventDefault();
682
732
  event.stopImmediatePropagation();
683
- this.clicked.emit(this.data());
733
+ this.clicked.emit({
734
+ type: 'reference',
735
+ data: this.data(),
736
+ });
684
737
  }
685
738
  generateText(ref) {
686
739
  if (ref) {
@@ -695,8 +748,8 @@ class ReferenceTemplate {
695
748
  return ref?.address ? `${href}?address=${ref.address}` : href;
696
749
  }
697
750
  }
698
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ReferenceTemplate, deps: [], target: i0.ɵɵFactoryTarget.Component });
699
- 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 } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
751
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ReferenceTemplate, deps: null, target: i0.ɵɵFactoryTarget.Component });
752
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ReferenceTemplate, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `
700
753
  <span class="le-table-template le-template-reference">
701
754
  @if (reference(); as reference) {
702
755
  @if (reference.href) {
@@ -737,10 +790,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
737
790
  }]
738
791
  }] });
739
792
 
740
- class JSONTemplate {
741
- data = input.required();
742
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: JSONTemplate, deps: [], target: i0.ɵɵFactoryTarget.Component });
743
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: JSONTemplate, isStandalone: true, selector: "ng-component", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `<pre class="le-table-template le-template-json">{{
793
+ class JSONTemplate extends BaseTemplate {
794
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: JSONTemplate, deps: null, target: i0.ɵɵFactoryTarget.Component });
795
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.21", type: JSONTemplate, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `<pre class="le-table-template le-template-json">{{
744
796
  data() ? (data() | json) : '–'
745
797
  }}</pre>`, isInline: true, dependencies: [{ kind: "pipe", type: JsonPipe, name: "json" }] });
746
798
  }
@@ -754,15 +806,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
754
806
  }]
755
807
  }] });
756
808
 
809
+ class FileTemplate extends BaseTemplate {
810
+ onClick(event) {
811
+ event.preventDefault();
812
+ event.stopImmediatePropagation();
813
+ this.clicked.emit({
814
+ type: 'file',
815
+ data: this.data(),
816
+ });
817
+ }
818
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FileTemplate, deps: null, target: i0.ɵɵFactoryTarget.Component });
819
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: FileTemplate, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `
820
+ <span class="le-table-template le-template-file">
821
+ @if (data()) {
822
+ <a [attr.aria-label]="'Download'" (click)="onClick($event)">
823
+ <le-icon size="16" class="le-icon-download" name="download"></le-icon>
824
+ Download
825
+ </a>
826
+ } @else {
827
+ No file attached
828
+ }
829
+ </span>
830
+ `, isInline: true, dependencies: [{ kind: "component", type: LeIconComponent, selector: "le-icon", inputs: ["name", "size"] }] });
831
+ }
832
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FileTemplate, decorators: [{
833
+ type: Component,
834
+ args: [{
835
+ standalone: true,
836
+ imports: [LeIconComponent],
837
+ template: `
838
+ <span class="le-table-template le-template-file">
839
+ @if (data()) {
840
+ <a [attr.aria-label]="'Download'" (click)="onClick($event)">
841
+ <le-icon size="16" class="le-icon-download" name="download"></le-icon>
842
+ Download
843
+ </a>
844
+ } @else {
845
+ No file attached
846
+ }
847
+ </span>
848
+ `,
849
+ }]
850
+ }] });
851
+
757
852
  const TABLE_SELL_TEMPLATE_NAMES = {
758
853
  StringTemplate: 'StringTemplate',
759
854
  ReferenceTemplate: 'ReferenceTemplate',
760
855
  JsonTemplate: 'JsonTemplate',
856
+ FileTemplate: 'FileTemplate',
761
857
  };
762
858
  const TABLE_CELL_TEMPLATES = {
763
859
  StringTemplate: StringTemplate,
764
860
  ReferenceTemplate: ReferenceTemplate,
765
861
  JsonTemplate: JSONTemplate,
862
+ FileTemplate: FileTemplate,
766
863
  };
767
864
 
768
865
  class TableViewCellDirective {
@@ -789,18 +886,16 @@ class TableViewCellDirective {
789
886
  }
790
887
  this.componentRef = this.vcr.createComponent(component);
791
888
  this.componentRef?.setInput('data', data);
792
- if (type === 'ReferenceTemplate') {
793
- if (column) {
794
- this.componentRef?.setInput('attribute', column);
795
- }
796
- if (metadata) {
797
- this.componentRef?.setInput('metadata', metadata);
798
- }
799
- const sub = (this.componentRef?.instance).clicked.subscribe(data => {
800
- this.clicked.emit(data);
801
- });
802
- this.componentRef?.onDestroy(() => sub.unsubscribe());
889
+ if (column) {
890
+ this.componentRef?.setInput('attribute', column);
803
891
  }
892
+ if (metadata) {
893
+ this.componentRef?.setInput('metadata', metadata);
894
+ }
895
+ const sub = (this.componentRef?.instance).clicked.subscribe(data => {
896
+ this.clicked.emit(data);
897
+ });
898
+ this.componentRef?.onDestroy(() => sub.unsubscribe());
804
899
  });
805
900
  });
806
901
  }
@@ -831,12 +926,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
831
926
  }] });
832
927
 
833
928
  class SidePanelComponent {
834
- dataService = inject(LEDataService);
929
+ viewService = inject(LeViewService);
835
930
  _selectedTab = signal(0);
836
931
  data = input.required();
837
932
  config = input();
838
933
  event = output();
839
- node = this.dataService.view;
934
+ node = this.viewService.view;
840
935
  tabs = computed(() => {
841
936
  const data = this.data();
842
937
  return data.tabs.length ? data.tabs : undefined;
@@ -850,7 +945,7 @@ class SidePanelComponent {
850
945
  const data = this.data();
851
946
  untracked(() => {
852
947
  if (data.node) {
853
- this.dataService.setView(data.node, true);
948
+ this.viewService.setView(data.node, true);
854
949
  }
855
950
  });
856
951
  });
@@ -862,7 +957,7 @@ class SidePanelComponent {
862
957
  this._selectedTab.set(index);
863
958
  }
864
959
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
865
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SidePanelComponent, isStandalone: true, selector: "ng-component", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { event: "event" }, host: { properties: { "style.width": "\"100%\"", "style.overflow": "\"auto\"", "style.padding": "\"0 16px\"" } }, providers: [LEDataService, LEFiltersService], ngImport: i0, template: "@if (node(); as node) {\n <le-node [node]=\"node\" [config]=\"data()?.config\" (event)=\"onEvent($event)\"></le-node>\n}\n\n@if (tabs(); as tabs) {\n <div class=\"le-tabs-nav\">\n @for (tab of tabs; track tab.type; let idx = $index) {\n <button\n class=\"le-button le-button-flat le-button--success\"\n [attr.aria-label]=\"'Select ' + tab.type\"\n [class.le-button--success]=\"selectedTabIndex() === idx\"\n (click)=\"onTabClick(idx)\"\n >\n {{ tab.label }}\n </button>\n }\n <span class=\"spacer\"></span>\n\n <button\n aria-label=\"Close side panel\"\n class=\"le-button le-button-flat\"\n (click)=\"event.emit({ type: 'close' })\"\n >Close</button>\n </div>\n}\n\n@if (selectedTab(); as selectedTab) {\n <div class=\"le-tabs-content\">\n @switch (selectedTab.type) {\n @case ('tree') {\n <le-tree-view [data]=\"selectedTab.data\"></le-tree-view>\n }\n @case ('table') {\n <le-node\n [node]=\"selectedTab.data\"\n [config]=\"data()?.config\"\n (event)=\"onEvent($event)\"\n ></le-node>\n }\n @case ('block') {\n <le-block-view\n [data]=\"selectedTab.data\"\n [columns]=\"selectedTab.columns\"\n (event)=\"onEvent($event)\"\n ></le-block-view>\n }\n }\n </div>\n}\n", dependencies: [{ kind: "component", type: i0.forwardRef(() => NodeComponent), selector: "le-node", inputs: ["node", "config"], outputs: ["event"] }, { kind: "component", type: i0.forwardRef(() => TreeViewComponent), selector: "le-tree-view", inputs: ["data"] }, { kind: "component", type: i0.forwardRef(() => BlockViewComponent), selector: "le-block-view", inputs: ["data", "columns"], outputs: ["event"] }] });
960
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SidePanelComponent, isStandalone: true, selector: "ng-component", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { event: "event" }, host: { properties: { "style.width": "\"100%\"", "style.overflow": "\"auto\"", "style.padding": "\"0 16px\"" } }, providers: [LeViewService, LEFiltersService], ngImport: i0, template: "@if (node(); as node) {\n <le-node [node]=\"node\" [config]=\"data()?.config\" (event)=\"onEvent($event)\"></le-node>\n}\n\n@if (tabs(); as tabs) {\n <div class=\"le-tabs-nav\">\n @for (tab of tabs; track tab.type; let idx = $index) {\n <button\n class=\"le-button le-button-flat le-button--success\"\n [attr.aria-label]=\"'Select ' + tab.type\"\n [class.le-button--success]=\"selectedTabIndex() === idx\"\n (click)=\"onTabClick(idx)\"\n >\n {{ tab.label }}\n </button>\n }\n <span class=\"spacer\"></span>\n\n <button\n aria-label=\"Close side panel\"\n class=\"le-button le-button-flat\"\n (click)=\"event.emit({ type: 'close' })\"\n >Close</button>\n </div>\n}\n\n@if (selectedTab(); as selectedTab) {\n <div class=\"le-tabs-content\">\n @switch (selectedTab.type) {\n @case ('tree') {\n <le-tree-view [data]=\"selectedTab.data\"></le-tree-view>\n }\n @case ('table') {\n <le-node\n [node]=\"selectedTab.data\"\n [config]=\"data()?.config\"\n (event)=\"onEvent($event)\"\n ></le-node>\n }\n @case ('block') {\n <le-block-view\n [data]=\"selectedTab.data\"\n [columns]=\"selectedTab.columns\"\n (event)=\"onEvent($event)\"\n ></le-block-view>\n }\n }\n </div>\n}\n", dependencies: [{ kind: "component", type: i0.forwardRef(() => NodeComponent), selector: "le-node", inputs: ["node", "config"], outputs: ["event"] }, { kind: "component", type: i0.forwardRef(() => TreeViewComponent), selector: "le-tree-view", inputs: ["data"] }, { kind: "component", type: i0.forwardRef(() => BlockViewComponent), selector: "le-block-view", inputs: ["data", "columns"], outputs: ["event"] }] });
866
961
  }
867
962
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SidePanelComponent, decorators: [{
868
963
  type: Component,
@@ -870,7 +965,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
870
965
  '[style.width]': '"100%"',
871
966
  '[style.overflow]': '"auto"',
872
967
  '[style.padding]': '"0 16px"',
873
- }, imports: [forwardRef(() => NodeComponent), TreeViewComponent, BlockViewComponent], providers: [LEDataService, LEFiltersService], template: "@if (node(); as node) {\n <le-node [node]=\"node\" [config]=\"data()?.config\" (event)=\"onEvent($event)\"></le-node>\n}\n\n@if (tabs(); as tabs) {\n <div class=\"le-tabs-nav\">\n @for (tab of tabs; track tab.type; let idx = $index) {\n <button\n class=\"le-button le-button-flat le-button--success\"\n [attr.aria-label]=\"'Select ' + tab.type\"\n [class.le-button--success]=\"selectedTabIndex() === idx\"\n (click)=\"onTabClick(idx)\"\n >\n {{ tab.label }}\n </button>\n }\n <span class=\"spacer\"></span>\n\n <button\n aria-label=\"Close side panel\"\n class=\"le-button le-button-flat\"\n (click)=\"event.emit({ type: 'close' })\"\n >Close</button>\n </div>\n}\n\n@if (selectedTab(); as selectedTab) {\n <div class=\"le-tabs-content\">\n @switch (selectedTab.type) {\n @case ('tree') {\n <le-tree-view [data]=\"selectedTab.data\"></le-tree-view>\n }\n @case ('table') {\n <le-node\n [node]=\"selectedTab.data\"\n [config]=\"data()?.config\"\n (event)=\"onEvent($event)\"\n ></le-node>\n }\n @case ('block') {\n <le-block-view\n [data]=\"selectedTab.data\"\n [columns]=\"selectedTab.columns\"\n (event)=\"onEvent($event)\"\n ></le-block-view>\n }\n }\n </div>\n}\n" }]
968
+ }, imports: [forwardRef(() => NodeComponent), TreeViewComponent, BlockViewComponent], providers: [LeViewService, LEFiltersService], template: "@if (node(); as node) {\n <le-node [node]=\"node\" [config]=\"data()?.config\" (event)=\"onEvent($event)\"></le-node>\n}\n\n@if (tabs(); as tabs) {\n <div class=\"le-tabs-nav\">\n @for (tab of tabs; track tab.type; let idx = $index) {\n <button\n class=\"le-button le-button-flat le-button--success\"\n [attr.aria-label]=\"'Select ' + tab.type\"\n [class.le-button--success]=\"selectedTabIndex() === idx\"\n (click)=\"onTabClick(idx)\"\n >\n {{ tab.label }}\n </button>\n }\n <span class=\"spacer\"></span>\n\n <button\n aria-label=\"Close side panel\"\n class=\"le-button le-button-flat\"\n (click)=\"event.emit({ type: 'close' })\"\n >Close</button>\n </div>\n}\n\n@if (selectedTab(); as selectedTab) {\n <div class=\"le-tabs-content\">\n @switch (selectedTab.type) {\n @case ('tree') {\n <le-tree-view [data]=\"selectedTab.data\"></le-tree-view>\n }\n @case ('table') {\n <le-node\n [node]=\"selectedTab.data\"\n [config]=\"data()?.config\"\n (event)=\"onEvent($event)\"\n ></le-node>\n }\n @case ('block') {\n <le-block-view\n [data]=\"selectedTab.data\"\n [columns]=\"selectedTab.columns\"\n (event)=\"onEvent($event)\"\n ></le-block-view>\n }\n }\n </div>\n}\n" }]
874
969
  }], ctorParameters: () => [] });
875
970
 
876
971
  const positionMap = {
@@ -1224,9 +1319,18 @@ const buildQueryString = (params) => {
1224
1319
  return query.filter((item) => !!item).join('&');
1225
1320
  };
1226
1321
 
1322
+ const download = (url) => {
1323
+ const a = document.createElement('a');
1324
+ a.style.display = 'none';
1325
+ a.href = url;
1326
+ document.body.appendChild(a);
1327
+ a.click();
1328
+ window.URL.revokeObjectURL(url);
1329
+ };
1330
+
1227
1331
  class TableViewComponent {
1228
1332
  apiService = inject(LEApiService);
1229
- dataService = inject(LEDataService);
1333
+ viewService = inject(LeViewService);
1230
1334
  filtersService = inject(LEFiltersService);
1231
1335
  sidePanelService = inject(LeSidePanelService);
1232
1336
  injector = inject(Injector);
@@ -1359,16 +1463,42 @@ class TableViewComponent {
1359
1463
  });
1360
1464
  }
1361
1465
  onCellClicked(data) {
1362
- const path = `${data.ref.resource}%23${data.ref.class_name}%3A${data.ref.class_version}%3A${data.ref.object_id}%3A${data.ref.object_version}`;
1466
+ if (data.type === 'reference') {
1467
+ this.processReferenceClick(data.data);
1468
+ }
1469
+ else if (data.type === 'file') {
1470
+ this.processFileClick(data.data);
1471
+ }
1472
+ }
1473
+ processReferenceClick(data) {
1474
+ const address = this.getAddressFromRef(data.ref);
1363
1475
  this.setView({
1364
- id: path,
1476
+ id: address,
1365
1477
  type: 'form',
1366
1478
  controlSource: {
1367
1479
  kind: 'object',
1368
- entity: path,
1480
+ entity: address,
1369
1481
  },
1370
1482
  });
1371
1483
  }
1484
+ processFileClick(data) {
1485
+ console.log('processFileClick', data);
1486
+ const ref = data.ref || data;
1487
+ if (ref && 'resource' in ref) {
1488
+ const address = this.getAddressFromRef(ref);
1489
+ this.apiService.getObjectByAddress(address, {}).subscribe({
1490
+ next: (res) => {
1491
+ download(res.rows[0].data);
1492
+ },
1493
+ });
1494
+ }
1495
+ else if (typeof ref === 'string') {
1496
+ download(ref);
1497
+ }
1498
+ }
1499
+ getAddressFromRef(ref) {
1500
+ return `${ref.resource}%23${ref.class_name}%3A${ref.class_version}%3A${ref.object_id}%3A${ref.object_version}`;
1501
+ }
1372
1502
  processRowClickAction(action, row) {
1373
1503
  const { type, node } = action;
1374
1504
  const clone = JSON.parse(JSON.stringify(node));
@@ -1421,7 +1551,7 @@ class TableViewComponent {
1421
1551
  }
1422
1552
  }
1423
1553
  setView(node) {
1424
- this.dataService.setView(node, !!this.config()?.skipLocationChange);
1554
+ this.viewService.setView(node, !!this.config()?.skipLocationChange);
1425
1555
  }
1426
1556
  setPagination(pagination) {
1427
1557
  this._pageSize.set(pagination?.pageSize ?? 0);
@@ -2145,10 +2275,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2145
2275
  }]
2146
2276
  }] });
2147
2277
 
2278
+ const isHttpResponse = (event) => {
2279
+ return event.type === HttpEventType.Response;
2280
+ };
2281
+
2148
2282
  let ID = 100_000_000;
2149
2283
  class FormViewComponent {
2150
2284
  apiService = inject(LEApiService);
2151
- dataService = inject(LEDataService);
2285
+ viewService = inject(LeViewService);
2152
2286
  attachmentService = inject(FormViewAttachmentService);
2153
2287
  viewportScroller = inject(ViewportScroller);
2154
2288
  toastService = inject(LeToastService);
@@ -2180,9 +2314,9 @@ class FormViewComponent {
2180
2314
  if (!action.async) {
2181
2315
  this._isLoading.set(true);
2182
2316
  }
2183
- return this.dataService
2317
+ return this.apiService
2184
2318
  .request(action.method, action.url, body)
2185
- .pipe(tap((response) => {
2319
+ .pipe(filter(isHttpResponse), tap((response) => {
2186
2320
  if (action.onSuccess && response.ok) {
2187
2321
  this.processActionList(action.onSuccess, response.body);
2188
2322
  }
@@ -2200,6 +2334,28 @@ class FormViewComponent {
2200
2334
  }
2201
2335
  return of(null);
2202
2336
  }));
2337
+ // return this.dataService
2338
+ // .request<ActionResponse, Record<string, any> | string>(action.method, action.url, body)
2339
+ // .pipe(
2340
+ // tap((response) => {
2341
+ // if (action.onSuccess && response.ok) {
2342
+ // this.processActionList(action.onSuccess, response.body);
2343
+ // } else if (action.onError && !response.ok) {
2344
+ // this.processActionList(action.onError);
2345
+ // } else {
2346
+ // this._isLoading.set(false);
2347
+ // }
2348
+ // this.event.emit({ type: 'refresh' });
2349
+ // this.event.emit({ type: 'close' });
2350
+ // }),
2351
+ // map(() => null),
2352
+ // catchError(() => {
2353
+ // if (action.onError) {
2354
+ // this.processActionList(action.onError);
2355
+ // }
2356
+ // return of(null);
2357
+ // }),
2358
+ // );
2203
2359
  },
2204
2360
  update_form: (action) => {
2205
2361
  const node = this.mapUpdateFormActionToFormNode(action.control_source);
@@ -2252,7 +2408,7 @@ class FormViewComponent {
2252
2408
  return of(null);
2253
2409
  },
2254
2410
  navigate_to_section: (action) => {
2255
- this.dataService.navigateByNodeId(action.section_id);
2411
+ this.viewService.navigateByNodeId(action.section_id);
2256
2412
  return of(null);
2257
2413
  },
2258
2414
  align_values: (action) => {
@@ -2289,7 +2445,7 @@ class FormViewComponent {
2289
2445
  const engine = this._engine();
2290
2446
  const sections = this._sections();
2291
2447
  const topLevelControls = this._topLevelControls();
2292
- const customCss = this.dataService.customCss() ?? '';
2448
+ const customCss = this.viewService.customCss() ?? '';
2293
2449
  if (!engine || !sections)
2294
2450
  return null;
2295
2451
  return {
@@ -2326,7 +2482,7 @@ class FormViewComponent {
2326
2482
  this._topLevelControls.set(form.controls ?? []);
2327
2483
  const resolvers = {
2328
2484
  attachment: (value) => this.attachmentService.resolve(value),
2329
- objectLatest: (className) => firstValueFrom(this.dataService.getObjectByClassName(className)),
2485
+ objectLatest: (className) => firstValueFrom(this.apiService.getObject(className)),
2330
2486
  };
2331
2487
  this._engine.set(createEngine(form, {}, resolvers));
2332
2488
  this.checkDelayedActions();
@@ -2343,7 +2499,7 @@ class FormViewComponent {
2343
2499
  });
2344
2500
  }
2345
2501
  setView(node) {
2346
- this.dataService.setView(node, !!this.config()?.skipLocationChange);
2502
+ this.viewService.setView(node, !!this.config()?.skipLocationChange);
2347
2503
  }
2348
2504
  processAction(action, response) {
2349
2505
  return this._actionHandlers[action.type](action, response);
@@ -2707,11 +2863,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2707
2863
 
2708
2864
  class LeContainerComponent {
2709
2865
  auth = inject(LEAuthService);
2710
- dataService = inject(LEDataService);
2866
+ viewService = inject(LeViewService);
2867
+ configService = inject(LeApiConfigService);
2711
2868
  sidebar = viewChild(SidebarComponent);
2712
2869
  data = computed(() => {
2713
- const config = this.dataService.config();
2714
- const view = this.dataService.view();
2870
+ const config = this.configService.config();
2871
+ const view = this.viewService.view();
2715
2872
  if (!config || !view)
2716
2873
  return null;
2717
2874
  return {
@@ -2722,10 +2879,18 @@ class LeContainerComponent {
2722
2879
  constructor() {
2723
2880
  this.listenAuthState();
2724
2881
  this.listenPageInit();
2725
- this.dataService.registerEffects();
2882
+ this.listenExternalViewChange();
2883
+ this.viewService.registerEffects();
2726
2884
  }
2727
2885
  onSelectionChange(view) {
2728
- this.dataService.setView(view);
2886
+ this.viewService.setView(view);
2887
+ }
2888
+ listenExternalViewChange() {
2889
+ this.configService.externalViewChange.pipe(takeUntilDestroyed()).subscribe({
2890
+ next: (data) => {
2891
+ this.viewService.setView(data);
2892
+ },
2893
+ });
2729
2894
  }
2730
2895
  listenAuthState() {
2731
2896
  effect(() => {
@@ -2733,14 +2898,18 @@ class LeContainerComponent {
2733
2898
  const isGuest = this.auth.isGuest();
2734
2899
  if (!token && !isGuest)
2735
2900
  return;
2736
- untracked(() => {
2737
- this.dataService.requestConfig();
2901
+ untracked(async () => {
2902
+ const config = await this.configService.requestConfig();
2903
+ if (!config) {
2904
+ return;
2905
+ }
2906
+ this.viewService.init(config);
2738
2907
  });
2739
2908
  });
2740
2909
  }
2741
2910
  listenPageInit() {
2742
2911
  effect(() => {
2743
- const path = this.dataService.parentPath();
2912
+ const path = this.viewService.parentPath();
2744
2913
  const sidebar = this.sidebar();
2745
2914
  if (!(path.length && sidebar))
2746
2915
  return;
@@ -2752,11 +2921,11 @@ class LeContainerComponent {
2752
2921
  });
2753
2922
  }
2754
2923
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2755
- 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", "config"], outputs: ["event"] }, { kind: "component", type: FiltersComponent, selector: "le-filters" }] });
2924
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: LeContainerComponent, isStandalone: true, selector: "le-container", providers: [LeViewService, 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", "config"], outputs: ["event"] }, { kind: "component", type: FiltersComponent, selector: "le-filters" }] });
2756
2925
  }
2757
2926
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeContainerComponent, decorators: [{
2758
2927
  type: Component,
2759
- 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" }]
2928
+ args: [{ selector: 'le-container', imports: [SidebarComponent, NodeComponent, FiltersComponent], providers: [LeViewService, 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" }]
2760
2929
  }], ctorParameters: () => [] });
2761
2930
 
2762
2931
  const provideConfig = (config) => {
@@ -2791,5 +2960,5 @@ const LEAuthInterceptor = (req, next) => {
2791
2960
  * Generated bundle index. Do not edit.
2792
2961
  */
2793
2962
 
2794
- export { CONFIG_TOKEN, LEAuthInterceptor, LEAuthService, CONFIG_TOKEN as LE_CONFIG_TOKEN, LE_REQUEST_CONTEXT_TOKEN, LeContainerComponent, LeToastService, provideConfig };
2963
+ export { CONFIG_TOKEN, IsParentMenuPipe, LEAuthInterceptor, LEAuthService, CONFIG_TOKEN as LE_CONFIG_TOKEN, LE_REQUEST_CONTEXT_TOKEN, LeApiConfigService, LeContainerComponent, LeToastService, provideConfig, provideConfig as provideEngineConfig };
2795
2964
  //# sourceMappingURL=planeasyinc-le-angular.mjs.map