wuic-framework-lib 1.7.6 → 1.7.8

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.
Files changed (21) hide show
  1. package/fesm2022/{wuic-framework-lib-chart-list.component-Bd81NAA4.mjs → wuic-framework-lib-chart-list.component-B-qi3f9x.mjs} +2 -2
  2. package/fesm2022/{wuic-framework-lib-code-editor.component-CT9RQP0j.mjs → wuic-framework-lib-code-editor.component-CdZRro82.mjs} +2 -2
  3. package/fesm2022/{wuic-framework-lib-designer.component-DARgqyVY.mjs → wuic-framework-lib-designer.component-NI80qEef.mjs} +2 -2
  4. package/fesm2022/{wuic-framework-lib-first-run-wizard.component-CpE5e6eG.mjs → wuic-framework-lib-first-run-wizard.component-CZRn9cUV.mjs} +2 -2
  5. package/fesm2022/{wuic-framework-lib-framework-docs.component-C04bapkD.mjs → wuic-framework-lib-framework-docs.component-CreW338k.mjs} +194 -104
  6. package/fesm2022/{wuic-framework-lib-pivot-builder.component-D48ouhKb.mjs → wuic-framework-lib-pivot-builder.component-0iwqvcfZ.mjs} +4 -4
  7. package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-CHdqlPlh.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-DFGOpdlV.mjs} +2 -2
  8. package/fesm2022/{wuic-framework-lib-report-designer.component-CR6AWWCs.mjs → wuic-framework-lib-report-designer.component-x1qjlyS9.mjs} +2 -2
  9. package/fesm2022/{wuic-framework-lib-report-scaffold-dialog.component-UOHh2H80.mjs → wuic-framework-lib-report-scaffold-dialog.component-YO8IyqI9.mjs} +2 -2
  10. package/fesm2022/{wuic-framework-lib-report-viewer.component-jggUwuS6.mjs → wuic-framework-lib-report-viewer.component-AOhX1ah0.mjs} +2 -2
  11. package/fesm2022/{wuic-framework-lib-scene3d-designer.component-Cf99bYCj.mjs → wuic-framework-lib-scene3d-designer.component-B-9lIpui.mjs} +5 -5
  12. package/fesm2022/{wuic-framework-lib-scene3d-light-baker-gpu-CIilDU9M.mjs → wuic-framework-lib-scene3d-light-baker-gpu-MyzRdukh.mjs} +2 -2
  13. package/fesm2022/{wuic-framework-lib-scene3d-viewer.component-BOMK1lig.mjs → wuic-framework-lib-scene3d-viewer.component-DHrKs3zg.mjs} +2 -2
  14. package/fesm2022/{wuic-framework-lib-scheduler-list.component-QpRYvvOw.mjs → wuic-framework-lib-scheduler-list.component-B4Y92Q0p.mjs} +2 -2
  15. package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-qCPw_JOC.mjs → wuic-framework-lib-spreadsheet-list-sf.component-BvVnXgfH.mjs} +2 -2
  16. package/fesm2022/{wuic-framework-lib-timeline-list.component-DUHygnTw.mjs → wuic-framework-lib-timeline-list.component-a_KcbMD0.mjs} +4 -4
  17. package/fesm2022/{wuic-framework-lib-workflow-designer.component-BcFyxfQI.mjs → wuic-framework-lib-workflow-designer.component-A6g5UefX.mjs} +14 -14
  18. package/fesm2022/{wuic-framework-lib-wuic-framework-lib-B2TNmDgm.mjs → wuic-framework-lib-wuic-framework-lib-D4Q320L6.mjs} +11179 -11046
  19. package/fesm2022/wuic-framework-lib.mjs +1 -1
  20. package/package.json +1 -1
  21. package/types/wuic-framework-lib.d.ts +70 -1
@@ -11,7 +11,7 @@ import * as i2 from 'primeng/autocomplete';
11
11
  import { AutoCompleteModule } from 'primeng/autocomplete';
12
12
  import * as i4 from 'primeng/button';
13
13
  import { ButtonModule } from 'primeng/button';
14
- import * as i12 from 'primeng/splitbutton';
14
+ import * as i6 from 'primeng/splitbutton';
15
15
  import { SplitButtonModule } from 'primeng/splitbutton';
16
16
  import * as i5 from 'primeng/select';
17
17
  import { SelectModule } from 'primeng/select';
@@ -25,7 +25,7 @@ import { TableModule } from 'primeng/table';
25
25
  import { Tabs, TabList, Tab, TabPanels, TabPanel } from 'primeng/tabs';
26
26
  import * as i1$3 from '@materia-ui/ngx-monaco-editor';
27
27
  import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
28
- import { W as WtoolboxService, U as UserInfoService, T as TranslationManagerService, M as MetadataProviderService, h as DataProviderService, o as MetaInfo, g as MetadatiColonna, q as FilterInfo, G as GlobalHandler, m as WuicClientException, n as WuicErrorCodes, r as LicenseFeatureService, C as ChatbotHostRegistryService, b as DataSourceComponent, F as FilterBarComponent } from './wuic-framework-lib-wuic-framework-lib-B2TNmDgm.mjs';
28
+ import { W as WtoolboxService, U as UserInfoService, T as TranslationManagerService, M as MetadataProviderService, h as DataProviderService, o as MetaInfo, g as MetadatiColonna, q as FilterInfo, G as GlobalHandler, m as WuicClientException, n as WuicErrorCodes, r as LicenseFeatureService, C as ChatbotHostRegistryService, b as DataSourceComponent, F as FilterBarComponent } from './wuic-framework-lib-wuic-framework-lib-D4Q320L6.mjs';
29
29
  import * as i7 from 'primeng/tooltip';
30
30
  import { TooltipModule } from 'primeng/tooltip';
31
31
  import { ClassicPreset, NodeEditor } from 'rete';
@@ -4936,7 +4936,7 @@ class PivotBuilderComponent {
4936
4936
  return axis.map((c) => c.dateGroupBy ? `${c.alias}(groupBy=${c.dateGroupBy})` : c.alias).join(', ');
4937
4937
  }
