wuic-framework-lib 1.5.0 → 1.7.0

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 (26) hide show
  1. package/fesm2022/{wuic-framework-lib-chart-list.component-0J1ghIrS.mjs → wuic-framework-lib-chart-list.component-Bl424n7x.mjs} +50 -38
  2. package/fesm2022/{wuic-framework-lib-code-editor.component-C21mvjyr.mjs → wuic-framework-lib-code-editor.component-N6HMl2mf.mjs} +174 -274
  3. package/fesm2022/{wuic-framework-lib-designer.component-x10ZzUEy.mjs → wuic-framework-lib-designer.component-Bd2fwl6H.mjs} +499 -581
  4. package/fesm2022/{wuic-framework-lib-first-run-wizard.component-BuSxs_CM.mjs → wuic-framework-lib-first-run-wizard.component-NN6cWVHL.mjs} +22 -24
  5. package/fesm2022/{wuic-framework-lib-framework-docs.component-xTGLbEnp.mjs → wuic-framework-lib-framework-docs.component-B867JAYe.mjs} +2912 -294
  6. package/fesm2022/{wuic-framework-lib-pivot-builder.component-BkFFjPm4.mjs → wuic-framework-lib-pivot-builder.component-DWukH0L-.mjs} +580 -68
  7. package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-Bi-TrJB6.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-DWO1Rcgv.mjs} +2 -2
  8. package/fesm2022/wuic-framework-lib-report-designer.component-QcrU81m6.mjs +380 -0
  9. package/fesm2022/wuic-framework-lib-report-scaffold-dialog.component-U-zdOoRV.mjs +431 -0
  10. package/fesm2022/{wuic-framework-lib-report-viewer.component-BR-BfI2r.mjs → wuic-framework-lib-report-viewer.component-B4LhA3SL.mjs} +8 -13
  11. package/fesm2022/{wuic-framework-lib-scene3d-designer.component-BQzFxSXP.mjs → wuic-framework-lib-scene3d-designer.component-DjOfzKLo.mjs} +323 -88
  12. package/fesm2022/{wuic-framework-lib-scene3d-light-baker-gpu-0LjqhSNn.mjs → wuic-framework-lib-scene3d-light-baker-gpu-C96T9uIW.mjs} +2 -2
  13. package/fesm2022/{wuic-framework-lib-scene3d-shader-effect-CQLWkuh1.mjs → wuic-framework-lib-scene3d-shader-effect-DjHyCAFK.mjs} +612 -32
  14. package/fesm2022/{wuic-framework-lib-scene3d-viewer.component-imoV3HOs.mjs → wuic-framework-lib-scene3d-viewer.component-Dboz1fjl.mjs} +149 -18
  15. package/fesm2022/{wuic-framework-lib-scheduler-list.component-xzlTEkoq.mjs → wuic-framework-lib-scheduler-list.component--wY21R3o.mjs} +169 -53
  16. package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-CrS6fOGj.mjs → wuic-framework-lib-spreadsheet-list-sf.component-Ek30J8v-.mjs} +149 -108
  17. package/fesm2022/{wuic-framework-lib-stimulsoft-license.service-BIyxB4pO.mjs → wuic-framework-lib-stimulsoft-license.service-CsNNSFYs.mjs} +3 -3
  18. package/fesm2022/wuic-framework-lib-timeline-list.component-aqCH4P0G.mjs +805 -0
  19. package/fesm2022/{wuic-framework-lib-workflow-designer.component-5xtQ7-6z.mjs → wuic-framework-lib-workflow-designer.component-DMM8BeXm.mjs} +180 -150
  20. package/fesm2022/{wuic-framework-lib-wuic-framework-lib-3TZ-j-yL.mjs → wuic-framework-lib-wuic-framework-lib-dfLTqam5.mjs} +6761 -2347
  21. package/fesm2022/wuic-framework-lib.mjs +1 -1
  22. package/package.json +4 -2
  23. package/styles/_wuic-tokens.scss +82 -0
  24. package/styles/styles.scss +160 -0
  25. package/types/wuic-framework-lib.d.ts +4264 -2691
  26. package/fesm2022/wuic-framework-lib-report-designer.component-ZvB46-LV.mjs +0 -194
