wuic-framework-lib 0.1.0 → 0.3.1

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.
@@ -5,7 +5,7 @@ import { SplitterModule } from 'primeng/splitter';
5
5
  import * as i11 from 'primeng/dragdrop';
6
6
  import { DragDropModule } from 'primeng/dragdrop';
7
7
  import { NgClass, NgStyle, NgTemplateOutlet, AsyncPipe, JsonPipe, NgFor, NgIf, NgComponentOutlet } from '@angular/common';
8
- import { W as WtoolboxService, D as DynamicGenericTemplateComponent, a as DataSourceComponent, b as DataRepeaterComponent, F as FilterBarComponent, L as LazyParametricDialogComponent, P as PagerComponent, M as MetadataProviderService, c as ParametricDialogComponent, d as MetadatiColonna, e as DataProviderService, U as UserInfoService, T as TranslationManagerService, f as MetadataEditorService, g as WorkflowRuntimeMetadataService, h as FieldEditorComponent, i as MetadataEditorComponent, A as ArchetypeConfiguratorComponent, C as CallbackPipe } from './wuic-framework-lib-wuic-framework-lib-CXpwV2Dc.mjs';
8
+ import { W as WtoolboxService, D as DynamicGenericTemplateComponent, a as DataSourceComponent, b as DataRepeaterComponent, F as FilterBarComponent, L as LazyParametricDialogComponent, P as PagerComponent, M as MetadataProviderService, c as ParametricDialogComponent, d as MetadatiColonna, e as DataProviderService, U as UserInfoService, T as TranslationManagerService, f as MetadataEditorService, g as WorkflowRuntimeMetadataService, h as FieldEditorComponent, i as MetadataEditorComponent, A as ArchetypeConfiguratorComponent } from './wuic-framework-lib-wuic-framework-lib-CpocrbwM.mjs';
9
9
  import { fromEvent, BehaviorSubject, merge, filter, Observable, switchMap, take, map, takeUntil, tap, timeInterval, scan, mergeMap, of, delay, repeat, Subject, startWith, pairwise, skipWhile, combineLatest } from 'rxjs';
10
10
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
11
  import { CdkAccordionModule, CdkAccordion, CdkAccordionItem } from '@angular/cdk/accordion';
@@ -52,10 +52,10 @@ class PropConverterPipe {
52
52
  }
53
53
  return null;
54
54
  }
55
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropConverterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
56
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.5", ngImport: i0, type: PropConverterPipe, isStandalone: true, name: "propConverter" });
55
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropConverterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
56
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.8", ngImport: i0, type: PropConverterPipe, isStandalone: true, name: "propConverter" });
57
57
  }
