@esfaenza/extensions 15.2.47 → 15.2.50

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 (65) hide show
  1. package/{esm2022 → esm2020}/esfaenza-extensions.mjs +4 -4
  2. package/esm2020/lib/models/CallResult.mjs +6 -0
  3. package/esm2020/lib/models/CsvHeaders.mjs +6 -0
  4. package/{esm2022 → esm2020}/lib/models/ExportConsts.mjs +31 -31
  5. package/esm2020/lib/models/ExtensionsModuleConfig.mjs +4 -0
  6. package/esm2020/lib/models/GenericItem.mjs +6 -0
  7. package/{esm2022 → esm2020}/lib/models/InboundMessageTypes.mjs +6 -6
  8. package/esm2020/lib/models/InterComMessage.mjs +14 -0
  9. package/{esm2022 → esm2020}/lib/models/TypeCode.mjs +24 -24
  10. package/{esm2022 → esm2020}/lib/modules/extensions.module.mjs +32 -32
  11. package/esm2020/lib/pipes/loc_date.pipe.mjs +37 -0
  12. package/esm2020/lib/services/extensions.base.mjs +29 -0
  13. package/esm2020/lib/services/extensions.clipboard.service.mjs +219 -0
  14. package/esm2020/lib/services/extensions.dates.service.mjs +246 -0
  15. package/esm2020/lib/services/extensions.embedding.service.mjs +208 -0
  16. package/esm2020/lib/services/extensions.exports.service.mjs +615 -0
  17. package/esm2020/lib/services/extensions.hashing.service.mjs +310 -0
  18. package/esm2020/lib/services/extensions.intercom.service.mjs +54 -0
  19. package/esm2020/lib/services/extensions.messages.service.mjs +433 -0
  20. package/esm2020/lib/services/extensions.utilities.service.mjs +252 -0
  21. package/{esm2022 → esm2020}/lib/tokens.mjs +11 -11
  22. package/{esm2022 → esm2020}/public-api.mjs +21 -21
  23. package/fesm2015/esfaenza-extensions.mjs +2517 -0
  24. package/fesm2015/esfaenza-extensions.mjs.map +1 -0
  25. package/{fesm2022 → fesm2020}/esfaenza-extensions.mjs +2445 -2509
  26. package/fesm2020/esfaenza-extensions.mjs.map +1 -0
  27. package/index.d.ts +5 -5
  28. package/lib/models/CallResult.d.ts +23 -23
  29. package/lib/models/CsvHeaders.d.ts +25 -25
  30. package/lib/models/ExportConsts.d.ts +31 -31
  31. package/lib/models/ExtensionsModuleConfig.d.ts +9 -9
  32. package/lib/models/GenericItem.d.ts +9 -9
  33. package/lib/models/InboundMessageTypes.d.ts +5 -5
  34. package/lib/models/InterComMessage.d.ts +12 -12
  35. package/lib/models/TypeCode.d.ts +23 -23
  36. package/lib/modules/extensions.module.d.ts +11 -11
  37. package/lib/pipes/loc_date.pipe.d.ts +24 -24
  38. package/lib/services/extensions.base.d.ts +22 -22
  39. package/lib/services/extensions.clipboard.service.d.ts +54 -54
  40. package/lib/services/extensions.dates.service.d.ts +101 -99
  41. package/lib/services/extensions.embedding.service.d.ts +28 -28
  42. package/lib/services/extensions.exports.service.d.ts +234 -234
  43. package/lib/services/extensions.hashing.service.d.ts +121 -121
  44. package/lib/services/extensions.intercom.service.d.ts +28 -28
  45. package/lib/services/extensions.messages.service.d.ts +195 -195
  46. package/lib/services/extensions.utilities.service.d.ts +107 -107
  47. package/lib/tokens.d.ts +11 -11
  48. package/package.json +11 -5
  49. package/public-api.d.ts +18 -18
  50. package/esm2022/lib/models/CallResult.mjs +0 -24
  51. package/esm2022/lib/models/CsvHeaders.mjs +0 -26
  52. package/esm2022/lib/models/ExtensionsModuleConfig.mjs +0 -10
  53. package/esm2022/lib/models/GenericItem.mjs +0 -10
  54. package/esm2022/lib/models/InterComMessage.mjs +0 -16
  55. package/esm2022/lib/pipes/loc_date.pipe.mjs +0 -38
  56. package/esm2022/lib/services/extensions.base.mjs +0 -30
  57. package/esm2022/lib/services/extensions.clipboard.service.mjs +0 -221
  58. package/esm2022/lib/services/extensions.dates.service.mjs +0 -244
  59. package/esm2022/lib/services/extensions.embedding.service.mjs +0 -213
  60. package/esm2022/lib/services/extensions.exports.service.mjs +0 -617
  61. package/esm2022/lib/services/extensions.hashing.service.mjs +0 -308
  62. package/esm2022/lib/services/extensions.intercom.service.mjs +0 -52
  63. package/esm2022/lib/services/extensions.messages.service.mjs +0 -450
  64. package/esm2022/lib/services/extensions.utilities.service.mjs +0 -250
  65. package/fesm2022/esfaenza-extensions.mjs.map +0 -1
