@smartbit4all/ng-client 7.0.0 → 7.0.2

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, reflectComponentType, Injectable, inject, DOCUMENT, PLATFORM_ID, Optional, Inject, RendererStyleFlags2, input, computed, Component, HostListener, HostBinding, Directive, ViewContainerRef, ElementRef, Renderer2, ChangeDetectorRef, Input, output, signal, Injector, ViewChild, ViewChildren, effect, afterNextRender, NgZone, forwardRef, Pipe, ChangeDetectionStrategy, ViewEncapsulation, ApplicationRef, makeEnvironmentProviders, importProvidersFrom } from '@angular/core';
2
+ import { InjectionToken, reflectComponentType, Injectable, inject, DOCUMENT, PLATFORM_ID, Optional, Inject, RendererStyleFlags2, input, computed, Component, HostListener, HostBinding, Directive, ViewContainerRef, ElementRef, Renderer2, ChangeDetectorRef, Input, output, signal, Injector, ViewChild, ViewChildren, effect, afterNextRender, NgZone, forwardRef, Pipe, ChangeDetectionStrategy, ViewEncapsulation, ApplicationRef, EventEmitter, Output, viewChild, makeEnvironmentProviders, importProvidersFrom } from '@angular/core';
3
3
  import * as i1 from '@angular/common/http';
4
4
  import { HttpHeaders, HttpContext, HttpErrorResponse, HttpParams, provideHttpClient, withInterceptors, withInterceptorsFromDi } from '@angular/common/http';
5
5
  import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
@@ -7,7 +7,7 @@ import { NgxMaskDirective, provideNgxMask } from 'ngx-mask';
7
7
  import { QuillEditorComponent, QuillModule } from 'ngx-quill';
8
8
  import { DateFnsAdapter } from '@angular/material-date-fns-adapter';
9
9
  import { enUS, hu } from 'date-fns/locale';
10
- import { isPlatformBrowser, NgClass, NgTemplateOutlet, NgStyle, AsyncPipe, KeyValuePipe, DatePipe, Location, NgIf } from '@angular/common';
10
+ import { isPlatformBrowser, NgClass, NgTemplateOutlet, NgStyle, AsyncPipe, KeyValuePipe, DatePipe, Location, NgIf, NgForOf } from '@angular/common';
11
11
  import { Subject, lastValueFrom, tap, takeUntil, throwError, from, interval, startWith, map, distinctUntilChanged, catchError as catchError$1 } from 'rxjs';
12
12
  import { catchError, switchMap, takeUntil as takeUntil$1 } from 'rxjs/operators';
13
13
  import { MatButton, MatIconButton, MatMiniFabButton } from '@angular/material/button';