58
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropConverterPipe, decorators: [{
58
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropConverterPipe, decorators: [{
59
59
  type: Pipe,
60
60
  args: [{
61
61
  name: 'propConverter',
@@ -1226,10 +1226,10 @@ class NgxDraggableDomDirective {
1226
1226
  // return the bounds checking for this original pass
1227
1227
  return new NgxDraggableDomBoundsCheckEvent(isTopEdgeCollided, isRightEdgeCollided, isBottomEdgeCollided, isLeftEdgeCollided, constrainedElP0, translation, displaceX !== undefined || displaceY !== undefined);
1228
1228
  }
1229
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: NgxDraggableDomDirective, deps: [{ token: ElementRef }, { token: Renderer2 }, { token: ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
1230
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: NgxDraggableDomDirective, isStandalone: true, selector: "[ngxDraggableDom]", inputs: { bounds: "bounds", constrainByBounds: "constrainByBounds", handle: "handle", requireMouseOver: "requireMouseOver", requireMouseOverBounds: "requireMouseOverBounds", ignoreMultiTouchEvents: "ignoreMultiTouchEvents", ngxDraggableDom: "ngxDraggableDom" }, outputs: { started: "started", stopped: "stopped", moved: "moved", edge: "edge" }, host: { listeners: { "mousedown": "onMouseDown($event)", "mouseleave": "onMouseLeave($event)", "touchstart": "onTouchStart($event)" } }, ngImport: i0 });
1229
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgxDraggableDomDirective, deps: [{ token: ElementRef }, { token: Renderer2 }, { token: ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
1230
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: NgxDraggableDomDirective, isStandalone: true, selector: "[ngxDraggableDom]", inputs: { bounds: "bounds", constrainByBounds: "constrainByBounds", handle: "handle", requireMouseOver: "requireMouseOver", requireMouseOverBounds: "requireMouseOverBounds", ignoreMultiTouchEvents: "ignoreMultiTouchEvents", ngxDraggableDom: "ngxDraggableDom" }, outputs: { started: "started", stopped: "stopped", moved: "moved", edge: "edge" }, host: { listeners: { "mousedown": "onMouseDown($event)", "mouseleave": "onMouseLeave($event)", "touchstart": "onTouchStart($event)" } }, ngImport: i0 });
1231
1231
  }
1232
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: NgxDraggableDomDirective, decorators: [{
1232
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgxDraggableDomDirective, decorators: [{
1233
1233
  type: Directive,
1234
1234
  args: [{
1235
1235
  selector: '[ngxDraggableDom]',
@@ -2049,10 +2049,10 @@ class AngularResizableDirective {
2049
2049
  }
2050
2050
  }
2051
2051
  }
2052
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AngularResizableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
2053
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: AngularResizableDirective, isStandalone: true, selector: "[ngResizable]", inputs: { ngResizable: "ngResizable", rzHandles: "rzHandles", rzHandleDoms: "rzHandleDoms", rzAspectRatio: "rzAspectRatio", rzContainment: "rzContainment", rzGrid: "rzGrid", rzMinWidth: "rzMinWidth", rzMinHeight: "rzMinHeight", rzMaxWidth: "rzMaxWidth", rzMaxHeight: "rzMaxHeight", rzScale: "rzScale", preventDefaultEvent: "preventDefaultEvent" }, outputs: { rzStart: "rzStart", rzResizing: "rzResizing", rzStop: "rzStop" }, usesOnChanges: true, ngImport: i0 });
2052
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AngularResizableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
2053
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: AngularResizableDirective, isStandalone: true, selector: "[ngResizable]", inputs: { ngResizable: "ngResizable", rzHandles: "rzHandles", rzHandleDoms: "rzHandleDoms", rzAspectRatio: "rzAspectRatio", rzContainment: "rzContainment", rzGrid: "rzGrid", rzMinWidth: "rzMinWidth", rzMinHeight: "rzMinHeight", rzMaxWidth: "rzMaxWidth", rzMaxHeight: "rzMaxHeight", rzScale: "rzScale", preventDefaultEvent: "preventDefaultEvent" }, outputs: { rzStart: "rzStart", rzResizing: "rzResizing", rzStop: "rzStop" }, usesOnChanges: true, ngImport: i0 });
2054
2054
  }
2055
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AngularResizableDirective, decorators: [{
2055
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AngularResizableDirective, decorators: [{
2056
2056
  type: Directive,
2057
2057
  args: [{
2058
2058
  selector: '[ngResizable]',
@@ -2138,10 +2138,10 @@ class DataBoundDirective {
2138
2138
  this.cd.detectChanges();
2139
2139
  }
2140
2140
  }
2141
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DataBoundDirective, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
2142
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: DataBoundDirective, isStandalone: true, selector: "[databound]", inputs: { databound: "databound", bindingFunction: "bindingFunction", clickCallback: "clickCallback", itemTemplate: "itemTemplate", inputs: "inputs" }, usesOnChanges: true, ngImport: i0 });
2141
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DataBoundDirective, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
2142
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: DataBoundDirective, isStandalone: true, selector: "[databound]", inputs: { databound: "databound", bindingFunction: "bindingFunction", clickCallback: "clickCallback", itemTemplate: "itemTemplate", inputs: "inputs" }, usesOnChanges: true, ngImport: i0 });
2143
2143
  }
2144
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DataBoundDirective, decorators: [{
2144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DataBoundDirective, decorators: [{
2145
2145
  type: Directive,
2146
2146
  args: [{
2147
2147
  selector: '[databound]',
@@ -2164,10 +2164,10 @@ class TabPanelWrapperComponent {
2164
2164
  * Input dal componente padre per selected; usata nella configurazione e nel rendering del componente.
2165
2165
  */
2166
2166
  selected;
2167
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TabPanelWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2168
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: TabPanelWrapperComponent, isStandalone: true, selector: "p-tabPanel", inputs: { selected: "selected" }, providers: [], ngImport: i0, template: "<div role=\"tabpanel\" class=\"p-tabview-panel\" [attr.aria-hidden]=\"!selected\" data-pc-name=\"tabpanel\"\r\n [hidden]=\"!selected\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".p-tabview-panel{height:100%;width:100%}\n"] });
2167
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TabPanelWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2168
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: TabPanelWrapperComponent, isStandalone: true, selector: "p-tabPanel", inputs: { selected: "selected" }, providers: [], ngImport: i0, template: "<div role=\"tabpanel\" class=\"p-tabview-panel\" [attr.aria-hidden]=\"!selected\" data-pc-name=\"tabpanel\"\r\n [hidden]=\"!selected\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".p-tabview-panel{height:100%;width:100%}\n"] });
2169
2169
  }
2170
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TabPanelWrapperComponent, decorators: [{
2170
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TabPanelWrapperComponent, decorators: [{
2171
2171
  type: Component,
2172
2172
  args: [{ selector: 'p-tabPanel', imports: [], providers: [], template: "<div role=\"tabpanel\" class=\"p-tabview-panel\" [attr.aria-hidden]=\"!selected\" data-pc-name=\"tabpanel\"\r\n [hidden]=\"!selected\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".p-tabview-panel{height:100%;width:100%}\n"] }]
2173
2173
  }], propDecorators: { selected: [{
@@ -2198,10 +2198,10 @@ class TabViewWrapperComponent {
2198
2198
  }
2199
2199
  });
2200
2200
  }
2201
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TabViewWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2202
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: TabViewWrapperComponent, isStandalone: true, selector: "p-tabView", inputs: { tabs: "tabs", activeIndex: "activeIndex" }, ngImport: i0, template: "<div data-pc-name=\"tabview\" class=\"p-tabview p-component\">\n <div class=\"p-tabview-nav-container\">\n <div class=\"p-tabview-nav-content\" data-pc-section=\"navcontent\">\n <ul role=\"tablist\" class=\"p-tabview-nav\" data-pc-section=\"nav\">\n @for (tab of tabs; track tab; let i = $index) {\n <li role=\"presentation\" data-p-disabled=\"false\"\n [ngClass]=\"{'p-highlight': activeIndex == i}\">\n <a role=\"tab\" pripple=\"\" class=\"p-element p-ripple p-tabview-nav-link\" (click)=\"setIndex(i)\"\n [attr.aria-selected]=\"activeIndex == i\" [attr.tabindex]=\"i\" aria-disabled=\"false\"\n [attr.data-pc-index]=\"i\" data-pc-section=\"headeraction\">\n <span class=\"p-tabview-title\">\n {{tab.inputs.header}}\n </span>\n </a>\n </li>\n }\n </ul>\n </div>\n </div>\n <div class=\"p-tabview-panels\">\n <ng-content></ng-content>\n </div>\n</div>", styles: [".p-tabview.p-component{height:100%}.p-tabview .p-tabview-nav-content{scroll-padding-inline:3rem}.p-tabview-nav-content{overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scrollbar-width:none;overscroll-behavior:contain auto}.p-tabview-nav{display:inline-flex;min-width:100%;margin:0;padding:0;list-style-type:none;flex:1 1 auto}.p-tabview .p-tabview-nav li .p-tabview-nav-link{border-width:0 0 2px 0;padding:1.25rem;font-weight:700;border-top-right-radius:6px;border-top-left-radius:6px;transition:box-shadow .2s;margin:0 0 -2px}.p-tabview-nav-link{cursor:pointer;-webkit-user-select:none;user-select:none;display:flex;align-items:center;position:relative;text-decoration:none;overflow:hidden}.p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link{border-color:#3b82f6;color:#3b82f6;background-color:transparent}.p-tabview-panels{height:calc(100% - 60px);overflow:auto}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
2201
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TabViewWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2202
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TabViewWrapperComponent, isStandalone: true, selector: "p-tabView", inputs: { tabs: "tabs", activeIndex: "activeIndex" }, ngImport: i0, template: "<div data-pc-name=\"tabview\" class=\"p-tabview p-component\">\n <div class=\"p-tabview-nav-container\">\n <div class=\"p-tabview-nav-content\" data-pc-section=\"navcontent\">\n <ul role=\"tablist\" class=\"p-tabview-nav\" data-pc-section=\"nav\">\n @for (tab of tabs; track tab; let i = $index) {\n <li role=\"presentation\" data-p-disabled=\"false\"\n [ngClass]=\"{'p-highlight': activeIndex == i}\">\n <a role=\"tab\" pripple=\"\" class=\"p-element p-ripple p-tabview-nav-link\" (click)=\"setIndex(i)\"\n [attr.aria-selected]=\"activeIndex == i\" [attr.tabindex]=\"i\" aria-disabled=\"false\"\n [attr.data-pc-index]=\"i\" data-pc-section=\"headeraction\">\n <span class=\"p-tabview-title\">\n {{tab.inputs.header}}\n </span>\n </a>\n </li>\n }\n </ul>\n </div>\n </div>\n <div class=\"p-tabview-panels\">\n <ng-content></ng-content>\n </div>\n</div>", styles: [".p-tabview.p-component{height:100%}.p-tabview .p-tabview-nav-content{scroll-padding-inline:3rem}.p-tabview-nav-content{overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scrollbar-width:none;overscroll-behavior:contain auto}.p-tabview-nav{display:inline-flex;min-width:100%;margin:0;padding:0;list-style-type:none;flex:1 1 auto}.p-tabview .p-tabview-nav li .p-tabview-nav-link{border-width:0 0 2px 0;padding:1.25rem;font-weight:700;border-top-right-radius:6px;border-top-left-radius:6px;transition:box-shadow .2s;margin:0 0 -2px}.p-tabview-nav-link{cursor:pointer;-webkit-user-select:none;user-select:none;display:flex;align-items:center;position:relative;text-decoration:none;overflow:hidden}.p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link{border-color:#3b82f6;color:#3b82f6;background-color:transparent}.p-tabview-panels{height:calc(100% - 60px);overflow:auto}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
2203
2203
  }
2204
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TabViewWrapperComponent, decorators: [{
2204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TabViewWrapperComponent, decorators: [{
2205
2205
  type: Component,
2206
2206
  args: [{ selector: 'p-tabView', imports: [NgClass], template: "<div data-pc-name=\"tabview\" class=\"p-tabview p-component\">\n <div class=\"p-tabview-nav-container\">\n <div class=\"p-tabview-nav-content\" data-pc-section=\"navcontent\">\n <ul role=\"tablist\" class=\"p-tabview-nav\" data-pc-section=\"nav\">\n @for (tab of tabs; track tab; let i = $index) {\n <li role=\"presentation\" data-p-disabled=\"false\"\n [ngClass]=\"{'p-highlight': activeIndex == i}\">\n <a role=\"tab\" pripple=\"\" class=\"p-element p-ripple p-tabview-nav-link\" (click)=\"setIndex(i)\"\n [attr.aria-selected]=\"activeIndex == i\" [attr.tabindex]=\"i\" aria-disabled=\"false\"\n [attr.data-pc-index]=\"i\" data-pc-section=\"headeraction\">\n <span class=\"p-tabview-title\">\n {{tab.inputs.header}}\n </span>\n </a>\n </li>\n }\n </ul>\n </div>\n </div>\n <div class=\"p-tabview-panels\">\n <ng-content></ng-content>\n </div>\n</div>", styles: [".p-tabview.p-component{height:100%}.p-tabview .p-tabview-nav-content{scroll-padding-inline:3rem}.p-tabview-nav-content{overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scrollbar-width:none;overscroll-behavior:contain auto}.p-tabview-nav{display:inline-flex;min-width:100%;margin:0;padding:0;list-style-type:none;flex:1 1 auto}.p-tabview .p-tabview-nav li .p-tabview-nav-link{border-width:0 0 2px 0;padding:1.25rem;font-weight:700;border-top-right-radius:6px;border-top-left-radius:6px;transition:box-shadow .2s;margin:0 0 -2px}.p-tabview-nav-link{cursor:pointer;-webkit-user-select:none;user-select:none;display:flex;align-items:center;position:relative;text-decoration:none;overflow:hidden}.p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link{border-color:#3b82f6;color:#3b82f6;background-color:transparent}.p-tabview-panels{height:calc(100% - 60px);overflow:auto}\n"] }]
2207
2207
  }], propDecorators: { tabs: [{
@@ -2347,10 +2347,10 @@ class SplitCustomEventsBehaviorDirective {
2347
2347
  }
2348
2348
  });
2349
2349
  }
2350
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitCustomEventsBehaviorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2351
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SplitCustomEventsBehaviorDirective, isStandalone: true, selector: "[asSplitCustomEventsBehavior]", inputs: { multiClickThreshold: { classPropertyName: "multiClickThreshold", publicName: "asSplitCustomMultiClickThreshold", isSignal: true, isRequired: true, transformFunction: null }, deltaInPx: { classPropertyName: "deltaInPx", publicName: "asSplitCustomClickDeltaInPx", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { mouseDown: "asSplitCustomMouseDown", click: "asSplitCustomClick", dblClick: "asSplitCustomDblClick", keyDown: "asSplitCustomKeyDown" }, ngImport: i0 });
2350
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitCustomEventsBehaviorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2351
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: SplitCustomEventsBehaviorDirective, isStandalone: true, selector: "[asSplitCustomEventsBehavior]", inputs: { multiClickThreshold: { classPropertyName: "multiClickThreshold", publicName: "asSplitCustomMultiClickThreshold", isSignal: true, isRequired: true, transformFunction: null }, deltaInPx: { classPropertyName: "deltaInPx", publicName: "asSplitCustomClickDeltaInPx", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { mouseDown: "asSplitCustomMouseDown", click: "asSplitCustomClick", dblClick: "asSplitCustomDblClick", keyDown: "asSplitCustomKeyDown" }, ngImport: i0 });
2352
2352
  }
2353
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitCustomEventsBehaviorDirective, decorators: [{
2353
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitCustomEventsBehaviorDirective, decorators: [{
2354
2354
  type: Directive,
2355
2355
  args: [{
2356
2356
  selector: '[asSplitCustomEventsBehavior]',
@@ -2472,10 +2472,10 @@ class SplitGutterDirective {
2472
2472
  static ngTemplateContextGuard(dir, ctx) {
2473
2473
  return true;
2474
2474
  }
2475
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitGutterDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
2476
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: SplitGutterDirective, isStandalone: true, selector: "[asSplitGutter]", ngImport: i0 });
2475
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitGutterDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
2476
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: SplitGutterDirective, isStandalone: true, selector: "[asSplitGutter]", ngImport: i0 });
2477
2477
  }
2478
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitGutterDirective, decorators: [{
2478
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitGutterDirective, decorators: [{
2479
2479
  type: Directive,
2480
2480
  args: [{
2481
2481
  selector: '[asSplitGutter]',
@@ -2517,10 +2517,10 @@ class SplitGutterDynamicInjectorDirective {
2517
2517
  static ngTemplateContextGuard(dir, ctx) {
2518
2518
  return true;
2519
2519
  }
2520
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitGutterDynamicInjectorDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
2521
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: SplitGutterDynamicInjectorDirective, isStandalone: true, selector: "[asSplitGutterDynamicInjector]", inputs: { gutterNum: ["asSplitGutterDynamicInjector", "gutterNum"] }, ngImport: i0 });
2520
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitGutterDynamicInjectorDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
2521
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: SplitGutterDynamicInjectorDirective, isStandalone: true, selector: "[asSplitGutterDynamicInjector]", inputs: { gutterNum: ["asSplitGutterDynamicInjector", "gutterNum"] }, ngImport: i0 });
2522
2522
  }
2523
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitGutterDynamicInjectorDirective, decorators: [{
2523
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitGutterDynamicInjectorDirective, decorators: [{
2524
2524
  type: Directive,
2525
2525
  args: [{
2526
2526
  selector: '[asSplitGutterDynamicInjector]',
@@ -3114,10 +3114,10 @@ class SplitComponent {
3114
3114
  });
3115
3115
  this.dragProgressSubject.next(this.createDragInteractionEvent(this.draggedGutterIndex()));
3116
3116
  }
3117
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3118
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: SplitComponent, isStandalone: true, selector: "p-splitter", inputs: { gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null }, gutterStep: { classPropertyName: "gutterStep", publicName: "gutterStep", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, gutterClickDeltaPx: { classPropertyName: "gutterClickDeltaPx", publicName: "gutterClickDeltaPx", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, dir: { classPropertyName: "dir", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, gutterAriaLabel: { classPropertyName: "gutterAriaLabel", publicName: "gutterAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, restrictMove: { classPropertyName: "restrictMove", publicName: "restrictMove", isSignal: true, isRequired: false, transformFunction: null }, useTransition: { classPropertyName: "useTransition", publicName: "useTransition", isSignal: true, isRequired: false, transformFunction: null }, gutterDblClickDuration: { classPropertyName: "gutterDblClickDuration", publicName: "gutterDblClickDuration", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { gutterClick: "gutterClick", gutterDblClick: "gutterDblClick", dragStart: "dragStart", dragEnd: "dragEnd", transitionEnd: "transitionEnd" }, host: { properties: { "class": "this.hostClassesBinding", "dir": "this.hostDirBinding" } }, queries: [{ propertyName: "_areas", predicate: SPLIT_AREA_CONTRACT, isSignal: true }, { propertyName: "customGutter", first: true, predicate: SplitGutterDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-content></ng-content>\n@for (area of _areas(); track area) {\n @if (!$last) {\n <div\n #gutter\n class=\"as-split-gutter\"\n role=\"separator\"\n tabindex=\"0\"\n [attr.aria-label]=\"gutterAriaLabel()\"\n [attr.aria-orientation]=\"direction()\"\n [attr.aria-valuemin]=\"getAriaValue(area.minSize())\"\n [attr.aria-valuemax]=\"getAriaValue(area.maxSize())\"\n [attr.aria-valuenow]=\"getAriaValue(area._internalSize())\"\n [attr.aria-valuetext]=\"getAriaAreaSizeText(area)\"\n [ngStyle]=\"getGutterGridStyle($index + 1)\"\n [class.as-dragged]=\"draggedGutterIndex() === $index\"\n asSplitCustomEventsBehavior\n [asSplitCustomMultiClickThreshold]=\"gutterDblClickDuration()\"\n [asSplitCustomClickDeltaInPx]=\"gutterClickDeltaPx()\"\n (asSplitCustomClick)=\"gutterClicked($index)\"\n (asSplitCustomDblClick)=\"gutterDoubleClicked($index)\"\n (asSplitCustomMouseDown)=\"gutterMouseDown($event, gutter, $index, $index, $index + 1)\"\n (asSplitCustomKeyDown)=\"gutterKeyDown($event, $index, $index, $index + 1)\"\n >\n @if (customGutter()?.template) {\n <ng-container *asSplitGutterDynamicInjector=\"$index + 1; let injector\">\n <ng-container\n *ngTemplateOutlet=\"\n customGutter().template;\n context: {\n areaBefore: area,\n areaAfter: _areas()[$index + 1],\n gutterNum: $index + 1,\n first: $first,\n last: $index === _areas().length - 2,\n isDragged: draggedGutterIndex() === $index\n };\n injector: injector\n \"\n ></ng-container>\n </ng-container>\n } @else {\n <div class=\"as-split-gutter-icon\"></div>\n }\n </div>\n }\n}\n", styles: ["@property --as-gutter-background-color{syntax: \"<color>\"; inherits: true; initial-value: #eeeeee;}@property --as-gutter-icon-horizontal{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==);}@property --as-gutter-icon-vertical{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFCAMAAABl/6zIAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAABRJREFUeAFjYGRkwIMJSeMHlBkOABP7AEGzSuPKAAAAAElFTkSuQmCC);}@property --as-gutter-icon-disabled{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==);}@property --as-transition-duration{syntax: \"<time>\"; inherits: true; initial-value: .3s;}@property --as-gutter-disabled-cursor{syntax: \"*\"; inherits: true; initial-value: default;}:host{--_as-gutter-background-color: var(--as-gutter-background-color, #eeeeee);--_as-gutter-icon-horizontal: var(--as-gutter-icon-horizontal, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==));--_as-gutter-icon-vertical: var(--as-gutter-icon-vertical, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFCAMAAABl/6zIAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAABRJREFUeAFjYGRkwIMJSeMHlBkOABP7AEGzSuPKAAAAAElFTkSuQmCC));--_as-gutter-icon-disabled: var(--as-gutter-icon-disabled, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==));--_as-transition-duration: var(--as-transition-duration, .3s);--_as-gutter-disabled-cursor: var(--as-gutter-disabled-cursor, default)}:host{display:grid;overflow:hidden;height:100%;width:100%}:host(.as-transition){transition:grid-template var(--_as-transition-duration)}.as-split-gutter{background-color:var(--_as-gutter-background-color);display:flex;align-items:center;justify-content:center;touch-action:none}:host(.as-horizontal)>.as-split-gutter{cursor:col-resize;height:100%}:host(.as-vertical)>.as-split-gutter{cursor:row-resize;width:100%}:host(.as-disabled)>.as-split-gutter{cursor:var(--_as-gutter-disabled-cursor)}.as-split-gutter-icon{width:100%;height:100%;background-position:center center;background-repeat:no-repeat}:host(.as-horizontal)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-horizontal)}:host(.as-vertical)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-vertical)}:host(.as-disabled)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-disabled)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: SplitCustomEventsBehaviorDirective, selector: "[asSplitCustomEventsBehavior]", inputs: ["asSplitCustomMultiClickThreshold", "asSplitCustomClickDeltaInPx"], outputs: ["asSplitCustomMouseDown", "asSplitCustomClick", "asSplitCustomDblClick", "asSplitCustomKeyDown"] }, { kind: "directive", type: SplitGutterDynamicInjectorDirective, selector: "[asSplitGutterDynamicInjector]", inputs: ["asSplitGutterDynamicInjector"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3117
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3118
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: SplitComponent, isStandalone: true, selector: "p-splitter", inputs: { gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null }, gutterStep: { classPropertyName: "gutterStep", publicName: "gutterStep", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, gutterClickDeltaPx: { classPropertyName: "gutterClickDeltaPx", publicName: "gutterClickDeltaPx", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, dir: { classPropertyName: "dir", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, gutterAriaLabel: { classPropertyName: "gutterAriaLabel", publicName: "gutterAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, restrictMove: { classPropertyName: "restrictMove", publicName: "restrictMove", isSignal: true, isRequired: false, transformFunction: null }, useTransition: { classPropertyName: "useTransition", publicName: "useTransition", isSignal: true, isRequired: false, transformFunction: null }, gutterDblClickDuration: { classPropertyName: "gutterDblClickDuration", publicName: "gutterDblClickDuration", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { gutterClick: "gutterClick", gutterDblClick: "gutterDblClick", dragStart: "dragStart", dragEnd: "dragEnd", transitionEnd: "transitionEnd" }, host: { properties: { "class": "this.hostClassesBinding", "dir": "this.hostDirBinding" } }, queries: [{ propertyName: "_areas", predicate: SPLIT_AREA_CONTRACT, isSignal: true }, { propertyName: "customGutter", first: true, predicate: SplitGutterDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-content></ng-content>\n@for (area of _areas(); track area) {\n @if (!$last) {\n <div\n #gutter\n class=\"as-split-gutter\"\n role=\"separator\"\n tabindex=\"0\"\n [attr.aria-label]=\"gutterAriaLabel()\"\n [attr.aria-orientation]=\"direction()\"\n [attr.aria-valuemin]=\"getAriaValue(area.minSize())\"\n [attr.aria-valuemax]=\"getAriaValue(area.maxSize())\"\n [attr.aria-valuenow]=\"getAriaValue(area._internalSize())\"\n [attr.aria-valuetext]=\"getAriaAreaSizeText(area)\"\n [ngStyle]=\"getGutterGridStyle($index + 1)\"\n [class.as-dragged]=\"draggedGutterIndex() === $index\"\n asSplitCustomEventsBehavior\n [asSplitCustomMultiClickThreshold]=\"gutterDblClickDuration()\"\n [asSplitCustomClickDeltaInPx]=\"gutterClickDeltaPx()\"\n (asSplitCustomClick)=\"gutterClicked($index)\"\n (asSplitCustomDblClick)=\"gutterDoubleClicked($index)\"\n (asSplitCustomMouseDown)=\"gutterMouseDown($event, gutter, $index, $index, $index + 1)\"\n (asSplitCustomKeyDown)=\"gutterKeyDown($event, $index, $index, $index + 1)\"\n >\n @if (customGutter()?.template) {\n <ng-container *asSplitGutterDynamicInjector=\"$index + 1; let injector\">\n <ng-container\n *ngTemplateOutlet=\"\n customGutter().template;\n context: {\n areaBefore: area,\n areaAfter: _areas()[$index + 1],\n gutterNum: $index + 1,\n first: $first,\n last: $index === _areas().length - 2,\n isDragged: draggedGutterIndex() === $index\n };\n injector: injector\n \"\n ></ng-container>\n </ng-container>\n } @else {\n <div class=\"as-split-gutter-icon\"></div>\n }\n </div>\n }\n}\n", styles: ["@property --as-gutter-background-color{syntax: \"<color>\"; inherits: true; initial-value: #eeeeee;}@property --as-gutter-icon-horizontal{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==);}@property --as-gutter-icon-vertical{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFCAMAAABl/6zIAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAABRJREFUeAFjYGRkwIMJSeMHlBkOABP7AEGzSuPKAAAAAElFTkSuQmCC);}@property --as-gutter-icon-disabled{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==);}@property --as-transition-duration{syntax: \"<time>\"; inherits: true; initial-value: .3s;}@property --as-gutter-disabled-cursor{syntax: \"*\"; inherits: true; initial-value: default;}:host{--_as-gutter-background-color: var(--as-gutter-background-color, #eeeeee);--_as-gutter-icon-horizontal: var(--as-gutter-icon-horizontal, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==));--_as-gutter-icon-vertical: var(--as-gutter-icon-vertical, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFCAMAAABl/6zIAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAABRJREFUeAFjYGRkwIMJSeMHlBkOABP7AEGzSuPKAAAAAElFTkSuQmCC));--_as-gutter-icon-disabled: var(--as-gutter-icon-disabled, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==));--_as-transition-duration: var(--as-transition-duration, .3s);--_as-gutter-disabled-cursor: var(--as-gutter-disabled-cursor, default)}:host{display:grid;overflow:hidden;height:100%;width:100%}:host(.as-transition){transition:grid-template var(--_as-transition-duration)}.as-split-gutter{background-color:var(--_as-gutter-background-color);display:flex;align-items:center;justify-content:center;touch-action:none}:host(.as-horizontal)>.as-split-gutter{cursor:col-resize;height:100%}:host(.as-vertical)>.as-split-gutter{cursor:row-resize;width:100%}:host(.as-disabled)>.as-split-gutter{cursor:var(--_as-gutter-disabled-cursor)}.as-split-gutter-icon{width:100%;height:100%;background-position:center center;background-repeat:no-repeat}:host(.as-horizontal)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-horizontal)}:host(.as-vertical)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-vertical)}:host(.as-disabled)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-disabled)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: SplitCustomEventsBehaviorDirective, selector: "[asSplitCustomEventsBehavior]", inputs: ["asSplitCustomMultiClickThreshold", "asSplitCustomClickDeltaInPx"], outputs: ["asSplitCustomMouseDown", "asSplitCustomClick", "asSplitCustomDblClick", "asSplitCustomKeyDown"] }, { kind: "directive", type: SplitGutterDynamicInjectorDirective, selector: "[asSplitGutterDynamicInjector]", inputs: ["asSplitGutterDynamicInjector"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3119
3119
  }
3120
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitComponent, decorators: [{
3120
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitComponent, decorators: [{
3121
3121
  type: Component,
3122
3122
  args: [{ selector: 'p-splitter', imports: [NgStyle, SplitCustomEventsBehaviorDirective, SplitGutterDynamicInjectorDirective, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n@for (area of _areas(); track area) {\n @if (!$last) {\n <div\n #gutter\n class=\"as-split-gutter\"\n role=\"separator\"\n tabindex=\"0\"\n [attr.aria-label]=\"gutterAriaLabel()\"\n [attr.aria-orientation]=\"direction()\"\n [attr.aria-valuemin]=\"getAriaValue(area.minSize())\"\n [attr.aria-valuemax]=\"getAriaValue(area.maxSize())\"\n [attr.aria-valuenow]=\"getAriaValue(area._internalSize())\"\n [attr.aria-valuetext]=\"getAriaAreaSizeText(area)\"\n [ngStyle]=\"getGutterGridStyle($index + 1)\"\n [class.as-dragged]=\"draggedGutterIndex() === $index\"\n asSplitCustomEventsBehavior\n [asSplitCustomMultiClickThreshold]=\"gutterDblClickDuration()\"\n [asSplitCustomClickDeltaInPx]=\"gutterClickDeltaPx()\"\n (asSplitCustomClick)=\"gutterClicked($index)\"\n (asSplitCustomDblClick)=\"gutterDoubleClicked($index)\"\n (asSplitCustomMouseDown)=\"gutterMouseDown($event, gutter, $index, $index, $index + 1)\"\n (asSplitCustomKeyDown)=\"gutterKeyDown($event, $index, $index, $index + 1)\"\n >\n @if (customGutter()?.template) {\n <ng-container *asSplitGutterDynamicInjector=\"$index + 1; let injector\">\n <ng-container\n *ngTemplateOutlet=\"\n customGutter().template;\n context: {\n areaBefore: area,\n areaAfter: _areas()[$index + 1],\n gutterNum: $index + 1,\n first: $first,\n last: $index === _areas().length - 2,\n isDragged: draggedGutterIndex() === $index\n };\n injector: injector\n \"\n ></ng-container>\n </ng-container>\n } @else {\n <div class=\"as-split-gutter-icon\"></div>\n }\n </div>\n }\n}\n", styles: ["@property --as-gutter-background-color{syntax: \"<color>\"; inherits: true; initial-value: #eeeeee;}@property --as-gutter-icon-horizontal{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==);}@property --as-gutter-icon-vertical{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFCAMAAABl/6zIAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAABRJREFUeAFjYGRkwIMJSeMHlBkOABP7AEGzSuPKAAAAAElFTkSuQmCC);}@property --as-gutter-icon-disabled{syntax: \"<url>\"; inherits: true; initial-value: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==);}@property --as-transition-duration{syntax: \"<time>\"; inherits: true; initial-value: .3s;}@property --as-gutter-disabled-cursor{syntax: \"*\"; inherits: true; initial-value: default;}:host{--_as-gutter-background-color: var(--as-gutter-background-color, #eeeeee);--_as-gutter-icon-horizontal: var(--as-gutter-icon-horizontal, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==));--_as-gutter-icon-vertical: var(--as-gutter-icon-vertical, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFCAMAAABl/6zIAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAABRJREFUeAFjYGRkwIMJSeMHlBkOABP7AEGzSuPKAAAAAElFTkSuQmCC));--_as-gutter-icon-disabled: var(--as-gutter-icon-disabled, url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==));--_as-transition-duration: var(--as-transition-duration, .3s);--_as-gutter-disabled-cursor: var(--as-gutter-disabled-cursor, default)}:host{display:grid;overflow:hidden;height:100%;width:100%}:host(.as-transition){transition:grid-template var(--_as-transition-duration)}.as-split-gutter{background-color:var(--_as-gutter-background-color);display:flex;align-items:center;justify-content:center;touch-action:none}:host(.as-horizontal)>.as-split-gutter{cursor:col-resize;height:100%}:host(.as-vertical)>.as-split-gutter{cursor:row-resize;width:100%}:host(.as-disabled)>.as-split-gutter{cursor:var(--_as-gutter-disabled-cursor)}.as-split-gutter-icon{width:100%;height:100%;background-position:center center;background-repeat:no-repeat}:host(.as-horizontal)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-horizontal)}:host(.as-vertical)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-vertical)}:host(.as-disabled)>.as-split-gutter>.as-split-gutter-icon{background-image:var(--_as-gutter-icon-disabled)}\n"] }]
3123
3123
  }], ctorParameters: () => [], propDecorators: { _areas: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SPLIT_AREA_CONTRACT), { isSignal: true }] }], customGutter: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SplitGutterDirective), { isSignal: true }] }], gutterSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterSize", required: false }] }], gutterStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterStep", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], gutterClickDeltaPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterClickDeltaPx", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], dir: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], gutterAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterAriaLabel", required: false }] }], restrictMove: [{ type: i0.Input, args: [{ isSignal: true, alias: "restrictMove", required: false }] }], useTransition: [{ type: i0.Input, args: [{ isSignal: true, alias: "useTransition", required: false }] }], gutterDblClickDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterDblClickDuration", required: false }] }], gutterClick: [{ type: i0.Output, args: ["gutterClick"] }], gutterDblClick: [{ type: i0.Output, args: ["gutterDblClick"] }], dragStart: [{ type: i0.Output, args: ["dragStart"] }], dragEnd: [{ type: i0.Output, args: ["dragEnd"] }], transitionEnd: [{ type: i0.Output, args: ["transitionEnd"] }], hostClassesBinding: [{
@@ -3298,15 +3298,15 @@ class SplitAreaComponent {
3298
3298
  }
3299
3299
  return boundarySize;
3300
3300
  }
3301
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitAreaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3302
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: SplitAreaComponent, isStandalone: true, selector: "p-splitter-area", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, minSize: { classPropertyName: "minSize", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, lockSize: { classPropertyName: "lockSize", publicName: "lockSize", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClassesBinding", "style.grid-column": "this.hostGridColumnStyleBinding", "style.grid-row": "this.hostGridRowStyleBinding", "style.position": "this.hostPositionStyleBinding" } }, providers: [
3301
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitAreaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3302
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: SplitAreaComponent, isStandalone: true, selector: "p-splitter-area", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, minSize: { classPropertyName: "minSize", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, lockSize: { classPropertyName: "lockSize", publicName: "lockSize", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClassesBinding", "style.grid-column": "this.hostGridColumnStyleBinding", "style.grid-row": "this.hostGridRowStyleBinding", "style.position": "this.hostPositionStyleBinding" } }, providers: [
3303
3303
  {
3304
3304
  provide: SPLIT_AREA_CONTRACT,
3305
3305
  useExisting: SplitAreaComponent,
3306
3306
  },
3307
3307
  ], ngImport: i0, template: "<ng-content></ng-content>\n@if (split._isDragging()) {\n <div class=\"as-iframe-fix\"></div>\n}\n", styles: [":host{overflow-x:hidden;overflow-y:auto}.as-horizontal>:host{height:100%}.as-vertical>:host{width:100%}.as-iframe-fix{position:absolute;top:0;left:0;width:100%;height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3308
3308
  }
3309
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SplitAreaComponent, decorators: [{
3309
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SplitAreaComponent, decorators: [{
3310
3310
  type: Component,
3311
3311
  args: [{ selector: 'p-splitter-area', standalone: true, providers: [
3312
3312
  {
@@ -3616,10 +3616,10 @@ class DynamicDashboardTemplateComponent {
3616
3616
  });
3617
3617
  return DynamicDashboardTemplateComponent;
3618
3618
  }
3619
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DynamicDashboardTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3620
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: DynamicDashboardTemplateComponent, isStandalone: false, selector: "wuic-dynamic-dashboard-template", inputs: { inputs: "inputs", inputProps: "inputProps", toolProps: "toolProps", suggestions: "suggestions", toolId: "toolId", componentId: "componentId", uniqueName: "uniqueName", name: "name", tag: "tag", icon: "icon", group: "group", nestedComponents: "nestedComponents", allowedChildren: "allowedChildren", hide: "hide", componentRef: "componentRef", onDrop: "onDrop", ctxItems: "ctxItems", component: "component" }, ngImport: i0, template: '', isInline: true, styles: [""] });
3619
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DynamicDashboardTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3620
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: DynamicDashboardTemplateComponent, isStandalone: false, selector: "wuic-dynamic-dashboard-template", inputs: { inputs: "inputs", inputProps: "inputProps", toolProps: "toolProps", suggestions: "suggestions", toolId: "toolId", componentId: "componentId", uniqueName: "uniqueName", name: "name", tag: "tag", icon: "icon", group: "group", nestedComponents: "nestedComponents", allowedChildren: "allowedChildren", hide: "hide", componentRef: "componentRef", onDrop: "onDrop", ctxItems: "ctxItems", component: "component" }, ngImport: i0, template: '', isInline: true, styles: [""] });
3621
3621
  }
3622
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DynamicDashboardTemplateComponent, decorators: [{
3622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DynamicDashboardTemplateComponent, decorators: [{
3623
3623
  type: Component,
3624
3624
  args: [{ selector: 'wuic-dynamic-dashboard-template', template: '', standalone: false }]
3625
3625
  }], propDecorators: { inputs: [{
@@ -3716,12 +3716,12 @@ class DashboardComponent {
3716
3716
  debugger;
3717
3717
  }
3718
3718
  ;
3719
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3720
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DashboardComponent, isStandalone: true, selector: "wuic-dashboard", inputs: { dashboardElements: "dashboardElements" }, ngImport: i0, template: "@for (dashboardElement of dashboardElements; track dashboardElement.uniqueName) {\r\n<ng-container *ngComponentOutlet=\"getComponent(dashboardElement); inputs: getComponentInputs(dashboardElement)\"></ng-container>\r\n}\r\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }] });
3719
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3720
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DashboardComponent, isStandalone: true, selector: "wuic-dashboard", inputs: { dashboardElements: "dashboardElements" }, ngImport: i0, template: "@for (dashboardElement of dashboardElements; track dashboardElement.uniqueName) {\r\n<ng-container *ngComponentOutlet=\"getComponent(dashboardElement); inputs: getComponentInputs(dashboardElement)\"></ng-container>\r\n}\r\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }] });
3721
3721
  }
3722
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DashboardComponent, decorators: [{
3722
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DashboardComponent, decorators: [{
3723
3723
  type: Component,
3724
- args: [{ selector: 'wuic-dashboard', imports: [NgTemplateOutlet, NgComponentOutlet], template: "@for (dashboardElement of dashboardElements; track dashboardElement.uniqueName) {\r\n<ng-container *ngComponentOutlet=\"getComponent(dashboardElement); inputs: getComponentInputs(dashboardElement)\"></ng-container>\r\n}\r\n" }]
3724
+ args: [{ selector: 'wuic-dashboard', imports: [NgComponentOutlet], template: "@for (dashboardElement of dashboardElements; track dashboardElement.uniqueName) {\r\n<ng-container *ngComponentOutlet=\"getComponent(dashboardElement); inputs: getComponentInputs(dashboardElement)\"></ng-container>\r\n}\r\n" }]
3725
3725
  }], ctorParameters: () => [], propDecorators: { dashboardElements: [{
3726
3726
  type: Input
3727
3727
  }] } });
@@ -4150,10 +4150,10 @@ class CssSheetEditorComponent {
4150
4150
  const found = sheet.classes.find((c) => String(c.SelectorString || '').trim() === String(this.selectedClassSelector || '').trim());
4151
4151
  return found || null;
4152
4152
  }
4153
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CssSheetEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4154
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CssSheetEditorComponent, isStandalone: true, selector: "wuic-css-sheet-editor", inputs: { visible: "visible", sheets: "sheets", selectedSheetPath: "selectedSheetPath", styleProps: "styleProps", assetsFolder: "assetsFolder" }, outputs: { visibleChange: "visibleChange", applyEditor: "applyEditor" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog\n [header]=\"'CSS Editor'\"\n [(visible)]=\"visible\"\n (visibleChange)=\"visibleChange.emit($event)\"\n [modal]=\"true\"\n [closable]=\"true\"\n [style]=\"{ width: '1100px', maxWidth: '98vw' }\"\n>\n <div class=\"css-editor-layout\">\n <div class=\"css-editor-col\">\n <div class=\"css-editor-row\">\n <label>File CSS</label>\n <p-select\n [options]=\"draftSheets\"\n optionLabel=\"SheetPath\"\n optionValue=\"SheetPath\"\n [(ngModel)]=\"selectedSheetPathDraft\"\n (ngModelChange)=\"onSelectedSheetChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '100%' }\">\n </p-select>\n </div>\n <div class=\"css-editor-row css-editor-inline\">\n <input type=\"text\" [(ngModel)]=\"newSheetName\" pattern=\"^[^/\\\\]+$\" [placeholder]=\"'Nuovo file in assets/' + (assetsFolder || '<dash_route>') + ' (solo nome, es. dashboard-custom.css)'\" />\n <p-button label=\"Crea file\" (onClick)=\"addSheet()\" [disabled]=\"!assetsFolder\"></p-button>\n </div>\n @if (!assetsFolder) {\n <div class=\"css-editor-row\">\n <small>Salva prima la dashboard per definire il folder (dash_route).</small>\n </div>\n }\n <div class=\"css-editor-row\">\n <p-button severity=\"danger\" label=\"Rimuovi file selezionato\" (onClick)=\"removeSelectedSheet()\" [disabled]=\"!currentSheet\"></p-button>\n </div>\n </div>\n\n @if (currentSheet) {\n <div class=\"css-editor-col\">\n <div class=\"css-editor-row\">\n <label>Classi</label>\n <p-select\n [options]=\"currentSheet?.classes || []\"\n optionLabel=\"SelectorString\"\n optionValue=\"SelectorString\"\n [(ngModel)]=\"selectedClassSelector\"\n (ngModelChange)=\"onSelectedClassChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '100%' }\">\n </p-select>\n </div>\n <div class=\"css-editor-row css-editor-inline\">\n <input type=\"text\" [(ngModel)]=\"newClassName\" placeholder=\"Nuova classe (es. card-title)\" />\n <p-button label=\"Crea classe\" (onClick)=\"addClassToSelectedSheet()\" [disabled]=\"!currentSheet\"></p-button>\n </div>\n <div class=\"css-editor-row\">\n <p-button severity=\"danger\" label=\"Rimuovi classe selezionata\" (onClick)=\"removeSelectedClass()\" [disabled]=\"!currentClass\"></p-button>\n </div>\n </div>\n }\n </div>\n\n @if (currentClass) {\n <div class=\"css-editor-styles\">\n <div class=\"css-editor-row css-style-row\" style=\"margin-bottom: 8px;\">\n <p-select\n [options]=\"styleProps\"\n optionLabel=\"key\"\n optionValue=\"key\"\n [(ngModel)]=\"pendingStyleKey\"\n (ngModelChange)=\"onPendingStyleKeyChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '260px' }\">\n </p-select>\n\n @if (isPropertyDictionary(pendingStyleKey)) {\n <p-select\n [options]=\"getPropertyValues(pendingStyleKey)\"\n [(ngModel)]=\"pendingStyleValue\"\n appendTo=\"body\"\n [style]=\"{ width: '320px' }\">\n </p-select>\n } @else if (isPropertyColor(pendingStyleKey)) {\n <div class=\"css-style-color-input\">\n <p-colorPicker\n [ngModel]=\"colorPickerValue(pendingStyleValue)\"\n (ngModelChange)=\"onPendingColorChanged($event)\"\n appendTo=\"body\">\n </p-colorPicker>\n <input type=\"text\" [(ngModel)]=\"pendingStyleValue\" style=\"width: 252px;\" />\n </div>\n } @else {\n <input type=\"text\" [(ngModel)]=\"pendingStyleValue\" style=\"width: 320px;\" />\n }\n\n <p-button label=\"Aggiungi propriet\u00E0 corrente\" (onClick)=\"addStyleToSelectedClass()\" [disabled]=\"!currentClass || !pendingStyleKey\"></p-button>\n </div>\n\n @for (style of currentClass.Styles; track style; let i = $index) {\n <div class=\"css-style-row\">\n <div class=\"css-style-readonly-key\">{{ style.Key }}</div>\n <div class=\"css-style-readonly-value\">{{ style.Value }}</div>\n\n <p-button icon=\"pi pi-trash\" severity=\"danger\" [text]=\"true\" (onClick)=\"removeStyle(i)\"></p-button>\n </div>\n }\n </div>\n }\n\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Chiudi\" severity=\"secondary\" (onClick)=\"close()\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [".css-editor-layout{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}.css-editor-col{border:1px solid #d0d0d0;border-radius:6px;padding:12px}.css-editor-row{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}.css-editor-inline{flex-direction:row;align-items:center}.css-editor-inline input{flex:1}.css-editor-styles{border:1px solid #d0d0d0;border-radius:6px;padding:12px;max-height:420px;overflow:auto}.css-style-row{display:flex;align-items:center;gap:8px;margin-bottom:8px}.css-style-readonly-key{width:260px;min-height:32px;display:flex;align-items:center;padding:0 8px;border:1px solid #d0d0d0;border-radius:4px;background:#f9f9f9;font-family:monospace}.css-style-readonly-value{width:320px;min-height:32px;display:flex;align-items:center;padding:0 8px;border:1px solid #d0d0d0;border-radius:4px;background:#f9f9f9;font-family:monospace}.css-style-color-input{display:flex;align-items:center;gap:8px;width:320px}@media(max-width:1024px){.css-editor-layout{grid-template-columns:1fr}.css-style-row{flex-wrap:wrap}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ColorPickerModule }, { kind: "component", type: i2$2.ColorPicker, selector: "p-colorPicker, p-colorpicker, p-color-picker", inputs: ["styleClass", "showTransitionOptions", "hideTransitionOptions", "inline", "format", "tabindex", "inputId", "autoZIndex", "autofocus", "defaultColor", "appendTo", "overlayOptions", "motionOptions"], outputs: ["onChange", "onShow", "onHide"] }] });
4153
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CssSheetEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4154
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: CssSheetEditorComponent, isStandalone: true, selector: "wuic-css-sheet-editor", inputs: { visible: "visible", sheets: "sheets", selectedSheetPath: "selectedSheetPath", styleProps: "styleProps", assetsFolder: "assetsFolder" }, outputs: { visibleChange: "visibleChange", applyEditor: "applyEditor" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog\n [header]=\"'CSS Editor'\"\n [(visible)]=\"visible\"\n (visibleChange)=\"visibleChange.emit($event)\"\n [modal]=\"true\"\n [closable]=\"true\"\n [style]=\"{ width: '1100px', maxWidth: '98vw' }\"\n>\n <div class=\"css-editor-layout\">\n <div class=\"css-editor-col\">\n <div class=\"css-editor-row\">\n <label>File CSS</label>\n <p-select\n [options]=\"draftSheets\"\n optionLabel=\"SheetPath\"\n optionValue=\"SheetPath\"\n [(ngModel)]=\"selectedSheetPathDraft\"\n (ngModelChange)=\"onSelectedSheetChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '100%' }\">\n </p-select>\n </div>\n <div class=\"css-editor-row css-editor-inline\">\n <input type=\"text\" [(ngModel)]=\"newSheetName\" pattern=\"^[^/\\\\]+$\" [placeholder]=\"'Nuovo file in assets/' + (assetsFolder || '<dash_route>') + ' (solo nome, es. dashboard-custom.css)'\" />\n <p-button label=\"Crea file\" (onClick)=\"addSheet()\" [disabled]=\"!assetsFolder\"></p-button>\n </div>\n @if (!assetsFolder) {\n <div class=\"css-editor-row\">\n <small>Salva prima la dashboard per definire il folder (dash_route).</small>\n </div>\n }\n <div class=\"css-editor-row\">\n <p-button severity=\"danger\" label=\"Rimuovi file selezionato\" (onClick)=\"removeSelectedSheet()\" [disabled]=\"!currentSheet\"></p-button>\n </div>\n </div>\n\n @if (currentSheet) {\n <div class=\"css-editor-col\">\n <div class=\"css-editor-row\">\n <label>Classi</label>\n <p-select\n [options]=\"currentSheet?.classes || []\"\n optionLabel=\"SelectorString\"\n optionValue=\"SelectorString\"\n [(ngModel)]=\"selectedClassSelector\"\n (ngModelChange)=\"onSelectedClassChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '100%' }\">\n </p-select>\n </div>\n <div class=\"css-editor-row css-editor-inline\">\n <input type=\"text\" [(ngModel)]=\"newClassName\" placeholder=\"Nuova classe (es. card-title)\" />\n <p-button label=\"Crea classe\" (onClick)=\"addClassToSelectedSheet()\" [disabled]=\"!currentSheet\"></p-button>\n </div>\n <div class=\"css-editor-row\">\n <p-button severity=\"danger\" label=\"Rimuovi classe selezionata\" (onClick)=\"removeSelectedClass()\" [disabled]=\"!currentClass\"></p-button>\n </div>\n </div>\n }\n </div>\n\n @if (currentClass) {\n <div class=\"css-editor-styles\">\n <div class=\"css-editor-row css-style-row\" style=\"margin-bottom: 8px;\">\n <p-select\n [options]=\"styleProps\"\n optionLabel=\"key\"\n optionValue=\"key\"\n [(ngModel)]=\"pendingStyleKey\"\n (ngModelChange)=\"onPendingStyleKeyChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '260px' }\">\n </p-select>\n\n @if (isPropertyDictionary(pendingStyleKey)) {\n <p-select\n [options]=\"getPropertyValues(pendingStyleKey)\"\n [(ngModel)]=\"pendingStyleValue\"\n appendTo=\"body\"\n [style]=\"{ width: '320px' }\">\n </p-select>\n } @else if (isPropertyColor(pendingStyleKey)) {\n <div class=\"css-style-color-input\">\n <p-colorPicker\n [ngModel]=\"colorPickerValue(pendingStyleValue)\"\n (ngModelChange)=\"onPendingColorChanged($event)\"\n appendTo=\"body\">\n </p-colorPicker>\n <input type=\"text\" [(ngModel)]=\"pendingStyleValue\" style=\"width: 252px;\" />\n </div>\n } @else {\n <input type=\"text\" [(ngModel)]=\"pendingStyleValue\" style=\"width: 320px;\" />\n }\n\n <p-button label=\"Aggiungi propriet\u00E0 corrente\" (onClick)=\"addStyleToSelectedClass()\" [disabled]=\"!currentClass || !pendingStyleKey\"></p-button>\n </div>\n\n @for (style of currentClass.Styles; track style; let i = $index) {\n <div class=\"css-style-row\">\n <div class=\"css-style-readonly-key\">{{ style.Key }}</div>\n <div class=\"css-style-readonly-value\">{{ style.Value }}</div>\n\n <p-button icon=\"pi pi-trash\" severity=\"danger\" [text]=\"true\" (onClick)=\"removeStyle(i)\"></p-button>\n </div>\n }\n </div>\n }\n\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Chiudi\" severity=\"secondary\" (onClick)=\"close()\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [".css-editor-layout{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}.css-editor-col{border:1px solid #d0d0d0;border-radius:6px;padding:12px}.css-editor-row{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}.css-editor-inline{flex-direction:row;align-items:center}.css-editor-inline input{flex:1}.css-editor-styles{border:1px solid #d0d0d0;border-radius:6px;padding:12px;max-height:420px;overflow:auto}.css-style-row{display:flex;align-items:center;gap:8px;margin-bottom:8px}.css-style-readonly-key{width:260px;min-height:32px;display:flex;align-items:center;padding:0 8px;border:1px solid #d0d0d0;border-radius:4px;background:#f9f9f9;font-family:monospace}.css-style-readonly-value{width:320px;min-height:32px;display:flex;align-items:center;padding:0 8px;border:1px solid #d0d0d0;border-radius:4px;background:#f9f9f9;font-family:monospace}.css-style-color-input{display:flex;align-items:center;gap:8px;width:320px}@media(max-width:1024px){.css-editor-layout{grid-template-columns:1fr}.css-style-row{flex-wrap:wrap}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ColorPickerModule }, { kind: "component", type: i2$2.ColorPicker, selector: "p-colorPicker, p-colorpicker, p-color-picker", inputs: ["styleClass", "showTransitionOptions", "hideTransitionOptions", "inline", "format", "tabindex", "inputId", "autoZIndex", "autofocus", "defaultColor", "appendTo", "overlayOptions", "motionOptions"], outputs: ["onChange", "onShow", "onHide"] }] });
4155
4155
  }
4156
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CssSheetEditorComponent, decorators: [{
4156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CssSheetEditorComponent, decorators: [{
4157
4157
  type: Component,
4158
4158
  args: [{ selector: 'wuic-css-sheet-editor', imports: [FormsModule, DialogModule, ButtonModule, SelectModule, ColorPickerModule], template: "<p-dialog\n [header]=\"'CSS Editor'\"\n [(visible)]=\"visible\"\n (visibleChange)=\"visibleChange.emit($event)\"\n [modal]=\"true\"\n [closable]=\"true\"\n [style]=\"{ width: '1100px', maxWidth: '98vw' }\"\n>\n <div class=\"css-editor-layout\">\n <div class=\"css-editor-col\">\n <div class=\"css-editor-row\">\n <label>File CSS</label>\n <p-select\n [options]=\"draftSheets\"\n optionLabel=\"SheetPath\"\n optionValue=\"SheetPath\"\n [(ngModel)]=\"selectedSheetPathDraft\"\n (ngModelChange)=\"onSelectedSheetChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '100%' }\">\n </p-select>\n </div>\n <div class=\"css-editor-row css-editor-inline\">\n <input type=\"text\" [(ngModel)]=\"newSheetName\" pattern=\"^[^/\\\\]+$\" [placeholder]=\"'Nuovo file in assets/' + (assetsFolder || '<dash_route>') + ' (solo nome, es. dashboard-custom.css)'\" />\n <p-button label=\"Crea file\" (onClick)=\"addSheet()\" [disabled]=\"!assetsFolder\"></p-button>\n </div>\n @if (!assetsFolder) {\n <div class=\"css-editor-row\">\n <small>Salva prima la dashboard per definire il folder (dash_route).</small>\n </div>\n }\n <div class=\"css-editor-row\">\n <p-button severity=\"danger\" label=\"Rimuovi file selezionato\" (onClick)=\"removeSelectedSheet()\" [disabled]=\"!currentSheet\"></p-button>\n </div>\n </div>\n\n @if (currentSheet) {\n <div class=\"css-editor-col\">\n <div class=\"css-editor-row\">\n <label>Classi</label>\n <p-select\n [options]=\"currentSheet?.classes || []\"\n optionLabel=\"SelectorString\"\n optionValue=\"SelectorString\"\n [(ngModel)]=\"selectedClassSelector\"\n (ngModelChange)=\"onSelectedClassChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '100%' }\">\n </p-select>\n </div>\n <div class=\"css-editor-row css-editor-inline\">\n <input type=\"text\" [(ngModel)]=\"newClassName\" placeholder=\"Nuova classe (es. card-title)\" />\n <p-button label=\"Crea classe\" (onClick)=\"addClassToSelectedSheet()\" [disabled]=\"!currentSheet\"></p-button>\n </div>\n <div class=\"css-editor-row\">\n <p-button severity=\"danger\" label=\"Rimuovi classe selezionata\" (onClick)=\"removeSelectedClass()\" [disabled]=\"!currentClass\"></p-button>\n </div>\n </div>\n }\n </div>\n\n @if (currentClass) {\n <div class=\"css-editor-styles\">\n <div class=\"css-editor-row css-style-row\" style=\"margin-bottom: 8px;\">\n <p-select\n [options]=\"styleProps\"\n optionLabel=\"key\"\n optionValue=\"key\"\n [(ngModel)]=\"pendingStyleKey\"\n (ngModelChange)=\"onPendingStyleKeyChanged()\"\n appendTo=\"body\"\n [style]=\"{ width: '260px' }\">\n </p-select>\n\n @if (isPropertyDictionary(pendingStyleKey)) {\n <p-select\n [options]=\"getPropertyValues(pendingStyleKey)\"\n [(ngModel)]=\"pendingStyleValue\"\n appendTo=\"body\"\n [style]=\"{ width: '320px' }\">\n </p-select>\n } @else if (isPropertyColor(pendingStyleKey)) {\n <div class=\"css-style-color-input\">\n <p-colorPicker\n [ngModel]=\"colorPickerValue(pendingStyleValue)\"\n (ngModelChange)=\"onPendingColorChanged($event)\"\n appendTo=\"body\">\n </p-colorPicker>\n <input type=\"text\" [(ngModel)]=\"pendingStyleValue\" style=\"width: 252px;\" />\n </div>\n } @else {\n <input type=\"text\" [(ngModel)]=\"pendingStyleValue\" style=\"width: 320px;\" />\n }\n\n <p-button label=\"Aggiungi propriet\u00E0 corrente\" (onClick)=\"addStyleToSelectedClass()\" [disabled]=\"!currentClass || !pendingStyleKey\"></p-button>\n </div>\n\n @for (style of currentClass.Styles; track style; let i = $index) {\n <div class=\"css-style-row\">\n <div class=\"css-style-readonly-key\">{{ style.Key }}</div>\n <div class=\"css-style-readonly-value\">{{ style.Value }}</div>\n\n <p-button icon=\"pi pi-trash\" severity=\"danger\" [text]=\"true\" (onClick)=\"removeStyle(i)\"></p-button>\n </div>\n }\n </div>\n }\n\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Chiudi\" severity=\"secondary\" (onClick)=\"close()\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [".css-editor-layout{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}.css-editor-col{border:1px solid #d0d0d0;border-radius:6px;padding:12px}.css-editor-row{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}.css-editor-inline{flex-direction:row;align-items:center}.css-editor-inline input{flex:1}.css-editor-styles{border:1px solid #d0d0d0;border-radius:6px;padding:12px;max-height:420px;overflow:auto}.css-style-row{display:flex;align-items:center;gap:8px;margin-bottom:8px}.css-style-readonly-key{width:260px;min-height:32px;display:flex;align-items:center;padding:0 8px;border:1px solid #d0d0d0;border-radius:4px;background:#f9f9f9;font-family:monospace}.css-style-readonly-value{width:320px;min-height:32px;display:flex;align-items:center;padding:0 8px;border:1px solid #d0d0d0;border-radius:4px;background:#f9f9f9;font-family:monospace}.css-style-color-input{display:flex;align-items:center;gap:8px;width:320px}@media(max-width:1024px){.css-editor-layout{grid-template-columns:1fr}.css-style-row{flex-wrap:wrap}}\n"] }]
4159
4159
  }], propDecorators: { visible: [{
@@ -4274,6 +4274,10 @@ class DesignerComponent {
4274
4274
  lastCommittedSnapshot = null;
4275
4275
  pendingColorHistoryBase = null;
4276
4276
  pendingColorHistoryDirty = false;
4277
+ _historyApplyIsRedo = false;
4278
+ _lastHistoryApplyTime = 0;
4279
+ _suppressRedoClear = false;
4280
+ _redoRebindTimer;
4277
4281
  lastKnownHashRoute = '';
4278
4282
  suppressNextHashGuard = false;
4279
4283
  footerHoverTargetElements = [];
@@ -4304,7 +4308,7 @@ class DesignerComponent {
4304
4308
  this.workflowRuntimeMetadata = workflowRuntimeMetadata;
4305
4309
  this.defaultCtxItems = [
4306
4310
  {
4307
- label: 'Remove',
4311
+ label: this.t('designer.remove', 'Remove'),
4308
4312
  icon: 'pi pi-trash',
4309
4313
  command: (menuItem) => {
4310
4314
  if (this.ctxElement) {
@@ -4316,14 +4320,14 @@ class DesignerComponent {
4316
4320
  this.ctxItems.next(this.defaultCtxItems);
4317
4321
  this.footerCtxItems = [
4318
4322
  {
4319
- label: 'Rename',
4323
+ label: this.t('designer.rename', 'Rename'),
4320
4324
  icon: 'pi pi-pencil',
4321
4325
  command: () => {
4322
4326
  this.renameFooterContextItem();
4323
4327
  }
4324
4328
  },
4325
4329
  {
4326
- label: 'Remove',
4330
+ label: this.t('designer.remove', 'Remove'),
4327
4331
  icon: 'pi pi-trash',
4328
4332
  command: () => {
4329
4333
  const uniqueName = String(this.footerCtxElement?.uniqueName || '').trim();
@@ -4335,7 +4339,7 @@ class DesignerComponent {
4335
4339
  ];
4336
4340
  this.hierarchyCtxItems = [
4337
4341
  {
4338
- label: 'Remove',
4342
+ label: this.t('designer.remove', 'Remove'),
4339
4343
  icon: 'pi pi-trash',
4340
4344
  command: () => {
4341
4345
  const uniqueName = String(this.hierarchyCtxElement?.uniqueName || '').trim();
@@ -4868,13 +4872,13 @@ class DesignerComponent {
4868
4872
  group: 'HTML',
4869
4873
  toolId: 7,
4870
4874
  name: 'UL',
4871
- tag: `<ul [attr.id]="uniqueName" [attr.title]="uniqueName" [databound]="inputs.datasource?.component" [itemTemplate]="inputs.itemTemplate" [inputs]="inputs" ngxDraggableDom="true" ngResizable [rzHandles] = "'se'" (rzResizing)="onResizing($event, this)" (moved)="onMoving($event, this)" ${this.htmlStyleString.replace(/0/g, 'inputs')}>
4872
- <li *ngFor="let li of (inputs.datasource?.component?.value?.resultInfo?.dato || (inputs.optionsCsv || '').split(','))">
4873
- <ng-container *ngIf="inputs.displayFormula; else ulItemTemplate">{{getUlItemDisplayValue(inputs, li)}}</ng-container>
4874
- <ng-template #ulItemTemplate>
4875
- {{getSelectOptionLabel(inputs, li)}}
4876
- </ng-template>
4877
- <li>
4875
+ tag: `<ul [attr.id]="uniqueName" [attr.title]="uniqueName" [databound]="inputs.datasource?.component" [itemTemplate]="inputs.itemTemplate" [inputs]="inputs" ngxDraggableDom="true" ngResizable [rzHandles] = "'se'" (rzResizing)="onResizing($event, this)" (moved)="onMoving($event, this)" ${this.htmlStyleString.replace(/0/g, 'inputs')}>
4876
+ <li *ngFor="let li of (inputs.datasource?.component?.value?.resultInfo?.dato || (inputs.optionsCsv || '').split(','))">
4877
+ <ng-container *ngIf="inputs.displayFormula; else ulItemTemplate">{{getUlItemDisplayValue(inputs, li)}}</ng-container>
4878
+ <ng-template #ulItemTemplate>
4879
+ {{getSelectOptionLabel(inputs, li)}}
4880
+ </ng-template>
4881
+ <li>
4878
4882
  </ul>`,
4879
4883
  icon: 'pi pi-list',
4880
4884
  inputProps: (() => {
@@ -5210,8 +5214,8 @@ class DesignerComponent {
5210
5214
  group: 'CONTAINER',
5211
5215
  toolId: 1000,
5212
5216
  name: 'TABVIEW',
5213
- tag: `<p-tabView [attr.id]="uniqueName" [attr.title]="uniqueName" [tabs]="nestedComponents" ngxDraggableDom="true" (moved)="onMoving($event, this)" ngResizable [rzHandles]="'se'" (rzResizing)="onResizing($event, this)" ${this.htmlStyleString.replace('[ngStyle]', '[style]').replace(/0/g, 'inputs')}>
5214
- <wuic-dashboard [dashboardElements]="nestedComponents"></wuic-dashboard>
5217
+ tag: `<p-tabView [attr.id]="uniqueName" [attr.title]="uniqueName" [tabs]="nestedComponents" ngxDraggableDom="true" (moved)="onMoving($event, this)" ngResizable [rzHandles]="'se'" (rzResizing)="onResizing($event, this)" ${this.htmlStyleString.replace('[ngStyle]', '[style]').replace(/0/g, 'inputs')}>
5218
+ <wuic-dashboard [dashboardElements]="nestedComponents"></wuic-dashboard>
5215
5219
  </p-tabView>`,
5216
5220
  icon: 'pi pi-folder',
5217
5221
  inputProps: this.htmlInputProperties,
@@ -5223,8 +5227,8 @@ class DesignerComponent {
5223
5227
  group: 'CONTAINER',
5224
5228
  toolId: 1001,
5225
5229
  name: 'TABPANEL',
5226
- tag: `<p-tabPanel [attr.id]="uniqueName" [attr.title]="uniqueName" [selected]="inputs.selected">
5227
- <wuic-dashboard [dashboardElements]="nestedComponents"></wuic-dashboard>
5230
+ tag: `<p-tabPanel [attr.id]="uniqueName" [attr.title]="uniqueName" [selected]="inputs.selected">
5231
+ <wuic-dashboard [dashboardElements]="nestedComponents"></wuic-dashboard>
5228
5232
  </p-tabPanel>`,
5229
5233
  icon: 'pi pi-tags',
5230
5234
  inputProps: {
@@ -5238,10 +5242,10 @@ class DesignerComponent {
5238
5242
  group: 'CONTAINER',
5239
5243
  toolId: 1002,
5240
5244
  name: 'SPLITTER',
5241
- tag: `<p-splitter [attr.id]="uniqueName" [attr.title]="uniqueName" [direction]="inputs.direction" (dragEnd)="inputs.resize?.($event, this)" ngxDraggableDom="true" (moved)="onMoving($event, this)" ngResizable [rzHandles]="'se'" (rzResizing)="onResizing($event, this)" ${this.htmlStyleString.replace(/0/g, 'inputs')}>
5242
- <p-splitter-area *ngFor="let nestedArea of nestedComponents" [attr.id]="nestedArea.uniqueName" [attr.title]="uniqueName + ' - ' + nestedArea.uniqueName" [size]="nestedArea.inputs.size" ${this.htmlStyleString.replace(/0/g, 'nestedArea.inputs')}>
5243
- <wuic-dashboard [dashboardElements]="nestedArea.nestedComponents"></wuic-dashboard>
5244
- </p-splitter-area>
5245
+ tag: `<p-splitter [attr.id]="uniqueName" [attr.title]="uniqueName" [direction]="inputs.direction" (dragEnd)="inputs.resize?.($event, this)" ngxDraggableDom="true" (moved)="onMoving($event, this)" ngResizable [rzHandles]="'se'" (rzResizing)="onResizing($event, this)" ${this.htmlStyleString.replace(/0/g, 'inputs')}>
5246
+ <p-splitter-area *ngFor="let nestedArea of nestedComponents" [attr.id]="nestedArea.uniqueName" [attr.title]="uniqueName + ' - ' + nestedArea.uniqueName" [size]="nestedArea.inputs.size" ${this.htmlStyleString.replace(/0/g, 'nestedArea.inputs')}>
5247
+ <wuic-dashboard [dashboardElements]="nestedArea.nestedComponents"></wuic-dashboard>
5248
+ </p-splitter-area>
5245
5249
  </p-splitter>`,
5246
5250
  icon: 'pi pi-objects-column',
5247
5251
  inputProps: this.splitterProps,
@@ -5266,16 +5270,16 @@ class DesignerComponent {
5266
5270
  group: 'CONTAINER',
5267
5271
  toolId: 1004,
5268
5272
  name: 'ACCORDION',
5269
- tag: ` <cdk-accordion class="wuic-accordion-tab" [attr.id]="uniqueName" [attr.title]="uniqueName" (dragEnd)="inputs.resize?.($event, this)" ngxDraggableDom="true" (moved)="onMoving($event, this)" ngResizable [rzHandles]="'se'" (rzResizing)="onResizing($event, this)" ${this.htmlStyleString.replace(/0/g, 'inputs')}>
5270
- <cdk-accordion-item *ngFor="let nestedItem of nestedComponents" [attr.id]="nestedItem.uniqueName" [attr.title]="nestedItem.uniqueName"
5271
- ${this.htmlStyleString.replace(/0/g, 'nestedItem.inputs')}>
5272
- <div class="wuic-accordion-header">
5273
- <a class="wuic-accordion-header-link" (click)="inputs.toggle?.($event, this, nestedItem)">{{nestedItem.inputs.header}}</a>
5274
- </div>
5275
- <div class="wuic-accordion-content" [style.minHeight]="'40px'" [style.display]="nestedItem.inputs.expanded ? '' : 'none'">
5276
- <wuic-dashboard [dashboardElements]="nestedItem.nestedComponents"></wuic-dashboard>
5277
- </div>
5278
- </cdk-accordion-item>
5273
+ tag: ` <cdk-accordion class="wuic-accordion-tab" [attr.id]="uniqueName" [attr.title]="uniqueName" (dragEnd)="inputs.resize?.($event, this)" ngxDraggableDom="true" (moved)="onMoving($event, this)" ngResizable [rzHandles]="'se'" (rzResizing)="onResizing($event, this)" ${this.htmlStyleString.replace(/0/g, 'inputs')}>
5274
+ <cdk-accordion-item *ngFor="let nestedItem of nestedComponents" [attr.id]="nestedItem.uniqueName" [attr.title]="nestedItem.uniqueName"
5275
+ ${this.htmlStyleString.replace(/0/g, 'nestedItem.inputs')}>
5276
+ <div class="wuic-accordion-header">
5277
+ <a class="wuic-accordion-header-link" (click)="inputs.toggle?.($event, this, nestedItem)">{{nestedItem.inputs.header}}</a>
5278
+ </div>
5279
+ <div class="wuic-accordion-content" [style.minHeight]="'40px'" [style.display]="nestedItem.inputs.expanded ? '' : 'none'">
5280
+ <wuic-dashboard [dashboardElements]="nestedItem.nestedComponents"></wuic-dashboard>
5281
+ </div>
5282
+ </cdk-accordion-item>
5279
5283
  </cdk-accordion>`,
5280
5284
  icon: 'pi pi-server',
5281
5285
  inputProps: this.accordionProps,
@@ -5327,7 +5331,7 @@ class DesignerComponent {
5327
5331
  label: this.trslSrv.instant('load')
5328
5332
  },
5329
5333
  {
5330
- label: 'CSS',
5334
+ label: this.t('designer.css', 'CSS'),
5331
5335
  command: () => {
5332
5336
  this.openCssSheetEditor();
5333
5337
  }
@@ -5727,11 +5731,37 @@ class DesignerComponent {
5727
5731
  'blueprint',
5728
5732
  'extraProps'
5729
5733
  ]);
5730
- this.flattenComponentTree(this.dashboardElements).forEach((element) => {
5734
+ const serializationFlattened = this.flattenComponentTree(this.dashboardElements);
5735
+ serializationFlattened.forEach((element) => {
5731
5736
  if (element.name == 'DATASOURCE') {
5732
5737
  const componentRef = element?.inputs?.['componentRef']?.value?.component;
5733
5738
  const metaInfoFromRef = componentRef?.value?.metaInfo ?? componentRef?.metaInfo ?? null;
5734
- element.inputs['metaInfo'] = metaInfoFromRef;
5739
+ // Only overwrite metaInfo if we got a live reference; otherwise keep the
5740
+ // serialized copy so that undo/redo snapshots preserve the metadata.
5741
+ if (metaInfoFromRef) {
5742
+ element.inputs['metaInfo'] = metaInfoFromRef;
5743
+ }
5744
+ }
5745
+ // Normalize DATAREPEATER.datasource to a lightweight {uniqueName, component}
5746
+ // before serialization. Ensures uniqueName survives JSON round-trip.
5747
+ if (element.name === 'DATAREPEATER' || element.name === 'SELECT' || element.name === 'MULTISELECT' || element.name === 'UL') {
5748
+ const dsInput = element.inputs?.['datasource'];
5749
+ if (dsInput && typeof dsInput === 'object' && !(dsInput instanceof BehaviorSubject)) {
5750
+ // Case 1: full DS element (has inputs) — reduce to lightweight ref
5751
+ if (dsInput.uniqueName && dsInput.inputs) {
5752
+ element.inputs['datasource'] = {
5753
+ uniqueName: dsInput.uniqueName,
5754
+ component: dsInput.component ?? null
5755
+ };
5756
+ }
5757
+ // Case 2: already lightweight but missing uniqueName — recover from tree
5758
+ if (!dsInput.uniqueName && dsInput.component) {
5759
+ const firstDs = serializationFlattened.find((e) => e.name === 'DATASOURCE');
5760
+ if (firstDs?.uniqueName) {
5761
+ dsInput.uniqueName = firstDs.uniqueName;
5762
+ }
5763
+ }
5764
+ }
5735
5765
  }
5736
5766
  });
5737
5767
  return WtoolboxService.safeStringify(this.dashboardElements, function (key, value) {
@@ -5741,6 +5771,16 @@ class DesignerComponent {
5741
5771
  if (key == 'component' && (currentParentProp == 'componentRef' || currentParentProp == 'datasource' || currentParentProp == 'parentDatasource')) {
5742
5772
  return null;
5743
5773
  }
5774
+ // Also null-out live DataSourceComponent instances nested deeper in the tree
5775
+ // (e.g. DATAREPEATER.inputs.datasource.component) where currentParentProp
5776
+ // tracking loses context due to JSON.stringify's sequential key visitation.
5777
+ // The value may be the component directly OR a BehaviorSubject wrapping it.
5778
+ if (key === 'component' && value && typeof value === 'object') {
5779
+ const inner = (value instanceof BehaviorSubject) ? value.value : value;
5780
+ if (inner && typeof inner === 'object' && ('fetchInfo$' in inner || '__ngContext__' in inner)) {
5781
+ return null;
5782
+ }
5783
+ }
5744
5784
  currentParentProp = key;
5745
5785
  if (value instanceof BehaviorSubject) {
5746
5786
  return value.value === undefined ? null : value.value;
@@ -6025,35 +6065,94 @@ class DesignerComponent {
6025
6065
  * Ripristina lo snapshot precedente dalla history undo.
6026
6066
  */
6027
6067
  undo() {
6068
+ console.log(`[UNDO-v9] called. undoLen=${this.undoHistory.length} redoLen=${this.redoHistory.length} applyingHistory=${this.applyingHistory}`);
6028
6069
  if (this.applyingHistory || this.undoHistory.length === 0) {
6070
+ console.log(`[UNDO-v9] SKIP`);
6029
6071
  return;
6030
6072
  }
6031
- const target = this.undoHistory.pop();
6032
- if (!target) {
6033
- return;
6073
+ // Cancel any pending redo rebind timer
6074
+ if (this._redoRebindTimer) {
6075
+ clearTimeout(this._redoRebindTimer);
6076
+ this._redoRebindTimer = undefined;
6077
+ console.log(`[UNDO-v9] cancelled redo rebind timer`);
6078
+ }
6079
+ try {
6080
+ const target = this.undoHistory.pop();
6081
+ if (this.lastCommittedSnapshot) {
6082
+ this.redoHistory.push(this.lastCommittedSnapshot);
6083
+ }
6084
+ this.lastCommittedSnapshot = target;
6085
+ console.log(`[UNDO-v9] applying target. undoLen=${this.undoHistory.length} redoLen=${this.redoHistory.length}`);
6086
+ this.applyHistorySnapshot(target, false);
6034
6087
  }
6035
- if (this.lastCommittedSnapshot) {
6036
- this.redoHistory.push(this.lastCommittedSnapshot);
6088
+ catch (err) {
6037
6089
  }
6038
- this.applyHistorySnapshot(target);
6039
- this.lastCommittedSnapshot = target;
6040
6090
  }
6041
6091
  /**
6042
6092
  * Riapplica lo snapshot successivo dalla history redo.
6043
6093
  */
6044
6094
  redo() {
6095
+ console.log(`[REDO-v9] called. undoLen=${this.undoHistory.length} redoLen=${this.redoHistory.length} applyingHistory=${this.applyingHistory}`);
6045
6096
  if (this.applyingHistory || this.redoHistory.length === 0) {
6097
+ console.log(`[REDO-v9] SKIP`);
6046
6098
  return;
6047
6099
  }
6048
- const target = this.redoHistory.pop();
6049
- if (!target) {
6050
- return;
6100
+ try {
6101
+ const target = this.redoHistory.pop();
6102
+ if (this.lastCommittedSnapshot) {
6103
+ this.undoHistory.push(this.lastCommittedSnapshot);
6104
+ }
6105
+ console.log(`[REDO-v9] applying target. undoLen=${this.undoHistory.length} redoLen=${this.redoHistory.length}`);
6106
+ this.lastCommittedSnapshot = target;
6107
+ this.applyHistorySnapshot(target, true);
6108
+ // Re-bind DATAREPEATER→DATASOURCE after redo.
6109
+ // Cancel any previous pending rebind (e.g. if user does redo then undo quickly).
6110
+ if (this._redoRebindTimer) {
6111
+ clearTimeout(this._redoRebindTimer);
6112
+ }
6113
+ this._redoRebindTimer = setTimeout(() => {
6114
+ this._redoRebindTimer = undefined;
6115
+ console.log(`[REDO-REBIND-v9] timer fired. redoLen=${this.redoHistory.length} applyingHistory=${this.applyingHistory}`);
6116
+ // Skip if user already did undo since the redo
6117
+ if (this.redoHistory.length > 0 || this.applyingHistory) {
6118
+ console.log(`[REDO-REBIND-v9] SKIP`);
6119
+ return;
6120
+ }
6121
+ this.applyingHistory = true;
6122
+ try {
6123
+ const liveFlat = this.flattenedDashboardElements || [];
6124
+ liveFlat.forEach((el) => {
6125
+ if (el?.name === 'DATASOURCE') {
6126
+ const cr = el?.inputs?.['componentRef'];
6127
+ const crVal = (cr instanceof BehaviorSubject) ? cr.value : cr;
6128
+ const liveComp = crVal?.component instanceof BehaviorSubject
6129
+ ? crVal.component.value : crVal?.component;
6130
+ if (liveComp) {
6131
+ liveFlat.forEach((dr) => {
6132
+ if (dr?.name === 'DATAREPEATER' || dr?.name === 'SELECT' || dr?.name === 'MULTISELECT' || dr?.name === 'UL') {
6133
+ const dsRef = dr?.inputs?.['datasource'];
6134
+ if (dsRef?.uniqueName === el.uniqueName && dsRef?.component instanceof BehaviorSubject) {
6135
+ dsRef.component.next(liveComp);
6136
+ }
6137
+ }
6138
+ });
6139
+ if (liveComp.fetchData) {
6140
+ liveComp.fetchData();
6141
+ }
6142
+ }
6143
+ }
6144
+ });
6145
+ this.cd.detectChanges();
6146
+ }
6147
+ finally {
6148
+ this.applyingHistory = false;
6149
+ this._lastHistoryApplyTime = Date.now();
6150
+ }
6151
+ }, 1000);
6051
6152
  }
6052
- if (this.lastCommittedSnapshot) {
6053
- this.undoHistory.push(this.lastCommittedSnapshot);
6153
+ catch (err) {
6154
+ // redo error — ignore
6054
6155
  }
6055
- this.applyHistorySnapshot(target);
6056
- this.lastCommittedSnapshot = target;
6057
6156
  }
6058
6157
  /**
6059
6158
  * Gestisce shortcut globali undo/redo (`Ctrl/Cmd+Z`, `Ctrl/Cmd+Shift+Z`, `Ctrl/Cmd+Y`)
@@ -6090,27 +6189,32 @@ class DesignerComponent {
6090
6189
  * Chiude transazioni history pendenti da color picker al rilascio mouse.
6091
6190
  */
6092
6191
  onWindowMouseup() {
6093
- this.finalizePendingColorHistory();
6094
- this.commitHistoryIfChanged();
6192
+ if (!this.finalizePendingColorHistory()) {
6193
+ // Do NOT call commitHistoryIfChanged here — mouseup fires BEFORE click,
6194
+ // so clicking Undo/Redo buttons triggers a commit that clears redoHistory
6195
+ // before the (click) handler runs. Commits are already handled by
6196
+ // setValue, drop, and removeElementByName.
6197
+ }
6095
6198
  }
6096
6199
  /**
6097
6200
  * Variante touch di finalizzazione history pendente.
6098
6201
  */
6099
6202
  onWindowTouchend() {
6100
- this.finalizePendingColorHistory();
6101
- this.commitHistoryIfChanged();
6203
+ if (!this.finalizePendingColorHistory()) {
6204
+ }
6102
6205
  }
6103
6206
  /**
6104
6207
  * Esegue commit history su modifiche input concluse da tastiera.
6105
6208
  */
6106
6209
  onWindowKeyup() {
6107
- this.commitHistoryIfChanged();
6108
6210
  }
6109
6211
  /**
6110
6212
  * Esegue commit history su eventi `change` globali dei controlli.
6111
6213
  */
6112
6214
  onWindowChange() {
6113
- this.commitHistoryIfChanged();
6215
+ // Removed commitHistoryIfChanged — change events from inputs during
6216
+ // undo/redo rehydration cause spurious commits that clear redoHistory.
6217
+ // Commits are already triggered by setValue, drop, mouseup, etc.
6114
6218
  }
6115
6219
  get currentDashboardTitle() {
6116
6220
  const route = String(this.currentDashboardRoute || '').trim();
@@ -6222,22 +6326,22 @@ class DesignerComponent {
6222
6326
  refreshGraphActionsMenuItems() {
6223
6327
  this.graphActionsMenuItems = [
6224
6328
  {
6225
- label: 'Riapri',
6329
+ label: this.t('designer.menu_reopen', 'Riapri'),
6226
6330
  icon: 'pi pi-folder-open',
6227
6331
  command: () => this.openReopenDashboardDialog()
6228
6332
  },
6229
6333
  {
6230
- label: 'Nuovo grafo',
6334
+ label: this.t('designer.menu_new', 'Nuovo grafo'),
6231
6335
  icon: 'pi pi-file',
6232
6336
  command: () => this.onToolbarNewDashboard()
6233
6337
  },
6234
6338
  {
6235
- label: 'Salva grafo',
6339
+ label: this.t('designer.menu_save', 'Salva grafo'),
6236
6340
  icon: 'pi pi-save',
6237
6341
  command: () => this.onToolbarSaveDashboard()
6238
6342
  },
6239
6343
  {
6240
- label: 'Elimina',
6344
+ label: this.t('designer.menu_delete', 'Elimina'),
6241
6345
  icon: 'pi pi-trash',
6242
6346
  disabled: !this.currentDashboardRoute,
6243
6347
  command: () => this.onToolbarDeleteDashboard()
@@ -6246,7 +6350,9 @@ class DesignerComponent {
6246
6350
  separator: true
6247
6351
  },
6248
6352
  {
6249
- label: this.hideDatasourcesInCanvas ? 'Mostra datasource nel canvas' : 'Nascondi datasource nel canvas',
6353
+ label: this.hideDatasourcesInCanvas
6354
+ ? this.t('designer.menu_show_datasources', 'Mostra datasource nel canvas')
6355
+ : this.t('designer.menu_hide_datasources', 'Nascondi datasource nel canvas'),
6250
6356
  icon: this.hideDatasourcesInCanvas ? 'pi pi-eye' : 'pi pi-eye-slash',
6251
6357
  command: () => this.toggleHideDatasourcesInCanvas()
6252
6358
  }
@@ -7176,7 +7282,7 @@ class DesignerComponent {
7176
7282
  buildFieldEditorContextMenuItems(field, ds) {
7177
7283
  return [
7178
7284
  {
7179
- label: 'Apri metadato colonna',
7285
+ label: this.t('designer.ctx_open_column_metadata', 'Apri metadato colonna'),
7180
7286
  icon: 'pi pi-external-link',
7181
7287
  command: () => {
7182
7288
  void this.metadataEditorSrv.openMetadataColumnEditorInContext(field, this.metaSrv, ds)
@@ -7184,7 +7290,7 @@ class DesignerComponent {
7184
7290
  }
7185
7291
  },
7186
7292
  {
7187
- label: 'Sposta in nuovo Tab',
7293
+ label: this.t('designer.ctx_move_to_new_tab', 'Sposta in nuovo Tab'),
7188
7294
  icon: 'pi pi-folder-open',
7189
7295
  command: () => {
7190
7296
  void this.moveContextFieldToNewTab(field, ds)
@@ -7192,7 +7298,7 @@ class DesignerComponent {
7192
7298
  }
7193
7299
  },
7194
7300
  {
7195
- label: 'Sposta in tab esistente',
7301
+ label: this.t('designer.ctx_move_to_existing_tab', 'Sposta in tab esistente'),
7196
7302
  icon: 'pi pi-list',
7197
7303
  command: () => {
7198
7304
  void this.moveContextFieldToExistingTab(field, ds)
@@ -7205,9 +7311,9 @@ class DesignerComponent {
7205
7311
  * Prompt nome tab e aggiorna `mc_edit_associated_tab` della colonna nel datasource designer.
7206
7312
  */
7207
7313
  async moveContextFieldToNewTab(field, ds) {
7208
- const promptResult = await WtoolboxService.promptDialog('Sposta in nuovo Tab', [{
7314
+ const promptResult = await WtoolboxService.promptDialog(this.t('designer.ctx_move_to_new_tab', 'Sposta in nuovo Tab'), [{
7209
7315
  name: 'tabName',
7210
- caption: 'Nome Tab',
7316
+ caption: this.t('designer.tab_name_caption', 'Nome Tab'),
7211
7317
  type: 'text',
7212
7318
  required: true,
7213
7319
  value: this.getAssociatedTabValue(field)
@@ -7685,8 +7791,21 @@ class DesignerComponent {
7685
7791
  if (tool.inputs[toolProp.key] == $event) {
7686
7792
  return;
7687
7793
  }
7688
- if (toolProp.value.asyncPath && !($event[toolProp.value.asyncPath] instanceof BehaviorSubject)) {
7689
- $event[toolProp.value.asyncPath] = new BehaviorSubject($event.inputs.componentRef.value.component);
7794
+ if (toolProp.value.asyncPath) {
7795
+ // For dropped-component-list (e.g. DATAREPEATER.datasource), store a lightweight
7796
+ // reference {uniqueName, component: BS(liveComp)} instead of the full element.
7797
+ // The full element contains circular references and Angular internals that break
7798
+ // JSON serialization and produce snapshots missing the uniqueName.
7799
+ const liveComp = $event?.inputs?.componentRef?.value?.component
7800
+ ?? $event?.inputs?.componentRef?.component
7801
+ ?? null;
7802
+ const compBs = ($event[toolProp.value.asyncPath] instanceof BehaviorSubject)
7803
+ ? $event[toolProp.value.asyncPath]
7804
+ : new BehaviorSubject(liveComp);
7805
+ $event = {
7806
+ uniqueName: $event.uniqueName,
7807
+ [toolProp.value.asyncPath]: compBs
7808
+ };
7690
7809
  }
7691
7810
  tool.inputs[toolProp.key] = $event;
7692
7811
  }
@@ -8366,35 +8485,35 @@ class DesignerComponent {
8366
8485
  const detailCommentRows = detailColumns.length
8367
8486
  ? detailColumns.map((col) => `- ${col}`).join('\n')
8368
8487
  : '- (no detail columns available yet)';
8369
- return `
8370
- declare type MasterDataItem = {
8371
- ${buildTypeRows(masterColumns, '[key: string]')}
8372
- };
8373
-
8374
- declare type DetailFilter = {
8375
- field: string;
8376
- operatore?: string;
8377
- value: any;
8378
- fixed?: boolean;
8379
- };
8380
-
8381
- declare const dataItem: MasterDataItem;
8382
- declare const detailColumns: string[];
8383
- declare function setFilter(field: string, value: any, operatore?: string, fixed?: boolean): void;
8384
- declare const currentFilters: DetailFilter[];
8385
- declare const detailDatasource: DataSourceComponent;
8386
- declare const masterDatasource: DataSourceComponent;
8387
- declare const wtoolbox: typeof WtoolboxService;
8388
-
8389
- /*
8390
- Master-detail formula context:
8391
- - master route: ${masterRoute || 'n/a'}
8392
- - detail route: ${detailRoute || 'n/a'}
8393
- - Use dataItem.<masterColumn> with autocomplete
8394
-
8395
- Detail columns:
8396
- ${detailCommentRows}
8397
- */
8488
+ return `
8489
+ declare type MasterDataItem = {
8490
+ ${buildTypeRows(masterColumns, '[key: string]')}
8491
+ };
8492
+
8493
+ declare type DetailFilter = {
8494
+ field: string;
8495
+ operatore?: string;
8496
+ value: any;
8497
+ fixed?: boolean;
8498
+ };
8499
+
8500
+ declare const dataItem: MasterDataItem;
8501
+ declare const detailColumns: string[];
8502
+ declare function setFilter(field: string, value: any, operatore?: string, fixed?: boolean): void;
8503
+ declare const currentFilters: DetailFilter[];
8504
+ declare const detailDatasource: DataSourceComponent;
8505
+ declare const masterDatasource: DataSourceComponent;
8506
+ declare const wtoolbox: typeof WtoolboxService;
8507
+
8508
+ /*
8509
+ Master-detail formula context:
8510
+ - master route: ${masterRoute || 'n/a'}
8511
+ - detail route: ${detailRoute || 'n/a'}
8512
+ - Use dataItem.<masterColumn> with autocomplete
8513
+
8514
+ Detail columns:
8515
+ ${detailCommentRows}
8516
+ */
8398
8517
  `;
8399
8518
  }
8400
8519
  /**
@@ -8412,33 +8531,33 @@ ${detailCommentRows}
8412
8531
  }).join('\n')
8413
8532
  : ' [key: string]: any;';
8414
8533
  const routeComment = routeName ? `route: ${routeName}` : 'route: n/a';
8415
- return `
8416
- declare type SelectOptionRecord = {
8417
- ${optionProps}
8418
- };
8419
-
8420
- declare type SelectDisplayFormulaFn = (
8421
- dataItem: SelectOptionRecord,
8422
- record: {[key: string]: BehaviorSubject<any>},
8423
- datasource: DataSourceComponent,
8424
- inputs: any,
8425
- wtoolbox: typeof WtoolboxService
8426
- ) => string;
8427
-
8428
- declare const dataItem: SelectOptionRecord;
8429
- declare const record: {[key: string]: BehaviorSubject<any>};
8430
- declare const datasource: DataSourceComponent;
8431
- declare const inputs: any;
8432
- declare const wtoolbox: typeof WtoolboxService;
8433
-
8434
- /*
8435
- Display formula context:
8436
- - ${routeComment}
8437
- - dataItem: current datasource row
8438
- - record: datasource.resultInfo.current (BehaviorSubject-based)
8439
- - datasource: datasource component bound to this select
8440
- - inputs: select inputs (valueField, textField, ...)
8441
- */
8534
+ return `
8535
+ declare type SelectOptionRecord = {
8536
+ ${optionProps}
8537
+ };
8538
+
8539
+ declare type SelectDisplayFormulaFn = (
8540
+ dataItem: SelectOptionRecord,
8541
+ record: {[key: string]: BehaviorSubject<any>},
8542
+ datasource: DataSourceComponent,
8543
+ inputs: any,
8544
+ wtoolbox: typeof WtoolboxService
8545
+ ) => string;
8546
+
8547
+ declare const dataItem: SelectOptionRecord;
8548
+ declare const record: {[key: string]: BehaviorSubject<any>};
8549
+ declare const datasource: DataSourceComponent;
8550
+ declare const inputs: any;
8551
+ declare const wtoolbox: typeof WtoolboxService;
8552
+
8553
+ /*
8554
+ Display formula context:
8555
+ - ${routeComment}
8556
+ - dataItem: current datasource row
8557
+ - record: datasource.resultInfo.current (BehaviorSubject-based)
8558
+ - datasource: datasource component bound to this select
8559
+ - inputs: select inputs (valueField, textField, ...)
8560
+ */
8442
8561
  `;
8443
8562
  }
8444
8563
  /**
@@ -9030,6 +9149,14 @@ Display formula context:
9030
9149
  }
9031
9150
  }
9032
9151
  }
9152
+ if (!destination) {
9153
+ WtoolboxService.messageNotificationService.add({
9154
+ severity: 'error',
9155
+ summary: this.t('error', 'Error'),
9156
+ detail: this.t('designer.invalid_child_component', 'Invalid child component')
9157
+ });
9158
+ return;
9159
+ }
9033
9160
  destination.push(currentTool);
9034
9161
  if (currentTool.onDrop) {
9035
9162
  currentTool.onDrop(currentTool);
@@ -9301,6 +9428,17 @@ Display formula context:
9301
9428
  dragEnd() {
9302
9429
  this.draggedPayload = null;
9303
9430
  }
9431
+ /**
9432
+ * Double-click su un tool nella palette: lo droppa al primo livello (root) del canvas,
9433
+ * senza nesting. Simula il flusso drag+drop ma forza destination = dashboardElements.
9434
+ */
9435
+ dropToolAtRoot(payload) {
9436
+ if (this.noEdit) {
9437
+ return;
9438
+ }
9439
+ this.draggedPayload = payload;
9440
+ this.drop({ toElement: null });
9441
+ }
9304
9442
  /**
9305
9443
  * Salva il dashboard corrente tramite `dataSrv.saveDashboard` -> server `MetaService.saveDashboard`.
9306
9444
  * Mapping persistenza verificato su `Kiara_wuic_new.dbo.dom_board`:
@@ -9394,7 +9532,7 @@ Display formula context:
9394
9532
  * e ricostruisce lo stato runtime del designer partendo da `dom_board.boardcontent`.
9395
9533
  * Supporta route in forme alias (`board_route`, `boardroute`, `dashRoute`).
9396
9534
  */
9397
- async loadDashboard(dashboard) {
9535
+ async loadDashboard(dashboard, skipServerFetch = false) {
9398
9536
  const dashRoute = String(dashboard?.board_route ??
9399
9537
  dashboard?.boardroute ??
9400
9538
  dashboard?.boardRoute ??
@@ -9417,14 +9555,17 @@ Display formula context:
9417
9555
  }
9418
9556
  this.currentDashboardRoute = dashRoute;
9419
9557
  this.refreshGraphActionsMenuItems();
9420
- var payload = {
9421
- user_id: this.userInfo.getuserInfo().user_id,
9422
- dashRoute: dashRoute
9423
- };
9424
- var result = await this.dataSrv.loadDashboard(payload);
9425
- const resultRows = Array.isArray(result)
9426
- ? result
9427
- : (Array.isArray(result?.results) ? result.results : (result ? [result] : []));
9558
+ let resultRows = [];
9559
+ if (!skipServerFetch) {
9560
+ var payload = {
9561
+ user_id: this.userInfo.getuserInfo().user_id,
9562
+ dashRoute: dashRoute
9563
+ };
9564
+ var result = await this.dataSrv.loadDashboard(payload);
9565
+ resultRows = Array.isArray(result)
9566
+ ? result
9567
+ : (Array.isArray(result?.results) ? result.results : (result ? [result] : []));
9568
+ }
9428
9569
  this.currentDashboardDescription = String(dashboard?.board_des ??
9429
9570
  dashboard?.boarddes ??
9430
9571
  resultRows?.[0]?.board_des ??
@@ -9536,6 +9677,7 @@ Display formula context:
9536
9677
  var dsElement = flattened.find(x => x.uniqueName == v.uniqueName);
9537
9678
  if (dsElement) {
9538
9679
  if (ds.component instanceof BehaviorSubject) {
9680
+ console.log(`[SUBSCRIBE-CHAIN-LOAD-v9] pushing liveComp into DR.datasource.component for ${ds.uniqueName}`);
9539
9681
  ds.component.next(v.component);
9540
9682
  if (dsElement.inputs['parentDatasource'] instanceof BehaviorSubject) {
9541
9683
  var dsParent = (dsElement.inputs['parentDatasource'] instanceof BehaviorSubject) ? dsElement.inputs['parentDatasource'].value : dsElement.inputs['parentDatasource'];
@@ -9553,7 +9695,7 @@ Display formula context:
9553
9695
  if (dsElements.length == dsElementCount) {
9554
9696
  combineLatest(dsSubs).subscribe((infos) => {
9555
9697
  infos.forEach((info, i) => {
9556
- if (info && dsElements[i].inputs['metaInfo']) {
9698
+ if (info?.metaInfo && dsElements[i].inputs['metaInfo']) {
9557
9699
  Object.assign(info.metaInfo, dsElements[i].inputs['metaInfo']);
9558
9700
  dsElements[i].inputs['metaInfo'] = null;
9559
9701
  }
@@ -9564,6 +9706,11 @@ Display formula context:
9564
9706
  this.propertyTreeBuilder(ld.inputs['action'].value, ld.inputs);
9565
9707
  }
9566
9708
  });
9709
+ // All DataSources loaded — re-capture the history snapshot
9710
+ // so it includes the full metaInfo. Without this, the initial
9711
+ // snapshot captured by resetHistory() has empty metaInfo because
9712
+ // the DS fetch is async.
9713
+ this.lastCommittedSnapshot = this.captureHistorySnapshot();
9567
9714
  });
9568
9715
  }
9569
9716
  }
@@ -9618,6 +9765,11 @@ Display formula context:
9618
9765
  if (this.applyingHistory || this.noEdit) {
9619
9766
  return;
9620
9767
  }
9768
+ // Skip commit right after undo/redo — the rehydration triggers change
9769
+ // events that would create spurious snapshots and clear redoHistory.
9770
+ if (Date.now() - this._lastHistoryApplyTime < 500) {
9771
+ return;
9772
+ }
9621
9773
  const current = this.captureHistorySnapshot();
9622
9774
  const previous = this.lastCommittedSnapshot;
9623
9775
  if (!previous) {
@@ -9632,7 +9784,9 @@ Display formula context:
9632
9784
  if (this.undoHistory.length > this.maxHistoryLength) {
9633
9785
  this.undoHistory.shift();
9634
9786
  }
9635
- this.redoHistory = [];
9787
+ if (!this._suppressRedoClear) {
9788
+ this.redoHistory = [];
9789
+ }
9636
9790
  this.lastCommittedSnapshot = current;
9637
9791
  }
9638
9792
  /**
@@ -9646,17 +9800,25 @@ Display formula context:
9646
9800
  this.pendingColorHistoryDirty = false;
9647
9801
  }
9648
9802
  /**
9649
- * Applica uno snapshot storico deserializzando gli elementi e ripristinando la selezione.
9803
+ * Applica uno snapshot storico usando lo stesso codepath di loadDashboard.
9804
+ * Passa il serializedElements come boardcontent finto, preservando la route corrente.
9650
9805
  */
9651
- applyHistorySnapshot(snapshot) {
9806
+ applyHistorySnapshot(snapshot, isRedo = false) {
9652
9807
  this.applyingHistory = true;
9808
+ // Destroy + recreate synchronously so applyingHistory stays true
9809
+ // through the entire operation and mouseup doesn't clear redoHistory.
9653
9810
  try {
9811
+ this.dashboardElements = [];
9812
+ this.flattenedDashboardElements = [];
9813
+ this.cd.detectChanges();
9654
9814
  this.applySerializedDashboardElements(snapshot?.serializedElements || '[]', snapshot?.selectedUniqueName || null);
9655
9815
  }
9656
9816
  finally {
9657
- this.applyingHistory = false;
9658
9817
  this.pendingColorHistoryBase = null;
9659
9818
  this.pendingColorHistoryDirty = false;
9819
+ this.lastCommittedSnapshot = snapshot;
9820
+ this.applyingHistory = false;
9821
+ this._lastHistoryApplyTime = Date.now();
9660
9822
  }
9661
9823
  }
9662
9824
  /**
@@ -9664,10 +9826,11 @@ Display formula context:
9664
9826
  */
9665
9827
  finalizePendingColorHistory() {
9666
9828
  if (this.applyingHistory || !this.pendingColorHistoryBase || !this.pendingColorHistoryDirty) {
9667
- return;
9829
+ return false;
9668
9830
  }
9669
9831
  const current = this.captureHistorySnapshot();
9670
9832
  const base = this.pendingColorHistoryBase;
9833
+ let committed = false;
9671
9834
  if (base.serializedElements !== current.serializedElements) {
9672
9835
  this.undoHistory.push(base);
9673
9836
  if (this.undoHistory.length > this.maxHistoryLength) {
@@ -9675,9 +9838,11 @@ Display formula context:
9675
9838
  }
9676
9839
  this.redoHistory = [];
9677
9840
  this.lastCommittedSnapshot = current;
9841
+ committed = true;
9678
9842
  }
9679
9843
  this.pendingColorHistoryBase = null;
9680
9844
  this.pendingColorHistoryDirty = false;
9845
+ return committed;
9681
9846
  }
9682
9847
  /**
9683
9848
  * Ripristina il designer da JSON serializzato:
@@ -9701,6 +9866,11 @@ Display formula context:
9701
9866
  }
9702
9867
  this.mergeMissingToolPropsRecursive(loadedDashboard);
9703
9868
  this.dashboardComponents = [];
9869
+ // Use the same DS tracking / combineLatest rehydration path as loadDashboard
9870
+ // so that DATASOURCE ↔ DATAREPEATER bindings are fully restored on undo/redo.
9871
+ const dsSubs = [];
9872
+ const dsElements = [];
9873
+ const dsElementCount = (loadedDashboard || []).filter((x) => x?.name === 'DATASOURCE').length;
9704
9874
  const flattened = this.flattenComponentTree(loadedDashboard);
9705
9875
  flattened.forEach((element) => {
9706
9876
  if (element?.inputs && element.inputs['cssClass'] !== undefined) {
@@ -9711,6 +9881,16 @@ Display formula context:
9711
9881
  if (normalizedAction) {
9712
9882
  element.inputs['action'] = normalizedAction;
9713
9883
  }
9884
+ else {
9885
+ const inferredFromCustom = Object.keys(element?.inputs || {})
9886
+ .find((k) => k.startsWith('customProps_') && element.inputs[k] != null);
9887
+ if (inferredFromCustom) {
9888
+ const inferredAction = this.normalizeArchetypeAction(inferredFromCustom.replace('customProps_', ''));
9889
+ if (inferredAction) {
9890
+ element.inputs['action'] = inferredAction;
9891
+ }
9892
+ }
9893
+ }
9714
9894
  this.ensureDataRepeaterTagSupportsHideToolbar(element);
9715
9895
  this.ensureDataRepeaterHideToolbar(element);
9716
9896
  this.ensureDataRepeaterRowCustomSelect(element);
@@ -9728,8 +9908,27 @@ Display formula context:
9728
9908
  const customProps = Object.keys(element?.inputs || {}).filter((x) => x.startsWith('customProps_'));
9729
9909
  customProps.forEach((prop) => this.hidrateCustomPropsRecursive(element.inputs[prop]));
9730
9910
  Object.keys(element?.inputProps || {}).forEach((prop) => {
9731
- if (element.inputProps[prop].async) {
9732
- if (element.inputProps[prop].type == 'dropped-component') {
9911
+ const propDef = element.inputProps[prop];
9912
+ // Hydrate dropped-component-list props (e.g. DATAREPEATER.datasource) that have
9913
+ // asyncPath but no async flag. Ensure the inner path (e.g. 'component') is a
9914
+ // BehaviorSubject so the DS→DR binding can be reconnected when Angular creates
9915
+ // the live DataSourceComponent. Do NOT wrap the outer value in a BS — the runtime
9916
+ // expects datasource to remain a plain object {uniqueName, component: BS(...)}.
9917
+ if (!propDef.async && propDef.asyncPath && (propDef.type === 'dropped-component-list' || propDef.type === 'dropped-component')) {
9918
+ const path = propDef.asyncPath;
9919
+ const rawValue = element.inputs[prop];
9920
+ console.log(`[HYDRATE-v9] ${element.name}.${prop}: rawValue=${rawValue === null ? 'NULL' : rawValue === undefined ? 'UNDEF' : 'object'} uniqueName=${rawValue?.uniqueName} keys=${rawValue ? Object.keys(rawValue) : '[]'}`);
9921
+ if (rawValue && typeof rawValue === 'object' && !(rawValue instanceof BehaviorSubject)) {
9922
+ // Only hydrate the component BS — do NOT invent a uniqueName if the
9923
+ // snapshot didn't have one. That would create a false binding on undo.
9924
+ if (!(rawValue[path] instanceof BehaviorSubject)) {
9925
+ rawValue[path] = new BehaviorSubject(rawValue[path] ?? null);
9926
+ console.log(`[HYDRATE-v9] created BS for ${path}`);
9927
+ }
9928
+ }
9929
+ }
9930
+ if (propDef.async) {
9931
+ if (propDef.type == 'dropped-component') {
9733
9932
  const currentValue = element.inputs[prop];
9734
9933
  element.inputs[prop] = new BehaviorSubject({
9735
9934
  component: currentValue?.component ?? currentValue ?? null,
@@ -9738,8 +9937,8 @@ Display formula context:
9738
9937
  uniqueName: element.uniqueName
9739
9938
  });
9740
9939
  }
9741
- else if (element.inputProps[prop].asyncPath) {
9742
- const path = element.inputProps[prop].asyncPath;
9940
+ else if (propDef.asyncPath) {
9941
+ const path = propDef.asyncPath;
9743
9942
  const rawValue = element.inputs[prop] ?? {};
9744
9943
  element.inputs[prop] = new BehaviorSubject({
9745
9944
  ...rawValue,
@@ -9765,8 +9964,45 @@ Display formula context:
9765
9964
  if (dsProp) {
9766
9965
  const dsBs = x.inputs[dsProp];
9767
9966
  const ds = (dsBs instanceof BehaviorSubject) ? dsBs.value : dsBs;
9768
- if (ds && ds.uniqueName == v.uniqueName && ds.component instanceof BehaviorSubject) {
9769
- ds.component.next(v.component);
9967
+ if (ds && ds.uniqueName == v.uniqueName) {
9968
+ const dsElement = flattened.find(fe => fe.uniqueName == v.uniqueName);
9969
+ if (dsElement) {
9970
+ if (ds.component instanceof BehaviorSubject) {
9971
+ console.log(`[SUBSCRIBE-CHAIN-v9] pushing liveComp into DR.datasource.component for ${ds.uniqueName}. applyingHistory=${this.applyingHistory}`);
9972
+ ds.component.next(v.component);
9973
+ if (dsElement.inputs['parentDatasource'] instanceof BehaviorSubject) {
9974
+ const dsParent = (dsElement.inputs['parentDatasource'] instanceof BehaviorSubject) ? dsElement.inputs['parentDatasource'].value : dsElement.inputs['parentDatasource'];
9975
+ if (dsParent?.uniqueName) {
9976
+ const parentElement = flattened.find(fe => fe.uniqueName == dsParent.uniqueName);
9977
+ if (parentElement) {
9978
+ dsParent.component.next(parentElement.inputs['componentRef'] instanceof BehaviorSubject ? parentElement.inputs['componentRef'].value : parentElement.inputs['componentRef']);
9979
+ }
9980
+ }
9981
+ }
9982
+ }
9983
+ if (!dsElements.find(de => de.uniqueName == v.uniqueName)) {
9984
+ dsSubs.push(v.component.fetchInfo$);
9985
+ dsElements.push(dsElement);
9986
+ if (dsElements.length == dsElementCount) {
9987
+ combineLatest(dsSubs).subscribe((infos) => {
9988
+ infos.forEach((info, i) => {
9989
+ if (info?.metaInfo && dsElements[i].inputs['metaInfo']) {
9990
+ Object.assign(info.metaInfo, dsElements[i].inputs['metaInfo']);
9991
+ dsElements[i].inputs['metaInfo'] = null;
9992
+ }
9993
+ });
9994
+ flattened.forEach((ld) => {
9995
+ if (ld.inputs['propertyTree']) {
9996
+ ld.inputs['propertyTree'] = new BehaviorSubject([]);
9997
+ this.propertyTreeBuilder(ld.inputs['action'].value, ld.inputs);
9998
+ }
9999
+ });
10000
+ // Re-capture snapshot after DS load (same as loadDashboard path)
10001
+ this.lastCommittedSnapshot = this.captureHistorySnapshot();
10002
+ });
10003
+ }
10004
+ }
10005
+ }
9770
10006
  }
9771
10007
  }
9772
10008
  });
@@ -9790,6 +10026,59 @@ Display formula context:
9790
10026
  ? (this.flattenedDashboardElements || []).find((x) => x?.uniqueName === selectedUniqueName) || null
9791
10027
  : null;
9792
10028
  this.cd.detectChanges();
10029
+ // After undo/redo, re-bind DATAREPEATER→DATASOURCE and force re-fetch.
10030
+ // This runs after Angular has created the live DataSourceComponent instances.
10031
+ if (this.applyingHistory) {
10032
+ setTimeout(() => {
10033
+ const liveFlat = this.flattenedDashboardElements || [];
10034
+ // Collect live DataSourceComponents by uniqueName
10035
+ const liveDataSources = {};
10036
+ liveFlat.forEach((el) => {
10037
+ if (el?.name === 'DATASOURCE') {
10038
+ const cr = el?.inputs?.['componentRef'];
10039
+ const crVal = (cr instanceof BehaviorSubject) ? cr.value : cr;
10040
+ const liveComp = crVal?.component instanceof BehaviorSubject
10041
+ ? crVal.component.value
10042
+ : crVal?.component;
10043
+ if (liveComp) {
10044
+ liveDataSources[el.uniqueName] = liveComp;
10045
+ if (liveComp.fetchData) {
10046
+ liveComp.fetchData();
10047
+ }
10048
+ }
10049
+ }
10050
+ });
10051
+ // Re-bind DATAREPEATERs: replicate the same binding that loadDashboard
10052
+ // and setValue do — get the live DataSourceComponent from the DS element's
10053
+ // componentRef and push it into the DATAREPEATER's datasource.component BS.
10054
+ liveFlat.forEach((el) => {
10055
+ if (el?.name === 'DATAREPEATER' || el?.name === 'SELECT' || el?.name === 'MULTISELECT' || el?.name === 'UL') {
10056
+ const dsRef = el?.inputs?.['datasource'];
10057
+ const dsUniqueName = dsRef?.uniqueName;
10058
+ if (dsUniqueName) {
10059
+ const dsElement = liveFlat.find((e) => e.uniqueName === dsUniqueName);
10060
+ if (dsElement) {
10061
+ // Get the live DataSourceComponent from componentRef — same path as setValue line 4078
10062
+ const crBs = dsElement.inputs?.['componentRef'];
10063
+ const crVal = (crBs instanceof BehaviorSubject) ? crBs.value : crBs;
10064
+ const liveComponent = crVal?.component instanceof BehaviorSubject
10065
+ ? crVal.component.value
10066
+ : crVal?.component;
10067
+ if (liveComponent) {
10068
+ if (!(dsRef.component instanceof BehaviorSubject)) {
10069
+ dsRef.component = new BehaviorSubject(liveComponent);
10070
+ }
10071
+ else {
10072
+ dsRef.component.next(liveComponent);
10073
+ }
10074
+ }
10075
+ }
10076
+ }
10077
+ }
10078
+ });
10079
+ this.cd.detectChanges();
10080
+ }, 300);
10081
+ }
9793
10082
  }
9794
10083
  /**
9795
10084
  * Rileva se il target evento e un controllo di input/editable per evitare shortcut globali indesiderate.
@@ -10169,7 +10458,7 @@ Display formula context:
10169
10458
  }
10170
10459
  const base = window.location.href.split('#')[0];
10171
10460
  const url = `${base}#/${encodeURIComponent(route)}/dashboard`;
10172
- window.open(url, '_blank', 'noopener');
10461
+ window.open(url, '_blank');
10173
10462
  }
10174
10463
  /**
10175
10464
  * Idrata ricorsivamente `customProps` convertendo i valori in `BehaviorSubject`
@@ -10186,12 +10475,12 @@ Display formula context:
10186
10475
  });
10187
10476
  // return customProps;
10188
10477
  }
10189
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DesignerComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: DataProviderService }, { token: MetadataProviderService }, { token: UserInfoService }, { token: i0.ChangeDetectorRef }, { token: TranslationManagerService }, { token: MetadataEditorService }, { token: WorkflowRuntimeMetadataService }], target: i0.ɵɵFactoryTarget.Component });
10190
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DesignerComponent, isStandalone: true, selector: "wuic-designer", host: { listeners: { "window:hashchange": "onWindowHashChange()", "window:beforeunload": "onWindowBeforeUnload($event)", "window:keydown": "onWindowKeydown($event)", "window:mouseup": "onWindowMouseup()", "window:touchend": "onWindowTouchend()", "window:keyup": "onWindowKeyup()", "window:change": "onWindowChange()" } }, providers: [TreeDragDropService], ngImport: i0, template: "<!-- <button pButton type=\"button\" (click)=\"loadDashboard()\" class=\"mr-2\">{{'load' | translate}}</button> -->\n@if (!noEdit) {\n<div class=\"designer-layout\">\n <div class=\"designer-toolbar\">\n <div class=\"designer-current-dashboard\">{{ currentDashboardTitle }}</div>\n\n <div class=\"designer-toolbar-spacer\"></div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"undo()\" [disabled]=\"!canUndo\">{{ 'designer.undo' | translate }}</button>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"redo()\" [disabled]=\"!canRedo\">{{ 'designer.redo' | translate }}</button>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"graphActionsMenu.toggle($event)\">{{ 'designer.actions_menu' | translate }}</button>\n <p-menu #graphActionsMenu [popup]=\"true\" [model]=\"graphActionsMenuItems\" appendTo=\"body\"></p-menu>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"openCurrentDashboardInNewTab()\" [disabled]=\"!currentDashboardRoute\">{{ 'designer.open_current_dashboard' | translate }}</button>\n </div>\n </div>\n <div class=\"designer-main\">\n <p-splitter [style]=\"{ height: '100%' }\" [panelSizes]=\"[15, 85]\" styleClass=\"designer-main-splitter\">\n <ng-template pTemplate>\n <p-splitter layout=\"vertical\" [style]=\"{ height: '100%', width: '100%' }\" [panelSizes]=\"[35, 65]\"\n [minSizes]=\"[20, 30]\" styleClass=\"designer-left-splitter\">\n <ng-template pTemplate>\n <div class=\"col flex designer-toolbox palette-panel\">\n <ul class=\"tool-groups\">\n @for (toolGroup of availableToolGroups; track toolGroup.group) {\n <li class=\"tool-group-item\">\n <div class=\"tool-group-title\">{{ toolGroup.group }}</div>\n <ul class=\"tool-group-list\">\n @for (tool of toolGroup.tools; track tool) {\n <li pDraggable (onDragStart)=\"dragStart(tool)\" (onDragEnd)=\"dragEnd()\" (onDrag)=\"onDrag($event)\">\n <i [ngClass]=\"tool.icon\" [title]=\"tool.name\"></i>\n </li>\n }\n </ul>\n </li>\n }\n </ul>\n </div>\n </ng-template>\n <ng-template pTemplate>\n <p-splitter layout=\"vertical\" [style]=\"{ height: '100%', width: '100%' }\" [panelSizes]=\"[68, 32]\"\n [minSizes]=\"[35, 20]\" styleClass=\"designer-left-bottom-splitter\">\n <ng-template pTemplate>\n <div class=\"properties-panel\">\n <p-select [style]=\"{width: '100%'}\" [options]=\"flattenedDashboardElements\" [(ngModel)]=\"tool\"\n optionLabel=\"uniqueName\" dataKey=\"componentId\" appendTo=\"body\" />\n <div class=\"col designer-toolbox\">\n @for (section of getToolPropertySections(tool); track section.key) {\n <details class=\"prop-section\" [open]=\"section.open\"\n (toggle)=\"onPropertySectionToggle(tool, section.key, $event)\">\n <summary class=\"prop-section-title\">{{ section.label }}</summary>\n <ul class=\"props\">\n @for (toolProp of section.props; track toolProp.key) {\n <li>\n @if (!toolProp.value.hideCaption) {\n <span>{{ toolProp.value?.propertyCaption ||\n toolProp.key[0].toUpperCase() + toolProp.key.slice(1)\n }}</span>\n }\n <br />\n @if (toolProp.value.type == 'button') {\n <p-button (click)=\"toolProp.value.callback(tool.inputs, toolProp.key, null, tool)\"\n class=\"k-button\" [style]=\"{width: '100%'}\">\n {{toolProp.value.propertyCaption}}\n </p-button>\n }\n @if (toolProp.value.type == 'metaEditor' &&\n tool.inputs['componentRef']?.value?.component) {\n <wuic-metadata-editor [hardcodedDatasource]=\"tool.inputs['componentRef']?.value?.component\"\n [saveCallback]=\"metaEditorSave\"></wuic-metadata-editor>\n }\n @if (toolProp.value.type == 'boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"tool.inputs[toolProp.key]\" />\n }\n @if (toolProp.value.type == 'numberToArray') {\n <input style=\"width: 100%;\" type=\"number\" pInputText [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'txt_area') {\n <textarea style=\"width: 100%;\" [(ngModel)]=\"tool.inputs[toolProp.key]\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\"></textarea>\n }\n @if (toolProp.value.type == 'string') {\n <input style=\"width: 100%;\" type=\"text\" pInputText [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'color') {\n <p-colorPicker\n [ngModel]=\"getDesignerColorPickerHex(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorPickerHexChange($event, tool, toolProp)\" appendTo=\"body\" />\n <div class=\"designer-color-alpha-row\">\n <label class=\"designer-color-alpha-label\">{{ 'designer.alpha' | translate }}</label>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n [ngModel]=\"getDesignerColorAlpha(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorAlphaChange($event, tool, toolProp)\" />\n <input\n type=\"number\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n [ngModel]=\"getDesignerColorAlpha(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorAlphaChange($event, tool, toolProp)\" />\n </div>\n <input type=\"text\" pInputText [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'dictionary' && !toolProp.value.async) {\n @if (toolProp.key == 'cssFile') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"availableProjectCssFiles\"\n [ngModel]=\"tool.inputs[toolProp.key]\" (ngModelChange)=\"onCssFileChanged($event, tool)\" />\n } @else if (toolProp.key == 'cssClass') {\n <p-multiSelect [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getCssClassOptionsForTool(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"onCssClassChanged($event, tool)\" [filter]=\"true\" [virtualScroll]=\"true\"\n [virtualScrollItemSize]=\"38\" scrollHeight=\"260px\" [showToggleAll]=\"false\" display=\"chip\"\n [maxSelectedLabels]=\"3\" [selectedItemsLabel]=\"'{0} selected'\">\n </p-multiSelect>\n } @else if ((tool.name == 'SELECT' || tool.name == 'MULTISELECT' || tool.name == 'UL') &&\n (toolProp.key == 'valueField' || toolProp.key == 'textField')) {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getDatasourceColumnOptions(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n } @else if (tool.name == 'LABEL' && toolProp.key == 'displayField') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getDatasourceColumnOptions(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n } @else {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"toolProp.value.values\"\n [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n }\n @if (toolProp.value.type == 'dictionary' && toolProp.value.async) {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"toolProp.value.values\"\n [ngModel]=\"tool.inputs[toolProp.key] | async\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (tool.name == 'DATAREPEATER' && toolProp.key == 'action' &&\n canOpenArchetypeConfigurator(tool)) {\n <button style=\"margin-top: 8px;\" (click)=\"openArchetypeConfigurator(tool)\">\n {{ 'designer.configure' | translate }} {{ (tool.inputs['action'] | async) || '' }}\n </button>\n }\n @if (toolProp.value.type == 'dropped-component-list') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [placeholder]=\"'select.component' | translate\" [options]=\"elementFilter(toolProp)\"\n [ngModel]=\"getDroppedComponentListModel(tool, toolProp)\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" optionLabel=\"uniqueName\"\n dataKey=\"uniqueName\" />\n }\n @if (toolProp.value.type == 'autocomplete') {\n <p-autoComplete [style]=\"{width: '100%'}\" appendTo=\"body\"\n [ngModel]=\"tool.inputs[toolProp.key] | async\" [forceSelection]=\"true\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" [suggestions]=\"tool.suggestions\"\n [optionLabel]=\"toolProp.value.displayField\" [optionValue]=\"toolProp.value.valueField\"\n (completeMethod)=\"search($event, tool, toolProp)\" [dropdown]=\"true\" dropdownMode=\"current\"\n [multiple]=\"toolProp.value.multiple\" />\n }\n @if (toolProp.value.type == 'propertyTree' && shouldShowPropertyTree(tool)) {\n <ul>\n @for (item of $any(tool.inputs[toolProp.key] | async); track item) {\n <li style=\"padding: 0; margin: 0;\">\n @if (item.col && tool.inputs['customProps_' + (tool.inputs['action'] | async)])\n {\n <wuic-field-editor [field]=\"item.col\"\n [record]=\"tool.inputs['customProps_' + (tool.inputs['action'] | async)]\"\n [metaInfo]=\"tool.inputs['datasource']?.component?.value?.metaInfo\"\n [triggerProp]=\"tool.inputs['action']\"></wuic-field-editor>\n }\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n </details>\n }\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate>\n <div class=\"hierarchy-panel\">\n <div class=\"hierarchy-panel-title\">{{ 'designer.canvas_hierarchy' | translate }}</div>\n <div class=\"hierarchy-tree-wrap\">\n <p-tree [value]=\"hierarchyTreeNodes\" [draggableNodes]=\"true\" [droppableNodes]=\"true\"\n selectionMode=\"single\" [(selection)]=\"hierarchySelection\"\n (onNodeSelect)=\"onHierarchyNodeSelect($event)\" draggableScope=\"designer-hierarchy\"\n droppableScope=\"designer-hierarchy\" (onNodeDrop)=\"onHierarchyNodeDrop($event)\">\n <ng-template let-node pTemplate=\"default\">\n <span class=\"hierarchy-node-label\" [class.active]=\"isHierarchyNodeSelected(node)\"\n (mouseenter)=\"onHierarchyNodeMouseEnter(node)\" (mouseleave)=\"onHierarchyNodeMouseLeave()\"\n (contextmenu)=\"showHierarchyNodeContextMenu($event, node, hierarchyCtxMenu)\">\n {{ node.label }}\n </span>\n </ng-template>\n </p-tree>\n </div>\n <p-contextMenu #hierarchyCtxMenu [model]=\"hierarchyCtxItems\" appendTo=\"body\" />\n </div>\n </ng-template>\n </p-splitter>\n </ng-template>\n </p-splitter>\n </ng-template>\n <ng-template pTemplate>\n <div class=\"col dashboard-design\" [class.designer-hide-datasources]=\"hideDatasourcesInCanvas\" pDroppable (onDrop)=\"drop($event)\" #canvas\n (contextmenu)=\"showCtx($event, this)\">\n <wuic-dashboard [dashboardElements]=\"dashboardElements\"></wuic-dashboard>\n <p-contextMenu [target]=\"canvas\" [model]=\"ctxItems | async\" appendTo=\"body\" />\n </div>\n </ng-template>\n </p-splitter>\n </div>\n <div class=\"designer-footer\">\n <div class=\"designer-footer-label\">{{ 'designer.items' | translate }}:</div>\n <div class=\"designer-footer-list\">\n @for (item of droppedDashboardItems; track item.uniqueName) {\n <button type=\"button\" class=\"designer-footer-item\" [class.active]=\"tool?.uniqueName === item?.uniqueName\"\n [attr.data-designer-unique-name]=\"item?.uniqueName\" (mouseenter)=\"setFooterHoverHighlight(item)\"\n (mouseleave)=\"clearFooterHoverHighlight()\" (click)=\"selectDashboardItem(item)\"\n (contextmenu)=\"showFooterContextMenu($event, item, footerCtxMenu)\">\n {{ getDroppedDashboardItemLabel(item) }}\n </button>\n }\n </div>\n <p-contextMenu #footerCtxMenu [model]=\"footerCtxItems\" appendTo=\"body\" />\n </div>\n</div>\n}\n\n@if (noEdit) {\n<wuic-dashboard [dashboardElements]=\"dashboardElements\"></wuic-dashboard>\n}\n\n<wuic-archetype-configurator [visible]=\"showArchetypeConfigurator\"\n (visibleChange)=\"onArchetypeConfigVisibleChange($event)\" [archetype]=\"getActiveArchetypeConfig()\"\n [metaInfo]=\"getArchetypeConfigMetaInfoForTool(archetypeConfigTool)\"\n [value]=\"getArchetypeConfigValueForTool(archetypeConfigTool)\" (applyConfig)=\"onArchetypeConfigApply($event)\">\n</wuic-archetype-configurator>\n\n<wuic-css-sheet-editor [visible]=\"showCssSheetEditor\" (visibleChange)=\"onCssSheetEditorVisibleChange($event)\"\n [sheets]=\"dashboardCssSheets\" [selectedSheetPath]=\"selectedCssEditorSheetPath\" [assetsFolder]=\"currentDashboardRoute\"\n [styleProps]=\"getCssEditorStyleProps()\" (applyEditor)=\"onCssSheetEditorApply($event)\">\n</wuic-css-sheet-editor>\n\n<p-dialog [header]=\"'Riapri dashboard'\" [(visible)]=\"reopenDashboardDialogVisible\" [modal]=\"true\" [closable]=\"true\"\n [draggable]=\"false\" [resizable]=\"false\" [appendTo]=\"'body'\" [style]=\"{ width: '34rem' }\"\n (onHide)=\"cancelReopenDashboardDialog()\">\n <div class=\"route-popup-form\">\n <label for=\"designer-reopen-select\">Dashboard esistenti</label>\n <p-select inputId=\"designer-reopen-select\" [options]=\"savedDashboardOptions\" optionLabel=\"label\" optionValue=\"value\"\n [(ngModel)]=\"reopenDialogSelectedDashboardRoute\" [filter]=\"true\" [showClear]=\"true\" [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenDashboardDialog()\">{{ 'cancel' | translate\n }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenDashboardDialog()\"\n [disabled]=\"!reopenDialogSelectedDashboardRoute\">Riapri</button>\n </div>\n </div>\n</p-dialog>\n", styles: [":host{display:block;width:100%;height:100%;min-width:0}.designer-layout{display:grid;grid-template-rows:auto minmax(0,1fr) auto;height:100%;min-height:0;width:100%;min-width:0}.designer-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:8px;border:1px solid inherit;border-radius:10px;background:transparent;padding:10px 12px;margin-bottom:8px}.designer-current-dashboard{min-width:220px;font-size:.86rem;font-weight:700;color:inherit}.designer-toolbar-spacer{flex:1 1 auto;min-width:16px}.designer-toolbar-menu-group{display:inline-flex}.designer-toolbar-menu-group button{height:32px;border:1px solid #2f67d8;border-radius:6px;background:#2f67d8;color:#fff;padding:0 10px;font-size:.82rem;cursor:pointer}.designer-toolbar-menu-group button[disabled]{opacity:.6;cursor:not-allowed}.designer-main{min-height:0;min-width:0;width:100%;overflow:hidden;direction:ltr}.designer-main-splitter{height:100%;width:100%;min-width:0;direction:ltr}.designer-toolbox{font-size:3rem}.designer-toolbox ul{list-style-type:none;padding:0;margin:0;width:100%}.designer-toolbox li{float:left;margin-left:5px;margin-top:5px}.designer-toolbox .tool-groups{display:block}.designer-toolbox .tool-group-item{float:none;margin-left:0;margin-top:10px;clear:both}.designer-toolbox .tool-group-title{font-size:.8rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.7;margin:0 0 4px 6px}.designer-toolbox .tool-group-list{display:flex;flex-wrap:wrap;align-items:flex-start;gap:4px}.designer-toolbox .tool-group-list li{float:none;margin-left:0;margin-top:0}.designer-toolbox .props{font-size:1rem}.designer-toolbox .props li{float:none;padding-bottom:15px}.designer-toolbox .prop-section{width:100%;border:1px solid inherit;border-radius:6px;margin-top:8px;background:transparent;padding:6px 8px 2px}.designer-toolbox .prop-section-title{font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;color:inherit;margin-bottom:6px}.palette-panel{height:100%;overflow:auto;width:100%}.designer-color-alpha-row{display:flex;align-items:center;gap:8px;margin-top:6px;margin-bottom:6px}.designer-color-alpha-label{font-size:.8rem;min-width:40px}.designer-color-alpha-row input[type=range]{flex:1 1 auto;min-width:90px}.designer-color-alpha-row input[type=number]{width:72px}.properties-panel{height:100%;overflow:hidden;width:100%;display:flex;flex-direction:column;min-height:0}.properties-panel>.designer-toolbox{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable}:host ::ng-deep .designer-left-bottom-splitter .p-splitterpanel{min-height:0!important;overflow:hidden!important}:host ::ng-deep .designer-left-bottom-splitter .p-splitterpanel>.p-splitterpanel-content{height:100%;min-height:0;overflow:hidden}.hierarchy-panel{height:100%;width:100%;min-height:0;display:flex;flex-direction:column;overflow:hidden;padding:6px}.hierarchy-panel-title{font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:#4b5563;margin:0 0 6px}.hierarchy-tree-wrap{flex:1 1 auto;min-height:0;border:1px solid inherit;border-radius:6px;background:transparent;overflow:auto;padding:4px}:host ::ng-deep .hierarchy-tree-wrap .p-tree{border:none;padding:0;height:100%;background:transparent}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content{border:1px solid transparent;border-radius:4px;background:transparent!important;color:inherit!important;padding:0!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content.p-highlight{border-color:transparent!important;background:transparent!important;color:inherit!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content:hover{background:transparent!important;color:inherit!important}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label{display:inline-block;border:1px solid inherit;background:transparent;color:inherit;border-radius:4px;padding:2px 8px;font-size:.8rem;line-height:1.25rem;cursor:pointer}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label:hover{border-color:#94a3b8}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label.active{border-color:#3b82f6!important;background:#eff6ff!important;color:#1d4ed8!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content.p-highlight .hierarchy-node-label{border-color:#3b82f6!important;background:#eff6ff!important;color:#1d4ed8!important}.designer-hierarchy-node{cursor:pointer;border:1px solid transparent;border-radius:4px;padding:2px 6px;font-size:.82rem;line-height:1.25rem}.designer-hierarchy-node-label{cursor:pointer;display:inline-block;width:100%}.designer-hierarchy-node.active{border-color:#3b82f6;background:#eff6ff;color:#1d4ed8}.designer-footer-item.designer-tree-hover-target{border-color:#3b82f6!important;outline:1px solid #3b82f6!important;outline-offset:-1px}.dashboard-design{height:100%;min-height:0;min-width:0;width:100%;overflow:auto;direction:ltr}:host ::ng-deep .dashboard-design.designer-hide-datasources .datasource-descriptor{display:none!important}.current-dashboard-title{font-weight:600;margin-right:12px}.designer-footer{display:flex;align-items:center;gap:8px;padding:6px 8px;border-top:1px solid inherit;background:transparent;min-height:36px;flex:0 0 auto;width:100%;overflow:auto}.designer-footer-label{font-size:.85rem;font-weight:600;color:inherit;white-space:nowrap}.designer-footer-list{display:flex;align-items:center;gap:6px;overflow-x:auto;overflow-y:hidden;white-space:nowrap;width:100%}.designer-footer-item{border:1px solid inherit;background:transparent;color:inherit;border-radius:4px;padding:2px 8px;font-size:.8rem;line-height:1.25rem;cursor:pointer;white-space:nowrap}.designer-footer-item.active{border-color:#3b82f6;background:transparent;color:#1d4ed8}:host ::ng-deep .designer-footer-hover-target{border-color:#3b82f6!important;outline:1px solid #3b82f6!important;outline-offset:-1px;box-shadow:inset 0 0 0 1px #3b82f6!important}.route-popup-form{display:flex;flex-direction:column;gap:8px}.route-popup-form label{font-size:.85rem;font-weight:600;color:#2f3f58}.route-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.route-popup-btn{border:1px solid inherit;background:transparent;color:inherit;border-radius:6px;padding:7px 12px;font-size:.85rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f67d8;background:#2f67d8;color:#fff}.p-colorpicker{border:1px solid black;border-radius:4px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SplitterModule }, { kind: "component", type: i10.Splitter, selector: "p-splitter", inputs: ["styleClass", "panelStyleClass", "panelStyle", "stateStorage", "stateKey", "layout", "gutterSize", "step", "minSizes", "panelSizes"], outputs: ["onResizeEnd", "onResizeStart"] }, { kind: "directive", type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i11.Draggable, selector: "[pDraggable]", inputs: ["pDraggable", "dragEffect", "dragHandle", "pDraggableDisabled"], outputs: ["onDragStart", "onDragEnd", "onDrag"] }, { kind: "directive", type: i11.Droppable, selector: "[pDroppable]", inputs: ["pDroppable", "pDroppableDisabled", "dropEffect"], outputs: ["onDragEnter", "onDragLeave", "onDrop"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ColorPickerModule }, { kind: "component", type: i2$2.ColorPicker, selector: "p-colorPicker, p-colorpicker, p-color-picker", inputs: ["styleClass", "showTransitionOptions", "hideTransitionOptions", "inline", "format", "tabindex", "inputId", "autoZIndex", "autofocus", "defaultColor", "appendTo", "overlayOptions", "motionOptions"], outputs: ["onChange", "onShow", "onHide"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i2$3.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "component", type: DashboardComponent, selector: "wuic-dashboard", inputs: ["dashboardElements"] }, { kind: "component", type: FieldEditorComponent, selector: "wuic-field-editor", inputs: ["datasource", "record", "field", "metaInfo", "readOnly", "isFilter", "hideLabel", "forceShowLabel", "operator", "nestedIndex", "triggerProp", "tabIndex", "onInlineCellValueChange"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i9.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: MetadataEditorComponent, selector: "wuic-metadata-editor", inputs: ["datasource", "hardcodedDatasource", "saveCallback", "hideReports", "hideRelatedTableActions", "hideRelatedColumnActions"] }, { kind: "ngmodule", type: MenubarModule }, { kind: "component", type: ArchetypeConfiguratorComponent, selector: "wuic-archetype-configurator", inputs: ["visible", "archetype", "metaInfo", "value"], outputs: ["visibleChange", "applyConfig"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i17.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: CssSheetEditorComponent, selector: "wuic-css-sheet-editor", inputs: ["visible", "sheets", "selectedSheetPath", "styleProps", "assetsFolder"], outputs: ["visibleChange", "applyEditor"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i9$1.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo", "motionOptions"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TreeModule }, { kind: "component", type: i3.Tree, selector: "p-tree", inputs: ["value", "selectionMode", "loadingMode", "selection", "styleClass", "contextMenu", "contextMenuSelectionMode", "contextMenuSelection", "draggableScope", "droppableScope", "draggableNodes", "droppableNodes", "metaKeySelection", "propagateSelectionUp", "propagateSelectionDown", "loading", "loadingIcon", "emptyMessage", "ariaLabel", "togglerAriaLabel", "ariaLabelledBy", "validateDrop", "filter", "filterInputAutoFocus", "filterBy", "filterMode", "filterOptions", "filterPlaceholder", "filteredNodes", "filterLocale", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "indentation", "_templateMap", "trackBy", "highlightOnSelect"], outputs: ["selectionChange", "contextMenuSelectionChange", "onNodeSelect", "onNodeUnselect", "onNodeExpand", "onNodeCollapse", "onNodeContextMenuSelect", "onNodeDoubleClick", "onNodeDrop", "onLazyLoad", "onScroll", "onScrollIndexChange", "onFilter"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
10478
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DesignerComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: DataProviderService }, { token: MetadataProviderService }, { token: UserInfoService }, { token: i0.ChangeDetectorRef }, { token: TranslationManagerService }, { token: MetadataEditorService }, { token: WorkflowRuntimeMetadataService }], target: i0.ɵɵFactoryTarget.Component });
10479
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: DesignerComponent, isStandalone: true, selector: "wuic-designer", host: { listeners: { "window:hashchange": "onWindowHashChange()", "window:beforeunload": "onWindowBeforeUnload($event)", "window:keydown": "onWindowKeydown($event)", "window:mouseup": "onWindowMouseup()", "window:touchend": "onWindowTouchend()", "window:keyup": "onWindowKeyup()", "window:change": "onWindowChange()" } }, providers: [TreeDragDropService], ngImport: i0, template: "<!-- <button pButton type=\"button\" (click)=\"loadDashboard()\" class=\"mr-2\">{{'load' | translate}}</button> -->\n@if (!noEdit) {\n<div class=\"designer-layout\">\n <div class=\"designer-toolbar\">\n <div class=\"designer-current-dashboard\">{{ currentDashboardTitle }}</div>\n\n <div class=\"designer-toolbar-spacer\"></div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"undo()\" [disabled]=\"!canUndo\">{{ 'designer.undo' | translate }}</button>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"redo()\" [disabled]=\"!canRedo\">{{ 'designer.redo' | translate }}</button>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"graphActionsMenu.toggle($event)\">{{ 'designer.actions_menu' | translate }}</button>\n <p-menu #graphActionsMenu [popup]=\"true\" [model]=\"graphActionsMenuItems\" appendTo=\"body\"></p-menu>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"openCurrentDashboardInNewTab()\" [disabled]=\"!currentDashboardRoute\">{{ 'designer.open_current_dashboard' | translate }}</button>\n </div>\n </div>\n <div class=\"designer-main\">\n <p-splitter [style]=\"{ height: '100%' }\" [panelSizes]=\"[15, 85]\" styleClass=\"designer-main-splitter\">\n <ng-template pTemplate>\n <p-splitter layout=\"vertical\" [style]=\"{ height: '100%', width: '100%' }\" [panelSizes]=\"[35, 65]\"\n [minSizes]=\"[20, 30]\" styleClass=\"designer-left-splitter\">\n <ng-template pTemplate>\n <div class=\"col flex designer-toolbox palette-panel\">\n <ul class=\"tool-groups\">\n @for (toolGroup of availableToolGroups; track toolGroup.group) {\n <li class=\"tool-group-item\">\n <div class=\"tool-group-title\">{{ toolGroup.group }}</div>\n <ul class=\"tool-group-list\">\n @for (tool of toolGroup.tools; track tool) {\n <li pDraggable (onDragStart)=\"dragStart(tool)\" (onDragEnd)=\"dragEnd()\" (onDrag)=\"onDrag($event)\" (dblclick)=\"dropToolAtRoot(tool)\">\n <i [ngClass]=\"tool.icon\" [title]=\"tool.name\"></i>\n </li>\n }\n </ul>\n </li>\n }\n </ul>\n </div>\n </ng-template>\n <ng-template pTemplate>\n <p-splitter layout=\"vertical\" [style]=\"{ height: '100%', width: '100%' }\" [panelSizes]=\"[68, 32]\"\n [minSizes]=\"[35, 20]\" styleClass=\"designer-left-bottom-splitter\">\n <ng-template pTemplate>\n <div class=\"properties-panel\">\n <p-select [style]=\"{width: '100%'}\" [options]=\"flattenedDashboardElements\" [(ngModel)]=\"tool\"\n optionLabel=\"uniqueName\" dataKey=\"componentId\" appendTo=\"body\" />\n <div class=\"col designer-toolbox\">\n @for (section of getToolPropertySections(tool); track section.key) {\n <details class=\"prop-section\" [open]=\"section.open\"\n (toggle)=\"onPropertySectionToggle(tool, section.key, $event)\">\n <summary class=\"prop-section-title\">{{ section.label }}</summary>\n <ul class=\"props\">\n @for (toolProp of section.props; track toolProp.key) {\n <li>\n @if (!toolProp.value.hideCaption) {\n <span>{{ toolProp.value?.propertyCaption ||\n toolProp.key[0].toUpperCase() + toolProp.key.slice(1)\n }}</span>\n }\n <br />\n @if (toolProp.value.type == 'button') {\n <p-button (click)=\"toolProp.value.callback(tool.inputs, toolProp.key, null, tool)\"\n class=\"k-button\" [style]=\"{width: '100%'}\">\n {{toolProp.value.propertyCaption}}\n </p-button>\n }\n @if (toolProp.value.type == 'metaEditor' &&\n tool.inputs['componentRef']?.value?.component) {\n <wuic-metadata-editor [hardcodedDatasource]=\"tool.inputs['componentRef']?.value?.component\"\n [saveCallback]=\"metaEditorSave\"></wuic-metadata-editor>\n }\n @if (toolProp.value.type == 'boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"tool.inputs[toolProp.key]\" />\n }\n @if (toolProp.value.type == 'numberToArray') {\n <input style=\"width: 100%;\" type=\"number\" pInputText [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'txt_area') {\n <textarea style=\"width: 100%;\" [(ngModel)]=\"tool.inputs[toolProp.key]\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\"></textarea>\n }\n @if (toolProp.value.type == 'string') {\n <input style=\"width: 100%;\" type=\"text\" pInputText [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'color') {\n <p-colorPicker\n [ngModel]=\"getDesignerColorPickerHex(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorPickerHexChange($event, tool, toolProp)\" appendTo=\"body\" />\n <div class=\"designer-color-alpha-row\">\n <label class=\"designer-color-alpha-label\">{{ 'designer.alpha' | translate }}</label>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n [ngModel]=\"getDesignerColorAlpha(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorAlphaChange($event, tool, toolProp)\" />\n <input\n type=\"number\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n [ngModel]=\"getDesignerColorAlpha(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorAlphaChange($event, tool, toolProp)\" />\n </div>\n <input type=\"text\" pInputText [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'dictionary' && !toolProp.value.async) {\n @if (toolProp.key == 'cssFile') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"availableProjectCssFiles\"\n [ngModel]=\"tool.inputs[toolProp.key]\" (ngModelChange)=\"onCssFileChanged($event, tool)\" />\n } @else if (toolProp.key == 'cssClass') {\n <p-multiSelect [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getCssClassOptionsForTool(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"onCssClassChanged($event, tool)\" [filter]=\"true\" [virtualScroll]=\"true\"\n [virtualScrollItemSize]=\"38\" scrollHeight=\"260px\" [showToggleAll]=\"false\" display=\"chip\"\n [maxSelectedLabels]=\"3\" [selectedItemsLabel]=\"'{0} selected'\">\n </p-multiSelect>\n } @else if ((tool.name == 'SELECT' || tool.name == 'MULTISELECT' || tool.name == 'UL') &&\n (toolProp.key == 'valueField' || toolProp.key == 'textField')) {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getDatasourceColumnOptions(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n } @else if (tool.name == 'LABEL' && toolProp.key == 'displayField') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getDatasourceColumnOptions(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n } @else {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"toolProp.value.values\"\n [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n }\n @if (toolProp.value.type == 'dictionary' && toolProp.value.async) {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"toolProp.value.values\"\n [ngModel]=\"tool.inputs[toolProp.key] | async\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (tool.name == 'DATAREPEATER' && toolProp.key == 'action' &&\n canOpenArchetypeConfigurator(tool)) {\n <button style=\"margin-top: 8px;\" (click)=\"openArchetypeConfigurator(tool)\">\n {{ 'designer.configure' | translate }} {{ (tool.inputs['action'] | async) || '' }}\n </button>\n }\n @if (toolProp.value.type == 'dropped-component-list') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [placeholder]=\"'select.component' | translate\" [options]=\"elementFilter(toolProp)\"\n [ngModel]=\"getDroppedComponentListModel(tool, toolProp)\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" optionLabel=\"uniqueName\"\n dataKey=\"uniqueName\" />\n }\n @if (toolProp.value.type == 'autocomplete') {\n <p-autoComplete [style]=\"{width: '100%'}\" appendTo=\"body\"\n [ngModel]=\"tool.inputs[toolProp.key] | async\" [forceSelection]=\"true\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" [suggestions]=\"tool.suggestions\"\n [optionLabel]=\"toolProp.value.displayField\" [optionValue]=\"toolProp.value.valueField\"\n (completeMethod)=\"search($event, tool, toolProp)\" [dropdown]=\"true\" dropdownMode=\"current\"\n [multiple]=\"toolProp.value.multiple\" />\n }\n @if (toolProp.value.type == 'propertyTree' && shouldShowPropertyTree(tool)) {\n <ul>\n @for (item of $any(tool.inputs[toolProp.key] | async); track item) {\n <li style=\"padding: 0; margin: 0;\">\n @if (item.col && tool.inputs['customProps_' + (tool.inputs['action'] | async)])\n {\n <wuic-field-editor [field]=\"item.col\"\n [record]=\"tool.inputs['customProps_' + (tool.inputs['action'] | async)]\"\n [metaInfo]=\"tool.inputs['datasource']?.component?.value?.metaInfo\"\n [triggerProp]=\"tool.inputs['action']\"></wuic-field-editor>\n }\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n </details>\n }\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate>\n <div class=\"hierarchy-panel\">\n <div class=\"hierarchy-panel-title\">{{ 'designer.canvas_hierarchy' | translate }}</div>\n <div class=\"hierarchy-tree-wrap\">\n <p-tree [value]=\"hierarchyTreeNodes\" [draggableNodes]=\"true\" [droppableNodes]=\"true\"\n selectionMode=\"single\" [(selection)]=\"hierarchySelection\"\n (onNodeSelect)=\"onHierarchyNodeSelect($event)\" draggableScope=\"designer-hierarchy\"\n droppableScope=\"designer-hierarchy\" (onNodeDrop)=\"onHierarchyNodeDrop($event)\">\n <ng-template let-node pTemplate=\"default\">\n <span class=\"hierarchy-node-label\" [class.active]=\"isHierarchyNodeSelected(node)\"\n (mouseenter)=\"onHierarchyNodeMouseEnter(node)\" (mouseleave)=\"onHierarchyNodeMouseLeave()\"\n (contextmenu)=\"showHierarchyNodeContextMenu($event, node, hierarchyCtxMenu)\">\n {{ node.label }}\n </span>\n </ng-template>\n </p-tree>\n </div>\n <p-contextMenu #hierarchyCtxMenu [model]=\"hierarchyCtxItems\" appendTo=\"body\" />\n </div>\n </ng-template>\n </p-splitter>\n </ng-template>\n </p-splitter>\n </ng-template>\n <ng-template pTemplate>\n <div class=\"col dashboard-design\" [class.designer-hide-datasources]=\"hideDatasourcesInCanvas\" pDroppable (onDrop)=\"drop($event)\" #canvas\n (contextmenu)=\"showCtx($event, this)\">\n <wuic-dashboard [dashboardElements]=\"dashboardElements\"></wuic-dashboard>\n <p-contextMenu [target]=\"canvas\" [model]=\"ctxItems | async\" appendTo=\"body\" />\n </div>\n </ng-template>\n </p-splitter>\n </div>\n <div class=\"designer-footer\">\n <div class=\"designer-footer-label\">{{ 'designer.items' | translate }}:</div>\n <div class=\"designer-footer-list\">\n @for (item of droppedDashboardItems; track item.uniqueName) {\n <button type=\"button\" class=\"designer-footer-item\" [class.active]=\"tool?.uniqueName === item?.uniqueName\"\n [attr.data-designer-unique-name]=\"item?.uniqueName\" (mouseenter)=\"setFooterHoverHighlight(item)\"\n (mouseleave)=\"clearFooterHoverHighlight()\" (click)=\"selectDashboardItem(item)\"\n (contextmenu)=\"showFooterContextMenu($event, item, footerCtxMenu)\">\n {{ getDroppedDashboardItemLabel(item) }}\n </button>\n }\n </div>\n <p-contextMenu #footerCtxMenu [model]=\"footerCtxItems\" appendTo=\"body\" />\n </div>\n</div>\n}\n\n@if (noEdit) {\n<wuic-dashboard [dashboardElements]=\"dashboardElements\"></wuic-dashboard>\n}\n\n<wuic-archetype-configurator [visible]=\"showArchetypeConfigurator\"\n (visibleChange)=\"onArchetypeConfigVisibleChange($event)\" [archetype]=\"getActiveArchetypeConfig()\"\n [metaInfo]=\"getArchetypeConfigMetaInfoForTool(archetypeConfigTool)\"\n [value]=\"getArchetypeConfigValueForTool(archetypeConfigTool)\" (applyConfig)=\"onArchetypeConfigApply($event)\">\n</wuic-archetype-configurator>\n\n<wuic-css-sheet-editor [visible]=\"showCssSheetEditor\" (visibleChange)=\"onCssSheetEditorVisibleChange($event)\"\n [sheets]=\"dashboardCssSheets\" [selectedSheetPath]=\"selectedCssEditorSheetPath\" [assetsFolder]=\"currentDashboardRoute\"\n [styleProps]=\"getCssEditorStyleProps()\" (applyEditor)=\"onCssSheetEditorApply($event)\">\n</wuic-css-sheet-editor>\n\n<p-dialog [header]=\"'designer.reopen_dashboard' | translate\" [(visible)]=\"reopenDashboardDialogVisible\" [modal]=\"true\" [closable]=\"true\"\n [draggable]=\"false\" [resizable]=\"false\" [appendTo]=\"'body'\" [style]=\"{ width: '34rem' }\"\n (onHide)=\"cancelReopenDashboardDialog()\">\n <div class=\"route-popup-form\">\n <label for=\"designer-reopen-select\">{{ 'designer.existing_dashboards' | translate }}</label>\n <p-select inputId=\"designer-reopen-select\" [options]=\"savedDashboardOptions\" optionLabel=\"label\" optionValue=\"value\"\n [(ngModel)]=\"reopenDialogSelectedDashboardRoute\" [filter]=\"true\" [showClear]=\"true\" [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenDashboardDialog()\">{{ 'cancel' | translate\n }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenDashboardDialog()\"\n [disabled]=\"!reopenDialogSelectedDashboardRoute\">{{ 'designer.reopen' | translate }}</button>\n </div>\n </div>\n</p-dialog>\n", styles: [":host{display:block;width:100%;height:100%;min-width:0}.designer-layout{display:grid;grid-template-rows:auto minmax(0,1fr) auto;height:100%;min-height:0;width:100%;min-width:0}.designer-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:8px;border:1px solid inherit;border-radius:10px;background:transparent;padding:10px 12px;margin-bottom:8px}.designer-current-dashboard{min-width:220px;font-size:.86rem;font-weight:700;color:inherit}.designer-toolbar-spacer{flex:1 1 auto;min-width:16px}.designer-toolbar-menu-group{display:inline-flex}.designer-toolbar-menu-group button{height:32px;border:1px solid #2f67d8;border-radius:6px;background:#2f67d8;color:#fff;padding:0 10px;font-size:.82rem;cursor:pointer}.designer-toolbar-menu-group button[disabled]{opacity:.6;cursor:not-allowed}.designer-main{min-height:0;min-width:0;width:100%;overflow:hidden;direction:ltr}.designer-main-splitter{height:100%;width:100%;min-width:0;direction:ltr}.designer-toolbox{font-size:3rem}.designer-toolbox ul{list-style-type:none;padding:0;margin:0;width:100%}.designer-toolbox li{float:left;margin-left:5px;margin-top:5px}.designer-toolbox .tool-groups{display:block}.designer-toolbox .tool-group-item{float:none;margin-left:0;margin-top:10px;clear:both}.designer-toolbox .tool-group-title{font-size:.8rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.7;margin:0 0 4px 6px}.designer-toolbox .tool-group-list{display:flex;flex-wrap:wrap;align-items:flex-start;gap:4px}.designer-toolbox .tool-group-list li{float:none;margin-left:0;margin-top:0}.designer-toolbox .props{font-size:1rem}.designer-toolbox .props li{float:none;padding-bottom:15px}.designer-toolbox .prop-section{width:100%;border:1px solid inherit;border-radius:6px;margin-top:8px;background:transparent;padding:6px 8px 2px}.designer-toolbox .prop-section-title{font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;color:inherit;margin-bottom:6px}.palette-panel{height:100%;overflow:auto;width:100%}.designer-color-alpha-row{display:flex;align-items:center;gap:8px;margin-top:6px;margin-bottom:6px}.designer-color-alpha-label{font-size:.8rem;min-width:40px}.designer-color-alpha-row input[type=range]{flex:1 1 auto;min-width:90px}.designer-color-alpha-row input[type=number]{width:72px}.properties-panel{height:100%;overflow:hidden;width:100%;display:flex;flex-direction:column;min-height:0}.properties-panel>.designer-toolbox{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable}:host ::ng-deep .designer-left-bottom-splitter .p-splitterpanel{min-height:0!important;overflow:hidden!important}.hierarchy-panel{height:100%;width:100%;min-height:0;display:flex;flex-direction:column;overflow:hidden;padding:6px}.hierarchy-panel-title{font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:#4b5563;margin:0 0 6px}.hierarchy-tree-wrap{flex:1 1 auto;min-height:0;border:1px solid inherit;border-radius:6px;background:transparent;overflow:auto;padding:4px}:host ::ng-deep .hierarchy-tree-wrap .p-tree{border:none;padding:0;height:100%;background:transparent}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content{border:1px solid transparent;border-radius:4px;background:transparent!important;color:inherit!important;padding:0!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content.p-highlight{border-color:transparent!important;background:transparent!important;color:inherit!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content:hover{background:transparent!important;color:inherit!important}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label{display:inline-block;border:1px solid inherit;background:transparent;color:inherit;border-radius:4px;padding:2px 8px;font-size:.8rem;line-height:1.25rem;cursor:pointer}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label:hover{border-color:#94a3b8}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label.active{border-color:#3b82f6!important;background:#eff6ff!important;color:#1d4ed8!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content.p-highlight .hierarchy-node-label{border-color:#3b82f6!important;background:#eff6ff!important;color:#1d4ed8!important}.designer-hierarchy-node{cursor:pointer;border:1px solid transparent;border-radius:4px;padding:2px 6px;font-size:.82rem;line-height:1.25rem}.designer-hierarchy-node-label{cursor:pointer;display:inline-block;width:100%}.designer-hierarchy-node.active{border-color:#3b82f6;background:#eff6ff;color:#1d4ed8}.designer-footer-item.designer-tree-hover-target{border-color:#3b82f6!important;outline:1px solid #3b82f6!important;outline-offset:-1px}.dashboard-design{height:100%;min-height:0;min-width:0;width:100%;overflow:auto;direction:ltr}:host ::ng-deep .dashboard-design.designer-hide-datasources .datasource-descriptor{display:none!important}.current-dashboard-title{font-weight:600;margin-right:12px}.designer-footer{display:flex;align-items:center;gap:8px;padding:6px 8px;border-top:1px solid inherit;background:transparent;min-height:36px;flex:0 0 auto;width:100%;overflow:auto}.designer-footer-label{font-size:.85rem;font-weight:600;color:inherit;white-space:nowrap}.designer-footer-list{display:flex;align-items:center;gap:6px;overflow-x:auto;overflow-y:hidden;white-space:nowrap;width:100%}.designer-footer-item{border:1px solid inherit;background:transparent;color:inherit;border-radius:4px;padding:2px 8px;font-size:.8rem;line-height:1.25rem;cursor:pointer;white-space:nowrap}.designer-footer-item.active{border-color:#3b82f6;background:transparent;color:#1d4ed8}:host ::ng-deep .designer-footer-hover-target{border-color:#3b82f6!important;outline:1px solid #3b82f6!important;outline-offset:-1px;box-shadow:inset 0 0 0 1px #3b82f6!important}.route-popup-form{display:flex;flex-direction:column;gap:8px}.route-popup-form label{font-size:.85rem;font-weight:600;color:#2f3f58}.route-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.route-popup-btn{border:1px solid inherit;background:transparent;color:inherit;border-radius:6px;padding:7px 12px;font-size:.85rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f67d8;background:#2f67d8;color:#fff}.p-colorpicker{border:1px solid black;border-radius:4px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SplitterModule }, { kind: "component", type: i10.Splitter, selector: "p-splitter", inputs: ["styleClass", "panelStyleClass", "panelStyle", "stateStorage", "stateKey", "layout", "gutterSize", "step", "minSizes", "panelSizes"], outputs: ["onResizeEnd", "onResizeStart"] }, { kind: "directive", type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i11.Draggable, selector: "[pDraggable]", inputs: ["pDraggable", "dragEffect", "dragHandle", "pDraggableDisabled"], outputs: ["onDragStart", "onDragEnd", "onDrag"] }, { kind: "directive", type: i11.Droppable, selector: "[pDroppable]", inputs: ["pDroppable", "pDroppableDisabled", "dropEffect"], outputs: ["onDragEnter", "onDragLeave", "onDrop"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ColorPickerModule }, { kind: "component", type: i2$2.ColorPicker, selector: "p-colorPicker, p-colorpicker, p-color-picker", inputs: ["styleClass", "showTransitionOptions", "hideTransitionOptions", "inline", "format", "tabindex", "inputId", "autoZIndex", "autofocus", "defaultColor", "appendTo", "overlayOptions", "motionOptions"], outputs: ["onChange", "onShow", "onHide"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i2$3.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "component", type: DashboardComponent, selector: "wuic-dashboard", inputs: ["dashboardElements"] }, { kind: "component", type: FieldEditorComponent, selector: "wuic-field-editor", inputs: ["datasource", "record", "field", "metaInfo", "readOnly", "isFilter", "hideLabel", "forceShowLabel", "operator", "nestedIndex", "triggerProp", "tabIndex", "onInlineCellValueChange"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i9.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: MetadataEditorComponent, selector: "wuic-metadata-editor", inputs: ["datasource", "hardcodedDatasource", "saveCallback", "hideReports", "hideRelatedTableActions", "hideRelatedColumnActions"] }, { kind: "ngmodule", type: MenubarModule }, { kind: "component", type: ArchetypeConfiguratorComponent, selector: "wuic-archetype-configurator", inputs: ["visible", "archetype", "metaInfo", "value"], outputs: ["visibleChange", "applyConfig"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i17.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: CssSheetEditorComponent, selector: "wuic-css-sheet-editor", inputs: ["visible", "sheets", "selectedSheetPath", "styleProps", "assetsFolder"], outputs: ["visibleChange", "applyEditor"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i9$1.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo", "motionOptions"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TreeModule }, { kind: "component", type: i3.Tree, selector: "p-tree", inputs: ["value", "selectionMode", "loadingMode", "selection", "styleClass", "contextMenu", "contextMenuSelectionMode", "contextMenuSelection", "draggableScope", "droppableScope", "draggableNodes", "droppableNodes", "metaKeySelection", "propagateSelectionUp", "propagateSelectionDown", "loading", "loadingIcon", "emptyMessage", "ariaLabel", "togglerAriaLabel", "ariaLabelledBy", "validateDrop", "filter", "filterInputAutoFocus", "filterBy", "filterMode", "filterOptions", "filterPlaceholder", "filteredNodes", "filterLocale", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "indentation", "_templateMap", "trackBy", "highlightOnSelect"], outputs: ["selectionChange", "contextMenuSelectionChange", "onNodeSelect", "onNodeUnselect", "onNodeExpand", "onNodeCollapse", "onNodeContextMenuSelect", "onNodeDoubleClick", "onNodeDrop", "onLazyLoad", "onScroll", "onScrollIndexChange", "onFilter"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
10191
10480
  }
10192
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DesignerComponent, decorators: [{
10481
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DesignerComponent, decorators: [{
10193
10482
  type: Component,
10194
- args: [{ selector: 'wuic-designer', imports: [NgClass, TranslateModule, NgTemplateOutlet, NgComponentOutlet, AsyncPipe, FormsModule, SplitterModule, DragDropModule, SelectModule, ColorPickerModule, AutoCompleteModule, DashboardComponent, CallbackPipe, FieldEditorComponent, JsonPipe, ContextMenuModule, MetadataEditorComponent, MenubarModule, ArchetypeConfiguratorComponent, ButtonModule, MultiSelectModule, CssSheetEditorComponent, MenuModule, DialogModule, TreeModule], providers: [TreeDragDropService], template: "<!-- <button pButton type=\"button\" (click)=\"loadDashboard()\" class=\"mr-2\">{{'load' | translate}}</button> -->\n@if (!noEdit) {\n<div class=\"designer-layout\">\n <div class=\"designer-toolbar\">\n <div class=\"designer-current-dashboard\">{{ currentDashboardTitle }}</div>\n\n <div class=\"designer-toolbar-spacer\"></div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"undo()\" [disabled]=\"!canUndo\">{{ 'designer.undo' | translate }}</button>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"redo()\" [disabled]=\"!canRedo\">{{ 'designer.redo' | translate }}</button>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"graphActionsMenu.toggle($event)\">{{ 'designer.actions_menu' | translate }}</button>\n <p-menu #graphActionsMenu [popup]=\"true\" [model]=\"graphActionsMenuItems\" appendTo=\"body\"></p-menu>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"openCurrentDashboardInNewTab()\" [disabled]=\"!currentDashboardRoute\">{{ 'designer.open_current_dashboard' | translate }}</button>\n </div>\n </div>\n <div class=\"designer-main\">\n <p-splitter [style]=\"{ height: '100%' }\" [panelSizes]=\"[15, 85]\" styleClass=\"designer-main-splitter\">\n <ng-template pTemplate>\n <p-splitter layout=\"vertical\" [style]=\"{ height: '100%', width: '100%' }\" [panelSizes]=\"[35, 65]\"\n [minSizes]=\"[20, 30]\" styleClass=\"designer-left-splitter\">\n <ng-template pTemplate>\n <div class=\"col flex designer-toolbox palette-panel\">\n <ul class=\"tool-groups\">\n @for (toolGroup of availableToolGroups; track toolGroup.group) {\n <li class=\"tool-group-item\">\n <div class=\"tool-group-title\">{{ toolGroup.group }}</div>\n <ul class=\"tool-group-list\">\n @for (tool of toolGroup.tools; track tool) {\n <li pDraggable (onDragStart)=\"dragStart(tool)\" (onDragEnd)=\"dragEnd()\" (onDrag)=\"onDrag($event)\">\n <i [ngClass]=\"tool.icon\" [title]=\"tool.name\"></i>\n </li>\n }\n </ul>\n </li>\n }\n </ul>\n </div>\n </ng-template>\n <ng-template pTemplate>\n <p-splitter layout=\"vertical\" [style]=\"{ height: '100%', width: '100%' }\" [panelSizes]=\"[68, 32]\"\n [minSizes]=\"[35, 20]\" styleClass=\"designer-left-bottom-splitter\">\n <ng-template pTemplate>\n <div class=\"properties-panel\">\n <p-select [style]=\"{width: '100%'}\" [options]=\"flattenedDashboardElements\" [(ngModel)]=\"tool\"\n optionLabel=\"uniqueName\" dataKey=\"componentId\" appendTo=\"body\" />\n <div class=\"col designer-toolbox\">\n @for (section of getToolPropertySections(tool); track section.key) {\n <details class=\"prop-section\" [open]=\"section.open\"\n (toggle)=\"onPropertySectionToggle(tool, section.key, $event)\">\n <summary class=\"prop-section-title\">{{ section.label }}</summary>\n <ul class=\"props\">\n @for (toolProp of section.props; track toolProp.key) {\n <li>\n @if (!toolProp.value.hideCaption) {\n <span>{{ toolProp.value?.propertyCaption ||\n toolProp.key[0].toUpperCase() + toolProp.key.slice(1)\n }}</span>\n }\n <br />\n @if (toolProp.value.type == 'button') {\n <p-button (click)=\"toolProp.value.callback(tool.inputs, toolProp.key, null, tool)\"\n class=\"k-button\" [style]=\"{width: '100%'}\">\n {{toolProp.value.propertyCaption}}\n </p-button>\n }\n @if (toolProp.value.type == 'metaEditor' &&\n tool.inputs['componentRef']?.value?.component) {\n <wuic-metadata-editor [hardcodedDatasource]=\"tool.inputs['componentRef']?.value?.component\"\n [saveCallback]=\"metaEditorSave\"></wuic-metadata-editor>\n }\n @if (toolProp.value.type == 'boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"tool.inputs[toolProp.key]\" />\n }\n @if (toolProp.value.type == 'numberToArray') {\n <input style=\"width: 100%;\" type=\"number\" pInputText [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'txt_area') {\n <textarea style=\"width: 100%;\" [(ngModel)]=\"tool.inputs[toolProp.key]\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\"></textarea>\n }\n @if (toolProp.value.type == 'string') {\n <input style=\"width: 100%;\" type=\"text\" pInputText [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'color') {\n <p-colorPicker\n [ngModel]=\"getDesignerColorPickerHex(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorPickerHexChange($event, tool, toolProp)\" appendTo=\"body\" />\n <div class=\"designer-color-alpha-row\">\n <label class=\"designer-color-alpha-label\">{{ 'designer.alpha' | translate }}</label>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n [ngModel]=\"getDesignerColorAlpha(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorAlphaChange($event, tool, toolProp)\" />\n <input\n type=\"number\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n [ngModel]=\"getDesignerColorAlpha(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorAlphaChange($event, tool, toolProp)\" />\n </div>\n <input type=\"text\" pInputText [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'dictionary' && !toolProp.value.async) {\n @if (toolProp.key == 'cssFile') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"availableProjectCssFiles\"\n [ngModel]=\"tool.inputs[toolProp.key]\" (ngModelChange)=\"onCssFileChanged($event, tool)\" />\n } @else if (toolProp.key == 'cssClass') {\n <p-multiSelect [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getCssClassOptionsForTool(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"onCssClassChanged($event, tool)\" [filter]=\"true\" [virtualScroll]=\"true\"\n [virtualScrollItemSize]=\"38\" scrollHeight=\"260px\" [showToggleAll]=\"false\" display=\"chip\"\n [maxSelectedLabels]=\"3\" [selectedItemsLabel]=\"'{0} selected'\">\n </p-multiSelect>\n } @else if ((tool.name == 'SELECT' || tool.name == 'MULTISELECT' || tool.name == 'UL') &&\n (toolProp.key == 'valueField' || toolProp.key == 'textField')) {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getDatasourceColumnOptions(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n } @else if (tool.name == 'LABEL' && toolProp.key == 'displayField') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getDatasourceColumnOptions(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n } @else {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"toolProp.value.values\"\n [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n }\n @if (toolProp.value.type == 'dictionary' && toolProp.value.async) {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"toolProp.value.values\"\n [ngModel]=\"tool.inputs[toolProp.key] | async\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (tool.name == 'DATAREPEATER' && toolProp.key == 'action' &&\n canOpenArchetypeConfigurator(tool)) {\n <button style=\"margin-top: 8px;\" (click)=\"openArchetypeConfigurator(tool)\">\n {{ 'designer.configure' | translate }} {{ (tool.inputs['action'] | async) || '' }}\n </button>\n }\n @if (toolProp.value.type == 'dropped-component-list') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [placeholder]=\"'select.component' | translate\" [options]=\"elementFilter(toolProp)\"\n [ngModel]=\"getDroppedComponentListModel(tool, toolProp)\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" optionLabel=\"uniqueName\"\n dataKey=\"uniqueName\" />\n }\n @if (toolProp.value.type == 'autocomplete') {\n <p-autoComplete [style]=\"{width: '100%'}\" appendTo=\"body\"\n [ngModel]=\"tool.inputs[toolProp.key] | async\" [forceSelection]=\"true\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" [suggestions]=\"tool.suggestions\"\n [optionLabel]=\"toolProp.value.displayField\" [optionValue]=\"toolProp.value.valueField\"\n (completeMethod)=\"search($event, tool, toolProp)\" [dropdown]=\"true\" dropdownMode=\"current\"\n [multiple]=\"toolProp.value.multiple\" />\n }\n @if (toolProp.value.type == 'propertyTree' && shouldShowPropertyTree(tool)) {\n <ul>\n @for (item of $any(tool.inputs[toolProp.key] | async); track item) {\n <li style=\"padding: 0; margin: 0;\">\n @if (item.col && tool.inputs['customProps_' + (tool.inputs['action'] | async)])\n {\n <wuic-field-editor [field]=\"item.col\"\n [record]=\"tool.inputs['customProps_' + (tool.inputs['action'] | async)]\"\n [metaInfo]=\"tool.inputs['datasource']?.component?.value?.metaInfo\"\n [triggerProp]=\"tool.inputs['action']\"></wuic-field-editor>\n }\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n </details>\n }\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate>\n <div class=\"hierarchy-panel\">\n <div class=\"hierarchy-panel-title\">{{ 'designer.canvas_hierarchy' | translate }}</div>\n <div class=\"hierarchy-tree-wrap\">\n <p-tree [value]=\"hierarchyTreeNodes\" [draggableNodes]=\"true\" [droppableNodes]=\"true\"\n selectionMode=\"single\" [(selection)]=\"hierarchySelection\"\n (onNodeSelect)=\"onHierarchyNodeSelect($event)\" draggableScope=\"designer-hierarchy\"\n droppableScope=\"designer-hierarchy\" (onNodeDrop)=\"onHierarchyNodeDrop($event)\">\n <ng-template let-node pTemplate=\"default\">\n <span class=\"hierarchy-node-label\" [class.active]=\"isHierarchyNodeSelected(node)\"\n (mouseenter)=\"onHierarchyNodeMouseEnter(node)\" (mouseleave)=\"onHierarchyNodeMouseLeave()\"\n (contextmenu)=\"showHierarchyNodeContextMenu($event, node, hierarchyCtxMenu)\">\n {{ node.label }}\n </span>\n </ng-template>\n </p-tree>\n </div>\n <p-contextMenu #hierarchyCtxMenu [model]=\"hierarchyCtxItems\" appendTo=\"body\" />\n </div>\n </ng-template>\n </p-splitter>\n </ng-template>\n </p-splitter>\n </ng-template>\n <ng-template pTemplate>\n <div class=\"col dashboard-design\" [class.designer-hide-datasources]=\"hideDatasourcesInCanvas\" pDroppable (onDrop)=\"drop($event)\" #canvas\n (contextmenu)=\"showCtx($event, this)\">\n <wuic-dashboard [dashboardElements]=\"dashboardElements\"></wuic-dashboard>\n <p-contextMenu [target]=\"canvas\" [model]=\"ctxItems | async\" appendTo=\"body\" />\n </div>\n </ng-template>\n </p-splitter>\n </div>\n <div class=\"designer-footer\">\n <div class=\"designer-footer-label\">{{ 'designer.items' | translate }}:</div>\n <div class=\"designer-footer-list\">\n @for (item of droppedDashboardItems; track item.uniqueName) {\n <button type=\"button\" class=\"designer-footer-item\" [class.active]=\"tool?.uniqueName === item?.uniqueName\"\n [attr.data-designer-unique-name]=\"item?.uniqueName\" (mouseenter)=\"setFooterHoverHighlight(item)\"\n (mouseleave)=\"clearFooterHoverHighlight()\" (click)=\"selectDashboardItem(item)\"\n (contextmenu)=\"showFooterContextMenu($event, item, footerCtxMenu)\">\n {{ getDroppedDashboardItemLabel(item) }}\n </button>\n }\n </div>\n <p-contextMenu #footerCtxMenu [model]=\"footerCtxItems\" appendTo=\"body\" />\n </div>\n</div>\n}\n\n@if (noEdit) {\n<wuic-dashboard [dashboardElements]=\"dashboardElements\"></wuic-dashboard>\n}\n\n<wuic-archetype-configurator [visible]=\"showArchetypeConfigurator\"\n (visibleChange)=\"onArchetypeConfigVisibleChange($event)\" [archetype]=\"getActiveArchetypeConfig()\"\n [metaInfo]=\"getArchetypeConfigMetaInfoForTool(archetypeConfigTool)\"\n [value]=\"getArchetypeConfigValueForTool(archetypeConfigTool)\" (applyConfig)=\"onArchetypeConfigApply($event)\">\n</wuic-archetype-configurator>\n\n<wuic-css-sheet-editor [visible]=\"showCssSheetEditor\" (visibleChange)=\"onCssSheetEditorVisibleChange($event)\"\n [sheets]=\"dashboardCssSheets\" [selectedSheetPath]=\"selectedCssEditorSheetPath\" [assetsFolder]=\"currentDashboardRoute\"\n [styleProps]=\"getCssEditorStyleProps()\" (applyEditor)=\"onCssSheetEditorApply($event)\">\n</wuic-css-sheet-editor>\n\n<p-dialog [header]=\"'Riapri dashboard'\" [(visible)]=\"reopenDashboardDialogVisible\" [modal]=\"true\" [closable]=\"true\"\n [draggable]=\"false\" [resizable]=\"false\" [appendTo]=\"'body'\" [style]=\"{ width: '34rem' }\"\n (onHide)=\"cancelReopenDashboardDialog()\">\n <div class=\"route-popup-form\">\n <label for=\"designer-reopen-select\">Dashboard esistenti</label>\n <p-select inputId=\"designer-reopen-select\" [options]=\"savedDashboardOptions\" optionLabel=\"label\" optionValue=\"value\"\n [(ngModel)]=\"reopenDialogSelectedDashboardRoute\" [filter]=\"true\" [showClear]=\"true\" [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenDashboardDialog()\">{{ 'cancel' | translate\n }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenDashboardDialog()\"\n [disabled]=\"!reopenDialogSelectedDashboardRoute\">Riapri</button>\n </div>\n </div>\n</p-dialog>\n", styles: [":host{display:block;width:100%;height:100%;min-width:0}.designer-layout{display:grid;grid-template-rows:auto minmax(0,1fr) auto;height:100%;min-height:0;width:100%;min-width:0}.designer-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:8px;border:1px solid inherit;border-radius:10px;background:transparent;padding:10px 12px;margin-bottom:8px}.designer-current-dashboard{min-width:220px;font-size:.86rem;font-weight:700;color:inherit}.designer-toolbar-spacer{flex:1 1 auto;min-width:16px}.designer-toolbar-menu-group{display:inline-flex}.designer-toolbar-menu-group button{height:32px;border:1px solid #2f67d8;border-radius:6px;background:#2f67d8;color:#fff;padding:0 10px;font-size:.82rem;cursor:pointer}.designer-toolbar-menu-group button[disabled]{opacity:.6;cursor:not-allowed}.designer-main{min-height:0;min-width:0;width:100%;overflow:hidden;direction:ltr}.designer-main-splitter{height:100%;width:100%;min-width:0;direction:ltr}.designer-toolbox{font-size:3rem}.designer-toolbox ul{list-style-type:none;padding:0;margin:0;width:100%}.designer-toolbox li{float:left;margin-left:5px;margin-top:5px}.designer-toolbox .tool-groups{display:block}.designer-toolbox .tool-group-item{float:none;margin-left:0;margin-top:10px;clear:both}.designer-toolbox .tool-group-title{font-size:.8rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.7;margin:0 0 4px 6px}.designer-toolbox .tool-group-list{display:flex;flex-wrap:wrap;align-items:flex-start;gap:4px}.designer-toolbox .tool-group-list li{float:none;margin-left:0;margin-top:0}.designer-toolbox .props{font-size:1rem}.designer-toolbox .props li{float:none;padding-bottom:15px}.designer-toolbox .prop-section{width:100%;border:1px solid inherit;border-radius:6px;margin-top:8px;background:transparent;padding:6px 8px 2px}.designer-toolbox .prop-section-title{font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;color:inherit;margin-bottom:6px}.palette-panel{height:100%;overflow:auto;width:100%}.designer-color-alpha-row{display:flex;align-items:center;gap:8px;margin-top:6px;margin-bottom:6px}.designer-color-alpha-label{font-size:.8rem;min-width:40px}.designer-color-alpha-row input[type=range]{flex:1 1 auto;min-width:90px}.designer-color-alpha-row input[type=number]{width:72px}.properties-panel{height:100%;overflow:hidden;width:100%;display:flex;flex-direction:column;min-height:0}.properties-panel>.designer-toolbox{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable}:host ::ng-deep .designer-left-bottom-splitter .p-splitterpanel{min-height:0!important;overflow:hidden!important}:host ::ng-deep .designer-left-bottom-splitter .p-splitterpanel>.p-splitterpanel-content{height:100%;min-height:0;overflow:hidden}.hierarchy-panel{height:100%;width:100%;min-height:0;display:flex;flex-direction:column;overflow:hidden;padding:6px}.hierarchy-panel-title{font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:#4b5563;margin:0 0 6px}.hierarchy-tree-wrap{flex:1 1 auto;min-height:0;border:1px solid inherit;border-radius:6px;background:transparent;overflow:auto;padding:4px}:host ::ng-deep .hierarchy-tree-wrap .p-tree{border:none;padding:0;height:100%;background:transparent}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content{border:1px solid transparent;border-radius:4px;background:transparent!important;color:inherit!important;padding:0!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content.p-highlight{border-color:transparent!important;background:transparent!important;color:inherit!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content:hover{background:transparent!important;color:inherit!important}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label{display:inline-block;border:1px solid inherit;background:transparent;color:inherit;border-radius:4px;padding:2px 8px;font-size:.8rem;line-height:1.25rem;cursor:pointer}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label:hover{border-color:#94a3b8}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label.active{border-color:#3b82f6!important;background:#eff6ff!important;color:#1d4ed8!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content.p-highlight .hierarchy-node-label{border-color:#3b82f6!important;background:#eff6ff!important;color:#1d4ed8!important}.designer-hierarchy-node{cursor:pointer;border:1px solid transparent;border-radius:4px;padding:2px 6px;font-size:.82rem;line-height:1.25rem}.designer-hierarchy-node-label{cursor:pointer;display:inline-block;width:100%}.designer-hierarchy-node.active{border-color:#3b82f6;background:#eff6ff;color:#1d4ed8}.designer-footer-item.designer-tree-hover-target{border-color:#3b82f6!important;outline:1px solid #3b82f6!important;outline-offset:-1px}.dashboard-design{height:100%;min-height:0;min-width:0;width:100%;overflow:auto;direction:ltr}:host ::ng-deep .dashboard-design.designer-hide-datasources .datasource-descriptor{display:none!important}.current-dashboard-title{font-weight:600;margin-right:12px}.designer-footer{display:flex;align-items:center;gap:8px;padding:6px 8px;border-top:1px solid inherit;background:transparent;min-height:36px;flex:0 0 auto;width:100%;overflow:auto}.designer-footer-label{font-size:.85rem;font-weight:600;color:inherit;white-space:nowrap}.designer-footer-list{display:flex;align-items:center;gap:6px;overflow-x:auto;overflow-y:hidden;white-space:nowrap;width:100%}.designer-footer-item{border:1px solid inherit;background:transparent;color:inherit;border-radius:4px;padding:2px 8px;font-size:.8rem;line-height:1.25rem;cursor:pointer;white-space:nowrap}.designer-footer-item.active{border-color:#3b82f6;background:transparent;color:#1d4ed8}:host ::ng-deep .designer-footer-hover-target{border-color:#3b82f6!important;outline:1px solid #3b82f6!important;outline-offset:-1px;box-shadow:inset 0 0 0 1px #3b82f6!important}.route-popup-form{display:flex;flex-direction:column;gap:8px}.route-popup-form label{font-size:.85rem;font-weight:600;color:#2f3f58}.route-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.route-popup-btn{border:1px solid inherit;background:transparent;color:inherit;border-radius:6px;padding:7px 12px;font-size:.85rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f67d8;background:#2f67d8;color:#fff}.p-colorpicker{border:1px solid black;border-radius:4px}\n"] }]
10483
+ args: [{ selector: 'wuic-designer', imports: [NgClass, TranslateModule, AsyncPipe, FormsModule, SplitterModule, DragDropModule, SelectModule, ColorPickerModule, AutoCompleteModule, DashboardComponent, FieldEditorComponent, ContextMenuModule, MetadataEditorComponent, MenubarModule, ArchetypeConfiguratorComponent, ButtonModule, MultiSelectModule, CssSheetEditorComponent, MenuModule, DialogModule, TreeModule], providers: [TreeDragDropService], template: "<!-- <button pButton type=\"button\" (click)=\"loadDashboard()\" class=\"mr-2\">{{'load' | translate}}</button> -->\n@if (!noEdit) {\n<div class=\"designer-layout\">\n <div class=\"designer-toolbar\">\n <div class=\"designer-current-dashboard\">{{ currentDashboardTitle }}</div>\n\n <div class=\"designer-toolbar-spacer\"></div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"undo()\" [disabled]=\"!canUndo\">{{ 'designer.undo' | translate }}</button>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"redo()\" [disabled]=\"!canRedo\">{{ 'designer.redo' | translate }}</button>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"graphActionsMenu.toggle($event)\">{{ 'designer.actions_menu' | translate }}</button>\n <p-menu #graphActionsMenu [popup]=\"true\" [model]=\"graphActionsMenuItems\" appendTo=\"body\"></p-menu>\n </div>\n\n <div class=\"designer-toolbar-menu-group\">\n <button type=\"button\" (click)=\"openCurrentDashboardInNewTab()\" [disabled]=\"!currentDashboardRoute\">{{ 'designer.open_current_dashboard' | translate }}</button>\n </div>\n </div>\n <div class=\"designer-main\">\n <p-splitter [style]=\"{ height: '100%' }\" [panelSizes]=\"[15, 85]\" styleClass=\"designer-main-splitter\">\n <ng-template pTemplate>\n <p-splitter layout=\"vertical\" [style]=\"{ height: '100%', width: '100%' }\" [panelSizes]=\"[35, 65]\"\n [minSizes]=\"[20, 30]\" styleClass=\"designer-left-splitter\">\n <ng-template pTemplate>\n <div class=\"col flex designer-toolbox palette-panel\">\n <ul class=\"tool-groups\">\n @for (toolGroup of availableToolGroups; track toolGroup.group) {\n <li class=\"tool-group-item\">\n <div class=\"tool-group-title\">{{ toolGroup.group }}</div>\n <ul class=\"tool-group-list\">\n @for (tool of toolGroup.tools; track tool) {\n <li pDraggable (onDragStart)=\"dragStart(tool)\" (onDragEnd)=\"dragEnd()\" (onDrag)=\"onDrag($event)\" (dblclick)=\"dropToolAtRoot(tool)\">\n <i [ngClass]=\"tool.icon\" [title]=\"tool.name\"></i>\n </li>\n }\n </ul>\n </li>\n }\n </ul>\n </div>\n </ng-template>\n <ng-template pTemplate>\n <p-splitter layout=\"vertical\" [style]=\"{ height: '100%', width: '100%' }\" [panelSizes]=\"[68, 32]\"\n [minSizes]=\"[35, 20]\" styleClass=\"designer-left-bottom-splitter\">\n <ng-template pTemplate>\n <div class=\"properties-panel\">\n <p-select [style]=\"{width: '100%'}\" [options]=\"flattenedDashboardElements\" [(ngModel)]=\"tool\"\n optionLabel=\"uniqueName\" dataKey=\"componentId\" appendTo=\"body\" />\n <div class=\"col designer-toolbox\">\n @for (section of getToolPropertySections(tool); track section.key) {\n <details class=\"prop-section\" [open]=\"section.open\"\n (toggle)=\"onPropertySectionToggle(tool, section.key, $event)\">\n <summary class=\"prop-section-title\">{{ section.label }}</summary>\n <ul class=\"props\">\n @for (toolProp of section.props; track toolProp.key) {\n <li>\n @if (!toolProp.value.hideCaption) {\n <span>{{ toolProp.value?.propertyCaption ||\n toolProp.key[0].toUpperCase() + toolProp.key.slice(1)\n }}</span>\n }\n <br />\n @if (toolProp.value.type == 'button') {\n <p-button (click)=\"toolProp.value.callback(tool.inputs, toolProp.key, null, tool)\"\n class=\"k-button\" [style]=\"{width: '100%'}\">\n {{toolProp.value.propertyCaption}}\n </p-button>\n }\n @if (toolProp.value.type == 'metaEditor' &&\n tool.inputs['componentRef']?.value?.component) {\n <wuic-metadata-editor [hardcodedDatasource]=\"tool.inputs['componentRef']?.value?.component\"\n [saveCallback]=\"metaEditorSave\"></wuic-metadata-editor>\n }\n @if (toolProp.value.type == 'boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"tool.inputs[toolProp.key]\" />\n }\n @if (toolProp.value.type == 'numberToArray') {\n <input style=\"width: 100%;\" type=\"number\" pInputText [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'txt_area') {\n <textarea style=\"width: 100%;\" [(ngModel)]=\"tool.inputs[toolProp.key]\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\"></textarea>\n }\n @if (toolProp.value.type == 'string') {\n <input style=\"width: 100%;\" type=\"text\" pInputText [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'color') {\n <p-colorPicker\n [ngModel]=\"getDesignerColorPickerHex(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorPickerHexChange($event, tool, toolProp)\" appendTo=\"body\" />\n <div class=\"designer-color-alpha-row\">\n <label class=\"designer-color-alpha-label\">{{ 'designer.alpha' | translate }}</label>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n [ngModel]=\"getDesignerColorAlpha(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorAlphaChange($event, tool, toolProp)\" />\n <input\n type=\"number\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n [ngModel]=\"getDesignerColorAlpha(tool, toolProp)\"\n (ngModelChange)=\"onDesignerColorAlphaChange($event, tool, toolProp)\" />\n </div>\n <input type=\"text\" pInputText [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (toolProp.value.type == 'dictionary' && !toolProp.value.async) {\n @if (toolProp.key == 'cssFile') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"availableProjectCssFiles\"\n [ngModel]=\"tool.inputs[toolProp.key]\" (ngModelChange)=\"onCssFileChanged($event, tool)\" />\n } @else if (toolProp.key == 'cssClass') {\n <p-multiSelect [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getCssClassOptionsForTool(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"onCssClassChanged($event, tool)\" [filter]=\"true\" [virtualScroll]=\"true\"\n [virtualScrollItemSize]=\"38\" scrollHeight=\"260px\" [showToggleAll]=\"false\" display=\"chip\"\n [maxSelectedLabels]=\"3\" [selectedItemsLabel]=\"'{0} selected'\">\n </p-multiSelect>\n } @else if ((tool.name == 'SELECT' || tool.name == 'MULTISELECT' || tool.name == 'UL') &&\n (toolProp.key == 'valueField' || toolProp.key == 'textField')) {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getDatasourceColumnOptions(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n } @else if (tool.name == 'LABEL' && toolProp.key == 'displayField') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [options]=\"getDatasourceColumnOptions(tool)\" [ngModel]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n } @else {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"toolProp.value.values\"\n [(ngModel)]=\"tool.inputs[toolProp.key]\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n }\n @if (toolProp.value.type == 'dictionary' && toolProp.value.async) {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\" [options]=\"toolProp.value.values\"\n [ngModel]=\"tool.inputs[toolProp.key] | async\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" />\n }\n @if (tool.name == 'DATAREPEATER' && toolProp.key == 'action' &&\n canOpenArchetypeConfigurator(tool)) {\n <button style=\"margin-top: 8px;\" (click)=\"openArchetypeConfigurator(tool)\">\n {{ 'designer.configure' | translate }} {{ (tool.inputs['action'] | async) || '' }}\n </button>\n }\n @if (toolProp.value.type == 'dropped-component-list') {\n <p-select [style]=\"{width: '100%'}\" appendTo=\"body\"\n [placeholder]=\"'select.component' | translate\" [options]=\"elementFilter(toolProp)\"\n [ngModel]=\"getDroppedComponentListModel(tool, toolProp)\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" optionLabel=\"uniqueName\"\n dataKey=\"uniqueName\" />\n }\n @if (toolProp.value.type == 'autocomplete') {\n <p-autoComplete [style]=\"{width: '100%'}\" appendTo=\"body\"\n [ngModel]=\"tool.inputs[toolProp.key] | async\" [forceSelection]=\"true\"\n (ngModelChange)=\"setValue($event, tool, toolProp)\" [suggestions]=\"tool.suggestions\"\n [optionLabel]=\"toolProp.value.displayField\" [optionValue]=\"toolProp.value.valueField\"\n (completeMethod)=\"search($event, tool, toolProp)\" [dropdown]=\"true\" dropdownMode=\"current\"\n [multiple]=\"toolProp.value.multiple\" />\n }\n @if (toolProp.value.type == 'propertyTree' && shouldShowPropertyTree(tool)) {\n <ul>\n @for (item of $any(tool.inputs[toolProp.key] | async); track item) {\n <li style=\"padding: 0; margin: 0;\">\n @if (item.col && tool.inputs['customProps_' + (tool.inputs['action'] | async)])\n {\n <wuic-field-editor [field]=\"item.col\"\n [record]=\"tool.inputs['customProps_' + (tool.inputs['action'] | async)]\"\n [metaInfo]=\"tool.inputs['datasource']?.component?.value?.metaInfo\"\n [triggerProp]=\"tool.inputs['action']\"></wuic-field-editor>\n }\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n </details>\n }\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate>\n <div class=\"hierarchy-panel\">\n <div class=\"hierarchy-panel-title\">{{ 'designer.canvas_hierarchy' | translate }}</div>\n <div class=\"hierarchy-tree-wrap\">\n <p-tree [value]=\"hierarchyTreeNodes\" [draggableNodes]=\"true\" [droppableNodes]=\"true\"\n selectionMode=\"single\" [(selection)]=\"hierarchySelection\"\n (onNodeSelect)=\"onHierarchyNodeSelect($event)\" draggableScope=\"designer-hierarchy\"\n droppableScope=\"designer-hierarchy\" (onNodeDrop)=\"onHierarchyNodeDrop($event)\">\n <ng-template let-node pTemplate=\"default\">\n <span class=\"hierarchy-node-label\" [class.active]=\"isHierarchyNodeSelected(node)\"\n (mouseenter)=\"onHierarchyNodeMouseEnter(node)\" (mouseleave)=\"onHierarchyNodeMouseLeave()\"\n (contextmenu)=\"showHierarchyNodeContextMenu($event, node, hierarchyCtxMenu)\">\n {{ node.label }}\n </span>\n </ng-template>\n </p-tree>\n </div>\n <p-contextMenu #hierarchyCtxMenu [model]=\"hierarchyCtxItems\" appendTo=\"body\" />\n </div>\n </ng-template>\n </p-splitter>\n </ng-template>\n </p-splitter>\n </ng-template>\n <ng-template pTemplate>\n <div class=\"col dashboard-design\" [class.designer-hide-datasources]=\"hideDatasourcesInCanvas\" pDroppable (onDrop)=\"drop($event)\" #canvas\n (contextmenu)=\"showCtx($event, this)\">\n <wuic-dashboard [dashboardElements]=\"dashboardElements\"></wuic-dashboard>\n <p-contextMenu [target]=\"canvas\" [model]=\"ctxItems | async\" appendTo=\"body\" />\n </div>\n </ng-template>\n </p-splitter>\n </div>\n <div class=\"designer-footer\">\n <div class=\"designer-footer-label\">{{ 'designer.items' | translate }}:</div>\n <div class=\"designer-footer-list\">\n @for (item of droppedDashboardItems; track item.uniqueName) {\n <button type=\"button\" class=\"designer-footer-item\" [class.active]=\"tool?.uniqueName === item?.uniqueName\"\n [attr.data-designer-unique-name]=\"item?.uniqueName\" (mouseenter)=\"setFooterHoverHighlight(item)\"\n (mouseleave)=\"clearFooterHoverHighlight()\" (click)=\"selectDashboardItem(item)\"\n (contextmenu)=\"showFooterContextMenu($event, item, footerCtxMenu)\">\n {{ getDroppedDashboardItemLabel(item) }}\n </button>\n }\n </div>\n <p-contextMenu #footerCtxMenu [model]=\"footerCtxItems\" appendTo=\"body\" />\n </div>\n</div>\n}\n\n@if (noEdit) {\n<wuic-dashboard [dashboardElements]=\"dashboardElements\"></wuic-dashboard>\n}\n\n<wuic-archetype-configurator [visible]=\"showArchetypeConfigurator\"\n (visibleChange)=\"onArchetypeConfigVisibleChange($event)\" [archetype]=\"getActiveArchetypeConfig()\"\n [metaInfo]=\"getArchetypeConfigMetaInfoForTool(archetypeConfigTool)\"\n [value]=\"getArchetypeConfigValueForTool(archetypeConfigTool)\" (applyConfig)=\"onArchetypeConfigApply($event)\">\n</wuic-archetype-configurator>\n\n<wuic-css-sheet-editor [visible]=\"showCssSheetEditor\" (visibleChange)=\"onCssSheetEditorVisibleChange($event)\"\n [sheets]=\"dashboardCssSheets\" [selectedSheetPath]=\"selectedCssEditorSheetPath\" [assetsFolder]=\"currentDashboardRoute\"\n [styleProps]=\"getCssEditorStyleProps()\" (applyEditor)=\"onCssSheetEditorApply($event)\">\n</wuic-css-sheet-editor>\n\n<p-dialog [header]=\"'designer.reopen_dashboard' | translate\" [(visible)]=\"reopenDashboardDialogVisible\" [modal]=\"true\" [closable]=\"true\"\n [draggable]=\"false\" [resizable]=\"false\" [appendTo]=\"'body'\" [style]=\"{ width: '34rem' }\"\n (onHide)=\"cancelReopenDashboardDialog()\">\n <div class=\"route-popup-form\">\n <label for=\"designer-reopen-select\">{{ 'designer.existing_dashboards' | translate }}</label>\n <p-select inputId=\"designer-reopen-select\" [options]=\"savedDashboardOptions\" optionLabel=\"label\" optionValue=\"value\"\n [(ngModel)]=\"reopenDialogSelectedDashboardRoute\" [filter]=\"true\" [showClear]=\"true\" [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenDashboardDialog()\">{{ 'cancel' | translate\n }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenDashboardDialog()\"\n [disabled]=\"!reopenDialogSelectedDashboardRoute\">{{ 'designer.reopen' | translate }}</button>\n </div>\n </div>\n</p-dialog>\n", styles: [":host{display:block;width:100%;height:100%;min-width:0}.designer-layout{display:grid;grid-template-rows:auto minmax(0,1fr) auto;height:100%;min-height:0;width:100%;min-width:0}.designer-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:8px;border:1px solid inherit;border-radius:10px;background:transparent;padding:10px 12px;margin-bottom:8px}.designer-current-dashboard{min-width:220px;font-size:.86rem;font-weight:700;color:inherit}.designer-toolbar-spacer{flex:1 1 auto;min-width:16px}.designer-toolbar-menu-group{display:inline-flex}.designer-toolbar-menu-group button{height:32px;border:1px solid #2f67d8;border-radius:6px;background:#2f67d8;color:#fff;padding:0 10px;font-size:.82rem;cursor:pointer}.designer-toolbar-menu-group button[disabled]{opacity:.6;cursor:not-allowed}.designer-main{min-height:0;min-width:0;width:100%;overflow:hidden;direction:ltr}.designer-main-splitter{height:100%;width:100%;min-width:0;direction:ltr}.designer-toolbox{font-size:3rem}.designer-toolbox ul{list-style-type:none;padding:0;margin:0;width:100%}.designer-toolbox li{float:left;margin-left:5px;margin-top:5px}.designer-toolbox .tool-groups{display:block}.designer-toolbox .tool-group-item{float:none;margin-left:0;margin-top:10px;clear:both}.designer-toolbox .tool-group-title{font-size:.8rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.7;margin:0 0 4px 6px}.designer-toolbox .tool-group-list{display:flex;flex-wrap:wrap;align-items:flex-start;gap:4px}.designer-toolbox .tool-group-list li{float:none;margin-left:0;margin-top:0}.designer-toolbox .props{font-size:1rem}.designer-toolbox .props li{float:none;padding-bottom:15px}.designer-toolbox .prop-section{width:100%;border:1px solid inherit;border-radius:6px;margin-top:8px;background:transparent;padding:6px 8px 2px}.designer-toolbox .prop-section-title{font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;color:inherit;margin-bottom:6px}.palette-panel{height:100%;overflow:auto;width:100%}.designer-color-alpha-row{display:flex;align-items:center;gap:8px;margin-top:6px;margin-bottom:6px}.designer-color-alpha-label{font-size:.8rem;min-width:40px}.designer-color-alpha-row input[type=range]{flex:1 1 auto;min-width:90px}.designer-color-alpha-row input[type=number]{width:72px}.properties-panel{height:100%;overflow:hidden;width:100%;display:flex;flex-direction:column;min-height:0}.properties-panel>.designer-toolbox{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable}:host ::ng-deep .designer-left-bottom-splitter .p-splitterpanel{min-height:0!important;overflow:hidden!important}.hierarchy-panel{height:100%;width:100%;min-height:0;display:flex;flex-direction:column;overflow:hidden;padding:6px}.hierarchy-panel-title{font-size:.82rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:#4b5563;margin:0 0 6px}.hierarchy-tree-wrap{flex:1 1 auto;min-height:0;border:1px solid inherit;border-radius:6px;background:transparent;overflow:auto;padding:4px}:host ::ng-deep .hierarchy-tree-wrap .p-tree{border:none;padding:0;height:100%;background:transparent}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content{border:1px solid transparent;border-radius:4px;background:transparent!important;color:inherit!important;padding:0!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content.p-highlight{border-color:transparent!important;background:transparent!important;color:inherit!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content:hover{background:transparent!important;color:inherit!important}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label{display:inline-block;border:1px solid inherit;background:transparent;color:inherit;border-radius:4px;padding:2px 8px;font-size:.8rem;line-height:1.25rem;cursor:pointer}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label:hover{border-color:#94a3b8}:host ::ng-deep .hierarchy-tree-wrap .hierarchy-node-label.active{border-color:#3b82f6!important;background:#eff6ff!important;color:#1d4ed8!important}:host ::ng-deep .hierarchy-tree-wrap .p-tree-node-content.p-highlight .hierarchy-node-label{border-color:#3b82f6!important;background:#eff6ff!important;color:#1d4ed8!important}.designer-hierarchy-node{cursor:pointer;border:1px solid transparent;border-radius:4px;padding:2px 6px;font-size:.82rem;line-height:1.25rem}.designer-hierarchy-node-label{cursor:pointer;display:inline-block;width:100%}.designer-hierarchy-node.active{border-color:#3b82f6;background:#eff6ff;color:#1d4ed8}.designer-footer-item.designer-tree-hover-target{border-color:#3b82f6!important;outline:1px solid #3b82f6!important;outline-offset:-1px}.dashboard-design{height:100%;min-height:0;min-width:0;width:100%;overflow:auto;direction:ltr}:host ::ng-deep .dashboard-design.designer-hide-datasources .datasource-descriptor{display:none!important}.current-dashboard-title{font-weight:600;margin-right:12px}.designer-footer{display:flex;align-items:center;gap:8px;padding:6px 8px;border-top:1px solid inherit;background:transparent;min-height:36px;flex:0 0 auto;width:100%;overflow:auto}.designer-footer-label{font-size:.85rem;font-weight:600;color:inherit;white-space:nowrap}.designer-footer-list{display:flex;align-items:center;gap:6px;overflow-x:auto;overflow-y:hidden;white-space:nowrap;width:100%}.designer-footer-item{border:1px solid inherit;background:transparent;color:inherit;border-radius:4px;padding:2px 8px;font-size:.8rem;line-height:1.25rem;cursor:pointer;white-space:nowrap}.designer-footer-item.active{border-color:#3b82f6;background:transparent;color:#1d4ed8}:host ::ng-deep .designer-footer-hover-target{border-color:#3b82f6!important;outline:1px solid #3b82f6!important;outline-offset:-1px;box-shadow:inset 0 0 0 1px #3b82f6!important}.route-popup-form{display:flex;flex-direction:column;gap:8px}.route-popup-form label{font-size:.85rem;font-weight:600;color:#2f3f58}.route-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.route-popup-btn{border:1px solid inherit;background:transparent;color:inherit;border-radius:6px;padding:7px 12px;font-size:.85rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f67d8;background:#2f67d8;color:#fff}.p-colorpicker{border:1px solid black;border-radius:4px}\n"] }]
10195
10484
  }], ctorParameters: () => [{ type: i1$1.ActivatedRoute }, { type: DataProviderService }, { type: MetadataProviderService }, { type: UserInfoService }, { type: i0.ChangeDetectorRef }, { type: TranslationManagerService }, { type: MetadataEditorService }, { type: WorkflowRuntimeMetadataService }], propDecorators: { onWindowHashChange: [{
10196
10485
  type: HostListener,
10197
10486
  args: ['window:hashchange']
@@ -10216,4 +10505,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
10216
10505
  }] } });
10217
10506
 
10218
10507
  export { DesignerComponent };
10219
- //# sourceMappingURL=wuic-framework-lib-designer.component-B61jxcjI.mjs.map
10508
+ //# sourceMappingURL=wuic-framework-lib-designer.component-BnGD84I-.mjs.map