4938
4938
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PivotBuilderComponent, deps: [{ token: DataProviderService }, { token: MetadataProviderService }, { token: TranslationManagerService }, { token: i1$2.ActivatedRoute }, { token: LicenseFeatureService }, { token: ChatbotHostRegistryService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
4939
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: PivotBuilderComponent, isStandalone: true, selector: "wuic-pivot-builder", viewQueries: [{ propertyName: "nestedSource", first: true, predicate: ["nestedSource"], descendants: true }, { propertyName: "viewBuilderRef", first: true, predicate: ["viewBuilderRef"], descendants: true }], ngImport: i0, template: "<div class=\"pivot-builder\">\r\n <!-- ===== Global header (just title) ===== -->\r\n <div class=\"pivot-toolbar\">\r\n <h2>{{ 'pivot_builder.title' | translate }}</h2>\r\n </div>\r\n\r\n <wuic-data-source #nestedSource class=\"pivot-hidden-datasource\" [route]=\"pivotRoute$\" [autoload]=\"true\">\r\n </wuic-data-source>\r\n\r\n <!-- ===== Tabs ===== -->\r\n <p-tabs [(value)]=\"activeTab\">\r\n <p-tablist>\r\n <p-tab [value]=\"0\">\r\n <i class=\"pi pi-sitemap mr-2\"></i>\r\n <span>{{ 'pivot_builder.tab.view_builder' | translate }}</span>\r\n </p-tab>\r\n <p-tab [value]=\"1\">\r\n <i class=\"pi pi-th-large mr-2\"></i>\r\n <span>{{ 'pivot_builder.tab.pivot_config' | translate }}</span>\r\n </p-tab>\r\n </p-tablist>\r\n <p-tabpanels>\r\n\r\n <!-- ==================== Tab 0: View Builder ==================== -->\r\n <p-tabpanel [value]=\"0\">\r\n <!-- View Builder toolbar -->\r\n <div class=\"pivot-actions-row\">\r\n <!-- Toolbar: tutti i button uniformati al tema selezionato\r\n (primary color della palette attiva \u2014 es. Aura Blu/Teal/...).\r\n Rimosse severity override per evitare mix `contrast/success/\r\n secondary` che rompeva la coerenza visiva.\r\n \"Create View\", \"Save Definition\", \"Open\" + \"Delete\" sono\r\n raggruppati nello split-button \"Definition\". -->\r\n <div class=\"pivot-actions\">\r\n <p-button [label]=\"'pivot_builder.vb.generate_query' | translate\" icon=\"pi pi-play\" [loading]=\"generatingViewDefSql\"\r\n [disabled]=\"!hasViewDefinition\" (onClick)=\"generateSqlFromViewDefinition()\">\r\n </p-button>\r\n <p-button [label]=\"'pivot_builder.vb.execute_query' | translate\" icon=\"pi pi-bolt\" [loading]=\"executingViewDefQuery\"\r\n [disabled]=\"!hasViewDefinition\" (onClick)=\"executeViewDefinitionQuery()\">\r\n </p-button>\r\n <p-splitButton #definitionSplitBtn\r\n [label]=\"'pivot_builder.vb.definition' | translate\"\r\n icon=\"pi pi-database\"\r\n [model]=\"definitionMenuItems\"\r\n styleClass=\"pivot-actions-definition-split\"\r\n [menuButtonProps]=\"{ ariaLabel: ('pivot_builder.vb.definition' | translate) }\"\r\n (onClick)=\"openDefinitionMenu(definitionSplitBtn, $event)\">\r\n </p-splitButton>\r\n </div>\r\n <!-- Chip della view creata: se c'e' una `createdViewRoute` rendiamo\r\n un anchor cliccabile verso `#/<route>/list` (apertura in nuovo\r\n tab, pattern standard del framework \u2014 vedi list-grid.component\r\n `mc_logic_navigate_new_window`). Altrimenti ricadiamo su uno\r\n span semplice (es. view creata senza scaffold, o payload\r\n legacy senza route). -->\r\n @if (createdViewName) {\r\n @if (createdViewRoute) {\r\n <a class=\"pivot-created-view-label pivot-created-view-link\"\r\n [href]=\"'#/' + createdViewRoute + '/list'\"\r\n target=\"_blank\" rel=\"noopener\"\r\n [title]=\"t('pivot_builder.vb.view_created_tooltip','DB View created from this definition') + ' \u2014 ' + createdViewRoute + '/list'\">\r\n <i class=\"pi pi-database\"></i> {{ createdViewName }}\r\n <i class=\"pi pi-external-link pivot-created-view-ext\"></i>\r\n </a>\r\n } @else {\r\n <span class=\"pivot-created-view-label\" [title]=\"t('pivot_builder.vb.view_created_tooltip','DB View created from this definition')\">\r\n <i class=\"pi pi-database\"></i> {{ createdViewName }}\r\n </span>\r\n }\r\n }\r\n <!-- Settings split-button (pattern \"Azioni designer\"): ogni voce\r\n del menu e' un toggle con icona check/stop che riflette lo\r\n stato corrente (auto-generate, manual SQL, all-filterable,\r\n auto-reflow). Click sulla voce inverte il flag.\r\n Allineato a destra della toolbar tramite\r\n `.pivot-actions-settings` (margin-left: auto). -->\r\n <div class=\"pivot-actions-settings\">\r\n <p-splitButton #settingsSplitBtn\r\n [label]=\"'pivot_builder.vb.settings' | translate\"\r\n icon=\"pi pi-cog\"\r\n [model]=\"settingsMenuItems\"\r\n styleClass=\"pivot-actions-settings-split\"\r\n [menuButtonProps]=\"{ ariaLabel: ('pivot_builder.vb.settings' | translate) }\"\r\n (onClick)=\"openSettingsMenu(settingsSplitBtn, $event)\">\r\n </p-splitButton>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter bar for View Builder (multi-table or single-table) \u2014 hidden in manual SQL mode -->\r\n @if (!manualSqlMode && (viewBuilderFilterMetas.length || viewBuilderFilterRoute)) {\r\n <div class=\"pivot-filter-full\">\r\n <wuic-filter-bar\r\n [multiDatasourceMetas]=\"viewBuilderFilterMetas\"\r\n [hardcodedDatasource]=\"viewBuilderFilterMetas.length ? null! : nestedSource\"\r\n [skipUrlSync]=\"true\"\r\n [skipFetch]=\"true\"\r\n (filterApplied)=\"onViewBuilderFilterApplied()\"\r\n (onFilterApplied)=\"onViewBuilderMultiFilterApplied($event)\"\r\n (onPageSizeApplied)=\"onViewBuilderPageSizeApplied($event)\"\r\n (onSortingApplied)=\"onViewBuilderSortingApplied($event)\"\r\n (onGroupingChanged)=\"onViewBuilderGroupingChanged($event)\">\r\n </wuic-filter-bar>\r\n </div>\r\n }\r\n\r\n <div style=\"flex: 1; min-height: 0; width: 100%;\" [class.pivot-disabled-overlay]=\"manualSqlMode\">\r\n <wuic-view-builder #viewBuilderRef [autoReflowLayout]=\"autoReflowLayout\"\r\n (viewDefinitionChange)=\"onViewDefinitionChange($event)\">\r\n </wuic-view-builder>\r\n </div>\r\n </p-tabpanel>\r\n\r\n <!-- ==================== Tab 1: Pivot Configuration ==================== -->\r\n <p-tabpanel [value]=\"1\">\r\n <!-- Pivot toolbar: route selector + actions -->\r\n <div class=\"pivot-actions-row\">\r\n <!-- Toolbar uniformata al tema selezionato (stessa regola della\r\n tab View Builder: nessuna severity override).\r\n \"Create View\", \"Create Materialized Table\",\r\n \"Save Configuration\", \"Open Pivot\" sono raggruppati nello\r\n split-button \"Actions\" (stesso pattern del Definition\r\n split-button del tab View Builder). -->\r\n <div class=\"pivot-actions\">\r\n <p-button [label]=\"'pivot_builder.generate_query' | translate\" icon=\"pi pi-play\" [loading]=\"generatingSql\"\r\n [disabled]=\"!canExecutePivot\" (onClick)=\"generatePivotSql()\">\r\n </p-button>\r\n <p-button [label]=\"'pivot_builder.execute_query' | translate\" icon=\"pi pi-bolt\"\r\n [loading]=\"executingQuery\" [disabled]=\"!canExecutePivot\" (onClick)=\"executePivotSql()\">\r\n </p-button>\r\n <p-splitButton #pivotConfigSplitBtn\r\n [label]=\"'pivot_builder.actions' | translate\"\r\n [icon]=\"(creatingView || creatingMaterializedTable || savingConfiguration || reopeningPivotList || deletingPivot)\r\n ? 'pi pi-spin pi-spinner'\r\n : 'pi pi-ellipsis-v'\"\r\n [model]=\"pivotConfigMenuItems\"\r\n styleClass=\"pivot-actions-config-split\"\r\n [menuButtonProps]=\"{ ariaLabel: ('pivot_builder.actions' | translate) }\"\r\n (onClick)=\"openPivotConfigMenu(pivotConfigSplitBtn, $event)\">\r\n </p-splitButton>\r\n <!-- Chip cliccabile della view/materialized-table scaffoldata\r\n dal pivot (pattern identico al chip createdViewName del\r\n tab View Builder). Apre `#/<route>/list` in nuovo tab.\r\n Tooltip include il tipo (view o table) serializzato. -->\r\n @if (pivotCreatedName) {\r\n @if (pivotCreatedRoute) {\r\n <a class=\"pivot-created-view-label pivot-created-view-link\"\r\n [href]=\"'#/' + pivotCreatedRoute + '/list'\"\r\n target=\"_blank\" rel=\"noopener\"\r\n [title]=\"(pivotCreatedKind === 'table'\r\n ? t('pivot_builder.pivot_table_created_tooltip','Materialized table created from this pivot')\r\n : t('pivot_builder.pivot_view_created_tooltip','DB view created from this pivot'))\r\n + ' \u2014 ' + pivotCreatedRoute + '/list'\">\r\n <i [ngClass]=\"pivotCreatedKind === 'table' ? 'pi pi-table' : 'pi pi-database'\"></i>\r\n {{ pivotCreatedName }}\r\n <i class=\"pi pi-external-link pivot-created-view-ext\"></i>\r\n </a>\r\n } @else {\r\n <span class=\"pivot-created-view-label\">\r\n <i [ngClass]=\"pivotCreatedKind === 'table' ? 'pi pi-table' : 'pi pi-database'\"></i>\r\n {{ pivotCreatedName }}\r\n </span>\r\n }\r\n }\r\n </div>\r\n <!-- Settings split-button del tab Pivot Config: stessi 3 toggle\r\n del View Builder Settings (auto-generate, manual SQL,\r\n all-filterable) meno il `auto-reflow` che e' specifico del\r\n canvas. Allineato a destra con `.pivot-actions-settings`. -->\r\n <div class=\"pivot-actions-settings\">\r\n <p-splitButton #pivotSettingsSplitBtn\r\n [label]=\"'pivot_builder.vb.settings' | translate\"\r\n icon=\"pi pi-cog\"\r\n [model]=\"pivotSettingsMenuItems\"\r\n styleClass=\"pivot-actions-settings-split\"\r\n [menuButtonProps]=\"{ ariaLabel: ('pivot_builder.vb.settings' | translate) }\"\r\n (onClick)=\"openPivotSettingsMenu(pivotSettingsSplitBtn, $event)\">\r\n </p-splitButton>\r\n </div>\r\n </div>\r\n\r\n <table style=\"width: 100%;\">\r\n <tr>\r\n <td>\r\n <p-autoComplete [(ngModel)]=\"selectedRouteOption\" [suggestions]=\"filteredRouteOptions\"\r\n (completeMethod)=\"filterRouteOptions($event)\" (onSelect)=\"onRouteOptionSelected($event.value)\"\r\n [dropdown]=\"true\" [forceSelection]=\"true\" optionLabel=\"label\"\r\n [placeholder]=\"'pivot_builder.select_route_placeholder' | translate\"\r\n styleClass=\"pivot-route-autocomplete\">\r\n </p-autoComplete>\r\n </td>\r\n <td>\r\n <label>{{ 'aggregation' | translate }}</label>\r\n <p-select [options]=\"aggregateOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [(ngModel)]=\"aggregateFunction\">\r\n </p-select>\r\n </td>\r\n <!-- Campo \"Top rows\" rimosso: il cap viene letto dal `nestedSource.pageSize`\r\n impostato via filter-bar \"Dimensione pagina\" (scelta utente con sentinel\r\n 0 = \"Illimitato\"). topRows resta in stato come default-fallback solo se\r\n il pageSize non e' stato applicato esplicitamente. -->\r\n </tr>\r\n </table>\r\n\r\n <!-- Filter panel -->\r\n <div class=\"pivot-filter-full\">\r\n\r\n @if (selectedRouteName) {\r\n <wuic-filter-bar [hardcodedDatasource]=\"nestedSource\" [skipUrlSync]=\"true\" [skipFetch]=\"true\"\r\n (filterApplied)=\"onFilterBarApplied()\"\r\n (onPageSizeApplied)=\"onPivotConfigPageSizeApplied($event)\"\r\n (onSortingApplied)=\"onPivotConfigSortingApplied($event)\"\r\n (onGroupingChanged)=\"onPivotConfigGroupingChanged($event)\"></wuic-filter-bar>\r\n }\r\n\r\n </div>\r\n\r\n <!-- 4-panel splitter: source cols | rows | columns | values -->\r\n <div class=\"pivot-buckets-row\">\r\n <p-splitter [panelSizes]=\"[28, 24, 24, 24]\" [style]=\"{ height: '100%', width: '100%' }\"\r\n styleClass=\"pivot-buckets-splitter\">\r\n <ng-template #panel>\r\n <div class=\"pivot-panel\">\r\n <h3>{{ 'pivot_builder.route_columns' | translate }}</h3>\r\n <div class=\"pivot-columns-list\" [ngClass]=\"{ 'is-loading': loadingRouteColumns }\">\r\n @for (col of sourceColumns; track col.alias) {\r\n <div class=\"pivot-column-item\" draggable=\"true\" (dragstart)=\"onDragStart($event, col)\">\r\n <span>{{ col.label }}</span>\r\n <div class=\"pivot-column-actions\">\r\n <button type=\"button\" class=\"mini-btn\" (click)=\"addToRows(col)\">{{ 'row' | translate }}</button>\r\n <button type=\"button\" class=\"mini-btn\" (click)=\"addToColumns(col)\">{{ 'column' | translate\r\n }}</button>\r\n <button type=\"button\" class=\"mini-btn\" (click)=\"addToValues(col)\">{{ 'value' | translate\r\n }}</button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #panel>\r\n <div class=\"pivot-panel\">\r\n <h3>{{ 'pivot_builder.rows_axis' | translate }}</h3>\r\n <div class=\"pivot-dropzone\" (dragover)=\"allowDrop($event)\" (drop)=\"onDropToRows($event)\">\r\n @if (!rowColumns.length) {\r\n <div class=\"pivot-empty\">{{ 'pivot_builder.drag_rows_here' | translate }}</div>\r\n }\r\n @for (col of rowColumns; track col.alias) {\r\n <div class=\"pivot-chip\">\r\n <span>{{ col.label }}</span>\r\n @if (isAxisDateCastAvailable(col)) {\r\n <label class=\"pivot-row-cast-flag\">\r\n <input type=\"checkbox\" [ngModel]=\"!!col.castDate\"\r\n (ngModelChange)=\"setRowCastDate(col.alias, $event)\" />\r\n {{ 'pivot_builder.cast_date' | translate }}\r\n </label>\r\n }\r\n @if (isAxisDateTimeGroupAvailable(col)) {\r\n <p-select [options]=\"dateGroupByOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [ngModel]=\"col.dateGroupBy || ''\" (ngModelChange)=\"setRowDateGroupBy(col.alias, $event)\"\r\n appendTo=\"body\" styleClass=\"pivot-chip-agg-select\">\r\n </p-select>\r\n }\r\n <button type=\"button\" (click)=\"removeFromRows(col.alias)\">x</button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #panel>\r\n <div class=\"pivot-panel\">\r\n <h3>{{ 'pivot_builder.columns_axis' | translate }}</h3>\r\n <div class=\"pivot-dropzone\" (dragover)=\"allowDrop($event)\" (drop)=\"onDropToColumns($event)\">\r\n @if (!columnColumns.length) {\r\n <div class=\"pivot-empty\">{{ 'pivot_builder.drag_columns_here' | translate }}</div>\r\n }\r\n @for (col of columnColumns; track col.alias) {\r\n <div class=\"pivot-chip\">\r\n <span>{{ col.label }}</span>\r\n @if (isAxisDateCastAvailable(col)) {\r\n <label class=\"pivot-row-cast-flag\">\r\n <input type=\"checkbox\" [ngModel]=\"!!col.castDate\"\r\n (ngModelChange)=\"setColumnCastDate(col.alias, $event)\" />\r\n {{ 'pivot_builder.cast_date' | translate }}\r\n </label>\r\n }\r\n @if (isAxisDateTimeGroupAvailable(col)) {\r\n <p-select [options]=\"dateGroupByOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [ngModel]=\"col.dateGroupBy || ''\" (ngModelChange)=\"setColumnDateGroupBy(col.alias, $event)\"\r\n appendTo=\"body\" styleClass=\"pivot-chip-agg-select\">\r\n </p-select>\r\n }\r\n <button type=\"button\" (click)=\"removeFromColumns(col.alias)\">x</button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #panel>\r\n <div class=\"pivot-panel\">\r\n <h3>{{ 'pivot_builder.values' | translate }}</h3>\r\n <div class=\"pivot-dropzone\" (dragover)=\"allowDrop($event)\" (drop)=\"onDropToValues($event)\">\r\n @if (!valueColumns.length) {\r\n <div class=\"pivot-empty\">{{ 'pivot_builder.drag_values_here' | translate }}</div>\r\n }\r\n @for (col of valueColumns; track col.id) {\r\n <div class=\"pivot-chip\">\r\n <input class=\"pivot-value-caption\" type=\"text\" [ngModel]=\"col.caption\"\r\n (ngModelChange)=\"setValueCaption(col.id, $event)\" [title]=\"col.label\"\r\n [placeholder]=\"'pivot_builder.metric_caption' | translate\" />\r\n <div class=\"pivot-chip-actions\">\r\n <p-select [options]=\"aggregateOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [ngModel]=\"getValueAggregate(col.id)\" (ngModelChange)=\"setValueAggregate(col.id, $event)\"\r\n appendTo=\"body\" styleClass=\"pivot-chip-agg-select\">\r\n </p-select>\r\n <button type=\"button\" (click)=\"removeFromValues(col.id)\">x</button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-splitter>\r\n </div>\r\n </p-tabpanel>\r\n </p-tabpanels>\r\n </p-tabs>\r\n\r\n <!-- ===== Output row (below tabs, always visible) ===== -->\r\n <div class=\"pivot-output-row\">\r\n @if (!showQueryResults) {\r\n <div class=\"pivot-sql-editor\">\r\n <h3 [innerHTML]=\"'pivot_builder.generated_sql' | translate\"></h3>\r\n @if (generatingViewDefSql || generatingSql) {\r\n <div class=\"pivot-sql-busy\"><i class=\"pi pi-spin pi-spinner\"></i> {{ 'pivot_builder.generating' | translate }}</div>\r\n }\r\n <ngx-monaco-editor [options]=\"sqlEditorOptions\" [(ngModel)]=\"generatedSql\"></ngx-monaco-editor>\r\n </div>\r\n } @else {\r\n <p-splitter [panelSizes]=\"[50, 50]\" [style]=\"{ height: '100%', width: '100%' }\" styleClass=\"pivot-result-splitter\">\r\n <ng-template #panel>\r\n <div class=\"pivot-sql-editor\">\r\n <h3 [innerHTML]=\"'pivot_builder.generated_sql' | translate\"></h3>\r\n @if (generatingViewDefSql || generatingSql) {\r\n <div class=\"pivot-sql-busy\"><i class=\"pi pi-spin pi-spinner\"></i> {{ 'pivot_builder.generating' | translate }}</div>\r\n }\r\n <ngx-monaco-editor [options]=\"sqlEditorOptions\" [(ngModel)]=\"generatedSql\"></ngx-monaco-editor>\r\n </div>\r\n </ng-template>\r\n <ng-template #panel>\r\n <div class=\"pivot-result-panel\">\r\n <h3>{{ 'pivot_builder.query_results' | translate }}</h3>\r\n <p-table [value]=\"queryResultRows\" [scrollable]=\"true\" scrollHeight=\"flex\" styleClass=\"pivot-result-table\">\r\n <ng-template pTemplate=\"header\">\r\n <tr>\r\n @for (c of queryResultColumns; track c) {\r\n <th>{{ c }}</th>\r\n }\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-row>\r\n <tr>\r\n @for (c of queryResultColumns; track c) {\r\n <td>{{ formatQueryCellValue(row?.[c], c) }}</td>\r\n }\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n </div>\r\n </ng-template>\r\n </p-splitter>\r\n }\r\n </div>\r\n</div>\r\n\r\n<p-dialog [header]=\"viewBuilderOpenMode ? t('pivot_builder.vb.open_view_definition','Open View Definition') : ('pivot_builder.reopen_pivot' | translate)\" [(visible)]=\"reopenPivotDialogVisible\" [modal]=\"true\"\r\n [closable]=\"true\" [draggable]=\"false\" [resizable]=\"false\" [appendTo]=\"'body'\" [style]=\"{ width: '34rem' }\"\r\n (onHide)=\"cancelReopenPivotDialog()\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"pivot-reopen-select\">{{ viewBuilderOpenMode ? t('pivot_builder.vb.saved_view_definitions','Saved view definitions') : ('pivot_builder.saved_pivots' | translate) }}</label>\r\n <p-select inputId=\"pivot-reopen-select\" [options]=\"savedPivotOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [(ngModel)]=\"reopenDialogSelectedPivotName\" [filter]=\"true\" [showClear]=\"true\" [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenPivotDialog()\">{{ 'cancel' | translate\r\n }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenPivotDialog()\"\r\n [disabled]=\"!reopenDialogSelectedPivotName\">{{ 'open' | translate }}</button>\r\n </div>\r\n </div>\r\n</p-dialog>", styles: [":host{display:block;height:100%;min-height:0}.pivot-builder{height:100%;min-height:0;padding:.5rem;box-sizing:border-box;display:grid;grid-template-rows:auto minmax(250px,1fr) clamp(120px,25vh,300px);gap:.5rem;overflow:auto}.pivot-toolbar{display:flex;align-items:center;gap:.6rem}.pivot-toolbar h2{margin:0;font-size:1.55rem;white-space:nowrap}.pivot-route-select{min-width:22rem;max-width:34rem;width:100%}.pivot-actions-row{height:40px;display:flex;align-items:center;gap:.75rem}.pivot-created-view-label{display:inline-flex;align-items:center;gap:4px;font-size:.8rem;white-space:nowrap;color:#16a34a;font-weight:600;padding:2px 8px;background:#f0fdf4;border:1px solid #bbf7d0;border-radius:4px}a.pivot-created-view-link{text-decoration:none;cursor:pointer;transition:background-color .12s ease,border-color .12s ease}a.pivot-created-view-link:hover,a.pivot-created-view-link:focus-visible{background:#dcfce7;border-color:#86efac;outline:none}.pivot-created-view-ext{font-size:.72rem;opacity:.6}a.pivot-created-view-link:hover .pivot-created-view-ext{opacity:1}.pivot-disabled-overlay{opacity:.4;pointer-events:none;filter:grayscale(.5)}.pivot-manual-sql-label{color:#dc3545;font-weight:600}.pivot-auto-generate-label{display:inline-flex;align-items:center;gap:4px;font-size:.8rem;white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none;margin-left:auto}.pivot-actions-settings{margin-left:auto;display:inline-flex;align-items:center}.pivot-settings-menu{display:flex;flex-direction:column;gap:10px;min-width:240px;padding:4px 2px}.pivot-settings-item{display:flex;align-items:center;gap:8px;font-size:.85rem;cursor:pointer;-webkit-user-select:none;user-select:none}.pivot-config-group{display:grid;grid-template-columns:minmax(200px,1fr) minmax(160px,200px);gap:.6rem;align-items:end}.pivot-config-item{display:inline;flex-direction:column;gap:.2rem}.pivot-config-item input[type=number]{width:100%;box-sizing:border-box;height:2.45rem;border:1px solid #d4d8e2;border-radius:6px;padding:.35rem .55rem}.pivot-actions{display:inline-flex;gap:.45rem;flex-wrap:wrap}.pivot-hidden-datasource{display:none}.pivot-filter-full{flex:0 0 auto;max-height:40%;max-width:100%;overflow:auto;position:relative;box-sizing:border-box;display:flex;flex-direction:column}.pivot-buckets-row{flex:1;min-height:120px;overflow:hidden}.pivot-output-row{min-height:0;overflow:hidden}.pivot-panel{height:100%;min-height:0;overflow:hidden;border:1px solid #d4d8e2;border-radius:10px;background:#fff;padding:.5rem;box-sizing:border-box;display:flex;flex-direction:column;gap:.4rem}.pivot-panel h3,.pivot-sql-editor h3,.pivot-result-panel h3{margin:0;font-size:.96rem}.pivot-columns-list{flex:1;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:.3rem}.pivot-column-item{border:1px solid #d4d8e2;border-radius:8px;padding:.3rem .4rem;background:#f8faff;cursor:grab;display:flex;align-items:center;justify-content:space-between;gap:.3rem}.pivot-column-actions{display:inline-flex;gap:.2rem}.mini-btn{border:1px solid #c8d0e1;background:#fff;border-radius:6px;font-size:.72rem;padding:.15rem .32rem;cursor:pointer}.pivot-dropzone{min-height:0;flex:1 1 auto;overflow:auto;border:1px dashed #9db0d8;border-radius:8px;padding:.4rem;display:flex;flex-direction:column;gap:.3rem;background:#fbfcff}.pivot-empty{color:#7f8797;font-size:.85rem}.pivot-chip{display:flex;align-items:center;justify-content:space-between;gap:.35rem;border:1px solid #cfd7ea;border-radius:8px;padding:.25rem .4rem;background:#fff}.pivot-value-caption{flex:1 1 auto;min-width:0;border:1px solid #cfd7ea;border-radius:6px;padding:.2rem .35rem;font-size:.82rem}.pivot-chip button{border:none;background:transparent;color:#6d7688;cursor:pointer}.pivot-chip-actions{display:inline-flex;align-items:center;gap:.25rem}:host ::ng-deep .pivot-chip-agg-select{min-width:6.2rem}.pivot-sql-editor,.pivot-result-panel{height:100%;min-height:0;border:1px solid #d4d8e2;border-radius:10px;overflow:hidden;background:#fff;display:flex;flex-direction:column;position:relative}.pivot-sql-busy{position:absolute;inset:0;background:#fffc;display:flex;align-items:center;justify-content:center;gap:.5rem;z-index:5;font-size:.9rem;color:var(--primary-color, #3B82F6)}.pivot-sql-editor h3,.pivot-result-panel h3{padding:.5rem .65rem;border-bottom:1px solid #d4d8e2;background:#f5f7fb}.pivot-sql-editor ngx-monaco-editor{display:block;min-height:0;flex:1 1 auto}:host ::ng-deep .pivot-result-table,:host ::ng-deep .pivot-result-table .p-datatable-wrapper{height:100%;overflow:auto}:host ::ng-deep .pivot-result-table td,:host ::ng-deep .pivot-result-table th{white-space:nowrap}:host ::ng-deep .pivot-buckets-splitter,:host ::ng-deep .pivot-result-splitter{height:100%}:host ::ng-deep .pivot-builder>p-tabs{display:flex;flex-direction:column;min-height:0;overflow:hidden}:host ::ng-deep .pivot-builder>p-tabs>p-tabpanels,:host ::ng-deep .pivot-builder>p-tabs>.p-tabpanels{flex:1;min-height:0;overflow:hidden}:host ::ng-deep .pivot-builder>p-tabs>p-tabpanels>.p-tabpanel:not([hidden]),:host ::ng-deep .pivot-builder>p-tabs>.p-tabpanels>.p-tabpanel:not([hidden]){height:100%;min-height:0;overflow:hidden;display:flex!important;flex-direction:column}:host ::ng-deep .pivot-filter-full .p-accordion,:host ::ng-deep .pivot-filter-full .p-accordionpanel,:host ::ng-deep .pivot-filter-full .p-accordioncontent,:host ::ng-deep .pivot-filter-full .p-accordionpanel-content,:host ::ng-deep .pivot-filter-full .p-accordioncontent-content{position:relative;height:auto!important;max-height:none!important;overflow:visible;max-width:100%}:host ::ng-deep .pivot-filter-full p-tablist,:host ::ng-deep .pivot-filter-full .p-tablist{position:sticky;top:0;z-index:2;background:var(--p-content-background, #fff)}:host ::ng-deep .pivot-filter-full p-tabpanels,:host ::ng-deep .pivot-filter-full .p-tabpanels,:host ::ng-deep .pivot-filter-full p-tabpanel,:host ::ng-deep .pivot-filter-full .p-tabpanel{overflow:visible;max-width:100%}.route-popup-form{display:flex;flex-direction:column;gap:.75rem}.route-popup-form label{font-size:.9rem;font-weight:600}.route-popup-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:.5rem}.route-popup-btn{border:1px solid #d4d8e2;background:#fff;color:#22314d;border-radius:8px;padding:.45rem .9rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f74f2;background:#2f74f2;color:#fff}.p-tabpanels>.p-tabpanel:not([hidden]){height:100%;width:100%;display:inline-block}@media(max-width:1200px){.pivot-builder{grid-template-rows:auto minmax(0,1fr) clamp(120px,25vh,300px)}.pivot-route-select{min-width:14rem}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i2.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: "directive", type: i3.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: SplitButtonModule }, { kind: "component", type: i12.SplitButton, selector: "p-splitbutton, p-splitButton, p-split-button", inputs: ["model", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "icon", "iconPos", "label", "tooltip", "tooltipOptions", "styleClass", "menuStyle", "menuStyleClass", "dropdownIcon", "appendTo", "dir", "expandAriaLabel", "showTransitionOptions", "hideTransitionOptions", "motionOptions", "buttonProps", "menuButtonProps", "autofocus", "disabled", "tabindex", "menuButtonDisabled", "buttonDisabled"], outputs: ["onClick", "onMenuHide", "onMenuShow", "onDropdownClick"] }, { 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: SplitterModule }, { kind: "component", type: i10.Splitter, selector: "p-splitter", inputs: ["styleClass", "panelStyleClass", "panelStyle", "stateStorage", "stateKey", "layout", "gutterSize", "step", "minSizes", "panelSizes"], outputs: ["onResizeEnd", "onResizeStart"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$1.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: TableModule }, { kind: "component", type: i9.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "component", type: Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: TabList, selector: "p-tablist" }, { kind: "component", type: Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: TabPanels, selector: "p-tabpanels" }, { kind: "component", type: TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: MonacoEditorModule }, { kind: "component", type: i1$3.MonacoEditorComponent, selector: "ngx-monaco-editor", inputs: ["options", "uri"], outputs: ["init"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: DataSourceComponent, selector: "wuic-data-source", inputs: ["route", "routeFromRouting", "hardcodedRoute", "autoload", "loading", "changeTracking", "parentRecord", "parentMetaInfo", "parentDatasource", "useComboEndpoint", "comboFormulaLookup", "comboMcId", "comboField", "comboExtraFields", "comboCurrentRecord", "componentRef"] }, { kind: "component", type: FilterBarComponent, selector: "wuic-filter-bar", inputs: ["datasource", "hardcodedDatasource", "multiDatasourceMetas", "skipUrlSync", "skipFetch"], outputs: ["filterApplied", "onFilterApplied", "onSortingApplied", "onPageSizeApplied", "onGroupingChanged", "onFilterBarCollapseChanged"] }, { kind: "component", type: ViewBuilderComponent, selector: "wuic-view-builder", inputs: ["autoReflowLayout"], outputs: ["viewDefinitionChange"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }] });
4939
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: PivotBuilderComponent, isStandalone: true, selector: "wuic-pivot-builder", viewQueries: [{ propertyName: "nestedSource", first: true, predicate: ["nestedSource"], descendants: true }, { propertyName: "viewBuilderRef", first: true, predicate: ["viewBuilderRef"], descendants: true }], ngImport: i0, template: "<div class=\"pivot-builder\">\r\n <!-- ===== Global header (just title) ===== -->\r\n <div class=\"pivot-toolbar\">\r\n <h2>{{ 'pivot_builder.title' | translate }}</h2>\r\n </div>\r\n\r\n <wuic-data-source #nestedSource class=\"pivot-hidden-datasource\" [route]=\"pivotRoute$\" [autoload]=\"true\">\r\n </wuic-data-source>\r\n\r\n <!-- ===== Tabs ===== -->\r\n <p-tabs [(value)]=\"activeTab\">\r\n <p-tablist>\r\n <p-tab [value]=\"0\">\r\n <i class=\"pi pi-sitemap mr-2\"></i>\r\n <span>{{ 'pivot_builder.tab.view_builder' | translate }}</span>\r\n </p-tab>\r\n <p-tab [value]=\"1\">\r\n <i class=\"pi pi-th-large mr-2\"></i>\r\n <span>{{ 'pivot_builder.tab.pivot_config' | translate }}</span>\r\n </p-tab>\r\n </p-tablist>\r\n <p-tabpanels>\r\n\r\n <!-- ==================== Tab 0: View Builder ==================== -->\r\n <p-tabpanel [value]=\"0\">\r\n <!-- View Builder toolbar -->\r\n <div class=\"pivot-actions-row\">\r\n <!-- Toolbar: tutti i button uniformati al tema selezionato\r\n (primary color della palette attiva \u2014 es. Aura Blu/Teal/...).\r\n Rimosse severity override per evitare mix `contrast/success/\r\n secondary` che rompeva la coerenza visiva.\r\n \"Create View\", \"Save Definition\", \"Open\" + \"Delete\" sono\r\n raggruppati nello split-button \"Definition\". -->\r\n <div class=\"pivot-actions\">\r\n <p-button [label]=\"'pivot_builder.vb.generate_query' | translate\" icon=\"pi pi-play\" [loading]=\"generatingViewDefSql\"\r\n [disabled]=\"!hasViewDefinition\" (onClick)=\"generateSqlFromViewDefinition()\">\r\n </p-button>\r\n <p-button [label]=\"'pivot_builder.vb.execute_query' | translate\" icon=\"pi pi-bolt\" [loading]=\"executingViewDefQuery\"\r\n [disabled]=\"!hasViewDefinition\" (onClick)=\"executeViewDefinitionQuery()\">\r\n </p-button>\r\n <p-splitButton #definitionSplitBtn\r\n [label]=\"'pivot_builder.vb.definition' | translate\"\r\n icon=\"pi pi-database\"\r\n [model]=\"definitionMenuItems\"\r\n styleClass=\"pivot-actions-definition-split\"\r\n [menuButtonProps]=\"{ ariaLabel: ('pivot_builder.vb.definition' | translate) }\"\r\n (onClick)=\"openDefinitionMenu(definitionSplitBtn, $event)\">\r\n </p-splitButton>\r\n </div>\r\n <!-- Chip della view creata: se c'e' una `createdViewRoute` rendiamo\r\n un anchor cliccabile verso `#/<route>/list` (apertura in nuovo\r\n tab, pattern standard del framework \u2014 vedi list-grid.component\r\n `mc_logic_navigate_new_window`). Altrimenti ricadiamo su uno\r\n span semplice (es. view creata senza scaffold, o payload\r\n legacy senza route). -->\r\n @if (createdViewName) {\r\n @if (createdViewRoute) {\r\n <a class=\"pivot-created-view-label pivot-created-view-link\"\r\n [href]=\"'#/' + createdViewRoute + '/list'\"\r\n target=\"_blank\" rel=\"noopener\"\r\n [title]=\"t('pivot_builder.vb.view_created_tooltip','DB View created from this definition') + ' \u2014 ' + createdViewRoute + '/list'\">\r\n <i class=\"pi pi-database\"></i> {{ createdViewName }}\r\n <i class=\"pi pi-external-link pivot-created-view-ext\"></i>\r\n </a>\r\n } @else {\r\n <span class=\"pivot-created-view-label\" [title]=\"t('pivot_builder.vb.view_created_tooltip','DB View created from this definition')\">\r\n <i class=\"pi pi-database\"></i> {{ createdViewName }}\r\n </span>\r\n }\r\n }\r\n <!-- Settings split-button (pattern \"Azioni designer\"): ogni voce\r\n del menu e' un toggle con icona check/stop che riflette lo\r\n stato corrente (auto-generate, manual SQL, all-filterable,\r\n auto-reflow). Click sulla voce inverte il flag.\r\n Allineato a destra della toolbar tramite\r\n `.pivot-actions-settings` (margin-left: auto). -->\r\n <div class=\"pivot-actions-settings\">\r\n <p-splitButton #settingsSplitBtn\r\n [label]=\"'pivot_builder.vb.settings' | translate\"\r\n icon=\"pi pi-cog\"\r\n [model]=\"settingsMenuItems\"\r\n styleClass=\"pivot-actions-settings-split\"\r\n [menuButtonProps]=\"{ ariaLabel: ('pivot_builder.vb.settings' | translate) }\"\r\n (onClick)=\"openSettingsMenu(settingsSplitBtn, $event)\">\r\n </p-splitButton>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter bar for View Builder (multi-table or single-table) \u2014 hidden in manual SQL mode -->\r\n @if (!manualSqlMode && (viewBuilderFilterMetas.length || viewBuilderFilterRoute)) {\r\n <div class=\"pivot-filter-full\">\r\n <wuic-filter-bar\r\n [multiDatasourceMetas]=\"viewBuilderFilterMetas\"\r\n [hardcodedDatasource]=\"viewBuilderFilterMetas.length ? null! : nestedSource\"\r\n [skipUrlSync]=\"true\"\r\n [skipFetch]=\"true\"\r\n (filterApplied)=\"onViewBuilderFilterApplied()\"\r\n (onFilterApplied)=\"onViewBuilderMultiFilterApplied($event)\"\r\n (onPageSizeApplied)=\"onViewBuilderPageSizeApplied($event)\"\r\n (onSortingApplied)=\"onViewBuilderSortingApplied($event)\"\r\n (onGroupingChanged)=\"onViewBuilderGroupingChanged($event)\">\r\n </wuic-filter-bar>\r\n </div>\r\n }\r\n\r\n <div style=\"flex: 1; min-height: 0; width: 100%;\" [class.pivot-disabled-overlay]=\"manualSqlMode\">\r\n <wuic-view-builder #viewBuilderRef [autoReflowLayout]=\"autoReflowLayout\"\r\n (viewDefinitionChange)=\"onViewDefinitionChange($event)\">\r\n </wuic-view-builder>\r\n </div>\r\n </p-tabpanel>\r\n\r\n <!-- ==================== Tab 1: Pivot Configuration ==================== -->\r\n <p-tabpanel [value]=\"1\">\r\n <!-- Pivot toolbar: route selector + actions -->\r\n <div class=\"pivot-actions-row\">\r\n <!-- Toolbar uniformata al tema selezionato (stessa regola della\r\n tab View Builder: nessuna severity override).\r\n \"Create View\", \"Create Materialized Table\",\r\n \"Save Configuration\", \"Open Pivot\" sono raggruppati nello\r\n split-button \"Actions\" (stesso pattern del Definition\r\n split-button del tab View Builder). -->\r\n <div class=\"pivot-actions\">\r\n <p-button [label]=\"'pivot_builder.generate_query' | translate\" icon=\"pi pi-play\" [loading]=\"generatingSql\"\r\n [disabled]=\"!canExecutePivot\" (onClick)=\"generatePivotSql()\">\r\n </p-button>\r\n <p-button [label]=\"'pivot_builder.execute_query' | translate\" icon=\"pi pi-bolt\"\r\n [loading]=\"executingQuery\" [disabled]=\"!canExecutePivot\" (onClick)=\"executePivotSql()\">\r\n </p-button>\r\n <p-splitButton #pivotConfigSplitBtn\r\n [label]=\"'pivot_builder.actions' | translate\"\r\n [icon]=\"(creatingView || creatingMaterializedTable || savingConfiguration || reopeningPivotList || deletingPivot)\r\n ? 'pi pi-spin pi-spinner'\r\n : 'pi pi-ellipsis-v'\"\r\n [model]=\"pivotConfigMenuItems\"\r\n styleClass=\"pivot-actions-config-split\"\r\n [menuButtonProps]=\"{ ariaLabel: ('pivot_builder.actions' | translate) }\"\r\n (onClick)=\"openPivotConfigMenu(pivotConfigSplitBtn, $event)\">\r\n </p-splitButton>\r\n <!-- Chip cliccabile della view/materialized-table scaffoldata\r\n dal pivot (pattern identico al chip createdViewName del\r\n tab View Builder). Apre `#/<route>/list` in nuovo tab.\r\n Tooltip include il tipo (view o table) serializzato. -->\r\n @if (pivotCreatedName) {\r\n @if (pivotCreatedRoute) {\r\n <a class=\"pivot-created-view-label pivot-created-view-link\"\r\n [href]=\"'#/' + pivotCreatedRoute + '/list'\"\r\n target=\"_blank\" rel=\"noopener\"\r\n [title]=\"(pivotCreatedKind === 'table'\r\n ? t('pivot_builder.pivot_table_created_tooltip','Materialized table created from this pivot')\r\n : t('pivot_builder.pivot_view_created_tooltip','DB view created from this pivot'))\r\n + ' \u2014 ' + pivotCreatedRoute + '/list'\">\r\n <i [ngClass]=\"pivotCreatedKind === 'table' ? 'pi pi-table' : 'pi pi-database'\"></i>\r\n {{ pivotCreatedName }}\r\n <i class=\"pi pi-external-link pivot-created-view-ext\"></i>\r\n </a>\r\n } @else {\r\n <span class=\"pivot-created-view-label\">\r\n <i [ngClass]=\"pivotCreatedKind === 'table' ? 'pi pi-table' : 'pi pi-database'\"></i>\r\n {{ pivotCreatedName }}\r\n </span>\r\n }\r\n }\r\n </div>\r\n <!-- Settings split-button del tab Pivot Config: stessi 3 toggle\r\n del View Builder Settings (auto-generate, manual SQL,\r\n all-filterable) meno il `auto-reflow` che e' specifico del\r\n canvas. Allineato a destra con `.pivot-actions-settings`. -->\r\n <div class=\"pivot-actions-settings\">\r\n <p-splitButton #pivotSettingsSplitBtn\r\n [label]=\"'pivot_builder.vb.settings' | translate\"\r\n icon=\"pi pi-cog\"\r\n [model]=\"pivotSettingsMenuItems\"\r\n styleClass=\"pivot-actions-settings-split\"\r\n [menuButtonProps]=\"{ ariaLabel: ('pivot_builder.vb.settings' | translate) }\"\r\n (onClick)=\"openPivotSettingsMenu(pivotSettingsSplitBtn, $event)\">\r\n </p-splitButton>\r\n </div>\r\n </div>\r\n\r\n <table style=\"width: 100%;\">\r\n <tr>\r\n <td>\r\n <p-autoComplete [(ngModel)]=\"selectedRouteOption\" [suggestions]=\"filteredRouteOptions\"\r\n (completeMethod)=\"filterRouteOptions($event)\" (onSelect)=\"onRouteOptionSelected($event.value)\"\r\n [dropdown]=\"true\" [forceSelection]=\"true\" optionLabel=\"label\"\r\n [placeholder]=\"'pivot_builder.select_route_placeholder' | translate\"\r\n styleClass=\"pivot-route-autocomplete\">\r\n </p-autoComplete>\r\n </td>\r\n <td>\r\n <label>{{ 'aggregation' | translate }}</label>\r\n <p-select [options]=\"aggregateOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [(ngModel)]=\"aggregateFunction\">\r\n </p-select>\r\n </td>\r\n <!-- Campo \"Top rows\" rimosso: il cap viene letto dal `nestedSource.pageSize`\r\n impostato via filter-bar \"Dimensione pagina\" (scelta utente con sentinel\r\n 0 = \"Illimitato\"). topRows resta in stato come default-fallback solo se\r\n il pageSize non e' stato applicato esplicitamente. -->\r\n </tr>\r\n </table>\r\n\r\n <!-- Filter panel -->\r\n <div class=\"pivot-filter-full\">\r\n\r\n @if (selectedRouteName) {\r\n <wuic-filter-bar [hardcodedDatasource]=\"nestedSource\" [skipUrlSync]=\"true\" [skipFetch]=\"true\"\r\n (filterApplied)=\"onFilterBarApplied()\"\r\n (onPageSizeApplied)=\"onPivotConfigPageSizeApplied($event)\"\r\n (onSortingApplied)=\"onPivotConfigSortingApplied($event)\"\r\n (onGroupingChanged)=\"onPivotConfigGroupingChanged($event)\"></wuic-filter-bar>\r\n }\r\n\r\n </div>\r\n\r\n <!-- 4-panel splitter: source cols | rows | columns | values -->\r\n <div class=\"pivot-buckets-row\">\r\n <p-splitter [panelSizes]=\"[28, 24, 24, 24]\" [style]=\"{ height: '100%', width: '100%' }\"\r\n styleClass=\"pivot-buckets-splitter\">\r\n <ng-template #panel>\r\n <div class=\"pivot-panel\">\r\n <h3>{{ 'pivot_builder.route_columns' | translate }}</h3>\r\n <div class=\"pivot-columns-list\" [ngClass]=\"{ 'is-loading': loadingRouteColumns }\">\r\n @for (col of sourceColumns; track col.alias) {\r\n <div class=\"pivot-column-item\" draggable=\"true\" (dragstart)=\"onDragStart($event, col)\">\r\n <span>{{ col.label }}</span>\r\n <div class=\"pivot-column-actions\">\r\n <button type=\"button\" class=\"mini-btn\" (click)=\"addToRows(col)\">{{ 'row' | translate }}</button>\r\n <button type=\"button\" class=\"mini-btn\" (click)=\"addToColumns(col)\">{{ 'column' | translate\r\n }}</button>\r\n <button type=\"button\" class=\"mini-btn\" (click)=\"addToValues(col)\">{{ 'value' | translate\r\n }}</button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #panel>\r\n <div class=\"pivot-panel\">\r\n <h3>{{ 'pivot_builder.rows_axis' | translate }}</h3>\r\n <div class=\"pivot-dropzone\" (dragover)=\"allowDrop($event)\" (drop)=\"onDropToRows($event)\">\r\n @if (!rowColumns.length) {\r\n <div class=\"pivot-empty\">{{ 'pivot_builder.drag_rows_here' | translate }}</div>\r\n }\r\n @for (col of rowColumns; track col.alias) {\r\n <div class=\"pivot-chip\">\r\n <span>{{ col.label }}</span>\r\n @if (isAxisDateCastAvailable(col)) {\r\n <label class=\"pivot-row-cast-flag\">\r\n <input type=\"checkbox\" [ngModel]=\"!!col.castDate\"\r\n (ngModelChange)=\"setRowCastDate(col.alias, $event)\" />\r\n {{ 'pivot_builder.cast_date' | translate }}\r\n </label>\r\n }\r\n @if (isAxisDateTimeGroupAvailable(col)) {\r\n <p-select [options]=\"dateGroupByOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [ngModel]=\"col.dateGroupBy || ''\" (ngModelChange)=\"setRowDateGroupBy(col.alias, $event)\"\r\n appendTo=\"body\" styleClass=\"pivot-chip-agg-select\">\r\n </p-select>\r\n }\r\n <button type=\"button\" (click)=\"removeFromRows(col.alias)\">x</button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #panel>\r\n <div class=\"pivot-panel\">\r\n <h3>{{ 'pivot_builder.columns_axis' | translate }}</h3>\r\n <div class=\"pivot-dropzone\" (dragover)=\"allowDrop($event)\" (drop)=\"onDropToColumns($event)\">\r\n @if (!columnColumns.length) {\r\n <div class=\"pivot-empty\">{{ 'pivot_builder.drag_columns_here' | translate }}</div>\r\n }\r\n @for (col of columnColumns; track col.alias) {\r\n <div class=\"pivot-chip\">\r\n <span>{{ col.label }}</span>\r\n @if (isAxisDateCastAvailable(col)) {\r\n <label class=\"pivot-row-cast-flag\">\r\n <input type=\"checkbox\" [ngModel]=\"!!col.castDate\"\r\n (ngModelChange)=\"setColumnCastDate(col.alias, $event)\" />\r\n {{ 'pivot_builder.cast_date' | translate }}\r\n </label>\r\n }\r\n @if (isAxisDateTimeGroupAvailable(col)) {\r\n <p-select [options]=\"dateGroupByOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [ngModel]=\"col.dateGroupBy || ''\" (ngModelChange)=\"setColumnDateGroupBy(col.alias, $event)\"\r\n appendTo=\"body\" styleClass=\"pivot-chip-agg-select\">\r\n </p-select>\r\n }\r\n <button type=\"button\" (click)=\"removeFromColumns(col.alias)\">x</button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #panel>\r\n <div class=\"pivot-panel\">\r\n <h3>{{ 'pivot_builder.values' | translate }}</h3>\r\n <div class=\"pivot-dropzone\" (dragover)=\"allowDrop($event)\" (drop)=\"onDropToValues($event)\">\r\n @if (!valueColumns.length) {\r\n <div class=\"pivot-empty\">{{ 'pivot_builder.drag_values_here' | translate }}</div>\r\n }\r\n @for (col of valueColumns; track col.id) {\r\n <div class=\"pivot-chip\">\r\n <input class=\"pivot-value-caption\" type=\"text\" [ngModel]=\"col.caption\"\r\n (ngModelChange)=\"setValueCaption(col.id, $event)\" [title]=\"col.label\"\r\n [placeholder]=\"'pivot_builder.metric_caption' | translate\" />\r\n <div class=\"pivot-chip-actions\">\r\n <p-select [options]=\"aggregateOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [ngModel]=\"getValueAggregate(col.id)\" (ngModelChange)=\"setValueAggregate(col.id, $event)\"\r\n appendTo=\"body\" styleClass=\"pivot-chip-agg-select\">\r\n </p-select>\r\n <button type=\"button\" (click)=\"removeFromValues(col.id)\">x</button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-splitter>\r\n </div>\r\n </p-tabpanel>\r\n </p-tabpanels>\r\n </p-tabs>\r\n\r\n <!-- ===== Output row (below tabs, always visible) ===== -->\r\n <div class=\"pivot-output-row\">\r\n @if (!showQueryResults) {\r\n <div class=\"pivot-sql-editor\">\r\n <h3 [innerHTML]=\"'pivot_builder.generated_sql' | translate\"></h3>\r\n @if (generatingViewDefSql || generatingSql) {\r\n <div class=\"pivot-sql-busy\"><i class=\"pi pi-spin pi-spinner\"></i> {{ 'pivot_builder.generating' | translate }}</div>\r\n }\r\n <ngx-monaco-editor [options]=\"sqlEditorOptions\" [(ngModel)]=\"generatedSql\"></ngx-monaco-editor>\r\n </div>\r\n } @else {\r\n <p-splitter [panelSizes]=\"[50, 50]\" [style]=\"{ height: '100%', width: '100%' }\" styleClass=\"pivot-result-splitter\">\r\n <ng-template #panel>\r\n <div class=\"pivot-sql-editor\">\r\n <h3 [innerHTML]=\"'pivot_builder.generated_sql' | translate\"></h3>\r\n @if (generatingViewDefSql || generatingSql) {\r\n <div class=\"pivot-sql-busy\"><i class=\"pi pi-spin pi-spinner\"></i> {{ 'pivot_builder.generating' | translate }}</div>\r\n }\r\n <ngx-monaco-editor [options]=\"sqlEditorOptions\" [(ngModel)]=\"generatedSql\"></ngx-monaco-editor>\r\n </div>\r\n </ng-template>\r\n <ng-template #panel>\r\n <div class=\"pivot-result-panel\">\r\n <h3>{{ 'pivot_builder.query_results' | translate }}</h3>\r\n <p-table [value]=\"queryResultRows\" [scrollable]=\"true\" scrollHeight=\"flex\" styleClass=\"pivot-result-table\">\r\n <ng-template pTemplate=\"header\">\r\n <tr>\r\n @for (c of queryResultColumns; track c) {\r\n <th>{{ c }}</th>\r\n }\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-row>\r\n <tr>\r\n @for (c of queryResultColumns; track c) {\r\n <td>{{ formatQueryCellValue(row?.[c], c) }}</td>\r\n }\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n </div>\r\n </ng-template>\r\n </p-splitter>\r\n }\r\n </div>\r\n</div>\r\n\r\n<p-dialog [header]=\"viewBuilderOpenMode ? t('pivot_builder.vb.open_view_definition','Open View Definition') : ('pivot_builder.reopen_pivot' | translate)\" [(visible)]=\"reopenPivotDialogVisible\" [modal]=\"true\"\r\n [closable]=\"true\" [draggable]=\"false\" [resizable]=\"false\" [appendTo]=\"'body'\" [style]=\"{ width: '34rem' }\"\r\n (onHide)=\"cancelReopenPivotDialog()\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"pivot-reopen-select\">{{ viewBuilderOpenMode ? t('pivot_builder.vb.saved_view_definitions','Saved view definitions') : ('pivot_builder.saved_pivots' | translate) }}</label>\r\n <p-select inputId=\"pivot-reopen-select\" [options]=\"savedPivotOptions\" optionLabel=\"label\" optionValue=\"value\"\r\n [(ngModel)]=\"reopenDialogSelectedPivotName\" [filter]=\"true\" [showClear]=\"true\" [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenPivotDialog()\">{{ 'cancel' | translate\r\n }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenPivotDialog()\"\r\n [disabled]=\"!reopenDialogSelectedPivotName\">{{ 'open' | translate }}</button>\r\n </div>\r\n </div>\r\n</p-dialog>", styles: [":host{display:block;height:100%;min-height:0}.pivot-builder{height:100%;min-height:0;padding:.5rem;box-sizing:border-box;display:grid;grid-template-rows:auto minmax(250px,1fr) clamp(120px,25vh,300px);gap:.5rem;overflow:auto}.pivot-toolbar{display:flex;align-items:center;gap:.6rem}.pivot-toolbar h2{margin:0;font-size:1.55rem;white-space:nowrap}.pivot-route-select{min-width:22rem;max-width:34rem;width:100%}.pivot-actions-row{height:40px;display:flex;align-items:center;gap:.75rem}.pivot-created-view-label{display:inline-flex;align-items:center;gap:4px;font-size:.8rem;white-space:nowrap;color:#16a34a;font-weight:600;padding:2px 8px;background:#f0fdf4;border:1px solid #bbf7d0;border-radius:4px}a.pivot-created-view-link{text-decoration:none;cursor:pointer;transition:background-color .12s ease,border-color .12s ease}a.pivot-created-view-link:hover,a.pivot-created-view-link:focus-visible{background:#dcfce7;border-color:#86efac;outline:none}.pivot-created-view-ext{font-size:.72rem;opacity:.6}a.pivot-created-view-link:hover .pivot-created-view-ext{opacity:1}.pivot-disabled-overlay{opacity:.4;pointer-events:none;filter:grayscale(.5)}.pivot-manual-sql-label{color:#dc3545;font-weight:600}.pivot-auto-generate-label{display:inline-flex;align-items:center;gap:4px;font-size:.8rem;white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none;margin-left:auto}.pivot-actions-settings{margin-left:auto;display:inline-flex;align-items:center}.pivot-settings-menu{display:flex;flex-direction:column;gap:10px;min-width:240px;padding:4px 2px}.pivot-settings-item{display:flex;align-items:center;gap:8px;font-size:.85rem;cursor:pointer;-webkit-user-select:none;user-select:none}.pivot-config-group{display:grid;grid-template-columns:minmax(200px,1fr) minmax(160px,200px);gap:.6rem;align-items:end}.pivot-config-item{display:inline;flex-direction:column;gap:.2rem}.pivot-config-item input[type=number]{width:100%;box-sizing:border-box;height:2.45rem;border:1px solid #d4d8e2;border-radius:6px;padding:.35rem .55rem}.pivot-actions{display:inline-flex;gap:.45rem;flex-wrap:wrap}.pivot-hidden-datasource{display:none}.pivot-filter-full{flex:0 0 auto;max-height:40%;max-width:100%;overflow:auto;position:relative;box-sizing:border-box;display:flex;flex-direction:column}.pivot-buckets-row{flex:1;min-height:120px;overflow:hidden}.pivot-output-row{min-height:0;overflow:hidden}.pivot-panel{height:100%;min-height:0;overflow:hidden;border:1px solid #d4d8e2;border-radius:10px;background:#fff;padding:.5rem;box-sizing:border-box;display:flex;flex-direction:column;gap:.4rem}.pivot-panel h3,.pivot-sql-editor h3,.pivot-result-panel h3{margin:0;font-size:.96rem}.pivot-columns-list{flex:1;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:.3rem}.pivot-column-item{border:1px solid #d4d8e2;border-radius:8px;padding:.3rem .4rem;background:#f8faff;cursor:grab;display:flex;align-items:center;justify-content:space-between;gap:.3rem}.pivot-column-actions{display:inline-flex;gap:.2rem}.mini-btn{border:1px solid #c8d0e1;background:#fff;border-radius:6px;font-size:.72rem;padding:.15rem .32rem;cursor:pointer}.pivot-dropzone{min-height:0;flex:1 1 auto;overflow:auto;border:1px dashed #9db0d8;border-radius:8px;padding:.4rem;display:flex;flex-direction:column;gap:.3rem;background:#fbfcff}.pivot-empty{color:#7f8797;font-size:.85rem}.pivot-chip{display:flex;align-items:center;justify-content:space-between;gap:.35rem;border:1px solid #cfd7ea;border-radius:8px;padding:.25rem .4rem;background:#fff}.pivot-value-caption{flex:1 1 auto;min-width:0;border:1px solid #cfd7ea;border-radius:6px;padding:.2rem .35rem;font-size:.82rem}.pivot-chip button{border:none;background:transparent;color:#6d7688;cursor:pointer}.pivot-chip-actions{display:inline-flex;align-items:center;gap:.25rem}:host ::ng-deep .pivot-chip-agg-select{min-width:6.2rem}.pivot-sql-editor,.pivot-result-panel{height:100%;min-height:0;border:1px solid #d4d8e2;border-radius:10px;overflow:hidden;background:#fff;display:flex;flex-direction:column;position:relative}.pivot-sql-busy{position:absolute;inset:0;background:#fffc;display:flex;align-items:center;justify-content:center;gap:.5rem;z-index:5;font-size:.9rem;color:var(--primary-color, #3B82F6)}.pivot-sql-editor h3,.pivot-result-panel h3{padding:.5rem .65rem;border-bottom:1px solid #d4d8e2;background:#f5f7fb}.pivot-sql-editor ngx-monaco-editor{display:block;min-height:0;flex:1 1 auto}:host ::ng-deep .pivot-result-table,:host ::ng-deep .pivot-result-table .p-datatable-wrapper{height:100%;overflow:auto}:host ::ng-deep .pivot-result-table td,:host ::ng-deep .pivot-result-table th{white-space:nowrap}:host ::ng-deep .pivot-buckets-splitter,:host ::ng-deep .pivot-result-splitter{height:100%}:host ::ng-deep .pivot-builder>p-tabs{display:flex;flex-direction:column;min-height:0;overflow:hidden}:host ::ng-deep .pivot-builder>p-tabs>p-tabpanels,:host ::ng-deep .pivot-builder>p-tabs>.p-tabpanels{flex:1;min-height:0;overflow:hidden}:host ::ng-deep .pivot-builder>p-tabs>p-tabpanels>.p-tabpanel:not([hidden]),:host ::ng-deep .pivot-builder>p-tabs>.p-tabpanels>.p-tabpanel:not([hidden]){height:100%;min-height:0;overflow:hidden;display:flex!important;flex-direction:column}:host ::ng-deep .pivot-filter-full .p-accordion,:host ::ng-deep .pivot-filter-full .p-accordionpanel,:host ::ng-deep .pivot-filter-full .p-accordioncontent,:host ::ng-deep .pivot-filter-full .p-accordionpanel-content,:host ::ng-deep .pivot-filter-full .p-accordioncontent-content{position:relative;height:auto!important;max-height:none!important;overflow:visible;max-width:100%}:host ::ng-deep .pivot-filter-full p-tablist,:host ::ng-deep .pivot-filter-full .p-tablist{position:sticky;top:0;z-index:2;background:var(--p-content-background, #fff)}:host ::ng-deep .pivot-filter-full p-tabpanels,:host ::ng-deep .pivot-filter-full .p-tabpanels,:host ::ng-deep .pivot-filter-full p-tabpanel,:host ::ng-deep .pivot-filter-full .p-tabpanel{overflow:visible;max-width:100%}.route-popup-form{display:flex;flex-direction:column;gap:.75rem}.route-popup-form label{font-size:.9rem;font-weight:600}.route-popup-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:.5rem}.route-popup-btn{border:1px solid #d4d8e2;background:#fff;color:#22314d;border-radius:8px;padding:.45rem .9rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f74f2;background:#2f74f2;color:#fff}.p-tabpanels>.p-tabpanel:not([hidden]){height:100%;width:100%;display:inline-block}@media(max-width:1200px){.pivot-builder{grid-template-rows:auto minmax(0,1fr) clamp(120px,25vh,300px)}.pivot-route-select{min-width:14rem}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i2.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: "directive", type: i3.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: SplitButtonModule }, { kind: "component", type: i6.SplitButton, selector: "p-splitbutton, p-splitButton, p-split-button", inputs: ["model", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "icon", "iconPos", "label", "tooltip", "tooltipOptions", "styleClass", "menuStyle", "menuStyleClass", "dropdownIcon", "appendTo", "dir", "expandAriaLabel", "showTransitionOptions", "hideTransitionOptions", "motionOptions", "buttonProps", "menuButtonProps", "autofocus", "disabled", "tabindex", "menuButtonDisabled", "buttonDisabled"], outputs: ["onClick", "onMenuHide", "onMenuShow", "onDropdownClick"] }, { 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: SplitterModule }, { kind: "component", type: i10.Splitter, selector: "p-splitter", inputs: ["styleClass", "panelStyleClass", "panelStyle", "stateStorage", "stateKey", "layout", "gutterSize", "step", "minSizes", "panelSizes"], outputs: ["onResizeEnd", "onResizeStart"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$1.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: TableModule }, { kind: "component", type: i9.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "component", type: Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: TabList, selector: "p-tablist" }, { kind: "component", type: Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: TabPanels, selector: "p-tabpanels" }, { kind: "component", type: TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: MonacoEditorModule }, { kind: "component", type: i1$3.MonacoEditorComponent, selector: "ngx-monaco-editor", inputs: ["options", "uri"], outputs: ["init"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: DataSourceComponent, selector: "wuic-data-source", inputs: ["route", "routeFromRouting", "hardcodedRoute", "autoload", "loading", "changeTracking", "parentRecord", "parentMetaInfo", "parentDatasource", "useComboEndpoint", "comboFormulaLookup", "comboMcId", "comboField", "comboExtraFields", "comboCurrentRecord", "componentRef"] }, { kind: "component", type: FilterBarComponent, selector: "wuic-filter-bar", inputs: ["datasource", "hardcodedDatasource", "multiDatasourceMetas", "skipUrlSync", "skipFetch"], outputs: ["filterApplied", "onFilterApplied", "onSortingApplied", "onPageSizeApplied", "onGroupingChanged", "onFilterBarCollapseChanged"] }, { kind: "component", type: ViewBuilderComponent, selector: "wuic-view-builder", inputs: ["autoReflowLayout"], outputs: ["viewDefinitionChange"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }] });
4940
4940
  }
4941
4941
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PivotBuilderComponent, decorators: [{
4942
4942
  type: Component,
@@ -4950,4 +4950,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4950
4950
  }] } });