@@ -0,0 +1,431 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { Component } from '@angular/core';
4
+ import * as i1$2 from '@angular/forms';
5
+ import { FormsModule } from '@angular/forms';
6
+ import * as i8 from '@ngx-translate/core';
7
+ import { TranslateModule } from '@ngx-translate/core';
8
+ import * as i4 from 'primeng/button';
9
+ import { ButtonModule } from 'primeng/button';
10
+ import * as i5 from 'primeng/checkbox';
11
+ import { CheckboxModule } from 'primeng/checkbox';
12
+ import * as i6 from 'primeng/radiobutton';
13
+ import { RadioButtonModule } from 'primeng/radiobutton';
14
+ import * as i5$1 from 'primeng/select';
15
+ import { SelectModule } from 'primeng/select';
16
+ import { W as WtoolboxService } from './wuic-framework-lib-wuic-framework-lib-dfLTqam5.mjs';
17
+ import * as i1 from 'primeng/dynamicdialog';
18
+ import * as i1$1 from '@angular/common/http';
19
+
20
+ /**
21
+ * Dialog intermedio del flusso "Crea report" (menubar metadata-editor):
22
+ * scelta del template (bands celle popolate / crosstab / cross-group
23
+ * raggruppato) + colonne da includere, con le specifiche del tipo.
24
+ *
25
+ * Aperto via DynamicDialog con `data: { route, metaInfo }`. Alla conferma
26
+ * chiude con `{ template, config }` (config = oggetto ScaffoldConfig, la
27
+ * serializzazione JSON la fa il caller via MetadataProviderService).
28
+ * Cancel → close(undefined) → il caller non fa nulla.
29
+ */
30
+ class ReportScaffoldDialogComponent {
31
+ ref;
32
+ config;
33
+ http;
34
+ route = '';
35
+ template = 'bands';
36
+ templates = [
37
+ { value: 'bands', labelKey: 'report.scaffold.template_bands', descKey: 'report.scaffold.template_bands_desc' },
38
+ { value: 'crosstab', labelKey: 'report.scaffold.template_crosstab', descKey: 'report.scaffold.template_crosstab_desc' },
39
+ { value: 'crossgroup', labelKey: 'report.scaffold.template_crossgroup', descKey: 'report.scaffold.template_crossgroup_desc' }
40
+ ];
41
+ aggregations = [
42
+ { value: 'Sum', label: 'Sum' },
43
+ { value: 'Avg', label: 'Avg' },
44
+ { value: 'Count', label: 'Count' },
45
+ { value: 'Min', label: 'Min' },
46
+ { value: 'Max', label: 'Max' }
47
+ ];
48
+ mainColumns = [];
49
+ childRoutes = [];
50
+ crosstabColumn = null;
51
+ crosstabValue = null;
52
+ crosstabAggregation = 'Sum';
53
+ groupBy = null;
54
+ totals = [];
55
+ constructor(ref, config, http) {
56
+ this.ref = ref;
57
+ this.config = config;
58
+ this.http = http;
59
+ }
60
+ ngOnInit() {
61
+ const data = this.config?.data || {};
62
+ this.route = String(data.route || '');
63
+ const metaInfo = data.metaInfo;
64
+ this.mainColumns = (metaInfo?.columnMetadata || [])
65
+ .filter((c) => c?.mc_nome_colonna && c.mc_ui_column_type !== 'button')
66
+ .map((c) => ({
67
+ name: String(c.mc_nome_colonna),
68
+ label: String(c.mc_display_string_in_view || c.mc_nome_colonna),
69
+ type: String(c.mc_ui_column_type || 'text'),
70
+ checked: true
71
+ }));
72
+ // Child route dichiarate nei metadata (detail-first, formato route||localkey||childkey).
73
+ const tableMeta = metaInfo?.tableMetadata || {};
74
+ const def = String(tableMeta.md_detail_grid_routes || tableMeta.md_nested_grid_routes || '');
75
+ this.childRoutes = def
76
+ ? def.split(',')
77
+ .map((token) => token.split('||')[0]?.trim())
78
+ .filter((r) => !!r)
79
+ .map((r) => ({ route: r, checked: false, loading: false, loaded: false, columns: [] }))
80
+ : [];
81
+ }
82
+ get allColumnOptions() {
83
+ return this.mainColumns;
84
+ }
85
+ /** Colonne candidate a valore/totali: numeriche; tutte se aggregazione Count. */
86
+ get valueColumnOptions() {
87
+ if (this.crosstabAggregation === 'Count' && this.template === 'crosstab') {
88
+ return this.mainColumns;
89
+ }
90
+ const numeric = this.mainColumns.filter((c) => c.type === 'number' || c.type === 'number_boolean');
91
+ return numeric.length ? numeric : this.mainColumns;
92
+ }
93
+ async onChildToggle(child, checked) {
94
+ child.checked = checked;
95
+ if (!checked || child.loaded || child.loading) {
96
+ return;
97
+ }
98
+ child.loading = true;
99
+ try {
100
+ const url = (WtoolboxService.appSettings?.global_root_url ?? '') + 'MetaService.getColonneByUserID';
101
+ const res = await this.http.post(url, { route: child.route }, { withCredentials: true }).toPromise();
102
+ child.columns = (res?.results || [])
103
+ .filter((c) => c?.mc_nome_colonna && c.mc_ui_column_type !== 'button')
104
+ .map((c) => ({
105
+ name: String(c.mc_nome_colonna),
106
+ label: String(c.mc_display_string_in_view || c.mc_nome_colonna),
107
+ type: String(c.mc_ui_column_type || 'text'),
108
+ checked: true
109
+ }));
110
+ child.loaded = true;
111
+ }
112
+ catch {
113
+ child.checked = false;
114
+ }
115
+ finally {
116
+ child.loading = false;
117
+ }
118
+ }
119
+ addTotal() {
120
+ const first = this.valueColumnOptions[0];
121
+ this.totals.push({ column: first ? first.name : null, aggregation: 'Sum' });
122
+ }
123
+ removeTotal(index) {
124
+ this.totals.splice(index, 1);
125
+ }
126
+ isValid() {
127
+ if (this.template === 'bands') {
128
+ return this.mainColumns.some((c) => c.checked);
129
+ }
130
+ if (this.template === 'crosstab') {
131
+ return this.mainColumns.some((c) => c.checked) && !!this.crosstabColumn && !!this.crosstabValue;
132
+ }
133
+ // crossgroup
134
+ return !!this.groupBy && this.mainColumns.some((c) => c.checked);
135
+ }
136
+ cancel() {
137
+ this.ref.close(undefined);
138
+ }
139
+ confirm() {
140
+ const checkedMain = this.mainColumns.filter((c) => c.checked).map((c) => c.name);
141
+ let config;
142
+ if (this.template === 'crosstab') {
143
+ config = {
144
+ crosstab: {
145
+ rows: checkedMain,
146
+ column: this.crosstabColumn,
147
+ value: this.crosstabValue,
148
+ aggregation: this.crosstabAggregation
149
+ }
150
+ };
151
+ }
152
+ else if (this.template === 'crossgroup') {
153
+ config = {
154
+ crossGroup: {
155
+ groupBy: this.groupBy,
156
+ detailColumns: checkedMain,
157
+ totals: this.totals
158
+ .filter((t) => !!t.column)
159
+ .map((t) => ({ column: t.column, aggregation: t.aggregation }))
160
+ }
161
+ };
162
+ }
163
+ else {
164
+ config = {
165
+ bands: {
166
+ columns: checkedMain,
167
+ children: this.childRoutes
168
+ .filter((ch) => ch.checked && ch.columns.some((c) => c.checked))
169
+ .map((ch) => ({
170
+ route: ch.route,
171
+ columns: ch.columns.filter((c) => c.checked).map((c) => c.name)
172
+ }))
173
+ }
174
+ };
175
+ }
176
+ this.ref.close({ template: this.template, config });
177
+ }
178
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ReportScaffoldDialogComponent, deps: [{ token: i1.DynamicDialogRef }, { token: i1.DynamicDialogConfig }, { token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
179
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ReportScaffoldDialogComponent, isStandalone: true, selector: "wuic-report-scaffold-dialog", ngImport: i0, template: `
180
+ <div class="rsd-section">
181
+ <h4>{{ 'report.scaffold.template_label' | translate }}</h4>
182
+ <div class="rsd-templates">
183
+ @for (t of templates; track t.value) {
184
+ <div class="rsd-template-row">
185
+ <p-radioButton [inputId]="'rsd-t-' + t.value" name="rsdTemplate" [value]="t.value" [(ngModel)]="template" />
186
+ <label [for]="'rsd-t-' + t.value">
187
+ <b>{{ t.labelKey | translate }}</b>
188
+ <div class="rsd-template-desc">{{ t.descKey | translate }}</div>
189
+ </label>
190
+ </div>
191
+ }
192
+ </div>
193
+ </div>
194
+
195
+ @if (template === 'bands') {
196
+ <div class="rsd-section">
197
+ <h4>{{ 'report.scaffold.columns_label' | translate }}</h4>
198
+ <div class="rsd-columns">
199
+ @for (col of mainColumns; track col.name) {
200
+ <div class="rsd-col-row">
201
+ <p-checkbox [binary]="true" [(ngModel)]="col.checked" [inputId]="'rsd-c-' + col.name" />
202
+ <label [for]="'rsd-c-' + col.name" class="rsd-col-label" [title]="col.name">{{ col.label }}</label>
203
+ </div>
204
+ }
205
+ </div>
206
+
207
+ @if (childRoutes.length) {
208
+ <h4 style="margin-top: .75rem">{{ 'report.scaffold.child_routes_label' | translate }}</h4>
209
+ @for (child of childRoutes; track child.route) {
210
+ <div class="rsd-child">
211
+ <div class="rsd-child-header">
212
+ <p-checkbox [binary]="true" [ngModel]="child.checked" (ngModelChange)="onChildToggle(child, $event)"
213
+ [inputId]="'rsd-ch-' + child.route" />
214
+ <label [for]="'rsd-ch-' + child.route">{{ child.route }}</label>
215
+ </div>
216
+ @if (child.checked) {
217
+ @if (child.loading) {
218
+ <div class="rsd-loading">{{ 'loading' | translate }}</div>
219
+ } @else {
220
+ <div class="rsd-columns" style="margin-top: .4rem">
221
+ @for (col of child.columns; track col.name) {
222
+ <div class="rsd-col-row">
223
+ <p-checkbox [binary]="true" [(ngModel)]="col.checked" [inputId]="'rsd-cc-' + child.route + '-' + col.name" />
224
+ <label [for]="'rsd-cc-' + child.route + '-' + col.name" class="rsd-col-label">{{ col.label }}</label>
225
+ </div>
226
+ }
227
+ </div>
228
+ }
229
+ }
230
+ </div>
231
+ }
232
+ }
233
+ </div>
234
+ }
235
+
236
+ @if (template === 'crosstab') {
237
+ <div class="rsd-section">
238
+ <div class="rsd-field">
239
+ <label>{{ 'report.scaffold.rows_label' | translate }}</label>
240
+ <div class="rsd-columns">
241
+ @for (col of mainColumns; track col.name) {
242
+ <div class="rsd-col-row">
243
+ <p-checkbox [binary]="true" [(ngModel)]="col.checked" [inputId]="'rsd-r-' + col.name" />
244
+ <label [for]="'rsd-r-' + col.name" class="rsd-col-label">{{ col.label }}</label>
245
+ </div>
246
+ }
247
+ </div>
248
+ </div>
249
+ <div class="rsd-field">
250
+ <label>{{ 'report.scaffold.column_label' | translate }}</label>
251
+ <p-select [options]="allColumnOptions" [(ngModel)]="crosstabColumn" optionLabel="label" optionValue="name" [filter]="true" appendTo="body" />
252
+ </div>
253
+ <div class="rsd-field">
254
+ <label>{{ 'report.scaffold.value_label' | translate }}</label>
255
+ <p-select [options]="valueColumnOptions" [(ngModel)]="crosstabValue" optionLabel="label" optionValue="name" [filter]="true" appendTo="body" />
256
+ </div>
257
+ <div class="rsd-field">
258
+ <label>{{ 'report.scaffold.aggregation_label' | translate }}</label>
259
+ <p-select [options]="aggregations" [(ngModel)]="crosstabAggregation" optionLabel="label" optionValue="value" appendTo="body" />
260
+ </div>
261
+ </div>
262
+ }
263
+
264
+ @if (template === 'crossgroup') {
265
+ <div class="rsd-section">
266
+ <div class="rsd-field">
267
+ <label>{{ 'report.scaffold.group_by_label' | translate }}</label>
268
+ <p-select [options]="allColumnOptions" [(ngModel)]="groupBy" optionLabel="label" optionValue="name" [filter]="true" appendTo="body" />
269
+ </div>
270
+ <div class="rsd-field">
271
+ <label>{{ 'report.scaffold.detail_columns_label' | translate }}</label>
272
+ <div class="rsd-columns">
273
+ @for (col of mainColumns; track col.name) {
274
+ <div class="rsd-col-row">
275
+ <p-checkbox [binary]="true" [(ngModel)]="col.checked" [inputId]="'rsd-d-' + col.name" />
276
+ <label [for]="'rsd-d-' + col.name" class="rsd-col-label">{{ col.label }}</label>
277
+ </div>
278
+ }
279
+ </div>
280
+ </div>
281
+ <div class="rsd-field">
282
+ <label>{{ 'report.scaffold.totals_label' | translate }}</label>
283
+ @for (total of totals; track $index) {
284
+ <div class="rsd-total-row">
285
+ <p-select [options]="valueColumnOptions" [(ngModel)]="total.column" optionLabel="label" optionValue="name" appendTo="body" />
286
+ <p-select [options]="aggregations" [(ngModel)]="total.aggregation" optionLabel="label" optionValue="value" appendTo="body" />
287
+ <p-button icon="pi pi-times" [text]="true" severity="danger" (onClick)="removeTotal($index)" />
288
+ </div>
289
+ }
290
+ <div class="rsd-total-row">
291
+ <p-button icon="pi pi-plus" [outlined]="true" size="small" (onClick)="addTotal()" [disabled]="!valueColumnOptions.length" />
292
+ </div>
293
+ </div>
294
+ </div>
295
+ }
296
+
297
+ <div class="rsd-footer">
298
+ <p-button [label]="'Cancel' | translate" [outlined]="true" (onClick)="cancel()" />
299
+ <p-button [label]="'report.scaffold.create_button' | translate" [disabled]="!isValid()" (onClick)="confirm()" />
300
+ </div>
301
+ `, isInline: true, styles: [":host{display:block}.rsd-section{margin-bottom:1rem}.rsd-templates{display:flex;flex-direction:column;gap:.5rem}.rsd-template-row{display:flex;align-items:flex-start;gap:.5rem}.rsd-template-desc{font-size:.8rem;opacity:.7}.rsd-columns{max-height:220px;overflow-y:auto;border:1px solid var(--p-content-border-color, #e2e8f0);border-radius:6px;padding:.5rem}.rsd-col-row{display:flex;align-items:center;gap:.5rem;padding:.15rem 0}.rsd-col-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rsd-child{border:1px solid var(--p-content-border-color, #e2e8f0);border-radius:6px;padding:.5rem;margin-top:.5rem}.rsd-child-header{display:flex;align-items:center;gap:.5rem;font-weight:600}.rsd-field{display:flex;flex-direction:column;gap:.25rem;margin-bottom:.75rem}.rsd-field label{font-size:.8rem;opacity:.75}.rsd-total-row{display:flex;align-items:center;gap:.5rem;margin-top:.35rem}.rsd-footer{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}.rsd-loading{font-style:italic;opacity:.7;padding:.25rem 0}h4{margin:0 0 .5rem}\n"], dependencies: [{ 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: CheckboxModule }, { kind: "component", type: i5.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i6.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "styleClass", "autofocus", "binary", "variant", "size"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5$1.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: TranslateModule }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }] });
302
+ }
303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ReportScaffoldDialogComponent, decorators: [{
304
+ type: Component,
305
+ args: [{ selector: 'wuic-report-scaffold-dialog', standalone: true, imports: [ButtonModule, CheckboxModule, CommonModule, FormsModule, RadioButtonModule, SelectModule, TranslateModule], template: `
306
+ <div class="rsd-section">
307
+ <h4>{{ 'report.scaffold.template_label' | translate }}</h4>
308
+ <div class="rsd-templates">
309
+ @for (t of templates; track t.value) {
310
+ <div class="rsd-template-row">
311
+ <p-radioButton [inputId]="'rsd-t-' + t.value" name="rsdTemplate" [value]="t.value" [(ngModel)]="template" />
312
+ <label [for]="'rsd-t-' + t.value">
313
+ <b>{{ t.labelKey | translate }}</b>
314
+ <div class="rsd-template-desc">{{ t.descKey | translate }}</div>
315
+ </label>
316
+ </div>
317
+ }
318
+ </div>
319
+ </div>
320
+
321
+ @if (template === 'bands') {
322
+ <div class="rsd-section">
323
+ <h4>{{ 'report.scaffold.columns_label' | translate }}</h4>
324
+ <div class="rsd-columns">
325
+ @for (col of mainColumns; track col.name) {
326
+ <div class="rsd-col-row">
327
+ <p-checkbox [binary]="true" [(ngModel)]="col.checked" [inputId]="'rsd-c-' + col.name" />
328
+ <label [for]="'rsd-c-' + col.name" class="rsd-col-label" [title]="col.name">{{ col.label }}</label>
329
+ </div>
330
+ }
331
+ </div>
332
+
333
+ @if (childRoutes.length) {
334
+ <h4 style="margin-top: .75rem">{{ 'report.scaffold.child_routes_label' | translate }}</h4>
335
+ @for (child of childRoutes; track child.route) {
336
+ <div class="rsd-child">
337
+ <div class="rsd-child-header">
338
+ <p-checkbox [binary]="true" [ngModel]="child.checked" (ngModelChange)="onChildToggle(child, $event)"
339
+ [inputId]="'rsd-ch-' + child.route" />
340
+ <label [for]="'rsd-ch-' + child.route">{{ child.route }}</label>
341
+ </div>
342
+ @if (child.checked) {
343
+ @if (child.loading) {
344
+ <div class="rsd-loading">{{ 'loading' | translate }}</div>
345
+ } @else {
346
+ <div class="rsd-columns" style="margin-top: .4rem">
347
+ @for (col of child.columns; track col.name) {
348
+ <div class="rsd-col-row">
349
+ <p-checkbox [binary]="true" [(ngModel)]="col.checked" [inputId]="'rsd-cc-' + child.route + '-' + col.name" />
350
+ <label [for]="'rsd-cc-' + child.route + '-' + col.name" class="rsd-col-label">{{ col.label }}</label>
351
+ </div>
352
+ }
353
+ </div>
354
+ }
355
+ }
356
+ </div>
357
+ }
358
+ }
359
+ </div>
360
+ }
361
+
362
+ @if (template === 'crosstab') {
363
+ <div class="rsd-section">
364
+ <div class="rsd-field">
365
+ <label>{{ 'report.scaffold.rows_label' | translate }}</label>
366
+ <div class="rsd-columns">
367
+ @for (col of mainColumns; track col.name) {
368
+ <div class="rsd-col-row">
369
+ <p-checkbox [binary]="true" [(ngModel)]="col.checked" [inputId]="'rsd-r-' + col.name" />
370
+ <label [for]="'rsd-r-' + col.name" class="rsd-col-label">{{ col.label }}</label>
371
+ </div>
372
+ }
373
+ </div>
374
+ </div>
375
+ <div class="rsd-field">
376
+ <label>{{ 'report.scaffold.column_label' | translate }}</label>
377
+ <p-select [options]="allColumnOptions" [(ngModel)]="crosstabColumn" optionLabel="label" optionValue="name" [filter]="true" appendTo="body" />
378
+ </div>
379
+ <div class="rsd-field">
380
+ <label>{{ 'report.scaffold.value_label' | translate }}</label>
381
+ <p-select [options]="valueColumnOptions" [(ngModel)]="crosstabValue" optionLabel="label" optionValue="name" [filter]="true" appendTo="body" />
382
+ </div>
383
+ <div class="rsd-field">
384
+ <label>{{ 'report.scaffold.aggregation_label' | translate }}</label>
385
+ <p-select [options]="aggregations" [(ngModel)]="crosstabAggregation" optionLabel="label" optionValue="value" appendTo="body" />
386
+ </div>
387
+ </div>
388
+ }
389
+
390
+ @if (template === 'crossgroup') {
391
+ <div class="rsd-section">
392
+ <div class="rsd-field">
393
+ <label>{{ 'report.scaffold.group_by_label' | translate }}</label>
394
+ <p-select [options]="allColumnOptions" [(ngModel)]="groupBy" optionLabel="label" optionValue="name" [filter]="true" appendTo="body" />
395
+ </div>
396
+ <div class="rsd-field">
397
+ <label>{{ 'report.scaffold.detail_columns_label' | translate }}</label>
398
+ <div class="rsd-columns">
399
+ @for (col of mainColumns; track col.name) {
400
+ <div class="rsd-col-row">
401
+ <p-checkbox [binary]="true" [(ngModel)]="col.checked" [inputId]="'rsd-d-' + col.name" />
402
+ <label [for]="'rsd-d-' + col.name" class="rsd-col-label">{{ col.label }}</label>
403
+ </div>
404
+ }
405
+ </div>
406
+ </div>
407
+ <div class="rsd-field">
408
+ <label>{{ 'report.scaffold.totals_label' | translate }}</label>
409
+ @for (total of totals; track $index) {
410
+ <div class="rsd-total-row">
411
+ <p-select [options]="valueColumnOptions" [(ngModel)]="total.column" optionLabel="label" optionValue="name" appendTo="body" />
412
+ <p-select [options]="aggregations" [(ngModel)]="total.aggregation" optionLabel="label" optionValue="value" appendTo="body" />
413
+ <p-button icon="pi pi-times" [text]="true" severity="danger" (onClick)="removeTotal($index)" />
414
+ </div>
415
+ }
416
+ <div class="rsd-total-row">
417
+ <p-button icon="pi pi-plus" [outlined]="true" size="small" (onClick)="addTotal()" [disabled]="!valueColumnOptions.length" />
418
+ </div>
419
+ </div>
420
+ </div>
421
+ }
422
+
423
+ <div class="rsd-footer">
424
+ <p-button [label]="'Cancel' | translate" [outlined]="true" (onClick)="cancel()" />
425
+ <p-button [label]="'report.scaffold.create_button' | translate" [disabled]="!isValid()" (onClick)="confirm()" />
426
+ </div>
427
+ `, styles: [":host{display:block}.rsd-section{margin-bottom:1rem}.rsd-templates{display:flex;flex-direction:column;gap:.5rem}.rsd-template-row{display:flex;align-items:flex-start;gap:.5rem}.rsd-template-desc{font-size:.8rem;opacity:.7}.rsd-columns{max-height:220px;overflow-y:auto;border:1px solid var(--p-content-border-color, #e2e8f0);border-radius:6px;padding:.5rem}.rsd-col-row{display:flex;align-items:center;gap:.5rem;padding:.15rem 0}.rsd-col-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rsd-child{border:1px solid var(--p-content-border-color, #e2e8f0);border-radius:6px;padding:.5rem;margin-top:.5rem}.rsd-child-header{display:flex;align-items:center;gap:.5rem;font-weight:600}.rsd-field{display:flex;flex-direction:column;gap:.25rem;margin-bottom:.75rem}.rsd-field label{font-size:.8rem;opacity:.75}.rsd-total-row{display:flex;align-items:center;gap:.5rem;margin-top:.35rem}.rsd-footer{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}.rsd-loading{font-style:italic;opacity:.7;padding:.25rem 0}h4{margin:0 0 .5rem}\n"] }]
428
+ }], ctorParameters: () => [{ type: i1.DynamicDialogRef }, { type: i1.DynamicDialogConfig }, { type: i1$1.HttpClient }] });
429
+
430
+ export { ReportScaffoldDialogComponent };
431
+ //# sourceMappingURL=wuic-framework-lib-report-scaffold-dialog.component-U-zdOoRV.mjs.map
@@ -5,8 +5,8 @@ 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-3TZ-j-yL.mjs';
9
- import { e as ensureWuicStimulsoftLicenseRegistered } from './wuic-framework-lib-stimulsoft-license.service-BIyxB4pO.mjs';
8
+ import { W as WtoolboxService } from './wuic-framework-lib-wuic-framework-lib-dfLTqam5.mjs';
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';
12
12
 