@@ -0,0 +1,2517 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, Injectable, Optional, Inject, Pipe, NgModule, Injector } from '@angular/core';
3
+ import * as i1 from '@esfaenza/localizations';
4
+ import { LocalizationModule } from '@esfaenza/localizations';
5
+ import { __awaiter } from 'tslib';
6
+ import { first, filter, take, map } from 'rxjs/operators';
7
+ import { of, Subject } from 'rxjs';
8
+ import { ToastrService } from 'ngx-toastr';
9
+ import swal from 'sweetalert2';
10
+ import * as i2 from '@angular/router';
11
+ import * as i3 from '@angular/common';
12
+
13
+ /**
14
+ * Token che indica il prefisso delle searchView che serve per storicizzarle evitando di tirarsi in memoria anche tutti gli oggetti. Se vuoto viene supposto 'Hot'
15
+ */
16
+ const APPSEARCH_PREFIX = new InjectionToken('APPSEARCH_PREFIX');
17
+ /**
18
+ * Token che indica se i metodi di estensione che utilizzano le date permettono l'uso di date in utc
19
+ */
20
+ const EXT_ALLOW_UTC = new InjectionToken('EXT_ALLOW_UTC');
21
+ /** Modalità di Debug */
22
+ const EXT_DEBUG_MODE = new InjectionToken('EXT_DEBUG_MODE');
23
+
24
+ /**
25
+ * Service che fornisce dei metodi di estensione per la gestione/manipolazione delle date
26
+ */
27
+ class DateService {
28
+ /**
29
+ * Costruttore
30
+ *
31
+ * @ignore
32
+ */
33
+ constructor(locProvider, allowUtc) {
34
+ this.locProvider = locProvider;
35
+ this.allowUtc = allowUtc;
36
+ /**
37
+ * Oggetto statico di localizzazione per i messaggi di questa Service
38
+ */
39
+ this.loc = {
40
+ "SMALL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY", 'it-IT': "DD/MM/YYYY" },
41
+ "FULL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
42
+ "FULL_DATE_FORMAT_NO_SS": { 'en-US': "MM/DD/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
43
+ "SMALL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY", 'it-IT': "DD/MM/YYYY" },
44
+ "SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR": { 'en-US': "DD/MM/YYYY HH", 'it-IT': "DD/MM/YYYY HH" },
45
+ "SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
46
+ "FULL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
47
+ "FULL_DATE_DISPLAY_FORMAT_NO_SS": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" }
48
+ };
49
+ /**
50
+ * Oggetto di configurazione per tenere da conto le informazioni sui formati
51
+ */
52
+ this.cfg = {
53
+ fulldate: "",
54
+ fulldateDisplay: "",
55
+ smallDate: "",
56
+ fulldateNoSS: "",
57
+ smallDateWithH: "",
58
+ smallDateWithM: "",
59
+ fulldateDisplayNoSS: ""
60
+ };
61
+ this.init();
62
+ }
63
+ init() {
64
+ return __awaiter(this, void 0, void 0, function* () {
65
+ let LOCALE = this.locProvider ? yield this.locProvider.Locale.pipe(first()).toPromise() : 'it-IT';
66
+ this.cfg.smallDate = this.loc["SMALL_DATE_FORMAT"][LOCALE];
67
+ this.cfg.fulldate = this.loc["FULL_DATE_FORMAT"][LOCALE];
68
+ this.cfg.fulldateNoSS = this.loc["FULL_DATE_FORMAT_NO_SS"][LOCALE];
69
+ this.cfg.fulldateDisplay = this.loc["FULL_DATE_DISPLAY_FORMAT"][LOCALE];
70
+ this.cfg.fulldateDisplayNoSS = this.loc["FULL_DATE_DISPLAY_FORMAT_NO_SS"][LOCALE];
71
+ this.cfg.smallDate = this.loc["SMALL_DATE_DISPLAY_FORMAT"][LOCALE];
72
+ this.cfg.smallDateWithH = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR"][LOCALE];
73
+ this.cfg.smallDateWithM = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE"][LOCALE];
74
+ });
75
+ }
76
+ /**
77
+ * Aggiusta una data in "istante finale" in base a qual è la parte di data significativa.
78
+ *
79
+ * Es. Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
80
+ *
81
+ * @param {any} date Data qualsiasi (Date, stringa, dayjs...), verrà ricondotta ad un oggetto dayJs
82
+ * @param {'day' | 'hour' | 'minute'} timepart Parte significativa della data
83
+ * @param {boolean} printSeconds Indica se effettuare la stampa dei secondi o no
84
+ */
85
+ adjustDateToFinalInstant(date, timepart, printSeconds = true) {
86
+ let mydt = this.getDateConvertion(date);
87
+ if (mydt == null)
88
+ return "FE: Not a Date";
89
+ let isZeroTime = mydt.startOf(timepart).valueOf() === mydt.valueOf();
90
+ if (!isZeroTime) {
91
+ if (timepart == "day" && mydt.subtract(1, "hour").hour() == mydt.hour()) {
92
+ // Se l'ora precedente è lo stesso orario dell'ora attuale l'istante finale dev'essere mandato avanti di 1
93
+ mydt = mydt.add(1, "hour");
94
+ }
95
+ return printSeconds ? mydt.format(this.cfg.fulldateDisplay) : mydt.format(this.cfg.fulldateDisplayNoSS);
96
+ }
97
+ let tmpValue = mydt.subtract(1, timepart);
98
+ let value = "";
99
+ // Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
100
+ if (timepart == 'day')
101
+ value = tmpValue.format(this.cfg.smallDate) + " 24:00" + (printSeconds ? ':00' : '');
102
+ // Istante finale dei minuti: giorno 05/10/1992 04:00:00 --> 05/10/1992 03:60(:00)
103
+ else if (timepart == 'hour')
104
+ value = tmpValue.format(this.cfg.smallDateWithH) + ":60" + (printSeconds ? ':00' : '');
105
+ // Istante finale dei secondi: giorno 05/10/1992 04:10:00 --> 05/10/1992 04:09:60
106
+ else if (timepart == 'minute')
107
+ value = tmpValue.format(this.cfg.smallDateWithM) + ":60";
108
+ return value;
109
+ }
110
+ /**
111
+ * Funzione che effettua l'ordinamento fra 2 date in base alla direzione specificata
112
+ *
113
+ * @param {any} a Prima data per il confronto
114
+ * @param {any} b Seconda data per il confronto
115
+ * @param {'asc' | 'desc'} direction Direzione rispetto a cui ordinare le due date
116
+ *
117
+ * @returns {number} 0 se le date sono uguali, 1 se la data A deve venire logicamente prima della data B, -1 altrimenti
118
+ */
119
+ dateSort(a, b, direction) {
120
+ if (a < b)
121
+ return direction == 'asc' ? 1 : -1;
122
+ else if (a > b)
123
+ return direction == 'asc' ? -1 : 1;
124
+ // con a uguale a b
125
+ return 0;
126
+ }
127
+ /**
128
+ * Effettua il trim dei secondi da una data espressa come stringa
129
+ *
130
+ * @param {string} value Data espressa come stringa
131
+ *
132
+ * @returns {string} Data senza i secondi
133
+ */
134
+ trimSeconds(value) {
135
+ //I numeri mangiati da dayjs spesso vengono ricondotti a date vere. Mi assicuro che se ci sono solo numeri proseguo
136
+ if (!isNaN(value))
137
+ return value;
138
+ //Se non ho qualcosa del tipo XX/YY/ZZZZ aa:bb:cc di sicuro non è una data che mi interessa
139
+ if (!/^\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d$/g.test(value))
140
+ return value;
141
+ //In questo caso mi arrivano valori che devono essere stampati as-is, solo tagliando i secondi
142
+ return "'" + value.substr(0, value.length - 3);
143
+ }
144
+ /**
145
+ * Data una lista di date Da e una lista di date A restituisce un oggetto rappresentante il range che include tutte le date passate
146
+ *
147
+ * @param {any[]} fromDates Lista dei Da
148
+ * @param {any[]} toDates Lista dei A
149
+ *
150
+ * @returns {{ from: any, to: any }} Range di date Da - A che include tutti i valori di **fromDates** e **toDates**
151
+ */
152
+ getMinMaxDatesRange(fromDates, toDates) {
153
+ let datesFroms = [];
154
+ let datesTo = [];
155
+ for (let i = 0; i < fromDates.length; i++) {
156
+ let d = fromDates[i];
157
+ var convertion = this.getDateConvertion(d);
158
+ if (convertion)
159
+ datesFroms.push(convertion);
160
+ }
161
+ for (let i = 0; i < toDates.length; i++) {
162
+ let d = toDates[i];
163
+ var convertion = this.getDateConvertion(d);
164
+ if (convertion)
165
+ datesTo.push(convertion);
166
+ }
167
+ return { from: dayjs.min(datesFroms), to: dayjs.max(datesTo) };
168
+ }
169
+ /**
170
+ * Ottiene la conversione di una data in qualsiasi formato al formato standard DayJs
171
+ *
172
+ * @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
173
+ * @param {boolean} useUtc Indica se usare l'estensione utc di Dayjs per parsare la data o no
174
+ * @param {string} format formato in cui emettere la conversione
175
+ *
176
+ * @returns {any} Data in modalità {format}
177
+ */
178
+ getDateConvertion(date, useUtc = false, format = 'dayjs', timestringSmall = true) {
179
+ if (!date)
180
+ return null;
181
+ if (this.isDayJs(date))
182
+ return this.formattedDayjs(date, format, timestringSmall);
183
+ if (this.isJsDate(date))
184
+ return this.formattedDayjs(useUtc ? dayjs.utc(date) : dayjs(date), format, timestringSmall);
185
+ // Se non c'è la proprietà length vuol dire che non è una stringa e a questo punto non ho idea di che minchia sia
186
+ let length = date.length;
187
+ if (!length)
188
+ return null;
189
+ if (useUtc && !this.allowUtc)
190
+ throw "@esfaenza/extensions: Richiesta data UTC ma da configurazione la libreria non lo supporta";
191
+ // Per risparmiare chiamate a tentoni, in base alla lunghezza della stringa chiamo direttamente il metodo giusto,
192
+ // controllando poi che mi generi una data come me la aspetto io
193
+ let tryThis = null;
194
+ let toCall = useUtc ? dayjs.utc : dayjs;
195
+ // Se la data contiene la lettera "T" vuol dire che è una data del tipo 2020-10-15T00:00:00, direttamente parsabile dal dayjs col locale corretto.
196
+ // Per il resto mi baso sulla lunghezza della stringa
197
+ if (date.includes("T"))
198
+ tryThis = toCall(date);
199
+ else if (length == this.cfg.fulldate.length)
200
+ tryThis = toCall(date, this.cfg.fulldate);
201
+ else if (length == this.cfg.smallDate.length)
202
+ tryThis = toCall(date, this.cfg.smallDate);
203
+ else if (length == this.cfg.fulldateNoSS.length)
204
+ tryThis = toCall(date, this.cfg.fulldateNoSS);
205
+ if (tryThis && tryThis.isValid && tryThis.isValid())
206
+ return this.formattedDayjs(tryThis, format, timestringSmall);
207
+ // Se niente funziona, null.
208
+ // Ricondurre l'Input ad una data non è possibile.
209
+ return null;
210
+ }
211
+ formattedDayjs(dayjs, format, timestringSmall) {
212
+ return format == 'dayjs' ? dayjs : format == 'date' ? dayjs.toDate() : this.getFormatted(dayjs, timestringSmall, false);
213
+ }
214
+ /**
215
+ * Helper che restituisce **true** qualora l'oggetto passato fosse una data vera e propria, **false** altrimenti
216
+ *
217
+ * @param {any} check Oggetto da controllare
218
+ *
219
+ * @returns {boolean} Indicazione se l'oggetto è un vero Date di Javascript o no
220
+ */
221
+ isJsDate(check) {
222
+ return check && Object.prototype.toString.call(check) === "[object Date]" && !isNaN(check);
223
+ }
224
+ /**
225
+ * Helper che restituisce **true** qualora l'oggetto passato fosse un DayJs vero e proprio, **false** altrimenti
226
+ *
227
+ * @param {any} check Oggetto da controllare
228
+ * @returns {boolean} Indicazione se l'oggetto è un vero DayJs o no
229
+ */
230
+ isDayJs(check) {
231
+ // Non uso instanceof perché sarebbe estremamente più lento
232
+ // Non uso nemmeno isDayjs() della libreria Dayjs dato che ha lo stesso problema: https://github.com/iamkun/dayjs/blob/06f88f425828b1ce96b737332d25145a95a4ee9d/src/index.js#L9
233
+ return check.$D !== undefined && check.$M !== undefined && check.$y !== undefined;
234
+ }
235
+ /**
236
+ * Ottiene la formattazione di una data in base alla versione richiesta "small" o "long" e a se stampare o meno i secondi
237
+ *
238
+ * @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
239
+ * @param {boolean} small Indica se formattarla con un formato breve (se **true**) o un formato più lungo (se **false**)
240
+ *
241
+ * @returns {string} Data formattata nel formato richiesto
242
+ */
243
+ getFormatted(date, small, seconds) {
244
+ var date = this.getDateConvertion(date);
245
+ if (!date)
246
+ return null;
247
+ return date.format(small ? this.cfg.smallDate : seconds ? this.cfg.fulldateDisplay : this.cfg.fulldateDisplayNoSS);
248
+ }
249
+ }
250
+ DateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateService, deps: [{ token: i1.BaseLocalization, optional: true }, { token: EXT_ALLOW_UTC, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
251
+ DateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateService, providedIn: "root" });
252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateService, decorators: [{
253
+ type: Injectable,
254
+ args: [{ providedIn: "root" }]
255
+ }], ctorParameters: function () {
256
+ return [{ type: i1.BaseLocalization, decorators: [{
257
+ type: Optional
258
+ }] }, { type: undefined, decorators: [{
259
+ type: Optional
260
+ }, {
261
+ type: Inject,
262
+ args: [EXT_ALLOW_UTC]
263
+ }] }];
264
+ } });
265
+
266
+ // Angular
267
+ /**
268
+ * Pipe che permette di formattare una data in base al formato specificato. Utilizza il **DateService** di **@esfaenza/extensions** per ricondurre l'input a una data valida
269
+ */
270
+ class LocDatePipe {
271
+ /**
272
+ * @ignore
273
+ */
274
+ constructor(dts) {
275
+ this.dts = dts;
276
+ }
277
+ /**
278
+ * Trasformazione della data in input in base al formato richiesto
279
+ *
280
+ * @param {any} value Valore da ricondurre ad una data e formattare
281
+ * @param {string} format Formato in output della data da visualizzare
282
+ *
283
+ * @returns {string} Data formattata in base al formato
284
+ */
285
+ transform(value, format = "DD/MM/YYYY") {
286
+ if (value == null || value === "")
287
+ return null;
288
+ var detatchedValue = JSON.parse(JSON.stringify(value));
289
+ var dt = this.dts.getDateConvertion(detatchedValue);
290
+ return dt.format(format);
291
+ }
292
+ }
293
+ LocDatePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LocDatePipe, deps: [{ token: DateService }], target: i0.ɵɵFactoryTarget.Pipe });
294
+ LocDatePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: LocDatePipe, name: "loc_date" });
295
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LocDatePipe, decorators: [{
296
+ type: Pipe,
297
+ args: [{ name: "loc_date", pure: true }]
298
+ }], ctorParameters: function () { return [{ type: DateService }]; } });
299
+
300
+ // Angular
301
+ class ExtensionsModule {
302
+ static forRoot(config) {
303
+ return {
304
+ ngModule: ExtensionsModule,
305
+ providers: [
306
+ { provide: APPSEARCH_PREFIX, useValue: (config === null || config === void 0 ? void 0 : config.appsearch_prefix) || 'Hot' },
307
+ { provide: EXT_ALLOW_UTC, useValue: (config === null || config === void 0 ? void 0 : config.allow_utc) == null ? false : config === null || config === void 0 ? void 0 : config.allow_utc },
308
+ { provide: EXT_DEBUG_MODE, useValue: (config === null || config === void 0 ? void 0 : config.debugMode) || false },
309
+ ]
310
+ };
311
+ }
312
+ }
313
+ ExtensionsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
314
+ ExtensionsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, declarations: [LocDatePipe], imports: [LocalizationModule], exports: [LocDatePipe] });
315
+ ExtensionsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, imports: [LocalizationModule] });
316
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExtensionsModule, decorators: [{
317
+ type: NgModule,
318
+ args: [{
319
+ imports: [LocalizationModule],
320
+ declarations: [LocDatePipe],
321
+ exports: [LocDatePipe]
322
+ }]
323
+ }] });
324
+
325
+ // Angular
326
+ /**
327
+ * Service che fornisce alcuni semplici funzioni di Hashing / GUID / ecc...
328
+ */
329
+ class HashingService {
330
+ constructor() {
331
+ /**
332
+ * Blacklist dei tipi da ignorare quando si effettua l'hashing degli oggetti
333
+ */
334
+ this.objBlacklist = {
335
+ "NgForm": true, "ElementRef": true, "ExtensionsService": true, "ToastrService": true, "LocaleService": true, "AppState": true, "Router": true,
336
+ "ActivatedRoute": true, "HTTPService": true, "Location": true, "CanvasComponent": true, "ModalDirective": true, "ChangeDetectorRef": true,
337
+ "DateService": true, "EventEmitter": true, "ViewRef_": true, "Subscriber": true, "ItemLocalization": true
338
+ };
339
+ /**
340
+ * Array dei possibili valori di un simbolo esadecimale
341
+ */
342
+ this.hex_chr = '0123456789abcdef'.split('');
343
+ }
344
+ /**
345
+ * Generazione di un GUID pseudo-univoco
346
+ *
347
+ * @returns {string} il GUID generato
348
+ */
349
+ getGUID() {
350
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {
351
+ var r = Math.random() * 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8);
352
+ return v.toString(16);
353
+ });
354
+ }
355
+ /**
356
+ * Calcolo dell'hash su un oggetto
357
+ *
358
+ * @param {any} o Oggetto di cui calcolare l'hash
359
+ * @param {number} level Livello di ricorsione nel caso venga effettuato l'hash di un oggetto che contiene altri oggetti
360
+ * @param {boolean} navigateFullDepth Indica se navigare l'oggetto per l'intera lunghezza. In caso contrario si ferma al secondo livello
361
+ *
362
+ * @returns {string} Hash generato per l'oggetto in questione
363
+ */
364
+ hashObject(o, level = 0, navigateFullDepth = false, precise = false) {
365
+ var strDef = this.stringify(o, level, navigateFullDepth);
366
+ var hash = precise ? this.md5(strDef) : this.simpleHash(strDef);
367
+ return hash;
368
+ }
369
+ /**
370
+ * Hash più semplice e più veloce dell'md5, ma meno sicuro
371
+ *
372
+ * Vedi https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript
373
+ *
374
+ * @param {string} str Stringa di cui calcolare l'hash
375
+ */
376
+ simpleHash(str, seed = 0) {
377
+ let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
378
+ for (let i = 0, ch; i < str.length; i++) {
379
+ ch = str.charCodeAt(i);
380
+ h1 = Math.imul(h1 ^ ch, 2654435761);
381
+ h2 = Math.imul(h2 ^ ch, 1597334677);
382
+ }
383
+ h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
384
+ h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
385
+ return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString();
386
+ }
387
+ /**
388
+ * Genera una stringa che identifica univocamente l'oggetto in questione
389
+ *
390
+ * @param {any} o Oggetto di cui calcolare la stringa univoca
391
+ * @param {number} level Livello di ricorsione nel caso venga effettuato l'hash di un oggetto che contiene altri oggetti
392
+ * @param {boolean} navigateFullDepth Indica se navigare l'oggetto per l'intera lunghezza. In caso contrario si ferma al secondo livello
393
+ */
394
+ stringify(o, level, navigateFullDepth) {
395
+ var i, r;
396
+ if (o === null)
397
+ return "n";
398
+ if (o === true)
399
+ return "t";
400
+ if (o === false)
401
+ return "f";
402
+ if (o instanceof Date)
403
+ return 'd:' + o.valueOf().toString();
404
+ i = typeof o;
405
+ if (i === "string")
406
+ return "s:" + o;
407
+ if (i === "number")
408
+ return "n:" + o;
409
+ if (o instanceof Function)
410
+ return "m:" + o.toString();
411
+ if (o instanceof Array) {
412
+ r = [];
413
+ for (i = 0; i < o.length; i++) {
414
+ let res = this.stringify(o[i], level, navigateFullDepth);
415
+ if (res)
416
+ r.push(res);
417
+ }
418
+ return r.length > 0 ? "a:" + r.join(";") : "";
419
+ }
420
+ r = [];
421
+ //Se è oggetto, escludo tutti quelli di sistema/inutili
422
+ if (o) {
423
+ var name = o.__proto__.constructor.name;
424
+ if (!this.objBlacklist[name]) {
425
+ for (i in o) {
426
+ if (o.hasOwnProperty(i) && (level <= 2 || navigateFullDepth)) {
427
+ let res = this.stringify(o[i], level + 1, navigateFullDepth);
428
+ if (res)
429
+ r.push(i + ":" + res);
430
+ }
431
+ }
432
+ }
433
+ }
434
+ return r.length > 0 ? "o:" + r.join(";") : "";
435
+ }
436
+ /**
437
+ * Data una stringa restituisce l'md5
438
+ *
439
+ * @param {string} s Stringa di cui calcolare l'md5
440
+ * @returns {string} md5 della stringa **s**
441
+ */
442
+ md5(s) {
443
+ return this.hex(this.md51(s));
444
+ }
445
+ /**
446
+ * @ignore
447
+ *
448
+ * Metodo di utilità per il calcolo dell'md5
449
+ */
450
+ md5cycle(x, k) {
451
+ var a = x[0], b = x[1], c = x[2], d = x[3];
452
+ a = this.ff(a, b, c, d, k[0], 7, -680876936);
453
+ d = this.ff(d, a, b, c, k[1], 12, -389564586);
454
+ c = this.ff(c, d, a, b, k[2], 17, 606105819);
455
+ b = this.ff(b, c, d, a, k[3], 22, -1044525330);
456
+ a = this.ff(a, b, c, d, k[4], 7, -176418897);
457
+ d = this.ff(d, a, b, c, k[5], 12, 1200080426);
458
+ c = this.ff(c, d, a, b, k[6], 17, -1473231341);
459
+ b = this.ff(b, c, d, a, k[7], 22, -45705983);
460
+ a = this.ff(a, b, c, d, k[8], 7, 1770035416);
461
+ d = this.ff(d, a, b, c, k[9], 12, -1958414417);
462
+ c = this.ff(c, d, a, b, k[10], 17, -42063);
463
+ b = this.ff(b, c, d, a, k[11], 22, -1990404162);
464
+ a = this.ff(a, b, c, d, k[12], 7, 1804603682);
465
+ d = this.ff(d, a, b, c, k[13], 12, -40341101);
466
+ c = this.ff(c, d, a, b, k[14], 17, -1502002290);
467
+ b = this.ff(b, c, d, a, k[15], 22, 1236535329);
468
+ a = this.gg(a, b, c, d, k[1], 5, -165796510);
469
+ d = this.gg(d, a, b, c, k[6], 9, -1069501632);
470
+ c = this.gg(c, d, a, b, k[11], 14, 643717713);
471
+ b = this.gg(b, c, d, a, k[0], 20, -373897302);
472
+ a = this.gg(a, b, c, d, k[5], 5, -701558691);
473
+ d = this.gg(d, a, b, c, k[10], 9, 38016083);
474
+ c = this.gg(c, d, a, b, k[15], 14, -660478335);
475
+ b = this.gg(b, c, d, a, k[4], 20, -405537848);
476
+ a = this.gg(a, b, c, d, k[9], 5, 568446438);
477
+ d = this.gg(d, a, b, c, k[14], 9, -1019803690);
478
+ c = this.gg(c, d, a, b, k[3], 14, -187363961);
479
+ b = this.gg(b, c, d, a, k[8], 20, 1163531501);
480
+ a = this.gg(a, b, c, d, k[13], 5, -1444681467);
481
+ d = this.gg(d, a, b, c, k[2], 9, -51403784);
482
+ c = this.gg(c, d, a, b, k[7], 14, 1735328473);
483
+ b = this.gg(b, c, d, a, k[12], 20, -1926607734);
484
+ a = this.hh(a, b, c, d, k[5], 4, -378558);
485
+ d = this.hh(d, a, b, c, k[8], 11, -2022574463);
486
+ c = this.hh(c, d, a, b, k[11], 16, 1839030562);
487
+ b = this.hh(b, c, d, a, k[14], 23, -35309556);
488
+ a = this.hh(a, b, c, d, k[1], 4, -1530992060);
489
+ d = this.hh(d, a, b, c, k[4], 11, 1272893353);
490
+ c = this.hh(c, d, a, b, k[7], 16, -155497632);
491
+ b = this.hh(b, c, d, a, k[10], 23, -1094730640);
492
+ a = this.hh(a, b, c, d, k[13], 4, 681279174);
493
+ d = this.hh(d, a, b, c, k[0], 11, -358537222);
494
+ c = this.hh(c, d, a, b, k[3], 16, -722521979);
495
+ b = this.hh(b, c, d, a, k[6], 23, 76029189);
496
+ a = this.hh(a, b, c, d, k[9], 4, -640364487);
497
+ d = this.hh(d, a, b, c, k[12], 11, -421815835);
498
+ c = this.hh(c, d, a, b, k[15], 16, 530742520);
499
+ b = this.hh(b, c, d, a, k[2], 23, -995338651);
500
+ a = this.ii(a, b, c, d, k[0], 6, -198630844);
501
+ d = this.ii(d, a, b, c, k[7], 10, 1126891415);
502
+ c = this.ii(c, d, a, b, k[14], 15, -1416354905);
503
+ b = this.ii(b, c, d, a, k[5], 21, -57434055);
504
+ a = this.ii(a, b, c, d, k[12], 6, 1700485571);
505
+ d = this.ii(d, a, b, c, k[3], 10, -1894986606);
506
+ c = this.ii(c, d, a, b, k[10], 15, -1051523);
507
+ b = this.ii(b, c, d, a, k[1], 21, -2054922799);
508
+ a = this.ii(a, b, c, d, k[8], 6, 1873313359);
509
+ d = this.ii(d, a, b, c, k[15], 10, -30611744);
510
+ c = this.ii(c, d, a, b, k[6], 15, -1560198380);
511
+ b = this.ii(b, c, d, a, k[13], 21, 1309151649);
512
+ a = this.ii(a, b, c, d, k[4], 6, -145523070);
513
+ d = this.ii(d, a, b, c, k[11], 10, -1120210379);
514
+ c = this.ii(c, d, a, b, k[2], 15, 718787259);
515
+ b = this.ii(b, c, d, a, k[9], 21, -343485551);
516
+ x[0] = this.add32(a, x[0]);
517
+ x[1] = this.add32(b, x[1]);
518
+ x[2] = this.add32(c, x[2]);
519
+ x[3] = this.add32(d, x[3]);
520
+ }
521
+ /**
522
+ * @ignore
523
+ *
524
+ * Metodo di utilità per il calcolo dell'md5
525
+ */
526
+ cmn(q, a, b, x, s, t) {
527
+ a = this.add32(this.add32(a, q), this.add32(x, t));
528
+ return this.add32((a << s) | (a >>> (32 - s)), b);
529
+ }
530
+ /**
531
+ * @ignore
532
+ *
533
+ * Metodo di utilità per il calcolo dell'md5
534
+ */
535
+ ff(a, b, c, d, x, s, t) {
536
+ return this.cmn((b & c) | ((~b) & d), a, b, x, s, t);
537
+ }
538
+ /**
539
+ * @ignore
540
+ *
541
+ * Metodo di utilità per il calcolo dell'md5
542
+ */
543
+ gg(a, b, c, d, x, s, t) {
544
+ return this.cmn((b & d) | (c & (~d)), a, b, x, s, t);
545
+ }
546
+ /**
547
+ * @ignore
548
+ *
549
+ * Metodo di utilità per il calcolo dell'md5
550
+ */
551
+ hh(a, b, c, d, x, s, t) {
552
+ return this.cmn(b ^ c ^ d, a, b, x, s, t);
553
+ }
554
+ /**
555
+ * @ignore
556
+ *
557
+ * Metodo di utilità per il calcolo dell'md5
558
+ */
559
+ ii(a, b, c, d, x, s, t) {
560
+ return this.cmn(c ^ (b | (~d)), a, b, x, s, t);
561
+ }
562
+ /**
563
+ * @ignore
564
+ *
565
+ * Metodo di utilità per il calcolo dell'md5
566
+ */
567
+ md51(s) {
568
+ var n = s.length, state = [1732584193, -271733879, -1732584194, 271733878], i;
569
+ for (i = 64; i <= s.length; i += 64)
570
+ this.md5cycle(state, this.md5blk(s.substring(i - 64, i)));
571
+ s = s.substring(i - 64);
572
+ var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
573
+ for (i = 0; i < s.length; i++)
574
+ tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
575
+ tail[i >> 2] |= 0x80 << ((i % 4) << 3);
576
+ if (i > 55) {
577
+ this.md5cycle(state, tail);
578
+ for (i = 0; i < 16; i++)
579
+ tail[i] = 0;
580
+ }
581
+ tail[14] = n * 8;
582
+ this.md5cycle(state, tail);
583
+ return state;
584
+ }
585
+ /**
586
+ * @ignore
587
+ *
588
+ * Metodo di utilità per il calcolo dell'md5
589
+ */
590
+ md5blk(s) {
591
+ var md5blks = [], i;
592
+ for (i = 0; i < 64; i += 4)
593
+ md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
594
+ return md5blks;
595
+ }
596
+ /**
597
+ * @ignore
598
+ *
599
+ * Metodo di utilità per il calcolo dell'md5
600
+ */
601
+ rhex(n) {
602
+ var s = '', j = 0;
603
+ for (; j < 4; j++)
604
+ s += this.hex_chr[(n >> (j * 8 + 4)) & 0x0F] + this.hex_chr[(n >> (j * 8)) & 0x0F];
605
+ return s;
606
+ }
607
+ /**
608
+ * @ignore
609
+ *
610
+ * Metodo di utilità per il calcolo dell'md5
611
+ */
612
+ hex(x) {
613
+ for (var i = 0; i < x.length; i++)
614
+ x[i] = this.rhex(x[i]);
615
+ return x.join('');
616
+ }
617
+ /**
618
+ * @ignore
619
+ *
620
+ * Metodo di utilità per il calcolo dell'md5
621
+ */
622
+ add32(a, b) {
623
+ return (a + b) & 0xFFFFFFFF;
624
+ }
625
+ }
626
+ HashingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HashingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
627
+ HashingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HashingService, providedIn: "root" });
628
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HashingService, decorators: [{
629
+ type: Injectable,
630
+ args: [{ providedIn: "root" }]
631
+ }] });
632
+
633
+ /**
634
+ * Service che fornisce funzionalità di alert nei tipi fondamentali: success, info, warning e danger
635
+ */
636
+ class MessageService {
637
+ /** Costruttore @ignore */
638
+ constructor(injector, locProvider, hash) {
639
+ this.injector = injector;
640
+ this.locProvider = locProvider;
641
+ this.hash = hash;
642
+ /** Oggetto statico in supporto alla localizzazione */
643
+ this.loc = {
644
+ 'Confirm': { 'en-US': "Confirm", 'it-IT': "Conferma", },
645
+ 'Cancel': { 'en-US': "Cancel", 'it-IT': "Annulla", },
646
+ 'Close': { 'en-US': "Close", 'it-IT': "Chiudi", },
647
+ 'Error': { 'en-US': "Error", 'it-IT': "Errore", },
648
+ 'Info': { 'en-US': "Info", 'it-IT': "Informazione", },
649
+ 'Success': { 'en-US': "Success", 'it-IT': "Successo", },
650
+ 'Warning': { 'en-US': "Warning", 'it-IT': "Attenzione", }
651
+ };
652
+ /** Supporto all'Embedding */
653
+ this.Embedded = false;
654
+ this.MainWindow = null;
655
+ this.MessageObserver = null;
656
+ this.GuidRepsonseFunctionsMap = {};
657
+ this.init();
658
+ }
659
+ /** Getter per il servizio dei toast. ngx-toastr è fatta talmente male che la service dev'essere recuperata in questo modo */
660
+ get toastr() {
661
+ return this.injector.get(ToastrService);
662
+ }
663
+ configureEmbeddability(mainWindow, messageObserver) {
664
+ this.Embedded = true;
665
+ this.MainWindow = mainWindow;
666
+ this.MessageObserver = messageObserver;
667
+ }
668
+ init() {
669
+ return __awaiter(this, void 0, void 0, function* () {
670
+ let LOCALE = this.locProvider ? yield this.locProvider.Locale.pipe(first()).toPromise() : 'it-IT';
671
+ this.expiredSessionSwal = swal.mixin({
672
+ showCancelButton: false,
673
+ confirmButtonText: 'Login',
674
+ customClass: {
675
+ confirmButton: "btn btn-primary",
676
+ container: "app-wrap",
677
+ },
678
+ buttonsStyling: false,
679
+ reverseButtons: false,
680
+ allowOutsideClick: false,
681
+ icon: "warning"
682
+ });
683
+ this.successSwalWithCancel = swal.mixin({
684
+ title: this.loc["Success"][LOCALE],
685
+ customClass: {
686
+ confirmButton: "btn btn-primary",
687
+ cancelButton: "btn btn-secondary app-margin-right-10",
688
+ container: "app-wrap",
689
+ },
690
+ buttonsStyling: false,
691
+ reverseButtons: true,
692
+ showCancelButton: true,
693
+ confirmButtonText: this.loc["Confirm"][LOCALE],
694
+ cancelButtonText: this.loc["Cancel"][LOCALE],
695
+ icon: "success"
696
+ });
697
+ this.warningSwalWithCancel = swal.mixin({
698
+ title: this.loc["Warning"][LOCALE],
699
+ customClass: {
700
+ confirmButton: "btn btn-primary",
701
+ cancelButton: "btn btn-secondary app-margin-right-10",
702
+ container: "app-wrap",
703
+ },
704
+ buttonsStyling: false,
705
+ reverseButtons: true,
706
+ showCancelButton: true,
707
+ confirmButtonText: this.loc["Confirm"][LOCALE],
708
+ cancelButtonText: this.loc["Cancel"][LOCALE],
709
+ icon: "warning"
710
+ });
711
+ this.warningSwal = swal.mixin({
712
+ title: this.loc["Warning"][LOCALE],
713
+ customClass: {
714
+ confirmButton: "btn btn-primary",
715
+ container: "app-wrap",
716
+ },
717
+ buttonsStyling: false,
718
+ reverseButtons: true,
719
+ showCancelButton: false,
720
+ confirmButtonText: this.loc["Close"][LOCALE],
721
+ icon: "warning"
722
+ });
723
+ this.successSwal = swal.mixin({
724
+ title: this.loc["Success"][LOCALE],
725
+ customClass: {
726
+ confirmButton: "btn btn-primary",
727
+ container: "app-wrap",
728
+ },
729
+ buttonsStyling: false,
730
+ reverseButtons: true,
731
+ showCancelButton: false,
732
+ confirmButtonText: this.loc["Close"][LOCALE],
733
+ icon: "success"
734
+ });
735
+ this.errorSwal = swal.mixin({
736
+ title: this.loc["Error"][LOCALE],
737
+ customClass: {
738
+ confirmButton: "btn btn-primary",
739
+ container: "app-wrap",
740
+ },
741
+ buttonsStyling: false,
742
+ reverseButtons: true,
743
+ showCancelButton: false,
744
+ confirmButtonText: this.loc["Close"][LOCALE],
745
+ icon: "error"
746
+ });
747
+ this.infoSwal = swal.mixin({
748
+ title: this.loc["Info"][LOCALE],
749
+ customClass: {
750
+ confirmButton: "btn btn-primary",
751
+ container: "app-wrap",
752
+ },
753
+ buttonsStyling: false,
754
+ reverseButtons: true,
755
+ showCancelButton: false,
756
+ confirmButtonText: this.loc["Close"][LOCALE],
757
+ icon: "info"
758
+ });
759
+ });
760
+ }
761
+ /**
762
+ * Presentazione di un semplice messaggio di successo
763
+ *
764
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
765
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
766
+ *
767
+ * @param {string} text Testo da mostrare
768
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
769
+ */
770
+ simpleSuccess(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
771
+ if (this.Embedded) {
772
+ this.MainWindow.postMessage({ type: "alert", level: 'success', msg: text }, "*");
773
+ return;
774
+ }
775
+ let tos = this.toastrOrSwal(secondaryNotificationType);
776
+ if (tos == "swal")
777
+ this.successSwal.fire("", text);
778
+ else
779
+ this.toastr.success(text, null, { positionClass: tos == "toastr" ? "toast-top-right" : "toast-top-center", timeOut: secondaryNotificationTimeout || (tos == "toastr" ? 0 : 5000), extendedTimeOut: tos == "toastr" ? 0 : 1000 });
780
+ }
781
+ /**
782
+ * Presentazione di un semplice messaggio di informazione
783
+ *
784
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
785
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
786
+ *
787
+ * @param {string} text Testo da mostrare
788
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
789
+ */
790
+ simpleInfo(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
791
+ if (this.Embedded) {
792
+ this.MainWindow.postMessage({ type: "alert", level: 'info', msg: text }, "*");
793
+ return;
794
+ }
795
+ let tos = this.toastrOrSwal(secondaryNotificationType);
796
+ if (tos == "swal")
797
+ this.infoSwal.fire("", text);
798
+ else
799
+ this.toastr.info(text, null, { positionClass: tos == "toastr" ? "toast-top-right" : "toast-top-center", timeOut: secondaryNotificationTimeout || (tos == "toastr" ? 0 : 5000), extendedTimeOut: tos == "toastr" ? 0 : 1000 });
800
+ }
801
+ /**
802
+ * Presentazione di un semplice messaggio di errore
803
+ *
804
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
805
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
806
+ *
807
+ * @param {string} text Testo da mostrare
808
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
809
+ */
810
+ simpleError(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
811
+ if (this.Embedded) {
812
+ this.MainWindow.postMessage({ type: "alert", level: 'error', msg: text }, "*");
813
+ return;
814
+ }
815
+ let tos = this.toastrOrSwal(secondaryNotificationType);
816
+ if (tos == "swal")
817
+ this.errorSwal.fire("", text);
818
+ else
819
+ this.toastr.error(text, null, { positionClass: tos == "toastr" ? "toast-top-right" : "toast-top-center", timeOut: secondaryNotificationTimeout || (tos == "toastr" ? 0 : 5000), extendedTimeOut: tos == "toastr" ? 0 : 1000 });
820
+ }
821
+ /**
822
+ * Presentazione di un semplice messaggio di avviso
823
+ *
824
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
825
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
826
+ *
827
+ * @param {string} text Testo da mostrare
828
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
829
+ */
830
+ simpleWarning(text, secondaryNotificationType = null, secondaryNotificationTimeout = null) {
831
+ if (this.Embedded) {
832
+ this.MainWindow.postMessage({ type: "alert", level: 'warning', msg: text }, "*");
833
+ return;
834
+ }
835
+ let tos = this.toastrOrSwal(secondaryNotificationType);
836
+ if (tos == "swal")
837
+ this.warningSwal.fire("", text);
838
+ else
839
+ this.toastr.warning(text, null, { positionClass: tos == "toastr" ? "toast-top-right" : "toast-top-center", timeOut: secondaryNotificationTimeout || (tos == "toastr" ? 0 : 5000), extendedTimeOut: tos == "toastr" ? 0 : 1000 });
840
+ }
841
+ /**
842
+ * Ripulisce tutti i messaggi presenti in un dato momento sullo schermo
843
+ */
844
+ clearMessages() {
845
+ this.toastr.clear();
846
+ swal.close();
847
+ }
848
+ /**
849
+ * Mostra un messaggio di avviso con richiesta di conferma
850
+ *
851
+ * @param {string} title Titolo del messaggio
852
+ * @param {string} text Contenuto del messaggio
853
+ *
854
+ * @returns {Promise} Restituisce una Promise col risultato scelto dall'utente (conferma o no)
855
+ */
856
+ promiseWarningWithChoice(title, text) {
857
+ return this.warningSwalWithCancel.fire(title, text);
858
+ }
859
+ /**
860
+ * In base alla configurazione attuale e all'eventuale override per la chiamata del caso indica se bisogna utilizzare toastr o sweetalert
861
+ *
862
+ * @param {"toastr" | "swal" | null} providerOverride Override alla modalità configurata
863
+ *
864
+ * @returns {"toastr" | "swal"} Indicazione su che provider di messaggi di avviso debba essere utilizzato
865
+ */
866
+ toastrOrSwal(providerOverride) {
867
+ if (providerOverride != null)
868
+ return providerOverride;
869
+ return "swal";
870
+ }
871
+ simpleWarningWithChoice(title, text, onsuccess, onerror, confirmtext = "", aborttext = '') {
872
+ this.withChoiceBase("warning", title, text, onsuccess, onerror, confirmtext, aborttext);
873
+ }
874
+ simpleSuccessWithChoice(title, text, onsuccess, onerror, confirmtext = "", aborttext = '') {
875
+ this.withChoiceBase("success", title, text, onsuccess, onerror, confirmtext, aborttext);
876
+ }
877
+ withChoiceBase(level, title, text, onsuccess, onerror, confirmtext = "", aborttext = '') {
878
+ if (this.Embedded) {
879
+ let guid = this.hash.getGUID();
880
+ this.GuidRepsonseFunctionsMap[guid] = { onsuccess, onerror };
881
+ this.MainWindow.postMessage({ type: "confirm", level, title, text, guid }, "*");
882
+ // Observe sulla risposta
883
+ console.log("Inviata confirm request alla pagina principale, in attesa di risposta...");
884
+ this.MessageObserver.pipe(filter(event => { var _a, _b; return ((_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.type) == "confirm-response" && ((_b = event === null || event === void 0 ? void 0 : event.data) === null || _b === void 0 ? void 0 : _b.guid) == guid; }), take(1)).subscribe(event => {
885
+ var _a, _b;
886
+ console.log("Event listener su window-message. Risposta pergiunta");
887
+ if (((_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.result) === true)
888
+ this.GuidRepsonseFunctionsMap[guid].onsuccess();
889
+ else if (((_b = event === null || event === void 0 ? void 0 : event.data) === null || _b === void 0 ? void 0 : _b.result) === true)
890
+ this.GuidRepsonseFunctionsMap[guid].onerror();
891
+ });
892
+ }
893
+ else
894
+ (level == "warning" ? this._simpleWarningWithChoice.bind(this) : this._simpleSuccessWithChoice.bind(this))(title, text, onsuccess, onerror, confirmtext, aborttext);
895
+ }
896
+ /**
897
+ * Mostra un messaggio di avviso con richiesta di conferma e gestisce il risultato chiamato i callback **onsuccess** o **onerror**
898
+ *
899
+ * @param {string} title Titolo del messaggio
900
+ * @param {string} text Contenuto del messaggio
901
+ * @param {Function} onsuccess Callback da chimare su conferma
902
+ * @param {Function} onerror Callback da chimare su errori
903
+ */
904
+ _simpleWarningWithChoice(title, text, onconfirm = null, onabort = null, confirmtext = "", aborttext = '') {
905
+ this._simpleWithChoice(this.warningSwalWithCancel, title, text, onconfirm, onabort, confirmtext, aborttext);
906
+ }
907
+ /**
908
+ * Mostra un messaggio di success con richiesta di conferma e gestisce il risultato chiamato i callback **onconfirm** o **onabort**
909
+ *
910
+ * @param {string} title Titolo del messaggio
911
+ * @param {string} text Contenuto del messaggio
912
+ * @param {Function} onconfirm Callback da chimare su conferma
913
+ * @param {Function} onabort Callback da chimare su annullamento
914
+ * @param {string} confirmtext Testo del pulsante di azione
915
+ * @param {string} aborttext Testo del pulsante di annullamento
916
+ */
917
+ _simpleSuccessWithChoice(title, text, onconfirm = null, onabort = null, confirmtext = "", aborttext = '') {
918
+ this._simpleWithChoice(this.successSwalWithCancel, title, text, onconfirm, onabort, confirmtext, aborttext);
919
+ }
920
+ /**
921
+ * Metodo base per richiedere una scelta all'utente
922
+ *
923
+ * @param {any} swal Swal mixin da utilizzare per visualizzare il messaggio di choice
924
+ * @param {string} title Titolo del messaggio
925
+ * @param {string} text Contenuto del messaggio
926
+ * @param {Function} onconfirm Callback da chimare su conferma
927
+ * @param {Function} onabort Callback da chimare su annullamento
928
+ * @param {string} confirmtext Testo del pulsante di azione
929
+ * @param {string} aborttext Testo del pulsante di annullamento
930
+ */
931
+ _simpleWithChoice(swal, title, text, onconfirm = null, onabort = null, confirmtext = "", aborttext = '') {
932
+ var configuration = {
933
+ title: title,
934
+ html: text
935
+ };
936
+ if (confirmtext)
937
+ configuration["confirmButtonText"] = confirmtext;
938
+ if (aborttext)
939
+ configuration["cancelButtonText"] = aborttext;
940
+ swal.fire(configuration).then((result) => {
941
+ if (result.value && onconfirm)
942
+ onconfirm();
943
+ else if (onabort)
944
+ onabort();
945
+ });
946
+ }
947
+ /**
948
+ * Mostra un messaggio di avviso con richiesta di conferma e gestisce il risultato chiamato i callback **onsuccess** o **onerror**
949
+ *
950
+ * @param {string} title Titolo del messaggio
951
+ * @param {string} text Contenuto del messaggio
952
+ */
953
+ observableSimpleWarningWithChoice(title, text) {
954
+ return of(this.warningSwalWithCancel.fire(title, text)).pipe(map(t => !!t.value));
955
+ }
956
+ /**
957
+ * Mostra un messaggio di avviso che la sessione corrente è scaduta e propone all'utente di navigare al login. Qualora l'utente decidesse di farlo
958
+ * verrà chiamata la funzione di callback **onnavigate
959
+ *
960
+ * @param {string} title Titolo del messaggio
961
+ * @param {string} text Contenuto del messaggio
962
+ * @param {Function} onnavigate Callback da chimare su navigazione in corso
963
+ */
964
+ expiredSessionMessage(title, text, onnavigate = null) {
965
+ this.expiredSessionSwal.fire(title, text).then((result) => {
966
+ if (result.value && onnavigate)
967
+ onnavigate();
968
+ });
969
+ }
970
+ /**
971
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **CallResult**
972
+ *
973
+ * @param {CallResult} response Risposta ricevuta dal server
974
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
975
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
976
+ * @param {Function} postSuccess Callback da chimare in caso di successo
977
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
978
+ */
979
+ manageCallResultResponse(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
980
+ let anyReponse = response;
981
+ if (response.success || anyReponse.Success) {
982
+ if (response.haswarning || anyReponse.HasWarning)
983
+ this.simpleWarning(response.warning || anyReponse.Warning);
984
+ else if (successMsg)
985
+ this.simpleSuccess(successMsg);
986
+ if (postSuccess)
987
+ postSuccess();
988
+ }
989
+ else {
990
+ this.simpleError((errorMsg ? errorMsg + ": " : "") + ((response.haserror || anyReponse.HasError) ? (response.error || anyReponse.Error) : '[NO ERR.]'));
991
+ if (postFailure)
992
+ postFailure();
993
+ }
994
+ }
995
+ /**
996
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **string**, considerando che:
997
+ *
998
+ * Stringa vuota --> Tutto bene
999
+ *
1000
+ * Stringa piena --> Questo è il messaggio d'errore per cui la chiamata è fallita
1001
+ *
1002
+ * @param {string} response Risposta ricevuta dal server
1003
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
1004
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
1005
+ * @param {Function} postSuccess Callback da chimare in caso di successo
1006
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
1007
+ */
1008
+ manageStringResponse(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
1009
+ if (!response) {
1010
+ if (successMsg)
1011
+ this.simpleSuccess(successMsg);
1012
+ if (postSuccess)
1013
+ postSuccess();
1014
+ }
1015
+ else {
1016
+ if (errorMsg)
1017
+ this.simpleError(errorMsg + ": " + response);
1018
+ if (postFailure)
1019
+ postFailure();
1020
+ }
1021
+ }
1022
+ /**
1023
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **boolean**
1024
+ *
1025
+ * @param {string} response Risposta ricevuta dal server
1026
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
1027
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
1028
+ * @param {Function} postSuccess Callback da chimare in caso di successo
1029
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
1030
+ */
1031
+ manageStringResponseBool(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
1032
+ if (response) {
1033
+ if (successMsg)
1034
+ this.simpleSuccess(successMsg);
1035
+ if (postSuccess)
1036
+ postSuccess();
1037
+ }
1038
+ else {
1039
+ if (errorMsg)
1040
+ this.simpleError(errorMsg);
1041
+ if (postFailure)
1042
+ postFailure();
1043
+ }
1044
+ }
1045
+ }
1046
+ MessageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService, deps: [{ token: Injector }, { token: i1.BaseLocalization, optional: true }, { token: HashingService }], target: i0.ɵɵFactoryTarget.Injectable });
1047
+ MessageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService, providedIn: "root" });
1048
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MessageService, decorators: [{
1049
+ type: Injectable,
1050
+ args: [{ providedIn: "root" }]
1051
+ }], ctorParameters: function () {
1052
+ return [{ type: i0.Injector, decorators: [{
1053
+ type: Inject,
1054
+ args: [Injector]
1055
+ }] }, { type: i1.BaseLocalization, decorators: [{
1056
+ type: Optional
1057
+ }] }, { type: HashingService }];
1058
+ } });
1059
+
1060
+ // Angular
1061
+ /* Classe che contiene tutte le informazioni sull'embedding in un unico contenitore per semplicità */
1062
+ class AppEmbeddingExtensions {
1063
+ constructor(msgService, router, location) {
1064
+ var _a;
1065
+ this.msgService = msgService;
1066
+ this.router = router;
1067
+ this.location = location;
1068
+ this.sidebarWidth = 230;
1069
+ this.Embedded = false;
1070
+ this.EmbeddingLevel = 0;
1071
+ this.MessageObserver = new Subject();
1072
+ this._reloadAllowed = true;
1073
+ this.MainWindow = window;
1074
+ while (this.MainWindow.parent != this.MainWindow) {
1075
+ this.MainWindow = this.MainWindow.parent;
1076
+ this.EmbeddingLevel++;
1077
+ this.Embedded = true;
1078
+ // Fallback per farlo funzionare forzatamente mentre lo testo
1079
+ this.EmbeddedModule = (_a = this.location.path().match(/module=([a-zA-Z_]+)/)) === null || _a === void 0 ? void 0 : _a[1];
1080
+ if (!this.EmbeddedModule)
1081
+ this.waitForMyConfigAndForceEmbeddedModule();
1082
+ }
1083
+ this.configureEmbeddability();
1084
+ if (this.Embedded)
1085
+ this.msgService.configureEmbeddability(this.MainWindow, this.MessageObserver);
1086
+ }
1087
+ waitForMyConfigAndForceEmbeddedModule() {
1088
+ // Aspetto di ricevere il myconfig e setto con lui l'embeddedmodule. Questo viene eseguito solo se this.location.path() per qualche motivo non contiene il module
1089
+ let interval = setInterval(() => {
1090
+ var _a;
1091
+ if ((_a = myconfig === null || myconfig === void 0 ? void 0 : myconfig.AppData) === null || _a === void 0 ? void 0 : _a.ModuleId) {
1092
+ this.EmbeddedModule = myconfig.AppData.ModuleId;
1093
+ clearInterval(interval);
1094
+ }
1095
+ }, 250);
1096
+ }
1097
+ IsReloadAllowed() {
1098
+ let ret = this._reloadAllowed;
1099
+ this._reloadAllowed = true;
1100
+ return ret;
1101
+ }
1102
+ configureEmbeddability() {
1103
+ window.onmessage = (event) => {
1104
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1105
+ // Ignoro i miei messaggi dato che mi interessano solo quelli degli altri iframe
1106
+ if (event.source == window && ((_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.type) != "modal-open")
1107
+ return;
1108
+ this.MessageObserver.next({ event: "window-message", data: event === null || event === void 0 ? void 0 : event.data });
1109
+ if (((_b = event === null || event === void 0 ? void 0 : event.data) === null || _b === void 0 ? void 0 : _b.type) == "alert") {
1110
+ console.log(`Window message - alert -> Level: ${(_c = event === null || event === void 0 ? void 0 : event.data) === null || _c === void 0 ? void 0 : _c.level}, Message: ${(_d = event === null || event === void 0 ? void 0 : event.data) === null || _d === void 0 ? void 0 : _d.msg}`);
1111
+ switch ((_e = event === null || event === void 0 ? void 0 : event.data) === null || _e === void 0 ? void 0 : _e.level) {
1112
+ case "success":
1113
+ this.msgService.simpleSuccess((_f = event === null || event === void 0 ? void 0 : event.data) === null || _f === void 0 ? void 0 : _f.msg);
1114
+ break;
1115
+ case "warning":
1116
+ this.msgService.simpleWarning((_g = event === null || event === void 0 ? void 0 : event.data) === null || _g === void 0 ? void 0 : _g.msg);
1117
+ break;
1118
+ case "error":
1119
+ this.msgService.simpleError((_h = event === null || event === void 0 ? void 0 : event.data) === null || _h === void 0 ? void 0 : _h.msg);
1120
+ break;
1121
+ case "info":
1122
+ this.msgService.simpleInfo((_j = event === null || event === void 0 ? void 0 : event.data) === null || _j === void 0 ? void 0 : _j.msg);
1123
+ break;
1124
+ }
1125
+ }
1126
+ else if (((_k = event === null || event === void 0 ? void 0 : event.data) === null || _k === void 0 ? void 0 : _k.type) == "replace-state") {
1127
+ console.log(`Window message - replace-state -> Url: ${(_l = event === null || event === void 0 ? void 0 : event.data) === null || _l === void 0 ? void 0 : _l.url}`);
1128
+ this.location.replaceState((_m = event === null || event === void 0 ? void 0 : event.data) === null || _m === void 0 ? void 0 : _m.url);
1129
+ }
1130
+ else if (((_o = event === null || event === void 0 ? void 0 : event.data) === null || _o === void 0 ? void 0 : _o.type) == "confirm") {
1131
+ console.log(`Window message - confirm -> Level: ${(_p = event === null || event === void 0 ? void 0 : event.data) === null || _p === void 0 ? void 0 : _p.level}, Message: ${(_q = event === null || event === void 0 ? void 0 : event.data) === null || _q === void 0 ? void 0 : _q.text}, Title: ${(_r = event === null || event === void 0 ? void 0 : event.data) === null || _r === void 0 ? void 0 : _r.title}, ID: ${(_s = event === null || event === void 0 ? void 0 : event.data) === null || _s === void 0 ? void 0 : _s.guid}`);
1132
+ var sourceWindow = event.source;
1133
+ var baseResponse = { type: "confirm-response", guid: (_t = event === null || event === void 0 ? void 0 : event.data) === null || _t === void 0 ? void 0 : _t.guid };
1134
+ switch ((_u = event === null || event === void 0 ? void 0 : event.data) === null || _u === void 0 ? void 0 : _u.level) {
1135
+ case "success":
1136
+ this.msgService.simpleSuccessWithChoice((_v = event === null || event === void 0 ? void 0 : event.data) === null || _v === void 0 ? void 0 : _v.title, (_w = event === null || event === void 0 ? void 0 : event.data) === null || _w === void 0 ? void 0 : _w.text, () => {
1137
+ sourceWindow.postMessage(Object.assign({ result: true }, baseResponse), "*");
1138
+ }, () => {
1139
+ sourceWindow.postMessage(Object.assign({ result: false }, baseResponse), "*");
1140
+ });
1141
+ break;
1142
+ case "warning":
1143
+ this.msgService.simpleWarningWithChoice((_x = event === null || event === void 0 ? void 0 : event.data) === null || _x === void 0 ? void 0 : _x.title, (_y = event === null || event === void 0 ? void 0 : event.data) === null || _y === void 0 ? void 0 : _y.text, () => {
1144
+ sourceWindow.postMessage(Object.assign({ result: true }, baseResponse), "*");
1145
+ }, () => {
1146
+ sourceWindow.postMessage(Object.assign({ result: false }, baseResponse), "*");
1147
+ });
1148
+ break;
1149
+ }
1150
+ }
1151
+ else if (((_z = event === null || event === void 0 ? void 0 : event.data) === null || _z === void 0 ? void 0 : _z.type) == "navigate") {
1152
+ console.log(`Window message - navigate -> ${(_0 = event === null || event === void 0 ? void 0 : event.data) === null || _0 === void 0 ? void 0 : _0.url}`);
1153
+ var newTab = (_1 = event === null || event === void 0 ? void 0 : event.data) === null || _1 === void 0 ? void 0 : _1.newTab;
1154
+ var replaceState = (_2 = event === null || event === void 0 ? void 0 : event.data) === null || _2 === void 0 ? void 0 : _2.replaceState;
1155
+ // Controllo se il router sta seguendo la chiamata attuale. Escludo i query params che sono gli unici che possono essere seccati dai replaceState
1156
+ // e che potrebbero fare del casino
1157
+ if (!window.location.href.includes(this.router.url.split("?")[0])) {
1158
+ console.warn("Doppia chiamata di navigazione, ignoro il secondo evento scoordinato dal router");
1159
+ return;
1160
+ }
1161
+ let newRelativeUrl = this.router.createUrlTree([(_3 = event === null || event === void 0 ? void 0 : event.data) === null || _3 === void 0 ? void 0 : _3.url]);
1162
+ let baseUrl = window.location.href.replace(this.router.url.replace("?ignoreStorage=true", ''), '');
1163
+ let newUrl = baseUrl + decodeURIComponent(newRelativeUrl.toString());
1164
+ if (replaceState)
1165
+ history.pushState({ _pushed: true }, "", newUrl);
1166
+ else if (newTab)
1167
+ window.open(newUrl, '_blank');
1168
+ }
1169
+ else if (((_4 = event === null || event === void 0 ? void 0 : event.data) === null || _4 === void 0 ? void 0 : _4.type) == "navigate-back") {
1170
+ console.log(`Window message - navigate-back -> ${(_5 = event === null || event === void 0 ? void 0 : event.data) === null || _5 === void 0 ? void 0 : _5.url}`);
1171
+ if ((_6 = history === null || history === void 0 ? void 0 : history.state) === null || _6 === void 0 ? void 0 : _6._pushed) {
1172
+ this._reloadAllowed = false;
1173
+ history.back();
1174
+ }
1175
+ }
1176
+ else if (((_7 = event === null || event === void 0 ? void 0 : event.data) === null || _7 === void 0 ? void 0 : _7.type) == "redirect") {
1177
+ console.log(`Window message - redirect -> ${(_8 = event === null || event === void 0 ? void 0 : event.data) === null || _8 === void 0 ? void 0 : _8.url}`);
1178
+ window.location.href = (_9 = event === null || event === void 0 ? void 0 : event.data) === null || _9 === void 0 ? void 0 : _9.url;
1179
+ }
1180
+ else if (((_10 = event === null || event === void 0 ? void 0 : event.data) === null || _10 === void 0 ? void 0 : _10.type) == "navigation") {
1181
+ console.log(`Window message - Navigation -> ${((_11 = event === null || event === void 0 ? void 0 : event.data) === null || _11 === void 0 ? void 0 : _11.internalNavigation) ? "[internal]" : ""} ${(_12 = event === null || event === void 0 ? void 0 : event.data) === null || _12 === void 0 ? void 0 : _12.title}`);
1182
+ this.MessageObserver.next({ event: "navigation", data: event === null || event === void 0 ? void 0 : event.data });
1183
+ }
1184
+ else if (((_13 = event === null || event === void 0 ? void 0 : event.data) === null || _13 === void 0 ? void 0 : _13.type) == "modal-open") {
1185
+ const wrapper = document.body.getElementsByClassName("main-wrapper")[0];
1186
+ let wrapperStyles = window.getComputedStyle(wrapper);
1187
+ const wrapperPaddingLeft = parseInt(wrapperStyles.getPropertyValue("padding-left"));
1188
+ const wrapperPaddingRight = parseInt(wrapperStyles.getPropertyValue("padding-right"));
1189
+ console.log(`Window message - Modal Open -> Backdrop Height: ${(_14 = event === null || event === void 0 ? void 0 : event.data) === null || _14 === void 0 ? void 0 : _14.backdropHeight}`);
1190
+ var topHeight = 80; // valore fisso, distanza fra il top e l'inizio dell'iframe, non sarà mai diverso
1191
+ var rightSpace = wrapperPaddingRight; // valore fisso, distanza fra la fine dell'iframe e il lato sinistro dello schermo, non sarà mai diverso
1192
+ var leftSpace = this.sidebarWidth + wrapperPaddingLeft;
1193
+ let commonStyles = "position: absolute; z-index: 9999; background-color: #000; opacity: 0.5; ";
1194
+ wrapper.style.setProperty("overflow", "hidden", "important");
1195
+ const top = document.createElement("div");
1196
+ top.className = "embedded-modal-top";
1197
+ top.style.cssText = commonStyles + `height: ${topHeight}px; top: 0; width: calc(100% - ${leftSpace}px); left: ${leftSpace}px`;
1198
+ top.id = "top";
1199
+ const left = document.createElement("div");
1200
+ left.className = "embedded-modal-left";
1201
+ left.style.cssText = commonStyles + `height: 100%; top: 0; width: ${leftSpace}px;`;
1202
+ left.id = "left";
1203
+ const right = document.createElement("div");
1204
+ right.className = "embedded-modal-right";
1205
+ right.style.cssText = commonStyles + `height: calc(100% - ${topHeight}px); top: ${topHeight}px; right: 0; width: ${rightSpace}px;`;
1206
+ right.id = "right";
1207
+ // const bottom = document.createElement("div");
1208
+ // bottom.className = "embedded-modal-bottom";
1209
+ // bottom.style.cssText = commonStyles + `height: ${topHeight}px; bottom: 0; width: calc(100% - ${leftSpace}px); left: ${leftSpace}px`;
1210
+ // bottom.id = "bottom";
1211
+ document.body.appendChild(top);
1212
+ document.body.appendChild(left);
1213
+ document.body.appendChild(right);
1214
+ }
1215
+ else if (((_15 = event === null || event === void 0 ? void 0 : event.data) === null || _15 === void 0 ? void 0 : _15.type) == "modal-close") {
1216
+ console.log(`Window message - Modal Close`);
1217
+ let wrapper = document.body.getElementsByClassName("main-wrapper")[0];
1218
+ wrapper.style.removeProperty("overflow");
1219
+ const top = document.getElementById("top");
1220
+ const left = document.getElementById("left");
1221
+ const right = document.getElementById("right");
1222
+ if (top)
1223
+ document.body.removeChild(top);
1224
+ if (left)
1225
+ document.body.removeChild(left);
1226
+ if (right)
1227
+ document.body.removeChild(right);
1228
+ }
1229
+ };
1230
+ if (this.Embedded)
1231
+ document.body.style.setProperty("overflow-y", "auto", "important");
1232
+ }
1233
+ replaceState(basePath, url) {
1234
+ // Esempio basePath: pages
1235
+ // Esempio url: parties/leads_search
1236
+ // Normalizzazione senza slash prima o dopo
1237
+ basePath = basePath.endsWith("/") ? basePath.substring(0, basePath.length - 2) : basePath;
1238
+ url = url.startsWith("/") ? url.substring(1) : url;
1239
+ this.location.replaceState(`${basePath}/${url}`);
1240
+ this.MainWindow.postMessage({ type: "replace-state", url: `pages/embed/${this.EmbeddedModule}/${url}` }, "*");
1241
+ }
1242
+ refreshBoundariesOnMenuCollapse() {
1243
+ const wrapper = document.body.getElementsByClassName("main-wrapper")[0];
1244
+ let wrapperStyles = window.getComputedStyle(wrapper);
1245
+ const wrapperPaddingLeft = parseInt(wrapperStyles.getPropertyValue("padding-left"));
1246
+ var leftSpace = 230 + wrapperPaddingLeft;
1247
+ const left = document.getElementById("left");
1248
+ const top = document.getElementById("top");
1249
+ if (top) {
1250
+ top.style.setProperty("left", (leftSpace) + "px");
1251
+ top.style.setProperty("width", `calc(100% - ${leftSpace}px)`);
1252
+ }
1253
+ if (left)
1254
+ left.style.setProperty("width", leftSpace + "px");
1255
+ }
1256
+ }
1257
+ AppEmbeddingExtensions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AppEmbeddingExtensions, deps: [{ token: MessageService }, { token: i2.Router }, { token: i3.Location }], target: i0.ɵɵFactoryTarget.Injectable });
1258
+ AppEmbeddingExtensions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AppEmbeddingExtensions, providedIn: "root" });
1259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AppEmbeddingExtensions, decorators: [{
1260
+ type: Injectable,
1261
+ args: [{ providedIn: "root" }]
1262
+ }], ctorParameters: function () { return [{ type: MessageService }, { type: i2.Router }, { type: i3.Location }]; } });
1263
+
1264
+ // Angular
1265
+ /**
1266
+ * Service che fornisce un accesso base in lettura/scrittura sulla clipboard
1267
+ */
1268
+ class BaseExtensionsService {
1269
+ constructor(emb) {
1270
+ this.emb = emb;
1271
+ this.RedirectMap = {};
1272
+ this.RoutesMap = {};
1273
+ for (let prop in this.RedirectMap) {
1274
+ this.RoutesMap[prop] = { route: null };
1275
+ this.RoutesMap[prop].route = (param) => {
1276
+ let obj = {};
1277
+ obj[this.RedirectMap[prop].params[0]] = param;
1278
+ return [(this.emb.Embedded ? "pages_ext/" : "pages/") + this.RedirectMap[prop].url, obj];
1279
+ };
1280
+ }
1281
+ }
1282
+ }
1283
+ BaseExtensionsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: BaseExtensionsService, deps: [{ token: AppEmbeddingExtensions }], target: i0.ɵɵFactoryTarget.Injectable });
1284
+ BaseExtensionsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: BaseExtensionsService, providedIn: "root" });
1285
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: BaseExtensionsService, decorators: [{
1286
+ type: Injectable,
1287
+ args: [{ providedIn: "root" }]
1288
+ }], ctorParameters: function () { return [{ type: AppEmbeddingExtensions }]; } });
1289
+
1290
+ /**
1291
+ * Suffisso della proprietà da generare in cui salvare il navigatore
1292
+ * utilizzato dal servizio di esportazione per prendere il valore delle proprietà di un oggetto
1293
+ */
1294
+ const csvValueNavigator = "_csvnav";
1295
+ /** Suffisso con le informazioni del tipo per le esportazioni di oggetti */
1296
+ const csvValueType = "_csvtype";
1297
+ /** Suffisso della proprietà da generare in cui salvare l'ordine di esportazione */
1298
+ const csvOrdPrefix = "_csvord";
1299
+ /** Suffisso della proprietà da generare in cui salvare la visibilità di questa proprietà */
1300
+ const csvVisPrefix = "_csvvis";
1301
+ /** Suffisso della proprietà da generare in cui salvare il nome della colonna in cui salvare questa proprietà */
1302
+ const csvHdrPrefix = "_csvhdr";
1303
+ /** Suffisso della proprietà da generare in cui salvare il codice del th a cui si riferisce questo campo */
1304
+ const csvPropKey = "_csvkey";
1305
+ /** Suffisso della proprietà da generare in cui salvare il valore da prendere per una proprietà di tipo Lista */
1306
+ const listCsvValPrefix = "_listcsvval";
1307
+ /** Suffisso della proprietà da generare in cui salvare l'Header della proprietà di tipo Lista relativo al valore esportato nella proprietà con suffisso **listCsvValPrefix** */
1308
+ const listCsvHdrPrefix = "_listcsvhdr";
1309
+ /** Suffisso della proprietà da generare in cui salvare il formato della proprietà di tipo Lista relativo al valore esportato nella proprietà con suffisso **listCsvValPrefix** */
1310
+ const listCsvValFormat = "_listcsvvalformat";
1311
+ /** Suffisso della proprietà da generare in cui salvare il valore da prendere per una proprietà di tipo Dizionario */
1312
+ const dictionaryCsvValPrefix = "_flatlistcsvval";
1313
+ /** Suffisso della proprietà da generare in cui salvare l'Header della proprietà di un Dizionario relativo al valore esportato nella proprietà con suffisso **dictionaryCsvValPrefix** */
1314
+ const dictionaryCsvHdrPrefix = "_flatlistcsvhdr";
1315
+ /** Suffisso della proprietà da generare in cui salvare il formato della proprietà che si sta esportando */
1316
+ const csvFormatPrefix = "_csvfmt";
1317
+ /** Nome della proprietà che contiene tutti i nomi di tutte le proprietà da esportare */
1318
+ const exportList = "__export_list__";
1319
+ /** Nome della proprietà che contiene la classe di localizzazione da utilizzare per una data esportazione */
1320
+ const locProperty = "__loc__";
1321
+
1322
+ /**
1323
+ * Mappatura del TypeCode del C#
1324
+ */
1325
+ var TypeCode;
1326
+ (function (TypeCode) {
1327
+ /** @ignore */ TypeCode[TypeCode["Empty"] = 0] = "Empty";
1328
+ /** @ignore */ TypeCode[TypeCode["Obj"] = 1] = "Obj";
1329
+ /** @ignore */ TypeCode[TypeCode["DBNull"] = 2] = "DBNull";
1330
+ /** @ignore */ TypeCode[TypeCode["Boolean"] = 3] = "Boolean";
1331
+ /** @ignore */ TypeCode[TypeCode["Char"] = 4] = "Char";
1332
+ /** @ignore */ TypeCode[TypeCode["SByte"] = 5] = "SByte";
1333
+ /** @ignore */ TypeCode[TypeCode["Byte"] = 6] = "Byte";
1334
+ /** @ignore */ TypeCode[TypeCode["Int16"] = 7] = "Int16";
1335
+ /** @ignore */ TypeCode[TypeCode["UInt16"] = 8] = "UInt16";
1336
+ /** @ignore */ TypeCode[TypeCode["Int32"] = 9] = "Int32";
1337
+ /** @ignore */ TypeCode[TypeCode["UInt32"] = 10] = "UInt32";
1338
+ /** @ignore */ TypeCode[TypeCode["Int64"] = 11] = "Int64";
1339
+ /** @ignore */ TypeCode[TypeCode["UInt64"] = 12] = "UInt64";
1340
+ /** @ignore */ TypeCode[TypeCode["Single"] = 13] = "Single";
1341
+ /** @ignore */ TypeCode[TypeCode["Double"] = 14] = "Double";
1342
+ /** @ignore */ TypeCode[TypeCode["Decimal"] = 15] = "Decimal";
1343
+ /** @ignore */ TypeCode[TypeCode["DateTime"] = 16] = "DateTime";
1344
+ /** @ignore */ TypeCode[TypeCode["String"] = 18] = "String";
1345
+ })(TypeCode || (TypeCode = {}));
1346
+
1347
+ // Angular
1348
+ /**
1349
+ * Service che fornisce metodi di pubblica utilità
1350
+ */
1351
+ class UtilityService {
1352
+ constructor() {
1353
+ // Funzione di throttling per non spammare richieste in caso di animazioni attivate
1354
+ //TODO: spostarla in un metodo di utilit� (esfaenza/extensions)
1355
+ /** @ignore */
1356
+ this.executionTimers = {};
1357
+ }
1358
+ /**
1359
+ * Deseleziona il testo eventualmente selezionato
1360
+ */
1361
+ clearTextSelection() {
1362
+ if (window.getSelection) {
1363
+ if (window.getSelection().empty) // Chrome
1364
+ window.getSelection().empty();
1365
+ else if (window.getSelection().removeAllRanges) // Firefox
1366
+ window.getSelection().removeAllRanges();
1367
+ }
1368
+ else if (document.selection) // IE?
1369
+ document.selection.empty();
1370
+ }
1371
+ /**
1372
+ * Partendo da una lista, dato il nome della proprietà chiave e il valore della chiave selezionata,
1373
+ * trova e restituisce l'oggetto desiderato
1374
+ *
1375
+ * @param {T[]} sourceList Lista di oggetti dentro cui cercare
1376
+ * @param {string} sourceItemIdField Nome della proprietà che rappresenta la chiave di un oggetto di tipo T
1377
+ * @param {string} selectedValue Valore di chiave selezionato
1378
+ *
1379
+ * @returns {T} Oggetto la cui proprietà **sourceItemIdField** assume il valore **selectedValue**
1380
+ */
1381
+ getSelectedItem(sourceList, sourceItemIdField, selectedValue) {
1382
+ for (let i = 0; i < sourceList.length; i++) {
1383
+ var item = sourceList[i];
1384
+ if (item[sourceItemIdField] == selectedValue)
1385
+ return item;
1386
+ }
1387
+ return null;
1388
+ }
1389
+ /**
1390
+ * Effettua il reset di un Form di Angular
1391
+ *
1392
+ * @param {NgForm} form Form da resettare
1393
+ * @param {string} exception1 Campo da non resettare
1394
+ * @param {string} exception2 Campo da non resettare
1395
+ */
1396
+ cleanForm(form, exception1 = null, exception2 = null) {
1397
+ for (let name in form.controls) {
1398
+ if (name && name != exception1 && name != exception1 + "_internal" && name != exception2 && name != exception2 + "_internal") {
1399
+ form.controls[name].reset();
1400
+ }
1401
+ else {
1402
+ form.controls[name].markAsPristine();
1403
+ form.controls[name].markAsUntouched();
1404
+ }
1405
+ }
1406
+ //Reimposto il submitted
1407
+ form.submitted = false;
1408
+ }
1409
+ /**
1410
+ * Helper che permette di scaricare un file dato un URL (Generato da una chiamata ad **window.URL.createObjectURL**)
1411
+ *
1412
+ * @param {string} url ObjectURL che rappresenta il file da scaricare
1413
+ * @param {string} filename Nome del file suggerito in fase di salvataggio
1414
+ */
1415
+ fileDownload(url, fileName) {
1416
+ var a = document.createElement("a");
1417
+ document.body.appendChild(a);
1418
+ a.className = "ta-display-none";
1419
+ a.href = url;
1420
+ a.download = fileName;
1421
+ a.click();
1422
+ window.URL.revokeObjectURL(url);
1423
+ document.body.removeChild(a);
1424
+ }
1425
+ /**
1426
+ * Helper per la formattazione di un numero di millisecondi in una stringa più comprensibile per un umano
1427
+ *
1428
+ * @param {number} duration Tempo espresso in millisecondi
1429
+ *
1430
+ * @returns {string} Durata formattata
1431
+ */
1432
+ msToTime(duration) {
1433
+ if (!duration)
1434
+ return "";
1435
+ var milliseconds = parseInt(((duration % 1000) / 100).toString()), seconds = parseInt(((duration / 1000) % 60).toString()), minutes = parseInt(((duration / (1000 * 60)) % 60).toString()), hours = parseInt(((duration / (1000 * 60 * 60)) % 24).toString());
1436
+ var st_hours = (hours < 10) ? "0" + hours : hours;
1437
+ var st_minutes = (minutes < 10) ? "0" + minutes : minutes;
1438
+ var st_seconds = (seconds < 10) ? "0" + seconds : seconds;
1439
+ return st_hours + ":" + st_minutes + ":" + st_seconds + "." + milliseconds;
1440
+ }
1441
+ /**
1442
+ * Helper che permette di scaricare un file in Base64
1443
+ *
1444
+ * @param {string} base64Data Base64 che rappresenta il file da scaricare
1445
+ * @param {string} filename Nome del file suggerito in fase di salvataggio
1446
+ */
1447
+ saveFile(base64Data, filename) {
1448
+ var sampleArr = this.base64ToArrayBuffer(base64Data);
1449
+ this.saveByteArray(sampleArr, filename);
1450
+ }
1451
+ /**
1452
+ * Trasforma un Base64 in un ArrayBuffer
1453
+ *
1454
+ * @param {string} base64Data Base64 da trasformare
1455
+ *
1456
+ * @returns {Uint8Array} Array UTF8
1457
+ */
1458
+ base64ToArrayBuffer(base64Data) {
1459
+ var binaryString = window.atob(base64Data);
1460
+ var binaryLen = binaryString.length;
1461
+ var bytes = new Uint8Array(binaryLen);
1462
+ for (var i = 0; i < binaryLen; i++) {
1463
+ var ascii = binaryString.charCodeAt(i);
1464
+ bytes[i] = ascii;
1465
+ }
1466
+ return bytes;
1467
+ }
1468
+ /**
1469
+ * Helper che permette di scaricare un file dato un array di Byte (**Uint8Array**)
1470
+ *
1471
+ * @param {Uint8Array} byte Rappresentazione del file da scaricare
1472
+ * @param {string} filename Nome del file suggerito in fase di salvataggio
1473
+ */
1474
+ saveByteArray(byte, filename) {
1475
+ var blob = new Blob([byte]);
1476
+ var link = document.createElement("a");
1477
+ document.body.appendChild(link);
1478
+ link.href = window.URL.createObjectURL(blob);
1479
+ var fileName = filename;
1480
+ link.download = fileName;
1481
+ link.click();
1482
+ document.body.removeChild(link);
1483
+ }
1484
+ ;
1485
+ /**
1486
+ * Utility per lo swap di due elementi di un array
1487
+ *
1488
+ * @param {any[]} array Array di cui invertire due elementi
1489
+ * @param {number} x Indice del primo elemento
1490
+ * @param {number} y Indice del secondo elemento
1491
+ */
1492
+ swap(array, x, y) {
1493
+ var b = array[x];
1494
+ array[x] = array[y];
1495
+ array[y] = b;
1496
+ }
1497
+ /**
1498
+ * Helper di trascodifica da tipo c# a tipo Typescript
1499
+ *
1500
+ * @param {TypeCode} type Tipo da trascodificare
1501
+ *
1502
+ * @returns {"boolean" | "number" | "string" | "date"} Tipo Typescript corrispondente
1503
+ */
1504
+ getJsTypeFromTypeCode(type) {
1505
+ switch (type) {
1506
+ case TypeCode.Boolean:
1507
+ return "boolean";
1508
+ case TypeCode.Decimal:
1509
+ case TypeCode.Double:
1510
+ case TypeCode.Single:
1511
+ case TypeCode.Int16:
1512
+ case TypeCode.Int32:
1513
+ case TypeCode.Int64:
1514
+ case TypeCode.Byte:
1515
+ case TypeCode.SByte:
1516
+ case TypeCode.UInt16:
1517
+ case TypeCode.UInt32:
1518
+ case TypeCode.UInt64:
1519
+ return "number";
1520
+ case TypeCode.Char:
1521
+ case TypeCode.String:
1522
+ return "string";
1523
+ case TypeCode.DateTime:
1524
+ return "date";
1525
+ default:
1526
+ console.log("Unrecognized input type. Typecode:" + type);
1527
+ return "string";
1528
+ }
1529
+ }
1530
+ /**
1531
+ * Effettua la clonazione profonda di un oggetto in maniera molto più performante che JSON.parse(JSON.stringify()).
1532
+ *
1533
+ * Usare solo per oggetti puri e quantomeno semplici per evitare complicazioni derivanti dalle semplificazioni che questo metodo assume
1534
+ *
1535
+ * @param {any} source Oggetto da clonare
1536
+ *
1537
+ * @return {any} Clone dell'oggetto passato
1538
+ */
1539
+ deepClone(source, type = null) {
1540
+ // Valori semplici
1541
+ if (source == null || typeof source !== 'object')
1542
+ return source;
1543
+ // Pseudo Struct
1544
+ switch (toString.call(source)) {
1545
+ case '[object Boolean]':
1546
+ case '[object Number]':
1547
+ case '[object String]':
1548
+ case '[object Date]':
1549
+ return new source.constructor(source.valueOf());
1550
+ // Clonazione di un file -> Restituisco il riferimento al file stesso
1551
+ case "[object File]":
1552
+ return source;
1553
+ default: break;
1554
+ }
1555
+ // Oggetti Complessi
1556
+ return this.recursiveStep(source, Array.isArray(source) || source instanceof Array ? [] : (type == null ? Object.create(Object.getPrototypeOf(source)) : new type()));
1557
+ }
1558
+ /**
1559
+ * @ignore
1560
+ * Step ricorsivo per la clonatura degli oggetti. Vedere **deepClone**
1561
+ */
1562
+ recursiveStep(source, destination) {
1563
+ if (Array.isArray(source) || source instanceof Array) {
1564
+ for (var i = 0, ii = source.length; i < ii; i++)
1565
+ destination.push(this.deepClone(source[i]));
1566
+ }
1567
+ else if (source && typeof source.hasOwnProperty === 'function') {
1568
+ for (let key in source) {
1569
+ if (source.hasOwnProperty(key))
1570
+ destination[key] = this.deepClone(source[key]);
1571
+ }
1572
+ }
1573
+ return destination;
1574
+ }
1575
+ cast(object, clss) {
1576
+ let ret = Object.assign(Object.create(clss.prototype), object);
1577
+ return ret;
1578
+ }
1579
+ /** @ignore */
1580
+ throttla(id, func, throttleTime) {
1581
+ //Se ho la funzione che vuole eseguire ripulisco quel timeout
1582
+ if (this.executionTimers[id])
1583
+ clearTimeout(this.executionTimers[id]);
1584
+ //Ricreo il timeout per eseguire quella funzione dopo throttleTime millisecondi
1585
+ this.executionTimers[id] = setTimeout(() => { func(); this.executionTimers[id] = null; }, throttleTime);
1586
+ }
1587
+ }
1588
+ UtilityService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UtilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1589
+ UtilityService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UtilityService, providedIn: "root" });
1590
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UtilityService, decorators: [{
1591
+ type: Injectable,
1592
+ args: [{ providedIn: "root" }]
1593
+ }] });
1594
+
1595
+ /**
1596
+ * Decoratore che fornisce la classe di localizzazione per tutte le proprietà esportate con @Export e qualsiasi altro tag che richieda localizzazioni.
1597
+ *
1598
+ * Sostanzilamente aggiunge la proprietà **__loc__** all'oggetto creato dalla classe corrente assegnandogli come valore il tipo del LocalizationService da usare per la traduzione
1599
+ *
1600
+ * @param {Type<LocalizationService>} loc Tipo ereditato dal LocalizationService che può essere creato a runtime sotto contesto della DI di Angular
1601
+ */
1602
+ function ExportLocalization(loc) {
1603
+ return function integrateLoc(constructor) {
1604
+ return class extends constructor {
1605
+ constructor() {
1606
+ super(...arguments);
1607
+ this.__loc__ = loc;
1608
+ }
1609
+ };
1610
+ };
1611
+ }
1612
+ /**
1613
+ * Decoratore di esportazione utilizzabile su una proprietà singola.
1614
+ * Verranno generate 3 proprietà che gestiranno l'esportazione: (prop, prop_csvvis, prop_csvhdr).
1615
+ *
1616
+ * Ad esempio, da questa configurazione:
1617
+ *
1618
+ * @example
1619
+ * ```
1620
+ * @Export(true, "MyHeader")
1621
+ * ciao: string;
1622
+ * ```
1623
+ *
1624
+ * Nasceranno le seguenti proprietà nell'oggetto esportabile:
1625
+ *
1626
+ * @example
1627
+ * ```
1628
+ * ciao_csvvis: string; => true
1629
+ * ciao: string;
1630
+ * ciao_csvhdr: string => "MyHeader"
1631
+ * ```
1632
+ *
1633
+ * @param {number} order Ordine di esportazione. Più piccolo è, prima appare il valore
1634
+ * @param {string} header Titolo della colonna nel file CSV esportato
1635
+ * @param {string} format Formato di esportazione. Può essere un formato data per i campi data o 'F' per i campi floating point
1636
+ */
1637
+ const Export = (order, header, format = null, tableid = null) => (target, propertyKey) => {
1638
+ if (format)
1639
+ Object.defineProperty(target, propertyKey + csvFormatPrefix, { value: format, writable: false });
1640
+ Object.defineProperty(target, propertyKey + csvOrdPrefix, { value: order, writable: false });
1641
+ Object.defineProperty(target, propertyKey + csvVisPrefix, { value: !!header, writable: false });
1642
+ Object.defineProperty(target, propertyKey + csvHdrPrefix, { value: header, writable: false });
1643
+ if (tableid)
1644
+ Object.defineProperty(target, propertyKey + csvPropKey, { value: tableid, writable: false });
1645
+ if (target[exportList])
1646
+ target[exportList].push(propertyKey + csvVisPrefix);
1647
+ else
1648
+ target[exportList] = [propertyKey + csvVisPrefix];
1649
+ };
1650
+ /**
1651
+ * Decoratore di esportazione utilizzabile su un oggetto.
1652
+ * Per ogni proprietà dell'oggetto verranno generate 3 proprietà che gestiranno l'esportazione: (prop, prop_csvvis, prop_csvhdr).
1653
+ * Per essere esportate, le proprietà dell'oggetto devono essere marcate con i Decoratori di esportazione
1654
+ *
1655
+ * Ad esempio, da questa configurazione:
1656
+ *
1657
+ * @example
1658
+ * ```
1659
+ * MyObj {
1660
+ * @Export(true, "MyHeader")
1661
+ * ciao: string;
1662
+ * }
1663
+ *
1664
+ * @ExportObject(true, "MyHeader")
1665
+ * test: MyObj;
1666
+ * ```
1667
+ *
1668
+ * Nasceranno le seguenti proprietà nell'oggetto esportabile:
1669
+ *
1670
+ * @example
1671
+ * ```
1672
+ * testciao: string; => Valore di MyObj.ciao
1673
+ * testciao_csvvis: string; => true
1674
+ * testciao_csvhdr: string => "MyHeader"
1675
+ * ```
1676
+ *
1677
+ * @param {number} order Ordine di esportazione. Più piccolo è, prima appare il valore
1678
+ * @param {any} type Tipo da esportare
1679
+ */
1680
+ const ExportAs = (order, type, prefix) => (target, propertyKey) => {
1681
+ var addedHere = {};
1682
+ var t = new type();
1683
+ var props = t[exportList];
1684
+ for (let i = 0; i < props.length; i++) {
1685
+ let prop = props[i].replace(csvVisPrefix, '');
1686
+ if (addedHere[prop])
1687
+ continue;
1688
+ if (typeof t[prop + csvVisPrefix] !== "undefined") {
1689
+ var toEmit = t[prop + csvVisPrefix];
1690
+ var lbl = t[prop + csvHdrPrefix];
1691
+ var format = t[prop + csvFormatPrefix];
1692
+ var orderProp = t[prop + csvOrdPrefix];
1693
+ var ppp = propertyKey + "$_$" + prop;
1694
+ if (format)
1695
+ Object.defineProperty(target, ppp + csvFormatPrefix, { value: format, writable: false });
1696
+ Object.defineProperty(target, ppp + csvOrdPrefix, { value: orderProp + order, writable: false });
1697
+ Object.defineProperty(target, ppp, { value: null, writable: true, enumerable: true });
1698
+ Object.defineProperty(target, ppp + csvValueNavigator, { value: propertyKey + "." + prop.replace(/\$_\$/g, '.'), writable: false });
1699
+ Object.defineProperty(target, ppp + csvVisPrefix, { value: toEmit, writable: false });
1700
+ Object.defineProperty(target, ppp + csvHdrPrefix, { value: (prefix ? prefix + ' ' : '') + lbl, writable: false });
1701
+ Object.defineProperty(target, ppp + csvValueType, { value: type, writable: false });
1702
+ if (target[exportList])
1703
+ target[exportList].push(ppp + csvVisPrefix);
1704
+ else
1705
+ target[exportList] = [ppp + csvVisPrefix];
1706
+ addedHere[ppp] = true;
1707
+ }
1708
+ }
1709
+ };
1710
+ /**
1711
+ * Decoratore di esportazione utilizzabile su una lista,
1712
+ * si utilizzano 2 navigator rispettivamente per la valorizzazione dell'Header e del Valore e
1713
+ * per ogni elemento dell'array verranno generate 3 proprietà che gestiranno l'esportazione: (prop, prop_csvvis, prop_csvhdr)
1714
+ *
1715
+ * ATTENZIONE: Gli oggetti esportati in questa modalità non devono presentare altri tag di tipo @Export{...} all'interno. Fa tutto questo decoratore
1716
+ *
1717
+ * I navigator hanno questa convenzione:
1718
+ *
1719
+ * . --> divide due proprietà da richiamare consecutivamente: "a.b" richiamerà "obj.a.b";
1720
+ *
1721
+ * | --> divide più proprietà per le concatenazioni con uno spazio fra una e l'altra: "regdesc|slice.slicename" diventerà obj.regdesc + " " + obj.slice.slicename
1722
+ *
1723
+ * @param {number} order Ordine di esportazione. Più piccolo è, prima appare il valore
1724
+ * @param {string} headernavigator Navigator col compito di selezionare il titolo per la colonna
1725
+ * @param {string} valuenavigator Navigator col compito di selezionare il valore per la colonna
1726
+ * @param {string} valueformat Formato di esportazione per i valori selezionati dal **valuenavigator**. Può essere un formato data per i campi data o 'F' per i campi floating point
1727
+ */
1728
+ const ExportList = (order, headernavigator, valuenavigator, valueformat = null) => (target, propertyKey) => {
1729
+ Object.defineProperty(target, propertyKey + csvOrdPrefix, { value: order, writable: false });
1730
+ Object.defineProperty(target, propertyKey + listCsvValPrefix, { value: valuenavigator, writable: false });
1731
+ Object.defineProperty(target, propertyKey + listCsvHdrPrefix, { value: headernavigator, writable: false });
1732
+ Object.defineProperty(target, propertyKey + listCsvValFormat, { value: valueformat, writable: false });
1733
+ if (target[exportList])
1734
+ target[exportList].push(propertyKey + listCsvHdrPrefix);
1735
+ else
1736
+ target[exportList] = [propertyKey + listCsvHdrPrefix];
1737
+ };
1738
+ /**
1739
+ * Decoratore di esportazione utilizzabile su un dizionario. Se ad esempio si vogliono generare le colonne
1740
+ *
1741
+ * Valore A = 1
1742
+ *
1743
+ * Valore B = 2
1744
+ *
1745
+ * Valore C = 3
1746
+ *
1747
+ * partendo da un oggetto iniziale { Valore { A: 1, B: 2, C: 3 } }
1748
+ *
1749
+ * @param {number} order Ordine di esportazione. Più piccolo è, prima appare il valore
1750
+ * @param {string} headerprefix Prefisso per l'header
1751
+ * @param {string} valueprefix Prefisso per il valore
1752
+ */
1753
+ const ExportDictionary = (order, headerprefix, valueprefix) => (target, propertyKey) => {
1754
+ Object.defineProperty(target, propertyKey + csvOrdPrefix, { value: order, writable: false });
1755
+ Object.defineProperty(target, propertyKey + dictionaryCsvValPrefix, { value: valueprefix, writable: false });
1756
+ Object.defineProperty(target, propertyKey + dictionaryCsvHdrPrefix, { value: headerprefix, writable: false });
1757
+ if (target[exportList])
1758
+ target[exportList].push(propertyKey + dictionaryCsvHdrPrefix);
1759
+ else
1760
+ target[exportList] = [propertyKey + dictionaryCsvHdrPrefix];
1761
+ };
1762
+ /**
1763
+ * Service che si occupa dell'esportazione degli oggetti marcati dai Decoratori **ExportDictionary**, **ExportList**, **ExportAs** o **Export**
1764
+ */
1765
+ class ExportService {
1766
+ /**
1767
+ * Costruttore
1768
+ *
1769
+ * @ignore
1770
+ */
1771
+ constructor(dates, utiExts, lc) {
1772
+ this.dates = dates;
1773
+ this.utiExts = utiExts;
1774
+ this.lc = lc;
1775
+ }
1776
+ /**
1777
+ * Data una lista di oggetti genera gli header per l'esportazione e integra ogni oggetto con le proprietà esportabili dalla libreria **@ctrl/ngx-csv**
1778
+ *
1779
+ * @param {any[]} objs Oggetti da esportare
1780
+ *
1781
+ * @returns {CsvHeaders[]} Header di esportazione già ordinati correttamente
1782
+ */
1783
+ setupForExport(objs, columns = []) {
1784
+ let headers = [];
1785
+ let headersCache = {};
1786
+ if (!objs || objs.length == 0)
1787
+ return headers;
1788
+ // Devo per forza farlo per tutti gli oggetti dato che devo esporre le proprietà che mi servono da esportare
1789
+ // Gli header li raccolgo tutti poi faccio uan distinct in modo da esportare tutte le proprietà per bene
1790
+ let columnSelectionDictionary = {};
1791
+ if ((columns === null || columns === void 0 ? void 0 : columns.length) > 0)
1792
+ for (let i = 0; i < (columns === null || columns === void 0 ? void 0 : columns.length); i++)
1793
+ columnSelectionDictionary[columns[i]] = true;
1794
+ for (let i = 0; i < objs.length; i++) {
1795
+ let hds = this.parseAndGetHeaders(objs[i], columnSelectionDictionary);
1796
+ // Aggiungo gli header facendo in modo di non aggiungerne mai due uguali per non dover fare una distinct dopo
1797
+ // che costerebbe comunque risorse. Utilizzo un dizionario d'appoggio per lookup istantanei
1798
+ for (let k = 0; k < hds.length; k++) {
1799
+ if (!headersCache[hds[k].key]) {
1800
+ headersCache[hds[k].key] = true;
1801
+ headers.push(hds[k]);
1802
+ }
1803
+ }
1804
+ }
1805
+ if (!columns || columns.length == 0)
1806
+ return headers.sort((a, b) => a.order - b.order);
1807
+ else {
1808
+ // Se mi arriva la lista di colonne non mi dà solo la visibilità, ma anche l'ordinamento
1809
+ // le esporto di conseguenza
1810
+ let orderedHeaders = [];
1811
+ for (let i = 0; i < columns.length; i++) {
1812
+ let thisId = columns[i];
1813
+ for (let i = 0; i < headers.length; i++) {
1814
+ if (headers[i].propKey == thisId) {
1815
+ orderedHeaders.push(headers[i]);
1816
+ break;
1817
+ }
1818
+ }
1819
+ }
1820
+ return orderedHeaders;
1821
+ }
1822
+ }
1823
+ /**
1824
+ * Data una lista di oggetti generici genera gli header per l'esportazione e integra ogni oggetto con le proprietà esportabili dalla libreria **@ctrl/ngx-csv**
1825
+ *
1826
+ * @param {GenericItem[]} objs Oggetti generici da esportare
1827
+ * @param {CsvHeaders[]} columns Colonne richieste dall'esportazione
1828
+ *
1829
+ * @returns {CsvHeaders[]} Header di esportazione già ordinati correttamente
1830
+ */
1831
+ setupForGenericExport(objs, columns) {
1832
+ let headers = [];
1833
+ if (!objs || objs.length == 0)
1834
+ return headers;
1835
+ // Devo per forza farlo per tutti gli oggetti dato che devo esporre le proprietà che mi servono da esportare
1836
+ objs.forEach((obj, index) => {
1837
+ if (index == 0)
1838
+ headers = this.parseAndGetGenericHeaders(obj, columns);
1839
+ else
1840
+ this.parseAndGetGenericHeaders(obj, columns);
1841
+ });
1842
+ return headers;
1843
+ }
1844
+ /**
1845
+ * Dato un oggetto generico genera gli header per l'esportazione e lo integra con le proprietà esportabili dalla libreria **@ctrl/ngx-csv**
1846
+ *
1847
+ * Metodo interno richiamato da **setupForGenericExport**
1848
+ *
1849
+ * @param {GenericItem} obj Oggetto generico da esportare
1850
+ * @param {CsvColumn[]} columns Colonne richieste dall'esportazione
1851
+ *
1852
+ * @returns {CsvHeaders[]} Header di esportazione già ordinati correttamente
1853
+ */
1854
+ parseAndGetGenericHeaders(obj, columns) {
1855
+ if (!obj.properties)
1856
+ return null;
1857
+ var headers = [];
1858
+ //Miracle incoming
1859
+ columns.forEach(t => {
1860
+ var propValue = obj.properties[t.key];
1861
+ Object.defineProperty(obj, t.key + "_exp", { value: propValue, writable: false, enumerable: true });
1862
+ headers.push({ label: t.label, key: t.key + "_exp", order: t.order, type: t.type, propKey: null });
1863
+ });
1864
+ //Tirati fuori tutti gli header faccio sort sull'ordinamento
1865
+ return headers.sort((a, b) => { return a.order - b.order; });
1866
+ }
1867
+ /**
1868
+ * Dato un oggetto genera gli header per l'esportazione e lo integra con le proprietà esportabili dalla libreria **@ctrl/ngx-csv**
1869
+ *
1870
+ * Metodo interno richiamato da **setupForExport**
1871
+ *
1872
+ * @param {any} obj Oggetto generico da esportare
1873
+ *
1874
+ * @returns {CsvHeaders[]} Header di esportazione già ordinati correttamente
1875
+ */
1876
+ parseAndGetHeaders(obj, columnsSelection) {
1877
+ var headers = [];
1878
+ // Miracle incoming
1879
+ let exportProps = obj[exportList] || [];
1880
+ let loc = obj[locProperty] ? this.lc.generateFromType(obj[locProperty]) : null;
1881
+ if (exportProps.length == 0)
1882
+ console.warn("[@esfaenza/extensions] Nessuna colonna configurata da esportare!");
1883
+ for (let i = 0; i < exportProps.length; i++) {
1884
+ let prop = exportProps[i];
1885
+ let propBase = "";
1886
+ let toCall;
1887
+ if (prop.endsWith(listCsvHdrPrefix)) {
1888
+ propBase = prop.replace(listCsvHdrPrefix, '');
1889
+ toCall = this.parseList.bind(this);
1890
+ }
1891
+ else if (prop.endsWith(dictionaryCsvHdrPrefix)) {
1892
+ propBase = prop.replace(dictionaryCsvHdrPrefix, '');
1893
+ toCall = this.parseDictionary.bind(this);
1894
+ }
1895
+ else if (prop.endsWith(csvVisPrefix)) {
1896
+ propBase = prop.replace(csvVisPrefix, '');
1897
+ if (typeof obj[propBase + csvValueNavigator] !== "undefined")
1898
+ toCall = this.parseObject.bind(this);
1899
+ else
1900
+ toCall = this.parseProperty.bind(this);
1901
+ }
1902
+ if (toCall)
1903
+ toCall(obj, propBase, headers, columnsSelection, loc);
1904
+ }
1905
+ return headers;
1906
+ }
1907
+ /**
1908
+ * Setup per l'esportazione di una singola proprietà.
1909
+ * Viene generato l'header e la proprietà relativa al valore formattato o no
1910
+ *
1911
+ * @param {any} obj Oggetto di cui esportare la proprietà **prop**
1912
+ * @param {string} prop Proprietà da esportare
1913
+ * @param {CsvHeaders} headers Contenitore degli header, verrà riempito da questa funzione
1914
+ * @param {LocalizationService} loc Servizio di localizzazione che traduce tutti i nomi che può
1915
+ */
1916
+ parseProperty(obj, prop, headers, columnsSelection, loc) {
1917
+ let toEmit = obj[prop + csvVisPrefix];
1918
+ let format = obj[prop + csvFormatPrefix];
1919
+ let propKey = obj[prop + csvPropKey];
1920
+ if (propKey && !columnsSelection[propKey] && Object.keys(columnsSelection).length > 0) {
1921
+ console.log("[@esfaenza/extensions] Colonna da non esportare: " + propKey);
1922
+ return;
1923
+ }
1924
+ let text = obj[prop + csvHdrPrefix];
1925
+ let label = loc && text ? loc.loc(text) : text || "";
1926
+ let order = obj[prop + csvOrdPrefix];
1927
+ if (!toEmit)
1928
+ return;
1929
+ // Se non ho un formato esporto direttamente
1930
+ if (!format) {
1931
+ // Se è un formato data mi assicuro di non stampare mai una data 00:00:00 altrimenti in esportazione viene uno schifo
1932
+ let val = obj[prop] ? this.dates.trimSeconds(obj[prop].toString()) : "";
1933
+ let key = prop + "_nofmt";
1934
+ Object.defineProperty(obj, key, { value: val, writable: false, enumerable: true });
1935
+ headers.push({ label, key, order, type: "string", propKey });
1936
+ }
1937
+ else {
1938
+ let key = prop + "_fmt";
1939
+ // Caso formato numerico
1940
+ if (format == "F") {
1941
+ // Check considerando la possibilità di zeri
1942
+ let val = obj[prop] != null ? obj[prop].toString() : "";
1943
+ // Elimino tutte le virgole (indicatori di migliaia per la culture default en-US)
1944
+ val = val.replace(/,/, "");
1945
+ // Il singolo punto che c'è, se presente (separatore decimali) lo trasformo in virgola
1946
+ let valConverted = val.replace(".", ",");
1947
+ Object.defineProperty(obj, key, { value: valConverted, writable: false, enumerable: true });
1948
+ headers.push({ label, key, order, type: "number", propKey });
1949
+ }
1950
+ else {
1951
+ // Se ho un formato data trasformo in dayjs, formatto ed esporto
1952
+ // Per la trasformazione in dayjs provo prima a passargli la stringa di netto, sperando la riconosca
1953
+ // Se non funziona provo a definirgli la formattazione standard del metering per quel linguaggio
1954
+ let val = this.dates.getFormatted(obj[prop], format.length <= 10, format.length > 16);
1955
+ Object.defineProperty(obj, key, { value: val !== null && val !== void 0 ? val : "", writable: false, enumerable: true });
1956
+ headers.push({ label, key, order, type: "date", propKey });
1957
+ }
1958
+ }
1959
+ }
1960
+ /**
1961
+ * Setup per l'esportazione di una singola proprietà da un oggetto.
1962
+ * Viene generato l'header e la proprietà relativa al valore formattato o no.
1963
+ *
1964
+ * Per ottenere il valore e l'header della proprietà vengono utilizzati i navigatori auto-generati nel decoratore **ExportAs**
1965
+ *
1966
+ * @param {any} obj Oggetto di cui esportare la proprietà **prop**
1967
+ * @param {string} prop Proprietà da esportare
1968
+ * @param {CsvHeaders} headers Contenitore degli header, verrà riempito da questa funzione
1969
+ * @param {LocalizationService} loc Servizio di localizzazione che traduce tutti i nomi che può
1970
+ */
1971
+ parseObject(obj, prop, headers, columnsSelection, loc) {
1972
+ //se questa proprietà ha un navigator significa che deriva da un oggetto interno, recupero il valore in questa fase dato che prima non ce l'ho
1973
+ let valuenavigator = obj[prop + csvValueNavigator];
1974
+ //Es. di valuenavigator obj.subobj.subsubobj.property
1975
+ let jmps = valuenavigator.split(".");
1976
+ // Localizzazione presa dalla classe base se c'è, altrimenti dalla classe interna (cioè dal primo saltino)
1977
+ if (!loc) {
1978
+ let type = obj[prop + csvValueType];
1979
+ let proto = new type();
1980
+ loc = proto[locProperty] ? this.lc.generateFromType(proto[locProperty]) : null;
1981
+ }
1982
+ //Mi clono l'oggetto originale per non uccidergli i riferimenti
1983
+ let clone = JSON.parse(JSON.stringify(obj));
1984
+ //Salto ricorsivamente su me stesso per arrivare alla proprietà
1985
+ //Salto 1 > diventa obj
1986
+ //Salto 2 > diventa obj.subobj
1987
+ //ecc...
1988
+ jmps.forEach(pp => { clone = clone === null || clone === void 0 ? void 0 : clone[pp]; });
1989
+ //Valore finale :D
1990
+ let value = clone;
1991
+ let text = obj[prop + csvHdrPrefix];
1992
+ let label = loc && text ? loc.loc(text) : text || "";
1993
+ let order = obj[prop + csvOrdPrefix];
1994
+ //Se per questa proprietà ho un formato lo applico
1995
+ let format = obj[prop + csvFormatPrefix];
1996
+ let type = "string";
1997
+ if (format == "F") {
1998
+ let val = value.toString();
1999
+ val = val.replace(/,/, "");
2000
+ value = val.replace(".", ",");
2001
+ type = "number";
2002
+ }
2003
+ else if (format) {
2004
+ value = this.dates.getFormatted(value, format.length <= 10, format.length > 16);
2005
+ type = "date";
2006
+ }
2007
+ Object.defineProperty(obj, prop, { value: value !== null && value !== void 0 ? value : "", writable: false, enumerable: true });
2008
+ headers.push({ label, key: prop, order, type, propKey: null });
2009
+ }
2010
+ /**
2011
+ * Setup per l'esportazione di una lista di valori pivottati dinamicamente:
2012
+ *
2013
+ * => Recupero il valore utilizzando i navigatori
2014
+ *
2015
+ * => Recupero l'header utilizzando i navigatori
2016
+ *
2017
+ * => Con il valore ci creo la property
2018
+ *
2019
+ * => Con l'header e il riferimento alla property appena creata creo un record negli header da esportare
2020
+ *
2021
+ * @param {any} obj Oggetto di cui esportare la proprietà **prop**
2022
+ * @param {string} prop Proprietà da esportare
2023
+ * @param {CsvHeaders} headers Contenitore degli header, verrà riempito da questa funzione
2024
+ * @param {LocalizationService} loc Servizio di localizzazione che traduce tutti i nomi che può
2025
+ */
2026
+ parseList(obj, prop, headers, columnsSelection, loc) {
2027
+ let headernavigator = obj[prop + listCsvHdrPrefix];
2028
+ let valuenavigator = obj[prop + listCsvValPrefix];
2029
+ let valueformat = obj[prop + listCsvValFormat];
2030
+ let order = obj[prop + csvOrdPrefix];
2031
+ var jumps, tmpRes;
2032
+ var objs = obj[prop];
2033
+ for (let idx = 0; idx < objs.length; idx++) {
2034
+ let listitem = objs[idx];
2035
+ var headersplit = headernavigator.split(" ");
2036
+ var label = "";
2037
+ // Per l'header si considera a se stante ogni pezzo separato da spazio per fare le concatenazioni
2038
+ headersplit.forEach(pr => {
2039
+ jumps = pr.split(".");
2040
+ tmpRes = JSON.parse(JSON.stringify(listitem));
2041
+ jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
2042
+ let localized = !!loc ? loc.loc(tmpRes) : tmpRes;
2043
+ if (!label)
2044
+ label = localized;
2045
+ else
2046
+ label += " " + localized;
2047
+ });
2048
+ jumps = valuenavigator.split(".");
2049
+ tmpRes = JSON.parse(JSON.stringify(listitem));
2050
+ jumps.forEach(pp => { tmpRes = tmpRes[pp]; });
2051
+ let value = tmpRes;
2052
+ let type = "string";
2053
+ if (valueformat == "F") {
2054
+ let val = value != null ? value.toString() : "";
2055
+ val = val.replace(/,/, "");
2056
+ value = val.replace(".", ",");
2057
+ type = "number";
2058
+ }
2059
+ else if (valueformat) {
2060
+ value = this.dates.getFormatted(obj[prop], valueformat.length <= 10, valueformat.length > 16);
2061
+ type = "date";
2062
+ }
2063
+ Object.defineProperty(obj, prop + idx, { value: value !== null && value !== void 0 ? value : "", writable: false });
2064
+ headers.push({ label, key: prop + idx, order: order + idx, type, propKey: null });
2065
+ }
2066
+ }
2067
+ /**
2068
+ * Setup per l'esportazione di una lista di valori pivottati dinamicamente:
2069
+ *
2070
+ * => Recupero il valore utilizzando i navigatori
2071
+ *
2072
+ * => Recupero l'header utilizzando i navigatori
2073
+ *
2074
+ * => Con il valore ci creo la property
2075
+ *
2076
+ * => Con l'header e il riferimento alla property appena creata creo un record negli header da esportare
2077
+ *
2078
+ * @param {any} obj Oggetto di cui esportare la proprietà **prop**
2079
+ * @param {string} prop Proprietà da esportare
2080
+ * @param {CsvHeaders} headers Contenitore degli header, verrà riempito da questa funzione
2081
+ */
2082
+ parseDictionary(obj, prop, headers, columnsSelection) {
2083
+ let headerprefix = obj[prop + dictionaryCsvHdrPrefix];
2084
+ let valueprefix = obj[prop + dictionaryCsvValPrefix];
2085
+ let order = obj[prop + csvOrdPrefix];
2086
+ var object = obj[prop];
2087
+ let idx = 0;
2088
+ for (const [key, val] of Object.entries(object)) {
2089
+ // Ignoro tutti i cmapi che non fanno parte della selezione delle colonne
2090
+ if (key && !columnsSelection[key] && Object.keys(columnsSelection).length > 0) {
2091
+ console.log("[@esfaenza/extensions] Colonna da non esportare: " + key);
2092
+ return;
2093
+ }
2094
+ let propname = prop + "_" + key;
2095
+ let value = valueprefix ? valueprefix + " " + val : val;
2096
+ let label = headerprefix ? headerprefix + " " + key : key;
2097
+ Object.defineProperty(obj, propname, { value: value !== null && value !== void 0 ? value : "", writable: false });
2098
+ headers.push({ label: label, key: propname, order: order + idx++, type: 'string', propKey: null });
2099
+ }
2100
+ }
2101
+ /**
2102
+ * Effettua l'esportazione in file CSV
2103
+ */
2104
+ exportCSV(fn, headers, data) {
2105
+ let csvData = '', row = '', sep = ';';
2106
+ for (let i = 0; i < headers.length; i++) {
2107
+ let h = headers[i];
2108
+ row += `${row != '' ? sep : ''}"${h.label}"`;
2109
+ }
2110
+ csvData += row + '\r\n';
2111
+ for (let i = 0; i < data.length; i++) {
2112
+ row = '';
2113
+ let item = data[i];
2114
+ for (let j = 0; j < headers.length; j++) {
2115
+ let val = item[headers[j].key];
2116
+ row += `${row != '' ? sep : ''}"${val}"`;
2117
+ }
2118
+ csvData += row + '\r\n';
2119
+ }
2120
+ var BOM = new Uint8Array([0xEF, 0xBB, 0xBF]);
2121
+ var blob = new Blob([BOM, csvData], { type: 'text/csv' });
2122
+ var objectUrl = URL.createObjectURL(blob);
2123
+ this.utiExts.fileDownload(objectUrl, fn.endsWith('.xlsx') ? fn.replace('.xlsx', '.csv') : fn.endsWith('.csv') ? fn : fn + ".csv");
2124
+ }
2125
+ /** Effettua l'esportazione del file Excel basandosi sul modulo **ExcelJS**, sugli header **headers** e sui dati **data** */
2126
+ exportExcel(fn, headers, data) {
2127
+ return __awaiter(this, void 0, void 0, function* () {
2128
+ try {
2129
+ this.ExcelJS = this.ExcelJS || (yield import('exceljs'));
2130
+ }
2131
+ catch (_a) {
2132
+ throw "Impossibile caricare la libreria per l'esportazione in Excel";
2133
+ }
2134
+ let iFix = 1;
2135
+ let workbook = new this.ExcelJS.Workbook();
2136
+ workbook.creator = "Ema's big Es-Table";
2137
+ workbook.created = new Date();
2138
+ let sheet = workbook.addWorksheet('Data');
2139
+ let header = sheet.getRow(1);
2140
+ header.font = { bold: true };
2141
+ headers = headers.sort((a, b) => a.order - b.order);
2142
+ for (let i = 0; i < headers.length; i++) {
2143
+ let h = headers[i];
2144
+ header.getCell(i + iFix).value = h.label;
2145
+ }
2146
+ for (let i = 0; i < data.length; i++) {
2147
+ let row = sheet.getRow(i + iFix + 1);
2148
+ let item = data[i];
2149
+ for (let i = 0; i < headers.length; i++) {
2150
+ let h = headers[i];
2151
+ let cell = row.getCell(i + 1);
2152
+ let val = item[h.key];
2153
+ if (!val) {
2154
+ cell.value = "";
2155
+ continue;
2156
+ }
2157
+ switch (h.type) {
2158
+ case 'date':
2159
+ // ExcelJS va di default in UTC quindi rischierebbe di tirare giù 2 ore ad ogni esportazione
2160
+ // Bisogna aggiungere l'utc offset alla data attuale
2161
+ let date = this.dates.getDateConvertion(val);
2162
+ if (date) {
2163
+ let correctedDate = date.add(date.utcOffset(), 'minute');
2164
+ cell.value = correctedDate.toDate();
2165
+ cell.numFmt = val.length > 10 ? 'dd/mm/yyyy h:m:s' : '';
2166
+ }
2167
+ break;
2168
+ case 'number':
2169
+ let converted = parseFloat(val.replace(',', '.'));
2170
+ cell.value = isNaN(converted) ? "" : converted;
2171
+ break;
2172
+ default:
2173
+ cell.value = val;
2174
+ break;
2175
+ }
2176
+ }
2177
+ }
2178
+ let buffer = yield workbook.xlsx.writeBuffer();
2179
+ let blob = new Blob([buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;" });
2180
+ let objectUrl = URL.createObjectURL(blob);
2181
+ this.utiExts.fileDownload(objectUrl, fn.endsWith('.csv') ? fn.replace('.csv', '.xlsx') : fn.endsWith('.xlsx') ? fn : fn + ".xlsx");
2182
+ });
2183
+ }
2184
+ /**
2185
+ * Metodo che effettivamente genera gli header e i dati per l'esportazione con **ngx-csv**
2186
+ *
2187
+ * @param {any[]} items Oggetti da esportare
2188
+ */
2189
+ export(items, format, fileName, type, columnsFilter, genericHeaders) {
2190
+ // Deepclone con assegnatura del tipo
2191
+ var createdItems = items.map(t => this.utiExts.deepClone(t, type));
2192
+ let headers = genericHeaders ? this.setupForGenericExport(createdItems, genericHeaders) : this.setupForExport(createdItems, columnsFilter);
2193
+ (format == "CSV" ? this.exportCSV : this.exportExcel).bind(this)(fileName, headers, createdItems);
2194
+ return headers;
2195
+ }
2196
+ }
2197
+ ExportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService, deps: [{ token: DateService }, { token: UtilityService }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Injectable });
2198
+ ExportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService, providedIn: "root" });
2199
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ExportService, decorators: [{
2200
+ type: Injectable,
2201
+ args: [{ providedIn: "root" }]
2202
+ }], ctorParameters: function () { return [{ type: DateService }, { type: UtilityService }, { type: i1.LocalizationService }]; } });
2203
+
2204
+ /**
2205
+ * Service che fornisce un accesso base in lettura/scrittura sulla clipboard
2206
+ */
2207
+ class ClipboardService {
2208
+ /**
2209
+ * Costruttore
2210
+ *
2211
+ * @ignore
2212
+ */
2213
+ constructor(msgService, locProvider) {
2214
+ this.msgService = msgService;
2215
+ this.locProvider = locProvider;
2216
+ /**
2217
+ * Oggetto statico di localizzazione per i messaggi di questa Service
2218
+ */
2219
+ this.loc = {
2220
+ "Unfortunately Firefox doesn't yet support direct Clipboard access if not via extensions, Please use Chrome to do this operation": {
2221
+ 'en-US': "Unfortunately Firefox doesn't yet support direct Clipboard access if not via extensions, Please use Chrome to do this operation",
2222
+ 'it-IT': "Mi dispiace ma Firefox non supporta l'accesso diretto alla Clipboard, se non attraverso le estensioni. Si prega di usare Chrome"
2223
+ },
2224
+ "Generic error during 'copy' command execution": {
2225
+ 'en-US': "Generic error during 'copy' command execution",
2226
+ 'it-IT': "Errore generico durante l'esecuzione del comando 'copy'"
2227
+ },
2228
+ "Error during Clipboard content read operation": {
2229
+ 'en-US': "Error during Clipboard content read operation",
2230
+ 'it-IT': "Errore nella lettura del contenuto della Clipboard"
2231
+ },
2232
+ "Error during Clipboard content copy operation": {
2233
+ 'en-US': "Error during Clipboard content copy operation",
2234
+ 'it-IT': "Errore nella scrittura del contenuto nella Clipboard"
2235
+ },
2236
+ "Please insert your clipboard content": {
2237
+ 'en-US': "Please insert your clipboard content",
2238
+ 'it-IT': "Si prega di incollare il contenuto della Clipboard"
2239
+ },
2240
+ "User input required": {
2241
+ 'en-US': "User input required",
2242
+ 'it-IT': "Richiesto Input utente"
2243
+ },
2244
+ "Your current browser does not support reading from the clipboard directly. Please paste your clipboard's content in this Input field and confirm the operation": {
2245
+ 'en-US': "Your current browser does not support reading from the clipboard directly. Please paste your clipboard's content in this Input field and confirm the operation",
2246
+ 'it-IT': "Il browser corrente non supporta la lettura diretta dei dati della Clipboard, si prega di effettuare un'incolla (CTRL + V) nella casella di testo e confermare l'operazione"
2247
+ },
2248
+ "Confirm": {
2249
+ 'en-US': "Confirm",
2250
+ 'it-IT': "Conferma"
2251
+ },
2252
+ "Cancel": {
2253
+ 'en-US': "Cancel",
2254
+ 'it-IT': "Annulla"
2255
+ },
2256
+ };
2257
+ }
2258
+ /**
2259
+ * Prende il valore della clipboard.
2260
+ * Si può specificare se ci si aspetta una lista o una matrice di valori in modo da ricevere già un risultato utilizzabile
2261
+ *
2262
+ * @param {'array' | 'matrix'} style Stile dell'output desiderato, se array o matrice
2263
+ * @param {Function} valueFoundCallback Callback che questa funzione chiamerà una volta ottenuto i valori richiesti dalla clipboard
2264
+ */
2265
+ getClipboard(style, valueFoundCallback) {
2266
+ return __awaiter(this, void 0, void 0, function* () {
2267
+ let LOCALE = this.locProvider ? yield this.locProvider.Locale.pipe(first()).toPromise() : 'it-IT';
2268
+ if (navigator.userAgent.indexOf("Firefox") != -1) {
2269
+ swal.fire({
2270
+ title: this.loc["User input required"][LOCALE],
2271
+ text: this.loc["Your current browser does not support reading from the clipboard directly. Please paste your clipboard's content in this Input field and confirm the operation"][LOCALE],
2272
+ input: 'textarea',
2273
+ icon: "warning",
2274
+ confirmButtonText: this.loc["Confirm"][LOCALE],
2275
+ cancelButtonText: this.loc["Cancel"][LOCALE],
2276
+ showCancelButton: true,
2277
+ customClass: {
2278
+ confirmButton: "btn btn-primary",
2279
+ cancelButton: "btn btn-secondary app-margin-right-15",
2280
+ container: "app-wrap",
2281
+ },
2282
+ reverseButtons: true,
2283
+ allowOutsideClick: false,
2284
+ inputValidator: (value) => {
2285
+ if (!value)
2286
+ return this.loc["Please insert your clipboard content"][LOCALE];
2287
+ }
2288
+ }).then(t => {
2289
+ if (t.isConfirmed) {
2290
+ console.log("[@esfaenza/extensions] Retrieving input data from user input");
2291
+ this.doClipboardDataGet(t.value, style, valueFoundCallback);
2292
+ }
2293
+ });
2294
+ return;
2295
+ }
2296
+ if (window.clipboardData) {
2297
+ console.log("[@esfaenza/extensions] Found clipboardData");
2298
+ let data = window.clipboardData.getData("Text");
2299
+ this.doClipboardDataGet(data, style, valueFoundCallback);
2300
+ }
2301
+ else if (window.navigator.clipboard) {
2302
+ console.log("[@esfaenza/extensions] Found navigator clipboard");
2303
+ window.navigator.permissions.query({ name: 'clipboard-read' }).then(result => {
2304
+ if (!(result.state === 'granted' || result.state === 'prompt')) {
2305
+ console.error("[@esfaenza/extensions] Clipboard permission not granted");
2306
+ if (valueFoundCallback)
2307
+ valueFoundCallback([]);
2308
+ return;
2309
+ }
2310
+ console.log("[@esfaenza/extensions] Clipboard permission granted, retrieving values");
2311
+ window.navigator.clipboard.readText()
2312
+ .then((t) => this.doClipboardDataGet(t, style, valueFoundCallback))
2313
+ .catch((err) => this.msgService.simpleError(this.loc["Error during Clipboard content read operation"][LOCALE] + ": " + err));
2314
+ });
2315
+ }
2316
+ });
2317
+ }
2318
+ /** @ignore */
2319
+ doClipboardDataGet(clipboardText, style, valueFoundCallback) {
2320
+ console.log("[@esfaenza/extensions] Retrieved clipboard values: " + clipboardText);
2321
+ let value = style == "array" ? this.getClipboardLines(clipboardText) :
2322
+ style == "matrix" ? this.getClipboardMatrix(clipboardText) : [];
2323
+ console.log(`[@esfaenza/extensions] Adapted for ${style}: ${JSON.stringify(value)}`);
2324
+ if (valueFoundCallback)
2325
+ valueFoundCallback(value);
2326
+ }
2327
+ /**
2328
+ * Ottiene il contenuto della clipboard diviso per righe (separate da newline)
2329
+ *
2330
+ * @param {string} data contenuto letto dalla clipboard
2331
+ *
2332
+ * @returns {string[]} Array contenente il testo preso dalla clipboard diviso per riga
2333
+ */
2334
+ getClipboardLines(data) {
2335
+ let trimmedData = data.trim();
2336
+ if (!trimmedData.includes("\r\n") && trimmedData.includes("\n"))
2337
+ return trimmedData.split("\n");
2338
+ return trimmedData.split("\r\n");
2339
+ }
2340
+ /**
2341
+ * Ottiene il contenuto della clipboard diviso per righe (separate da newline) e colonne (separate da tab)
2342
+ *
2343
+ * @param {string} data contenuto letto dalla clipboard
2344
+ *
2345
+ * @returns {string[][]} Matrice contenente il testo preso dalla clipboard diviso per riga e colonna
2346
+ */
2347
+ getClipboardMatrix(data) {
2348
+ var ret = [];
2349
+ var rows = !data.includes("\r\n") && data.includes("\n") ? data.split("\n") : data.split("\r\n");
2350
+ // A quanto pare ogni valore è separato da un \t... spero che sia uno standard di quando si copia da excel altrimenti ciao
2351
+ for (let i = 0; i < rows.length; i++)
2352
+ ret.push(rows[i].split('\t').map(t => t.trim()));
2353
+ return ret;
2354
+ }
2355
+ /**
2356
+ * Metodo che copia un testo all'interno della clipboard
2357
+ *
2358
+ * @param {string} text Testo da inserire nella clipboard
2359
+ */
2360
+ copyTextToClipboard(text) {
2361
+ return __awaiter(this, void 0, void 0, function* () {
2362
+ let LOCALE = this.locProvider ? yield this.locProvider.Locale.pipe(first()).toPromise() : 'it-IT';
2363
+ var textArea = document.createElement("textarea");
2364
+ //
2365
+ // *** This styling is an extra step which is likely not required. ***
2366
+ //
2367
+ // Why is it here? To ensure:
2368
+ // 1. the element is able to have focus and selection.
2369
+ // 2. if element was to flash render it has minimal visual impact.
2370
+ // 3. less flakyness with selection and copying which **might** occur if
2371
+ // the textarea element is not visible.
2372
+ //
2373
+ // The likelihood is the element won't even render, not even a flash,
2374
+ // so some of these are just precautions. However in IE the element
2375
+ // is visible whilst the popup box asking the user for permission for
2376
+ // the web page to copy to the clipboard.
2377
+ //
2378
+ // Place in top-left corner of screen regardless of scroll position.
2379
+ textArea.style.position = "fixed";
2380
+ textArea.style.top = "0";
2381
+ textArea.style.left = "0";
2382
+ // Ensure it has a small width and height. Setting to 1px / 1em
2383
+ // doesn't work as this gives a negative w/h on some browsers.
2384
+ textArea.style.width = "2em";
2385
+ textArea.style.height = "2em";
2386
+ // We don't need padding, reducing the size if it does flash render.
2387
+ textArea.style.padding = "0";
2388
+ // Clean up any borders.
2389
+ textArea.style.border = "none";
2390
+ textArea.style.outline = "none";
2391
+ textArea.style.boxShadow = "none";
2392
+ // Avoid flash of white box if rendered for any reason.
2393
+ textArea.style.background = "transparent";
2394
+ textArea.value = text;
2395
+ document.body.appendChild(textArea);
2396
+ textArea.focus();
2397
+ textArea.select();
2398
+ try {
2399
+ var successful = document.execCommand("copy");
2400
+ if (!successful)
2401
+ this.msgService.simpleError(this.loc["Generic error during 'copy' command execution"][LOCALE]);
2402
+ }
2403
+ catch (err) {
2404
+ this.msgService.simpleError(this.loc["Error during Clipboard content copy operation"][LOCALE] + ": " + err);
2405
+ }
2406
+ document.body.removeChild(textArea);
2407
+ });
2408
+ }
2409
+ }
2410
+ ClipboardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ClipboardService, deps: [{ token: MessageService }, { token: i1.BaseLocalization, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
2411
+ ClipboardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ClipboardService, providedIn: "root" });
2412
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ClipboardService, decorators: [{
2413
+ type: Injectable,
2414
+ args: [{ providedIn: "root" }]
2415
+ }], ctorParameters: function () {
2416
+ return [{ type: MessageService }, { type: i1.BaseLocalization, decorators: [{
2417
+ type: Optional
2418
+ }] }];
2419
+ } });
2420
+
2421
+ /**
2422
+ * Classe che rappresenta una risposta ricevuta da un Backend
2423
+ */
2424
+ class CallResult {
2425
+ }
2426
+
2427
+ /**
2428
+ * Header per il file CSV che sta venendo generato
2429
+ */
2430
+ class CsvHeaders {
2431
+ }
2432
+
2433
+ /**
2434
+ * Rappresentazione di un oggetto generico
2435
+ */
2436
+ class GenericItem {
2437
+ }
2438
+
2439
+ /** Enumeratore dei tipi di messaggio che i moduli esterni possono contattare sull'applicazione principale */
2440
+ var InboundMessageTypes;
2441
+ (function (InboundMessageTypes) {
2442
+ /** Evento di navigazione */
2443
+ InboundMessageTypes[InboundMessageTypes["Navigation"] = 0] = "Navigation";
2444
+ })(InboundMessageTypes || (InboundMessageTypes = {}));
2445
+
2446
+ /** Classe che rappresenta un generico messaggio scambiato fra applicazione e moduli */
2447
+ class InterComMessage {
2448
+ /**
2449
+ * Costruttore
2450
+ *
2451
+ * @param type Tipo di messaggio
2452
+ * @param message Contenuto del messaggio
2453
+ */
2454
+ constructor(type, message) {
2455
+ this.type = type;
2456
+ this.message = message;
2457
+ }
2458
+ }
2459
+
2460
+ // Angular
2461
+ /** Service che si occupa di gestire la comunicazione fra i moduli interni ed esterni dell'applicativo */
2462
+ class InterComService {
2463
+ constructor() {
2464
+ /** Messaggi in uscita, uno per ogni recipient registratosi dall'entrypoint **register** */
2465
+ this.outbounds = {};
2466
+ /** Messaggi in entrata, unico per applicazione principale */
2467
+ this.inbounds = new Subject();
2468
+ }
2469
+ /**
2470
+ * Metodo che permette di inviare un messaggio dall'applicazione ad un modulo esterno o viceversa
2471
+ *
2472
+ * @param {any} messageType Tipologia di messaggio. Sarà di tipo **InboundMessageTypes** per tutti i messaggi inbound, dinamico per tutti i mesaggi outbound (il tipo dipenderà dagli enum dei messaggi dei moduli esterni)
2473
+ * @param {any} message Messaggio da inviare che può essere un dto in casi complessi ma dovrà essere gestito a dovere lato implementativo
2474
+ * @param {string} recipient Destinatario del messaggio. Per i messaggi inbound dev'essere lasciato vuoto, per i messaggi outbound sarà valorizzato alla chiave del modulo a cui si vuole inviare il messaggio
2475
+ */
2476
+ send(messageType, message, recipient) {
2477
+ let msg = new InterComMessage(messageType, message);
2478
+ // Se non c'è un recipient significa che è un modulo esterno che invia messaggi al modulo main (quindi messaggio in entrata - inbound)
2479
+ // Altrimenti significa che è il modulo main ad inviare messaggi ai moduli esterni (messaggio in uscita - outbound)
2480
+ if (!recipient) {
2481
+ this.inbounds.next(msg);
2482
+ }
2483
+ else {
2484
+ if (!this.outbounds[recipient])
2485
+ console.warn("@esfaenza/extensions - InterComService: Impossibile inviare il messaggio al recipient " + recipient + " assicurarsi che il modulo sia caricato e che effettui la chiamata al metodo 'regisster'");
2486
+ else
2487
+ this.outbounds[recipient].next(msg);
2488
+ }
2489
+ }
2490
+ /**
2491
+ * Permette di registrare un modulo esterno alla lista dei moduli in listening sulla coda di messaggi
2492
+ *
2493
+ * @param {string} key Chiave del modulo da registrare. Tutti i messaggi inbound saranno inviati dall'applicazione principale su questa chiave
2494
+ */
2495
+ register(key) {
2496
+ if (this.outbounds[key])
2497
+ throw "@esfaenza/extensions - InterComService: Impossibile registrare più volte lo stesso modulo";
2498
+ this.outbounds[key] = new Subject();
2499
+ }
2500
+ }
2501
+ InterComService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: InterComService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2502
+ InterComService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: InterComService, providedIn: "root" });
2503
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: InterComService, decorators: [{
2504
+ type: Injectable,
2505
+ args: [{ providedIn: "root" }]
2506
+ }] });
2507
+
2508
+ /*
2509
+ * Public API Surface of extensions
2510
+ */
2511
+
2512
+ /**
2513
+ * Generated bundle index. Do not edit.
2514
+ */
2515
+
2516
+ export { APPSEARCH_PREFIX, AppEmbeddingExtensions, BaseExtensionsService, CallResult, ClipboardService, CsvHeaders, DateService, EXT_ALLOW_UTC, EXT_DEBUG_MODE, Export, ExportAs, ExportDictionary, ExportList, ExportLocalization, ExportService, ExtensionsModule, GenericItem, HashingService, InboundMessageTypes, InterComMessage, InterComService, LocDatePipe, MessageService, UtilityService };
2517
+ //# sourceMappingURL=esfaenza-extensions.mjs.map