4951
4951
 
4952
4952
  export { PivotBuilderComponent };
4953
- //# sourceMappingURL=wuic-framework-lib-pivot-builder.component-D48ouhKb.mjs.map
4953
+ //# sourceMappingURL=wuic-framework-lib-pivot-builder.component-0iwqvcfZ.mjs.map
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { EventEmitter, Output, Input, Component } from '@angular/core';
3
3
  import * as i2 from 'primeng/dialog';
4
4
  import { DialogModule } from 'primeng/dialog';
5
- import { f as ParametricDialogComponent } from './wuic-framework-lib-wuic-framework-lib-B2TNmDgm.mjs';
5
+ import { f as ParametricDialogComponent } from './wuic-framework-lib-wuic-framework-lib-D4Q320L6.mjs';
6
6
 
7
7
  class PromptDialogFallbackHostComponent {
8
8
  datasource;
@@ -96,4 +96,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
96
96
  }] } });
97
97
 
98
98
  export { PromptDialogFallbackHostComponent };
99
- //# sourceMappingURL=wuic-framework-lib-prompt-dialog-fallback-host.component-CHdqlPlh.mjs.map
99
+ //# sourceMappingURL=wuic-framework-lib-prompt-dialog-fallback-host.component-DFGOpdlV.mjs.map
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { ViewChild, Component } from '@angular/core';
3
- import { W as WtoolboxService, M as MetadataProviderService, C as ChatbotHostRegistryService } from './wuic-framework-lib-wuic-framework-lib-B2TNmDgm.mjs';
3
+ import { W as WtoolboxService, M as MetadataProviderService, C as ChatbotHostRegistryService } from './wuic-framework-lib-wuic-framework-lib-D4Q320L6.mjs';
4
4
  import * as i4 from 'stimulsoft-designer-angular';