@@ -51,7 +51,7 @@ class ReportViewerComponent {
51
51
  /**
52
52
  * Proprieta di stato del componente per action, usata dalla logica interna e dal template.
53
53
  */
54
- action;
54
+ action = 'InitViewer';
55
55
  /**
56
56
  * Valore corrente selezionato per current report, usato dai flussi interattivi del componente.
57
57
  */
@@ -87,7 +87,6 @@ class ReportViewerComponent {
87
87
  this.router = router;
88
88
  this.aRoute = aRoute;
89
89
  this.http = http;
90
- this.action = 'InitViewer';
91
90
  this.baseRequestUrl = WtoolboxService.appSettings.api_url + 'ReportViewer/{action}';
92
91
  this.requestUrl = WtoolboxService.appSettings.api_url + 'ReportViewer/{action}';
93
92
  this.viewerProperties = {
@@ -436,11 +435,7 @@ class ReportViewerComponent {
436
435
  this.logDiag('output.error', event);
437
436
  }
438
437
  logDiag(message, payload) {
439
- // if (payload !== undefined) {
440
- // console.log(`${this.diagnosticPrefix} ${message}`, payload);
441
- // return;
442
- // }
443
- // console.log(`${this.diagnosticPrefix} ${message}`);
438
+ // no-op: hook diagnostico disattivato (riattivare qui il console.log se serve)
444
439
  }
445
440
  downloadBlob(blob, fileName) {
446
441
  if (!blob) {
@@ -455,7 +450,7 @@ class ReportViewerComponent {
455
450
  anchor.style.display = 'none';
456
451
  document.body.appendChild(anchor);
457
452
  anchor.click();
458
- document.body.removeChild(anchor);
453
+ anchor.remove();
459
454
  setTimeout(() => URL.revokeObjectURL(blobUrl), 2000);
460
455
  }
461
456
  /**
@@ -465,15 +460,15 @@ class ReportViewerComponent {
465
460
  this.routerEventsSubscription?.unsubscribe();
466
461
  }
467
462
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ReportViewerComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
468
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ReportViewerComponent, isStandalone: true, selector: "wuic-report-viewer", viewQueries: [{ propertyName: "viewer", first: true, predicate: StimulsoftViewerComponent, descendants: true }], ngImport: i0, template: "@defer (on immediate) {\n @if (canRenderViewer) {\n <stimulsoft-viewer-angular [requestUrl]=\"requestUrl\" [action]=\"action\" [width]=\"'100%'\"\n [height]=\"'calc(100% - 10px)'\" [properties]=\"viewerProperties\" (loaded)=\"onViewerLoaded()\" (export)=\"onExportEvent($event)\"\n (print)=\"onPrintEvent($event)\" (error)=\"onViewerError($event)\"></stimulsoft-viewer-angular>\n } @else {\n <!-- Preflight in corso o fallito. Se fallito, la dialog localizzata e'\n gia' stata mostrata da WuicErrorInterceptor \u2192 GlobalHandler. -->\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Verifica disponibilit\u00E0 report\u2026</span>\n </div>\n }\n} @placeholder {\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Caricamento Report Viewer\u2026</span>\n <small>Il SDK Stimulsoft \u00E8 in download (~15 MB). Operazione una tantum.</small>\n </div>\n} @loading (minimum 300ms) {\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Rendering report\u2026</span>\n </div>\n} @error {\n <div class=\"stimulsoft-error-placeholder\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>Errore nel caricamento del Report Viewer. Verifica connessione e ricarica la pagina.</span>\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%;flex:1 1 auto;min-height:0}:host ::ng-deep stimulsoft-viewer-angular{display:block;width:100%;height:100%}:host ::ng-deep .stiJsViewerForm,:host ::ng-deep .stiJsViewerDisabledPanel{display:none!important}.stimulsoft-loading-placeholder,.stimulsoft-error-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:100%;height:100%;min-height:400px;color:#64748b;font-size:1rem;background:#f8fafc;border:1px dashed #cbd5e1;border-radius:8px}.stimulsoft-loading-placeholder .pi-spinner{font-size:2rem;color:#6366f1}.stimulsoft-loading-placeholder small{font-size:.8rem;color:#94a3b8;max-width:400px;text-align:center}.stimulsoft-error-placeholder{color:#b91c1c;background:#fef2f2;border-color:#fecaca}.stimulsoft-error-placeholder .pi-exclamation-triangle{font-size:2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: StimulsoftViewerModule }], deferBlockDependencies: [() => [i3.StimulsoftViewerComponent]] });
463
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ReportViewerComponent, isStandalone: true, selector: "wuic-report-viewer", viewQueries: [{ propertyName: "viewer", first: true, predicate: StimulsoftViewerComponent, descendants: true }], ngImport: i0, template: "@defer (on immediate) {\n @if (canRenderViewer) {\n <stimulsoft-viewer-angular [requestUrl]=\"requestUrl\" [action]=\"action\" [width]=\"'100%'\"\n [height]=\"'calc(100% - 10px)'\" [properties]=\"viewerProperties\" (loaded)=\"onViewerLoaded()\" (export)=\"onExportEvent($event)\"\n (print)=\"onPrintEvent($event)\" (error)=\"onViewerError($event)\"></stimulsoft-viewer-angular>\n } @else {\n <!-- Preflight in corso o fallito. Se fallito, la dialog localizzata e'\n gia' stata mostrata da WuicErrorInterceptor \u2192 GlobalHandler. -->\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Verifica disponibilit\u00E0 report\u2026</span>\n </div>\n }\n} @placeholder {\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Caricamento Report Viewer\u2026</span>\n <small>Il SDK Stimulsoft \u00E8 in download (~15 MB). Operazione una tantum.</small>\n </div>\n} @loading (minimum 300ms) {\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Rendering report\u2026</span>\n </div>\n} @error {\n <div class=\"stimulsoft-error-placeholder\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>Errore nel caricamento del Report Viewer. Verifica connessione e ricarica la pagina.</span>\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%;flex:1 1 auto;min-height:0}:host ::ng-deep stimulsoft-viewer-angular{display:block;width:100%;height:100%}:host ::ng-deep .stiJsViewerForm,:host ::ng-deep .stiJsViewerDisabledPanel{display:none!important}.stimulsoft-loading-placeholder,.stimulsoft-error-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:100%;height:100%;min-height:400px;color:var(--wuic-text-muted, #64748b);font-size:1rem;background:var(--wuic-surface-soft, #f8fafc);border:1px dashed var(--wuic-border, #cbd5e1);border-radius:var(--wuic-radius-lg, 8px)}.stimulsoft-loading-placeholder .pi-spinner{font-size:2rem;color:var(--wuic-accent, #6366f1)}.stimulsoft-loading-placeholder small{font-size:.8rem;color:var(--wuic-text-muted, #94a3b8);max-width:400px;text-align:center}.stimulsoft-error-placeholder{color:#b91c1c;background:#fef2f2;border-color:#fecaca}.stimulsoft-error-placeholder .pi-exclamation-triangle{font-size:2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: StimulsoftViewerModule }], deferBlockDependencies: [() => [i3.StimulsoftViewerComponent]] });
469
464
  }
470
465
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ReportViewerComponent, decorators: [{
471
466
  type: Component,
472
- args: [{ selector: 'wuic-report-viewer', imports: [CommonModule, StimulsoftViewerModule], template: "@defer (on immediate) {\n @if (canRenderViewer) {\n <stimulsoft-viewer-angular [requestUrl]=\"requestUrl\" [action]=\"action\" [width]=\"'100%'\"\n [height]=\"'calc(100% - 10px)'\" [properties]=\"viewerProperties\" (loaded)=\"onViewerLoaded()\" (export)=\"onExportEvent($event)\"\n (print)=\"onPrintEvent($event)\" (error)=\"onViewerError($event)\"></stimulsoft-viewer-angular>\n } @else {\n <!-- Preflight in corso o fallito. Se fallito, la dialog localizzata e'\n gia' stata mostrata da WuicErrorInterceptor \u2192 GlobalHandler. -->\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Verifica disponibilit\u00E0 report\u2026</span>\n </div>\n }\n} @placeholder {\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Caricamento Report Viewer\u2026</span>\n <small>Il SDK Stimulsoft \u00E8 in download (~15 MB). Operazione una tantum.</small>\n </div>\n} @loading (minimum 300ms) {\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Rendering report\u2026</span>\n </div>\n} @error {\n <div class=\"stimulsoft-error-placeholder\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>Errore nel caricamento del Report Viewer. Verifica connessione e ricarica la pagina.</span>\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%;flex:1 1 auto;min-height:0}:host ::ng-deep stimulsoft-viewer-angular{display:block;width:100%;height:100%}:host ::ng-deep .stiJsViewerForm,:host ::ng-deep .stiJsViewerDisabledPanel{display:none!important}.stimulsoft-loading-placeholder,.stimulsoft-error-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:100%;height:100%;min-height:400px;color:#64748b;font-size:1rem;background:#f8fafc;border:1px dashed #cbd5e1;border-radius:8px}.stimulsoft-loading-placeholder .pi-spinner{font-size:2rem;color:#6366f1}.stimulsoft-loading-placeholder small{font-size:.8rem;color:#94a3b8;max-width:400px;text-align:center}.stimulsoft-error-placeholder{color:#b91c1c;background:#fef2f2;border-color:#fecaca}.stimulsoft-error-placeholder .pi-exclamation-triangle{font-size:2rem}\n"] }]
467
+ args: [{ selector: 'wuic-report-viewer', imports: [CommonModule, StimulsoftViewerModule], template: "@defer (on immediate) {\n @if (canRenderViewer) {\n <stimulsoft-viewer-angular [requestUrl]=\"requestUrl\" [action]=\"action\" [width]=\"'100%'\"\n [height]=\"'calc(100% - 10px)'\" [properties]=\"viewerProperties\" (loaded)=\"onViewerLoaded()\" (export)=\"onExportEvent($event)\"\n (print)=\"onPrintEvent($event)\" (error)=\"onViewerError($event)\"></stimulsoft-viewer-angular>\n } @else {\n <!-- Preflight in corso o fallito. Se fallito, la dialog localizzata e'\n gia' stata mostrata da WuicErrorInterceptor \u2192 GlobalHandler. -->\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Verifica disponibilit\u00E0 report\u2026</span>\n </div>\n }\n} @placeholder {\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Caricamento Report Viewer\u2026</span>\n <small>Il SDK Stimulsoft \u00E8 in download (~15 MB). Operazione una tantum.</small>\n </div>\n} @loading (minimum 300ms) {\n <div class=\"stimulsoft-loading-placeholder\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Rendering report\u2026</span>\n </div>\n} @error {\n <div class=\"stimulsoft-error-placeholder\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>Errore nel caricamento del Report Viewer. Verifica connessione e ricarica la pagina.</span>\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%;flex:1 1 auto;min-height:0}:host ::ng-deep stimulsoft-viewer-angular{display:block;width:100%;height:100%}:host ::ng-deep .stiJsViewerForm,:host ::ng-deep .stiJsViewerDisabledPanel{display:none!important}.stimulsoft-loading-placeholder,.stimulsoft-error-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:100%;height:100%;min-height:400px;color:var(--wuic-text-muted, #64748b);font-size:1rem;background:var(--wuic-surface-soft, #f8fafc);border:1px dashed var(--wuic-border, #cbd5e1);border-radius:var(--wuic-radius-lg, 8px)}.stimulsoft-loading-placeholder .pi-spinner{font-size:2rem;color:var(--wuic-accent, #6366f1)}.stimulsoft-loading-placeholder small{font-size:.8rem;color:var(--wuic-text-muted, #94a3b8);max-width:400px;text-align:center}.stimulsoft-error-placeholder{color:#b91c1c;background:#fef2f2;border-color:#fecaca}.stimulsoft-error-placeholder .pi-exclamation-triangle{font-size:2rem}\n"] }]
473
468
  }], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i1$1.HttpClient }], propDecorators: { viewer: [{
474
469
  type: ViewChild,
475
470
  args: [StimulsoftViewerComponent]
476
471
  }] } });
477
472
 
478
473
  export { ReportViewerComponent };
479
- //# sourceMappingURL=wuic-framework-lib-report-viewer.component-BR-BfI2r.mjs.map
474
+ //# sourceMappingURL=wuic-framework-lib-report-viewer.component-B4LhA3SL.mjs.map