@@ -24,7 +24,7 @@ import { MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autoc
24
24
  import { MatChipGrid, MatChipRow, MatChipRemove, MatChipInput, MatChip } from '@angular/material/chips';
25
25
  import { deepEqual } from 'fast-equals';
26
26
  import { set } from 'date-fns';
27
- import { Overlay, OverlayPositionBuilder } from '@angular/cdk/overlay';
27
+ import { Overlay, OverlayPositionBuilder, ScrollDispatcher } from '@angular/cdk/overlay';
28
28
  import { TemplatePortal } from '@angular/cdk/portal';
29
29
  import { MatLabel, MatFormField, MatSuffix, MatHint, MatPrefix } from '@angular/material/form-field';
30
30
  import WaveSurfer from 'wavesurfer.js';
@@ -5288,7 +5288,7 @@ class UiActionService {
5288
5288
  }
5289
5289
  else if (uiAction.submit || uiAction.model) {
5290
5290
  if (options?.widgetId && options?.nodeId) {
5291
- uiActionRequest.params['clientPageModel'] = executor.getModel();
5291
+ uiActionRequest.params['clientPageModel'] = { data: executor.getModel() };
5292
5292
  }
5293
5293
  else {
5294
5294
  uiActionRequest.params['model'] = executor.getModel();
@@ -7474,6 +7474,7 @@ class HoverMenuComponent {
7474
7474
  this.overlay = inject(Overlay);
7475
7475
  this.viewContainerRef = inject(ViewContainerRef);
7476
7476
  this.overlayPositionBuilder = inject(OverlayPositionBuilder);
7477
+ this.scrollDispatcher = inject(ScrollDispatcher);
7477
7478
  /**
7478
7479
  * The open menu's overlay, and with it {@link isOpen}. A signal because the menu is also
7479
7480
  * closed from outside a template event — `UiMenuService`'s close signal — and the trigger
@@ -7495,6 +7496,10 @@ class HoverMenuComponent {
7495
7496
  this.submenuOpenMap = new Map();
7496
7497
  this.subActions = [];
7497
7498
  this.hasCheckedChildren = false;
7499
+ this.lastScrollContainer = null;
7500
+ this.onContainerScroll = () => {
7501
+ this.overlayRef?.updatePosition();
7502
+ };
7498
7503
  this.icon = 'chevron_right';
7499
7504
  }
7500
7505
  ngOnInit() {
@@ -7562,6 +7567,11 @@ class HoverMenuComponent {
7562
7567
  }
7563
7568
  closeMenu() {
7564
7569
  if (this.overlayRef) {
7570
+ const container = this.lastScrollContainer;
7571
+ if (container) {
7572
+ container.removeEventListener('scroll', this.onContainerScroll);
7573
+ this.lastScrollContainer = null;
7574
+ }
7565
7575
  this.overlayRef.dispose();
7566
7576
  this.overlayRef = null;
7567
7577
  this.hasCheckedChildren = false;
@@ -7598,19 +7608,42 @@ class HoverMenuComponent {
7598
7608
  var positions = isSubmenu
7599
7609
  ? getSubmenuPositions(this.menuOpenDirection())
7600
7610
  : getMenuPositions(triggerAction?.descriptor?.menu?.openDirection);
7611
+ const scrollContainer = this.getScrollContainer(triggerElement);
7601
7612
  let positionStrategy = this.overlayPositionBuilder
7602
7613
  .flexibleConnectedTo(triggerElement)
7603
7614
  .withFlexibleDimensions(false)
7604
7615
  .withPush(true)
7605
- .withPositions(positions);
7616
+ .withPositions(positions)
7617
+ .withScrollableContainers(this.scrollDispatcher.getAncestorScrollContainers(triggerElement));
7606
7618
  this.overlayRef = this.overlay.create({
7607
7619
  positionStrategy,
7608
7620
  scrollStrategy: this.overlay.scrollStrategies.reposition(),
7609
7621
  hasBackdrop: false,
7610
7622
  });
7623
+ if (scrollContainer) {
7624
+ this.lastScrollContainer = scrollContainer;
7625
+ scrollContainer.addEventListener('scroll', this.onContainerScroll, { passive: true });
7626
+ }
7611
7627
  let portal = new TemplatePortal(this.menuTemplate, this.viewContainerRef);
7612
7628
  this.overlayRef.attach(portal);
7613
7629
  }
7630
+ /**
7631
+ * The nearest scrolling ancestor of the trigger, if any. The CDK only knows about
7632
+ * `cdkScrollable` containers; a plain overflow container (a dialog body, a page section)
7633
+ * would otherwise scroll away under an open menu.
7634
+ */
7635
+ getScrollContainer(el) {
7636
+ let parent = el.parentElement;
7637
+ while (parent) {
7638
+ const style = window.getComputedStyle(parent);
7639
+ const overflow = style.overflow + style.overflowY;
7640
+ if (/auto|scroll/.test(overflow) && parent.scrollHeight > parent.clientHeight) {
7641
+ return parent;
7642
+ }
7643
+ parent = parent.parentElement;
7644
+ }
7645
+ return null;
7646
+ }
7614
7647
  toggleMenu(event) {
7615
7648
  if (!this.isOpen) {
7616
7649
  this.openMenu(event);
@@ -7714,6 +7747,7 @@ class ClickMenuComponent {
7714
7747
  this.overlay = inject(Overlay);
7715
7748
  this.viewContainerRef = inject(ViewContainerRef);
7716
7749
  this.overlayPositionBuilder = inject(OverlayPositionBuilder);
7750
+ this.scrollDispatcher = inject(ScrollDispatcher);
7717
7751
  /**
7718
7752
  * The open menu's overlay, and with it {@link isOpen}. A signal because the menu is also
7719
7753
  * closed from outside a template event — `UiMenuService`'s close signal — and the trigger
@@ -7733,6 +7767,10 @@ class ClickMenuComponent {
7733
7767
  this.submenuOpenMap = new Map();
7734
7768
  this.subActions = [];
7735
7769
  this.hasCheckedChildren = false;
7770
+ this.lastScrollContainer = null;
7771
+ this.onContainerScroll = () => {
7772
+ this.overlayRef?.updatePosition();
7773
+ };
7736
7774
  this.icon = 'chevron_right';
7737
7775
  }
7738
7776
  ngOnInit() {
@@ -7800,6 +7838,11 @@ class ClickMenuComponent {
7800
7838
  }
7801
7839
  closeMenu() {
7802
7840
  if (this.overlayRef) {
7841
+ const container = this.lastScrollContainer;
7842
+ if (container) {
7843
+ container.removeEventListener('scroll', this.onContainerScroll);
7844
+ this.lastScrollContainer = null;
7845
+ }
7803
7846
  this.overlayRef.dispose();
7804
7847
  this.overlayRef = null;
7805
7848
  this.hasCheckedChildren = false;
@@ -7835,19 +7878,42 @@ class ClickMenuComponent {
7835
7878
  var positions = isSubmenu
7836
7879
  ? getSubmenuPositions(this.menuOpenDirection())
7837
7880
  : getMenuPositions(triggerAction?.descriptor?.menu?.openDirection);
7881
+ const scrollContainer = this.getScrollContainer(triggerElement);
7838
7882
  let positionStrategy = this.overlayPositionBuilder
7839
7883
  .flexibleConnectedTo(triggerElement)
7840
7884
  .withFlexibleDimensions(false)
7841
7885
  .withPush(true)
7842
- .withPositions(positions);
7886
+ .withPositions(positions)
7887
+ .withScrollableContainers(this.scrollDispatcher.getAncestorScrollContainers(triggerElement));
7843
7888
  this.overlayRef = this.overlay.create({
7844
7889
  positionStrategy,
7845
7890
  scrollStrategy: this.overlay.scrollStrategies.reposition(),
7846
7891
  hasBackdrop: false,
7847
7892
  });
7893
+ if (scrollContainer) {
7894
+ this.lastScrollContainer = scrollContainer;
7895
+ scrollContainer.addEventListener('scroll', this.onContainerScroll, { passive: true });
7896
+ }
7848
7897
  let portal = new TemplatePortal(this.menuTemplate, this.viewContainerRef);
7849
7898
  this.overlayRef.attach(portal);
7850
7899
  }
7900
+ /**
7901
+ * The nearest scrolling ancestor of the trigger, if any. The CDK only knows about
7902
+ * `cdkScrollable` containers; a plain overflow container (a dialog body, a page section)
7903
+ * would otherwise scroll away under an open menu.
7904
+ */
7905
+ getScrollContainer(el) {
7906
+ let parent = el.parentElement;
7907
+ while (parent) {
7908
+ const style = window.getComputedStyle(parent);
7909
+ const overflow = style.overflow + style.overflowY;
7910
+ if (/auto|scroll/.test(overflow) && parent.scrollHeight > parent.clientHeight) {
7911
+ return parent;
7912
+ }
7913
+ parent = parent.parentElement;
7914
+ }
7915
+ return null;
7916
+ }
7851
7917
  toggleMenu(event) {
7852
7918
  if (!this.isOpen) {
7853
7919
  this.openMenu(event);
@@ -8236,6 +8302,7 @@ class UiActionToolbarComponent {
8236
8302
  }
8237
8303
  async onActionClicked(event, entry) {
8238
8304
  // event.stopPropagation();
8305
+ this.menuService.closeAllMenus();
8239
8306
  if (entry.model.uiAction.disabled) {
8240
8307
  return;
8241
8308
  }
@@ -8322,11 +8389,11 @@ class UiActionToolbarComponent {
8322
8389
  return MenuTriggerType;
8323
8390
  }
8324
8391
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: UiActionToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8325
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: UiActionToolbarComponent, isStandalone: true, selector: "smart-ui-action-toolbar", inputs: { uiActionModels: { classPropertyName: "uiActionModels", publicName: "uiActionModels", isSignal: false, isRequired: false, transformFunction: null }, uiActionDescriptorService: { classPropertyName: "uiActionDescriptorService", publicName: "uiActionDescriptorService", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: false, isRequired: false, transformFunction: null }, executor: { classPropertyName: "executor", publicName: "executor", isSignal: true, isRequired: false, transformFunction: null }, widgetId: { classPropertyName: "widgetId", publicName: "widgetId", isSignal: true, isRequired: false, transformFunction: null }, nodeId: { classPropertyName: "nodeId", publicName: "nodeId", isSignal: true, isRequired: false, transformFunction: null }, actionParams: { classPropertyName: "actionParams", publicName: "actionParams", isSignal: true, isRequired: false, transformFunction: null }, scrollOnWrap: { classPropertyName: "scrollOnWrap", publicName: "scrollOnWrap", isSignal: false, isRequired: false, transformFunction: null }, toolbarPropertes: { classPropertyName: "toolbarPropertes", publicName: "toolbarPropertes", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "@if (isScrollable && scrollOnWrap) {\n <ui-action-button\n [disabled]=\"!isScrollable\"\n [descriptor]=\"buttonLeft\"\n (actionClick)=\"scrollLeft()\"\n (mousedown)=\"scrollStart('left')\"\n (mouseup)=\"stopScroll()\"\n (mouseleave)=\"stopScroll()\"\n (touchstart)=\"scrollStart('left')\"\n (touchend)=\"stopScroll()\"\n />\n}\n\n<div\n #container\n class=\"uiActionButtonsContainer\"\n [ngClass]=\"{\n scrollableContent: scrollOnWrap,\n verticalToolbar: isVertical,\n horizontalToolbar: isHorizontal,\n alignedStart: isAlignedStart,\n alignedEnd: isAlignedEnd,\n }\"\n >\n <!--\n Tracked by a synthesized key \u2014 the action code plus its ordinal among the entries with\n the same code \u2014 because a code is not unique inside a toolbar. Unique by construction,\n and a button's DOM node follows its action across reordering and insertion. See A14.\n -->\n @for (entry of entries(); track entry.key) {\n @if (entry.model.uiAction.code === 'themeSelector') {\n <theme-selector [model]=\"entry.model\"></theme-selector>\n } @else if (entry.model.uiAction.subActions && entry.model.uiAction.subActions.length > 0) {\n <ng-container *ngTemplateOutlet=\"menuTypes; context: { entry: entry }\"></ng-container>\n } @else {\n <ui-action-button\n (mouseenter)=\"onHover()\"\n [descriptor]=\"entry.descriptor!\"\n [code]=\"entry.model.uiAction.code\"\n [disabled]=\"!!entry.model.uiAction.disabled\"\n [addedCssClass]=\"entry.model.cssClass\"\n [viewActivated]=\"entry.model.uiAction.viewActivated\"\n (actionClick)=\"onActionClicked($event, entry)\"\n (actionDoubleClick)=\"onActionDoubleClicked($event, entry)\"\n >\n </ui-action-button>\n }\n }\n</div>\n\n@if (isScrollable && scrollOnWrap) {\n <ui-action-button\n [disabled]=\"!isScrollable\"\n [descriptor]=\"buttonRight\"\n (actionClick)=\"scrollRight()\"\n (mousedown)=\"scrollStart('right')\"\n (mouseup)=\"stopScroll()\"\n (mouseleave)=\"stopScroll()\"\n (touchstart)=\"scrollStart('right')\"\n (touchend)=\"stopScroll()\"\n />\n}\n\n<ng-template #menuTypes let-entry=\"entry\">\n @switch ($safeNavigationMigration(entry?.model?.uiAction?.descriptor?.menu?.triggerType)) {\n @case (triggerType.HOVER) {\n <ui-hover-menu\n #menu\n [toolbarId]=\"id\"\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-hover-menu>\n }\n @case (triggerType.CLICK) {\n <ui-tiered-menu\n #menu\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-tiered-menu>\n }\n @default {\n <ui-tiered-menu\n #menu\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-tiered-menu>\n }\n }\n</ng-template>\n", styles: [":host:has(.uiActionButtonsContainer.scrollableContent){display:flex;flex-direction:row;justify-content:space-between;gap:.5rem;width:100%;align-items:center}:host:has(.verticalToolbar){height:100%}:host:has(.horizontalToolbar.alignedEnd){width:100%}.uiActionButtonsContainer{display:flex;flex-direction:row;gap:1rem;flex-wrap:wrap}.uiActionButtonsContainer ::ng-deep button{display:flex;gap:1rem;align-items:center;justify-content:center}.uiActionButtonsContainer ::ng-deep .buttonWrapper{position:relative;width:fit-content;height:fit-content}.scrollableContent{flex:1;flex-wrap:nowrap;overflow-x:auto;overflow-y:visible;display:flex;scrollbar-width:none;padding:.5rem 0;align-items:center}.scrollableContent::-webkit-scrollbar{display:none!important}.verticalToolbar{display:flex;flex-direction:column;height:100%}.verticalToolbar ::ng-deep ui-action-button,.verticalToolbar ::ng-deep button{width:100%}.alignedStart{justify-content:flex-start}.alignedEnd{justify-content:flex-end}\n"], dependencies: [{ kind: "component", type: UiActionButtonComponent, selector: "ui-action-button", inputs: ["disabled", "descriptor", "code", "viewActivated", "addedCssClass", "addBasicClasses", "iconPlaceholder"], outputs: ["actionClick", "actionDoubleClick"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ThemeSelectorComponent, selector: "theme-selector", inputs: ["model"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HoverMenuComponent, selector: "ui-hover-menu", inputs: ["triggerAction", "isSubmenu", "menuOpenDirection", "toolbarId"], outputs: ["actionClick", "submenuOpened"] }, { kind: "component", type: ClickMenuComponent, selector: "ui-tiered-menu", inputs: ["triggerAction", "isSubmenu", "menuOpenDirection"], outputs: ["actionClick", "submenuOpened"] }] }); }
8392
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: UiActionToolbarComponent, isStandalone: true, selector: "smart-ui-action-toolbar", inputs: { uiActionModels: { classPropertyName: "uiActionModels", publicName: "uiActionModels", isSignal: false, isRequired: false, transformFunction: null }, uiActionDescriptorService: { classPropertyName: "uiActionDescriptorService", publicName: "uiActionDescriptorService", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: false, isRequired: false, transformFunction: null }, executor: { classPropertyName: "executor", publicName: "executor", isSignal: true, isRequired: false, transformFunction: null }, widgetId: { classPropertyName: "widgetId", publicName: "widgetId", isSignal: true, isRequired: false, transformFunction: null }, nodeId: { classPropertyName: "nodeId", publicName: "nodeId", isSignal: true, isRequired: false, transformFunction: null }, actionParams: { classPropertyName: "actionParams", publicName: "actionParams", isSignal: true, isRequired: false, transformFunction: null }, scrollOnWrap: { classPropertyName: "scrollOnWrap", publicName: "scrollOnWrap", isSignal: false, isRequired: false, transformFunction: null }, toolbarPropertes: { classPropertyName: "toolbarPropertes", publicName: "toolbarPropertes", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "@if (isScrollable && scrollOnWrap) {\n <ui-action-button\n [disabled]=\"!isScrollable\"\n [descriptor]=\"buttonLeft\"\n (actionClick)=\"scrollLeft()\"\n (mousedown)=\"scrollStart('left')\"\n (mouseup)=\"stopScroll()\"\n (mouseleave)=\"stopScroll()\"\n (touchstart)=\"scrollStart('left')\"\n (touchend)=\"stopScroll()\"\n />\n}\n\n<div\n #container\n class=\"uiActionButtonsContainer\"\n (click)=\"$event.stopPropagation()\"\n [ngClass]=\"{\n scrollableContent: scrollOnWrap,\n verticalToolbar: isVertical,\n horizontalToolbar: isHorizontal,\n alignedStart: isAlignedStart,\n alignedEnd: isAlignedEnd,\n }\"\n >\n <!--\n Tracked by a synthesized key \u2014 the action code plus its ordinal among the entries with\n the same code \u2014 because a code is not unique inside a toolbar. Unique by construction,\n and a button's DOM node follows its action across reordering and insertion. See A14.\n -->\n @for (entry of entries(); track entry.key) {\n @if (entry.model.uiAction.code === 'themeSelector') {\n <theme-selector [model]=\"entry.model\"></theme-selector>\n } @else if (entry.model.uiAction.subActions && entry.model.uiAction.subActions.length > 0) {\n <ng-container *ngTemplateOutlet=\"menuTypes; context: { entry: entry }\"></ng-container>\n } @else {\n <ui-action-button\n (mouseenter)=\"onHover()\"\n [descriptor]=\"entry.descriptor!\"\n [code]=\"entry.model.uiAction.code\"\n [disabled]=\"!!entry.model.uiAction.disabled\"\n [addedCssClass]=\"entry.model.cssClass\"\n [viewActivated]=\"entry.model.uiAction.viewActivated\"\n (actionClick)=\"onActionClicked($event, entry)\"\n (actionDoubleClick)=\"onActionDoubleClicked($event, entry)\"\n >\n </ui-action-button>\n }\n }\n</div>\n\n@if (isScrollable && scrollOnWrap) {\n <ui-action-button\n [disabled]=\"!isScrollable\"\n [descriptor]=\"buttonRight\"\n (actionClick)=\"scrollRight()\"\n (mousedown)=\"scrollStart('right')\"\n (mouseup)=\"stopScroll()\"\n (mouseleave)=\"stopScroll()\"\n (touchstart)=\"scrollStart('right')\"\n (touchend)=\"stopScroll()\"\n />\n}\n\n<ng-template #menuTypes let-entry=\"entry\">\n @switch ($safeNavigationMigration(entry?.model?.uiAction?.descriptor?.menu?.triggerType)) {\n @case (triggerType.HOVER) {\n <ui-hover-menu\n #menu\n [toolbarId]=\"id\"\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-hover-menu>\n }\n @case (triggerType.CLICK) {\n <ui-tiered-menu\n #menu\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-tiered-menu>\n }\n @default {\n <ui-tiered-menu\n #menu\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-tiered-menu>\n }\n }\n</ng-template>\n", styles: [":host:has(.uiActionButtonsContainer.scrollableContent){display:flex;flex-direction:row;justify-content:space-between;gap:.5rem;width:100%;align-items:center}:host:has(.verticalToolbar){height:100%}:host:has(.horizontalToolbar.alignedEnd){width:100%}.uiActionButtonsContainer{display:flex;flex-direction:row;gap:1rem;flex-wrap:wrap}.uiActionButtonsContainer ::ng-deep button{display:flex;gap:1rem;align-items:center;justify-content:center}.uiActionButtonsContainer ::ng-deep .buttonWrapper{position:relative;width:fit-content;height:fit-content}.scrollableContent{flex:1;flex-wrap:nowrap;overflow-x:auto;overflow-y:visible;display:flex;scrollbar-width:none;padding:.5rem 0;align-items:center}.scrollableContent::-webkit-scrollbar{display:none!important}.verticalToolbar{display:flex;flex-direction:column;height:100%}.verticalToolbar ::ng-deep ui-action-button,.verticalToolbar ::ng-deep button{width:100%}.alignedStart{justify-content:flex-start}.alignedEnd{justify-content:flex-end}\n"], dependencies: [{ kind: "component", type: UiActionButtonComponent, selector: "ui-action-button", inputs: ["disabled", "descriptor", "code", "viewActivated", "addedCssClass", "addBasicClasses", "iconPlaceholder"], outputs: ["actionClick", "actionDoubleClick"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ThemeSelectorComponent, selector: "theme-selector", inputs: ["model"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HoverMenuComponent, selector: "ui-hover-menu", inputs: ["triggerAction", "isSubmenu", "menuOpenDirection", "toolbarId"], outputs: ["actionClick", "submenuOpened"] }, { kind: "component", type: ClickMenuComponent, selector: "ui-tiered-menu", inputs: ["triggerAction", "isSubmenu", "menuOpenDirection"], outputs: ["actionClick", "submenuOpened"] }] }); }
8326
8393
  }
8327
8394
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: UiActionToolbarComponent, decorators: [{
8328
8395
  type: Component,
8329
- args: [{ selector: 'smart-ui-action-toolbar', imports: [UiActionButtonComponent, NgClass, ThemeSelectorComponent, NgTemplateOutlet, HoverMenuComponent, ClickMenuComponent], template: "@if (isScrollable && scrollOnWrap) {\n <ui-action-button\n [disabled]=\"!isScrollable\"\n [descriptor]=\"buttonLeft\"\n (actionClick)=\"scrollLeft()\"\n (mousedown)=\"scrollStart('left')\"\n (mouseup)=\"stopScroll()\"\n (mouseleave)=\"stopScroll()\"\n (touchstart)=\"scrollStart('left')\"\n (touchend)=\"stopScroll()\"\n />\n}\n\n<div\n #container\n class=\"uiActionButtonsContainer\"\n [ngClass]=\"{\n scrollableContent: scrollOnWrap,\n verticalToolbar: isVertical,\n horizontalToolbar: isHorizontal,\n alignedStart: isAlignedStart,\n alignedEnd: isAlignedEnd,\n }\"\n >\n <!--\n Tracked by a synthesized key \u2014 the action code plus its ordinal among the entries with\n the same code \u2014 because a code is not unique inside a toolbar. Unique by construction,\n and a button's DOM node follows its action across reordering and insertion. See A14.\n -->\n @for (entry of entries(); track entry.key) {\n @if (entry.model.uiAction.code === 'themeSelector') {\n <theme-selector [model]=\"entry.model\"></theme-selector>\n } @else if (entry.model.uiAction.subActions && entry.model.uiAction.subActions.length > 0) {\n <ng-container *ngTemplateOutlet=\"menuTypes; context: { entry: entry }\"></ng-container>\n } @else {\n <ui-action-button\n (mouseenter)=\"onHover()\"\n [descriptor]=\"entry.descriptor!\"\n [code]=\"entry.model.uiAction.code\"\n [disabled]=\"!!entry.model.uiAction.disabled\"\n [addedCssClass]=\"entry.model.cssClass\"\n [viewActivated]=\"entry.model.uiAction.viewActivated\"\n (actionClick)=\"onActionClicked($event, entry)\"\n (actionDoubleClick)=\"onActionDoubleClicked($event, entry)\"\n >\n </ui-action-button>\n }\n }\n</div>\n\n@if (isScrollable && scrollOnWrap) {\n <ui-action-button\n [disabled]=\"!isScrollable\"\n [descriptor]=\"buttonRight\"\n (actionClick)=\"scrollRight()\"\n (mousedown)=\"scrollStart('right')\"\n (mouseup)=\"stopScroll()\"\n (mouseleave)=\"stopScroll()\"\n (touchstart)=\"scrollStart('right')\"\n (touchend)=\"stopScroll()\"\n />\n}\n\n<ng-template #menuTypes let-entry=\"entry\">\n @switch ($safeNavigationMigration(entry?.model?.uiAction?.descriptor?.menu?.triggerType)) {\n @case (triggerType.HOVER) {\n <ui-hover-menu\n #menu\n [toolbarId]=\"id\"\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-hover-menu>\n }\n @case (triggerType.CLICK) {\n <ui-tiered-menu\n #menu\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-tiered-menu>\n }\n @default {\n <ui-tiered-menu\n #menu\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-tiered-menu>\n }\n }\n</ng-template>\n", styles: [":host:has(.uiActionButtonsContainer.scrollableContent){display:flex;flex-direction:row;justify-content:space-between;gap:.5rem;width:100%;align-items:center}:host:has(.verticalToolbar){height:100%}:host:has(.horizontalToolbar.alignedEnd){width:100%}.uiActionButtonsContainer{display:flex;flex-direction:row;gap:1rem;flex-wrap:wrap}.uiActionButtonsContainer ::ng-deep button{display:flex;gap:1rem;align-items:center;justify-content:center}.uiActionButtonsContainer ::ng-deep .buttonWrapper{position:relative;width:fit-content;height:fit-content}.scrollableContent{flex:1;flex-wrap:nowrap;overflow-x:auto;overflow-y:visible;display:flex;scrollbar-width:none;padding:.5rem 0;align-items:center}.scrollableContent::-webkit-scrollbar{display:none!important}.verticalToolbar{display:flex;flex-direction:column;height:100%}.verticalToolbar ::ng-deep ui-action-button,.verticalToolbar ::ng-deep button{width:100%}.alignedStart{justify-content:flex-start}.alignedEnd{justify-content:flex-end}\n"] }]
8396
+ args: [{ selector: 'smart-ui-action-toolbar', imports: [UiActionButtonComponent, NgClass, ThemeSelectorComponent, NgTemplateOutlet, HoverMenuComponent, ClickMenuComponent], template: "@if (isScrollable && scrollOnWrap) {\n <ui-action-button\n [disabled]=\"!isScrollable\"\n [descriptor]=\"buttonLeft\"\n (actionClick)=\"scrollLeft()\"\n (mousedown)=\"scrollStart('left')\"\n (mouseup)=\"stopScroll()\"\n (mouseleave)=\"stopScroll()\"\n (touchstart)=\"scrollStart('left')\"\n (touchend)=\"stopScroll()\"\n />\n}\n\n<div\n #container\n class=\"uiActionButtonsContainer\"\n (click)=\"$event.stopPropagation()\"\n [ngClass]=\"{\n scrollableContent: scrollOnWrap,\n verticalToolbar: isVertical,\n horizontalToolbar: isHorizontal,\n alignedStart: isAlignedStart,\n alignedEnd: isAlignedEnd,\n }\"\n >\n <!--\n Tracked by a synthesized key \u2014 the action code plus its ordinal among the entries with\n the same code \u2014 because a code is not unique inside a toolbar. Unique by construction,\n and a button's DOM node follows its action across reordering and insertion. See A14.\n -->\n @for (entry of entries(); track entry.key) {\n @if (entry.model.uiAction.code === 'themeSelector') {\n <theme-selector [model]=\"entry.model\"></theme-selector>\n } @else if (entry.model.uiAction.subActions && entry.model.uiAction.subActions.length > 0) {\n <ng-container *ngTemplateOutlet=\"menuTypes; context: { entry: entry }\"></ng-container>\n } @else {\n <ui-action-button\n (mouseenter)=\"onHover()\"\n [descriptor]=\"entry.descriptor!\"\n [code]=\"entry.model.uiAction.code\"\n [disabled]=\"!!entry.model.uiAction.disabled\"\n [addedCssClass]=\"entry.model.cssClass\"\n [viewActivated]=\"entry.model.uiAction.viewActivated\"\n (actionClick)=\"onActionClicked($event, entry)\"\n (actionDoubleClick)=\"onActionDoubleClicked($event, entry)\"\n >\n </ui-action-button>\n }\n }\n</div>\n\n@if (isScrollable && scrollOnWrap) {\n <ui-action-button\n [disabled]=\"!isScrollable\"\n [descriptor]=\"buttonRight\"\n (actionClick)=\"scrollRight()\"\n (mousedown)=\"scrollStart('right')\"\n (mouseup)=\"stopScroll()\"\n (mouseleave)=\"stopScroll()\"\n (touchstart)=\"scrollStart('right')\"\n (touchend)=\"stopScroll()\"\n />\n}\n\n<ng-template #menuTypes let-entry=\"entry\">\n @switch ($safeNavigationMigration(entry?.model?.uiAction?.descriptor?.menu?.triggerType)) {\n @case (triggerType.HOVER) {\n <ui-hover-menu\n #menu\n [toolbarId]=\"id\"\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-hover-menu>\n }\n @case (triggerType.CLICK) {\n <ui-tiered-menu\n #menu\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-tiered-menu>\n }\n @default {\n <ui-tiered-menu\n #menu\n (mouseenter)=\"onHover()\"\n [triggerAction]=\"entry.model.uiAction\"\n (actionClick)=\"onActionClicked($event, entry)\"\n ></ui-tiered-menu>\n }\n }\n</ng-template>\n", styles: [":host:has(.uiActionButtonsContainer.scrollableContent){display:flex;flex-direction:row;justify-content:space-between;gap:.5rem;width:100%;align-items:center}:host:has(.verticalToolbar){height:100%}:host:has(.horizontalToolbar.alignedEnd){width:100%}.uiActionButtonsContainer{display:flex;flex-direction:row;gap:1rem;flex-wrap:wrap}.uiActionButtonsContainer ::ng-deep button{display:flex;gap:1rem;align-items:center;justify-content:center}.uiActionButtonsContainer ::ng-deep .buttonWrapper{position:relative;width:fit-content;height:fit-content}.scrollableContent{flex:1;flex-wrap:nowrap;overflow-x:auto;overflow-y:visible;display:flex;scrollbar-width:none;padding:.5rem 0;align-items:center}.scrollableContent::-webkit-scrollbar{display:none!important}.verticalToolbar{display:flex;flex-direction:column;height:100%}.verticalToolbar ::ng-deep ui-action-button,.verticalToolbar ::ng-deep button{width:100%}.alignedStart{justify-content:flex-start}.alignedEnd{justify-content:flex-end}\n"] }]
8330
8397
  }], ctorParameters: () => [], propDecorators: { containerRef: [{
8331
8398
  type: ViewChild,
8332
8399
  args: ['container', { static: false }]
@@ -8557,11 +8624,11 @@ class SmartfileuploaderComponent {
8557
8624
  };
8558
8625
  }
8559
8626
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartfileuploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8560
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartfileuploaderComponent, isStandalone: true, selector: "smartfileuploader", inputs: { uploadCallback: { classPropertyName: "uploadCallback", publicName: "uploadCallback", isSignal: true, isRequired: true, transformFunction: null }, fileFormats: { classPropertyName: "fileFormats", publicName: "fileFormats", isSignal: true, isRequired: false, transformFunction: null }, maxSizeMb: { classPropertyName: "maxSizeMb", publicName: "maxSizeMb", isSignal: true, isRequired: false, transformFunction: null }, i18n: { classPropertyName: "i18n", publicName: "i18n", isSignal: false, isRequired: false, transformFunction: null }, useIconButton: { classPropertyName: "useIconButton", publicName: "useIconButton", isSignal: true, isRequired: false, transformFunction: null }, isMultiple: { classPropertyName: "isMultiple", publicName: "isMultiple", isSignal: true, isRequired: false, transformFunction: null }, autoUpload: { classPropertyName: "autoUpload", publicName: "autoUpload", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div\n class=\"container\"\n [ngClass]=\"{ disabledWidget: isDisabled() }\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n [class.dragover]=\"isDragOver\"\n >\n <div class=\"fileContainer\" (click)=\"fileInput.click()\">\n <input\n #fileInput\n id=\"addFile\"\n placeholder=\"fileInput\"\n type=\"file\"\n (change)=\"getFile($event)\"\n class=\"file\"\n accept=\"{{ fileFormats()?.join(', ') }}\"\n [size]=\"maxSizeMb()\"\n [multiple]=\"isMultiple()\"\n [disabled]=\"isDisabled()\"\n style=\"display: none\"\n />\n <div class=\"fileUploadContentContainer\">\n <div class=\"icon\">\n @if (useIconButton()) {\n <mat-label class=\"addFileButton\">\n <mat-icon color=\"primary\" class=\"addCircle\">add_circle</mat-icon>\n </mat-label>\n }\n @if (!useIconButton()) {\n <button mat-raised-button color=\"primary\" class=\"addFileButton\">\n {{ i18n!.addFile }}\n </button>\n }\n </div>\n <div class=\"labels\">\n @if (useIconButton()) {\n <mat-label class=\"label primary title\">\n {{ i18n!.addFile }}\n </mat-label>\n }\n <mat-label class=\"label secondary\"> {{ i18n!.browseOrDrag }} </mat-label>\n <mat-label class=\"subLabel primary\"> {{ i18n!.maxSize }} </mat-label>\n <mat-label class=\"subLabel primary\"> {{ i18n!.formats }} </mat-label>\n </div>\n @if (files.length) {\n <div class=\"uploadButton\">\n <ui-action-button (actionClick)=\"uploadFile()\" [descriptor]=\"uploadButton\">\n </ui-action-button>\n </div>\n }\n </div>\n </div>\n\n @if (errors.length) {\n <div class=\"errorMessage\">\n <smart-icon [icon]=\"'error'\" [color]=\"'warn'\"></smart-icon>\n <div class=\"errors\">\n @for (error of errors; track error) {\n <span>{{ error }}</span>\n }\n </div>\n </div>\n }\n\n @if (files.length) {\n <div class=\"uploadedFilesContainer\">\n @for (file of files; track file; let i = $index) {\n <div class=\"uploadedFile\">\n @if (filePreviewUrl(file)) {\n <img [src]=\"filePreviewUrl(file)\" [alt]=\"file.name\" width=\"50\" height=\"50\" />\n } @else {\n <smart-icon [icon]=\"'insert_drive_file'\"></smart-icon>\n }\n <div class=\"fileData\">\n <div class=\"fileDataContainer\">\n <span class=\"fileName\">{{ file.name }}</span>\n <span class=\"fileSize\">{{ formatSize(file.size) }}</span>\n </div>\n </div>\n <div class=\"fileActions\">\n <smart-icon class=\"downloadIcon\" icon=\"download\" (click)=\"downloadFile(file)\"></smart-icon>\n <smart-icon class=\"removeIcon\" icon=\"delete\" (click)=\"remove(i)\"></smart-icon>\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{--border-color: #a6aabd60;--warninig-color: #be2d2e;--def-border-radius: .5rem}.container{display:flex;flex-direction:column;border:2px dashed var(--border-color);border-radius:var(--def-border-radius)}.fileContainer{cursor:pointer;padding:1rem;display:flex;flex-direction:column}.fileContainer:hover{background-color:rgb(from var(--border-color) r g b / .1)}.disabledWidget ::ng-deep .fileContainer:hover{background-color:unset;cursor:unset}.disabledWidget ::ng-deep *{opacity:.85}.dragover{background-color:rgb(from var(--border-color) r g b / .1)}.fileUploadContentContainer{display:flex;flex-direction:row;gap:1rem}.icon mat-icon{font-size:3rem;width:unset;height:unset}.icon{align-content:center}.labels{flex:1;display:flex;flex-direction:column;justify-content:center;width:fit-content}.uploadButton{align-content:center}.primary{color:var(--primary-color)}.secondary{color:var(--gray)}.label{margin:unset}.subLabel{font-size:smaller}.title{padding-bottom:.3rem}.errorMessage,.uploadedFilesContainer{border-top:2px solid var(--border-color)}.errorMessage{display:flex;flex-direction:row;align-items:center;color:var(--warninig-color);padding:.5rem 1rem;gap:1rem}.errorMessage ::ng-deep mat-icon{color:var(--warninig-color)}.errors{display:flex;flex-direction:column}.uploadedFile{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;gap:1rem}.uploadedFile:last-child{border-bottom:none}.fileSize{display:flex;flex-direction:row;font-size:smaller}.fileData{flex:1;display:flex;flex-direction:column}.fileDataContainer{display:flex;flex-direction:column;justify-content:flex-end;width:fit-content}.removeIcon ::ng-deep mat-icon{color:var(--warninig-color)}smart-icon ::ng-deep mat-icon{font-size:3rem;width:unset;height:unset}.fileActions{display:flex;flex-direction:row;justify-content:flex-end;gap:.5rem}.removeIcon ::ng-deep i,.removeIcon ::ng-deep mat-icon{color:var(--warninig-color)}.removeIcon ::ng-deep mat-icon,.downloadIcon ::ng-deep mat-icon{font-size:2rem}.removeIcon:hover,.downloadIcon:hover{cursor:pointer}smart-icon{display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: UiActionButtonComponent, selector: "ui-action-button", inputs: ["disabled", "descriptor", "code", "viewActivated", "addedCssClass", "addBasicClasses", "iconPlaceholder"], outputs: ["actionClick", "actionDoubleClick"] }, { kind: "component", type: SmartIconComponent, selector: "smart-icon", inputs: ["icon", "color", "imageResource"] }] }); }
8627
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartfileuploaderComponent, isStandalone: true, selector: "smartfileuploader", inputs: { uploadCallback: { classPropertyName: "uploadCallback", publicName: "uploadCallback", isSignal: true, isRequired: true, transformFunction: null }, fileFormats: { classPropertyName: "fileFormats", publicName: "fileFormats", isSignal: true, isRequired: false, transformFunction: null }, maxSizeMb: { classPropertyName: "maxSizeMb", publicName: "maxSizeMb", isSignal: true, isRequired: false, transformFunction: null }, i18n: { classPropertyName: "i18n", publicName: "i18n", isSignal: false, isRequired: false, transformFunction: null }, useIconButton: { classPropertyName: "useIconButton", publicName: "useIconButton", isSignal: true, isRequired: false, transformFunction: null }, isMultiple: { classPropertyName: "isMultiple", publicName: "isMultiple", isSignal: true, isRequired: false, transformFunction: null }, autoUpload: { classPropertyName: "autoUpload", publicName: "autoUpload", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div\n class=\"container\"\n [ngClass]=\"{ disabledWidget: isDisabled() }\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n [class.dragover]=\"isDragOver\"\n >\n <div class=\"fileContainer\" (click)=\"fileInput.click()\">\n <input\n #fileInput\n id=\"addFile\"\n placeholder=\"fileInput\"\n type=\"file\"\n (change)=\"getFile($event)\"\n class=\"file\"\n accept=\"{{ fileFormats()?.join(', ') }}\"\n [size]=\"maxSizeMb()\"\n [multiple]=\"isMultiple()\"\n [disabled]=\"isDisabled()\"\n style=\"display: none\"\n />\n <div class=\"fileUploadContentContainer\">\n <div class=\"icon\">\n @if (useIconButton()) {\n <mat-label class=\"addFileButton\">\n <mat-icon color=\"primary\" class=\"addCircle\">add_circle</mat-icon>\n </mat-label>\n }\n @if (!useIconButton()) {\n <button mat-raised-button color=\"primary\" class=\"addFileButton\">\n {{ i18n!.addFile }}\n </button>\n }\n </div>\n <div class=\"labels\">\n @if (useIconButton()) {\n <mat-label class=\"label primary title\">\n {{ i18n!.addFile }}\n </mat-label>\n }\n <mat-label class=\"label secondary\"> {{ i18n!.browseOrDrag }} </mat-label>\n <mat-label class=\"subLabel primary\"> {{ i18n!.maxSize }} </mat-label>\n <mat-label class=\"subLabel primary\"> {{ i18n!.formats }} </mat-label>\n </div>\n @if (files.length) {\n <div class=\"uploadButton\">\n <ui-action-button\n (actionClick)=\"uploadFile()\"\n [code]=\"'default-upload'\"\n [descriptor]=\"uploadButton\"\n >\n </ui-action-button>\n </div>\n }\n </div>\n </div>\n\n @if (errors.length) {\n <div class=\"errorMessage\">\n <smart-icon [icon]=\"'error'\" [color]=\"'warn'\"></smart-icon>\n <div class=\"errors\">\n @for (error of errors; track error) {\n <span>{{ error }}</span>\n }\n </div>\n </div>\n }\n\n @if (files.length) {\n <div class=\"uploadedFilesContainer\">\n @for (file of files; track file; let i = $index) {\n <div class=\"uploadedFile\">\n @if (filePreviewUrl(file)) {\n <img [src]=\"filePreviewUrl(file)\" [alt]=\"file.name\" width=\"50\" height=\"50\" />\n } @else {\n <smart-icon [icon]=\"'insert_drive_file'\"></smart-icon>\n }\n <div class=\"fileData\">\n <div class=\"fileDataContainer\">\n <span class=\"fileName\">{{ file.name }}</span>\n <span class=\"fileSize\">{{ formatSize(file.size) }}</span>\n </div>\n </div>\n <div class=\"fileActions\">\n <smart-icon\n class=\"downloadIcon\"\n icon=\"download\"\n (click)=\"downloadFile(file)\"\n [attr.data-testid]=\"'default_download'\"\n ></smart-icon>\n <smart-icon\n class=\"removeIcon\"\n icon=\"delete\"\n [attr.data-testid]=\"'default_remove'\"\n (click)=\"remove(i)\"\n ></smart-icon>\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{--border-color: #a6aabd60;--warninig-color: #be2d2e;--def-border-radius: .5rem}.container{display:flex;flex-direction:column;border:2px dashed var(--border-color);border-radius:var(--def-border-radius)}.fileContainer{cursor:pointer;padding:1rem;display:flex;flex-direction:column}.fileContainer:hover{background-color:rgb(from var(--border-color) r g b / .1)}.disabledWidget ::ng-deep .fileContainer:hover{background-color:unset;cursor:unset}.disabledWidget ::ng-deep *{opacity:.85}.dragover{background-color:rgb(from var(--border-color) r g b / .1)}.fileUploadContentContainer{display:flex;flex-direction:row;gap:1rem}.icon mat-icon{font-size:3rem;width:unset;height:unset}.icon{align-content:center}.labels{flex:1;display:flex;flex-direction:column;justify-content:center;width:fit-content}.uploadButton{align-content:center}.primary{color:var(--primary-color)}.secondary{color:var(--gray)}.label{margin:unset}.subLabel{font-size:smaller}.title{padding-bottom:.3rem}.errorMessage,.uploadedFilesContainer{border-top:2px solid var(--border-color)}.errorMessage{display:flex;flex-direction:row;align-items:center;color:var(--warninig-color);padding:.5rem 1rem;gap:1rem}.errorMessage ::ng-deep mat-icon{color:var(--warninig-color)}.errors{display:flex;flex-direction:column}.uploadedFile{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;gap:1rem}.uploadedFile:last-child{border-bottom:none}.fileSize{display:flex;flex-direction:row;font-size:smaller}.fileData{flex:1;display:flex;flex-direction:column}.fileDataContainer{display:flex;flex-direction:column;justify-content:flex-end;width:fit-content}.removeIcon ::ng-deep mat-icon{color:var(--warninig-color)}smart-icon ::ng-deep mat-icon{font-size:3rem;width:unset;height:unset}.fileActions{display:flex;flex-direction:row;justify-content:flex-end;gap:.5rem}.removeIcon ::ng-deep i,.removeIcon ::ng-deep mat-icon{color:var(--warninig-color)}.removeIcon ::ng-deep mat-icon,.downloadIcon ::ng-deep mat-icon{font-size:2rem}.removeIcon:hover,.downloadIcon:hover{cursor:pointer}smart-icon{display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: UiActionButtonComponent, selector: "ui-action-button", inputs: ["disabled", "descriptor", "code", "viewActivated", "addedCssClass", "addBasicClasses", "iconPlaceholder"], outputs: ["actionClick", "actionDoubleClick"] }, { kind: "component", type: SmartIconComponent, selector: "smart-icon", inputs: ["icon", "color", "imageResource"] }] }); }
8561
8628
  }
8562
8629
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartfileuploaderComponent, decorators: [{
8563
8630
  type: Component,
8564
- args: [{ selector: 'smartfileuploader', imports: [NgClass, MatLabel, MatIcon, MatButton, UiActionButtonComponent, SmartIconComponent], template: "<div\n class=\"container\"\n [ngClass]=\"{ disabledWidget: isDisabled() }\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n [class.dragover]=\"isDragOver\"\n >\n <div class=\"fileContainer\" (click)=\"fileInput.click()\">\n <input\n #fileInput\n id=\"addFile\"\n placeholder=\"fileInput\"\n type=\"file\"\n (change)=\"getFile($event)\"\n class=\"file\"\n accept=\"{{ fileFormats()?.join(', ') }}\"\n [size]=\"maxSizeMb()\"\n [multiple]=\"isMultiple()\"\n [disabled]=\"isDisabled()\"\n style=\"display: none\"\n />\n <div class=\"fileUploadContentContainer\">\n <div class=\"icon\">\n @if (useIconButton()) {\n <mat-label class=\"addFileButton\">\n <mat-icon color=\"primary\" class=\"addCircle\">add_circle</mat-icon>\n </mat-label>\n }\n @if (!useIconButton()) {\n <button mat-raised-button color=\"primary\" class=\"addFileButton\">\n {{ i18n!.addFile }}\n </button>\n }\n </div>\n <div class=\"labels\">\n @if (useIconButton()) {\n <mat-label class=\"label primary title\">\n {{ i18n!.addFile }}\n </mat-label>\n }\n <mat-label class=\"label secondary\"> {{ i18n!.browseOrDrag }} </mat-label>\n <mat-label class=\"subLabel primary\"> {{ i18n!.maxSize }} </mat-label>\n <mat-label class=\"subLabel primary\"> {{ i18n!.formats }} </mat-label>\n </div>\n @if (files.length) {\n <div class=\"uploadButton\">\n <ui-action-button (actionClick)=\"uploadFile()\" [descriptor]=\"uploadButton\">\n </ui-action-button>\n </div>\n }\n </div>\n </div>\n\n @if (errors.length) {\n <div class=\"errorMessage\">\n <smart-icon [icon]=\"'error'\" [color]=\"'warn'\"></smart-icon>\n <div class=\"errors\">\n @for (error of errors; track error) {\n <span>{{ error }}</span>\n }\n </div>\n </div>\n }\n\n @if (files.length) {\n <div class=\"uploadedFilesContainer\">\n @for (file of files; track file; let i = $index) {\n <div class=\"uploadedFile\">\n @if (filePreviewUrl(file)) {\n <img [src]=\"filePreviewUrl(file)\" [alt]=\"file.name\" width=\"50\" height=\"50\" />\n } @else {\n <smart-icon [icon]=\"'insert_drive_file'\"></smart-icon>\n }\n <div class=\"fileData\">\n <div class=\"fileDataContainer\">\n <span class=\"fileName\">{{ file.name }}</span>\n <span class=\"fileSize\">{{ formatSize(file.size) }}</span>\n </div>\n </div>\n <div class=\"fileActions\">\n <smart-icon class=\"downloadIcon\" icon=\"download\" (click)=\"downloadFile(file)\"></smart-icon>\n <smart-icon class=\"removeIcon\" icon=\"delete\" (click)=\"remove(i)\"></smart-icon>\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{--border-color: #a6aabd60;--warninig-color: #be2d2e;--def-border-radius: .5rem}.container{display:flex;flex-direction:column;border:2px dashed var(--border-color);border-radius:var(--def-border-radius)}.fileContainer{cursor:pointer;padding:1rem;display:flex;flex-direction:column}.fileContainer:hover{background-color:rgb(from var(--border-color) r g b / .1)}.disabledWidget ::ng-deep .fileContainer:hover{background-color:unset;cursor:unset}.disabledWidget ::ng-deep *{opacity:.85}.dragover{background-color:rgb(from var(--border-color) r g b / .1)}.fileUploadContentContainer{display:flex;flex-direction:row;gap:1rem}.icon mat-icon{font-size:3rem;width:unset;height:unset}.icon{align-content:center}.labels{flex:1;display:flex;flex-direction:column;justify-content:center;width:fit-content}.uploadButton{align-content:center}.primary{color:var(--primary-color)}.secondary{color:var(--gray)}.label{margin:unset}.subLabel{font-size:smaller}.title{padding-bottom:.3rem}.errorMessage,.uploadedFilesContainer{border-top:2px solid var(--border-color)}.errorMessage{display:flex;flex-direction:row;align-items:center;color:var(--warninig-color);padding:.5rem 1rem;gap:1rem}.errorMessage ::ng-deep mat-icon{color:var(--warninig-color)}.errors{display:flex;flex-direction:column}.uploadedFile{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;gap:1rem}.uploadedFile:last-child{border-bottom:none}.fileSize{display:flex;flex-direction:row;font-size:smaller}.fileData{flex:1;display:flex;flex-direction:column}.fileDataContainer{display:flex;flex-direction:column;justify-content:flex-end;width:fit-content}.removeIcon ::ng-deep mat-icon{color:var(--warninig-color)}smart-icon ::ng-deep mat-icon{font-size:3rem;width:unset;height:unset}.fileActions{display:flex;flex-direction:row;justify-content:flex-end;gap:.5rem}.removeIcon ::ng-deep i,.removeIcon ::ng-deep mat-icon{color:var(--warninig-color)}.removeIcon ::ng-deep mat-icon,.downloadIcon ::ng-deep mat-icon{font-size:2rem}.removeIcon:hover,.downloadIcon:hover{cursor:pointer}smart-icon{display:flex;align-items:center}\n"] }]
8631
+ args: [{ selector: 'smartfileuploader', imports: [NgClass, MatLabel, MatIcon, MatButton, UiActionButtonComponent, SmartIconComponent], template: "<div\n class=\"container\"\n [ngClass]=\"{ disabledWidget: isDisabled() }\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n [class.dragover]=\"isDragOver\"\n >\n <div class=\"fileContainer\" (click)=\"fileInput.click()\">\n <input\n #fileInput\n id=\"addFile\"\n placeholder=\"fileInput\"\n type=\"file\"\n (change)=\"getFile($event)\"\n class=\"file\"\n accept=\"{{ fileFormats()?.join(', ') }}\"\n [size]=\"maxSizeMb()\"\n [multiple]=\"isMultiple()\"\n [disabled]=\"isDisabled()\"\n style=\"display: none\"\n />\n <div class=\"fileUploadContentContainer\">\n <div class=\"icon\">\n @if (useIconButton()) {\n <mat-label class=\"addFileButton\">\n <mat-icon color=\"primary\" class=\"addCircle\">add_circle</mat-icon>\n </mat-label>\n }\n @if (!useIconButton()) {\n <button mat-raised-button color=\"primary\" class=\"addFileButton\">\n {{ i18n!.addFile }}\n </button>\n }\n </div>\n <div class=\"labels\">\n @if (useIconButton()) {\n <mat-label class=\"label primary title\">\n {{ i18n!.addFile }}\n </mat-label>\n }\n <mat-label class=\"label secondary\"> {{ i18n!.browseOrDrag }} </mat-label>\n <mat-label class=\"subLabel primary\"> {{ i18n!.maxSize }} </mat-label>\n <mat-label class=\"subLabel primary\"> {{ i18n!.formats }} </mat-label>\n </div>\n @if (files.length) {\n <div class=\"uploadButton\">\n <ui-action-button\n (actionClick)=\"uploadFile()\"\n [code]=\"'default-upload'\"\n [descriptor]=\"uploadButton\"\n >\n </ui-action-button>\n </div>\n }\n </div>\n </div>\n\n @if (errors.length) {\n <div class=\"errorMessage\">\n <smart-icon [icon]=\"'error'\" [color]=\"'warn'\"></smart-icon>\n <div class=\"errors\">\n @for (error of errors; track error) {\n <span>{{ error }}</span>\n }\n </div>\n </div>\n }\n\n @if (files.length) {\n <div class=\"uploadedFilesContainer\">\n @for (file of files; track file; let i = $index) {\n <div class=\"uploadedFile\">\n @if (filePreviewUrl(file)) {\n <img [src]=\"filePreviewUrl(file)\" [alt]=\"file.name\" width=\"50\" height=\"50\" />\n } @else {\n <smart-icon [icon]=\"'insert_drive_file'\"></smart-icon>\n }\n <div class=\"fileData\">\n <div class=\"fileDataContainer\">\n <span class=\"fileName\">{{ file.name }}</span>\n <span class=\"fileSize\">{{ formatSize(file.size) }}</span>\n </div>\n </div>\n <div class=\"fileActions\">\n <smart-icon\n class=\"downloadIcon\"\n icon=\"download\"\n (click)=\"downloadFile(file)\"\n [attr.data-testid]=\"'default_download'\"\n ></smart-icon>\n <smart-icon\n class=\"removeIcon\"\n icon=\"delete\"\n [attr.data-testid]=\"'default_remove'\"\n (click)=\"remove(i)\"\n ></smart-icon>\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{--border-color: #a6aabd60;--warninig-color: #be2d2e;--def-border-radius: .5rem}.container{display:flex;flex-direction:column;border:2px dashed var(--border-color);border-radius:var(--def-border-radius)}.fileContainer{cursor:pointer;padding:1rem;display:flex;flex-direction:column}.fileContainer:hover{background-color:rgb(from var(--border-color) r g b / .1)}.disabledWidget ::ng-deep .fileContainer:hover{background-color:unset;cursor:unset}.disabledWidget ::ng-deep *{opacity:.85}.dragover{background-color:rgb(from var(--border-color) r g b / .1)}.fileUploadContentContainer{display:flex;flex-direction:row;gap:1rem}.icon mat-icon{font-size:3rem;width:unset;height:unset}.icon{align-content:center}.labels{flex:1;display:flex;flex-direction:column;justify-content:center;width:fit-content}.uploadButton{align-content:center}.primary{color:var(--primary-color)}.secondary{color:var(--gray)}.label{margin:unset}.subLabel{font-size:smaller}.title{padding-bottom:.3rem}.errorMessage,.uploadedFilesContainer{border-top:2px solid var(--border-color)}.errorMessage{display:flex;flex-direction:row;align-items:center;color:var(--warninig-color);padding:.5rem 1rem;gap:1rem}.errorMessage ::ng-deep mat-icon{color:var(--warninig-color)}.errors{display:flex;flex-direction:column}.uploadedFile{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;gap:1rem}.uploadedFile:last-child{border-bottom:none}.fileSize{display:flex;flex-direction:row;font-size:smaller}.fileData{flex:1;display:flex;flex-direction:column}.fileDataContainer{display:flex;flex-direction:column;justify-content:flex-end;width:fit-content}.removeIcon ::ng-deep mat-icon{color:var(--warninig-color)}smart-icon ::ng-deep mat-icon{font-size:3rem;width:unset;height:unset}.fileActions{display:flex;flex-direction:row;justify-content:flex-end;gap:.5rem}.removeIcon ::ng-deep i,.removeIcon ::ng-deep mat-icon{color:var(--warninig-color)}.removeIcon ::ng-deep mat-icon,.downloadIcon ::ng-deep mat-icon{font-size:2rem}.removeIcon:hover,.downloadIcon:hover{cursor:pointer}smart-icon{display:flex;align-items:center}\n"] }]
8565
8632
  }], propDecorators: { fileInput: [{
8566
8633
  type: ViewChild,
8567
8634
  args: ['fileInput']
@@ -12433,7 +12500,25 @@ class SmartFilterEditorService {
12433
12500
  constructor() {
12434
12501
  this.service = inject(FilterService);
12435
12502
  this.viewCtxService = inject(SmartViewContextService);
12503
+ /** Signal-backed so template gates (ours and the hosts') re-evaluate under zoneless CD. */
12504
+ this.modelState = signal(undefined, /* @ts-ignore */
12505
+ ...(ngDevMode ? [{ debugName: "modelState" }] : /* istanbul ignore next */ []));
12436
12506
  this.modelChanged = new Subject();
12507
+ this.itemSelected = new Subject();
12508
+ this.toolbars = [];
12509
+ }
12510
+ get model() {
12511
+ return this.modelState();
12512
+ }
12513
+ set model(model) {
12514
+ this.modelState.set(model);
12515
+ }
12516
+ getComplexToolbars() {
12517
+ return [...this.toolbars];
12518
+ }
12519
+ setComplexToolbars(toolbars) {
12520
+ this.toolbars = [...toolbars];
12521
+ this.parentSmartComponent?.initActions();
12437
12522
  }
12438
12523
  async load() {
12439
12524
  if (this.config.uuid) {
@@ -12479,6 +12564,20 @@ class SmartFilterEditorService {
12479
12564
  getAdditionalParams(uiAction) {
12480
12565
  throw new Error('Method not implemented.');
12481
12566
  }
12567
+ async bulkUpdateFilterExpression(operationType, item) {
12568
+ if (!this.model?.readOnly) {
12569
+ if (item) {
12570
+ item.expressionData.boolOperator = operationType;
12571
+ }
12572
+ await this.peformWidgetAction({
12573
+ code: 'BULK_UPDATE_FILTER_EXPRESSION',
12574
+ params: {
12575
+ model: item,
12576
+ operator: operationType,
12577
+ },
12578
+ });
12579
+ }
12580
+ }
12482
12581
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartFilterEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
12483
12582
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartFilterEditorService }); }
12484
12583
  }
@@ -18310,11 +18409,11 @@ class SmartGridComponent {
18310
18409
  this.dialog.open(TableLayoutDefinerComponent, { data: dialogData });
18311
18410
  }
18312
18411
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
18313
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartGridComponent, isStandalone: true, selector: "smart-grid", inputs: { smartGrid: { classPropertyName: "smartGrid", publicName: "smartGrid", isSignal: false, isRequired: false, transformFunction: null }, uuid: { classPropertyName: "uuid", publicName: "uuid", isSignal: false, isRequired: false, transformFunction: null }, parentLayoutComponent: { classPropertyName: "parentLayoutComponent", publicName: "parentLayoutComponent", isSignal: true, isRequired: false, transformFunction: null }, dev: { classPropertyName: "dev", publicName: "dev", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-testid": "this.testId" } }, providers: [SmartGridService], viewQueries: [{ propertyName: "vcRefTable", first: true, predicate: ["table"], descendants: true, read: ViewContainerRef }, { propertyName: "expandedRowsComps", predicate: ExpandedRowRendererComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (smartGrid) {\n <div class=\"smartGrid-container\">\n <div class=\"smart-grid-toolbar\">\n <smart-ui-action-toolbar [id]=\"toolbarId\"></smart-ui-action-toolbar>\n @if (smartGrid.showEditColumns) {\n <button\n (click)=\"editColumns()\"\n mat-mini-fab\n color=\"text-primary\"\n >\n <mat-icon aria-hidden=\"false\" aria-label=\"Columns\" class=\"smart-grid-edit-icon\"\n >view_columns</mat-icon\n >\n </button>\n }\n </div>\n <!-- <div [ngClass]=\"isBlocked ? 'blocked' : ''\"></div> -->\n <div class=\"smartGridContent\">\n <div>\n @if (smartGrid.showResultCount) {\n <div>\n <div class=\"smartGrid-data-number\">\n {{ smartGrid.gridModel.totalRowCount }}\n </div>\n </div>\n }\n </div>\n <div class=\"smart-grid-table-container\">\n <ng-template #table></ng-template>\n </div>\n @if (smartGrid.layoutDef === layoutDef().EXPANDABLE) {\n <div>\n @for (expandableSection of expandableSections; track expandableSection) {\n <smart-expandable-section\n #gridExpandableSection\n [data]=\"expandableSection\"\n ></smart-expandable-section>\n }\n </div>\n }\n @if (smartGrid.layoutDef === layoutDef().CARD && smartGrid.dataLayoutDef) {\n <div\n class=\"cards-container\"\n [ngStyle]=\"{\n 'grid-template-columns':\n smartGrid.numberOfColumn !== undefined\n ? 'repeat(' + smartGrid.numberOfColumn + ', 1fr)'\n : '',\n }\"\n >\n @for (row of smartGrid.gridModel.page.rows; track row) {\n <app-smart-grid-card\n class=\"smartGrid-card-container\"\n [class.clickable-row]=\"row.layoutDescriptor\"\n (click)=\"row.layoutDescriptor && onClick(row)\"\n [item]=\"row\"\n [smartGrid]=\"smartGrid\"\n [parentLayoutComponent]=\"parentLayoutComponent()\"\n ></app-smart-grid-card>\n }\n </div>\n }\n @if (smartGrid.layoutDef === layoutDef().TREE && treeControl) {\n <div\n class=\"tree-container\"\n [ngStyle]=\"{\n 'grid-template-columns':\n smartGrid.numberOfColumn !== undefined\n ? 'repeat(' + smartGrid.numberOfColumn + ', 1fr)'\n : '',\n }\"\n >\n <mat-tree [dataSource]=\"treeDataSource!\" [treeControl]=\"treeControl!\">\n <mat-tree-node\n *matTreeNodeDef=\"let node\"\n matTreeNodeToggle\n matTreeNodePadding\n matTreeNodePaddingIndent=\"24\"\n >\n <button mat-icon-button disabled class=\"tree-button\"></button>\n <mat-checkbox\n class=\"checklist-leaf-node\"\n [checked]=\"$safeNavigationMigration(treeChecklistSelection?.isSelected(node))\"\n (change)=\"treeNodeSelectionToggle(node)\"\n >{{ getTreeItem(node) }}</mat-checkbox\n >\n </mat-tree-node>\n <mat-tree-node\n *matTreeNodeDef=\"let node; when: hasChild\"\n matTreeNodePadding\n matTreeNodePaddingIndent=\"24\"\n >\n <button\n mat-icon-button\n matTreeNodeToggle\n class=\"tree-button\"\n [attr.aria-label]=\"'Toggle ' + node.item\"\n >\n <mat-icon class=\"mat-icon-rtl-mirror\">\n {{ treeControl!.isExpanded(node) ? 'expand_more' : 'chevron_right' }}\n </mat-icon>\n </button>\n <mat-checkbox\n [checked]=\"$safeNavigationMigration(treeChecklistSelection?.isSelected(node))\"\n [indeterminate]=\"descendantsPartiallySelected(node)\"\n (change)=\"treeNodeSelectionToggle(node)\"\n >{{ getTreeItem(node) }}</mat-checkbox\n >\n </mat-tree-node>\n </mat-tree>\n </div>\n }\n </div>\n @if (smartGrid.paginator) {\n <div class=\"paginator-row-material\">\n @if (smartGrid.gridModel.refreshEnabled) {\n <button mat-icon-button type=\"button\" matTooltip=\"Friss\u00EDt\u00E9s\" (click)=\"refreshPartialResults()\">\n <mat-icon>refresh</mat-icon>\n </button>\n }\n @if (smartGrid.paginator && !treeControl) {\n <mat-paginator\n #paginator\n [length]=\"length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n (page)=\"onChangePage($event)\"\n ></mat-paginator>\n }\n </div>\n }\n </div>\n }\n", styles: [".smartGrid-container{position:relative;padding:1.5rem;display:flex;flex-direction:column;gap:1rem}.smartGrid-data-number{padding-bottom:1rem}.cards-container{display:grid;gap:1rem;padding:1rem}.smartGrid-container ::ng-deep .mat-form-field-appearance-legacy .mat-form-field-underline{bottom:0}.smartGridContent{width:100%;flex:1;overflow:auto}.blocked{position:absolute;width:calc(100% - 3rem);height:calc(100% - 3rem);z-index:110;background-color:#0003}.smart-grid-table-container{display:flex;flex-direction:column;gap:1rem}.smart-grid-toolbar{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.smart-grid-toolbar smart-ui-action-toolbar{width:100%}.smart-grid-edit-icon{color:var(--light-gray)}.tree-button{width:24px!important;height:24px!important}.paginator-row-material{display:flex;align-items:center;align-self:flex-end;gap:.25rem}.clickable-row{cursor:pointer}\n"], dependencies: [{ kind: "component", type: UiActionToolbarComponent, selector: "smart-ui-action-toolbar", inputs: ["uiActionModels", "uiActionDescriptorService", "id", "executor", "widgetId", "nodeId", "actionParams", "scrollOnWrap", "toolbarPropertes"] }, { kind: "component", type: MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ExpandableSectionComponent, selector: "smart-expandable-section", inputs: ["data", "index"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SmartGridCardComponent, selector: "app-smart-grid-card", inputs: ["item", "smartGrid", "parentLayoutComponent"] }, { kind: "component", type: MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "directive", type: MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "directive", type: MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }] }); }
18412
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartGridComponent, isStandalone: true, selector: "smart-grid", inputs: { smartGrid: { classPropertyName: "smartGrid", publicName: "smartGrid", isSignal: false, isRequired: false, transformFunction: null }, uuid: { classPropertyName: "uuid", publicName: "uuid", isSignal: false, isRequired: false, transformFunction: null }, parentLayoutComponent: { classPropertyName: "parentLayoutComponent", publicName: "parentLayoutComponent", isSignal: true, isRequired: false, transformFunction: null }, dev: { classPropertyName: "dev", publicName: "dev", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-testid": "this.testId" } }, providers: [SmartGridService], viewQueries: [{ propertyName: "vcRefTable", first: true, predicate: ["table"], descendants: true, read: ViewContainerRef }, { propertyName: "expandedRowsComps", predicate: ExpandedRowRendererComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (smartGrid) {\n <div class=\"smartGrid-container\">\n <div class=\"smart-grid-toolbar\">\n <smart-ui-action-toolbar [id]=\"toolbarId\"></smart-ui-action-toolbar>\n @if (smartGrid.showEditColumns) {\n <button\n (click)=\"editColumns()\"\n mat-mini-fab\n color=\"text-primary\"\n >\n <mat-icon aria-hidden=\"false\" aria-label=\"Columns\" class=\"smart-grid-edit-icon\"\n >view_columns</mat-icon\n >\n </button>\n }\n </div>\n <!-- <div [ngClass]=\"isBlocked ? 'blocked' : ''\"></div> -->\n <div class=\"smartGridContent\">\n <div>\n @if (smartGrid.showResultCount) {\n <div>\n <div class=\"smartGrid-data-number\">\n {{ smartGrid.gridModel.totalRowCount }}\n </div>\n </div>\n }\n </div>\n <div class=\"smart-grid-table-container\">\n <ng-template #table></ng-template>\n </div>\n @if (smartGrid.layoutDef === layoutDef().EXPANDABLE) {\n <div>\n @for (expandableSection of expandableSections; track expandableSection) {\n <smart-expandable-section\n #gridExpandableSection\n [data]=\"expandableSection\"\n ></smart-expandable-section>\n }\n </div>\n }\n @if (smartGrid.layoutDef === layoutDef().CARD && smartGrid.dataLayoutDef) {\n <div\n class=\"cards-container\"\n [ngStyle]=\"{\n 'grid-template-columns':\n smartGrid.numberOfColumn !== undefined\n ? 'repeat(' + smartGrid.numberOfColumn + ', 1fr)'\n : '',\n }\"\n >\n @for (row of smartGrid.gridModel.page.rows; track row.id) {\n <app-smart-grid-card\n class=\"smartGrid-card-container\"\n [class.clickable-row]=\"row.layoutDescriptor\"\n (click)=\"row.layoutDescriptor && onClick(row)\"\n [item]=\"row\"\n [smartGrid]=\"smartGrid\"\n [parentLayoutComponent]=\"parentLayoutComponent()\"\n ></app-smart-grid-card>\n }\n </div>\n }\n @if (smartGrid.layoutDef === layoutDef().TREE && treeControl) {\n <div\n class=\"tree-container\"\n [ngStyle]=\"{\n 'grid-template-columns':\n smartGrid.numberOfColumn !== undefined\n ? 'repeat(' + smartGrid.numberOfColumn + ', 1fr)'\n : '',\n }\"\n >\n <mat-tree [dataSource]=\"treeDataSource!\" [treeControl]=\"treeControl!\">\n <mat-tree-node\n *matTreeNodeDef=\"let node\"\n matTreeNodeToggle\n matTreeNodePadding\n matTreeNodePaddingIndent=\"24\"\n >\n <button mat-icon-button disabled class=\"tree-button\"></button>\n <mat-checkbox\n class=\"checklist-leaf-node\"\n [checked]=\"$safeNavigationMigration(treeChecklistSelection?.isSelected(node))\"\n (change)=\"treeNodeSelectionToggle(node)\"\n >{{ getTreeItem(node) }}</mat-checkbox\n >\n </mat-tree-node>\n <mat-tree-node\n *matTreeNodeDef=\"let node; when: hasChild\"\n matTreeNodePadding\n matTreeNodePaddingIndent=\"24\"\n >\n <button\n mat-icon-button\n matTreeNodeToggle\n class=\"tree-button\"\n [attr.aria-label]=\"'Toggle ' + node.item\"\n >\n <mat-icon class=\"mat-icon-rtl-mirror\">\n {{ treeControl!.isExpanded(node) ? 'expand_more' : 'chevron_right' }}\n </mat-icon>\n </button>\n <mat-checkbox\n [checked]=\"$safeNavigationMigration(treeChecklistSelection?.isSelected(node))\"\n [indeterminate]=\"descendantsPartiallySelected(node)\"\n (change)=\"treeNodeSelectionToggle(node)\"\n >{{ getTreeItem(node) }}</mat-checkbox\n >\n </mat-tree-node>\n </mat-tree>\n </div>\n }\n </div>\n @if (smartGrid.paginator) {\n <div class=\"paginator-row-material\">\n @if (smartGrid.gridModel.refreshEnabled) {\n <button mat-icon-button type=\"button\" matTooltip=\"Friss\u00EDt\u00E9s\" (click)=\"refreshPartialResults()\">\n <mat-icon>refresh</mat-icon>\n </button>\n }\n @if (smartGrid.paginator && !treeControl) {\n <mat-paginator\n #paginator\n [length]=\"length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n (page)=\"onChangePage($event)\"\n ></mat-paginator>\n }\n </div>\n }\n </div>\n }\n", styles: [".smartGrid-container{position:relative;padding:1.5rem;display:flex;flex-direction:column;gap:1rem}.smartGrid-data-number{padding-bottom:1rem}.cards-container{display:grid;gap:1rem;padding:1rem}.smartGrid-container ::ng-deep .mat-form-field-appearance-legacy .mat-form-field-underline{bottom:0}.smartGridContent{width:100%;flex:1;overflow:auto}.blocked{position:absolute;width:calc(100% - 3rem);height:calc(100% - 3rem);z-index:110;background-color:#0003}.smart-grid-table-container{display:flex;flex-direction:column;gap:1rem}.smart-grid-toolbar{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.smart-grid-toolbar smart-ui-action-toolbar{width:100%}.smart-grid-edit-icon{color:var(--light-gray)}.tree-button{width:24px!important;height:24px!important}.paginator-row-material{display:flex;align-items:center;align-self:flex-end;gap:.25rem}.clickable-row{cursor:pointer}\n"], dependencies: [{ kind: "component", type: UiActionToolbarComponent, selector: "smart-ui-action-toolbar", inputs: ["uiActionModels", "uiActionDescriptorService", "id", "executor", "widgetId", "nodeId", "actionParams", "scrollOnWrap", "toolbarPropertes"] }, { kind: "component", type: MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ExpandableSectionComponent, selector: "smart-expandable-section", inputs: ["data", "index"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SmartGridCardComponent, selector: "app-smart-grid-card", inputs: ["item", "smartGrid", "parentLayoutComponent"] }, { kind: "component", type: MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "directive", type: MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "directive", type: MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }] }); }
18314
18413
  }
18315
18414
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartGridComponent, decorators: [{
18316
18415
  type: Component,
18317
- args: [{ selector: 'smart-grid', providers: [SmartGridService], imports: [UiActionToolbarComponent, MatMiniFabButton, MatIcon, ExpandableSectionComponent, NgStyle, SmartGridCardComponent, MatTree, MatTreeNodeDef, MatTreeNode, MatTreeNodeToggle, MatTreeNodePadding, MatIconButton, MatCheckbox, MatTooltip, MatPaginator], template: "@if (smartGrid) {\n <div class=\"smartGrid-container\">\n <div class=\"smart-grid-toolbar\">\n <smart-ui-action-toolbar [id]=\"toolbarId\"></smart-ui-action-toolbar>\n @if (smartGrid.showEditColumns) {\n <button\n (click)=\"editColumns()\"\n mat-mini-fab\n color=\"text-primary\"\n >\n <mat-icon aria-hidden=\"false\" aria-label=\"Columns\" class=\"smart-grid-edit-icon\"\n >view_columns</mat-icon\n >\n </button>\n }\n </div>\n <!-- <div [ngClass]=\"isBlocked ? 'blocked' : ''\"></div> -->\n <div class=\"smartGridContent\">\n <div>\n @if (smartGrid.showResultCount) {\n <div>\n <div class=\"smartGrid-data-number\">\n {{ smartGrid.gridModel.totalRowCount }}\n </div>\n </div>\n }\n </div>\n <div class=\"smart-grid-table-container\">\n <ng-template #table></ng-template>\n </div>\n @if (smartGrid.layoutDef === layoutDef().EXPANDABLE) {\n <div>\n @for (expandableSection of expandableSections; track expandableSection) {\n <smart-expandable-section\n #gridExpandableSection\n [data]=\"expandableSection\"\n ></smart-expandable-section>\n }\n </div>\n }\n @if (smartGrid.layoutDef === layoutDef().CARD && smartGrid.dataLayoutDef) {\n <div\n class=\"cards-container\"\n [ngStyle]=\"{\n 'grid-template-columns':\n smartGrid.numberOfColumn !== undefined\n ? 'repeat(' + smartGrid.numberOfColumn + ', 1fr)'\n : '',\n }\"\n >\n @for (row of smartGrid.gridModel.page.rows; track row) {\n <app-smart-grid-card\n class=\"smartGrid-card-container\"\n [class.clickable-row]=\"row.layoutDescriptor\"\n (click)=\"row.layoutDescriptor && onClick(row)\"\n [item]=\"row\"\n [smartGrid]=\"smartGrid\"\n [parentLayoutComponent]=\"parentLayoutComponent()\"\n ></app-smart-grid-card>\n }\n </div>\n }\n @if (smartGrid.layoutDef === layoutDef().TREE && treeControl) {\n <div\n class=\"tree-container\"\n [ngStyle]=\"{\n 'grid-template-columns':\n smartGrid.numberOfColumn !== undefined\n ? 'repeat(' + smartGrid.numberOfColumn + ', 1fr)'\n : '',\n }\"\n >\n <mat-tree [dataSource]=\"treeDataSource!\" [treeControl]=\"treeControl!\">\n <mat-tree-node\n *matTreeNodeDef=\"let node\"\n matTreeNodeToggle\n matTreeNodePadding\n matTreeNodePaddingIndent=\"24\"\n >\n <button mat-icon-button disabled class=\"tree-button\"></button>\n <mat-checkbox\n class=\"checklist-leaf-node\"\n [checked]=\"$safeNavigationMigration(treeChecklistSelection?.isSelected(node))\"\n (change)=\"treeNodeSelectionToggle(node)\"\n >{{ getTreeItem(node) }}</mat-checkbox\n >\n </mat-tree-node>\n <mat-tree-node\n *matTreeNodeDef=\"let node; when: hasChild\"\n matTreeNodePadding\n matTreeNodePaddingIndent=\"24\"\n >\n <button\n mat-icon-button\n matTreeNodeToggle\n class=\"tree-button\"\n [attr.aria-label]=\"'Toggle ' + node.item\"\n >\n <mat-icon class=\"mat-icon-rtl-mirror\">\n {{ treeControl!.isExpanded(node) ? 'expand_more' : 'chevron_right' }}\n </mat-icon>\n </button>\n <mat-checkbox\n [checked]=\"$safeNavigationMigration(treeChecklistSelection?.isSelected(node))\"\n [indeterminate]=\"descendantsPartiallySelected(node)\"\n (change)=\"treeNodeSelectionToggle(node)\"\n >{{ getTreeItem(node) }}</mat-checkbox\n >\n </mat-tree-node>\n </mat-tree>\n </div>\n }\n </div>\n @if (smartGrid.paginator) {\n <div class=\"paginator-row-material\">\n @if (smartGrid.gridModel.refreshEnabled) {\n <button mat-icon-button type=\"button\" matTooltip=\"Friss\u00EDt\u00E9s\" (click)=\"refreshPartialResults()\">\n <mat-icon>refresh</mat-icon>\n </button>\n }\n @if (smartGrid.paginator && !treeControl) {\n <mat-paginator\n #paginator\n [length]=\"length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n (page)=\"onChangePage($event)\"\n ></mat-paginator>\n }\n </div>\n }\n </div>\n }\n", styles: [".smartGrid-container{position:relative;padding:1.5rem;display:flex;flex-direction:column;gap:1rem}.smartGrid-data-number{padding-bottom:1rem}.cards-container{display:grid;gap:1rem;padding:1rem}.smartGrid-container ::ng-deep .mat-form-field-appearance-legacy .mat-form-field-underline{bottom:0}.smartGridContent{width:100%;flex:1;overflow:auto}.blocked{position:absolute;width:calc(100% - 3rem);height:calc(100% - 3rem);z-index:110;background-color:#0003}.smart-grid-table-container{display:flex;flex-direction:column;gap:1rem}.smart-grid-toolbar{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.smart-grid-toolbar smart-ui-action-toolbar{width:100%}.smart-grid-edit-icon{color:var(--light-gray)}.tree-button{width:24px!important;height:24px!important}.paginator-row-material{display:flex;align-items:center;align-self:flex-end;gap:.25rem}.clickable-row{cursor:pointer}\n"] }]
18416
+ args: [{ selector: 'smart-grid', providers: [SmartGridService], imports: [UiActionToolbarComponent, MatMiniFabButton, MatIcon, ExpandableSectionComponent, NgStyle, SmartGridCardComponent, MatTree, MatTreeNodeDef, MatTreeNode, MatTreeNodeToggle, MatTreeNodePadding, MatIconButton, MatCheckbox, MatTooltip, MatPaginator], template: "@if (smartGrid) {\n <div class=\"smartGrid-container\">\n <div class=\"smart-grid-toolbar\">\n <smart-ui-action-toolbar [id]=\"toolbarId\"></smart-ui-action-toolbar>\n @if (smartGrid.showEditColumns) {\n <button\n (click)=\"editColumns()\"\n mat-mini-fab\n color=\"text-primary\"\n >\n <mat-icon aria-hidden=\"false\" aria-label=\"Columns\" class=\"smart-grid-edit-icon\"\n >view_columns</mat-icon\n >\n </button>\n }\n </div>\n <!-- <div [ngClass]=\"isBlocked ? 'blocked' : ''\"></div> -->\n <div class=\"smartGridContent\">\n <div>\n @if (smartGrid.showResultCount) {\n <div>\n <div class=\"smartGrid-data-number\">\n {{ smartGrid.gridModel.totalRowCount }}\n </div>\n </div>\n }\n </div>\n <div class=\"smart-grid-table-container\">\n <ng-template #table></ng-template>\n </div>\n @if (smartGrid.layoutDef === layoutDef().EXPANDABLE) {\n <div>\n @for (expandableSection of expandableSections; track expandableSection) {\n <smart-expandable-section\n #gridExpandableSection\n [data]=\"expandableSection\"\n ></smart-expandable-section>\n }\n </div>\n }\n @if (smartGrid.layoutDef === layoutDef().CARD && smartGrid.dataLayoutDef) {\n <div\n class=\"cards-container\"\n [ngStyle]=\"{\n 'grid-template-columns':\n smartGrid.numberOfColumn !== undefined\n ? 'repeat(' + smartGrid.numberOfColumn + ', 1fr)'\n : '',\n }\"\n >\n @for (row of smartGrid.gridModel.page.rows; track row.id) {\n <app-smart-grid-card\n class=\"smartGrid-card-container\"\n [class.clickable-row]=\"row.layoutDescriptor\"\n (click)=\"row.layoutDescriptor && onClick(row)\"\n [item]=\"row\"\n [smartGrid]=\"smartGrid\"\n [parentLayoutComponent]=\"parentLayoutComponent()\"\n ></app-smart-grid-card>\n }\n </div>\n }\n @if (smartGrid.layoutDef === layoutDef().TREE && treeControl) {\n <div\n class=\"tree-container\"\n [ngStyle]=\"{\n 'grid-template-columns':\n smartGrid.numberOfColumn !== undefined\n ? 'repeat(' + smartGrid.numberOfColumn + ', 1fr)'\n : '',\n }\"\n >\n <mat-tree [dataSource]=\"treeDataSource!\" [treeControl]=\"treeControl!\">\n <mat-tree-node\n *matTreeNodeDef=\"let node\"\n matTreeNodeToggle\n matTreeNodePadding\n matTreeNodePaddingIndent=\"24\"\n >\n <button mat-icon-button disabled class=\"tree-button\"></button>\n <mat-checkbox\n class=\"checklist-leaf-node\"\n [checked]=\"$safeNavigationMigration(treeChecklistSelection?.isSelected(node))\"\n (change)=\"treeNodeSelectionToggle(node)\"\n >{{ getTreeItem(node) }}</mat-checkbox\n >\n </mat-tree-node>\n <mat-tree-node\n *matTreeNodeDef=\"let node; when: hasChild\"\n matTreeNodePadding\n matTreeNodePaddingIndent=\"24\"\n >\n <button\n mat-icon-button\n matTreeNodeToggle\n class=\"tree-button\"\n [attr.aria-label]=\"'Toggle ' + node.item\"\n >\n <mat-icon class=\"mat-icon-rtl-mirror\">\n {{ treeControl!.isExpanded(node) ? 'expand_more' : 'chevron_right' }}\n </mat-icon>\n </button>\n <mat-checkbox\n [checked]=\"$safeNavigationMigration(treeChecklistSelection?.isSelected(node))\"\n [indeterminate]=\"descendantsPartiallySelected(node)\"\n (change)=\"treeNodeSelectionToggle(node)\"\n >{{ getTreeItem(node) }}</mat-checkbox\n >\n </mat-tree-node>\n </mat-tree>\n </div>\n }\n </div>\n @if (smartGrid.paginator) {\n <div class=\"paginator-row-material\">\n @if (smartGrid.gridModel.refreshEnabled) {\n <button mat-icon-button type=\"button\" matTooltip=\"Friss\u00EDt\u00E9s\" (click)=\"refreshPartialResults()\">\n <mat-icon>refresh</mat-icon>\n </button>\n }\n @if (smartGrid.paginator && !treeControl) {\n <mat-paginator\n #paginator\n [length]=\"length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n (page)=\"onChangePage($event)\"\n ></mat-paginator>\n }\n </div>\n }\n </div>\n }\n", styles: [".smartGrid-container{position:relative;padding:1.5rem;display:flex;flex-direction:column;gap:1rem}.smartGrid-data-number{padding-bottom:1rem}.cards-container{display:grid;gap:1rem;padding:1rem}.smartGrid-container ::ng-deep .mat-form-field-appearance-legacy .mat-form-field-underline{bottom:0}.smartGridContent{width:100%;flex:1;overflow:auto}.blocked{position:absolute;width:calc(100% - 3rem);height:calc(100% - 3rem);z-index:110;background-color:#0003}.smart-grid-table-container{display:flex;flex-direction:column;gap:1rem}.smart-grid-toolbar{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.smart-grid-toolbar smart-ui-action-toolbar{width:100%}.smart-grid-edit-icon{color:var(--light-gray)}.tree-button{width:24px!important;height:24px!important}.paginator-row-material{display:flex;align-items:center;align-self:flex-end;gap:.25rem}.clickable-row{cursor:pointer}\n"] }]
18318
18417
  }], ctorParameters: () => [], propDecorators: { smartGrid: [{
18319
18418
  type: Input
18320
18419
  }], uuid: [{
@@ -20981,7 +21080,7 @@ class SmartComponentLayoutComponent {
20981
21080
  layoutDefinitions: this.smartComponentLayout?.form,
20982
21081
  });
20983
21082
  const gridRow = this.gridRow;
20984
- if (gridRow && !gridRow.valueSet) {
21083
+ if (gridRow && !gridRow.valueSets) {
20985
21084
  gridRow.valueSets = this.smartComponent?.model?.valueSets;
20986
21085
  }
20987
21086
  this.smartForm = {
@@ -21008,7 +21107,7 @@ class SmartComponentLayoutComponent {
21008
21107
  rowUiActionType: GridUiActionType.POPUP_MENU,
21009
21108
  },
21010
21109
  layoutDef: SmartLayoutDef.TABLE,
21011
- paginator: true,
21110
+ paginator: false,
21012
21111
  // What a card of this grid instantiates for a row that carries a layoutDescriptor.
21013
21112
  // The grid model is the only way across: the card cannot import this class.
21014
21113
  layoutComponent: SmartComponentLayoutComponent,
@@ -21152,11 +21251,11 @@ class GenericPageComponent extends SmartComponent {
21152
21251
  return false;
21153
21252
  }
21154
21253
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: GenericPageComponent, deps: [{ token: i0.Injector }, { token: SMART_GENERIC_PAGE_NAME }, { token: SMART_GENERIC_COMPONENT_NAME }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
21155
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: GenericPageComponent, isStandalone: true, selector: "app-generic-page", usesInheritance: true, ngImport: i0, template: "<div class=\"generic-page-container\">\n @if (componentLayout) {\n <smart-component-layout\n class=\"generic-page-layout\"\n [smartComponentLayout]=\"componentLayout\"\n ></smart-component-layout>\n }\n <smart-ui-action-toolbar\n class=\"generic-page-toolbar\"\n [uiActionModels]=\"uiActionModels\"\n ></smart-ui-action-toolbar>\n</div>\n@if (showRouterOutlet()) {\n <div>\n <ng-container [smartEmbeddedSlot]=\"'router-outlet'\" [containerUuid]=\"uuid\"></ng-container>\n </div>\n}\n", styles: [".generic-page-container{display:flex;flex-direction:column;gap:1rem}:host{min-width:200px;width:40vw}\n"], dependencies: [{ kind: "component", type: SmartComponentLayoutComponent, selector: "smart-component-layout", inputs: ["smartComponentLayout", "parentLayoutComponent", "gridRow"] }, { kind: "component", type: UiActionToolbarComponent, selector: "smart-ui-action-toolbar", inputs: ["uiActionModels", "uiActionDescriptorService", "id", "executor", "widgetId", "nodeId", "actionParams", "scrollOnWrap", "toolbarPropertes"] }, { kind: "directive", type: SmartEmbeddedSlotDirective, selector: "[smartEmbeddedSlot]", inputs: ["smartEmbeddedSlot", "containerUuid"] }] }); }
21254
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: GenericPageComponent, isStandalone: true, selector: "app-generic-page", usesInheritance: true, ngImport: i0, template: "<div class=\"generic-page-container\">\n @if (componentLayout) {\n <smart-component-layout\n class=\"generic-page-layout\"\n [smartComponentLayout]=\"componentLayout\"\n ></smart-component-layout>\n }\n <smart-ui-action-toolbar\n class=\"generic-page-toolbar\"\n [uiActionModels]=\"uiActionModels\"\n ></smart-ui-action-toolbar>\n</div>\n@if (showRouterOutlet()) {\n <div>\n <ng-container [smartEmbeddedSlot]=\"'router-outlet'\" [containerUuid]=\"uuid\"></ng-container>\n </div>\n}\n", styles: [".generic-page-container{display:flex;flex-direction:column;gap:1rem}\n"], dependencies: [{ kind: "component", type: SmartComponentLayoutComponent, selector: "smart-component-layout", inputs: ["smartComponentLayout", "parentLayoutComponent", "gridRow"] }, { kind: "component", type: UiActionToolbarComponent, selector: "smart-ui-action-toolbar", inputs: ["uiActionModels", "uiActionDescriptorService", "id", "executor", "widgetId", "nodeId", "actionParams", "scrollOnWrap", "toolbarPropertes"] }, { kind: "directive", type: SmartEmbeddedSlotDirective, selector: "[smartEmbeddedSlot]", inputs: ["smartEmbeddedSlot", "containerUuid"] }] }); }
21156
21255
  }
21157
21256
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: GenericPageComponent, decorators: [{
21158
21257
  type: Component,
21159
- args: [{ selector: 'app-generic-page', imports: [SmartComponentLayoutComponent, UiActionToolbarComponent, SmartEmbeddedSlotDirective], template: "<div class=\"generic-page-container\">\n @if (componentLayout) {\n <smart-component-layout\n class=\"generic-page-layout\"\n [smartComponentLayout]=\"componentLayout\"\n ></smart-component-layout>\n }\n <smart-ui-action-toolbar\n class=\"generic-page-toolbar\"\n [uiActionModels]=\"uiActionModels\"\n ></smart-ui-action-toolbar>\n</div>\n@if (showRouterOutlet()) {\n <div>\n <ng-container [smartEmbeddedSlot]=\"'router-outlet'\" [containerUuid]=\"uuid\"></ng-container>\n </div>\n}\n", styles: [".generic-page-container{display:flex;flex-direction:column;gap:1rem}:host{min-width:200px;width:40vw}\n"] }]
21258
+ args: [{ selector: 'app-generic-page', imports: [SmartComponentLayoutComponent, UiActionToolbarComponent, SmartEmbeddedSlotDirective], template: "<div class=\"generic-page-container\">\n @if (componentLayout) {\n <smart-component-layout\n class=\"generic-page-layout\"\n [smartComponentLayout]=\"componentLayout\"\n ></smart-component-layout>\n }\n <smart-ui-action-toolbar\n class=\"generic-page-toolbar\"\n [uiActionModels]=\"uiActionModels\"\n ></smart-ui-action-toolbar>\n</div>\n@if (showRouterOutlet()) {\n <div>\n <ng-container [smartEmbeddedSlot]=\"'router-outlet'\" [containerUuid]=\"uuid\"></ng-container>\n </div>\n}\n", styles: [".generic-page-container{display:flex;flex-direction:column;gap:1rem}\n"] }]
21160
21259
  }], ctorParameters: () => [{ type: i0.Injector }, { type: undefined, decorators: [{
21161
21260
  type: Inject,
21162
21261
  args: [SMART_GENERIC_PAGE_NAME]
@@ -21179,11 +21278,11 @@ class SmartFilterParamComponent {
21179
21278
  });
21180
21279
  }
21181
21280
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartFilterParamComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
21182
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartFilterParamComponent, isStandalone: true, selector: "app-target-group-filter-param", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"targetGroupFilterParamContainer\">\n @for (data of data()?.group; track data) {\n <div\n class=\"targetGroupFilterItem\"\n (click)=\"onItemClick(data)\"\n >\n <smart-icon icon=\"Ic24_Chevron_Right\" color=\"gray\"></smart-icon>\n <div class=\"mat-caption\">\n {{ data.label }}\n </div>\n </div>\n }\n</div>\n", styles: [".targetGroupFilterParamContainer{display:flex;flex-direction:column;gap:.25rem}.targetGroupFilterItem{padding:.75rem;border-radius:.25rem;display:flex;flex-direction:row;gap:.5rem;cursor:pointer}.targetGroupFilterItem .mat-caption{margin:auto 0}\n"], dependencies: [{ kind: "component", type: SmartIconComponent, selector: "smart-icon", inputs: ["icon", "color", "imageResource"] }] }); }
21281
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartFilterParamComponent, isStandalone: true, selector: "app-target-group-filter-param", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"targetGroupFilterParamContainer\">\n @for (data of data()?.group; track data) {\n <div\n class=\"targetGroupFilterItem\"\n (click)=\"onItemClick(data)\"\n >\n <smart-icon icon=\"chevron_right\" color=\"gray\"></smart-icon>\n <div class=\"mat-caption\">\n {{ data.label }}\n </div>\n </div>\n }\n</div>\n", styles: [".targetGroupFilterParamContainer{display:flex;flex-direction:column;gap:.25rem}.targetGroupFilterItem{padding:.75rem;border-radius:.25rem;display:flex;flex-direction:row;gap:.5rem;cursor:pointer}.targetGroupFilterItem .mat-caption{margin:auto 0}\n"], dependencies: [{ kind: "component", type: SmartIconComponent, selector: "smart-icon", inputs: ["icon", "color", "imageResource"] }] }); }
21183
21282
  }
21184
21283
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartFilterParamComponent, decorators: [{
21185
21284
  type: Component,
21186
- args: [{ selector: 'app-target-group-filter-param', imports: [SmartIconComponent], template: "<div class=\"targetGroupFilterParamContainer\">\n @for (data of data()?.group; track data) {\n <div\n class=\"targetGroupFilterItem\"\n (click)=\"onItemClick(data)\"\n >\n <smart-icon icon=\"Ic24_Chevron_Right\" color=\"gray\"></smart-icon>\n <div class=\"mat-caption\">\n {{ data.label }}\n </div>\n </div>\n }\n</div>\n", styles: [".targetGroupFilterParamContainer{display:flex;flex-direction:column;gap:.25rem}.targetGroupFilterItem{padding:.75rem;border-radius:.25rem;display:flex;flex-direction:row;gap:.5rem;cursor:pointer}.targetGroupFilterItem .mat-caption{margin:auto 0}\n"] }]
21285
+ args: [{ selector: 'app-target-group-filter-param', imports: [SmartIconComponent], template: "<div class=\"targetGroupFilterParamContainer\">\n @for (data of data()?.group; track data) {\n <div\n class=\"targetGroupFilterItem\"\n (click)=\"onItemClick(data)\"\n >\n <smart-icon icon=\"chevron_right\" color=\"gray\"></smart-icon>\n <div class=\"mat-caption\">\n {{ data.label }}\n </div>\n </div>\n }\n</div>\n", styles: [".targetGroupFilterParamContainer{display:flex;flex-direction:column;gap:.25rem}.targetGroupFilterItem{padding:.75rem;border-radius:.25rem;display:flex;flex-direction:row;gap:.5rem;cursor:pointer}.targetGroupFilterItem .mat-caption{margin:auto 0}\n"] }]
21187
21286
  }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }] } });
21188
21287
 
21189
21288
  class SmartFilterParamsComponent {
@@ -21699,6 +21798,8 @@ var FilterExpressionBuilderApiActions;
21699
21798
  FilterExpressionBuilderApiActions["SAVE_EXPRESSION_FIELD_LIST"] = "SAVE_EXPRESSION_FIELD_LIST";
21700
21799
  })(FilterExpressionBuilderApiActions || (FilterExpressionBuilderApiActions = {}));
21701
21800
 
21801
+ const USE_ADVANCED_FILTER = new InjectionToken('USE_ADVANCED_FILTER');
21802
+
21702
21803
  /**
21703
21804
  * Filter API 2
21704
21805
  * Filter API 2
@@ -21726,8 +21827,7 @@ class SmartFilterExpressionItemComponent {
21726
21827
  this.boolOperatorType = FilterExpressionBoolOperator;
21727
21828
  }
21728
21829
  ngOnInit() {
21729
- this.isSelected =
21730
- JSON.stringify(this.service().model?.selectedField) === JSON.stringify(this.item);
21830
+ this.isSelected = this.service().model?.selectedField?.id === this.item.id;
21731
21831
  }
21732
21832
  setOperatorTo(event, operationType) {
21733
21833
  event?.stopPropagation();
@@ -21742,12 +21842,12 @@ class SmartFilterExpressionItemComponent {
21742
21842
  });
21743
21843
  }
21744
21844
  }
21745
- select(event, item) {
21845
+ async select(event, item) {
21746
21846
  event?.stopPropagation();
21747
21847
  const service = this.service();
21748
21848
  if (!service.model?.readOnly) {
21749
21849
  if (!this.isSelected) {
21750
- service.peformWidgetAction({
21850
+ await service.peformWidgetAction({
21751
21851
  code: 'SELECT_FIELD',
21752
21852
  params: {
21753
21853
  model: this.item,
@@ -21755,7 +21855,7 @@ class SmartFilterExpressionItemComponent {
21755
21855
  });
21756
21856
  }
21757
21857
  else {
21758
- service.peformWidgetAction({
21858
+ await service.peformWidgetAction({
21759
21859
  code: 'SELECT_FIELD',
21760
21860
  params: {
21761
21861
  model: this.item,
@@ -21785,23 +21885,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
21785
21885
  type: Input
21786
21886
  }], hasNext: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasNext", required: true }] }], service: [{ type: i0.Input, args: [{ isSignal: true, alias: "service", required: true }] }] } });
21787
21887
 
21788
- class SmartFilterExpressionItemsComponent {
21789
- get isSelected() {
21790
- return this.isSelectedState();
21888
+ class AdvancedRelationButtonComponent {
21889
+ constructor() {
21890
+ this.boolOperatorChanged = new EventEmitter();
21891
+ this.boolOperatorType = FilterExpressionBoolOperator;
21791
21892
  }
21792
- set isSelected(isSelected) {
21793
- this.isSelectedState.set(isSelected);
21893
+ toggle(event) {
21894
+ this.boolOperatorChanged.emit(this.boolOperator === FilterExpressionBoolOperator.AND
21895
+ ? FilterExpressionBoolOperator.OR
21896
+ : FilterExpressionBoolOperator.AND);
21897
+ }
21898
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AdvancedRelationButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
21899
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AdvancedRelationButtonComponent, isStandalone: true, selector: "lib-advanced-relation-button", inputs: { boolOperator: "boolOperator" }, outputs: { boolOperatorChanged: "boolOperatorChanged" }, ngImport: i0, template: "<div class=\"relationItemBubble\">\n <button\n mat-button\n (click)=\"toggle($event)\"\n class=\"mat-raised-button\"\n [ngClass]=\"boolOperator === boolOperatorType.AND ? 'and-oeprator' : 'or-operator'\"\n color=\"black\"\n >\n {{ boolOperator === boolOperatorType.AND ? '\u00C9S' : 'VAGY' }}\n </button>\n</div>\n", styles: [".relationItemBubble .mat-mdc-button{border-radius:1.5rem;height:100%;margin:auto 0;padding-top:.75em;padding-bottom:.75em}.relationItemBubble{display:flex;flex-direction:row;border-radius:1.5rem;border:1px solid #cdcdcd;padding:.25rem;max-height:42px;height:100%}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
21900
+ }
21901
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AdvancedRelationButtonComponent, decorators: [{
21902
+ type: Component,
21903
+ args: [{ selector: 'lib-advanced-relation-button', imports: [NgClass, MatButton], template: "<div class=\"relationItemBubble\">\n <button\n mat-button\n (click)=\"toggle($event)\"\n class=\"mat-raised-button\"\n [ngClass]=\"boolOperator === boolOperatorType.AND ? 'and-oeprator' : 'or-operator'\"\n color=\"black\"\n >\n {{ boolOperator === boolOperatorType.AND ? '\u00C9S' : 'VAGY' }}\n </button>\n</div>\n", styles: [".relationItemBubble .mat-mdc-button{border-radius:1.5rem;height:100%;margin:auto 0;padding-top:.75em;padding-bottom:.75em}.relationItemBubble{display:flex;flex-direction:row;border-radius:1.5rem;border:1px solid #cdcdcd;padding:.25rem;max-height:42px;height:100%}\n"] }]
21904
+ }], propDecorators: { boolOperator: [{
21905
+ type: Input
21906
+ }], boolOperatorChanged: [{
21907
+ type: Output
21908
+ }] } });
21909
+
21910
+ class AdvancedSmartFilterExpressionItemComponent extends SmartFilterExpressionItemComponent {
21911
+ async onOperatorChanged(operator) {
21912
+ await this.service().bulkUpdateFilterExpression(operator, this.item);
21913
+ }
21914
+ async select(event, item) {
21915
+ await super.select(event, item);
21916
+ this.service().itemSelected.next(item);
21917
+ }
21918
+ deleteItem($event) {
21919
+ $event.stopPropagation();
21920
+ this.service().peformWidgetAction({
21921
+ code: 'REMOVE_FILTER_EXPRESSION',
21922
+ params: {
21923
+ model: this.item,
21924
+ },
21925
+ });
21794
21926
  }
21927
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AdvancedSmartFilterExpressionItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
21928
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AdvancedSmartFilterExpressionItemComponent, isStandalone: true, selector: "app-advanced-expression-item", usesInheritance: true, ngImport: i0, template: "<div class=\"expressionItemContainer\">\n <div\n class=\"expressionItemInnerContainer\"\n [ngClass]=\"\n item.expressionData?.currentOperation === 'EXPRESSION'\n ? isSelected\n ? 'selectedExpressionContainer'\n : 'expressionContainer'\n : ''\n \"\n >\n <div\n *ngIf=\"\n item.expressionData?.currentOperation === 'EXPRESSION';\n then expression;\n else simpleItem\n \"\n ></div>\n <ng-template #expression>\n <div class=\"sub-expression-container\" (click)=\"select($event, item)\">\n <div\n class=\"expressionItemBubble expression sub-expression-start\"\n (click)=\"select($event, item)\"\n ></div>\n <div class=\"sub-expression-items\">\n <app-advanced-expression-item\n [item]=\"subItem\"\n [service]=\"service()\"\n [hasNext]=\"i < (item.subFieldList?.filters)!.length - 1\"\n *ngFor=\"let subItem of item.subFieldList?.filters; let i = index\"\n ></app-advanced-expression-item>\n </div>\n <lib-advanced-relation-button\n [boolOperator]=\"item.subFieldList?.defaultOperation\"\n (boolOperatorChanged)=\"onOperatorChanged($event)\"\n ></lib-advanced-relation-button>\n <div class=\"expressionItemBubble expression sub-expression-end\"></div>\n </div>\n </ng-template>\n <ng-template #simpleItem>\n <div>\n <div\n (click)=\"select($event, item)\"\n class=\"expressionItemBubble simpleItem\"\n [ngClass]=\"isSelected ? 'selectedSimpleItem' : ''\"\n >\n <button mat-button class=\"mat-raised-button delete-button\" (click)=\"deleteItem($event)\"\n >x</button\n >\n\n {{ item.label }}:\n <div *ngIf=\"item.expressionData?.currentOperation !== 'BETWEEN'\">\n <div *ngIf=\"item.widgetType === 'DATE'\">\n <b>{{ item.expressionData!.operand2!.valueAsString! | smartDate }}</b>\n </div>\n <div *ngIf=\"item.widgetType === 'DATE_TIME'\">\n <b>{{ item.expressionData!.operand2!.valueAsString! | smartDateTime }}</b>\n </div>\n <div *ngIf=\"item.widgetType !== 'DATE_TIME' && item.widgetType !== 'DATE'\">\n <b>{{ getDisplayValue(item.expressionData!.operand2!.valueAsString!) }}</b>\n </div>\n </div>\n <div *ngIf=\"item.expressionData?.currentOperation === 'IN'\">\n <b *ngFor=\"let value of item.expressionData?.operand2?.selectedValues; let last = last\">\n {{ getDisplayValue(value) }} <b *ngIf=\"!last\">,</b>\n </b>\n </div>\n <div class=\"expressionValues\" *ngIf=\"item.expressionData?.currentOperation === 'BETWEEN'\">\n <div *ngIf=\"item.widgetType === 'DATE'\">\n <b>{{ item.expressionData!.operand2!.valueAsString! | smartDate }}</b>\n </div>\n <div *ngIf=\"item.widgetType === 'DATE_TIME'\">\n <b>{{ item.expressionData!.operand2!.valueAsString! | smartDateTime }}</b>\n </div>\n <div *ngIf=\"item.widgetType !== 'DATE_TIME' && item.widgetType !== 'DATE'\">\n <b>{{ item.expressionData?.operand2?.valueAsString }}</b>\n </div>\n <b>-</b>\n <div *ngIf=\"item.widgetType === 'DATE'\">\n <b>{{ item.expressionData!.operand3!.valueAsString! | smartDate }}</b>\n </div>\n <div *ngIf=\"item.widgetType === 'DATE_TIME'\">\n <b>{{ item.expressionData!.operand3!.valueAsString! | smartDateTime }}</b>\n </div>\n <div *ngIf=\"item.widgetType !== 'DATE_TIME' && item.widgetType !== 'DATE'\">\n <b>{{ item.expressionData?.operand3?.valueAsString }}</b>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: [".expressionItemContainer{display:flex;flex-direction:row;gap:.75rem}.expressionItemInnerContainer{display:flex;flex-direction:row;grid-area:.75rem;padding:.25rem;border-radius:.25rem}.expressionContainer{border:1px dashed var(--primary-lighter-gray-color);cursor:pointer}.selectedExpressionContainer{border:2px dashed var(--primary-color)}.expressionItemBubble,.relationItemBubble{display:flex;flex-direction:row;border-radius:1.5rem}.expressionItemBubble{padding:.75rem}.expression{background-color:var(--inner-container);font-weight:600;margin:auto 0}.simpleItem{background-color:#c6ddff;cursor:pointer}.relationItemBubble{border:1px solid #cdcdcd;padding:.25rem;max-height:42px;margin-top:.25rem}.relationItemBubble .mat-mdc-button{border-radius:1.5rem;height:100%;margin:auto 0}.expressionValues{display:flex;flex-direction:row;gap:.5rem}.sub-expression-container{display:flex;align-items:stretch}.sub-expression-start{padding:5px;height:100%;border-left:2px solid black;border-top:2px solid black;border-bottom:2px solid black;border-radius:0}.sub-expression-end{padding:5px;height:100%;border-right:2px solid black;border-top:2px solid black;border-bottom:2px solid black;border-radius:0}.sub-expression-items{display:flex;flex-wrap:wrap}lib-advanced-relation-button{margin-top:.25rem;margin-bottom:.25rem}.delete-button{min-width:10px;top:-7px;height:20px;padding:5px;border-radius:1.5rem}\n"], dependencies: [{ kind: "component", type: AdvancedSmartFilterExpressionItemComponent, selector: "app-advanced-expression-item" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: AdvancedRelationButtonComponent, selector: "lib-advanced-relation-button", inputs: ["boolOperator"], outputs: ["boolOperatorChanged"] }, { kind: "pipe", type: SmartDatePipe, name: "smartDate" }, { kind: "pipe", type: SmartDateTimePipe, name: "smartDateTime" }] }); }
21929
+ }
21930
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AdvancedSmartFilterExpressionItemComponent, decorators: [{
21931
+ type: Component,
21932
+ args: [{ selector: 'app-advanced-expression-item', imports: [
21933
+ NgClass,
21934
+ NgIf,
21935
+ NgForOf,
21936
+ MatButton,
21937
+ SmartDatePipe,
21938
+ SmartDateTimePipe,
21939
+ AdvancedRelationButtonComponent,
21940
+ ], template: "<div class=\"expressionItemContainer\">\n <div\n class=\"expressionItemInnerContainer\"\n [ngClass]=\"\n item.expressionData?.currentOperation === 'EXPRESSION'\n ? isSelected\n ? 'selectedExpressionContainer'\n : 'expressionContainer'\n : ''\n \"\n >\n <div\n *ngIf=\"\n item.expressionData?.currentOperation === 'EXPRESSION';\n then expression;\n else simpleItem\n \"\n ></div>\n <ng-template #expression>\n <div class=\"sub-expression-container\" (click)=\"select($event, item)\">\n <div\n class=\"expressionItemBubble expression sub-expression-start\"\n (click)=\"select($event, item)\"\n ></div>\n <div class=\"sub-expression-items\">\n <app-advanced-expression-item\n [item]=\"subItem\"\n [service]=\"service()\"\n [hasNext]=\"i < (item.subFieldList?.filters)!.length - 1\"\n *ngFor=\"let subItem of item.subFieldList?.filters; let i = index\"\n ></app-advanced-expression-item>\n </div>\n <lib-advanced-relation-button\n [boolOperator]=\"item.subFieldList?.defaultOperation\"\n (boolOperatorChanged)=\"onOperatorChanged($event)\"\n ></lib-advanced-relation-button>\n <div class=\"expressionItemBubble expression sub-expression-end\"></div>\n </div>\n </ng-template>\n <ng-template #simpleItem>\n <div>\n <div\n (click)=\"select($event, item)\"\n class=\"expressionItemBubble simpleItem\"\n [ngClass]=\"isSelected ? 'selectedSimpleItem' : ''\"\n >\n <button mat-button class=\"mat-raised-button delete-button\" (click)=\"deleteItem($event)\"\n >x</button\n >\n\n {{ item.label }}:\n <div *ngIf=\"item.expressionData?.currentOperation !== 'BETWEEN'\">\n <div *ngIf=\"item.widgetType === 'DATE'\">\n <b>{{ item.expressionData!.operand2!.valueAsString! | smartDate }}</b>\n </div>\n <div *ngIf=\"item.widgetType === 'DATE_TIME'\">\n <b>{{ item.expressionData!.operand2!.valueAsString! | smartDateTime }}</b>\n </div>\n <div *ngIf=\"item.widgetType !== 'DATE_TIME' && item.widgetType !== 'DATE'\">\n <b>{{ getDisplayValue(item.expressionData!.operand2!.valueAsString!) }}</b>\n </div>\n </div>\n <div *ngIf=\"item.expressionData?.currentOperation === 'IN'\">\n <b *ngFor=\"let value of item.expressionData?.operand2?.selectedValues; let last = last\">\n {{ getDisplayValue(value) }} <b *ngIf=\"!last\">,</b>\n </b>\n </div>\n <div class=\"expressionValues\" *ngIf=\"item.expressionData?.currentOperation === 'BETWEEN'\">\n <div *ngIf=\"item.widgetType === 'DATE'\">\n <b>{{ item.expressionData!.operand2!.valueAsString! | smartDate }}</b>\n </div>\n <div *ngIf=\"item.widgetType === 'DATE_TIME'\">\n <b>{{ item.expressionData!.operand2!.valueAsString! | smartDateTime }}</b>\n </div>\n <div *ngIf=\"item.widgetType !== 'DATE_TIME' && item.widgetType !== 'DATE'\">\n <b>{{ item.expressionData?.operand2?.valueAsString }}</b>\n </div>\n <b>-</b>\n <div *ngIf=\"item.widgetType === 'DATE'\">\n <b>{{ item.expressionData!.operand3!.valueAsString! | smartDate }}</b>\n </div>\n <div *ngIf=\"item.widgetType === 'DATE_TIME'\">\n <b>{{ item.expressionData!.operand3!.valueAsString! | smartDateTime }}</b>\n </div>\n <div *ngIf=\"item.widgetType !== 'DATE_TIME' && item.widgetType !== 'DATE'\">\n <b>{{ item.expressionData?.operand3?.valueAsString }}</b>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: [".expressionItemContainer{display:flex;flex-direction:row;gap:.75rem}.expressionItemInnerContainer{display:flex;flex-direction:row;grid-area:.75rem;padding:.25rem;border-radius:.25rem}.expressionContainer{border:1px dashed var(--primary-lighter-gray-color);cursor:pointer}.selectedExpressionContainer{border:2px dashed var(--primary-color)}.expressionItemBubble,.relationItemBubble{display:flex;flex-direction:row;border-radius:1.5rem}.expressionItemBubble{padding:.75rem}.expression{background-color:var(--inner-container);font-weight:600;margin:auto 0}.simpleItem{background-color:#c6ddff;cursor:pointer}.relationItemBubble{border:1px solid #cdcdcd;padding:.25rem;max-height:42px;margin-top:.25rem}.relationItemBubble .mat-mdc-button{border-radius:1.5rem;height:100%;margin:auto 0}.expressionValues{display:flex;flex-direction:row;gap:.5rem}.sub-expression-container{display:flex;align-items:stretch}.sub-expression-start{padding:5px;height:100%;border-left:2px solid black;border-top:2px solid black;border-bottom:2px solid black;border-radius:0}.sub-expression-end{padding:5px;height:100%;border-right:2px solid black;border-top:2px solid black;border-bottom:2px solid black;border-radius:0}.sub-expression-items{display:flex;flex-wrap:wrap}lib-advanced-relation-button{margin-top:.25rem;margin-bottom:.25rem}.delete-button{min-width:10px;top:-7px;height:20px;padding:5px;border-radius:1.5rem}\n"] }]
21941
+ }] });
21942
+
21943
+ class SmartFilterExpressionItemsComponent {
21795
21944
  constructor() {
21796
21945
  this._destroy$ = new Subject();
21797
21946
  this.items = input.required(/* @ts-ignore */
21798
21947
  ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
21799
21948
  this.service = input.required(/* @ts-ignore */
21800
21949
  ...(ngDevMode ? [{ debugName: "service" }] : /* istanbul ignore next */ []));
21950
+ this.useAdvancedFilter = inject(USE_ADVANCED_FILTER, { optional: true });
21801
21951
  /** Written from the editor service's `modelChanged`, never from a template event. */
21802
21952
  this.isSelectedState = signal(false, /* @ts-ignore */
21803
21953
  ...(ngDevMode ? [{ debugName: "isSelectedState" }] : /* istanbul ignore next */ []));
21804
21954
  }
21955
+ get isSelected() {
21956
+ return this.isSelectedState();
21957
+ }
21958
+ set isSelected(isSelected) {
21959
+ this.isSelectedState.set(isSelected);
21960
+ }
21805
21961
  ngOnInit() {
21806
21962
  this.service().modelChanged.subscribe(() => {
21807
21963
  const service = this.service();
@@ -21820,13 +21976,83 @@ class SmartFilterExpressionItemsComponent {
21820
21976
  drop(event) {
21821
21977
  moveItemInArray(this.items(), event.previousIndex, event.currentIndex);
21822
21978
  }
21979
+ async onOperatorChanged($event) {
21980
+ await this.service().bulkUpdateFilterExpression($event);
21981
+ }
21823
21982
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartFilterExpressionItemsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
21824
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartFilterExpressionItemsComponent, isStandalone: true, selector: "app-expression-items", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, service: { classPropertyName: "service", publicName: "service", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"expressionsContainer example-list\"\n [ngClass]=\"isSelected ? 'selected' : ''\"\n >\n @for (item of items(); track item; let i = $index) {\n <div cdkDrag class=\"expressionItem\">\n <app-expression-item\n [item]=\"item\"\n [hasNext]=\"i < items().length - 1\"\n [service]=\"service()\"\n ></app-expression-item>\n </div>\n }\n</div>\n", styles: [".expressionsContainer{display:flex;flex-direction:row;flex-wrap:wrap;gap:.75rem;border:1px dashed var(--primary-lighter-gray-color);padding:.25rem;border-radius:.25rem}.selected{border:2px dashed var(--primary-darker-color)}.expressionItem{margin:auto 0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.example-custom-placeholder{background:#ccc;border:dotted 3px #999;min-height:60px;transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SmartFilterExpressionItemComponent, selector: "app-expression-item", inputs: ["item", "hasNext", "service"] }] }); }
21983
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartFilterExpressionItemsComponent, isStandalone: true, selector: "app-expression-items", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, service: { classPropertyName: "service", publicName: "service", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if (useAdvancedFilter) {\n <div class=\"advanced-expression-builder-container\">\n <div\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"expressionsContainer example-list\"\n [ngClass]=\"isSelected ? 'selected' : ''\"\n >\n @for (item of items(); track item; let i = $index) {\n <div\n cdkDrag\n class=\"expressionItem\"\n [ngClass]=\"item.expressionData?.currentOperation == 'EXPRESSION' ? 'non-flex' : ''\"\n >\n <app-advanced-expression-item\n [item]=\"item\"\n [hasNext]=\"i < items().length - 1\"\n [service]=\"service()\"\n ></app-advanced-expression-item>\n </div>\n }\n </div>\n\n <div class=\"relationItemBubble\">\n <lib-advanced-relation-button\n [boolOperator]=\"service().model?.model?.workplaceList?.defaultOperation\"\n (boolOperatorChanged)=\"onOperatorChanged($event)\"\n ></lib-advanced-relation-button>\n </div>\n </div>\n} @else {\n <div\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"expressionsContainer example-list\"\n [ngClass]=\"isSelected ? 'selected' : ''\"\n >\n @for (item of items(); track item; let i = $index) {\n <div cdkDrag class=\"expressionItem\">\n <app-expression-item\n [item]=\"item\"\n [hasNext]=\"i < items().length - 1\"\n [service]=\"service()\"\n ></app-expression-item>\n </div>\n }\n </div>\n}\n", styles: [".expressionsContainer{display:flex;flex-direction:row;flex-wrap:wrap;gap:.75rem;border:1px dashed var(--primary-lighter-gray-color);padding:.25rem;border-radius:.25rem}.selected{border:2px dashed var(--primary-darker-color)}.expressionItem{margin:auto 0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.example-custom-placeholder{background:#ccc;border:dotted 3px #999;min-height:60px;transition:transform .25s cubic-bezier(0,0,.2,1)}.non-flex{flex:0 0 100%}lib-advanced-relation-button{margin-top:.25rem;margin-bottom:.25rem}:host{display:flex}.advanced-expression-builder-container{display:inline-flex}.relationItemBubble{padding:.5rem}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SmartFilterExpressionItemComponent, selector: "app-expression-item", inputs: ["item", "hasNext", "service"] }, { kind: "component", type: AdvancedSmartFilterExpressionItemComponent, selector: "app-advanced-expression-item" }, { kind: "component", type: AdvancedRelationButtonComponent, selector: "lib-advanced-relation-button", inputs: ["boolOperator"], outputs: ["boolOperatorChanged"] }] }); }
21825
21984
  }
21826
21985
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartFilterExpressionItemsComponent, decorators: [{
21827
21986
  type: Component,
21828
- args: [{ selector: 'app-expression-items', imports: [NgClass, SmartFilterExpressionItemComponent], template: "<div\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"expressionsContainer example-list\"\n [ngClass]=\"isSelected ? 'selected' : ''\"\n >\n @for (item of items(); track item; let i = $index) {\n <div cdkDrag class=\"expressionItem\">\n <app-expression-item\n [item]=\"item\"\n [hasNext]=\"i < items().length - 1\"\n [service]=\"service()\"\n ></app-expression-item>\n </div>\n }\n</div>\n", styles: [".expressionsContainer{display:flex;flex-direction:row;flex-wrap:wrap;gap:.75rem;border:1px dashed var(--primary-lighter-gray-color);padding:.25rem;border-radius:.25rem}.selected{border:2px dashed var(--primary-darker-color)}.expressionItem{margin:auto 0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.example-custom-placeholder{background:#ccc;border:dotted 3px #999;min-height:60px;transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
21829
- }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], service: [{ type: i0.Input, args: [{ isSignal: true, alias: "service", required: true }] }] } });
21987
+ args: [{ selector: 'app-expression-items', imports: [
21988
+ NgClass,
21989
+ SmartFilterExpressionItemComponent,
21990
+ AdvancedSmartFilterExpressionItemComponent,
21991
+ AdvancedRelationButtonComponent,
21992
+ ], template: "@if (useAdvancedFilter) {\n <div class=\"advanced-expression-builder-container\">\n <div\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"expressionsContainer example-list\"\n [ngClass]=\"isSelected ? 'selected' : ''\"\n >\n @for (item of items(); track item; let i = $index) {\n <div\n cdkDrag\n class=\"expressionItem\"\n [ngClass]=\"item.expressionData?.currentOperation == 'EXPRESSION' ? 'non-flex' : ''\"\n >\n <app-advanced-expression-item\n [item]=\"item\"\n [hasNext]=\"i < items().length - 1\"\n [service]=\"service()\"\n ></app-advanced-expression-item>\n </div>\n }\n </div>\n\n <div class=\"relationItemBubble\">\n <lib-advanced-relation-button\n [boolOperator]=\"service().model?.model?.workplaceList?.defaultOperation\"\n (boolOperatorChanged)=\"onOperatorChanged($event)\"\n ></lib-advanced-relation-button>\n </div>\n </div>\n} @else {\n <div\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"expressionsContainer example-list\"\n [ngClass]=\"isSelected ? 'selected' : ''\"\n >\n @for (item of items(); track item; let i = $index) {\n <div cdkDrag class=\"expressionItem\">\n <app-expression-item\n [item]=\"item\"\n [hasNext]=\"i < items().length - 1\"\n [service]=\"service()\"\n ></app-expression-item>\n </div>\n }\n </div>\n}\n", styles: [".expressionsContainer{display:flex;flex-direction:row;flex-wrap:wrap;gap:.75rem;border:1px dashed var(--primary-lighter-gray-color);padding:.25rem;border-radius:.25rem}.selected{border:2px dashed var(--primary-darker-color)}.expressionItem{margin:auto 0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.example-custom-placeholder{background:#ccc;border:dotted 3px #999;min-height:60px;transition:transform .25s cubic-bezier(0,0,.2,1)}.non-flex{flex:0 0 100%}lib-advanced-relation-button{margin-top:.25rem;margin-bottom:.25rem}:host{display:flex}.advanced-expression-builder-container{display:inline-flex}.relationItemBubble{padding:.5rem}\n"] }]
21993
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], service: [{ type: i0.Input, args: [{ isSignal: true, alias: "service", required: true }] }] } });
21994
+
21995
+ class ExpressionEditorDialogComponent {
21996
+ constructor() {
21997
+ this.service = inject(ExpressionEditorDialogService);
21998
+ this.smartForm = this.service.form;
21999
+ }
22000
+ cancel() {
22001
+ this.service.closeDialog(false);
22002
+ }
22003
+ save() {
22004
+ let submittedForm = this.formComponent.submitForm();
22005
+ this.service.onSave(submittedForm.componentModel.data);
22006
+ }
22007
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ExpressionEditorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
22008
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: ExpressionEditorDialogComponent, isStandalone: true, selector: "lib-expression-editor-dialog", viewQueries: [{ propertyName: "formComponent", first: true, predicate: ["form"], descendants: true, read: SmartformComponent }], ngImport: i0, template: "<smartform #form [smartForm]=\"smartForm\"></smartform>\n<div class=\"button-container\">\n <button (click)=\"save()\" mat-raised-button color=\"primary\">Ment\u00E9s</button>\n <button (click)=\"cancel()\" mat-raised-button color=\"secondary\">M\u00E9gsem</button>\n</div>\n", styles: [".button-container{display:flex;justify-content:flex-end;gap:1rem}:host{display:flex;flex-direction:column;padding:1rem}:host::ng-deep h4{margin:0}:host::ng-deep .mat-mdc-form-field-infix:has(input){padding:0}\n"], dependencies: [{ kind: "component", type: SmartformComponent, selector: "smartform", inputs: ["smartForm"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
22009
+ }
22010
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ExpressionEditorDialogComponent, decorators: [{
22011
+ type: Component,
22012
+ args: [{ selector: 'lib-expression-editor-dialog', imports: [SmartformComponent, MatButton], template: "<smartform #form [smartForm]=\"smartForm\"></smartform>\n<div class=\"button-container\">\n <button (click)=\"save()\" mat-raised-button color=\"primary\">Ment\u00E9s</button>\n <button (click)=\"cancel()\" mat-raised-button color=\"secondary\">M\u00E9gsem</button>\n</div>\n", styles: [".button-container{display:flex;justify-content:flex-end;gap:1rem}:host{display:flex;flex-direction:column;padding:1rem}:host::ng-deep h4{margin:0}:host::ng-deep .mat-mdc-form-field-infix:has(input){padding:0}\n"] }]
22013
+ }], ctorParameters: () => [], propDecorators: { formComponent: [{
22014
+ type: ViewChild,
22015
+ args: ['form', { read: SmartformComponent }]
22016
+ }] } });
22017
+
22018
+ class ExpressionEditorDialogService extends SmartdialogService {
22019
+ constructor() {
22020
+ const dialog = inject(MatDialog);
22021
+ const inject$1 = inject(Injector);
22022
+ super(dialog, inject$1);
22023
+ this._destroy$ = new Subject();
22024
+ this.saveEvent = new Subject();
22025
+ }
22026
+ setDataAndOpenDialog(form) {
22027
+ this.form = form;
22028
+ console.log(this.form);
22029
+ this.openDialog();
22030
+ }
22031
+ openDialog() {
22032
+ const dialogData = {
22033
+ content: {
22034
+ title: '',
22035
+ },
22036
+ size: {},
22037
+ customComponent: ExpressionEditorDialogComponent,
22038
+ };
22039
+ this.createDialog(dialogData, ExpressionEditorDialogComponent);
22040
+ }
22041
+ onSave(data) {
22042
+ this.saveEvent.next(data);
22043
+ // this.onAction.complete();
22044
+ this.closeDialog();
22045
+ // this.onAction = new SmartSubject(this._destroy$);
22046
+ }
22047
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ExpressionEditorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
22048
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ExpressionEditorDialogService, providedIn: 'root' }); }
22049
+ }
22050
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ExpressionEditorDialogService, decorators: [{
22051
+ type: Injectable,
22052
+ args: [{
22053
+ providedIn: 'root',
22054
+ }]
22055
+ }], ctorParameters: () => [] });
21830
22056
 
21831
22057
  class SmartFilterEditorContentComponent {
21832
22058
  get uiActionModels() {
@@ -21853,6 +22079,8 @@ class SmartFilterEditorContentComponent {
21853
22079
  this.type = FilterExpressionBuilderUiModelTypeEnum;
21854
22080
  /** The screen component this filter belongs to; the source of its uuid. (ADR-0005) */
21855
22081
  this.smartComponent = injectSmartComponent();
22082
+ this.expressionEditorDialogService = inject(ExpressionEditorDialogService);
22083
+ this.useAdvancedFilter = inject(USE_ADVANCED_FILTER, { optional: true });
21856
22084
  registerSmartWidget(this.smartComponent, {
21857
22085
  identifier: () => this.service?.config?.identifier,
21858
22086
  reload: () => this.service.load(),
@@ -21896,6 +22124,19 @@ class SmartFilterEditorContentComponent {
21896
22124
  }
21897
22125
  this.service.modelChanged.pipe(takeUntil(this._destroy$)).subscribe(() => this.setUp());
21898
22126
  this.service.load();
22127
+ if (this.useAdvancedFilter) {
22128
+ this.service.itemSelected.pipe(takeUntil(this._destroy$)).subscribe((item) => {
22129
+ if (item.expressionData?.currentOperation !== 'EXPRESSION') {
22130
+ this.expressionEditorDialogService.setDataAndOpenDialog(this.createFilterEditorForm());
22131
+ }
22132
+ });
22133
+ this.expressionEditorDialogService.saveEvent
22134
+ .pipe(takeUntil(this._destroy$))
22135
+ .subscribe((data) => {
22136
+ this.service.model.selectedField = data;
22137
+ this.updateFilterExpression();
22138
+ });
22139
+ }
21899
22140
  }
21900
22141
  ngOnDestroy() {
21901
22142
  this._destroy$.next();
@@ -21941,8 +22182,8 @@ class SmartFilterEditorContentComponent {
21941
22182
  let smartForm = {
21942
22183
  direction: SmartFormWidgetDirection.ROW,
21943
22184
  componentModel: { data: model },
21944
- useOnValueChangeEvent: true,
21945
- useOnBlurEvent: true,
22185
+ useOnValueChangeEvent: !this.useAdvancedFilter,
22186
+ useOnBlurEvent: !this.useAdvancedFilter,
21946
22187
  widgets,
21947
22188
  };
21948
22189
  if (this.simpleFilterRef?.instance) {
@@ -22018,26 +22259,32 @@ class SmartFilterEditorContentComponent {
22018
22259
  }
22019
22260
  }
22020
22261
  constructForm() {
22262
+ this.smartForm = this.createFilterEditorForm();
22021
22263
  this.vcRef?.clear();
22022
22264
  this.formCompRef?.destroy();
22023
22265
  if (!this.vcRef) {
22024
22266
  return;
22025
22267
  }
22268
+ this.formCompRef = this.cfService.createComponent(this.vcRef, SmartformComponent, new Map([['smartForm', this.smartForm]]));
22269
+ this.subscribeEditorFormChildrenEvents();
22270
+ }
22271
+ createFilterEditorForm() {
22026
22272
  let generatedWidgets = this.layoutService.render({
22027
22273
  layoutDefinitions: this.service.model?.selectedFieldEditor?.layoutDef?.widgets,
22028
22274
  });
22029
- this.smartForm = {
22275
+ return {
22030
22276
  direction: SmartFormWidgetDirection.ROW,
22031
22277
  useOnBlurEvent: true,
22032
22278
  useOnValueChangeEvent: true,
22033
22279
  componentModel: { data: this.service.model?.selectedField },
22034
22280
  widgets: generatedWidgets,
22035
22281
  };
22036
- this.formCompRef = this.cfService.createComponent(this.vcRef, SmartformComponent, new Map([['smartForm', this.smartForm]]));
22037
- this.subscribeEditorFormChildrenEvents();
22038
22282
  }
22039
22283
  save() {
22040
22284
  this.formCompRef?.instance?.submitForm(false);
22285
+ this.updateFilterExpression();
22286
+ }
22287
+ updateFilterExpression() {
22041
22288
  this.service.peformWidgetAction({
22042
22289
  code: 'UPDATE_FILTER_EXPRESSION',
22043
22290
  params: {
@@ -22093,12 +22340,19 @@ class SmartFilterEditorContentComponent {
22093
22340
  };
22094
22341
  return widget;
22095
22342
  }
22343
+ async unSelectItems(event) {
22344
+ event.stopPropagation();
22345
+ await this.service.peformWidgetAction({
22346
+ code: 'SELECT_FIELD',
22347
+ params: {},
22348
+ });
22349
+ }
22096
22350
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartFilterEditorContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
22097
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartFilterEditorContentComponent, isStandalone: true, selector: "smart-filter-expression-editor", inputs: { service: "service" }, viewQueries: [{ propertyName: "vcRef", first: true, predicate: ["form"], descendants: true, read: ViewContainerRef }, { propertyName: "simpleFilterVcRef", first: true, predicate: ["simpleFilterFromChild"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div class=\"smart-filter-editor-container\" *ngIf=\"service.model\">\n @if (service.model.model?.label) {\n <h3 class=\"smart-filter-editor-title\">{{ service.model.model?.label }}</h3>\n }\n\n <div *ngIf=\"service.model?.type === type.SIMPLE; then simpleFilter; else complexFilter\"></div>\n\n <ng-template #simpleFilter>\n <div class=\"smart-filter-editor-expressionsContainer\">\n <ng-template #simpleFilterFromChild></ng-template>\n <!-- #simpleFilterFromChild [smartForm]=\"simpleFilterForm\"></smartform> -->\n </div>\n </ng-template>\n <ng-template #complexFilter>\n <div class=\"smart-filter-editor-uiActionsBar\" *ngIf=\"!service.model?.readOnly\">\n <smart-ui-action-toolbar\n [uiActionModels]=\"uiActionModels\"\n [executor]=\"service\"\n ></smart-ui-action-toolbar>\n </div>\n <div\n *ngIf=\"\n service?.model?.model?.workplaceList?.filters?.length;\n then withParameters;\n else withoutParameters\n \"\n ></div>\n <ng-template #withoutParameters>\n <div class=\"smart-filter-editor-withoutParametersContainer\">\n <span class=\"mat-body\"> M\u00E9g nincs megadva param\u00E9ter </span>\n </div>\n </ng-template>\n <ng-template #withParameters>\n <div class=\"smart-filter-editor-withParametersContainer\">\n <div\n class=\"smart-filter-editor-expressionsContainer\"\n *ngIf=\"service?.model?.model?.workplaceList?.filters?.length\"\n >\n <app-expression-items\n [items]=\"(service.model.model?.workplaceList)!.filters\"\n [service]=\"service\"\n ></app-expression-items>\n </div>\n <div class=\"smart-filter-editor-expressionEditorContainer\">\n <!-- <smartform #form [smartForm]=\"smartForm\"></smartform> -->\n <ng-template #form></ng-template>\n <div *ngIf=\"smartForm\">\n <button (click)=\"remove()\" mat-raised-button color=\"primary\">T\u00F6rl\u00E9s</button>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-template>\n</div>\n", styles: [".smart-filter-editor-container{display:flex;flex-direction:column;overflow:auto;position:relative}.targetGroupContentContainer h3{margin:0;font-weight:600}.smart-filter-editor-uiActionsBar{padding:1.5rem;border-radius:.25rem;background-color:var(--container-color);display:flex;flex-direction:row;gap:1rem}.smart-filter-editor-withoutParametersContainer{display:flex;flex-direction:column;background-color:var(--container-color)}.withoutParametersContainer .mat-body{font-weight:600;text-align:center}.smart-filter-editor-withParametersContainer{display:flex;flex-direction:column;background-color:var(--container-color)}.smart-filter-editor-expressionEditorContainer{display:flex;flex-direction:column;gap:.75rem}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: UiActionToolbarComponent, selector: "smart-ui-action-toolbar", inputs: ["uiActionModels", "uiActionDescriptorService", "id", "executor", "widgetId", "nodeId", "actionParams", "scrollOnWrap", "toolbarPropertes"] }, { kind: "component", type: SmartFilterExpressionItemsComponent, selector: "app-expression-items", inputs: ["items", "service"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
22351
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SmartFilterEditorContentComponent, isStandalone: true, selector: "smart-filter-expression-editor", inputs: { service: "service" }, viewQueries: [{ propertyName: "vcRef", first: true, predicate: ["form"], descendants: true, read: ViewContainerRef }, { propertyName: "simpleFilterVcRef", first: true, predicate: ["simpleFilterFromChild"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div class=\"smart-filter-editor-container\" *ngIf=\"service.model\">\n @if (service.model.model?.label) {\n <h3 class=\"smart-filter-editor-title\">{{ service.model.model?.label }}</h3>\n }\n\n <div *ngIf=\"service.model.type === type.SIMPLE; then simpleFilter; else complexFilter\"></div>\n\n <ng-template #simpleFilter>\n <div class=\"smart-filter-editor-expressionsContainer\">\n <ng-template #simpleFilterFromChild></ng-template>\n <!-- #simpleFilterFromChild [smartForm]=\"simpleFilterForm\"></smartform> -->\n </div>\n </ng-template>\n <ng-template #complexFilter>\n <div class=\"smart-filter-editor-uiActionsBar\" *ngIf=\"!service.model?.readOnly\">\n <smart-ui-action-toolbar\n [uiActionModels]=\"uiActionModels\"\n [executor]=\"service\"\n ></smart-ui-action-toolbar>\n </div>\n <div\n *ngIf=\"\n service.model?.model?.workplaceList?.filters?.length;\n then withParameters;\n else withoutParameters\n \"\n ></div>\n <ng-template #withoutParameters>\n <div class=\"smart-filter-editor-withoutParametersContainer\">\n <span class=\"mat-body\"> M\u00E9g nincs megadva param\u00E9ter </span>\n </div>\n </ng-template>\n <ng-template #withParameters>\n <div class=\"smart-filter-editor-withParametersContainer\">\n <div\n class=\"smart-filter-editor-expressionsContainer\"\n *ngIf=\"service.model?.model?.workplaceList?.filters?.length\"\n (click)=\"unSelectItems($event)\"\n >\n <app-expression-items\n [items]=\"(service.model?.model?.workplaceList)!.filters\"\n [service]=\"service\"\n ></app-expression-items>\n </div>\n <div\n *ngIf=\"\n !useAdvancedFilter ||\n service.model?.selectedField?.expressionData?.currentOperation === 'EXPRESSION'\n \"\n class=\"smart-filter-editor-expressionEditorContainer\"\n >\n <!-- <smartform #form [smartForm]=\"smartForm\"></smartform> -->\n <ng-template #form></ng-template>\n <div *ngIf=\"smartForm\">\n <button (click)=\"remove()\" mat-raised-button color=\"primary\">T\u00F6rl\u00E9s</button>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-template>\n</div>\n", styles: [".smart-filter-editor-container{display:flex;flex-direction:column;overflow:auto;position:relative}.targetGroupContentContainer h3{margin:0;font-weight:600}.smart-filter-editor-uiActionsBar{padding:1.5rem;border-radius:.25rem;background-color:var(--container-color);display:flex;flex-direction:row;gap:1rem}.smart-filter-editor-withoutParametersContainer{display:flex;flex-direction:column;background-color:var(--container-color)}.withoutParametersContainer .mat-body{font-weight:600;text-align:center}.smart-filter-editor-withParametersContainer{display:flex;flex-direction:column;background-color:var(--container-color)}.smart-filter-editor-expressionEditorContainer{display:flex;flex-direction:column;gap:.75rem}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: UiActionToolbarComponent, selector: "smart-ui-action-toolbar", inputs: ["uiActionModels", "uiActionDescriptorService", "id", "executor", "widgetId", "nodeId", "actionParams", "scrollOnWrap", "toolbarPropertes"] }, { kind: "component", type: SmartFilterExpressionItemsComponent, selector: "app-expression-items", inputs: ["items", "service"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
22098
22352
  }
22099
22353
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SmartFilterEditorContentComponent, decorators: [{
22100
22354
  type: Component,
22101
- args: [{ selector: 'smart-filter-expression-editor', imports: [NgIf, UiActionToolbarComponent, SmartFilterExpressionItemsComponent, MatButton], template: "<div class=\"smart-filter-editor-container\" *ngIf=\"service.model\">\n @if (service.model.model?.label) {\n <h3 class=\"smart-filter-editor-title\">{{ service.model.model?.label }}</h3>\n }\n\n <div *ngIf=\"service.model?.type === type.SIMPLE; then simpleFilter; else complexFilter\"></div>\n\n <ng-template #simpleFilter>\n <div class=\"smart-filter-editor-expressionsContainer\">\n <ng-template #simpleFilterFromChild></ng-template>\n <!-- #simpleFilterFromChild [smartForm]=\"simpleFilterForm\"></smartform> -->\n </div>\n </ng-template>\n <ng-template #complexFilter>\n <div class=\"smart-filter-editor-uiActionsBar\" *ngIf=\"!service.model?.readOnly\">\n <smart-ui-action-toolbar\n [uiActionModels]=\"uiActionModels\"\n [executor]=\"service\"\n ></smart-ui-action-toolbar>\n </div>\n <div\n *ngIf=\"\n service?.model?.model?.workplaceList?.filters?.length;\n then withParameters;\n else withoutParameters\n \"\n ></div>\n <ng-template #withoutParameters>\n <div class=\"smart-filter-editor-withoutParametersContainer\">\n <span class=\"mat-body\"> M\u00E9g nincs megadva param\u00E9ter </span>\n </div>\n </ng-template>\n <ng-template #withParameters>\n <div class=\"smart-filter-editor-withParametersContainer\">\n <div\n class=\"smart-filter-editor-expressionsContainer\"\n *ngIf=\"service?.model?.model?.workplaceList?.filters?.length\"\n >\n <app-expression-items\n [items]=\"(service.model.model?.workplaceList)!.filters\"\n [service]=\"service\"\n ></app-expression-items>\n </div>\n <div class=\"smart-filter-editor-expressionEditorContainer\">\n <!-- <smartform #form [smartForm]=\"smartForm\"></smartform> -->\n <ng-template #form></ng-template>\n <div *ngIf=\"smartForm\">\n <button (click)=\"remove()\" mat-raised-button color=\"primary\">T\u00F6rl\u00E9s</button>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-template>\n</div>\n", styles: [".smart-filter-editor-container{display:flex;flex-direction:column;overflow:auto;position:relative}.targetGroupContentContainer h3{margin:0;font-weight:600}.smart-filter-editor-uiActionsBar{padding:1.5rem;border-radius:.25rem;background-color:var(--container-color);display:flex;flex-direction:row;gap:1rem}.smart-filter-editor-withoutParametersContainer{display:flex;flex-direction:column;background-color:var(--container-color)}.withoutParametersContainer .mat-body{font-weight:600;text-align:center}.smart-filter-editor-withParametersContainer{display:flex;flex-direction:column;background-color:var(--container-color)}.smart-filter-editor-expressionEditorContainer{display:flex;flex-direction:column;gap:.75rem}\n"] }]
22355
+ args: [{ selector: 'smart-filter-expression-editor', imports: [NgIf, UiActionToolbarComponent, SmartFilterExpressionItemsComponent, MatButton], template: "<div class=\"smart-filter-editor-container\" *ngIf=\"service.model\">\n @if (service.model.model?.label) {\n <h3 class=\"smart-filter-editor-title\">{{ service.model.model?.label }}</h3>\n }\n\n <div *ngIf=\"service.model.type === type.SIMPLE; then simpleFilter; else complexFilter\"></div>\n\n <ng-template #simpleFilter>\n <div class=\"smart-filter-editor-expressionsContainer\">\n <ng-template #simpleFilterFromChild></ng-template>\n <!-- #simpleFilterFromChild [smartForm]=\"simpleFilterForm\"></smartform> -->\n </div>\n </ng-template>\n <ng-template #complexFilter>\n <div class=\"smart-filter-editor-uiActionsBar\" *ngIf=\"!service.model?.readOnly\">\n <smart-ui-action-toolbar\n [uiActionModels]=\"uiActionModels\"\n [executor]=\"service\"\n ></smart-ui-action-toolbar>\n </div>\n <div\n *ngIf=\"\n service.model?.model?.workplaceList?.filters?.length;\n then withParameters;\n else withoutParameters\n \"\n ></div>\n <ng-template #withoutParameters>\n <div class=\"smart-filter-editor-withoutParametersContainer\">\n <span class=\"mat-body\"> M\u00E9g nincs megadva param\u00E9ter </span>\n </div>\n </ng-template>\n <ng-template #withParameters>\n <div class=\"smart-filter-editor-withParametersContainer\">\n <div\n class=\"smart-filter-editor-expressionsContainer\"\n *ngIf=\"service.model?.model?.workplaceList?.filters?.length\"\n (click)=\"unSelectItems($event)\"\n >\n <app-expression-items\n [items]=\"(service.model?.model?.workplaceList)!.filters\"\n [service]=\"service\"\n ></app-expression-items>\n </div>\n <div\n *ngIf=\"\n !useAdvancedFilter ||\n service.model?.selectedField?.expressionData?.currentOperation === 'EXPRESSION'\n \"\n class=\"smart-filter-editor-expressionEditorContainer\"\n >\n <!-- <smartform #form [smartForm]=\"smartForm\"></smartform> -->\n <ng-template #form></ng-template>\n <div *ngIf=\"smartForm\">\n <button (click)=\"remove()\" mat-raised-button color=\"primary\">T\u00F6rl\u00E9s</button>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-template>\n</div>\n", styles: [".smart-filter-editor-container{display:flex;flex-direction:column;overflow:auto;position:relative}.targetGroupContentContainer h3{margin:0;font-weight:600}.smart-filter-editor-uiActionsBar{padding:1.5rem;border-radius:.25rem;background-color:var(--container-color);display:flex;flex-direction:row;gap:1rem}.smart-filter-editor-withoutParametersContainer{display:flex;flex-direction:column;background-color:var(--container-color)}.withoutParametersContainer .mat-body{font-weight:600;text-align:center}.smart-filter-editor-withParametersContainer{display:flex;flex-direction:column;background-color:var(--container-color)}.smart-filter-editor-expressionEditorContainer{display:flex;flex-direction:column;gap:.75rem}\n"] }]
22102
22356
  }], ctorParameters: () => [], propDecorators: { service: [{
22103
22357
  type: Input
22104
22358
  }], vcRef: [{
@@ -22125,6 +22379,13 @@ class SearchPageComponent extends SmartComponent {
22125
22379
  /** Written from `dataChanged`, so a signal. */
22126
22380
  this.layoutState = signal(undefined, /* @ts-ignore */
22127
22381
  ...(ngDevMode ? [{ debugName: "layoutState" }] : /* istanbul ignore next */ []));
22382
+ /**
22383
+ * The page's own layout, handed to the grid so that the row layouts of a card grid never
22384
+ * look like the root of an embedded-view tree (#28870). A signal query: the template binds
22385
+ * it, and the layout is only rendered once the model arrives.
22386
+ */
22387
+ this.layoutComponent = viewChild(SmartComponentLayoutComponent, /* @ts-ignore */
22388
+ ...(ngDevMode ? [{ debugName: "layoutComponent" }] : /* istanbul ignore next */ []));
22128
22389
  this.setupGrid();
22129
22390
  this.sendModelOnWidgetAction = true;
22130
22391
  // uuid is set in onUuidResolved — it is not known at construction for
@@ -22164,17 +22425,19 @@ class SearchPageComponent extends SmartComponent {
22164
22425
  options: {
22165
22426
  rowUiActionType: GridUiActionType.POPUP_MENU,
22166
22427
  },
22428
+ // Card grids render the row's own layout with this class (see SmartGridCardComponent).
22429
+ layoutComponent: SmartComponentLayoutComponent,
22167
22430
  };
22168
22431
  }
22169
22432
  isShowNoResultText() {
22170
22433
  return this.data?.noResultText !== undefined && this.data?.noResultText !== null;
22171
22434
  }
22172
22435
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SearchPageComponent, deps: [{ token: i0.Injector }, { token: SmartFilterEditorService }, { token: SMART_SEARCH_PAGE_NAME }, { token: SMART_SEARCH_COMPONENT_NAME }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
22173
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SearchPageComponent, isStandalone: true, selector: "search-page", providers: [SmartFilterEditorService], viewQueries: [{ propertyName: "grid", first: true, predicate: ["grid"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"searchPageContainer\" [ngClass]=\"$safeNavigationMigration(data?.cssClassOfPage)\">\n <h1 class=\"search-page-title\"> {{ data?.pageTitle }} </h1>\n <!-- <div class=\"filterContainer\">\n <smart-filter [filter]=\"filter\"></smart-filter>\n</div> -->\n<smart-ui-action-toolbar [uiActionModels]=\"uiActionModels\"></smart-ui-action-toolbar>\n@if (filterService.model) {\n <div class=\"filter-editor-container\">\n <smart-filter-group-params [service]=\"filterService\"></smart-filter-group-params>\n <smart-filter-expression-editor [service]=\"filterService\"></smart-filter-expression-editor>\n </div>\n}\n@if (layout) {\n <smart-component-layout\n [smartComponentLayout]=\"layout\"\n ></smart-component-layout>\n}\n<div class=\"gridContainer\">\n @if (isShowNoResultText()) {\n <h2 class=\"noResultText\">\n {{ data?.noResultText }}\n </h2>\n }\n @if (!isShowNoResultText()) {\n <smart-grid\n #grid\n [smartGrid]=\"smartGrid\"\n [uuid]=\"uuid!\"\n ></smart-grid>\n }\n</div>\n</div>\n", styles: [".searchPageContainer{display:flex;flex-direction:column;gap:1.5rem}.filterContainer{display:flex;flex-direction:row;gap:1rem}.gridContainer{flex-grow:1}.filter-editor-container{display:flex;flex-direction:row}.noResultText{width:100%;text-align:center;padding-top:2rem;padding-bottom:2rem}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: UiActionToolbarComponent, selector: "smart-ui-action-toolbar", inputs: ["uiActionModels", "uiActionDescriptorService", "id", "executor", "widgetId", "nodeId", "actionParams", "scrollOnWrap", "toolbarPropertes"] }, { kind: "component", type: SmartFilterParamsComponent, selector: "smart-filter-group-params", inputs: ["service"] }, { kind: "component", type: SmartFilterEditorContentComponent, selector: "smart-filter-expression-editor", inputs: ["service"] }, { kind: "component", type: SmartComponentLayoutComponent, selector: "smart-component-layout", inputs: ["smartComponentLayout", "parentLayoutComponent", "gridRow"] }, { kind: "component", type: SmartGridComponent, selector: "smart-grid", inputs: ["smartGrid", "uuid", "parentLayoutComponent", "dev"] }] }); }
22436
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: SearchPageComponent, isStandalone: true, selector: "search-page", providers: [SmartFilterEditorService], viewQueries: [{ propertyName: "layoutComponent", first: true, predicate: SmartComponentLayoutComponent, descendants: true, isSignal: true }, { propertyName: "grid", first: true, predicate: ["grid"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"searchPageContainer\" [ngClass]=\"$safeNavigationMigration(data?.cssClassOfPage)\">\n @if (data?.showTitle) {\n <h1 class=\"search-page-title\"> {{ data?.pageTitle }} </h1>\n }\n <!-- <div class=\"filterContainer\">\n <smart-filter [filter]=\"filter\"></smart-filter>\n</div> -->\n@if (data?.showToolbar) {\n <smart-ui-action-toolbar [uiActionModels]=\"uiActionModels\"></smart-ui-action-toolbar>\n}\n@if (data?.showFilter && filterService.model) {\n <div class=\"filter-editor-container\">\n <smart-filter-group-params [service]=\"filterService\"></smart-filter-group-params>\n <smart-filter-expression-editor [service]=\"filterService\"></smart-filter-expression-editor>\n </div>\n}\n@if (data?.showLayout && layout) {\n <smart-component-layout\n [smartComponentLayout]=\"layout\"\n ></smart-component-layout>\n}\n@if (data?.showGrid) {\n <div class=\"gridContainer\">\n @if (isShowNoResultText()) {\n <h2 class=\"noResultText\">\n {{ data?.noResultText }}\n </h2>\n }\n @if (!isShowNoResultText()) {\n <smart-grid\n #grid\n [smartGrid]=\"smartGrid\"\n [uuid]=\"uuid!\"\n [parentLayoutComponent]=\"layoutComponent()\"\n ></smart-grid>\n }\n </div>\n}\n</div>\n", styles: [".searchPageContainer{display:flex;flex-direction:column;gap:1.5rem}.filterContainer{display:flex;flex-direction:row;gap:1rem}.gridContainer{flex-grow:1}.filter-editor-container{display:flex;flex-direction:row}.noResultText{width:100%;text-align:center;padding-top:2rem;padding-bottom:2rem}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: UiActionToolbarComponent, selector: "smart-ui-action-toolbar", inputs: ["uiActionModels", "uiActionDescriptorService", "id", "executor", "widgetId", "nodeId", "actionParams", "scrollOnWrap", "toolbarPropertes"] }, { kind: "component", type: SmartFilterParamsComponent, selector: "smart-filter-group-params", inputs: ["service"] }, { kind: "component", type: SmartFilterEditorContentComponent, selector: "smart-filter-expression-editor", inputs: ["service"] }, { kind: "component", type: SmartComponentLayoutComponent, selector: "smart-component-layout", inputs: ["smartComponentLayout", "parentLayoutComponent", "gridRow"] }, { kind: "component", type: SmartGridComponent, selector: "smart-grid", inputs: ["smartGrid", "uuid", "parentLayoutComponent", "dev"] }] }); }
22174
22437
  }
22175
22438
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SearchPageComponent, decorators: [{
22176
22439
  type: Component,
22177
- args: [{ selector: 'search-page', providers: [SmartFilterEditorService], imports: [NgClass, UiActionToolbarComponent, SmartFilterParamsComponent, SmartFilterEditorContentComponent, SmartComponentLayoutComponent, SmartGridComponent], template: "<div class=\"searchPageContainer\" [ngClass]=\"$safeNavigationMigration(data?.cssClassOfPage)\">\n <h1 class=\"search-page-title\"> {{ data?.pageTitle }} </h1>\n <!-- <div class=\"filterContainer\">\n <smart-filter [filter]=\"filter\"></smart-filter>\n</div> -->\n<smart-ui-action-toolbar [uiActionModels]=\"uiActionModels\"></smart-ui-action-toolbar>\n@if (filterService.model) {\n <div class=\"filter-editor-container\">\n <smart-filter-group-params [service]=\"filterService\"></smart-filter-group-params>\n <smart-filter-expression-editor [service]=\"filterService\"></smart-filter-expression-editor>\n </div>\n}\n@if (layout) {\n <smart-component-layout\n [smartComponentLayout]=\"layout\"\n ></smart-component-layout>\n}\n<div class=\"gridContainer\">\n @if (isShowNoResultText()) {\n <h2 class=\"noResultText\">\n {{ data?.noResultText }}\n </h2>\n }\n @if (!isShowNoResultText()) {\n <smart-grid\n #grid\n [smartGrid]=\"smartGrid\"\n [uuid]=\"uuid!\"\n ></smart-grid>\n }\n</div>\n</div>\n", styles: [".searchPageContainer{display:flex;flex-direction:column;gap:1.5rem}.filterContainer{display:flex;flex-direction:row;gap:1rem}.gridContainer{flex-grow:1}.filter-editor-container{display:flex;flex-direction:row}.noResultText{width:100%;text-align:center;padding-top:2rem;padding-bottom:2rem}\n"] }]
22440
+ args: [{ selector: 'search-page', providers: [SmartFilterEditorService], imports: [NgClass, UiActionToolbarComponent, SmartFilterParamsComponent, SmartFilterEditorContentComponent, SmartComponentLayoutComponent, SmartGridComponent], template: "<div class=\"searchPageContainer\" [ngClass]=\"$safeNavigationMigration(data?.cssClassOfPage)\">\n @if (data?.showTitle) {\n <h1 class=\"search-page-title\"> {{ data?.pageTitle }} </h1>\n }\n <!-- <div class=\"filterContainer\">\n <smart-filter [filter]=\"filter\"></smart-filter>\n</div> -->\n@if (data?.showToolbar) {\n <smart-ui-action-toolbar [uiActionModels]=\"uiActionModels\"></smart-ui-action-toolbar>\n}\n@if (data?.showFilter && filterService.model) {\n <div class=\"filter-editor-container\">\n <smart-filter-group-params [service]=\"filterService\"></smart-filter-group-params>\n <smart-filter-expression-editor [service]=\"filterService\"></smart-filter-expression-editor>\n </div>\n}\n@if (data?.showLayout && layout) {\n <smart-component-layout\n [smartComponentLayout]=\"layout\"\n ></smart-component-layout>\n}\n@if (data?.showGrid) {\n <div class=\"gridContainer\">\n @if (isShowNoResultText()) {\n <h2 class=\"noResultText\">\n {{ data?.noResultText }}\n </h2>\n }\n @if (!isShowNoResultText()) {\n <smart-grid\n #grid\n [smartGrid]=\"smartGrid\"\n [uuid]=\"uuid!\"\n [parentLayoutComponent]=\"layoutComponent()\"\n ></smart-grid>\n }\n </div>\n}\n</div>\n", styles: [".searchPageContainer{display:flex;flex-direction:column;gap:1.5rem}.filterContainer{display:flex;flex-direction:row;gap:1rem}.gridContainer{flex-grow:1}.filter-editor-container{display:flex;flex-direction:row}.noResultText{width:100%;text-align:center;padding-top:2rem;padding-bottom:2rem}\n"] }]
22178
22441
  }], ctorParameters: () => [{ type: i0.Injector }, { type: SmartFilterEditorService }, { type: undefined, decorators: [{
22179
22442
  type: Inject,
22180
22443
  args: [SMART_SEARCH_PAGE_NAME]
@@ -22184,7 +22447,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
22184
22447
  }] }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { grid: [{
22185
22448
  type: ViewChild,
22186
22449
  args: ['grid']
22187
- }] } });
22450
+ }], layoutComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SmartComponentLayoutComponent), { isSignal: true }] }] } });
22188
22451
 
22189
22452
  class UiActionFileUploadDialogComponent {
22190
22453
  constructor() {
@@ -23129,5 +23392,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
23129
23392
  * Generated bundle index. Do not edit.
23130
23393
  */
23131
23394
 
23132
- export { ACLEntry, APIS$5 as APIS, AclEditingViewComponent, ApiQueueService, BASE_PATH$7 as BASE_PATH, COLLECTION_FORMATS$7 as COLLECTION_FORMATS, CUSTOM_DIAGRAM_OPTIONS, CloseResult, ComponentFactoryService, ComponentType, ComponentWidgetType, Configuration$7 as Configuration, DIALOG_DISABLE_CLOSE, DataChangeKind, DefaultChartOptionsProvider, DefaultUiActionCode_CLOSE, DrawTime, EMPTY_PARAMS, ExpandableSectionButtonIconPosition, ExpandableSectionButtonType, ExpandableSectionComponent, FilterExpressionBoolOperator$1 as FilterExpressionBoolOperator, FilterExpressionBuilderGroupBuilderGroupKindEnum, FilterExpressionBuilderUiModelTypeEnum, FilterExpressionDataType, FilterExpressionFieldWidgetType, FilterExpressionOperation, FilterExpressionOrderByOrderEnum, GenericPageComponent, GeoMapDataLoadingMode, GeoMapDataSourceType, GeoMapItemKind, GeoMapOperationMode, GeoMapSelectionMode, GeoMapTextType, GridColumnContentType, GridDataAccessConfigKindEnum, GridSelectionMode, GridSelectionType, GridUiActionType, GridViewDescriptorKindEnum, HighlightPipe, IS_ASYNC_PARAM_NAME, IconPosition, ImageResourceKindEnum, InvalidSmartlinkComponent, LayoutDirection, LinkTargetEnum, MAP_ENGINE, MapEngine, MenuOpenDirection, MenuTriggerType, MessageOptionType, MessageTextType, MessageType, NAMED_VALIDATOR, NamedValidatorOperationEnum, NamedValidatorService, NoPermissionPageComponent, REUSE_ROUTER_SLOT_COMPONENT, ROOT_CONTAINER_UUID, ROUTER_SLOT_ID, RecordingUploaderPropertiesOpenDirectionEnum, SMART_DATE_FORMATS, SMART_DEFAULT_VIEW_COMPONENTS, SMART_NG_CLIENT_CONFIG, SearchPageComponent, SelectionDefinitionTypeEnum, SelectionDefinitionValueSetValueTypeEnum, ServerRequestType, SessionAPIS, SessionErrorBehaviour, SessionService, SmartActionHost, SmartActionType, SmartBackendBootstrapService, SmartComponent, SmartComponentApiClient, SmartComponentDetachedDirective, SmartComponentHost, SmartComponentLayoutComponent, SmartDateFnsAdapter, SmartDatePipe, SmartDateTimePipe, SmartDefaultErrorUiService, SmartDiagramComponent, SmartDialog, SmartEmbeddedSlotDirective, SmartExpandableSectionService, SmartFileEditorComponent, SmartFilterComponent, SmartFilterEditorContentComponent, SmartFilterEditorService, SmartFilterExpressionFieldComponent, SmartFilterPosition, SmartFilterType, SmartFormInputMode, SmartFormTextFieldButtonIconPosition, SmartFormWidgetDirection, SmartFormWidgetType, SmartFormWidgetWidth, SmartGridButtonType, SmartGridComponent, SmartGridDataLayout, SmartGridService, SmartGridType, SmartIconComponent, SmartIconService, SmartLayoutDef, SmartLinkChannelVariableInPath, SmartLinkMigrationStatusStatusEnum, SmartLinkUuidVariableInPath, SmartMapComponent, SmartMultiFileEditorComponent, SmartNavbarComponent, SmartNavbarService, SmartNavigationService, SmartNgClientFeatureKind, SmartService, SmartSessionService, SmartSessionTimerComponent, SmartTable, SmartTableButtonType, SmartTableHeaderPropertyType, SmartTableInterfaceTypeEnum, SmartTableOptionButtonDirection, SmartTableOrder, SmartTableType, SmartTimePipe, SmartTooltipDirective, SmartTreeComponent, SmartTreeNodeButtonType, SmartUserSettinsIconPosition, SmartValidatorName, SmartViewContextService, SmartViewRedirect, SmartVoiceRecorderComponent, SmartWidgetHintPosition, SmartWidgetHintPositionEnum, SmartdialogService, SmartfileuploaderComponent, SmartformComponent, SmartformLayoutDefinitionService, SmarttreeGenericService, SmarttreeService, SubjectSelectorComponent, ThemeService, ToggleLabelPosition, ToolbarAlignment, ToolbarDirection, TreeArrowPosition, UiActionButtonComponent, UiActionButtonType, UiActionConfirmDialogService, UiActionDescriptorService, UiActionDialogButtonComponent, UiActionDialogType, UiActionFeedbackType, UiActionInputDialogService, UiActionInputType, UiActionService, UiActionToolbarComponent, UiActionTooltipTooltipPositionEnum, UiBadgeComponent, UiBadgeDirective, UploadWidgetType, ValidationResultPageComponent, ValueChangeMode, ViewContextRebuiltError, ViewEventHandlerViewEventTypeEnum, ViewService, ViewState, ViewType, barChart, bubbleChart, createBasicOptions, doughnutChart, horizontalBarChart, horizontalStackedBarChart, injectSmartComponent, multiAxisLineChart, pieChart, polarAreaChart, provideSmartNgClient, radarChart, registerSmartWidget, resolveDateLocale, resolveSlot, resolveSmartNgClientConfig, resolveViewHandler, scatterChart, stackedBarChart, transformDataToBarLikeDataSet, transformDataToBasicDataSets, transformDataToBubble, transformDataToScatter, withSmartDiagram, withSmartMap };
23395
+ export { ACLEntry, APIS$5 as APIS, AclEditingViewComponent, ApiQueueService, BASE_PATH$7 as BASE_PATH, COLLECTION_FORMATS$7 as COLLECTION_FORMATS, CUSTOM_DIAGRAM_OPTIONS, CloseResult, ComponentFactoryService, ComponentType, ComponentWidgetType, Configuration$7 as Configuration, DIALOG_DISABLE_CLOSE, DataChangeKind, DefaultChartOptionsProvider, DefaultUiActionCode_CLOSE, DrawTime, EMPTY_PARAMS, ExpandableSectionButtonIconPosition, ExpandableSectionButtonType, ExpandableSectionComponent, FilterExpressionBoolOperator$1 as FilterExpressionBoolOperator, FilterExpressionBuilderGroupBuilderGroupKindEnum, FilterExpressionBuilderUiModelTypeEnum, FilterExpressionDataType, FilterExpressionFieldWidgetType, FilterExpressionOperation, FilterExpressionOrderByOrderEnum, GenericPageComponent, GeoMapDataLoadingMode, GeoMapDataSourceType, GeoMapItemKind, GeoMapOperationMode, GeoMapSelectionMode, GeoMapTextType, GridColumnContentType, GridDataAccessConfigKindEnum, GridSelectionMode, GridSelectionType, GridUiActionType, GridViewDescriptorKindEnum, HighlightPipe, IS_ASYNC_PARAM_NAME, IconPosition, ImageResourceKindEnum, InvalidSmartlinkComponent, LayoutDirection, LinkTargetEnum, MAP_ENGINE, MapEngine, MenuOpenDirection, MenuTriggerType, MessageOptionType, MessageTextType, MessageType, NAMED_VALIDATOR, NamedValidatorOperationEnum, NamedValidatorService, NoPermissionPageComponent, REUSE_ROUTER_SLOT_COMPONENT, ROOT_CONTAINER_UUID, ROUTER_SLOT_ID, RecordingUploaderPropertiesOpenDirectionEnum, SMART_DATE_FORMATS, SMART_DEFAULT_VIEW_COMPONENTS, SMART_NG_CLIENT_CONFIG, SearchPageComponent, SelectionDefinitionTypeEnum, SelectionDefinitionValueSetValueTypeEnum, ServerRequestType, SessionAPIS, SessionErrorBehaviour, SessionService, SmartActionHost, SmartActionType, SmartBackendBootstrapService, SmartComponent, SmartComponentApiClient, SmartComponentDetachedDirective, SmartComponentHost, SmartComponentLayoutComponent, SmartDateFnsAdapter, SmartDatePipe, SmartDateTimePipe, SmartDefaultErrorUiService, SmartDiagramComponent, SmartDialog, SmartEmbeddedSlotDirective, SmartExpandableSectionService, SmartFileEditorComponent, SmartFilterComponent, SmartFilterEditorContentComponent, SmartFilterEditorService, SmartFilterExpressionFieldComponent, SmartFilterPosition, SmartFilterType, SmartFormInputMode, SmartFormTextFieldButtonIconPosition, SmartFormWidgetDirection, SmartFormWidgetType, SmartFormWidgetWidth, SmartGridButtonType, SmartGridComponent, SmartGridDataLayout, SmartGridService, SmartGridType, SmartIconComponent, SmartIconService, SmartLayoutDef, SmartLinkChannelVariableInPath, SmartLinkMigrationStatusStatusEnum, SmartLinkUuidVariableInPath, SmartMapComponent, SmartMultiFileEditorComponent, SmartNavbarComponent, SmartNavbarService, SmartNavigationService, SmartNgClientFeatureKind, SmartService, SmartSessionService, SmartSessionTimerComponent, SmartTable, SmartTableButtonType, SmartTableHeaderPropertyType, SmartTableInterfaceTypeEnum, SmartTableOptionButtonDirection, SmartTableOrder, SmartTableType, SmartTimePipe, SmartTooltipDirective, SmartTreeComponent, SmartTreeNodeButtonType, SmartUserSettinsIconPosition, SmartValidatorName, SmartViewContextService, SmartViewRedirect, SmartVoiceRecorderComponent, SmartWidgetHintPosition, SmartWidgetHintPositionEnum, SmartdialogService, SmartfileuploaderComponent, SmartformComponent, SmartformLayoutDefinitionService, SmarttreeGenericService, SmarttreeService, SubjectSelectorComponent, ThemeService, ToggleLabelPosition, ToolbarAlignment, ToolbarDirection, TreeArrowPosition, USE_ADVANCED_FILTER, UiActionButtonComponent, UiActionButtonType, UiActionConfirmDialogService, UiActionDescriptorService, UiActionDialogButtonComponent, UiActionDialogType, UiActionFeedbackType, UiActionInputDialogService, UiActionInputType, UiActionService, UiActionToolbarComponent, UiActionTooltipTooltipPositionEnum, UiBadgeComponent, UiBadgeDirective, UploadWidgetType, ValidationResultPageComponent, ValueChangeMode, ViewContextRebuiltError, ViewEventHandlerViewEventTypeEnum, ViewService, ViewState, ViewType, barChart, bubbleChart, createBasicOptions, doughnutChart, horizontalBarChart, horizontalStackedBarChart, injectSmartComponent, multiAxisLineChart, pieChart, polarAreaChart, provideSmartNgClient, radarChart, registerSmartWidget, resolveDateLocale, resolveSlot, resolveSmartNgClientConfig, resolveViewHandler, scatterChart, stackedBarChart, transformDataToBarLikeDataSet, transformDataToBasicDataSets, transformDataToBubble, transformDataToScatter, withSmartDiagram, withSmartMap };
23133
23396
  //# sourceMappingURL=smartbit4all-ng-client.mjs.map