5
5
  import { StimulsoftDesignerModule, StimulsoftDesignerComponent } from 'stimulsoft-designer-angular';
6
6
  import * as i1 from '@angular/router';
@@ -377,4 +377,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
377
377
  }] } });
378
378
 
379
379
  export { ReportDesignerComponent };
380
- //# sourceMappingURL=wuic-framework-lib-report-designer.component-CR6AWWCs.mjs.map
380
+ //# sourceMappingURL=wuic-framework-lib-report-designer.component-x1qjlyS9.mjs.map
@@ -13,7 +13,7 @@ import * as i6 from 'primeng/radiobutton';
13
13
  import { RadioButtonModule } from 'primeng/radiobutton';
14
14
  import * as i5$1 from 'primeng/select';
15
15
  import { SelectModule } from 'primeng/select';
16
- import { W as WtoolboxService } from './wuic-framework-lib-wuic-framework-lib-B2TNmDgm.mjs';
16
+ import { W as WtoolboxService } from './wuic-framework-lib-wuic-framework-lib-D4Q320L6.mjs';
17
17
  import * as i1 from 'primeng/dynamicdialog';
18
18
  import * as i1$1 from '@angular/common/http';
19
19
 
@@ -428,4 +428,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
428
428
  }], ctorParameters: () => [{ type: i1.DynamicDialogRef }, { type: i1.DynamicDialogConfig }, { type: i1$1.HttpClient }] });
429
429
 
430
430
  export { ReportScaffoldDialogComponent };
431
- //# sourceMappingURL=wuic-framework-lib-report-scaffold-dialog.component-UOHh2H80.mjs.map
431
+ //# sourceMappingURL=wuic-framework-lib-report-scaffold-dialog.component-YO8IyqI9.mjs.map
@@ -5,7 +5,7 @@ import { NavigationEnd } from '@angular/router';
5
5
  import { CommonModule } from '@angular/common';
6
6
  import * as i3 from 'stimulsoft-viewer-angular';
7
7
  import { StimulsoftViewerModule, StimulsoftViewerComponent } from 'stimulsoft-viewer-angular';
8
- import { W as WtoolboxService } from './wuic-framework-lib-wuic-framework-lib-B2TNmDgm.mjs';
8
+ import { W as WtoolboxService } from './wuic-framework-lib-wuic-framework-lib-D4Q320L6.mjs';
9
9
  import { e as ensureWuicStimulsoftLicenseRegistered } from './wuic-framework-lib-stimulsoft-license.service-CsNNSFYs.mjs';
10
10
  import { firstValueFrom } from 'rxjs';
11
11
  import * as i1$1 from '@angular/common/http';
@@ -471,4 +471,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
471
471
  }] } });
472
472
 
473
473
  export { ReportViewerComponent };
474
- //# sourceMappingURL=wuic-framework-lib-report-viewer.component-jggUwuS6.mjs.map
474
+ //# sourceMappingURL=wuic-framework-lib-report-viewer.component-AOhX1ah0.mjs.map